]> git.donarmstrong.com Git - roundcube.git/commitdiff
Imported Upstream version 0.3
authorJérémy Bobbio <lunar@debian.org>
Sat, 18 Jun 2011 15:03:11 +0000 (17:03 +0200)
committerJérémy Bobbio <lunar@debian.org>
Sat, 18 Jun 2011 15:03:11 +0000 (17:03 +0200)
565 files changed:
.htaccess
CHANGELOG
INSTALL
INSTALL.orig [new file with mode: 0644]
README
SQL/mssql.initial.sql
SQL/mysql.initial.sql
SQL/postgres.initial.sql
SQL/sqlite.initial.sql
UPGRADING
bin/decrypt.php [new file with mode: 0644]
bin/modcss.php
bin/quotaimg.php
config/main.inc.php.dist
config/mimetypes.php
index.php
installer/check.php
installer/config.php
installer/index.php
installer/rcube_install.php
installer/test.php
installer/utils.php
plugins/additional_message_headers/additional_message_headers.php [new file with mode: 0644]
plugins/archive/archive.js [new file with mode: 0644]
plugins/archive/archive.php [new file with mode: 0644]
plugins/archive/archive_act.png [new file with mode: 0644]
plugins/archive/archive_pas.png [new file with mode: 0644]
plugins/archive/foldericon.png [new file with mode: 0644]
plugins/archive/localization/de_CH.inc [new file with mode: 0644]
plugins/archive/localization/de_DE.inc [new file with mode: 0644]
plugins/archive/localization/en_US.inc [new file with mode: 0644]
plugins/archive/localization/fr_FR.inc [new file with mode: 0644]
plugins/archive/localization/pl_PL.inc [new file with mode: 0644]
plugins/autologon/autologon.php [new file with mode: 0644]
plugins/database_attachments/database_attachments.php [new file with mode: 0644]
plugins/debug_logger/debug_logger.php [new file with mode: 0644]
plugins/debug_logger/runlog/runlog.php [new file with mode: 0644]
plugins/emoticons/emoticons.php [new file with mode: 0644]
plugins/example_addressbook/example_addressbook.php [new file with mode: 0644]
plugins/example_addressbook/example_addressbook_backend.php [new file with mode: 0644]
plugins/filesystem_attachments/filesystem_attachments.php [new file with mode: 0644]
plugins/help/config.inc.php.dist [new file with mode: 0644]
plugins/help/content/about.html [new file with mode: 0644]
plugins/help/content/license.html [new file with mode: 0644]
plugins/help/help.php [new file with mode: 0644]
plugins/help/localization/en_GB.inc [new file with mode: 0644]
plugins/help/localization/en_US.inc [new file with mode: 0644]
plugins/help/localization/et_EE.inc [new file with mode: 0644]
plugins/help/localization/pl_PL.inc [new file with mode: 0644]
plugins/help/localization/sv_SE.inc [new file with mode: 0644]
plugins/help/skins/default/help.css [new file with mode: 0644]
plugins/help/skins/default/help.gif [new file with mode: 0644]
plugins/help/skins/default/templates/help.html [new file with mode: 0644]
plugins/http_authentication/http_authentication.php [new file with mode: 0644]
plugins/managesieve/Changelog [new file with mode: 0644]
plugins/managesieve/config.inc.php.dist [new file with mode: 0644]
plugins/managesieve/lib/Net/Sieve.php [new file with mode: 0644]
plugins/managesieve/lib/rcube_sieve.php [new file with mode: 0644]
plugins/managesieve/localization/bg_BG.inc [new file with mode: 0644]
plugins/managesieve/localization/de_CH.inc [new file with mode: 0644]
plugins/managesieve/localization/de_DE.inc [new file with mode: 0644]
plugins/managesieve/localization/en_US.inc [new file with mode: 0644]
plugins/managesieve/localization/es_ES.inc [new file with mode: 0644]
plugins/managesieve/localization/et_EE.inc [new file with mode: 0644]
plugins/managesieve/localization/fi_FI.inc [new file with mode: 0644]
plugins/managesieve/localization/fr_FR.inc [new file with mode: 0644]
plugins/managesieve/localization/gb_GB.inc [new file with mode: 0644]
plugins/managesieve/localization/hu_HU.inc [new file with mode: 0644]
plugins/managesieve/localization/it_IT.inc [new file with mode: 0644]
plugins/managesieve/localization/nl_NL.inc [new file with mode: 0644]
plugins/managesieve/localization/pl_PL.inc [new file with mode: 0644]
plugins/managesieve/localization/pt_BR.inc [new file with mode: 0644]
plugins/managesieve/localization/ru_RU.inc [new file with mode: 0644]
plugins/managesieve/localization/sl_SI.inc [new file with mode: 0644]
plugins/managesieve/localization/sv_SE.inc [new file with mode: 0644]
plugins/managesieve/localization/uk_UA.inc [new file with mode: 0644]
plugins/managesieve/localization/zh_CN.inc [new file with mode: 0644]
plugins/managesieve/managesieve.js [new file with mode: 0644]
plugins/managesieve/managesieve.php [new file with mode: 0644]
plugins/managesieve/skins/default/filter_add_act.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_add_pas.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_add_sel.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_del_act.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_del_pas.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_del_sel.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_down_act.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_down_pas.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_down_sel.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_up_act.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_up_pas.png [new file with mode: 0644]
plugins/managesieve/skins/default/filter_up_sel.png [new file with mode: 0644]
plugins/managesieve/skins/default/managesieve.css [new file with mode: 0644]
plugins/managesieve/skins/default/templates/managesieve.html [new file with mode: 0644]
plugins/managesieve/skins/default/templates/managesieveedit.html [new file with mode: 0644]
plugins/markasjunk/junk_act.png [new file with mode: 0644]
plugins/markasjunk/junk_pas.png [new file with mode: 0644]
plugins/markasjunk/localization/en_US.inc [new file with mode: 0644]
plugins/markasjunk/localization/et_EE.inc [new file with mode: 0644]
plugins/markasjunk/localization/pl_PL.inc [new file with mode: 0644]
plugins/markasjunk/localization/sv_SE.inc [new file with mode: 0644]
plugins/markasjunk/markasjunk.js [new file with mode: 0644]
plugins/markasjunk/markasjunk.php [new file with mode: 0644]
plugins/new_user_dialog/localization/de_CH.inc [new file with mode: 0644]
plugins/new_user_dialog/localization/de_DE.inc [new file with mode: 0644]
plugins/new_user_dialog/localization/en_US.inc [new file with mode: 0644]
plugins/new_user_dialog/localization/et_EE.inc [new file with mode: 0644]
plugins/new_user_dialog/localization/pl_PL.inc [new file with mode: 0644]
plugins/new_user_dialog/localization/sv_SE.inc [new file with mode: 0644]
plugins/new_user_dialog/new_user_dialog.php [new file with mode: 0644]
plugins/new_user_dialog/newuserdialog.css [new file with mode: 0644]
plugins/new_user_identity/new_user_identity.php [new file with mode: 0644]
plugins/password/README [new file with mode: 0644]
plugins/password/config.inc.php.dist [new file with mode: 0644]
plugins/password/drivers/chgsaslpasswd.c [new file with mode: 0644]
plugins/password/drivers/directadmin.php [new file with mode: 0644]
plugins/password/drivers/ldap.php [new file with mode: 0644]
plugins/password/drivers/poppassd.php [new file with mode: 0644]
plugins/password/drivers/sasl.php [new file with mode: 0644]
plugins/password/drivers/sql.php [new file with mode: 0644]
plugins/password/localization/de_CH.inc [new file with mode: 0644]
plugins/password/localization/de_DE.inc [new file with mode: 0644]
plugins/password/localization/en_US.inc [new file with mode: 0644]
plugins/password/localization/et_EE.inc [new file with mode: 0644]
plugins/password/localization/fr_FR.inc [new file with mode: 0644]
plugins/password/localization/hu_HU.inc [new file with mode: 0644]
plugins/password/localization/it_IT.inc [new file with mode: 0644]
plugins/password/localization/nl_NL.inc [new file with mode: 0644]
plugins/password/localization/pl_PL.inc [new file with mode: 0644]
plugins/password/localization/pt_BR.inc [new file with mode: 0644]
plugins/password/localization/pt_PT.inc [new file with mode: 0644]
plugins/password/localization/sl_SI.inc [new file with mode: 0644]
plugins/password/localization/sv_SE.inc [new file with mode: 0644]
plugins/password/password.js [new file with mode: 0644]
plugins/password/password.php [new file with mode: 0644]
plugins/show_additional_headers/show_additional_headers.php [new file with mode: 0644]
plugins/squirrelmail_usercopy/config.inc.php.dist [new file with mode: 0644]
plugins/squirrelmail_usercopy/squirrelmail_usercopy.php [new file with mode: 0644]
plugins/subscriptions_option/localization/en_US.inc [new file with mode: 0644]
plugins/subscriptions_option/localization/et_EE.inc [new file with mode: 0644]
plugins/subscriptions_option/localization/pl_PL.inc [new file with mode: 0644]
plugins/subscriptions_option/localization/sv_SE.inc [new file with mode: 0644]
plugins/subscriptions_option/subscriptions_option.php [new file with mode: 0644]
plugins/userinfo/localization/de_CH.inc [new file with mode: 0644]
plugins/userinfo/localization/en_US.inc [new file with mode: 0644]
plugins/userinfo/localization/et_EE.inc [new file with mode: 0644]
plugins/userinfo/localization/pl_PL.inc [new file with mode: 0644]
plugins/userinfo/localization/pt_PT.inc [new file with mode: 0644]
plugins/userinfo/localization/sv_SE.inc [new file with mode: 0644]
plugins/userinfo/userinfo.js [new file with mode: 0644]
plugins/userinfo/userinfo.php [new file with mode: 0644]
plugins/vcard_attachments/vcard_add_contact.png [new file with mode: 0644]
plugins/vcard_attachments/vcard_attachments.php [new file with mode: 0644]
plugins/vcard_attachments/vcardattach.js [new file with mode: 0644]
program/include/bugs.inc
program/include/html.php
program/include/iniset.php
program/include/main.inc
program/include/rcmail.php
program/include/rcube_addressbook.php [new file with mode: 0644]
program/include/rcube_browser.php
program/include/rcube_config.php
program/include/rcube_contacts.php
program/include/rcube_html_page.php
program/include/rcube_imap.php
program/include/rcube_json_output.php
program/include/rcube_ldap.php
program/include/rcube_mail_mime.php
program/include/rcube_mdb2.php
program/include/rcube_message.php
program/include/rcube_plugin.php [new file with mode: 0644]
program/include/rcube_plugin_api.php [new file with mode: 0644]
program/include/rcube_shared.inc
program/include/rcube_smtp.inc [deleted file]
program/include/rcube_smtp.php [new file with mode: 0644]
program/include/rcube_string_replacer.php
program/include/rcube_template.php
program/include/rcube_user.php
program/include/rcube_vcard.php
program/include/session.inc
program/js/app.js
program/js/app.js.src [deleted file]
program/js/common.js
program/js/common.js.src [deleted file]
program/js/editor.js
program/js/googiespell.js
program/js/googiespell.js.src [deleted file]
program/js/jquery-1.3.min.js [new file with mode: 0644]
program/js/list.js
program/js/list.js.src [deleted file]
program/js/tiny_mce/plugins/compat2x/editor_plugin.js
program/js/tiny_mce/plugins/contextmenu/editor_plugin.js
program/js/tiny_mce/plugins/directionality/editor_plugin.js
program/js/tiny_mce/plugins/emotions/editor_plugin.js
program/js/tiny_mce/plugins/emotions/emotions.htm
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/media.htm
program/js/tiny_mce/plugins/nonbreaking/editor_plugin.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/paste/js/pastetext.js
program/js/tiny_mce/plugins/paste/js/pasteword.js
program/js/tiny_mce/plugins/paste/pastetext.htm
program/js/tiny_mce/plugins/paste/pasteword.htm
program/js/tiny_mce/plugins/searchreplace/editor_plugin.js
program/js/tiny_mce/plugins/searchreplace/js/searchreplace.js
program/js/tiny_mce/plugins/searchreplace/searchreplace.htm
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/merge_cells.js
program/js/tiny_mce/plugins/table/js/table.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/xhtmlxtras/abbr.htm
program/js/tiny_mce/plugins/xhtmlxtras/acronym.htm
program/js/tiny_mce/plugins/xhtmlxtras/attributes.htm
program/js/tiny_mce/plugins/xhtmlxtras/cite.htm
program/js/tiny_mce/plugins/xhtmlxtras/del.htm
program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin.js
program/js/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js
program/js/tiny_mce/plugins/xhtmlxtras/ins.htm
program/js/tiny_mce/plugins/xhtmlxtras/js/del.js
program/js/tiny_mce/plugins/xhtmlxtras/js/element_common.js
program/js/tiny_mce/plugins/xhtmlxtras/js/ins.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/link.js
program/js/tiny_mce/themes/advanced/js/source_editor.js
program/js/tiny_mce/themes/advanced/link.htm
program/js/tiny_mce/themes/advanced/skins/default/dialog.css
program/js/tiny_mce/themes/advanced/skins/default/ui.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/themes/simple/skins/default/ui.css
program/js/tiny_mce/themes/simple/skins/o2k7/ui.css
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/lib/enriched.inc
program/lib/icl_commons.inc [deleted file]
program/lib/imap.inc
program/lib/mime.inc
program/lib/tnef_decoder.inc
program/lib/washtml.php
program/localization/ar_SA/labels.inc
program/localization/ast/labels.inc
program/localization/az_AZ/labels.inc
program/localization/bg_BG/labels.inc
program/localization/bn_BD/labels.inc
program/localization/br/labels.inc [new file with mode: 0644]
program/localization/br/messages.inc [new file with mode: 0644]
program/localization/bs_BA/labels.inc
program/localization/ca_ES/labels.inc
program/localization/ca_ES/messages.inc
program/localization/cs_CZ/labels.inc
program/localization/cs_CZ/messages.inc
program/localization/cy_GB/labels.inc
program/localization/cy_GB/messages.inc
program/localization/da_DK/labels.inc
program/localization/da_DK/messages.inc
program/localization/de_CH/labels.inc
program/localization/de_CH/messages.inc
program/localization/de_DE/labels.inc
program/localization/de_DE/messages.inc
program/localization/el_GR/labels.inc
program/localization/en_GB/labels.inc
program/localization/en_GB/messages.inc
program/localization/en_US/labels.inc
program/localization/en_US/messages.inc
program/localization/eo/labels.inc
program/localization/es_AR/labels.inc
program/localization/es_AR/messages.inc
program/localization/es_ES/labels.inc
program/localization/es_ES/messages.inc
program/localization/et_EE/labels.inc
program/localization/et_EE/messages.inc
program/localization/eu_ES/labels.inc
program/localization/fa/labels.inc
program/localization/fa_AF/labels.inc [new file with mode: 0644]
program/localization/fa_AF/messages.inc [new file with mode: 0644]
program/localization/fi_FI/labels.inc
program/localization/fi_FI/messages.inc
program/localization/fr_FR/labels.inc
program/localization/fr_FR/messages.inc
program/localization/ga_IE/labels.inc
program/localization/gl_ES/labels.inc
program/localization/gl_ES/messages.inc
program/localization/he_IL/labels.inc
program/localization/he_IL/messages.inc
program/localization/hi_IN/labels.inc
program/localization/hr_HR/labels.inc
program/localization/hu_HU/labels.inc
program/localization/hu_HU/messages.inc
program/localization/hy_AM/labels.inc
program/localization/hy_AM/messages.inc
program/localization/id_ID/labels.inc
program/localization/id_ID/messages.inc
program/localization/index.inc
program/localization/is_IS/labels.inc
program/localization/it_IT/labels.inc
program/localization/it_IT/messages.inc
program/localization/ja_JP/labels.inc
program/localization/ja_JP/messages.inc
program/localization/ka_GE/labels.inc
program/localization/ko_KR/labels.inc
program/localization/ku/labels.inc
program/localization/lt_LT/labels.inc
program/localization/lt_LT/messages.inc
program/localization/lv_LV/labels.inc
program/localization/lv_LV/messages.inc
program/localization/mk_MK/labels.inc
program/localization/mr_IN/labels.inc [new file with mode: 0755]
program/localization/mr_IN/messages.inc [new file with mode: 0755]
program/localization/ms_MY/labels.inc
program/localization/nb_NO/labels.inc
program/localization/nb_NO/messages.inc
program/localization/ne_NP/labels.inc
program/localization/ne_NP/messages.inc
program/localization/nl_BE/labels.inc
program/localization/nl_NL/labels.inc
program/localization/nl_NL/messages.inc
program/localization/nn_NO/labels.inc
program/localization/pl_PL/labels.inc
program/localization/pl_PL/messages.inc
program/localization/ps/labels.inc [new file with mode: 0755]
program/localization/ps/messages.inc [new file with mode: 0755]
program/localization/pt_BR/labels.inc
program/localization/pt_BR/messages.inc
program/localization/pt_PT/labels.inc
program/localization/ro_RO/labels.inc
program/localization/ro_RO/messages.inc
program/localization/ru_RU/labels.inc
program/localization/ru_RU/messages.inc
program/localization/si_LK/labels.inc
program/localization/si_LK/messages.inc
program/localization/sk_SK/labels.inc
program/localization/sl_SI/labels.inc
program/localization/sl_SI/messages.inc
program/localization/sq_AL/labels.inc
program/localization/sr_CS/labels.inc
program/localization/sr_CS/messages.inc
program/localization/sv_SE/labels.inc
program/localization/sv_SE/messages.inc
program/localization/th_TH/labels.inc
program/localization/tr_TR/labels.inc
program/localization/tr_TR/messages.inc
program/localization/uk_UA/labels.inc
program/localization/vi_VN/labels.inc
program/localization/vi_VN/messages.inc
program/localization/zh_CN/labels.inc
program/localization/zh_TW/labels.inc
program/localization/zh_TW/messages.inc
program/steps/addressbook/copy.inc
program/steps/addressbook/delete.inc
program/steps/addressbook/edit.inc
program/steps/addressbook/export.inc
program/steps/addressbook/func.inc
program/steps/addressbook/import.inc
program/steps/addressbook/save.inc
program/steps/addressbook/search.inc
program/steps/error.inc
program/steps/mail/addcontact.inc
program/steps/mail/attachments.inc
program/steps/mail/autocomplete.inc
program/steps/mail/check_recent.inc
program/steps/mail/compose.inc
program/steps/mail/folders.inc
program/steps/mail/func.inc
program/steps/mail/get.inc
program/steps/mail/list.inc
program/steps/mail/mark.inc
program/steps/mail/move_del.inc
program/steps/mail/rss.inc
program/steps/mail/search.inc
program/steps/mail/sendmail.inc
program/steps/mail/sendmdn.inc
program/steps/mail/show.inc
program/steps/mail/spell_pspell.inc
program/steps/mail/viewsource.inc
program/steps/settings/delete_identity.inc
program/steps/settings/edit_identity.inc
program/steps/settings/edit_prefs.inc [new file with mode: 0644]
program/steps/settings/func.inc
program/steps/settings/manage_folders.inc
program/steps/settings/save_identity.inc
program/steps/settings/save_prefs.inc
skins/default/addresses.css
skins/default/common.css
skins/default/editor_content.css
skins/default/functions.js
skins/default/googiespell.css
skins/default/ie6hacks.css [new file with mode: 0644]
skins/default/iehacks.css [new file with mode: 0644]
skins/default/images/abook_toolbar.gif [new file with mode: 0644]
skins/default/images/abook_toolbar.png [new file with mode: 0644]
skins/default/images/buttons/add_act.png
skins/default/images/buttons/add_contact_act.png [deleted file]
skins/default/images/buttons/add_contact_pas.png [deleted file]
skins/default/images/buttons/add_contact_sel.png [deleted file]
skins/default/images/buttons/add_pas.png
skins/default/images/buttons/add_sel.png
skins/default/images/buttons/addressbook.gif [deleted file]
skins/default/images/buttons/addressbook.png [deleted file]
skins/default/images/buttons/adr_import_act.png [deleted file]
skins/default/images/buttons/adr_import_pas.png [deleted file]
skins/default/images/buttons/adr_import_sel.png [deleted file]
skins/default/images/buttons/attach_act.png [deleted file]
skins/default/images/buttons/attach_pas.png [deleted file]
skins/default/images/buttons/attach_sel.png [deleted file]
skins/default/images/buttons/back_act.png [deleted file]
skins/default/images/buttons/back_pas.png [deleted file]
skins/default/images/buttons/back_sel.png [deleted file]
skins/default/images/buttons/compose_act.png [deleted file]
skins/default/images/buttons/compose_pas.png [deleted file]
skins/default/images/buttons/compose_sel.png [deleted file]
skins/default/images/buttons/contacts_act.png [deleted file]
skins/default/images/buttons/contacts_pas.png [deleted file]
skins/default/images/buttons/contacts_sel.png [deleted file]
skins/default/images/buttons/delete_act.png [deleted file]
skins/default/images/buttons/delete_pas.png [deleted file]
skins/default/images/buttons/delete_sel.png [deleted file]
skins/default/images/buttons/down_arrow.png [deleted file]
skins/default/images/buttons/download_act.png [deleted file]
skins/default/images/buttons/download_pas.png [deleted file]
skins/default/images/buttons/download_sel.png [deleted file]
skins/default/images/buttons/drafts_act.png [deleted file]
skins/default/images/buttons/drafts_pas.png [deleted file]
skins/default/images/buttons/drafts_sel.png [deleted file]
skins/default/images/buttons/edit_contact_act.png [deleted file]
skins/default/images/buttons/edit_contact_pas.png [deleted file]
skins/default/images/buttons/edit_contact_sel.png [deleted file]
skins/default/images/buttons/first_act.png [deleted file]
skins/default/images/buttons/first_pas.png [deleted file]
skins/default/images/buttons/first_sel.png [deleted file]
skins/default/images/buttons/forward_act.png [deleted file]
skins/default/images/buttons/forward_pas.png [deleted file]
skins/default/images/buttons/forward_sel.png [deleted file]
skins/default/images/buttons/inbox_act.png [deleted file]
skins/default/images/buttons/inbox_pas.png [deleted file]
skins/default/images/buttons/inbox_sel.png [deleted file]
skins/default/images/buttons/last_act.png [deleted file]
skins/default/images/buttons/last_pas.png [deleted file]
skins/default/images/buttons/last_sel.png [deleted file]
skins/default/images/buttons/logout.gif [deleted file]
skins/default/images/buttons/logout.png [deleted file]
skins/default/images/buttons/mail.gif [deleted file]
skins/default/images/buttons/mail.png [deleted file]
skins/default/images/buttons/markread_act.png [deleted file]
skins/default/images/buttons/next_act.png [deleted file]
skins/default/images/buttons/next_pas.png [deleted file]
skins/default/images/buttons/next_sel.png [deleted file]
skins/default/images/buttons/previous_act.png [deleted file]
skins/default/images/buttons/previous_pas.png [deleted file]
skins/default/images/buttons/previous_sel.png [deleted file]
skins/default/images/buttons/print_act.png [deleted file]
skins/default/images/buttons/print_pas.png [deleted file]
skins/default/images/buttons/print_sel.png [deleted file]
skins/default/images/buttons/reply_act.png [deleted file]
skins/default/images/buttons/reply_pas.png [deleted file]
skins/default/images/buttons/reply_sel.png [deleted file]
skins/default/images/buttons/replyall_act.png [deleted file]
skins/default/images/buttons/replyall_pas.png [deleted file]
skins/default/images/buttons/replyall_sel.png [deleted file]
skins/default/images/buttons/send_act.png [deleted file]
skins/default/images/buttons/send_pas.png [deleted file]
skins/default/images/buttons/send_sel.png [deleted file]
skins/default/images/buttons/settings.gif [deleted file]
skins/default/images/buttons/settings.png [deleted file]
skins/default/images/buttons/source_act.png [deleted file]
skins/default/images/buttons/source_pas.png [deleted file]
skins/default/images/buttons/source_sel.png [deleted file]
skins/default/images/buttons/spacer.gif [deleted file]
skins/default/images/buttons/spellcheck_act.png [deleted file]
skins/default/images/buttons/spellcheck_pas.png [deleted file]
skins/default/images/buttons/spellcheck_sel.png [deleted file]
skins/default/images/buttons/up_arrow.png [deleted file]
skins/default/images/display/confirm.png [deleted file]
skins/default/images/display/icons.gif [new file with mode: 0644]
skins/default/images/display/icons.png [new file with mode: 0644]
skins/default/images/display/info.png [deleted file]
skins/default/images/display/warning.png [deleted file]
skins/default/images/favicon.ico
skins/default/images/icons/delete.png [new file with mode: 0644]
skins/default/images/icons/folder-closed.png [deleted file]
skins/default/images/icons/folder-drafts.png [deleted file]
skins/default/images/icons/folder-inbox.png [deleted file]
skins/default/images/icons/folder-junk.png [deleted file]
skins/default/images/icons/folder-open.png [deleted file]
skins/default/images/icons/folder-sent.png [deleted file]
skins/default/images/icons/folder-trash.png [deleted file]
skins/default/images/icons/folders.gif [new file with mode: 0644]
skins/default/images/icons/folders.png [new file with mode: 0644]
skins/default/images/icons/glass.gif [new file with mode: 0644]
skins/default/images/icons/glass.png [new file with mode: 0644]
skins/default/images/icons/glass_roll.png [new file with mode: 0644]
skins/default/images/icons/remove-attachment.png [deleted file]
skins/default/images/icons/silhouette.png
skins/default/images/icons/sort.gif [new file with mode: 0644]
skins/default/images/listheader.gif [new file with mode: 0644]
skins/default/images/listheader_aqua.gif [deleted file]
skins/default/images/listheader_dark.gif [deleted file]
skins/default/images/listheader_light.gif [deleted file]
skins/default/images/mail_toolbar.gif [new file with mode: 0644]
skins/default/images/mail_toolbar.png [new file with mode: 0644]
skins/default/images/messageactions.gif [new file with mode: 0644]
skins/default/images/messageactions.png [new file with mode: 0644]
skins/default/images/pagenav.gif [new file with mode: 0644]
skins/default/images/roundcube_logo.gif [deleted file]
skins/default/images/roundcube_logo.png
skins/default/images/roundcube_logo_print.gif [deleted file]
skins/default/images/searchfield.gif
skins/default/images/sort_asc.gif [deleted file]
skins/default/images/sort_desc.gif [deleted file]
skins/default/images/tab_act.gif [deleted file]
skins/default/images/tab_pas.gif [deleted file]
skins/default/images/tabs.gif [new file with mode: 0644]
skins/default/images/taskicons.gif [new file with mode: 0644]
skins/default/images/taskicons.png [new file with mode: 0644]
skins/default/includes/links.html
skins/default/includes/messagemenu.html [new file with mode: 0644]
skins/default/includes/settingstabs.html
skins/default/includes/taskbar.html
skins/default/mail.css
skins/default/print.css
skins/default/safari.css [new file with mode: 0644]
skins/default/settings.css
skins/default/splitter.js
skins/default/templates/addcontact.html
skins/default/templates/addressbook.html
skins/default/templates/compose.html
skins/default/templates/editcontact.html
skins/default/templates/editidentity.html
skins/default/templates/error.html
skins/default/templates/identities.html
skins/default/templates/importcontacts.html
skins/default/templates/login.html
skins/default/templates/mail.html
skins/default/templates/managefolders.html
skins/default/templates/message.html
skins/default/templates/messageerror.html [new file with mode: 0644]
skins/default/templates/messagepart.html
skins/default/templates/messagepreview.html
skins/default/templates/plugin.html [new file with mode: 0644]
skins/default/templates/printmessage.html
skins/default/templates/settings.html
skins/default/templates/settingsedit.html [new file with mode: 0644]
skins/default/templates/showcontact.html
skins/default/watermark.html

index 36d574865ac6b8a30624a8d29891876a85ffa5df..19064fdcaad870a2ebb499ef0fc19c5d552e65c0 100644 (file)
--- a/.htaccess
+++ b/.htaccess
@@ -4,15 +4,16 @@ AddType text/x-component .htc
 <IfModule mod_php5.c>
 php_flag       display_errors  Off
 php_flag       log_errors      On
-php_value      error_log       logs/errors
+# php_value    error_log       logs/errors
 
 php_value      upload_max_filesize     5M
-php_value      post_max_size   6M
-php_value      memory_limit    64M
+php_value      post_max_size           6M
+php_value      memory_limit            64M
 
-php_value      zlib.output_compression 0
-php_value      magic_quotes_gpc        0
+php_value      zlib.output_compression         Off
+php_value      magic_quotes_gpc                0
 php_value      zend.ze1_compatibility_mode     0
+php_value      suhosin.session.encrypt         Off 
 
 php_value      session.auto_start      0
 php_value      session.gc_maxlifetime  21600
@@ -27,6 +28,21 @@ php_value    mbstring.func_overload  0
 RewriteEngine On
 RewriteRule ^favicon.ico$ skins/default/images/favicon.ico
 </IfModule>
-Order deny,allow
-Allow from all
+
+<IfModule mod_deflate.c>
+SetOutputFilter DEFLATE
+</IfModule>
+
+<IfModule mod_headers.c>
+# replace 'append' with 'merge' for Apache version 2.2.9 and later
+Header append Cache-Control public env=!NO_CACHE
+</IfModule>
+
+<IfModule mod_expires.c>
+ExpiresActive On
+ExpiresDefault "access plus 1 month"
+</IfModule>
+
+FileETag MTime Size
+
+
index ddf2027178a7064bb707441a1c303bd2f92298ba..b5d57b4e2b6a1251f04156aa722c06b6ede1fd93 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,71 +1,36 @@
-CHANGELOG RoundCube Webmail
+CHANGELOG Roundcube Webmail (release 0.3-stable)
 ===========================
 
-- Fix quicksearchbox look in Chrome and Konqueror (#1484841)
-- Fix UTF-8 byte-order mark removing (#1485514)
-- Fix folders subscribtions on Konqueror (#1484841) 
-- Fix debug console on Konqueror and Safari
-- Fix messagelist focus issue when modifying status of selected messages (#1485807)
-- Support STARTTLS in IMAP connection (#1485284)
-- Fix DEL key problem in search boxes (#1485528)
-- Support several e-mail addresses per user from virtuser_file (#1485678)
-- Fix drag&drop with scrolling on IE (#1485786)
-- Fix adding signature separator in html mode (#1485350)
-- Fix opening attachment marks message as read (#1485803)
-- Fix 'temp_dir' does not support relative path under Windows (#1484529)
-- Fix "Initialize Database" button missing from installer (#1485802)
-- Fix compose window doesn't fit 1024x768 window (#1485396)
-- Fix service not available error when pressing back from compose dialog (#1485552)
-- Fix using mail() on Windows (#1485779)
-- Fix word wrapping in message-part's <PRE>s for printing (#1485787)
-- Fix incorrect word wrapping in outgoing plaintext multibyte messages (#1485714)
-- Fix double footer in HTML message with embedded images
-- Fix TNEF implementation bug (#1485773)
-- Fix incorrect row id parsing for LDAP contacts list (#1485784) 
-- Fix 'mode' parameter in sqlite DSN (#1485772)
+- Fix gn and givenName should be synonymous in LDAP addressbook (#1485892)
+- Add mail_domain to LDAP email entries without @ sign (#1485201)
+- Fix saving empty values in LDAP contact data (#1485781)
+- Fix LDAP contact update when RDN field is changed (#1485788)
+- Fix LDAP attributes case senitivity problems (#1485830)
+- Fix LDAP addressbook browsing when only one directory is used (#1486022)
+- Fix endless loop on error response for APPEND command (#1486060)
+- Don't require date.timezone setting in installer (#1485989)
+- Fix date sorting problem with Courier IMAP server (#1486065)
+- Unselect pressed buttons on mouse up (#1485987)
+- Don't set php_value error_log in .htaccess but mention in INSTALL (#1485924)
+- Fix too small status/flag/attachment columns in Safari 4 (#1486063)
+- Fix selection disabling while dragging splitter in webkit browsers (#1486056)
+- Added 'new_messages' plugin hook (#1486005)
+- Added 'logout_after' plugin hook (#1486042)
+- Added 'message_compose' hook
+- Added 'imap_connect' hook (#1485956)
+- Fix vcard_attachments plugin (#1486035)
+- Updated PEAR::Auth_SASL to 1.0.3 version
+- Use sequence names only with PostgreSQL (#1486018)
+- Re-designed User Preferences interface 
+- Fix MS SQL DDL (#1486020)
+- Fix rcube_mdb2.php: call to setCharset not implemented in mssql driver (#1486019)
+- Added 'display_next' option
+- Fix rcube_mdb2::unixtimestamp for MS SQL (#1486015)
+- Fix HTML washing to respect character encoding
+- Fix endless loop in iil_C_Login() with Courier IMAP (#1486010)
+- Fix #messagemenu display on IE (#1486006)
+- Speedup UI by using sprites for (toolbar) buttons
+- Fix charset names with X- prefix handling
+- Fix displaying of HTML messages with unknown/malformed tags (#1486003)
+
 
-RELEASE 0.2.1
-------------------
-- Use US-ASCII as failover when Unicode searching fails (#1485762)
-- Fix errors handling in IMAP command continuations (#1485762)
-- Fix FETCH result parsing for servers returning flags at the end of result (#1485763)
-- Fix datetime columns defaults in mysql's DDL (#1485641)
-- Fix attaching more than nine inline images (#1485759)
-- Support 'UNICODE-1-1-UTF-7' alias for UTF-7 encoding (#1485758)
-- Fix mime-type detection using a hard-coded map (#1485311)
-- Don't return empty string if charset conversion failed (#1485757)
-- Disable concurrent autocomplete query results display (#1485743)
-- Fix new lines stripped from message footer (#1485751)
-- Fix IE problem with mouse click autocomplete (#1485739)
-- Fix html body washing on reply/forward + fix attachments handling (#1485676)
-- Fix multiple recipients input parsing (#1485733)
-- Fix replying to message with html attachment (#1485676)
-- Use default_charset for messages without specified charset (#1485661, #1484961)
-- Support non-standard "GMT-XXXX" literal in date header (#1485729)
-- Added TNEF support to decode MS Outlook attachments (winmail.dat)
-- Fix "value continuation" MIME headers by adding required semicolon (#1485727)
-- Fix pressing select all/unread multiple times (#1485723)
-- Fix selecting all unread does not honor new messages (#1485724)
-- Fix some base64 encoded attachments handling (#1485725)
-- Support NGINX as IMAP backend: better BAD response handling (#1485720)
-- Performance fix: don't fetch attachment parts headers twice to parse filename
-- Fix checking for recent messages on various IMAP servers (#1485702)
-- Performance fix: Don't fetch quota and recent messages in "message view" mode
-- Fix displaying of alternative-inside-alternative messages (#1485713)
-- Fix MDNSent flag checking, use arbitrary keywords (asterisk) flag (#1485706)
-- Fix creation of folders with '&' sign in name
-- Fix parsing of email addresses without angle brackets (#1485693)
-- Save spellcheck corrections when switching from plain to html editor (and spellchecking is on)
-- Fix large search results on server without SORT capability (#1485668)
-- Get rid of preg_replace() with eval modifier and create_function usage (#1485686)
-- Bring back <base> and <link> tags in HTML messages
-- Fix XSS vulnerability through background attributes as reported by Julien Cayssol
-- Fix problems with backslash as IMAP hierarchy delimiter (#1484467)
-- Secure vcard export by getting rid of preg's 'e' modifier use (#1485689)
-- Fix authentication when submitting form with existing session (#1485679)
-- Allow absolute URLs to images in HTML messages/sigs (#1485666)
-- Fix message body which contains both inline attachments and emotions
-- Fix SQL query execution errors handling in rcube_mdb2 class (#1485509)
-- Fix address names with '@' sign handling (#1485654)
-- Improve messages display performance
-- Fix messages searching with 'to:' modifier
diff --git a/INSTALL b/INSTALL
index fe71cdf167ff5d072b83da4631991c4df5ab3d4e..ff905bd89ec548271f25b958e4cf49faad58b175 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -44,11 +44,20 @@ INSTALLATION
    - /logs
 3. Create a new database and a database user for RoundCube (see DATABASE SETUP)
 4. Point your browser to http://url-to-roundcube/installer/
-5. Follow the instructions of the install script (or see MANUAL CONFINGURATION)
+5. Follow the instructions of the install script (or see MANUAL CONFIGURATION)
 6. After creating and testing the configuration, remove the installer directory
 7. Done!
 
 
+CONFIGURATION HINTS
+===================
+
+RoundCube writes internal errors to the 'errors' log file located in the logs
+directory which can be configured in config/main.inc.php. If you want ordinary
+PHP errors to be logged there as well, enable the 'php_value error_log' line
+in the .htaccess file and set the path to the log file accordingly.
+
+
 DATABASE SETUP
 ==============
 
@@ -76,12 +85,16 @@ RoundCube with utf-8 charset.
 
 * SQLite
 --------
-Sqlite requires specifically php5 (sqlite in php4 currently doesn't
-work with roundcube), and you need sqlite 2 (preferably 2.8) to setup
-the sqlite db (sqlite 3.x also doesn't work at the moment). Here is
+You need sqlite 2 (preferably 2.8) to setup the sqlite db 
+(sqlite 3.x also doesn't work at the moment). Here is
 an example how you can setup the sqlite.db for roundcube:
 
 # sqlite -init SQL/sqlite.initial.sql sqlite.db
+Loading resources from SQL/sqlite.initial.sql
+SQLite version 2.8.16
+Enter ".help" for instructions
+sqlite> .exit
+# chmod o+rw sqlite.db
 
 Make sure your configuration points to the sqlite.db file and that the
 webserver can write to the file and the directory containing the file.
@@ -126,3 +139,80 @@ If you already have a previous version of RoundCube installed,
 please refer to the instructions in UPGRADING guide.
 
 
+OPTIMISING
+==========
+
+There are two forms of optimisation here, compression and caching, both aimed
+at increasing an end user's experience using RoundCube Webmail. Compression
+allows the static web pages to be delivered with less bandwidth. The index.php
+of RoundCube Webmail already enables compression on its output. The settings
+below allow compression to occur for all static files. Caching sets HTTP 
+response headers that enable a user's web client to understand what is static
+and how to cache it.
+
+The caching directives used are:
+ * Etags - sets at tag so the client can request is the page has changed
+ * Cache-control - defines the age of the page and that the page is 'public'
+   This enables clients to cache javascript files that don't have private 
+   information between sessions even if using HTTPS. It also allows proxies
+   to share the same cached page between users.
+ * Expires - provides another hint to increase the lifetime of static pages.
+
+For more information refer to RFC 2616.
+
+Side effects:
+-------------
+These directives are designed for production use. If you are using this in
+a development environment you may get horribly confused if your webclient
+is caching stuff that you changed on the server. Disabling the expires 
+parts below should save you some grief.
+
+If you are changing the skins, it is recommended that you copy content to 
+a different directory apart from 'default'.
+
+Apache:
+-------
+To enable these features in apache the following modules need to be enabled:
+ * mod_deflate
+ * mod_expires
+ * mod_headers
+
+The optimisation is already included in the .htaccess file in the top 
+directory of your installation.
+
+If you are using Apache version 2.2.9 and later, in the .htaccess file
+change the 'append' word to 'merge' for a more correct response. Keeping
+as 'append' shouldn't cause any problems though changing to merge will 
+eliminate the possibility of duplicate 'public' headers in Cache-control.
+
+Lighttpd:
+---------
+With Lightty the addition of Expire: tags by mod_expire is incompatible with
+the addition of "Cache-control: public". Using Cache-control 'public' is 
+used below as it is assumed to give a better caching result.
+
+Enable modules in server.modules:
+    "mod_setenv"
+    "mod_compress"
+
+Mod_compress is a server side cache of compressed files to improve its performance.
+
+$HTTP["host"] == "www.example.com" {
+
+    static-file.etags = "enable"
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Etag.use-mtimeDetails
+    etag.use-mtime = "enable"
+
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModSetEnv
+    $HTTP["url"] =~ "^/roundcubemail/(plugins|skins|program)" {
+        setenv.add-response-header  = ( "Cache-Control" => "public, max-age=2592000")
+    }
+
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModCompress
+    # set compress.cache-dir to somewhere outside the docroot.
+    compress.cache-dir   = var.statedir + "/cache/compress"
+
+    compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml", "image/gif", "image/png")
+}
+
+
diff --git a/INSTALL.orig b/INSTALL.orig
new file mode 100644 (file)
index 0000000..67fbce9
--- /dev/null
@@ -0,0 +1,212 @@
+INTRODUCTION
+============
+
+This file describes the basic steps to install RoundCube Webmail on your
+web server. For additional information, please also consult the project's
+wiki page at http://trac.roundcube.net/wiki
+
+
+REQUIREMENTS
+============
+
+* The Apache or Lighttpd Webserver
+* .htaccess support allowing overrides for DirectoryIndex
+* PHP Version 5.2 or greater including
+   - PCRE (perl compatible regular expression)
+   - DOM (xml document object model)
+   - libiconv (recommended)
+   - mbstring (optional)
+* php.ini options:
+   - error_reporting E_ALL & ~E_NOTICE (or lower)
+   - memory_limit (increase as suitable to support large attachments)
+   - file_uploads enabled (for attachment upload features)
+   - session.auto_start disabled
+   - zend.ze1_compatibility_mode disabled
+* PHP compiled with OpenSSL to connect to IMAPS and to use the spell checker
+* A MySQL or PostgreSQL database engine or the SQLite extension for PHP
+* One of the above databases with permission to create tables
+* An SMTP server or PHP configured for mail delivery
+
+
+INSTALLATION
+============
+
+1. Decompress and put this folder somewhere inside your document root
+2. Make sure that the following directories (and the files within)
+   are writable by the webserver
+   - /temp
+   - /logs
+3. Create a new database and a database user for RoundCube (see DATABASE SETUP)
+4. Point your browser to http://url-to-roundcube/installer/
+5. Follow the instructions of the install script (or see MANUAL CONFIGURATION)
+6. After creating and testing the configuration, remove the installer directory
+7. Done!
+
+
+CONFIGURATION HINTS
+===================
+
+RoundCube writes internal errors to the 'errors' log file located in the logs
+directory which can be configured in config/main.inc.php. If you want ordinary
+PHP errors to be logged there as well, enable the 'php_value error_log' line
+in the .htaccess file and set the path to the log file accordingly.
+
+
+DATABASE SETUP
+==============
+
+* MySQL
+-------
+Setting up the mysql database can be done by creating an empty database,
+importing the table layout and granting the proper permissions to the
+roundcube user. Here is an example of that procedure:
+
+# mysql
+> CREATE DATABASE roundcubemail /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost
+    IDENTIFIED BY 'password';
+> quit
+
+# mysql roundcubemail < SQL/mysql.initial.sql
+
+Note 1: 'password' is the master password for the roundcube user. It is strongly
+recommended you replace this with a more secure password. Please keep in
+mind: You need to specify this password later in 'config/db.inc.php'.
+
+Note 2: For MySQL version 4.1 and up, it's recommended to create the database for
+RoundCube with utf-8 charset.
+
+
+* SQLite
+--------
+You need sqlite 2 (preferably 2.8) to setup the sqlite db 
+(sqlite 3.x also doesn't work at the moment). Here is
+an example how you can setup the sqlite.db for roundcube:
+
+# sqlite -init SQL/sqlite.initial.sql sqlite.db
+Loading resources from SQL/sqlite.initial.sql
+SQLite version 2.8.16
+Enter ".help" for instructions
+sqlite> .exit
+# chmod o+rw sqlite.db
+
+Make sure your configuration points to the sqlite.db file and that the
+webserver can write to the file and the directory containing the file.
+
+
+* PostgreSQL
+------------
+To use RoundCube with PostgreSQL support you have to follow these
+simple steps, which have to be done as the postgres system user (or
+which ever is the database superuser):
+
+$ createuser roundcube
+$ createdb -O roundcube -E UNICODE roundcubemail
+$ psql roundcubemail
+
+roundcubemail =# ALTER USER roundcube WITH PASSWORD 'the_new_password';
+roundcubemail =# \c - roundcube
+roundcubemail => \i SQL/postgres.initial.sql
+
+All this has been tested with PostgreSQL 8.x and 7.4.x. Older
+versions don't have a -O option for the createdb, so if you are
+using that version you'll have to change ownership of the DB later.
+
+
+MANUAL CONFIGURATION
+====================
+
+First of all, rename the files config/*.inc.php.dist to config/*.inc.php.
+You can then change these files according to your environment and your needs.
+Details about the config parameters can be found in the config files.
+See http://trac.roundcube.net/wiki/Howto_Install for even more guidance.
+
+You can also modify the default .htaccess file. This is necessary to
+increase the allowed size of file attachments, for example:
+       php_value       upload_max_filesize     2M
+
+
+UPGRADING
+=========
+
+If you already have a previous version of RoundCube installed,
+please refer to the instructions in UPGRADING guide.
+
+
+OPTIMISING
+==========
+
+There are two forms of optimisation here, compression and caching, both aimed
+at increasing an end user's experience using RoundCube Webmail. Compression
+allows the static web pages to be delivered with less bandwidth. The index.php
+of RoundCube Webmail already enables compression on its output. The settings
+below allow compression to occur for all static files. Caching sets HTTP 
+response headers that enable a user's web client to understand what is static
+and how to cache it.
+
+The caching directives used are:
+ * Etags - sets at tag so the client can request is the page has changed
+ * Cache-control - defines the age of the page and that the page is 'public'
+   This enables clients to cache javascript files that don't have private 
+   information between sessions even if using HTTPS. It also allows proxies
+   to share the same cached page between users.
+ * Expires - provides another hint to increase the lifetime of static pages.
+
+For more information refer to RFC 2616.
+
+Side effects:
+-------------
+These directives are designed for production use. If you are using this in
+a development environment you may get horribly confused if your webclient
+is caching stuff that you changed on the server. Disabling the expires 
+parts below should save you some grief.
+
+If you are changing the skins, it is recommended that you copy content to 
+a different directory apart from 'default'.
+
+Apache:
+-------
+To enable these features in apache the following modules need to be enabled:
+ * mod_deflate
+ * mod_expires
+ * mod_headers
+
+The optimisation is already included in the .htaccess file in the top 
+directory of your installation.
+
+If you are using Apache version 2.2.9 and later, in the .htaccess file
+change the 'append' word to 'merge' for a more correct response. Keeping
+as 'append' shouldn't cause any problems though changing to merge will 
+eliminate the possibility of duplicate 'public' headers in Cache-control.
+
+Lighttpd:
+---------
+With Lightty the addition of Expire: tags by mod_expire is incompatible with
+the addition of "Cache-control: public". Using Cache-control 'public' is 
+used below as it is assumed to give a better caching result.
+
+Enable modules in server.modules:
+    "mod_setenv"
+    "mod_compress"
+
+Mod_compress is a server side cache of compressed files to improve its performance.
+
+$HTTP["host"] == "www.example.com" {
+
+    static-file.etags = "enable"
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Etag.use-mtimeDetails
+    etag.use-mtime = "enable"
+
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModSetEnv
+    $HTTP["url"] =~ "^/roundcubemail/(plugins|skins|program)" {
+        setenv.add-response-header  = ( "Cache-Control" => "public, max-age=2592000")
+    }
+
+    # http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ModCompress
+    # set compress.cache-dir to somewhere outside the docroot.
+    compress.cache-dir   = var.statedir + "/cache/compress"
+
+    compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml", "image/gif", "image/png")
+}
+
+
diff --git a/README b/README
index d7a13f74d2b544cc31e87c2f228dbca94940d135..ff975de23e98cbba1fc27a6e0b835a5f72429f2a 100644 (file)
--- a/README
+++ b/README
@@ -1,9 +1,9 @@
-RoundCube Webmail (http://roundcube.net)
+Roundcube Webmail (http://roundcube.net)
 
 
 Introduction:
 -------------
-RoundCube Webmail is a browser-based multilingual IMAP client with an
+Roundcube Webmail is a browser-based multilingual IMAP client with an
 application-like user interface. It provides full functionality you expect
 from an e-mail client, including MIME support, address book, folder management,
 message searching and spell checking. RoundCube Webmail is written in PHP and
@@ -35,7 +35,7 @@ LICENSE for more information about our license.
 
 Contribution:
 -------------
-Want to help make RoundCube the best webmail solution ever?
+Want to help make Roundcube the best webmail solution ever?
 RoundCube is open source software. Our developers and contributors all
 are volunteers and we're always looking for new additions and resources.
 For more information visit http://roundcube.net/contribute
index 534e327403dcade8306aaefc83a74d2dfaf11e03..e97a9a7b740a72c07138e4647feae01f7d346432 100644 (file)
@@ -30,7 +30,7 @@ CREATE TABLE [dbo].[identities] (
        [email] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,\r
        [reply-to] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,\r
        [bcc] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,\r
-       [signature] [text] COLLATE Latin1_General_CI_AI NOT NULL, \r
+       [signature] [text] COLLATE Latin1_General_CI_AI NULL, \r
        [html_signature] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL\r
 ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]\r
 GO\r
@@ -69,9 +69,9 @@ CREATE TABLE [dbo].[users] (
        [mail_host] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,\r
        [alias] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,\r
        [created] [datetime] NOT NULL ,\r
-       [last_login] [datetime] NULL ,\r
+       [last_login] [datetime] NOT NULL ,\r
        [language] [varchar] (5) COLLATE Latin1_General_CI_AI NULL ,\r
-       [preferences] [text] COLLATE Latin1_General_CI_AI NOT NULL \r
+       [preferences] [text] COLLATE Latin1_General_CI_AI NULL \r
 ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]\r
 GO\r
 \r
@@ -155,6 +155,7 @@ ALTER TABLE [dbo].[identities] ADD
        CONSTRAINT [DF_identities_email] DEFAULT ('') FOR [email],\r
        CONSTRAINT [DF_identities_reply] DEFAULT ('') FOR [reply-to],\r
        CONSTRAINT [DF_identities_bcc] DEFAULT ('') FOR [bcc],\r
+       CONSTRAINT [DF_identities_html_signature] DEFAULT ('0') FOR [html_signature],\r
         CHECK ([standard] = '1' or [standard] = '0'),\r
         CHECK ([del] = '1' or [del] = '0')\r
 GO\r
@@ -202,7 +203,7 @@ ALTER TABLE [dbo].[users] ADD
        CONSTRAINT [DF_users_username] DEFAULT ('') FOR [username],\r
        CONSTRAINT [DF_users_mail_host] DEFAULT ('') FOR [mail_host],\r
        CONSTRAINT [DF_users_alias] DEFAULT ('') FOR [alias],\r
-       CONSTRAINT [DF_users_created] DEFAULT (getdate()) FOR [created],\r
+       CONSTRAINT [DF_users_created] DEFAULT (getdate()) FOR [created]\r
 GO\r
 \r
  CREATE  INDEX [IX_users_username] ON [dbo].[users]([username]) ON [PRIMARY]\r
index 9815282f370b7062024b01ac9b206e3c155b4f9c..9464dd702e68d3d553335febd5e9cdf2c1f73c84 100644 (file)
@@ -1,11 +1,8 @@
 -- RoundCube Webmail initial database structure
--- Version 0.2
 
--- --------------------------------------------------------
 
 /*!40014  SET FOREIGN_KEY_CHECKS=0 */;
 
-
 -- Table structure for table `session`
 
 CREATE TABLE `session` (
index eb53332bf8e5225dcbfe2424a726c55adf3f8a0a..1a21ee28b130021b6fa81478a82c638126e758cd 100644 (file)
@@ -1,3 +1,5 @@
+-- RoundCube Webmail initial database structure
+
 --
 -- Sequence "user_ids"
 -- Name: user_ids; Type: SEQUENCE; Schema: public; Owner: postgres
index 5120ea0b7a27eacedd8b6b505724b844e96b2fe6..ef7cb43178f4c124003e59fe297c9f52cb433d46 100644 (file)
@@ -1,8 +1,4 @@
 -- RoundCube Webmail initial database structure
--- Version 0.1
--- 
-
--- --------------------------------------------------------
 
 -- 
 -- Table structure for table `cache`
index b2c1977b2c7371b2f367361b1b988bddd1243fa4..6362e0ca54678ad90b434f5cfc7cf6d7fe334eaf 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -14,6 +14,7 @@ of RoundCube Webmail.
    - ./program/
    - ./installer/
    - ./skins/default/
+   - ./plugins/
 2. Run ./bin/update.sh from the commandline OR
    open http://url-to-roundcube/installer/ in a browser. To enable
    the latter one, you have to temporary set 'enable_installer' to true
@@ -24,6 +25,7 @@ of RoundCube Webmail.
    ./SQL/[yourdbtype].update.sql that are superscribed with the
    currently installed version number.
 5. Make sure 'enable_installer' is set to false again.
+6. Check .htaccess settings (some php settings could become required)
 
 
 For manually upgrading your RoundCube installation follow the instructions
diff --git a/bin/decrypt.php b/bin/decrypt.php
new file mode 100644 (file)
index 0000000..7ef5a47
--- /dev/null
@@ -0,0 +1,70 @@
+#!/usr/bin/env php
+<?php
+/*
+
+ +-----------------------------------------------------------------------+
+ | bin/decrypt.php                                                       |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Decrypt the encrypted parts of the HTTP Received: headers           |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Tomas Tevesz <ice@extreme.hu>                                 |
+ +-----------------------------------------------------------------------+
+
+ $Id$
+*/
+
+/*-
+ * If http_received_header_encrypt is configured, the IP address and the
+ * host name of the added Received: header is encrypted with 3DES, to
+ * protect information that some could consider sensitve, yet their
+ * availability is a must in some circumstances.
+ *
+ * Such an encrypted Received: header might look like:
+ *
+ * Received: from DzgkvJBO5+bw+oje5JACeNIa/uSI4mRw2cy5YoPBba73eyBmjtyHnQ==
+ *     [my0nUbjZXKtl7KVBZcsvWOxxtyVFxza4]
+ *     with HTTP/1.1 (POST); Thu, 14 May 2009 19:17:28 +0200
+ *
+ * In this example, the two encrypted components are the sender host name
+ * (DzgkvJBO5+bw+oje5JACeNIa/uSI4mRw2cy5YoPBba73eyBmjtyHnQ==) and the IP
+ * address (my0nUbjZXKtl7KVBZcsvWOxxtyVFxza4).
+ *
+ * Using this tool, they can be decrypted into plain text:
+ *
+ * $ bin/decrypt_received.php 'my0nUbjZXKtl7KVBZcsvWOxxtyVFxza4' \
+ * > 'DzgkvJBO5+bw+oje5JACeNIa/uSI4mRw2cy5YoPBba73eyBmjtyHnQ=='
+ * 84.3.187.208
+ * 5403BBD0.catv.pool.telekom.hu
+ * $
+ *
+ * Thus it is known that this particular message was sent by 84.3.187.208,
+ * having, at the time of sending, the name of 5403BBD0.catv.pool.telekom.hu.
+ *
+ * If (most likely binary) junk is shown, then
+ *  - either the encryption password has, between the time the mail was sent
+ *    and `now', changed, or
+ *  - you are dealing with counterfeit header data.
+ */
+
+if (php_sapi_name() != 'cli') {
+       die("Not on the 'shell' (php-cli).\n");
+}
+
+define('INSTALL_PATH', realpath(dirname(__FILE__).'/..') . '/');
+require INSTALL_PATH . 'program/include/iniset.php';
+
+if ($argc < 2) {
+       die("Usage: " . basename($argv[0]) . " encrypted-hdr-part [encrypted-hdr-part ...]\n");
+}
+
+$RCMAIL = rcmail::get_instance();
+
+for ($i = 1; $i < $argc; $i++) {
+       printf("%s\n", $RCMAIL->decrypt($argv[$i]));
+};
index 093add6d0c9ae6cb71a564c3e0a476ee8b3a8b24..e6fb3f607fc1412d4098e47daddc5a2d32bc4222 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: modcss.php 2249 2009-01-22 11:23:00Z thomasb $
+ $Id: modcss.php 2853 2009-08-12 10:44:46Z thomasb $
 
 */
 
@@ -33,7 +33,7 @@ if (empty($RCMAIL->user->ID)) {
     exit;
 }
 
-$url = preg_replace('/[^a-z0-9.-_\?\$&=%]/i', '', $_GET['u']);
+$url = preg_replace('![^a-z0-9:./\-_?$&=%]!i', '', $_GET['u']);
 if ($url === null) {
     header('HTTP/1.1 403 Forbidden');
     echo $error;
@@ -45,42 +45,63 @@ $port  = $a_uri['port'] ? $a_uri['port'] : 80;
 $host  = $a_uri['host'];
 $path  = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : '');
 
-if (!($fp = fsockopen($host, $port, $errno, $errstr, 30))) {
+// don't allow any other connections than http(s)
+if (strtolower(substr($a_uri['scheme'], 0, 4)) != 'http') {
+    header('HTTP/1.1 403 Forbidden');
+    echo "Invalid URL";
+    exit;
+}
+
+// try to open socket connection
+if (!($fp = fsockopen($host, $port, $errno, $error, 15))) {
     header('HTTP/1.1 500 Internal Server Error');
     echo $error;
     exit;
 }
 
+// set timeout for socket
+stream_set_timeout($fp, 30);
+
+// send request
 $out  = "GET $path HTTP/1.0\r\n";
 $out .= "Host: $host\r\n";
 $out .= "Connection: Close\r\n\r\n";
 fwrite($fp, $out);
 
+// read response
 $header = true;
+$headers = array();
 while (!feof($fp)) {
     $line = trim(fgets($fp, 4048));
 
-    if ($header
-        && preg_match('/^HTTP\/1\..\s+(\d+)/', $line, $regs)
-        && intval($regs[1]) != 200) {
-        break;
-    } else if (empty($line) && $header) {
-        $header = false;
-    } else if (!$header) {
+    if ($header) {
+        if (preg_match('/^HTTP\/1\..\s+(\d+)/', $line, $regs)
+            && intval($regs[1]) != 200) {
+            break;
+        }
+        else if (empty($line)) {
+            $header = false;
+        }
+        else {
+            list($key, $value) = explode(': ', $line);
+            $headers[strtolower($key)] = $value;
+        }
+    }
+    else {
         $source .= "$line\n";
     }
 }
 fclose($fp);
 
-if (!empty($source)) {
+// check content-type header and mod styles
+$mimetype = strtolower($headers['content-type']);
+if (!empty($source) && in_array($mimetype, array('text/css','text/plain'))) {
     header('Content-Type: text/css');
-    echo rcmail_mod_css_styles(
-        $source,
-        preg_replace('/[^a-z0-9]/i', '', $_GET['c']),
-        $url
-    );
+    echo rcmail_mod_css_styles($source, preg_replace('/[^a-z0-9]/i', '', $_GET['c']));
     exit;
 }
+else
+    $error = "Invalid response returned by server";
 
 header('HTTP/1.0 404 Not Found');
 echo $error;
index ed6ce8173a1237f949f657a846d262dae3f0bf20..7111b89e711c7996ae4b648cf6a1c3d1f3fe6e86 100644 (file)
@@ -14,7 +14,7 @@
  | Author: Brett Patterson <brett2@umbc.edu>                             |
  +-----------------------------------------------------------------------+
 
- $Id: quotaimg.php 2237 2009-01-17 01:55:39Z till $
+ $Id: quotaimg.php 2453 2009-05-04 08:31:55Z alec $
 
 */
 
@@ -102,7 +102,7 @@ function genQuota($used, $total, $width, $height)
         ***********************************/
 
        // @todo: Set to "??" instead?
-       if (ereg("^[^0-9?]*$", $used) || ereg("^[^0-9?]*$", $total)) {
+       if (preg_match('/^[^0-9?]*$/', $used) || preg_match('/^[^0-9?]*$/', $total)) {
                return false; 
        }
 
@@ -172,7 +172,8 @@ function genQuota($used, $total, $width, $height)
                }
 
                $quota_width = $quota / 100 * $width;
-               imagefilledrectangle($im, $border, 0, $quota_width, $height-2*$border, $fill);
+               if ($quota_width)
+                       imagefilledrectangle($im, $border, 0, $quota_width, $height-2*$border, $fill);
 
                $string = $quota . '%';
                $mid    = floor(($width-(strlen($string)*imagefontwidth($font)))/2)+1;
index 42af34d6251ea25d1c2074c184a2102c9b90d06b..42881dfcd49f901e4c2a5688ccf13c16af44bc1f 100644 (file)
 
 $rcmail_config = array();
 
-
 // system error reporting: 1 = log; 2 = report (not implemented yet), 4 = show, 8 = trace
 $rcmail_config['debug_level'] = 1;
 
 // log driver:  'syslog' or 'file'.
 $rcmail_config['log_driver'] = 'file';
 
+// date format for log entries
+// (read http://php.net/manual/en/function.date.php for all format characters)  
+$rcmail_config['log_date_format'] = 'd-M-Y H:i:s O';
+
 // Syslog ident string to use, if using the 'syslog' log driver.
 $rcmail_config['syslog_id'] = 'roundcube';
 
@@ -35,6 +38,9 @@ $rcmail_config['log_dir'] = 'logs/';
 // use this folder to store temp files (must be writeable for apache user)
 $rcmail_config['temp_dir'] = 'temp/';
 
+// List of active plugins (in plugins/ directory)
+$rcmail_config['plugins'] = array();
+
 // enable caching of messages and mailbox data in the local database.
 // this is recommended if the IMAP server does not run on the same machine
 $rcmail_config['enable_caching'] = TRUE;
@@ -43,6 +49,10 @@ $rcmail_config['enable_caching'] = TRUE;
 // possible units: s, m, h, d, w
 $rcmail_config['message_cache_lifetime'] = '10d';
 
+// enforce connections over https
+// with this option enabled, all non-secure connections will be redirected
+$rcmail_config['force_https'] = FALSE;
+
 // automatically create a new RoundCube user when log-in the first time.
 // a new user will be created once the IMAP login succeeds.
 // set to false if only registered users can use this service
@@ -80,12 +90,14 @@ $rcmail_config['virtuser_file'] = '';
 
 // Query to resolve user names and e-mail addresses from the database
 // %u will be replaced with the current username for login.
-// The query should select the user's e-mail address as first col
+// The query should select the user's e-mail address as first column
+// and optional identity name as second column
 $rcmail_config['virtuser_query'] = '';
 
 // use this host for sending mails.
 // to use SSL connection, set ssl://smtp.host.com
 // if left blank, the PHP mail() function is used
+// Use %h variable as replacement for user's IMAP hostname
 $rcmail_config['smtp_server'] = '';
 
 // SMTP port (default is 25; 465 for SSL)
@@ -112,6 +124,15 @@ $rcmail_config['smtp_helo_host'] = '';
 // Log sent messages
 $rcmail_config['smtp_log'] = TRUE;
 
+// Log SQL queries to <log_dir>/sql or to syslog
+$rcmail_config['sql_debug'] = false;
+
+// Log IMAP conversation to <log_dir>/imap or to syslog
+$rcmail_config['imap_debug'] = false;
+
+// Log SMTP conversation to <log_dir>/smtp or to syslog
+$rcmail_config['smtp_debug'] = false;
+
 // How many seconds must pass between emails sent by a user
 $rcmail_config['sendmail_delay'] = 0;
 
@@ -142,17 +163,17 @@ $rcmail_config['des_key'] = 'rcmail-!24ByteDESkey*Str';
 // RFC1766 formatted language name like en_US, de_DE, de_CH, fr_FR, pt_BR
 $rcmail_config['language'] = null;
 
-// use this format for short date display
+// use this format for short date display (date or strftime format)
 $rcmail_config['date_short'] = 'D H:i';
 
-// use this format for detailed date/time formatting
+// use this format for detailed date/time formatting (date or strftime format)
 $rcmail_config['date_long'] = 'd.m.Y H:i';
 
-// use this format for today's date display
+// use this format for today's date display (date or strftime format)
 $rcmail_config['date_today'] = 'H:i';
 
 // add this user-agent to message headers when sending
-$rcmail_config['useragent'] = 'RoundCube Webmail/0.2.2';
+$rcmail_config['useragent'] = 'RoundCube Webmail/'.RCMAIL_VERSION;
 
 // use this name to compose page titles
 $rcmail_config['product_name'] = 'RoundCube Webmail';
@@ -209,8 +230,7 @@ $rcmail_config['spellcheck_uri'] = '';
 
 // These languages can be selected for spell checking.
 // Configure as a PHP style hash array: array('en'=>'English', 'de'=>'Deutsch');
-// Leave empty for default set of Google spell check languages, should be defined
-// when using local Pspell extension
+// Leave empty for default set of available language.
 $rcmail_config['spellcheck_languages'] = NULL;
 
 // path to a text file which will be added to each sent message
@@ -220,6 +240,12 @@ $rcmail_config['generic_message_footer'] = '';
 // add a received header to outgoing mails containing the creators IP and hostname
 $rcmail_config['http_received_header'] = false;
 
+// Whether or not to encrypt the IP address and the host name
+// these could, in some circles, be considered as sensitive information;
+// however, for the administrator, these could be invaluable help
+// when tracking down issues.
+$rcmail_config['http_received_header_encrypt'] = false;
+
 // this string is used as a delimiter for message headers when sending
 // leave empty for auto-detection
 $rcmail_config['mail_header_delimiter'] = NULL;
@@ -390,7 +416,7 @@ $rcmail_config['inline_images'] = TRUE;
 // 0 - Full RFC 2231 compatible
 // 1 - RFC 2047 for 'name' and RFC 2231 for 'filename' parameter (Thunderbird's default)
 // 2 - Full 2047 compatible
-$rcmail_config['mime_param_folding'] = 0;
+$rcmail_config['mime_param_folding'] = 1;
 
 // Set TRUE if deleted messages should not be displayed
 // This will make the application run slower
@@ -400,9 +426,8 @@ $rcmail_config['skip_deleted'] = FALSE;
 // False means that a message's read status is not affected by marking it as deleted
 $rcmail_config['read_when_deleted'] = TRUE;
 
-// When a Trash folder is not present and a message is deleted, flag 
-// the message for deletion rather than deleting it immediately.  Setting this to 
-// false causes deleted messages to be permanantly removed if there is no Trash folder
+// Set to TRUE to newer delete messages immediately
+// Use 'Purge' to remove messages marked as deleted 
 $rcmail_config['flag_for_deletion'] = FALSE;
 
 // Default interval for keep-alive/check-recent requests (in seconds)
@@ -412,5 +437,8 @@ $rcmail_config['keep_alive'] = 60;
 // If true all folders will be checked for recent messages
 $rcmail_config['check_all_folders'] = FALSE;
 
+// If true, after message delete/move, the next message will be displayed
+$rcmail_config['display_next'] = FALSE;
+
 // end of config file
 ?>
index 2e95a29fd93de544b29877e83ff93b71f2072e16..159fce0d0e0235daf2f4aaa6d92104dc809a4913 100644 (file)
@@ -41,6 +41,7 @@ return array(
   'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
   'xps' => 'application/vnd.ms-xpsdocument',
   'rar' => 'application/x-rar-compressed',
+  'vcf' => 'text/vcard',
 );
 
 ?>
\ No newline at end of file
index a61ca2f5cf12b6f1c6ca1b0e880e9f333e751f3d..624d8980ebf70a7cc9837f0ee69918895722c356 100644 (file)
--- a/index.php
+++ b/index.php
@@ -2,7 +2,7 @@
 /*
  +-------------------------------------------------------------------------+
  | RoundCube Webmail IMAP Client                                           |
- | Version 0.2.2                                                           |
+ | Version 0.3-stable                                                      |
  |                                                                         |
  | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                   |
  |                                                                         |
@@ -23,7 +23,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                          |
  +-------------------------------------------------------------------------+
 
- $Id: index.php 2484 2009-05-15 10:24:09Z thomasb $
+ $Id: index.php 2916 2009-09-04 10:58:29Z thomasb $
 
 */
 
@@ -36,18 +36,11 @@ $RCMAIL = rcmail::get_instance();
 // init output class
 $OUTPUT = !empty($_REQUEST['_remote']) ? $RCMAIL->init_json() : $RCMAIL->load_gui(!empty($_REQUEST['_framed']));
 
-// set output buffering
-if ($RCMAIL->action != 'get' && $RCMAIL->action != 'viewsource') {
-  // use gzip compression if supported
-  if (function_exists('ob_gzhandler')
-      && !ini_get('zlib.output_compression')
-      && ini_get('output_handler') != 'ob_gzhandler') {
-    ob_start('ob_gzhandler');
-  }
-  else {
-    ob_start();
-  }
-}
+// init plugin API
+$RCMAIL->plugins->init();
+
+// turn on output buffering
+ob_start();
 
 // check if config files had errors
 if ($err_str = $RCMAIL->config->get_error()) {
@@ -70,23 +63,38 @@ if ($RCMAIL->action=='error' && !empty($_GET['_code'])) {
   raise_error(array('code' => hexdec($_GET['_code'])), FALSE, TRUE);
 }
 
+// check if https is required (for login) and redirect if necessary
+if ($RCMAIL->config->get('force_https', false) && empty($_SESSION['user_id']) && !(isset($_SERVER['HTTPS']) || $_SERVER['SERVER_PORT'] == 443)) {
+  header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
+  exit;
+}
+
+// trigger startup plugin hook
+$startup = $RCMAIL->plugins->exec_hook('startup', array('task' => $RCMAIL->task, 'action' => $RCMAIL->action));
+$RCMAIL->set_task($startup['task']);
+$RCMAIL->action = $startup['action'];
+
+
 // try to log in
 if ($RCMAIL->action=='login' && $RCMAIL->task=='mail') {
   // purge the session in case of new login when a session already exists 
-  $RCMAIL->kill_session(); 
-  
-  // set IMAP host
-  $host = $RCMAIL->autoselect_host();
+  $RCMAIL->kill_session();
   
+  $auth = $RCMAIL->plugins->exec_hook('authenticate', array(
+    'host' => $RCMAIL->autoselect_host(),
+    'user' => trim(get_input_value('_user', RCUBE_INPUT_POST)),
+    'cookiecheck' => true,
+  )) + array('pass' => get_input_value('_pass', RCUBE_INPUT_POST, true, 'ISO-8859-1'));
+
   // check if client supports cookies
-  if (empty($_COOKIE)) {
+  if ($auth['cookiecheck'] && empty($_COOKIE)) {
     $OUTPUT->show_message("cookiesdisabled", 'warning');
   }
-  else if ($_SESSION['temp'] && !empty($_POST['_user']) && !empty($_POST['_pass']) &&
-           $RCMAIL->login(trim(get_input_value('_user', RCUBE_INPUT_POST), ' '),
-              get_input_value('_pass', RCUBE_INPUT_POST, true, 'ISO-8859-1'), $host)) {
+  else if ($_SESSION['temp'] && !$auth['abort'] && !empty($auth['host']) &&
+            !empty($auth['user']) && isset($auth['pass']) && 
+            $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'])) {
     // create new session ID
-    unset($_SESSION['temp']);
+    rcube_sess_unset('temp');
     rcube_sess_regenerate_id();
 
     // send auth cookie if necessary
@@ -99,21 +107,33 @@ if ($RCMAIL->action=='login' && $RCMAIL->task=='mail') {
         $RCMAIL->user->ID,
         $_SERVER['REMOTE_ADDR']));
     }
+    
+    // restore original request parameters
+    $query = array();
+    if ($url = get_input_value('_url', RCUBE_INPUT_POST))
+      parse_str($url, $query);
+
+    // allow plugins to control the redirect url after login success
+    $redir = $RCMAIL->plugins->exec_hook('login_after', $query + array('task' => $RCMAIL->task));
+    unset($redir['abort']);
 
     // send redirect
-    $OUTPUT->redirect();
+    $OUTPUT->redirect($redir);
   }
   else {
     $OUTPUT->show_message($IMAP->error_code < -1 ? 'imaperror' : 'loginfailed', 'warning');
+    $RCMAIL->plugins->exec_hook('login_failed', array('code' => $IMAP->error_code, 'host' => $auth['host'], 'user' => $auth['user']));
     $RCMAIL->kill_session();
   }
 }
 
 // end session
-else if (($RCMAIL->task=='logout' || $RCMAIL->action=='logout') && isset($_SESSION['user_id'])) {
+else if ($RCMAIL->task=='logout' && isset($_SESSION['user_id'])) {
+  $userdata = array('user' => $_SESSION['username'], 'host' => $_SESSION['imap_host'], 'lang' => $RCMAIL->user->language);
   $OUTPUT->show_message('loggedout');
   $RCMAIL->logout_actions();
   $RCMAIL->kill_session();
+  $RCMAIL->plugins->exec_hook('logout_after', $userdata);
 }
 
 // check session and auth cookie
@@ -124,14 +144,21 @@ else if ($RCMAIL->action != 'login' && $_SESSION['user_id'] && $RCMAIL->action !
   }
 }
 
+// don't check for valid request tokens in these actions
+$request_check_whitelist = array('login'=>1, 'spell'=>1);
 
 // check client X-header to verify request origin
 if ($OUTPUT->ajax_call) {
-  if (!$RCMAIL->config->get('devel_mode') && !rc_request_header('X-RoundCube-Referer')) {
+  if (!$RCMAIL->config->get('devel_mode') && rc_request_header('X-RoundCube-Request') != $RCMAIL->get_request_token()) {
     header('HTTP/1.1 404 Not Found');
     die("Invalid Request");
   }
 }
+// check request token in POST form submissions
+else if (!empty($_POST) && !$request_check_whitelist[$RCMAIL->action] && !$RCMAIL->check_request()) {
+  $OUTPUT->show_message('invalidrequest', 'error');
+  $OUTPUT->send($RCMAIL->task);
+}
 
 
 // not logged in -> show login page
@@ -201,16 +228,22 @@ $action_map = array(
 );
 
 // include task specific functions
-include_once 'program/steps/'.$RCMAIL->task.'/func.inc';
+if (is_file($incfile = 'program/steps/'.$RCMAIL->task.'/func.inc'))
+  include_once($incfile);
 
 // allow 5 "redirects" to another action
 $redirects = 0; $incstep = null;
 while ($redirects < 5) {
   $stepfile = !empty($action_map[$RCMAIL->task][$RCMAIL->action]) ?
     $action_map[$RCMAIL->task][$RCMAIL->action] : strtr($RCMAIL->action, '-', '_') . '.inc';
-    
+
+  // execute a plugin action
+  if (preg_match('/^plugin\./', $RCMAIL->action)) {
+    $RCMAIL->plugins->exec_action($RCMAIL->action);
+    break;
+  }
   // try to include the step file
-  if (is_file(($incfile = 'program/steps/'.$RCMAIL->task.'/'.$stepfile))) {
+  else if (is_file($incfile = 'program/steps/'.$RCMAIL->task.'/'.$stepfile)) {
     include($incfile);
     $redirects++;
   }
index 4c34dd6de5db4fd9a02a754d081bb75e9c63a983..9bdb41ba5e9ae3efb1e83bd407daecaeb518ab1e 100644 (file)
@@ -1,7 +1,8 @@
 <form action="index.php" method="get">
 <?php
 
-$required_php_exts = array('PCRE' => 'pcre', 'DOM' => 'dom', 'Session' => 'session');
+$required_php_exts = array('PCRE' => 'pcre', 'DOM' => 'dom',
+    'Session' => 'session', 'XML' => 'xml');
 
 $optional_php_exts = array('FileInfo' => 'fileinfo', 'Libiconv' => 'iconv',
     'Multibyte' => 'mbstring', 'OpenSSL' => 'openssl', 'Mcrypt' => 'mcrypt',
@@ -15,7 +16,10 @@ $supported_dbs = array('MySQL' => 'mysql', 'MySQLi' => 'mysqli',
     'PostgreSQL' => 'pgsql', 'SQLite (v2)' => 'sqlite');
 
 $ini_checks = array('file_uploads' => 1, 'session.auto_start' => 0,
-    'zend.ze1_compatibility_mode' => 0, 'mbstring.func_overload' => 0);
+    'zend.ze1_compatibility_mode' => 0, 'mbstring.func_overload' => 0,
+    'suhosin.session.encrypt' => 0);
+
+$optional_checks = array('date.timezone' => '-NOTEMPTY-');
 
 $source_urls = array(
     'Sockets' => 'http://www.php.net/manual/en/ref.sockets.php',
@@ -66,7 +70,7 @@ foreach ($required_php_exts AS $name => $ext) {
 
 ?>
 
-<p class="hint">The next couple of extensions are <em>optional</em> but recommended to get the best performance:</p>
+<p class="hint">The next couple of extensions are <em>optional</em> and recommended to get the best performance:</p>
 <?php
 
 foreach ($optional_php_exts AS $name => $ext) {
@@ -125,21 +129,54 @@ foreach ($required_libs as $classname => $file) {
 ?>
 
 <h3>Checking php.ini/.htaccess settings</h3>
+<p class="hint">The following settings are <em>required</em> to run RoundCube:</p>
 
 <?php
 
 foreach ($ini_checks as $var => $val) {
     $status = ini_get($var);
+    if ($val === '-NOTEMPTY-') {
+        if (empty($status)) {
+            $RCI->fail($var, "cannot be empty and needs to be set");
+        } else {
+            $RCI->pass($var);
+        }
+        echo '<br />';
+        continue;
+    }
     if ($status == $val) {
         $RCI->pass($var);
-    }
-    else {
+    } else {
       $RCI->fail($var, "is '$status', should be '$val'");
     }
     echo '<br />';
 }
 ?>
 
+<p class="hint">The following settings are <em>optional</em> and recommended:</p>
+
+<?php
+
+foreach ($optional_checks as $var => $val) {
+    $status = ini_get($var);
+    if ($val === '-NOTEMPTY-') {
+        if (empty($status)) {
+            $RCI->optfail($var, "Could be set");
+        } else {
+            $RCI->pass($var);
+        }
+        echo '<br />';
+        continue;
+    }
+    if ($status == $val) {
+        $RCI->pass($var);
+    } else {
+      $RCI->optfail($var, "is '$status', could be '$val'");
+    }
+    echo '<br />';
+}
+?>
+
 <?php
 
 if ($RCI->failures) {
index fef222d8a2fc27124d17ca91241ea70cbc682610..e51b4bf0af6624168cfaef62697933416205e07f 100644 (file)
@@ -112,14 +112,26 @@ echo $check_caching->show(intval($RCI->getprop('enable_caching')), array('value'
 <dt class="propname">enable_spellcheck</dt>
 <dd>
 <?php
+$check_spell = new html_checkbox(array('name' => '_enable_spellcheck', 'id' => "cfgspellcheck"));
+echo $check_spell->show(intval($RCI->getprop('enable_spellcheck')), array('value' => 1));
+?>
+<label for="cfgspellcheck">Make use of the spell checker</label><br />
+</dd>
+
+<dt class="propname">spellcheck_engine</dt>
+<dd>
+<?php
+$select_spell = new html_select(array('name' => '_spellcheck_engine', 'id' => "cfgspellcheckengine"));
+if (extension_loaded('pspell'))
+  $select_spell->add('pspell', 'pspell');
+$select_spell->add('Googlie', 'googlie');
 
-$check_caching = new html_checkbox(array('name' => '_enable_spellcheck', 'id' => "cfgspellcheck"));
-echo $check_caching->show(intval($RCI->getprop('enable_spellcheck')), array('value' => 1));
+echo $select_spell->show($RCI->is_post ? $_POST['_spellcheck_engine'] : 'pspell');
 
 ?>
-<label for="cfgspellcheck">Make use of the built-in spell checker</label><br />
+<label for="cfgspellcheckengine">Which spell checker to use</label><br />
 
-<p class="hint">It is based on GoogieSpell what implies that the message content will be sent to Google in order to check the spelling.</p>
+<p class="hint">GoogieSpell implies that the message content will be sent to Google in order to check the spelling.</p>
 </dd>
 
 <dt class="propname">identities_level</dt>
@@ -255,13 +267,13 @@ $dsnw = MDB2::parseDSN($RCI->getprop('db_dsnw'));
 echo $select_dbtype->show($RCI->is_post ? $_POST['_dbtype'] : $dsnw['phptype']);
 echo '<label for="cfgdbtype">Database type</label><br />';
 echo $input_dbhost->show($RCI->is_post ? $_POST['_dbhost'] : $dsnw['hostspec']);
-echo '<label for="cfgdbhost">Database server</label><br />';
+echo '<label for="cfgdbhost">Database server (omit for sqlite)</label><br />';
 echo $input_dbname->show($RCI->is_post ? $_POST['_dbname'] : $dsnw['database']);
-echo '<label for="cfgdbname">Database name</label><br />';
+echo '<label for="cfgdbname">Database name (use a path and filename for sqlite)</label><br />';
 echo $input_dbuser->show($RCI->is_post ? $_POST['_dbuser'] : $dsnw['username']);
-echo '<label for="cfgdbuser">Database user name (needs write permissions)</label><br />';
+echo '<label for="cfgdbuser">Database user name (needs write permissions)(omit for sqlite)</label><br />';
 echo $input_dbpass->show($RCI->is_post ? $_POST['_dbpass'] : $dsnw['password']);
-echo '<label for="cfgdbpass">Database password</label><br />';
+echo '<label for="cfgdbpass">Database password (omit for sqlite)</label><br />';
 
 ?>
 </dd>
@@ -417,7 +429,7 @@ $text_smtpport = new html_inputfield(array('name' => '_smtp_port', 'size' => 6,
 echo $text_smtpport->show($RCI->getprop('smtp_port'));
 
 ?>
-<div>SMTP port (default is 25; 465 for SSL)</div>
+<div>SMTP port (default is 25; 465 for SSL; 587 for submission)</div>
 </dd>
 
 <dt class="propname">smtp_user/smtp_pass</dt>
@@ -473,7 +485,7 @@ echo $check_smtplog->show(intval($RCI->getprop('smtp_log')), array('value' => 1)
 <legend>Display settings &amp; user prefs</legend>
 <dl class="configblock" id="cgfblockdisplay">
 
-<dt class="propname">language</dt>
+<dt class="propname">language <span class="userconf">*</span></dt>
 <dd>
 <?php
 
@@ -547,7 +559,7 @@ echo $check_htmlcomp->show(intval($RCI->getprop('htmleditor')));
 
 $select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => 'cfgautosave'));
 $select_autosave->add('never', 0);
-foreach (array(3, 5, 10) as $i => $min)
+foreach (array(1, 3, 5, 10) as $i => $min)
   $select_autosave->add("$min min", $min*60);
 
 echo $select_autosave->show(intval($RCI->getprop('draft_autosave')));
index 549b6f007ac0f5919a2365d4e96edc52609e0b5c..d1c55e4ec8f370d9331f8d2536118cb20d10174a 100644 (file)
@@ -13,8 +13,8 @@ $include_path .= ini_get('include_path');
 
 set_include_path($include_path);
 
-require_once 'rcube_shared.inc';
 require_once 'utils.php';
+require_once 'main.inc';
 
 session_start();
 
@@ -47,9 +47,9 @@ if ($RCI->configured && ($RCI->getprop('enable_installer') || $_SESSION['allowin
   exit;
 }
 
-// go to 'test' step if we have a local configuration
+// go to 'check env' step if we have a local configuration
 if ($RCI->configured && empty($_REQUEST['_step'])) {
-  header("Location: ./?_step=3");
+  header("Location: ./?_step=1");
   exit;
 }
 
index b2b8257f7041de61796827ada20bcbf07842ac60..f30c0085f1e4b3f44c86c6f870ddb4af4cb70055 100644 (file)
@@ -136,10 +136,10 @@ class rcube_install
    */
   function create_config($which, $force = false)
   {
-    $out = file_get_contents(RCMAIL_CONFIG_DIR . "/{$which}.inc.php.dist");
+    $out = @file_get_contents(RCMAIL_CONFIG_DIR . "/{$which}.inc.php.dist");
     
     if (!$out)
-      return '[Warning: could not read the template file]';
+      return '[Warning: could not read the config template file]';
 
     foreach ($this->config as $prop => $default) {
       $value = (isset($_POST["_$prop"]) || $this->bool_config_props[$prop]) ? $_POST["_$prop"] : $default;
@@ -176,6 +176,18 @@ class rcube_install
       else if ($prop == 'smtp_pass' && !empty($_POST['_smtp_user_u'])) {
         $value = '%p';
       }
+      else if ($prop == 'default_imap_folders'){
+       $value = Array();
+       foreach($this->config['default_imap_folders'] as $_folder){
+         switch($_folder) {
+         case 'Drafts': $_folder = $this->config['drafts_mbox']; break;
+         case 'Sent':   $_folder = $this->config['sent_mbox']; break;
+         case 'Junk':   $_folder = $this->config['junk_mbox']; break;
+         case 'Trash':  $_folder = $this->config['trash_mbox']; break;
+          }
+         if (!in_array($_folder, $value))  $value[] = $_folder;
+        }
+      }
       else if (is_bool($default)) {
         $value = (bool)$value;
       }
@@ -244,9 +256,11 @@ class rcube_install
         $out['dependencies'][] = array('prop' => 'spellcheck_engine',
           'explain' => 'This requires the <tt>pspell</tt> extension which could not be loaded.');
       }
-      if (empty($this->config['spellcheck_languages'])) {
-        $out['dependencies'][] = array('prop' => 'spellcheck_languages',
-          'explain' => 'You should specify the list of languages supported by your local pspell installation.');
+      if (!empty($this->config['spellcheck_languages'])) {
+        foreach ($this->config['spellcheck_languages'] as $lang => $descr)
+         if (!pspell_new($lang))
+            $out['dependencies'][] = array('prop' => 'spellcheck_languages',
+              'explain' => "You are missing pspell support for language $lang ($descr)");
       }
     }
     
@@ -453,6 +467,20 @@ class rcube_install
     echo Q($name) . ':&nbsp; <span class="fail">NOT OK</span>';
     $this->_showhint($message, $url);
   }
+
+
+  /**
+   * Display an error status for optional settings/features
+   *
+   * @param string Test name
+   * @param string Error message
+   * @param string URL for details
+   */
+  function optfail($name, $message = '', $url = '')
+  {
+    echo Q($name) . ':&nbsp; <span class="na">NOT OK</span>';
+    $this->_showhint($message, $url);
+  }
   
   
   /**
@@ -537,11 +565,11 @@ class rcube_install
     if ($lines = @file($fname, FILE_SKIP_EMPTY_LINES)) {
       $buff = '';
       foreach ($lines as $i => $line) {
-        if (eregi('^--', $line))
+        if (preg_match('/^--/', $line))
           continue;
           
         $buff .= $line . "\n";
-        if (eregi(';$', trim($line))) {
+        if (preg_match('/;$/', trim($line))) {
           $DB->query($buff);
           $buff = '';
           if ($this->get_error())
index 5740a648958ff505eeee6afe73450d4c919cfb47..90d089ffdfbc399aec7bf7c6905f892475edfcb8 100644 (file)
@@ -248,13 +248,11 @@ $to_field = new html_inputfield(array('name' => '_to', 'id' => 'sendmailto'));
 
 if (isset($_POST['sendmail']) && !empty($_POST['_from']) && !empty($_POST['_to'])) {
   
-  require_once 'rcube_smtp.inc';
-  
   echo '<p>Trying to send email...<br />';
   
   if (preg_match('/^' . $RCI->email_pattern . '$/i', trim($_POST['_from'])) &&
       preg_match('/^' . $RCI->email_pattern . '$/i', trim($_POST['_to']))) {
-  
+
     $headers = array(
       'From'    => trim($_POST['_from']),
       'To'      => trim($_POST['_to']),
@@ -267,7 +265,7 @@ if (isset($_POST['sendmail']) && !empty($_POST['_from']) && !empty($_POST['_to']
     // send mail using configured SMTP server
     if ($RCI->getprop('smtp_server')) {
       $CONFIG = $RCI->config;
-      
+
       if (!empty($_POST['_smtp_user'])) {
         $CONFIG['smtp_user'] = $_POST['_smtp_user'];
       }
@@ -277,10 +275,14 @@ if (isset($_POST['sendmail']) && !empty($_POST['_from']) && !empty($_POST['_to']
 
       $mail_object  = new rcube_mail_mime();
       $send_headers = $mail_object->headers($headers);
-      
-      $status = smtp_mail($headers['From'], $headers['To'],
-          ($foo = $mail_object->txtHeaders($send_headers)),
-          $body, $smtp_response);
+
+      $SMTP = new rcube_smtp();
+      $SMTP->connect();
+
+      $status = $SMTP->send_mail($headers['From'], $headers['To'],
+          ($foo = $mail_object->txtHeaders($send_headers)), $body);
+
+      $smtp_response = $SMTP->get_response();
     }
     else {    // use mail()
       $header_str = 'From: ' . $headers['From'];
index c1775f2bba6f6a856d54db16bd0e4829c4b4c308..1c101058fcc0608503dcbf21b98353820c05424c 100644 (file)
@@ -1,15 +1,41 @@
 <?php
-
+/*
+ +-------------------------------------------------------------------------+
+ | RoundCube Webmail IMAP Client                                           |
+ | Version 0.3-20090702                                                    |
+ |                                                                         |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                   |
+ |                                                                         |
+ | This program is free software; you can redistribute it and/or modify    |
+ | it under the terms of the GNU General Public License version 2          |
+ | as published by the Free Software Foundation.                           |
+ |                                                                         |
+ | This program is distributed in the hope that it will be useful,         |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
+ | GNU General Public License for more details.                            |
+ |                                                                         |
+ | You should have received a copy of the GNU General Public License along |
+ | with this program; if not, write to the Free Software Foundation, Inc., |
+ | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.             |
+ |                                                                         |
+ +-------------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                          |
+ +-------------------------------------------------------------------------+
+
+ $Id: index.php 2696 2009-07-02 06:38:26Z thomasb $
+
+*/
 
 /**
  * Use PHP5 autoload for dynamic class loading
- * (copy from program/incllude/iniset.php)
+ * (copy from program/include/iniset.php)
  */
 function __autoload($classname)
 {
   $filename = preg_replace(
-      array('/MDB2_(.+)/', '/Mail_(.+)/', '/^html_.+/', '/^utf8$/'),
-      array('MDB2/\\1', 'Mail/\\1', 'html', 'utf8.class'),
+      array('/MDB2_(.+)/', '/Mail_(.+)/', '/Net_(.+)/', '/^html_.+/', '/^utf8$/'),
+      array('MDB2/\\1', 'Mail/\\1', 'Net/\\1', 'html', 'utf8.class'),
       $classname
   );
   include_once $filename. '.php';
@@ -17,19 +43,7 @@ function __autoload($classname)
 
 
 /**
- * Shortcut function for htmlentities()
- *
- * @param string String to quote
- * @return string The html-encoded string
- */
-function Q($string)
-{
-  return htmlentities($string, ENT_COMPAT, 'UTF-8');
-}
-
-
-/**
- * Fake rinternal error handler to catch errors
+ * Fake internal error handler to catch errors
  */
 function raise_error($p)
 {
@@ -37,4 +51,3 @@ function raise_error($p)
   $rci->raise_error($p);
 }
 
-
diff --git a/plugins/additional_message_headers/additional_message_headers.php b/plugins/additional_message_headers/additional_message_headers.php
new file mode 100644 (file)
index 0000000..9247138
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Additional Message Headers
+ *
+ * Very simple plugin which will read additional headers for outgoing messages from the config file.
+ *
+ * Enable the plugin in config/main.inc.php and add your desired headers.
+ *
+ * @version 1.0
+ * @author Ziba Scott
+ * @website http://roundcube.net
+ * 
+ * Example:
+ *
+ * $rcmail_config['additional_message_headers']['X-Remote-Browser'] = $_SERVER['HTTP_USER_AGENT'];
+ * $rcmail_config['additional_message_headers']['X-Originating-IP'] = $_SERVER['REMOTE_ADDR'];
+ * $rcmail_config['additional_message_headers']['X-RoundCube-Server'] = $_SERVER['SERVER_ADDR'];
+ * if( isset( $_SERVER['MACHINE_NAME'] )) {
+ *     $rcmail_config['additional_message_headers']['X-RoundCube-Server'] .= ' (' . $_SERVER['MACHINE_NAME'] . ')';
+ * }
+ */
+class additional_message_headers extends rcube_plugin
+{
+    public $task = 'mail';
+    
+    function init()
+    {
+        $this->add_hook('outgoing_message_headers', array($this, 'message_headers'));
+    }
+
+    function message_headers($args){
+
+        // additional email headers
+        $additional_headers = rcmail::get_instance()->config->get('additional_message_headers',array());
+        foreach($additional_headers as $header=>$value){
+            $args['headers'][$header] = $value;
+        }
+
+        return $args;
+    }
+}
diff --git a/plugins/archive/archive.js b/plugins/archive/archive.js
new file mode 100644 (file)
index 0000000..d771fb6
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Archive plugin script
+ * @version 1.2
+ */
+
+function rcmail_archive(prop)
+{
+  if (!rcmail.env.uid && (!rcmail.message_list || !rcmail.message_list.get_selection().length))
+    return;
+  
+  var uids = rcmail.env.uid ? rcmail.env.uid : rcmail.message_list.get_selection().join(',');
+    
+  rcmail.set_busy(true, 'loading');
+  rcmail.http_post('plugin.archive', '_uid='+uids+'&_mbox='+urlencode(rcmail.env.mailbox), true);
+}
+
+// callback for app-onload event
+if (window.rcmail) {
+  rcmail.addEventListener('init', function(evt) {
+    
+    // register command (directly enable in message view mode)
+    rcmail.register_command('plugin.archive', rcmail_archive, (rcmail.env.uid && rcmail.env.mailbox != rcmail.env.archive_folder));
+    
+    // add event-listener to message list
+    if (rcmail.message_list)
+      rcmail.message_list.addEventListener('select', function(list){
+        rcmail.enable_command('plugin.archive', (list.get_selection().length > 0 && rcmail.env.mailbox != rcmail.env.archive_folder));
+      });
+    
+    // set css style for archive folder
+    var li;
+    if (rcmail.env.archive_folder && (li = rcmail.get_folder_li(rcmail.env.archive_folder)))
+      $(li).css('background-image', 'url(plugins/archive/foldericon.png)');
+  })
+}
+
diff --git a/plugins/archive/archive.php b/plugins/archive/archive.php
new file mode 100644 (file)
index 0000000..9df7f8b
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * Archive
+ *
+ * Plugin that adds a new button to the mailbox toolbar
+ * to move messages to a (user selectable) archive folder.
+ *
+ * @version 1.4
+ * @author Andre Rodier, Thomas Bruederli
+ */
+class archive extends rcube_plugin
+{
+  public $task = 'mail|settings';
+
+  function init()
+  {
+    $this->register_action('plugin.archive', array($this, 'request_action'));
+
+    # There is no "Archived flags"
+    # $GLOBALS['IMAP_FLAGS']['ARCHIVED'] = 'Archive';
+    
+    $rcmail = rcmail::get_instance();
+    if ($rcmail->task == 'mail' && ($rcmail->action == '' || $rcmail->action == 'show') && ($archive_folder = $rcmail->config->get('archive_mbox'))) {
+      $this->include_script('archive.js');
+      $this->add_texts('localization', true);
+      $this->add_button(
+        array(
+            'command' => 'plugin.archive',
+            'imagepas' => 'archive_pas.png',
+            'imageact' => 'archive_act.png',
+            'title' => 'buttontitle',
+            'domain' => $this->ID,
+        ),
+        'toolbar');
+      
+      // register hook to localize the archive folder
+      $this->add_hook('render_mailboxlist', array($this, 'render_mailboxlist'));
+
+      // set env variable for client
+      $rcmail->output->set_env('archive_folder', $archive_folder);
+
+      // add archive folder to the list of default mailboxes
+      if (($default_folders = $rcmail->config->get('default_imap_folders')) && !in_array($archive_folder, $default_folders)) {
+        $default_folders[] = $archive_folder;
+        $rcmail->config->set('default_imap_folders', $default_folders);
+      }
+      
+    }
+    else if ($rcmail->task == 'settings') {
+      $dont_override = $rcmail->config->get('dont_override', array());
+      if (!in_array('archive_mbox', $dont_override)) {
+        $this->add_hook('user_preferences', array($this, 'prefs_table'));
+        $this->add_hook('save_preferences', array($this, 'save_prefs'));
+      }
+    }
+  }
+  
+  function render_mailboxlist($p)
+  {
+    $rcmail = rcmail::get_instance();
+    $archive_folder = $rcmail->config->get('archive_mbox');
+
+    // set localized name for the configured archive folder
+    if ($archive_folder) {
+      if (isset($p['list'][$archive_folder]))
+        $p['list'][$archive_folder]['name'] = $this->gettext('archivefolder');
+      else // search in subfolders
+        $this->_mod_folder_name($p['list'], $archive_folder, $this->gettext('archivefolder'));
+    }
+
+    return $p;
+  }
+
+  function _mod_folder_name(&$list, $folder, $new_name)
+  {
+    foreach ($list as $idx => $item) {
+      if ($item['id'] == $folder) {
+        $list[$idx]['name'] = $new_name;
+       return true;
+      } else if (!empty($item['folders']))
+        if ($this->_mod_folder_name($list[$idx]['folders'], $folder, $new_name))
+         return true;
+    }
+    return false;
+  }
+
+  function request_action()
+  {
+    $this->add_texts('localization');
+    
+    $uids = get_input_value('_uid', RCUBE_INPUT_POST);
+    $mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
+    
+    $rcmail = rcmail::get_instance();
+    
+    // There is no "Archive flags", but I left this line in case it may be useful
+    // $rcmail->imap->set_flag($uids, 'ARCHIVE');
+    
+    if (($archive_mbox = $rcmail->config->get('archive_mbox')) && $mbox != $archive_mbox) {
+      $rcmail->output->command('move_messages', $archive_mbox);
+      $rcmail->output->command('display_message', $this->gettext('archived'), 'confirmation');
+    }
+    
+    $rcmail->output->send();
+  }
+
+  function prefs_table($args)
+  {
+    if ($args['section'] == 'folders') {
+      $this->add_texts('localization');
+      
+      $rcmail = rcmail::get_instance();
+      $select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true, 'maxlength' => 30));
+
+      $args['blocks']['main']['options']['archive_mbox'] = array(
+          'title' => $this->gettext('archivefolder'),
+          'content' => $select->show($rcmail->config->get('archive_mbox'), array('name' => "_archive_mbox"))
+      );
+    }
+
+    return $args;
+  }
+
+  function save_prefs($args)
+  {
+    if ($args['section'] == 'folders') {
+      $args['prefs']['archive_mbox'] = get_input_value('_archive_mbox', RCUBE_INPUT_POST);
+      return $args;
+    }
+  }
+
+}
diff --git a/plugins/archive/archive_act.png b/plugins/archive/archive_act.png
new file mode 100644 (file)
index 0000000..2a17358
Binary files /dev/null and b/plugins/archive/archive_act.png differ
diff --git a/plugins/archive/archive_pas.png b/plugins/archive/archive_pas.png
new file mode 100644 (file)
index 0000000..8de2085
Binary files /dev/null and b/plugins/archive/archive_pas.png differ
diff --git a/plugins/archive/foldericon.png b/plugins/archive/foldericon.png
new file mode 100644 (file)
index 0000000..ec0853c
Binary files /dev/null and b/plugins/archive/foldericon.png differ
diff --git a/plugins/archive/localization/de_CH.inc b/plugins/archive/localization/de_CH.inc
new file mode 100644 (file)
index 0000000..2ed0f5a
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Nachricht archivieren';
+$labels['archived'] = 'Nachricht erfolgreich archiviert';
+$labels['archivefolder'] = 'Archiv';
+
+?>
diff --git a/plugins/archive/localization/de_DE.inc b/plugins/archive/localization/de_DE.inc
new file mode 100644 (file)
index 0000000..2ed0f5a
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Nachricht archivieren';
+$labels['archived'] = 'Nachricht erfolgreich archiviert';
+$labels['archivefolder'] = 'Archiv';
+
+?>
diff --git a/plugins/archive/localization/en_US.inc b/plugins/archive/localization/en_US.inc
new file mode 100644 (file)
index 0000000..fce31a0
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Archive this message';
+$labels['archived'] = 'Successfully archived';
+$labels['archivefolder'] = 'Archive';
+
+?>
diff --git a/plugins/archive/localization/fr_FR.inc b/plugins/archive/localization/fr_FR.inc
new file mode 100644 (file)
index 0000000..422d45d
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Archiver ce message';
+$labels['archived'] = 'Message archivé avec success';
+$labels['archivefolder'] = 'Archive';
+
+?>
+
diff --git a/plugins/archive/localization/pl_PL.inc b/plugins/archive/localization/pl_PL.inc
new file mode 100644 (file)
index 0000000..2ecc779
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Przenieś do archiwum';
+$labels['archived'] = 'Pomyślnie zarchiwizowano';
+$labels['archivefolder'] = 'Archiwum';
+
+?>
diff --git a/plugins/autologon/autologon.php b/plugins/autologon/autologon.php
new file mode 100644 (file)
index 0000000..c40f2d4
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * Sample plugin to try out some hooks.
+ * This performs an automatic login if accessed from localhost
+ */
+class autologon extends rcube_plugin
+{
+
+  function init()
+  {
+    $this->add_hook('startup', array($this, 'startup'));
+    $this->add_hook('authenticate', array($this, 'authenticate'));
+  }
+
+  function startup($args)
+  {
+    $rcmail = rcmail::get_instance();
+
+    // change action to login
+    if ($args['task'] == 'mail' && empty($args['action']) && empty($_SESSION['user_id']) && !empty($_GET['_autologin']) && $this->is_localhost())
+      $args['action'] = 'login';
+
+    return $args;
+  }
+
+  function authenticate($args)
+  {
+    if (!empty($_GET['_autologin']) && $this->is_localhost()) {
+      $args['user'] = 'me';
+      $args['pass'] = '******';
+      $args['host'] = 'localhost';
+    }
+  
+    return $args;
+  }
+
+  function is_localhost()
+  {
+    return $_SERVER['REMOTE_ADDR'] == '::1' || $_SERVER['REMOTE_ADDR'] == '127.0.0.1';
+  }
+
+}
+
diff --git a/plugins/database_attachments/database_attachments.php b/plugins/database_attachments/database_attachments.php
new file mode 100644 (file)
index 0000000..a8ac62e
--- /dev/null
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Filesystem Attachments
+ * 
+ * This plugin which provides database backed storage for temporary
+ * attachment file handling.  The primary advantage of this plugin
+ * is its compatibility with round-robin dns multi-server roundcube
+ * installations.
+ *
+ * This plugin relies on the core filesystem_attachments plugin
+ *
+ * @author Ziba Scott <ziba@umich.edu>
+ * 
+ */
+require_once('plugins/filesystem_attachments/filesystem_attachments.php');
+class database_attachments extends filesystem_attachments
+{
+
+    // A prefix for the cache key used in the session and in the key field of the cache table
+    private $cache_prefix = "db_attach";
+
+    /**
+     * Helper method to generate a unique key for the given attachment file
+     */
+    private function _key($filepath)
+    {
+        return  $this->cache_prefix.md5(mktime().$filepath.$_SESSION['user_id']); 
+    }
+
+    /**
+     * Save a newly uploaded attachment
+     */
+    function upload($args)
+    {
+        $args['status'] = false;
+        $rcmail = rcmail::get_instance();
+        $key = $this->_key($args['path']);
+        $data = base64_encode(file_get_contents($args['path']));
+
+        $status = $rcmail->db->query(
+            "INSERT INTO ".get_table_name('cache')."
+             (created, user_id, cache_key, data)
+             VALUES (".$rcmail->db->now().", ?, ?, ?)",
+            $_SESSION['user_id'],
+            $key,
+            $data);
+            
+        if ($status) {
+            $args['id'] = $key;
+            $args['status'] = true;
+            unset($args['path']);
+        }
+        
+        return $args;
+    }
+
+    /**
+     * Save an attachment from a non-upload source (draft or forward)
+     */
+    function save($args)
+    {
+        $args['status'] = false;
+        $rcmail = rcmail::get_instance();
+
+        $key = $this->_key($args['name']);
+
+       if ($args['path'])
+           $args['data'] = file_get_contents($args['path']);
+
+        $data = base64_encode($args['data']);
+
+        $status = $rcmail->db->query(
+            "INSERT INTO ".get_table_name('cache')."
+             (created, user_id, cache_key, data)
+             VALUES (".$rcmail->db->now().", ?, ?, ?)",
+            $_SESSION['user_id'],
+            $key,
+            $data);
+        
+        if ($status) {
+            $args['id'] = $key;
+            $args['status'] = true;
+        }
+
+        return $args;
+    }
+
+    /**
+     * Remove an attachment from storage
+     * This is triggered by the remove attachment button on the compose screen
+     */
+    function remove($args)
+    {
+        $args['status'] = false;
+        $rcmail = rcmail::get_instance();
+        $status = $rcmail->db->query(
+            "DELETE FROM ".get_table_name('cache')."
+             WHERE  user_id=?
+             AND    cache_key=?",
+            $_SESSION['user_id'],
+            $args['id']);
+    
+        if ($status) {
+            $args['status'] = true;
+        }
+        
+        return $args;
+    }
+
+    /**
+     * When composing an html message, image attachments may be shown
+     * For this plugin, $this->get_attachment will check the file and
+     * return it's contents
+     */
+    function display($args)
+    {
+        return $this->get_attachment($args);
+    }
+
+    /**
+     * When displaying or sending the attachment the file contents are fetched
+     * using this method. This is also called by the display_attachment hook.
+     */
+    function get_attachment($args)
+    {
+        $rcmail = rcmail::get_instance();
+        
+        $sql_result = $rcmail->db->query(
+            "SELECT cache_id, data
+             FROM ".get_table_name('cache')."
+             WHERE  user_id=?
+             AND    cache_key=?",
+            $_SESSION['user_id'],
+            $args['id']);
+
+        if ($sql_arr = $rcmail->db->fetch_assoc($sql_result)) {
+            $args['data'] = base64_decode($sql_arr['data']);
+            $args['status'] = true;
+        }
+        
+        return $args;
+    }
+    
+    /**
+     * Delete all temp files associated with this user
+     */
+    function cleanup($args)
+    {
+        $rcmail = rcmail::get_instance();
+        $rcmail->db->query(
+            "DELETE FROM ".get_table_name('cache')."
+             WHERE  user_id=?
+             AND cache_key like '{$this->cache_prefix}%'",
+            $_SESSION['user_id']);
+    }
+}
diff --git a/plugins/debug_logger/debug_logger.php b/plugins/debug_logger/debug_logger.php
new file mode 100644 (file)
index 0000000..f04ba6a
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * Debug Logger
+ *
+ * Enhanced logging for debugging purposes.  It is not recommened
+ * to be enabled on production systems without testing because of
+ * the somewhat increased memory, cpu and disk i/o overhead.
+ *
+ * Debug Logger listens for existing console("message") calls and
+ * introduces start and end tags as well as free form tagging
+ * which can redirect messages to files.  The resulting log files
+ * provide timing and tag quantity results.
+ *
+ * Enable the plugin in config/main.inc.php and add your desired
+ * log types and files.
+ *
+ * @version 1.0
+ * @author Ziba Scott
+ * @website http://roundcube.net
+ * 
+ * Example:
+ *
+ * config/main.inc.php:
+ *
+ *   // $rcmail_config['debug_logger'][type of logging] = name of file in log_dir
+ *   // The 'master' log includes timing information
+ *   $rcmail_config['debug_logger']['master'] = 'master';
+ *   // If you want sql messages to also go into a separate file 
+ *   $rcmail_config['debug_logger']['sql'] = 'sql';
+ *
+ * index.php (just after $RCMAIL->plugins->init()):
+ *
+ *   console("my test","start");
+ *   console("my message");
+ *   console("my sql calls","start");
+ *   console("cp -r * /dev/null","shell exec");
+ *   console("select * from example","sql");
+ *   console("select * from example","sql");
+ *   console("select * from example","sql");
+ *   console("end");
+ *   console("end");
+ *
+ *
+ * logs/master (after reloading the main page):
+ *
+ *   [17-Feb-2009 16:51:37 -0500] start: Task: mail. 
+ *   [17-Feb-2009 16:51:37 -0500]   start: my test
+ *   [17-Feb-2009 16:51:37 -0500]     my message
+ *   [17-Feb-2009 16:51:37 -0500]     shell exec: cp -r * /dev/null
+ *   [17-Feb-2009 16:51:37 -0500]     start: my sql calls
+ *   [17-Feb-2009 16:51:37 -0500]       sql: select * from example
+ *   [17-Feb-2009 16:51:37 -0500]       sql: select * from example
+ *   [17-Feb-2009 16:51:37 -0500]       sql: select * from example
+ *   [17-Feb-2009 16:51:37 -0500]     end: my sql calls - 0.0018 seconds shell exec: 1, sql: 3, 
+ *   [17-Feb-2009 16:51:37 -0500]   end: my test - 0.0055 seconds shell exec: 1, sql: 3, 
+ *   [17-Feb-2009 16:51:38 -0500] end: Task: mail.  - 0.8854 seconds shell exec: 1, sql: 3, 
+ * 
+ * logs/sql (after reloading the main page):
+ *
+ *   [17-Feb-2009 16:51:37 -0500]       sql: select * from example
+ *   [17-Feb-2009 16:51:37 -0500]       sql: select * from example
+ *   [17-Feb-2009 16:51:37 -0500]       sql: select * from example
+ */
+class debug_logger extends rcube_plugin
+{
+    function init()
+    {
+        require_once(dirname(__FILE__).'/runlog/runlog.php');
+        $this->runlog = new runlog(); 
+
+        if(!rcmail::get_instance()->config->get('log_dir')){
+            rcmail::get_instance()->config->set('log_dir',INSTALL_PATH.'logs');
+        }
+
+        $log_config = rcmail::get_instance()->config->get('debug_logger',array());
+
+        foreach($log_config as $type=>$file){
+            $this->runlog->set_file(rcmail::get_instance()->config->get('log_dir').'/'.$file, $type);
+        }
+
+        $start_string = "";
+        $action = rcmail::get_instance()->action;
+        $task = rcmail::get_instance()->task;
+        if($action){
+               $start_string .= "Action: ".$action.". "; 
+        }
+        if($task){
+               $start_string .= "Task: ".$task.". "; 
+        }
+        $this->runlog->start($start_string);
+
+        $this->add_hook('console', array($this, 'console'));
+        $this->add_hook('authenticate', array($this, 'authenticate'));
+    }
+
+    function authenticate($args){
+        $this->runlog->note('Authenticating '.$args['user'].'@'.$args['host']);
+        return $args;
+    }
+
+    function console($args){
+        $note = $args[0];
+        $type = $args[1];
+
+
+        if(!isset($args[1])){
+            // This could be extended to detect types based on the 
+            // file which called console.  For now only rcube_imap.inc is supported
+            $bt = debug_backtrace();
+            $file  = $bt[3]['file'];
+            switch(basename($file)){
+                case 'rcube_imap.php':
+                    $type = 'imap';
+                    break;
+                default:
+                    $type = FALSE; 
+                    break; 
+            }
+        }
+        switch($note){
+            case 'end':
+                $type = 'end';
+                break;
+        }
+
+
+        switch($type){
+            case 'start':
+                $this->runlog->start($note);
+                break;
+            case 'end':
+                $this->runlog->end();
+                break;
+            default:
+                $this->runlog->note($note, $type);
+                break;
+        }
+        return $args;
+    }
+
+    function __destruct(){
+                $this->runlog->end();
+    }
+}
+?>
diff --git a/plugins/debug_logger/runlog/runlog.php b/plugins/debug_logger/runlog/runlog.php
new file mode 100644 (file)
index 0000000..c9f6726
--- /dev/null
@@ -0,0 +1,227 @@
+<?php
+
+/**
+ * runlog 
+ * 
+ * @author Ziba Scott <ziba@umich.edu> 
+ */
+class runlog {
+
+    private $start_time = FALSE;
+
+    private $parent_stack = array();
+
+    public $print_to_console = FALSE;
+
+    private $file_handles = array();
+
+    private $indent = 0;
+
+    public $threshold = 0;
+
+    public $tag_count = array();
+
+    public $timestamp = "d-M-Y H:i:s O";
+
+    public $max_line_size = 150;
+
+    private $run_log = array();
+
+    function runlog()
+    {
+        $this->start_time = microtime( TRUE );
+    }
+
+    public function start( $name, $tag = FALSE  )
+    {
+        $this->run_log[] = array( 'type' => 'start',
+                                  'tag' => $tag,
+                                  'index' => count($this->run_log),
+                                  'value' => $name,
+                                  'time' => microtime( TRUE ),
+                                  'parents' => $this->parent_stack,
+                                  'ended' => false,
+                                   );
+        $this->parent_stack[] = $name;
+
+        $this->print_to_console("start: ".$name, $tag, 'start');
+        $this->print_to_file("start: ".$name, $tag, 'start');
+        $this->indent++;
+    }
+
+    public function end()
+    {
+        $name = array_pop( $this->parent_stack );
+        foreach ( $this->run_log as $k => $entry ) {
+            if ( $entry['value'] == $name && $entry['type'] == 'start'  && $entry['ended'] == false) {
+                $lastk = $k;
+            }
+        }
+        $start = $this->run_log[$lastk]['time'];
+        $this->run_log[$lastk]['duration'] = microtime( TRUE ) - $start;
+        $this->run_log[$lastk]['ended'] = true;
+
+        $this->run_log[] = array( 'type' => 'end',
+                                  'tag' =>  $this->run_log[$lastk]['tag'],
+                                  'index' => $lastk,
+                                  'value' => $name,
+                                  'time' => microtime( TRUE ),
+                                  'duration' => microtime( TRUE ) - $start,
+                                  'parents' => $this->parent_stack,
+                                   );
+        $this->indent--;
+        if($this->run_log[$lastk]['duration'] >= $this->threshold){ 
+            $tag_report = "";
+            foreach($this->tag_count as $tag=>$count){
+                $tag_report .= "$tag: $count, ";
+            }
+            if(!empty($tag_report)){
+//                $tag_report = "\n$tag_report\n";
+            }
+            $end_txt = sprintf("end: $name - %0.4f seconds $tag_report", $this->run_log[$lastk]['duration'] ); 
+            $this->print_to_console($end_txt, $this->run_log[$lastk]['tag'] , 'end');
+            $this->print_to_file($end_txt,  $this->run_log[$lastk]['tag'], 'end');
+        }
+    }
+
+    public function increase_tag_count($tag){
+            if(!isset($this->tag_count[$tag])){
+                $this->tag_count[$tag] = 0;
+            }
+            $this->tag_count[$tag]++;
+    }
+
+    public function get_text(){
+        $text = "";
+        foreach($this->run_log as $entry){
+           $text .= str_repeat("   ",count($entry['parents']));
+           if($entry['tag'] != 'text'){
+            $text .= $entry['tag'].': ';
+           }
+           $text .= $entry['value'];
+
+           if($entry['tag'] == 'end'){
+            $text .= sprintf(" - %0.4f seconds", $entry['duration'] ); 
+           }
+
+           $text .= "\n"; 
+        }
+        return $text;
+    }
+
+    public function set_file($filename, $tag = 'master'){
+        if(!isset($this->file_handle[$tag])){
+            $this->file_handles[$tag] = fopen($filename, 'a');
+            if(!$this->file_handles[$tag]){
+                trigger_error('Could not open file for writing: '.$filename);
+            }
+        }
+    }
+
+    public function note( $msg, $tag = FALSE )
+    {
+        if($tag){
+            $this->increase_tag_count($tag);
+        }
+        if ( is_array( $msg )) {
+            $msg = '<pre>' . print_r( $msg, TRUE ) . '</pre>';
+        }
+        $this->debug_messages[] = $msg;
+        $this->run_log[] = array( 'type' => 'note',
+                                  'tag' => $tag ? $tag:"text",
+                                  'value' => htmlentities($msg),
+                                  'time' => microtime( TRUE ),
+                                  'parents' => $this->parent_stack,
+             );
+
+       $this->print_to_file($msg, $tag);
+       $this->print_to_console($msg, $tag);
+
+    }
+
+    public function print_to_file($msg, $tag = FALSE, $type = FALSE){
+       if(!$tag){
+        $file_handle_tag = 'master';
+       }
+       else{
+            $file_handle_tag = $tag;
+       }
+       if($file_handle_tag != 'master' && isset($this->file_handles[$file_handle_tag])){
+           $buffer = $this->get_indent();
+           $buffer .= "$msg\n";
+           if(!empty($this->timestamp)){
+                $buffer = sprintf("[%s] %s",date($this->timestamp, mktime()), $buffer);
+           }
+           fwrite($this->file_handles[$file_handle_tag], wordwrap($buffer, $this->max_line_size, "\n     "));
+        }
+       if(isset($this->file_handles['master']) && $this->file_handles['master']){
+           $buffer = $this->get_indent();
+           if($tag){
+            $buffer .= "$tag: ";
+           }
+           $msg = str_replace("\n","",$msg);
+           $buffer .= "$msg";
+           if(!empty($this->timestamp)){
+                $buffer = sprintf("[%s] %s",date($this->timestamp, mktime()), $buffer);
+           }
+           if(strlen($buffer) > $this->max_line_size){
+                $buffer = substr($buffer,0,$this->max_line_size - 3)."...";
+           }
+           fwrite($this->file_handles['master'], $buffer."\n");
+       }
+    }
+
+    public function print_to_console($msg, $tag=FALSE){
+        if($this->print_to_console){
+            if(is_array($this->print_to_console)){
+                if(in_array($tag, $this->print_to_console)){
+                    echo $this->get_indent();
+                    if($tag){
+                        echo "$tag: ";
+                    }
+                    echo "$msg\n";
+                }
+            }
+            else{
+                echo $this->get_indent();
+                if($tag){
+                    echo "$tag: ";
+                }
+                echo "$msg\n";
+            }
+        }
+    }
+
+    public function print_totals(){
+        $totals = array();
+        foreach ( $this->run_log as $k => $entry ) {
+            if ( $entry['type'] == 'start'  && $entry['ended'] == true) {
+                $totals[$entry['value']]['duration'] += $entry['duration'];
+                $totals[$entry['value']]['count'] += 1;
+            }
+        }
+       if($this->file_handle){
+           foreach($totals as $name=>$details){
+            fwrite($this->file_handle,$name.": ".number_format($details['duration'],4)."sec,  ".$details['count']." calls \n");
+           }
+        }
+    }
+
+    private function get_indent(){
+           $buf = "";
+           for($i = 0; $i < $this->indent; $i++){
+               $buf .= "  "; 
+           }
+           return $buf;
+    }
+
+
+   function  __destruct(){
+       foreach($this->file_handles as $handle){
+            fclose($handle);
+        }
+    }
+
+}
+
+?>
diff --git a/plugins/emoticons/emoticons.php b/plugins/emoticons/emoticons.php
new file mode 100644 (file)
index 0000000..be736b6
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * Display Emoticons
+ *
+ * Sample plugin to replace emoticons in plain text message body with real icons
+ *
+ * @version 1.0.1
+ * @author Thomas Bruederli
+ * @website http://roundcube.net
+ */
+class emoticons extends rcube_plugin
+{
+  public $task = 'mail';
+  private $map;
+
+  function init()
+  {
+    $this->task = 'mail';
+    $this->add_hook('message_part_after', array($this, 'replace'));
+  
+    $this->map = array(
+      ':)'  => html::img(array('src' => './program/js/tiny_mce/plugins/emotions/img/smiley-smile.gif', 'alt' => ':)')),
+      ':-)' => html::img(array('src' => './program/js/tiny_mce/plugins/emotions/img/smiley-smile.gif', 'alt' => ':-)')),
+      ':('  => html::img(array('src' => './program/js/tiny_mce/plugins/emotions/img/smiley-cry.gif', 'alt' => ':(')),
+      ':-(' => html::img(array('src' => './program/js/tiny_mce/plugins/emotions/img/smiley-cry.gif', 'alt' => ':-(')),
+    );
+  }
+
+  function replace($args)
+  {
+    if ($args['type'] == 'plain')
+      return array('body' => strtr($args['body'], $this->map));
+  
+    return null;
+  }
+
+}
+
diff --git a/plugins/example_addressbook/example_addressbook.php b/plugins/example_addressbook/example_addressbook.php
new file mode 100644 (file)
index 0000000..081efcb
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Sample plugin to add a new address book
+ * with just a static list of contacts
+ */
+class example_addressbook extends rcube_plugin
+{
+  private $abook_id = 'static';
+  
+  public function init()
+  {
+    $this->add_hook('address_sources', array($this, 'address_sources'));
+    $this->add_hook('get_address_book', array($this, 'get_address_book'));
+    
+    // use this address book for autocompletion queries
+    // (maybe this should be configurable by the user?)
+    $config = rcmail::get_instance()->config;
+    $sources = $config->get('autocomplete_addressbooks', array('sql'));
+    if (!in_array($this->abook_id, $sources)) {
+      $sources[] = $this->abook_id;
+      $config->set('autocomplete_addressbooks', $sources);
+    }
+  }
+  
+  public function address_sources($p)
+  {
+    $p['sources'][$this->abook_id] = array('id' => $this->abook_id, 'name' => 'Static List', 'readonly' => true);
+    return $p;
+  }
+  
+  public function get_address_book($p)
+  {
+    if ($p['id'] == $this->abook_id) {
+      require_once(dirname(__FILE__) . '/example_addressbook_backend.php');
+      $p['instance'] = new example_addressbook_backend;
+    }
+    
+    return $p;
+  }
+  
+}
diff --git a/plugins/example_addressbook/example_addressbook_backend.php b/plugins/example_addressbook/example_addressbook_backend.php
new file mode 100644 (file)
index 0000000..ad6b89d
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * Example backend class for a custom address book
+ *
+ * This one just holds a static list of address records
+ *
+ * @author Thomas Bruederli
+ */
+class example_addressbook_backend extends rcube_addressbook
+{
+  public $primary_key = 'ID';
+  public $readonly = true;
+  
+  private $filter;
+  private $result;
+  
+  public function __construct()
+  {
+    $this->ready = true;
+  }
+  
+  public function set_search_set($filter)
+  {
+    $this->filter = $filter;
+  }
+  
+  public function get_search_set()
+  {
+    return $this->filter;
+  }
+
+  public function reset()
+  {
+    $this->result = null;
+    $this->filter = null;
+  }
+
+  public function list_records($cols=null, $subset=0)
+  {
+    $this->result = $this->count();
+    $this->result->add(array('ID' => '111', 'name' => "Example Contact", 'firstname' => "Example", 'surname' => "Contact", 'email' => "example@roundcube.net"));
+    
+    return $this->result;
+  }
+
+  public function search($fields, $value, $strict=false, $select=true)
+  {
+    // no search implemented, just list all records
+    return $this->list_records();
+  }
+
+  public function count()
+  {
+    return new rcube_result_set(1, ($this->list_page-1) * $this->page_size);
+  }
+
+  public function get_result()
+  {
+    return $this->result;
+  }
+
+  public function get_record($id, $assoc=false)
+  {
+    $this->list_records();
+    $first = $this->result->first();
+    $sql_arr = $first['ID'] == $id ? $first : null;
+    
+    return $assoc && $sql_arr ? $sql_arr : $this->result;
+  }
+  
+}
diff --git a/plugins/filesystem_attachments/filesystem_attachments.php b/plugins/filesystem_attachments/filesystem_attachments.php
new file mode 100644 (file)
index 0000000..fcdcea7
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+/**
+ * Filesystem Attachments
+ * 
+ * This is a core plugin which provides basic, filesystem based
+ * attachment temporary file handling.  This includes storing
+ * attachments of messages currently being composed, writing attachments
+ * to disk when drafts with attachments are re-opened and writing
+ * attachments to disk for inline display in current html compositions.
+ *
+ * Developers may wish to extend this class when creating attachment
+ * handler plugins:
+ *   require_once('plugins/filesystem_attachments/filesystem_attachments.php');
+ *   class myCustom_attachments extends filesystem_attachments
+ *
+ * @author Ziba Scott <ziba@umich.edu>
+ * @author Thomas Bruederli <roundcube@gmail.com>
+ * 
+ */
+class filesystem_attachments extends rcube_plugin
+{
+    public $task = 'mail';
+    
+    function init()
+    {
+        // Save a newly uploaded attachment
+        $this->add_hook('upload_attachment', array($this, 'upload'));
+
+        // Save an attachment from a non-upload source (draft or forward)
+        $this->add_hook('save_attachment', array($this, 'save'));
+
+        // Remove an attachment from storage
+        $this->add_hook('remove_attachment', array($this, 'remove'));
+
+        // When composing an html message, image attachments may be shown
+        $this->add_hook('display_attachment', array($this, 'display'));
+
+        // Get the attachment from storage and place it on disk to be sent
+        $this->add_hook('get_attachment', array($this, 'get_attachment'));
+
+        // Delete all temp files associated with this user
+        $this->add_hook('cleanup_attachments', array($this, 'cleanup'));
+        $this->add_hook('kill_session', array($this, 'cleanup'));
+    }
+
+    /**
+     * Save a newly uploaded attachment
+     */
+    function upload($args)
+    {
+        $args['status'] = false;
+        $rcmail = rcmail::get_instance();
+
+        // use common temp dir for file uploads
+        // #1484529: we need absolute path on Windows for move_uploaded_file()
+        $temp_dir = realpath($rcmail->config->get('temp_dir'));
+        $tmpfname = tempnam($temp_dir, 'rcmAttmnt');
+
+        if (move_uploaded_file($args['path'], $tmpfname) && file_exists($tmpfname)) {
+            $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
+            $args['path'] = $tmpfname;
+            $args['status'] = true;
+
+            // Note the file for later cleanup
+            $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $tmpfname;
+        }
+
+        return $args;
+    }
+
+    /**
+     * Save an attachment from a non-upload source (draft or forward)
+     */
+    function save($args)
+    {
+        $args['status'] = false;
+
+        if (!$args['path']) {
+            $rcmail = rcmail::get_instance();
+            $temp_dir = unslashify($rcmail->config->get('temp_dir'));
+            $tmp_path = tempnam($temp_dir, 'rcmAttmnt');
+
+            if ($fp = fopen($tmp_path, 'w')) {
+                fwrite($fp, $args['data']);
+                fclose($fp);
+                $args['path'] = $tmp_path;
+            } else
+                return $args;
+        }
+        
+        $args['id'] = count($_SESSION['plugins']['filesystem_attachments']['tmp_files'])+1;
+        $args['status'] = true;
+            
+        // Note the file for later cleanup
+        $_SESSION['plugins']['filesystem_attachments']['tmp_files'][] = $args['path'];
+
+        return $args;
+    }
+
+    /**
+     * Remove an attachment from storage
+     * This is triggered by the remove attachment button on the compose screen
+     */
+    function remove($args)
+    {
+        $args['status'] = @unlink($args['path']);
+        return $args;
+    }
+
+    /**
+     * When composing an html message, image attachments may be shown
+     * For this plugin, the file is already in place, just check for
+     * the existance of the proper metadata
+     */
+    function display($args)
+    {
+        $args['status'] = file_exists($args['path']);
+        return $args;
+    }
+
+    /**
+     * This attachment plugin doesn't require any steps to put the file
+     * on disk for use.  This stub function is kept here to make this 
+     * class handy as a parent class for other plugins which may need it.
+     */
+    function get_attachment($args)
+    {
+        return $args;
+    }
+    
+    /**
+     * Delete all temp files associated with this user
+     */
+    function cleanup($args)
+    {
+        // $_SESSION['compose']['attachments'] is not a complete record of
+        // temporary files because loading a draft or starting a forward copies
+        // the file to disk, but does not make an entry in that array
+        if (is_array($_SESSION['plugins']['filesystem_attachments']['tmp_files'])){
+            foreach ($_SESSION['plugins']['filesystem_attachments']['tmp_files'] as $filename){
+                if(file_exists($filename)){
+                    unlink($filename);
+                }
+            }
+            unset($_SESSION['plugins']['filesystem_attachments']['tmp_files']);
+        }
+        return $args;
+    }
+}
diff --git a/plugins/help/config.inc.php.dist b/plugins/help/config.inc.php.dist
new file mode 100644 (file)
index 0000000..6b27227
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+// Help content iframe source
+// $rcmail_config['help_source'] = 'http://trac.roundcube.net/wiki';
+$rcmail_config['help_source'] = '';
+
+?>
+  
\ No newline at end of file
diff --git a/plugins/help/content/about.html b/plugins/help/content/about.html
new file mode 100644 (file)
index 0000000..afaded6
--- /dev/null
@@ -0,0 +1,37 @@
+<div id="helpabout">
+<h3 align="center">Copyright &copy; 2005-2009, RoundCube Dev. - Switzerland</h3>
+
+<p>This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2
+as published by the Free Software Foundation.
+</p>
+<p>
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+GNU General Public License for more details.
+</p>
+<p>
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.   
+</p>
+
+<div align="center">
+<h3>Project management and administration</h3>
+<b>Thomas Bruederli (thomasb)</b> - Project leader and head developer<br />
+<b>Till Klampäckel (till)</b> - Co-leader<br />
+<b>Brett Patterson</b> - Forum administrator<br />
+<b>Adam Grelck</b> - Trac administrator<br />
+<b>Jason Fesler</b> - Mailing list administrator<br />
+<b>Brennan Stehling</b> - Mentor, Coordinator
+
+<h3>Developers</h3>
+<b>Eric Stadtherr (estadtherr)</b><br />
+<b>Robin Elfrink (robin, wobin)</b><br />
+<b>Rich Sandberg (richs)</b><br />
+<b>Tomasz Pajor (tomekp)</b><br />
+<b>Fourat Zouari (fourat.zouari)</b><br />
+<b>Aleksander Machniak (alec)</b>
+</div>
+</div>
diff --git a/plugins/help/content/license.html b/plugins/help/content/license.html
new file mode 100644 (file)
index 0000000..2d83c60
--- /dev/null
@@ -0,0 +1,387 @@
+<div id="helplicense">
+<h3>GNU GENERAL PUBLIC LICENSE</h3>
+<p>
+Version 2, June 1991
+</p>
+
+<pre>
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.  
+51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+</pre>
+
+<h3>Preamble</h3>
+
+<p>
+The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+</p>
+
+<p>
+When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+</p>
+
+<p>
+To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+</p>
+
+<p>
+For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+</p>
+
+<p>
+We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+</p>
+
+<p>
+Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+</p>
+
+<p>
+Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+</p>
+
+<p>
+  The precise terms and conditions for copying, distribution and
+modification follow.
+</p>
+
+
+<h3>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</h3>
+
+
+<p>
+<strong>0.</strong>
+This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+</p>
+
+<p>
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+</p>
+
+<p>
+<strong>1.</strong>
+You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+</p>
+
+<p>
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+</p>
+
+<p>
+<strong>2.</strong>
+You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+</p>
+
+<dl>
+  <dt></dt>
+    <dd>
+      <strong>a)</strong>
+      You must cause the modified files to carry prominent notices
+      stating that you changed the files and the date of any change.
+    </dd>
+  <dt></dt>
+    <dd>
+      <strong>b)</strong>
+      You must cause any work that you distribute or publish, that in
+      whole or in part contains or is derived from the Program or any
+      part thereof, to be licensed as a whole at no charge to all third
+      parties under the terms of this License.
+    </dd>
+  <dt></dt>
+    <dd>
+      <strong>c)</strong>
+      If the modified program normally reads commands interactively
+      when run, you must cause it, when started running for such
+      interactive use in the most ordinary way, to print or display an
+      announcement including an appropriate copyright notice and a
+      notice that there is no warranty (or else, saying that you provide
+      a warranty) and that users may redistribute the program under
+      these conditions, and telling the user how to view a copy of this
+      License.  (Exception: if the Program itself is interactive but
+      does not normally print such an announcement, your work based on
+      the Program is not required to print an announcement.)
+    </dd>
+</dl>
+
+<p>
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+</p>
+
+<p>
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+</p>
+
+<p>
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+</p>
+
+<p>
+<strong>3.</strong>
+You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+</p>
+
+<dl>
+  <dt></dt>
+    <dd>
+      <strong>a)</strong>
+      Accompany it with the complete corresponding machine-readable
+      source code, which must be distributed under the terms of Sections
+      1 and 2 above on a medium customarily used for software interchange; or,
+    </dd>
+  <dt></dt>
+    <dd>
+      <strong>b)</strong>
+      Accompany it with a written offer, valid for at least three
+      years, to give any third party, for a charge no more than your
+      cost of physically performing source distribution, a complete
+      machine-readable copy of the corresponding source code, to be
+      distributed under the terms of Sections 1 and 2 above on a medium
+      customarily used for software interchange; or,
+    </dd>
+  <dt></dt>
+    <dd>
+      <strong>c)</strong>
+      Accompany it with the information you received as to the offer
+      to distribute corresponding source code.  (This alternative is
+      allowed only for noncommercial distribution and only if you
+      received the program in object code or executable form with such
+      an offer, in accord with Subsection b above.)
+    </dd>
+</dl>
+
+<p>
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+</p>
+
+<p>
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+</p>
+
+<p>
+<strong>4.</strong>
+You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+</p>
+
+<p>
+<strong>5.</strong>
+You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+</p>
+
+<p>
+<strong>6.</strong>
+Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+</p>
+
+<p>
+<strong>7.</strong>
+If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+</p>
+
+<p>
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+</p>
+
+<p>
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+</p>
+
+<p>
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+</p>
+
+<p>
+<strong>8.</strong>
+If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+</p>
+
+<p>
+<strong>9.</strong>
+The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+</p>
+
+<p>
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+</p>
+
+<p>
+<strong>10.</strong>
+If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+</p>
+
+<p><strong>NO WARRANTY</strong></p>
+
+<p>
+<strong>11.</strong>
+BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+</p>
+
+<p>
+<strong>12.</strong>
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+</p>
+</div>
diff --git a/plugins/help/help.php b/plugins/help/help.php
new file mode 100644 (file)
index 0000000..c02b7e9
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * Help Plugin
+ *
+ * @author Aleksander 'A.L.E.C' Machniak
+ * @licence GNU GPL
+ *
+ * Configuration (see config.inc.php.dist)
+ * 
+ **/
+
+class help extends rcube_plugin
+{
+    function init()
+    {
+      $this->add_texts('localization/', false);
+      
+      // register actions
+      $this->register_action('plugin.help', array($this, 'action'));
+      $this->register_action('plugin.helpabout', array($this, 'action'));
+      $this->register_action('plugin.helplicense', array($this, 'action'));
+
+      // add taskbar button
+      $this->add_button(array(
+       'name'  => 'helptask',
+       'class' => 'button-help',
+       'label' => 'help.help',
+       'href'  => './?_task=dummy&_action=plugin.help',
+        ), 'taskbar');
+
+      $skin = rcmail::get_instance()->config->get('skin');
+      if (!file_exists($this->home."/skins/$skin/help.css"))
+       $skin = 'default';
+
+      // add style for taskbar button (must be here) and Help UI    
+      $this->include_stylesheet("skins/$skin/help.css");
+    }
+
+    function action()
+    {
+      $rcmail = rcmail::get_instance();
+
+      $this->load_config();
+
+      // register UI objects
+      $rcmail->output->add_handlers(array(
+           'helpcontent' => array($this, 'content'),
+      ));
+
+      if ($rcmail->action == 'plugin.helpabout')
+       $rcmail->output->set_pagetitle($this->gettext('about'));
+      else if ($rcmail->action == 'plugin.helplicense')
+        $rcmail->output->set_pagetitle($this->gettext('license'));
+      else
+        $rcmail->output->set_pagetitle($this->gettext('help'));
+
+      $rcmail->output->send('help.help');
+    }
+    
+    function content($attrib)
+    {
+      $rcmail = rcmail::get_instance();
+
+      if ($rcmail->action == 'plugin.helpabout') {
+       return @file_get_contents($this->home.'/content/about.html');
+      }
+      else if ($rcmail->action == 'plugin.helplicense') {
+       return @file_get_contents($this->home.'/content/license.html');
+      }
+
+      // default content: iframe
+
+      if ($src = $rcmail->config->get('help_source'))
+       $attrib['src'] = $src;
+
+      if (empty($attrib['id']))
+        $attrib['id'] = 'rcmailhelpcontent';
+    
+      // allow the following attributes to be added to the <iframe> tag
+      $attrib_str = create_attrib_string($attrib, array('id', 'class', 'style', 'src', 'width', 'height', 'frameborder'));
+      $framename = $attrib['id'];
+
+      $out = sprintf('<iframe name="%s"%s></iframe>'."\n", $framename, $attrib_str);
+    
+      return $out;
+    }
+    
+}
+
+?>
diff --git a/plugins/help/localization/en_GB.inc b/plugins/help/localization/en_GB.inc
new file mode 100644 (file)
index 0000000..8c2d151
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['help'] = 'Help';
+$labels['about'] = 'About';
+$labels['license'] = 'License';
+
+?>
diff --git a/plugins/help/localization/en_US.inc b/plugins/help/localization/en_US.inc
new file mode 100644 (file)
index 0000000..8c2d151
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['help'] = 'Help';
+$labels['about'] = 'About';
+$labels['license'] = 'License';
+
+?>
diff --git a/plugins/help/localization/et_EE.inc b/plugins/help/localization/et_EE.inc
new file mode 100644 (file)
index 0000000..f95f098
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['help'] = 'Abi';
+$labels['about'] = 'Roundcube info';
+$labels['license'] = 'Litsents';
+
+?>
diff --git a/plugins/help/localization/pl_PL.inc b/plugins/help/localization/pl_PL.inc
new file mode 100644 (file)
index 0000000..087bc07
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['help'] = 'Pomoc';
+$labels['about'] = 'O programie';
+$labels['license'] = 'Licencja';
+
+?>
diff --git a/plugins/help/localization/sv_SE.inc b/plugins/help/localization/sv_SE.inc
new file mode 100644 (file)
index 0000000..8b0d487
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['help'] = 'Hjälp';
+$labels['about'] = 'Om';
+$labels['license'] = 'Licens';
+
+?>
diff --git a/plugins/help/skins/default/help.css b/plugins/help/skins/default/help.css
new file mode 100644 (file)
index 0000000..7ccc671
--- /dev/null
@@ -0,0 +1,26 @@
+/***** RoundCube|Mail Help task styles *****/
+
+#taskbar a.button-help
+{
+  background-image: url('help.gif');
+}
+
+#help-box
+{
+  position: absolute;
+  bottom: 30px; 
+  top: 95px;
+  left: 20px;
+  right: 20px;
+  border: 1px solid #999999;
+  overflow: auto;  
+  background-color: #F2F2F2;
+  /* IE hack */
+  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');
+  width: expression((parseInt(document.documentElement.clientWight)-40)+'px');
+}
+
+#helplicense, #helpabout
+{
+  padding: 20px;
+}
diff --git a/plugins/help/skins/default/help.gif b/plugins/help/skins/default/help.gif
new file mode 100644 (file)
index 0000000..1ae9032
Binary files /dev/null and b/plugins/help/skins/default/help.gif differ
diff --git a/plugins/help/skins/default/templates/help.html b/plugins/help/skins/default/templates/help.html
new file mode 100644 (file)
index 0000000..14b8fca
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/help.css" />
+<link rel="stylesheet" type="text/css" href="/settings.css" />
+<script type="text/javascript">
+function help_init_settings_tabs()
+{
+    var tab = '#helptabdefault';
+    if (window.rcmail && rcmail.env.action) {
+       var action = rcmail.env.action.replace(/^plugin\.help/, '');
+       tab = '#helptab' + (action ? action : 'default');
+    }
+    $(tab).addClass('tablink-selected');
+}             
+</script>
+</head>
+<body>
+
+<roundcube:include file="/includes/taskbar.html" />
+<roundcube:include file="/includes/header.html" />
+
+<div id="tabsbar">
+<span id="helptabdefault" class="tablink"><roundcube:button name="helpdefault" href="?_task=dummy&_action=plugin.help" type="link" label="help.help" title="help.help" /></span>
+<span id="helptababout" class="tablink"><roundcube:button name="helpabout" href="?_task=dummy&_action=plugin.helpabout" type="link" label="help.about" title="help.about" class="tablink" /></span>
+<span id="helptablicense" class="tablink"><roundcube:button name="helplicense" href="?_task=dummy&_action=plugin.helplicense" type="link" label="help.license" title="help.license" class="tablink" /></span>
+<roundcube:container name="helptabs" id="helptabsbar" />
+<script type="text/javascript"> if (window.rcmail) rcmail.add_onload(help_init_settings_tabs);</script>
+</div>
+
+<div id="help-box">
+<roundcube:object name="helpcontent" id="helpcontentframe" width="100%" height="100%" frameborder="0" src="/watermark.html" />
+</div>
+
+</body>
+</html>
diff --git a/plugins/http_authentication/http_authentication.php b/plugins/http_authentication/http_authentication.php
new file mode 100644 (file)
index 0000000..57422a7
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * HTTP Basic Authentication
+ *
+ * Make use of an existing HTTP authentication and perform login with the existing user credentials
+ *
+ * @version 1.0
+ * @author Thomas Bruederli
+ */
+class http_authentication extends rcube_plugin
+{
+
+  function init()
+  {
+    $this->add_hook('startup', array($this, 'startup'));
+    $this->add_hook('authenticate', array($this, 'authenticate'));
+  }
+
+  function startup($args)
+  {
+    // change action to login
+    if ($args['task'] == 'mail' && empty($args['action']) && empty($_SESSION['user_id'])
+        && !empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW']))
+      $args['action'] = 'login';
+
+    return $args;
+  }
+
+  function authenticate($args)
+  {
+    if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) {
+      $args['user'] = $_SERVER['PHP_AUTH_USER'];
+      $args['pass'] = $_SERVER['PHP_AUTH_PW'];
+    }
+  
+    return $args;
+  }
+
+}
+
diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog
new file mode 100644 (file)
index 0000000..358836f
--- /dev/null
@@ -0,0 +1,79 @@
+* version 1.4 [2009-07-29]
+-----------------------------------------------------------
+- Updated PEAR::Net_Sieve to 1.1.7
+
+* version 1.3 [2009-07-24]
+-----------------------------------------------------------
+- support more languages
+- support config.inc.php file
+
+* version 1.2 [2009-06-28]
+-----------------------------------------------------------
+- Support IMAP namespaces in fileinto (#1485943)
+- Added it_IT localization
+
+* version 1.1 [2009-05-27]
+-----------------------------------------------------------    
+- Added new icons
+- Added support for headers lists (coma-separated) in rules
+- Added de_CH localization
+
+* version 1.0 [2009-05-21]
+-----------------------------------------------------------    
+- Rewritten using plugin API
+- Added hu_HU localization (Tamas Tevesz)
+
+* version beta7 (svn-r2300) [2009-03-01]
+-----------------------------------------------------------    
+- Added SquirrelMail script auto-import (Jonathan Ernst)
+- Added 'vacation' support (Jonathan Ernst & alec)
+- Added 'stop' support (Jonathan Ernst)
+- Added option for extensions disabling (Jonathan Ernst & alec)
+- Added fi_FI, nl_NL, bg_BG localization
+- Small style fixes
+
+* version 0.2-stable1 (svn-r2205) [2009-01-03]
+-----------------------------------------------------------    
+- Fix moving down filter row
+- Fixes for compressed js files in stable release package
+- Created patch for svn version r2205
+
+* version 0.2-stable [2008-12-31]
+-----------------------------------------------------------    
+- Added ru_RU, fr_FR, zh_CN translation
+- Fixes for Roundcube 0.2-stable
+
+* version rc0.2beta [2008-09-21]
+-----------------------------------------------------------    
+- Small css fixes for IE
+- Fixes for Roundcube 0.2-beta
+
+* version beta6 [2008-08-08]
+-----------------------------------------------------------    
+- Added de_DE translation
+- Fix for Roundcube r1634
+
+* version beta5 [2008-06-10]
+-----------------------------------------------------------    
+- Fixed 'exists' operators
+- Fixed 'not*' operators for custom headers
+- Fixed filters deleting
+
+* version beta4 [2008-06-09]
+-----------------------------------------------------------    
+- Fix for Roundcube r1490
+
+* version beta3 [2008-05-22]
+-----------------------------------------------------------    
+- Fixed textarea error class setting
+- Added pagetitle setting
+- Added option 'managesieve_replace_delimiter'
+- Fixed errors on IE (still need some css fixes)
+    
+* version beta2 [2008-05-20]
+-----------------------------------------------------------    
+- Use 'if' only for first filter and 'elsif' for the rest
+
+* version beta1 [2008-05-15]
+-----------------------------------------------------------    
+- Initial version for Roundcube r1388.
diff --git a/plugins/managesieve/config.inc.php.dist b/plugins/managesieve/config.inc.php.dist
new file mode 100644 (file)
index 0000000..d8e949a
--- /dev/null
@@ -0,0 +1,28 @@
+<?php
+
+// managesieve server port
+$rcmail_config['managesieve_port'] = 2000;
+
+// managesieve server address
+$rcmail_config['managesieve_host'] = 'localhost';
+
+// use or not TLS for managesieve server connection
+// it's because I've problems with TLS and dovecot's managesieve plugin
+// and it's not needed on localhost
+$rcmail_config['managesieve_usetls'] = false;
+
+// default contents of filters script (eg. default spam filter)
+$rcmail_config['managesieve_default'] = '/etc/dovecot/sieve/global';
+
+// I need this because my dovecot (with listescape plugin) uses
+// ':' delimiter, but creates folders with dot delimiter
+$rcmail_config['managesieve_replace_delimiter'] = '';
+
+// disabled sieve extensions (body, copy, date, editheader, encoded-character,
+// envelope, environment, ereject, fileinto, ihave, imap4flags, index,
+// mailbox, mboxmetadata, regex, reject, relational, servermetadata,
+// spamtest, spamtestplus, subaddress, vacation, variables, virustest, etc.
+// Note: not all extensions are implemented
+$rcmail_config['managesieve_disabled_extensions'] = array();
+
+?>
diff --git a/plugins/managesieve/lib/Net/Sieve.php b/plugins/managesieve/lib/Net/Sieve.php
new file mode 100644 (file)
index 0000000..072905d
--- /dev/null
@@ -0,0 +1,1188 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | Copyright (c) 2002-2003, Richard Heyes                                |
+// | Copyright (c) 2006,2008 Anish Mistry                                  |
+// | All rights reserved.                                                  |
+// |                                                                       |
+// | Redistribution and use in source and binary forms, with or without    |
+// | modification, are permitted provided that the following conditions    |
+// | are met:                                                              |
+// |                                                                       |
+// | o Redistributions of source code must retain the above copyright      |
+// |   notice, this list of conditions and the following disclaimer.       |
+// | o Redistributions in binary form must reproduce the above copyright   |
+// |   notice, this list of conditions and the following disclaimer in the |
+// |   documentation and/or other materials provided with the distribution.|
+// | o The names of the authors may not be used to endorse or promote      |
+// |   products derived from this software without specific prior written  |
+// |   permission.                                                         |
+// |                                                                       |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
+// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
+// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
+// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
+// |                                                                       |
+// +-----------------------------------------------------------------------+
+// | Author: Richard Heyes <richard@phpguru.org>                           |
+// | Co-Author: Damian Fernandez Sosa <damlists@cnba.uba.ar>               |
+// | Co-Author: Anish Mistry <amistry@am-productions.biz>                  |
+// +-----------------------------------------------------------------------+
+
+require_once('Net/Socket.php');
+
+/**
+* TODO
+*
+* o supportsAuthMech()
+*/
+
+/**
+* Disconnected state
+* @const NET_SIEVE_STATE_DISCONNECTED
+*/
+define('NET_SIEVE_STATE_DISCONNECTED',  1, true);
+
+/**
+* Authorisation state
+* @const NET_SIEVE_STATE_AUTHORISATION
+*/
+define('NET_SIEVE_STATE_AUTHORISATION', 2, true);
+
+/**
+* Transaction state
+* @const NET_SIEVE_STATE_TRANSACTION
+*/
+define('NET_SIEVE_STATE_TRANSACTION',   3, true);
+
+/**
+* A class for talking to the timsieved server which
+* comes with Cyrus IMAP.
+*
+* SIEVE: RFC3028 http://www.ietf.org/rfc/rfc3028.txt
+* MANAGE-SIEVE: http://www.ietf.org/internet-drafts/draft-martin-managesieve-07.txt
+*
+* @author  Richard Heyes <richard@php.net>
+* @author  Damian Fernandez Sosa <damlists@cnba.uba.ar>
+* @author  Anish Mistry <amistry@am-productions.biz>
+* @access  public
+* @version 1.2.0
+* @package Net_Sieve
+*/
+
+class Net_Sieve
+{
+    /**
+    * The socket object
+    * @var object
+    */
+    var $_sock;
+
+    /**
+    * Info about the connect
+    * @var array
+    */
+    var $_data;
+
+    /**
+    * Current state of the connection
+    * @var integer
+    */
+    var $_state;
+
+    /**
+    * Constructor error is any
+    * @var object
+    */
+    var $_error;
+
+    /**
+    * To allow class debuging
+    * @var boolean
+    */
+    var $_debug = false;
+
+    /**
+    * Allows picking up of an already established connection
+    * @var boolean
+    */
+    var $_bypassAuth = false;
+
+    /**
+    * Whether to use TLS if available
+    * @var boolean
+    */
+    var $_useTLS = true;
+
+    /**
+    * Additional options for stream_context_create()
+    * @var array
+    */
+    var $_options = null;
+
+    /**
+    * The auth methods this class support
+    * @var array
+    */
+    var $supportedAuthMethods=array('DIGEST-MD5', 'CRAM-MD5', 'EXTERNAL', 'PLAIN' , 'LOGIN');
+    //if you have problems using DIGEST-MD5 authentication  please comment the line above and uncomment the following line
+    //var $supportedAuthMethods=array( 'CRAM-MD5', 'PLAIN' , 'LOGIN');
+
+    //var $supportedAuthMethods=array( 'PLAIN' , 'LOGIN');
+
+    /**
+    * The auth methods this class support
+    * @var array
+    */
+    var $supportedSASLAuthMethods=array('DIGEST-MD5', 'CRAM-MD5');
+
+    /**
+    * Handles posible referral loops
+    * @var array
+    */
+    var $_maxReferralCount = 15;
+
+    /**
+    * Constructor
+    * Sets up the object, connects to the server and logs in. stores
+    * any generated error in $this->_error, which can be retrieved
+    * using the getError() method.
+    *
+    * @param  string $user      Login username
+    * @param  string $pass      Login password
+    * @param  string $host      Hostname of server
+    * @param  string $port      Port of server
+    * @param  string $logintype Type of login to perform
+    * @param  string $euser     Effective User (if $user=admin, login as $euser)
+    * @param  string $bypassAuth Skip the authentication phase.  Useful if the socket
+                                  is already open.
+    * @param  boolean $useTLS Use TLS if available
+    * @param  array  $options   options for stream_context_create()
+    */
+    function Net_Sieve($user = null , $pass  = null , $host = 'localhost', $port = 2000, $logintype = '', $euser = '', $debug = false, $bypassAuth = false, $useTLS = true, $options = null)
+    {
+        $this->_state = NET_SIEVE_STATE_DISCONNECTED;
+        $this->_data['user'] = $user;
+        $this->_data['pass'] = $pass;
+        $this->_data['host'] = $host;
+        $this->_data['port'] = $port;
+        $this->_data['logintype'] = $logintype;
+        $this->_data['euser'] = $euser;
+        $this->_sock = &new Net_Socket();
+        $this->_debug = $debug;
+        $this->_bypassAuth = $bypassAuth;
+        $this->_useTLS = $useTLS;
+        $this->_options = $options;
+        /*
+        * Include the Auth_SASL package.  If the package is not available,
+        * we disable the authentication methods that depend upon it.
+        */
+        if ((@include_once 'Auth/SASL.php') === false) {
+            if($this->_debug){
+                echo "AUTH_SASL NOT PRESENT!\n";
+            }
+            foreach($this->supportedSASLAuthMethods as $SASLMethod){
+                $pos = array_search( $SASLMethod, $this->supportedAuthMethods );
+                if($this->_debug){
+                    echo "DISABLING METHOD $SASLMethod\n";
+                }
+                unset($this->supportedAuthMethods[$pos]);
+            }
+        }
+        if( ($user != null) && ($pass != null) ){
+            $this->_error = $this->_handleConnectAndLogin();
+        }
+    }
+
+    /**
+    * Handles the errors the class can find
+    * on the server
+    *
+    * @access private
+    * @param mixed $msg  Text error message or PEAR error object
+    * @param integer $code  Numeric error code
+    * @return PEAR_Error
+    */
+    function _raiseError($msg, $code)
+    {
+        include_once 'PEAR.php';
+        return PEAR::raiseError($msg, $code);
+    }
+
+    /**
+    * Handles connect and login.
+    * on the server
+    *
+    * @access private
+    * @return mixed Indexed array of scriptnames or PEAR_Error on failure
+    */
+    function _handleConnectAndLogin()
+    {
+        if (PEAR::isError($res = $this->connect($this->_data['host'] , $this->_data['port'], $this->_options, $this->_useTLS ))) {
+            return $res;
+        }
+        if($this->_bypassAuth === false) {
+           if (PEAR::isError($res = $this->login($this->_data['user'], $this->_data['pass'], $this->_data['logintype'] , $this->_data['euser'] , $this->_bypassAuth) ) ) {
+                return $res;
+            }
+        }
+        return true;
+    }
+
+    /**
+    * Returns an indexed array of scripts currently
+    * on the server
+    *
+    * @return mixed Indexed array of scriptnames or PEAR_Error on failure
+    */
+    function listScripts()
+    {
+        if (is_array($scripts = $this->_cmdListScripts())) {
+            $this->_active = $scripts[1];
+            return $scripts[0];
+        } else {
+            return $scripts;
+        }
+    }
+
+    /**
+    * Returns the active script
+    *
+    * @return mixed The active scriptname or PEAR_Error on failure
+    */
+    function getActive()
+    {
+        if (!empty($this->_active)) {
+            return $this->_active;
+
+        } elseif (is_array($scripts = $this->_cmdListScripts())) {
+            $this->_active = $scripts[1];
+            return $scripts[1];
+        }
+    }
+
+    /**
+    * Sets the active script
+    *
+    * @param  string $scriptname The name of the script to be set as active
+    * @return mixed              true on success, PEAR_Error on failure
+    */
+    function setActive($scriptname)
+    {
+        return $this->_cmdSetActive($scriptname);
+    }
+
+    /**
+    * Retrieves a script
+    *
+    * @param  string $scriptname The name of the script to be retrieved
+    * @return mixed              The script on success, PEAR_Error on failure
+    */
+    function getScript($scriptname)
+    {
+        return $this->_cmdGetScript($scriptname);
+    }
+
+    /**
+    * Adds a script to the server
+    *
+    * @param  string $scriptname Name of the script
+    * @param  string $script     The script
+    * @param  boolean $makeactive Whether to make this the active script
+    * @return mixed              true on success, PEAR_Error on failure
+    */
+    function installScript($scriptname, $script, $makeactive = false)
+    {
+        if (PEAR::isError($res = $this->_cmdPutScript($scriptname, $script))) {
+            return $res;
+
+        } elseif ($makeactive) {
+            return $this->_cmdSetActive($scriptname);
+
+        } else {
+            return true;
+        }
+    }
+
+    /**
+    * Removes a script from the server
+    *
+    * @param  string $scriptname Name of the script
+    * @return mixed              True on success, PEAR_Error on failure
+    */
+    function removeScript($scriptname)
+    {
+        return $this->_cmdDeleteScript($scriptname);
+    }
+
+    /**
+    * Returns any error that may have been generated in the
+    * constructor
+    *
+    * @return mixed False if no error, PEAR_Error otherwise
+    */
+    function getError()
+    {
+        return PEAR::isError($this->_error) ? $this->_error : false;
+    }
+
+    /**
+    * Handles connecting to the server and checking the
+    * response is valid.
+    *
+    * @access private
+    * @param  string $host Hostname of server
+    * @param  string $port Port of server
+    * @param  array  $options List of options to pass to connect
+    * @param  boolean $useTLS Use TLS if available
+    * @return mixed        True on success, PEAR_Error otherwise
+    */
+    function connect($host, $port, $options = null, $useTLS = true)
+    {
+        if (NET_SIEVE_STATE_DISCONNECTED != $this->_state) {
+            $msg='Not currently in DISCONNECTED state';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if (PEAR::isError($res = $this->_sock->connect($host, $port, false, 5, $options))) {
+            return $res;
+        }
+
+        if($this->_bypassAuth === false) {
+            $this->_state = NET_SIEVE_STATE_AUTHORISATION;
+            if (PEAR::isError($res = $this->_doCmd())) {
+                return $res;
+            }
+        } else {
+            $this->_state = NET_SIEVE_STATE_TRANSACTION;
+        }
+
+        // Explicitly ask for the capabilities in case the connection
+        // is picked up from an existing connection.
+        if(PEAR::isError($res = $this->_cmdCapability() )) {
+            $msg='Failed to connect, server said: ' . $res->getMessage();
+            $code=2;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if($useTLS === true) {
+            // check if we can enable TLS via STARTTLS
+            if(isset($this->_capability['starttls']) && function_exists('stream_socket_enable_crypto') === true) {
+                if (PEAR::isError($res = $this->_startTLS())) {
+                    return $res;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+    * Logs into server.
+    *
+    * @param  string  $user          Login username
+    * @param  string  $pass          Login password
+    * @param  string  $logintype     Type of login method to use
+    * @param  string  $euser         Effective UID (perform on behalf of $euser)
+    * @param  boolean $bypassAuth    Do not perform authentication
+    * @return mixed                  True on success, PEAR_Error otherwise
+    */
+    function login($user, $pass, $logintype = null , $euser = '', $bypassAuth = false)
+    {
+        if (NET_SIEVE_STATE_AUTHORISATION != $this->_state) {
+            $msg='Not currently in AUTHORISATION state';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if( $bypassAuth === false ){
+            if(PEAR::isError($res=$this->_cmdAuthenticate($user , $pass , $logintype, $euser ) ) ){
+                return $res;
+            }
+        }
+        $this->_state = NET_SIEVE_STATE_TRANSACTION;
+        return true;
+    }
+
+    /**
+     * Handles the authentication using any known method
+     *
+     * @param string $uid The userid to authenticate as.
+     * @param string $pwd The password to authenticate with.
+     * @param string $userMethod The method to use ( if $userMethod == '' then the class chooses the best method (the stronger is the best ) )
+     * @param string $euser The effective uid to authenticate as.
+     *
+     * @return mixed  string or PEAR_Error
+     *
+     * @access private
+     * @since  1.0
+     */
+    function _cmdAuthenticate($uid , $pwd , $userMethod = null , $euser = '' )
+    {
+        if ( PEAR::isError( $method = $this->_getBestAuthMethod($userMethod) ) ) {
+            return $method;
+        }
+        switch ($method) {
+            case 'DIGEST-MD5':
+                $result = $this->_authDigest_MD5( $uid , $pwd , $euser );
+                return $result;
+                break;
+            case 'CRAM-MD5':
+                $result = $this->_authCRAM_MD5( $uid , $pwd, $euser);
+                break;
+            case 'LOGIN':
+                $result = $this->_authLOGIN( $uid , $pwd , $euser );
+                break;
+            case 'PLAIN':
+                $result = $this->_authPLAIN( $uid , $pwd , $euser );
+                break;
+            case 'EXTERNAL':
+                $result = $this->_authEXTERNAL( $uid , $pwd , $euser );
+                break;
+            default :
+                $result = new PEAR_Error( "$method is not a supported authentication method" );
+                break;
+        }
+
+        if (PEAR::isError($res = $this->_doCmd() )) {
+            return $res;
+        }
+        return $result;
+    }
+
+    /**
+     * Authenticates the user using the PLAIN method.
+     *
+     * @param string $user The userid to authenticate as.
+     * @param string $pass The password to authenticate with.
+     * @param string $euser The effective uid to authenticate as.
+     *
+     * @return array Returns an array containing the response
+     *
+     * @access private
+     * @since  1.0
+     */
+    function _authPLAIN($user, $pass , $euser )
+    {
+        if ($euser != '') {
+            $cmd=sprintf('AUTHENTICATE "PLAIN" "%s"', base64_encode($euser . chr(0) . $user . chr(0) . $pass ) ) ;
+        } else {
+            $cmd=sprintf('AUTHENTICATE "PLAIN" "%s"', base64_encode( chr(0) . $user . chr(0) . $pass ) );
+        }
+        return  $this->_sendCmd( $cmd ) ;
+    }
+
+    /**
+     * Authenticates the user using the PLAIN method.
+     *
+     * @param string $user The userid to authenticate as.
+     * @param string $pass The password to authenticate with.
+     * @param string $euser The effective uid to authenticate as.
+     *
+     * @return array Returns an array containing the response
+     *
+     * @access private
+     * @since  1.0
+     */
+    function _authLOGIN($user, $pass , $euser )
+    {
+        $this->_sendCmd('AUTHENTICATE "LOGIN"');
+        $this->_doCmd(sprintf('"%s"', base64_encode($user)));
+        $this->_doCmd(sprintf('"%s"', base64_encode($pass)));
+    }
+
+    /**
+     * Authenticates the user using the CRAM-MD5 method.
+     *
+     * @param string $uid The userid to authenticate as.
+     * @param string $pwd The password to authenticate with.
+     * @param string $euser The effective uid to authenticate as.
+     *
+     * @return array Returns an array containing the response
+     *
+     * @access private
+     * @since  1.0
+     */
+    function _authCRAM_MD5($uid, $pwd, $euser)
+    {
+        if ( PEAR::isError( $challenge = $this->_doCmd( 'AUTHENTICATE "CRAM-MD5"' ) ) ) {
+            $this->_error=$challenge;
+            return $challenge;
+        }
+        $challenge=trim($challenge);
+        $challenge = base64_decode( trim($challenge) );
+        $cram = &Auth_SASL::factory('crammd5');
+        if ( PEAR::isError($resp=$cram->getResponse( $uid , $pwd , $challenge ) ) ) {
+            $this->_error=$resp;
+            return $resp;
+        }
+        $auth_str = base64_encode( $resp );
+        if ( PEAR::isError($error = $this->_sendStringResponse( $auth_str  ) ) ) {
+            $this->_error=$error;
+            return $error;
+        }
+
+    }
+
+    /**
+     * Authenticates the user using the DIGEST-MD5 method.
+     *
+     * @param string $uid The userid to authenticate as.
+     * @param string $pwd The password to authenticate with.
+     * @param string $euser The effective uid to authenticate as.
+     *
+     * @return array Returns an array containing the response
+     *
+     * @access private
+     * @since  1.0
+     */
+    function _authDigest_MD5($uid, $pwd, $euser)
+    {
+        if ( PEAR::isError( $challenge = $this->_doCmd('AUTHENTICATE "DIGEST-MD5"') ) ) {
+            $this->_error= $challenge;
+            return $challenge;
+        }
+        $challenge = base64_decode( $challenge );
+        $digest = &Auth_SASL::factory('digestmd5');
+
+        if(PEAR::isError($param=$digest->getResponse($uid, $pwd, $challenge, "localhost", "sieve" , $euser) )) {
+            return $param;
+        }
+        $auth_str = base64_encode($param);
+
+        if ( PEAR::isError($error = $this->_sendStringResponse( $auth_str  ) ) ) {
+            $this->_error=$error;
+            return $error;
+        }
+
+        if ( PEAR::isError( $challenge = $this->_doCmd() ) ) {
+            $this->_error=$challenge ;
+            return $challenge ;
+        }
+
+        if( strtoupper(substr($challenge,0,2))== 'OK' ){
+                return true;
+        }
+
+        /**
+        * We don't use the protocol's third step because SIEVE doesn't allow
+        * subsequent authentication, so we just silently ignore it.
+        */
+        if ( PEAR::isError($error = $this->_sendStringResponse( '' ) ) ) {
+            $this->_error=$error;
+            return $error;
+        }
+
+        if (PEAR::isError($res = $this->_doCmd() )) {
+            return $res;
+        }
+    }
+
+     /**
+     * Authenticates the user using the EXTERNAL method.
+     *
+     * @param string $user The userid to authenticate as.
+     * @param string $pass The password to authenticate with.
+     * @param string $euser The effective uid to authenticate as.
+     *
+     * @return array Returns an array containing the response
+     *
+     * @access private
+     * @since  1.1.7
+     */
+    function _authEXTERNAL($user, $pass, $euser)
+    {
+        if ($euser != '') {
+            $cmd=sprintf('AUTHENTICATE "EXTERNAL" "%s"', base64_encode($euser) ) ;
+        } else {
+            $cmd=sprintf('AUTHENTICATE "EXTERNAL" "%s"', base64_encode($user) );
+        }
+        return $this->_sendCmd( $cmd ) ;
+    }
+
+    /**
+    * Removes a script from the server
+    *
+    * @access private
+    * @param  string $scriptname Name of the script to delete
+    * @return mixed              True on success, PEAR_Error otherwise
+    */
+    function _cmdDeleteScript($scriptname)
+    {
+        if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+            $msg='Not currently in AUTHORISATION state';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+        if (PEAR::isError($res = $this->_doCmd(sprintf('DELETESCRIPT "%s"', $scriptname) ) )) {
+            return $res;
+        }
+        return true;
+    }
+
+    /**
+    * Retrieves the contents of the named script
+    *
+    * @access private
+    * @param  string $scriptname Name of the script to retrieve
+    * @return mixed              The script if successful, PEAR_Error otherwise
+    */
+    function _cmdGetScript($scriptname)
+    {
+        if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+            $msg='Not currently in AUTHORISATION state';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if (PEAR::isError($res = $this->_doCmd(sprintf('GETSCRIPT "%s"', $scriptname) ) ) ) {
+            return $res;
+        }
+
+        return preg_replace('/{[0-9]+}\r\n/', '', $res);
+    }
+
+    /**
+    * Sets the ACTIVE script, ie the one that gets run on new mail
+    * by the server
+    *
+    * @access private
+    * @param  string $scriptname The name of the script to mark as active
+    * @return mixed              True on success, PEAR_Error otherwise
+    */
+    function _cmdSetActive($scriptname)
+    {
+        if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+            $msg='Not currently in AUTHORISATION state';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if (PEAR::isError($res = $this->_doCmd(sprintf('SETACTIVE "%s"', $scriptname) ) ) ) {
+            return $res;
+        }
+
+        $this->_activeScript = $scriptname;
+        return true;
+    }
+
+    /**
+    * Sends the LISTSCRIPTS command
+    *
+    * @access private
+    * @return mixed Two item array of scripts, and active script on success,
+    *               PEAR_Error otherwise.
+    */
+    function _cmdListScripts()
+    {
+        if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+            $msg='Not currently in AUTHORISATION state';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+
+        $scripts = array();
+        $activescript = null;
+
+        if (PEAR::isError($res = $this->_doCmd('LISTSCRIPTS'))) {
+            return $res;
+        }
+
+        $res = explode("\r\n", $res);
+
+        foreach ($res as $value) {
+            if (preg_match('/^"(.*)"( ACTIVE)?$/i', $value, $matches)) {
+                $scripts[] = $matches[1];
+                if (!empty($matches[2])) {
+                    $activescript = $matches[1];
+                }
+            }
+        }
+
+        return array($scripts, $activescript);
+    }
+
+    /**
+    * Sends the PUTSCRIPT command to add a script to
+    * the server.
+    *
+    * @access private
+    * @param  string $scriptname Name of the new script
+    * @param  string $scriptdata The new script
+    * @return mixed              True on success, PEAR_Error otherwise
+    */
+    function _cmdPutScript($scriptname, $scriptdata)
+    {
+        if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+            $msg='Not currently in TRANSACTION state';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+
+        $stringLength = $this->_getLineLength($scriptdata);
+
+        if (PEAR::isError($res = $this->_doCmd(sprintf("PUTSCRIPT \"%s\" {%d+}\r\n%s", $scriptname, $stringLength, $scriptdata) ))) {
+            return $res;
+        }
+
+        return true;
+    }
+
+    /**
+    * Sends the LOGOUT command and terminates the connection
+    *
+    * @access private
+    * @param boolean $sendLogoutCMD True to send LOGOUT command before disconnecting
+    * @return mixed True on success, PEAR_Error otherwise
+    */
+    function _cmdLogout($sendLogoutCMD=true)
+    {
+        if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
+            $msg='Not currently connected';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+            //return PEAR::raiseError('Not currently connected');
+        }
+
+        if($sendLogoutCMD){
+            if (PEAR::isError($res = $this->_doCmd('LOGOUT'))) {
+                return $res;
+            }
+        }
+
+        $this->_sock->disconnect();
+        $this->_state = NET_SIEVE_STATE_DISCONNECTED;
+        return true;
+    }
+
+    /**
+    * Sends the CAPABILITY command
+    *
+    * @access private
+    * @return mixed True on success, PEAR_Error otherwise
+    */
+    function _cmdCapability()
+    {
+        if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
+            $msg='Not currently connected';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if (PEAR::isError($res = $this->_doCmd('CAPABILITY'))) {
+            return $res;
+        }
+        $this->_parseCapability($res);
+        return true;
+    }
+
+    /**
+    * Checks if the server has space to store the script
+    * by the server
+    *
+    * @param  string $scriptname The name of the script to mark as active
+    * @param integer $size The size of the script
+    * @return mixed              True on success, PEAR_Error otherwise
+    */
+    function haveSpace($scriptname,$size)
+    {
+        if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
+            $msg='Not currently in TRANSACTION state';
+            $code=1;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE "%s" %d', $scriptname, $size) ) ) ) {
+            return $res;
+        }
+
+        return true;
+    }
+
+    /**
+    * Parses the response from the capability command. Stores
+    * the result in $this->_capability
+    *
+    * @access private
+    * @param string $data The response from the capability command
+    */
+    function _parseCapability($data)
+    {
+        // clear the cached capabilities
+        $this->_capability = array();
+
+        $data = preg_split('/\r?\n/', $data, -1, PREG_SPLIT_NO_EMPTY);
+
+        for ($i = 0; $i < count($data); $i++) {
+            if (preg_match('/^"([a-z]+)"( "(.*)")?$/i', $data[$i], $matches)) {
+                switch (strtolower($matches[1])) {
+                    case 'implementation':
+                        $this->_capability['implementation'] = $matches[3];
+                        break;
+
+                    case 'sasl':
+                        $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]);
+                        break;
+
+                    case 'sieve':
+                        $this->_capability['extensions'] = preg_split('/\s+/', $matches[3]);
+                        break;
+
+                    case 'starttls':
+                        $this->_capability['starttls'] = true;
+                        break;
+                }
+            }
+        }
+    }
+
+    /**
+    * Sends a command to the server
+    *
+    * @access private
+    * @param string $cmd The command to send
+    */
+    function _sendCmd($cmd)
+    {
+        $status = $this->_sock->getStatus();
+        if (PEAR::isError($status) || $status['eof']) {
+            return new PEAR_Error( 'Failed to write to socket: (connection lost!) ' );
+        }
+        if ( PEAR::isError( $error = $this->_sock->write( $cmd . "\r\n" ) ) ) {
+            return new PEAR_Error( 'Failed to write to socket: ' . $error->getMessage() );
+        }
+
+        if( $this->_debug ){
+            // C: means this data was sent by  the client (this class)
+            echo "C:$cmd\n";
+        }
+        return true;
+    }
+
+    /**
+    * Sends a string response to the server
+    *
+    * @access private
+    * @param string $cmd The command to send
+    */
+    function _sendStringResponse($str)
+    {
+        $response='{' .  $this->_getLineLength($str) . "+}\r\n" . $str  ;
+        return $this->_sendCmd($response);
+    }
+
+    function _recvLn()
+    {
+        $lastline='';
+        if (PEAR::isError( $lastline = $this->_sock->gets( 8192 ) ) ) {
+            return new PEAR_Error( 'Failed to write to socket: ' . $lastline->getMessage() );
+        }
+        $lastline=rtrim($lastline);
+        if($this->_debug){
+            // S: means this data was sent by  the IMAP Server
+            echo "S:$lastline\n" ;
+        }
+
+        if( $lastline === '' ) {
+            return new PEAR_Error( 'Failed to receive from the socket' );
+        }
+
+        return $lastline;
+    }
+
+    /**
+    * Send a command and retrieves a response from the server.
+    *
+    *
+    * @access private
+    * @param string $cmd The command to send
+    * @return mixed Reponse string if an OK response, PEAR_Error if a NO response
+    */
+    function _doCmd($cmd = '' )
+    {
+        $referralCount=0;
+        while($referralCount < $this->_maxReferralCount ){
+
+            if($cmd != '' ){
+                if(PEAR::isError($error = $this->_sendCmd($cmd) )) {
+                    return $error;
+                }
+            }
+            $response = '';
+
+            while (true) {
+                    if(PEAR::isError( $line=$this->_recvLn() )){
+                        return $line;
+                    }
+                    if ('ok' === strtolower(substr($line, 0, 2))) {
+                        $response .= $line;
+                        return rtrim($response);
+
+                    } elseif ('no' === strtolower(substr($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 ));
+                            if($this->_debug){
+                                echo "S:$line\n";
+                            }
+                        }
+                        $msg=trim($response . substr($line, 2));
+                        $code=3;
+                        return $this->_raiseError($msg,$code);
+                    } elseif ('bye' === strtolower(substr($line, 0, 3))) {
+
+                        if(PEAR::isError($error = $this->disconnect(false) ) ){
+                            $msg="Can't handle bye, The error was= " . $error->getMessage() ;
+                            $code=4;
+                            return $this->_raiseError($msg,$code);
+                        }
+                        //if (preg_match('/^bye \(referral "([^"]+)/i', $line, $matches)) {
+                        if (preg_match('/^bye \(referral "(sieve:\/\/)?([^"]+)/i', $line, $matches)) {
+                            // Check for referral, then follow it.  Otherwise, carp an error.
+                            // Replace the old host with the referral host preserving any protocol prefix
+                            $this->_data['host'] = preg_replace('/\w+(?!(\w|\:\/\/)).*/',$matches[2],$this->_data['host']);
+                           if (PEAR::isError($error = $this->_handleConnectAndLogin() ) ){
+                                $msg="Can't follow referral to " . $this->_data['host'] . ", The error was= " . $error->getMessage() ;
+                                $code=5;
+                                return $this->_raiseError($msg,$code);
+                            }
+                            break;
+                            // Retry the command
+                            if(PEAR::isError($error = $this->_sendCmd($cmd) )) {
+                                return $error;
+                            }
+                            continue;
+                        }
+                        $msg=trim($response . $line);
+                        $code=6;
+                        return $this->_raiseError($msg,$code);
+                    } elseif (preg_match('/^{([0-9]+)\+?}/i', $line, $matches)) {
+                        // Matches String Responses.
+                        //$line = str_replace("\r\n", ' ', $this->_sock->read($matches[1] + 2 ));
+                        $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);
+                        }
+                        if($this->_debug){
+                            echo "S:$line\n";
+                        }
+                        if($this->_state != NET_SIEVE_STATE_AUTHORISATION) {
+                            // receive the pending OK only if we aren't authenticating
+                            // since string responses during authentication don't need an
+                            // OK.
+                            $this->_recvLn();
+                        }
+                        return $line;
+                    }
+                    $response .= $line . "\r\n";
+                    $referralCount++;
+                }
+        }
+        $msg="Max referral count reached ($referralCount times) Cyrus murder loop error?";
+        $code=7;
+        return $this->_raiseError($msg,$code);
+    }
+
+    /**
+    * Sets the debug state
+    *
+    * @param boolean $debug
+    * @return void
+    */
+    function setDebug($debug = true)
+    {
+        $this->_debug = $debug;
+    }
+
+    /**
+    * Disconnect from the Sieve server
+    *
+    * @param  string $scriptname The name of the script to be set as active
+    * @return mixed              true on success, PEAR_Error on failure
+    */
+    function disconnect($sendLogoutCMD=true)
+    {
+        return $this->_cmdLogout($sendLogoutCMD);
+    }
+
+    /**
+     * Returns the name of the best authentication method that the server
+     * has advertised.
+     *
+     * @param string if !=null,authenticate with this method ($userMethod).
+     *
+     * @return mixed    Returns a string containing the name of the best
+     *                  supported authentication method or a PEAR_Error object
+     *                  if a failure condition is encountered.
+     * @access private
+     * @since  1.0
+     */
+    function _getBestAuthMethod($userMethod = null)
+    {
+       if( isset($this->_capability['sasl']) ){
+           $serverMethods=$this->_capability['sasl'];
+       }else{
+           // if the server don't send an sasl capability fallback to login auth
+           //return 'LOGIN';
+           return new PEAR_Error("This server don't support any Auth methods SASL problem?");
+       }
+
+        if($userMethod != null ){
+            $methods = array();
+            $methods[] = $userMethod;
+        }else{
+
+            $methods = $this->supportedAuthMethods;
+        }
+        if( ($methods != null) && ($serverMethods != null)){
+            foreach ( $methods as $method ) {
+                if ( in_array( $method , $serverMethods ) ) {
+                    return $method;
+                }
+            }
+            $serverMethods=implode(',' , $serverMethods );
+            $myMethods=implode(',' ,$this->supportedAuthMethods);
+            return new PEAR_Error("$method NOT supported authentication method!. This server " .
+                "supports these methods= $serverMethods, but I support $myMethods");
+        }else{
+            return new PEAR_Error("This server don't support any Auth methods");
+        }
+    }
+
+    /**
+    * Return the list of extensions the server supports
+    *
+    * @return mixed              array  on success, PEAR_Error on failure
+    */
+    function getExtensions()
+    {
+        if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
+            $msg='Not currently connected';
+            $code=7;
+            return $this->_raiseError($msg,$code);
+        }
+
+        return $this->_capability['extensions'];
+    }
+
+    /**
+    * Return true if tyhe server has that extension
+    *
+    * @param string  the extension to compare
+    * @return mixed              array  on success, PEAR_Error on failure
+    */
+    function hasExtension($extension)
+    {
+        if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
+            $msg='Not currently connected';
+            $code=7;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if(is_array($this->_capability['extensions'] ) ){
+            foreach( $this->_capability['extensions'] as $ext){
+                if( trim( strtolower( $ext ) ) === trim( strtolower( $extension ) ) )
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+    * Return the list of auth methods the server supports
+    *
+    * @return mixed              array  on success, PEAR_Error on failure
+    */
+    function getAuthMechs()
+    {
+        if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
+            $msg='Not currently connected';
+            $code=7;
+            return $this->_raiseError($msg,$code);
+        }
+        if(!isset($this->_capability['sasl']) ){
+            $this->_capability['sasl']=array();
+        }
+        return $this->_capability['sasl'];
+    }
+
+    /**
+    * Return true if the server has that extension
+    *
+    * @param string  the extension to compare
+    * @return mixed              array  on success, PEAR_Error on failure
+    */
+    function hasAuthMech($method)
+    {
+        if (NET_SIEVE_STATE_DISCONNECTED === $this->_state) {
+            $msg='Not currently connected';
+            $code=7;
+            return $this->_raiseError($msg,$code);
+            //return PEAR::raiseError('Not currently connected');
+        }
+
+        if(is_array($this->_capability['sasl'] ) ){
+            foreach( $this->_capability['sasl'] as $ext){
+                if( trim( strtolower( $ext ) ) === trim( strtolower( $method ) ) )
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+    * Return true if the TLS negotiation was successful
+    *
+    * @access private
+    * @return mixed              true on success, PEAR_Error on failure
+    */
+    function _startTLS()
+    {
+        if (PEAR::isError($res = $this->_doCmd("STARTTLS"))) {
+            return $res;
+        }
+
+        if(stream_socket_enable_crypto($this->_sock->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT) == false) {
+            $msg='Failed to establish TLS connection';
+            $code=2;
+            return $this->_raiseError($msg,$code);
+        }
+
+        if($this->_debug === true) {
+            echo "STARTTLS Negotiation Successful\n";
+        }
+
+        // The server should be sending a CAPABILITY response after
+        // negotiating TLS. Read it, and ignore if it doesn't.
+        $this->_doCmd();
+
+        // RFC says we need to query the server capabilities again now that
+        // we are under encryption
+        if(PEAR::isError($res = $this->_cmdCapability() )) {
+            $msg='Failed to connect, server said: ' . $res->getMessage();
+            $code=2;
+            return $this->_raiseError($msg,$code);
+        }
+
+        return true;
+    }
+
+    function _getLineLength($string) {
+        if (extension_loaded('mbstring') || @dl(PHP_SHLIB_PREFIX.'mbstring.'.PHP_SHLIB_SUFFIX)) {
+          return mb_strlen($string,'latin1');
+        } else {
+          return strlen($string);
+        }
+    }
+}
+?>
diff --git a/plugins/managesieve/lib/rcube_sieve.php b/plugins/managesieve/lib/rcube_sieve.php
new file mode 100644 (file)
index 0000000..3bb150e
--- /dev/null
@@ -0,0 +1,727 @@
+<?php
+
+/*
+  Classes for managesieve operations (using PEAR::Net_Sieve)
+
+  Author: Aleksander Machniak <alec@alec.pl>
+
+  $Id$
+
+*/
+
+//  Sieve Language Basics: http://www.ietf.org/rfc/rfc5228.txt
+
+define('SIEVE_ERROR_CONNECTION', 1);
+define('SIEVE_ERROR_LOGIN', 2);
+define('SIEVE_ERROR_NOT_EXISTS', 3);   // script not exists
+define('SIEVE_ERROR_INSTALL', 4);      // script installation
+define('SIEVE_ERROR_ACTIVATE', 5);     // script activation
+define('SIEVE_ERROR_OTHER', 255);      // other/unknown error
+
+
+class rcube_sieve
+{
+  var $sieve;                          // Net_Sieve object
+  var $error = false;                  // error flag 
+  var $list = array();                         // scripts list 
+
+  public $script;                      // rcube_sieve_script object
+  private $disabled;                   // array of disabled extensions
+
+  /**
+    * Object constructor
+    *
+    * @param  string  Username (to managesieve login)
+    * @param  string  Password (to managesieve login)
+    * @param  string  Managesieve server hostname/address
+    * @param  string  Managesieve server port number
+    * @param  string  Enable/disable TLS use
+    * @param  array   Disabled extensions
+    */
+  public function __construct($username, $password='', $host='localhost', $port=2000, $usetls=true, $disabled=array())
+    {
+      $this->sieve = new Net_Sieve();
+      
+//      $this->sieve->setDebug();
+      if (PEAR::isError($this->sieve->connect($host, $port, NULL, $usetls)))
+        return $this->_set_error(SIEVE_ERROR_CONNECTION);
+
+      if (PEAR::isError($this->sieve->login($username, $password)))
+        return $this->_set_error(SIEVE_ERROR_LOGIN);
+
+      $this->disabled = $disabled;
+      $this->_get_script();
+    }
+
+  /**
+    * Getter for error code
+    */
+  public function error()
+    {
+      return $this->error ? $this->error : false;
+    }
+                           
+  public function save()
+    {
+      $script = $this->script->as_text();
+
+      if (!$script)
+       $script = '/* empty script */';
+
+      if (PEAR::isError($this->sieve->installScript('roundcube', $script)))
+       return $this->_set_error(SIEVE_ERROR_INSTALL);
+
+      if (PEAR::isError($this->sieve->setActive('roundcube')))
+       return $this->_set_error(SIEVE_ERROR_ACTIVATE);
+
+      return true;
+    }
+
+  public function get_extensions()
+    {
+      if ($this->sieve) {
+       $ext = $this->sieve->getExtensions();
+
+       if ($this->script) {
+         $supported = $this->script->get_extensions();
+         foreach ($ext as $idx => $ext_name)
+           if (!in_array($ext_name, $supported))
+             unset($ext[$idx]);
+       }
+
+        return array_values($ext);
+      }
+    }
+
+  private function _get_script()
+    {
+      if (!$this->sieve)
+        return false;
+    
+      $this->list = $this->sieve->listScripts();
+
+      if (PEAR::isError($this->list))
+       return $this->_set_error(SIEVE_ERROR_OTHER);
+    
+      if (in_array('roundcube', $this->list))
+        {
+          $script = $this->sieve->getScript('roundcube');
+    
+          if (PEAR::isError($script))
+           return $this->_set_error(SIEVE_ERROR_OTHER);
+       }
+      // import scripts from squirrelmail
+      elseif (in_array('phpscript', $this->list))
+        {
+          $script = $this->sieve->getScript('phpscript');
+
+          $script = $this->_convert_from_squirrel_rules($script);
+
+          $this->script = new rcube_sieve_script($script);
+       
+          $this->save();
+
+          $script = $this->sieve->getScript('roundcube');
+
+          if (PEAR::isError($script))
+            return $this->_set_error(SIEVE_ERROR_OTHER);
+        }
+      else
+        {
+         $this->_set_error(SIEVE_ERROR_NOT_EXISTS);
+          $script = '';
+       }
+
+      $this->script = new rcube_sieve_script($script, $this->disabled);
+    }
+    
+  private function _convert_from_squirrel_rules($script)
+    {
+      $i = 0;
+      $name = array();
+      // tokenize rules
+      if ($tokens = preg_split('/(#START_SIEVE_RULE.*END_SIEVE_RULE)\n/', $script, -1, PREG_SPLIT_DELIM_CAPTURE))
+        foreach($tokens as $token)
+          {
+            if (preg_match('/^#START_SIEVE_RULE.*/', $token, $matches))
+              {
+               $name[$i] = "unnamed rule ".($i+1);
+                $content .= "# rule:[".$name[$i]."]\n";
+              }
+            elseif (isset($name[$i]))
+              {
+               $content .= "if ".$token."\n";
+               $i++;
+              }
+          }
+
+      return $content;
+    }
+
+
+  private function _set_error($error)
+    {
+      $this->error = $error;
+      return false;
+    }    
+}
+
+class rcube_sieve_script
+{
+  var $content = array();      // script rules array   
+
+  private $supported = array(  // extensions supported by class
+    'fileinto',
+    'reject',
+    'ereject',
+    'vacation',        // RFC5230
+    // TODO: (most wanted first) body, imapflags, notify, regex
+    );
+  
+  /**
+    * Object constructor
+    *
+    * @param  string  Script's text content
+    * @param  array   Disabled extensions
+    */
+  public function __construct($script, $disabled)
+    {
+      if (!empty($disabled))
+        foreach ($disabled as $ext)
+          if (($idx = array_search($ext, $this->supported)) !== false)
+           unset($this->supported[$idx]);
+
+      $this->content = $this->_parse_text($script);
+    }
+
+  /**
+    * Adds script contents as text to the script array (at the end)
+    *
+    * @param   string  Text script contents
+    */
+  public function add_text($script)
+    {
+      $content = $this->_parse_text($script);
+      $result = false;
+      
+      // check existsing script rules names
+      foreach ($this->content as $idx => $elem)
+        $names[$elem['name']] = $idx;
+      
+      foreach ($content as $elem)
+        if (!isset($names[$elem['name']]))
+         {
+            array_push($this->content, $elem);
+           $result = true;
+         }
+
+      return $result;
+    }
+
+  /**
+    * Adds rule to the script (at the end)
+    *
+    * @param   string  Rule name
+    * @param   array   Rule content (as array)
+    */
+  public function add_rule($content)
+    {
+      // TODO: check this->supported
+      array_push($this->content, $content);
+      return sizeof($this->content)-1;
+    }
+
+  public function delete_rule($index)
+    {
+      if(isset($this->content[$index]))
+        {
+          unset($this->content[$index]);
+         return true;
+       }
+      return false;
+    }
+
+  public function size()
+    {
+      return sizeof($this->content);
+    }
+
+  public function update_rule($index, $content)
+    {
+      // TODO: check this->supported
+      if ($this->content[$index])
+        {
+         $this->content[$index] = $content;
+         return $index;
+       }
+      return false;
+    }
+
+  /**
+    * Returns script as text
+    */
+  public function as_text()
+    {
+      $script = '';
+      $exts = array();
+      
+      // rules
+      foreach ($this->content as $idx => $rule)
+        {
+         $extension = '';
+         $tests = array();
+         $i = 0;
+         
+         // header
+         $script .= '# rule:[' . $rule['name'] . "]\n";
+  
+         // constraints expressions
+         foreach ($rule['tests'] as $test)
+           {
+             $tests[$i] = '';
+             switch ($test['test'])
+               {
+                 case 'size':
+                   $tests[$i] .= ($test['not'] ? 'not ' : '');
+                   $tests[$i] .= 'size :' . ($test['type']=='under' ? 'under ' : 'over ') . $test['arg'];
+                 break;
+                 case 'true':
+                   $tests[$i] .= ($test['not'] ? 'not true' : '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']) . '"';
+                 break;    
+                 case 'header':
+                   $tests[$i] .= ($test['not'] ? 'not ' : '');
+                   $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']) . '"';
+                 break;
+               }
+             $i++;
+           }
+  
+         $script .= ($idx>0 ? 'els' : '').($rule['join'] ? 'if allof (' : 'if anyof (');
+         if (sizeof($tests) > 1)
+           $script .= implode(",\n\t", $tests);
+         elseif (sizeof($tests))
+           $script .= $tests[0];
+         else
+           $script .= 'true';
+         $script .= ")\n{\n";
+  
+         // action(s)
+         foreach ($rule['actions'] as $action)
+           switch ($action['type'])
+           {
+             case 'fileinto':
+               $extension = 'fileinto';
+               $script .= "\tfileinto \"" . $this->_escape_string($action['target']) . "\";\n";
+             break;
+             case 'redirect':
+               $script .= "\tredirect \"" . $this->_escape_string($action['target']) . "\";\n";
+             break;
+             case 'reject':
+             case 'ereject':
+               $extension = $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";
+             break;
+             case 'keep':
+             case 'discard':
+             case 'stop':
+               $script .= "\t" . $action['type'] .";\n";
+             break;
+             case 'vacation':
+                $extension = 'vacation';
+                $script .= "\tvacation";
+               if ($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'])
+                 $script .= " :mime";
+               if (strpos($action['reason'], "\n")!==false)
+                 $script .= " text:\n" . $action['reason'] . "\n.\n;\n";
+               else
+                 $script .= " \"" . $this->_escape_string($action['reason']) . "\";\n";
+             break;
+           }
+         
+         $script .= "}\n";
+       
+         if ($extension && !isset($exts[$extension]))
+           $exts[$extension] = $extension;
+       }
+      
+      // requires
+      if (sizeof($exts))
+        $script = 'require ["' . implode('","', $exts) . "\"];\n" . $script;
+
+      return $script;
+    }
+
+  /**
+    * Returns script object
+    *
+    */
+  public function as_array()
+    {
+      return $this->content;
+    }
+
+  /**
+    * Returns array of supported extensions
+    *
+    */
+  public function get_extensions()
+    {
+      return array_values($this->supported);
+    }
+
+  /**
+    * Converts text script to rules array
+    *
+    * @param   string  Text script
+    */
+  private function _parse_text($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)
+         {
+           if (preg_match('/^# rule:\[(.*)\]/', $token, $matches))
+             {
+               $content[$i]['name'] = $matches[1];
+             }
+           elseif (isset($content[$i]['name']) && sizeof($content[$i]) == 1)
+             {
+               if ($rule = $this->_tokenize_rule($token))
+                 {
+                   $content[$i] = array_merge($content[$i], $rule);
+                   $i++;
+                 }
+               else // unknown rule format
+                   unset($content[$i]);
+             }
+         }
+
+      return $content;
+    }
+
+  /**
+    * Convert text script fragment to rule object
+    *
+    * @param   string  Text rule
+    */
+  private function _tokenize_rule($content)
+    {
+      $result = NULL;
+    
+      if (preg_match('/^(if|elsif|else)\s+((allof|anyof|exists|header|not|size)\s+(.*))\s+\{(.*)\}$/sm', trim($content), $matches))
+        {
+         list($tests, $join) = $this->_parse_tests(trim($matches[2]));
+         $actions = $this->_parse_actions(trim($matches[5]));
+
+         if ($tests && $actions)
+           $result = array(
+                   'tests' => $tests,
+                   'actions' => $actions,
+                   'join' => $join,
+           );
+       }
+    
+      return $result;
+    }    
+
+  /**
+    * Parse body of actions section
+    *
+    * @param   string  Text body
+    * @return  array   Array of parsed action type/target pairs
+    */
+  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+(.*?[^\\\]);';
+
+      $pattern = '/(' . implode('$)|(', $patterns) . '$)/ms';
+
+      // parse actions body
+      if (preg_match_all($pattern, $content, $mm, PREG_SET_ORDER))
+      {
+       foreach ($mm as $m)
+       {
+         $content = trim($m[0]);
+         
+         if(preg_match('/^(discard|keep|stop)/', $content, $matches))
+           {
+             $result[] = array('type' => $matches[1]);
+           }
+          elseif(preg_match('/^fileinto/', $content))
+           {
+             $result[] = array('type' => 'fileinto', 'target' => $this->_parse_string($m[sizeof($m)-1])); 
+           }
+          elseif(preg_match('/^redirect/', $content))
+           {
+             $result[] = array('type' => 'redirect', 'target' => $this->_parse_string($m[sizeof($m)-1])); 
+           }
+         elseif(preg_match('/^(reject|ereject)\s+(.*);$/sm', $content, $matches))
+           {
+             $result[] = array('type' => $matches[1], 'target' => $this->_parse_string($matches[2])); 
+           }
+          elseif(preg_match('/^vacation\s+(.*);$/sm', $content, $matches))
+            {
+             $vacation = array('type' => 'vacation');
+
+             if (preg_match('/:(days)\s+([0-9]+)/', $content, $vm)) {
+               $vacation['days'] = $vm[2];
+               $content = preg_replace('/:(days)\s+([0-9]+)/', '', $content); 
+             }
+             if (preg_match('/:(subject)\s+(".*?[^\\\]")/', $content, $vm)) {
+               $vacation['subject'] = $vm[2];
+               $content = preg_replace('/:(subject)\s+(".*?[^\\\]")/', '', $content); 
+             }
+             if (preg_match('/:(addresses)\s+\[(.*?[^\\\])\]/', $content, $vm)) {
+               $vacation['addresses'] = $this->_parse_list($vm[2]);
+               $content = preg_replace('/:(addresses)\s+\[(.*?[^\\\])\]/', '', $content); 
+             }
+             if (preg_match('/:(handle)\s+(".*?[^\\\]")/', $content, $vm)) {
+               $vacation['handle'] = $vm[2];
+               $content = preg_replace('/:(handle)\s+(".*?[^\\\]")/', '', $content); 
+             }
+             if (preg_match('/:(from)\s+(".*?[^\\\]")/', $content, $vm)) {
+               $vacation['from'] = $vm[2];
+               $content = preg_replace('/:(from)\s+(".*?[^\\\]")/', '', $content); 
+             }
+             $content = preg_replace('/^vacation/', '', $content);          
+             $content = preg_replace('/;$/', '', $content);
+             $content = trim($content);
+             if (preg_match('/^:(mime)/', $content, $vm)) {
+               $vacation['mime'] = true;
+               $content = preg_replace('/^:mime/', '', $content); 
+             }
+
+             $vacation['reason'] = $this->_parse_string($content);
+
+              $result[] = $vacation;
+            }
+        }
+      }
+
+      return $result;
+    }    
+    
+   /**
+    * Parse test/conditions section
+    *
+    * @param   string  Text 
+    */
+
+  private function _parse_tests($content)
+    {
+      $result = NULL;
+
+      // lists
+      if (preg_match('/^(allof|anyof)\s+\((.*)\)$/sm', $content, $matches))
+       {
+         $content = $matches[2];
+         $join = $matches[1]=='allof' ? true : false;
+       }
+      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+\[(.*?[^\\\]")\]';
+      
+      // 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
+                 );
+               }
+             elseif (preg_match('/^(not\s+)?header/', $match[0]))
+               {
+                 $result[] = array(
+                   'test'      => 'header',
+                   'not'       => $match[$size-5] ? true : false,
+                   'type'      => $match[$size-3], // is/contains/matches
+                   'arg1'      => $this->_parse_list($match[$size-2]), // header(s)
+                   'arg2'      => $this->_parse_list($match[$size-1]), // string(s)
+                 );  
+               }
+             elseif (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)
+                 );
+               }
+             elseif (preg_match('/^(not\s+)?true/', $match[0]))
+               {
+                 $result[] = array(
+                   'test'      => 'true',
+                   'not'       => $match[$size-2] ? true : false,
+                 );
+               }
+           }
+       }
+
+      return array($result, $join);
+    }    
+
+   /**
+    * Parse string value
+    *
+    * @param   string  Text 
+    */
+  private function _parse_string($content)
+    {
+      $text = '';
+      $content = trim($content);
+
+      if (preg_match('/^text:(.*)\.$/sm', $content, $matches))
+        $text = trim($matches[1]);
+      elseif (preg_match('/^"(.*)"$/', $content, $matches))
+        $text = str_replace('\"', '"', $matches[1]);
+
+      return $text;
+    }    
+
+   /**
+    * Escape special chars in string value
+    *
+    * @param   string  Text 
+    */
+  private function _escape_string($content)
+    {
+      $replace['/"/'] = '\\"';
+      
+      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]);
+        
+         return $content;
+       }
+      else
+        return preg_replace(array_keys($replace), array_values($replace), $content);
+    }
+
+   /**
+    * Parse string or list of strings to string or array of strings
+    *
+    * @param   string  Text 
+    */
+  private function _parse_list($content)
+    {
+      $result = array();
+      
+      for ($x=0, $len=strlen($content); $x<$len; $x++)
+        {
+         switch ($content[$x])
+           {
+             case '\\':
+               $str .= $content[++$x];
+              break;
+             case '"':
+               if (isset($str))
+                 {
+                   $result[] = $str;
+                   unset($str);
+                 }
+               else
+                 $str = '';
+             break;
+             default:
+               if(isset($str))
+                 $str .= $content[$x];
+             break;
+           }
+       }
+      
+      if (sizeof($result)>1)
+        return $result;
+      elseif (sizeof($result) == 1)
+       return $result[0];
+      else
+        return NULL;
+    }    
+
+   /**
+    * 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) . '"]';
+    }
+}
+
+?>
diff --git a/plugins/managesieve/localization/bg_BG.inc b/plugins/managesieve/localization/bg_BG.inc
new file mode 100644 (file)
index 0000000..96ce63b
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+
+$labels = array();
+$labels['filters'] = 'Филтри';
+$labels['managefilters'] = 'Управление на филтри за входяща поща';
+$labels['filtername'] = 'Име на филтър';
+$labels['newfilter'] = 'Нов филтър';
+$labels['filteradd'] = 'Добавяне на филтър';
+$labels['filterdel'] = 'Изтриване на филтър';
+$labels['moveup'] = 'Преместване нагоре';
+$labels['movedown'] = 'Преместване надолу';
+$labels['filterallof'] = 'съвпадение на всички следващи правила';
+$labels['filteranyof'] = 'съвпадение на някое от следните правила';
+$labels['filterany'] = 'всички съобщения';
+$labels['filtercontains'] = 'съдържа';
+$labels['filternotcontains'] = 'не съдържа';
+$labels['filteris'] = 'е равно на';
+$labels['filterisnot'] = 'не е равно на';
+$labels['filterexists'] = 'съществува';
+$labels['filternotexists'] = 'не съществува';
+$labels['filterunder'] = 'под';
+$labels['filterover'] = 'над';
+$labels['addrule'] = 'Добавяне на правило';
+$labels['delrule'] = 'Изтриване на правило';
+$labels['messagemoveto'] = 'Преместване на съобщението в';
+$labels['messageredirect'] = 'Пренасочване на съобщението до';
+$labels['messagereply'] = 'Отговор със съобщение';
+$labels['messagedelete'] = 'Изтриване на съобщение';
+$labels['messagediscard'] = 'Отхвърляне със съобщение';
+$labels['messagesrules'] = 'За входящата поща:';
+$labels['messagesactions'] = '...изпълнение на следните действия';
+$labels['add'] = 'Добавяне';
+$labels['del'] = 'Изтриване';
+$labels['sender'] = 'Подател';
+$labels['recipient'] = 'Получател';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Неизвестна грешка на сървъра';
+$messages['filterconnerror'] = 'Невъзможност за свързване с managesieve сървъра ';
+$messages['filterdeleteerror'] = 'Невъзможност за изтриване на филтър. Сървър грешка';
+$messages['filterdeleted'] = 'Филтърът е изтрит успешно';
+$messages['filterconfirmdelete'] = 'Наистина ли искате да изтриете избрания филтър?';
+$messages['filtersaved'] = 'Филтърът е записан успешно';
+$messages['filtersaveerror'] = 'Филтърът не може да бъде записан. Сървър грешка.';
+$messages['ruledeleteconfirm'] = 'Сигурни ли сте, че искате да изтриете избраното правило?';
+$messages['actiondeleteconfirm'] = 'Сигурни ли сте, че искате да изтриете избраното действие?';
+$messages['forbiddenchars'] = 'Забранени символи в полето';
+$messages['cannotbeempty'] = 'Полето не може да бъде празно';
+
+?>
diff --git a/plugins/managesieve/localization/de_CH.inc b/plugins/managesieve/localization/de_CH.inc
new file mode 100644 (file)
index 0000000..c4d4d49
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+$labels['filters'] = 'Filter';
+$labels['managefilters'] = 'Verwalte eingehende Nachrichtenfilter';
+$labels['filtername'] = 'Filtername';
+$labels['newfilter'] = 'Neuer Filter';
+$labels['filteradd'] = 'Filter hinzufügen';
+$labels['filterdel'] = 'Filter löschen';
+$labels['moveup'] = 'Nach oben';
+$labels['movedown'] = 'Nach unten';
+$labels['filterallof'] = 'UND (alle Regeln müssen zutreffen)';
+$labels['filteranyof'] = 'ODER (eine der Regeln muss zutreffen';
+$labels['filterany'] = 'Für alle Nachrichten';
+$labels['filtercontains'] = 'enthält';
+$labels['filternotcontains'] = 'enthält nicht';
+$labels['filteris'] = 'ist gleich';
+$labels['filterisnot'] = 'ist ungleich';
+$labels['filterexists'] = 'ist vorhanden';
+$labels['filternotexists'] = 'nicht vorhanden';
+$labels['filterunder'] = 'unter';
+$labels['filterover'] = 'über';
+$labels['addrule'] = 'Regel hinzufügen';
+$labels['delrule'] = 'Regel löschen';
+$labels['messagemoveto'] = 'Verschiebe Nachricht nach';
+$labels['messageredirect'] = 'Leite Nachricht um nach';
+$labels['messagereply'] = 'Antworte mit Nachricht';
+$labels['messagedelete'] = 'Nachricht löschen';
+$labels['messagediscard'] = 'Discard with message';
+$labels['messagesrules'] = 'Für eingehende Nachrichten:';
+$labels['messagesactions'] = 'Führe folgende Aktionen aus:';
+$labels['add'] = 'Hinzufügen';
+$labels['del'] = 'Löschen';
+$labels['sender'] = 'Absender';
+$labels['recipient'] = 'Empfänger';
+$labels['vacationaddresses'] = 'Zusätzliche Liste von Empfängern (Komma getrennt):';
+$labels['vacationdays'] = 'Antwort wird erneut gesendet nach (in Tagen):';
+$labels['vacationreason'] = 'Inhalt der Nachricht (Abwesenheitsgrund):';
+$labels['rulestop'] = 'Regelauswertung anhalten';
+
+$messages['filterunknownerror'] = 'Unbekannter Serverfehler';
+$messages['filterconnerror'] = 'Kann nicht zum Sieve-Server verbinden';
+$messages['filterdeleteerror'] = 'Fehler beim des löschen  Filters. Serverfehler';
+$messages['filterdeleted'] = 'Filter erfolgreich gelöscht';
+$messages['filterconfirmdelete'] = 'Möchten Sie den Filter löschen ?';
+$messages['filtersaved'] = 'Filter gespeichert';
+$messages['filtersaveerror'] = 'Serverfehler, konnte den Filter nicht speichern.';
+$messages['ruledeleteconfirm'] = 'Sicher, dass Sie die Regel löschen wollen?';
+$messages['actiondeleteconfirm'] = 'Sicher, dass Sie die ausgewaehlte Aktion löschen wollen?';
+$messages['forbiddenchars'] = 'Unerlaubte Zeichen im Feld';
+$messages['cannotbeempty'] = 'Feld darf nicht leer sein';
+
+?>
diff --git a/plugins/managesieve/localization/de_DE.inc b/plugins/managesieve/localization/de_DE.inc
new file mode 100644 (file)
index 0000000..c3a2feb
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+$labels['filters'] = 'Filter';
+$labels['managefilters'] = 'Verwalte eingehende Nachrichtenfilter';
+$labels['filtername'] = 'Filtername';
+$labels['newfilter'] = 'Neuer Filter';
+$labels['filteradd'] = 'Filter hinzufügen';
+$labels['filterdel'] = 'Filter löschen';
+$labels['moveup'] = 'Nach oben';
+$labels['movedown'] = 'Nach unten';
+$labels['filterallof'] = 'trifft auf alle folgenden Regeln zu';
+$labels['filteranyof'] = 'trifft auf eine der folgenden Regeln zu';
+$labels['filterany'] = 'alle Nachrichten';
+$labels['filtercontains'] = 'enthält';
+$labels['filternotcontains'] = 'enthält nicht';
+$labels['filteris'] = 'ist gleich';
+$labels['filterisnot'] = 'ist ungleich';
+$labels['filterexists'] = 'vorhanden';
+$labels['filternotexists'] = 'nicht vorhanden';
+$labels['filterunder'] = 'unter';
+$labels['filterover'] = 'über';
+$labels['addrule'] = 'Regel hinzufügen';
+$labels['delrule'] = 'Regel löschen';
+$labels['messagemoveto'] = 'Verschiebe Nachricht nach';
+$labels['messageredirect'] = 'Leite Nachricht um nach';
+$labels['messagereply'] = 'Antworte mit Nachricht';
+$labels['messagedelete'] = 'Nachricht löschen';
+$labels['messagediscard'] = 'Discard with message';
+$labels['messagesrules'] = 'Für eingehende Nachrichten:';
+$labels['messagesactions'] = '...führe folgende Aktionen aus:';
+$labels['add'] = 'Hinzufügen';
+$labels['del'] = 'Löschen';
+$labels['sender'] = 'Absender';
+$labels['recipient'] = 'Empfänger';
+$labels['vacationaddresses'] = 'Zusätzliche Liste von eMail-Empfängern (Komma getrennt):';
+$labels['vacationdays'] = 'Wie oft sollen Nachrichten gesendet werden (in Tagen):';
+$labels['vacationreason'] = 'Inhalt der Nachricht (Abwesenheitsgrund):';
+$labels['rulestop'] = 'Regelauswertung anhalten';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Unbekannter Serverfehler';
+$messages['filterconnerror'] = 'Kann nicht zum Sieve-Server verbinden';
+$messages['filterdeleteerror'] = 'Fehler beim des löschen  Filters. Serverfehler';
+$messages['filterdeleted'] = 'Filter erfolgreich gelöscht';
+$messages['filterconfirmdelete'] = 'Möchten Sie den Filter löschen ?';
+$messages['filtersaved'] = 'Filter gespeichert';
+$messages['filtersaveerror'] = 'Serverfehler, konnte den Filter nicht speichern.';
+$messages['ruledeleteconfirm'] = 'Sicher, dass Sie die Regel löschen wollen?';
+$messages['actiondeleteconfirm'] = 'Sicher, dass Sie die ausgewaehlte Aktion löschen wollen?';
+$messages['forbiddenchars'] = 'Unerlaubte Zeichen im Feld';
+$messages['cannotbeempty'] = 'Feld darf nicht leer sein';
+
+?>
diff --git a/plugins/managesieve/localization/en_US.inc b/plugins/managesieve/localization/en_US.inc
new file mode 100644 (file)
index 0000000..c671b83
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+$labels['filters'] = 'Filters';
+$labels['managefilters'] = 'Manage incoming mail filters';
+$labels['filtername'] = 'Filter name';
+$labels['newfilter'] = 'New filter';
+$labels['filteradd'] = 'Add filter';
+$labels['filterdel'] = 'Delete filter';
+$labels['moveup'] = 'Move up';
+$labels['movedown'] = 'Move down';
+$labels['filterallof'] = 'matching all of the following rules';
+$labels['filteranyof'] = 'matching any of the following rules';
+$labels['filterany'] = 'all messages';
+$labels['filtercontains'] = 'contains';
+$labels['filternotcontains'] = 'not contains';
+$labels['filteris'] = 'is equal to';
+$labels['filterisnot'] = 'is not equal to';
+$labels['filterexists'] = 'exists';
+$labels['filternotexists'] = 'not exists';
+$labels['filterunder'] = 'under';
+$labels['filterover'] = 'over';
+$labels['addrule'] = 'Add rule';
+$labels['delrule'] = 'Delete rule';
+$labels['messagemoveto'] = 'Move message to';
+$labels['messageredirect'] = 'Redirect message to';
+$labels['messagereply'] = 'Reply with message';
+$labels['messagedelete'] = 'Delete message';
+$labels['messagediscard'] = 'Discard with message';
+$labels['messagesrules'] = 'For incoming mail:';
+$labels['messagesactions'] = '...execute the following actions:';
+$labels['add'] = 'Add';
+$labels['del'] = 'Delete';
+$labels['sender'] = 'Sender';
+$labels['recipient'] = 'Recipient';
+$labels['vacationaddresses'] = 'Additional list of recipient e-mails (comma separated):';
+$labels['vacationdays'] = 'How often send messages (in days):';
+$labels['vacationreason'] = 'Message body (vacation reason):';
+$labels['rulestop'] = 'Stop evaluating rules';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Unknown server error';
+$messages['filterconnerror'] = 'Unable to connect to managesieve server';
+$messages['filterdeleteerror'] = 'Unable to delete filter. Server error occured';
+$messages['filterdeleted'] = 'Filter deleted successfully';
+$messages['filterconfirmdelete'] = 'Do you really want to delete selected filter?';
+$messages['filtersaved'] = 'Filter saved successfully';
+$messages['filtersaveerror'] = 'Unable to save filter. Server error occured.';
+$messages['ruledeleteconfirm'] = 'Are you sure, you want to delete selected rule?';
+$messages['actiondeleteconfirm'] = 'Are you sure, you want to delete selected action?';
+$messages['forbiddenchars'] = 'Forbidden characters in field';
+$messages['cannotbeempty'] = 'Field cannot be empty';
+
+?>
diff --git a/plugins/managesieve/localization/es_ES.inc b/plugins/managesieve/localization/es_ES.inc
new file mode 100644 (file)
index 0000000..9e7e3f5
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+$labels = array();
+$labels['filters'] = 'Filtros';
+$labels['managefilters'] = 'Administrar filtros de correo entrante';
+$labels['filtername'] = 'Nombre del filtro';
+$labels['newfilter'] = 'Nuevo filtro';
+$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['filteranyof'] = 'coincidir con alguna de las reglas siguientes';
+$labels['filterany'] = 'todos los mensajes';
+$labels['filtercontains'] = 'contiene';
+$labels['filternotcontains'] = 'no contiene';
+$labels['filteris'] = 'es igual a';
+$labels['filterisnot'] = 'no es igual a';
+$labels['filterexists'] = 'existe';
+$labels['filternotexists'] = 'no existe';
+$labels['filterunder'] = 'bajo';
+$labels['filterover'] = 'sobre';
+$labels['addrule'] = 'Agregar regla';
+$labels['delrule'] = 'Eliminar regla';
+$labels['messagemoveto'] = 'Mover mensaje a';
+$labels['messageredirect'] = 'Redirigir mensaje a';
+$labels['messagereply'] = 'Responder con un mensaje';
+$labels['messagedelete'] = 'Eliminar mensaje';
+$labels['messagediscard'] = 'Descartar con un mensaje';
+$labels['messagesrules'] = 'Para el correo entrante:';
+$labels['messagesactions'] = '... ejecutar las siguientes acciones:';
+$labels['add'] = 'Agregar';
+$labels['del'] = 'Eliminar';
+$labels['sender'] = 'Remitente';
+$labels['recipient'] = 'Destinatario';
+$labels['vacationaddresses'] = 'Lista de direcciones de correo de destinatarios adicionales (separados por comas):';
+$labels['vacationdays'] = 'Cada cuanto enviar mensajes (en días):';
+$labels['vacationreason'] = 'Cuerpo del mensaje (razón de vacaciones):';
+$labels['rulestop'] = 'Parar de evaluar reglas';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Error desconocido de servidor';
+$messages['filterconnerror'] = 'Imposible conectar con el servidor managesieve';
+$messages['filterdeleteerror'] = 'Imposible borrar filtro. Ha ocurrido un error en el servidor';
+$messages['filterdeleted'] = 'Filtro borrado satisfactoriamente';
+$messages['filterconfirmdelete'] = '¿Realmente desea borrar el filtro seleccionado?';
+$messages['filtersaved'] = 'Filtro guardado satisfactoriamente';
+$messages['filtersaveerror'] = 'Imposible guardar ell filtro. Ha ocurrido un error en el servidor';
+$messages['ruledeleteconfirm'] = '¿Está seguro de que desea borrar la regla seleccionada?';
+$messages['actiondeleteconfirm'] = '¿Está seguro de que desea borrar la acción seleccionada?';
+$messages['forbiddenchars'] = 'Caracteres prohibidos en el campo';
+$messages['cannotbeempty'] = 'El campo no puede estar vacío';
+
+?>
diff --git a/plugins/managesieve/localization/et_EE.inc b/plugins/managesieve/localization/et_EE.inc
new file mode 100644 (file)
index 0000000..2915de8
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+$labels['filters'] = 'Filtrid';
+$labels['managefilters'] = 'Halda sisenevate kirjade filtreid';
+$labels['filtername'] = 'Filtri nimi';
+$labels['newfilter'] = 'Uus filter';
+$labels['filteradd'] = 'Lisa filter';
+$labels['filterdel'] = 'Kustuta filter';
+$labels['moveup'] = 'Liiguta üles';
+$labels['movedown'] = 'Liiguta alla';
+$labels['filterallof'] = 'vastab kõikidele järgnevatele reeglitele';
+$labels['filteranyof'] = 'vastab mõnele järgnevatest reeglitest';
+$labels['filterany'] = 'kõik kirjad';
+$labels['filtercontains'] = 'sisaldab';
+$labels['filternotcontains'] = 'ei sisalda';
+$labels['filteris'] = 'on võrdne kui';
+$labels['filterisnot'] = 'ei ole võrdne kui';
+$labels['filterexists'] = 'on olemas';
+$labels['filternotexists'] = 'pole olemas';
+$labels['filterunder'] = 'alt';
+$labels['filterover'] = 'üle';
+$labels['addrule'] = 'Lisa reegel';
+$labels['delrule'] = 'Kustuta reegel';
+$labels['messagemoveto'] = 'Liiguta kiri';
+$labels['messageredirect'] = 'Suuna kiri ümber';
+$labels['messagereply'] = 'Vasta kirjaga';
+$labels['messagedelete'] = 'Kustuta kiri';
+$labels['messagediscard'] = 'Viska ära teatega';
+$labels['messagesrules'] = 'Siseneva kirja puhul, mis:';
+$labels['messagesactions'] = '...käivita järgnevad tegevused:';
+$labels['add'] = 'Lisa';
+$labels['del'] = 'Kustuta';
+$labels['sender'] = 'Saatja';
+$labels['recipient'] = 'Saaja';
+$labels['vacationaddresses'] = 'Lisanimekiri saaja e-posti aadressidest (komadega eraldatud):';
+$labels['vacationdays'] = 'Kui tihti kirju saata (päevades):';
+$labels['vacationreason'] = 'Kirja sisu (puhkuse põhjus):';
+$labels['rulestop'] = 'Peata reeglite otsimine';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Tundmatu serveri tõrge';
+$messages['filterconnerror'] = 'Managesieve serveriga ühendumine nurjus';
+$messages['filterdeleteerror'] = 'Filtri kustutamine nurjus. Ilmnes serveri tõrge.';
+$messages['filterdeleted'] = 'Filter edukalt kustutatud';
+$messages['filterconfirmdelete'] = 'Soovid valitud filtri kustutada?';
+$messages['filtersaved'] = 'Filter edukalt salvestatud';
+$messages['filtersaveerror'] = 'Filtri salvestamine nurjus. Ilmnes serveri tõrge.';
+$messages['ruledeleteconfirm'] = 'Soovid valitud reegli kustutada?';
+$messages['actiondeleteconfirm'] = 'Soovid valitud tegevuse kustutada?';
+$messages['forbiddenchars'] = 'Väljal on lubamatu märk';
+$messages['cannotbeempty'] = 'Väli ei või tühi olla';
+
+?>
diff --git a/plugins/managesieve/localization/fi_FI.inc b/plugins/managesieve/localization/fi_FI.inc
new file mode 100644 (file)
index 0000000..f066ca6
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+$labels['filters'] = 'Suodattimet';
+$labels['managefilters'] = 'Muokkaa saapuvan sähköpostin suodattimia';
+$labels['filtername'] = 'Suodattimen nimi';
+$labels['newfilter'] = 'Uusi suodatin';
+$labels['filteradd'] = 'Lisää suodatin';
+$labels['filterdel'] = 'Poista suodatin';
+$labels['moveup'] = 'Siirrä ylös';
+$labels['movedown'] = 'Siirrä alas';
+$labels['filterallof'] = 'Täsmää kaikkien sääntöjen mukaan';
+$labels['filteranyof'] = 'Täsmää minkä tahansa sääntöjen mukaan';
+$labels['filterany'] = 'Kaikki viestit';
+$labels['filtercontains'] = 'Sisältää';
+$labels['filternotcontains'] = 'Ei Sisällä';
+$labels['filteris'] = 'on samanlainen kuin';
+$labels['filterisnot'] = 'ei ole samanlainen kuin';
+$labels['filterexists'] = 'on olemassa';
+$labels['filternotexists'] = 'ei ole olemassa';
+$labels['filterunder'] = 'alla';
+$labels['filterover'] = 'yli';
+$labels['addrule'] = 'Lisää sääntö';
+$labels['delrule'] = 'Poista sääntö';
+$labels['messagemoveto'] = 'Siirrä viesti';
+$labels['messageredirect'] = 'Uudelleen ohjaa viesti';
+$labels['messagereply'] = 'Vastaa viestin kanssa';
+$labels['messagedelete'] = 'Poista viesti';
+$labels['messagediscard'] = 'Hylkää viesti';
+$labels['messagesrules'] = 'Saapuva sähköposti';
+$labels['messagesactions'] = 'Suorita seuraavat tapahtumat';
+$labels['add'] = 'Lisää';
+$labels['del'] = 'Poista';
+$labels['sender'] = 'Lähettäjä';
+$labels['recipient'] = 'Vastaanottaja';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Tuntematon palvelin virhe';
+$messages['filterconnerror'] = 'Yhdistäminen palvelimeen epäonnistui';
+$messages['filterdeleteerror'] = 'Suodattimen poistaminen epäonnistui. Palvelin virhe';
+$messages['filterdeleted'] = 'Suodatin poistettu';
+$messages['filterconfirmdelete'] = 'Haluatko varmasti poistaa valitut suodattimet?';
+$messages['filtersaved'] = 'Suodatin tallennettu';
+$messages['filtersaveerror'] = 'Suodattimen tallennus epäonnistui. Palvelin virhe';
+$messages['ruledeleteconfirm'] = 'Haluatko poistaa valitut säännöt?';
+$messages['actiondeleteconfirm'] = 'Haluatko poistaa valitut tapahtumat?';
+$messages['forbiddenchars'] = 'Sisältää kiellettyjä kirjaimia';
+$messages['cannotbeempty'] = 'Kenttä ei voi olla tyhjä';
+
+?>
diff --git a/plugins/managesieve/localization/fr_FR.inc b/plugins/managesieve/localization/fr_FR.inc
new file mode 100644 (file)
index 0000000..632db98
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+$labels['filters'] = 'Filtres';
+$labels['managefilters'] = 'Gestion des filtres sur les mails entrants';
+$labels['filtername'] = 'Nom du filtre';
+$labels['newfilter'] = 'Nouveau filtre';
+$labels['filteradd'] = 'Ajouter un filtre';
+$labels['filterdel'] = 'Supprimer un filtre';
+$labels['moveup'] = 'Monter';
+$labels['movedown'] = 'Descendre';
+$labels['filterallof'] = 'valident toutes les conditions suivantes';
+$labels['filteranyof'] = 'valident au moins une des conditions suivantes';
+$labels['filterany'] = 'tous les messages';
+$labels['filtercontains'] = 'contient';
+$labels['filternotcontains'] = 'ne contient pas';
+$labels['filteris'] = 'est ';
+$labels['filterisnot'] = 'n\'est pas';
+$labels['filterexists'] = 'existe';
+$labels['filternotexists'] = 'n\'existe pas';
+$labels['filterunder'] = 'est plus petit que';
+$labels['filterover'] = 'est plus grand que';
+$labels['addrule'] = 'Ajouter une règle';
+$labels['delrule'] = 'Supprimer une règle';
+$labels['messagemoveto'] = 'Déplacer le message vers';
+$labels['messageredirect'] = 'Transférer le message à';
+$labels['messagereply'] = 'Répondre avec le message';
+$labels['messagedelete'] = 'Supprimer le message';
+$labels['messagediscard'] = 'Rejeter avec le message';
+$labels['messagesrules'] = 'Pour les mails entrants:';
+$labels['messagesactions'] = '...exécuter les actions suivantes:';
+$labels['add'] = 'Ajouter';
+$labels['del'] = 'Supprimer';
+$labels['sender'] = 'Expéditeur';
+$labels['recipient'] = 'Destinataire';
+$labels['vacationaddresses'] = 'Liste des destinataires (séparés par une virgule) :';
+$labels['vacationdays'] = 'Ne pas renvoyer un message avant (jours) :';
+$labels['vacationreason'] = 'Corps du message (raison de l\'absence) :';
+$labels['rulestop'] = 'Arrêter d\'évaluer les prochaines règles';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Erreur du serveur inconnue';
+$messages['filterconnerror'] = 'Connexion au serveur Managesieve impossible';
+$messages['filterdeleteerror'] = 'Suppression du filtre impossible. Le serveur à produit une erreur';
+$messages['filterdeleted'] = 'Le filtre a bien été supprimé';
+$messages['filterconfirmdelete'] = 'Voulez-vous vraiment supprimer le filtre sélectionné?';
+$messages['filtersaved'] = 'Le filtre a bien été enregistré';
+$messages['filtersaveerror'] = 'Enregistrement du filtre impossibe. Le serveur à produit une erreur';
+$messages['ruledeleteconfirm'] = 'Voulez-vous vraiment supprimer la règle sélectionnée?';
+$messages['actiondeleteconfirm'] = 'Voulez-vous vraiment supprimer l\'action sélectionnée?';
+$messages['forbiddenchars'] = 'Caractères interdits dans le champ';
+$messages['cannotbeempty'] = 'Le champ ne peut pas être vide';
+
+?>
diff --git a/plugins/managesieve/localization/gb_GB.inc b/plugins/managesieve/localization/gb_GB.inc
new file mode 100644 (file)
index 0000000..c671b83
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+$labels['filters'] = 'Filters';
+$labels['managefilters'] = 'Manage incoming mail filters';
+$labels['filtername'] = 'Filter name';
+$labels['newfilter'] = 'New filter';
+$labels['filteradd'] = 'Add filter';
+$labels['filterdel'] = 'Delete filter';
+$labels['moveup'] = 'Move up';
+$labels['movedown'] = 'Move down';
+$labels['filterallof'] = 'matching all of the following rules';
+$labels['filteranyof'] = 'matching any of the following rules';
+$labels['filterany'] = 'all messages';
+$labels['filtercontains'] = 'contains';
+$labels['filternotcontains'] = 'not contains';
+$labels['filteris'] = 'is equal to';
+$labels['filterisnot'] = 'is not equal to';
+$labels['filterexists'] = 'exists';
+$labels['filternotexists'] = 'not exists';
+$labels['filterunder'] = 'under';
+$labels['filterover'] = 'over';
+$labels['addrule'] = 'Add rule';
+$labels['delrule'] = 'Delete rule';
+$labels['messagemoveto'] = 'Move message to';
+$labels['messageredirect'] = 'Redirect message to';
+$labels['messagereply'] = 'Reply with message';
+$labels['messagedelete'] = 'Delete message';
+$labels['messagediscard'] = 'Discard with message';
+$labels['messagesrules'] = 'For incoming mail:';
+$labels['messagesactions'] = '...execute the following actions:';
+$labels['add'] = 'Add';
+$labels['del'] = 'Delete';
+$labels['sender'] = 'Sender';
+$labels['recipient'] = 'Recipient';
+$labels['vacationaddresses'] = 'Additional list of recipient e-mails (comma separated):';
+$labels['vacationdays'] = 'How often send messages (in days):';
+$labels['vacationreason'] = 'Message body (vacation reason):';
+$labels['rulestop'] = 'Stop evaluating rules';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Unknown server error';
+$messages['filterconnerror'] = 'Unable to connect to managesieve server';
+$messages['filterdeleteerror'] = 'Unable to delete filter. Server error occured';
+$messages['filterdeleted'] = 'Filter deleted successfully';
+$messages['filterconfirmdelete'] = 'Do you really want to delete selected filter?';
+$messages['filtersaved'] = 'Filter saved successfully';
+$messages['filtersaveerror'] = 'Unable to save filter. Server error occured.';
+$messages['ruledeleteconfirm'] = 'Are you sure, you want to delete selected rule?';
+$messages['actiondeleteconfirm'] = 'Are you sure, you want to delete selected action?';
+$messages['forbiddenchars'] = 'Forbidden characters in field';
+$messages['cannotbeempty'] = 'Field cannot be empty';
+
+?>
diff --git a/plugins/managesieve/localization/hu_HU.inc b/plugins/managesieve/localization/hu_HU.inc
new file mode 100644 (file)
index 0000000..1647fbe
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+$labels = array();
+$labels['filters'] = 'Üzenetszűrők';
+$labels['managefilters'] = 'Bejövő üzenetek szűrői';
+$labels['filtername'] = 'Szűrő neve';
+$labels['newfilter'] = 'Új szűrő';
+$labels['filteradd'] = 'Szűrő hozzáadása';
+$labels['filterdel'] = 'Szűrő törlése';
+$labels['moveup'] = 'Mozgatás felfelé';
+$labels['movedown'] = 'Mozgatás lefelé';
+$labels['filterallof'] = 'A következők mind illeszkedjenek';
+$labels['filteranyof'] = 'A következők bármelyike illeszkedjen';
+$labels['filterany'] = 'Minden üzenet illeszkedjen';
+$labels['filtercontains'] = 'tartalmazza';
+$labels['filternotcontains'] = 'nem tartalmazza';
+$labels['filteris'] = 'megegyezik';
+$labels['filterisnot'] = 'nem egyezik meg';
+$labels['filterexists'] = 'létezik';
+$labels['filternotexists'] = 'nem létezik';
+$labels['filterunder'] = 'alatta';
+$labels['filterover'] = 'felette';
+$labels['addrule'] = 'Szabály hozzáadása';
+$labels['delrule'] = 'Szabály törlése';
+$labels['messagemoveto'] = 'Üzenet áthelyezése ide:';
+$labels['messageredirect'] = 'Üzenet továbbítása ide:';
+$labels['messagereply'] = 'Válaszüzenet küldése (autoreply)';
+$labels['messagedelete'] = 'Üzenet törlése';
+$labels['messagediscard'] = 'Válaszüzenet küldése, a levél törlése';
+$labels['messagesrules'] = 'Az adott tulajdonságú beérkezett üzenetekre:';
+$labels['messagesactions'] = '... a következő műveletek végrehajtása:';
+$labels['add'] = 'Hozzáadás';
+$labels['del'] = 'Törlés';
+$labels['sender'] = 'Feladó';
+$labels['recipient'] = 'Címzett';
+$labels['vacationaddresses'] = 'További címzettek (vesszővel elválasztva):';
+$labels['vacationdays'] = 'Válaszüzenet küldése ennyi naponként:';
+$labels['vacationreason'] = 'Levél szövege (automatikus válasz):';
+$labels['rulestop'] = 'Műveletek végrehajtásának befejezése';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Ismeretlen szerverhiba';
+$messages['filterconnerror'] = 'Nem tudok a szűrőszerverhez kapcsolódni';
+$messages['filterdeleteerror'] = 'A szűrőt nem lehet törölni, szerverhiba történt';
+$messages['filterdeleted'] = 'A szűrő törlése sikeres';
+$messages['filterconfirmdelete'] = 'Biztosan törli ezt a szűrőt?';
+$messages['filtersaved'] = 'A szűrő mentése sikeres';
+$messages['filtersaveerror'] = 'A szűrő mentése sikertelen, szerverhiba történt';
+$messages['ruledeleteconfirm'] = 'Biztosan törli ezt a szabályt?';
+$messages['actiondeleteconfirm'] = 'Biztosan törli ezt a műveletet?';
+$messages['forbiddenchars'] = 'Érvénytelen karakter a mezőben';
+$messages['cannotbeempty'] = 'A mező nem lehet üres';
+
+?>
diff --git a/plugins/managesieve/localization/it_IT.inc b/plugins/managesieve/localization/it_IT.inc
new file mode 100644 (file)
index 0000000..f7079b3
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+$labels = array();
+$labels['filters'] = 'Filtri';
+$labels['managefilters'] = 'Gestione dei filtri per la posta in arrivo';
+$labels['filtername'] = 'Nome del filtro';
+$labels['newfilter'] = 'Nuovo filtro';
+$labels['filteradd'] = 'Aggiungi filtro';
+$labels['filterdel'] = 'Elimina filtro';
+$labels['moveup'] = 'Sposta sopra';
+$labels['movedown'] = 'Sposta sotto';
+$labels['filterallof'] = 'che soddisfa tutte le regole seguenti';
+$labels['filteranyof'] = 'che soddisfa una qualsiasi delle regole seguenti';
+$labels['filterany'] = 'tutti i messaggi';
+$labels['filtercontains'] = 'contiene';
+$labels['filternotcontains'] = 'non contiene';
+$labels['filteris'] = 'è uguale a';
+$labels['filterisnot'] = 'è diverso da';
+$labels['filterexists'] = 'esiste';
+$labels['filternotexists'] = 'non esiste';
+$labels['filterunder'] = 'sotto';
+$labels['filterover'] = 'sopra';
+$labels['addrule'] = 'Aggiungi regola';
+$labels['delrule'] = 'Elimina regola';
+$labels['messagemoveto'] = 'Sposta il messaggio in';
+$labels['messageredirect'] = 'Inoltra il messaggio a';
+$labels['messagereply'] = 'Rispondi con il messaggio';
+$labels['messagedelete'] = 'Elimina il messaggio';
+$labels['messagediscard'] = 'Rifiuta con messaggio';
+$labels['messagesrules'] = 'Per la posta in arrivo';
+$labels['messagesactions'] = '...esegui le seguenti azioni:';
+$labels['add'] = 'Aggiungi';
+$labels['del'] = 'Elimina';
+$labels['sender'] = 'Mittente';
+$labels['recipient'] = 'Destinatario';
+$labels['vacationaddresses'] = 'Lista di indirizzi e-mail di destinatari addizionali (separati da virgola):';
+$labels['vacationdays'] = 'Ogni quanti giorni ribadire il messaggio allo stesso mittente';
+$labels['vacationreason'] = 'Corpo del messaggio (dettagli relativi all\'assenza):';
+$labels['rulestop'] = 'Non valutare le regole successive';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Errore sconosciuto del server';
+$messages['filterconnerror'] = 'Collegamento al server managesieve fallito';
+$messages['filterdeleteerror'] = 'Eliminazione del filtro fallita. Si è verificato un errore nel server';
+$messages['filterdeleted'] = 'Filtro eliminato con successo';
+$messages['filterconfirmdelete'] = 'Vuoi veramente eliminare il filtro selezionato?';
+$messages['filtersaved'] = 'Filtro salvato con successo';
+$messages['filtersaveerror'] = 'Salvataggio del filtro fallito. Si è verificato un errore nel server';
+$messages['ruledeleteconfirm'] = 'Sei sicuro di voler eliminare la regola selezionata?';
+$messages['actiondeleteconfirm'] = 'Sei sicuro di voler eliminare l\'azione selezionata?';
+$messages['forbiddenchars'] = 'Caratteri non consentiti nel campo';
+$messages['cannotbeempty'] = 'Il campo non può essere vuoto';
+
+?>
diff --git a/plugins/managesieve/localization/nl_NL.inc b/plugins/managesieve/localization/nl_NL.inc
new file mode 100644 (file)
index 0000000..83a4e69
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+$labels['filters'] = 'Filters';
+$labels['managefilters'] = 'Beheer inkomende mail filters';
+$labels['filtername'] = 'Filternaam';
+$labels['newfilter'] = 'Nieuw filter';
+$labels['filteradd'] = 'Filter toevoegen';
+$labels['filterdel'] = 'Filter verwijderen';
+$labels['moveup'] = 'Omhoog';
+$labels['movedown'] = 'Omlaag';
+$labels['filterallof'] = 'die voldoen aan alle volgende regels';
+$labels['filteranyof'] = 'die voldoen aan een van de volgende regels';
+$labels['filterany'] = 'alle berichten';
+$labels['filtercontains'] = 'bevat';
+$labels['filternotcontains'] = 'bevat niet';
+$labels['filteris'] = 'is gelijk aan';
+$labels['filterisnot'] = 'is niet gelijk aan';
+$labels['filterexists'] = 'bestaat';
+$labels['filternotexists'] = 'bestaat niet';
+$labels['filterunder'] = 'onder';
+$labels['filterover'] = 'over';
+$labels['addrule'] = 'Regel toevoegen';
+$labels['delrule'] = 'Regel verwijderen';
+$labels['messagemoveto'] = 'Verplaats bericht naar';
+$labels['messageredirect'] = 'Redirect bericht naar';
+$labels['messagereply'] = 'Beantwoord met bericht';
+$labels['messagedelete'] = 'Verwijder bericht';
+$labels['messagediscard'] = 'Wijs af met bericht';
+$labels['messagesrules'] = 'Voor binnenkomende e-mail';
+$labels['messagesactions'] = '...voer de volgende acties uit';
+$labels['add'] = 'Toevoegen';
+$labels['del'] = 'Verwijderen';
+$labels['sender'] = 'Afzender';
+$labels['recipient'] = 'Ontvanger';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Onbekende fout';
+$messages['filterconnerror'] = 'Kan geen verbinding maken met de managesieve server';
+$messages['filterdeleteerror'] = 'Kan filter niet verwijderen. Er is een fout opgetreden';
+$messages['filterdeleted'] = 'Filter succesvol verwijderd';
+$messages['filterconfirmdelete'] = 'Weet je zeker dat je het geselecteerde filter wilt verwijderen?';
+$messages['filtersaved'] = 'Filter succesvol opgeslagen';
+$messages['filtersaveerror'] = 'Kan filter niet opslaan. Er is een fout opgetreden.';
+$messages['ruledeleteconfirm'] = 'Weet je zeker dat je de geselecteerde regel wilt verwijderen?';
+$messages['actiondeleteconfirm'] = 'Weet je zeker dat je de geselecteerde actie wilt verwijderen?';
+$messages['forbiddenchars'] = 'Verboden karakters in het veld';
+$messages['cannotbeempty'] = 'Veld mag niet leeg zijn';
+
+?>
diff --git a/plugins/managesieve/localization/pl_PL.inc b/plugins/managesieve/localization/pl_PL.inc
new file mode 100644 (file)
index 0000000..f309a43
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+$labels = array();
+$labels['filters'] = 'Filtry';
+$labels['managefilters'] = 'Zarządzaj filtrami wiadomości przychodzących';
+$labels['filtername'] = 'Nazwa filtru';
+$labels['newfilter'] = 'Nowy filtr';
+$labels['filteradd'] = 'Dodaj filtr';
+$labels['filterdel'] = 'Usuń filtr';
+$labels['moveup'] = 'Przenieś wyżej';
+$labels['movedown'] = 'Przenieś niżej';
+$labels['filterallof'] = 'spełniające wszystkie poniższe kryteria';
+$labels['filteranyof'] = 'spełniające dowolne z poniższych kryteriów';
+$labels['filterany'] = 'wszystkich';
+$labels['filtercontains'] = 'zawiera';
+$labels['filternotcontains'] = 'nie zawiera';
+$labels['filteris'] = 'jest równe';
+$labels['filterisnot'] = 'nie jest równe';
+$labels['filterexists'] = 'istnieje';
+$labels['filternotexists'] = 'nie istnieje';
+$labels['filterunder'] = 'poniżej';
+$labels['filterover'] = 'ponad';
+$labels['addrule'] = 'Dodaj regułę';
+$labels['delrule'] = 'Usuń regułę';
+$labels['messagemoveto'] = 'Przenieś wiadomość do';
+$labels['messageredirect'] = 'Przekaż wiadomość na konto';
+$labels['messagereply'] = 'Odpowiedz wiadomością o treści';
+$labels['messagedelete'] = 'Usuń wiadomość';
+$labels['messagediscard'] = 'Odrzuć z komunikatem';
+$labels['messagesrules'] = 'W stosunku do przychodzących wiadomości:';
+$labels['messagesactions'] = '...wykonaj następujące czynności:';
+$labels['add'] = 'Dodaj';
+$labels['del'] = 'Usuń';
+$labels['sender'] = 'Nadawca';
+$labels['recipient'] = 'Odbiorca';
+$labels['rulestop'] = 'Przerwij przetwarzanie reguł';
+$labels['vacationdays'] = 'Częstotliwość wysyłania wiadomości (w dniach):';
+$labels['vacationaddresses'] = 'Lista dodatkowych adresów odbiorców (oddzielonych przecinkami):';
+$labels['vacationreason'] = 'Treść (przyczyna nieobecności):';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Nieznany błąd serwera';
+$messages['filterconnerror'] = 'Nie można nawiązać połączenia z serwerem managesieve';
+$messages['filterdeleteerror'] = 'Nie można usunąć filtra. Wystąpił błąd serwera';
+$messages['filterdeleted'] = 'Filtr został usunięty pomyślnie';
+$messages['filterconfirmdelete'] = 'Czy na pewno chcesz usunąć wybrany filtr?';
+$messages['filtersaved'] = 'Filtr został zapisany pomyślnie';
+$messages['filtersaveerror'] = 'Nie można zapisać filtra. Wystąpił błąd serwera.';
+$messages['ruledeleteconfirm'] = 'Czy na pewno chcesz usunąć wybraną regułę?';
+$messages['actiondeleteconfirm'] = 'Czy na pewno usunąć wybraną akcję?';
+$messages['forbiddenchars'] = 'Pole zawiera niedozwolone znaki';
+$messages['cannotbeempty'] = 'Pole nie może być puste';
+
+?>
diff --git a/plugins/managesieve/localization/pt_BR.inc b/plugins/managesieve/localization/pt_BR.inc
new file mode 100644 (file)
index 0000000..4515deb
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+$labels['filters'] = 'Filtros';
+$labels['managefilters'] = 'Gerenciar filtros de entrada de e-mail';
+$labels['filtername'] = 'Nome do filtro';
+$labels['newfilter'] = 'Novo filtro';
+$labels['filteradd'] = 'Adicionar filtro';
+$labels['filterdel'] = 'Excluir filtro';
+$labels['moveup'] = 'Mover para cima';
+$labels['movedown'] = 'Mover para baixo';
+$labels['filterallof'] = 'casando todas as seguintes regras';
+$labels['filteranyof'] = 'casando qualquer das seguintes regras';
+$labels['filterany'] = 'todas as mensagens';
+$labels['filtercontains'] = 'contem';
+$labels['filternotcontains'] = 'não contem';
+$labels['filteris'] = 'é igual a';
+$labels['filterisnot'] = 'não é igual a';
+$labels['filterexists'] = 'existe';
+$labels['filternotexists'] = 'não existe';
+$labels['filterunder'] = 'inferior a';
+$labels['filterover'] = 'superior a';
+$labels['addrule'] = 'Adicionar regra';
+$labels['delrule'] = 'Excluir regra';
+$labels['messagemoveto'] = 'Mover mensagem para';
+$labels['messageredirect'] = 'Redirecionar mensagem para';
+$labels['messagereply'] = 'Responder com mensagem';
+$labels['messagedelete'] = 'Excluir mensagem';
+$labels['messagediscard'] = 'Descartar com mensagem';
+$labels['messagesrules'] = 'Para e-mails recebidos:';
+$labels['messagesactions'] = '...execute as seguintes ações:';
+$labels['add'] = 'Adicionar';
+$labels['del'] = 'Excluir';
+$labels['sender'] = 'Remetente';
+$labels['recipient'] = 'Destinatário';
+$labels['vacationaddresses'] = 'Lista adicional de e-mails de remetente (separado por vírgula):';
+$labels['vacationdays'] = 'Enviar mensagens com que frequência (em dias):';
+$labels['vacationreason'] = 'Corpo da mensagem (motivo de férias):';
+$labels['rulestop'] = 'Parar de avaliar regras';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Erro desconhecido de servidor';
+$messages['filterconnerror'] = 'Não foi possível conectar ao servidor managesieve';
+$messages['filterdeleteerror'] = 'Não foi possível excluir filtro. Occorreu um erro de servidor';
+$messages['filterdeleted'] = 'Filtro excluído com sucesso';
+$messages['filterconfirmdelete'] = 'Deseja realmente excluir o filtro selecionado?';
+$messages['filtersaved'] = 'Filtro gravado com sucesso';
+$messages['filtersaveerror'] = 'Não foi possível gravar filtro. Occoreu um erro de servidor.';
+$messages['ruledeleteconfirm'] = 'Deseja realmente excluir a regra selecionada?';
+$messages['actiondeleteconfirm'] = 'Deseja realmente excluir a ação selecionada?';
+$messages['forbiddenchars'] = 'Caracteres não permitidos no campo';
+$messages['cannotbeempty'] = 'Campo não pode ficar em branco';
+
+?>
diff --git a/plugins/managesieve/localization/ru_RU.inc b/plugins/managesieve/localization/ru_RU.inc
new file mode 100644 (file)
index 0000000..ad459a0
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+$labels['filters'] = 'Фильтры';
+$labels['managefilters'] = 'Управление фильтрами для входящей почты';
+$labels['filtername'] = 'Название фильтра';
+$labels['newfilter'] = 'Новый фильтр';
+$labels['filteradd'] = 'Добавить фильтр';
+$labels['filterdel'] = 'Удалить фильтр';
+$labels['moveup'] = 'Сдвинуть вверх';
+$labels['movedown'] = 'Сдвинуть вниз';
+$labels['filterallof'] = 'соответствует всем указанным правилам';
+$labels['filteranyof'] = 'соответствует любому из указанных правил';
+$labels['filterany'] = 'все сообщения';
+$labels['filtercontains'] = 'содержит';
+$labels['filternotcontains'] = 'не содержит';
+$labels['filteris'] = 'соответсвует';
+$labels['filterisnot'] = 'не соответсвует';
+$labels['filterexists'] = 'существует';
+$labels['filternotexists'] = 'не существует';
+$labels['filterunder'] = 'под';
+$labels['filterover'] = 'на';
+$labels['addrule'] = 'Добавить правило';
+$labels['delrule'] = 'Удалить правило';
+$labels['messagemoveto'] = 'Переместить сообщение в';
+$labels['messageredirect'] = 'Перенаправить сообщение на ';
+$labels['messagereply'] = 'Ответить с сообщением';
+$labels['messagedelete'] = 'Удалить сообщение';
+$labels['messagediscard'] = 'Отбросить с сообщением';
+$labels['messagesrules'] = 'Для входящей почты:';
+$labels['messagesactions'] = '...выполнить следующие действия:';
+$labels['add'] = 'Добавить';
+$labels['del'] = 'Удалить';
+$labels['sender'] = 'Отправитель';
+$labels['recipient'] = 'Получатель';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Неизвестная ошибка сервера';
+$messages['filterconnerror'] = 'Невозможно подсоединится к серверу фильтров';
+$messages['filterdeleteerror'] = 'Невозможно удалить фильтр. Ошибка сервера';
+$messages['filterdeleted'] = 'Фильтр успешно удалён';
+$messages['filterconfirmdelete'] = 'Вы действительно хотите удалить фильтр?';
+$messages['filtersaved'] = 'Фильтр успешно сохранён';
+$messages['filtersaveerror'] = 'Невозможно сохранить фильтр. Ошибка сервера';
+$messages['ruledeleteconfirm'] = 'Вы уверенны, что хотите удалить это правило?';
+$messages['actiondeleteconfirm'] = 'Вы уверенны, что хотите удалить это действие?';
+$messages['forbiddenchars'] = 'Недопустимые символы в поле';
+$messages['cannotbeempty'] = 'Поле не может быть пустым';
+
+?>
diff --git a/plugins/managesieve/localization/sl_SI.inc b/plugins/managesieve/localization/sl_SI.inc
new file mode 100644 (file)
index 0000000..ee3c6fe
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+       
+$labels['filters'] = 'Pravila';
+$labels['managefilters'] = 'Uredi sporočilna pravila';
+$labels['filtername'] = 'Ime pravila';
+$labels['newfilter'] = 'Novo pravilo';
+$labels['filteradd'] = 'Dodaj pravilo';
+$labels['filterdel'] = 'Izbriši pravilo';
+$labels['moveup'] = 'Pomakni se više';
+$labels['movedown'] = 'Pomakni se niže';
+$labels['filterallof'] = 'izpolnjeni morajo biti vsi pogoji';
+$labels['filteranyof'] = 'izpolnjen mora biti vsaj eden od navedenih pogojev';
+$labels['filterany'] = 'pogoj velja za vsa sporočila';
+$labels['filtercontains'] = 'vsebuje';
+$labels['filternotcontains'] = 'ne vsebuje';
+$labels['filteris'] = 'je enak/a';
+$labels['filterisnot'] = 'ni enak/a';
+$labels['filterexists'] = 'obstaja';
+$labels['filternotexists'] = 'ne obstaja';
+$labels['filterunder'] = 'pod';
+$labels['filterover'] = 'nad';
+$labels['addrule'] = 'Dodaj pravilo';
+$labels['delrule'] = 'Izbriši pravilo';
+$labels['messagemoveto'] = 'Premakni sporočilo v';
+$labels['messageredirect'] = 'Preusmeri sporočilo v';
+$labels['messagereply'] = 'Odgovori s sporočilom';
+$labels['messagedelete'] = 'Izbriši sporočilo';
+$labels['messagediscard'] = 'Zavrži s sporočilom';
+$labels['messagesrules'] = 'Določi pravila za dohodno pošto:';
+$labels['messagesactions'] = '...izvrši naslednja dejanja:';
+$labels['add'] = 'Dodaj';
+$labels['del'] = 'Izbriši';
+$labels['sender'] = 'Pošiljatelj';
+$labels['recipient'] = 'Prejemnik';
+$labels['vacationaddresses'] = 'Dodaten seznam naslovov prejemnikov (ločenih z vejico):';
+$labels['vacationdays'] = 'Kako pogosto naj bodo sporočila poslana (v dnevih):';
+$labels['vacationreason'] = 'Vsebina sporočila (vzrok za odsotnost):';
+$labels['rulestop'] = 'Prekini z izvajanjem pravil';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Prišlo je do neznane napake.';
+$messages['filterconnerror'] = 'Povezave s strežnikom (managesieve) ni bilo mogoče vzpostaviti';
+$messages['filterdeleteerror'] = 'Pravila ni bilo mogoče izbrisati. Prišlo je do napake.';
+$messages['filterdeleted'] = 'Pravilo je bilo uspešno izbrisano.';
+$messages['filterconfirmdelete'] = 'Ste prepričani, da želite izbrisati izbrano pravilo?';
+$messages['filtersaved'] = 'Pravilo je bilo uspešno shranjeno';
+$messages['filtersaveerror'] = 'Pravilo ni bilo shranjeno. Prišlo je do napake.';
+$messages['ruledeleteconfirm'] = 'Ste prepričani, da želite izbrisati izbrano pravilo?';
+$messages['actiondeleteconfirm'] = 'Ste prepričani, da želite izbrisati izbrano dejanje?';
+$messages['forbiddenchars'] = 'V polju so neveljavni znaki';
+$messages['cannotbeempty'] = 'Polje ne sme biti prazno';
+
+?>
diff --git a/plugins/managesieve/localization/sv_SE.inc b/plugins/managesieve/localization/sv_SE.inc
new file mode 100644 (file)
index 0000000..48d0158
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+$labels = array();
+$labels['filters'] = 'Filter';
+$labels['managefilters'] = 'Administrera filter';
+$labels['filtername'] = 'Filternamn';
+$labels['newfilter'] = 'Nytt filter';
+$labels['filteradd'] = 'Lägg till filter';
+$labels['filterdel'] = 'Ta bort filter';
+$labels['moveup'] = 'Flytta upp filter';
+$labels['movedown'] = 'Flytta ner filter';
+$labels['filterallof'] = 'Filtrera på alla följande regler';
+$labels['filteranyof'] = 'Filtrera på någon av följande regler';
+$labels['filterany'] = 'Filtrera alla meddelanden';
+$labels['filtercontains'] = 'innehåller';
+$labels['filternotcontains'] = 'inte innehåller';
+$labels['filteris'] = 'är lika med';
+$labels['filterisnot'] = 'är inte lika med';
+$labels['filterexists'] = 'finns';
+$labels['filternotexists'] = 'inte finns';
+$labels['filterunder'] = 'under';
+$labels['filterover'] = 'över';
+$labels['addrule'] = 'Lägg till regel';
+$labels['delrule'] = 'Ta bort regel';
+$labels['messagemoveto'] = 'Flytta meddelande till';
+$labels['messageredirect'] = 'Ändra mottagare till';
+$labels['messagereply'] = 'Besvara meddelande';
+$labels['messagedelete'] = 'Ta bort meddelande';
+$labels['messagediscard'] = 'Avböj med felmeddelande';
+$labels['messagesrules'] = 'För inkommande meddelande';
+$labels['messagesactions'] = 'Utför följande åtgärd';
+$labels['add'] = 'Lägg till';
+$labels['del'] = 'Ta bort';
+$labels['sender'] = 'Avsändare';
+$labels['recipient'] = 'Mottagare';
+$labels['vacationaddresses'] = 'Ytterligare mottagaradresser (avdelade med kommatecken)';
+$labels['vacationdays'] = 'Antal dagar mellan auto-svar';
+$labels['vacationreason'] = 'Meddelande i auto-svar';
+$labels['rulestop'] = 'Avsluta filtrering';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Okänt serverfel';
+$messages['filterconnerror'] = 'Anslutning till serverns filtertjänst misslyckades';
+$messages['filterdeleteerror'] = 'Filtret kunde inte tas bort på grund av serverfel';
+$messages['filterdeleted'] = 'Filtret är borttaget';
+$messages['filterconfirmdelete'] = 'Vill du ta bort det markerade filtret?';
+$messages['filtersaved'] = 'Filtret har sparats';
+$messages['filtersaveerror'] = 'Filtret kunde inte sparas på grund av serverfel';
+$messages['ruledeleteconfirm'] = 'Vill du ta bort filterregeln?';
+$messages['actiondeleteconfirm'] = 'Vill du ta bort filteråtgärden?';
+$messages['forbiddenchars'] = 'Otillåtet tecken i fältet';
+$messages['cannotbeempty'] = 'Fältet kan inte lämnas tomt';
+
+?>
diff --git a/plugins/managesieve/localization/uk_UA.inc b/plugins/managesieve/localization/uk_UA.inc
new file mode 100644 (file)
index 0000000..2cc4436
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+$labels = array();
+$labels['filters'] = 'Фільтри';
+$labels['managefilters'] = 'Керування фільтрами вхідної пошти';
+$labels['filtername'] = 'Назва фільтру';
+$labels['newfilter'] = 'Новий фільтр';
+$labels['filteradd'] = 'Додати фільтр';
+$labels['filterdel'] = 'Видалити фільтр';
+$labels['moveup'] = 'Пересунути вгору';
+$labels['movedown'] = 'Пересунути вниз';
+$labels['filterallof'] = 'задовольняє усім наступним';
+$labels['filteranyof'] = 'задовольняє будь-якому з наступного';
+$labels['filterany'] = 'всі повідомлення';
+$labels['filtercontains'] = 'містить';
+$labels['filternotcontains'] = 'не містить';
+$labels['filteris'] = 'ідентичний до';
+$labels['filterisnot'] = 'не ідентичний до';
+$labels['filterexists'] = 'існує';
+$labels['filternotexists'] = 'не існує';
+$labels['filterunder'] = 'під';
+$labels['filterover'] = 'над';
+$labels['addrule'] = 'Додати правило';
+$labels['delrule'] = 'Видалити правило';
+$labels['messagemoveto'] = 'Пересунути повідомлення до';
+$labels['messageredirect'] = 'Перенаправити повідомлення до';
+$labels['messagereply'] = 'Відповісти з повідомленням';
+$labels['messagedelete'] = 'Видалити повідомлення';
+$labels['messagediscard'] = 'Відхилити з повідомленням';
+$labels['messagesrules'] = 'Для вхідної пошти';
+$labels['messagesactions'] = '... виконати дію:';
+$labels['add'] = 'Додати';
+$labels['del'] = 'Видалити';
+$labels['sender'] = 'Відправник';
+$labels['recipient'] = 'Отримувач';
+$labels['vacationaddresses'] = 'Додатковий список адрес отримувачів (розділених комою)';
+$labels['vacationdays'] = 'Частота надсилання повідомлень (у днях):';
+$labels['vacationreason'] = 'Тіло повідомлення (причина):';
+$labels['rulestop'] = 'Зупинити перевірку правил';
+
+$messages = array();
+$messages['filterunknownerror'] = 'Невідома помилка сервера.';
+$messages['filterconnerror'] = 'Неможливо з\'єднатися з сервером.';
+$messages['filterdeleteerror'] = 'Неможливо видалити фільтр. Помилка сервера.';
+$messages['filterdeleted'] = 'Фільтр успішно видалено.';
+$messages['filterconfirmdelete'] = 'Ви дійсно хочете видалити вибраний фільтр?';
+$messages['filtersaved'] = 'Фільтр успішно збережено.';
+$messages['filtersaveerror'] = 'Неможливо зберегти фільтр. Помилка сервера.';
+$messages['ruledeleteconfirm'] = 'Ви дійсно хочете видалити вибране правило?';
+$messages['actiondeleteconfirm'] = 'Ви дійсно хочете видалити вибрану дію?';
+$messages['forbiddenchars'] = 'Введено заборонений символ.';
+$messages['cannotbeempty'] = 'Поле не може бути пустим.';
+
+?>
diff --git a/plugins/managesieve/localization/zh_CN.inc b/plugins/managesieve/localization/zh_CN.inc
new file mode 100644 (file)
index 0000000..fe63c6d
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+$labels['filters'] = '过滤器';
+$labels['managefilters'] = '管理邮件过滤器';
+$labels['filtername'] = '过滤器名称';
+$labels['newfilter'] = '新建过滤器';
+$labels['filteradd'] = '添加过滤器';
+$labels['filterdel'] = '删除过滤器';
+$labels['moveup'] = '上移';
+$labels['movedown'] = '下移';
+$labels['filterallof'] = '匹配所有规则';
+$labels['filteranyof'] = '匹配任意一条规则';
+$labels['filterany'] = '所有邮件';
+$labels['filtercontains'] = '包含';
+$labels['filternotcontains'] = '不包含';
+$labels['filteris'] = '等于';
+$labels['filterisnot'] = '不等于';
+$labels['filterexists'] = '存在';
+$labels['filternotexists'] = '不存在';
+$labels['filterunder'] = '小于';
+$labels['filterover'] = '大于';
+$labels['addrule'] = '添加规则';
+$labels['delrule'] = '删除规则';
+$labels['messagemoveto'] = '将邮件移动到';
+$labels['messageredirect'] = '将邮件转发到';
+$labels['messagereply'] = '回复以下信息';
+$labels['messagedelete'] = '删除邮件';
+$labels['messagediscard'] = '丢弃邮件并回复以下信息';
+$labels['messagesrules'] = '对收取的邮件应用规则:';
+$labels['messagesactions'] = '...执行以下动作:';
+$labels['add'] = '添加';
+$labels['del'] = '删除';
+$labels['sender'] = '发件人';
+$labels['recipient'] = '收件人';
+
+$messages = array();
+$messages['filterunknownerror'] = '未知的服务器错误';
+$messages['filterconnerror'] = '无法连接到 managesieve 服务器';
+$messages['filterdeleteerror'] = '无法删除过滤器。服务器错误';
+$messages['filterdeleted'] = '过滤器已成功删除';
+$messages['filterconfirmdelete'] = '您确定要删除所选择的过滤器吗?';
+$messages['filtersaved'] = '过滤器已成功保存。';
+$messages['filtersaveerror'] = '无法保存过滤器。服务器错误';
+$messages['ruledeleteconfirm'] = '您确定要删除所选择的规则吗?';
+$messages['actiondeleteconfirm'] = '您确定要删除所选择的动作吗?';
+$messages['forbiddenchars'] = '内容中包含禁用的字符';
+$messages['cannotbeempty'] = '内容不能为空';
+
+?>
diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js
new file mode 100644 (file)
index 0000000..7ff1acf
--- /dev/null
@@ -0,0 +1,381 @@
+/* Sieve Filters (tab) */
+
+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', 'settingstabpluginmanagesieve').addClass('tablink');
+    
+    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);
+    rcmail.register_command('plugin.managesieve-up', function() { rcmail.managesieve_up() }, true);
+    rcmail.register_command('plugin.managesieve-down', function() { rcmail.managesieve_down() }, true);
+
+    if (rcmail.env.action == 'plugin.managesieve')
+      {
+       if (rcmail.gui_objects.sieveform)
+         rcmail.enable_command('plugin.managesieve-save', true);
+       else {
+         rcmail.enable_command('plugin.managesieve-del', 'plugin.managesieve-up', 'plugin.managesieve-down', false);
+          rcmail.enable_command('plugin.managesieve-add', !rcmail.env.sieveconnerror);
+       }
+       
+        if (rcmail.gui_objects.filterslist) {
+           var p = rcmail;
+           rcmail.filters_list = new rcube_list_widget(rcmail.gui_objects.filterslist, {multiselect:false, draggable:false, keyboard:false});
+           rcmail.filters_list.addEventListener('select', function(o){ p.managesieve_select(o); });
+           rcmail.filters_list.init();
+           rcmail.filters_list.focus();
+         }
+      }
+  });
+
+  /*********************************************************/
+  /*********     Managesieve filters methods       *********/
+  /*********************************************************/
+
+  rcube_webmail.prototype.managesieve_add = function()
+    {
+      this.load_managesieveframe();
+      this.filters_list.clear_selection();
+    };
+
+  rcube_webmail.prototype.managesieve_del = function()
+    {
+    var id = this.filters_list.get_single_selection();
+
+    if (confirm(this.get_label('managesieve.filterconfirmdelete')))
+      this.http_request('plugin.managesieve',
+           '_act=delete&_fid='+this.filters_list.rows[id].uid, true);
+    };
+
+  rcube_webmail.prototype.managesieve_up = function()
+    {
+    var id = this.filters_list.get_single_selection();
+    this.http_request('plugin.managesieve',
+           '_act=up&_fid='+this.filters_list.rows[id].uid, true);
+    };
+
+  rcube_webmail.prototype.managesieve_down = function()
+    {
+    var id = this.filters_list.get_single_selection();
+    this.http_request('plugin.managesieve',
+           '_act=down&_fid='+this.filters_list.rows[id].uid, true);
+    };
+
+  rcube_webmail.prototype.managesieve_rowid = function(id)
+    {
+    var rows = this.filters_list.rows;
+    
+    for (var i=0; i<rows.length; i++)
+      if (rows[i] != null && rows[i].uid == id)
+       return i;
+    }
+
+  rcube_webmail.prototype.managesieve_updatelist = function(action, name, id)
+    {
+    this.set_busy(true);
+
+    switch (action)
+      {
+      case 'delete':
+        this.filters_list.remove_row(this.managesieve_rowid(id));
+       this.filters_list.clear_selection();
+       this.enable_command('plugin.managesieve-del', 'plugin.managesieve-up', 'plugin.managesieve-down', false);
+       this.show_contentframe(false);
+
+       // re-numbering filters
+        var rows = this.filters_list.rows;
+        for (var i=0; i<rows.length; i++)
+          {
+         if (rows[i] != null && rows[i].uid > id)
+           rows[i].uid = rows[i].uid-1;
+         }
+       break;
+
+      case 'down':
+        var rows = this.filters_list.rows;
+       var from;
+
+       // we need only to replace filter names...
+        for (var i=0; i<rows.length; i++)
+        {
+         if (rows[i]==null) { // removed row
+           continue;
+          } else if (rows[i].uid == id) {
+           from = rows[i].obj.cells[0];
+         } else if (rows[i].uid == id+1){
+           name = rows[i].obj.cells[0].innerHTML;
+           rows[i].obj.cells[0].innerHTML = from.innerHTML;
+           from.innerHTML = name;
+           this.filters_list.highlight_row(i);
+           break;
+         }
+       }
+       // ... and disable/enable Down button
+       this.filters_listbuttons();
+        break;
+
+      case 'up':
+        var rows = this.filters_list.rows;
+       var from;
+
+       // we need only to replace filter names...
+        for (var i=0; i<rows.length; i++)
+        {
+         if (rows[i]==null) { // removed row
+           continue;
+          } else if (rows[i].uid == id-1) {
+           from = rows[i].obj.cells[0];
+           this.filters_list.highlight_row(i);
+         } else if (rows[i].uid == id) {
+           name = rows[i].obj.cells[0].innerHTML;
+           rows[i].obj.cells[0].innerHTML = from.innerHTML;
+           from.innerHTML = name;
+           break;
+         }
+       }
+       // ... and disable/enable Up button
+       this.filters_listbuttons();
+        break;
+       
+      case 'update':
+        var rows = parent.rcmail.filters_list.rows;
+        for (var i=0; i<rows.length; i++)
+         if (rows[i] && rows[i].uid == id)
+           {
+           rows[i].obj.cells[0].innerHTML = name;
+           break;
+           }
+        break;
+      
+      case 'add':
+        var row, new_row, td;
+       var list = parent.rcmail.filters_list;
+
+       if (!list)
+          break;
+
+       for (var i=0; i<list.rows.length; i++)
+         if (list.rows[i] != null && String(list.rows[i].obj.id).match(/^rcmrow/))
+           row = list.rows[i].obj;
+
+        if (row)
+         {
+           new_row = parent.document.createElement('tr');
+           new_row.id = 'rcmrow'+id;
+           td = parent.document.createElement('td');
+           new_row.appendChild(td);
+           list.insert_row(new_row, false);
+
+           if (row.cells[0].className)
+             td.className = row.cells[0].className;
+        
+           td.innerHTML = name;
+           list.highlight_row(id);
+
+           parent.rcmail.enable_command('plugin.managesieve-del', 'plugin.managesieve-up', true);
+         }
+        else // refresh whole page
+         parent.rcmail.goto_url('plugin.managesieve');
+       break;
+      }
+
+    this.set_busy(false);
+
+    };
+
+  rcube_webmail.prototype.managesieve_select = function(list)
+    {
+    var id = list.get_single_selection();
+    if (id != null)
+      this.load_managesieveframe(list.rows[id].uid);
+    };
+
+  rcube_webmail.prototype.managesieve_save = function()
+    {
+      if (parent.rcmail && parent.rcmail.filters_list)
+        {
+        var id = parent.rcmail.filters_list.get_single_selection();
+       if (id != null)
+         this.gui_objects.sieveform.elements['_fid'].value = parent.rcmail.filters_list.rows[id].uid;
+        }
+      this.gui_objects.sieveform.submit();
+    };
+
+  // load filter frame
+  rcube_webmail.prototype.load_managesieveframe = function(id)
+    {
+    if (typeof(id) != 'undefined' && id != null)
+      {
+      this.enable_command('plugin.managesieve-del', true);
+      this.filters_listbuttons();
+      }
+    else
+      this.enable_command('plugin.managesieve-up', 'plugin.managesieve-down', 'plugin.managesieve-del', false);
+
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      target = window.frames[this.env.contentframe];
+      this.set_busy(true, 'loading');
+      target.location.href = this.env.comm_path+'&_action=plugin.managesieve&_framed=1&_fid='+id;
+      }
+    };
+
+  // enable/disable Up/Down buttons
+  rcube_webmail.prototype.filters_listbuttons = function()
+    {
+    var id = this.filters_list.get_single_selection();
+    var rows = this.filters_list.rows;
+
+    for (var i=0; i<rows.length; i++)
+      {
+      if (rows[i] == null) { // removed row
+        } else if (i == id) {
+         this.enable_command('plugin.managesieve-up', false);
+         break;
+        } else {
+         this.enable_command('plugin.managesieve-up', true);
+         break;
+        }
+      }
+
+    for (var i=rows.length-1; i>0; i--)
+      {
+        if (rows[i] == null) { // removed row
+       } else if (i == id) {
+         this.enable_command('plugin.managesieve-down', false);
+         break;
+       } else {
+         this.enable_command('plugin.managesieve-down', true);
+         break;
+       }
+      } 
+    };
+
+  // operations on filters form
+  rcube_webmail.prototype.managesieve_ruleadd = function(id)
+    {
+      this.http_post('plugin.managesieve', '_act=ruleadd&_rid='+id);
+    };
+
+  rcube_webmail.prototype.managesieve_rulefill = function(content, id, after)
+    {
+      if (content != '')
+        {
+       // create new element
+       var div = document.getElementById('rules');
+       var row = document.createElement('div');
+
+       this.managesieve_insertrow(div, row, after);
+       // fill row after inserting (for IE)
+       row.setAttribute('id', 'rulerow'+id);
+       row.className = 'rulerow';
+        row.innerHTML = content;
+
+       this.managesieve_formbuttons(div);
+       }
+    };
+
+  rcube_webmail.prototype.managesieve_ruledel = function(id)
+    {
+      if (confirm(this.get_label('managesieve.ruledeleteconfirm')))
+       {
+       var row = document.getElementById('rulerow'+id);
+       row.parentNode.removeChild(row);
+       this.managesieve_formbuttons(document.getElementById('rules'));
+       }
+    };
+
+  rcube_webmail.prototype.managesieve_actionadd = function(id)
+    {
+      this.http_post('plugin.managesieve', '_act=actionadd&_aid='+id);
+    };
+
+  rcube_webmail.prototype.managesieve_actionfill = function(content, id, after)
+    {
+      if (content != '')
+        {
+       var div = document.getElementById('actions');
+       var row = document.createElement('div');
+
+       this.managesieve_insertrow(div, row, after);
+       // fill row after inserting (for IE)
+       row.className = 'actionrow';
+       row.setAttribute('id', 'actionrow'+id);
+        row.innerHTML = content;
+
+        this.managesieve_formbuttons(div);
+       }
+    };
+
+  rcube_webmail.prototype.managesieve_actiondel = function(id)
+    {
+      if (confirm(this.get_label('managesieve.actiondeleteconfirm')))
+       {
+       var row = document.getElementById('actionrow'+id);
+       row.parentNode.removeChild(row);
+       this.managesieve_formbuttons(document.getElementById('actions'));
+       }
+    };
+
+  // insert rule/action row in specified place on the list
+  rcube_webmail.prototype.managesieve_insertrow = function(div, row, after)
+    {
+      for (var i=0; i<div.childNodes.length; i++)
+       {
+        if (div.childNodes[i].id == (div.id == 'rules' ? 'rulerow' : 'actionrow')  + after)
+         break;
+       }
+
+      if (div.childNodes[i+1])
+        div.insertBefore(row, div.childNodes[i+1]);
+      else
+        div.appendChild(row);
+    }
+
+  // update Delete buttons status
+  rcube_webmail.prototype.managesieve_formbuttons = function(div)
+    {
+      var buttons = new Array();
+      var i, j=0;
+      // count and get buttons
+      for (i=0; i<div.childNodes.length; i++)
+       {
+       if (div.id == 'rules' && div.childNodes[i].id)
+         {
+         if (/rulerow/.test(div.childNodes[i].id))
+           buttons.push('ruledel' + div.childNodes[i].id.replace(/rulerow/, ''));
+         }
+       else if (div.childNodes[i].id)
+         {
+         if (/actionrow/.test(div.childNodes[i].id))
+           buttons.push( 'actiondel' + div.childNodes[i].id.replace(/actionrow/, ''));
+         }
+        }
+
+      for (i=0; i<buttons.length; i++)
+       {
+       var button = document.getElementById(buttons[i]);
+       if (i>0 || buttons.length>1)
+         {
+         $(button).removeClass('disabled');
+         button.removeAttribute('disabled');
+         }
+       else
+         {
+         $(button).addClass('disabled');
+         button.setAttribute('disabled', true);
+         }
+        }
+    }
+}
diff --git a/plugins/managesieve/managesieve.php b/plugins/managesieve/managesieve.php
new file mode 100644 (file)
index 0000000..21d974d
--- /dev/null
@@ -0,0 +1,854 @@
+<?php
+
+/**
+ * Managesieve (Sieve Filters)
+ *
+ * Plugin that adds a possibility to manage Sieve filters in Thunderbird's style.
+ * It's clickable interface which operates on text scripts and communicates
+ * with server using managesieve protocol. Adds Filters tab in Settings.
+ *
+ * @version 1.3
+ * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
+ *
+ * Configuration (see config.inc.php.dist):
+ */
+
+class managesieve extends rcube_plugin
+{
+  public $task = 'settings';
+
+  private $rc;
+  private $sieve;
+  private $errors;
+  private $form;
+  private $script = array();
+  private $exts = array();
+  private $headers = array(
+    'subject' => 'Subject',
+    'sender' => 'From',
+    'recipient' => 'To',
+  );
+
+  function init()
+  {
+    // add Tab label/title
+    $this->add_texts('localization/', array('filters','managefilters'));
+
+    // register actions
+    $this->register_action('plugin.managesieve', array($this, 'managesieve_init'));
+    $this->register_action('plugin.managesieve-save', array($this, 'managesieve_save'));
+
+    // include main js script
+    $this->include_script('managesieve.js');
+  }
+  
+  function managesieve_start()
+  {
+    $rcmail = rcmail::get_instance();
+    $this->rc = &$rcmail;
+
+    $this->load_config();
+
+    // register UI objects
+    $this->rc->output->add_handlers(array(
+       'filterslist' => array($this, 'filters_list'),
+       'filterframe' => array($this, 'filter_frame'),
+       'filterform' => array($this, 'filter_form'),
+    ));
+
+    require_once($this->home . '/lib/Net/Sieve.php');
+    require_once($this->home . '/lib/rcube_sieve.php');
+
+    // try to connect to managesieve server and to fetch the script
+    $this->sieve = new rcube_sieve($_SESSION['username'],
+       $this->rc->decrypt($_SESSION['password']), 
+       $this->rc->config->get('managesieve_host', 'localhost'),
+       $this->rc->config->get('managesieve_port', 2000),
+       $this->rc->config->get('managesieve_usetls', false),
+       $this->rc->config->get('managesieve_disabled_extensions'));
+
+    $error = $this->sieve->error();
+
+    if ($error == SIEVE_ERROR_NOT_EXISTS)
+    {
+      // if script not exists build default script contents
+      $script_file = $this->rc->config->get('managesieve_default');
+      if ($script_file && is_readable($script_file))
+       $this->sieve->script->add_text(file_get_contents($script_file)); 
+      // that's not exactly an error
+      $error = false;
+    }
+    elseif ($error)
+    {
+      switch ($error)
+      {
+       case SIEVE_ERROR_CONNECTION:
+       case SIEVE_ERROR_LOGIN:
+          $this->rc->output->show_message('managesieve.filterconnerror', 'error');  
+       break;
+       default:
+          $this->rc->output->show_message('managesieve.filterunknownerror', 'error');
+       break;
+      }
+
+      // to disable 'Add filter' button set env variable
+      $this->rc->output->set_env('filterconnerror', true);
+    }
+
+    // finally set script objects
+    if ($error)
+    {
+      $this->script = array();
+    }
+    else
+    {
+      $this->script = $this->sieve->script->as_array();
+      $this->exts = $this->sieve->get_extensions();
+    }
+    
+    return $error;
+  }
+
+  function managesieve_init()
+  {
+    // Init plugin and handle managesieve connection
+    $error = $this->managesieve_start();
+
+    // Handle user requests
+    if ($action = get_input_value('_act', RCUBE_INPUT_GPC))
+    {
+      $fid = (int) get_input_value('_fid', RCUBE_INPUT_GET);
+
+      if ($action=='up' && !$error)
+      {
+        if ($fid && isset($this->script[$fid]) && isset($this->script[$fid-1]))
+        {
+          if ($this->sieve->script->update_rule($fid, $this->script[$fid-1]) !== false
+               && $this->sieve->script->update_rule($fid-1, $this->script[$fid]) !== false)
+           $result = $this->sieve->save();
+      
+          if ($result) {
+//          $this->rc->output->show_message('managesieve.filtersaved', 'confirmation');
+           $this->rc->output->command('managesieve_updatelist', 'up', '', $fid);
+          } else
+            $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+        }
+      }
+      elseif ($action=='down' && !$error)
+      {
+        if (isset($this->script[$fid]) && isset($this->script[$fid+1]))
+        {
+          if ($this->sieve->script->update_rule($fid, $this->script[$fid+1]) !== false
+               && $this->sieve->script->update_rule($fid+1, $this->script[$fid]) !== false)
+           $result = $this->sieve->save();
+      
+          if ($result) {
+//          $this->rc->output->show_message('managesieve.filtersaved', 'confirmation');
+           $this->rc->output->command('managesieve_updatelist', 'down', '', $fid);
+          } else
+            $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+        }
+      }
+      elseif ($action=='delete' && !$error)
+      {
+        if (isset($this->script[$fid]))
+        {
+          if ($this->sieve->script->delete_rule($fid))
+            $result = $this->sieve->save();
+
+          if (!$result)
+            $this->rc->output->show_message('managesieve.filterdeleteerror', 'error');
+          else {
+           $this->rc->output->show_message('managesieve.filterdeleted', 'confirmation');
+           $this->rc->output->command('managesieve_updatelist', 'delete', '', $fid);
+          }
+        }
+      }
+      elseif ($action=='ruleadd')
+      {
+        $rid = get_input_value('_rid', RCUBE_INPUT_GPC);
+        $id = $this->genid();
+        $content = $this->rule_div($fid, $id, false);
+
+        $this->rc->output->command('managesieve_rulefill', $content, $id, $rid);
+      }
+      elseif ($action=='actionadd')
+      {
+        $aid = get_input_value('_aid', RCUBE_INPUT_GPC);
+        $id = $this->genid();
+        $content = $this->action_div($fid, $id, false);
+    
+        $this->rc->output->command('managesieve_actionfill', $content, $id, $aid);
+      }
+
+      $this->rc->output->send();
+    }
+
+    $this->managesieve_send();
+  }
+
+  function managesieve_save()
+  {
+    // Init plugin and handle managesieve connection
+    $error = $this->managesieve_start();
+
+    // add/edit action
+    if (isset($_POST['_name']))
+    {
+      $name = trim(get_input_value('_name', RCUBE_INPUT_POST));
+      $fid = trim(get_input_value('_fid', RCUBE_INPUT_POST));
+      $join = trim(get_input_value('_join', RCUBE_INPUT_POST));
+  
+      // and arrays
+      $headers = $_POST['_header'];
+      $cust_headers = $_POST['_custom_header'];
+      $ops = $_POST['_rule_op'];
+      $sizeops = $_POST['_rule_size_op'];
+      $sizeitems = $_POST['_rule_size_item'];
+      $sizetargets = $_POST['_rule_size_target'];
+      $targets = $_POST['_rule_target'];
+      $act_types = $_POST['_action_type'];
+      $mailboxes = $_POST['_action_mailbox'];
+      $act_targets = $_POST['_action_target'];
+      $area_targets = $_POST['_action_target_area'];
+      $reasons = $_POST['_action_reason'];
+      $addresses = $_POST['_action_addresses'];
+      $days = $_POST['_action_days'];
+
+      // we need a "hack" for radiobuttons
+      foreach ($sizeitems as $item)
+       $items[] = $item;
+
+      $this->form['join'] = $join=='allof' ? true : false;
+      $this->form['name'] = $name;
+      $this->form['tests'] = array();
+      $this->form['actions'] = array();
+
+      if ($name == '')
+       $this->errors['name'] = $this->gettext('cannotbeempty');
+      else
+       foreach($this->script as $idx => $rule)
+          if($rule['name'] == $name && $idx != $fid) {
+           $this->errors['name'] = $this->gettext('ruleexist');
+             break;
+          }
+      
+      $i = 0;
+      // rules
+      if ($join == 'any')
+      {
+       $this->form['tests'][0]['test'] = 'true';
+      }
+      else foreach($headers as $idx => $header)
+      {
+       $header = $this->strip_value($header);
+       $target = $this->strip_value($targets[$idx]);
+       $op = $this->strip_value($ops[$idx]);
+
+       // normal header
+       if (in_array($header, $this->headers))
+       {
+          if(preg_match('/^not/', $op))
+           $this->form['tests'][$i]['not'] = true;
+          $type = preg_replace('/^not/', '', $op);
+
+          if ($type == 'exists')
+         {
+           $this->form['tests'][$i]['test'] = 'exists';
+           $this->form['tests'][$i]['arg'] = $header;
+         }
+          else
+          {    
+           $this->form['tests'][$i]['type'] = $type;
+           $this->form['tests'][$i]['test'] = 'header';
+           $this->form['tests'][$i]['arg1'] = $header;
+           $this->form['tests'][$i]['arg2'] = $target;
+
+           if ($target == '')
+              $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty');
+         }
+       }
+       else
+          switch ($header)
+          {
+           case 'size':
+             $sizeop = $this->strip_value($sizeops[$idx]);
+             $sizeitem = $this->strip_value($items[$idx]);
+             $sizetarget = $this->strip_value($sizetargets[$idx]);
+
+              $this->form['tests'][$i]['test'] = 'size';
+              $this->form['tests'][$i]['type'] = $sizeop;
+              $this->form['tests'][$i]['arg'] = $sizetarget.$sizeitem;
+
+             if (!preg_match('/^[0-9]+(K|M|G)*$/i', $sizetarget))
+               $this->errors['tests'][$i]['sizetarget'] = $this->gettext('wrongformat');
+             break;
+           case '...':
+              $cust_header = $headers = $this->strip_value($cust_headers[$idx]);
+
+              if(preg_match('/^not/', $op))
+               $this->form['tests'][$i]['not'] = true;
+             $type = preg_replace('/^not/', '', $op);
+
+              if ($cust_header == '')
+               $this->errors['tests'][$i]['header'] = $this->gettext('cannotbeempty');
+              else {
+               $headers = preg_split('/[\s,]+/', $cust_header, -1, PREG_SPLIT_NO_EMPTY);
+               
+               if (!count($headers))
+                 $this->errors['tests'][$i]['header'] = $this->gettext('cannotbeempty');
+               else {
+                 foreach ($headers as $hr)
+                   if (!preg_match('/^[a-z0-9-]+$/i', $hr))
+                     $this->errors['tests'][$i]['header'] = $this->gettext('forbiddenchars');
+               }
+             }
+             
+             if (empty($this->errors['tests'][$i]['header']))
+               $cust_header = (is_array($headers) && count($headers) == 1) ? $headers[0] : $headers;
+              
+             if ($type == 'exists')
+             {
+               $this->form['tests'][$i]['test'] = 'exists';
+               $this->form['tests'][$i]['arg'] = $cust_header;
+             }
+              else
+             { 
+               $this->form['tests'][$i]['test'] = 'header';
+               $this->form['tests'][$i]['type'] = $type;
+               $this->form['tests'][$i]['arg1'] = $cust_header;
+               $this->form['tests'][$i]['arg2'] = $target;
+
+               if ($target == '')
+                 $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty');
+             }
+           break;
+          }
+       $i++;
+      }
+  
+      $i = 0;
+      // actions
+      foreach($act_types as $idx => $type)
+      {
+       $type = $this->strip_value($type);
+       $target = $this->strip_value($act_targets[$idx]);
+  
+       $this->form['actions'][$i]['type'] = $type;
+    
+       switch ($type)
+       {
+          case 'fileinto':
+           $mailbox = $this->strip_value($mailboxes[$idx]);
+           $this->form['actions'][$i]['target'] = $mailbox;
+          break;
+          case 'reject':
+          case 'ereject':
+           $target = $this->strip_value($area_targets[$idx]);
+           $this->form['actions'][$i]['target'] = str_replace("\r\n", "\n", $target);
+
+ //         if ($target == '')
+//             $this->errors['actions'][$i]['targetarea'] = $this->gettext('cannotbeempty');
+          break;
+          case 'redirect':
+           $this->form['actions'][$i]['target'] = $target;
+
+           if ($this->form['actions'][$i]['target'] == '')
+             $this->errors['actions'][$i]['target'] = $this->gettext('cannotbeempty');
+           else if (!$this->check_email($this->form['actions'][$i]['target']))
+             $this->errors['actions'][$i]['target'] = $this->gettext('noemailwarning');
+         break;
+          case 'vacation':
+           $reason = $this->strip_value($reasons[$idx]);
+           $this->form['actions'][$i]['reason'] = str_replace("\r\n", "\n", $reason);
+           $this->form['actions'][$i]['days'] = $days[$idx];
+           $this->form['actions'][$i]['addresses'] = explode(',', $addresses[$idx]);
+// @TODO: vacation :subject, :mime, :from, :handle
+
+           if ($this->form['actions'][$i]['addresses']) {
+             foreach($this->form['actions'][$i]['addresses'] as $aidx => $address) {
+               $address = trim($address);
+               if (!$address)
+                 unset($this->form['actions'][$i]['addresses'][$aidx]);
+               else if(!$this->check_email($address)) {
+                 $this->errors['actions'][$i]['addresses'] = $this->gettext('noemailwarning');
+                 break;
+               } else
+                 $this->form['actions'][$i]['addresses'][$aidx] = $address;
+             }
+           }
+        
+           if ($this->form['actions'][$i]['reason'] == '')
+             $this->errors['actions'][$i]['reason'] = $this->gettext('cannotbeempty');
+           if ($this->form['actions'][$i]['days'] && !preg_match('/^[0-9]+$/', $this->form['actions'][$i]['days']))
+             $this->errors['actions'][$i]['days'] = $this->gettext('forbiddenchars');
+          break;
+       }
+  
+        $i++;
+      }
+
+      if (!$this->errors)
+      {
+        // zapis skryptu
+        if (!isset($this->script[$fid])) {
+         $fid = $this->sieve->script->add_rule($this->form);
+          $new = true;
+       } else
+          $fid = $this->sieve->script->update_rule($fid, $this->form);
+
+       if ($fid !== false)
+          $save = $this->sieve->save();
+
+       if ($save && $fid !== false)
+       {
+         $this->rc->output->show_message('managesieve.filtersaved', 'confirmation');
+         $this->rc->output->add_script(sprintf("rcmail.managesieve_updatelist('%s', '%s', %d);",
+           isset($new) ? 'add' : 'update', $this->form['name'], $fid), 'foot');
+//       $this->rc->output->command('managesieve_updatelist', isset($new) ? 'add' : 'update', $this->form['name'], $fid);
+//       $this->rc->output->send();
+       }
+       else
+       {
+         $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+//       $this->rc->output->send();
+       }
+      }
+    }
+
+    $this->managesieve_send();
+  }
+
+  private function managesieve_send()
+  {
+    // Handle form action 
+    if (isset($_GET['_framed']) || isset($_POST['_framed']))
+      $this->rc->output->send('managesieve.managesieveedit');
+    else {
+      $this->rc->output->set_pagetitle($this->gettext('filters'));
+      $this->rc->output->send('managesieve.managesieve');
+    }
+  }
+  
+  // return the filters list as HTML table
+  function filters_list($attrib)
+  {
+    // add id to message list table if not specified
+    if (!strlen($attrib['id']))
+      $attrib['id'] = 'rcmfilterslist';
+  
+    // define list of cols to be displayed
+    $a_show_cols = array('managesieve.filtername');
+
+    foreach($this->script as $idx => $filter)
+      $result[] = array('managesieve.filtername' => $filter['name'], 'id' => $idx);
+    
+    // create XHTML table
+    $out = rcube_table_output($attrib, $result, $a_show_cols, 'id');
+
+    // set client env
+    $this->rc->output->add_gui_object('filterslist', $attrib['id']);
+    $this->rc->output->include_script('list.js');
+  
+    // add some labels to client
+    $this->rc->output->add_label('managesieve.filterconfirmdelete');
+  
+    return $out;
+  }
+
+  function filter_frame($attrib)
+  {
+    if (!$attrib['id'])
+      $attrib['id'] = 'rcmfilterframe';
+    
+    $attrib['name'] = $attrib['id'];
+
+    $this->rc->output->set_env('contentframe', $attrib['name']);
+    $this->rc->output->set_env('blankpage', $attrib['src'] ? 
+       $this->rc->output->abs_url($attrib['src']) : 'program/blank.gif');
+
+    return html::tag('iframe', $attrib);
+  }
+
+
+  function filter_form($attrib)
+  {
+    if (!$attrib['id'])
+      $attrib['id'] = 'rcmfilterform';
+
+    $fid = get_input_value('_fid', RCUBE_INPUT_GPC);
+    $scr = isset($this->form) ? $this->form : $this->script[$fid];
+
+    $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $this->rc->task));
+    $hiddenfields->add(array('name' => '_action', 'value' => 'plugin.managesieve-save'));
+    $hiddenfields->add(array('name' => '_framed', 'value' => ($_POST['_framed'] || $_GET['_framed'] ? 1 : 0)));
+    $hiddenfields->add(array('name' => '_fid', 'value' => $fid));
+
+    $out = '<form name="filterform" action="./" method="post">'."\n";
+    $out .= $hiddenfields->show();
+
+    // 'any' flag 
+    if (sizeof($scr['tests']) == 1 && $scr['tests'][0]['test'] == 'true' && !$scr['tests'][0]['not'])
+      $any = true; 
+
+    // filter name input
+    $field_id = '_name';
+    $input_name = new html_inputfield(array('name' => '_name', 'id' => $field_id, 'size' => 30,
+       'class' => ($this->errors['name'] ? 'error' : '')));
+
+    if (isset($scr))
+      $input_name = $input_name->show($scr['name']);
+    else
+      $input_name = $input_name->show();
+
+    $out .= sprintf("\n<label for=\"%s\"><b>%s:</b></label> %s<br /><br />\n",
+               $field_id, Q($this->gettext('filtername')), $input_name);
+
+    $out .= '<fieldset><legend>' . Q($this->gettext('messagesrules')) . "</legend>\n";
+
+    // any, allof, anyof radio buttons
+    $field_id = '_allof';
+    $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'allof',
+       'onclick' => 'rule_join_radio(\'allof\')', 'class' => 'radio'));
+
+    if (isset($scr) && !$any)
+      $input_join = $input_join->show($scr['join'] ? 'allof' : '');
+    else
+      $input_join = $input_join->show();
+
+    $out .= sprintf("%s<label for=\"%s\">%s</label>&nbsp;\n",
+               $input_join, $field_id, Q($this->gettext('filterallof')));
+
+    $field_id = '_anyof';
+    $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'anyof',
+       'onclick' => 'rule_join_radio(\'anyof\')', 'class' => 'radio'));
+
+    if (isset($scr) && !$any)
+      $input_join = $input_join->show($scr['join'] ? '' : 'anyof');
+    else
+      $input_join = $input_join->show('anyof'); // default
+
+    $out .= sprintf("%s<label for=\"%s\">%s</label>\n",
+               $input_join, $field_id, Q($this->gettext('filteranyof')));
+
+    $field_id = '_any';
+    $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'any',
+       'onclick' => 'rule_join_radio(\'any\')', 'class' => 'radio'));
+
+    $input_join = $input_join->show($any ? 'any' : '');
+
+    $out .= sprintf("%s<label for=\"%s\">%s</label>\n",
+               $input_join, $field_id, Q($this->gettext('filterany')));
+
+    $rows_num = isset($scr) ? sizeof($scr['tests']) : 1;
+
+    $out .= '<div id="rules"'.($any ? ' style="display: none"' : '').'>';
+    for ($x=0; $x<$rows_num; $x++)
+      $out .= $this->rule_div($fid, $x);
+    $out .= "</div>\n";
+
+    $out .= "</fieldset>\n";
+
+    // actions
+    $out .= '<fieldset><legend>' . Q($this->gettext('messagesactions')) . "</legend>\n";
+
+    $rows_num = isset($scr) ? sizeof($scr['actions']) : 1;
+
+    $out .= '<div id="actions">';
+    for ($x=0; $x<$rows_num; $x++)
+      $out .= $this->action_div($fid, $x);
+    $out .= "</div>\n";
+
+    $out .= "</fieldset>\n";
+
+    $this->rc->output->add_label('managesieve.ruledeleteconfirm');
+    $this->rc->output->add_label('managesieve.actiondeleteconfirm');
+    $this->rc->output->add_gui_object('sieveform', 'filterform');
+
+    return $out;
+  }
+
+  function rule_div($fid, $id, $div=true)
+  {
+    $rule = isset($this->form) ? $this->form['tests'][$id] : $this->script[$fid]['tests'][$id];
+    $rows_num = isset($this->form) ? sizeof($this->form['tests']) : sizeof($this->script[$fid]['tests']);
+  
+    $out = $div ? '<div class="rulerow" id="rulerow' .$id .'">'."\n" : '';
+
+    $out .= '<table><tr><td class="rowactions">';
+
+    // headers select
+    $select_header = new html_select(array('name' => "_header[]", 'id' => 'header'.$id,
+       'onchange' => 'header_select(' .$id .')'));
+    foreach($this->headers as $name => $val)
+      $select_header->add(Q($this->gettext($name)), Q($val));
+    $select_header->add(Q($this->gettext('size')), 'size');
+    $select_header->add(Q($this->gettext('...')), '...');
+
+    // TODO: list arguments
+
+    if ((isset($rule['test']) && $rule['test'] == 'header')
+       && !is_array($rule['arg1']) && in_array($rule['arg1'], $this->headers))
+      $out .= $select_header->show($rule['arg1']);
+    elseif ((isset($rule['test']) && $rule['test'] == 'exists')
+       && !is_array($rule['arg']) && in_array($rule['arg'], $this->headers))
+      $out .= $select_header->show($rule['arg']);
+    elseif (isset($rule['test']) && $rule['test'] == 'size')
+      $out .= $select_header->show('size');
+    elseif (isset($rule['test']) && $rule['test'] != 'true')
+      $out .= $select_header->show('...');
+    else
+      $out .= $select_header->show();
+
+    $out .= '</td><td class="rowtargets">';
+
+    if ((isset($rule['test']) && $rule['test'] == 'header')
+       && (is_array($rule['arg1']) || !in_array($rule['arg1'], $this->headers)))
+      $custom = is_array($rule['arg1']) ? implode(', ', $rule['arg1']) : $rule['arg1'];
+    elseif ((isset($rule['test']) && $rule['test'] == 'exists')
+       && (is_array($rule['arg']) || !in_array($rule['arg'], $this->headers)))
+      $custom = is_array($rule['arg']) ? implode(', ', $rule['arg']) : $rule['arg'];
+    
+    $out .= '<div id="custom_header' .$id. '" style="display:' .(isset($custom) ? 'inline' : 'none'). '">
+       <input type="text" name="_custom_header[]" '. $this->error_class($id, 'test', 'header')
+       .' value="' .Q($custom). '" size="20" />&nbsp;</div>' . "\n";
+  
+    // matching type select (operator)
+    $select_op = new html_select(array('name' => "_rule_op[]", 'id' => 'rule_op'.$id, 
+       'style' => 'display:' .($rule['test']!='size' ? 'inline' : 'none'), 'onchange' => 'rule_op_select('.$id.')'));
+    $select_op->add(Q($this->gettext('filtercontains')), 'contains');
+    $select_op->add(Q($this->gettext('filternotcontains')), 'notcontains');
+    $select_op->add(Q($this->gettext('filteris')), 'is');
+    $select_op->add(Q($this->gettext('filterisnot')), 'notis');
+    $select_op->add(Q($this->gettext('filterexists')), 'exists');
+    $select_op->add(Q($this->gettext('filternotexists')), 'notexists');
+//    $select_op->add(Q($this->gettext('filtermatches')), 'matches');
+//    $select_op->add(Q($this->gettext('filternotmatches')), 'notmatches');
+
+    // target input (TODO: lists)
+
+    if ($rule['test'] == 'header')
+    {
+      $out .= $select_op->show(($rule['not'] ? 'not' : '').$rule['type']);
+      $target = $rule['arg2'];
+    }
+    elseif ($rule['test'] == 'size')
+    {
+      $out .= $select_op->show();
+      if(preg_match('/^([0-9]+)(K|M|G)*$/', $rule['arg'], $matches))
+      {
+       $sizetarget = $matches[1];
+       $sizeitem = $matches[2];
+      }
+    }
+    else
+    {
+      $out .= $select_op->show(($rule['not'] ? 'not' : '').$rule['test']);
+      $target = '';
+    }
+
+    $out .= '<input type="text" name="_rule_target[]" id="rule_target' .$id. '" 
+       value="' .Q($target). '" size="20" ' . $this->error_class($id, 'test', 'target') 
+       . ' style="display:' . ($rule['test']!='size' && $rule['test'] != 'exists' ? 'inline' : 'none') . '" />'."\n";
+
+    $select_size_op = new html_select(array('name' => "_rule_size_op[]", 'id' => 'rule_size_op'.$id));
+    $select_size_op->add(Q($this->gettext('filterunder')), 'under');
+    $select_size_op->add(Q($this->gettext('filterover')), 'over');
+
+    $out .= '<div id="rule_size' .$id. '" style="display:' . ($rule['test']=='size' ? 'inline' : 'none') .'">';
+    $out .= $select_size_op->show($rule['test']=='size' ? $rule['type'] : '');
+    $out .= '<input type="text" name="_rule_size_target[]" value="'.$sizetarget.'" size="10" ' . $this->error_class($id, 'test', 'sizetarget') .' />
+       <input type="radio" name="_rule_size_item['.$id.']" value=""'. (!$sizeitem ? ' checked="checked"' : '') .' class="radio" />B
+       <input type="radio" name="_rule_size_item['.$id.']" value="K"'. ($sizeitem=='K' ? ' checked="checked"' : '') .' class="radio" />kB
+       <input type="radio" name="_rule_size_item['.$id.']" value="M"'. ($sizeitem=='M' ? ' checked="checked"' : '') .' class="radio" />MB
+       <input type="radio" name="_rule_size_item['.$id.']" value="G"'. ($sizeitem=='G' ? ' checked="checked"' : '') .' class="radio" />GB';
+    $out .= '</div>';
+    $out .= '</td>';
+  
+    // add/del buttons
+    $out .= '<td class="rowbuttons">';
+    $out .= '<input type="button" id="ruleadd' . $id .'" value="'. Q($this->gettext('add')). '" 
+       onclick="rcmail.managesieve_ruleadd(' . $id .')" class="button" /> ';
+    $out .= '<input type="button" id="ruledel' . $id .'" value="'. Q($this->gettext('del')). '"
+       onclick="rcmail.managesieve_ruledel(' . $id .')" class="button' . ($rows_num<2 ? ' disabled' : '') .'"'
+       . ($rows_num<2 ? ' disabled="disabled"' : '') .' />';
+    $out .= '</td></tr></table>';
+
+    $out .= $div ? "</div>\n" : '';
+        
+    return $out;
+  }
+
+  function action_div($fid, $id, $div=true)
+  {
+    $action = isset($this->form) ? $this->form['actions'][$id] : $this->script[$fid]['actions'][$id];
+    $rows_num = isset($this->form) ? sizeof($this->form['actions']) : sizeof($this->script[$fid]['actions']);
+
+    $out = $div ? '<div class="actionrow" id="actionrow' .$id .'">'."\n" : '';
+
+    $out .= '<table><tr><td class="rowactions">';
+
+    // action select
+    $select_action = new html_select(array('name' => "_action_type[]", 'id' => 'action_type'.$id,
+       'onchange' => 'action_type_select(' .$id .')'));
+    if (in_array('fileinto', $this->exts))
+      $select_action->add(Q($this->gettext('messagemoveto')), 'fileinto');
+    $select_action->add(Q($this->gettext('messageredirect')), 'redirect');
+    if (in_array('reject', $this->exts))
+      $select_action->add(Q($this->gettext('messagediscard')), 'reject');
+    elseif (in_array('ereject', $this->exts))
+      $select_action->add(Q($this->gettext('messagediscard')), 'ereject');
+    if (in_array('vacation', $this->exts))
+      $select_action->add(Q($this->gettext('messagereply')), 'vacation');
+    $select_action->add(Q($this->gettext('messagedelete')), 'discard');
+    $select_action->add(Q($this->gettext('rulestop')), 'stop');
+
+    $out .= $select_action->show($action['type']);
+    $out .= '</td>';
+
+    // actions target inputs
+    $out .= '<td class="rowtargets">';
+    // shared targets
+    $out .= '<input type="text" name="_action_target[]" id="action_target' .$id. '" '
+       .'value="' .($action['type']=='redirect' ? Q($action['target'], 'strict', false) : ''). '" size="40" '
+       .'style="display:' .($action['type']=='redirect' ? 'inline' : 'none') .'" '
+       . $this->error_class($id, 'action', 'target') .' />';
+    $out .= '<textarea name="_action_target_area[]" id="action_target_area' .$id. '" '
+       .'rows="3" cols="40" '. $this->error_class($id, 'action', 'targetarea')
+       .'style="display:' .(in_array($action['type'], array('reject', 'ereject')) ? 'inline' : 'none') .'">'
+       . (in_array($action['type'], array('reject', 'ereject')) ? Q($action['target'], 'strict', false) : '')
+       . "</textarea>\n";
+
+    // vacation
+    $out .= '<div id="action_vacation' .$id.'" style="display:' .($action['type']=='vacation' ? 'inline' : 'none') .'">';
+    $out .= '<span class="label">'. Q($this->gettext('vacationreason')) .'</span><br />'
+       .'<textarea name="_action_reason[]" id="action_reason' .$id. '" '
+       .'rows="3" cols="40" '. $this->error_class($id, 'action', 'reason') . '>'
+       . Q($action['reason'], 'strict', false) . "</textarea>\n";
+    $out .= '<br /><span class="label">' .Q($this->gettext('vacationaddresses')) . '</span><br />'
+       .'<input type="text" name="_action_addresses[]" '
+        .'value="' . (is_array($action['addresses']) ? Q(implode(', ', $action['addresses']), 'strict', false) : $action['addresses']) . '" size="40" '
+        . $this->error_class($id, 'action', 'addresses') .' />';
+    $out .= '<br /><span class="label">' . Q($this->gettext('vacationdays')) . '</span><br />'
+       .'<input type="text" name="_action_days[]" '
+        .'value="' .Q($action['days'], 'strict', false) . '" size="2" '
+        . $this->error_class($id, 'action', 'days') .' />';
+    $out .= '</div>';
+
+    // mailbox select
+    $out .= '<select id="action_mailbox' .$id. '" name="_action_mailbox[]" style="display:' 
+       .(!isset($action) || $action['type']=='fileinto' ? 'inline' : 'none'). '">';
+
+    $this->rc->imap_init(true);
+
+    $a_folders = $this->rc->imap->list_mailboxes();
+    $delimiter = $this->rc->imap->get_hierarchy_delimiter();
+
+    if ($action['type'] == 'fileinto')
+      $mailbox = $action['target'];
+    else
+      $mailbox = '';
+
+    foreach ($a_folders as $folder)
+    {
+      $utf7folder = $this->rc->imap->mod_mailbox($folder);
+      $names = explode($delimiter, rcube_charset_convert($folder, 'UTF7-IMAP'));
+      $name = $names[sizeof($names)-1];
+    
+      if ($replace_delimiter = $this->rc->config->get('managesieve_replace_delimiter'))
+        $utf7folder = str_replace($delimiter, $replace_delimiter, $utf7folder);
+    
+      if ($folder_class = rcmail_folder_classname($name))
+        $foldername = $this->gettext($folder_class);
+      else
+        $foldername = $name;
+
+      $out .= sprintf('<option value="%s"%s>%s%s</option>'."\n",
+                    htmlspecialchars($utf7folder),
+                   ($mailbox == $utf7folder ? ' selected="selected"' : ''),
+                   str_repeat('&nbsp;', 4 * (sizeof($names)-1)),
+                   Q(abbreviate_string($foldername, 40 - (2 * sizeof($names)-1))));
+    }
+    $out .= '</select>';
+    $out .= '</td>';
+
+    // add/del buttons
+    $out .= '<td class="rowbuttons">';
+    $out .= '<input type="button" id="actionadd' . $id .'" value="'. Q($this->gettext('add')). '" 
+       onclick="rcmail.managesieve_actionadd(' . $id .')" class="button" /> ';
+    $out .= '<input type="button" id="actiondel' . $id .'" value="'. Q($this->gettext('del')). '"
+        onclick="rcmail.managesieve_actiondel(' . $id .')" class="button' . ($rows_num<2 ? ' disabled' : '') .'"'
+       . ($rows_num<2 ? ' disabled="disabled"' : '') .' />';
+    $out .= '</td>';
+  
+    $out .= '</tr></table>';
+
+    $out .= $div ? "</div>\n" : '';
+
+    return $out;
+  }
+
+  private function genid()
+  {
+    $result = intval(rcube_timer());
+    return $result;
+  }
+
+  private function strip_value($str)
+  {
+    return trim(strip_tags($str));
+  }
+
+  private function error_class($id, $type, $target, $name_only=false)
+  {
+    // TODO: tooltips
+    if ($type == 'test' && isset($this->errors['tests'][$id][$target]))
+      return ($name_only ? 'error' : ' class="error"');
+    elseif ($type == 'action' && isset($this->errors['actions'][$id][$target]))
+      return ($name_only ? 'error' : ' class="error"');
+
+    return '';
+  }
+
+  private function check_email($email)
+  {
+    // Check for invalid characters
+    if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $email))
+      return false;
+
+    // Check that there's one @ symbol, and that the lengths are right
+    if (!preg_match('/^[^@]{1,64}@[^@]{1,255}$/', $email))
+      return false;
+
+    // Split it into sections to make life easier
+    $email_array = explode('@', $email);
+
+    // Check local part
+    $local_array = explode('.', $email_array[0]);
+    foreach ($local_array as $local_part)
+      if (!preg_match('/^(([A-Za-z0-9!#$%&\'*+\/=?^_`{|}~-]+)|("[^"]+"))$/', $local_part))
+        return false;
+
+    // Check domain part
+    if (preg_match('/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$/', $email_array[1]) 
+      || preg_match('/^\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]$/', $email_array[1]))
+      return true; // If an IP address
+    else
+    { // If not an IP address
+      $domain_array = explode('.', $email_array[1]);
+      if (sizeof($domain_array) < 2)
+        return false; // Not enough parts to be a valid domain
+
+      foreach ($domain_array as $domain_part)
+        if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]))$/', $domain_part))
+         return false;
+
+      return true;
+    }
+  
+    return false;
+  }
+}
+
+?>
diff --git a/plugins/managesieve/skins/default/filter_add_act.png b/plugins/managesieve/skins/default/filter_add_act.png
new file mode 100644 (file)
index 0000000..d8915dc
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_add_act.png differ
diff --git a/plugins/managesieve/skins/default/filter_add_pas.png b/plugins/managesieve/skins/default/filter_add_pas.png
new file mode 100644 (file)
index 0000000..b5be806
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_add_pas.png differ
diff --git a/plugins/managesieve/skins/default/filter_add_sel.png b/plugins/managesieve/skins/default/filter_add_sel.png
new file mode 100644 (file)
index 0000000..8cb0593
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_add_sel.png differ
diff --git a/plugins/managesieve/skins/default/filter_del_act.png b/plugins/managesieve/skins/default/filter_del_act.png
new file mode 100644 (file)
index 0000000..1974417
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_del_act.png differ
diff --git a/plugins/managesieve/skins/default/filter_del_pas.png b/plugins/managesieve/skins/default/filter_del_pas.png
new file mode 100644 (file)
index 0000000..9f17e38
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_del_pas.png differ
diff --git a/plugins/managesieve/skins/default/filter_del_sel.png b/plugins/managesieve/skins/default/filter_del_sel.png
new file mode 100644 (file)
index 0000000..483ffc0
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_del_sel.png differ
diff --git a/plugins/managesieve/skins/default/filter_down_act.png b/plugins/managesieve/skins/default/filter_down_act.png
new file mode 100644 (file)
index 0000000..7a24a4f
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_down_act.png differ
diff --git a/plugins/managesieve/skins/default/filter_down_pas.png b/plugins/managesieve/skins/default/filter_down_pas.png
new file mode 100644 (file)
index 0000000..ac65239
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_down_pas.png differ
diff --git a/plugins/managesieve/skins/default/filter_down_sel.png b/plugins/managesieve/skins/default/filter_down_sel.png
new file mode 100644 (file)
index 0000000..b7a9e67
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_down_sel.png differ
diff --git a/plugins/managesieve/skins/default/filter_up_act.png b/plugins/managesieve/skins/default/filter_up_act.png
new file mode 100644 (file)
index 0000000..fd9689b
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_up_act.png differ
diff --git a/plugins/managesieve/skins/default/filter_up_pas.png b/plugins/managesieve/skins/default/filter_up_pas.png
new file mode 100644 (file)
index 0000000..c60226c
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_up_pas.png differ
diff --git a/plugins/managesieve/skins/default/filter_up_sel.png b/plugins/managesieve/skins/default/filter_up_sel.png
new file mode 100644 (file)
index 0000000..de4c5c3
Binary files /dev/null and b/plugins/managesieve/skins/default/filter_up_sel.png differ
diff --git a/plugins/managesieve/skins/default/managesieve.css b/plugins/managesieve/skins/default/managesieve.css
new file mode 100644 (file)
index 0000000..ce24936
--- /dev/null
@@ -0,0 +1,157 @@
+/***** RoundCube|Filters styles *****/
+
+
+#filterslist
+{
+  position: absolute;
+  left: 20px;
+  width: 220px;
+  top: 130px;
+  bottom: 30px;
+  border: 1px solid #999999;
+  background-color: #F9F9F9;
+  overflow: auto;
+  /* css hack for IE */
+  height: expression((parseInt(document.documentElement.clientHeight)-155)+'px');
+}
+
+#filters-table
+{
+  width: 100%;
+  table-layout: fixed;
+  /* css hack for IE */
+  width: expression(document.getElementById('filterslist').clientWidth);
+}
+
+#filters-table tbody td
+{
+  cursor: pointer;
+}
+
+#filtersbuttons
+{
+  position: absolute;
+  left: 20px;
+  top: 95px;
+}
+
+#filter-box
+{
+  position: absolute;
+  top: 95px;
+  left: 250px;
+  right: 20px;
+  bottom: 30px;
+  border: 1px solid #999999;
+  overflow: hidden;
+  /* css hack for IE */
+  width: expression((parseInt(document.documentElement.clientWidth)-30-parseInt(document.getElementById('filterslist').offsetLeft)-parseInt(document.getElementById('filterslist').offsetWidth))+'px');
+  height: expression((parseInt(document.documentElement.clientHeight)-120)+'px');
+}
+
+#filter-frame
+{
+  background-color: #F9F9F9;
+  border: none;
+}
+
+body.iframe
+{
+  background-color: #F9F9F9;
+  min-width: 740px;
+  width: expression(Math.max(740, document.documentElement.clientWidth)+'px');
+}
+
+#filter-form
+{
+  min-width: 650px;
+  white-space: nowrap;
+  background-color: #F9F9F9;
+  padding: 20px 10px 10px 10px;
+}
+
+#filter-form input, select
+{
+  font-size: 10pt;
+  font-family: inherit;
+}
+
+fieldset
+{
+  background-color: white;
+}
+
+legend, label
+{
+  color: #666666;
+}
+
+#rules, #actions
+{
+  margin-top: 5px;
+  width: 100%;
+  padding: 0;
+  border-collapse: collapse;
+}
+
+div.rulerow, div.actionrow
+{
+  width: 100%;
+  padding: 2px;
+  white-space: nowrap;
+  float: left;
+  border: 1px solid white;
+  display: block;
+}
+
+div.rulerow:hover, div.actionrow:hover
+{
+  padding: 2px;
+  white-space: nowrap;
+  display: block;
+  float: left;
+  background: #F2F2F2;
+  border: 1px solid silver;
+}
+
+div.rulerow table, div.actionrow table
+{
+  width: 100%;
+  padding: 0px;
+}
+
+td.rowbuttons
+{
+  width: 98%;
+  text-align: right;
+  white-space: nowrap;
+}
+
+td.rowactions, td.rowtargets
+{
+  width: 1%;
+  white-space: nowrap;
+}
+
+input.disabled, input.disabled:hover
+{
+  color: #999999;
+}
+
+input.error, textarea.error
+{
+  background-color: #FFFF88;
+}
+
+input.box,
+input.radio
+{
+  border: 0;
+}
+
+span.label
+{
+  color: #666666;
+  font-size: 10px;
+  white-space: nowrap;
+}
diff --git a/plugins/managesieve/skins/default/templates/managesieve.html b/plugins/managesieve/skins/default/templates/managesieve.html
new file mode 100644 (file)
index 0000000..d5dd6c4
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/managesieve.css" />
+<script type="text/javascript" src="/functions.js"></script>
+</head>
+<body>
+
+<roundcube:include file="/includes/taskbar.html" />
+<roundcube:include file="/includes/header.html" />
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="filtersbuttons">
+<roundcube:button command="plugin.managesieve-add" imageSel="/this/filter_add_sel.png" imagePas="/this/filter_add_pas.png" imageAct="/this/filter_add_act.png" width="32" height="32" title="managesieve.filteradd" />
+<roundcube:button command="plugin.managesieve-del" imageSel="/this/filter_del_sel.png" imagePas="/this/filter_del_pas.png" imageAct="/this/filter_del_act.png"  width="32" height="32" title="managesieve.filterdel" />
+<roundcube:button command="plugin.managesieve-up" imageSel="/this/filter_up_sel.png" imagePas="/this/filter_up_pas.png" imageAct="/this/filter_up_act.png"  width="32" height="32" title="managesieve.moveup" />
+<roundcube:button command="plugin.managesieve-down" imageSel="/this/filter_down_sel.png" imagePas="/this/filter_down_pas.png" imageAct="/this/filter_down_act.png"  width="32" height="32" title="managesieve.movedown" />
+</div>
+
+<div id="filterslist">
+<roundcube:object name="filterslist" id="filters-table" class="records-table" cellspacing="0" summary="Filters list" />
+</div>
+
+<div id="filter-box">
+<roundcube:object name="filterframe" id="filter-frame" width="100%" height="100%" frameborder="0" src="/watermark.html" />
+</div>
+
+</body>
+</html>
diff --git a/plugins/managesieve/skins/default/templates/managesieveedit.html b/plugins/managesieve/skins/default/templates/managesieveedit.html
new file mode 100644 (file)
index 0000000..2302073
--- /dev/null
@@ -0,0 +1,109 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/managesieve.css" />
+</head>
+<body class="iframe">
+
+<script type="text/javascript">
+
+function header_select(id)
+{
+    var obj = document.getElementById('header'+id);
+
+    if (obj.value == 'size')
+    {
+       document.getElementById('rule_size' + id).style.display = 'inline';
+       document.getElementById('rule_op' + id).style.display = 'none';
+       document.getElementById('rule_target' + id).style.display = 'none';
+       document.getElementById('custom_header' + id).style.display = 'none';
+    }
+    else
+    {
+       if (obj.value != '...')
+           document.getElementById('custom_header' + id).style.display = 'none';
+       else
+           document.getElementById('custom_header' + id).style.display = 'inline';
+    
+       document.getElementById('rule_size' + id).style.display = 'none';
+       document.getElementById('rule_op' + id).style.display = 'inline';
+       rule_op_select(id);
+    }
+}
+
+function rule_op_select(id)
+{
+    var obj = document.getElementById('rule_op'+id);
+
+    if (obj.value == 'exists' || obj.value == 'notexists')
+    {
+       document.getElementById('rule_target' + id).style.display = 'none';
+    }
+    else
+    {
+       document.getElementById('rule_target' + id).style.display = 'inline';
+    }
+}
+
+function action_type_select(id)
+{
+    var obj = document.getElementById('action_type'+id);
+
+    if (obj.value == 'fileinto')
+    {
+       document.getElementById('action_mailbox' + id).style.display = 'inline';
+       document.getElementById('action_target' + id).style.display = 'none';
+       document.getElementById('action_target_area' + id).style.display = 'none';
+       document.getElementById('action_vacation' + id).style.display = 'none';
+    }
+    else if (obj.value == 'redirect')
+    {
+       document.getElementById('action_target' + id).style.display = 'inline';
+       document.getElementById('action_mailbox' + id).style.display = 'none';
+       document.getElementById('action_target_area' + id).style.display = 'none';
+       document.getElementById('action_vacation' + id).style.display = 'none';
+    }
+    else if (obj.value.match(/^reject|ereject$/))
+    {
+       document.getElementById('action_target_area' + id).style.display = 'inline';
+       document.getElementById('action_vacation' + id).style.display = 'none';
+       document.getElementById('action_target' + id).style.display = 'none';
+       document.getElementById('action_mailbox' + id).style.display = 'none';
+    }
+    else if (obj.value == 'vacation')
+    {
+       document.getElementById('action_vacation' + id).style.display = 'inline';
+        document.getElementById('action_target_area' + id).style.display = 'none';
+       document.getElementById('action_target' + id).style.display = 'none';
+       document.getElementById('action_mailbox' + id).style.display = 'none';
+    }
+    else // discard, keep, stop
+    {
+       document.getElementById('action_target_area' + id).style.display = 'none';
+       document.getElementById('action_vacation' + id).style.display = 'none';
+       document.getElementById('action_target' + id).style.display = 'none';
+       document.getElementById('action_mailbox' + id).style.display = 'none';
+    }
+}
+
+function rule_join_radio(value)
+{
+    document.getElementById('rules').style.display = (value=='any' ? 'none' : 'block');
+}
+</script>
+
+<div id="filter-form">
+<roundcube:object name="filterform" />
+
+<p>
+<roundcube:button command="plugin.managesieve-save" type="input" class="button mainaction" label="save" />
+</p>
+
+</form>
+</div>
+
+
+</body>
+</html>
diff --git a/plugins/markasjunk/junk_act.png b/plugins/markasjunk/junk_act.png
new file mode 100644 (file)
index 0000000..b5a84f6
Binary files /dev/null and b/plugins/markasjunk/junk_act.png differ
diff --git a/plugins/markasjunk/junk_pas.png b/plugins/markasjunk/junk_pas.png
new file mode 100644 (file)
index 0000000..b88a561
Binary files /dev/null and b/plugins/markasjunk/junk_pas.png differ
diff --git a/plugins/markasjunk/localization/en_US.inc b/plugins/markasjunk/localization/en_US.inc
new file mode 100644 (file)
index 0000000..6f63e16
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Mark as Junk';
+$labels['reportedasjunk'] = 'Successfully reported as Junk';
+
+?>
\ No newline at end of file
diff --git a/plugins/markasjunk/localization/et_EE.inc b/plugins/markasjunk/localization/et_EE.inc
new file mode 100644 (file)
index 0000000..daf1405
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Märgista Rämpsuks';
+$labels['reportedasjunk'] = 'Edukalt Rämpsuks märgitud';
+
+?>
diff --git a/plugins/markasjunk/localization/pl_PL.inc b/plugins/markasjunk/localization/pl_PL.inc
new file mode 100644 (file)
index 0000000..a98f0aa
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Oznacz jako SPAM';
+$labels['reportedasjunk'] = 'Pomyślnie oznaczono jako SPAM';
+
+?>
diff --git a/plugins/markasjunk/localization/sv_SE.inc b/plugins/markasjunk/localization/sv_SE.inc
new file mode 100644 (file)
index 0000000..f4c5959
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['buttontitle'] = 'Märk som skräp';
+$labels['reportedasjunk'] = 'Framgångsrikt rapporterat som skräp';
+
+?>
\ No newline at end of file
diff --git a/plugins/markasjunk/markasjunk.js b/plugins/markasjunk/markasjunk.js
new file mode 100644 (file)
index 0000000..8b02d74
--- /dev/null
@@ -0,0 +1,28 @@
+/* Mark-as-Junk plugin script */
+
+function rcmail_markasjunk(prop)
+{
+  if (!rcmail.env.uid && (!rcmail.message_list || !rcmail.message_list.get_selection().length))
+    return;
+  
+    var uids = rcmail.env.uid ? rcmail.env.uid : rcmail.message_list.get_selection().join(',');
+    
+    rcmail.set_busy(true, 'loading');
+    rcmail.http_post('plugin.markasjunk', '_uid='+uids+'&_mbox='+urlencode(rcmail.env.mailbox), true);
+}
+
+// callback for app-onload event
+if (window.rcmail) {
+  rcmail.addEventListener('init', function(evt) {
+    
+    // register command (directly enable in message view mode)
+    rcmail.register_command('plugin.markasjunk', rcmail_markasjunk, rcmail.env.uid);
+    
+    // add event-listener to message list
+    if (rcmail.message_list)
+      rcmail.message_list.addEventListener('select', function(list){
+        rcmail.enable_command('plugin.markasjunk', list.get_selection().length > 0);
+      });
+  })
+}
+
diff --git a/plugins/markasjunk/markasjunk.php b/plugins/markasjunk/markasjunk.php
new file mode 100644 (file)
index 0000000..959111d
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * Mark as Junk
+ *
+ * Sample plugin that adds a new button to the mailbox toolbar
+ * to mark the selected messages as Junk and move them to the Junk folder
+ *
+ * @version 1.0
+ * @author Thomas Bruederli
+ */
+class markasjunk extends rcube_plugin
+{
+  public $task = 'mail';
+
+  function init()
+  {
+    $this->register_action('plugin.markasjunk', array($this, 'request_action'));
+    $GLOBALS['IMAP_FLAGS']['JUNK'] = 'Junk';
+    
+    $rcmail = rcmail::get_instance();
+    if ($rcmail->action == '' || $rcmail->action == 'show') {
+      $this->include_script('markasjunk.js');
+      $this->add_texts('localization', true);
+      $this->add_button(array('command' => 'plugin.markasjunk', 'imagepas' => 'junk_pas.png', 'imageact' => 'junk_act.png'), 'toolbar');
+    }
+  }
+
+  function request_action()
+  {
+    $this->add_texts('localization');
+    
+    $uids = get_input_value('_uid', RCUBE_INPUT_POST);
+    $mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
+    
+    $rcmail = rcmail::get_instance();
+    $rcmail->imap->set_flag($uids, 'JUNK');
+    
+    if (($junk_mbox = $rcmail->config->get('junk_mbox')) && $mbox != $junk_mbox) {
+      $rcmail->output->command('move_messages', $junk_mbox);
+    }
+    
+    $rcmail->output->command('display_message', $this->gettext('reportedasjunk'), 'confirmation');
+    $rcmail->output->send();
+  }
+
+}
\ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/de_CH.inc b/plugins/new_user_dialog/localization/de_CH.inc
new file mode 100644 (file)
index 0000000..d2a1310
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['identitydialogtitle'] = 'Bitte vervollständigen Sie Ihre Absender-Informationen';
+$labels['identitydialoghint'] = 'Dieser Dialog erscheint nur einmal beim ersten Login.';
+
+?>
\ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/de_DE.inc b/plugins/new_user_dialog/localization/de_DE.inc
new file mode 100644 (file)
index 0000000..d2a1310
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['identitydialogtitle'] = 'Bitte vervollständigen Sie Ihre Absender-Informationen';
+$labels['identitydialoghint'] = 'Dieser Dialog erscheint nur einmal beim ersten Login.';
+
+?>
\ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/en_US.inc b/plugins/new_user_dialog/localization/en_US.inc
new file mode 100644 (file)
index 0000000..d9f531b
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['identitydialogtitle'] = 'Please complete your sender identity';
+$labels['identitydialoghint'] = 'This box only appears once at the first login.';
+
+?>
\ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/et_EE.inc b/plugins/new_user_dialog/localization/et_EE.inc
new file mode 100644 (file)
index 0000000..7c6b3f2
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['identitydialogtitle'] = 'Palun täida oma saatja identiteet';
+$labels['identitydialoghint'] = 'See kast ilmub ainult esimesel sisselogimisel.';
+
+?>
diff --git a/plugins/new_user_dialog/localization/pl_PL.inc b/plugins/new_user_dialog/localization/pl_PL.inc
new file mode 100644 (file)
index 0000000..a385836
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['identitydialogtitle'] = 'Uzupełnij tożsamość nadawcy';
+$labels['identitydialoghint'] = 'To okno pojawia się tylko przy pierwszym logowaniu.';
+
+?>
diff --git a/plugins/new_user_dialog/localization/sv_SE.inc b/plugins/new_user_dialog/localization/sv_SE.inc
new file mode 100644 (file)
index 0000000..b3e665e
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+$labels = array();
+$labels['identitydialogtitle'] = 'Vänligen fyll i namn och avsändaradress under personliga inställningar';
+$labels['identitydialoghint'] = 'Informationen visas endast vid första inloggningen.';
+
+?>
\ No newline at end of file
diff --git a/plugins/new_user_dialog/new_user_dialog.php b/plugins/new_user_dialog/new_user_dialog.php
new file mode 100644 (file)
index 0000000..4f6250f
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+
+/**
+ * Present identities settings dialog to new users
+ *
+ * When a new user is created, this plugin checks the default identity
+ * and sets a session flag in case it is incomplete. An overlay box will appear
+ * on the screen until the user has reviewed/completed his identity.
+ *
+ * @version 1.0
+ * @author Thomas Bruederli
+ */
+class new_user_dialog extends rcube_plugin
+{
+  public $task = 'mail';
+  
+  function init()
+  {
+    $this->add_hook('create_identity', array($this, 'create_identity'));
+    
+    // register additional hooks if session flag is set
+    if ($_SESSION['plugin.newuserdialog']) {
+      $this->add_hook('render_page', array($this, 'render_page'));
+      $this->register_action('plugin.newusersave', array($this, 'save_data'));
+    }
+  }
+  
+  /**
+   * Check newly created identity at first login
+   */
+  function create_identity($p)
+  {
+    // set session flag when a new user was created and the default identity seems to be incomplete
+    if ($p['login'] && !$p['complete'])
+      $_SESSION['plugin.newuserdialog'] = true;
+  }
+
+  /**
+   * Callback function when HTML page is rendered
+   * We'll add an overlay box here.
+   */
+  function render_page($p)
+  {
+    if ($_SESSION['plugin.newuserdialog']) {
+      $this->add_texts('localization');
+      
+      $rcmail = rcmail::get_instance();
+      $identity = $rcmail->user->get_identity();
+      $identities_level = intval($rcmail->config->get('identities_level', 0));
+      
+      // compose user-identity dialog
+      $table = new html_table(array('cols' => 2));
+      
+      $table->add('title', $this->gettext('name'));
+      $table->add(null, html::tag('input', array('type' => "text", 'name' => "_name", 'value' => $identity['name'])));
+
+      $table->add('title', $this->gettext('email'));
+      $table->add(null, html::tag('input', array('type' => "text", 'name' => "_email", 'value' => $identity['email'], 'disabled' => ($identities_level == 1 || $identities_level == 3))));
+      
+      // add overlay input box to html page
+      $rcmail->output->add_footer(html::div(array('id' => "newuseroverlay"),
+        html::tag('form', array(
+            'action' => $rcmail->url('plugin.newusersave'),
+            'method' => "post"),
+          html::tag('h3', null, Q($this->gettext('identitydialogtitle'))) .
+          html::p('hint', Q($this->gettext('identitydialoghint'))) .
+          $table->show() .
+          html::p(array('class' => "formbuttons"),
+            html::tag('input', array('type' => "submit", 'class' => "button mainaction", 'value' => $this->gettext('save'))))
+        )
+      ));
+      
+      $this->include_stylesheet('newuserdialog.css');
+    }
+  }
+
+  /**
+   * Handler for submitted form
+   *
+   * Check fields and save to default identity if valid.
+   * Afterwards the session flag is removed and we're done.
+   */
+  function save_data()
+  {
+    $rcmail = rcmail::get_instance();
+    $identity = $rcmail->user->get_identity();
+    $identities_level = intval($rcmail->config->get('identities_level', 0));
+    
+    $save_data = array(
+      'name' => get_input_value('_name', RCUBE_INPUT_POST),
+      'email' => get_input_value('_email', RCUBE_INPUT_POST),
+    );
+    
+    // don't let the user alter the e-mail address if disabled by config
+    if ($identities_level == 1 || $identities_level == 3)
+      $save_data['email'] = $identity['email'];
+    
+    // save data if not empty
+    if (!empty($save_data['name']) && !empty($save_data['name'])) {
+      $rcmail->user->update_identity($identity['identity_id'], $save_data);
+      rcube_sess_unset('plugin.newuserdialog');
+    }
+    
+    $rcmail->output->redirect('');
+  }
+  
+}
+
+?>
\ No newline at end of file
diff --git a/plugins/new_user_dialog/newuserdialog.css b/plugins/new_user_dialog/newuserdialog.css
new file mode 100644 (file)
index 0000000..c03e6fd
--- /dev/null
@@ -0,0 +1,59 @@
+/** Styles for the new-user-dialog overlay box */
+
+#newuseroverlay {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 10000;
+  background: rgba(0,0,0,0.5) !important;
+  background: #333;
+  
+  /** IE hacks */
+  filter: alpha(opacity=90);
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
+  width: expression(document.documentElement.clientWidth+'px');
+  height: expression(document.documentElement.clientHeight+'px');
+}
+
+#newuseroverlay h3 {
+  color: #333;
+  font-size: normal;
+  margin-top: 0.5em;
+  margin-bottom: 0;
+}
+
+#newuseroverlay p.hint {
+  margin-top: 0.5em;
+  font-style: italic;
+}
+
+#newuseroverlay form {
+  width: 32em;
+  margin: 8em auto;
+  padding: 1em 2em;
+  background: #F6F6F6;
+  border: 2px solid #555;
+  border-radius: 6px;
+  -moz-border-radius: 6px;
+  -webkit-border-radius: 6px;
+}
+
+#newuseroverlay table td.title
+{
+  color: #666;
+  text-align: right;
+  padding-right: 1em;
+  white-space: nowrap;
+}
+
+#newuseroverlay table td input
+{
+  width: 20em;
+}
+
+#newuseroverlay .formbuttons {
+  margin-top: 1.5em;
+  text-align: center;
+}
\ No newline at end of file
diff --git a/plugins/new_user_identity/new_user_identity.php b/plugins/new_user_identity/new_user_identity.php
new file mode 100644 (file)
index 0000000..7559569
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+/**
+ * New user identity
+ *
+ * Populates a new user's default identity from LDAP on their first visit.
+ *
+ * This plugin requires that a working public_ldap directory be configured.
+ *
+ * @version 1.0
+ * @author Kris Steinhoff
+ *
+ * Example configuration:
+ *
+ *  // The id of the address book to use to automatically set a new
+ *  // user's full name in their new identity. (This should be an
+ *  // string, which refers to the $rcmail_config['ldap_public'] array.)
+ *  $rcmail_config['new_user_identity_addressbook'] = 'People';
+ *  
+ *  // When automatically setting a new users's full name in their
+ *  // new identity, match the user's login name against this field.
+ *  $rcmail_config['new_user_identity_match'] = 'uid';
+ *  
+ *  // Use the value in this field to automatically set a new users's
+ *  // full name in their new identity.
+ *  $rcmail_config['new_user_identity_field'] = 'name';
+ */
+class new_user_identity extends rcube_plugin
+{
+    function init()
+    {
+        $this->add_hook('create_user', array($this, 'lookup_user_name'));
+    }
+
+    function lookup_user_name($args)
+    {
+        $rcmail = rcmail::get_instance();
+        if ($addressbook = $rcmail->config->get('new_user_identity_addressbook')) {
+            $match = $rcmail->config->get('new_user_identity_match');
+            $ldap = $rcmail->get_address_book($addressbook);
+            $ldap->prop['search_fields'] = array($match);
+            $results = $ldap->search($match, $args['user'], TRUE);
+            if (count($results->records) == 1) {
+                $args['user_name'] = $results->records[0][$rcmail->config->get('new_user_identity_field')];
+            }
+        }
+        return $args;
+    }
+}
+?>
diff --git a/plugins/password/README b/plugins/password/README
new file mode 100644 (file)
index 0000000..033af5f
--- /dev/null
@@ -0,0 +1,184 @@
+ -----------------------------------------------------------------------
+ Password Plugin for Roundcube
+ -----------------------------------------------------------------------
+
+ Plugin that adds a possibility to change user password using many
+ methods (drivers) via Settings/Password tab.
+
+ -----------------------------------------------------------------------
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2
+ as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ @version 1.2
+ @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
+ @author <see driver files for driver authors>
+ -----------------------------------------------------------------------
+
+ 1.    Configuration
+ 2.    Drivers
+ 2.1.  Database (sql)
+ 2.2.  Cyrus/SASL (sasl)
+ 2.3.  Poppassd/Courierpassd (poppassd)
+ 2.4.  LDAP (ldap)
+ 2.5.  DirectAdmin Control Panel
+ 3.    Driver API
+
+
+ 1. Configuration
+ ----------------
+
+ Copy config.inc.php.dist to config.inc.php and set the options as described
+ within the file.
+
+
+ 2. Drivers
+ ----------
+
+ Password plugin supports many password change mechanisms which are
+ handled by included drivers. Just pass driver name in 'password_driver' option.
+
+
+ 2.1. Database (sql)
+ -------------------
+
+ You can specify which database to connect by 'password_db_dsn' option and
+ what SQL query to execute by 'password_query'. See main.inc.php file for
+ more info.
+
+ Example implementations of an update_passwd function:
+
+ - This is for use with LMS (http://lms.org.pl) database and postgres:
+
+       CREATE OR REPLACE FUNCTION update_passwd(hash text, account text) RETURNS integer AS $$
+       DECLARE
+           res integer;
+       BEGIN
+           UPDATE passwd SET password = hash
+           WHERE login = split_part(account, '@', 1)
+               AND domainid = (SELECT id FROM domains WHERE name = split_part(account, '@', 2))
+           RETURNING id INTO res;
+           RETURN res;
+       END;
+       $$ LANGUAGE plpgsql SECURITY DEFINER;
+
+ - This is for use with a SELECT update_passwd(%o,%c,%u) query
+       Updates the password only when the old password matches the MD5 password
+       in the database
+
+       CREATE FUNCTION update_password (oldpass text, cryptpass text, user text) RETURNS text
+           MODIFIES SQL DATA
+       BEGIN
+           DECLARE currentsalt varchar(20);
+           DECLARE error text;
+           SET error = 'incorrect current password';
+           SELECT substring_index(substr(user.password,4),_latin1'$',1) INTO currentsalt FROM users WHERE username=user;
+           SELECT '' INTO error FROM users WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
+           UPDATE users SET password=cryptpass WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
+           RETURN error;
+       END
+
+ Example SQL UPDATEs:
+
+ - Plain text passwords:
+    UPDATE users SET password=%p WHERE username=%u AND password=%o AND domain=%h LIMIT 1
+
+ - Crypt text passwords:
+    UPDATE users SET password=%c WHERE username=%u LIMIT 1
+
+ - Use a MYSQL crypt function (*nix only) with random 8 character salt
+    UPDATE users SET password=ENCRYPT(%p,concat(_utf8'$1$',right(md5(rand()),8),_utf8'$')) WHERE username=%u LIMIT 1
+
+ - MD5 stored passwords:
+    UPDATE users SET password=MD5(%p) WHERE username=%u AND password=MD5(%o) LIMIT 1
+
+
+ 2.2. Cyrus/SASL (sasl)
+ ----------------------
+
+ Cyrus SASL database authentication allows your Cyrus+RoundCube
+ installation to host mail users without requiring a Unix Shell account!
+
+ This driver only covers the "sasldb" case when using Cyrus SASL. Kerberos
+ and PAM authentication mechanisms will require other techniques to enable
+ user password manipulations.
+
+ Cyrus SASL includes a shell utility called "saslpasswd" for manipulating
+ user passwords in the "sasldb" database.  This plugin attempts to use
+ this utility to perform password manipulations required by your webmail
+ users without any administrative interaction. Unfortunately, this
+ scheme requires that the "saslpasswd" utility be run as the "cyrus"
+ user - kind of a security problem since we have chosen to SUID a small
+ script which will allow this to happen.
+
+ This driver is based on the Squirrelmail Change SASL Password Plugin.
+ See http://www.squirrelmail.org/plugin_view.php?id=107 for details.
+
+ Installation:
+
+ Change into the drivers directory. Edit the chgsaslpasswd.c file as is
+ documented within it.
+
+ Compile the wrapper program:
+       gcc -o chgsaslpasswd chgsaslpasswd.c
+
+ Chown the compiled chgsaslpasswd binary to the cyrus user and group
+ that your browser runs as, then chmod them to 4550.
+
+ For example, if your cyrus user is 'cyrus' and the apache server group is
+ 'nobody' (I've been told Redhat runs Apache as user 'apache'):
+
+       chown cyrus:nobody chgsaslpasswd
+       chmod 4550 chgsaslpasswd
+
+ Stephen Carr has suggested users should try to run the scripts on a test
+ account as the cyrus user eg;
+
+       su cyrus -c "./chgsaslpasswd -p test_account"
+
+ This will allow you to make sure that the script will work for your setup.
+ Should the script not work, make sure that:
+ 1) the user the script runs as has access to the saslpasswd|saslpasswd2
+   file and proper permissions
+ 2) make sure the user in the chgsaslpasswd.c file is set correctly.
+   This could save you some headaches if you are the paranoid type.
+
+
+ 2.3. Poppassd/Courierpassd (poppassd)
+ -------------------------------------
+
+ You can specify which host to connect to via `password_pop_host` and
+ what port via `password_pop_port`. See config.inc.php file for more info.
+
+
+ 2.4. LDAP (ldap)
+ ----------------
+
+ See config.inc.php file. Requires PEAR::Net_LDAP2 package.
+
+
+ 2.5. DirectAdmin Control Panel
+ -------------------------------------
+
+ You can specify which host to connect to via `password_directadmin_host` 
+ and what port via `password_direactadmin_port`. See config.inc.php file 
+ for more info.
+
+
+ 3. Driver API
+ -------------
+
+ Driver file (<driver_name>.php) must define 'password_save' function with
+ two arguments. First - current password, second - new password. Function
+ may return PASSWORD_SUCCESS on success or any of PASSWORD_CONNECT_ERROR,
+ PASSWORD_CRYPT_ERROR, PASSWORD_ERROR when driver was unable to change password.
+ See existing drivers in drivers/ directory for examples.
diff --git a/plugins/password/config.inc.php.dist b/plugins/password/config.inc.php.dist
new file mode 100644 (file)
index 0000000..076cfd6
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+
+// Password Plugin options
+// -----------------------
+// A driver to use for password change. Default: "sql".
+$rcmail_config['password_driver'] = 'sql';
+
+// Determine whether current password is required to change password.
+// Default: false.
+$rcmail_config['password_confirm_current'] = true;
+
+
+// SQL Driver options
+// ------------------
+// PEAR database DSN for performing the query. By default
+// Roundcube DB settings are used.
+$rcmail_config['password_db_dsn'] = '';
+
+// The SQL query used to change the password.
+// The query can contain the following macros that will be expanded as follows:
+//      %p is replaced with the plaintext new password
+//      %c is replaced with the crypt version of the new password, MD5 if available
+//         otherwise DES.
+//      %o is replaced with the password before the change
+//      %n is replaced with the hashed version of the new password
+//      %q is replaced with the hashed password before the change
+//      %h is replaced with the imap host (from the session info)
+//      %u is replaced with the username (from the session info)
+//      %l is replaced with the local part of the username
+//         (in case the username is an email address)
+//      %d is replaced with the domain part of the username
+//         (in case the username is an email address)
+// Escaping of macros is handled by this module.
+// Default: "SELECT update_passwd(%c, %u)"
+$rcmail_config['password_query'] = 'SELECT update_passwd(%c, %u)';
+
+// Using a password hash for %n and %q variables.
+// Determine which hashing algorithm should be used to generate
+// the hashed new and current password for using them within the
+// SQL query. Requires PHP's 'hash' extension.
+$rcmail_config['password_hash_algorithm'] = 'sha1';
+
+// You can also decide whether the hash should be provided
+// as hex string or in base64 encoded format.
+$rcmail_config['password_hash_base64'] = false;
+
+
+// Poppassd Driver options
+// -----------------------
+// The host which changes the password
+$rcmail_config['password_pop_host'] = 'localhost';
+
+// TCP port used for poppassd connections
+$rcmail_config['password_pop_port'] = 106;
+
+
+// SASL Driver options
+// -------------------
+// Additional arguments for the saslpasswd2 call
+$rcmail_config['password_saslpasswd_args'] = '';
+
+
+// LDAP Driver options
+// -------------------
+// LDAP server name to connect to. 
+// You can provide one or several hosts in an array in which case the hosts are tried from left to right.
+// Exemple: array('ldap1.exemple.com', 'ldap2.exemple.com');
+// Default: 'localhost'
+$rcmail_config['password_ldap_host'] = 'localhost';
+
+// LDAP server port to connect to
+// Default: '389'
+$rcmail_config['password_ldap_port'] = '389';
+
+// TLS is started after connecting
+// Using TLS for password modification is recommanded.
+// Default: false
+$rcmail_config['password_ldap_starttls'] = false;
+
+// LDAP version
+// Default: '3'
+$rcmail_config['password_ldap_version'] = '3';
+
+// LDAP base name (root directory)
+// Exemple: 'dc=exemple,dc=com'
+$rcmail_config['password_ldap_basedn'] = 'dc=exemple,dc=com';
+
+// LDAP connection method
+// There is two connection method for changing a user's LDAP password.
+// 'user': use user credential (recommanded, require password_confirm_current=true)
+// 'admin': use admin credential (this mode require password_ldap_adminDN and password_ldap_adminPW)
+// Default: 'user'
+$rcmail_config['password_ldap_method'] = 'user';
+
+// LDAP Admin DN
+// Used only in admin connection mode
+// Default: null
+$rcmail_config['password_ldap_adminDN'] = null;
+
+// LDAP Admin Password
+// Used only in admin connection mode
+// Default: null
+$rcmail_config['password_ldap_adminPW'] = null;
+
+// LDAP user DN mask
+// The user's DN is mandatory and as we only have his login,
+// we need to re-create his DN using a mask
+// '%login' will be replaced by the current roundcube user's login
+// '%name' will be replaced by the current roundcube user's name part
+// '%domain' will be replaced by the current roundcube user's domain part
+// Exemple: 'uid=%login,ou=people,dc=exemple,dc=com'
+$rcmail_config['password_ldap_userDN_mask'] = 'uid=%login,ou=people,dc=exemple,dc=com';
+
+// LDAP password hash type
+// Standard LDAP encryption type which must be one of: crypt,
+// ext_des, md5crypt, blowfish, md5, sha, smd5, ssha, or clear.
+// Please note that most encodage types require external libraries
+// to be included in your PHP installation, see function hashPassword in drivers/ldap.php for more info.
+// Default: 'crypt'
+$rcmail_config['password_ldap_encodage'] = 'crypt';
+
+// LDAP password attribute
+// Name of the ldap's attribute used for storing user password
+// Default: 'userPassword'
+$rcmail_config['password_ldap_pwattr'] = 'userPassword';
+
+// LDAP password force replace
+// Force LDAP replace in cases where ACL allows only replace not read
+// See http://pear.php.net/package/Net_LDAP2/docs/latest/Net_LDAP2/Net_LDAP2_Entry.html#methodreplace
+// Default: true
+$rcmail_config['password_ldap_force_replace'] = true;
+
+
+// DirectAdmin Driver options
+// --------------------------
+// The host which changes the password
+$rcmail_config['password_directadmin_host'] = 'localhost';
+
+// TCP port used for DirectAdmin connections
+$rcmail_config['password_directadmin_port'] = 2222;
+
+?>
diff --git a/plugins/password/drivers/chgsaslpasswd.c b/plugins/password/drivers/chgsaslpasswd.c
new file mode 100644 (file)
index 0000000..bcdcb2e
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <unistd.h>
+
+// set the UID this script will run as (cyrus user)
+#define UID 96
+// set the path to saslpasswd or saslpasswd2
+#define CMD "/usr/sbin/saslpasswd2"
+
+/* INSTALLING:
+  gcc -o chgsaslpasswd chgsaslpasswd.c
+  chown cyrus.apache chgsaslpasswd
+  strip chgsaslpasswd
+  chmod 4550 chgsaslpasswd
+*/
+
+main(int argc, char *argv[])
+{
+  int rc,cc;
+
+  cc = setuid(UID);
+  rc = execvp(CMD, argv);
+  if ((rc != 0) || (cc != 0))
+  {
+    fprintf(stderr, "__ %s:  failed %d  %d\n", argv[0], rc, cc);
+    return 1;
+  }
+
+  return 0;
+}
diff --git a/plugins/password/drivers/directadmin.php b/plugins/password/drivers/directadmin.php
new file mode 100644 (file)
index 0000000..d11aae7
--- /dev/null
@@ -0,0 +1,483 @@
+<?php
+
+/**
+ * DirectAdmin Password Driver
+ *
+ * Driver to change passwords via DirectAdmin Control Panel
+ *
+ * @version 1.0
+ * @author Victor Benincasa <vbenincasa@gmail.com>
+ *
+ */
+
+
+function password_save($curpass, $passwd){
+
+    $rcmail = rcmail::get_instance();
+    $Socket = new HTTPSocket;
+
+    $da_user    = $_SESSION['username'];
+    $da_curpass = $curpass;
+    $da_newpass = $passwd;
+    $da_host    = $rcmail->config->get('password_directadmin_host');
+    $da_port    = $rcmail->config->get('password_directadmin_port');
+
+    $Socket->connect($da_host,$da_port); 
+    $Socket->set_method('POST');
+    $Socket->query('/CMD_CHANGE_EMAIL_PASSWORD',
+        array(
+            'email'            => $da_user,
+            'oldpassword'      => $da_curpass,
+            'password1'        => $da_newpass,
+            'password2'        => $da_newpass,
+            'api'                      => '1'
+    ));
+    $response = $Socket->fetch_parsed_body();
+
+       //console("DA error response: $response[text] [$da_user]");
+
+    if($Socket->result_status_code <> 200)
+        return PASSWORD_CONNECT_ERROR;
+    elseif($response['error'] == 1){ //Error description: $response[text] 
+        return PASSWORD_ERROR;
+    }else 
+        return PASSWORD_SUCCESS;
+
+}
+
+
+/**
+ * Socket communication class.
+ *
+ * Originally designed for use with DirectAdmin's API, this class will fill any HTTP socket need.
+ *
+ * Very, very basic usage:
+ *   $Socket = new HTTPSocket;
+ *   echo $Socket->get('http://user:pass@somesite.com/somedir/some.file?query=string&this=that');
+ *
+ * @author Phi1 'l0rdphi1' Stier <l0rdphi1@liquenox.net>
+ * @package HTTPSocket
+ * @version 2.6
+ */
+class HTTPSocket {
+
+    var $version = '2.6';
+    
+    /* all vars are private except $error, $query_cache, and $doFollowLocationHeader */
+
+    var $method = 'GET';
+
+    var $remote_host;
+    var $remote_port;
+    var $remote_uname;
+    var $remote_passwd;
+
+    var $result;
+    var $result_header;
+    var $result_body;
+    var $result_status_code;
+
+    var $lastTransferSpeed;
+
+    var $bind_host;
+
+    var $error = array();
+    var $warn = array();
+    var $query_cache = array();
+
+    var $doFollowLocationHeader = TRUE;
+    var $redirectURL;
+
+    var $extra_headers = array();
+
+    /**
+     * Create server "connection".
+     *
+     */
+    function connect($host, $port = '' )
+    {
+        if (!is_numeric($port))
+        {
+            $port = 80;
+        }
+
+        $this->remote_host = $host;
+        $this->remote_port = $port;
+    }
+
+    function bind( $ip = '' )
+    {
+        if ( $ip == '' )
+        {
+            $ip = $_SERVER['SERVER_ADDR'];
+        }
+
+        $this->bind_host = $ip;
+    }
+
+    /**
+     * Change the method being used to communicate.
+     *
+     * @param string|null request method. supports GET, POST, and HEAD. default is GET
+     */
+    function set_method( $method = 'GET' )
+    {
+        $this->method = strtoupper($method);
+    }
+
+    /**
+     * Specify a username and password.
+     *
+     * @param string|null username. defualt is null
+     * @param string|null password. defualt is null
+     */
+    function set_login( $uname = '', $passwd = '' )
+    {
+        if ( strlen($uname) > 0 )
+        {
+            $this->remote_uname = $uname;
+        }
+
+        if ( strlen($passwd) > 0 )
+        {
+            $this->remote_passwd = $passwd;
+        }
+
+    }
+
+    /**
+     * Query the server
+     *
+     * @param string containing properly formatted server API. See DA API docs and examples. Http:// URLs O.K. too.
+     * @param string|array query to pass to url
+     * @param int if connection KB/s drops below value here, will drop connection
+     */
+    function query( $request, $content = '', $doSpeedCheck = 0 )
+    {
+        $this->error = $this->warn = array();
+        $this->result_status_code = NULL;
+
+        // is our request a http:// ... ?
+        if (preg_match('!^http://!i',$request))
+        {
+            $location = parse_url($request);
+            $this->connect($location['host'],$location['port']);
+            $this->set_login($location['user'],$location['pass']);
+            
+            $request = $location['path'];
+            $content = $location['query'];
+
+            if ( strlen($request) < 1 )
+            {
+                $request = '/';
+            }
+
+        }
+
+        $array_headers = array(
+            'User-Agent' => "HTTPSocket/$this->version",
+            'Host' => ( $this->remote_port == 80 ? $this->remote_host : "$this->remote_host:$this->remote_port" ),
+            'Accept' => '*/*',
+            'Connection' => 'Close' );
+
+        foreach ( $this->extra_headers as $key => $value )
+        {
+            $array_headers[$key] = $value;
+        }
+
+        $this->result = $this->result_header = $this->result_body = '';
+
+        // was content sent as an array? if so, turn it into a string
+        if (is_array($content))
+        {
+            $pairs = array();
+
+            foreach ( $content as $key => $value )
+            {
+                $pairs[] = "$key=".urlencode($value);
+            }
+
+            $content = join('&',$pairs);
+            unset($pairs);
+        }
+
+        $OK = TRUE;
+
+        // instance connection
+        if ($this->bind_host)
+        {
+            $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+            socket_bind($socket,$this->bind_host);
+
+            if (!@socket_connect($socket,$this->remote_host,$this->remote_port))
+            {
+                $OK = FALSE;
+            }
+
+        }
+        else
+        {
+            $socket = @fsockopen( $this->remote_host, $this->remote_port, $sock_errno, $sock_errstr, 10 );
+        }
+
+        if ( !$socket || !$OK )
+        {
+            $this->error[] = "Can't create socket connection to $this->remote_host:$this->remote_port.";
+            return 0;
+        }
+
+        // if we have a username and password, add the header
+        if ( isset($this->remote_uname) && isset($this->remote_passwd) )
+        {
+            $array_headers['Authorization'] = 'Basic '.base64_encode("$this->remote_uname:$this->remote_passwd");
+        }
+
+        // for DA skins: if $this->remote_passwd is NULL, try to use the login key system
+        if ( isset($this->remote_uname) && $this->remote_passwd == NULL )
+        {
+            $array_headers['Cookie'] = "session={$_SERVER['SESSION_ID']}; key={$_SERVER['SESSION_KEY']}";
+        }
+
+        // if method is POST, add content length & type headers
+        if ( $this->method == 'POST' )
+        {
+            $array_headers['Content-type'] = 'application/x-www-form-urlencoded';
+            $array_headers['Content-length'] = strlen($content);
+        }
+        // else method is GET or HEAD. we don't support anything else right now.
+        else
+        {
+            if ($content)
+            {
+                $request .= "?$content";
+            }
+        }
+
+        // prepare query
+        $query = "$this->method $request HTTP/1.0\r\n";
+        foreach ( $array_headers as $key => $value )
+        {
+            $query .= "$key: $value\r\n";
+        }
+        $query .= "\r\n";
+
+        // if POST we need to append our content
+        if ( $this->method == 'POST' && $content )
+        {
+            $query .= "$content\r\n\r\n";
+        }
+
+        // query connection
+        if ($this->bind_host)
+        {
+            socket_write($socket,$query);
+
+            // now load results
+            while ( $out = socket_read($socket,2048) )
+            {
+                $this->result .= $out;
+            }
+        }
+        else
+        {
+            fwrite( $socket, $query, strlen($query) );
+
+            // now load results
+            $this->lastTransferSpeed = 0;
+            $status = socket_get_status($socket);
+            $startTime = time();
+            $length = 0;
+            $prevSecond = 0;
+            while ( !feof($socket) && !$status['timed_out'] )
+            {
+                $chunk = fgets($socket,1024);
+                $length += strlen($chunk);
+                $this->result .= $chunk;
+
+                $elapsedTime = time() - $startTime;
+
+                if ( $elapsedTime > 0 )
+                {
+                    $this->lastTransferSpeed = ($length/1024)/$elapsedTime;
+                }
+
+                if ( $doSpeedCheck > 0 && $elapsedTime > 5 && $this->lastTransferSpeed < $doSpeedCheck )
+                {
+                    $this->warn[] = "kB/s for last 5 seconds is below 50 kB/s (~".( ($length/1024)/$elapsedTime )."), dropping connection...";
+                    $this->result_status_code = 503;
+                    break;
+                }
+
+            }
+
+            if ( $this->lastTransferSpeed == 0 )
+            {
+                $this->lastTransferSpeed = $length/1024;
+            }
+
+        }
+        
+        list($this->result_header,$this->result_body) = split("\r\n\r\n",$this->result,2);
+
+        if ($this->bind_host)
+        {
+            socket_close($socket);
+        }
+        else
+        {
+            fclose($socket);
+        }
+
+        $this->query_cache[] = $query;
+
+
+        $headers = $this->fetch_header();
+
+        // what return status did we get?
+        if (!$this->result_status_code)
+        {
+            preg_match("#HTTP/1\.. (\d+)#",$headers[0],$matches);
+            $this->result_status_code = $matches[1];
+        }
+
+        // did we get the full file?
+        if ( !empty($headers['content-length']) && $headers['content-length'] != strlen($this->result_body) )
+        {
+            $this->result_status_code = 206;
+        }
+
+        // now, if we're being passed a location header, should we follow it?
+        if ($this->doFollowLocationHeader)
+        {
+            if ($headers['location'])
+            {
+                $this->redirectURL = $headers['location'];
+                $this->query($headers['location']);
+            }
+        }
+        
+    }
+
+    function getTransferSpeed()
+    {
+        return $this->lastTransferSpeed;
+    }
+
+    /**
+     * The quick way to get a URL's content :)
+     *
+     * @param string URL
+     * @param boolean return as array? (like PHP's file() command)
+     * @return string result body
+     */
+    function get($location, $asArray = FALSE )
+    {
+        $this->query($location);
+
+        if ( $this->get_status_code() == 200 )
+        {
+            if ($asArray)
+            {
+                return split("\n",$this->fetch_body());
+            }
+
+            return $this->fetch_body();
+        }
+
+        return FALSE;
+    }
+
+    /**
+     * Returns the last status code.
+     * 200 = OK;
+     * 403 = FORBIDDEN;
+     * etc.
+     *
+     * @return int status code
+     */
+    function get_status_code()
+    {
+        return $this->result_status_code;
+    }
+
+    /**
+     * Adds a header, sent with the next query.
+     *
+     * @param string header name
+     * @param string header value
+     */
+    function add_header($key,$value)
+    {
+        $this->extra_headers[$key] = $value;
+    }
+
+    /**
+     * Clears any extra headers.
+     *
+     */
+    function clear_headers()
+    {
+        $this->extra_headers = array();
+    }
+
+    /**
+     * Return the result of a query.
+     *
+     * @return string result
+     */
+    function fetch_result()
+    {
+        return $this->result;
+    }
+
+    /**
+     * Return the header of result (stuff before body).
+     *
+     * @param string (optional) header to return
+     * @return array result header
+     */
+    function fetch_header( $header = '' )
+    {
+        $array_headers = split("\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);
+            $array_return[strtolower($key)] = $value;
+        }
+
+        if ( $header != '' )
+        {
+            return $array_return[strtolower($header)];
+        }
+
+        return $array_return;
+    }
+
+    /**
+     * Return the body of result (stuff after header).
+     *
+     * @return string result body
+     */
+    function fetch_body()
+    {
+        return $this->result_body;
+    }
+
+    /**
+     * Return parsed body in array format.
+     *
+     * @return array result parsed
+     */
+    function fetch_parsed_body()
+    {
+        parse_str($this->result_body,$x);
+        return $x;
+    }
+
+}
+
+?>
diff --git a/plugins/password/drivers/ldap.php b/plugins/password/drivers/ldap.php
new file mode 100644 (file)
index 0000000..e38f13f
--- /dev/null
@@ -0,0 +1,186 @@
+<?php
+
+/**
+ * LDAP Password Driver
+ *
+ * Driver for passwords stored in LDAP
+ * This driver use the PEAR Net_LDAP2 class (http://pear.php.net/package/Net_LDAP2).
+ *
+ * @version 1.0 (2009-06-24)
+ * @author Edouard MOREAU <edouard.moreau@ensma.fr>
+ *
+ * function hashPassword based on code from the phpLDAPadmin development team (http://phpldapadmin.sourceforge.net/).
+ * function randomSalt based on code from the phpLDAPadmin development team (http://phpldapadmin.sourceforge.net/).
+ *
+ */
+
+function password_save($curpass, $passwd)
+{
+    $rcmail = rcmail::get_instance();
+    require_once ('Net/LDAP2.php');
+    
+    // Building user DN
+    $userDN = str_replace('%login', $_SESSION['username'], $rcmail->config->get('password_ldap_userDN_mask'));
+    
+    $parts = explode('@', $_SESSION['username']);
+    if (count($parts) == 2)
+    {
+        $userDN = str_replace('%name', $parts[0], $userDN);
+        $userDN = str_replace('%domain', $parts[1], $userDN);
+    }
+
+    if (empty($userDN)) {return PASSWORD_CONNECT_ERROR;}
+    
+    // Connection Method
+    switch($rcmail->config->get('password_ldap_method')) {
+        case 'user': $binddn = $userDN; $bindpw = $curpass; break;
+        case 'admin': $binddn = $rcmail->config->get('password_ldap_adminDN'); $bindpw = $rcmail->config->get('password_ldap_adminPW'); break;
+        default: $binddn = $userDN; $bindpw = $curpass; break; // default is user mode
+    }
+    
+    // Configuration array
+    $ldapConfig = array (
+        'binddn'    => $binddn,
+        'bindpw'    => $bindpw,
+        'basedn'    => $rcmail->config->get('password_ldap_basedn'),
+        'host'      => $rcmail->config->get('password_ldap_host'),
+        'port'      => $rcmail->config->get('password_ldap_port'),
+        'starttls'  => $rcmail->config->get('password_ldap_starttls'),
+        'version'   => $rcmail->config->get('password_ldap_version'),
+    );
+    
+    // Connecting using the configuration array
+    $ldap = Net_LDAP2::connect($ldapConfig);
+    
+    // Checking for connection error
+    if (PEAR::isError($ldap)) {return PASSWORD_CONNECT_ERROR;}
+    
+    // Crypting new password
+    $newCryptedPassword = hashPassword($passwd, $rcmail->config->get('password_ldap_encodage'));
+    if (!$newCryptedPassword) {return PASSWORD_CRYPT_ERROR;}
+    
+    // Writing new crypted password to LDAP
+    $userEntry = $ldap->getEntry($userDN);
+    if (Net_LDAP2::isError($userEntry)) {return PASSWORD_CONNECT_ERROR;}
+    if (!$userEntry->replace(array($rcmail->config->get('password_ldap_pwattr') => $newCryptedPassword),$rcmail->config->get('password_ldap_force_replace'))) {return PASSWORD_CONNECT_ERROR;}
+    if (Net_LDAP2::isError($userEntry->update())) {return PASSWORD_CONNECT_ERROR;}
+    
+    // All done, no error
+    return PASSWORD_SUCCESS;    
+}
+
+
+/**
+ * Code originaly from the phpLDAPadmin development team
+ * http://phpldapadmin.sourceforge.net/
+ *
+ * Hashes a password and returns the hash based on the specified enc_type.
+ *
+ * @param string $passwordClear The password to hash in clear text.
+ * @param string $encodageType Standard LDAP encryption type which must be one of
+ *        crypt, ext_des, md5crypt, blowfish, md5, sha, smd5, ssha, or clear.
+ * @return string The hashed password.
+ *
+ */
+
+function hashPassword( $passwordClear, $encodageType ) 
+{
+    $encodageType = strtolower( $encodageType );
+    switch( $encodageType ) {
+        case 'crypt': 
+            $cryptedPassword = '{CRYPT}' . crypt($passwordClear,randomSalt(2)); 
+            break;
+            
+        case 'ext_des':
+            // extended des crypt. see OpenBSD crypt man page.
+            if ( ! defined( 'CRYPT_EXT_DES' ) || CRYPT_EXT_DES == 0 ) {return FALSE;} //Your system crypt library does not support extended DES encryption.
+            $cryptedPassword = '{CRYPT}' . crypt( $passwordClear, '_' . randomSalt(8) );
+            break;
+
+        case 'md5crypt':
+            if( ! defined( 'CRYPT_MD5' ) || CRYPT_MD5 == 0 ) {return FALSE;} //Your system crypt library does not support md5crypt encryption.
+            $cryptedPassword = '{CRYPT}' . crypt( $passwordClear , '$1$' . randomSalt(9) );
+            break;
+
+        case 'blowfish':
+            if( ! defined( 'CRYPT_BLOWFISH' ) || CRYPT_BLOWFISH == 0 ) {return FALSE;} //Your system crypt library does not support blowfish encryption.
+            $cryptedPassword = '{CRYPT}' . crypt( $passwordClear , '$2a$12$' . randomSalt(13) ); // hardcoded to second blowfish version and set number of rounds
+            break;
+
+        case 'md5':
+            $cryptedPassword = '{MD5}' . base64_encode( pack( 'H*' , md5( $passwordClear) ) );
+            break;
+
+        case 'sha':
+            if( function_exists('sha1') ) {
+                // use php 4.3.0+ sha1 function, if it is available.
+                $cryptedPassword = '{SHA}' . base64_encode( pack( 'H*' , sha1( $passwordClear) ) );
+            } elseif( function_exists( 'mhash' ) ) {
+                $cryptedPassword = '{SHA}' . base64_encode( mhash( MHASH_SHA1, $passwordClear) );
+            } else {
+                return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
+            }
+            break;
+
+        case 'ssha':
+            if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
+                mt_srand( (double) microtime() * 1000000 );
+                $salt = mhash_keygen_s2k( MHASH_SHA1, $passwordClear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
+                $cryptedPassword = "{SSHA}".base64_encode( mhash( MHASH_SHA1, $passwordClear.$salt ).$salt );
+            } else {
+                return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
+            }
+            break;
+
+        case 'smd5':
+            if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) {
+                mt_srand( (double) microtime() * 1000000 );
+                $salt = mhash_keygen_s2k( MHASH_MD5, $passwordClear, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
+                $cryptedPassword = "{SMD5}".base64_encode( mhash( MHASH_MD5, $passwordClear.$salt ).$salt );
+            } else {
+                return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes.
+            }
+            break;
+
+        case 'clear':
+        default:
+            $cryptedPassword = $passwordClear;
+    }
+
+    return $cryptedPassword;
+}
+
+
+
+/**
+ * Code originaly from the phpLDAPadmin development team
+ * http://phpldapadmin.sourceforge.net/
+ *
+ * Used to generate a random salt for crypt-style passwords. Salt strings are used
+ * to make pre-built hash cracking dictionaries difficult to use as the hash algorithm uses
+ * not only the user's password but also a randomly generated string. The string is
+ * stored as the first N characters of the hash for reference of hashing algorithms later.
+ *
+ * --- added 20021125 by bayu irawan <bayuir@divnet.telkom.co.id> ---
+ * --- ammended 20030625 by S C Rigler <srigler@houston.rr.com> ---
+ *
+ * @param int $length The length of the salt string to generate.
+ * @return string The generated salt string.
+ */
+function randomSalt( $length ) 
+{
+    $possible = '0123456789'.
+        'abcdefghijklmnopqrstuvwxyz'.
+        'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
+        './';
+    $str = "";
+    mt_srand((double)microtime() * 1000000);
+
+    while( strlen( $str ) < $length )
+        $str .= substr( $possible, ( rand() % strlen( $possible ) ), 1 );
+
+    return $str;
+}
+
+?>
diff --git a/plugins/password/drivers/poppassd.php b/plugins/password/drivers/poppassd.php
new file mode 100644 (file)
index 0000000..8a54fb7
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * Poppassd Password Driver
+ *
+ * Driver to change passwords via Poppassd/Courierpassd
+ *
+ * @version 1.0
+ * @author Philip Weir
+ *
+ */
+
+function password_save($curpass, $passwd)
+{
+    $rcmail = rcmail::get_instance();
+//    include('Net/Socket.php');
+    $poppassd = new Net_Socket();
+
+    if (PEAR::isError($poppassd->connect($rcmail->config->get('password_pop_host'), $rcmail->config->get('password_pop_port'), null))) {
+        return PASSWORD_CONNECT_ERROR;
+    }
+    else {
+        $result = $poppassd->readLine();
+        if(!preg_match('/^2\d\d/', $result)) {
+            $poppassd->disconnect();
+            return PASSWORD_ERROR;
+        }
+        else {
+            $poppassd->writeLine("user ". $_SESSION['username']);
+            $result = $poppassd->readLine();
+            if(!preg_match('/^[23]\d\d/', $result) ) {
+                $poppassd->disconnect();
+                return PASSWORD_CONNECT_ERROR;
+            }
+            else {
+                $poppassd->writeLine("pass ". $curpass);
+                $result = $poppassd->readLine();
+                if(!preg_match('/^[23]\d\d/', $result) ) {
+                    $poppassd->disconnect();
+                    return PASSWORD_ERROR;
+                }
+                else {
+                    $poppassd->writeLine("newpass ". $passwd);
+                    $result = $poppassd->readLine();
+                    $poppassd->disconnect();
+                    if (!preg_match('/^2\d\d/', $result))
+                        return PASSWORD_ERROR;
+                    else
+                        return PASSWORD_SUCCESS;
+                }
+            }
+        }
+    }
+}
+
+?>
diff --git a/plugins/password/drivers/sasl.php b/plugins/password/drivers/sasl.php
new file mode 100644 (file)
index 0000000..b1e9ba4
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * SASL Password Driver
+ *
+ * Driver that adds functionality to change the users Cyrus/SASL password.
+ * The code is derrived from the Squirrelmail "Change SASL Password" Plugin
+ * by Galen Johnson.
+ *
+ * It only works with saslpasswd2 on the same host where RoundCube runs
+ * and requires shell access and gcc in order to compile the binary.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 1.0
+ * @author Thomas Bruederli
+ */
+function password_save($currpass, $newpass)
+{
+    $curdir = realpath(dirname(__FILE__));
+    $username = escapeshellcmd($_SESSION['username']);
+    $args = rcmail::get_instance()->config->get('password_saslpasswd_args', '');
+
+    if ($fh = popen("$curdir/chgsaslpasswd -p $args $username", 'w')) {
+        fwrite($fh, $newpass."\n");
+        $code = pclose($fh);
+
+        if ($code == 0)
+            return PASSWORD_SUCCESS;
+    }
+    else {
+        raise_error(array(
+            'code' => 600,
+            'type' => 'php',
+            'file' => __FILE__,
+            'message' => "Password plugin: Unable to execute $curdir/chgsaslpasswd"
+            ), true, false);
+    }
+
+    return PASSWORD_ERROR;
+}
+
+?>
diff --git a/plugins/password/drivers/sql.php b/plugins/password/drivers/sql.php
new file mode 100644 (file)
index 0000000..9afaa65
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * SQL Password Driver
+ *
+ * Driver for passwords stored in SQL database
+ *
+ * @version 1.2
+ * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
+ *
+ */
+
+function password_save($curpass, $passwd)
+{
+    $rcmail = rcmail::get_instance();
+
+    if (!($sql = $rcmail->config->get('password_query')))
+        $sql = 'SELECT update_passwd(%c, %u)';
+
+    if ($dsn = $rcmail->config->get('password_db_dsn')) {
+       // #1486067: enable new_link option
+       if (is_array($dsn) && empty($dsn['new_link']))
+           $dsn['new_link'] = true;
+       else if (!is_array($dsn) && !preg_match('/\?new_link=true/', $dsn))
+         $dsn .= '?new_link=true';
+
+        $db = new rcube_mdb2($dsn, '', FALSE);
+        $db->set_debug((bool)$rcmail->config->get('sql_debug'));
+        $db->db_connect('w');
+    } else {
+        $db = $rcmail->get_dbh();
+    }
+
+    if ($err = $db->is_error())
+        return PASSWORD_ERROR;
+    
+    // crypted password
+    if (strpos($sql, '%c') !== FALSE) {
+        $salt = '';
+        if (CRYPT_MD5) { 
+           $len = rand(3, CRYPT_SALT_LENGTH);
+        } else if (CRYPT_STD_DES) {
+           $len = 2;
+        } else {
+           return PASSWORD_CRYPT_ERROR;
+        }
+        for ($i = 0; $i < $len ; $i++) {
+           $salt .= chr(rand(ord('.'), ord('z')));
+        }
+        $sql = str_replace('%c',  $db->quote(crypt($passwd, CRYPT_MD5 ? '$1$'.$salt.'$' : $salt)), $sql);
+    }
+    
+    // hashed passwords
+    if (preg_match('/%[n|q]/', $sql)) {
+
+       if (!extension_loaded('hash')) {
+           raise_error(array(
+               'code' => 600,
+               'type' => 'php',
+               'file' => __FILE__,
+               'message' => "Password plugin: 'hash' extension not loaded!"
+               ), true, false);
+           return PASSWORD_ERROR;                          
+       }
+
+       if (!($hash_algo = strtolower($rcmail->config->get('password_hash_algorithm'))))
+            $hash_algo = 'sha1';
+        
+       $hash_passwd = hash($hash_algo, $passwd);
+        $hash_curpass = hash($hash_algo, $curpass);
+        
+       if ($rcmail->config->get('password_hash_base64')) {
+            $hash_passwd = base64_encode(pack('H*', $hash_passwd));
+            $hash_curpass = base64_encode(pack('H*', $hash_curpass));
+        }
+       
+       $sql = str_replace('%n', $db->quote($hash_passwd, 'text'), $sql);
+       $sql = str_replace('%q', $db->quote($hash_curpass, 'text'), $sql);
+    }
+
+    $user_info = explode('@', $_SESSION['username']);
+    if (count($user_info) >= 2) {
+       $sql = str_replace('%l', $db->quote($user_info[0], 'text'), $sql);
+       $sql = str_replace('%d', $db->quote($user_info[0], 'text'), $sql);
+    }
+    
+    $sql = str_replace('%u', $db->quote($_SESSION['username'],'text'), $sql);
+    $sql = str_replace('%h', $db->quote($_SESSION['imap_host'],'text'), $sql);
+    $sql = str_replace('%p', $db->quote($passwd,'text'), $sql);
+    $sql = str_replace('%o', $db->quote($curpass,'text'), $sql);
+
+    $res = $db->query($sql);
+
+    if (!$db->is_error()) {
+       if (strtolower(substr(trim($query),0,6))=='select') {
+           if ($result = $db->fetch_array($res))
+               return PASSWORD_SUCCESS;
+       } else { 
+           if ($db->affected_rows($res) == 1)
+               return PASSWORD_SUCCESS; // This is the good case: 1 row updated
+       }
+    }
+
+    return PASSWORD_ERROR;
+}
+
+?>
diff --git a/plugins/password/localization/de_CH.inc b/plugins/password/localization/de_CH.inc
new file mode 100644 (file)
index 0000000..a28990d
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Passwort ändern';
+$labels['curpasswd']  = 'Aktuelles Passwort';
+$labels['newpasswd']  = 'Neues Passwort';
+$labels['confpasswd']  = 'Passwort Wiederholung';
+
+$messages = array();
+$messages['nopassword'] = "Bitte geben Sie ein neues Passwort ein";
+$messages['nocurpassword'] = "Bitte geben Sie Ihr aktuelles Passwort an";
+$messages['passwordincorrect'] = "Das aktuelle Passwort ist nicht korrekt";
+$messages['passwordinconsistency'] = "Das neue Passwort und dessen Wiederholung stimmen nicht überein";
+$messages['crypterror'] = "Neues Passwort nicht gespeichert: Verschlüsselungsfunktion fehlt";
+$messages['connecterror'] = "Neues Passwort nicht gespeichert: Verbindungsfehler";
+$messages['internalerror'] = "Neues Passwort nicht gespeichert";
+
+
+?>
\ No newline at end of file
diff --git a/plugins/password/localization/de_DE.inc b/plugins/password/localization/de_DE.inc
new file mode 100644 (file)
index 0000000..a28990d
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Passwort ändern';
+$labels['curpasswd']  = 'Aktuelles Passwort';
+$labels['newpasswd']  = 'Neues Passwort';
+$labels['confpasswd']  = 'Passwort Wiederholung';
+
+$messages = array();
+$messages['nopassword'] = "Bitte geben Sie ein neues Passwort ein";
+$messages['nocurpassword'] = "Bitte geben Sie Ihr aktuelles Passwort an";
+$messages['passwordincorrect'] = "Das aktuelle Passwort ist nicht korrekt";
+$messages['passwordinconsistency'] = "Das neue Passwort und dessen Wiederholung stimmen nicht überein";
+$messages['crypterror'] = "Neues Passwort nicht gespeichert: Verschlüsselungsfunktion fehlt";
+$messages['connecterror'] = "Neues Passwort nicht gespeichert: Verbindungsfehler";
+$messages['internalerror'] = "Neues Passwort nicht gespeichert";
+
+
+?>
\ No newline at end of file
diff --git a/plugins/password/localization/en_US.inc b/plugins/password/localization/en_US.inc
new file mode 100644 (file)
index 0000000..6c64cc0
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Change Password';
+$labels['curpasswd']  = 'Current Password:';
+$labels['newpasswd']  = 'New Password:';
+$labels['confpasswd']  = 'Confirm New Password:';
+
+$messages = array();
+$messages['nopassword'] = 'Please input new password.';
+$messages['nocurpassword'] = 'Please input current password.';
+$messages['passwordincorrect'] = 'Current password incorrect.';
+$messages['passwordinconsistency'] = 'Passwords do not match, please try again.';
+$messages['crypterror'] = 'Could not save new password. Encrypt function missing.';
+$messages['connecterror'] = 'Could not save new password. Connection error.';
+$messages['internalerror'] = 'Could not save new password.';
+
+?>
diff --git a/plugins/password/localization/et_EE.inc b/plugins/password/localization/et_EE.inc
new file mode 100644 (file)
index 0000000..0f351d7
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Muuda parooli';
+$labels['curpasswd']  = 'Vana parool:';
+$labels['newpasswd']  = 'Uus parool:';
+$labels['confpasswd']  = 'Uus parool uuesti:';
+
+$messages = array();
+$messages['nopassword'] = 'Palun sisesta uus parool.';
+$messages['nocurpassword'] = 'Palun sisesta vana parool.';
+$messages['passwordincorrect'] = 'Vana parool on vale.';
+$messages['passwordinconsistency'] = 'Paroolid ei kattu, palun proovi uuesti.';
+$messages['crypterror'] = 'Serveris ei ole parooli krüpteerimiseks vajalikku funktsiooni.';
+$messages['internalerror'] = 'Uue parooli andmebaasi salvestamine nurjus.';
+
+?>
diff --git a/plugins/password/localization/fr_FR.inc b/plugins/password/localization/fr_FR.inc
new file mode 100644 (file)
index 0000000..8ba37b1
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Changer le mot de passe';
+$labels['curpasswd']  = 'Mot de passe actuel:';
+$labels['newpasswd']  = 'Nouveau mot de passe:';
+$labels['confpasswd']  = 'Confirmez le nouveau mot de passe:';
+
+$messages = array();
+$messages['nopassword'] = 'Veuillez saisir le nouveau mot de passe.';
+$messages['nocurpassword'] = 'Veuillez saisir le mot de passe actuel.';
+$messages['passwordincorrect'] = 'Mot de passe actuel incorrect.';
+$messages['passwordinconsistency'] = 'Les nouveaux mots de passe ne correspondent pas, veuillez réessayer.';
+$messages['crypterror'] = 'Impossible d\'enregistrer le nouveau mot de passe. Fonction de cryptage manquante.';
+$messages['connecterror'] = 'Impossible d\'enregistrer le nouveau mot de passe. Erreur de connexion au serveur.';
+$messages['internalerror'] = 'Impossible d\'enregistrer le nouveau mot de passe.';
+
+?>
diff --git a/plugins/password/localization/hu_HU.inc b/plugins/password/localization/hu_HU.inc
new file mode 100644 (file)
index 0000000..c8c3015
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Jelszóváltás';
+$labels['curpasswd']  = 'Jelenlegi jelszó:';
+$labels['newpasswd']  = 'Új jelszó:';
+$labels['confpasswd']  = 'Új jelszó mégegyszer:';
+
+$messages = array();
+$messages['nopassword'] = 'Kérjük adja meg az új jelszót.';
+$messages['nocurpassword'] = 'Kérjük adja meg a jelenlegi jelszót.';
+$messages['passwordincorrect'] = 'Érvénytelen a jelenlegi jelszó.';
+$messages['passwordinconsistency'] = 'A két új jelszó nem egyezik.';
+$messages['crypterror'] = 'Hiba történt a kérés feldolgozása során.';
+$messages['internalerror'] = 'Hiba történt a kérés feldolgozása során.';
+
+?>
diff --git a/plugins/password/localization/it_IT.inc b/plugins/password/localization/it_IT.inc
new file mode 100644 (file)
index 0000000..b33d8d5
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Cambia la Password';
+$labels['curpasswd']  = 'Password corrente:';
+$labels['newpasswd']  = 'Nuova Password:';
+$labels['confpasswd']  = 'Conferma la Nuova Password:';
+
+$messages = array();
+$messages['nopassword'] = 'Per favore inserisci la nuova password.';
+$messages['nocurpassword'] = 'Per favore inserisci la password corrente.';
+$messages['passwordincorrect'] = 'Password corrente sbagliata.';
+$messages['passwordinconsistency'] = 'Le password non coincidono, inserirle di nuovo.';
+$messages['crypterror'] = 'Non posso salvare la password, funzione di cifratura assente.';
+$messages['connecterror'] = 'Non posso salvare la password, errore di connessione.';
+$messages['internalerror'] = 'Non posso salvare la password.';
+
+?>
diff --git a/plugins/password/localization/nl_NL.inc b/plugins/password/localization/nl_NL.inc
new file mode 100644 (file)
index 0000000..6d7c401
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Wijzig Wachtwoord';
+$labels['curpasswd']  = 'Huidig Wachtwoord:';
+$labels['newpasswd']  = 'Nieuw Wachtwoord:';
+$labels['confpasswd']  = 'Bevestig Nieuw Wachtwoord:';
+
+$messages = array();
+$messages['nopassword'] = 'Vul een wachtwoord in.';
+$messages['nocurpassword'] = 'vul het huidige wachtwoord in.';
+$messages['passwordincorrect'] = 'Huidig wachtwoord is onjuist.';
+$messages['passwordinconsistency'] = 'Wachtwoorden komen niet overeen, probeer het opnieuw.';
+$messages['crypterror'] = 'De server mist een functie om uw wachtwoord et beveiligen.';
+$messages['internalerror'] = 'Uw wachtwoord kan niet worden opgeslagen.';
+
+?>
diff --git a/plugins/password/localization/pl_PL.inc b/plugins/password/localization/pl_PL.inc
new file mode 100644 (file)
index 0000000..4520d79
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Zmiana hasła';
+$labels['curpasswd']  = 'Aktualne hasło:';
+$labels['newpasswd']  = 'Nowe hasło:';
+$labels['confpasswd']  = 'Potwierdź hasło:';
+
+$messages = array();
+$messages['nopassword'] = 'Wprowadź nowe hasło.';
+$messages['nocurpassword'] = 'Wprowadź aktualne hasło.';
+$messages['passwordincorrect'] = 'Błędne aktualne hasło, spróbuj ponownie.';
+$messages['passwordinconsistency'] = 'Hasła nie pasują, spróbuj ponownie.';
+$messages['crypterror'] = 'Nie udało się zapisać nowego hasła. Brak funkcji kodującej.';
+$messages['connecterror'] = 'Nie udało się zapisać nowego hasła. Błąd połączenia.';
+$messages['internalerror'] = 'Nie udało się zapisać nowego hasła.';
+
+?>
diff --git a/plugins/password/localization/pt_BR.inc b/plugins/password/localization/pt_BR.inc
new file mode 100644 (file)
index 0000000..c196d75
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Alterar senha';
+$labels['curpasswd']  = 'Senha atual:';
+$labels['newpasswd']  = 'Nova senha:';
+$labels['confpasswd']  = 'Confirmar nova senha:';
+
+$messages = array();
+$messages['nopassword'] = 'Por favor, informe a nova senha.';
+$messages['nocurpassword'] = 'Por favor, informe a senha atual.';
+$messages['passwordincorrect'] = 'Senha atual incorreta.';
+$messages['passwordinconsistency'] = 'Senhas não combinam, por favor tente novamente.';
+$messages['crypterror'] = 'Não foi possível gravar nova senha. Função de criptografia ausente.';
+$messages['connecterror'] = 'Não foi possível gravar nova senha. Erro de conexão.';
+$messages['internalerror'] = 'Não foi possível gravar nova senha.';
+
+?>
diff --git a/plugins/password/localization/pt_PT.inc b/plugins/password/localization/pt_PT.inc
new file mode 100644 (file)
index 0000000..80ddf58
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Alterar password';
+$labels['curpasswd']  = 'Password atual:';
+$labels['newpasswd']  = 'Nova password:';
+$labels['confpasswd']  = 'Confirmar password:';
+
+$messages = array();
+$messages['nopassword'] = 'Introduza a nova password.';
+$messages['nocurpassword'] = 'Introduza a password actual.';
+$messages['passwordincorrect'] = 'Password actual errada.';
+$messages['passwordinconsistency'] = 'Password's não combinam, tente novamente..';
+$messages['crypterror'] = 'Não foi possível gravar a nova password. Função de criptografica inexistente.';
+$messages['connecterror'] = 'Não foi possível gravar a nova password. Erro de ligação.';
+$messages['internalerror'] = 'Não foi possível gravar a nova password.';
+
+?>
diff --git a/plugins/password/localization/sl_SI.inc b/plugins/password/localization/sl_SI.inc
new file mode 100644 (file)
index 0000000..df17583
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+       
+$labels = array();
+$labels['changepasswd']  = 'Spremeni geslo';
+$labels['curpasswd']  = 'Obstoječe geslo:';
+$labels['newpasswd']  = 'Novo geslo:';
+$labels['confpasswd']  = 'Potrdi novo geslo:';
+       
+$messages = array();
+$messages['nopassword'] = 'Vnesite novo geslo.';
+$messages['nocurpassword'] = 'Vnesite obstoječe geslo.';
+$messages['passwordincorrect'] = 'Obstoječe geslo ni veljavno.';
+$messages['passwordinconsistency'] = 'Gesli se ne ujemata, poskusite znova.';
+$messages['crypterror'] = 'Novega gesla ni bilo mogoče shraniti. Prišlo je do napake pri šifriranju.';
+$messages['connecterror'] = 'Novega gesla ni bilo mogoče shraniti. Prišlo je do napake v povezavi.';
+$messages['internalerror'] = 'Novega gesla ni bilo mogoče shraniti.';
+
+?>
diff --git a/plugins/password/localization/sv_SE.inc b/plugins/password/localization/sv_SE.inc
new file mode 100644 (file)
index 0000000..5d9398e
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+$labels = array();
+$labels['changepasswd']  = 'Ändra lösenord';
+$labels['curpasswd']  = 'Nuvarande lösenord:';
+$labels['newpasswd']  = 'Nytt lösenord:';
+$labels['confpasswd']  = 'Bekräfta nytt lösenord:';
+
+$messages = array();
+$messages['nopassword'] = 'Vänligen ange nytt lösenord.';
+$messages['nocurpassword'] = 'Vänligen ange nuvarande lösenord.';
+$messages['passwordincorrect'] = 'Felaktigt nuvarande lösenord.';
+$messages['passwordinconsistency'] = 'Nya lösenordet och bekräftelsen överensstämmer inte, försök igen.';
+$messages['crypterror'] = 'Lösenordet kunde inte ändras. Krypteringsfunktionen saknas.';
+$messages['connecterror'] = 'Lösenordet kunde inte ändras. Anslutningen misslyckades.';
+$messages['internalerror'] = 'Lösenordet kunde inte ändras.';
+
+?>
\ No newline at end of file
diff --git a/plugins/password/password.js b/plugins/password/password.js
new file mode 100644 (file)
index 0000000..c3252f0
--- /dev/null
@@ -0,0 +1,36 @@
+/* Password change interface (tab) */
+
+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) });
+
+    // 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');
+          var input_confpasswd = rcube_find_object('_confpasswd');
+    
+      if (input_curpasswd && input_curpasswd.value=='') {
+          alert(rcmail.gettext('nocurpassword', 'password'));
+          input_curpasswd.focus();
+      } else if (input_newpasswd && input_newpasswd.value=='') {
+          alert(rcmail.gettext('nopassword', 'password'));
+          input_newpasswd.focus();
+      } else if (input_confpasswd && input_confpasswd.value=='') {
+          alert(rcmail.gettext('nopassword', 'password'));
+          input_confpasswd.focus();
+      } else if ((input_newpasswd && input_confpasswd) && (input_newpasswd.value != input_confpasswd.value)) {
+          alert(rcmail.gettext('passwordinconsistency', 'password'));
+          input_newpasswd.focus();
+      } else {
+          rcmail.gui_objects.passform.submit();
+      }
+    }, true);
+  })
+}
diff --git a/plugins/password/password.php b/plugins/password/password.php
new file mode 100644 (file)
index 0000000..0e5e1ef
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+
+/*
+ +-------------------------------------------------------------------------+
+ | Password Plugin for Roundcube                                           |
+ | Version 1.3.1                                                           |
+ |                                                                         |
+ | Copyright (C) 2009, RoundCube Dev.                                      |
+ |                                                                         |
+ | This program is free software; you can redistribute it and/or modify    |
+ | it under the terms of the GNU General Public License version 2          |
+ | as published by the Free Software Foundation.                           |
+ |                                                                         |
+ | This program is distributed in the hope that it will be useful,         |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
+ | GNU General Public License for more details.                            |
+ |                                                                         |
+ | You should have received a copy of the GNU General Public License along |
+ | with this program; if not, write to the Free Software Foundation, Inc., |
+ | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.             |
+ |                                                                         |
+ +-------------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl>                              |
+ +-------------------------------------------------------------------------+
+
+ $Id: index.php 2645 2009-06-15 07:01:36Z alec $
+
+*/
+
+define('PASSWORD_CRYPT_ERROR', 1);
+define('PASSWORD_ERROR', 2);
+define('PASSWORD_CONNECT_ERROR', 3);
+define('PASSWORD_SUCCESS', 0);
+
+/**
+ * Change password plugin
+ *
+ * Plugin that adds functionality to change a users password.
+ * It provides common functionality and user interface and supports
+ * several backends to finally update the password.
+ *
+ * For installation and configuration instructions please read the README file.
+ *
+ * @version 1.3.1
+ * @author Aleksander Machniak
+ */
+class password extends rcube_plugin
+{
+  public $task = 'settings';
+
+  function init()
+  {
+    $rcmail = rcmail::get_instance();
+    // add Tab label
+    $rcmail->output->add_label('password');
+    $this->register_action('plugin.password', array($this, 'password_init'));
+    $this->register_action('plugin.password-save', array($this, 'password_save'));
+    $this->include_script('password.js');
+  }
+
+  function password_init()
+  {
+    $this->add_texts('localization/');
+    $this->register_handler('plugin.body', array($this, 'password_form'));
+
+    $rcmail = rcmail::get_instance();
+    $rcmail->output->set_pagetitle($this->gettext('changepasswd'));
+    $rcmail->output->send('plugin');
+  }
+  
+  function password_save()
+  {
+    $rcmail = rcmail::get_instance();
+    $this->load_config();
+
+    $this->add_texts('localization/');
+    $this->register_handler('plugin.body', array($this, 'password_form'));
+    $rcmail->output->set_pagetitle($this->gettext('changepasswd'));
+
+    $confirm = $rcmail->config->get('password_confirm_current');
+
+    if (($confirm && !isset($_POST['_curpasswd'])) || !isset($_POST['_newpasswd'])) {
+      $rcmail->output->command('display_message', $this->gettext('nopassword'), 'error');
+    }
+    else {
+      $curpwd = get_input_value('_curpasswd', RCUBE_INPUT_POST);
+      $newpwd = get_input_value('_newpasswd', RCUBE_INPUT_POST);
+
+      if ($confirm && $rcmail->decrypt($_SESSION['password']) != $curpwd)
+        $rcmail->output->command('display_message', $this->gettext('passwordincorrect'), 'error');
+      else if (!($res = $this->_save($curpwd,$newpwd))) {
+        $rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation');
+        $_SESSION['password'] = $rcmail->encrypt($newpwd);
+      } else
+        $rcmail->output->command('display_message', $res, 'error');
+    }
+
+    rcmail_overwrite_action('plugin.password');
+    $rcmail->output->send('plugin');
+  }
+
+  function password_form()
+  {
+    $rcmail = rcmail::get_instance();
+    $this->load_config();
+
+    // add some labels to client
+    $rcmail->output->add_label(
+      'password.nopassword',
+      'password.nocurpassword',
+      'password.passwordinconsistency'
+    );
+
+    $rcmail->output->set_env('product_name', $rcmail->config->get('product_name'));
+
+    $table = new html_table(array('cols' => 2));
+
+    if ($rcmail->config->get('password_confirm_current')) {
+      // show current password selection
+      $field_id = 'curpasswd';
+      $input_curpasswd = new html_passwordfield(array('name' => '_curpasswd', 'id' => $field_id,
+        'size' => 20, 'autocomplete' => 'off'));
+  
+      $table->add('title', html::label($field_id, Q($this->gettext('curpasswd'))));
+      $table->add(null, $input_curpasswd->show());
+    }
+
+    // show new password selection
+    $field_id = 'newpasswd';
+    $input_newpasswd = new html_passwordfield(array('name' => '_newpasswd', 'id' => $field_id,
+      'size' => 20, 'autocomplete' => 'off'));
+
+    $table->add('title', html::label($field_id, Q($this->gettext('newpasswd'))));
+    $table->add(null, $input_newpasswd->show());
+
+    // show confirm password selection
+    $field_id = 'confpasswd';
+    $input_confpasswd = new html_passwordfield(array('name' => '_confpasswd', 'id' => $field_id,
+      'size' => 20, 'autocomplete' => 'off'));
+
+    $table->add('title', html::label($field_id, Q($this->gettext('confpasswd'))));
+    $table->add(null, $input_confpasswd->show());
+
+    $out = html::div(array('class' => "settingsbox", 'style' => "margin:0"),
+      html::div(array('id' => "prefs-title"), $this->gettext('changepasswd')) .
+      html::div(array('style' => "padding:15px"), $table->show() .
+        html::p(null,
+          $rcmail->output->button(array(
+            'command' => 'plugin.password-save',
+            'type' => 'input',
+            'class' => 'button mainaction',
+            'label' => 'save'
+        )))
+      )
+    );
+
+    $rcmail->output->add_gui_object('passform', 'password-form');
+
+    return $rcmail->output->form_tag(array(
+      'id' => 'password-form',
+      'name' => 'password-form',
+      'method' => 'post',
+      'action' => './?_task=settings&_action=plugin.password-save',
+      ), $out);
+  }
+
+  private function _save($curpass, $passwd)
+  {
+    $config = rcmail::get_instance()->config;
+    $driver = $this->home.'/drivers/'.$config->get('password_driver', 'sql').'.php';
+    
+    if (!is_readable($driver)) {
+      raise_error(array(
+        'code' => 600,
+        'type' => 'php',
+        'file' => __FILE__,
+        'message' => "Password plugin: Unable to open driver file $driver"
+        ), true, false);
+      return $this->gettext('internalerror');
+    }
+    
+    include($driver);
+
+    if (!function_exists('password_save')) {
+      raise_error(array(
+        'code' => 600,
+        'type' => 'php',
+        'file' => __FILE__,
+        'message' => "Password plugin: Broken driver: $driver"
+        ), true, false);
+      return $this->gettext('internalerror');
+    }
+
+    $result = password_save($curpass, $passwd);
+
+    switch ($result) {
+      case PASSWORD_SUCCESS:
+        return;
+      case PASSWORD_CRYPT_ERROR;
+        return $this->gettext('crypterror');
+      case PASSWORD_CONNECT_ERROR;
+        return $this->gettext('connecterror');
+      case PASSWORD_ERROR:
+      default:
+        return $this->gettext('internalerror');
+    }
+  }
+
+}
+
+?>
diff --git a/plugins/show_additional_headers/show_additional_headers.php b/plugins/show_additional_headers/show_additional_headers.php
new file mode 100644 (file)
index 0000000..7e7c503
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * Show additional message headers
+ *
+ * Proof-of-concept plugin which will fetch additional headers
+ * and display them in the message view.
+ *
+ * Enable the plugin in config/main.inc.php and add your desired headers:
+ *   $rcmail_config['show_additional_headers'] = array('User-Agent');
+ *
+ * @version 1.0
+ * @author Thomas Bruederli
+ * @website http://roundcube.net
+ */
+class show_additional_headers extends rcube_plugin
+{
+  public $task = 'mail';
+  
+  function init()
+  {
+    $rcmail = rcmail::get_instance();
+    if ($rcmail->action == 'show' || $rcmail->action == 'preview') {
+      $this->add_hook('imap_init', array($this, 'imap_init'));
+      $this->add_hook('message_headers_output', array($this, 'message_headers'));
+    } else if ($rcmail->action == '') {
+      // with enabled_caching we're fetching additional headers before show/preview
+      $this->add_hook('imap_init', array($this, 'imap_init'));
+    }
+  }
+  
+  function imap_init($p)
+  {
+    $rcmail = rcmail::get_instance();
+    if ($add_headers = $rcmail->config->get('show_additional_headers', array()))
+      $p['fetch_headers'] = trim($p['fetch_headers'].' ' . strtoupper(join(' ', $add_headers)));
+
+    return $p;
+  }
+
+  function message_headers($p)
+  {
+    $rcmail = rcmail::get_instance();
+    foreach ($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);
+    }
+
+    return $p;
+  }
+}
diff --git a/plugins/squirrelmail_usercopy/config.inc.php.dist b/plugins/squirrelmail_usercopy/config.inc.php.dist
new file mode 100644 (file)
index 0000000..5c2560f
--- /dev/null
@@ -0,0 +1,5 @@
+<?php
+
+// full path to the squirrelmail data directory
+$rcmail_config['squirrelmail_data_dir'] = '';
+
diff --git a/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php b/plugins/squirrelmail_usercopy/squirrelmail_usercopy.php
new file mode 100644 (file)
index 0000000..4a14ff2
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * Copy a new users identity and settings from a nearby Squirrelmail installation
+ *
+ * Currently only file-based data storage of Squirrelmail is supported.
+ *
+ * @version 1.0
+ * @author Thomas Bruederli
+ */
+class squirrelmail_usercopy extends rcube_plugin
+{
+       private $prefs = null;
+       private $abook = array();
+
+       public function init()
+       {
+               $this->add_hook('create_user', array($this, 'create_user'));
+               $this->add_hook('create_identity', array($this, 'create_identity'));
+       }
+
+       public function create_user($p)
+       {
+               // read prefs and add email address
+               $this->read_squirrel_prefs($p['user']);
+               if ($this->prefs['email_address'])
+                       $p['user_email'] = $this->prefs['email_address'];
+
+               return $p;
+       }
+
+       public function create_identity($p)
+       {
+               // only execute on login
+               if ($p['login'] && $this->prefs) {
+                       if ($this->prefs['full_name'])
+                               $p['record']['name'] = $this->prefs['full_name'];
+                       if ($this->prefs['email_address'])
+                               $p['record']['email'] = $this->prefs['email_address'];
+                       if ($this->prefs['signature'])
+                               $p['record']['signature'] = $this->prefs['signature'];
+               
+                       // copy address book
+                       $rcmail = rcmail::get_instance();
+                       $contacts = $rcmail->get_address_book(null, true);
+                       if ($contacts && count($this->abook)) {
+                               foreach ($this->abook as $rec)
+                                       $contacts->insert($rec, true);
+                       }
+                       
+                       // mark identity as complete for following hooks
+                       $p['complete'] = true;
+               }
+
+               return $p;
+       }
+
+       private function read_squirrel_prefs($uname)
+       {
+               $this->load_config();
+               $rcmail = rcmail::get_instance();
+
+               if ($srcdir = $rcmail->config->get('squirrelmail_data_dir')) {
+                       $prefsfile = slashify($srcdir) . $uname . '.pref';
+                       $abookfile = slashify($srcdir) . $uname . '.abook';
+                       $sigfile = slashify($srcdir) . $uname . '.sig';
+
+                       if (is_readable($prefsfile)) {
+                               $this->prefs = array();
+                               foreach (file($prefsfile) as $line) {
+                                       list($key, $value) = explode('=', $line);
+                                       $this->prefs[$key] = utf8_encode(rtrim($value));
+                               }
+
+                               // also read signature file if exists
+                               if (is_readable($sigfile)) {
+                                       $this->prefs['signature'] = utf8_encode(file_get_contents($sigfile));
+                               }
+
+                               // parse addres book file
+                               if (filesize($abookfile)) {
+                                       foreach(file($abookfile) as $line) {
+                                               list($rec['name'], $rec['firstname'], $rec['surname'], $rec['email']) = explode('|', utf8_encode(rtrim($line)));
+                                               if ($rec['name'] && $rec['email'])
+                                                       $this->abook[] = $rec;
+                                       }
+                               }
+                       }
+               }
+       }
+
+}
+
+?>
\ No newline at end of file
diff --git a/plugins/subscriptions_option/localization/en_US.inc b/plugins/subscriptions_option/localization/en_US.inc
new file mode 100644 (file)
index 0000000..5a348e0
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+$labels = array();
+$labels['useimapsubscriptions']  = 'Use IMAP Subscriptions';
+
+?>
diff --git a/plugins/subscriptions_option/localization/et_EE.inc b/plugins/subscriptions_option/localization/et_EE.inc
new file mode 100644 (file)
index 0000000..6c5f6f4
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+$labels = array();
+$labels['useimapsubscriptions']  = 'Kasuta IMAP tellimusi';
+
+?>
diff --git a/plugins/subscriptions_option/localization/pl_PL.inc b/plugins/subscriptions_option/localization/pl_PL.inc
new file mode 100644 (file)
index 0000000..8544c7d
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+$labels = array();
+$labels['useimapsubscriptions']  = 'Używaj subskrypcji IMAP';
+
+?>
diff --git a/plugins/subscriptions_option/localization/sv_SE.inc b/plugins/subscriptions_option/localization/sv_SE.inc
new file mode 100644 (file)
index 0000000..05b7006
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+$labels = array();
+$labels['useimapsubscriptions']  = 'Använd IMAP-prenumerationer';
+
+?>
diff --git a/plugins/subscriptions_option/subscriptions_option.php b/plugins/subscriptions_option/subscriptions_option.php
new file mode 100644 (file)
index 0000000..09ee6e3
--- /dev/null
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * Subscription Options
+ *
+ * A plugin which can enable or disable the use of imap subscriptions.
+ * It includes a toggle on the settings page under "Server Settings".
+ * The preference can also be locked
+ *
+ * Add it to the plugins list in config/main.inc.php to enable the user option
+ * The user option can be hidden and set globally by adding 'use_subscriptions'
+ * to the the 'dont_override' configure line:
+ * $rcmail_config['dont_override'] = array('use_subscriptions');
+ * and then set the global preference
+ * $rcmail_config['use_subscriptions'] = true; // or false
+ *
+ * Roundcube caches folder lists.  When a user changes this option or visits
+ * their folder list, this cache is refreshed.  If the option is on the
+ * 'dont_override' list and the global option has changed, don't expect
+ * to see the change until the folder list cache is refreshed.
+ *
+ * @version 1.0
+ * @author Ziba Scott
+ */
+class subscriptions_option extends rcube_plugin
+{
+    public $task = 'mail|settings';
+    
+    function init()
+    {
+        $this->add_texts('localization/', false);
+        $dont_override = rcmail::get_instance()->config->get('dont_override', array());
+        if (!in_array('use_subscriptions', $dont_override)) {
+            $this->add_hook('user_preferences', array($this, 'settings_blocks'));
+            $this->add_hook('save_preferences', array($this, 'save_prefs'));
+        }
+        $this->add_hook('list_mailboxes', array($this, 'list_mailboxes'));
+        $this->add_hook('manage_folders', array($this, 'manage_folders'));
+    }
+
+    function settings_blocks($args)
+    {
+        if ($args['section'] == 'server') {
+            $use_subscriptions = rcmail::get_instance()->config->get('use_subscriptions');
+            $field_id = 'rcmfd_use_subscriptions';
+            $checkbox = new html_checkbox(array('name' => '_use_subscriptions', 'id' => $field_id, 'value' => 1));
+
+            $args['blocks']['main']['options']['use_subscriptions'] = array(
+               'title' => html::label($field_id, Q($this->gettext('useimapsubscriptions'))),
+                'content' => $checkbox->show($use_subscriptions?1:0),
+           );
+        }
+
+        return $args;
+    }
+
+    function save_prefs($args)
+    {
+        if ($args['section'] == 'server') {
+           $rcmail = rcmail::get_instance();
+            $use_subscriptions = $rcmail->config->get('use_subscriptions');
+
+           $args['prefs']['use_subscriptions'] = isset($_POST['_use_subscriptions']) ? true : false;
+
+           // if the use_subscriptions preference changes, flush the folder cache
+           if (($use_subscriptions && !isset($_POST['_use_subscriptions'])) ||
+               (!$use_subscriptions && isset($_POST['_use_subscriptions']))) {
+                   $rcmail->imap_init(true);
+                   $rcmail->imap->clear_cache('mailboxes');
+           }
+       }
+        return $args;
+    }
+
+    function list_mailboxes($args)
+    {
+        $rcmail = rcmail::get_instance();
+        if (!$rcmail->config->get('use_subscriptions', true)) {
+            $args['folders'] = iil_C_ListMailboxes($rcmail->imap->conn, $rcmail->imap->mod_mailbox($args['root']), $args['filter']);
+        }
+        return $args;
+    }
+
+    function manage_folders($args)
+    {
+        $rcmail = rcmail::get_instance();
+        if (!$rcmail->config->get('use_subscriptions', true)) {
+            $args['table']->remove_column('subscribed');
+        }
+        return $args;
+    }
+}
diff --git a/plugins/userinfo/localization/de_CH.inc b/plugins/userinfo/localization/de_CH.inc
new file mode 100644 (file)
index 0000000..5f236b6
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['userinfo'] = 'Benutzerinfo';
+$labels['created'] = 'Erstellt';
+$labels['lastlogin'] = 'Letztes Login';
+$labels['defaultidentity'] = 'Standard-Absender';
+
+?>
\ No newline at end of file
diff --git a/plugins/userinfo/localization/en_US.inc b/plugins/userinfo/localization/en_US.inc
new file mode 100644 (file)
index 0000000..1a2fd90
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['userinfo'] = 'User info';
+$labels['created'] = 'Created';
+$labels['lastlogin'] = 'Last Login';
+$labels['defaultidentity'] = 'Default Identity';
+
+?>
\ No newline at end of file
diff --git a/plugins/userinfo/localization/et_EE.inc b/plugins/userinfo/localization/et_EE.inc
new file mode 100644 (file)
index 0000000..97830b4
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['userinfo'] = 'Kasutaja info';
+$labels['created'] = 'Loodud';
+$labels['lastlogin'] = 'Viimane logimine';
+$labels['defaultidentity'] = 'Vaikeidentiteet';
+
+?>
diff --git a/plugins/userinfo/localization/pl_PL.inc b/plugins/userinfo/localization/pl_PL.inc
new file mode 100644 (file)
index 0000000..6b03c32
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['userinfo'] = 'Informacje';
+$labels['created'] = 'Utworzony';
+$labels['lastlogin'] = 'Ostatnie logowanie';
+$labels['defaultidentity'] = 'Domyślna tożsamość';
+
+?>
diff --git a/plugins/userinfo/localization/pt_PT.inc b/plugins/userinfo/localization/pt_PT.inc
new file mode 100644 (file)
index 0000000..e36d678
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['userinfo'] = 'Informação do utilizador';
+$labels['created'] = 'Criado';
+$labels['lastlogin'] = 'Último login';
+$labels['defaultidentity'] = 'Identidade pré-definida';
+
+?>
diff --git a/plugins/userinfo/localization/sv_SE.inc b/plugins/userinfo/localization/sv_SE.inc
new file mode 100644 (file)
index 0000000..a34923a
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['userinfo'] = 'Användarinfo';
+$labels['created'] = 'Skapad';
+$labels['lastlogin'] = 'Senast inloggad';
+$labels['defaultidentity'] = 'Standardprofil';
+
+?>
\ No newline at end of file
diff --git a/plugins/userinfo/userinfo.js b/plugins/userinfo/userinfo.js
new file mode 100644 (file)
index 0000000..70a5085
--- /dev/null
@@ -0,0 +1,16 @@
+/* Show user-info plugin script */
+
+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', 'settingstabpluginuserinfo').addClass('tablink');
+    
+    var button = $('<a>').attr('href', rcmail.env.comm_path+'&_action=plugin.userinfo').html(rcmail.gettext('userinfo', 'userinfo')).appendTo(tab);
+    button.bind('click', function(e){ return rcmail.command('plugin.userinfo', this) });
+    
+    // add button and register command
+    rcmail.add_element(tab, 'tabs');
+    rcmail.register_command('plugin.userinfo', function(){ rcmail.goto_url('plugin.userinfo') }, true);
+  })
+}
+
diff --git a/plugins/userinfo/userinfo.php b/plugins/userinfo/userinfo.php
new file mode 100644 (file)
index 0000000..0f1b18c
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Sample plugin that adds a new tab to the settings section
+ * to display some information about the current user
+ */
+class userinfo extends rcube_plugin
+{
+  public $task = 'settings';
+
+  function init()
+  {
+    $this->add_texts('localization/', array('userinfo'));
+    $this->register_action('plugin.userinfo', array($this, 'infostep'));
+    $this->include_script('userinfo.js');
+  }
+
+  function infostep()
+  {
+    $this->register_handler('plugin.body', array($this, 'infohtml'));
+    rcmail::get_instance()->output->send('plugin');
+  }
+  
+  function infohtml()
+  {
+    $rcmail = rcmail::get_instance();
+    $user = $rcmail->user;
+    
+    $table = new html_table(array('cols' => 2, 'cellpadding' => 3));
+
+    $table->add('title', 'ID');
+    $table->add('', Q($user->ID));
+    
+    $table->add('title', Q($this->gettext('username')));
+    $table->add('', Q($user->data['username']));
+    
+    $table->add('title', Q($this->gettext('server')));
+    $table->add('', Q($user->data['mail_host']));
+
+    $table->add('title', Q($this->gettext('created')));
+    $table->add('', Q($user->data['created']));
+
+    $table->add('title', Q($this->gettext('lastlogin')));
+    $table->add('', Q($user->data['last_login']));
+    
+    $identity = $user->get_identity();
+    $table->add('title', Q($this->gettext('defaultidentity')));
+    $table->add('', Q($identity['name'] . ' <' . $identity['email'] . '>'));
+    
+    return html::tag('h4', null, Q('Infos for ' . $user->get_username())) . $table->show();
+  }
+
+}
\ No newline at end of file
diff --git a/plugins/vcard_attachments/vcard_add_contact.png b/plugins/vcard_attachments/vcard_add_contact.png
new file mode 100644 (file)
index 0000000..478c1f3
Binary files /dev/null and b/plugins/vcard_attachments/vcard_add_contact.png differ
diff --git a/plugins/vcard_attachments/vcard_attachments.php b/plugins/vcard_attachments/vcard_attachments.php
new file mode 100644 (file)
index 0000000..532311e
--- /dev/null
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * Detect VCard attachments and show a button to add them to address book
+ *
+ * @version 1.0
+ * @author Thomas Bruederli
+ */
+class vcard_attachments extends rcube_plugin
+{
+  public $task = 'mail';
+  
+  private $message;
+  private $vcard_part;
+
+  function init()
+  {
+    $rcmail = rcmail::get_instance();
+    if ($rcmail->action == 'show' || $rcmail->action == 'preview') {
+      $this->add_hook('message_load', array($this, 'message_load'));
+      $this->add_hook('template_object_messagebody', array($this, 'html_output'));
+    }
+    
+    $this->register_action('plugin.savevcard', array($this, 'save_vcard'));
+  }
+  
+  /**
+   * Check message attachments for vcards
+   */
+  function message_load($p)
+  {
+    $this->message = $p['object'];
+    
+    foreach ((array)$this->message->attachments as $attachment) {
+      if (in_array($attachment->mimetype, array('text/vcard', 'text/x-vcard')))
+        $this->vcard_part = $attachment->mime_id;
+    }
+  }
+  
+  /**
+   * This callback function adds a box below the message content
+   * if there is a vcard attachment available
+   */
+  function html_output($p)
+  {
+    if ($this->vcard_part) {
+      $vcard = new rcube_vcard($this->message->get_part_content($this->vcard_part));
+      
+      // successfully parsed vcard
+      if ($vcard->displayname) {
+        $display = $vcard->displayname;
+        if ($vcard->email[0])
+          $display .= ' <'.$vcard->email[0].'>';
+        
+        // add box below messsage body
+        $p['content'] .= html::p(array('style' => "margin:1em; padding:0.5em; border:1px solid #999; border-radius:4px; -moz-border-radius:4px; -webkit-border-radius:4px; width: auto;"),
+          html::a(array(
+              'href' => "#",
+              'onclick' => "return plugin_vcard_save_contact('".JQ($this->vcard_part)."')",
+              'title' => "Save contact in local address book"),  // TODO: localize this title
+            html::img(array('src' => $this->url('vcard_add_contact.png'), 'align' => "middle")))
+            . ' ' . html::span(null, Q($display)));
+        
+        $this->include_script('vcardattach.js');
+      }
+    }
+    
+    return $p;
+  }
+  
+  /**
+   * Handler for request action
+   */
+  function save_vcard()
+  {
+    $uid = get_input_value('_uid', RCUBE_INPUT_POST);
+    $mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
+    $mime_id = get_input_value('_part', RCUBE_INPUT_POST);
+    
+    $rcmail = rcmail::get_instance();
+    $part = $uid && $mime_id ? $rcmail->imap->get_message_part($uid, $mime_id) : null;
+    
+    $error_msg = 'Failed to saved vcard'; // TODO: localize this text
+    
+    if ($part && ($vcard = new rcube_vcard($part)) && $vcard->displayname && $vcard->email) {
+      $contacts = $rcmail->get_address_book(null, true);
+      
+      // check for existing contacts
+      $existing = $contacts->search('email', $vcard->email[0], true, false);
+      if ($done = $existing->count) {
+        $rcmail->output->command('display_message', $this->gettext('contactexists'), 'warning');
+      }
+      else {
+        // add contact
+        $success = $contacts->insert(array(
+          'name' => $vcard->displayname,
+          'firstname' => $vcard->firstname,
+          'surname' => $vcard->surname,
+          'email' => $vcard->email[0],
+          'vcard' => $vcard->export(),
+        ));
+        
+        if ($success)
+          $rcmail->output->command('display_message', $this->gettext('addedsuccessfully'), 'confirmation');
+        else
+          $rcmail->output->command('display_message', $error_msg, 'error');
+      }
+    }
+    else
+      $rcmail->output->command('display_message', $error_msg, 'error');
+    
+    $rcmail->output->send();
+  }
+  
+}
\ No newline at end of file
diff --git a/plugins/vcard_attachments/vcardattach.js b/plugins/vcard_attachments/vcardattach.js
new file mode 100644 (file)
index 0000000..e03e508
--- /dev/null
@@ -0,0 +1,10 @@
+
+function plugin_vcard_save_contact(mime_id)
+{
+  rcmail.set_busy(true, 'loading');
+  rcmail.http_post('plugin.savevcard', '_uid='+rcmail.env.uid+'&_mbox='+urlencode(rcmail.env.mailbox)+'&_part='+urlencode(mime_id), true);
+  
+  return false;
+}
+
+
index e5dcf42236b4771d79969f3608770f704f72331a..4ce4998c4efdde65243a0c7322eda5d566f9a63f 100644 (file)
@@ -5,7 +5,7 @@
  | program/include/bugs.inc                                              |
  |                                                                       |
  | This file is part of the RoudCube Webmail client                      |
- | Copyright (C) 2005-2007, RoudCube Dev - Switzerland                   |
+ | Copyright (C) 2005-2009, RoudCube Dev - Switzerland                   |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: bugs.inc 2025 2008-10-30 09:15:01Z alec $
+ $Id: bugs.inc 2862 2009-08-17 09:54:53Z thomasb $
 
 */
 
@@ -73,31 +73,16 @@ function log_bug($arg_arr)
   if ($CONFIG['debug_level'] & 1)
   {
     $post_query = ($_SERVER['REQUEST_METHOD'] == 'POST' ? '?_task='.urlencode($_POST['_task']).'&_action='.urlencode($_POST['_action']) : '');
-    $log_entry = sprintf("[%s] %s Error: %s%s (%s %s)\n",
-      date("d-M-Y H:i:s O", mktime()),
+    $log_entry = sprintf("%s Error: %s%s (%s %s)",
       $program,
       $arg_arr['message'],
       $arg_arr['file'] ? sprintf(' in %s on line %d', $arg_arr['file'], $arg_arr['line']) : '',
       $_SERVER['REQUEST_METHOD'],
       $_SERVER['REQUEST_URI'] . $post_query);
-      
-    if (empty($CONFIG['log_dir']))
-      $CONFIG['log_dir'] = INSTALL_PATH.'logs';
-      
-    // try to open specific log file for writing
-    if ($CONFIG['log_driver'] == 'syslog')
+    
+    if (!write_log('errors', $log_entry))
     {
-      syslog(LOG_ERR, $log_entry);
-    }
-    else if ($fp = @fopen($CONFIG['log_dir'].'/errors', 'a'))
-    {
-      // log_driver == 'file' is the default, assumed here.
-      fwrite($fp, $log_entry);
-      fclose($fp);
-    }
-    else
-    {
-      // send error to PHPs error handler
+      // send error to PHPs error handler if write_log didn't succeed
       trigger_error($arg_arr['message']);
     }
   }
index 01ad415443ff04d7e2c77903a10ee159cef4322f..350b894ee940baf1bc655d89ac8074f52b9fb837 100644 (file)
@@ -33,7 +33,7 @@ class html
     protected $content;
 
     public static $common_attrib = array('id','class','style','title','align');
-    public static $containers = array('iframe','div','span','p','h1','h2','h3','form','textarea','table','tr','th','td','style');
+    public static $containers = array('iframe','div','span','p','h1','h2','h3','form','textarea','table','tr','th','td','style','script');
     public static $lc_tags = true;
 
     /**
@@ -457,7 +457,7 @@ class html_textarea extends html
             unset($this->attrib['value']);
         }
 
-        if (!empty($value) && !ereg('mce_editor', $this->attrib['class'])) {
+        if (!empty($value) && !preg_match('/mce_editor/', $this->attrib['class'])) {
             $value = Q($value, 'strict', false);
         }
 
@@ -599,6 +599,34 @@ class html_table extends html
         $this->header[] = $cell;
     }
 
+     /**
+     * Remove a column from a table
+     * Useful for plugins making alterations
+     * 
+     * @param string $class 
+     */
+    public function remove_column($class)
+    {
+        // Remove the header
+        foreach($this->header as $index=>$header){
+            if($header->attrib['class'] == $class){
+                unset($this->header[$index]);
+                break;
+            }
+        }
+
+        // Remove cells from rows
+        foreach($this->rows as $i=>$row){
+            foreach($row->cells as $j=>$cell){
+                if($cell->attrib['class'] == $class){
+                    unset($this->rows[$i]->cells[$j]);
+                    break;
+                }
+            }
+        }
+    }
+
+
     /**
      * Jump to next row
      *
index 5ca17ccf06dc553a9c538ebfee566ddf180cb2a1..5d836860bb0add2587bde62248c5e7932b5cb582 100755 (executable)
  |         Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: cache.inc 88 2005-12-03 16:54:12Z roundcube $
+ $Id: iniset.php 2916 2009-09-04 10:58:29Z thomasb $
 
 */
 
 
 // application constants
-define('RCMAIL_VERSION', '0.2.2');
+define('RCMAIL_VERSION', '0.3-stable');
 define('RCMAIL_CHARSET', 'UTF-8');
 define('JS_OBJECT_NAME', 'rcmail');
 
@@ -34,7 +34,7 @@ define('RCMAIL_CONFIG_DIR', INSTALL_PATH . 'config');
 
 // make sure path_separator is defined
 if (!defined('PATH_SEPARATOR')) {
-  define('PATH_SEPARATOR', (eregi('win', PHP_OS) ? ';' : ':'));
+  define('PATH_SEPARATOR', (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') ? ';' : ':');
 }
 
 // RC include folders MUST be included FIRST to avoid other
@@ -58,8 +58,10 @@ if  (isset($_SERVER['HTTPS'])) {
 }
 ini_set('session.name', 'roundcube_sessid');
 ini_set('session.use_cookies', 1);
-ini_set('session.only_use_cookies', 1);
-set_magic_quotes_runtime(0);
+ini_set('session.use_only_cookies', 1);
+if (function_exists('set_magic_quotes_runtime')) {
+  set_magic_quotes_runtime(0);
+}
 
 // increase maximum execution time for php scripts
 // (does not work in safe mode)
@@ -78,26 +80,32 @@ if(extension_loaded('mbstring'))
  * @todo Make Zend, PEAR etc play with this
  * @todo Make our classes conform to a more straight forward CS.
  */
-function __autoload($classname)
+function rcube_autoload($classname)
 {
   $filename = preg_replace(
-      array('/MDB2_(.+)/',
-           '/Mail_(.+)/',
-           '/^html_.+/',
-           '/^utf8$/',
-           '/html2text/'
-       ),
-      array('MDB2/\\1',
-           'Mail/\\1',
-           'html',
-           'utf8.class',
-           'lib/html2text'     // see #1485505
-       ),
+      array(
+        '/MDB2_(.+)/',
+        '/Mail_(.+)/',
+        '/Net_(.+)/',
+        '/^html_.+/',
+        '/^utf8$/',
+        '/html2text/'
+      ),
+      array(
+        'MDB2/\\1',
+        'Mail/\\1',
+        'Net/\\1',
+        'html',
+        'utf8.class',
+        'lib/html2text'  // see #1485505
+      ),
       $classname
   );
   include $filename. '.php';
 }
 
+spl_autoload_register('rcube_autoload');
+
 /**
  * Local callback function for PEAR errors
  */
index 4c6ddffb272f764ef910c769af61dcbc4258c944..f25f4cbd755f45b6f285c7255e9287db6baaeb82 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: main.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: main.inc 2852 2009-08-10 21:32:44Z thomasb $
 
 */
 
@@ -84,9 +84,9 @@ function get_sequence_name($sequence)
  * @return string Localized text
  * @see rcmail::gettext()
  */
-function rcube_label($p)
+function rcube_label($p, $domain=null)
 {
-  return rcmail::get_instance()->gettext($p);
+  return rcmail::get_instance()->gettext($p, $domain);
 }
 
 
@@ -124,7 +124,9 @@ function rcmail_url($action, $p=array(), $task=null)
  */
 function rcmail_temp_gc()
   {
-  $tmp = unslashify($CONFIG['temp_dir']);
+  $rcmail = rcmail::get_instance();
+
+  $tmp = unslashify($rcmail->config->get('temp_dir'));
   $expire = mktime() - 172800;  // expire in 48 hours
 
   if ($dir = opendir($tmp))
@@ -177,35 +179,19 @@ function rcube_charset_convert($str, $from, $to=NULL)
   static $mbstring_loaded = null;
   static $mbstring_list = null;
   static $convert_warning = false;
+  static $conv = null;
+  
+  $error = false;
 
-  $from = strtoupper($from);
-  $to = $to==NULL ? strtoupper(RCMAIL_CHARSET) : strtoupper($to);
-  $error = false; $conv = null;
-
-  # RFC1642
-  if ($from == 'UNICODE-1-1-UTF-7')
-    $from = 'UTF-7';
-  if ($to == 'UNICODE-1-1-UTF-7')
-    $to = 'UTF-7';
+  $to = empty($to) ? $to = strtoupper(RCMAIL_CHARSET) : rcube_parse_charset($to);
+  $from = rcube_parse_charset($from);
 
   if ($from == $to || empty($str) || empty($from))
     return $str;
-    
-  $aliases = array(
-    'US-ASCII'         => 'ISO-8859-1',
-    'ANSI_X3.110-1983' => 'ISO-8859-1',
-    'ANSI_X3.4-1968'   => 'ISO-8859-1',
-    'UNKNOWN-8BIT'     => 'ISO-8859-15',
-    'X-UNKNOWN'        => 'ISO-8859-15',
-    'X-USER-DEFINED'   => 'ISO-8859-15',
-    'ISO-8859-8-I'     => 'ISO-8859-8',
-    'KS_C_5601-1987'   => 'EUC-KR',
-  );
 
   // convert charset using iconv module  
   if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') {
-    $aliases['GB2312'] = 'GB18030';
-    $_iconv = iconv(($aliases[$from] ? $aliases[$from] : $from), ($aliases[$to] ? $aliases[$to] : $to) . "//IGNORE", $str);
+    $_iconv = iconv($from, $to . '//IGNORE', $str);
     if ($_iconv !== false) {
         return $_iconv;
     }
@@ -216,14 +202,13 @@ function rcube_charset_convert($str, $from, $to=NULL)
     
   // convert charset using mbstring module
   if ($mbstring_loaded) {
-    $aliases['UTF-7'] = 'UTF7-IMAP';
     $aliases['WINDOWS-1257'] = 'ISO-8859-13';
     
     if (is_null($mbstring_list)) {
       $mbstring_list = mb_list_encodings();
       $mbstring_list = array_map('strtoupper', $mbstring_list);
     }
-    
+
     $mb_from = $aliases[$from] ? $aliases[$from] : $from;
     $mb_to = $aliases[$to] ? $aliases[$to] : $to;
     
@@ -234,59 +219,211 @@ function rcube_charset_convert($str, $from, $to=NULL)
     }
   }
 
-  # try to convert with custom classes
-  if (class_exists('utf8'))
-    $conv = new utf8();
-
-  // convert string to UTF-8
-  if ($from == 'UTF-7') {
-    if ($_str = utf7_to_utf8($str))
-      $str = $_str;
-    else
-      $error = true;
-  }
-  else if (($from == 'ISO-8859-1') && function_exists('utf8_encode')) {
-    $str = utf8_encode($str);
-  }
-  else if ($from != 'UTF-8' && $conv) {
-    $conv->loadCharset($from);
-    $str = $conv->strToUtf8($str);
-  }
-  else if ($from != 'UTF-8')
+  // convert charset using bundled classes/functions
+  if ($to == 'UTF-8') {
+    if ($from == 'UTF7-IMAP') {
+      if ($_str = utf7_to_utf8($str))
+        return $_str;
+    }
+    else if ($from == 'UTF-7') {
+      if ($_str = rcube_utf7_to_utf8($str))
+        return $_str;
+    }
+    else if (($from == 'ISO-8859-1') && function_exists('utf8_encode')) {
+      return utf8_encode($str);
+    }
+    else if (class_exists('utf8')) {
+      if (!$conv)
+        $conv = new utf8($from);
+      else
+        $conv->loadCharset($from);
+
+      if($_str = $conv->strToUtf8($str))
+        return $_str;
+    }
     $error = true;
-
-  // encode string for output
-  if ($to == 'UTF-7') {
-    return utf8_to_utf7($str);
-  }
-  else if ($to == 'ISO-8859-1' && function_exists('utf8_decode')) {
-    return utf8_decode($str);
   }
-  else if ($to != 'UTF-8' && $conv) {
-    $conv->loadCharset($to);
-    return $conv->utf8ToStr($str);
-  }
-  else if ($to != 'UTF-8') {
+  
+  // encode string for output
+  if ($from == 'UTF-8') {
+    // @TODO: we need a function for UTF-7 (RFC2152) conversion
+    if ($to == 'UTF7-IMAP' || $to == 'UTF-7') {
+      if ($_str = utf8_to_utf7($str))
+        return $_str;
+    }
+    else if ($to == 'ISO-8859-1' && function_exists('utf8_decode')) {
+      return utf8_decode($str);
+    }
+    else if (class_exists('utf8')) {
+      if (!$conv)
+        $conv = new utf8($to);
+      else
+        $conv->loadCharset($from);
+
+      if ($_str = $conv->strToUtf8($str))
+        return $_str;
+    }
     $error = true;
   }
   
   // report error
-  if ($error && !$convert_warning){
+  if ($error && !$convert_warning) {
     raise_error(array(
       'code' => 500,
       'type' => 'php',
       'file' => __FILE__,
-      'message' => "Could not convert string from $from to $to. Make sure iconv is installed or lib/utf8.class is available"
+      'line' => __LINE__,
+      'message' => "Could not convert string from $from to $to. Make sure iconv/mbstring is installed or lib/utf8.class is available."
       ), true, false);
     
     $convert_warning = true;
   }
   
-  // return UTF-8 string
+  // return UTF-8 or original string
   return $str;
   }
 
 
+/**
+ * Parse and validate charset name string (see #1485758).
+ * Sometimes charset string is malformed, there are also charset aliases 
+ * but we need strict names for charset conversion (specially utf8 class)
+ *
+ * @param  string  Input charset name
+ * @return The validated charset name
+ */
+function rcube_parse_charset($charset)
+  {
+  $charset = strtoupper($charset);
+
+  # RFC1642
+  $charset = str_replace('UNICODE-1-1-', '', $charset);
+
+  # Aliases: some of them from HTML5 spec.
+  $aliases = array(
+    'USASCII'       => 'WINDOWS-1252',
+    'ANSIX31101983' => 'WINDOWS-1252',
+    'ANSIX341968'   => 'WINDOWS-1252',
+    'UNKNOWN8BIT'   => 'ISO-8859-15',
+    'UNKNOWN'       => 'ISO-8859-15',
+    'USERDEFINED'   => 'ISO-8859-15',
+    'KSC56011987'   => 'EUC-KR',
+    'GB2312'       => 'GBK',
+    'GB231280'     => 'GBK',
+    'UNICODE'      => 'UTF-8',
+    'UTF7IMAP'     => 'UTF7-IMAP',
+    'TIS620'       => 'WINDOWS-874',
+    'ISO88599'     => 'WINDOWS-1254',
+    'ISO885911'            => 'WINDOWS-874',
+  );
+
+  // allow a-z and 0-9 only and remove X- prefix (e.g. X-ROMAN8 => ROMAN8)
+  $str = preg_replace(array('/[^a-z0-9]/i', '/^x+/i'), '', $charset);
+
+  if (isset($aliases[$str]))
+    return $aliases[$str];
+
+  if (preg_match('/UTF(7|8|16|32)(BE|LE)*/', $str, $m))
+    return 'UTF-' . $m[1] . $m[2];
+
+  if (preg_match('/ISO8859([0-9]{0,2})/', $str, $m)) {
+    $iso = 'ISO-8859-' . ($m[1] ? $m[1] : 1);
+    # some clients sends windows-1252 text as latin1,
+    # it is safe to use windows-1252 for all latin1
+    return $iso == 'ISO-8859-1' ? 'WINDOWS-1252' : $iso;
+    }
+
+  return $charset;
+  }
+
+
+/**
+ * Converts string from standard UTF-7 (RFC 2152) to UTF-8.
+ *
+ * @param  string  Input string
+ * @return The converted string
+ */
+function rcube_utf7_to_utf8($str)
+{
+  $Index_64 = array(
+    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
+    0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0,
+    1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,
+    0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
+    1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
+    0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
+    1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
+  );
+
+  $u7len = strlen($str);
+  $str = strval($str);
+  $res = '';
+
+  for ($i=0; $u7len > 0; $i++, $u7len--)
+  {
+    $u7 = $str[$i];
+    if ($u7 == '+')
+    {
+      $i++;
+      $u7len--;
+      $ch = '';
+
+      for (; $u7len > 0; $i++, $u7len--)
+      {
+        $u7 = $str[$i];
+
+        if (!$Index_64[ord($u7)])
+          break;
+
+       $ch .= $u7;
+      }
+
+      if ($ch == '') {
+        if ($u7 == '-')
+          $res .= '+';
+        continue;
+      }
+
+      $res .= rcube_utf16_to_utf8(base64_decode($ch));
+    }
+    else
+    {
+      $res .= $u7;
+    }
+  }
+
+  return $res;
+}
+
+/**
+ * Converts string from UTF-16 to UTF-8 (helper for utf-7 to utf-8 conversion)
+ *
+ * @param  string  Input string
+ * @return The converted string
+ */
+function rcube_utf16_to_utf8($str)
+{
+  $len = strlen($str);
+  $dec = '';
+
+  for ($i = 0; $i < $len; $i += 2) {
+    $c = ord($str[$i]) << 8 | ord($str[$i + 1]);
+    if ($c >= 0x0001 && $c <= 0x007F) {
+      $dec .= chr($c);
+    } else if ($c > 0x07FF) {
+      $dec .= chr(0xE0 | (($c >> 12) & 0x0F));
+      $dec .= chr(0x80 | (($c >>  6) & 0x3F));
+      $dec .= chr(0x80 | (($c >>  0) & 0x3F));
+    } else {
+      $dec .= chr(0xC0 | (($c >>  6) & 0x1F));
+      $dec .= chr(0x80 | (($c >>  0) & 0x3F));
+    }
+  }
+  return $dec;
+}
+
+
 /**
  * Replacing specials characters to a specific encoding type
  *
@@ -298,23 +435,13 @@ function rcube_charset_convert($str, $from, $to=NULL)
  */
 function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE)
   {
-  global $OUTPUT;
   static $html_encode_arr = false;
   static $js_rep_table = false;
   static $xml_rep_table = false;
 
-  $charset = $OUTPUT->get_charset();
-  $is_iso_8859_1 = false;
-  if ($charset == 'ISO-8859-1') {
-    $is_iso_8859_1 = true;
-  }
   if (!$enctype)
     $enctype = $OUTPUT->type;
 
-  // encode for plaintext
-  if ($enctype=='text')
-    return str_replace("\r\n", "\n", $mode=='remove' ? strip_tags($str) : $str);
-
   // encode for HTML output
   if ($enctype=='html')
     {
@@ -344,9 +471,6 @@ function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE)
     return $newlines ? nl2br($out) : $out;
     }
 
-  if ($enctype=='url')
-    return rawurlencode($str);
-
   // if the replace tables for XML and JS are not yet defined
   if ($js_rep_table===false)
     {
@@ -354,12 +478,7 @@ function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE)
     $xml_rep_table['&'] = '&amp;';
 
     for ($c=160; $c<256; $c++)  // can be increased to support more charsets
-      {
       $xml_rep_table[Chr($c)] = "&#$c;";
-      
-      if ($is_iso_8859_1)
-        $js_rep_table[Chr($c)] = sprintf("\\u%04x", $c);
-      }
 
     $xml_rep_table['"'] = '&quot;';
     $js_rep_table['"'] = '\\"';
@@ -367,18 +486,20 @@ function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE)
     $js_rep_table["\\"] = "\\\\";
     }
 
-  // encode for XML
-  if ($enctype=='xml')
-    return strtr($str, $xml_rep_table);
-
   // encode for javascript use
   if ($enctype=='js')
-    {
-    if ($charset!='UTF-8')
-      $str = rcube_charset_convert($str, RCMAIL_CHARSET,$charset);
-      
     return preg_replace(array("/\r?\n/", "/\r/", '/<\\//'), array('\n', '\n', '<\\/'), strtr($str, $js_rep_table));
-    }
+
+  // encode for plaintext
+  if ($enctype=='text')
+    return str_replace("\r\n", "\n", $mode=='remove' ? strip_tags($str) : $str);
+
+  if ($enctype=='url')
+    return rawurlencode($str);
+
+  // encode for XML
+  if ($enctype=='xml')
+    return strtr($str, $xml_rep_table);
 
   // no encoding given -> return original string
   return $str;
@@ -420,7 +541,7 @@ function JQ($str)
  * @return string   Field value or NULL if not available
  */
 function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL)
-  {
+{
   global $OUTPUT;
   $value = NULL;
   
@@ -437,7 +558,10 @@ function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL)
     else if (isset($_COOKIE[$fname]))
       $value = $_COOKIE[$fname];
     }
-  
+
+  if (empty($value))
+    return $value;
+
   // strip single quotes if magic_quotes_sybase is enabled
   if (ini_get('magic_quotes_sybase'))
     $value = str_replace("''", "'", $value);
@@ -454,16 +578,35 @@ function get_input_value($fname, $source, $allow_html=FALSE, $charset=NULL)
     return rcube_charset_convert($value, $OUTPUT->get_charset(), $charset);
   else
     return $value;
+}
+
+/**
+ * Convert array of request parameters (prefixed with _)
+ * to a regular array with non-prefixed keys.
+ *
+ * @param  int   Source to get value from (GPC)
+ * @return array Hash array with all request parameters
+ */
+function request2param($mode = RCUBE_INPUT_GPC)
+{
+  $out = array();
+  $src = $mode == RCUBE_INPUT_GET ? $_GET : ($mode == RCUBE_INPUT_POST ? $_POST : $_REQUEST);
+  foreach ($src as $key => $value) {
+    $fname = $key[0] == '_' ? substr($key, 1) : $key;
+    $out[$fname] = get_input_value($key, $mode);
   }
+  
+  return $out;
+}
 
 /**
  * Remove all non-ascii and non-word chars
- * except . and -
+ * except ., -, _
  */
-function asciiwords($str, $css_id = false)
+function asciiwords($str, $css_id = false, $replace_with = '')
 {
   $allowed = 'a-z0-9\_\-' . (!$css_id ? '\.' : '');
-  return preg_replace("/[^$allowed]/i", '', $str);
+  return preg_replace("/[^$allowed]/i", $replace_with, $str);
 }
 
 /**
@@ -516,7 +659,7 @@ function rcube_table_output($attrib, $table_data, $a_show_cols, $id_col)
     while ($table_data && ($sql_arr = $db->fetch_assoc($table_data)))
     {
       $zebra_class = $c % 2 ? 'even' : 'odd';
-      $table->add_row(array('id' => 'rcmrow' . $sql_arr[$id_col], 'class' => "contact $zebra_class"));
+      $table->add_row(array('id' => 'rcmrow' . $sql_arr[$id_col], 'class' => $zebra_class));
 
       // format each col
       foreach ($a_show_cols as $col)
@@ -530,7 +673,7 @@ function rcube_table_output($attrib, $table_data, $a_show_cols, $id_col)
     foreach ($table_data as $row_data)
     {
       $zebra_class = $c % 2 ? 'even' : 'odd';
-      $table->add_row(array('id' => 'rcmrow' . $row_data[$id_col], 'class' => "contact $zebra_class"));
+      $table->add_row(array('id' => 'rcmrow' . $row_data[$id_col], 'class' => $zebra_class));
 
       // format each col
       foreach ($a_show_cols as $col)
@@ -596,7 +739,7 @@ function rcmail_mod_css_styles($source, $container_id)
   $replacements = new rcube_string_replacer;
   
   // ignore the whole block if evil styles are detected
-  $stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entitiy_decode($source));
+  $stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entity_decode($source));
   if (preg_match('/expression|behavior|url\(|import/', $stripped))
     return '/* evil! */';
 
@@ -637,22 +780,22 @@ function rcmail_mod_css_styles($source, $container_id)
  * @param string CSS content to decode
  * @return string Decoded string
  */
-function rcmail_xss_entitiy_decode($content)
+function rcmail_xss_entity_decode($content)
 {
   $out = html_entity_decode(html_entity_decode($content));
-  $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entitiy_decode_callback', $out);
+  $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entity_decode_callback', $out);
   $out = preg_replace('#/\*.*\*/#Um', '', $out);
   return $out;
 }
 
 
 /**
- * preg_replace_callback callback for rcmail_xss_entitiy_decode_callback
+ * preg_replace_callback callback for rcmail_xss_entity_decode_callback
  *
  * @param array matches result from preg_replace_callback
  * @return string decoded entity
  */ 
-function rcmail_xss_entitiy_decode_callback($matches)
+function rcmail_xss_entity_decode_callback($matches)
 { 
   return chr(hexdec($matches[1]));
 }
@@ -688,11 +831,11 @@ function parse_attrib_string($str)
   preg_match_all('/\s*([-_a-z]+)=(["\'])??(?(2)([^\2]*)\2|(\S+?))/Ui', stripslashes($str), $regs, PREG_SET_ORDER);
 
   // convert attributes to an associative array (name => value)
-  if ($regs)
-    foreach ($regs as $attr)
-      {
-      $attrib[strtolower($attr[1])] = $attr[3] . $attr[4];
-      }
+  if ($regs) {
+    foreach ($regs as $attr) {
+      $attrib[strtolower($attr[1])] = html_entity_decode($attr[3] . $attr[4]);
+    }
+  }
 
   return $attrib;
   }
@@ -761,6 +904,9 @@ function format_date($date, $format=NULL)
   else if (!$format)
     $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);
 
   // 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()
@@ -825,8 +971,16 @@ function format_email_recipient($email, $name='')
  */
 function console()
   {
+  $args = func_get_args();
+
+  if (class_exists('rcmail', false)) {
+    $rcmail = rcmail::get_instance();
+    if (is_object($rcmail->plugins))
+      $rcmail->plugins->exec_hook('console', $args);
+  }
+
   $msg = array();
-  foreach (func_get_args() as $arg)
+  foreach ($args as $arg)
     $msg[] = !is_string($arg) ? var_export($arg, true) : $arg;
 
   if (!($GLOBALS['CONFIG']['debug_level'] & 4))
@@ -851,22 +1005,34 @@ function console()
  */
 function write_log($name, $line)
   {
-  global $CONFIG;
+  global $CONFIG, $RCMAIL;
 
   if (!is_string($line))
     $line = var_export($line, true);
+  if (empty($CONFIG['log_date_format']))
+    $CONFIG['log_date_format'] = 'd-M-Y H:i:s O';
+  
+  $date = date($CONFIG['log_date_format']);
   
-  $log_entry = sprintf("[%s]: %s\n",
-                 date("d-M-Y H:i:s O", mktime()),
-                 $line);
+  // trigger logging hook
+  if (is_object($RCMAIL) && is_object($RCMAIL->plugins)) {
+    $log = $RCMAIL->plugins->exec_hook('write_log', array('name' => $name, 'date' => $date, 'line' => $line));
+    $name = $log['name'];
+    $line = $log['line'];
+    $date = $log['date'];
+    if ($log['abort'])
+      return;
+  }
+  $log_entry = sprintf("[%s]: %s\n", $date, $line);
 
   if ($CONFIG['log_driver'] == 'syslog') {
-    if ($name == 'errors')
-      $prio = LOG_ERR;
-    else
-      $prio = LOG_INFO;
+    $prio = $name == 'errors' ? LOG_ERR : LOG_INFO;
     syslog($prio, $log_entry);
-  } else {
+    return true;
+  }
+  else {
     // log_driver == 'file' is assumed here
     if (empty($CONFIG['log_dir']))
       $CONFIG['log_dir'] = INSTALL_PATH.'logs';
@@ -876,8 +1042,10 @@ function write_log($name, $line)
       fwrite($fp, $log_entry);
       fflush($fp);
       fclose($fp);
+      return true;
     }
   }
+  return false;
 }
 
 
@@ -885,17 +1053,16 @@ function write_log($name, $line)
  * @access private
  */
 function rcube_timer()
-  {
-  list($usec, $sec) = explode(" ", microtime());
-  return ((float)$usec + (float)$sec);
-  }
+{
+  return microtime(true);
+}
   
 
 /**
  * @access private
  */
-function rcube_print_time($timer, $label='Timer')
-  {
+function rcube_print_time($timer, $label='Timer', $dest='console')
+{
   static $print_count = 0;
   
   $print_count++;
@@ -905,8 +1072,8 @@ function rcube_print_time($timer, $label='Timer')
   if (empty($label))
     $label = 'Timer '.$print_count;
   
-  console(sprintf("%s: %0.4f sec", $label, $diff));
-  }
+  write_log($dest, sprintf("%s: %0.4f sec", $label, $diff));
+}
 
 
 /**
@@ -944,6 +1111,9 @@ function rcmail_mailbox_list($attrib)
     foreach ($a_folders as $folder)
       rcmail_build_folder_tree($a_mailboxes, $folder, $delimiter);
   }
+  
+  // allow plugins to alter the folder tree or to localize folder names
+  $hook = $RCMAIL->plugins->exec_hook('render_mailboxlist', array('list' => $a_mailboxes, 'delimiter' => $delimiter));
 
   if ($type=='select') {
     $select = new html_select($attrib);
@@ -952,12 +1122,12 @@ function rcmail_mailbox_list($attrib)
     if ($attrib['noselection'])
       $select->add(rcube_label($attrib['noselection']), '0');
     
-    rcmail_render_folder_tree_select($a_mailboxes, $mbox_name, $attrib['maxlength'], $select, $attrib['realnames']);
+    rcmail_render_folder_tree_select($hook['list'], $mbox_name, $attrib['maxlength'], $select, $attrib['realnames']);
     $out = $select->show();
   }
   else {
     $js_mailboxlist = array();
-    $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib);
+    $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($hook['list'], $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib);
     
     $RCMAIL->output->add_gui_object('mailboxlist', $attrib['id']);
     $RCMAIL->output->set_env('mailboxes', $js_mailboxlist);
@@ -1018,7 +1188,7 @@ function rcmail_build_folder_tree(&$arrFolders, $folder, $delm='/', $path='')
   if (!isset($arrFolders[$currentFolder])) {
     $arrFolders[$currentFolder] = array(
       'id' => $path,
-      'name' => rcube_charset_convert($currentFolder, 'UTF-7'),
+      'name' => rcube_charset_convert($currentFolder, 'UTF7-IMAP'),
       'virtual' => $virtual,
       'folders' => array());
   }
@@ -1064,7 +1234,7 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $at
     }
 
     // make folder name safe for ids and class names
-    $folder_id = asciiwords($folder['id'], true);
+    $folder_id = asciiwords($folder['id'], true, '_');
     $classes = array('mailbox');
 
     // set special class for Sent, Drafts, Trash and Junk
@@ -1193,7 +1363,7 @@ function rcmail_localize_foldername($name)
   if ($folder_class = rcmail_folder_classname($name))
     return rcube_label($folder_class);
   else
-    return rcube_charset_convert($name, 'UTF-7');
+    return rcube_charset_convert($name, 'UTF7-IMAP');
 }
 
 
index 9aad25b2743fb3505063b0538e002d01e79f70bc..4624ee1943ee758dc9af5d19f1d6ff91b6eedb09 100644 (file)
  */
 class rcmail
 {
-  static public $main_tasks = array('mail','settings','addressbook','login','logout');
+  static public $main_tasks = array('mail','settings','addressbook','login','logout','dummy');
   
   static private $instance;
   
   public $config;
   public $user;
   public $db;
+  public $smtp;
   public $imap;
   public $output;
+  public $plugins;
   public $task = 'mail';
   public $action = '';
   public $comm_path = './';
@@ -88,9 +90,9 @@ class rcmail
       $syslog_facility = $this->config->get('syslog_facility', LOG_USER);
       openlog($syslog_id, LOG_ODELAY, $syslog_facility);
     }
-                               
+
     // set task and action properties
-    $this->set_task(strip_quotes(get_input_value('_task', RCUBE_INPUT_GPC)));
+    $this->set_task(get_input_value('_task', RCUBE_INPUT_GPC));
     $this->action = asciiwords(get_input_value('_action', RCUBE_INPUT_GPC));
 
     // connect to database
@@ -123,7 +125,7 @@ class rcmail
 
     // reset some session parameters when changing task
     if ($_SESSION['task'] != $this->task)
-      unset($_SESSION['page']);
+      rcube_sess_unset('page');
 
     // set current task to session
     $_SESSION['task'] = $this->task;
@@ -131,6 +133,9 @@ class rcmail
     // create IMAP object
     if ($this->task == 'mail')
       $this->imap_init();
+      
+    // create plugin API and load plugins
+    $this->plugins = rcube_plugin_api::get_instance();
   }
   
   
@@ -141,14 +146,12 @@ class rcmail
    */
   public function set_task($task)
   {
-    if (!in_array($task, self::$main_tasks))
-      $task = 'mail';
-    
-    $this->task = $task;
-    $this->comm_path = $this->url(array('task' => $task));
+    $task = asciiwords($task);
+    $this->task = $task ? $task : 'mail';
+    $this->comm_path = $this->url(array('task' => $this->task));
     
     if ($this->output)
-      $this->output->set_env('task', $task);
+      $this->output->set_env('task', $this->task);
   }
   
   
@@ -255,10 +258,19 @@ class rcmail
     $contacts = null;
     $ldap_config = (array)$this->config->get('ldap_public');
     $abook_type = strtolower($this->config->get('address_book_type'));
+
+    $plugin = $this->plugins->exec_hook('get_address_book', array('id' => $id, 'writeable' => $writeable));
     
-    if ($id && $ldap_config[$id]) {
+    // 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]);
     }
+    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) {
@@ -290,10 +302,6 @@ class rcmail
     if (!($this->output instanceof rcube_template))
       $this->output = new rcube_template($this->task, $framed);
 
-    foreach (array('flag_for_deletion','read_when_deleted') as $js_config_var) {
-      $this->output->set_env($js_config_var, $this->config->get($js_config_var));
-    }
-    
     // set keep-alive/check-recent interval
     if ($keep_alive = $this->config->get('keep_alive')) {
       // be sure that it's less than session lifetime
@@ -310,10 +318,10 @@ class rcmail
     $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($this->config->get('charset', RCMAIL_CHARSET));
+    $this->output->set_charset(RCMAIL_CHARSET);
 
     // add some basic label to client
-    $this->output->add_label('loading');
+    $this->output->add_label('loading', 'servererror');
     
     return $this->output;
   }
@@ -331,6 +339,20 @@ class rcmail
     
     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();
+  }
   
   
   /**
@@ -358,13 +380,10 @@ class rcmail
     $options = array(
       'imap' => $this->config->get('imap_auth_type', 'check'),
       'delimiter' => isset($_SESSION['imap_delimiter']) ? $_SESSION['imap_delimiter'] : $this->config->get('imap_delimiter'),
+      'rootdir' => isset($_SESSION['imap_root']) ? $_SESSION['imap_root'] : $this->config->get('imap_root'),
+      'debug_mode' => (bool) $this->config->get('imap_debug', 0),
     );
-    
-    if (isset($_SESSION['imap_root']))
-      $options['rootdir'] = $_SESSION['imap_root'];
-    else if ($imap_root = $this->config->get('imap_root'))
-      $options['rootdir'] = $imap_root;
-    
+
     $this->imap->set_options($options);
   
     // set global object for backward compatibility
@@ -385,7 +404,7 @@ class rcmail
     $conn = false;
     
     if ($_SESSION['imap_host'] && !$this->imap->conn) {
-      if (!($conn = $this->imap->connect($_SESSION['imap_host'], $_SESSION['username'], $this->decrypt_passwd($_SESSION['password']), $_SESSION['imap_port'], $_SESSION['imap_ssl']))) {
+      if (!($conn = $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->error_code == -1 ? 'imaperror' : 'sessionerror', 'error');
       }
@@ -462,7 +481,7 @@ class rcmail
 
     // lowercase username if it's an e-mail address (#1484473)
     if (strpos($username, '@'))
-      $username = rc_strtolower($username);
+      $username = mb_strtolower($username);
 
     // user already registered -> overwrite username
     if ($user = rcube_user::query($username, $host))
@@ -484,6 +503,13 @@ class rcmail
         // get existing mailboxes (but why?)
         // $a_mailboxes = $this->imap->list_mailboxes();
       }
+      else {
+        raise_error(array(
+          'code' => 600,
+          'type' => 'php',
+          'message' => "Failed to create a user record. Maybe aborted by a plugin?"
+          ), true, false);        
+      }
     }
     else {
       raise_error(array(
@@ -504,7 +530,7 @@ class rcmail
       $_SESSION['imap_host'] = $host;
       $_SESSION['imap_port'] = $imap_port;
       $_SESSION['imap_ssl']  = $imap_ssl;
-      $_SESSION['password']  = $this->encrypt_passwd($pass);
+      $_SESSION['password']  = $this->encrypt($pass);
       $_SESSION['login_time'] = mktime();
       
       if ($_REQUEST['_timezone'] != '_default_')
@@ -598,7 +624,7 @@ class rcmail
    * @param mixed Named parameters array or label name
    * @return string Localized text
    */
-  public function gettext($attrib)
+  public function gettext($attrib, $domain=null)
   {
     // load localization files if not done yet
     if (empty($this->texts))
@@ -613,9 +639,12 @@ class rcmail
 
     $command_name = !empty($attrib['command']) ? $attrib['command'] : NULL;
     $alias = $attrib['name'] ? $attrib['name'] : ($command_name && $command_label_map[$command_name] ? $command_label_map[$command_name] : '');
-
+    
+    // check for text with domain
+    if ($domain && ($text_item = $this->texts[$domain.'.'.$alias]))
+      ;
     // text does not exist
-    if (!($text_item = $this->texts[$alias])) {
+    else if (!($text_item = $this->texts[$alias])) {
       /*
       raise_error(array(
         'code' => 500,
@@ -677,7 +706,7 @@ class rcmail
    *
    * @param string Language ID
    */
-  public function load_language($lang = null)
+  public function load_language($lang = null, $add = array())
   {
     $lang = $this->language_prop(($lang ? $lang : $_SESSION['language']));
     
@@ -707,6 +736,10 @@ class rcmail
       
       $_SESSION['language'] = $lang;
     }
+
+    // append additional texts (from plugin)
+    if (is_array($add) && !empty($add))
+      $this->texts += $add;
   }
 
 
@@ -779,6 +812,9 @@ class rcmail
    */
   public function kill_session()
   {
+    $this->plugins->exec_hook('kill_session');
+    
+    rcube_sess_unset();
     $_SESSION = array('language' => $this->user->language, 'auth_time' => time(), 'temp' => true);
     rcmail::setcookie('sessauth', '-del-', time() - 60);
     $this->user->reset();
@@ -821,6 +857,9 @@ class rcmail
       $this->imap->write_cache();
     }
 
+    if (is_object($this->smtp))
+      $this->smtp->disconnect();
+
     if (is_object($this->contacts))
       $this->contacts->close();
 
@@ -830,6 +869,35 @@ class rcmail
   }
   
   
+  /**
+   * Generate a unique token to be used in a form request
+   *
+   * @return string The request token
+   */
+  public function get_request_token()
+  {
+    $key = $this->task;
+    
+    if (!$_SESSION['request_tokens'][$key])
+      $_SESSION['request_tokens'][$key] = md5(uniqid($key . rand(), true));
+    
+    return $_SESSION['request_tokens'][$key];
+  }
+  
+  
+  /**
+   * 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);
+    return !empty($token) && $_SESSION['request_tokens'][$this->task] == $token;
+  }
+  
+  
   /**
    * Create unique authorization hash
    *
@@ -851,65 +919,109 @@ class rcmail
       return md5($auth_string);
   }
 
+
   /**
-   * Encrypt IMAP password using DES encryption
+   * 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
    *
-   * @param string Password to encrypt
-   * @return string Encryprted string
+   * @return string encrypted text
    */
-  public function encrypt_passwd($pass)
+  public function encrypt($clear, $key = 'des_key', $base64 = true)
   {
-    if (function_exists('mcrypt_module_open') && ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, ""))) {
+    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 = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
-      mcrypt_generic_init($td, $this->config->get_des_key(), $iv);
-      $cypher = mcrypt_generic($td, $pass);
+      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 if (function_exists('des')) {
-      $cypher = des($this->config->get_des_key(), $pass, 1, 0, NULL);
+    else if (function_exists('des'))
+    {
+      define('DES_IV_SIZE', 8);
+      $iv = '';
+      for ($i = 0; $i < constant('DES_IV_SIZE'); $i++)
+        $iv .= sprintf("%c", mt_rand(0, 255));
+      $cipher = $iv . des($this->config->get_crypto_key($key), $clear, 1, 1, $iv);
     }
-    else {
-      $cypher = $pass;
-
+    else
+    {
       raise_error(array(
         'code' => 500,
         'type' => 'php',
         'file' => __FILE__,
-        'message' => "Could not convert encrypt password. Make sure Mcrypt is installed or lib/des.inc is available"
-        ), true, false);
+        'message' => "Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available"
+      ), true, true);
     }
-
-    return base64_encode($cypher);
+  
+    return $base64 ? base64_encode($cipher) : $cipher;
   }
 
-
   /**
-   * Decrypt IMAP password using DES encryption
+   * 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
    *
-   * @param string Encrypted password
-   * @return string Plain password
+   * @return string decrypted text
    */
-  public function decrypt_passwd($cypher)
+  public function decrypt($cipher, $key = 'des_key', $base64 = true)
   {
-    if (function_exists('mcrypt_module_open') && ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, ""))) {
-      $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
-      mcrypt_generic_init($td, $this->config->get_des_key(), $iv);
-      $pass = mdecrypt_generic($td, base64_decode($cypher));
+    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 = substr($cipher, 0, mcrypt_enc_get_iv_size($td));
+      $cipher = substr($cipher, mcrypt_enc_get_iv_size($td));
+      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 if (function_exists('des')) {
-      $pass = des($this->config->get_des_key(), base64_decode($cypher), 0, 0, NULL);
+    else if (function_exists('des'))
+    {
+      define('DES_IV_SIZE', 8);
+      $iv = substr($cipher, 0, constant('DES_IV_SIZE'));
+      $cipher = substr($cipher, constant('DES_IV_SIZE'));
+      $clear = des($this->config->get_crypto_key($key), $cipher, 0, 1, $iv);
     }
-    else {
-      $pass = base64_decode($cypher);
+    else
+    {
+      raise_error(array(
+        'code' => 500,
+        'type' => 'php',
+        'file' => __FILE__,
+        'message' => "Could not perform decryption; make sure Mcrypt is installed or lib/des.inc is available"
+      ), true, true);
     }
-
-    return preg_replace('/\x00/', '', $pass);
+  
+    /*-
+     * 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;
   }
 
-
   /**
    * Build a valid URL to this instance of RoundCube
    *
@@ -920,18 +1032,17 @@ class rcmail
   {
     if (!is_array($p))
       $p = array('_action' => @func_get_arg(0));
-
-    if (!$p['task'] || !in_array($p['task'], rcmail::$main_tasks))
-      $p['task'] = $this->task;
-
-    $p['_task'] = $p['task'];
+    
+    $task = $p['_task'] ? $p['_task'] : ($p['task'] ? $p['task'] : $this->task);
+    $p['_task'] = $task;
     unset($p['task']);
 
     $url = './';
     $delm = '?';
-    foreach (array_reverse($p) as $par => $val)
+    foreach (array_reverse($p) as $key => $val)
     {
       if (!empty($val)) {
+        $par = $key[0] == '_' ? $key : '_'.$key;
         $url .= $delm.urlencode($par).'='.urlencode($val);
         $delm = '&';
       }
diff --git a/program/include/rcube_addressbook.php b/program/include/rcube_addressbook.php
new file mode 100644 (file)
index 0000000..9e970f2
--- /dev/null
@@ -0,0 +1,169 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_addressbook.php                                 |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2006-2009, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Interface to the local address book database                        |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+
+ $Id:  $
+
+*/
+
+
+/**
+ * Abstract skeleton of an address book/repository
+ *
+ * @package Addressbook
+ */
+abstract class rcube_addressbook
+{
+    /** public properties */
+    var $primary_key;
+    var $readonly = true;
+    var $ready = false;
+    var $list_page = 1;
+    var $page_size = 10;
+
+    /**
+     * Save a search string for future listings
+     *
+     * @param mixed Search params to use in listing method, obtained by get_search_set()
+     */
+    abstract function set_search_set($filter);
+
+    /**
+     * Getter for saved search properties
+     *
+     * @return mixed Search properties used by this class
+     */
+    abstract function get_search_set();
+
+    /**
+     * Reset saved results and search parameters
+     */
+    abstract function reset();
+
+    /**
+     * List the current set of contact records
+     *
+     * @param  array  List of cols to show
+     * @param  int    Only return this number of records, use negative values for tail
+     * @return array  Indexed list of contact records, each a hash array
+     */
+    abstract function list_records($cols=null, $subset=0);
+
+    /**
+     * Search records
+     *
+     * @param array   List of fields to search in
+     * @param string  Search value
+     * @param boolean True if results are requested, False if count only
+     * @return Indexed list of contact records and 'count' value
+     */
+    abstract function search($fields, $value, $strict=false, $select=true);
+
+    /**
+     * Count number of available contacts in database
+     *
+     * @return object rcube_result_set Result set with values for 'count' and 'first'
+     */
+    abstract function count();
+
+    /**
+     * Return the last result set
+     *
+     * @return object rcube_result_set Current result set or NULL if nothing selected yet
+     */
+    abstract function get_result();
+
+    /**
+     * Get a specific contact record
+     *
+     * @param mixed record identifier(s)
+     * @param boolean True to return record as associative array, otherwise a result set is returned
+     * @return mixed Result object with all record fields or False if not found
+     */
+    abstract function get_record($id, $assoc=false);
+
+    /**
+     * Close connection to source
+     * Called on script shutdown
+     */
+    function close() { }
+
+    /**
+     * Set internal list page
+     *
+     * @param  number  Page number to list
+     * @access public
+     */
+    function set_page($page)
+    {
+      $this->list_page = (int)$page;
+    }
+
+    /**
+     * Set internal page size
+     *
+     * @param  number  Number of messages to display on one page
+     * @access public
+     */
+    function set_pagesize($size)
+    {
+      $this->page_size = (int)$size;
+    }
+
+    /**
+     * Create a new contact record
+     *
+     * @param array Assoziative array with save data
+     * @param boolean True to check for duplicates first
+     * @return The created record ID on success, False on error
+     */
+    function insert($save_data, $check=false)
+    {
+      /* empty for read-only address books */
+    }
+
+    /**
+     * Update a specific contact record
+     *
+     * @param mixed Record identifier
+     * @param array Assoziative array with save data
+     * @return True on success, False on error
+     */
+    function update($id, $save_cols)
+    {
+      /* empty for read-only address books */
+    }
+
+    /**
+     * Mark one or more contact records as deleted
+     *
+     * @param array  Record identifiers
+     */
+    function delete($ids)
+    {
+      /* empty for read-only address books */
+    }
+
+    /**
+     * Remove all records from the database
+     */
+    function delete_all()
+    {
+      /* empty for read-only address books */
+    }
+
+}
\ No newline at end of file
index 56e6d3ce2dcf8ee5a002b87997c382a37191c29b..4010dbc48f082c4cc9e130f2f8b77c51ee3178e7 100644 (file)
@@ -47,23 +47,23 @@ class rcube_browser
         $this->safari = ($this->khtml || stristr($HTTP_USER_AGENT, 'safari'));
 
         if ($this->ns) {
-            $test = eregi("mozilla\/([0-9\.]+)", $HTTP_USER_AGENT, $regs);
+            $test = preg_match('/mozilla\/([0-9.]+)/i', $HTTP_USER_AGENT, $regs);
             $this->ver = $test ? (float)$regs[1] : 0;
         }
         if ($this->mz) {
-            $test = ereg("rv:([0-9\.]+)", $HTTP_USER_AGENT, $regs);
+            $test = preg_match('/rv:([0-9.]+)/', $HTTP_USER_AGENT, $regs);
             $this->ver = $test ? (float)$regs[1] : 0;
         }
         if($this->ie) {
-            $test = eregi("msie ([0-9\.]+)", $HTTP_USER_AGENT, $regs);
+            $test = preg_match('/msie ([0-9.]+)/i', $HTTP_USER_AGENT, $regs);
             $this->ver = $test ? (float)$regs[1] : 0;
         }
         if ($this->opera) {
-            $test = eregi("opera ([0-9\.]+)", $HTTP_USER_AGENT, $regs);
+            $test = preg_match('/opera ([0-9.]+)/i', $HTTP_USER_AGENT, $regs);
             $this->ver = $test ? (float)$regs[1] : 0;
         }
 
-        if (eregi(" ([a-z]{2})-([a-z]{2})", $HTTP_USER_AGENT, $regs))
+        if (preg_match('/ ([a-z]{2})-([a-z]{2})/i', $HTTP_USER_AGENT, $regs))
             $this->lang =  $regs[1];
         else
             $this->lang =  'en';
index 7be2b0d2cff69ad6a55adebd5ce60e9a2be4fb7f..b30cf2d38a8861ef8a3eb8c04b4e067b0f2504e4 100644 (file)
@@ -51,15 +51,11 @@ class rcube_config
     ob_start();
     
     // load main config file
-    if (include(RCMAIL_CONFIG_DIR . '/main.inc.php'))
-      $this->prop = (array)$rcmail_config;
-    else
+    if (!$this->load_from_file(RCMAIL_CONFIG_DIR . '/main.inc.php'))
       $this->errors[] = 'main.inc.php was not found.';
 
     // load database config
-    if (include(RCMAIL_CONFIG_DIR . '/db.inc.php'))
-      $this->prop += (array)$rcmail_config;
-    else
+    if (!$this->load_from_file(RCMAIL_CONFIG_DIR . '/db.inc.php'))
       $this->errors[] = 'db.inc.php was not found.';
     
     // load host-specific configuration
@@ -77,11 +73,11 @@ class rcube_config
 
     // fix default imap folders encoding
     foreach (array('drafts_mbox', 'junk_mbox', 'sent_mbox', 'trash_mbox') as $folder)
-      $this->prop[$folder] = rcube_charset_convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF-7');
+      $this->prop[$folder] = rcube_charset_convert($this->prop[$folder], RCMAIL_CHARSET, 'UTF7-IMAP');
 
     if (!empty($this->prop['default_imap_folders']))
       foreach ($this->prop['default_imap_folders'] as $n => $folder)
-        $this->prop['default_imap_folders'][$n] = rcube_charset_convert($folder, RCMAIL_CHARSET, 'UTF-7');
+        $this->prop['default_imap_folders'][$n] = rcube_charset_convert($folder, RCMAIL_CHARSET, 'UTF7-IMAP');
 
     // set PHP error logging according to config
     if ($this->prop['debug_level'] & 1) {
@@ -123,10 +119,30 @@ class rcube_config
       $fname = preg_replace('/[^a-z0-9\.\-_]/i', '', $_SERVER['HTTP_HOST']) . '.inc.php';
     }
 
-    if ($fname && is_file(RCMAIL_CONFIG_DIR . '/' . $fname)) {
-      include(RCMAIL_CONFIG_DIR . '/' . $fname);
-      $this->prop = array_merge($this->prop, (array)$rcmail_config);
+    if ($fname) {
+      $this->load_from_file(RCMAIL_CONFIG_DIR . '/' . $fname);
+    }
+  }
+  
+  
+  /**
+   * Read configuration from a file
+   * and merge with the already stored config values
+   *
+   * @param string Full path to the config file to be loaded
+   * @return booelan True on success, false on failure
+   */
+  public function load_from_file($fpath)
+  {
+    if (is_file($fpath) && is_readable($fpath)) {
+      include($fpath);
+      if (is_array($rcmail_config)) {
+        $this->prop = array_merge($this->prop, $rcmail_config);
+        return true;
+      }
     }
+    
+    return false;
   }
   
   
@@ -175,28 +191,42 @@ class rcube_config
   {
     return $this->prop;
   }
-  
-  
+
   /**
-   * Return a 24 byte key for the DES encryption
+   * Return requested DES crypto key.
    *
-   * @return string DES encryption key
+   * @param string Crypto key name
+   * @return string Crypto key
    */
-  public function get_des_key()
+  public function get_crypto_key($key)
   {
-    $key = !empty($this->prop['des_key']) ? $this->prop['des_key'] : 'rcmail?24BitPwDkeyF**ECB';
-    $len = strlen($key);
-
-    // make sure the key is exactly 24 chars long
-    if ($len<24)
-      $key .= str_repeat('_', 24-$len);
-    else if ($len>24)
-      substr($key, 0, 24);
+    // Bomb out if the requested key does not exist
+    if (!array_key_exists($key, $this->prop))
+    {
+      raise_error(array(
+        'code' => 500,
+        'type' => 'php',
+        'file' => __FILE__,
+        'message' => "Request for unconfigured crypto key \"$key\""
+      ), true, true);
+    }
+  
+    $key = $this->prop[$key];
+  
+    // Bomb out if the configured key is not exactly 24 bytes long
+    if (strlen($key) != 24)
+    {
+      raise_error(array(
+        'code' => 500,
+        'type' => 'php',
+        'file' => __FILE__,
+        'message' => "Configured crypto key \"$key\" is not exactly 24 bytes long"
+      ), true, true);
+    }
 
     return $key;
   }
-  
-  
+
   /**
    * Try to autodetect operating system and find the correct line endings
    *
@@ -207,9 +237,9 @@ class rcube_config
     // use the configured delimiter for headers
     if (!empty($this->prop['mail_header_delimiter']))
       return $this->prop['mail_header_delimiter'];
-    else if (strtolower(substr(PHP_OS, 0, 3) == 'win'))
+    else if (strtolower(substr(PHP_OS, 0, 3)) == 'win')
       return "\r\n";
-    else if (strtolower(substr(PHP_OS, 0, 3) == 'mac'))
+    else if (strtolower(substr(PHP_OS, 0, 3)) == 'mac')
       return "\r\n";
     else
       return "\n";
index 65d89ca2b2b597795233fda5c28f5f09ae757d7c..a931845ae581924c626ff8765511abe7d807c016 100644 (file)
@@ -25,7 +25,7 @@
  *
  * @package Addressbook
  */
-class rcube_contacts
+class rcube_contacts extends rcube_addressbook
 {
   var $db = null;
   var $db_name = '';
@@ -59,30 +59,6 @@ class rcube_contacts
   }
 
 
-  /**
-   * Set internal list page
-   *
-   * @param  number  Page number to list
-   * @access public
-   */
-  function set_page($page)
-  {
-    $this->list_page = (int)$page;
-  }
-
-
-  /**
-   * Set internal page size
-   *
-   * @param  number  Number of messages to display on one page
-   * @access public
-   */
-  function set_pagesize($size)
-  {
-    $this->page_size = (int)$size;
-  }
-
-
   /**
    * Save a search string for future listings
    *
@@ -117,13 +93,6 @@ class rcube_contacts
   }
   
   
-  /**
-   * Close connection to source
-   * Called on script shutdown
-   */
-  function close(){}
-  
-  
   /**
    * List the current set of contact records
    *
@@ -185,7 +154,7 @@ class rcube_contacts
     {
       if ($col == 'ID' || $col == $this->primary_key)
       {
-        $ids = !is_array($value) ? split(',', $value) : $value;
+        $ids = !is_array($value) ? explode(',', $value) : $value;
         $add_where[] = $this->primary_key.' IN ('.join(',', $ids).')';
       }
       else if ($strict)
@@ -233,7 +202,7 @@ class rcube_contacts
    *
    * @return Result array or NULL if nothing selected yet
    */
-  function get_result($as_res=true)
+  function get_result()
   {
     return $this->result;
   }
@@ -293,18 +262,18 @@ class rcube_contacts
         $a_insert_cols[] = $this->db->quoteIdentifier($col);
         $a_insert_values[] = $this->db->quote($save_data[$col]);
       }
-    
+
     if (!$existing->count && !empty($a_insert_cols))
     {
       $this->db->query(
         "INSERT INTO ".$this->db_name."
          (user_id, changed, del, ".join(', ', $a_insert_cols).")
-         VALUES (?, ".$this->db->now().", 0, ".join(', ', $a_insert_values).")",
-        $this->user_id);
+         VALUES (".intval($this->user_id).", ".$this->db->now().", 0, ".join(', ', $a_insert_values).")"
+        );
         
-      $insert_id = $this->db->insert_id(get_sequence_name('contacts'));
+      $insert_id = $this->db->insert_id('contacts');
     }
-    
+
     return $insert_id;
   }
 
index 78f6176bfd65cb6eeaa9ce61b3e50d10210c2afc..6a197036bf1d8a3a8ca4458473feaf19875b2b8d 100644 (file)
@@ -29,10 +29,10 @@ class rcube_html_page
     protected $scripts_path = '';
     protected $script_files = array();
     protected $scripts = array();
-    protected $charset = 'UTF-8';
+    protected $charset = RCMAIL_CHARSET;
 
-    protected $script_tag_file = "<script type=\"text/javascript\" src=\"%s%s\"></script>\n";
-    protected $script_tag      = "<script type=\"text/javascript\">\n<!--\n%s\n\n//-->\n</script>\n";
+    protected $script_tag_file = "<script type=\"text/javascript\" src=\"%s\"></script>\n";
+    protected $script_tag  =  "<script type=\"text/javascript\">\n/* <![CDATA[ */\n%s\n/* ]]> */\n</script>";
     protected $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>";
 
     protected $title = '';
@@ -53,6 +53,9 @@ class rcube_html_page
     public function include_script($file, $position='head')
     {
         static $sa_files = array();
+        
+        if (!preg_match('|^https?://|i', $file) && $file[0] != '/')
+          $file = $this->scripts_path . $file . (($fs = @filemtime($this->scripts_path . $file)) ? '?s='.$fs : '');
 
         if (in_array($file, $sa_files)) {
             return;
@@ -165,7 +168,7 @@ class rcube_html_page
         // definition of the code to be placed in the document header and footer
         if (is_array($this->script_files['head'])) {
             foreach ($this->script_files['head'] as $file) {
-                $__page_header .= sprintf($this->script_tag_file, $this->scripts_path, $file);
+                $__page_header .= sprintf($this->script_tag_file, $file);
             }
         }
 
@@ -180,7 +183,7 @@ class rcube_html_page
 
         if (is_array($this->script_files['foot'])) {
             foreach ($this->script_files['foot'] as $file) {
-                $__page_footer .= sprintf($this->script_tag_file, $this->scripts_path, $file);
+                $__page_footer .= sprintf($this->script_tag_file, $file);
             }
         }
 
@@ -246,10 +249,22 @@ class rcube_html_page
         $__page_header = $__page_footer = '';
 
         // correct absolute paths in images and other tags
-        $output = preg_replace('/(src|href|background)=(["\']?)(\/[a-z0-9_\-]+)/Ui', "\\1=\\2$base_path\\3", $output);
+        $output = preg_replace('!(src|href|background)=(["\']?)(/[a-z0-9_-]+)!i', "\\1=\\2$base_path\\3", $output);
+        $output = preg_replace_callback('!(src|href)=(["\']?)([a-z0-9/_.-]+.(css|js))(["\'\s>])!i', array($this, 'add_filemtime'), $output);
         $output = str_replace('$__skin_path', $base_path, $output);
 
-        echo rcube_charset_convert($output, 'UTF-8', $this->charset);
+        if ($this->charset != RCMAIL_CHARSET)
+           echo rcube_charset_convert($output, RCMAIL_CHARSET, $this->charset);
+       else
+           echo $output;
+    }
+    
+    /**
+     * Callback function for preg_replace_callback in write()
+     */
+    public function add_filemtime($matches)
+    {
+        return sprintf("%s=%s%s?s=%d%s", $matches[1], $matches[2], $matches[3], @filemtime($matches[3]), $matches[5]);
     }
 }
 
index 018bf7a5031879feb1eaeb19b3d017447dbdcc2a..bc6d40a0614e06d8b67e62cae6062896c69b8d2f 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_imap.php 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: rcube_imap.php 2884 2009-08-28 08:31:41Z alec $
 
 */
 
@@ -36,7 +36,7 @@ require_once('lib/tnef_decoder.inc');
  *
  * @package    Mail
  * @author     Thomas Bruederli <roundcube@gmail.com>
- * @version    1.40
+ * @version    1.5
  * @link       http://ilohamail.org
  */
 class rcube_imap
@@ -53,8 +53,10 @@ class rcube_imap
   var $delimiter = NULL;
   var $caching_enabled = FALSE;
   var $default_charset = 'ISO-8859-1';
+  var $struct_charset = NULL;
   var $default_folders = array('INBOX');
   var $default_folders_lc = array('inbox');
+  var $fetch_add_headers = '';
   var $cache = array();
   var $cache_keys = array();  
   var $cache_changes = array();
@@ -68,6 +70,8 @@ class rcube_imap
   var $debug_level = 1;
   var $error_code = 0;
   var $options = array('imap' => 'check');
+  
+  private $host, $user, $pass, $port, $ssl;
 
 
   /**
@@ -99,24 +103,31 @@ class rcube_imap
     // check for Open-SSL support in PHP build
     if ($use_ssl && extension_loaded('openssl'))
       $ICL_SSL = $use_ssl == 'imaps' ? 'ssl' : $use_ssl;
-    else if ($use_ssl)
-      {
+    else if ($use_ssl) {
       raise_error(array('code' => 403, 'type' => 'imap', 'file' => __FILE__,
                         'message' => 'Open SSL not available;'), TRUE, FALSE);
       $port = 143;
-      }
+    }
 
     $ICL_PORT = $port;
     $IMAP_USE_INTERNAL_DATE = false;
+    
+    $attempt = 0;
+    do {
+      $data = rcmail::get_instance()->plugins->exec_hook('imap_connect', array('host' => $host, 'user' => $user, 'attempt' => ++$attempt));
+      if (!empty($data['pass']))
+        $pass = $data['pass'];
 
-    $this->conn = iil_Connect($host, $user, $pass, $this->options);
-    $this->host = $host;
-    $this->user = $user;
+      $this->conn = iil_Connect($data['host'], $data['user'], $pass, $this->options);
+    } while(!$this->conn && $data['retry']);
+
+    $this->host = $data['host'];
+    $this->user = $data['user'];
     $this->pass = $pass;
     $this->port = $port;
     $this->ssl = $use_ssl;
     
-    // print trace mesages
+    // print trace messages
     if ($this->conn && ($this->debug_level & 8))
       console($this->conn->message);
     
@@ -137,7 +148,7 @@ class rcube_imap
       if (!empty($this->conn->rootdir))
         {
         $this->set_rootdir($this->conn->rootdir);
-        $this->root_ns = ereg_replace('[\.\/]$', '', $this->conn->rootdir);
+        $this->root_ns = preg_replace('/[.\/]$/', '', $this->conn->rootdir);
         }
       }
 
@@ -193,7 +204,7 @@ class rcube_imap
    */
   function set_rootdir($root)
     {
-    if (ereg('[\.\/]$', $root)) //(substr($root, -1, 1)==='/')
+    if (preg_match('/[.\/]$/', $root)) //(substr($root, -1, 1)==='/')
       $root = substr($root, 0, -1);
 
     $this->root_dir = $root;
@@ -252,7 +263,7 @@ class rcube_imap
    */
   function set_mailbox($new_mbox)
     {
-    $mailbox = $this->_mod_mailbox($new_mbox);
+    $mailbox = $this->mod_mailbox($new_mbox);
 
     if ($this->mailbox == $mailbox)
       return;
@@ -301,7 +312,7 @@ class rcube_imap
     if (is_array($str) && $msgs == null)
       list($str, $msgs, $charset, $sort_field) = $str;
     if ($msgs != null && !is_array($msgs))
-      $msgs = split(',', $msgs);
+      $msgs = explode(',', $msgs);
       
     $this->search_string = $str;
     $this->search_set = $msgs;
@@ -328,7 +339,7 @@ class rcube_imap
    */
   function get_mailbox_name()
     {
-    return $this->conn ? $this->_mod_mailbox($this->mailbox, 'out') : '';
+    return $this->conn ? $this->mod_mailbox($this->mailbox, 'out') : '';
     }
 
 
@@ -396,7 +407,7 @@ class rcube_imap
 
     foreach ($a_mboxes as $mbox_row)
       {
-      $name = $this->_mod_mailbox($mbox_row, 'out');
+      $name = $this->mod_mailbox($mbox_row, 'out');
       if (strlen($name))
         $a_out[] = $name;
       }
@@ -419,7 +430,7 @@ class rcube_imap
    * @see     rcube_imap::list_mailboxes()
    * @access  private
    */
-  function _list_mailboxes($root='', $filter='*')
+  private function _list_mailboxes($root='', $filter='*')
     {
     $a_defaults = $a_out = array();
     
@@ -428,8 +439,16 @@ class rcube_imap
     if (is_array($a_mboxes))
       return $a_mboxes;
 
-    // retrieve list of folders from IMAP server
-    $a_folders = iil_C_ListSubscribed($this->conn, $this->_mod_mailbox($root), $filter);
+    // Give plugins a chance to provide a list of mailboxes
+    $data = rcmail::get_instance()->plugins->exec_hook('list_mailboxes',array('root'=>$root,'filter'=>$filter));
+    if (isset($data['folders'])) {
+        $a_folders = $data['folders'];
+    }
+    else{
+        // retrieve list of folders from IMAP server
+        $a_folders = iil_C_ListSubscribed($this->conn, $this->mod_mailbox($root), $filter);
+    }
+
     
     if (!is_array($a_folders) || !sizeof($a_folders))
       $a_folders = array();
@@ -452,7 +471,7 @@ class rcube_imap
    */
   function messagecount($mbox_name='', $mode='ALL', $force=FALSE)
     {
-    $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
     return $this->_messagecount($mailbox, $mode, $force);
     }
 
@@ -463,7 +482,7 @@ class rcube_imap
    * @access  private
    * @see     rcube_imap::messagecount()
    */
-  function _messagecount($mailbox='', $mode='ALL', $force=FALSE)
+  private function _messagecount($mailbox='', $mode='ALL', $force=FALSE)
     {
     $a_mailbox_cache = FALSE;
     $mode = strtoupper($mode);
@@ -496,14 +515,8 @@ class rcube_imap
 
       // get message count using SEARCH
       // not very performant but more precise (using UNDELETED)
-      $count = 0;
       $index = $this->_search_index($mailbox, $search_str);
-      if (is_array($index))
-        {
-        $str = implode(",", $index);
-        if (!empty($str))
-          $count = count($index);
-        }
+      $count = is_array($index) ? count($index) : 0;
       }
     else
       {
@@ -533,13 +546,14 @@ class rcube_imap
    * @param   int      Current page to list
    * @param   string   Header field to sort by
    * @param   string   Sort order [ASC|DESC]
+   * @param   boolean  Number of slice items to extract from result array
    * @return  array    Indexed array with message header objects
    * @access  public   
    */
-  function list_headers($mbox_name='', $page=NULL, $sort_field=NULL, $sort_order=NULL)
+  function list_headers($mbox_name='', $page=NULL, $sort_field=NULL, $sort_order=NULL, $slice=0)
     {
-    $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
-    return $this->_list_headers($mailbox, $page, $sort_field, $sort_order);
+    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
+    return $this->_list_headers($mailbox, $page, $sort_field, $sort_order, false, $slice);
     }
 
 
@@ -549,85 +563,91 @@ class rcube_imap
    * @access  private
    * @see     rcube_imap::list_headers
    */
-  function _list_headers($mailbox='', $page=NULL, $sort_field=NULL, $sort_order=NULL, $recursive=FALSE)
+  private function _list_headers($mailbox='', $page=NULL, $sort_field=NULL, $sort_order=NULL, $recursive=FALSE, $slice=0)
     {
     if (!strlen($mailbox))
       return array();
 
     // use saved message set
     if ($this->search_string && $mailbox == $this->mailbox)
-      return $this->_list_header_set($mailbox, $page, $sort_field, $sort_order);
+      return $this->_list_header_set($mailbox, $page, $sort_field, $sort_order, $slice);
 
     $this->_set_sort_order($sort_field, $sort_order);
 
-    $max = $this->_messagecount($mailbox);
-    $start_msg = ($this->list_page-1) * $this->page_size;
-
-    list($begin, $end) = $this->_get_message_range($max, $page);
-
-    // mailbox is empty
-    if ($begin >= $end)
-      return array();
-      
-    $headers_sorted = FALSE;
+    $page = $page ? $page : $this->list_page;
     $cache_key = $mailbox.'.msg';
     $cache_status = $this->check_cache_status($mailbox, $cache_key);
 
     // cache is OK, we can get all messages from local cache
     if ($cache_status>0)
       {
+      $start_msg = ($page-1) * $this->page_size;
       $a_msg_headers = $this->get_message_cache($cache_key, $start_msg, $start_msg+$this->page_size, $this->sort_field, $this->sort_order);
-      $headers_sorted = TRUE;
+      $result = array_values($a_msg_headers);
+      if ($slice)
+        $result = array_slice($result, -$slice, $slice);
+      return $result;
       }
     // cache is dirty, sync it
     else if ($this->caching_enabled && $cache_status==-1 && !$recursive)
       {
       $this->sync_header_index($mailbox);
-      return $this->_list_headers($mailbox, $page, $this->sort_field, $this->sort_order, TRUE);
+      return $this->_list_headers($mailbox, $page, $this->sort_field, $this->sort_order, TRUE, $slice);
       }
-    else
+
+    // retrieve headers from IMAP
+    $a_msg_headers = array();
+
+    if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
       {
-      // retrieve headers from IMAP
-      if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
-        {
-        $mymsgidx = array_slice ($msg_index, $begin, $end-$begin);
-        $msgs = join(",", $mymsgidx);
-        }
-      else
-        {
-        $msgs = sprintf("%d:%d", $begin+1, $end);
-        $msg_index = range($begin, $end);
-        }
+      list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
+      $max = max($msg_index);
+      $msg_index = array_slice($msg_index, $begin, $end-$begin);
 
+      if ($slice)
+        $msg_index = array_slice($msg_index, ($this->sort_order == 'DESC' ? 0 : -$slice), $slice);
 
-      // fetch reuested headers from server
-      $a_msg_headers = array();
-      $deleted_count = $this->_fetch_headers($mailbox, $msgs, $a_msg_headers, $cache_key);
+      // fetch reqested headers from server
+      $this->_fetch_headers($mailbox, join(',', $msg_index), $a_msg_headers, $cache_key);
+      }
+    else
+      {
+      $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted);
+    
+      if (empty($a_index))
+        return array();
+
+      asort($a_index); // ASC
+      $msg_index = array_keys($a_index);
+      $max = max($msg_index);
+      list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
+      $msg_index = array_slice($msg_index, $begin, $end-$begin);
 
-      // delete cached messages with a higher index than $max+1
-      // Changed $max to $max+1 to fix this bug : #1484295
-      $this->clear_message_cache($cache_key, $max + 1);
+      if ($slice)
+        $msg_index = array_slice($msg_index, ($this->sort_order == 'DESC' ? 0 : -$slice), $slice);
 
-      // kick child process to sync cache
-      // ...
+      // fetch reqested headers from server
+      $this->_fetch_headers($mailbox, join(",", $msg_index), $a_msg_headers, $cache_key);
       }
 
+    // delete cached messages with a higher index than $max+1
+    // Changed $max to $max+1 to fix this bug : #1484295
+    $this->clear_message_cache($cache_key, $max + 1);
+
+    // kick child process to sync cache
+    // ...
+
     // return empty array if no messages found
-    if (!is_array($a_msg_headers) || empty($a_msg_headers)) {
+    if (!is_array($a_msg_headers) || empty($a_msg_headers))
       return array();
-    }
-
-    // if not already sorted
-    if (!$headers_sorted)
-      {
-      // use this class for message sorting
-      $sorter = new rcube_header_sorter();
-      $sorter->set_sequence_numbers($msg_index);
-      $sorter->sort_headers($a_msg_headers);
+    
+    // use this class for message sorting
+    $sorter = new rcube_header_sorter();
+    $sorter->set_sequence_numbers($msg_index);
+    $sorter->sort_headers($a_msg_headers);
 
-      if ($this->sort_order == 'DESC')
-        $a_msg_headers = array_reverse($a_msg_headers);
-      }
+    if ($this->sort_order == 'DESC')
+      $a_msg_headers = array_reverse($a_msg_headers);      
 
     return array_values($a_msg_headers);
     }
@@ -640,18 +660,20 @@ class rcube_imap
    * @param   int      Current page to list
    * @param   string   Header field to sort by
    * @param   string   Sort order [ASC|DESC]
+   * @param   boolean  Number of slice items to extract from result array
    * @return  array    Indexed array with message header objects
    * @access  private
    * @see     rcube_imap::list_header_set()
    */
-  function _list_header_set($mailbox, $page=NULL, $sort_field=NULL, $sort_order=NULL)
+  private function _list_header_set($mailbox, $page=NULL, $sort_field=NULL, $sort_order=NULL, $slice=0)
     {
     if (!strlen($mailbox) || empty($this->search_set))
       return array();
 
     $msgs = $this->search_set;
     $a_msg_headers = array();
-    $start_msg = ($this->list_page-1) * $this->page_size;
+    $page = $page ? $page : $this->list_page;
+    $start_msg = ($page-1) * $this->page_size;
 
     $this->_set_sort_order($sort_field, $sort_order);
 
@@ -674,6 +696,9 @@ class rcube_imap
       // get messages uids for one page
       $msgs = array_slice(array_values($msgs), $start_msg, min(count($msgs)-$start_msg, $this->page_size));
 
+      if ($slice)
+        $msgs = array_slice($msgs, -$slice, $slice);
+
       // fetch headers
       $this->_fetch_headers($mailbox, join(',',$msgs), $a_msg_headers, NULL);
 
@@ -690,6 +715,8 @@ class rcube_imap
        $a_index = $this->message_index('', $this->sort_field, $this->sort_order);
         // get messages uids for one page...
         $msgs = array_slice($a_index, $start_msg, min($cnt-$start_msg, $this->page_size));
+        if ($slice)
+          $msgs = array_slice($msgs, -$slice, $slice);
        // ...and fetch headers
         $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
 
@@ -715,7 +742,11 @@ class rcube_imap
         $a_msg_headers = iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order);
       
         // only return the requested part of the set
-        return array_slice(array_values($a_msg_headers), $start_msg, min($cnt-$start_msg, $this->page_size));
+       $a_msg_headers = array_slice(array_values($a_msg_headers), $start_msg, min($cnt-$start_msg, $this->page_size));
+        if ($slice)
+          $a_msg_headers = array_slice($a_msg_headers, -$slice, $slice);
+
+        return $a_msg_headers;
         }
       }
     }
@@ -729,9 +760,9 @@ class rcube_imap
    * @return array   array with two values: first index, last index
    * @access private
    */
-  function _get_message_range($max, $page)
+  private function _get_message_range($max, $page)
     {
-    $start_msg = ($this->list_page-1) * $this->page_size;
+    $start_msg = ($page-1) * $this->page_size;
     
     if ($page=='all')
       {
@@ -756,7 +787,6 @@ class rcube_imap
     return array($begin, $end);
     }
     
-    
 
   /**
    * Fetches message headers
@@ -766,41 +796,41 @@ class rcube_imap
    * @param  string  Message index to fetch
    * @param  array   Reference to message headers array
    * @param  array   Array with cache index
-   * @return int     Number of deleted messages
+   * @return int     Messages count
    * @access private
    */
-  function _fetch_headers($mailbox, $msgs, &$a_msg_headers, $cache_key)
+  private function _fetch_headers($mailbox, $msgs, &$a_msg_headers, $cache_key)
     {
-    // cache is incomplete
-    $cache_index = $this->get_message_cache_index($cache_key);
-    
-    // fetch reuested headers from server
-    $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, $msgs);
-    $deleted_count = 0;
-    
+    // fetch reqested headers from server
+    $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, $msgs, false, false, $this->fetch_add_headers);
+
     if (!empty($a_header_index))
       {
+      // cache is incomplete
+      $cache_index = $this->get_message_cache_index($cache_key);
+    
       foreach ($a_header_index as $i => $headers)
-        {
+        { 
+/*
         if ($headers->deleted && $this->skip_deleted)
           {
           // delete from cache
           if ($cache_index[$headers->id] && $cache_index[$headers->id] == $headers->uid)
-            $this->remove_message_cache($cache_key, $headers->id);
+            $this->remove_message_cache($cache_key, $headers->uid);
 
-          $deleted_count++;
           continue;
           }
-
+*/
         // add message to cache
         if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid)
-          $this->add_message_cache($cache_key, $headers->id, $headers);
+          $this->add_message_cache($cache_key, $headers->id, $headers, NULL,
+               !in_array((string)$headers->uid, $cache_index, true));
 
         $a_msg_headers[$headers->uid] = $headers;
         }
       }
-        
-    return $deleted_count;
+
+    return count($a_msg_headers);
     }
     
   
@@ -816,7 +846,7 @@ class rcube_imap
     {
     $this->_set_sort_order($sort_field, $sort_order);
 
-    $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
     $key = "{$mailbox}:{$this->sort_field}:{$this->sort_order}:{$this->search_string}.msgi";
 
     // we have a saved search result. get index from there
@@ -829,14 +859,14 @@ class rcube_imap
         if ($this->sort_field && $this->search_sort_field != $this->sort_field)
           $this->search('', $this->search_string, $this->search_charset, $this->sort_field);
 
-       if ($this->sort_order == 'DESC')
+        if ($this->sort_order == 'DESC')
           $this->cache[$key] = array_reverse($this->search_set);
-       else
-         $this->cache[$key] = $this->search_set;
+        else
+          $this->cache[$key] = $this->search_set;
         }
       else
         {
-       $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, join(',', $this->search_set), $this->sort_field);
+        $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, join(',', $this->search_set), $this->sort_field, $this->skip_deleted);
 
         if ($this->sort_order=="ASC")
           asort($a_index);
@@ -863,8 +893,7 @@ class rcube_imap
       }
 
     // fetch complete message index
-    $msg_count = $this->_messagecount($mailbox);
-    if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, '')))
+    if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
       {
       if ($this->sort_order == 'DESC')
         $a_index = array_reverse($a_index);
@@ -873,7 +902,7 @@ class rcube_imap
       }
     else
       {
-      $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:$msg_count", $this->sort_field);
+      $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted);
 
       if ($this->sort_order=="ASC")
         asort($a_index);
@@ -894,10 +923,12 @@ class rcube_imap
     {
     $cache_key = $mailbox.'.msg';
     $cache_index = $this->get_message_cache_index($cache_key);
-    $msg_count = $this->_messagecount($mailbox);
 
     // fetch complete message index
-    $a_message_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:$msg_count", 'UID');
+    $a_message_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", 'UID', $this->skip_deleted);
+    
+    if ($a_message_index === false)
+      return false;
         
     foreach ($a_message_index as $id => $uid)
       {
@@ -911,27 +942,32 @@ class rcube_imap
       // message in cache but in wrong position
       if (in_array((string)$uid, $cache_index, TRUE))
         {
-        unset($cache_index[$id]);        
+        unset($cache_index[$id]);
         }
       
       // other message at this position
       if (isset($cache_index[$id]))
         {
-        $this->remove_message_cache($cache_key, $id);
+       $for_remove[] = $cache_index[$id];
         unset($cache_index[$id]);
         }
         
-
-      // fetch complete headers and add to cache
-      $headers = iil_C_FetchHeader($this->conn, $mailbox, $id);
-      $this->add_message_cache($cache_key, $headers->id, $headers);
+       $for_update[] = $id;
       }
 
-    // those ids that are still in cache_index have been deleted      
+    // clear messages at wrong positions and those deleted that are still in cache_index      
+    if (!empty($for_remove))
+      $cache_index = array_merge($cache_index, $for_remove);
+    
     if (!empty($cache_index))
-      {
-      foreach ($cache_index as $id => $uid)
-        $this->remove_message_cache($cache_key, $id);
+      $this->remove_message_cache($cache_key, $cache_index);
+
+    // fetch complete headers and add to cache
+    if (!empty($for_update)) {
+      if ($headers = iil_C_FetchHeader($this->conn, $mailbox, join(',', $for_update), false, $this->fetch_add_headers))
+        foreach ($headers as $header)
+          $this->add_message_cache($cache_key, $header->id, $header, NULL,
+               in_array((string)$header->uid, (array)$for_remove, true));
       }
     }
 
@@ -951,13 +987,13 @@ class rcube_imap
     if (!$str)
       return false;
     
-    $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
 
     $results = $this->_search_index($mailbox, $str, $charset, $sort_field);
 
     // try search with US-ASCII charset (should be supported by server)
     // only if UTF-8 search is not supported
-    if (empty($results) && !is_array($results) && !empty($charset) && $charset!='US-ASCII')
+    if (empty($results) && !is_array($results) && !empty($charset) && $charset != 'US-ASCII')
       {
        // convert strings to US_ASCII
         if(preg_match_all('/\{([0-9]+)\}\r\n/', $str, $matches, PREG_OFFSET_CAPTURE))
@@ -978,7 +1014,7 @@ class rcube_imap
        else // strings for conversion not found
          $res = $str;
          
-       $results = $this->search($mbox_name, $res, 'US-ASCII', $sort_field);
+       $results = $this->search($mbox_name, $res, NULL, $sort_field);
       }
 
     $this->set_search_set($str, $results, $charset, $sort_field);
@@ -994,8 +1030,13 @@ class rcube_imap
    * @access private
    * @see rcube_imap::search()
    */
-  function _search_index($mailbox, $criteria='ALL', $charset=NULL, $sort_field=NULL)
+  private function _search_index($mailbox, $criteria='ALL', $charset=NULL, $sort_field=NULL)
     {
+    $orig_criteria = $criteria;
+
+    if ($this->skip_deleted && !preg_match('/UNDELETED/', $criteria))
+      $criteria = 'UNDELETED '.$criteria;
+
     if ($sort_field && $this->get_capability('sort'))
       {
       $charset = $charset ? $charset : $this->default_charset;
@@ -1003,14 +1044,11 @@ class rcube_imap
       }
     else
       $a_messages = iil_C_Search($this->conn, $mailbox, ($charset ? "CHARSET $charset " : '') . $criteria);
-
-    // clean message list (there might be some empty entries)
-    if (is_array($a_messages))
-      {
-      foreach ($a_messages as $i => $val)
-        if (empty($val))
-          unset($a_messages[$i]);
-      }
+    
+    // update messagecount cache ?
+//    $a_mailbox_cache = get_cache('messagecount');
+//    $a_mailbox_cache[$mailbox][$criteria] = sizeof($a_messages);
+//    $this->update_cache('messagecount', $a_mailbox_cache);
         
     return $a_messages;
     }
@@ -1055,14 +1093,14 @@ class rcube_imap
    */
   function get_headers($id, $mbox_name=NULL, $is_uid=TRUE, $bodystr=FALSE)
     {
-    $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
     $uid = $is_uid ? $id : $this->_id2uid($id);
 
     // get cached headers
     if ($uid && ($headers = &$this->get_cached_message($mailbox.'.msg', $uid)))
       return $headers;
 
-    $headers = iil_C_FetchHeader($this->conn, $mailbox, $id, $is_uid, $bodystr);
+    $headers = iil_C_FetchHeader($this->conn, $mailbox, $id, $is_uid, $bodystr, $this->fetch_add_headers);
 
     // write headers cache
     if ($headers)
@@ -1070,7 +1108,7 @@ class rcube_imap
       if ($headers->uid && $headers->id)
         $this->uid_id_map[$mailbox][$headers->uid] = $headers->id;
 
-      $this->add_message_cache($mailbox.'.msg', $headers->id, $headers);
+      $this->add_message_cache($mailbox.'.msg', $headers->id, $headers, NULL, true);
       }
 
     return $headers;
@@ -1088,29 +1126,30 @@ class rcube_imap
   function &get_structure($uid, $structure_str='')
     {
     $cache_key = $this->mailbox.'.msg';
-    $headers = &$this->get_cached_message($cache_key, $uid, true);
+    $headers = &$this->get_cached_message($cache_key, $uid);
 
     // return cached message structure
     if (is_object($headers) && is_object($headers->structure)) {
       return $headers->structure;
     }
 
-    // resolve message sequence number
-    if (!($msg_id = $this->_uid2id($uid))) {
-      return FALSE;
-    }
-
     if (!$structure_str)
-      $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $msg_id);
+      $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $uid, true);
     $structure = iml_GetRawStructureArray($structure_str);
     $struct = false;
 
     // parse structure and add headers
     if (!empty($structure))
       {
-      $this->_msg_id = $msg_id;
       $headers = $this->get_headers($uid);
-      
+      $this->_msg_id = $headers->id;
+
+      // set message charset from message headers
+      if ($headers->charset)
+        $this->struct_charset = $headers->charset;
+      else
+        $this->struct_charset = $this->_structure_charset($structure);
+
       $struct = &$this->_structure_part($structure);
       $struct->headers = get_object_vars($headers);
 
@@ -1124,7 +1163,7 @@ class rcube_imap
 
       // write structure to cache
       if ($this->caching_enabled)
-        $this->add_message_cache($cache_key, $msg_id, $headers, $struct);
+        $this->add_message_cache($cache_key, $this->_msg_id, $headers, $struct);
       }
 
     return $struct;
@@ -1140,7 +1179,7 @@ class rcube_imap
     {
     $struct = new rcube_message_part;
     $struct->mime_id = empty($parent) ? (string)$count : "$parent.$count";
-    
+
     // multipart
     if (is_array($part[0]))
       {
@@ -1162,18 +1201,19 @@ class rcube_imap
          // fetch message headers if message/rfc822 or named part (could contain Content-Location header)
          if (strtolower($part[$i][0]) == 'message' ||
            (in_array('name', (array)$part[$i][2]) && (empty($part[$i][3]) || $part[$i][3]=='NIL'))) {
-           $part_headers[] = $struct->mime_id ? $struct->mime_id.'.'.$i+1 : $i+1;
+           $part_headers[] = $struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1;
            }
-    
+
       // pre-fetch headers of all parts (in one command for better performance)
       if ($part_headers)
         $part_headers = iil_C_FetchMIMEHeaders($this->conn, $this->mailbox, $this->_msg_id, $part_headers);
 
       $struct->parts = array();
       for ($i=0, $count=0; $i<count($part); $i++)
-        if (is_array($part[$i]) && count($part[$i]) > 3)
+        if (is_array($part[$i]) && count($part[$i]) > 3) {
           $struct->parts[] = $this->_structure_part($part[$i], ++$count, $struct->mime_id,
-               $part_headers[$struct->mime_id ? $struck->mime_id.'.'.$i+1 : $i+1]);
+               $part_headers[$struct->mime_id ? $struct->mime_id.'.'.($i+1) : $i+1]);
+       }
 
       return $struct;
       }
@@ -1240,7 +1280,7 @@ class rcube_imap
     // fetch message headers if message/rfc822 or named part (could contain Content-Location header)
     if ($struct->ctype_primary == 'message' || ($struct->ctype_parameters['name'] && !$struct->content_id)) {
       if (empty($raw_headers))
-        $raw_headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $struct->mime_id);
+        $raw_headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, false, $struct->mime_id);
       $struct->headers = $this->_parse_headers($raw_headers) + $struct->headers;
     }
 
@@ -1263,7 +1303,7 @@ class rcube_imap
    * @param  object rcube_message_part Part object
    * @param  string Part's raw headers
    */
-  function _set_part_filename(&$part, $headers=null)
+  private function _set_part_filename(&$part, $headers=null)
     {
     if (!empty($part->d_parameters['filename']))
       $filename_mime = $part->d_parameters['filename'];
@@ -1283,7 +1323,7 @@ class rcube_imap
       // we must fetch and parse headers "manually"
       if ($i<2) {
        if (!$headers)
-          $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id);
+          $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, false, $part->mime_id);
         $filename_mime = '';
         $i = 0;
         while (preg_match('/filename\*'.$i.'\s*=\s*"*([^"\n;]+)[";]*/', $headers, $matches)) {
@@ -1300,7 +1340,7 @@ class rcube_imap
       }
       if ($i<2) {
        if (!$headers)
-          $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id);
+          $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, false, $part->mime_id);
         $filename_encoded = '';
         $i = 0; $matches = array();
         while (preg_match('/filename\*'.$i.'\*\s*=\s*"*([^"\n;]+)[";]*/', $headers, $matches)) {
@@ -1317,7 +1357,7 @@ class rcube_imap
       }
       if ($i<2) {
        if (!$headers)
-          $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id);
+          $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, false, $part->mime_id);
         $filename_mime = '';
         $i = 0; $matches = array();
         while (preg_match('/\s+name\*'.$i.'\s*=\s*"*([^"\n;]+)[";]*/', $headers, $matches)) {
@@ -1334,7 +1374,7 @@ class rcube_imap
       }
       if ($i<2) {
        if (!$headers)
-          $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, $part->mime_id);
+          $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $this->_msg_id, false, $part->mime_id);
         $filename_encoded = '';
         $i = 0; $matches = array();
         while (preg_match('/\s+name\*'.$i.'\*\s*=\s*"*([^"\n;]+)[";]*/', $headers, $matches)) {
@@ -1355,7 +1395,8 @@ class rcube_imap
     // decode filename
     if (!empty($filename_mime)) {
       $part->filename = rcube_imap::decode_mime_string($filename_mime, 
-        $part->charset ? $part->charset : rc_detect_encoding($filename_mime, $this->default_charset));
+        $part->charset ? $part->charset : $this->struct_charset ? $this->struct_charset :
+           rc_detect_encoding($filename_mime, $this->default_charset));
       } 
     else if (!empty($filename_encoded)) {
       // decode filename according to RFC 2231, Section 4
@@ -1366,8 +1407,25 @@ class rcube_imap
       $part->filename = rcube_charset_convert(urldecode($filename_encoded), $filename_charset);
       }
     }
-     
-  
+
+
+  /**
+   * Get charset name from message structure (first part)
+   *
+   * @access private
+   * @param  array  Message structure
+   * @return string Charset name
+   */
+  function _structure_charset($structure)
+    {
+      while (is_array($structure)) {
+       if (is_array($structure[2]) && $structure[2][0] == 'charset')
+         return $structure[2][1];
+       $structure = $structure[0];
+       }
+    } 
+
+
   /**
    * Fetch message body of a specific message from the server
    *
@@ -1380,14 +1438,15 @@ class rcube_imap
    */
   function &get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL)
     {
-    if (!($msg_id = $this->_uid2id($uid)))
-      return FALSE;
-    
     // get part encoding if not provided
     if (!is_object($o_part))
       {
-      $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $msg_id); 
+      $structure_str = iil_C_FetchStructureString($this->conn, $this->mailbox, $uid, true); 
       $structure = iml_GetRawStructureArray($structure_str);
+      // error or message not found
+      if (empty($structure))
+        return false;
+
       $part_type = iml_GetPartTypeCode($structure, $part);
       $o_part = new rcube_message_part;
       $o_part->ctype_primary = $part_type==0 ? 'text' : ($part_type==2 ? 'message' : 'other');
@@ -1399,44 +1458,19 @@ class rcube_imap
 
     if (!$part) $part = 'TEXT';
 
-    if ($print)
-      {
-      $mode = $o_part->encoding == 'base64' ? 3 : ($o_part->encoding == 'quoted-printable' ? 1 : 2);
-      $body = iil_C_HandlePartBody($this->conn, $this->mailbox, $msg_id, $part, $mode);
-      
-      // we have to decode the part manually before printing
-      if ($mode == 1)
-        {
-        echo $this->mime_decode($body, $o_part->encoding);
-        $body = true;
-        }
-      }
-    else
-      {
-      if ($fp && $o_part->encoding == 'base64')
-        return iil_C_HandlePartBody($this->conn, $this->mailbox, $msg_id, $part, 3, $fp);
-      else
-        $body = iil_C_HandlePartBody($this->conn, $this->mailbox, $msg_id, $part, 1);
+    $body = iil_C_HandlePartBody($this->conn, $this->mailbox, $uid, true, $part,
+        $o_part->encoding, $print, $fp);
 
-      // decode part body
-      if ($o_part->encoding)
-        $body = $this->mime_decode($body, $o_part->encoding);
+    if ($fp || $print)
+      return true;
 
-      // convert charset (if text or message part)
-      if ($o_part->ctype_primary=='text' || $o_part->ctype_primary=='message')
-        {
-        // assume default if no charset specified
-        if (empty($o_part->charset))
-          $o_part->charset = $this->default_charset;
+    // convert charset (if text or message part)
+    if ($o_part->ctype_primary=='text' || $o_part->ctype_primary=='message') {
+      // assume default if no charset specified
+      if (empty($o_part->charset))
+        $o_part->charset = $this->default_charset;
 
-        $body = rcube_charset_convert($body, $o_part->charset);
-        }
-      
-      if ($fp)
-        {
-        fwrite($fp, $body);
-        return true;
-        }
+      $body = rcube_charset_convert($body, $o_part->charset);
       }
     
     return $body;
@@ -1453,8 +1487,7 @@ class rcube_imap
   function &get_body($uid, $part=1)
     {
     $headers = $this->get_headers($uid);
-    return rcube_charset_convert(
-      $this->mime_decode($this->get_message_part($uid, $part), 'quoted-printable'),
+    return rcube_charset_convert($this->get_message_part($uid, $part, NULL),
       $headers->charset ? $headers->charset : $this->default_charset);
     }
 
@@ -1467,10 +1500,7 @@ class rcube_imap
    */
   function &get_raw_body($uid)
     {
-    if (!($msg_id = $this->_uid2id($uid)))
-      return FALSE;
-
-    return iil_C_HandlePartBody($this->conn, $this->mailbox, $msg_id);
+    return iil_C_HandlePartBody($this->conn, $this->mailbox, $uid, true);
     }
 
 
@@ -1482,12 +1512,7 @@ class rcube_imap
    */
   function &get_raw_headers($uid)
     {
-    if (!($msg_id = $this->_uid2id($uid)))
-      return FALSE;
-
-    $headers = iil_C_FetchPartHeader($this->conn, $this->mailbox, $msg_id, NULL);
-
-    return $headers;    
+    return iil_C_FetchPartHeader($this->conn, $this->mailbox, $uid, true);
     }
     
 
@@ -1498,10 +1523,7 @@ class rcube_imap
    */ 
   function print_raw_body($uid)
     {
-    if (!($msg_id = $this->_uid2id($uid)))
-      return FALSE;
-
-    iil_C_HandlePartBody($this->conn, $this->mailbox, $msg_id, NULL, 2);
+    iil_C_HandlePartBody($this->conn, $this->mailbox, $uid, true, NULL, NULL, true);
     }
 
 
@@ -1510,40 +1532,27 @@ class rcube_imap
    *
    * @param mixed  Message UIDs as array or as comma-separated string
    * @param string Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
+   * @param string Folder name
    * @return boolean True on success, False on failure
    */
-  function set_flag($uids, $flag)
+  function set_flag($uids, $flag, $mbox_name=NULL)
     {
+    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
+
     $flag = strtoupper($flag);
-    $msg_ids = array();
     if (!is_array($uids))
       $uids = explode(',',$uids);
       
-    foreach ($uids as $uid) {
-      $msg_ids[$uid] = $this->_uid2id($uid);
-    }
-      
-    if ($flag=='UNDELETED')
-      $result = iil_C_Undelete($this->conn, $this->mailbox, join(',', array_values($msg_ids)));
-    else if ($flag=='UNSEEN')
-      $result = iil_C_Unseen($this->conn, $this->mailbox, join(',', array_values($msg_ids)));
-    else if ($flag=='UNFLAGGED')
-      $result = iil_C_UnFlag($this->conn, $this->mailbox, join(',', array_values($msg_ids)), 'FLAGGED');
+    if (strpos($flag, 'UN') === 0)
+      $result = iil_C_UnFlag($this->conn, $mailbox, join(',', $uids), substr($flag, 2));
     else
-      $result = iil_C_Flag($this->conn, $this->mailbox, join(',', array_values($msg_ids)), $flag);
+      $result = iil_C_Flag($this->conn, $mailbox, join(',', $uids), $flag);
 
     // reload message headers if cached
-    $cache_key = $this->mailbox.'.msg';
     if ($this->caching_enabled)
       {
-      foreach ($msg_ids as $uid => $id)
-        {
-        if ($cached_headers = $this->get_cached_message($cache_key, $uid))
-          {
-          $this->remove_message_cache($cache_key, $id);
-          //$this->get_headers($uid);
-          }
-        }
+      $cache_key = $mailbox.'.msg';
+      $this->remove_message_cache($cache_key, $uids);
 
       // close and re-open connection
       // this prevents connection problems with Courier 
@@ -1551,20 +1560,35 @@ class rcube_imap
       }
 
     // set nr of messages that were flaged
-    $count = count($msg_ids);
+    $count = count($uids);
 
     // clear message count cache
     if ($result && $flag=='SEEN')
-      $this->_set_messagecount($this->mailbox, 'UNSEEN', $count*(-1));
+      $this->_set_messagecount($mailbox, 'UNSEEN', $count*(-1));
     else if ($result && $flag=='UNSEEN')
-      $this->_set_messagecount($this->mailbox, 'UNSEEN', $count);
+      $this->_set_messagecount($mailbox, 'UNSEEN', $count);
     else if ($result && $flag=='DELETED')
-      $this->_set_messagecount($this->mailbox, 'ALL', $count*(-1));
+      $this->_set_messagecount($mailbox, 'ALL', $count*(-1));
 
     return $result;
     }
 
 
+  /**
+   * Remove message flag for one or several messages
+   *
+   * @param mixed  Message UIDs as array or as comma-separated string
+   * @param string Flag to unset: SEEN, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
+   * @param string Folder name
+   * @return boolean True on success, False on failure
+   * @see set_flag
+   */
+  function unset_flag($uids, $flag, $mbox_name=NULL)
+    {
+    return $this->set_flag($uids, 'UN'.$flag, $mbox_name);
+    }
+
+
   /**
    * Append a mail message (source) to a specific mailbox
    *
@@ -1574,7 +1598,7 @@ class rcube_imap
    */
   function save_message($mbox_name, &$message)
     {
-    $mailbox = $this->_mod_mailbox($mbox_name);
+    $mailbox = $this->mod_mailbox($mbox_name);
 
     // make sure mailbox exists
     if (($mailbox == 'INBOX') || in_array($mailbox, $this->_list_mailboxes()))
@@ -1600,8 +1624,8 @@ class rcube_imap
    */
   function move_message($uids, $to_mbox, $from_mbox='')
     {
-    $to_mbox = $this->_mod_mailbox($to_mbox);
-    $from_mbox = $from_mbox ? $this->_mod_mailbox($from_mbox) : $this->mailbox;
+    $to_mbox = $this->mod_mailbox($to_mbox);
+    $from_mbox = $from_mbox ? $this->mod_mailbox($from_mbox) : $this->mailbox;
 
     // make sure mailbox exists
     if ($to_mbox != 'INBOX' && !in_array($to_mbox, $this->_list_mailboxes()))
@@ -1616,48 +1640,33 @@ class rcube_imap
     $a_uids = is_string($uids) ? explode(',', $uids) : (is_array($uids) ? $uids : NULL);
     
     // exit if no message uids are specified
-    if (!is_array($a_uids))
+    if (!is_array($a_uids) || empty($a_uids))
       return false;
 
-    // convert uids to message ids
-    $a_mids = array();
-    foreach ($a_uids as $uid)
-      $a_mids[] = $this->_uid2id($uid, $from_mbox);
-
-    $iil_move = iil_C_Move($this->conn, join(',', $a_mids), $from_mbox, $to_mbox);
+    $iil_move = iil_C_Move($this->conn, join(',', $a_uids), $from_mbox, $to_mbox);
     $moved = !($iil_move === false || $iil_move < 0);
     
     // send expunge command in order to have the moved message
     // really deleted from the source mailbox
     if ($moved) {
-      // but only when flag_for_deletion is set to false
-      if (!rcmail::get_instance()->config->get('flag_for_deletion', false))
-        {
-        $this->_expunge($from_mbox, FALSE);
-        $this->_clear_messagecount($from_mbox);
-        $this->_clear_messagecount($to_mbox);
-        }
+      $this->_expunge($from_mbox, FALSE, $a_uids);
+      $this->_clear_messagecount($from_mbox);
+      $this->_clear_messagecount($to_mbox);
     }
     // moving failed
     else if (rcmail::get_instance()->config->get('delete_always', false)) {
-      return iil_C_Delete($this->conn, $from_mbox, join(',', $a_mids));
+      return iil_C_Delete($this->conn, $from_mbox, join(',', $a_uids));
     }
       
     // remove message ids from search set
-    if ($moved && $this->search_set && $from_mbox == $this->mailbox)
+    if ($moved && $this->search_set && $from_mbox == $this->mailbox) {
+      foreach ($a_uids as $uid)
+        $a_mids[] = $this->_uid2id($uid, $from_mbox);
       $this->search_set = array_diff($this->search_set, $a_mids);
-
+    }
     // update cached message headers
     $cache_key = $from_mbox.'.msg';
-    if ($moved && ($a_cache_index = $this->get_message_cache_index($cache_key)))
-      {
-      $start_index = 100000;
-      foreach ($a_uids as $uid)
-        {
-        if (($index = array_search($uid, $a_cache_index)) !== FALSE)
-          $start_index = min($index, $start_index);
-        }
-
+    if ($moved && $start_index = $this->get_message_cache_index_min($cache_key, $a_uids)) {
       // clear cache from the lowest index on
       $this->clear_message_cache($cache_key, $start_index);
       }
@@ -1675,46 +1684,36 @@ class rcube_imap
    */
   function delete_message($uids, $mbox_name='')
     {
-    $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
 
     // convert the list of uids to array
     $a_uids = is_string($uids) ? explode(',', $uids) : (is_array($uids) ? $uids : NULL);
     
     // exit if no message uids are specified
-    if (!is_array($a_uids))
+    if (!is_array($a_uids) || empty($a_uids))
       return false;
 
-    // convert uids to message ids
-    $a_mids = array();
-    foreach ($a_uids as $uid)
-      $a_mids[] = $this->_uid2id($uid, $mailbox);
-        
-    $deleted = iil_C_Delete($this->conn, $mailbox, join(',', $a_mids));
+    $deleted = iil_C_Delete($this->conn, $mailbox, join(',', $a_uids));
     
     // send expunge command in order to have the deleted message
     // really deleted from the mailbox
     if ($deleted)
       {
-      $this->_expunge($mailbox, FALSE);
+      $this->_expunge($mailbox, FALSE, $a_uids);
       $this->_clear_messagecount($mailbox);
       unset($this->uid_id_map[$mailbox]);
       }
 
     // remove message ids from search set
-    if ($deleted && $this->search_set && $mailbox == $this->mailbox)
+    if ($deleted && $this->search_set && $mailbox == $this->mailbox) {
+      foreach ($a_uids as $uid)
+        $a_mids[] = $this->_uid2id($uid, $mailbox);
       $this->search_set = array_diff($this->search_set, $a_mids);
-
+    }
+    
     // remove deleted messages from cache
     $cache_key = $mailbox.'.msg';
-    if ($deleted && ($a_cache_index = $this->get_message_cache_index($cache_key)))
-      {
-      $start_index = 100000;
-      foreach ($a_uids as $uid)
-        {
-        if (($index = array_search($uid, $a_cache_index)) !== FALSE)
-          $start_index = min($index, $start_index);
-        }
-
+    if ($deleted && $start_index = $this->get_message_cache_index_min($cache_key, $a_uids)) {
       // clear cache from the lowest index on
       $this->clear_message_cache($cache_key, $start_index);
       }
@@ -1731,7 +1730,7 @@ class rcube_imap
    */
   function clear_mailbox($mbox_name=NULL)
     {
-    $mailbox = !empty($mbox_name) ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+    $mailbox = !empty($mbox_name) ? $this->mod_mailbox($mbox_name) : $this->mailbox;
     $msg_count = $this->_messagecount($mailbox, 'ALL');
     
     if ($msg_count>0)
@@ -1763,7 +1762,7 @@ class rcube_imap
    */
   function expunge($mbox_name='', $clear_cache=TRUE)
     {
-    $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
     return $this->_expunge($mailbox, $clear_cache);
     }
 
@@ -1772,11 +1771,20 @@ class rcube_imap
    * Send IMAP expunge command and clear cache
    *
    * @see rcube_imap::expunge()
+   * @param string     Mailbox name
+   * @param boolean    False if cache should not be cleared
+   * @param string     List of UIDs to remove, separated by comma
+   * @return boolean True on success
    * @access private
    */
-  function _expunge($mailbox, $clear_cache=TRUE)
+  private function _expunge($mailbox, $clear_cache=TRUE, $uids=NULL)
     {
-    $result = iil_C_Expunge($this->conn, $mailbox);
+    if ($uids && $this->get_capability('UIDPLUS')) 
+      $a_uids = is_array($uids) ? join(',', $uids) : $uids;
+    else
+      $a_uids = NULL;
+
+    $result = iil_C_Expunge($this->conn, $mailbox, $a_uids);
 
     if ($result>=0 && $clear_cache)
       {
@@ -1807,12 +1815,12 @@ class rcube_imap
       return $sa_unsubscribed;
       
     // retrieve list of folders from IMAP server
-    $a_mboxes = iil_C_ListMailboxes($this->conn, $this->_mod_mailbox($root), '*');
+    $a_mboxes = iil_C_ListMailboxes($this->conn, $this->mod_mailbox($root), '*');
 
     // modify names with root dir
     foreach ($a_mboxes as $mbox_name)
       {
-      $name = $this->_mod_mailbox($mbox_name, 'out');
+      $name = $this->mod_mailbox($mbox_name, 'out');
       if (strlen($name))
         $a_folders[] = $name;
       }
@@ -1884,7 +1892,7 @@ class rcube_imap
     // reduce mailbox name to 100 chars
     $name = substr($name, 0, 100);
 
-    $abs_name = $this->_mod_mailbox($name);
+    $abs_name = $this->mod_mailbox($name);
     $a_mailbox_cache = $this->get_cache('mailboxes');
 
     if (strlen($abs_name) && (!is_array($a_mailbox_cache) || !in_array($abs_name, $a_mailbox_cache)))
@@ -1913,8 +1921,8 @@ class rcube_imap
     $name = substr($new_name, 0, 100);
 
     // make absolute path
-    $mailbox = $this->_mod_mailbox($mbox_name);
-    $abs_name = $this->_mod_mailbox($name);
+    $mailbox = $this->mod_mailbox($mbox_name);
+    $abs_name = $this->mod_mailbox($name);
     
     // check if mailbox is subscribed
     $a_subscribed = $this->_list_mailboxes();
@@ -1955,7 +1963,7 @@ class rcube_imap
   /**
    * Remove mailboxes from server
    *
-   * @param string Mailbox name
+   * @param string Mailbox name(s) string/array
    * @return boolean True on success
    */
   function delete_mailbox($mbox_name)
@@ -1967,21 +1975,23 @@ class rcube_imap
     else if (is_string($mbox_name) && strlen($mbox_name))
       $a_mboxes = explode(',', $mbox_name);
 
-    $all_mboxes = iil_C_ListMailboxes($this->conn, $this->_mod_mailbox($root), '*');
+    $all_mboxes = iil_C_ListMailboxes($this->conn, $this->mod_mailbox($root), '*');
 
     if (is_array($a_mboxes))
       foreach ($a_mboxes as $mbox_name)
         {
-        $mailbox = $this->_mod_mailbox($mbox_name);
+        $mailbox = $this->mod_mailbox($mbox_name);
 
         // unsubscribe mailbox before deleting
         iil_C_UnSubscribe($this->conn, $mailbox);
 
         // send delete command to server
         $result = iil_C_DeleteFolder($this->conn, $mailbox);
-        if ($result>=0)
+        if ($result >= 0) {
           $deleted = TRUE;
-
+          $this->clear_message_cache($mailbox.'.msg');
+         }
+         
         foreach ($all_mboxes as $c_mbox)
           {
           $regex = preg_quote($mailbox . $this->delimiter, '/');
@@ -1990,18 +2000,17 @@ class rcube_imap
             {
             iil_C_UnSubscribe($this->conn, $c_mbox);
             $result = iil_C_DeleteFolder($this->conn, $c_mbox);
-            if ($result>=0)
+            if ($result >= 0) {
               $deleted = TRUE;
-            }
+             $this->clear_message_cache($c_mbox.'.msg');
+              }
+           }
           }
         }
 
     // clear mailboxlist cache
     if ($deleted)
-      {
-      $this->clear_message_cache($mailbox.'.msg');
       $this->clear_cache('mailboxes');
-      }
 
     return $deleted;
     }
@@ -2012,13 +2021,13 @@ class rcube_imap
    */
   function create_default_folders()
     {
-    $a_folders = iil_C_ListMailboxes($this->conn, $this->_mod_mailbox(''), '*');
-    $a_subscribed = iil_C_ListSubscribed($this->conn, $this->_mod_mailbox(''), '*');
+    $a_folders = iil_C_ListMailboxes($this->conn, $this->mod_mailbox(''), '*');
+    $a_subscribed = iil_C_ListSubscribed($this->conn, $this->mod_mailbox(''), '*');
     
     // create default folders if they do not exist
     foreach ($this->default_folders as $folder)
       {
-      $abs_name = $this->_mod_mailbox($folder);
+      $abs_name = $this->mod_mailbox($folder);
       if (!in_array_nocase($abs_name, $a_folders))
         $this->create_mailbox($folder, TRUE);
       else if (!in_array_nocase($abs_name, $a_subscribed))
@@ -2051,8 +2060,7 @@ class rcube_imap
     // read cache
     if (!isset($this->cache[$key]) && $this->caching_enabled)
       {
-      $cache_data = $this->_read_cache_record('IMAP.'.$key);
-      $this->cache[$key] = strlen($cache_data) ? unserialize($cache_data) : FALSE;
+      return $this->_read_cache_record($key);
       }
     
     return $this->cache[$key];
@@ -2078,7 +2086,7 @@ class rcube_imap
       foreach ($this->cache as $key => $data)
         {
         if ($this->cache_changes[$key])
-          $this->_write_cache_record('IMAP.'.$key, serialize($data));
+          $this->_write_cache_record($key, serialize($data));
         }
       }    
     }
@@ -2094,7 +2102,7 @@ class rcube_imap
     if ($key===NULL)
       {
       foreach ($this->cache as $key => $data)
-        $this->_clear_cache_record('IMAP.'.$key);
+        $this->_clear_cache_record($key);
 
       $this->cache = array();
       $this->cache_changed = FALSE;
@@ -2102,7 +2110,7 @@ class rcube_imap
       }
     else
       {
-      $this->_clear_cache_record('IMAP.'.$key);
+      $this->_clear_cache_record($key);
       $this->cache_changes[$key] = FALSE;
       unset($this->cache[$key]);
       }
@@ -2111,35 +2119,33 @@ class rcube_imap
   /**
    * @access private
    */
-  function _read_cache_record($key)
+  private function _read_cache_record($key)
     {
-    $cache_data = FALSE;
-    
     if ($this->db)
       {
       // get cached data from DB
       $sql_result = $this->db->query(
-        "SELECT cache_id, data
+        "SELECT cache_id, data, cache_key
          FROM ".get_table_name('cache')."
          WHERE  user_id=?
-         AND    cache_key=?",
-        $_SESSION['user_id'],
-        $key);
+        AND cache_key LIKE 'IMAP.%'",
+        $_SESSION['user_id']);
 
-      if ($sql_arr = $this->db->fetch_assoc($sql_result))
+      while ($sql_arr = $this->db->fetch_assoc($sql_result))
         {
-        $cache_data = $sql_arr['data'];
-        $this->cache_keys[$key] = $sql_arr['cache_id'];
+       $sql_key = preg_replace('/^IMAP\./', '', $sql_arr['cache_key']);
+        $this->cache_keys[$sql_key] = $sql_arr['cache_id'];
+       $this->cache[$sql_key] = $sql_arr['data'] ? unserialize($sql_arr['data']) : FALSE;
         }
       }
 
-    return $cache_data;
+    return $this->cache[$key];
     }
 
   /**
    * @access private
    */
-  function _write_cache_record($key, $data)
+  private function _write_cache_record($key, $data)
     {
     if (!$this->db)
       return FALSE;
@@ -2153,7 +2159,7 @@ class rcube_imap
          WHERE  user_id=?
          AND    cache_key=?",
         $_SESSION['user_id'],
-        $key);
+        'IMAP.'.$key);
                                      
       if ($sql_arr = $this->db->fetch_assoc($sql_result))
         $this->cache_keys[$key] = $sql_arr['cache_id'];
@@ -2171,7 +2177,7 @@ class rcube_imap
          AND    cache_key=?",
         $data,
         $_SESSION['user_id'],
-        $key);
+        'IMAP.'.$key);
       }
     // add new cache record
     else
@@ -2181,7 +2187,7 @@ class rcube_imap
          (created, user_id, cache_key, data)
          VALUES (".$this->db->now().", ?, ?, ?)",
         $_SESSION['user_id'],
-        $key,
+        'IMAP.'.$key,
         $data);
       }
     }
@@ -2189,14 +2195,14 @@ class rcube_imap
   /**
    * @access private
    */
-  function _clear_cache_record($key)
+  private function _clear_cache_record($key)
     {
     $this->db->query(
       "DELETE FROM ".get_table_name('cache')."
        WHERE  user_id=?
        AND    cache_key=?",
       $_SESSION['user_id'],
-      $key);
+      'IMAP.'.$key);
     }
 
 
@@ -2213,8 +2219,8 @@ class rcube_imap
    * @param string Internal cache key
    * @return int -3 = off, -2 = incomplete, -1 = dirty
    */
-  function check_cache_status($mailbox, $cache_key)
-    {
+  private function check_cache_status($mailbox, $cache_key)
+  {
     if (!$this->caching_enabled)
       return -3;
 
@@ -2224,30 +2230,42 @@ class rcube_imap
 
     // console("Cache check: $msg_count !== ".count($cache_index));
 
-    if ($cache_count==$msg_count)
-      {
-      // get highest index
-      $header = iil_C_FetchHeader($this->conn, $mailbox, "$msg_count");
-      $cache_uid = array_pop($cache_index);
-      
-      // uids of highest message matches -> cache seems OK
-      if ($cache_uid == $header->uid)
-        return 1;
+    if ($cache_count==$msg_count) {
+      if ($this->skip_deleted) {
+       $h_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", 'UID', $this->skip_deleted);
+
+       if (sizeof($h_index) == $cache_count) {
+         $cache_index = array_flip($cache_index);
+         foreach ($h_index as $idx => $uid)
+            unset($cache_index[$uid]);
 
+         if (empty($cache_index))
+           return 1;
+       }
+       return -2;
+      } else {
+        // get highest index
+        $header = iil_C_FetchHeader($this->conn, $mailbox, "$msg_count");
+        $cache_uid = array_pop($cache_index);
+      
+        // uids of highest message matches -> cache seems OK
+        if ($cache_uid == $header->uid)
+          return 1;
+      }
       // cache is dirty
       return -1;
-      }
+    }
     // if cache count differs less than 10% report as dirty
     else if (abs($msg_count - $cache_count) < $msg_count/10)
       return -1;
     else
       return -2;
-    }
+  }
 
   /**
    * @access private
    */
-  function get_message_cache($key, $from, $to, $sort_field, $sort_order)
+  private function get_message_cache($key, $from, $to, $sort_field, $sort_order)
     {
     $cache_key = "$key:$from:$to:$sort_field:$sort_order";
     $db_header_fields = array('idx', 'uid', 'subject', 'from', 'to', 'cc', 'date', 'size');
@@ -2263,8 +2281,7 @@ class rcube_imap
          FROM ".get_table_name('messages')."
          WHERE  user_id=?
          AND    cache_key=?
-         ORDER BY ".$this->db->quoteIdentifier($sort_field)." ".
-         strtoupper($sort_order),
+         ORDER BY ".$this->db->quoteIdentifier($sort_field)." ".strtoupper($sort_order),
         $from,
         $to-$from,
         $_SESSION['user_id'],
@@ -2273,30 +2290,28 @@ class rcube_imap
       while ($sql_arr = $this->db->fetch_assoc($sql_result))
         {
         $uid = $sql_arr['uid'];
-        $this->cache[$cache_key][$uid] = unserialize($sql_arr['headers']);
-        
+        $this->cache[$cache_key][$uid] =  $this->db->decode(unserialize($sql_arr['headers']));
+
         // featch headers if unserialize failed
         if (empty($this->cache[$cache_key][$uid]))
-          $this->cache[$cache_key][$uid] = iil_C_FetchHeader($this->conn, preg_replace('/.msg$/', '', $key), $uid, true);
+          $this->cache[$cache_key][$uid] = iil_C_FetchHeader($this->conn, preg_replace('/.msg$/', '', $key), $uid, true, $this->fetch_add_headers);
         }
       }
-      
+
     return $this->cache[$cache_key];
     }
 
   /**
    * @access private
    */
-  function &get_cached_message($key, $uid, $struct=false)
+  private function &get_cached_message($key, $uid)
     {
     $internal_key = '__single_msg';
     
-    if ($this->caching_enabled && (!isset($this->cache[$internal_key][$uid]) ||
-        ($struct && empty($this->cache[$internal_key][$uid]->structure))))
+    if ($this->caching_enabled && !isset($this->cache[$internal_key][$uid]))
       {
-      $sql_select = "idx, uid, headers" . ($struct ? ", structure" : '');
       $sql_result = $this->db->query(
-        "SELECT $sql_select
+        "SELECT idx, headers, structure
          FROM ".get_table_name('messages')."
          WHERE  user_id=?
          AND    cache_key=?
@@ -2307,9 +2322,10 @@ class rcube_imap
 
       if ($sql_arr = $this->db->fetch_assoc($sql_result))
         {
-        $this->cache[$internal_key][$uid] = unserialize($sql_arr['headers']);
+       $this->uid_id_map[preg_replace('/\.msg$/', '', $key)][$uid] = $sql_arr['idx'];
+        $this->cache[$internal_key][$uid] = $this->db->decode(unserialize($sql_arr['headers']));
         if (is_object($this->cache[$internal_key][$uid]) && !empty($sql_arr['structure']))
-          $this->cache[$internal_key][$uid]->structure = unserialize($sql_arr['structure']);
+          $this->cache[$internal_key][$uid]->structure = $this->db->decode(unserialize($sql_arr['structure']));
         }
       }
 
@@ -2319,7 +2335,7 @@ class rcube_imap
   /**
    * @access private
    */  
-  function get_message_cache_index($key, $force=FALSE, $sort_field='idx', $sort_order='ASC')
+  private function get_message_cache_index($key, $force=FALSE, $sort_field='idx', $sort_order='ASC')
     {
     static $sa_message_index = array();
     
@@ -2349,21 +2365,22 @@ class rcube_imap
   /**
    * @access private
    */
-  function add_message_cache($key, $index, $headers, $struct=null)
+  private function add_message_cache($key, $index, $headers, $struct=null, $force=false)
     {
     if (empty($key) || !is_object($headers) || empty($headers->uid))
         return;
 
     // add to internal (fast) cache
-    $this->cache['__single_msg'][$headers->uid] = $headers;
+    $this->cache['__single_msg'][$headers->uid] = clone $headers;
     $this->cache['__single_msg'][$headers->uid]->structure = $struct;
-    
+
     // no further caching
     if (!$this->caching_enabled)
       return;
     
     // check for an existing record (probly headers are cached but structure not)
-    $sql_result = $this->db->query(
+    if (!$force) {
+      $sql_result = $this->db->query(
         "SELECT message_id
          FROM ".get_table_name('messages')."
          WHERE  user_id=?
@@ -2373,18 +2390,21 @@ class rcube_imap
         $_SESSION['user_id'],
         $key,
         $headers->uid);
+      if ($sql_arr = $this->db->fetch_assoc($sql_result))
+        $message_id = $sql_arr['message_id'];
+      }
 
     // update cache record
-    if ($sql_arr = $this->db->fetch_assoc($sql_result))
+    if ($message_id)
       {
       $this->db->query(
         "UPDATE ".get_table_name('messages')."
          SET   idx=?, headers=?, structure=?
          WHERE message_id=?",
         $index,
-        serialize($headers),
-        is_object($struct) ? serialize($struct) : NULL,
-        $sql_arr['message_id']
+        serialize($this->db->encode(clone $headers)),
+        is_object($struct) ? serialize($this->db->encode(clone $struct)) : NULL,
+        $message_id
         );
       }
     else  // insert new record
@@ -2397,13 +2417,13 @@ class rcube_imap
         $key,
         $index,
         $headers->uid,
-        (string)substr($this->decode_header($headers->subject, TRUE), 0, 128),
-        (string)substr($this->decode_header($headers->from, TRUE), 0, 128),
-        (string)substr($this->decode_header($headers->to, TRUE), 0, 128),
-        (string)substr($this->decode_header($headers->cc, TRUE), 0, 128),
+        (string)mb_substr($this->db->encode($this->decode_header($headers->subject, TRUE)), 0, 128),
+        (string)mb_substr($this->db->encode($this->decode_header($headers->from, TRUE)), 0, 128),
+        (string)mb_substr($this->db->encode($this->decode_header($headers->to, TRUE)), 0, 128),
+        (string)mb_substr($this->db->encode($this->decode_header($headers->cc, TRUE)), 0, 128),
         (int)$headers->size,
-        serialize($headers),
-        is_object($struct) ? serialize($struct) : NULL
+        serialize($this->db->encode(clone $headers)),
+        is_object($struct) ? serialize($this->db->encode(clone $struct)) : NULL
         );
       }
     }
@@ -2411,25 +2431,24 @@ class rcube_imap
   /**
    * @access private
    */
-  function remove_message_cache($key, $index)
+  private function remove_message_cache($key, $uids)
     {
     if (!$this->caching_enabled)
       return;
     
     $this->db->query(
       "DELETE FROM ".get_table_name('messages')."
-       WHERE  user_id=?
-       AND    cache_key=?
-       AND    idx=?",
+      WHERE  user_id=?
+      AND    cache_key=?
+      AND    uid IN (".$this->db->array2list($uids, 'integer').")",
       $_SESSION['user_id'],
-      $key,
-      $index);
+      $key);
     }
 
   /**
    * @access private
    */
-  function clear_message_cache($key, $start_index=1)
+  private function clear_message_cache($key, $start_index=1)
     {
     if (!$this->caching_enabled)
       return;
@@ -2444,7 +2463,28 @@ class rcube_imap
       $start_index);
     }
 
+  /**
+   * @access private
+   */
+  private function get_message_cache_index_min($key, $uids=NULL)
+    {
+    if (!$this->caching_enabled)
+      return;
+    
+    $sql_result = $this->db->query(
+      "SELECT MIN(idx) AS minidx
+      FROM ".get_table_name('messages')."
+      WHERE  user_id=?
+      AND    cache_key=?"
+      .(!empty($uids) ? " AND uid IN (".$this->db->array2list($uids, 'integer').")" : ''),
+      $_SESSION['user_id'],
+      $key);
 
+    if ($sql_arr = $this->db->fetch_assoc($sql_result))
+      return $sql_arr['minidx'];
+    else
+      return 0;  
+    }
 
 
   /* --------------------------------
@@ -2608,7 +2648,7 @@ class rcube_imap
    *
    * @access private
    */
-  function _decode_mime_string_part($str)
+  private function _decode_mime_string_part($str)
     {
     $a = explode('?', $str);
     $count = count($a);
@@ -2640,16 +2680,11 @@ class rcube_imap
    * @param string Input string
    * @param string Part encoding
    * @return string Decoded string
-   * @access private
    */
   function mime_decode($input, $encoding='7bit')
     {
     switch (strtolower($encoding))
       {
-      case '7bit':
-        return $input;
-        break;
-      
       case 'quoted-printable':
         return quoted_printable_decode($input);
         break;
@@ -2657,7 +2692,15 @@ class rcube_imap
       case 'base64':
         return base64_decode($input);
         break;
-      
+
+      case 'x-uuencode':
+      case 'x-uue':
+      case 'uue':
+      case 'uuencode':
+        return convert_uudecode($input);
+        break;
+                                                     
+      case '7bit':
       default:
         return $input;
       }
@@ -2665,7 +2708,7 @@ class rcube_imap
 
 
   /**
-   * Convert body charset to UTF-8 according to the ctype_parameters
+   * Convert body charset to RCMAIL_CHARSET according to the ctype_parameters
    *
    * @param string Part body to decode
    * @param string Charset to convert from
@@ -2690,7 +2733,7 @@ class rcube_imap
    */
   function get_id($uid, $mbox_name=NULL) 
     {
-      $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+      $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
       return $this->_uid2id($uid, $mailbox);
     }
 
@@ -2704,21 +2747,19 @@ class rcube_imap
    */
   function get_uid($id,$mbox_name=NULL)
     {
-      $mailbox = $mbox_name ? $this->_mod_mailbox($mbox_name) : $this->mailbox;
+      $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
       return $this->_id2uid($id, $mailbox);
     }
 
 
-
-  /* --------------------------------
-   *         private methods
-   * --------------------------------*/
-
-
   /**
-   * @access private
+   * Modify folder name for input/output according to root dir and namespace
+   *
+   * @param string  Folder name
+   * @param string  Mode
+   * @return string Folder name
    */
-  function _mod_mailbox($mbox_name, $mode='in')
+  function mod_mailbox($mbox_name, $mode='in')
     {
     if ((!empty($this->root_ns) && $this->root_ns == $mbox_name) || $mbox_name == 'INBOX')
       return $mbox_name;
@@ -2731,11 +2772,16 @@ class rcube_imap
     return $mbox_name;
     }
 
+
+  /* --------------------------------
+   *         private methods
+   * --------------------------------*/
+
   /**
    * Validate the given input and save to local properties
    * @access private
    */
-  function _set_sort_order($sort_field, $sort_order)
+  private function _set_sort_order($sort_field, $sort_order)
   {
     if ($sort_field != null)
       $this->sort_field = asciiwords($sort_field);
@@ -2747,7 +2793,7 @@ class rcube_imap
    * Sort mailboxes first by default folders and then in alphabethical order
    * @access private
    */
-  function _sort_mailbox_list($a_folders)
+  private function _sort_mailbox_list($a_folders)
     {
     $a_out = $a_defaults = $folders = array();
 
@@ -2762,7 +2808,7 @@ class rcube_imap
       if (($p = array_search(strtolower($folder), $this->default_folders_lc)) !== false && !$a_defaults[$p])
         $a_defaults[$p] = $folder;
       else
-        $folders[$folder] = rc_strtolower(rcube_charset_convert($folder, 'UTF-7'));
+        $folders[$folder] = mb_strtolower(rcube_charset_convert($folder, 'UTF7-IMAP'));
       }
 
     // sort folders and place defaults on the top
@@ -2788,7 +2834,7 @@ class rcube_imap
   /**
    * @access private
    */
-  function _rsort($folder, $delimiter, &$list, &$out)
+  private function _rsort($folder, $delimiter, &$list, &$out)
     {
       while (list($key, $name) = each($list)) {
        if (strpos($name, $folder.$delimiter) === 0) {
@@ -2805,7 +2851,7 @@ class rcube_imap
   /**
    * @access private
    */
-  function _uid2id($uid, $mbox_name=NULL)
+  private function _uid2id($uid, $mbox_name=NULL)
     {
     if (!$mbox_name)
       $mbox_name = $this->mailbox;
@@ -2819,7 +2865,7 @@ class rcube_imap
   /**
    * @access private
    */
-  function _id2uid($id, $mbox_name=NULL)
+  private function _id2uid($id, $mbox_name=NULL)
     {
     if (!$mbox_name)
       $mbox_name = $this->mailbox;
@@ -2841,26 +2887,23 @@ class rcube_imap
    * Subscribe/unsubscribe a list of mailboxes and update local cache
    * @access private
    */
-  function _change_subscription($a_mboxes, $mode)
+  private function _change_subscription($a_mboxes, $mode)
     {
     $updated = FALSE;
-    
+
     if (is_array($a_mboxes))
       foreach ($a_mboxes as $i => $mbox_name)
         {
-        $mailbox = $this->_mod_mailbox($mbox_name);
+        $mailbox = $this->mod_mailbox($mbox_name);
         $a_mboxes[$i] = $mailbox;
 
         if ($mode=='subscribe')
-          $result = iil_C_Subscribe($this->conn, $mailbox);
+          $updated = iil_C_Subscribe($this->conn, $mailbox);
         else if ($mode=='unsubscribe')
-          $result = iil_C_UnSubscribe($this->conn, $mailbox);
-
-        if ($result>=0)
-          $updated = TRUE;
+          $updated = iil_C_UnSubscribe($this->conn, $mailbox);
         }
-        
-    // get cached mailbox list    
+
+    // get cached mailbox list
     if ($updated)
       {
       $a_mailbox_cache = $this->get_cache('mailboxes');
@@ -2872,7 +2915,7 @@ class rcube_imap
         $a_mailbox_cache = array_merge($a_mailbox_cache, $a_mboxes);
       else if ($mode=='unsubscribe')
         $a_mailbox_cache = array_diff($a_mailbox_cache, $a_mboxes);
-        
+
       // write mailboxlist to cache
       $this->update_cache('mailboxes', $this->_sort_mailbox_list($a_mailbox_cache));
       }
@@ -2885,7 +2928,7 @@ class rcube_imap
    * Increde/decrese messagecount for a specific mailbox
    * @access private
    */
-  function _set_messagecount($mbox_name, $mode, $increment)
+  private function _set_messagecount($mbox_name, $mode, $increment)
     {
     $a_mailbox_cache = FALSE;
     $mailbox = $mbox_name ? $mbox_name : $this->mailbox;
@@ -2914,7 +2957,7 @@ class rcube_imap
    * Remove messagecount of a specific mailbox from cache
    * @access private
    */
-  function _clear_messagecount($mbox_name='')
+  private function _clear_messagecount($mbox_name='')
     {
     $a_mailbox_cache = FALSE;
     $mailbox = $mbox_name ? $mbox_name : $this->mailbox;
@@ -2933,7 +2976,7 @@ class rcube_imap
    * Split RFC822 header string into an associative array
    * @access private
    */
-  function _parse_headers($headers)
+  private function _parse_headers($headers)
     {
     $a_headers = array();
     $lines = explode("\n", $headers);
@@ -2956,7 +2999,7 @@ class rcube_imap
   /**
    * @access private
    */
-  function _parse_address_list($str, $decode=true)
+  private function _parse_address_list($str, $decode=true)
     {
     // remove any newlines and carriage returns before
     $a = rcube_explode_quoted_string('[,;]', preg_replace( "/[\r\n]/", " ", $str));
@@ -3009,6 +3052,13 @@ class rcube_message_part
   var $d_parameters = array();
   var $ctype_parameters = array();
 
+  function __clone()
+  {
+    if (isset($this->parts))
+      foreach ($this->parts as $idx => $part)
+        if (is_object($part))
+         $this->parts[$idx] = clone $part;
+  }                            
 }
 
 
@@ -3066,71 +3116,3 @@ class rcube_header_sorter
       return $posa - $posb;
    }
 }
-
-
-/**
- * Add quoted-printable encoding to a given string
- * 
- * @param string   String to encode
- * @param int      Add new line after this number of characters
- * @param boolean  True if spaces should be converted into =20
- * @return string Encoded string
- */
-function quoted_printable_encode($input, $line_max=76, $space_conv=false)
-  {
-  $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
-  $lines = preg_split("/(?:\r\n|\r|\n)/", $input);
-  $eol = "\r\n";
-  $escape = "=";
-  $output = "";
-
-  while( list(, $line) = each($lines))
-    {
-    //$line = rtrim($line); // remove trailing white space -> no =20\r\n necessary
-    $linlen = strlen($line);
-    $newline = "";
-    for($i = 0; $i < $linlen; $i++)
-      {
-      $c = substr( $line, $i, 1 );
-      $dec = ord( $c );
-      if ( ( $i == 0 ) && ( $dec == 46 ) ) // convert first point in the line into =2E
-        {
-        $c = "=2E";
-        }
-      if ( $dec == 32 )
-        {
-        if ( $i == ( $linlen - 1 ) ) // convert space at eol only
-          {
-          $c = "=20";
-          }
-        else if ( $space_conv )
-          {
-          $c = "=20";
-          }
-        }
-      else if ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) )  // always encode "\t", which is *not* required
-        {
-        $h2 = floor($dec/16);
-        $h1 = floor($dec%16);
-        $c = $escape.$hex["$h2"].$hex["$h1"];
-        }
-         
-      if ( (strlen($newline) + strlen($c)) >= $line_max )  // CRLF is not counted
-        {
-        $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
-        $newline = "";
-        // check if newline first character will be point or not
-        if ( $dec == 46 )
-          {
-          $c = "=2E";
-          }
-        }
-      $newline .= $c;
-      } // end of for
-    $output .= $newline.$eol;
-    } // end of while
-
-  return trim($output);
-  }
-
-
index 0bd3a2bad84b5eed3bb94c64ad1ea9ceba1f08e9..ea23dc20ba3866bcce133a72dfc18f4fc5aa30a2 100644 (file)
 class rcube_json_output
 {
     private $config;
-    private $charset = 'UTF-8';
+    private $charset = RCMAIL_CHARSET;
     private $env = array();
     private $texts = array();
     private $commands = array();
+    private $callbacks = array();
+    private $message = null;
 
     public $type = 'js';
     public $ajax_call = true;
@@ -66,7 +68,7 @@ class rcube_json_output
     public function set_pagetitle($title)
     {
         $name = $this->config->get('product_name');
-        $this->command('set_pagetitle', JQ(empty($name) ? $title : $name.' :: '.$title));
+        $this->command('set_pagetitle', empty($name) ? $title : $name.' :: '.$title);
     }
 
     /**
@@ -121,7 +123,12 @@ class rcube_json_output
      */
     public function command()
     {
-        $this->commands[] = func_get_args();
+        $cmd = func_get_args();
+        
+        if (strpos($cmd[0], 'plugin.') === 0)
+          $this->callbacks[] = $cmd;
+        else
+          $this->commands[] = $cmd;
     }
     
     
@@ -130,8 +137,11 @@ class rcube_json_output
      */
     public function add_label()
     {
-        $arg_list = func_get_args();
-        foreach ($arg_list as $i => $name) {
+        $args = func_get_args();
+        if (count($args) == 1 && is_array($args[0]))
+            $args = $args[0];
+        
+        foreach ($args as $name) {
             $this->texts[$name] = rcube_label($name);
         }
     }
@@ -143,15 +153,19 @@ class rcube_json_output
      * @param string Message to display
      * @param string Message type [notice|confirm|error]
      * @param array Key-value pairs to be replaced in localized text
+     * @param boolean Override last set message
      * @uses self::command()
      */
-    public function show_message($message, $type='notice', $vars=null)
+    public function show_message($message, $type='notice', $vars=null, $override=true)
     {
-        $this->command(
-            'display_message',
-            rcube_label(array('name' => $message, 'vars' => $vars)),
-            $type
-        );
+        if ($override || !$this->message) {
+            $this->message = $message;
+            $this->command(
+                'display_message',
+                rcube_label(array('name' => $message, 'vars' => $vars)),
+                $type
+            );
+        }
     }
     
     /**
@@ -196,26 +210,36 @@ class rcube_json_output
      * @return void
      * @deprecated
      */
-    public function remote_response($add='', $flush=false)
+    public function remote_response($add='')
     {
         static $s_header_sent = false;
 
         if (!$s_header_sent) {
             $s_header_sent = true;
             send_nocacheing_headers();
-            header('Content-Type: application/x-javascript; charset=' . $this->get_charset());
+            header('Content-Type: text/plain; charset=' . $this->get_charset());
             print '/** ajax response ['.date('d/M/Y h:i:s O')."] **/\n";
         }
 
         // unset default env vars
         unset($this->env['task'], $this->env['action'], $this->env['comm_path']);
 
-        // send response code
-        echo $this->get_js_commands() . $add;
+        $rcmail = rcmail::get_instance();
+        $response = array('action' => $rcmail->action, 'unlock' => (bool)$_REQUEST['_unlock']);
+        
+        if (!empty($this->env))
+          $response['env'] = $this->env;
+          
+        if (!empty($this->texts))
+          $response['texts'] = $this->texts;
 
-        // flush the output buffer
-        if ($flush)
-            flush();
+        // send function calls
+        $response['exec'] = $this->get_js_commands() . $add;
+        
+        if (!empty($this->callbacks))
+          $response['callbacks'] = $this->callbacks;
+
+        echo json_serialize($response);
     }
     
     
@@ -227,14 +251,7 @@ class rcube_json_output
     private function get_js_commands()
     {
         $out = '';
-       
-       if (sizeof($this->env))
-           $out .= 'this.set_env('.json_serialize($this->env).");\n";
         
-        foreach($this->texts as $name => $text) {
-            $out .= sprintf("this.add_label('%s', '%s');\n", $name, JQ($text));
-        }
-
         foreach ($this->commands as $i => $args) {
             $method = array_shift($args);
             foreach ($args as $i => $arg) {
index f1bbab6332afcf0eb00579fe3a0273c39a9c0037..e071ed03384844e71ab8cc4f08e897097669319f 100644 (file)
@@ -14,7 +14,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_ldap.php 2237 2009-01-17 01:55:39Z till $
+ $Id: rcube_ldap.php 2894 2009-08-29 20:56:00Z alec $
 
 */
 
@@ -24,7 +24,7 @@
  *
  * @package Addressbook
  */
-class rcube_ldap
+class rcube_ldap extends rcube_addressbook
 {
   var $conn;
   var $prop = array();
@@ -52,12 +52,15 @@ class rcube_ldap
   function __construct($p)
   {
     $this->prop = $p;
-    
+
     foreach ($p as $prop => $value)
       if (preg_match('/^(.+)_field$/', $prop, $matches))
-        $this->fieldmap[$matches[1]] = $value;
+        $this->fieldmap[$matches[1]] = $this->_attr_name(strtolower($value));
+
+    foreach ($this->prop['required_fields'] as $key => $val)
+      $this->prop['required_fields'][$key] = $this->_attr_name(strtolower($val));
 
-    $this->sort_col = $p["sort"];
+    $this->sort_col = $p['sort'];
 
     $this->connect();
   }
@@ -102,10 +105,10 @@ class rcube_ldap
       $this->ready = true;
 
       // User specific access, generate the proper values to use.
-      if ($this->prop["user_specific"]) {
+      if ($this->prop['user_specific']) {
         // No password set, use the session password
         if (empty($this->prop['bind_pass'])) {
-          $this->prop['bind_pass'] = $RCMAIL->decrypt_passwd($_SESSION["password"]);
+          $this->prop['bind_pass'] = $RCMAIL->decrypt($_SESSION['password']);
         }
 
         // Get the pieces needed for variable replacement.
@@ -166,7 +169,7 @@ class rcube_ldap
   {
     if ($this->conn)
     {
-      @ldap_unbind($this->conn);
+      ldap_unbind($this->conn);
       $this->conn = null;
     }
   }
@@ -244,19 +247,19 @@ class rcube_ldap
       $filter = $this->prop['filter'];
       $this->set_search_set($filter);
     }
-    
+
     // exec LDAP search if no result resource is stored
     if ($this->conn && !$this->ldap_result)
       $this->_exec_search();
     
     // count contacts for this user
     $this->result = $this->count();
-    
+
     // we have a search result resource
     if ($this->ldap_result && $this->result->count > 0)
     {
-      if ($this->sort_col && $this->prop['scope'] !== "base")
-        @ldap_sort($this->conn, $this->ldap_result, $this->sort_col);
+      if ($this->sort_col && $this->prop['scope'] !== 'base')
+        ldap_sort($this->conn, $this->ldap_result, $this->sort_col);
 
       $start_row = $subset < 0 ? $this->result->first + $this->page_size + $subset : $this->result->first;
       $last_row = $this->result->first + $this->page_size;
@@ -381,13 +384,15 @@ class rcube_ldap
     $res = null;
     if ($this->conn && $dn)
     {
-      $this->ldap_result = @ldap_read($this->conn, base64_decode($dn), "(objectclass=*)", array_values($this->fieldmap));
+      $this->ldap_result = ldap_read($this->conn, base64_decode($dn), '(objectclass=*)', array_values($this->fieldmap));
       $entry = @ldap_first_entry($this->conn, $this->ldap_result);
-      
+
       if ($entry && ($rec = ldap_get_attributes($this->conn, $entry)))
       {
+        $rec = array_change_key_case($rec, CASE_LOWER);
+
         // Add in the dn for the entry.
-        $rec["dn"] = base64_decode($dn);
+        $rec['dn'] = base64_decode($dn);
         $res = $this->_ldap2result($rec);
         $this->result = new rcube_result_set(1);
         $this->result->add($res);
@@ -408,11 +413,10 @@ class rcube_ldap
   {
     // Map out the column names to their LDAP ones to build the new entry.
     $newentry = array();
-    $newentry["objectClass"] = $this->prop["LDAP_Object_Classes"];
+    $newentry['objectClass'] = $this->prop['LDAP_Object_Classes'];
     foreach ($save_cols as $col => $val) {
-      $fld = "";
       $fld = $this->_map_field($col);
-      if ($fld != "") {
+      if ($fld && $val) {
         // The field does exist, add it to the entry.
         $newentry[$fld] = $val;
       } // end if
@@ -421,15 +425,15 @@ class rcube_ldap
     // Verify that the required fields are set.
     // We know that the email address is required as a default of rcube, so
     // we will default its value into any unfilled required fields.
-    foreach ($this->prop["required_fields"] as $fld) {
+    foreach ($this->prop['required_fields'] as $fld) {
       if (!isset($newentry[$fld])) {
-        $newentry[$fld] = $newentry[$this->_map_field("email")];
+        $newentry[$fld] = $newentry[$this->_map_field('email')];
       } // end if
     } // end foreach
 
     // Build the new entries DN.
-    $dn = $this->prop["LDAP_rdn"]."=".$newentry[$this->prop["LDAP_rdn"]].",".$this->prop['base_dn'];
-    $res = @ldap_add($this->conn, $dn, $newentry);
+    $dn = $this->prop['LDAP_rdn'].'='.$newentry[$this->prop['LDAP_rdn']].','.$this->prop['base_dn'];
+    $res = ldap_add($this->conn, $dn, $newentry);
     if ($res === FALSE) {
       return false;
     } // end if
@@ -455,9 +459,8 @@ class rcube_ldap
     $replacedata = array();
     $deletedata = array();
     foreach ($save_cols as $col => $val) {
-      $fld = "";
       $fld = $this->_map_field($col);
-      if ($fld != "") {
+      if ($fld) {
         // The field does exist compare it to the ldap record.
         if ($record[$col] != $val) {
           // Changed, but find out how.
@@ -465,9 +468,9 @@ class rcube_ldap
             // Field was not set prior, need to add it.
             $newdata[$fld] = $val;
           } // end if
-          elseif ($val == "") {
+          elseif ($val == '') {
             // Field supplied is empty, verify that it is not required.
-            if (!in_array($fld, $this->prop["required_fields"])) {
+            if (!in_array($fld, $this->prop['required_fields'])) {
               // It is not, safe to clear.
               $deletedata[$fld] = $record[$col];
             } // end if
@@ -480,32 +483,43 @@ class rcube_ldap
       } // end if
     } // end foreach
 
-    // Update the entry as required.
     $dn = base64_decode($id);
+
+    // Update the entry as required.
     if (!empty($deletedata)) {
       // Delete the fields.
-      $res = @ldap_mod_del($this->conn, $dn, $deletedata);
-      if ($res === FALSE) {
+      if (!ldap_mod_del($this->conn, $dn, $deletedata))
         return false;
-      } // end if
     } // end if
 
     if (!empty($replacedata)) {
+      // Handle RDN change
+      if ($replacedata[$this->prop['LDAP_rdn']]) {
+        $newdn = $this->prop['LDAP_rdn'].'='.$replacedata[$this->prop['LDAP_rdn']].','.$this->prop['base_dn']; 
+        if ($dn != $newdn) {
+          $newrdn = $this->prop['LDAP_rdn'].'='.$replacedata[$this->prop['LDAP_rdn']];
+          unset($replacedata[$this->prop['LDAP_rdn']]);
+        }
+      }
       // Replace the fields.
-      $res = @ldap_mod_replace($this->conn, $dn, $replacedata);
-      if ($res === FALSE) {
-        return false;
+      if (!empty($replacedata)) {
+        if (!ldap_mod_replace($this->conn, $dn, $replacedata))
+          return false;
       } // end if
     } // end if
 
     if (!empty($newdata)) {
       // Add the fields.
-      $res = @ldap_mod_add($this->conn, $dn, $newdata);
-      if ($res === FALSE) {
+      if (!ldap_mod_add($this->conn, $dn, $newdata))
         return false;
-      } // end if
     } // end if
 
+    // Handle RDN change
+    if (!empty($newrdn)) {
+      if (@ldap_rename($this->conn, $dn, $newrdn, NULL, TRUE))
+        return base64_encode($newdn);
+    }
+
     return true;
   }
   
@@ -520,13 +534,13 @@ class rcube_ldap
   {
     if (!is_array($ids)) {
       // Not an array, break apart the encoded DNs.
-      $dns = explode(",", $ids);
+      $dns = explode(',', $ids);
     } // end if
 
     foreach ($dns as $id) {
       $dn = base64_decode($id);
       // Delete the record.
-      $res = @ldap_delete($this->conn, $dn);
+      $res = ldap_delete($this->conn, $dn);
       if ($res === FALSE) {
         return false;
       } // end if
@@ -541,12 +555,13 @@ class rcube_ldap
    *
    * @access private
    */
-  function _exec_search()
+  private function _exec_search()
   {
-    if ($this->ready && $this->filter)
+    if ($this->ready)
     {
+      $filter = $this->filter ? $this->filter : '(objectclass=*)';
       $function = $this->prop['scope'] == 'sub' ? 'ldap_search' : ($this->prop['scope'] == 'base' ? 'ldap_read' : 'ldap_list');
-      $this->ldap_result = $function($this->conn, $this->prop['base_dn'], $this->filter, array_values($this->fieldmap), 0, 0);
+      $this->ldap_result = $function($this->conn, $this->prop['base_dn'], $filter, array_values($this->fieldmap), 0, 0);
       return true;
     }
     else
@@ -557,8 +572,10 @@ class rcube_ldap
   /**
    * @access private
    */
-  function _ldap2result($rec)
+  private function _ldap2result($rec)
   {
+    global $RCMAIL;
+
     $out = array();
     
     if ($rec['dn'])
@@ -566,8 +583,12 @@ class rcube_ldap
     
     foreach ($this->fieldmap as $rf => $lf)
     {
-      if ($rec[$lf]['count'])
-        $out[$rf] = $rec[$lf][0];
+      if ($rec[$lf]['count']) {
+        if ($rf == 'email' && !strpos($rec[$lf][0], '@'))
+          $out[$rf] = sprintf('%s@%s', $rec[$lf][0] , $RCMAIL->config->mail_domain($_SESSION['imap_host']));
+        else
+          $out[$rf] = $rec[$lf][0];
+      }
     }
     
     return $out;
@@ -577,12 +598,29 @@ class rcube_ldap
   /**
    * @access private
    */
-  function _map_field($field)
+  private function _map_field($field)
   {
     return $this->fieldmap[$field];
   }
   
   
+  /**
+   * @access private
+   */
+  private function _attr_name($name)
+  {
+    // list of known attribute aliases
+    $aliases = array(
+      'gn' => 'givenname',
+      'rfc822mailbox' => 'mail',
+      'userid' => 'uid',
+      'emailaddress' => 'email',
+      'pkcs9email' => 'email',
+    );
+    return isset($aliases[$name]) ? $aliases[$name] : $name;
+  }
+
+
   /**
    * @static
    */
@@ -591,7 +629,6 @@ class rcube_ldap
     return strtr($str, array('*'=>'\2a', '('=>'\28', ')'=>'\29', '\\'=>'\5c'));
   }
 
-
 }
 
-
+?>
index f59354fea3e4c54d0112b3cb83ed06b7a07ed753..ab93d3a708029cfecc2f8314b7eae451fb2fc7b4 100644 (file)
@@ -180,7 +180,7 @@ class rcube_mail_mime extends Mail_mime
         }
       }
 
-      $input[$hdr_name] = $hdr_value;
+      $input[$hdr_name] = wordwrap($hdr_value, 990, "\n", true);  // hard limit header length
     }
 
     return $input;
index 36b5cc7b547664c06959328fa1f8def9d726b5b5..51f8be3ce72d0a1e891b9278d056bceb468a9db4 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Lukas Kahwe Smith <smith@pooteeweet.org>                      |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_mdb2.php 2237 2009-01-17 01:55:39Z till $
+ $Id: rcube_mdb2.php 2834 2009-08-04 08:22:41Z alec $
 
 */
 
@@ -106,7 +106,7 @@ class rcube_mdb2
       if (!filesize($dsn_array['database']) && !empty($this->sqlite_initials))
         $this->_sqlite_create_database($dbh, $this->sqlite_initials);
       }
-    else
+    else if ($this->db_provider!='mssql')
       $dbh->setCharset('utf8');
 
     return $dbh;
@@ -177,6 +177,17 @@ class rcube_mdb2
     }
     
 
+  /**
+   * Connection state checker
+   *
+   * @param  boolean  True if in connected state
+   */
+  function is_connected()
+    {
+    return PEAR::isError($this->db_handle) ? false : true;
+    }
+
+
   /**
    * Execute a SQL query
    *
@@ -187,6 +198,9 @@ class rcube_mdb2
    */
   function query()
     {
+    if (!$this->is_connected())
+      return NULL;
+    
     $params = func_get_args();
     $query = array_shift($params);
 
@@ -228,7 +242,7 @@ class rcube_mdb2
   function _query($query, $offset, $numrows, $params)
     {
     // Read or write ?
-    if (strtolower(trim(substr($query,0,6)))=='select')
+    if (strtolower(substr(trim($query),0,6))=='select')
       $mode='r';
     else
       $mode='w';
@@ -307,16 +321,22 @@ class rcube_mdb2
    * Get last inserted record ID
    * For Postgres databases, a sequence name is required
    *
-   * @param  string  Sequence name for increment
+   * @param  string  Table name (to find the incremented sequence)
    * @return mixed   ID or FALSE on failure
    * @access public
    */
-  function insert_id($sequence = '')
+  function insert_id($table = '')
     {
     if (!$this->db_handle || $this->db_mode=='r')
       return FALSE;
 
-    return $this->db_handle->lastInsertID($sequence);
+    // find sequence name
+    if ($table && $this->db_provider == 'pgsql')
+      $table = get_sequence_name($table);
+
+    $id = $this->db_handle->lastInsertID($table);
+    
+    return $this->db_handle->isError($id) ? null : $id;
     }
 
 
@@ -360,7 +380,7 @@ class rcube_mdb2
    */
   function _fetch_row($result, $mode)
     {
-    if ($result === FALSE || PEAR::isError($result))
+    if ($result === FALSE || PEAR::isError($result) || !$this->is_connected())
       return FALSE;
 
     return $result->fetchRow($mode);
@@ -455,6 +475,26 @@ class rcube_mdb2
     }
 
 
+  /**
+   * Return list of elements for use with SQL's IN clause
+   *
+   * @param  string Input array
+   * @return string Elements list string
+   * @access public
+   */
+  function array2list($arr, $type=null)
+    {
+    if (!is_array($arr))
+      return $this->quote($arr, $type);
+    
+    $res = array();
+    foreach ($arr as $item)
+      $res[] = $this->quote($item, $type);
+
+    return implode(',', $res);
+    }
+
+
   /**
    * Return SQL statement to convert a field value into a unix timestamp
    *
@@ -471,7 +511,7 @@ class rcube_mdb2
         break;
 
       case 'mssql':
-        return "datediff(s, '1970-01-01 00:00:00', $field)";
+       return "DATEDIFF(second, '19700101', $field) + DATEDIFF(second, GETDATE(), GETUTCDATE())";
 
       default:
         return "UNIX_TIMESTAMP($field)";
@@ -522,6 +562,54 @@ class rcube_mdb2
     }
 
 
+  /**
+   * Encodes non-UTF-8 characters in string/array/object (recursive)
+   *
+   * @param  mixed  Data to fix
+   * @return mixed  Properly UTF-8 encoded data
+   * @access public
+   */
+  function encode($input)
+    {
+    if (is_object($input)) {
+      foreach (get_object_vars($input) as $idx => $value)
+        $input->$idx = $this->encode($value);
+      return $input;
+      }
+    else if (is_array($input)) {
+      foreach ($input as $idx => $value)
+        $input[$idx] = $this->encode($value);
+      return $input;   
+      }
+
+    return utf8_encode($input);
+    }
+
+
+  /**
+   * Decodes encoded UTF-8 string/object/array (recursive)
+   *
+   * @param  mixed  Input data
+   * @return mixed  Decoded data
+   * @access public
+   */
+  function decode($input)
+    {
+    if (is_object($input)) {
+      foreach (get_object_vars($input) as $idx => $value)
+        $input->$idx = $this->decode($value);
+      return $input;
+      }
+    else if (is_array($input)) {
+      foreach ($input as $idx => $value)
+        $input[$idx] = $this->decode($value);
+      return $input;   
+      }
+
+    return utf8_decode($input);
+    }
+
+
   /**
    * Adds a query result and returns a handle ID
    *
@@ -585,7 +673,9 @@ class rcube_mdb2
     $data = file_get_contents($file_name);
 
     if (strlen($data))
-      sqlite_exec($dbh->connection, $data);
+      if (!sqlite_exec($dbh->connection, $data, $error) || MDB2::isError($dbh)) 
+        raise_error(array('code' => 500, 'type' => 'db',
+           'line' => __LINE__, 'file' => __FILE__, 'message' => $error), TRUE, FALSE); 
     }
 
 
@@ -617,8 +707,6 @@ function mdb2_debug_handler(&$db, $scope, $message, $context = array())
   {
     $debug_output = $scope . '('.$db->db_index.'): ';
     $debug_output .= $message . $db->getOption('log_line_break');
-    write_log('sqllog', $debug_output);
+    write_log('sql', $debug_output);
   }
 }
-
-
index ec3be4b00a889fa8e3e6996e67b334f47e8b8cf9..7c2457e5579b6f6932b833bd7ae753b75e77e1c1 100644 (file)
@@ -84,6 +84,9 @@ class rcube_message
     else {
       $this->body = $this->imap->get_body($uid);
     }
+    
+    // notify plugins and let them analyze this structured message object
+    $this->app->plugins->exec_hook('message_load', array('object' => $this));
   }
   
   
@@ -320,8 +323,16 @@ class rcube_message
       $p->ctype_primary = 'text';
       $p->ctype_secondary = 'plain';
       $p->body = rcube_label('encryptedmessage');
+      $p->size = strlen($p->body);
       
-      $this->parts[] = $p;
+      // maybe some plugins are able to decode this encrypted message part
+      $data = $this->app->plugins->exec_hook('message_part_encrypted', array('object' => $this, 'struct' => $structure, 'part' => $p));
+      if (is_array($data['parts'])) {
+        $this->parts = array_merge($this->parts, $data['parts']);
+      }
+      else if ($data['part']) {
+        $this->parts[] = $p;
+      }
     }
     // message contains multiple parts
     else if (is_array($structure->parts) && !empty($structure->parts)) {
@@ -338,7 +349,7 @@ class rcube_message
         // part text/[plain|html] OR message/delivery-status
         else if (($primary_type == 'text' && ($secondary_type == 'plain' || $secondary_type == 'html') && $mail_part->disposition != 'attachment') ||
                  ($primary_type == 'message' && ($secondary_type == 'delivery-status' || $secondary_type == 'disposition-notification'))) {
-          
+
           // add text part if we're not in alternative mode or if it matches the prefs
           if (!$this->parse_alternative ||
               ($secondary_type == 'html' && $this->opt['prefer_html']) ||
@@ -363,7 +374,7 @@ class rcube_message
         else if ($primary_type == 'protocol')
           continue;
           
-        // part is Microsoft outlook TNEF (winmail.dat)
+        // part is Microsoft Outlook TNEF (winmail.dat)
         else if ($primary_type == 'application' && $secondary_type == 'ms-tnef') {
           foreach ((array)$this->imap->tnef_decode($mail_part, $structure->headers['uid']) as $tnef_part) {
             $this->mime_parts[$tnef_part->mime_id] = $tnef_part;
@@ -371,26 +382,27 @@ class rcube_message
           }
         }
 
-        // part is file/attachment
-        else if ($mail_part->disposition == 'attachment' || $mail_part->disposition == 'inline' ||
+        // part is file/attachment
+        else if (preg_match('/^(inline|attach)/', $mail_part->disposition) ||
                  $mail_part->headers['content-id'] || (empty($mail_part->disposition) && $mail_part->filename)) {
+
           // skip apple resource forks
           if ($message_ctype_secondary == 'appledouble' && $secondary_type == 'applefile')
             continue;
 
-          // part belongs to a related message
-          if ($message_ctype_secondary == 'related') {
+          // part belongs to a related message and is linked
+          if ($message_ctype_secondary == 'related'
+              && preg_match('!^image/!', $mail_part->mimetype)
+              && ($mail_part->headers['content-id'] || $mail_part->headers['content-location'])) {
             if ($mail_part->headers['content-id'])
               $mail_part->content_id = preg_replace(array('/^</', '/>$/'), '', $mail_part->headers['content-id']);
             if ($mail_part->headers['content-location'])
               $mail_part->content_location = $mail_part->headers['content-base'] . $mail_part->headers['content-location'];
-            
-            if ($mail_part->content_id || $mail_part->content_location) {
-              $this->inline_parts[] = $mail_part;
-            }
+              
+            $this->inline_parts[] = $mail_part;
           }
-          // is regular attachment
-          else {
+          // is regular attachment
+          else if (preg_match('!^[a-z]+/[a-z0-9-.]+$!i', $mail_part->mimetype)) {
             if (!$mail_part->filename)
               $mail_part->filename = 'Part '.$mail_part->mime_id;
             $this->attachments[] = $mail_part;
diff --git a/program/include/rcube_plugin.php b/program/include/rcube_plugin.php
new file mode 100644 (file)
index 0000000..5e37764
--- /dev/null
@@ -0,0 +1,245 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_plugin.php                                      |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |  Abstract plugins interface/class                                     |
+ |  All plugins need to extend this class                                |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+
+ $Id: $
+
+*/
+
+/**
+ * Plugin interface class
+ *
+ * @package Core
+ */
+abstract class rcube_plugin
+{
+  public $ID;
+  public $api;
+  public $task;
+  protected $home;
+  protected $urlbase;
+
+  /**
+   * Default constructor.
+   */
+  public function __construct($api)
+  {
+    $this->ID = get_class($this);
+    $this->api = $api;
+    $this->home = $api->dir . DIRECTORY_SEPARATOR . $this->ID;
+    $this->urlbase = $api->url . $this->ID . '/';
+  }
+  
+  /**
+   * Initialization method, needs to be implemented by the plugin itself
+   */
+  abstract function init();
+  
+  /**
+   * Load local config file from plugins directory.
+   * The loaded values are patched over the global configuration.
+   *
+   * @param string Config file name relative to the plugin's folder
+   * @return boolean True on success, false on failure
+   */
+  public function load_config($fname = 'config.inc.php')
+  {
+    $fpath = $this->home.'/'.$fname;
+    $rcmail = rcmail::get_instance();
+    if (!$rcmail->config->load_from_file($fpath)) {
+      raise_error(array('code' => 527, 'type' => 'php', 'message' => "Failed to load config from $fpath"), true, false);
+      return false;
+    }
+    
+    return true;
+  }
+
+  /**
+   * Register a callback function for a specific (server-side) hook
+   *
+   * @param string Hook name
+   * @param mixed Callback function as string or array with object reference and method name
+   */
+  public function add_hook($hook, $callback)
+  {
+    $this->api->register_hook($hook, $callback);
+  }
+  
+  /**
+   * Load localized texts from the plugins dir
+   *
+   * @param string Directory to search in
+   * @param mixed Make texts also available on the client (array with list or true for all)
+   */
+  public function add_texts($dir, $add2client = false)
+  {
+    $domain = $this->ID;
+    
+    $lang = $_SESSION['language'];
+    $locdir = slashify(realpath(slashify($this->home) . $dir));
+    $texts = array();
+    
+    foreach (array('en_US', $lang) as $lng) {
+      @include($locdir . $lng . '.inc');
+      $texts = (array)$labels + (array)$messages + (array)$texts;
+    }
+
+    // prepend domain to text keys and add to the application texts repository
+    if (!empty($texts)) {
+      $add = array();
+      foreach ($texts as $key => $value)
+        $add[$domain.'.'.$key] = $value;
+
+      $rcmail = rcmail::get_instance();
+      $rcmail->load_language($lang, $add);
+      
+      // add labels to client
+      if ($add2client) {
+        $js_labels = is_array($add2client) ? array_map(array($this, 'label_map_callback'), $add2client) : array_keys($add);
+        $rcmail->output->add_label($js_labels);
+      }
+    }
+  }
+  
+  /**
+   * Wrapper for rcmail::gettext() adding the plugin ID as domain
+   *
+   * @return string Localized text
+   * @see rcmail::gettext()
+   */
+  public function gettext($p)
+  {
+    return rcmail::get_instance()->gettext($p, $this->ID);
+  }
+
+  /**
+   * Register this plugin to be responsible for a specific task
+   *
+   * @param string Task name (only characters [a-z0-9_.-] are allowed)
+   */
+  public function register_task($task)
+  {
+    if ($task != asciiwords($task)) {
+      raise_error(array('code' => 526, 'type' => 'php', 'message' => "Invalid task name: $task. Only characters [a-z0-9_.-] are allowed"), true, false);
+    }
+    else if (in_array(rcmail::$main_tasks, $task)) {
+      raise_error(array('code' => 526, 'type' => 'php', 'message' => "Cannot register taks $task; already taken by another plugin or the application itself"), true, false);
+    }
+    else {
+      rcmail::$main_tasks[] = $task;
+    }
+  }
+
+  /**
+    * Register a handler for a specific client-request action
+    *
+    * The callback will be executed upon a request like /?_task=mail&_action=plugin.myaction
+    *
+    * @param string Action name (should be unique)
+    * @param mixed Callback function as string or array with object reference and method name
+   */
+  public function register_action($action, $callback)
+  {
+    $this->api->register_action($action, $this->ID, $callback);
+  }
+
+  /**
+   * Register a handler function for a template object
+   *
+   * When parsing a template for display, tags like <roundcube:object name="plugin.myobject" />
+   * will be replaced by the return value if the registered callback function.
+   *
+   * @param string Object name (should be unique and start with 'plugin.')
+   * @param mixed Callback function as string or array with object reference and method name
+   */
+  public function register_handler($name, $callback)
+  {
+    $this->api->register_handler($name, $this->ID, $callback);
+  }
+
+  /**
+   * Make this javascipt file available on the client
+   *
+   * @param string File path; absolute or relative to the plugin directory
+   */
+  public function include_script($fn)
+  {
+    $this->api->include_script($this->resource_url($fn));
+  }
+
+  /**
+   * Make this stylesheet available on the client
+   *
+   * @param string File path; absolute or relative to the plugin directory
+   */
+  public function include_stylesheet($fn)
+  {
+    $this->api->include_stylesheet($this->resource_url($fn));
+  }
+  
+  /**
+   * Append a button to a certain container
+   *
+   * @param array Hash array with named parameters (as used in skin templates)
+   * @param string Container name where the buttons should be added to
+   * @see rcube_remplate::button()
+   */
+  public function add_button($p, $container)
+  {
+    if ($this->api->output->type == 'html') {
+      // fix relative paths
+      foreach (array('imagepas', 'imageact', 'imagesel') as $key)
+        if ($p[$key])
+          $p[$key] = $this->api->url . $this->resource_url($p[$key]);
+      
+      $this->api->add_content($this->api->output->button($p), $container);
+    }
+  }
+  
+  /**
+   * Generate an absolute URL to the given resource within the current
+   * plugin directory
+   *
+   * @param string The file name
+   * @return string Absolute URL to the given resource
+   */
+  public function url($fn)
+  {
+      return $this->api->url . $this->resource_url($fn);
+  }
+
+  /**
+   * Make the given file name link into the plugin directory
+   */
+  private function resource_url($fn)
+  {
+    if ($fn[0] != '/' && !preg_match('|^https?://|i', $fn))
+      return $this->ID . '/' . $fn;
+    else
+      return $fn;
+  }
+
+  /**
+   * Callback function for array_map
+   */
+  private function label_map_callback($key)
+  {
+    return $this->ID.'.'.$key;
+  }
+
+
+}
+
diff --git a/program/include/rcube_plugin_api.php b/program/include/rcube_plugin_api.php
new file mode 100644 (file)
index 0000000..75f1cc4
--- /dev/null
@@ -0,0 +1,329 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_plugin_api.php                                  |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2008-2009, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Plugins repository                                                  |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+
+ $Id: $
+
+*/
+
+/**
+ * The plugin loader and global API
+ *
+ * @package Core
+ */
+class rcube_plugin_api
+{
+  static private $instance;
+  
+  public $dir;
+  public $url = 'plugins/';
+  public $output;
+  
+  public $handlers = array();
+  private $plugins = array();
+  private $actions = array();
+  private $actionmap = array();
+  private $objectsmap = array();
+  private $template_contents = array();
+  
+  private $required_plugins = array('filesystem_attachments');
+  private $active_hook = false;
+
+  /**
+   * This implements the 'singleton' design pattern
+   *
+   * @return object rcube_plugin_api The one and only instance if this class
+   */
+  static function get_instance()
+  {
+    if (!self::$instance) {
+      self::$instance = new rcube_plugin_api();
+    }
+
+    return self::$instance;
+  }
+  
+  
+  /**
+   * Private constructor
+   */
+  private function __construct()
+  {
+    $this->dir = INSTALL_PATH . $this->url;
+  }
+  
+  
+  /**
+   * Load and init all enabled plugins
+   *
+   * This has to be done after rcmail::load_gui() or rcmail::init_json()
+   * was called because plugins need to have access to rcmail->output
+   */
+  public function init()
+  {
+    $rcmail = rcmail::get_instance();
+    $this->output = $rcmail->output;
+    
+    $plugins_dir = dir($this->dir);
+    $plugins_enabled = (array)$rcmail->config->get('plugins', array());
+    
+    foreach ($plugins_enabled as $plugin_name) {
+      $fn = $plugins_dir->path . DIRECTORY_SEPARATOR . $plugin_name . DIRECTORY_SEPARATOR . $plugin_name . '.php';
+      
+      if (file_exists($fn)) {
+        include($fn);
+        
+        // instantiate class if exists
+        if (class_exists($plugin_name, false)) {
+          $plugin = new $plugin_name($this);
+          // check inheritance and task specification
+          if (is_subclass_of($plugin, 'rcube_plugin') && (!$plugin->task || preg_match('/('.$plugin->task.')/i', $rcmail->task))) {
+            $plugin->init();
+            $this->plugins[] = $plugin;
+          }
+        }
+        else {
+          raise_error(array('code' => 520, 'type' => 'php', 'message' => "No plugin class $plugin_name found in $fn"), true, false);
+        }
+      }
+      else {
+        raise_error(array('code' => 520, 'type' => 'php', 'message' => "Failed to load plugin file $fn"), true, false);
+      }
+    }
+    
+    // check existance of all required core plugins
+    foreach ($this->required_plugins as $plugin_name) {
+      $loaded = false;
+      foreach ($this->plugins as $plugin) {
+        if ($plugin instanceof $plugin_name) {
+          $loaded = true;
+          break;
+        }
+      }
+      
+      // load required core plugin if no derivate was found
+      if (!$loaded) {
+        $fn = $plugins_dir->path . DIRECTORY_SEPARATOR . $plugin_name . DIRECTORY_SEPARATOR . $plugin_name . '.php';
+        if (file_exists($fn)) {
+          include_once($fn);
+          
+          if (class_exists($plugin_name, false)) {
+            $plugin = new $plugin_name($this);
+            // check inheritance
+            if (is_subclass_of($plugin, 'rcube_plugin')) {
+             if (!$plugin->task || preg_match('/('.$plugin->task.')/i', $rcmail->task)) {
+                $plugin->init();
+                $this->plugins[] = $plugin;
+              }
+             $loaded = true;
+            }
+          }
+        }
+      }
+      
+      // trigger fatal error if still not loaded
+      if (!$loaded) {
+        raise_error(array('code' => 520, 'type' => 'php', 'message' => "Requried plugin $plugin_name was not loaded"), true, true);
+      }
+    }
+
+    // register an internal hook
+    $this->register_hook('template_container', array($this, 'template_container_hook'));
+    
+    // maybe also register a shudown function which triggers shutdown functions of all plugin objects
+    
+    
+    // call imap_init right now
+    // (should actually be done in rcmail::imap_init() but plugins are not initialized then)
+    if ($rcmail->imap) {
+      $hook = $this->exec_hook('imap_init', array('fetch_headers' => $rcmail->imap->fetch_add_headers));
+      if ($hook['fetch_headers'])
+        $rcmail->imap->fetch_add_headers = $hook['fetch_headers'];
+    }
+  }
+  
+  
+  /**
+   * Allows a plugin object to register a callback for a certain hook
+   *
+   * @param string Hook name
+   * @param mixed String with global function name or array($obj, 'methodname')
+   */
+  public function register_hook($hook, $callback)
+  {
+    if (is_callable($callback))
+      $this->handlers[$hook][] = $callback;
+    else
+      raise_error(array('code' => 521, 'type' => 'php', 'message' => "Invalid callback function for $hook"), true, false);
+  }
+  
+  
+  /**
+   * Triggers a plugin hook.
+   * This is called from the application and executes all registered handlers
+   *
+   * @param string Hook name
+   * @param array Named arguments (key->value pairs)
+   * @return array The (probably) altered hook arguments
+   */
+  public function exec_hook($hook, $args = array())
+  {
+    $args += array('abort' => false);
+    $this->active_hook = $hook;
+    
+    foreach ((array)$this->handlers[$hook] as $callback) {
+      $ret = call_user_func($callback, $args);
+      if ($ret && is_array($ret))
+        $args = $ret + $args;
+      
+      if ($args['abort'])
+        break;
+    }
+    
+    $this->active_hook = false;
+    return $args;
+  }
+
+
+  /**
+   * Let a plugin register a handler for a specific request
+   *
+   * @param string Action name (_task=mail&_action=plugin.foo)
+   * @param string Plugin name that registers this action
+   * @param mixed Callback: string with global function name or array($obj, 'methodname')
+   */
+  public function register_action($action, $owner, $callback)
+  {
+    // check action name
+    if (strpos($action, 'plugin.') !== 0)
+      $action = 'plugin.'.$action;
+    
+    // can register action only if it's not taken or registered by myself
+    if (!isset($this->actionmap[$action]) || $this->actionmap[$action] == $owner) {
+      $this->actions[$action] = $callback;
+      $this->actionmap[$action] = $owner;
+    }
+    else {
+      raise_error(array('code' => 523, 'type' => 'php', 'message' => "Cannot register action $action; already taken by another plugin"), true, false);
+    }
+  }
+
+
+  /**
+   * This method handles requests like _task=mail&_action=plugin.foo
+   * It executes the callback function that was registered with the given action.
+   *
+   * @param string Action name
+   */
+  public function exec_action($action)
+  {
+    if (isset($this->actions[$action])) {
+      call_user_func($this->actions[$action]);
+    }
+    else {
+      raise_error(array('code' => 524, 'type' => 'php', 'message' => "No handler found for action $action"), true, true);
+    }
+  }
+
+
+  /**
+   * Register a handler function for template objects
+   *
+   * @param string Object name
+   * @param string Plugin name that registers this action
+   * @param mixed Callback: string with global function name or array($obj, 'methodname')
+   */
+  public function register_handler($name, $owner, $callback)
+  {
+    // check name
+    if (strpos($name, 'plugin.') !== 0)
+      $name = 'plugin.'.$name;
+    
+    // can register handler only if it's not taken or registered by myself
+    if (!isset($this->objectsmap[$name]) || $this->objectsmap[$name] == $owner) {
+      $this->output->add_handler($name, $callback);
+      $this->objectsmap[$name] = $owner;
+    }
+    else {
+      raise_error(array('code' => 525, 'type' => 'php', 'message' => "Cannot register template handler $name; already taken by another plugin"), true, false);
+    }
+  }
+  
+  
+  /**
+   * Check if a plugin hook is currently processing.
+   * Mainly used to prevent loops and recursion.
+   *
+   * @param string Hook to check (optional)
+   * @return boolean True if any/the given hook is currently processed, otherwise false
+   */
+  public function is_processing($hook = null)
+  {
+    return $this->active_hook && (!$hook || $this->active_hook == $hook);
+  }
+  
+  /**
+   * Include a plugin script file in the current HTML page
+   */
+  public function include_script($fn)
+  {
+    if ($this->output->type == 'html') {
+      $src = $this->resource_url($fn);
+      $this->output->add_header(html::tag('script', array('type' => "text/javascript", 'src' => $src)));
+    }
+  }
+
+  /**
+   * Include a plugin stylesheet in the current HTML page
+   */
+  public function include_stylesheet($fn)
+  {
+    if ($this->output->type == 'html') {
+      $src = $this->resource_url($fn);
+      $this->output->add_header(html::tag('link', array('rel' => "stylesheet", 'type' => "text/css", 'href' => $src)));
+    }
+  }
+  
+  /**
+   * Save the given HTML content to be added to a template container
+   */
+  public function add_content($html, $container)
+  {
+    $this->template_contents[$container] .= $html . "\n";
+  }
+  
+  /**
+   * Callback for template_container hooks
+   */
+  private function template_container_hook($attrib)
+  {
+    $container = $attrib['name'];
+    return array('content' => $attrib['content'] . $this->template_contents[$container]);
+  }
+  
+  /**
+   * Make the given file name link into the plugins directory
+   */
+  private function resource_url($fn)
+  {
+    if ($fn[0] != '/' && !preg_match('|^https?://|i', $fn))
+      return $this->url . $fn;
+    else
+      return $fn;
+  }
+
+}
+
index ccf30d2f61ca0e27a6642944c7d8b018e9088735..e99d324e5550847b384f2c393b7b2dda89b1b2ff 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_shared.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: rcube_shared.inc 2789 2009-07-23 12:14:17Z alec $
 
 */
 
@@ -170,7 +170,7 @@ function json_serialize($var)
       foreach ($var as $key => $value)
       {
         // enclose key with quotes if it is not variable-name conform
-        if (!ereg("^[_a-zA-Z]{1}[_a-zA-Z0-9]*$", $key) || is_js_reserved_word($key))
+        if (!preg_match('/^[_a-zA-Z]{1}[_a-zA-Z0-9]*$/', $key) || is_js_reserved_word($key))
           $key = "'$key'";
 
         $pairs[] = sprintf("%s%s", $is_assoc ? "$key:" : '', json_serialize($value));
@@ -185,7 +185,6 @@ function json_serialize($var)
     return $var ? '1' : '0';
   else
     return "'".JQ($var)."'";
-
 }
 
 
@@ -209,9 +208,9 @@ function array2js($arr, $type='')
  */
 function in_array_nocase($needle, $haystack)
 {
-  $needle = rc_strtolower($needle);
+  $needle = mb_strtolower($needle);
   foreach ($haystack as $value)
-    if ($needle===rc_strtolower($value))
+    if ($needle===mb_strtolower($value))
       return true;
   
   return false;
@@ -227,7 +226,7 @@ function in_array_nocase($needle, $haystack)
 function get_boolean($str)
 {
   $str = strtolower($str);
-  if(in_array($str, array('false', '0', 'no', 'nein', ''), TRUE))
+  if (in_array($str, array('false', '0', 'no', 'nein', ''), TRUE))
     return FALSE;
   else
     return TRUE;
@@ -238,12 +237,12 @@ function get_boolean($str)
  * Parse a human readable string for a number of bytes
  *
  * @param string Input string
- * @return int Number of bytes
+ * @return float Number of bytes
  */
 function parse_bytes($str)
 {
   if (is_numeric($str))
-    return intval($str);
+    return floatval($str);
     
   if (preg_match('/([0-9]+)([a-z])/i', $str, $regs))
   {
@@ -262,7 +261,7 @@ function parse_bytes($str)
     }
   }
 
-  return intval($bytes);
+  return floatval($bytes);
 }
     
 /**
@@ -338,81 +337,11 @@ function make_absolute_url($path, $base_url)
   return $abs_path;
 }
 
-
-/**
- * Wrapper function for strlen
- */
-function rc_strlen($str)
-{
-  if (function_exists('mb_strlen'))
-    return mb_strlen($str);
-  else
-    return strlen($str);
-}
-  
-/**
- * Wrapper function for strtolower
- */
-function rc_strtolower($str)
-{
-  if (function_exists('mb_strtolower'))
-    return mb_strtolower($str);
-  else
-    return strtolower($str);
-}
-
-/**
- * Wrapper function for strtoupper
- */
-function rc_strtoupper($str)
-{
-  if (function_exists('mb_strtoupper'))
-    return mb_strtoupper($str);
-  else
-    return strtoupper($str);
-}
-
-/**
- * Wrapper function for substr
- */
-function rc_substr($str, $start, $len=null)
-{
-  if (function_exists('mb_substr'))
-    return mb_substr($str, $start, $len);
-  else
-    return substr($str, $start, $len);
-}
-
-/**
- * Wrapper function for strpos
- */
-function rc_strpos($haystack, $needle, $offset=0)
-{
-  if (function_exists('mb_strpos'))
-    return mb_strpos($haystack, $needle, $offset);
-  else
-    return strpos($haystack, $needle, $offset);
-}
-
-/**
- * Wrapper function for strrpos
- */
-function rc_strrpos($haystack, $needle, $offset=0)
-{
-  if (function_exists('mb_strrpos'))
-    return mb_strrpos($haystack, $needle, $offset);
-  else
-    return strrpos($haystack, $needle, $offset);
-}
-
 /**
  * Wrapper function for wordwrap
  */
 function rc_wordwrap($string, $width=75, $break="\n", $cut=false)
 {
-  if (!function_exists('mb_substr') || !function_exists('mb_strlen'))
-    return wordwrap($string, $width, $break, $cut);
-    
   $para = explode($break, $string);
   $string = '';
   while (count($para)) {
@@ -425,7 +354,7 @@ function rc_wordwrap($string, $width=75, $break="\n", $cut=false)
 
       if ($newlen <= $width) {
         $string .= ($len ? ' ' : '').$line;
-        $len += ($len ? 1 : 0) + $l;
+        $len += (1 + $l);
       } else {
        if ($l > $width) {
          if ($cut) {
@@ -478,30 +407,6 @@ function rc_request_header($name)
   }
 
 
-/**
- * Replace the middle part of a string with ...
- * if it is longer than the allowed length
- *
- * @param string Input string
- * @param int    Max. length
- * @param string Replace removed chars with this
- * @return string Abbreviated string
- */
-function abbreviate_string($str, $maxlength, $place_holder='...')
-{
-  $length = rc_strlen($str);
-  $first_part_length = floor($maxlength/2) - rc_strlen($place_holder);
-  
-  if ($length > $maxlength)
-  {
-    $second_starting_location = $length - $maxlength + $first_part_length + 1;
-    $str = rc_substr($str, 0, $first_part_length) . $place_holder . rc_substr($str, $second_starting_location, $length);
-  }
-
-  return $str;
-}
-
-
 /**
  * Make sure the string ends with a slash
  */
@@ -579,6 +484,29 @@ function get_offset_time($offset_str, $factor=1)
 }
 
 
+/**
+ * Replace the middle part of a string with ...
+ * if it is longer than the allowed length
+ *
+ * @param string Input string
+ * @param int    Max. length
+ * @param string Replace removed chars with this
+ * @return string Abbreviated string
+ */
+function abbreviate_string($str, $maxlength, $place_holder='...')
+{
+  $length = mb_strlen($str);
+  $first_part_length = floor($maxlength/2) - mb_strlen($place_holder);
+  
+  if ($length > $maxlength)
+  {
+    $second_starting_location = $length - $maxlength + $first_part_length + 1;
+    $str = mb_substr($str, 0, $first_part_length) . $place_holder . mb_substr($str, $second_starting_location, $length);
+  }
+
+  return $str;
+}
+
 /**
  * A method to guess the mime_type of an attachment.
  *
@@ -683,4 +611,42 @@ function rcube_explode_quoted_string($delimiter, $string)
   return $result;
 }
 
+
+/**
+ * mbstring replacement functions
+ */
+
+if (!extension_loaded('mbstring'))
+{
+    function mb_strlen($str)
+    {
+       return strlen($str);
+    }
+
+    function mb_strtolower($str)
+    {
+        return strtolower($str);
+    }
+
+    function mb_strtoupper($str)
+    {
+        return strtoupper($str);
+    }
+
+    function mb_substr($str, $start, $len=null)
+    {
+        return substr($str, $start, $len);
+    }
+
+    function mb_strpos($haystack, $needle, $offset=0)
+    {
+        return strpos($haystack, $needle, $offset);
+    }
+
+    function mb_strrpos($haystack, $needle, $offset=0)
+    {
+        return strrpos($haystack, $needle, $offset);
+    }
+}
+
 ?>
diff --git a/program/include/rcube_smtp.inc b/program/include/rcube_smtp.inc
deleted file mode 100644 (file)
index f4995d8..0000000
+++ /dev/null
@@ -1,349 +0,0 @@
-<?php
-
-/*
- +-----------------------------------------------------------------------+
- | program/include/rcube_smtp.inc                                        |
- |                                                                       |
- | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- | PURPOSE:                                                              |
- |   Provide SMTP functionality using socket connections                 |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Thomas Bruederli <roundcube@gmail.com>                        |
- +-----------------------------------------------------------------------+
-
- $Id: rcube_smtp.inc 2291 2009-02-13 10:44:49Z alec $
-
-*/
-
-/**
- * SMTP delivery functions
- *
- * @package Mail
- */
-
-// include required PEAR classes
-require_once('Net/SMTP.php');
-
-
-// define headers delimiter
-define('SMTP_MIME_CRLF', "\r\n");
-
-$SMTP_CONN = null;
-
-/**
- * Function for sending mail using SMTP.
- *
- * @param string Sender e-Mail address
- *
- * @param mixed  Either a comma-seperated list of recipients
- *               (RFC822 compliant), or an array of recipients,
- *               each RFC822 valid. This may contain recipients not
- *               specified in the headers, for Bcc:, resending
- *               messages, etc.
- *
- * @param mixed  The message headers to send with the mail
- *               Either as an associative array or a finally
- *               formatted string
- *
- * @param string The full text of the message body, including any Mime parts, etc.
- *
- * @return bool  Returns TRUE on success, or FALSE on error
- */
-function smtp_mail($from, $recipients, &$headers, &$body, &$response)
-  {
-  global $SMTP_CONN, $CONFIG, $RCMAIL;
-  $smtp_timeout = null;
-  $smtp_host = $CONFIG['smtp_server'];
-  $smtp_port = is_numeric($CONFIG['smtp_port']) ? $CONFIG['smtp_port'] : 25;
-  $smtp_host_url = parse_url($CONFIG['smtp_server']);
-  
-  // overwrite port
-  if (isset($smtp_host_url['host']) && isset($smtp_host_url['port']))
-    {
-    $smtp_host = $smtp_host_url['host'];
-    $smtp_port = $smtp_host_url['port'];
-    }
-
-  // re-write smtp host
-  if (isset($smtp_host_url['host']) && isset($smtp_host_url['scheme']))
-    $smtp_host = sprintf('%s://%s', $smtp_host_url['scheme'], $smtp_host_url['host']);
-
-
-  // create Net_SMTP object and connect to server
-  if (!is_object($SMTP_CONN))
-    {
-    if (!empty($CONFIG['smtp_helo_host']))
-      $helo_host = $CONFIG['smtp_helo_host'];
-    else if (!empty($_SERVER['SERVER_NAME']))
-      $helo_host = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']);
-    else
-      $helo_host = 'localhost';
-
-    $SMTP_CONN = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
-
-    // try to connect to server and exit on failure
-    $result = $SMTP_CONN->connect($smtp_timeout);
-    if (PEAR::isError($result))
-      {
-      $SMTP_CONN = null;
-      $response[] = "Connection failed: ".$result->getMessage();
-      return FALSE;
-      }
-      
-    // attempt to authenticate to the SMTP server
-    if ($CONFIG['smtp_user'] && $CONFIG['smtp_pass'])
-      {
-      if (strstr($CONFIG['smtp_user'], '%u'))
-        $smtp_user = str_replace('%u', $_SESSION['username'], $CONFIG['smtp_user']);
-      else
-        $smtp_user = $CONFIG['smtp_user'];
-
-      if (strstr($CONFIG['smtp_pass'], '%p'))
-        $smtp_pass = str_replace('%p', $RCMAIL->decrypt_passwd($_SESSION['password']), $CONFIG['smtp_pass']);
-      else
-        $smtp_pass = $CONFIG['smtp_pass'];
-
-      $smtp_auth_type = empty($CONFIG['smtp_auth_type']) ? NULL : $CONFIG['smtp_auth_type'];
-      $result = $SMTP_CONN->auth($smtp_user, $smtp_pass, $smtp_auth_type);
-    
-      if (PEAR::isError($result))
-        {
-        smtp_reset();
-        $response[] .= 'Authentication failure: ' . $result->getMessage() . ' (Code: ' . $result->getCode() . ')';
-        return FALSE;
-        }
-      }
-    }
-
-
-  // prepare message headers as string
-  if (is_array($headers))
-    {
-    $headerElements = smtp_prepare_headers($headers);
-    if (!$headerElements)
-      {
-      smtp_reset();
-      return FALSE;
-      }
-
-    list($from, $text_headers) = $headerElements;
-    }
-  else if (is_string($headers))
-    $text_headers = $headers;
-  else
-    {
-    smtp_reset();
-    $response[] .= "Invalid message headers";
-    return FALSE;
-    }
-
-  // exit if no from address is given
-  if (!isset($from))
-    {
-    smtp_reset();
-    $response[] .= "No From address has been provided";
-    return FALSE;
-    }
-
-
-  // set From: address
-  if (PEAR::isError($SMTP_CONN->mailFrom($from)))
-    {
-    smtp_reset();
-    $response[] .= "Failed to set sender '$from'";
-    return FALSE;
-    }
-
-
-  // prepare list of recipients
-  $recipients = smtp_parse_rfc822($recipients);
-  if (PEAR::isError($recipients))
-    {
-    smtp_reset();
-    return FALSE;
-    }
-
-
-  // set mail recipients
-  foreach ($recipients as $recipient)
-    {
-    if (PEAR::isError($SMTP_CONN->rcptTo($recipient)))
-      {
-      smtp_reset();
-      $response[] .= "Failed to add recipient '$recipient'";
-      return FALSE;
-      }
-    }
-
-
-  // Concatenate headers and body so it can be passed by reference to SMTP_CONN->data
-  // so preg_replace in SMTP_CONN->quotedata will store a reference instead of a copy. 
-  // We are still forced to make another copy here for a couple ticks so we don't really 
-  // get to save a copy in the method call.
-  $data = $text_headers . "\r\n" . $body;
-
-  // unset old vars to save data and so we can pass into SMTP_CONN->data by reference.
-  unset($text_headers, $body);
-   
-  // Send the message's headers and the body as SMTP data.
-  if (PEAR::isError($SMTP_CONN->data($data)))
-    {
-    smtp_reset();
-    $response[] .= "Failed to send data";
-    return FALSE;
-    }
-
-  $response[] = join(': ', $SMTP_CONN->getResponse());
-  return TRUE;
-  }
-
-
-
-/**
- * Reset the global SMTP connection
- * @access public
- */
-function smtp_reset()
-  {
-  global $SMTP_CONN;
-
-  if (is_object($SMTP_CONN))
-    {
-    $SMTP_CONN->rset();
-    smtp_disconnect();
-    }
-  }
-
-
-
-/**
- * Disconnect the global SMTP connection and destroy object
- * @access public
- */
-function smtp_disconnect()
-  {
-  global $SMTP_CONN;
-
-  if (is_object($SMTP_CONN))
-    {
-    $SMTP_CONN->disconnect();
-    $SMTP_CONN = null;
-    }
-  }
-
-
-/**
- * Take an array of mail headers and return a string containing
- * text usable in sending a message.
- *
- * @param array $headers The array of headers to prepare, in an associative
- *              array, where the array key is the header name (ie,
- *              'Subject'), and the array value is the header
- *              value (ie, 'test'). The header produced from those
- *              values would be 'Subject: test'.
- *
- * @return mixed Returns false if it encounters a bad address,
- *               otherwise returns an array containing two
- *               elements: Any From: address found in the headers,
- *               and the plain text version of the headers.
- * @access private
- */
-function smtp_prepare_headers($headers)
-  {
-  $lines = array();
-  $from = null;
-
-  foreach ($headers as $key => $value)
-    {
-    if (strcasecmp($key, 'From') === 0)
-      {
-      $addresses = smtp_parse_rfc822($value);
-
-      if (is_array($addresses))
-        $from = $addresses[0];
-
-      // Reject envelope From: addresses with spaces.
-      if (strstr($from, ' '))
-        return FALSE;
-
-
-      $lines[] = $key . ': ' . $value;
-      }
-    else if (strcasecmp($key, 'Received') === 0)
-      {
-      $received = array();
-      if (is_array($value))
-        {
-        foreach ($value as $line)
-          $received[] = $key . ': ' . $line;
-        }
-      else
-        {
-        $received[] = $key . ': ' . $value;
-        }
-
-      // Put Received: headers at the top.  Spam detectors often
-      // flag messages with Received: headers after the Subject:
-      // as spam.
-      $lines = array_merge($received, $lines);
-      }
-
-    else
-      {
-      // If $value is an array (i.e., a list of addresses), convert
-      // it to a comma-delimited string of its elements (addresses).
-      if (is_array($value))
-        $value = implode(', ', $value);
-
-      $lines[] = $key . ': ' . $value;
-      }
-    }
-
-  return array($from, join(SMTP_MIME_CRLF, $lines) . SMTP_MIME_CRLF);
-  }
-
-
-
-/**
- * Take a set of recipients and parse them, returning an array of
- * bare addresses (forward paths) that can be passed to sendmail
- * or an smtp server with the rcpt to: command.
- *
- * @param mixed Either a comma-seperated list of recipients
- *              (RFC822 compliant), or an array of recipients,
- *              each RFC822 valid.
- *
- * @return array An array of forward paths (bare addresses).
- * @access private
- */
-function smtp_parse_rfc822($recipients)
-  {
-  // if we're passed an array, assume addresses are valid and implode them before parsing.
-  if (is_array($recipients))
-    $recipients = implode(', ', $recipients);
-    
-  $addresses = array();
-  $recipients = rcube_explode_quoted_string(',', $recipients);
-  
-  reset($recipients);
-  while (list($k, $recipient) = each($recipients))
-    {
-  $a = explode(" ", $recipient);
-  while (list($k2, $word) = each($a))
-    {
-      if ((strpos($word, "@") > 0) && (strpos($word, "\"")===false))
-        {
-        $word = ereg_replace('^<|>$', '', trim($word));
-        if (in_array($word, $addresses)===false)
-          array_push($addresses, $word);
-        }
-      }
-    }
-  return $addresses;
-  }
-
-?>
diff --git a/program/include/rcube_smtp.php b/program/include/rcube_smtp.php
new file mode 100644 (file)
index 0000000..9253468
--- /dev/null
@@ -0,0 +1,394 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_smtp.php                                        |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Provide SMTP functionality using socket connections                 |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+
+ $Id$
+
+*/
+
+// define headers delimiter
+define('SMTP_MIME_CRLF', "\r\n");
+
+class rcube_smtp {
+
+  private $conn = null;
+  private $response;
+  private $error;
+
+
+  /**
+   * Object constructor
+   *
+   * @param 
+   */
+  function __construct()
+  {
+  }
+
+
+  /**
+   * SMTP Connection and authentication
+   *
+   * @return bool  Returns true on success, or false on error
+   */
+  public function connect()
+  {
+    $RCMAIL = rcmail::get_instance();
+  
+    // disconnect/destroy $this->conn
+    $this->disconnect();
+    
+    // reset error/response var
+    $this->error = $this->response = null;
+  
+    // let plugins alter smtp connection config
+    $CONFIG = $RCMAIL->plugins->exec_hook('smtp_connect', array(
+      'smtp_server' => $RCMAIL->config->get('smtp_server'),
+      'smtp_port'   => $RCMAIL->config->get('smtp_port', 25),
+      'smtp_user'   => $RCMAIL->config->get('smtp_user'),
+      'smtp_pass'   => $RCMAIL->config->get('smtp_pass'),
+      'smtp_auth_type' => $RCMAIL->config->get('smtp_auth_type'),
+      'smtp_helo_host' => $RCMAIL->config->get('smtp_helo_host'),
+      'smtp_timeout'   => $RCMAIL->config->get('smtp_timeout'),
+    ));
+
+    $smtp_host = str_replace('%h', $_SESSION['imap_host'], $CONFIG['smtp_server']);
+    // when called from Installer it's possible to have empty $smtp_host here
+    if (!$smtp_host) $smtp_host = 'localhost';
+    $smtp_port = is_numeric($CONFIG['smtp_port']) ? $CONFIG['smtp_port'] : 25;
+    $smtp_host_url = parse_url($smtp_host);
+
+    // overwrite port
+    if (isset($smtp_host_url['host']) && isset($smtp_host_url['port']))
+    {
+      $smtp_host = $smtp_host_url['host'];
+      $smtp_port = $smtp_host_url['port'];
+    }
+
+    // re-write smtp host
+    if (isset($smtp_host_url['host']) && isset($smtp_host_url['scheme']))
+      $smtp_host = sprintf('%s://%s', $smtp_host_url['scheme'], $smtp_host_url['host']);
+
+    if (!empty($CONFIG['smtp_helo_host']))
+      $helo_host = $CONFIG['smtp_helo_host'];
+    else if (!empty($_SERVER['SERVER_NAME']))
+      $helo_host = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']);
+    else
+      $helo_host = 'localhost';
+
+    $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
+
+    if($RCMAIL->config->get('smtp_debug'))
+      $this->conn->setDebug(true, array($this, 'debug_handler'));
+    
+    // try to connect to server and exit on failure
+    $result = $this->conn->connect($smtp_timeout);
+    if (PEAR::isError($result))
+    {
+      $this->response[] = "Connection failed: ".$result->getMessage();
+      $this->error = array('label' => 'smtpconnerror', 'vars' => array('code' => $this->conn->_code));
+      $this->conn = null;
+      return false;
+    }
+
+    $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'];
+      
+    // attempt to authenticate to the SMTP server
+    if ($smtp_user && $smtp_pass)
+    {
+      $result = $this->conn->auth($smtp_user, $smtp_pass, $smtp_auth_type);
+      if (PEAR::isError($result))
+      {
+        $this->error = array('label' => 'smtpautherror', 'vars' => array('code' => $this->conn->_code));
+        $this->response[] .= 'Authentication failure: ' . $result->getMessage() . ' (Code: ' . $result->getCode() . ')';
+        $this->reset();
+       $this->disconnect();
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+
+  /**
+   * Function for sending mail
+   *
+   * @param string Sender e-Mail address
+   *
+   * @param mixed  Either a comma-seperated list of recipients
+   *               (RFC822 compliant), or an array of recipients,
+   *               each RFC822 valid. This may contain recipients not
+   *               specified in the headers, for Bcc:, resending
+   *               messages, etc.
+   *
+   * @param mixed  The message headers to send with the mail
+   *               Either as an associative array or a finally
+   *               formatted string
+   *
+   * @param string The full text of the message body, including any Mime parts, etc.
+   *
+   * @return bool  Returns true on success, or false on error
+   */
+  public function send_mail($from, $recipients, &$headers, &$body)
+  {
+    if (!is_object($this->conn))
+      return false;
+
+    // prepare message headers as string
+    if (is_array($headers))
+    {
+      if (!($headerElements = $this->_prepare_headers($headers))) {
+        $this->reset();
+        return false;
+      }
+
+      list($from, $text_headers) = $headerElements;
+    }
+    else if (is_string($headers))
+      $text_headers = $headers;
+    else
+    {
+      $this->reset();
+      $this->response[] .= "Invalid message headers";
+      return false;
+    }
+
+    // exit if no from address is given
+    if (!isset($from))
+    {
+      $this->reset();
+      $this->response[] .= "No From address has been provided";
+      return false;
+    }
+
+    // set From: address
+    if (PEAR::isError($this->conn->mailFrom($from)))
+    {
+      $this->error = array('label' => 'smtpfromerror', 'vars' => array('from' => $from, 'code' => $this->conn->_code));
+      $this->response[] .= "Failed to set sender '$from'";
+      $this->reset();
+      return false;
+    }
+
+    // prepare list of recipients
+    $recipients = $this->_parse_rfc822($recipients);
+    if (PEAR::isError($recipients))
+    {
+      $this->error = array('label' => 'smtprecipientserror');
+      $this->reset();
+      return false;
+    }
+
+    // set mail recipients
+    foreach ($recipients as $recipient)
+    {
+      if (PEAR::isError($this->conn->rcptTo($recipient))) {
+        $this->error = array('label' => 'smtptoerror', 'vars' => array('to' => $recipient, 'code' => $this->conn->_code));
+        $this->response[] .= "Failed to add recipient '$recipient'";
+        $this->reset();
+        return false;
+      }
+    }
+
+    // Concatenate headers and body so it can be passed by reference to SMTP_CONN->data
+    // so preg_replace in SMTP_CONN->quotedata will store a reference instead of a copy. 
+    // We are still forced to make another copy here for a couple ticks so we don't really 
+    // get to save a copy in the method call.
+    $data = $text_headers . "\r\n" . $body;
+
+    // unset old vars to save data and so we can pass into SMTP_CONN->data by reference.
+    unset($text_headers, $body);
+   
+    // Send the message's headers and the body as SMTP data.
+    if (PEAR::isError($result = $this->conn->data($data)))
+    {
+      $this->error = array('label' => 'smtperror', 'vars' => array('msg' => $result->getMessage()));
+      $this->response[] .= "Failed to send data";
+      $this->reset();
+      return false;
+    }
+
+    $this->response[] = join(': ', $this->conn->getResponse());
+    return true;
+  }
+
+
+  /**
+   * Reset the global SMTP connection
+   * @access public
+   */
+  public function reset()
+  {
+    if (is_object($this->conn))
+      $this->conn->rset();
+  }
+
+
+  /**
+   * Disconnect the global SMTP connection
+   * @access public
+   */
+  public function disconnect()
+  {
+    if (is_object($this->conn)) {
+      $this->conn->disconnect();
+      $this->conn = null;
+    }
+  }
+
+
+  /**
+   * This is our own debug handler for the SMTP connection
+   * @access public
+   */
+  public function debug_handler(&$smtp, $message)
+  {
+    write_log('smtp', preg_replace('/\r\n$/', '', $message));
+  }
+
+
+  /**
+   * Get error message
+   * @access public
+   */
+  public function get_error()
+  {
+    return $this->error;
+  }
+
+
+  /**
+   * Get server response messages array
+   * @access public
+   */
+  public function get_response()
+  {
+    return $this->response;
+  }
+
+
+  /**
+   * Take an array of mail headers and return a string containing
+   * text usable in sending a message.
+   *
+   * @param array $headers The array of headers to prepare, in an associative
+   *              array, where the array key is the header name (ie,
+   *              'Subject'), and the array value is the header
+   *              value (ie, 'test'). The header produced from those
+   *              values would be 'Subject: test'.
+   *
+   * @return mixed Returns false if it encounters a bad address,
+   *               otherwise returns an array containing two
+   *               elements: Any From: address found in the headers,
+   *               and the plain text version of the headers.
+   * @access private
+   */
+  private function _prepare_headers($headers)
+  {
+    $lines = array();
+    $from = null;
+
+    foreach ($headers as $key => $value)
+    {
+      if (strcasecmp($key, 'From') === 0)
+      {
+        $addresses = $this->_parse_rfc822($value);
+
+        if (is_array($addresses))
+          $from = $addresses[0];
+
+        // Reject envelope From: addresses with spaces.
+        if (strstr($from, ' '))
+          return false;
+
+        $lines[] = $key . ': ' . $value;
+      }
+      else if (strcasecmp($key, 'Received') === 0)
+      {
+        $received = array();
+        if (is_array($value))
+        {
+          foreach ($value as $line)
+            $received[] = $key . ': ' . $line;
+        }
+        else
+        {
+          $received[] = $key . ': ' . $value;
+        }
+
+        // Put Received: headers at the top.  Spam detectors often
+        // flag messages with Received: headers after the Subject:
+        // as spam.
+        $lines = array_merge($received, $lines);
+      }
+      else
+      {
+        // If $value is an array (i.e., a list of addresses), convert
+        // it to a comma-delimited string of its elements (addresses).
+        if (is_array($value))
+          $value = implode(', ', $value);
+
+        $lines[] = $key . ': ' . $value;
+      }
+    }
+    
+    return array($from, join(SMTP_MIME_CRLF, $lines) . SMTP_MIME_CRLF);
+  }
+
+  /**
+   * Take a set of recipients and parse them, returning an array of
+   * bare addresses (forward paths) that can be passed to sendmail
+   * or an smtp server with the rcpt to: command.
+   *
+   * @param mixed Either a comma-seperated list of recipients
+   *              (RFC822 compliant), or an array of recipients,
+   *              each RFC822 valid.
+   *
+   * @return array An array of forward paths (bare addresses).
+   * @access private
+   */
+  private function _parse_rfc822($recipients)
+  {
+    // if we're passed an array, assume addresses are valid and implode them before parsing.
+    if (is_array($recipients))
+      $recipients = implode(', ', $recipients);
+    
+    $addresses = array();
+    $recipients = rcube_explode_quoted_string(',', $recipients);
+  
+    reset($recipients);
+    while (list($k, $recipient) = each($recipients))
+    {
+      $a = explode(" ", $recipient);
+      while (list($k2, $word) = each($a))
+      {
+        if ((strpos($word, "@") > 0) && (strpos($word, "\"")===false))
+        {
+          $word = preg_replace('/^<|>$/', '', trim($word));
+          if (in_array($word, $addresses)===false)
+            array_push($addresses, $word);
+        }
+      }
+    }
+    return $addresses;
+  }
+
+}
+
+?>
index fe082a583c98b1e57a0f1658058dafab72dd917d..2625fdfb9a8b34b7bff594c3975c99e6f85bb000 100644 (file)
 class rcube_string_replacer
 {
   public static $pattern = '/##str_replacement\[([0-9]+)\]##/';
-
+  public $mailto_pattern;
+  public $link_pattern;
   private $values = array();
 
 
+  function __construct()
+  {
+    $url_chars = 'a-z0-9_\-\+\*\$\/&%=@#:;';
+    $url_chars_within = '\?\.~,!';
+
+    $this->link_pattern = "/([\w]+:\/\/|\Wwww\.)([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/i";
+    $this->mailto_pattern = "/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/i";
+  }
+
   /**
    * Add a string to the internal list
    *
@@ -64,16 +74,17 @@ class rcube_string_replacer
     $i = -1;
     $scheme = strtolower($matches[1]);
 
-    if ($scheme == 'http' || $scheme == 'https' || $scheme == 'ftp') {
-      $url = $matches[1] . '://' . $matches[2];
-      $i = $this->add(html::a(array('href' => $url, 'target' => "_blank"), Q($url)));
+    if (preg_match('!^(http|ftp|file)s?://!', $scheme)) {
+      $url = $matches[1] . $matches[2];
+      $i = $this->add(html::a(array('href' => $url, 'target' => '_blank'), Q($url)));
     }
-    else if ($matches[2] == 'www.') {
-      $url = $matches[2] . $matches[3];
-      $i = $this->add($matches[1] . html::a(array('href' => 'http://' . $url, 'target' => "_blank"), Q($url)));
+    else if (preg_match('/^(\W)www\.$/', $matches[1], $m)) {
+      $url = 'www.' . $matches[2];
+      $i = $this->add($m[1] . html::a(array('href' => 'http://' . $url, 'target' => '_blank'), Q($url)));
     }
 
-    return $i >= 0 ? $this->get_replacement($i) : '';
+    // Return valid link for recognized schemes, otherwise, return the unmodified string for unrecognized schemes.
+    return $i >= 0 ? $this->get_replacement($i) : $matches[0];
   }
 
   /**
index 1e732ca110b2b0f6097463e24a43358b4441ecda..3d894b5b6d0a2aa65843af3ac8c2e0086f53657f 100755 (executable)
@@ -34,6 +34,7 @@ class rcube_template extends rcube_html_page
     var $config;
     var $framed = false;
     var $pagetitle = '';
+    var $message = null;
     var $env = array();
     var $js_env = array();
     var $js_commands = array();
@@ -58,6 +59,7 @@ class rcube_template extends rcube_html_page
         
         //$this->framed = $framed;
         $this->set_env('task', $task);
+        $this->set_env('request_token', $this->app->get_request_token());
 
         // load the correct skin (in case user-defined)
         $this->set_skin($this->config['skin']);
@@ -66,11 +68,12 @@ class rcube_template extends rcube_html_page
         $javascript = 'var '.JS_OBJECT_NAME.' = new rcube_webmail();';
 
         // don't wait for page onload. Call init at the bottom of the page (delayed)
-        $javascript_foot = "if (window.call_init)\n call_init('".JS_OBJECT_NAME."');";
+        $javascript_foot = '$(document).ready(function(){ '.JS_OBJECT_NAME.'.init(); });';
 
         $this->add_script($javascript, 'head_top');
         $this->add_script($javascript_foot, 'foot');
         $this->scripts_path = 'program/js/';
+        $this->include_script('jquery-1.3.min.js');
         $this->include_script('common.js');
         $this->include_script('app.js');
 
@@ -199,7 +202,9 @@ class rcube_template extends rcube_html_page
      */
     public function command()
     {
-        $this->js_commands[] = func_get_args();
+        $cmd = func_get_args();
+        if (strpos($cmd[0], 'plugin.') === false)
+          $this->js_commands[] = $cmd;
     }
 
 
@@ -208,8 +213,11 @@ class rcube_template extends rcube_html_page
      */
     public function add_label()
     {
-        $arg_list = func_get_args();
-        foreach ($arg_list as $i => $name) {
+        $args = func_get_args();
+        if (count($args) == 1 && is_array($args[0]))
+          $args = $args[0];
+        
+        foreach ($args as $name) {
             $this->command('add_label', $name, rcube_label($name));
         }
     }
@@ -221,14 +229,18 @@ class rcube_template extends rcube_html_page
      * @param string Message to display
      * @param string Message type [notice|confirm|error]
      * @param array Key-value pairs to be replaced in localized text
+     * @param boolean Override last set message
      * @uses self::command()
      */
-    public function show_message($message, $type='notice', $vars=NULL)
+    public function show_message($message, $type='notice', $vars=null, $override=true)
     {
-        $this->command(
-            'display_message',
-            rcube_label(array('name' => $message, 'vars' => $vars)),
-            $type);
+        if ($override || !$this->message) {
+            $this->message = $message;
+            $this->command(
+                'display_message',
+                rcube_label(array('name' => $message, 'vars' => $vars)),
+                $type);
+        }
     }
 
 
@@ -276,6 +288,11 @@ class rcube_template extends rcube_html_page
     public function send($templ = null, $exit = true)
     {
         if ($templ != 'iframe') {
+            // prevent from endless loops
+            if ($exit != 'recur' && $this->app->plugins->is_processing('render_page')) {
+                raise_error(array('code' => 505, 'type' => 'php', 'message' => 'Recursion alert: ignoring output->send()'), true, false);
+                return;
+            }
             $this->parse($templ, false);
         }
         else {
@@ -283,6 +300,10 @@ class rcube_template extends rcube_html_page
             $this->write();
         }
 
+        // set output asap
+        ob_flush();
+        flush();
+        
         if ($exit) {
             exit;
         }
@@ -305,6 +326,10 @@ class rcube_template extends rcube_html_page
         $js = $this->framed ? "if(window.parent) {\n" : '';
         $js .= $this->get_js_commands() . ($this->framed ? ' }' : '');
         $this->add_script($js, 'head_top');
+        
+        // make sure all <form> tags have a valid request token
+        $template = preg_replace_callback('/<form\s+([^>]+)>/Ui', array($this, 'alter_form_tag'), $template);
+        $this->footer = preg_replace_callback('/<form\s+([^>]+)>/Ui', array($this, 'alter_form_tag'), $this->footer);
 
         // call super method
         parent::write($template, $this->config['skin_path']);
@@ -323,6 +348,20 @@ class rcube_template extends rcube_html_page
     private function parse($name = 'main', $exit = true)
     {
         $skin_path = $this->config['skin_path'];
+        $plugin = false;
+        
+        $temp = explode(".", $name, 2);
+        if (count($temp) > 1) {
+            $plugin = $temp[0];
+            $name = $temp[1];
+            $skin_dir = $plugin . '/skins/' . $this->config['skin'];
+            $skin_path = $this->app->plugins->dir . $skin_dir;
+            if (!is_dir($skin_path)) {  // fallback to default skin
+                $skin_dir = $plugin . '/skins/default';
+                $skin_path = $this->app->plugins->dir . $skin_dir;
+            }
+        }
+        
         $path = "$skin_path/templates/$name.html";
 
         // read template file
@@ -336,20 +375,30 @@ class rcube_template extends rcube_html_page
                 ), true, true);
             return false;
         }
+        
+        // replace all path references to plugins/... with the configured plugins dir
+        // and /this/ to the current plugin skin directory
+        if ($plugin) {
+            $templ = preg_replace(array('/\bplugins\//', '/(["\']?)\/this\//'), array($this->app->plugins->url, '\\1'.$this->app->plugins->url.$skin_dir.'/'), $templ);
+        }
 
         // parse for specialtags
         $output = $this->parse_conditions($templ);
         $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));
 
         // add debug console
         if ($this->config['debug_level'] & 8) {
-            $this->add_footer('<div style="position:absolute;top:5px;left:5px;width:405px;padding:2px;background:white;opacity:0.8;filter:alpha(opacity=80);z-index:9000">
+            $this->add_footer('<div id="console" style="position:absolute;top:5px;left:5px;width:405px;padding:2px;background:white;z-index:9000;">
                 <a href="#toggle" onclick="con=document.getElementById(\'dbgconsole\');con.style.display=(con.style.display==\'none\'?\'block\':\'none\');return false">console</a>
                 <form action="/" name="debugform" style="display:inline"><textarea name="console" id="dbgconsole" rows="20" cols="40" wrap="off" style="display:none;width:400px;border:none;font-size:x-small" spellcheck="false"></textarea></form></div>'
             );
         }
-        $output = $this->parse_with_globals($output);
-        $this->write(trim($output), $skin_path);
+        
+        $output = $this->parse_with_globals($hook['content']);
+        $this->write(trim($output));
         if ($exit) {
             exit;
         }
@@ -375,9 +424,9 @@ class rcube_template extends rcube_html_page
             $parent = $this->framed || preg_match('/^parent\./', $method);
             $out .= sprintf(
                 "%s.%s(%s);\n",
-            ($parent ? 'parent.' : '') . JS_OBJECT_NAME,
-            preg_replace('/^parent\./', '', $method),
-            implode(',', $args)
+                ($parent ? 'if(window.parent && parent.'.JS_OBJECT_NAME.') parent.' : '') . JS_OBJECT_NAME,
+                preg_replace('/^parent\./', '', $method),
+                implode(',', $args)
             );
         }
         
@@ -404,6 +453,7 @@ class rcube_template extends rcube_html_page
      */
     private function parse_with_globals($input)
     {
+        $GLOBALS['__version'] = Q(RCMAIL_VERSION);
         $GLOBALS['__comm_path'] = Q($this->app->comm_path);
         return preg_replace('/\$(__[a-z0-9_\-]+)/e', '$GLOBALS["\\1"]', $input);
     }
@@ -469,7 +519,24 @@ class rcube_template extends rcube_html_page
      */
     private function check_condition($condition)
     {
-            return eval("return (".$this->parse_expression($condition).");");
+        return eval("return (".$this->parse_expression($condition).");");
+    }
+    
+    
+    /**
+     *
+     */
+    private function alter_form_tag($matches)
+    {
+        $out = $matches[0];
+        $attrib  = parse_attrib_string($matches[1]);
+      
+        if (strtolower($attrib['method']) == 'post') {
+            $hidden = new html_hiddenfield(array('name' => '_token', 'value' => $this->app->get_request_token()));
+            $out .= "\n" . $hidden->show();
+        }
+      
+        return $out;
     }
 
 
@@ -487,14 +554,16 @@ class rcube_template extends rcube_html_page
                 '/config:([a-z0-9_]+)(:([a-z0-9_]+))?/i',
                 '/env:([a-z0-9_]+)/i',
                 '/request:([a-z0-9_]+)/i',
-                '/cookie:([a-z0-9_]+)/i'
+                '/cookie:([a-z0-9_]+)/i',
+                '/browser:([a-z0-9_]+)/i'
             ),
             array(
                 "\$_SESSION['\\1']",
                 "\$this->app->config->get('\\1',get_boolean('\\3'))",
                 "\$this->env['\\1']",
                 "get_input_value('\\1', RCUBE_INPUT_GPC)",
-                "\$_COOKIE['\\1']"
+                "\$_COOKIE['\\1']",
+                "\$this->browser->{'\\1'}"
             ),
             $expression);
     }
@@ -511,37 +580,21 @@ class rcube_template extends rcube_html_page
      */
     private function parse_xml($input)
     {
-        return preg_replace_callback('/<roundcube:([-_a-z]+)\s+([^>]+)>/Ui', array($this, 'xml_command_callback'), $input);
+        return preg_replace_callback('/<roundcube:([-_a-z]+)\s+([^>]+)>/Ui', array($this, 'xml_command'), $input);
     }
 
 
     /**
-     * This is a callback function for preg_replace_callback (see #1485286)
-     * It's only purpose is to reconfigure parameters for xml_command, so that the signature isn't disturbed
-     */
-    private function xml_command_callback($matches)
-    {
-        $str_attrib = isset($matches[2]) ? $matches[2] : '';
-        $add_attrib = isset($matches[3]) ? $matches[3] : array();
-
-        $command = $matches[1];
-        //matches[0] is the entire matched portion of the string
-
-        return $this->xml_command($command, $str_attrib, $add_attrib);
-    }
-
-
-    /**
-     * Convert a xml command tag into real content
+     * Callback function for parsing an xml command tag
+     * and turn it into real html content
      *
-     * @param  string Tag command: object,button,label, etc.
-     * @param  string Attribute string
+     * @param  array Matches array of preg_replace_callback
      * @return string Tag/Object content
      */
-    private function xml_command($command, $str_attrib, $add_attrib = array())
+    private function xml_command($matches)
     {
-        $command = strtolower($command);
-        $attrib  = parse_attrib_string($str_attrib) + $add_attrib;
+        $command = strtolower($matches[1]);
+        $attrib  = parse_attrib_string($matches[2]);
 
         // empty output if required condition is not met
         if (!empty($attrib['condition']) && !$this->check_condition($attrib['condition'])) {
@@ -572,67 +625,71 @@ class rcube_template extends rcube_html_page
                         $incl = $this->include_php($path);
                     }
                     else {
-                       $incl = file_get_contents($path);
-                   }
+                      $incl = file_get_contents($path);
+                    }
+                    $incl = $this->parse_conditions($incl);
                     return $this->parse_xml($incl);
                 }
                 break;
 
             case 'plugin.include':
-                //rcube::tfk_debug(var_export($this->config['skin_path'], true));
-                $path = realpath($this->config['skin_path'].$attrib['file']);
-                if (!$path) {
-                    //rcube::tfk_debug("Does not exist:");
-                    //rcube::tfk_debug($this->config['skin_path']);
-                    //rcube::tfk_debug($attrib['file']);
-                    //rcube::tfk_debug($path);
-                }
-                $incl = file_get_contents($path);
-                if ($incl) {
-                    return $this->parse_xml($incl);
+                $hook = $this->app->plugins->exec_hook("template_plugin_include", $attrib);
+                return $hook['content'];
+                break;
+            
+            // define a container block
+            case 'container':
+                if ($attrib['name'] && $attrib['id']) {
+                    $this->command('gui_container', $attrib['name'], $attrib['id']);
+                    // let plugins insert some content here
+                    $hook = $this->app->plugins->exec_hook("template_container", $attrib);
+                    return $hook['content'];
                 }
                 break;
 
             // return code for a specific application object
             case 'object':
                 $object = strtolower($attrib['name']);
+                $content = '';
 
                 // we are calling a class/method
                 if (($handler = $this->object_handlers[$object]) && is_array($handler)) {
                     if ((is_object($handler[0]) && method_exists($handler[0], $handler[1])) ||
                     (is_string($handler[0]) && class_exists($handler[0])))
-                    return call_user_func($handler, $attrib);
+                    $content = call_user_func($handler, $attrib);
                 }
+                // execute object handler function
                 else if (function_exists($handler)) {
-                    // execute object handler function
-                    return call_user_func($handler, $attrib);
+                    $content = call_user_func($handler, $attrib);
                 }
-
-                if ($object=='productname') {
+                else if ($object == 'productname') {
                     $name = !empty($this->config['product_name']) ? $this->config['product_name'] : 'RoundCube Webmail';
-                    return Q($name);
+                    $content = Q($name);
                 }
-                if ($object=='version') {
+                else if ($object == 'version') {
                     $ver = (string)RCMAIL_VERSION;
                     if (is_file(INSTALL_PATH . '.svn/entries')) {
                         if (preg_match('/Revision:\s(\d+)/', @shell_exec('svn info'), $regs))
                           $ver .= ' [SVN r'.$regs[1].']';
                     }
-                    return $ver;
+                    $content = Q($ver);
                 }
-                if ($object=='steptitle') {
-                  return Q($this->get_pagetitle());
+                else if ($object == 'steptitle') {
+                  $content = Q($this->get_pagetitle());
                 }
-                if ($object=='pagetitle') {
+                else if ($object == 'pagetitle') {
                     $title = !empty($this->config['product_name']) ? $this->config['product_name'].' :: ' : '';
                     $title .= $this->get_pagetitle();
-                    return Q($title);
+                    $content = Q($title);
                 }
-                break;
+                
+                // exec plugin hooks for this template object
+                $hook = $this->app->plugins->exec_hook("template_object_$object", $attrib + array('content' => $content));
+                return $hook['content'];
 
             // return code for a specified eval expression
             case 'exp':
-               $value = $this->parse_expression($attrib['expression']);
+                $value = $this->parse_expression($attrib['expression']);
                 return eval("return Q($value);");
             
             // return variable
@@ -660,6 +717,9 @@ class rcube_template extends rcube_html_page
                     case 'cookie':
                         $value = htmlspecialchars($_COOKIE[$name]);
                         break;
+                    case 'browser':
+                        $value = $this->browser->{$name};
+                        break;
                 }
 
                 if (is_array($value)) {
@@ -702,7 +762,7 @@ class rcube_template extends rcube_html_page
         static $s_button_count = 100;
 
         // these commands can be called directly via url
-        $a_static_commands = array('compose', 'list');
+        $a_static_commands = array('compose', 'list', 'preferences', 'folders', 'identities');
 
         if (!($attrib['command'] || $attrib['name'])) {
             return '';
@@ -741,18 +801,18 @@ class rcube_template extends rcube_html_page
         }
         // get localized text for labels and titles
         if ($attrib['title']) {
-            $attrib['title'] = Q(rcube_label($attrib['title']));
+            $attrib['title'] = Q(rcube_label($attrib['title'], $attrib['domain']));
         }
         if ($attrib['label']) {
-            $attrib['label'] = Q(rcube_label($attrib['label']));
+            $attrib['label'] = Q(rcube_label($attrib['label'], $attrib['domain']));
         }
         if ($attrib['alt']) {
-            $attrib['alt'] = Q(rcube_label($attrib['alt']));
+            $attrib['alt'] = Q(rcube_label($attrib['alt'], $attrib['domain']));
         }
+
         // set title to alt attribute for IE browsers
-        if ($this->browser->ie && $attrib['title'] && !$attrib['alt']) {
-            $attrib['alt'] = $attrib['title'];
-            unset($attrib['title']);
+        if ($this->browser->ie && !$attrib['title'] && $attrib['alt']) {
+            $attrib['title'] = $attrib['alt'];
         }
 
         // add empty alt attribute for XHTML compatibility
@@ -781,7 +841,7 @@ class rcube_template extends rcube_html_page
                 $attrib['href'] = rcmail_url($attrib['command']);
             }
             else if ($attrib['command'] == 'permaurl' && !empty($this->env['permaurl'])) {
-                $attrib['href'] = $this->env['permaurl'];
+              $attrib['href'] = $this->env['permaurl'];
             }
         }
 
@@ -797,35 +857,6 @@ class rcube_template extends rcube_html_page
                 $attrib['prop']
             );
         }
-        if ($command && $attrib['imageover']) {
-            $attrib['onmouseover'] = sprintf(
-                "return %s.button_over('%s','%s')",
-                JS_OBJECT_NAME,
-                $command,
-                $attrib['id']
-            );
-            $attrib['onmouseout'] = sprintf(
-                "return %s.button_out('%s','%s')",
-                JS_OBJECT_NAME,
-                $command,
-                $attrib['id']
-            );
-        }
-
-        if ($command && $attrib['imagesel']) {
-            $attrib['onmousedown'] = sprintf(
-                "return %s.button_sel('%s','%s')",
-                JS_OBJECT_NAME,
-                $command,
-                $attrib['id']
-            );
-            $attrib['onmouseup'] = sprintf(
-                "return %s.button_out('%s','%s')",
-                JS_OBJECT_NAME,
-                $command,
-                $attrib['id']
-            );
-        }
 
         $out = '';
 
@@ -834,19 +865,18 @@ class rcube_template extends rcube_html_page
             $attrib_str = html::attrib_string(
                 $attrib,
                 array(
-                    'style', 'class', 'id', 'width',
-                    'height', 'border', 'hspace',
-                    'vspace', 'align', 'alt', 'tabindex'
+                    'style', 'class', 'id', 'width', 'height', 'border', 'hspace',
+                    'vspace', 'align', 'alt', 'tabindex', 'title'
                 )
             );
             $btn_content = sprintf('<img src="%s"%s />', $this->abs_url($attrib['image']), $attrib_str);
             if ($attrib['label']) {
                 $btn_content .= ' '.$attrib['label'];
             }
-            $link_attrib = array('href', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup', 'title', 'target');
+            $link_attrib = array('href', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup', 'target');
         }
         else if ($attrib['type']=='link') {
-            $btn_content = $attrib['label'] ? $attrib['label'] : $attrib['command'];
+            $btn_content = isset($attrib['content']) ? $attrib['content'] : ($attrib['label'] ? $attrib['label'] : $attrib['command']);
             $link_attrib = array('href', 'onclick', 'title', 'id', 'class', 'style', 'tabindex', 'target');
         }
         else if ($attrib['type']=='input') {
@@ -859,8 +889,7 @@ class rcube_template extends rcube_html_page
             $attrib_str = html::attrib_string(
                 $attrib,
                 array(
-                    'type', 'value', 'onclick',
-                    'id', 'class', 'style', 'tabindex'
+                    'type', 'value', 'onclick', 'id', 'class', 'style', 'tabindex'
                 )
             );
             $out = sprintf('<input%s disabled="disabled" />', $attrib_str);
@@ -887,7 +916,7 @@ class rcube_template extends rcube_html_page
      */
     public function form_tag($attrib, $content = null)
     {
-      if ($this->framed) {
+      if ($this->framed || !empty($_REQUEST['_framed'])) {
         $hiddenfield = new html_hiddenfield(array('name' => '_framed', 'value' => '1'));
         $hidden = $hiddenfield->show();
       }
@@ -897,7 +926,36 @@ class rcube_template extends rcube_html_page
       
       return html::tag('form',
         $attrib + array('action' => "./", 'method' => "get"),
-        $hidden . $content);
+        $hidden . $content,
+        array('id','class','style','name','method','action','enctype','onsubmit'));
+    }
+    
+    
+    /**
+     * Build a form tag with a unique request token
+     *
+     * @param array Named tag parameters including 'action' and 'task' values which will be put into hidden fields
+     * @param string Form content
+     * @return string HTML code for the form
+     */
+    public function request_form($attrib, $content = '')
+    {
+        $hidden = new html_hiddenfield();
+        if ($attrib['task']) {
+            $hidden->add(array('name' => '_task', 'value' => $attrib['task']));
+        }
+        if ($attrib['action']) {
+            $hidden->add(array('name' => '_action', 'value' => $attrib['action']));
+        }
+      
+        unset($attrib['task'], $attrib['request']);
+        $attrib['action'] = './';
+      
+        // we already have a <form> tag
+        if ($attrib['form'])
+            return $hidden->show() . $content;
+        else
+            return $this->form_tag($attrib, $hidden->show() . $content);
     }
 
 
@@ -941,11 +999,17 @@ class rcube_template extends rcube_html_page
         $default_host = $this->config['default_host'];
 
         $_SESSION['temp'] = true;
+        
+        // save original url
+        $url = get_input_value('_url', RCUBE_INPUT_POST);
+        if (empty($url) && !preg_match('/_(task|action)=logout/', $_SERVER['QUERY_STRING']))
+            $url = $_SERVER['QUERY_STRING'];
 
         $input_user   = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser', 'size' => 30) + $attrib);
         $input_pass   = new html_passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'size' => 30) + $attrib);
         $input_action = new html_hiddenfield(array('name' => '_action', 'value' => 'login'));
         $input_tzone  = new html_hiddenfield(array('name' => '_timezone', 'id' => 'rcmlogintz', 'value' => '_default_'));
+        $input_url    = new html_hiddenfield(array('name' => '_url', 'id' => 'rcmloginurl', 'value' => $url));
         $input_host   = null;
 
         if (is_array($default_host)) {
@@ -985,6 +1049,7 @@ class rcube_template extends rcube_html_page
 
         $out = $input_action->show();
         $out .= $input_tzone->show();
+        $out .= $input_url->show();
         $out .= $table->show();
 
         // surround html output with a form tag
index 17debeb7ad056fb9b5421e5da95f5530f008c1eb..54a76c5abe67b615d4e8923c4beedcbf10f7c6ac 100644 (file)
@@ -135,12 +135,12 @@ class rcube_user
    * Get default identity of this user
    *
    * @param int  Identity ID. If empty, the default identity is returned
-   * @return array Hash array with all cols of the 
+   * @return array Hash array with all cols of the identity record
    */
   function get_identity($id = null)
   {
-    $sql_result = $this->list_identities($id ? sprintf('AND identity_id=%d', $id) : '');
-    return $this->db->fetch_assoc($sql_result);
+    $result = $this->list_identities($id ? sprintf('AND identity_id=%d', $id) : '');
+    return $result[0];
   }
   
   
@@ -160,7 +160,12 @@ class rcube_user
        ORDER BY ".$this->db->quoteIdentifier('standard')." DESC, name ASC, identity_id ASC",
       $this->ID);
     
-    return $sql_result;
+    $result = array();
+    while ($sql_arr = $this->db->fetch_assoc($sql_result)) {
+      $result[] = $sql_arr;
+    }
+    
+    return $result;
   }
   
   
@@ -176,23 +181,24 @@ class rcube_user
     if (!$this->ID)
       return false;
     
-    $write_sql = array();
+    $query_cols = $query_params = array();
     
     foreach ((array)$data as $col => $value)
     {
-      $write_sql[] = sprintf("%s=%s",
-        $this->db->quoteIdentifier($col),
-        $this->db->quote($value));
+      $query_cols[] = $this->db->quoteIdentifier($col) . '=?';
+      $query_params[] = $value;
     }
-    
-    $this->db->query(
-      "UPDATE ".get_table_name('identities')."
-       SET ".join(', ', $write_sql)."
+    $query_params[] = $iid;
+    $query_params[] = $this->ID;
+
+    $sql = "UPDATE ".get_table_name('identities')."
+       SET ".join(', ', $query_cols)."
        WHERE  identity_id=?
        AND    user_id=?
-       AND    del<>1",
-      $iid,
-      $this->ID);
+       AND    del<>1";
+
+    call_user_func_array(array($this->db, 'query'),
+                        array_merge(array($sql), $query_params));
     
     return $this->db->affected_rows();
   }
@@ -213,16 +219,19 @@ class rcube_user
     foreach ((array)$data as $col => $value)
     {
       $insert_cols[] = $this->db->quoteIdentifier($col);
-      $insert_values[] = $this->db->quote($value);
+      $insert_values[] = $value;
     }
+    $insert_cols[] = 'user_id';
+    $insert_values[] = $this->ID;
 
-    $this->db->query(
-      "INSERT INTO ".get_table_name('identities')."
-        (user_id, ".join(', ', $insert_cols).")
-       VALUES (?, ".join(', ', $insert_values).")",
-      $this->ID);
+    $sql = "INSERT INTO ".get_table_name('identities')."
+        (".join(', ', $insert_cols).")
+       VALUES (".join(', ', array_pad(array(), sizeof($insert_values), '?')).")";
 
-    return $this->db->insert_id(get_sequence_name('identities'));
+    call_user_func_array(array($this->db, 'query'),
+                        array_merge(array($sql), $insert_values));
+
+    return $this->db->insert_id('identities');
   }
   
   
@@ -346,49 +355,93 @@ class rcube_user
    */
   static function create($user, $host)
   {
+    $user_name  = '';
     $user_email = '';
     $rcmail = rcmail::get_instance();
-    $dbh = $rcmail->get_dbh();
 
     // try to resolve user in virtuser table and file
     if (!strpos($user, '@')) {
-      if ($email_list = self::user2email($user, false))
-        $user_email = $email_list[0];
+      if ($email_list = self::user2email($user, false, true))
+        $user_email = is_array($email_list[0]) ? $email_list[0][0] : $email_list[0];
     }
-    
+
+    $data = $rcmail->plugins->exec_hook('create_user',
+       array('user'=>$user, 'user_name'=>$user_name, 'user_email'=>$user_email));
+
+    // plugin aborted this operation
+    if ($data['abort'])
+      return false;
+
+    $user_name = $data['user_name'];
+    $user_email = $data['user_email'];
+
+    $dbh = $rcmail->get_dbh();
+
     $dbh->query(
       "INSERT INTO ".get_table_name('users')."
         (created, last_login, username, mail_host, alias, language)
        VALUES (".$dbh->now().", ".$dbh->now().", ?, ?, ?, ?)",
       strip_newlines($user),
       strip_newlines($host),
-      strip_newlines($user_email),
+      strip_newlines($data['alias'] ? $data['alias'] : $user_email),
       $_SESSION['language']);
 
-    if ($user_id = $dbh->insert_id(get_sequence_name('users')))
+    if ($user_id = $dbh->insert_id('users'))
     {
+      // create rcube_user instance to make plugin hooks work
+      $user_instance = new rcube_user($user_id);
+      $rcmail->user = $user_instance;
+
       $mail_domain = $rcmail->config->mail_domain($host);
 
       if ($user_email=='')
         $user_email = strpos($user, '@') ? $user : sprintf('%s@%s', $user, $mail_domain);
 
-      $user_name = $user != $user_email ? $user : '';
+      if ($user_name == '') {
+        $user_name = $user != $user_email ? $user : '';
+      }
 
       if (empty($email_list))
-        $email_list[] = strip_newlines($user_email); 
+        $email_list[] = strip_newlines($user_email);
+      // identities_level check
+      else if (count($email_list) > 1 && $rcmail->config->get('identities_level', 0) > 1)
+        $email_list = array($email_list[0]);
 
-      // also create new identity records
+      // create new identities records
       $standard = 1;
-      foreach ($email_list as $email) {
-        $dbh->query(
-            "INSERT INTO ".get_table_name('identities')."
-              (user_id, del, standard, name, email)
-             VALUES (?, 0, ?, ?, ?)",
-            $user_id,
-           $standard,
-            strip_newlines($user_name),
-            preg_replace('/^@/', $user . '@', $email));
-       $standard = 0;
+      foreach ($email_list as $row) {
+        if (is_array($row)) {
+          $email = $row[0];
+          $name = $row[1] ? $row[1] : $user_name;
+        }
+        else {
+          $email = $row;
+          $name = $user_name;
+        }
+
+        $plugin = $rcmail->plugins->exec_hook('create_identity', array(
+          'login' => true,
+          'record' => array(
+            'user_id' => $user_id,
+            'name' => strip_newlines($name),
+            'email' => $email,
+            'standard' => $standard,
+            'signature' => '',
+          ),
+        ));
+          
+        if (!$plugin['abort'] && $plugin['record']['email']) {
+          $dbh->query(
+              "INSERT INTO ".get_table_name('identities')."
+                (user_id, del, standard, name, email, signature)
+               VALUES (?, 0, ?, ?, ?, ?)",
+              $user_id,
+              $plugin['record']['standard'],
+              $plugin['record']['name'] != NULL ? $plugin['record']['name'] : '',
+              $plugin['record']['email'],
+              $plugin['record']['signature']);
+        }
+        $standard = 0;
       }
     }
     else
@@ -401,7 +454,7 @@ class rcube_user
         'message' => "Failed to create new user"), true, false);
     }
     
-    return $user_id ? new rcube_user($user_id) : false;
+    return $user_id ? $user_instance : false;
   }
   
   
@@ -413,7 +466,7 @@ class rcube_user
    */
   static function email2user($email)
   {
-    $r = self::findinvirtual('^' . quotemeta($email) . '[[:space:]]');
+    $r = self::findinvirtual('/^' . preg_quote($email, '/') . '\s/');
 
     for ($i=0; $i<count($r); $i++)
     {
@@ -432,9 +485,10 @@ class rcube_user
    *
    * @param string User name
    * @param boolean If true returns first found entry
+   * @param boolean If true returns email as array (email and name for identity)
    * @return mixed Resolved e-mail address string or array of strings
    */
-  static function user2email($user, $first=true)
+  static function user2email($user, $first=true, $extended=false)
   {
     $result = array();
     $rcmail = rcmail::get_instance();
@@ -445,13 +499,13 @@ class rcube_user
       $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escapeSimple($user), $virtuser_query));
       while ($sql_arr = $dbh->fetch_array($sql_result))
         if (strpos($sql_arr[0], '@')) {
-          $result[] = $sql_arr[0];
-         if ($first)
-           return $result[0];
-       }
+          $result[] = ($extended && count($sql_arr) > 1) ? $sql_arr : $sql_arr[0];
+          if ($first)
+            return $result[0];
+        }
     }
     // File lookup
-    $r = self::findinvirtual('[[:space:]]' . quotemeta($user) . '[[:space:]]*$');
+    $r = self::findinvirtual('/\s' . preg_quote($user, '/') . '\s*$/');
     for ($i=0; $i<count($r); $i++)
     {
       $data = $r[$i];
@@ -460,7 +514,7 @@ class rcube_user
       {
         $result[] = trim(str_replace('\\@', '@', $arr[0]));
 
-       if ($first)
+        if ($first)
           return $result[0];
       }
     }
@@ -493,7 +547,7 @@ class rcube_user
       if (empty($line) || $line{0}=='#')
         continue;
         
-      if (eregi($pattern, $line))
+      if (preg_match($pattern, $line))
         $result[] = $line;
     }
     
index ce5087a0fef20ce00cd880bc63eb5bd8757fa76c..7dbbb3f71da22fdbe13b4f9fc8706d3aea4e8824 100644 (file)
@@ -263,15 +263,15 @@ class rcube_vcard
           $line[1] .= ';' . (strpos($prop, '=') ? $prop : 'TYPE='.$prop);
       }
 
-      if (!preg_match('/^(BEGIN|END)$/', $line[1]) && preg_match_all('/([^\\;]+);?/', $line[1], $regs2)) {
-        $entry = array('');
-        $field = $regs2[1][0];
+      if (!preg_match('/^(BEGIN|END)$/i', $line[1]) && preg_match_all('/([^\\;]+);?/', $line[1], $regs2)) {
+        $entry = array();
+        $field = strtoupper($regs2[1][0]);
 
         foreach($regs2[1] as $attrid => $attr) {
           if ((list($key, $value) = explode('=', $attr)) && $value) {
             if ($key == 'ENCODING') {
-              # add next line(s) to value string if QP line end detected
-              while ($value == 'QUOTED-PRINTABLE' && ereg('=$', $lines[$i]))
+              // add next line(s) to value string if QP line end detected
+              while ($value == 'QUOTED-PRINTABLE' && preg_match('/=$/', $lines[$i]))
                   $line[2] .= "\n" . $lines[++$i];
               
               $line[2] = self::decode_value($line[2], $value);
@@ -280,17 +280,16 @@ class rcube_vcard
               $entry[strtolower($key)] = array_merge((array)$entry[strtolower($key)], (array)self::vcard_unquote($value, ','));
           }
           else if ($attrid > 0) {
-            $entry[$key] = true;  # true means attr without =value
+            $entry[$key] = true;  // true means attr without =value
           }
         }
 
-        $entry[0] = self::vcard_unquote($line[2]);
+        $entry = array_merge($entry, (array)self::vcard_unquote($line[2]));
         $data[$field][] = count($entry) > 1 ? $entry : $entry[0];
       }
     }
 
     unset($data['VERSION']);
-
     return $data;
   }
 
@@ -360,7 +359,7 @@ class rcube_vcard
             if (is_int($attrname))
               $value[] = $attrvalues;
             elseif ($attrvalues === true)
-              $attr .= ";$attrname";    # true means just tag, not tag=value, as in PHOTO;BASE64:...
+              $attr .= ";$attrname";    // true means just tag, not tag=value, as in PHOTO;BASE64:...
             else {
               foreach((array)$attrvalues as $attrvalue)
                 $attr .= ";$attrname=" . self::vcard_quote($attrvalue, ',');
index b1ff1d2569192d7d11417b002edbd4a86c198d74..35bd1b869cc257d73ddca96202bd0ba72660cb87 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: session.inc 2237 2009-01-17 01:55:39Z till $
+ $Id: session.inc 2573 2009-05-29 19:10:24Z alec $
 
 */
 
+$GLOBALS['rcube_session_unsets'] = array();
 
 function rcube_sess_open($save_path, $session_name)
 {
@@ -39,10 +40,6 @@ function rcube_sess_read($key)
   
   $DB = rcmail::get_instance()->get_dbh();
   
-  if ($DB->is_error()) {
-    return false;
-  }
-  
   $sql_result = $DB->query(
     "SELECT vars, ip, " . $DB->unixtimestamp('changed') . " AS changed
      FROM " . get_table_name('session') . "
@@ -66,23 +63,23 @@ function rcube_sess_write($key, $vars)
 {
   $DB = rcmail::get_instance()->get_dbh();
   
-  if ($DB->is_error()) {
-    return false;
-  }
+  $now = $DB->fromunixtime(time());
 
   $sql_result = $DB->query(
-    "SELECT 1 FROM " . get_table_name('session') . "
-     WHERE  sess_id=?",
-    $key);
+    "SELECT vars FROM " . get_table_name('session') . "
+     WHERE  sess_id=?", $key);
 
-  $now = $DB->fromunixtime(time());
+  if ($sql_arr = $DB->fetch_assoc($sql_result)) {
+
+    $a_oldvars = rcube_sess_unserialize($sql_arr['vars']);
+    foreach ((array)$GLOBALS['rcube_session_unsets'] as $k)
+      unset($a_oldvars[$k]);
 
-  if ($DB->num_rows($sql_result)) {
     $DB->query(
       "UPDATE " . get_table_name('session') . "
        SET    vars=?, changed= " . $now . "
        WHERE  sess_id=?",
-      $vars,
+      rcube_sess_serialize(array_merge($a_oldvars, rcube_sess_unserialize($vars))),
       $key);
   }
   else {
@@ -95,20 +92,129 @@ function rcube_sess_write($key, $vars)
       (string)$_SERVER['REMOTE_ADDR']);
   }
 
+  $GLOBALS['rcube_session_unsets'] = array();
+  return true;
+}
+
+
+// unset session variable
+function rcube_sess_unset($var=NULL)
+{
+  if (empty($var))
+    return rcube_sess_destroy(session_id());
+
+  $GLOBALS['rcube_session_unsets'][] = $var;
+  unset($_SESSION[$var]);
+
   return true;
 }
 
 
+// serialize session data
+function rcube_sess_serialize($vars)
+{
+  $data = '';
+  if (is_array($vars))
+    foreach ($vars as $var=>$value)
+      $data .= $var.'|'.serialize($value);
+  else
+    $data = 'b:0;';
+  return $data;
+}
+
+
+// unserialize session data
+// http://www.php.net/manual/en/function.session-decode.php#56106
+function rcube_sess_unserialize($str)
+{
+  $str = (string)$str;
+  $endptr = strlen($str);
+  $p = 0;
+
+  $serialized = '';
+  $items = 0;
+  $level = 0;
+
+  while ($p < $endptr) {
+    $q = $p;
+    while ($str[$q] != '|')
+      if (++$q >= $endptr) break 2;
+
+    if ($str[$p] == '!') {
+      $p++;
+      $has_value = false;
+    } else {
+      $has_value = true;
+    }
+
+    $name = substr($str, $p, $q - $p);
+    $q++;
+
+    $serialized .= 's:' . strlen($name) . ':"' . $name . '";';
+
+    if ($has_value) {
+      for (;;) {
+        $p = $q;
+        switch (strtolower($str[$q])) {
+          case 'n': /* null */
+          case 'b': /* boolean */
+          case 'i': /* integer */
+          case 'd': /* decimal */
+            do $q++;
+            while ( ($q < $endptr) && ($str[$q] != ';') );
+            $q++;
+            $serialized .= substr($str, $p, $q - $p);
+            if ($level == 0) break 2;
+            break;
+          case 'r': /* reference  */
+            $q+= 2;
+            for ($id = ''; ($q < $endptr) && ($str[$q] != ';'); $q++) $id .= $str[$q];
+            $q++;
+            $serialized .= 'R:' . ($id + 1) . ';'; /* increment pointer because of outer array */
+            if ($level == 0) break 2;
+            break;
+          case 's': /* string */
+            $q+=2;
+            for ($length=''; ($q < $endptr) && ($str[$q] != ':'); $q++) $length .= $str[$q];
+            $q+=2;
+            $q+= (int)$length + 2;
+            $serialized .= substr($str, $p, $q - $p);
+            if ($level == 0) break 2;
+            break;
+          case 'a': /* array */
+          case 'o': /* object */
+            do $q++;
+            while ( ($q < $endptr) && ($str[$q] != '{') );
+            $q++;
+            $level++;
+            $serialized .= substr($str, $p, $q - $p);
+            break;
+          case '}': /* end of array|object */
+            $q++;
+            $serialized .= substr($str, $p, $q - $p);
+            if (--$level == 0) break 2;
+            break;
+          default:
+            return false;
+        }
+      }
+    } else {
+      $serialized .= 'N;';
+      $q+= 2;
+    }
+    $items++;
+    $p = $q;
+  }
+
+  return unserialize( 'a:' . $items . ':{' . $serialized . '}' );
+}
+
+
 // handler for session_destroy()
 function rcube_sess_destroy($key)
 {
-  $rcmail = rcmail::get_instance();
-  $DB = $rcmail->get_dbh();
+  $DB = rcmail::get_instance()->get_dbh();
   
-  if ($DB->is_error()) {
-    return false;
-  }
-
   $DB->query("DELETE FROM " . get_table_name('session') . " WHERE sess_id=?", $key);
 
   return true;
@@ -121,10 +227,6 @@ function rcube_sess_gc($maxlifetime)
   $rcmail = rcmail::get_instance();
   $DB = $rcmail->get_dbh();
 
-  if ($DB->is_error()) {
-    return false;
-  }
-
   // just delete all expired sessions
   $DB->query("DELETE FROM " . get_table_name('session') . "
     WHERE changed < " . $DB->fromunixtime(time() - $maxlifetime));
index da37e1287490e1bf9229b953d9e2afee61420b41..5d1903fcce7758e1e0aba5a2e0fdbdd8508c9551 100644 (file)
-var rcube_webmail_client;
-function rcube_webmail(){
-this.env=new Object();
-this.labels=new Object();
-this.buttons=new Object();
-this.gui_objects=new Object();
-this.commands=new Object();
-this.onloads=new Array();
-rcube_webmail_client=this;
-this.ref="rcube_webmail_client";
-var _1=this;
-this.dblclick_time=500;
-this.message_time=3000;
-this.identifier_expr=new RegExp("[^0-9a-z-_]","gi");
-this.mimetypes=new Array("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.bin_path="./bin/";
-this.env.blankpage="program/blank.gif";
-this.set_env=function(p,_3){
-if(p!=null&&typeof (p)=="object"&&!_3){
-for(var n in p){
-this.env[n]=p[n];
-}
-}else{
-this.env[p]=_3;
-}
-};
-this.add_label=function(_5,_6){
-this.labels[_5]=_6;
-};
-this.register_button=function(_7,id,_9,_a,_b,_c){
-if(!this.buttons[_7]){
-this.buttons[_7]=new Array();
-}
-var _d={id:id,type:_9};
-if(_a){
-_d.act=_a;
-}
-if(_b){
-_d.sel=_b;
-}
-if(_c){
-_d.over=_c;
-}
-this.buttons[_7][this.buttons[_7].length]=_d;
-};
-this.gui_object=function(_e,id){
-this.gui_objects[_e]=id;
-};
-this.add_onload=function(f){
-this.onloads[this.onloads.length]=f;
-};
-this.init=function(){
-var p=this;
-this.task=this.env.task;
-if(!bw.dom||!bw.xmlhttp_test()){
-this.goto_url("error","_code=0x199");
-return;
-}
-for(var n in this.gui_objects){
-this.gui_objects[n]=rcube_find_object(this.gui_objects[n]);
-}
-if(this.env.framed&&parent.rcmail&&parent.rcmail.set_busy){
-parent.rcmail.set_busy(false);
-}
-this.enable_command("logout","mail","addressbook","settings",true);
-if(this.env.permaurl){
-this.enable_command("permaurl",true);
-}
-switch(this.task){
-case "mail":
-if(this.gui_objects.messagelist){
-this.message_list=new rcube_list_widget(this.gui_objects.messagelist,{multiselect:true,draggable:true,keyboard:true,dblclick_time:this.dblclick_time});
-this.message_list.row_init=function(o){
-p.init_message_row(o);
-};
-this.message_list.addEventListener("dblclick",function(o){
-p.msglist_dbl_click(o);
-});
-this.message_list.addEventListener("keypress",function(o){
-p.msglist_keypress(o);
-});
-this.message_list.addEventListener("select",function(o){
-p.msglist_select(o);
-});
-this.message_list.addEventListener("dragstart",function(o){
-p.drag_start(o);
-});
-this.message_list.addEventListener("dragmove",function(o,e){
-p.drag_move(e);
-});
-this.message_list.addEventListener("dragend",function(o){
-p.drag_active=false;
-});
-this.message_list.init();
-this.enable_command("toggle_status","toggle_flag",true);
-if(this.gui_objects.mailcontframe){
-this.gui_objects.mailcontframe.onmousedown=function(e){
-return p.click_on_list(e);
-};
-document.onmouseup=function(e){
-return p.doc_mouse_up(e);
-};
-}else{
-this.message_list.focus();
-}
-}
-if(this.env.coltypes){
-this.set_message_coltypes(this.env.coltypes);
-}
-this.enable_command("list","checkmail","compose","add-contact","search","reset-search","collapse-folder",true);
-if(this.env.search_text!=null&&document.getElementById("quicksearchbox")!=null){
-document.getElementById("quicksearchbox").value=this.env.search_text;
-}
-if(this.env.action=="show"||this.env.action=="preview"){
-this.enable_command("show","reply","reply-all","forward","moveto","delete","mark","viewsource","print","load-attachment","load-headers",true);
-if(this.env.next_uid){
-this.enable_command("nextmessage",true);
-this.enable_command("lastmessage",true);
-}
-if(this.env.prev_uid){
-this.enable_command("previousmessage",true);
-this.enable_command("firstmessage",true);
-}
-}
-if(this.env.trash_mailbox&&this.env.mailbox!=this.env.trash_mailbox){
-this.set_alttext("delete","movemessagetotrash");
-}
-if(this.env.action=="preview"&&this.env.framed&&parent.rcmail){
-this.enable_command("compose","add-contact",false);
-parent.rcmail.show_contentframe(true);
-}
-if((this.env.action=="show"||this.env.action=="preview")&&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=="compose"){
-this.enable_command("add-attachment","send-attachment","remove-attachment","send",true);
-if(this.env.spellcheck){
-this.env.spellcheck.spelling_state_observer=function(s){
-_1.set_spellcheck_state(s);
-};
-this.set_spellcheck_state("ready");
-if(rcube_find_object("_is_html").value=="1"){
-this.display_spellcheck_controls(false);
-}
-}
-if(this.env.drafts_mailbox){
-this.enable_command("savedraft",true);
-}
-document.onmouseup=function(e){
-return p.doc_mouse_up(e);
-};
-}
-if(this.env.messagecount){
-this.enable_command("select-all","select-none","expunge",true);
-}
-if(this.purge_mailbox_test()){
-this.enable_command("purge",true);
-}
-this.set_page_buttons();
-if(this.env.action=="compose"){
-this.init_messageform();
-}
-if(this.env.action=="print"){
-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){
-var _1f="_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox);
-if(confirm(this.get_label("mdnrequest"))){
-this.http_post("sendmdn",_1f);
-}else{
-this.http_post("mark",_1f+"&_flag=mdnsent");
-}
-}
-break;
-case "addressbook":
-if(this.gui_objects.contactslist){
-this.contact_list=new rcube_list_widget(this.gui_objects.contactslist,{multiselect:true,draggable:true,keyboard:true});
-this.contact_list.addEventListener("keypress",function(o){
-p.contactlist_keypress(o);
-});
-this.contact_list.addEventListener("select",function(o){
-p.contactlist_select(o);
-});
-this.contact_list.addEventListener("dragstart",function(o){
-p.drag_start(o);
-});
-this.contact_list.addEventListener("dragmove",function(o,e){
-p.drag_move(e);
-});
-this.contact_list.addEventListener("dragend",function(o){
-p.drag_active=false;
-});
-this.contact_list.init();
-if(this.env.cid){
-this.contact_list.highlight_row(this.env.cid);
-}
-if(this.gui_objects.contactslist.parentNode){
-this.gui_objects.contactslist.parentNode.onmousedown=function(e){
-return p.click_on_list(e);
-};
-document.onmouseup=function(e){
-return p.doc_mouse_up(e);
-};
-}else{
-this.contact_list.focus();
-}
-}
-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",true);
-}
-if(this.env.cid){
-this.enable_command("show","edit",true);
-}
-if((this.env.action=="add"||this.env.action=="edit")&&this.gui_objects.editform){
-this.enable_command("save",true);
-}else{
-this.enable_command("search","reset-search","moveto","import",true);
-}
-if(this.contact_list&&this.contact_list.rowcount>0){
-this.enable_command("export",true);
-}
-this.enable_command("list",true);
-break;
-case "settings":
-this.enable_command("preferences","identities","save","folders",true);
-if(this.env.action=="identities"||this.env.action=="edit-identity"||this.env.action=="add-identity"){
-this.enable_command("add",this.env.identities_level<2);
-this.enable_command("delete","edit",true);
-}
-if(this.env.action=="edit-identity"||this.env.action=="add-identity"){
-this.enable_command("save",true);
-}
-if(this.env.action=="folders"){
-this.enable_command("subscribe","unsubscribe","create-folder","rename-folder","delete-folder",true);
-}
-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(o){
-p.identity_select(o);
-});
-this.identity_list.init();
-this.identity_list.focus();
-if(this.env.iid){
-this.identity_list.highlight_row(this.env.iid);
-}
-}
-if(this.gui_objects.subscriptionlist){
-this.init_subscription_list();
-}
-break;
-case "login":
-var _29=rcube_find_object("rcmloginuser");
-var _2a=rcube_find_object("rcmloginpwd");
-var _2b=rcube_find_object("rcmlogintz");
-if(_29){
-_29.onkeyup=function(e){
-return rcmail.login_user_keyup(e);
-};
-}
-if(_29&&_29.value==""){
-_29.focus();
-}else{
-if(_2a){
-_2a.focus();
-}
-}
-if(_2b){
-_2b.value=new Date().getTimezoneOffset()/-60;
-}
-this.enable_command("login",true);
-break;
-default:
-break;
-}
-this.enable_command("logout",true);
-this.loaded=true;
-if(this.pending_message){
-this.display_message(this.pending_message[0],this.pending_message[1]);
-}
-this.start_keepalive();
-for(var i=0;i<this.onloads.length;i++){
-if(typeof (this.onloads[i])=="string"){
-eval(this.onloads[i]);
-}else{
-if(typeof (this.onloads[i])=="function"){
-this.onloads[i]();
-}
-}
-}
-};
-this.start_keepalive=function(){
-if(this.env.keep_alive&&!this.env.framed&&this.task=="mail"&&this.gui_objects.mailboxlist){
-this._int=setInterval(function(){
-_1.check_for_recent(false);
-},this.env.keep_alive*1000);
-}else{
-if(this.env.keep_alive&&!this.env.framed&&this.task!="login"){
-this._int=setInterval(function(){
-_1.send_keep_alive();
-},this.env.keep_alive*1000);
-}
-}
-};
-this.init_message_row=function(row){
-var uid=row.uid;
-if(uid&&this.env.messages[uid]){
-row.deleted=this.env.messages[uid].deleted?true:false;
-row.unread=this.env.messages[uid].unread?true:false;
-row.replied=this.env.messages[uid].replied?true:false;
-row.flagged=this.env.messages[uid].flagged?true:false;
-row.forwarded=this.env.messages[uid].forwarded?true:false;
-}
-if((row.icon=row.obj.cells[0].childNodes[0])&&row.icon.nodeName=="IMG"){
-var p=this;
-row.icon.id="msgicn_"+row.uid;
-row.icon._row=row.obj;
-row.icon.onmousedown=function(e){
-p.command("toggle_status",this);
-};
-}
-if(!this.env.flagged_col&&this.env.coltypes){
-var _32;
-if((_32=find_in_array("flag",this.env.coltypes))>=0){
-this.set_env("flagged_col",_32+1);
-}
-}
-if(this.env.flagged_col&&(row.flagged_icon=row.obj.cells[this.env.flagged_col].childNodes[0])&&row.flagged_icon.nodeName=="IMG"){
-var p=this;
-row.flagged_icon.id="flaggedicn_"+row.uid;
-row.flagged_icon._row=row.obj;
-row.flagged_icon.onmousedown=function(e){
-p.command("toggle_flag",this);
-};
-}
-};
-this.init_messageform=function(){
-if(!this.gui_objects.messageform){
-return false;
-}
-var _34=rcube_find_object("_from");
-var _35=rcube_find_object("_to");
-var _36=rcube_find_object("_cc");
-var _37=rcube_find_object("_bcc");
-var _38=rcube_find_object("_replyto");
-var _39=rcube_find_object("_subject");
-var _3a=rcube_find_object("_message");
-var _3b=rcube_find_object("_draft_saveid");
-if(_35){
-this.init_address_input_events(_35);
-}
-if(_36){
-this.init_address_input_events(_36);
-}
-if(_37){
-this.init_address_input_events(_37);
-}
-if(_34&&_34.type=="select-one"&&(!_3b||_3b.value=="")&&rcube_find_object("_is_html").value!="1"){
-this.change_identity(_34);
-}
-if(_35&&_35.value==""){
-_35.focus();
-}else{
-if(_39&&_39.value==""){
-_39.focus();
-}else{
-if(_3a){
-this.set_caret2start(_3a);
-}
-}
-}
-this.compose_field_hash(true);
-this.auto_save_start();
-};
-this.init_address_input_events=function(obj){
-var _3d=function(e){
-return _1.ksearch_keypress(e,this);
-};
-if(obj.addEventListener){
-obj.addEventListener(bw.safari?"keydown":"keypress",_3d,false);
-}else{
-obj.onkeydown=_3d;
-}
-obj.setAttribute("autocomplete","off");
-};
-this.command=function(_3f,_40,obj){
-if(obj&&obj.blur){
-obj.blur();
-}
-if(this.busy){
-return false;
-}
-if(!this.commands[_3f]){
-if(this.env.framed&&parent.rcmail&&parent.rcmail.command){
-parent.rcmail.command(_3f,_40);
-}
-return false;
-}
-if(this.task=="mail"&&this.env.action=="compose"&&(_3f=="list"||_3f=="mail"||_3f=="addressbook"||_3f=="settings")){
-if(this.cmp_hash!=this.compose_field_hash()&&!confirm(this.get_label("notsentwarning"))){
-return false;
-}
-}
-switch(_3f){
-case "login":
-if(this.gui_objects.loginform){
-this.gui_objects.loginform.submit();
-}
-break;
-case "logout":
-this.goto_url("logout","",true);
-break;
-case "mail":
-case "addressbook":
-case "settings":
-this.switch_task(_3f);
-break;
-case "permaurl":
-if(obj&&obj.href&&obj.target){
-return true;
-}else{
-if(this.env.permaurl){
-parent.location.href=this.env.permaurl;
-}
-}
-break;
-case "list":
-if(this.task=="mail"){
-if(this.env.search_request<0||(_40!=""&&(this.env.search_request&&_40!=this.env.mailbox))){
-this.reset_qsearch();
-}
-this.list_mailbox(_40);
-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<0||(this.env.search_request&&_40!=this.env.source)){
-this.reset_qsearch();
-}
-this.list_contacts(_40);
-this.enable_command("add",(this.env.address_sources&&!this.env.address_sources[_40].readonly));
-}
-}
-break;
-case "load-headers":
-this.load_headers(obj);
-break;
-case "sort":
-var _42=_40.split("_");
-var _43=_42[0];
-var _44=_42[1]?_42[1].toUpperCase():null;
-var _45;
-if(_44==null){
-if(this.env.sort_col==_43){
-_44=this.env.sort_order=="ASC"?"DESC":"ASC";
-}else{
-_44=this.env.sort_order;
-}
-}
-if(this.env.sort_col==_43&&this.env.sort_order==_44){
-break;
-}
-if(_45=document.getElementById("rcm"+this.env.sort_col)){
-this.set_classname(_45,"sorted"+(this.env.sort_order.toUpperCase()),false);
-}
-if(_45=document.getElementById("rcm"+_43)){
-this.set_classname(_45,"sorted"+_44,true);
-}
-this.env.sort_col=_43;
-this.env.sort_order=_44;
-this.list_mailbox("","",_43+"_"+_44);
-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":
-if(this.env.messagecount){
-this.expunge_mailbox(this.env.mailbox);
-}
-break;
-case "purge":
-case "empty-mailbox":
-if(this.env.messagecount){
-this.purge_mailbox(this.env.mailbox);
-}
-break;
-case "show":
-if(this.task=="mail"){
-var uid=this.get_single_uid();
-if(uid&&(!this.env.uid||uid!=this.env.uid)){
-if(this.env.mailbox==this.env.drafts_mailbox){
-this.goto_url("compose","_draft_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true);
-}else{
-this.show_message(uid);
-}
-}
-}else{
-if(this.task=="addressbook"){
-var cid=_40?_40:this.get_single_cid();
-if(cid&&!(this.env.action=="show"&&cid==this.env.cid)){
-this.load_contact(cid,"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":
-var cid;
-if(this.task=="addressbook"&&(cid=this.get_single_cid())){
-this.load_contact(cid,"edit");
-}else{
-if(this.task=="settings"&&_40){
-this.load_identity(_40,"edit-identity");
-}
-}
-break;
-case "save-identity":
-case "save":
-if(this.gui_objects.editform){
-var _48=rcube_find_object("_pagesize");
-var _49=rcube_find_object("_name");
-var _4a=rcube_find_object("_email");
-if(_48&&isNaN(parseInt(_48.value))){
-alert(this.get_label("nopagesizewarning"));
-_48.focus();
-break;
-}else{
-if(_49&&_49.value==""){
-alert(this.get_label("nonamewarning"));
-_49.focus();
-break;
-}else{
-if(_4a&&!rcube_check_email(_4a.value)){
-alert(this.get_label("noemailwarning"));
-_4a.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{
-if(this.task=="settings"){
-this.delete_identity();
-}
-}
-}
-break;
-case "move":
-case "moveto":
-if(this.task=="mail"){
-this.move_messages(_40);
-}else{
-if(this.task=="addressbook"&&this.drag_active){
-this.copy_contact(null,_40);
-}
-}
-break;
-case "mark":
-if(_40){
-this.mark_message(_40);
-}
-break;
-case "toggle_status":
-if(_40&&!_40._row){
-break;
-}
-var uid;
-var _4b="read";
-if(_40._row.uid){
-uid=_40._row.uid;
-if(this.message_list.rows[uid].deleted){
-_4b="undelete";
-}else{
-if(!this.message_list.rows[uid].unread){
-_4b="unread";
-}
-}
-}
-this.mark_message(_4b,uid);
-break;
-case "toggle_flag":
-if(_40&&!_40._row){
-break;
-}
-var uid;
-var _4b="flagged";
-if(_40._row.uid){
-uid=_40._row.uid;
-if(this.message_list.rows[uid].flagged){
-_4b="unflagged";
-}
-}
-this.mark_message(_4b,uid);
-break;
-case "always-load":
-if(this.env.uid&&this.env.sender){
-this.add_contact(urlencode(this.env.sender));
-window.setTimeout(function(){
-_1.command("load-images");
-},300);
-break;
-}
-case "load-images":
-if(this.env.uid){
-this.show_message(this.env.uid,true,this.env.action=="preview");
-}
-break;
-case "load-attachment":
-var _4c="_mbox="+urlencode(this.env.mailbox)+"&_uid="+this.env.uid+"&_part="+_40.part;
-if(this.env.uid&&_40.mimetype&&find_in_array(_40.mimetype,this.mimetypes)>=0){
-if(_40.mimetype=="text/html"){
-_4c+="&_safe=1";
-}
-this.attachment_win=window.open(this.env.comm_path+"&_action=get&"+_4c+"&_frame=1","rcubemailattachment");
-if(this.attachment_win){
-window.setTimeout(function(){
-_1.attachment_win.focus();
-},10);
-break;
-}
-}
-this.goto_url("get",_4c+"&_download=1",false);
-break;
-case "select-all":
-this.message_list.select_all(_40);
-break;
-case "select-none":
-this.message_list.clear_selection();
-break;
-case "nextmessage":
-if(this.env.next_uid){
-this.show_message(this.env.next_uid,false,this.env.action=="preview");
-}
-break;
-case "lastmessage":
-if(this.env.last_uid){
-this.show_message(this.env.last_uid);
-}
-break;
-case "previousmessage":
-if(this.env.prev_uid){
-this.show_message(this.env.prev_uid,false,this.env.action=="preview");
-}
-break;
-case "firstmessage":
-if(this.env.first_uid){
-this.show_message(this.env.first_uid);
-}
-break;
-case "checkmail":
-this.check_for_recent(true);
-break;
-case "compose":
-var url=this.env.comm_path+"&_action=compose";
-if(this.task=="mail"){
-url+="&_mbox="+urlencode(this.env.mailbox);
-if(this.env.mailbox==this.env.drafts_mailbox){
-var uid;
-if(uid=this.get_single_uid()){
-url+="&_draft_uid="+uid;
-}
-}else{
-if(_40){
-url+="&_to="+urlencode(_40);
-}
-}
-}else{
-if(this.task=="addressbook"){
-if(_40&&_40.indexOf("@")>0){
-url=this.get_task_url("mail",url);
-this.redirect(url+"&_to="+urlencode(_40));
-break;
-}
-var _4e=new Array();
-if(_40){
-_4e[_4e.length]=_40;
-}else{
-if(this.contact_list){
-var _4f=this.contact_list.get_selection();
-for(var n=0;n<_4f.length;n++){
-_4e[_4e.length]=_4f[n];
-}
-}
-}
-if(_4e.length){
-this.http_request("mailto","_cid="+urlencode(_4e.join(","))+"&_source="+urlencode(this.env.source),true);
-}
-break;
-}
-}
-url=url.replace(/&_framed=1/,"");
-this.redirect(url);
-break;
-case "spellcheck":
-if(window.tinyMCE&&tinyMCE.get("compose-body")){
-tinyMCE.execCommand("mceSpellCheck",true);
-}else{
-if(this.env.spellcheck&&this.env.spellcheck.spellCheck&&this.spellcheck_ready){
-this.env.spellcheck.spellCheck(this.env.spellcheck.check_link);
-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;
-}
-this.set_busy(true,"savingmessage");
-var _51=this.gui_objects.messageform;
-_51.target="savetarget";
-_51._draft.value="1";
-_51.submit();
-break;
-case "send":
-if(!this.gui_objects.messageform){
-break;
-}
-if(!this.check_compose_input()){
-break;
-}
-self.clearTimeout(this.save_timer);
-this.set_busy(true,"sendingmessage");
-var _51=this.gui_objects.messageform;
-_51.target="savetarget";
-_51._draft.value="";
-_51.submit();
-clearTimeout(this.request_timer);
-break;
-case "add-attachment":
-this.show_attachment_form(true);
-case "send-attachment":
-self.clearTimeout(this.save_timer);
-this.upload_file(_40);
-break;
-case "remove-attachment":
-this.remove_attachment(_40);
-break;
-case "reply-all":
-case "reply":
-var uid;
-if(uid=this.get_single_uid()){
-this.goto_url("compose","_reply_uid="+uid+"&_mbox="+urlencode(this.env.mailbox)+(_3f=="reply-all"?"&_all=1":""),true);
-}
-break;
-case "forward":
-var uid;
-if(uid=this.get_single_uid()){
-this.goto_url("compose","_forward_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true);
-}
-break;
-case "print":
-var uid;
-if(uid=this.get_single_uid()){
-_1.printwin=window.open(this.env.comm_path+"&_action=print&_uid="+uid+"&_mbox="+urlencode(this.env.mailbox)+(this.env.safemode?"&_safe=1":""));
-if(this.printwin){
-window.setTimeout(function(){
-_1.printwin.focus();
-},20);
-if(this.env.action!="show"){
-this.mark_message("read",uid);
-}
-}
-}
-break;
-case "viewsource":
-var uid;
-if(uid=this.get_single_uid()){
-_1.sourcewin=window.open(this.env.comm_path+"&_action=viewsource&_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox));
-if(this.sourcewin){
-window.setTimeout(function(){
-_1.sourcewin.focus();
-},20);
-}
-}
-break;
-case "add-contact":
-this.add_contact(_40);
-break;
-case "search":
-if(!_40&&this.gui_objects.qsearchbox){
-_40=this.gui_objects.qsearchbox.value;
-}
-if(_40){
-this.qsearch(_40);
-break;
-}
-case "reset-search":
-var s=this.env.search_request;
-this.reset_qsearch();
-if(s&&this.env.mailbox){
-this.list_mailbox(this.env.mailbox);
-}else{
-if(s&&this.task=="addressbook"){
-this.list_contacts(this.env.source);
-}
-}
-break;
-case "import":
-if(this.env.action=="import"&&this.gui_objects.importform){
-var _53=document.getElementById("rcmimportfile");
-if(_53&&!_53.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");
-}
-break;
-case "export":
-if(this.contact_list.rowcount>0){
-var _54=(this.env.source?"_source="+urlencode(this.env.source)+"&":"");
-if(this.env.search_request){
-_54+="_search="+this.env.search_request;
-}
-this.goto_url("export",_54);
-}
-break;
-case "collapse-folder":
-if(_40){
-this.collapse_folder(_40);
-}
-break;
-case "preferences":
-this.goto_url("");
-break;
-case "identities":
-this.goto_url("identities");
-break;
-case "delete-identity":
-this.delete_identity();
-case "folders":
-this.goto_url("folders");
-break;
-case "subscribe":
-this.subscribe_folder(_40);
-break;
-case "unsubscribe":
-this.unsubscribe_folder(_40);
-break;
-case "create-folder":
-this.create_folder(_40);
-break;
-case "rename-folder":
-this.rename_folder(_40);
-break;
-case "delete-folder":
-this.delete_folder(_40);
-break;
-}
-return obj?false:true;
-};
-this.enable_command=function(){
-var _55=arguments;
-if(!_55.length){
-return -1;
-}
-var _56;
-var _57=_55[_55.length-1];
-for(var n=0;n<_55.length-1;n++){
-_56=_55[n];
-this.commands[_56]=_57;
-this.set_button(_56,(_57?"act":"pas"));
-}
-return true;
-};
-this.set_busy=function(a,_5a){
-if(a&&_5a){
-var msg=this.get_label(_5a);
-if(msg==_5a){
-msg="Loading...";
-}
-this.display_message(msg,"loading",true);
-}else{
-if(!a){
-this.hide_message();
-}
-}
-this.busy=a;
-if(this.gui_objects.editform){
-this.lock_form(this.gui_objects.editform,a);
-}
-if(this.request_timer){
-clearTimeout(this.request_timer);
-}
-if(a&&this.env.request_timeout){
-this.request_timer=window.setTimeout(function(){
-_1.request_timed_out();
-},this.env.request_timeout*1000);
-}
-};
-this.get_label=function(_5c){
-if(this.labels[_5c]){
-return this.labels[_5c];
-}else{
-return _5c;
-}
-};
-this.switch_task=function(_5d){
-if(this.task===_5d&&_5d!="mail"){
-return;
-}
-var url=this.get_task_url(_5d);
-if(_5d=="mail"){
-url+="&_mbox=INBOX";
-}
-this.redirect(url);
-};
-this.get_task_url=function(_5f,url){
-if(!url){
-url=this.env.comm_path;
-}
-return url.replace(/_task=[a-z]+/,"_task="+_5f);
-};
-this.request_timed_out=function(){
-this.set_busy(false);
-this.display_message("Request timed out!","error");
-};
-this.doc_mouse_up=function(e){
-var _62,li;
-if(this.message_list){
-if(!rcube_mouse_is_over(e,this.message_list.list)){
-this.message_list.blur();
-}
-_62=this.env.mailboxes;
-}else{
-if(this.contact_list){
-if(!rcube_mouse_is_over(e,this.contact_list.list)){
-this.contact_list.blur();
-}
-_62=this.env.address_sources;
-}else{
-if(this.ksearch_value){
-this.ksearch_blur();
-}
-}
-}
-if(this.drag_active&&_62&&this.env.last_folder_target){
-this.set_classname(this.get_folder_li(this.env.last_folder_target),"droptarget",false);
-this.command("moveto",_62[this.env.last_folder_target].id);
-this.env.last_folder_target=null;
-}
-};
-this.drag_start=function(_64){
-this.initialBodyScrollTop=bw.ie?0:window.pageYOffset;
-this.initialMailBoxScrollTop=document.getElementById("mailboxlist-container").scrollTop;
-var _65=this.task=="mail"?this.env.mailboxes:this.env.address_sources;
-this.drag_active=true;
-if(this.preview_timer){
-clearTimeout(this.preview_timer);
-}
-if(this.gui_objects.folderlist&&_65){
-var li,pos,_64,_68;
-_64=rcube_find_object(this.task=="mail"?"mailboxlist":"directorylist");
-pos=rcube_get_object_pos(_64);
-this.env.folderlist_coords={x1:pos.x,y1:pos.y,x2:pos.x+_64.offsetWidth,y2:pos.y+_64.offsetHeight};
-this.env.folder_coords=new Array();
-for(var k in _65){
-if(li=this.get_folder_li(k)){
-pos=rcube_get_object_pos(li.firstChild);
-if(_68=li.firstChild.offsetHeight){
-this.env.folder_coords[k]={x1:pos.x,y1:pos.y,x2:pos.x+li.firstChild.offsetWidth,y2:pos.y+_68};
-}
-}
-}
-}
-};
-this.drag_move=function(e){
-if(this.gui_objects.folderlist&&this.env.folder_coords){
-var _6b=bw.ie?-document.documentElement.scrollTop:this.initialBodyScrollTop;
-var _6c=this.initialMailBoxScrollTop-document.getElementById("mailboxlist-container").scrollTop;
-var _6d=-_6c-_6b;
-var li,pos,_70;
-_70=rcube_event.get_mouse_pos(e);
-pos=this.env.folderlist_coords;
-_70.y+=_6d;
-if(_70.x<pos.x1||_70.x>=pos.x2||_70.y<pos.y1||_70.y>=pos.y2){
-if(this.env.last_folder_target){
-this.set_classname(this.get_folder_li(this.env.last_folder_target),"droptarget",false);
-this.env.last_folder_target=null;
-}
-return;
-}
-for(var k in this.env.folder_coords){
-pos=this.env.folder_coords[k];
-if(this.check_droptarget(k)&&((_70.x>=pos.x1)&&(_70.x<pos.x2)&&(_70.y>=pos.y1)&&(_70.y<pos.y2))){
-this.set_classname(this.get_folder_li(k),"droptarget",true);
-this.env.last_folder_target=k;
-}else{
-this.set_classname(this.get_folder_li(k),"droptarget",false);
-}
-}
-}
-};
-this.collapse_folder=function(id){
-var div;
-if((li=this.get_folder_li(id))&&(div=li.getElementsByTagName("div")[0])&&(div.className.match(/collapsed/)||div.className.match(/expanded/))){
-var ul=li.getElementsByTagName("ul")[0];
-if(div.className.match(/collapsed/)){
-ul.style.display="";
-this.set_classname(div,"collapsed",false);
-this.set_classname(div,"expanded",true);
-var reg=new RegExp("&"+urlencode(id)+"&");
-this.set_env("collapsed_folders",this.env.collapsed_folders.replace(reg,""));
-}else{
-ul.style.display="none";
-this.set_classname(div,"expanded",false);
-this.set_classname(div,"collapsed",true);
-this.set_env("collapsed_folders",this.env.collapsed_folders+"&"+urlencode(id)+"&");
-if(this.env.mailbox.indexOf(id+this.env.delimiter)==0){
-this.command("list",id);
-}
-}
-if((bw.ie6||bw.ie7)&&li.nextSibling&&(li.nextSibling.getElementsByTagName("ul").length>0)&&li.nextSibling.getElementsByTagName("ul")[0].style&&(li.nextSibling.getElementsByTagName("ul")[0].style.display!="none")){
-li.nextSibling.getElementsByTagName("ul")[0].style.display="none";
-li.nextSibling.getElementsByTagName("ul")[0].style.display="";
-}
-this.http_post("save-pref","_name=collapsed_folders&_value="+urlencode(this.env.collapsed_folders));
-this.set_unread_count_display(id,false);
-}
-};
-this.click_on_list=function(e){
-if(this.gui_objects.qsearchbox){
-this.gui_objects.qsearchbox.blur();
-}
-if(this.message_list){
-this.message_list.focus();
-}else{
-if(this.contact_list){
-this.contact_list.focus();
-}
-}
-var _77;
-if(_77=this.get_folder_li()){
-this.set_classname(_77,"unfocused",true);
-}
-return rcube_event.get_button(e)==2?true:rcube_event.cancel(e);
-};
-this.msglist_select=function(_78){
-if(this.preview_timer){
-clearTimeout(this.preview_timer);
-}
-var _79=_78.selection.length==1;
-if(this.env.mailbox==this.env.drafts_mailbox){
-this.enable_command("reply","reply-all","forward",false);
-this.enable_command("show","print",_79);
-this.enable_command("delete","moveto","mark",(_78.selection.length>0?true:false));
-}else{
-this.enable_command("show","reply","reply-all","forward","print",_79);
-this.enable_command("delete","moveto","mark",(_78.selection.length>0?true:false));
-}
-if(_79&&this.env.contentframe&&!_78.multi_selecting){
-this.preview_timer=window.setTimeout(function(){
-_1.msglist_get_preview();
-},200);
-}else{
-if(this.env.contentframe){
-this.show_contentframe(false);
-}
-}
-};
-this.msglist_dbl_click=function(_7a){
-if(this.preview_timer){
-clearTimeout(this.preview_timer);
-}
-var uid=_7a.get_single_selection();
-if(uid&&this.env.mailbox==this.env.drafts_mailbox){
-this.goto_url("compose","_draft_uid="+uid+"&_mbox="+urlencode(this.env.mailbox),true);
-}else{
-if(uid){
-this.show_message(uid,false,false);
-}
-}
-};
-this.msglist_keypress=function(_7c){
-if(_7c.key_pressed==_7c.ENTER_KEY){
-this.command("show");
-}else{
-if(_7c.key_pressed==_7c.DELETE_KEY){
-this.command("delete");
-}else{
-if(_7c.key_pressed==_7c.BACKSPACE_KEY){
-this.command("delete");
-}else{
-_7c.shiftkey=false;
-}
-}
-}
-};
-this.msglist_get_preview=function(){
-var uid=this.get_single_uid();
-if(uid&&this.env.contentframe&&!this.drag_active){
-this.show_message(uid,false,true);
-}else{
-if(this.env.contentframe){
-this.show_contentframe(false);
-}
-}
-};
-this.check_droptarget=function(id){
-if(this.task=="mail"){
-return (this.env.mailboxes[id]&&this.env.mailboxes[id].id!=this.env.mailbox&&!this.env.mailboxes[id].virtual);
-}else{
-if(this.task=="addressbook"){
-return (id!=this.env.source&&this.env.address_sources[id]&&!this.env.address_sources[id].readonly);
-}else{
-if(this.task=="settings"){
-return (id!=this.env.folder);
-}
-}
-}
-};
-this.show_message=function(id,_80,_81){
-if(!id){
-return;
-}
-var _82="";
-var _83=_81?"preview":"show";
-var _84=window;
-if(_81&&this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
-_84=window.frames[this.env.contentframe];
-_82="&_framed=1";
-}
-if(_80){
-_82="&_safe=1";
-}
-if(this.env.search_request){
-_82+="&_search="+this.env.search_request;
-}
-var url="&_action="+_83+"&_uid="+id+"&_mbox="+urlencode(this.env.mailbox)+_82;
-if(_83=="preview"&&String(_84.location.href).indexOf(url)>=0){
-this.show_contentframe(true);
-}else{
-this.set_busy(true,"loading");
-_84.location.href=this.env.comm_path+url;
-if(_83=="preview"&&this.message_list&&this.message_list.rows[id]&&this.message_list.rows[id].unread){
-this.set_message(id,"unread",false);
-if(this.env.unread_counts[this.env.mailbox]){
-this.env.unread_counts[this.env.mailbox]-=1;
-this.set_unread_count(this.env.mailbox,this.env.unread_counts[this.env.mailbox],this.env.mailbox=="INBOX");
-}
-}
-}
-};
-this.show_contentframe=function(_86){
-var frm;
-if(this.env.contentframe&&(frm=rcube_find_object(this.env.contentframe))){
-if(!_86&&window.frames[this.env.contentframe]){
-if(window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0){
-window.frames[this.env.contentframe].location.href=this.env.blankpage;
-}
-}else{
-if(!bw.safari&&!bw.konq){
-frm.style.display=_86?"block":"none";
-}
-}
-}
-if(!_86&&this.busy){
-this.set_busy(false);
-}
-};
-this.list_page=function(_88){
-if(_88=="next"){
-_88=this.env.current_page+1;
-}
-if(_88=="last"){
-_88=this.env.pagecount;
-}
-if(_88=="prev"&&this.env.current_page>1){
-_88=this.env.current_page-1;
-}
-if(_88=="first"&&this.env.current_page>1){
-_88=1;
-}
-if(_88>0&&_88<=this.env.pagecount){
-this.env.current_page=_88;
-if(this.task=="mail"){
-this.list_mailbox(this.env.mailbox,_88);
-}else{
-if(this.task=="addressbook"){
-this.list_contacts(this.env.source,_88);
-}
-}
-}
-};
-this.filter_mailbox=function(_89){
-var _8a;
-if(this.gui_objects.qsearchbox){
-_8a=this.gui_objects.qsearchbox.value;
-}
-this.message_list.clear();
-this.env.current_page=1;
-this.set_busy(true,"searching");
-this.http_request("search","_filter="+_89+(_8a?"&_q="+urlencode(_8a):"")+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):""),true);
-};
-this.list_mailbox=function(_8b,_8c,_8d){
-this.last_selected=0;
-var _8e="";
-var _8f=window;
-if(!_8b){
-_8b=this.env.mailbox;
-}
-if(_8d){
-_8e+="&_sort="+_8d;
-}
-if(this.env.search_request){
-_8e+="&_search="+this.env.search_request;
-}
-if(!_8c&&_8b!=this.env.mailbox){
-_8c=1;
-this.env.current_page=_8c;
-if(this.message_list){
-this.message_list.clear_selection();
-}
-this.show_contentframe(false);
-}
-if(_8b!=this.env.mailbox||(_8b==this.env.mailbox&&!_8c&&!_8d)){
-_8e+="&_refresh=1";
-}
-this.select_folder(_8b,this.env.mailbox);
-this.env.mailbox=_8b;
-if(this.gui_objects.messagelist){
-this.list_mailbox_remote(_8b,_8c,_8e);
-return;
-}
-if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
-_8f=window.frames[this.env.contentframe];
-_8e+="&_framed=1";
-}
-if(_8b){
-this.set_busy(true,"loading");
-_8f.location.href=this.env.comm_path+"&_mbox="+urlencode(_8b)+(_8c?"&_page="+_8c:"")+_8e;
-}
-};
-this.list_mailbox_remote=function(_90,_91,_92){
-this.message_list.clear();
-var url="_mbox="+urlencode(_90)+(_91?"&_page="+_91:"");
-this.set_busy(true,"loading");
-this.http_request("list",url+_92,true);
-};
-this.expunge_mailbox=function(_94){
-var _95=false;
-var _96="";
-if(_94==this.env.mailbox){
-_95=true;
-this.set_busy(true,"loading");
-_96="&_reload=1";
-}
-var url="_mbox="+urlencode(_94);
-this.http_post("expunge",url+_96,_95);
-};
-this.purge_mailbox=function(_98){
-var _99=false;
-var _9a="";
-if(!confirm(this.get_label("purgefolderconfirm"))){
-return false;
-}
-if(_98==this.env.mailbox){
-_99=true;
-this.set_busy(true,"loading");
-_9a="&_reload=1";
-}
-var url="_mbox="+urlencode(_98);
-this.http_post("purge",url+_9a,_99);
-return true;
-};
-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.set_message_icon=function(uid){
-var _9d;
-var _9e=this.message_list.rows;
-if(!_9e[uid]){
-return false;
-}
-if(_9e[uid].deleted&&this.env.deletedicon){
-_9d=this.env.deletedicon;
-}else{
-if(_9e[uid].replied&&this.env.repliedicon){
-if(_9e[uid].forwarded&&this.env.forwardedrepliedicon){
-_9d=this.env.forwardedrepliedicon;
-}else{
-_9d=this.env.repliedicon;
-}
-}else{
-if(_9e[uid].forwarded&&this.env.forwardedicon){
-_9d=this.env.forwardedicon;
-}else{
-if(_9e[uid].unread&&this.env.unreadicon){
-_9d=this.env.unreadicon;
-}else{
-if(this.env.messageicon){
-_9d=this.env.messageicon;
-}
-}
-}
-}
-}
-if(_9d&&_9e[uid].icon){
-_9e[uid].icon.src=_9d;
-}
-_9d="";
-if(_9e[uid].flagged&&this.env.flaggedicon){
-_9d=this.env.flaggedicon;
-}else{
-if(!_9e[uid].flagged&&this.env.unflaggedicon){
-_9d=this.env.unflaggedicon;
-}
-}
-if(_9e[uid].flagged_icon&&_9d){
-_9e[uid].flagged_icon.src=_9d;
-}
-};
-this.set_message_status=function(uid,_a0,_a1){
-var _a2=this.message_list.rows;
-if(!_a2[uid]){
-return false;
-}
-if(_a0=="unread"){
-_a2[uid].unread=_a1;
-}else{
-if(_a0=="deleted"){
-_a2[uid].deleted=_a1;
-}else{
-if(_a0=="replied"){
-_a2[uid].replied=_a1;
-}else{
-if(_a0=="forwarded"){
-_a2[uid].forwarded=_a1;
-}else{
-if(_a0=="flagged"){
-_a2[uid].flagged=_a1;
-}
-}
-}
-}
-}
-this.env.messages[uid]=_a2[uid];
-};
-this.set_message=function(uid,_a4,_a5){
-var _a6=this.message_list.rows;
-if(!_a6[uid]){
-return false;
-}
-if(_a4){
-this.set_message_status(uid,_a4,_a5);
-}
-if(_a6[uid].unread&&_a6[uid].classname.indexOf("unread")<0){
-_a6[uid].classname+=" unread";
-this.set_classname(_a6[uid].obj,"unread",true);
-}else{
-if(!_a6[uid].unread&&_a6[uid].classname.indexOf("unread")>=0){
-_a6[uid].classname=_a6[uid].classname.replace(/\s*unread/,"");
-this.set_classname(_a6[uid].obj,"unread",false);
-}
-}
-if(_a6[uid].deleted&&_a6[uid].classname.indexOf("deleted")<0){
-_a6[uid].classname+=" deleted";
-this.set_classname(_a6[uid].obj,"deleted",true);
-}else{
-if(!_a6[uid].deleted&&_a6[uid].classname.indexOf("deleted")>=0){
-_a6[uid].classname=_a6[uid].classname.replace(/\s*deleted/,"");
-this.set_classname(_a6[uid].obj,"deleted",false);
-}
-}
-if(_a6[uid].flagged&&_a6[uid].classname.indexOf("flagged")<0){
-_a6[uid].classname+=" flagged";
-this.set_classname(_a6[uid].obj,"flagged",true);
-}else{
-if(!_a6[uid].flagged&&_a6[uid].classname.indexOf("flagged")>=0){
-_a6[uid].classname=_a6[uid].classname.replace(/\s*flagged/,"");
-this.set_classname(_a6[uid].obj,"flagged",false);
-}
-}
-this.set_message_icon(uid);
-};
-this.move_messages=function(_a7){
-if(!_a7||_a7==this.env.mailbox||(!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){
-return;
-}
-var _a8=false;
-var _a9="&_target_mbox="+urlencode(_a7)+"&_from="+(this.env.action?this.env.action:"");
-if(this.env.action=="show"){
-_a8=true;
-this.set_busy(true,"movingmessage");
-}else{
-if(!this.env.flag_for_deletion){
-this.show_contentframe(false);
-}
-}
-this.enable_command("reply","reply-all","forward","delete","mark","print",false);
-this._with_selected_messages("moveto",_a8,_a9,(this.env.flag_for_deletion?false:true));
-};
-this.delete_messages=function(){
-var _aa=this.message_list?this.message_list.get_selection():new Array();
-if(!this.env.uid&&!_aa.length){
-return;
-}
-if(this.env.trash_mailbox&&String(this.env.mailbox).toLowerCase()!=String(this.env.trash_mailbox).toLowerCase()){
-if(this.message_list&&this.message_list.shiftkey){
-if(confirm(this.get_label("deletemessagesconfirm"))){
-this.permanently_remove_messages();
-}
-}else{
-this.move_messages(this.env.trash_mailbox);
-}
-}else{
-if(this.env.trash_mailbox&&String(this.env.mailbox).toLowerCase()==String(this.env.trash_mailbox).toLowerCase()){
-this.permanently_remove_messages();
-}else{
-if(!this.env.trash_mailbox&&this.env.flag_for_deletion){
-this.mark_message("delete");
-if(this.env.action=="show"){
-this.command("nextmessage","",this);
-}else{
-if(_aa.length==1){
-this.message_list.select_next();
-}
-}
-}else{
-if(!this.env.trash_mailbox){
-this.permanently_remove_messages();
-}
-}
-}
-}
-};
-this.permanently_remove_messages=function(){
-if(!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length)){
-return;
-}
-this.show_contentframe(false);
-this._with_selected_messages("delete",false,"&_from="+(this.env.action?this.env.action:""),true);
-};
-this._with_selected_messages=function(_ab,_ac,_ad,_ae){
-var _af=new Array();
-if(this.env.uid){
-_af[0]=this.env.uid;
-}else{
-var _b0=this.message_list.get_selection();
-var _b1=this.message_list.rows;
-var id;
-for(var n=0;n<_b0.length;n++){
-id=_b0[n];
-_af[_af.length]=id;
-if(_ae){
-this.message_list.remove_row(id,(n==_b0.length-1));
-}else{
-this.set_message_status(id,"deleted",true);
-if(this.env.read_when_deleted){
-this.set_message_status(id,"unread",false);
-}
-this.set_message(id);
-}
-}
-}
-if(this.env.search_request){
-_ad+="&_search="+this.env.search_request;
-}
-this.http_post(_ab,"_uid="+_af.join(",")+"&_mbox="+urlencode(this.env.mailbox)+_ad,_ac);
-};
-this.mark_message=function(_b4,uid){
-var _b6=new Array();
-var _b7=new Array();
-var _b8=this.message_list?this.message_list.get_selection():new Array();
-if(uid){
-_b6[0]=uid;
-}else{
-if(this.env.uid){
-_b6[0]=this.env.uid;
-}else{
-if(this.message_list){
-for(var n=0;n<_b8.length;n++){
-_b6[_b6.length]=_b8[n];
-}
-}
-}
-}
-if(!this.message_list){
-_b7=_b6;
-}else{
-for(var id,n=0;n<_b6.length;n++){
-id=_b6[n];
-if((_b4=="read"&&this.message_list.rows[id].unread)||(_b4=="unread"&&!this.message_list.rows[id].unread)||(_b4=="delete"&&!this.message_list.rows[id].deleted)||(_b4=="undelete"&&this.message_list.rows[id].deleted)||(_b4=="flagged"&&!this.message_list.rows[id].flagged)||(_b4=="unflagged"&&this.message_list.rows[id].flagged)){
-_b7[_b7.length]=id;
-}
-}
-}
-if(!_b7.length){
-return;
-}
-switch(_b4){
-case "read":
-case "unread":
-this.toggle_read_status(_b4,_b7);
-break;
-case "delete":
-case "undelete":
-this.toggle_delete_status(_b7);
-break;
-case "flagged":
-case "unflagged":
-this.toggle_flagged_status(_b4,_b6);
-break;
-}
-};
-this.toggle_read_status=function(_bb,_bc){
-for(var i=0;i<_bc.length;i++){
-this.set_message(_bc[i],"unread",(_bb=="unread"?true:false));
-}
-this.http_post("mark","_uid="+_bc.join(",")+"&_flag="+_bb);
-};
-this.toggle_flagged_status=function(_be,_bf){
-for(var i=0;i<_bf.length;i++){
-this.set_message(_bf[i],"flagged",(_be=="flagged"?true:false));
-}
-this.http_post("mark","_uid="+_bf.join(",")+"&_flag="+_be);
-};
-this.toggle_delete_status=function(_c1){
-var _c2=this.message_list?this.message_list.rows:new Array();
-if(_c1.length==1){
-if(!_c2.length||(_c2[_c1[0]]&&!_c2[_c1[0]].deleted)){
-this.flag_as_deleted(_c1);
-}else{
-this.flag_as_undeleted(_c1);
-}
-return true;
-}
-var _c3=true;
-for(var i=0;i<_c1.length;i++){
-uid=_c1[i];
-if(_c2[uid]){
-if(!_c2[uid].deleted){
-_c3=false;
-break;
-}
-}
-}
-if(_c3){
-this.flag_as_undeleted(_c1);
-}else{
-this.flag_as_deleted(_c1);
-}
-return true;
-};
-this.flag_as_undeleted=function(_c5){
-for(var i=0;i<_c5.length;i++){
-this.set_message(_c5[i],"deleted",false);
-}
-this.http_post("mark","_uid="+_c5.join(",")+"&_flag=undelete");
-return true;
-};
-this.flag_as_deleted=function(_c7){
-var _c8="";
-var _c9=new Array();
-var _ca=this.message_list?this.message_list.rows:new Array();
-for(var i=0;i<_c7.length;i++){
-uid=_c7[i];
-if(_ca[uid]){
-this.set_message(uid,"deleted",true);
-if(_ca[uid].unread){
-_c9[_c9.length]=uid;
-}
-}
-}
-if(_c9.length){
-_c8="&_ruid="+_c9.join(",");
-}
-this.http_post("mark","_uid="+_c7.join(",")+"&_flag=delete"+_c8);
-return true;
-};
-this.flag_deleted_as_read=function(_cc){
-var _cd;
-var _ce=this.message_list?this.message_list.rows:new Array();
-var str=String(_cc);
-var _d0=new Array();
-_d0=str.split(",");
-for(var uid,i=0;i<_d0.length;i++){
-uid=_d0[i];
-if(_ce[uid]){
-this.set_message(uid,"unread",false);
-}
-}
-};
-this.login_user_keyup=function(e){
-var key=rcube_event.get_keycode(e);
-var elm;
-if((key==13)&&(elm=rcube_find_object("_pass"))){
-elm.focus();
-return false;
-}
-};
-this.check_compose_input=function(){
-var _d6=rcube_find_object("_to");
-var _d7=rcube_find_object("_cc");
-var _d8=rcube_find_object("_bcc");
-var _d9=rcube_find_object("_from");
-var _da=rcube_find_object("_subject");
-var _db=rcube_find_object("_message");
-if(_d9.type=="text"&&!rcube_check_email(_d9.value,true)){
-alert(this.get_label("nosenderwarning"));
-_d9.focus();
-return false;
-}
-var _dc=_d6.value?_d6.value:(_d7.value?_d7.value:_d8.value);
-if(!rcube_check_email(_dc.replace(/^\s+/,"").replace(/[\s,;]+$/,""),true)){
-alert(this.get_label("norecipientwarning"));
-_d6.focus();
-return false;
-}
-if(_da&&_da.value==""){
-var _dd=prompt(this.get_label("nosubjectwarning"),this.get_label("nosubject"));
-if(!_dd&&_dd!==""){
-_da.focus();
-return false;
-}else{
-_da.value=_dd?_dd:this.get_label("nosubject");
-}
-}
-if((!window.tinyMCE||!tinyMCE.get("compose-body"))&&_db.value==""&&!confirm(this.get_label("nobodywarning"))){
-_db.focus();
-return false;
-}else{
-if(window.tinyMCE&&tinyMCE.get("compose-body")&&!tinyMCE.get("compose-body").getContent()&&!confirm(this.get_label("nobodywarning"))){
-tinyMCE.get("compose-body").focus();
-return false;
-}
-}
-this.stop_spellchecking();
-return true;
-};
-this.stop_spellchecking=function(){
-if(this.env.spellcheck&&!this.spellcheck_ready){
-exec_event(this.env.spellcheck.check_link,"click");
-this.set_spellcheck_state("ready");
-}
-};
-this.display_spellcheck_controls=function(vis){
-if(this.env.spellcheck){
-if(!vis){
-this.stop_spellchecking();
-}
-this.env.spellcheck.check_link.style.visibility=vis?"visible":"hidden";
-this.env.spellcheck.switch_lan_pic.style.visibility=vis?"visible":"hidden";
-}
-};
-this.set_spellcheck_state=function(s){
-this.spellcheck_ready=(s=="check_spelling"||s=="ready");
-this.enable_command("spellcheck",this.spellcheck_ready);
-};
-this.set_draft_id=function(id){
-var f;
-if(f=rcube_find_object("_draft_saveid")){
-f.value=id;
-}
-};
-this.auto_save_start=function(){
-if(this.env.draft_autosave){
-this.save_timer=self.setTimeout(function(){
-_1.command("savedraft");
-},this.env.draft_autosave*1000);
-}
-this.busy=false;
-};
-this.compose_field_hash=function(_e2){
-var _e3=rcube_find_object("_to");
-var _e4=rcube_find_object("_cc");
-var _e5=rcube_find_object("_bcc");
-var _e6=rcube_find_object("_subject");
-var _e7,_e8;
-var str="";
-if(_e3&&_e3.value){
-str+=_e3.value+":";
-}
-if(_e4&&_e4.value){
-str+=_e4.value+":";
-}
-if(_e5&&_e5.value){
-str+=_e5.value+":";
-}
-if(_e6&&_e6.value){
-str+=_e6.value+":";
-}
-if(_e7=tinyMCE.get("compose-body")){
-str+=_e7.getContent();
-}else{
-_e8=rcube_find_object("_message");
-str+=_e8.value;
-}
-if(_e2){
-this.cmp_hash=str;
-}
-return str;
-};
-this.change_identity=function(obj){
-if(!obj||!obj.options){
-return false;
-}
-var id=obj.options[obj.selectedIndex].value;
-var _ec=rcube_find_object("_message");
-var _ed=_ec?_ec.value:"";
-var _ee=(rcube_find_object("_is_html").value=="1");
-var sig,p;
-if(!this.env.identity){
-this.env.identity=id;
-}
-if(!_ee){
-if(this.env.identity&&this.env.signatures&&this.env.signatures[this.env.identity]){
-if(this.env.signatures[this.env.identity]["is_html"]){
-sig=this.env.signatures[this.env.identity]["plain_text"];
-}else{
-sig=this.env.signatures[this.env.identity]["text"];
-}
-if(sig.indexOf("-- ")!=0){
-sig="-- \n"+sig;
-}
-p=_ed.lastIndexOf(sig);
-if(p>=0){
-_ed=_ed.substring(0,p-1)+_ed.substring(p+sig.length,_ed.length);
-}
-}
-_ed=_ed.replace(/[\r\n]+$/,"");
-if(this.env.signatures&&this.env.signatures[id]){
-sig=this.env.signatures[id]["text"];
-if(this.env.signatures[id]["is_html"]){
-sig=this.env.signatures[id]["plain_text"];
-}
-if(sig.indexOf("-- ")!=0){
-sig="-- \n"+sig;
-}
-_ed+="\n\n"+sig;
-}
-}else{
-var _f1=tinyMCE.get("compose-body");
-if(this.env.signatures){
-var _f2=_f1.dom.get("_rc_sig");
-var _f3="";
-var _f4=true;
-if(!_f2){
-if(bw.ie){
-_f1.getBody().appendChild(_f1.getDoc().createElement("br"));
-}
-_f2=_f1.getDoc().createElement("div");
-_f2.setAttribute("id","_rc_sig");
-_f1.getBody().appendChild(_f2);
-}
-if(this.env.signatures[id]){
-_f3=this.env.signatures[id]["text"];
-_f4=this.env.signatures[id]["is_html"];
-if(_f3){
-if(_f4&&this.env.signatures[id]["plain_text"].indexOf("-- ")!=0){
-_f3="<p>-- </p>"+_f3;
-}else{
-if(!_f4&&_f3.indexOf("-- ")!=0){
-_f3="-- \n"+_f3;
-}
-}
-}
-}
-if(_f4){
-_f2.innerHTML=_f3;
-}else{
-_f2.innerHTML="<pre>"+_f3+"</pre>";
-}
-}
-}
-if(_ec){
-_ec.value=_ed;
-}
-this.env.identity=id;
-return true;
-};
-this.show_attachment_form=function(a){
-if(!this.gui_objects.uploadbox){
-return false;
-}
-var elm,_f7;
-if(elm=this.gui_objects.uploadbox){
-if(a&&(_f7=this.gui_objects.attachmentlist)){
-var pos=rcube_get_object_pos(_f7);
-var _f9=pos.x;
-var top=pos.y+_f7.offsetHeight+10;
-elm.style.top=top+"px";
-elm.style.left=_f9+"px";
-}
-elm.style.visibility=a?"visible":"hidden";
-}
-try{
-if(!a&&this.gui_objects.attachmentform!=this.gui_objects.messageform){
-this.gui_objects.attachmentform.reset();
-}
-}
-catch(e){
-}
-return true;
-};
-this.upload_file=function(_fb){
-if(!_fb){
-return false;
-}
-var _fc=false;
-for(var n=0;n<_fb.elements.length;n++){
-if(_fb.elements[n].type=="file"&&_fb.elements[n].value){
-_fc=true;
-break;
-}
-}
-if(_fc){
-var ts=new Date().getTime();
-var _ff="rcmupload"+ts;
-if(document.all){
-var html="<iframe name=\""+_ff+"\" src=\"program/blank.gif\" style=\"width:0;height:0;visibility:hidden;\"></iframe>";
-document.body.insertAdjacentHTML("BeforeEnd",html);
-}else{
-var _101=document.createElement("IFRAME");
-_101.name=_ff;
-_101.style.border="none";
-_101.style.width=0;
-_101.style.height=0;
-_101.style.visibility="hidden";
-document.body.appendChild(_101);
-}
-_fb.target=_ff;
-_fb.action=this.env.comm_path+"&_action=upload";
-_fb.setAttribute("enctype","multipart/form-data");
-_fb.submit();
-}
-this.gui_objects.attachmentform=_fb;
-return true;
-};
-this.add2attachment_list=function(name,_103){
-if(!this.gui_objects.attachmentlist){
-return false;
-}
-var li=document.createElement("LI");
-li.id=name;
-li.innerHTML=_103;
-this.gui_objects.attachmentlist.appendChild(li);
-return true;
-};
-this.remove_from_attachment_list=function(name){
-if(!this.gui_objects.attachmentlist){
-return false;
-}
-var list=this.gui_objects.attachmentlist.getElementsByTagName("li");
-for(i=0;i<list.length;i++){
-if(list[i].id==name){
-this.gui_objects.attachmentlist.removeChild(list[i]);
-}
-}
-};
-this.remove_attachment=function(name){
-if(name){
-this.http_post("remove-attachment","_file="+urlencode(name));
-}
-return true;
-};
-this.add_contact=function(_108){
-if(_108){
-this.http_post("addcontact","_address="+_108);
-}
-return true;
-};
-this.qsearch=function(_109,_10a){
-if(_109!=""){
-if(this.message_list){
-this.message_list.clear();
-}else{
-if(this.contact_list){
-this.contact_list.clear(true);
-this.show_contentframe(false);
-}
-}
-if(this.gui_objects.search_filter){
-_10a="&_filter="+this.gui_objects.search_filter.value;
-}
-this.env.current_page=1;
-this.set_busy(true,"searching");
-this.http_request("search","_q="+urlencode(_109)+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):"")+(this.env.source?"&_source="+urlencode(this.env.source):"")+(_10a?_10a:""),true);
-}
-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(type,msg){
-this.list_mailbox();
-this.display_message(msg,type,true);
-};
-this.ksearch_keypress=function(e,obj){
-if(this.ksearch_timer){
-clearTimeout(this.ksearch_timer);
-}
-var _10f;
-var key=rcube_event.get_keycode(e);
-var mod=rcube_event.get_modifier(e);
-switch(key){
-case 38:
-case 40:
-if(!this.ksearch_pane){
-break;
-}
-var dir=key==38?1:0;
-_10f=document.getElementById("rcmksearchSelected");
-if(!_10f){
-_10f=this.ksearch_pane.ul.firstChild;
-}
-if(_10f){
-this.ksearch_select(dir?_10f.previousSibling:_10f.nextSibling);
-}
-return rcube_event.cancel(e);
-case 9:
-if(mod==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(e);
-case 27:
-this.ksearch_hide();
-break;
-case 37:
-case 39:
-if(mod!=SHIFT_KEY){
-return;
-}
-}
-this.ksearch_timer=window.setTimeout(function(){
-_1.ksearch_get_results();
-},200);
-this.ksearch_input=obj;
-return true;
-};
-this.ksearch_select=function(node){
-var _114=document.getElementById("rcmksearchSelected");
-if(_114&&node){
-_114.removeAttribute("id");
-this.set_classname(_114,"selected",false);
-}
-if(node){
-node.setAttribute("id","rcmksearchSelected");
-this.set_classname(node,"selected",true);
-this.ksearch_selected=node._rcm_id;
-}
-};
-this.insert_recipient=function(id){
-if(!this.env.contacts[id]||!this.ksearch_input){
-return;
-}
-var _116=this.ksearch_input.value.toLowerCase();
-var cpos=this.get_caret_pos(this.ksearch_input);
-var p=_116.lastIndexOf(this.ksearch_value,cpos);
-var pre=this.ksearch_input.value.substring(0,p);
-var end=this.ksearch_input.value.substring(p+this.ksearch_value.length,this.ksearch_input.value.length);
-var _11b=this.env.contacts[id]+", ";
-this.ksearch_input.value=pre+_11b+end;
-cpos=p+_11b.length;
-if(this.ksearch_input.setSelectionRange){
-this.ksearch_input.setSelectionRange(cpos,cpos);
-}
-};
-this.ksearch_get_results=function(){
-var _11c=this.ksearch_input?this.ksearch_input.value:null;
-if(_11c===null){
-return;
-}
-if(this.ksearch_pane&&this.ksearch_pane.visible){
-this.ksearch_pane.show(0);
-}
-var cpos=this.get_caret_pos(this.ksearch_input);
-var p=_11c.lastIndexOf(",",cpos-1);
-var q=_11c.substring(p+1,cpos);
-q=q.replace(/(^\s+|\s+$)/g,"").toLowerCase();
-if(!q.length||q==this.ksearch_value){
-return;
-}
-this.ksearch_value=q;
-this.display_message(this.get_label("searching"),"loading",true);
-this.http_post("autocomplete","_search="+q);
-};
-this.ksearch_query_results=function(_120,_121){
-if(_121!=this.ksearch_value){
-return;
-}
-this.hide_message();
-this.env.contacts=_120?_120:[];
-this.ksearch_display_results(this.env.contacts);
-};
-this.ksearch_display_results=function(_122){
-if(_122.length&&this.ksearch_input){
-var p,ul,li;
-if(!this.ksearch_pane){
-ul=document.createElement("UL");
-this.ksearch_pane=new rcube_layer("rcmKSearchpane",{vis:0,zindex:30000});
-this.ksearch_pane.elm.appendChild(ul);
-this.ksearch_pane.ul=ul;
-}else{
-ul=this.ksearch_pane.ul;
-}
-ul.innerHTML="";
-for(i=0;i<_122.length;i++){
-li=document.createElement("LI");
-li.innerHTML=_122[i].replace(new RegExp("("+this.ksearch_value+")","ig"),"##$1%%").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/##([^%]+)%%/g,"<b>$1</b>");
-li.onmouseover=function(){
-_1.ksearch_select(this);
-};
-li.onmouseup=function(){
-_1.ksearch_click(this);
-};
-li._rcm_id=i;
-ul.appendChild(li);
-}
-ul.firstChild.setAttribute("id","rcmksearchSelected");
-this.set_classname(ul.firstChild,"selected",true);
-this.ksearch_selected=0;
-var pos=rcube_get_object_pos(this.ksearch_input);
-this.ksearch_pane.move(pos.x,pos.y+this.ksearch_input.offsetHeight);
-this.ksearch_pane.show(1);
-}else{
-this.ksearch_hide();
-}
-};
-this.ksearch_click=function(node){
-if(this.ksearch_input){
-this.ksearch_input.focus();
-}
-this.insert_recipient(node._rcm_id);
-this.ksearch_hide();
-};
-this.ksearch_blur=function(){
-if(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;
-if(this.ksearch_pane){
-this.ksearch_pane.show(0);
-}
-};
-this.contactlist_keypress=function(list){
-if(list.key_pressed==list.DELETE_KEY){
-this.command("delete");
-}
-};
-this.contactlist_select=function(list){
-if(this.preview_timer){
-clearTimeout(this.preview_timer);
-}
-var id,_12b,_1=this;
-if(id=list.get_single_selection()){
-this.preview_timer=window.setTimeout(function(){
-_1.load_contact(id,"show");
-},200);
-}else{
-if(this.env.contentframe){
-this.show_contentframe(false);
-}
-}
-this.enable_command("compose",list.selection.length>0);
-this.enable_command("edit",(id&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly)?true:false);
-this.enable_command("delete",list.selection.length&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly);
-return false;
-};
-this.list_contacts=function(src,page){
-var _12e="";
-var _12f=window;
-if(!src){
-src=this.env.source;
-}
-if(page&&this.current_page==page&&src==this.env.source){
-return false;
-}
-if(src!=this.env.source){
-page=1;
-this.env.current_page=page;
-this.reset_qsearch();
-}
-this.select_folder(src,this.env.source);
-this.env.source=src;
-if(this.gui_objects.contactslist){
-this.list_contacts_remote(src,page);
-return;
-}
-if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
-_12f=window.frames[this.env.contentframe];
-_12e="&_framed=1";
-}
-if(this.env.search_request){
-_12e+="&_search="+this.env.search_request;
-}
-this.set_busy(true,"loading");
-_12f.location.href=this.env.comm_path+(src?"&_source="+urlencode(src):"")+(page?"&_page="+page:"")+_12e;
-};
-this.list_contacts_remote=function(src,page){
-this.contact_list.clear(true);
-this.show_contentframe(false);
-this.enable_command("delete","compose",false);
-var url=(src?"_source="+urlencode(src):"")+(page?(src?"&":"")+"_page="+page:"");
-this.env.source=src;
-if(this.env.search_request){
-url+="&_search="+this.env.search_request;
-}
-this.set_busy(true,"loading");
-this.http_request("list",url,true);
-};
-this.load_contact=function(cid,_134,_135){
-var _136="";
-var _137=window;
-if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
-_136="&_framed=1";
-_137=window.frames[this.env.contentframe];
-this.show_contentframe(true);
-}else{
-if(_135){
-return false;
-}
-}
-if(_134&&(cid||_134=="add")&&!this.drag_active){
-this.set_busy(true);
-_137.location.href=this.env.comm_path+"&_action="+_134+"&_source="+urlencode(this.env.source)+"&_cid="+urlencode(cid)+_136;
-}
-return true;
-};
-this.copy_contact=function(cid,to){
-if(!cid){
-cid=this.contact_list.get_selection().join(",");
-}
-if(to!=this.env.source&&cid&&this.env.address_sources[to]&&!this.env.address_sources[to].readonly){
-this.http_post("copy","_cid="+urlencode(cid)+"&_source="+urlencode(this.env.source)+"&_to="+urlencode(to));
-}
-};
-this.delete_contacts=function(){
-var _13a=this.contact_list.get_selection();
-if(!(_13a.length||this.env.cid)||!confirm(this.get_label("deletecontactconfirm"))){
-return;
-}
-var _13b=new Array();
-var qs="";
-if(this.env.cid){
-_13b[_13b.length]=this.env.cid;
-}else{
-var id;
-for(var n=0;n<_13a.length;n++){
-id=_13a[n];
-_13b[_13b.length]=id;
-this.contact_list.remove_row(id,(n==_13a.length-1));
-}
-if(_13a.length==1){
-this.show_contentframe(false);
-}
-}
-if(this.env.search_request){
-qs+="&_search="+this.env.search_request;
-}
-this.http_post("delete","_cid="+urlencode(_13b.join(","))+"&_source="+urlencode(this.env.source)+"&_from="+(this.env.action?this.env.action:"")+qs);
-return true;
-};
-this.update_contact_row=function(cid,_140){
-var row;
-if(this.contact_list.rows[cid]&&(row=this.contact_list.rows[cid].obj)){
-for(var c=0;c<_140.length;c++){
-if(row.cells[c]){
-row.cells[c].innerHTML=_140[c];
-}
-}
-return true;
-}
-return false;
-};
-this.init_subscription_list=function(){
-var p=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(o){
-p.subscription_select(o);
-});
-this.subscription_list.addEventListener("dragstart",function(o){
-p.drag_active=true;
-});
-this.subscription_list.addEventListener("dragend",function(o){
-p.subscription_move_folder(o);
-});
-this.subscription_list.row_init=function(row){
-var _148=row.obj.getElementsByTagName("A");
-if(_148[0]){
-_148[0].onclick=function(){
-p.rename_folder(row.id);
-return false;
-};
-}
-if(_148[1]){
-_148[1].onclick=function(){
-p.delete_folder(row.id);
-return false;
-};
-}
-row.obj.onmouseover=function(){
-p.focus_subscription(row.id);
-};
-row.obj.onmouseout=function(){
-p.unfocus_subscription(row.id);
-};
-};
-this.subscription_list.init();
-};
-this.identity_select=function(list){
-var id;
-if(id=list.get_single_selection()){
-this.load_identity(id,"edit-identity");
-}
-};
-this.load_identity=function(id,_14c){
-if(_14c=="edit-identity"&&(!id||id==this.env.iid)){
-return false;
-}
-var _14d="";
-var _14e=window;
-if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){
-_14d="&_framed=1";
-_14e=window.frames[this.env.contentframe];
-document.getElementById(this.env.contentframe).style.visibility="inherit";
-}
-if(_14c&&(id||_14c=="add-identity")){
-this.set_busy(true);
-_14e.location.href=this.env.comm_path+"&_action="+_14c+"&_iid="+id+_14d;
-}
-return true;
-};
-this.delete_identity=function(id){
-var _150=this.identity_list.get_selection();
-if(!(_150.length||this.env.iid)){
-return;
-}
-if(!id){
-id=this.env.iid?this.env.iid:_150[0];
-}
-this.goto_url("delete-identity","_iid="+id,true);
-return true;
-};
-this.focus_subscription=function(id){
-var row,_153;
-var reg=RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$");
-if(this.drag_active&&this.env.folder&&(row=document.getElementById(id))){
-if(this.env.subscriptionrows[id]&&(_153=this.env.subscriptionrows[id][0])){
-if(this.check_droptarget(_153)&&!this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2]&&(_153!=this.env.folder.replace(reg,""))&&(!_153.match(new RegExp("^"+RegExp.escape(this.env.folder+this.env.delimiter))))){
-this.set_env("dstfolder",_153);
-this.set_classname(row,"droptarget",true);
-}
-}else{
-if(this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter)))){
-this.set_env("dstfolder",this.env.delimiter);
-this.set_classname(this.subscription_list.frame,"droptarget",true);
-}
-}
-}
-};
-this.unfocus_subscription=function(id){
-var row;
-this.set_env("dstfolder",null);
-if(this.env.subscriptionrows[id]&&(row=document.getElementById(id))){
-this.set_classname(row,"droptarget",false);
-}else{
-this.set_classname(this.subscription_list.frame,"droptarget",false);
-}
-};
-this.subscription_select=function(list){
-var id,_159;
-if((id=list.get_single_selection())&&this.env.subscriptionrows["rcmrow"+id]&&(_159=this.env.subscriptionrows["rcmrow"+id][0])){
-this.set_env("folder",_159);
-}else{
-this.set_env("folder",null);
-}
-if(this.gui_objects.createfolderhint){
-this.gui_objects.createfolderhint.innerHTML=this.env.folder?this.get_label("addsubfolderhint"):"";
-}
-};
-this.subscription_move_folder=function(list){
-var reg=RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$");
-if(this.env.folder&&this.env.dstfolder&&(this.env.dstfolder!=this.env.folder)&&(this.env.dstfolder!=this.env.folder.replace(reg,""))){
-var reg=new RegExp("[^"+RegExp.escape(this.env.delimiter)+"]*["+RegExp.escape(this.env.delimiter)+"]","g");
-var _15c=this.env.folder.replace(reg,"");
-var _15d=this.env.dstfolder==this.env.delimiter?_15c:this.env.dstfolder+this.env.delimiter+_15c;
-this.set_busy(true,"foldermoving");
-this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.folder)+"&_folder_newname="+urlencode(_15d),true);
-}
-this.drag_active=false;
-this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder));
-};
-this.create_folder=function(name){
-if(this.edit_folder){
-this.reset_folder_rename();
-}
-var form;
-if((form=this.gui_objects.editform)&&form.elements["_folder_name"]){
-name=form.elements["_folder_name"].value;
-if(name.indexOf(this.env.delimiter)>=0){
-alert(this.get_label("forbiddencharacter")+" ("+this.env.delimiter+")");
-return false;
-}
-if(this.env.folder&&name!=""){
-name=this.env.folder+this.env.delimiter+name;
-}
-this.set_busy(true,"foldercreating");
-this.http_post("create-folder","_name="+urlencode(name),true);
-}else{
-if(form.elements["_folder_name"]){
-form.elements["_folder_name"].focus();
-}
-}
-};
-this.rename_folder=function(id){
-var temp,row,form;
-if(temp=this.edit_folder){
-this.reset_folder_rename();
-if(temp==id){
-return;
-}
-}
-if(id&&this.env.subscriptionrows[id]&&(row=document.getElementById(id))){
-var reg=new RegExp(".*["+RegExp.escape(this.env.delimiter)+"]");
-this.name_input=document.createElement("INPUT");
-this.name_input.value=this.env.subscriptionrows[id][0].replace(reg,"");
-this.name_input.style.width="100%";
-reg=new RegExp("["+RegExp.escape(this.env.delimiter)+"]?[^"+RegExp.escape(this.env.delimiter)+"]+$");
-this.name_input.__parent=this.env.subscriptionrows[id][0].replace(reg,"");
-this.name_input.onkeypress=function(e){
-rcmail.name_input_keypress(e);
-};
-row.cells[0].replaceChild(this.name_input,row.cells[0].firstChild);
-this.edit_folder=id;
-this.name_input.select();
-if(form=this.gui_objects.editform){
-form.onsubmit=function(){
-return false;
-};
-}
-}
-};
-this.reset_folder_rename=function(){
-var cell=this.name_input?this.name_input.parentNode:null;
-if(cell&&this.edit_folder&&this.env.subscriptionrows[this.edit_folder]){
-cell.innerHTML=this.env.subscriptionrows[this.edit_folder][1];
-}
-this.edit_folder=null;
-};
-this.name_input_keypress=function(e){
-var key=rcube_event.get_keycode(e);
-if(key==13){
-var _169=this.name_input?this.name_input.value:null;
-if(this.edit_folder&&_169){
-if(_169.indexOf(this.env.delimiter)>=0){
-alert(this.get_label("forbiddencharacter")+" ("+this.env.delimiter+")");
-return false;
-}
-if(this.name_input.__parent){
-_169=this.name_input.__parent+this.env.delimiter+_169;
-}
-this.set_busy(true,"folderrenaming");
-this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.subscriptionrows[this.edit_folder][0])+"&_folder_newname="+urlencode(_169),true);
-}
-}else{
-if(key==27){
-this.reset_folder_rename();
-}
-}
-};
-this.delete_folder=function(id){
-var _16b=this.env.subscriptionrows[id][0];
-if(this.edit_folder){
-this.reset_folder_rename();
-}
-if(_16b&&confirm(this.get_label("deletefolderconfirm"))){
-this.set_busy(true,"folderdeleting");
-this.http_post("delete-folder","_mboxes="+urlencode(_16b),true);
-this.set_env("folder",null);
-if(this.gui_objects.createfolderhint){
-this.gui_objects.createfolderhint.innerHTML="";
-}
-}
-};
-this.add_folder_row=function(name,_16d,_16e,_16f){
-if(!this.gui_objects.subscriptionlist){
-return false;
-}
-for(var _170 in this.env.subscriptionrows){
-if(this.env.subscriptionrows[_170]!=null&&!this.env.subscriptionrows[_170][2]){
-break;
-}
-}
-var _171,form;
-var _173=this.gui_objects.subscriptionlist.tBodies[0];
-var id="rcmrow"+(_173.childNodes.length+1);
-var _175=this.subscription_list.get_single_selection();
-if(_16e&&_16e.id){
-id=_16e.id;
-_170=_16e.id;
-}
-if(!id||!(_171=document.getElementById(_170))){
-this.goto_url("folders");
-}else{
-var row=this.clone_table_row(_171);
-row.id=id;
-if(_16f&&(_16f=this.get_folder_row_id(_16f))){
-_173.insertBefore(row,document.getElementById(_16f));
-}else{
-_173.appendChild(row);
-}
-if(_16e){
-_173.removeChild(_16e);
-}
-}
-this.env.subscriptionrows[row.id]=[name,_16d,0];
-row.cells[0].innerHTML=_16d;
-if(!_16e){
-row.cells[1].innerHTML="*";
-}
-if(!_16e&&row.cells[2]&&row.cells[2].firstChild.tagName=="INPUT"){
-row.cells[2].firstChild.value=name;
-row.cells[2].firstChild.checked=true;
-}
-if(!_16e&&(form=this.gui_objects.editform)){
-if(form.elements["_folder_oldname"]){
-form.elements["_folder_oldname"].options[form.elements["_folder_oldname"].options.length]=new Option(name,name);
-}
-if(form.elements["_folder_name"]){
-form.elements["_folder_name"].value="";
-}
-}
-this.init_subscription_list();
-if(_175&&document.getElementById("rcmrow"+_175)){
-this.subscription_list.select_row(_175);
-}
-if(document.getElementById(id).scrollIntoView){
-document.getElementById(id).scrollIntoView();
-}
-};
-this.replace_folder_row=function(_177,_178,_179,_17a){
-var id=this.get_folder_row_id(_177);
-var row=document.getElementById(id);
-this.add_folder_row(_178,_179,row,_17a);
-var form,elm;
-if((form=this.gui_objects.editform)&&(elm=form.elements["_folder_oldname"])){
-for(var i=0;i<elm.options.length;i++){
-if(elm.options[i].value==_177){
-elm.options[i].text=_179;
-elm.options[i].value=_178;
-break;
-}
-}
-form.elements["_folder_newname"].value="";
-}
-};
-this.remove_folder_row=function(_180){
-var row;
-var id=this.get_folder_row_id(_180);
-if(id&&(row=document.getElementById(id))){
-row.style.display="none";
-}
-var form;
-if((form=this.gui_objects.editform)&&form.elements["_folder_oldname"]){
-for(var i=0;i<form.elements["_folder_oldname"].options.length;i++){
-if(form.elements["_folder_oldname"].options[i].value==_180){
-form.elements["_folder_oldname"].options[i]=null;
-break;
-}
-}
-}
-if(form&&form.elements["_folder_newname"]){
-form.elements["_folder_newname"].value="";
-}
-};
-this.subscribe_folder=function(_185){
-if(_185){
-this.http_post("subscribe","_mbox="+urlencode(_185));
-}
-};
-this.unsubscribe_folder=function(_186){
-if(_186){
-this.http_post("unsubscribe","_mbox="+urlencode(_186));
-}
-};
-this.get_folder_row_id=function(_187){
-for(var id in this.env.subscriptionrows){
-if(this.env.subscriptionrows[id]&&this.env.subscriptionrows[id][0]==_187){
-break;
-}
-}
-return id;
-};
-this.clone_table_row=function(row){
-var cell,td;
-var _18c=document.createElement("TR");
-for(var n=0;n<row.cells.length;n++){
-cell=row.cells[n];
-td=document.createElement("TD");
-if(cell.className){
-td.className=cell.className;
-}
-if(cell.align){
-td.setAttribute("align",cell.align);
-}
-td.innerHTML=cell.innerHTML;
-_18c.appendChild(td);
-}
-return _18c;
-};
-this.set_page_buttons=function(){
-this.enable_command("nextpage",(this.env.pagecount>this.env.current_page));
-this.enable_command("lastpage",(this.env.pagecount>this.env.current_page));
-this.enable_command("previouspage",(this.env.current_page>1));
-this.enable_command("firstpage",(this.env.current_page>1));
-};
-this.set_button=function(_18e,_18f){
-var _190=this.buttons[_18e];
-var _191,obj;
-if(!_190||!_190.length){
-return false;
-}
-for(var n=0;n<_190.length;n++){
-_191=_190[n];
-obj=document.getElementById(_191.id);
-if(obj&&_191.type=="image"&&!_191.status){
-_191.pas=obj._original_src?obj._original_src:obj.src;
-if(obj.runtimeStyle&&obj.runtimeStyle.filter&&obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/)){
-_191.pas=RegExp.$1;
-}
-}else{
-if(obj&&!_191.status){
-_191.pas=String(obj.className);
-}
-}
-if(obj&&_191.type=="image"&&_191[_18f]){
-_191.status=_18f;
-obj.src=_191[_18f];
-}else{
-if(obj&&typeof (_191[_18f])!="undefined"){
-_191.status=_18f;
-obj.className=_191[_18f];
-}
-}
-if(obj&&_191.type=="input"){
-_191.status=_18f;
-obj.disabled=!_18f;
-}
-}
-};
-this.set_alttext=function(_194,_195){
-if(!this.buttons[_194]||!this.buttons[_194].length){
-return;
-}
-var _196,obj,link;
-for(var n=0;n<this.buttons[_194].length;n++){
-_196=this.buttons[_194][n];
-obj=document.getElementById(_196.id);
-if(_196.type=="image"&&obj){
-obj.setAttribute("alt",this.get_label(_195));
-if((link=obj.parentNode)&&link.tagName=="A"){
-link.setAttribute("title",this.get_label(_195));
-}
-}else{
-if(obj){
-obj.setAttribute("title",this.get_label(_195));
-}
-}
-}
-};
-this.button_over=function(_19a,id){
-var _19c=this.buttons[_19a];
-var _19d,img;
-if(!_19c||!_19c.length){
-return false;
-}
-for(var n=0;n<_19c.length;n++){
-_19d=_19c[n];
-if(_19d.id==id&&_19d.status=="act"){
-img=document.getElementById(_19d.id);
-if(img&&_19d.over){
-img.src=_19d.over;
-}
-}
-}
-};
-this.button_sel=function(_1a0,id){
-var _1a2=this.buttons[_1a0];
-var _1a3,img;
-if(!_1a2||!_1a2.length){
-return;
-}
-for(var n=0;n<_1a2.length;n++){
-_1a3=_1a2[n];
-if(_1a3.id==id&&_1a3.status=="act"){
-img=document.getElementById(_1a3.id);
-if(img&&_1a3.sel){
-img.src=_1a3.sel;
-}
-}
-}
-};
-this.button_out=function(_1a6,id){
-var _1a8=this.buttons[_1a6];
-var _1a9,img;
-if(!_1a8||!_1a8.length){
-return;
-}
-for(var n=0;n<_1a8.length;n++){
-_1a9=_1a8[n];
-if(_1a9.id==id&&_1a9.status=="act"){
-img=document.getElementById(_1a9.id);
-if(img&&_1a9.act){
-img.src=_1a9.act;
-}
-}
-}
-};
-this.set_classname=function(obj,_1ad,set){
-var reg=new RegExp("s*"+_1ad,"i");
-if(!set&&obj.className.match(reg)){
-obj.className=obj.className.replace(reg,"");
-}else{
-if(set&&!obj.className.match(reg)){
-obj.className+=" "+_1ad;
-}
-}
-};
-this.set_pagetitle=function(_1b0){
-if(_1b0&&document.title){
-document.title=_1b0;
-}
-};
-this.display_message=function(msg,type,hold){
-if(!this.loaded){
-this.pending_message=new Array(msg,type);
-return true;
-}
-if(this.env.framed&&parent.rcmail){
-return parent.rcmail.display_message(msg,type,hold);
-}
-if(!this.gui_objects.message){
-return false;
-}
-if(this.message_timer){
-clearTimeout(this.message_timer);
-}
-var cont=msg;
-if(type){
-cont="<div class=\""+type+"\">"+cont+"</div>";
-}
-var _1b5=this;
-this.gui_objects.message.innerHTML=cont;
-this.gui_objects.message.style.display="block";
-if(type!="loading"){
-this.gui_objects.message.onmousedown=function(){
-_1b5.hide_message();
-return true;
-};
-}
-if(!hold){
-this.message_timer=window.setTimeout(function(){
-_1.hide_message();
-},this.message_time);
-}
-};
-this.hide_message=function(){
-if(this.gui_objects.message){
-this.gui_objects.message.style.display="none";
-this.gui_objects.message.onmousedown=null;
-}
-};
-this.select_folder=function(name,old){
-if(this.gui_objects.folderlist){
-var _1b8,_1b9;
-if((_1b8=this.get_folder_li(old))){
-this.set_classname(_1b8,"selected",false);
-this.set_classname(_1b8,"unfocused",false);
-}
-if((_1b9=this.get_folder_li(name))){
-this.set_classname(_1b9,"unfocused",false);
-this.set_classname(_1b9,"selected",true);
-}
-}
-};
-this.get_folder_li=function(name){
-if(this.gui_objects.folderlist){
-name=String(name).replace(this.identifier_expr,"");
-return document.getElementById("rcmli"+name);
-}
-return null;
-};
-this.set_message_coltypes=function(_1bb){
-this.coltypes=_1bb;
-var cell,col;
-var _1be=this.gui_objects.messagelist?this.gui_objects.messagelist.tHead:null;
-for(var n=0;_1be&&n<this.coltypes.length;n++){
-col=this.coltypes[n];
-if((cell=_1be.rows[0].cells[n+1])&&(col=="from"||col=="to")){
-if(cell.firstChild&&cell.firstChild.tagName=="A"){
-cell.firstChild.innerHTML=this.get_label(this.coltypes[n]);
-cell.firstChild.onclick=function(){
-return rcmail.command("sort",this.__col,this);
-};
-cell.firstChild.__col=col;
-}else{
-cell.innerHTML=this.get_label(this.coltypes[n]);
-}
-cell.id="rcm"+col;
-}else{
-if(col=="subject"&&this.message_list){
-this.message_list.subject_col=n+1;
-}
-}
-}
-};
-this.add_message_row=function(uid,cols,_1c2,_1c3,_1c4){
-if(!this.gui_objects.messagelist||!this.message_list){
-return false;
-}
-var _1c5=this.gui_objects.messagelist.tBodies[0];
-var _1c6=_1c5.rows.length;
-var even=_1c6%2;
-this.env.messages[uid]={deleted:_1c2.deleted?1:0,replied:_1c2.replied?1:0,unread:_1c2.unread?1:0,forwarded:_1c2.forwarded?1:0,flagged:_1c2.flagged?1:0};
-var row=document.createElement("TR");
-row.id="rcmrow"+uid;
-row.className="message"+(even?" even":" odd")+(_1c2.unread?" unread":"")+(_1c2.deleted?" deleted":"")+(_1c2.flagged?" flagged":"");
-if(this.message_list.in_selection(uid)){
-row.className+=" selected";
-}
-var icon=this.env.messageicon;
-if(_1c2.deleted&&this.env.deletedicon){
-icon=this.env.deletedicon;
-}else{
-if(_1c2.replied&&this.env.repliedicon){
-if(_1c2.forwarded&&this.env.forwardedrepliedicon){
-icon=this.env.forwardedrepliedicon;
-}else{
-icon=this.env.repliedicon;
-}
-}else{
-if(_1c2.forwarded&&this.env.forwardedicon){
-icon=this.env.forwardedicon;
-}else{
-if(_1c2.unread&&this.env.unreadicon){
-icon=this.env.unreadicon;
-}
-}
-}
-}
-var col=document.createElement("TD");
-col.className="icon";
-col.innerHTML=icon?"<img src=\""+icon+"\" alt=\"\" />":"";
-row.appendChild(col);
-for(var n=0;n<this.coltypes.length;n++){
-var c=this.coltypes[n];
-col=document.createElement("TD");
-col.className=String(c).toLowerCase();
-if(c=="flag"){
-if(_1c2.flagged&&this.env.flaggedicon){
-col.innerHTML="<img src=\""+this.env.flaggedicon+"\" alt=\"\" />";
-}else{
-if(!_1c2.flagged&&this.env.unflaggedicon){
-col.innerHTML="<img src=\""+this.env.unflaggedicon+"\" alt=\"\" />";
-}
-}
-}else{
-if(c=="attachment"){
-col.innerHTML=_1c3&&this.env.attachmenticon?"<img src=\""+this.env.attachmenticon+"\" alt=\"\" />":"&nbsp;";
-}else{
-col.innerHTML=cols[c];
-}
-}
-row.appendChild(col);
-}
-this.message_list.insert_row(row,_1c4);
-if(_1c4&&this.env.pagesize&&this.message_list.rowcount>this.env.pagesize){
-var uid=this.message_list.get_last_row();
-this.message_list.remove_row(uid);
-this.message_list.clear_selection(uid);
-}
-};
-this.set_rowcount=function(text){
-if(this.gui_objects.countdisplay){
-this.gui_objects.countdisplay.innerHTML=text;
-}
-this.set_page_buttons();
-};
-this.set_mailboxname=function(_1ce){
-if(this.gui_objects.mailboxname&&_1ce){
-this.gui_objects.mailboxname.innerHTML=_1ce;
-}
-};
-this.set_quota=function(_1cf){
-if(this.gui_objects.quotadisplay&&_1cf){
-this.gui_objects.quotadisplay.innerHTML=_1cf;
-}
-};
-this.set_unread_count=function(mbox,_1d1,_1d2){
-if(!this.gui_objects.mailboxlist){
-return false;
-}
-this.env.unread_counts[mbox]=_1d1;
-this.set_unread_count_display(mbox,_1d2);
-};
-this.set_unread_count_display=function(mbox,_1d4){
-var reg,_1d6,item,_1d8,_1d9,div;
-if(item=this.get_folder_li(mbox)){
-_1d8=this.env.unread_counts[mbox]?this.env.unread_counts[mbox]:0;
-_1d6=item.getElementsByTagName("a")[0];
-reg=/\s+\([0-9]+\)$/i;
-_1d9=0;
-if((div=item.getElementsByTagName("div")[0])&&div.className.match(/collapsed/)){
-for(var k in this.env.unread_counts){
-if(k.indexOf(mbox+this.env.delimiter)==0){
-_1d9+=this.env.unread_counts[k];
-}
-}
-}
-if(_1d8&&_1d6.innerHTML.match(reg)){
-_1d6.innerHTML=_1d6.innerHTML.replace(reg," ("+_1d8+")");
-}else{
-if(_1d8){
-_1d6.innerHTML+=" ("+_1d8+")";
-}else{
-_1d6.innerHTML=_1d6.innerHTML.replace(reg,"");
-}
-}
-reg=new RegExp(RegExp.escape(this.env.delimiter)+"[^"+RegExp.escape(this.env.delimiter)+"]+$");
-if(mbox.match(reg)){
-this.set_unread_count_display(mbox.replace(reg,""),false);
-}
-this.set_classname(item,"unread",(_1d8+_1d9)>0?true:false);
-}
-reg=/^\([0-9]+\)\s+/i;
-if(_1d4&&document.title){
-var _1dc=String(document.title);
-var _1dd="";
-if(_1d8&&_1dc.match(reg)){
-_1dd=_1dc.replace(reg,"("+_1d8+") ");
-}else{
-if(_1d8){
-_1dd="("+_1d8+") "+_1dc;
-}else{
-_1dd=_1dc.replace(reg,"");
-}
-}
-this.set_pagetitle(_1dd);
-}
-};
-this.new_message_focus=function(){
-if(this.env.framed&&window.parent){
-window.parent.focus();
-}else{
-window.focus();
-}
-};
-this.add_contact_row=function(cid,cols,_1e0){
-if(!this.gui_objects.contactslist||!this.gui_objects.contactslist.tBodies[0]){
-return false;
-}
-var _1e1=this.gui_objects.contactslist.tBodies[0];
-var _1e2=_1e1.rows.length;
-var even=_1e2%2;
-var row=document.createElement("TR");
-row.id="rcmrow"+cid;
-row.className="contact "+(even?"even":"odd");
-if(this.contact_list.in_selection(cid)){
-row.className+=" selected";
-}
-for(var c in cols){
-col=document.createElement("TD");
-col.className=String(c).toLowerCase();
-col.innerHTML=cols[c];
-row.appendChild(col);
-}
-this.contact_list.insert_row(row);
-this.enable_command("export",(this.contact_list.rowcount>0));
-};
-this.toggle_prefer_html=function(_1e6){
-var _1e7;
-if(_1e7=document.getElementById("rcmfd_addrbook_show_images")){
-_1e7.disabled=!_1e6.checked;
-}
-};
-this.set_headers=function(_1e8){
-if(this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box&&_1e8){
-var box=this.gui_objects.all_headers_box;
-box.innerHTML=_1e8;
-box.style.display="block";
-if(this.env.framed&&parent.rcmail){
-parent.rcmail.set_busy(false);
-}else{
-this.set_busy(false);
-}
-}
-};
-this.load_headers=function(elem){
-if(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box||!this.env.uid){
-return;
-}
-this.set_classname(elem,"show-headers",false);
-this.set_classname(elem,"hide-headers",true);
-this.gui_objects.all_headers_row.style.display=bw.ie?"block":"table-row";
-elem.onclick=function(){
-rcmail.hide_headers(elem);
-};
-if(!this.gui_objects.all_headers_box.innerHTML){
-this.display_message(this.get_label("loading"),"loading",true);
-this.http_post("headers","_uid="+this.env.uid);
-}
-};
-this.hide_headers=function(elem){
-if(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box){
-return;
-}
-this.set_classname(elem,"hide-headers",false);
-this.set_classname(elem,"show-headers",true);
-this.gui_objects.all_headers_row.style.display="none";
-elem.onclick=function(){
-rcmail.load_headers(elem);
-};
-};
-this.html2plain=function(_1ec,id){
-var _1ee=new rcube_http_request();
-var url=this.env.bin_path+"html2text.php";
-var _1f0=this;
-this.set_busy(true,"converting");
-console.log("HTTP POST: "+url);
-_1ee.onerror=function(o){
-_1f0.http_error(o);
-};
-_1ee.oncomplete=function(o){
-_1f0.set_text_value(o,id);
-};
-_1ee.POST(url,_1ec,"application/octet-stream");
-};
-this.set_text_value=function(_1f3,id){
-this.set_busy(false);
-document.getElementById(id).value=_1f3.get_text();
-console.log(_1f3.get_text());
-};
-this.redirect=function(url,lock){
-if(lock||lock===null){
-this.set_busy(true);
-}
-if(this.env.framed&&window.parent){
-parent.location.href=url;
-}else{
-location.href=url;
-}
-};
-this.goto_url=function(_1f7,_1f8,lock){
-var _1fa=_1f8?"&"+_1f8:"";
-this.redirect(this.env.comm_path+"&_action="+_1f7+_1fa,lock);
-};
-this.http_sockets=new Array();
-this.get_request_obj=function(){
-for(var n=0;n<this.http_sockets.length;n++){
-if(!this.http_sockets[n].busy){
-return this.http_sockets[n];
-}
-}
-var i=this.http_sockets.length;
-this.http_sockets[i]=new rcube_http_request();
-return this.http_sockets[i];
-};
-this.http_request=function(_1fd,_1fe,lock){
-var _200=this.get_request_obj();
-_1fe+=(_1fe?"&":"")+"_remote=1";
-if(bw.safari){
-_1fe+="&_ts="+(new Date().getTime());
-}
-if(_200){
-console.log("HTTP request: "+this.env.comm_path+"&_action="+_1fd+"&"+_1fe);
-if(lock){
-this.set_busy(true);
-}
-var rcm=this;
-_200.__lock=lock?true:false;
-_200.__action=_1fd;
-_200.onerror=function(o){
-_1.http_error(o);
-};
-_200.oncomplete=function(o){
-_1.http_response(o);
-};
-_200.GET(this.env.comm_path+"&_action="+_1fd+"&"+_1fe);
-}
-};
-this.http_post=function(_204,_205,lock){
-var _207;
-if(_205&&typeof (_205)=="object"){
-_205._remote=1;
-}else{
-_205+=(_205?"&":"")+"_remote=1";
-}
-if(_207=this.get_request_obj()){
-console.log("HTTP POST: "+this.env.comm_path+"&_action="+_204);
-if(lock){
-this.set_busy(true);
-}
-var rcm=this;
-_207.__lock=lock?true:false;
-_207.__action=_204;
-_207.onerror=function(o){
-rcm.http_error(o);
-};
-_207.oncomplete=function(o){
-rcm.http_response(o);
-};
-_207.POST(this.env.comm_path+"&_action="+_204,_205);
-}
-};
-this.http_response=function(_20b){
-var _20c=_20b.get_header("Content-Type");
-if(_20c){
-_20c=String(_20c).toLowerCase();
-var _20d=_20c.split(";");
-_20c=_20d[0];
-}
-if(_20b.__lock){
-this.set_busy(false);
-}
-console.log(_20b.get_text());
-if(_20b.get_text()&&(_20c=="text/javascript"||_20c=="application/x-javascript")){
-eval(_20b.get_text());
-}
-switch(_20b.__action){
-case "delete":
-if(this.task=="addressbook"){
-var uid=this.contact_list.get_selection();
-this.enable_command("compose",(uid&&this.contact_list.rows[uid]));
-this.enable_command("delete","edit",(uid&&this.contact_list.rows[uid]&&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.command("list");
-}else{
-if(this.message_list){
-this.message_list.init();
-}
-}
-break;
-case "purge":
-case "expunge":
-if(!this.env.messagecount&&this.task=="mail"){
-if(this.env.contentframe){
-this.show_contentframe(false);
-}
-this.enable_command("show","reply","reply-all","forward","moveto","delete","mark","viewsource","print","load-attachment","purge","expunge","select-all","select-none","sort",false);
-}
-break;
-case "check-recent":
-case "getunread":
-case "list":
-if(this.task=="mail"){
-if(this.message_list&&_20b.__action=="list"){
-this.msglist_select(this.message_list);
-}
-this.enable_command("show","expunge","select-all","select-none","sort",(this.env.messagecount>0));
-this.enable_command("purge",this.purge_mailbox_test());
-}else{
-if(this.task=="addressbook"){
-this.enable_command("export",(this.contact_list&&this.contact_list.rowcount>0));
-}
-}
-break;
-}
-_20b.reset();
-};
-this.http_error=function(_20f){
-if(_20f.__lock){
-this.set_busy(false);
-}
-_20f.reset();
-_20f.__lock=false;
-this.display_message("Unknown Server Error!","error");
-};
-this.send_keep_alive=function(){
-var d=new Date();
-this.http_request("keep-alive","_t="+d.getTime());
-};
-this.check_for_recent=function(_211){
-if(this.busy){
-return;
-}
-if(_211){
-this.set_busy(true,"checkingmail");
-}
-var _212="_t="+(new Date().getTime());
-if(this.gui_objects.messagelist){
-_212+="&_list=1";
-}
-if(this.gui_objects.quotadisplay){
-_212+="&_quota=1";
-}
-if(this.env.search_request){
-_212+="&_search="+this.env.search_request;
-}
-this.http_request("check-recent",_212,true);
-};
-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(obj){
-if(typeof (obj.selectionEnd)!="undefined"){
-return obj.selectionEnd;
-}else{
-if(document.selection&&document.selection.createRange){
-var _214=document.selection.createRange();
-if(_214.parentElement()!=obj){
-return 0;
-}
-var gm=_214.duplicate();
-if(obj.tagName=="TEXTAREA"){
-gm.moveToElementText(obj);
-}else{
-gm.expand("textedit");
-}
-gm.setEndPoint("EndToStart",_214);
-var p=gm.text.length;
-return p<=obj.value.length?p:-1;
-}else{
-return obj.value.length;
-}
-}
-};
-this.set_caret2start=function(obj){
-if(obj.createTextRange){
-var _218=obj.createTextRange();
-_218.collapse(true);
-_218.select();
-}else{
-if(obj.setSelectionRange){
-obj.setSelectionRange(0,0);
-}
-}
-obj.focus();
-};
-this.lock_form=function(form,lock){
-if(!form||!form.elements){
-return;
-}
-var type;
-for(var n=0;n<form.elements.length;n++){
-type=form.elements[n];
-if(type=="hidden"){
-continue;
-}
-form.elements[n].disabled=lock;
-}
-};
-};
-function rcube_http_request(){
-this.url="";
-this.busy=false;
-this.xmlhttp=null;
-this.reset=function(){
-this.onloading=function(){
-};
-this.onloaded=function(){
-};
-this.oninteractive=function(){
-};
-this.oncomplete=function(){
-};
-this.onabort=function(){
-};
-this.onerror=function(){
-};
-this.url="";
-this.busy=false;
-this.xmlhttp=null;
-};
-this.build=function(){
-if(window.XMLHttpRequest){
-this.xmlhttp=new XMLHttpRequest();
-}else{
-if(window.ActiveXObject){
-try{
-this.xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
-}
-catch(e){
-this.xmlhttp=null;
-}
-}else{
-}
-}
-};
-this.GET=function(url){
-this.build();
-if(!this.xmlhttp){
-this.onerror(this);
-return false;
-}
-var _ref=this;
-this.url=url;
-this.busy=true;
-this.xmlhttp.onreadystatechange=function(){
-_ref.xmlhttp_onreadystatechange();
-};
-this.xmlhttp.open("GET",url,true);
-this.xmlhttp.setRequestHeader("X-RoundCube-Referer",bw.get_cookie("roundcube_sessid"));
-this.xmlhttp.send(null);
-};
-this.POST=function(url,body,_221){
-if(typeof (_221)=="undefined"){
-_221="application/x-www-form-urlencoded";
-}
-this.build();
-if(!this.xmlhttp){
-this.onerror(this);
-return false;
-}
-var _222=body;
-if(typeof (body)=="object"){
-_222="";
-for(var p in body){
-_222+=(_222?"&":"")+p+"="+urlencode(body[p]);
-}
-}
-var ref=this;
-this.url=url;
-this.busy=true;
-this.xmlhttp.onreadystatechange=function(){
-ref.xmlhttp_onreadystatechange();
-};
-this.xmlhttp.open("POST",url,true);
-this.xmlhttp.setRequestHeader("Content-Type",_221);
-this.xmlhttp.setRequestHeader("X-RoundCube-Referer",bw.get_cookie("roundcube_sessid"));
-this.xmlhttp.send(_222);
-};
-this.xmlhttp_onreadystatechange=function(){
-if(this.xmlhttp.readyState==1){
-this.onloading(this);
-}else{
-if(this.xmlhttp.readyState==2){
-this.onloaded(this);
-}else{
-if(this.xmlhttp.readyState==3){
-this.oninteractive(this);
-}else{
-if(this.xmlhttp.readyState==4){
-try{
-if(this.xmlhttp.status==0){
-this.onabort(this);
-}else{
-if(this.xmlhttp.status==200){
-this.oncomplete(this);
-}else{
-this.onerror(this);
-}
-}
-this.busy=false;
-}
-catch(err){
-this.onerror(this);
-this.busy=false;
-}
-}
-}
-}
-}
-};
-this.get_header=function(name){
-return this.xmlhttp.getResponseHeader(name);
-};
-this.get_text=function(){
-return this.xmlhttp.responseText;
-};
-this.get_xml=function(){
-return this.xmlhttp.responseXML;
-};
-this.reset();
-};
-function call_init(o){
-window.setTimeout("if (window['"+o+"'] && window['"+o+"'].init) { "+o+".init(); }",bw.win?500:200);
-};
+/*
+ +-----------------------------------------------------------------------+
+ | RoundCube Webmail Client Script                                       |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2005-2009, RoundCube Dev, - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
+ |          Charles McNulty <charles@charlesmcnulty.com>                 |
+ +-----------------------------------------------------------------------+
+ | Requires: jquery.js, common.js, list.js                               |
+ +-----------------------------------------------------------------------+
+
+  $Id: app.js 2889 2009-08-29 18:41:17Z alec $
+*/
+
+
+function rcube_webmail()
+{
+  this.env = new Object();
+  this.labels = new Object();
+  this.buttons = new Object();
+  this.buttons_sel = new Object();
+  this.gui_objects = new Object();
+  this.gui_containers = new Object();
+  this.commands = new Object();
+  this.command_handlers = new Object();
+  this.onloads = new Array();
+
+  // create protected reference to myself
+  this.ref = 'rcmail';
+  var ref = this;
+  // webmail client settings
+  this.dblclick_time = 500;
+  this.message_time = 3000;
+  
+  this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi');
+  
+  // mimetypes supported by the browser (default settings)
+  this.mimetypes = new Array('text/plain', 'text/html', 'text/xml',
+                             'image/jpeg', 'image/gif', 'image/png',
+                             'application/x-javascript', 'application/pdf',
+                             'application/x-shockwave-flash');
+
+  // default environment vars
+  this.env.keep_alive = 60;        // seconds
+  this.env.request_timeout = 180;  // seconds
+  this.env.draft_autosave = 0;     // seconds
+  this.env.comm_path = './';
+  this.env.bin_path = './bin/';
+  this.env.blankpage = 'program/blank.gif';
+
+  // set jQuery ajax options
+  jQuery.ajaxSetup({ cache:false,
+    error:function(request, status, err){ ref.http_error(request, status, err); },
+    beforeSend:function(xmlhttp){ xmlhttp.setRequestHeader('X-RoundCube-Request', ref.env.request_token); }
+  });
+
+  // set environment variable(s)
+  this.set_env = function(p, value)
+    {
+    if (p != null && typeof(p) == 'object' && !value)
+      for (var n in p)
+        this.env[n] = p[n];
+    else
+      this.env[p] = value;
+    };
+
+  // add a localized label to the client environment
+  this.add_label = function(key, value)
+    {
+    this.labels[key] = value;
+    };
+
+  // add a button to the button list
+  this.register_button = function(command, id, type, act, sel, over)
+    {
+    if (!this.buttons[command])
+      this.buttons[command] = new Array();
+      
+    var button_prop = {id:id, type:type};
+    if (act) button_prop.act = act;
+    if (sel) button_prop.sel = sel;
+    if (over) button_prop.over = over;
+
+    this.buttons[command][this.buttons[command].length] = button_prop;    
+    };
+
+  // register a specific gui object
+  this.gui_object = function(name, id)
+    {
+    this.gui_objects[name] = id;
+    };
+  
+  // register a container object
+  this.gui_container = function(name, id)
+  {
+    this.gui_containers[name] = id;
+  };
+  
+  // add a GUI element (html node) to a specified container
+  this.add_element = function(elm, container)
+  {
+    if (this.gui_containers[container] && this.gui_containers[container].jquery)
+      this.gui_containers[container].append(elm);
+  };
+
+  // register an external handler for a certain command
+  this.register_command = function(command, callback, enable)
+  {
+    this.command_handlers[command] = callback;
+    
+    if (enable)
+      this.enable_command(command, true);
+  };
+  
+  // execute the given script on load
+  this.add_onload = function(f)
+  {
+    this.onloads[this.onloads.length] = f;
+  };
+
+  // initialize webmail client
+  this.init = function()
+    {
+    var p = this;
+    this.task = this.env.task;
+    
+    // check browser
+    if (!bw.dom || !bw.xmlhttp_test())
+      {
+      this.goto_url('error', '_code=0x199');
+      return;
+      }
+
+    // find all registered gui containers
+    for (var n in this.gui_containers)
+      this.gui_containers[n] = $('#'+this.gui_containers[n]);
+
+    // find all registered gui objects
+    for (var n in this.gui_objects)
+      this.gui_objects[n] = rcube_find_object(this.gui_objects[n]);
+      
+    // init registered buttons
+    this.init_buttons();
+
+    // tell parent window that this frame is loaded
+    if (this.env.framed && parent.rcmail && parent.rcmail.set_busy)
+      parent.rcmail.set_busy(false);
+
+    // enable general commands
+    this.enable_command('logout', 'mail', 'addressbook', 'settings', true);
+    
+    if (this.env.permaurl)
+      this.enable_command('permaurl', true);
+
+    switch (this.task)
+      {
+      case 'mail':
+        if (this.gui_objects.messagelist)
+          {
+          this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {multiselect:true, draggable:true, keyboard:true, dblclick_time:this.dblclick_time});
+          this.message_list.row_init = function(o){ p.init_message_row(o); };
+          this.message_list.addEventListener('dblclick', function(o){ p.msglist_dbl_click(o); });
+          this.message_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); });
+          this.message_list.addEventListener('select', function(o){ p.msglist_select(o); });
+          this.message_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
+          this.message_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
+          this.message_list.addEventListener('dragend', function(e){ p.drag_end(e); });
+          document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+
+          this.message_list.init();
+          this.enable_command('toggle_status', 'toggle_flag', true);
+          
+          if (this.gui_objects.mailcontframe)
+            this.gui_objects.mailcontframe.onmousedown = function(e){ return p.click_on_list(e); };
+          else
+            this.message_list.focus();
+          }
+          
+        if (this.env.coltypes)
+          this.set_message_coltypes(this.env.coltypes);
+
+        // enable mail commands
+        this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
+
+        if (this.env.search_text != null && document.getElementById('quicksearchbox') != null)
+          document.getElementById('quicksearchbox').value = this.env.search_text;
+        
+        if (this.env.action=='show' || this.env.action=='preview')
+          {
+          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete',
+            'open', 'mark', 'edit', 'viewsource', 'download', 'print', 'load-attachment', 'load-headers', true);
+
+          if (this.env.next_uid)
+            {
+            this.enable_command('nextmessage', true);
+            this.enable_command('lastmessage', true);
+            }
+          if (this.env.prev_uid)
+            {
+            this.enable_command('previousmessage', true);
+            this.enable_command('firstmessage', true);
+            }
+        
+          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.trash_mailbox && this.env.mailbox != this.env.trash_mailbox)
+          this.set_alttext('delete', 'movemessagetotrash');
+        
+        // make preview/message frame visible
+        if (this.env.action == 'preview' && this.env.framed && parent.rcmail)
+          {
+          this.enable_command('compose', 'add-contact', false);
+          parent.rcmail.show_contentframe(true);
+          }
+
+        if (this.env.action=='compose')
+          {
+          this.enable_command('add-attachment', 'send-attachment', 'remove-attachment', 'send', true);
+          if (this.env.spellcheck)
+            {
+            this.env.spellcheck.spelling_state_observer = function(s){ ref.set_spellcheck_state(s); };
+            this.set_spellcheck_state('ready');
+            if ($("input[name='_is_html']").val() == '1')
+              this.display_spellcheck_controls(false);
+            }
+          if (this.env.drafts_mailbox)
+            this.enable_command('savedraft', true);
+            
+          document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+
+          // init message compose form
+          this.init_messageform();
+          }
+
+        if (this.env.messagecount)
+          this.enable_command('select-all', 'select-none', 'expunge', true);
+
+        if (this.purge_mailbox_test())
+          this.enable_command('purge', true);
+
+        this.set_page_buttons();
+
+        // show printing dialog
+        if (this.env.action=='print')
+          window.print();
+
+        // get unread count for each mailbox
+        if (this.gui_objects.mailboxlist)
+        {
+          this.env.unread_counts = {};
+          this.gui_objects.folderlist = this.gui_objects.mailboxlist;
+          this.http_request('getunread', '');
+        }
+        
+        // ask user to send MDN
+        if (this.env.mdn_request && this.env.uid)
+        {
+          var mdnurl = '_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox);
+          if (confirm(this.get_label('mdnrequest')))
+            this.http_post('sendmdn', mdnurl);
+          else
+            this.http_post('mark', mdnurl+'&_flag=mdnsent');
+        }
+
+        break;
+
+
+      case 'addressbook':
+        if (this.gui_objects.contactslist)
+          {
+          this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, {multiselect:true, draggable:true, keyboard:true});
+          this.contact_list.row_init = function(row){ p.triggerEvent('insertrow', { cid:row.uid, row:row }); };
+          this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); });
+          this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); });
+          this.contact_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
+          this.contact_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
+          this.contact_list.addEventListener('dragend', function(e){ p.drag_end(e); });
+          this.contact_list.init();
+
+          if (this.env.cid)
+            this.contact_list.highlight_row(this.env.cid);
+
+          if (this.gui_objects.contactslist.parentNode)
+            {
+            this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
+            document.onmouseup = function(e){ return p.doc_mouse_up(e); };
+            }
+          else
+            this.contact_list.focus();
+            
+          this.gui_objects.folderlist = this.gui_objects.contactslist;
+          }
+
+        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', true);
+        
+        if (this.env.cid)
+          this.enable_command('show', 'edit', true);
+
+        if ((this.env.action=='add' || this.env.action=='edit') && this.gui_objects.editform)
+          this.enable_command('save', true);
+        else
+          this.enable_command('search', 'reset-search', 'moveto', 'import', true);
+          
+        if (this.contact_list && this.contact_list.rowcount > 0)
+          this.enable_command('export', true);
+
+        this.enable_command('list', 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', true);
+        }
+        else if (this.env.action=='folders')
+          this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', 'delete-folder', true);
+
+        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(o){ p.identity_select(o); });
+          this.identity_list.init();
+          this.identity_list.focus();
+
+          if (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(o){ p.section_select(o); });
+          this.sections_list.init();
+          this.sections_list.focus();
+          this.sections_list.select('general');  // open first section by default
+        }
+        else if (this.gui_objects.subscriptionlist)
+          this.init_subscription_list();
+
+        break;
+
+      case 'login':
+        var input_user = $('#rcmloginuser');
+        input_user.bind('keyup', function(e){ return rcmail.login_user_keyup(e); });
+        
+        if (input_user.val() == '')
+          input_user.focus();
+        else
+          $('#rcmloginpwd').focus();
+
+        // detect client timezone
+        $('#rcmlogintz').val(new Date().getTimezoneOffset() / -60);
+
+        this.enable_command('login', true);
+        break;
+      
+      default:
+        break;
+      }
+
+    // flag object as complete
+    this.loaded = true;
+
+    // show message
+    if (this.pending_message)
+      this.display_message(this.pending_message[0], this.pending_message[1]);
+      
+    // map implicit containers
+    if (this.gui_objects.folderlist)
+      this.gui_containers.foldertray = $(this.gui_objects.folderlist);
+
+    // trigger init event hook
+    this.triggerEvent('init', { task:this.task, action:this.env.action });
+    
+    // execute all foreign onload scripts
+    // @deprecated
+    for (var i=0; i<this.onloads.length; i++)
+      {
+      if (typeof(this.onloads[i]) == 'string')
+        eval(this.onloads[i]);
+      else if (typeof(this.onloads[i]) == 'function')
+        this.onloads[i]();
+      }
+
+    // start keep-alive interval
+    this.start_keepalive();
+  };
+
+  // start interval for keep-alive/recent_check signal
+  this.start_keepalive = function()
+    {
+    if (this.env.keep_alive && !this.env.framed && this.task=='mail' && this.gui_objects.mailboxlist)
+      this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000);
+    else if (this.env.keep_alive && !this.env.framed && this.task!='login')
+      this._int = setInterval(function(){ ref.send_keep_alive(); }, this.env.keep_alive * 1000);
+    }
+
+  this.init_message_row = function(row)
+  {
+    var uid = row.uid;
+    if (uid && this.env.messages[uid])
+      {
+      row.deleted = this.env.messages[uid].deleted ? true : false;
+      row.unread = this.env.messages[uid].unread ? true : false;
+      row.replied = this.env.messages[uid].replied ? true : false;
+      row.flagged = this.env.messages[uid].flagged ? true : false;
+      row.forwarded = this.env.messages[uid].forwarded ? true : false;
+      }
+
+    // set eventhandler to message icon
+    if (row.icon = row.obj.getElementsByTagName('td')[0].getElementsByTagName('img')[0])
+      {
+      var p = this;
+      row.icon.id = 'msgicn_'+row.uid;
+      row.icon._row = row.obj;
+      row.icon.onmousedown = function(e) { p.command('toggle_status', this); };
+      }
+
+    // global variable 'flagged_col' may be not defined yet
+    if (!this.env.flagged_col && this.env.coltypes)
+      {
+      var found;
+      if((found = find_in_array('flag', this.env.coltypes)) >= 0)
+        this.set_env('flagged_col', found+1);
+      }
+
+    // set eventhandler to flag icon, if icon found
+    if (this.env.flagged_col && (row.flagged_icon = row.obj.getElementsByTagName('td')[this.env.flagged_col].getElementsByTagName('img')[0]))
+      {
+      var p = this;
+      row.flagged_icon.id = 'flaggedicn_'+row.uid;
+      row.flagged_icon._row = row.obj;
+      row.flagged_icon.onmousedown = function(e) { p.command('toggle_flag', this); };
+      }
+      
+    this.triggerEvent('insertrow', { uid:uid, row:row });
+  };
+
+  // init message compose form: set focus and eventhandlers
+  this.init_messageform = function()
+    {
+    if (!this.gui_objects.messageform)
+      return false;
+    
+    //this.messageform = this.gui_objects.messageform;
+    var input_from = $("[name='_from']");
+    var input_to = $("[name='_to']");
+    var input_subject = $("input[name='_subject']");
+    var input_message = $("[name='_message']").get(0);
+
+    // init live search events
+    this.init_address_input_events(input_to);
+    this.init_address_input_events($("[name='_cc']"));
+    this.init_address_input_events($("[name='_bcc']"));
+
+    // add signature according to selected identity
+    if (input_from.attr('type') == 'select-one' && $("input[name='_draft_saveid']").val() == ''
+        && $("input[name='_is_html']").val() != '1') {  // if we have HTML editor, signature is added in callback
+      this.change_identity(input_from[0]);
+    }
+
+    if (input_to.val() == '')
+      input_to.focus();
+    else if (input_subject.val() == '')
+      input_subject.focus();
+    else if (input_message)
+      input_message.focus();
+
+    // get summary of all field values
+    this.compose_field_hash(true);
+    // start the auto-save timer
+    this.auto_save_start();
+    };
+
+  this.init_address_input_events = function(obj)
+    {
+    var handler = function(e){ return ref.ksearch_keypress(e,this); };
+    obj.bind((bw.safari || bw.ie ? 'keydown' : 'keypress'), handler);
+    obj.attr('autocomplete', 'off');
+    };
+
+
+  /*********************************************************/
+  /*********       client command interface        *********/
+  /*********************************************************/
+
+  // execute a specific command on the web client
+  this.command = function(command, props, obj)
+    {
+    if (obj && obj.blur)
+      obj.blur();
+
+    if (this.busy)
+      return false;
+
+    // command not supported or allowed
+    if (!this.commands[command])
+      {
+      // pass command to parent window
+      if (this.env.framed && parent.rcmail && parent.rcmail.command)
+        parent.rcmail.command(command, props);
+
+      return false;
+      }
+      
+   // check input before leaving compose step
+   if (this.task=='mail' && this.env.action=='compose' && (command=='list' || command=='mail' || command=='addressbook' || command=='settings'))
+     {
+     if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
+        return false;
+     }
+
+    // process external commands
+    if (typeof this.command_handlers[command] == 'function')
+    {
+      var ret = this.command_handlers[command](props, obj);
+      return ret !== null ? ret : (obj ? false : true);
+    }
+    else if (typeof this.command_handlers[command] == 'string')
+    {
+      var ret = window[this.command_handlers[command]](props, obj);
+      return ret !== null ? ret : (obj ? false : true);
+    }
+    
+    // trigger plugin hook
+    var event_ret = this.triggerEvent('before'+command, props);
+    if (typeof event_ret != 'undefined') {
+      // abort if one the handlers returned false
+      if (event_ret === false)
+        return false;
+      else
+        props = event_ret;
+    }
+
+    // process internal command
+    switch (command)
+      {
+      case 'login':
+        if (this.gui_objects.loginform)
+          this.gui_objects.loginform.submit();
+        break;
+
+      // commands to switch task
+      case 'mail':
+      case 'addressbook':
+      case 'settings':
+      case 'logout':
+        this.switch_task(command);
+        break;
+
+      case 'permaurl':
+        if (obj && obj.href && obj.target)
+          return true;
+        else if (this.env.permaurl)
+          parent.location.href = this.env.permaurl;
+        break;
+
+      case 'open':
+        var uid;
+        if (uid = this.get_single_uid())
+        {
+          obj.href = '?_task='+this.env.task+'&_action=show&_mbox='+urlencode(this.env.mailbox)+'&_uid='+uid;
+          return true;
+        }
+        break;
+
+      // misc list commands
+      case 'list':
+        if (this.task=='mail')
+          {
+          if (this.env.search_request<0 || (props != '' && (this.env.search_request && props != this.env.mailbox)))
+            this.reset_qsearch();
+
+          this.list_mailbox(props);
+
+          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<0 || (this.env.search_request && props != this.env.source))
+            this.reset_qsearch();
+
+          this.list_contacts(props);
+          this.enable_command('add', (this.env.address_sources && !this.env.address_sources[props].readonly));
+          }
+        break;
+
+
+      case 'load-headers':
+        this.load_headers(obj);
+        break;
+
+
+      case 'sort':
+        var sort_order, sort_col = props;
+
+        if (this.env.sort_col==sort_col)
+          sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC';
+        else
+         sort_order = 'ASC';
+       
+        // set table header class
+        $('#rcm'+this.env.sort_col).removeClass('sorted'+(this.env.sort_order.toUpperCase()));
+        $('#rcm'+sort_col).addClass('sorted'+sort_order);
+
+        // save new sort properties
+        this.env.sort_col = sort_col;
+        this.env.sort_order = sort_order;
+
+        // reload message list
+        this.list_mailbox('', '', sort_col+'_'+sort_order);
+        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':
+        if (this.env.messagecount)
+          this.expunge_mailbox(this.env.mailbox);
+        break;
+
+      case 'purge':
+      case 'empty-mailbox':
+        if (this.env.messagecount)
+          this.purge_mailbox(this.env.mailbox);
+        break;
+
+
+      // common commands used in multiple tasks
+      case 'show':
+        if (this.task=='mail')
+          {
+          var uid = this.get_single_uid();
+          if (uid && (!this.env.uid || uid != this.env.uid))
+            {
+            if (this.env.mailbox == this.env.drafts_mailbox)
+              this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
+            else
+              this.show_message(uid);
+            }
+          }
+        else if (this.task=='addressbook')
+          {
+          var cid = props ? props : this.get_single_cid();
+          if (cid && !(this.env.action=='show' && cid==this.env.cid))
+            this.load_contact(cid, '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':
+        var cid;
+        if (this.task=='addressbook' && (cid = this.get_single_cid()))
+          this.load_contact(cid, 'edit');
+        else if (this.task=='settings' && props)
+          this.load_identity(props, 'edit-identity');
+        else if (this.task=='mail' && (cid = this.get_single_uid())) {
+          var url = (this.env.mailbox == this.env.drafts_mailbox) ? '_draft_uid=' : '_uid=';
+          this.goto_url('compose', url+cid+'&_mbox='+urlencode(this.env.mailbox), true);
+        }
+        break;
+
+      case 'save-identity':
+      case 'save':
+        if (this.gui_objects.editform)
+          {
+          var input_pagesize = $("input[name='_pagesize']");
+          var input_name  = $("input[name='_name']");
+          var input_email = $("input[name='_email']");
+
+          // user prefs
+          if (input_pagesize.length && isNaN(parseInt(input_pagesize.val())))
+            {
+            alert(this.get_label('nopagesizewarning'));
+            input_pagesize.focus();
+            break;
+            }
+          // contacts/identities
+          else
+            {
+            if (input_name.length && input_name.val() == '')
+              {
+              alert(this.get_label('nonamewarning'));
+              input_name.focus();
+              break;
+              }
+            else if (input_email.length && !rcube_check_email(input_email.val()))
+              {
+              alert(this.get_label('noemailwarning'));
+              input_email.focus();
+              break;
+              }
+            }
+
+          this.gui_objects.editform.submit();
+          }
+        break;
+
+      case 'delete':
+        // mail task
+        if (this.task=='mail')
+          this.delete_messages();
+        // addressbook task
+        else if (this.task=='addressbook')
+          this.delete_contacts();
+        // user settings task
+        else if (this.task=='settings')
+          this.delete_identity();
+        break;
+
+
+      // mail task commands
+      case 'move':
+      case 'moveto':
+        if (this.task == 'mail')
+          this.move_messages(props);
+        else if (this.task == 'addressbook' && this.drag_active)
+          this.copy_contact(null, props);
+        break;
+
+      case 'mark':
+        if (props)
+          this.mark_message(props);
+        break;
+      
+      case 'toggle_status':
+        if (props && !props._row)
+          break;
+        
+        var uid;
+        var flag = 'read';
+        
+        if (props._row.uid)
+          {
+          uid = props._row.uid;
+          
+          // toggle read/unread
+          if (this.message_list.rows[uid].deleted) {
+            flag = 'undelete';
+          } else if (!this.message_list.rows[uid].unread)
+            flag = 'unread';
+          }
+          
+        this.mark_message(flag, uid);
+        break;
+        
+      case 'toggle_flag':
+        if (props && !props._row)
+          break;
+
+        var uid;
+        var flag = 'flagged';
+
+        if (props._row.uid)
+          {
+          uid = props._row.uid;
+          // toggle flagged/unflagged
+          if (this.message_list.rows[uid].flagged)
+            flag = 'unflagged';
+          }
+        this.mark_message(flag, uid);
+        break;
+
+      case 'always-load':
+        if (this.env.uid && this.env.sender) {
+          this.add_contact(urlencode(this.env.sender));
+          window.setTimeout(function(){ ref.command('load-images'); }, 300);
+          break;
+        }
+        
+      case 'load-images':
+        if (this.env.uid)
+          this.show_message(this.env.uid, true, this.env.action=='preview');
+        break;
+
+      case 'load-attachment':
+        var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part;
+        
+        // open attachment in frame if it's of a supported mimetype
+        if (this.env.uid && props.mimetype && find_in_array(props.mimetype, this.mimetypes)>=0)
+          {
+          if (props.mimetype == 'text/html')
+            qstring += '&_safe=1';
+          this.attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment');
+          if (this.attachment_win)
+            {
+            window.setTimeout(function(){ ref.attachment_win.focus(); }, 10);
+            break;
+            }
+          }
+
+        this.goto_url('get', qstring+'&_download=1', false);
+        break;
+        
+      case 'select-all':
+        if (props == 'invert')
+          this.message_list.invert_selection();
+        else
+          this.message_list.select_all(props);
+        break;
+
+      case 'select-none':
+        this.message_list.clear_selection();
+        break;
+
+      case 'nextmessage':
+        if (this.env.next_uid)
+          this.show_message(this.env.next_uid, false, this.env.action=='preview');
+        break;
+
+      case 'lastmessage':
+        if (this.env.last_uid)
+          this.show_message(this.env.last_uid);
+        break;
+
+      case 'previousmessage':
+        if (this.env.prev_uid)
+          this.show_message(this.env.prev_uid, false, this.env.action=='preview');
+        break;
+
+      case 'firstmessage':
+        if (this.env.first_uid)
+          this.show_message(this.env.first_uid);
+        break;
+      
+      case 'checkmail':
+        this.check_for_recent(true);
+        break;
+      
+      case 'compose':
+        var url = this.env.comm_path+'&_action=compose';
+       
+        if (this.task=='mail')
+        {
+          url += '&_mbox='+urlencode(this.env.mailbox);
+          
+          if (this.env.mailbox==this.env.drafts_mailbox)
+          {
+            var uid;
+            if (uid = this.get_single_uid())
+              url += '&_draft_uid='+uid;
+          }
+          else if (props)
+             url += '&_to='+urlencode(props);
+        }
+        // modify url if we're in addressbook
+        else if (this.task=='addressbook')
+          {
+          // switch to mail compose step directly
+          if (props && props.indexOf('@') > 0)
+            {
+            url = this.get_task_url('mail', url);
+            this.redirect(url + '&_to='+urlencode(props));
+            break;
+            }
+          
+          // use contact_id passed as command parameter
+          var a_cids = new Array();
+          if (props)
+            a_cids[a_cids.length] = props;
+          // get selected contacts
+          else if (this.contact_list)
+            {
+            var selection = this.contact_list.get_selection();
+            for (var n=0; n<selection.length; n++)
+              a_cids[a_cids.length] = selection[n];
+            }
+            
+          if (a_cids.length)
+            this.http_request('mailto', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source), true);
+
+          break;
+          }
+
+        // don't know if this is necessary...
+        url = url.replace(/&_framed=1/, "");
+
+        this.redirect(url);
+        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':
+        // Reset the auto-save timer
+        self.clearTimeout(this.save_timer);
+
+        if (!this.gui_objects.messageform)
+          break;
+
+        // if saving Drafts is disabled in main.inc.php
+        // or if compose form did not change
+        if (!this.env.drafts_mailbox || this.cmp_hash == this.compose_field_hash())
+          break;
+
+        this.set_busy(true, 'savingmessage');
+        var form = this.gui_objects.messageform;
+        form.target = "savetarget";
+        form._draft.value = '1';
+        form.submit();
+        break;
+
+      case 'send':
+        if (!this.gui_objects.messageform)
+          break;
+
+        if (!this.check_compose_input())
+          break;
+
+        // Reset the auto-save timer
+        self.clearTimeout(this.save_timer);
+
+        // all checks passed, send message
+        this.set_busy(true, 'sendingmessage');
+        var form = this.gui_objects.messageform;
+        form.target = "savetarget";     
+        form._draft.value = '';
+        form.submit();
+        
+        // clear timeout (sending could take longer)
+        clearTimeout(this.request_timer);
+        break;
+
+      case 'add-attachment':
+        this.show_attachment_form(true);
+        
+      case 'send-attachment':
+        // Reset the auto-save timer
+        self.clearTimeout(this.save_timer);
+
+        this.upload_file(props)      
+        break;
+      
+      case 'remove-attachment':
+        this.remove_attachment(props);
+        break;
+
+      case 'reply-all':
+      case 'reply':
+        var uid;
+        if (uid = this.get_single_uid())
+          this.goto_url('compose', '_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(command=='reply-all' ? '&_all=1' : ''), true);
+        break;      
+
+      case 'forward':
+        var uid;
+        if (uid = this.get_single_uid())
+          this.goto_url('compose', '_forward_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
+        break;
+        
+      case 'print':
+        var uid;
+        if (uid = this.get_single_uid())
+        {
+          ref.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : ''));
+          if (this.printwin)
+          {
+            window.setTimeout(function(){ ref.printwin.focus(); }, 20);
+            if (this.env.action != 'show')
+              this.mark_message('read', uid);
+          }
+        }
+        break;
+
+      case 'viewsource':
+        var uid;
+        if (uid = this.get_single_uid())
+          {
+          ref.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox));
+          if (this.sourcewin)
+            window.setTimeout(function(){ ref.sourcewin.focus(); }, 20);
+          }
+        break;
+
+      case 'download':
+        var uid;
+        if (uid = this.get_single_uid())
+          this.goto_url('viewsource', '&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+'&_save=1');
+        break;
+
+      case 'add-contact':
+        this.add_contact(props);
+        break;
+      
+      // quicksearch
+      case 'search':
+        if (!props && this.gui_objects.qsearchbox)
+          props = this.gui_objects.qsearchbox.value;
+        if (props)
+        {
+          this.qsearch(props);
+          break;
+        }
+
+      // reset quicksearch
+      case 'reset-search':
+        var s = this.env.search_request;
+        this.reset_qsearch();
+        
+        if (s && this.env.mailbox)
+          this.list_mailbox(this.env.mailbox);
+        else if (s && this.task == 'addressbook')
+          this.list_contacts(this.env.source);
+        break;
+
+      case 'import':
+        if (this.env.action == 'import' && this.gui_objects.importform) {
+          var file = document.getElementById('rcmimportfile');
+          if (file && !file.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');
+        break;
+        
+      case 'export':
+        if (this.contact_list.rowcount > 0) {
+          var add_url = (this.env.source ? '_source='+urlencode(this.env.source)+'&' : '');
+          if (this.env.search_request)
+            add_url += '_search='+this.env.search_request;
+        
+          this.goto_url('export', add_url);
+        }
+        break;
+
+      // collapse/expand folder
+      case 'collapse-folder':
+        if (props)
+          this.collapse_folder(props);
+        break;
+
+      // user settings commands
+      case 'preferences':
+        this.goto_url('');
+        break;
+
+      case 'identities':
+        this.goto_url('identities');
+        break;
+          
+      case 'delete-identity':
+        this.delete_identity();
+        
+      case 'folders':
+        this.goto_url('folders');
+        break;
+
+      case 'subscribe':
+        this.subscribe_folder(props);
+        break;
+
+      case 'unsubscribe':
+        this.unsubscribe_folder(props);
+        break;
+        
+      case 'create-folder':
+        this.create_folder(props);
+        break;
+
+      case 'rename-folder':
+        this.rename_folder(props);
+        break;
+
+      case 'delete-folder':
+        this.delete_folder(props);
+        break;
+
+      }
+      
+    this.triggerEvent('after'+command, props);
+
+    return obj ? false : true;
+    };
+
+  // set command enabled or disabled
+  this.enable_command = function()
+    {
+    var args = arguments;
+    if(!args.length) return -1;
+
+    var command;
+    var enable = args[args.length-1];
+    
+    for(var n=0; n<args.length-1; n++)
+      {
+      command = args[n];
+      this.commands[command] = enable;
+      this.set_button(command, (enable ? 'act' : 'pas'));
+      }
+      return true;
+    };
+
+  // lock/unlock interface
+  this.set_busy = function(a, message)
+    {
+    if (a && message)
+      {
+      var msg = this.get_label(message);
+      if (msg==message)        
+        msg = 'Loading...';
+
+      this.display_message(msg, 'loading', true);
+      }
+    else if (!a)
+      this.hide_message();
+
+    this.busy = a;
+    //document.body.style.cursor = a ? 'wait' : 'default';
+    
+    if (this.gui_objects.editform)
+      this.lock_form(this.gui_objects.editform, a);
+      
+    // clear pending timer
+    if (this.request_timer)
+      clearTimeout(this.request_timer);
+
+    // set timer for requests
+    if (a && this.env.request_timeout)
+      this.request_timer = window.setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000);
+    };
+
+  // return a localized string
+  this.get_label = function(name, domain)
+    {
+    if (domain && this.labels[domain+'.'+name])
+      return this.labels[domain+'.'+name];
+    else if (this.labels[name])
+      return this.labels[name];
+    else
+      return name;
+    };
+  
+  // alias for convenience reasons
+  this.gettext = this.get_label;
+
+  // switch to another application task
+  this.switch_task = function(task)
+    {
+    if (this.task===task && task!='mail')
+      return;
+
+    var url = this.get_task_url(task);
+    if (task=='mail')
+      url += '&_mbox=INBOX';
+
+    this.redirect(url);
+    };
+
+  this.get_task_url = function(task, url)
+    {
+    if (!url)
+      url = this.env.comm_path;
+
+    return url.replace(/_task=[a-z]+/, '_task='+task);
+    };
+    
+  // called when a request timed out
+  this.request_timed_out = function()
+    {
+    this.set_busy(false);
+    this.display_message('Request timed out!', 'error');
+    };
+  
+  this.reload = function(delay)
+  {
+    if (this.env.framed && parent.rcmail)
+      parent.rcmail.reload(delay);
+    else if (delay)
+      window.setTimeout(function(){ rcmail.reload(); }, delay);
+    else if (window.location)
+      location.href = this.env.comm_path;
+  };
+
+
+  /*********************************************************/
+  /*********        event handling methods         *********/
+  /*********************************************************/
+
+  this.doc_mouse_up = function(e)
+  {
+    var model, list, li;
+
+    if (this.message_list) {
+      if (!rcube_mouse_is_over(e, this.message_list.list))
+        this.message_list.blur();
+      list = this.message_list;
+      model = this.env.mailboxes;
+    }
+    else if (this.contact_list) {
+      if (!rcube_mouse_is_over(e, this.contact_list.list))
+        this.contact_list.blur();
+      list = this.contact_list;
+      model = this.env.address_sources;
+    }
+    else if (this.ksearch_value) {
+      this.ksearch_blur();
+    }
+
+    // handle mouse release when dragging
+    if (this.drag_active && model && this.env.last_folder_target) {
+      $(this.get_folder_li(this.env.last_folder_target)).removeClass('droptarget');
+      this.command('moveto', model[this.env.last_folder_target].id);
+      this.env.last_folder_target = null;
+      list.draglayer.hide();
+    }
+    
+    // reset 'pressed' buttons
+    if (this.buttons_sel) {
+      for (var id in this.buttons_sel)
+        if (typeof id != 'function')
+          this.button_out(this.buttons_sel[id], id);
+      this.buttons_sel = {};
+    }
+  };
+
+  this.drag_start = function(list)
+  {
+    var model = this.task == 'mail' ? this.env.mailboxes : this.env.address_sources;
+
+    this.drag_active = true;
+    if (this.preview_timer)
+      clearTimeout(this.preview_timer);
+    
+    // save folderlist and folders location/sizes for droptarget calculation in drag_move()
+    if (this.gui_objects.folderlist && model)
+      {
+      this.initialBodyScrollTop = bw.ie ? 0 : window.pageYOffset;
+      this.initialListScrollTop = this.gui_objects.folderlist.parentNode.scrollTop;
+
+      var li, pos, list, height;
+      list = $(this.gui_objects.folderlist);
+      pos = list.offset();
+      this.env.folderlist_coords = { x1:pos.left, y1:pos.top, x2:pos.left + list.width(), y2:pos.top + list.height() };
+
+      this.env.folder_coords = new Array();
+      for (var k in model) {
+        if (li = this.get_folder_li(k)) {
+          // only visible folders
+          if (height = li.firstChild.offsetHeight) {
+            pos = $(li.firstChild).offset();
+            this.env.folder_coords[k] = { x1:pos.left, y1:pos.top,
+              x2:pos.left + li.firstChild.offsetWidth, y2:pos.top + height, on:0 };
+          }
+        }
+      }
+    }
+  };
+
+  this.drag_end = function(e)
+  {
+    this.drag_active = false;
+    this.env.last_folder_target = null;
+    
+    if (this.folder_auto_timer) {
+      window.clearTimeout(this.folder_auto_timer);
+      this.folder_auto_timer = null;
+      this.folder_auto_expand = null;
+    }
+
+    // over the folders
+    if (this.gui_objects.folderlist && this.env.folder_coords) {
+      for (var k in this.env.folder_coords) {
+        if (this.env.folder_coords[k].on)
+          $(this.get_folder_li(k)).removeClass('droptarget');
+      }
+    }
+  };
+  
+  this.drag_move = function(e)
+  {
+    if (this.gui_objects.folderlist && this.env.folder_coords) {
+      // offsets to compensate for scrolling while dragging a message
+      var boffset = bw.ie ? -document.documentElement.scrollTop : this.initialBodyScrollTop;
+      var moffset = this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop;
+      var toffset = -moffset-boffset;
+
+      var li, div, pos, mouse;
+      mouse = rcube_event.get_mouse_pos(e);
+      pos = this.env.folderlist_coords;
+      mouse.y += toffset;
+
+      // if mouse pointer is outside of folderlist
+      if (mouse.x < pos.x1 || mouse.x >= pos.x2 || mouse.y < pos.y1 || mouse.y >= pos.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;
+        }
+        return;
+      }
+    
+      // over the folders
+      for (var k in this.env.folder_coords) {
+        pos = this.env.folder_coords[k];
+        if (mouse.x >= pos.x1 && mouse.x < pos.x2 && mouse.y >= pos.y1 && mouse.y < pos.y2
+            && this.check_droptarget(k)) {
+
+          li = this.get_folder_li(k);
+          div = $(li.getElementsByTagName("div")[0]);
+
+          // if the folder is collapsed, expand it after 1sec and restart the drag & drop process.
+          if (div.hasClass('collapsed')) {
+            if (this.folder_auto_timer)
+              window.clearTimeout(this.folder_auto_timer);
+            
+            this.folder_auto_expand = k;
+            this.folder_auto_timer = window.setTimeout(function() {
+                rcmail.command("collapse-folder", rcmail.folder_auto_expand);
+                rcmail.drag_start(null);
+              }, 1000);
+          } else if (this.folder_auto_timer) {
+            window.clearTimeout(this.folder_auto_timer);
+            this.folder_auto_timer = null;
+            this.folder_auto_expand = null;
+          }
+          
+          $(li).addClass('droptarget');
+          this.env.last_folder_target = k;
+          this.env.folder_coords[k].on = 1;
+        }
+        else if (pos.on) {
+          $(this.get_folder_li(k)).removeClass('droptarget');
+          this.env.folder_coords[k].on = 0;
+        }
+      }
+    }
+  };
+
+  this.collapse_folder = function(id)
+    {
+    var div;
+    if ((li = this.get_folder_li(id)) &&
+        (div = $(li.getElementsByTagName("div")[0])) &&
+        (div.hasClass('collapsed') || div.hasClass('expanded')))
+      {
+      var ul = $(li.getElementsByTagName("ul")[0]);
+      if (div.hasClass('collapsed'))
+        {
+        ul.show();
+        div.removeClass('collapsed').addClass('expanded');
+        var reg = new RegExp('&'+urlencode(id)+'&');
+        this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
+        }
+      else
+        {
+        ul.hide();
+        div.removeClass('expanded').addClass('collapsed');
+        this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+urlencode(id)+'&');
+
+        // select parent folder if one of its childs is currently selected
+        if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0)
+          this.command('list', id);
+        }
+
+      // Work around a bug in IE6 and IE7, see #1485309
+      if ((bw.ie6 || bw.ie7) &&
+          li.nextSibling &&
+          (li.nextSibling.getElementsByTagName("ul").length>0) &&
+          li.nextSibling.getElementsByTagName("ul")[0].style &&
+          (li.nextSibling.getElementsByTagName("ul")[0].style.display!='none'))
+        {
+          li.nextSibling.getElementsByTagName("ul")[0].style.display = 'none';
+          li.nextSibling.getElementsByTagName("ul")[0].style.display = '';
+        }
+
+      this.http_post('save-pref', '_name=collapsed_folders&_value='+urlencode(this.env.collapsed_folders));
+      this.set_unread_count_display(id, false);
+      }
+    }
+
+  this.click_on_list = function(e)
+    {
+    if (this.gui_objects.qsearchbox)
+      this.gui_objects.qsearchbox.blur();
+
+    if (this.message_list)
+      this.message_list.focus();
+    else if (this.contact_list)
+      this.contact_list.focus();
+
+    return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e);
+    };
+
+  this.msglist_select = function(list)
+    {
+    if (this.preview_timer)
+      clearTimeout(this.preview_timer);
+
+    var selected = list.selection.length==1;
+
+    // Hide certain command buttons when Drafts folder is selected
+    if (this.env.mailbox == this.env.drafts_mailbox)
+      {
+      this.enable_command('reply', 'reply-all', 'forward', false);
+      this.enable_command('show', 'print', 'open', 'edit', 'download', 'viewsource', selected);
+      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
+      }
+    else
+      {
+      this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', 'edit', 'open', 'download', 'viewsource', selected);
+      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
+      }
+
+    // start timer for message preview (wait for double click)
+    if (selected && this.env.contentframe && !list.multi_selecting)
+      this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200);
+    else if (this.env.contentframe)
+      this.show_contentframe(false);
+    };
+
+  this.msglist_dbl_click = function(list)
+    {
+      if (this.preview_timer)
+        clearTimeout(this.preview_timer);
+
+    var uid = list.get_single_selection();
+    if (uid && this.env.mailbox == this.env.drafts_mailbox)
+      this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
+    else if (uid)
+      this.show_message(uid, false, false);
+    };
+
+  this.msglist_keypress = function(list)
+    {
+    if (list.key_pressed == list.ENTER_KEY)
+      this.command('show');
+    else if (list.key_pressed == list.DELETE_KEY)
+      this.command('delete');
+    else if (list.key_pressed == list.BACKSPACE_KEY)
+      this.command('delete');
+    else
+      list.shiftkey = false;
+    };
+
+  this.msglist_get_preview = function()
+  {
+    var uid = this.get_single_uid();
+    if (uid && this.env.contentframe && !this.drag_active)
+      this.show_message(uid, false, true);
+    else if (this.env.contentframe)
+      this.show_contentframe(false);
+  };
+  
+  this.check_droptarget = function(id)
+  {
+    if (this.task == 'mail')
+      return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual);
+    else if (this.task == 'addressbook')
+      return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly);
+    else if (this.task == 'settings')
+      return (id != this.env.folder);
+  };
+
+
+  /*********************************************************/
+  /*********     (message) list functionality      *********/
+  /*********************************************************/
+
+  // when user doble-clicks on a row
+  this.show_message = function(id, safe, preview)
+    {
+    if (!id) return;
+    
+    var add_url = '';
+    var action = preview ? 'preview': 'show';
+    var target = window;
+    
+    if (preview && this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      target = window.frames[this.env.contentframe];
+      add_url = '&_framed=1';
+      }
+
+    if (safe)
+      add_url = '&_safe=1';
+
+    // also send search request to get the right messages
+    if (this.env.search_request)
+      add_url += '&_search='+this.env.search_request;
+
+    var url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.env.mailbox)+add_url;
+    if (action == 'preview' && String(target.location.href).indexOf(url) >= 0)
+      this.show_contentframe(true);
+    else
+      {
+      this.set_busy(true, 'loading');
+      target.location.href = this.env.comm_path+url;
+
+      // mark as read and change mbox unread counter
+      if (action == 'preview' && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread)
+        {
+        this.set_message(id, 'unread', false);
+        if (this.env.unread_counts[this.env.mailbox])
+          {
+          this.env.unread_counts[this.env.mailbox] -= 1;
+          this.set_unread_count(this.env.mailbox, this.env.unread_counts[this.env.mailbox], this.env.mailbox == 'INBOX');
+          }
+        }
+      }
+    };
+
+  this.show_contentframe = function(show)
+    {
+    var frm;
+    if (this.env.contentframe && (frm = $('#'+this.env.contentframe)) && frm.length)
+      {
+      if (!show && window.frames[this.env.contentframe])
+        {
+        if (window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0)
+          window.frames[this.env.contentframe].location.href = this.env.blankpage;
+        }
+      else if (!bw.safari && !bw.konq)
+        frm[show ? 'show' : 'hide']();
+      }
+
+    if (!show && this.busy)
+      this.set_busy(false);
+    };
+
+  // list a specific page
+  this.list_page = function(page)
+    {
+    if (page=='next')
+      page = this.env.current_page+1;
+    if (page=='last')
+      page = this.env.pagecount;
+    if (page=='prev' && this.env.current_page>1)
+      page = this.env.current_page-1;
+    if (page=='first' && this.env.current_page>1)
+      page = 1;
+      
+    if (page > 0 && page <= this.env.pagecount)
+      {
+      this.env.current_page = page;
+      
+      if (this.task=='mail')
+        this.list_mailbox(this.env.mailbox, page);
+      else if (this.task=='addressbook')
+        this.list_contacts(this.env.source, page);
+      }
+    };
+
+  // list messages of a specific mailbox using filter
+  this.filter_mailbox = function(filter)
+    {
+      var search;
+      if (this.gui_objects.qsearchbox)
+        search = this.gui_objects.qsearchbox.value;
+      
+      this.message_list.clear();
+
+      // reset vars
+      this.env.current_page = 1;
+      this.set_busy(true, 'searching');
+      this.http_request('search', '_filter='+filter
+           + (search ? '&_q='+urlencode(search) : '')
+           + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : ''), true);
+    }
+
+
+  // list messages of a specific mailbox
+  this.list_mailbox = function(mbox, page, sort)
+    {
+    var add_url = '';
+    var target = window;
+
+    if (!mbox)
+      mbox = this.env.mailbox;
+
+    // add sort to url if set
+    if (sort)
+      add_url += '&_sort=' + sort;
+
+    // also send search request to get the right messages
+    if (this.env.search_request)
+      add_url += '&_search='+this.env.search_request;
+      
+    // set page=1 if changeing to another mailbox
+    if (!page)
+      {
+      page = 1;
+      this.env.current_page = page;
+      this.show_contentframe(false);
+      }
+    
+    if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort))
+      add_url += '&_refresh=1';
+
+    // unselect selected messages
+    this.last_selected = 0;
+    if (this.message_list)
+      this.message_list.clear_selection();
+    
+    this.select_folder(mbox, this.env.mailbox);
+    this.env.mailbox = mbox;
+
+    // load message list remotely
+    if (this.gui_objects.messagelist)
+      {
+      this.list_mailbox_remote(mbox, page, add_url);
+      return;
+      }
+    
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      target = window.frames[this.env.contentframe];
+      add_url += '&_framed=1';
+      }
+
+    // load message list to target frame/window
+    if (mbox)
+      {
+      this.set_busy(true, 'loading');
+      target.location.href = this.env.comm_path+'&_mbox='+urlencode(mbox)+(page ? '&_page='+page : '')+add_url;
+      }
+    };
+
+  // send remote request to load message list
+  this.list_mailbox_remote = function(mbox, page, add_url)
+    {
+    // clear message list first
+    this.message_list.clear();
+
+    // send request to server
+    var url = '_mbox='+urlencode(mbox)+(page ? '&_page='+page : '');
+    this.set_busy(true, 'loading');
+    this.http_request('list', url+add_url, true);
+    };
+
+  this.expunge_mailbox = function(mbox)
+    {
+    var lock = false;
+    var add_url = '';
+    
+    // lock interface if it's the active mailbox
+    if (mbox == this.env.mailbox)
+       {
+       lock = true;
+       this.set_busy(true, 'loading');
+       add_url = '&_reload=1';
+       }
+
+    // send request to server
+    var url = '_mbox='+urlencode(mbox);
+    this.http_post('expunge', url+add_url, lock);
+    };
+
+  this.purge_mailbox = function(mbox)
+    {
+    var lock = false;
+    var add_url = '';
+    
+    if (!confirm(this.get_label('purgefolderconfirm')))
+      return false;
+    
+    // lock interface if it's the active mailbox
+    if (mbox == this.env.mailbox)
+       {
+       lock = true;
+       this.set_busy(true, 'loading');
+       add_url = '&_reload=1';
+       }
+
+    // send request to server
+    var url = '_mbox='+urlencode(mbox);
+    this.http_post('purge', url+add_url, lock);
+    return true;
+    };
+
+  // test if purge command is allowed
+  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))));
+  };
+
+  // set message icon
+  this.set_message_icon = function(uid)
+  {
+    var icn_src;
+    var rows = this.message_list.rows;
+
+    if (!rows[uid])
+      return false;
+
+    if (rows[uid].deleted && this.env.deletedicon)
+      icn_src = this.env.deletedicon;
+    else if (rows[uid].replied && this.env.repliedicon)
+      {
+      if (rows[uid].forwarded && this.env.forwardedrepliedicon)
+        icn_src = this.env.forwardedrepliedicon;
+      else
+        icn_src = this.env.repliedicon;
+      }
+    else if (rows[uid].forwarded && this.env.forwardedicon)
+      icn_src = this.env.forwardedicon;
+    else if (rows[uid].unread && this.env.unreadicon)
+      icn_src = this.env.unreadicon;
+    else if (this.env.messageicon)
+      icn_src = this.env.messageicon;
+      
+    if (icn_src && rows[uid].icon)
+      rows[uid].icon.src = icn_src;
+
+    icn_src = '';
+    
+    if (rows[uid].flagged && this.env.flaggedicon)
+      icn_src = this.env.flaggedicon;
+    else if (!rows[uid].flagged && this.env.unflaggedicon)
+      icn_src = this.env.unflaggedicon;
+
+    if (rows[uid].flagged_icon && icn_src)
+      rows[uid].flagged_icon.src = icn_src;
+  }
+
+  // set message status
+  this.set_message_status = function(uid, flag, status)
+    {
+    var rows = this.message_list.rows;
+
+    if (!rows[uid]) return false;
+
+    if (flag == 'unread')
+      rows[uid].unread = status;
+    else if(flag == 'deleted')
+      rows[uid].deleted = status;
+    else if (flag == 'replied')
+      rows[uid].replied = status;
+    else if (flag == 'forwarded')
+      rows[uid].forwarded = status;
+    else if (flag == 'flagged')
+      rows[uid].flagged = status;
+
+    this.env.messages[uid] = rows[uid];
+    }
+
+  // set message row status, class and icon
+  this.set_message = function(uid, flag, status)
+    {
+    var rows = this.message_list.rows;
+
+    if (!rows[uid]) return false;
+    
+    if (flag)
+      this.set_message_status(uid, flag, status);
+    
+    var rowobj = $(rows[uid].obj);
+    if (rows[uid].unread && rows[uid].classname.indexOf('unread')<0)
+      {
+      rows[uid].classname += ' unread';
+      rowobj.addClass('unread');
+      }
+    else if (!rows[uid].unread && rows[uid].classname.indexOf('unread')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*unread/, '');
+      rowobj.removeClass('unread');
+      }
+    
+    if (rows[uid].deleted && rows[uid].classname.indexOf('deleted')<0)
+      {
+      rows[uid].classname += ' deleted';
+      rowobj.addClass('deleted');
+      }
+    else if (!rows[uid].deleted && rows[uid].classname.indexOf('deleted')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, '');
+      rowobj.removeClass('deleted');
+      }
+
+    if (rows[uid].flagged && rows[uid].classname.indexOf('flagged')<0)
+      {
+      rows[uid].classname += ' flagged';
+      rowobj.addClass('flagged');
+      }
+    else if (!rows[uid].flagged && rows[uid].classname.indexOf('flagged')>=0)
+      {
+      rows[uid].classname = rows[uid].classname.replace(/\s*flagged/, '');
+      rowobj.removeClass('flagged');
+      }
+
+    this.set_message_icon(uid);
+    }
+
+  // move selected messages to the specified mailbox
+  this.move_messages = function(mbox)
+    {
+    // exit if current or no mailbox specified or if selection is empty
+    if (!mbox || mbox == this.env.mailbox || (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length)))
+      return;
+
+    var lock = false;
+    var add_url = '&_target_mbox='+urlencode(mbox)+'&_from='+(this.env.action ? this.env.action : '');
+
+    // show wait message
+    if (this.env.action=='show')
+      {
+      lock = true;
+      this.set_busy(true, 'movingmessage');
+      }
+    else
+      this.show_contentframe(false);
+
+    // Hide message command buttons until a message is selected
+    this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'edit', 'viewsource', 'download', false);
+
+    this._with_selected_messages('moveto', lock, add_url);
+    };
+
+  // delete selected messages from the current mailbox
+  this.delete_messages = function()
+    {
+    var selection = this.message_list ? this.message_list.get_selection() : new Array();
+
+    // exit if no mailbox specified or if selection is empty
+    if (!this.env.uid && !selection.length)
+      return;
+
+    // if config is set to flag for deletion
+    if (this.env.flag_for_deletion)
+      this.mark_message('delete');
+    // if there isn't a defined trash mailbox or we are in it
+    else if (!this.env.trash_mailbox || String(this.env.mailbox).toLowerCase() == String(this.env.trash_mailbox).toLowerCase()) 
+      this.permanently_remove_messages();
+    // if there is a trash mailbox defined and we're not currently in it
+    else {
+      // if shift was pressed delete it immediately
+      if (this.message_list && this.message_list.shiftkey)
+        {
+        if (confirm(this.get_label('deletemessagesconfirm')))
+          this.permanently_remove_messages();
+        }
+      else
+        this.move_messages(this.env.trash_mailbox);
+      }
+  };
+
+  // delete the selected messages permanently
+  this.permanently_remove_messages = function()
+    {
+    // exit if no mailbox specified or if selection is empty
+    if (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length))
+      return;
+      
+    this.show_contentframe(false);
+    this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : ''));
+    };
+
+  // Send a specifc request with UIDs of all selected messages
+  // @private
+  this._with_selected_messages = function(action, lock, add_url, remove)
+  {
+    var a_uids = new Array();
+
+    if (this.env.uid)
+      a_uids[0] = this.env.uid;
+    else
+    {
+      var selection = this.message_list.get_selection();
+      var rows = this.message_list.rows;
+      var id;
+      for (var n=0; n<selection.length; n++) {
+        id = selection[n];
+        a_uids[a_uids.length] = id;
+        this.message_list.remove_row(id, (this.env.display_next && n == selection.length-1));
+      }
+      // make sure there are no selected rows
+      if (!this.env.display_next)
+        this.message_list.clear_selection();
+    }
+
+    // also send search request to get the right messages 
+    if (this.env.search_request) 
+      add_url += '&_search='+this.env.search_request;
+
+    if (this.env.display_next && this.env.next_uid)
+      add_url += '&_next_uid='+this.env.next_uid;
+
+    // send request to server
+    this.http_post(action, '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+add_url, lock);
+  };
+
+  // set a specific flag to one or more messages
+  this.mark_message = function(flag, uid)
+    {
+    var a_uids = new Array();
+    var r_uids = new Array();
+    var selection = this.message_list ? this.message_list.get_selection() : new Array();
+
+    if (uid)
+      a_uids[0] = uid;
+    else if (this.env.uid)
+      a_uids[0] = this.env.uid;
+    else if (this.message_list)
+      {
+      for (var n=0; n<selection.length; n++)
+        {
+          a_uids[a_uids.length] = selection[n];
+        }
+      }
+
+    if (!this.message_list)
+      r_uids = a_uids;
+    else
+      for (var id, n=0; n<a_uids.length; n++)
+      {
+        id = a_uids[n];
+        if ((flag=='read' && this.message_list.rows[id].unread) 
+            || (flag=='unread' && !this.message_list.rows[id].unread)
+            || (flag=='delete' && !this.message_list.rows[id].deleted)
+            || (flag=='undelete' && this.message_list.rows[id].deleted)
+            || (flag=='flagged' && !this.message_list.rows[id].flagged)
+            || (flag=='unflagged' && this.message_list.rows[id].flagged))
+        {
+          r_uids[r_uids.length] = id;
+        }
+      }
+
+    // nothing to do
+    if (!r_uids.length)
+      return;
+
+    switch (flag)
+      {
+        case 'read':
+        case 'unread':
+          this.toggle_read_status(flag, r_uids);
+          break;
+        case 'delete':
+        case 'undelete':
+          this.toggle_delete_status(r_uids);
+          break;
+        case 'flagged':
+        case 'unflagged':
+          this.toggle_flagged_status(flag, a_uids);
+          break;
+      }
+    };
+
+  // set class to read/unread
+  this.toggle_read_status = function(flag, a_uids)
+  {
+    // mark all message rows as read/unread
+    for (var i=0; i<a_uids.length; i++)
+      this.set_message(a_uids[i], 'unread', (flag=='unread' ? true : false));
+
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
+  };
+
+  // set image to flagged or unflagged
+  this.toggle_flagged_status = function(flag, a_uids)
+  {
+    // mark all message rows as flagged/unflagged
+    for (var i=0; i<a_uids.length; i++)
+      this.set_message(a_uids[i], 'flagged', (flag=='flagged' ? true : false));
+
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
+  };
+  
+  // mark all message rows as deleted/undeleted
+  this.toggle_delete_status = function(a_uids)
+  {
+    var rows = this.message_list ? this.message_list.rows : new Array();
+    
+    if (a_uids.length==1)
+    {
+      if (!rows.length || (rows[a_uids[0]] && !rows[a_uids[0]].deleted))
+        this.flag_as_deleted(a_uids);
+      else
+        this.flag_as_undeleted(a_uids);
+
+      return true;
+    }
+    
+    var all_deleted = true;
+    for (var i=0; i<a_uids.length; i++)
+    {
+      uid = a_uids[i];
+      if (rows[uid]) {
+        if (!rows[uid].deleted)
+        {
+          all_deleted = false;
+          break;
+        }
+      }
+    }
+    
+    if (all_deleted)
+      this.flag_as_undeleted(a_uids);
+    else
+      this.flag_as_deleted(a_uids);
+    
+    return true;
+  };
+
+  this.flag_as_undeleted = function(a_uids)
+  {
+    for (var i=0; i<a_uids.length; i++)
+      this.set_message(a_uids[i], 'deleted', false);
+
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=undelete');
+    return true;
+  };
+
+  this.flag_as_deleted = function(a_uids)
+  {
+    var add_url = '';
+    var r_uids = new Array();
+    var rows = this.message_list ? this.message_list.rows : new Array();
+    
+    for (var i=0; i<a_uids.length; i++)
+      {
+      uid = a_uids[i];
+      if (rows[uid])
+        {
+        if (rows[uid].unread)
+          r_uids[r_uids.length] = uid;
+
+       if (this.env.skip_deleted)
+          this.message_list.remove_row(uid, (this.env.display_next && i == this.message_list.selection.length-1));
+       else
+         this.set_message(uid, 'deleted', true);
+        }
+      }
+
+    // make sure there are no selected rows
+    if (this.env.skip_deleted && !this.env.display_next && this.message_list)
+      this.message_list.clear_selection();
+
+    add_url = '&_from='+(this.env.action ? this.env.action : '');
+    
+    if (r_uids.length)
+      add_url += '&_ruid='+r_uids.join(',');
+
+    if (this.env.skip_deleted) {
+      // also send search request to get the right messages 
+      if (this.env.search_request) 
+        add_url += '&_search='+this.env.search_request;
+      if (this.env.display_next && this.env.next_uid)
+        add_url += '&_next_uid='+this.env.next_uid;
+    }
+    
+    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=delete'+add_url);
+    return true;  
+  };
+
+  // flag as read without mark request (called from backend)
+  // argument should be a coma-separated list of uids
+  this.flag_deleted_as_read = function(uids)
+  {
+    var icn_src;
+    var rows = this.message_list ? this.message_list.rows : new Array();
+    var str = String(uids);
+    var a_uids = new Array();
+
+    a_uids = str.split(',');
+
+    for (var uid, i=0; i<a_uids.length; i++)
+      {
+      uid = a_uids[i];
+      if (rows[uid])
+        this.set_message(uid, 'unread', false);
+      }
+  };
+  
+  
+  /*********************************************************/
+  /*********           login form methods          *********/
+  /*********************************************************/
+
+  // handler for keyboard events on the _user field
+  this.login_user_keyup = function(e)
+  {
+    var key = rcube_event.get_keycode(e);
+    var passwd = $('#rcmloginpwd');
+
+    // enter
+    if (key == 13 && passwd.length && !passwd.val()) {
+      passwd.focus();
+      return rcube_event.cancel(e);
+    }
+    
+    return true;
+  };
+
+
+  /*********************************************************/
+  /*********        message compose methods        *********/
+  /*********************************************************/
+  
+  // checks the input fields before sending a message
+  this.check_compose_input = function()
+    {
+    // check input fields
+    var input_to = $("[name='_to']");
+    var input_cc = $("[name='_cc']");
+    var input_bcc = $("[name='_bcc']");
+    var input_from = $("[name='_from']");
+    var input_subject = $("[name='_subject']");
+    var input_message = $("[name='_message']");
+
+    // check sender (if have no identities)
+    if (input_from.attr('type') == 'text' && !rcube_check_email(input_from.val(), true))
+      {
+      alert(this.get_label('nosenderwarning'));
+      input_from.focus();
+      return false;
+      }
+
+    // check for empty recipient
+    var recipients = input_to.val() ? input_to.val() : (input_cc.val() ? input_cc.val() : input_bcc.val());
+    if (!rcube_check_email(recipients.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true))
+      {
+      alert(this.get_label('norecipientwarning'));
+      input_to.focus();
+      return false;
+      }
+
+    // display localized warning for missing subject
+    if (input_subject.val() == '')
+      {
+      var subject = prompt(this.get_label('nosubjectwarning'), this.get_label('nosubject'));
+
+      // user hit cancel, so don't send
+      if (!subject && subject !== '')
+        {
+        input_subject.focus();
+        return false;
+        }
+      else
+        {
+        input_subject.val((subject ? subject : this.get_label('nosubject')));
+        }
+      }
+
+    // check for empty body
+    if ((!window.tinyMCE || !tinyMCE.get(this.env.composebody))
+       && input_message.val() == '' && !confirm(this.get_label('nobodywarning')))
+      {
+      input_message.focus();
+      return false;
+      }
+    else if (window.tinyMCE && tinyMCE.get(this.env.composebody)
+       && !tinyMCE.get(this.env.composebody).getContent()
+       && !confirm(this.get_label('nobodywarning')))
+      {
+      tinyMCE.get(this.env.composebody).focus();
+      return false;
+      }
+
+    // Apply spellcheck changes if spell checker is active
+    this.stop_spellchecking();
+
+    // move body from html editor to textarea (just to be sure, #1485860)
+    if (window.tinyMCE && tinyMCE.get(this.env.composebody))
+      tinyMCE.triggerSave();
+
+    return true;
+    };
+
+  this.stop_spellchecking = function()
+    {
+    if (this.env.spellcheck && !this.spellcheck_ready) {
+      $(this.env.spellcheck.spell_span).trigger('click');
+      this.set_spellcheck_state('ready');
+      }
+    };
+
+  this.display_spellcheck_controls = function(vis)
+    {
+    if (this.env.spellcheck) {
+      // stop spellchecking process
+      if (!vis)
+       this.stop_spellchecking();
+
+      $(this.env.spellcheck.spell_container).css('visibility', vis ? 'visible' : 'hidden');
+      }
+    };
+
+  this.set_spellcheck_state = function(s)
+    {
+    this.spellcheck_ready = (s == 'ready' || s == 'no_error_found');
+    this.enable_command('spellcheck', this.spellcheck_ready);
+    };
+
+  this.set_draft_id = function(id)
+    {
+    $("input[name='_draft_saveid']").val(id);
+    };
+
+  this.auto_save_start = function()
+    {
+    if (this.env.draft_autosave)
+      this.save_timer = self.setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000);
+
+    // Unlock interface now that saving is complete
+    this.busy = false;
+    };
+
+  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 = '';
+    
+    if (value_to)
+      str += value_to+':';
+    if (value_cc)
+      str += value_cc+':';
+    if (value_bcc)
+      str += value_bcc+':';
+    if (value_subject)
+      str += value_subject+':';
+    
+    var editor = tinyMCE.get(this.env.composebody);
+    if (editor)
+      str += editor.getContent();
+    else
+      str += $("[name='_message']").val();
+    
+    if (save)
+      this.cmp_hash = str;
+    
+    return str;
+    };
+    
+  this.change_identity = function(obj)
+    {
+    if (!obj || !obj.options)
+      return false;
+
+    var id = obj.options[obj.selectedIndex].value;
+    var input_message = $("[name='_message']");
+    var message = input_message.val();
+    var is_html = ($("input[name='_is_html']").val() == '1');
+    var sig, p, len;
+
+    if (!this.env.identity)
+      this.env.identity = id
+  
+    if (!is_html)
+      {
+      // remove the 'old' signature
+      if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity])
+        {
+        if (this.env.signatures[this.env.identity]['is_html'])
+          sig = this.env.signatures[this.env.identity]['plain_text'];
+        else
+          sig = this.env.signatures[this.env.identity]['text'];
+        
+        if (sig.indexOf('-- ')!=0)
+          sig = '-- \n'+sig;
+
+        p = message.lastIndexOf(sig);
+        if (p>=0)
+          message = message.substring(0, p-1) + message.substring(p+sig.length, message.length);
+        }
+
+      message = message.replace(/[\r\n]+$/, '');
+      len = message.length;
+
+      // add the new signature string
+      if (this.env.signatures && this.env.signatures[id])
+        {
+        sig = this.env.signatures[id]['text'];
+        if (this.env.signatures[id]['is_html'])
+          {
+          sig = this.env.signatures[id]['plain_text'];
+          }
+        if (sig.indexOf('-- ')!=0)
+          sig = '-- \n'+sig;
+        message += '\n\n'+sig;
+       if (len) len += 1;
+        }
+      }
+    else
+      {
+      var editor = tinyMCE.get(this.env.composebody);
+
+      if (this.env.signatures)
+        {
+        // Append the signature as a div within the body
+        var sigElem = editor.dom.get('_rc_sig');
+        var newsig = '';
+        var htmlsig = true;
+
+        if (!sigElem)
+          {
+          // add empty line before signature on IE
+          if (bw.ie)
+            editor.getBody().appendChild(editor.getDoc().createElement('br'));
+
+          sigElem = editor.getDoc().createElement('div');
+          sigElem.setAttribute('id', '_rc_sig');
+          editor.getBody().appendChild(sigElem);
+          }
+
+        if (this.env.signatures[id])
+        {
+          newsig = this.env.signatures[id]['text'];
+          htmlsig = this.env.signatures[id]['is_html'];
+
+          if (newsig) {
+            if (htmlsig && this.env.signatures[id]['plain_text'].indexOf('-- ')!=0)
+              newsig = '<p>-- </p>' + newsig;
+            else if (!htmlsig && newsig.indexOf('-- ')!=0)
+              newsig = '-- \n' + newsig;
+          }
+        }
+
+        if (htmlsig)
+          sigElem.innerHTML = newsig;
+        else
+          sigElem.innerHTML = '<pre>' + newsig + '</pre>';
+        }
+      }
+
+    input_message.val(message);
+
+    // move cursor before the signature
+    if (!is_html)
+      this.set_caret_pos(input_message.get(0), len);
+
+    this.env.identity = id;
+    return true;
+    };
+
+  this.show_attachment_form = function(a)
+    {
+    if (!this.gui_objects.uploadbox)
+      return false;
+      
+    var elm, list;
+    if (elm = this.gui_objects.uploadbox)
+      {
+      if (a && (list = this.gui_objects.attachmentlist))
+        {
+        var pos = $(list).offset();
+        elm.style.top = (pos.top + list.offsetHeight + 10) + 'px';
+        elm.style.left = pos.left + 'px';
+        }
+      
+      elm.style.visibility = a ? 'visible' : 'hidden';
+      }
+      
+    // clear upload form
+    try {
+      if (!a && this.gui_objects.attachmentform != this.gui_objects.messageform)
+        this.gui_objects.attachmentform.reset();
+    }
+    catch(e){}  // ignore errors
+    
+    return true;
+    };
+
+  // upload attachment file
+  this.upload_file = function(form)
+    {
+    if (!form)
+      return false;
+      
+    // get file input fields
+    var send = false;
+    for (var n=0; n<form.elements.length; n++)
+      if (form.elements[n].type=='file' && form.elements[n].value)
+        {
+        send = true;
+        break;
+        }
+    
+    // create hidden iframe and post upload form
+    if (send)
+      {
+      var ts = new Date().getTime();
+      var frame_name = 'rcmupload'+ts;
+
+      // have to do it this way for IE
+      // otherwise the form will be posted to a new window
+      if(document.all)
+        {
+        var html = '<iframe name="'+frame_name+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>';
+        document.body.insertAdjacentHTML('BeforeEnd',html);
+        }
+      else  // for standards-compilant browsers
+        {
+        var frame = document.createElement('iframe');
+        frame.name = frame_name;
+        frame.style.border = 'none';
+        frame.style.width = 0;
+        frame.style.height = 0;
+        frame.style.visibility = 'hidden';
+        document.body.appendChild(frame);
+        }
+
+      form.target = frame_name;
+      form.action = this.env.comm_path+'&_action=upload';
+      form.setAttribute('enctype', 'multipart/form-data');
+      form.submit();
+      }
+    
+    // set reference to the form object
+    this.gui_objects.attachmentform = form;
+    return true;
+    };
+
+  // add file name to attachment list
+  // called from upload page
+  this.add2attachment_list = function(name, content)
+    {
+    if (!this.gui_objects.attachmentlist)
+      return false;
+      
+    $('<li>').attr('id', name).html(content).appendTo(this.gui_objects.attachmentlist);
+    return true;
+    };
+
+  this.remove_from_attachment_list = function(name)
+    {
+    if (!this.gui_objects.attachmentlist)
+      return false;
+
+    var list = this.gui_objects.attachmentlist.getElementsByTagName("li");
+    for (i=0;i<list.length;i++)
+      if (list[i].id == name)
+        this.gui_objects.attachmentlist.removeChild(list[i]);
+    };
+
+  this.remove_attachment = function(name)
+    {
+    if (name)
+      this.http_post('remove-attachment', '_file='+urlencode(name));
+
+    return true;
+    };
+
+  // send remote request to add a new contact
+  this.add_contact = function(value)
+    {
+    if (value)
+      this.http_post('addcontact', '_address='+value);
+    
+    return true;
+    };
+
+  // send remote request to search mail or contacts
+  this.qsearch = function(value)
+    {
+    if (value != '')
+      {
+      var addurl = '';
+      if (this.message_list) {
+        this.message_list.clear();
+       if (this.env.search_mods) {
+          var head_arr = new Array();
+          for (var n in this.env.search_mods)
+           head_arr.push(n);
+         addurl += '&_headers='+head_arr.join(',');
+          }
+        } else if (this.contact_list) {
+        this.contact_list.clear(true);
+        this.show_contentframe(false);
+        }
+
+      if (this.gui_objects.search_filter)
+        addurl += '&_filter=' + this.gui_objects.search_filter.value;
+
+      // reset vars
+      this.env.current_page = 1;
+      this.set_busy(true, 'searching');
+      this.http_request('search', '_q='+urlencode(value)
+        + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '')
+        + (this.env.source ? '&_source='+urlencode(this.env.source) : '')
+        + (addurl ? addurl : ''), true);
+      }
+    return true;
+    };
+
+  // reset quick-search form
+  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(type, msg)
+    {
+    this.list_mailbox();
+    this.display_message(msg, type, true);
+    }
+
+
+  /*********************************************************/
+  /*********     keyboard live-search methods      *********/
+  /*********************************************************/
+
+  // handler for keyboard events on address-fields
+  this.ksearch_keypress = function(e, obj)
+  {
+    if (this.ksearch_timer)
+      clearTimeout(this.ksearch_timer);
+
+    var highlight;
+    var key = rcube_event.get_keycode(e);
+    var mod = rcube_event.get_modifier(e);
+
+    switch (key)
+      {
+      case 38:  // key up
+      case 40:  // key down
+        if (!this.ksearch_pane)
+          break;
+          
+        var dir = key==38 ? 1 : 0;
+        
+        highlight = document.getElementById('rcmksearchSelected');
+        if (!highlight)
+          highlight = this.ksearch_pane.__ul.firstChild;
+        
+        if (highlight)
+          this.ksearch_select(dir ? highlight.previousSibling : highlight.nextSibling);
+
+        return rcube_event.cancel(e);
+
+      case 9:  // tab
+        if(mod == SHIFT_KEY)
+          break;
+
+      case 13:  // enter
+        if (this.ksearch_selected===null || !this.ksearch_input || !this.ksearch_value)
+          break;
+
+        // insert selected address and hide ksearch pane
+        this.insert_recipient(this.ksearch_selected);
+        this.ksearch_hide();
+
+        return rcube_event.cancel(e);
+
+      case 27:  // escape
+        this.ksearch_hide();
+        break;
+      
+      case 37:  // left
+      case 39:  // right
+        if (mod != SHIFT_KEY)
+         return;
+      }
+
+    // start timer
+    this.ksearch_timer = window.setTimeout(function(){ ref.ksearch_get_results(); }, 200);
+    this.ksearch_input = obj;
+    
+    return true;
+  };
+  
+  this.ksearch_select = function(node)
+  {
+    var current = $('#rcmksearchSelected');
+    if (current[0] && node) {
+      current.removeAttr('id').removeClass('selected');
+    }
+
+    if (node) {
+      $(node).attr('id', 'rcmksearchSelected').addClass('selected');
+      this.ksearch_selected = node._rcm_id;
+    }
+  };
+
+  this.insert_recipient = function(id)
+  {
+    if (!this.env.contacts[id] || !this.ksearch_input)
+      return;
+    
+    // get cursor pos
+    var inp_value = this.ksearch_input.value.toLowerCase();
+    var cpos = this.get_caret_pos(this.ksearch_input);
+    var p = inp_value.lastIndexOf(this.ksearch_value, cpos);
+
+    // replace search string with full address
+    var pre = this.ksearch_input.value.substring(0, p);
+    var end = this.ksearch_input.value.substring(p+this.ksearch_value.length, this.ksearch_input.value.length);
+    var insert  = this.env.contacts[id]+', ';
+    this.ksearch_input.value = pre + insert + end;
+
+    // set caret to insert pos
+    cpos = p+insert.length;
+    if (this.ksearch_input.setSelectionRange)
+      this.ksearch_input.setSelectionRange(cpos, cpos);
+  };
+
+  // address search processor
+  this.ksearch_get_results = function()
+  {
+    var inp_value = this.ksearch_input ? this.ksearch_input.value : null;
+    if (inp_value === null)
+      return;
+      
+    if (this.ksearch_pane && this.ksearch_pane.is(":visible"))
+      this.ksearch_pane.hide();
+
+    // get string from current cursor pos to last comma
+    var cpos = this.get_caret_pos(this.ksearch_input);
+    var p = inp_value.lastIndexOf(',', cpos-1);
+    var q = inp_value.substring(p+1, cpos);
+
+    // trim query string
+    q = q.replace(/(^\s+|\s+$)/g, '').toLowerCase();
+
+    // Don't (re-)search if the last results are still active
+    if (q == this.ksearch_value)
+      return;
+    
+    var old_value = this.ksearch_value;
+    this.ksearch_value = q;
+    
+    // ...string is empty
+    if (!q.length)
+      return;
+
+    // ...new search value contains old one and previous search result was empty
+    if (old_value && old_value.length && this.env.contacts && !this.env.contacts.length && q.indexOf(old_value) == 0)
+      return;
+    
+    this.display_message(this.get_label('searching'), 'loading', true);
+    this.http_post('autocomplete', '_search='+urlencode(q));
+  };
+
+  this.ksearch_query_results = function(results, search)
+  {
+    // ignore this outdated search response
+    if (this.ksearch_value && search != this.ksearch_value)
+      return;
+      
+    this.hide_message();
+    this.env.contacts = results ? results : [];
+    this.ksearch_display_results(this.env.contacts);
+  };
+
+  this.ksearch_display_results = function (a_results)
+  {
+    // display search results
+    if (a_results.length && this.ksearch_input) {
+      var p, ul, li;
+      
+      // create results pane if not present
+      if (!this.ksearch_pane) {
+        ul = $('<ul>');
+        this.ksearch_pane = $('<div>').attr('id', 'rcmKSearchpane').css({ position:'absolute', 'z-index':30000 }).append(ul).appendTo(document.body);
+        this.ksearch_pane.__ul = ul[0];
+      }
+
+      // remove all search results
+      ul = this.ksearch_pane.__ul;
+      ul.innerHTML = '';
+            
+      // add each result line to list
+      for (i=0; i<a_results.length; i++) {
+        li = document.createElement('LI');
+        li.innerHTML = a_results[i].replace(new RegExp('('+this.ksearch_value+')', 'ig'), '##$1%%').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/##([^%]+)%%/g, '<b>$1</b>');
+        li.onmouseover = function(){ ref.ksearch_select(this); };
+        li.onmouseup = function(){ ref.ksearch_click(this) };
+        li._rcm_id = i;
+        ul.appendChild(li);
+      }
+
+      // select the first
+      $(ul.firstChild).attr('id', 'rcmksearchSelected').addClass('selected');
+      this.ksearch_selected = 0;
+
+      // move the results pane right under the input box and make it visible
+      var pos = $(this.ksearch_input).offset();
+      this.ksearch_pane.css({ left:pos.left+'px', top:(pos.top + this.ksearch_input.offsetHeight)+'px' }).show();
+    }
+    // hide results pane
+    else
+      this.ksearch_hide();
+  };
+  
+  this.ksearch_click = function(node)
+  {
+    if (this.ksearch_input)
+      this.ksearch_input.focus();
+
+    this.insert_recipient(node._rcm_id);
+    this.ksearch_hide();
+  };
+
+  this.ksearch_blur = function()
+    {
+    if (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;
+    
+    if (this.ksearch_pane)
+      this.ksearch_pane.hide();
+    };
+
+
+  /*********************************************************/
+  /*********         address book methods          *********/
+  /*********************************************************/
+
+  this.contactlist_keypress = function(list)
+    {
+      if (list.key_pressed == list.DELETE_KEY)
+        this.command('delete');
+    };
+
+  this.contactlist_select = function(list)
+    {
+      if (this.preview_timer)
+        clearTimeout(this.preview_timer);
+
+      var id, frame, ref = this;
+      if (id = list.get_single_selection())
+        this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200);
+      else if (this.env.contentframe)
+        this.show_contentframe(false);
+
+      this.enable_command('compose', list.selection.length > 0);
+      this.enable_command('edit', (id && this.env.address_sources && !this.env.address_sources[this.env.source].readonly) ? true : false);
+      this.enable_command('delete', list.selection.length && this.env.address_sources && !this.env.address_sources[this.env.source].readonly);
+
+      return false;
+    };
+
+  this.list_contacts = function(src, page)
+    {
+    var add_url = '';
+    var target = window;
+    
+    if (!src)
+      src = this.env.source;
+    
+    if (page && this.current_page==page && src == this.env.source)
+      return false;
+      
+    if (src != this.env.source)
+      {
+      page = 1;
+      this.env.current_page = page;
+      this.reset_qsearch();
+      }
+
+    this.select_folder(src, this.env.source);
+    this.env.source = src;
+
+    // load contacts remotely
+    if (this.gui_objects.contactslist)
+      {
+      this.list_contacts_remote(src, page);
+      return;
+      }
+
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      target = window.frames[this.env.contentframe];
+      add_url = '&_framed=1';
+      }
+
+    // also send search request to get the correct listing
+    if (this.env.search_request)
+      add_url += '&_search='+this.env.search_request;
+
+    this.set_busy(true, 'loading');
+    target.location.href = this.env.comm_path+(src ? '&_source='+urlencode(src) : '')+(page ? '&_page='+page : '')+add_url;
+    };
+
+  // send remote request to load contacts list
+  this.list_contacts_remote = function(src, page)
+    {
+    // clear message list first
+    this.contact_list.clear(true);
+    this.show_contentframe(false);
+    this.enable_command('delete', 'compose', false);
+
+    // send request to server
+    var url = (src ? '_source='+urlencode(src) : '') + (page ? (src?'&':'') + '_page='+page : '');
+    this.env.source = src;
+    
+    // also send search request to get the right messages 
+    if (this.env.search_request) 
+      url += '&_search='+this.env.search_request;
+
+    this.set_busy(true, 'loading');
+    this.http_request('list', url, true);
+    };
+
+  // load contact record
+  this.load_contact = function(cid, action, framed)
+    {
+    var add_url = '';
+    var target = window;
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      add_url = '&_framed=1';
+      target = window.frames[this.env.contentframe];
+      this.show_contentframe(true);
+      }
+    else if (framed)
+      return false;
+      
+    if (action && (cid || action=='add') && !this.drag_active)
+      {
+      this.set_busy(true);
+      target.location.href = this.env.comm_path+'&_action='+action+'&_source='+urlencode(this.env.source)+'&_cid='+urlencode(cid) + add_url;
+      }
+    return true;
+    };
+
+  // copy a contact to the specified target (group or directory)
+  this.copy_contact = function(cid, to)
+    {
+    if (!cid)
+      cid = this.contact_list.get_selection().join(',');
+
+    if (to != this.env.source && cid && this.env.address_sources[to] && !this.env.address_sources[to].readonly)
+      this.http_post('copy', '_cid='+urlencode(cid)+'&_source='+urlencode(this.env.source)+'&_to='+urlencode(to));
+    };
+
+
+  this.delete_contacts = function()
+    {
+    // exit if no mailbox specified or if selection is empty
+    var selection = this.contact_list.get_selection();
+    if (!(selection.length || this.env.cid) || !confirm(this.get_label('deletecontactconfirm')))
+      return;
+      
+    var a_cids = new Array();
+    var qs = '';
+
+    if (this.env.cid)
+      a_cids[a_cids.length] = this.env.cid;
+    else
+      {
+      var id;
+      for (var n=0; n<selection.length; n++)
+        {
+        id = selection[n];
+        a_cids[a_cids.length] = id;
+        this.contact_list.remove_row(id, (n == selection.length-1));
+        }
+
+      // hide content frame if we delete the currently displayed contact
+      if (selection.length == 1)
+        this.show_contentframe(false);
+      }
+
+    // also send search request to get the right records from the next page
+    if (this.env.search_request) 
+      qs += '&_search='+this.env.search_request;
+
+    // send request to server
+    this.http_post('delete', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source)+'&_from='+(this.env.action ? this.env.action : '')+qs);
+    return true;
+    };
+
+  // update a contact record in the list
+  this.update_contact_row = function(cid, cols_arr, newcid)
+  {
+    var row;
+    if (this.contact_list.rows[cid] && (row = this.contact_list.rows[cid].obj)) {
+      for (var c=0; c<cols_arr.length; c++)
+        if (row.cells[c])
+          $(row.cells[c]).html(cols_arr[c]);
+
+      // cid change
+      if (newcid) {
+       row.id = 'rcmrow' + newcid;
+        this.contact_list.remove_row(cid);
+        this.contact_list.init_row(row);
+       this.contact_list.selection[0] = newcid;
+       row.style.display = '';
+      }
+
+      return true;
+    }
+
+    return false;
+  };
+
+  // add row to contacts list
+  this.add_contact_row = function(cid, cols, select)
+    {
+    if (!this.gui_objects.contactslist || !this.gui_objects.contactslist.tBodies[0])
+      return false;
+    
+    var tbody = this.gui_objects.contactslist.tBodies[0];
+    var rowcount = tbody.rows.length;
+    var even = rowcount%2;
+    
+    var row = document.createElement('tr');
+    row.id = 'rcmrow'+cid;
+    row.className = 'contact '+(even ? 'even' : 'odd');
+           
+    if (this.contact_list.in_selection(cid))
+      row.className += ' selected';
+
+    // add each submitted col
+    for (var c in cols) {
+      col = document.createElement('td');
+      col.className = String(c).toLowerCase();
+      col.innerHTML = cols[c];
+      row.appendChild(col);
+    }
+    
+    this.contact_list.insert_row(row);
+    
+    this.enable_command('export', (this.contact_list.rowcount > 0));
+    };
+
+
+  /*********************************************************/
+  /*********        user settings methods          *********/
+  /*********************************************************/
+
+  this.init_subscription_list = function()
+    {
+    var p = 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(o){ p.subscription_select(o); });
+    this.subscription_list.addEventListener('dragstart', function(o){ p.drag_active = true; });
+    this.subscription_list.addEventListener('dragend', function(o){ p.subscription_move_folder(o); });
+    this.subscription_list.row_init = function (row)
+      {
+      var anchors = row.obj.getElementsByTagName('a');
+      if (anchors[0])
+        anchors[0].onclick = function() { p.rename_folder(row.id); return false; };
+      if (anchors[1])
+        anchors[1].onclick = function() { p.delete_folder(row.id); return false; };
+      row.obj.onmouseover = function() { p.focus_subscription(row.id); };
+      row.obj.onmouseout = function() { p.unfocus_subscription(row.id); };
+      }
+    this.subscription_list.init();
+    }
+
+  // preferences section select and load options frame
+  this.section_select = function(list)
+    {
+    var id = list.get_single_selection();
+    
+    if (id) {
+      var add_url = '';
+      var target = window;
+      this.set_busy(true);
+
+      if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) {
+        add_url = '&_framed=1';
+        target = window.frames[this.env.contentframe];
+        }
+
+      target.location.href = this.env.comm_path+'&_action=edit-prefs&_section='+id+add_url;
+      }
+
+    return true;
+    };
+
+  this.identity_select = function(list)
+    {
+    var id;
+    if (id = list.get_single_selection())
+      this.load_identity(id, 'edit-identity');
+    };
+
+  // load identity record
+  this.load_identity = function(id, action)
+    {
+    if (action=='edit-identity' && (!id || id==this.env.iid))
+      return false;
+
+    var add_url = '';
+    var target = window;
+    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
+      {
+      add_url = '&_framed=1';
+      target = window.frames[this.env.contentframe];
+      document.getElementById(this.env.contentframe).style.visibility = 'inherit';
+      }
+
+    if (action && (id || action=='add-identity'))
+      {
+      this.set_busy(true);
+      target.location.href = this.env.comm_path+'&_action='+action+'&_iid='+id+add_url;
+      }
+    return true;
+    };
+
+  this.delete_identity = function(id)
+    {
+    // exit if no mailbox specified or if selection is empty
+    var selection = this.identity_list.get_selection();
+    if (!(selection.length || this.env.iid))
+      return;
+    
+    if (!id)
+      id = this.env.iid ? this.env.iid : selection[0];
+
+    // append token to request
+    this.goto_url('delete-identity', '_iid='+id+'&_token='+this.env.request_token, true);
+    
+    return true;
+    };
+
+  this.focus_subscription = function(id)
+    {
+    var row, folder;
+    var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
+
+    if (this.drag_active && this.env.folder && (row = document.getElementById(id)))
+      if (this.env.subscriptionrows[id] &&
+          (folder = this.env.subscriptionrows[id][0]))
+        {
+        if (this.check_droptarget(folder) &&
+            !this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2] &&
+            (folder != this.env.folder.replace(reg, '')) &&
+            (!folder.match(new RegExp('^'+RegExp.escape(this.env.folder+this.env.delimiter)))))
+          {
+          this.set_env('dstfolder', folder);
+          $(row).addClass('droptarget');
+          }
+        }
+      else if (this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter))))
+        {
+        this.set_env('dstfolder', this.env.delimiter);
+        $(this.subscription_list.frame).addClass('droptarget');
+        }
+    }
+
+  this.unfocus_subscription = function(id)
+    {
+      var row = $('#'+id);
+      this.set_env('dstfolder', null);
+      if (this.env.subscriptionrows[id] && row[0])
+        row.removeClass('droptarget');
+      else
+        $(this.subscription_list.frame).removeClass('droptarget');
+    }
+
+  this.subscription_select = function(list)
+    {
+    var id, folder;
+    if ((id = list.get_single_selection()) &&
+        this.env.subscriptionrows['rcmrow'+id] &&
+        (folder = this.env.subscriptionrows['rcmrow'+id][0]))
+      this.set_env('folder', folder);
+    else
+      this.set_env('folder', null);
+      
+    if (this.gui_objects.createfolderhint)
+      $(this.gui_objects.createfolderhint).html(this.env.folder ? this.get_label('addsubfolderhint') : '');
+    };
+
+  this.subscription_move_folder = function(list)
+    {
+    var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
+    if (this.env.folder && this.env.dstfolder && (this.env.dstfolder != this.env.folder) &&
+        (this.env.dstfolder != this.env.folder.replace(reg, '')))
+      {
+      var reg = new RegExp('[^'+RegExp.escape(this.env.delimiter)+']*['+RegExp.escape(this.env.delimiter)+']', 'g');
+      var basename = this.env.folder.replace(reg, '');
+      var newname = this.env.dstfolder==this.env.delimiter ? basename : this.env.dstfolder+this.env.delimiter+basename;
+
+      this.set_busy(true, 'foldermoving');
+      this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.folder)+'&_folder_newname='+urlencode(newname), true);
+      }
+    this.drag_active = false;
+    this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder));
+    };
+
+  // tell server to create and subscribe a new mailbox
+  this.create_folder = function(name)
+    {
+    if (this.edit_folder)
+      this.reset_folder_rename();
+
+    var form;
+    if ((form = this.gui_objects.editform) && form.elements['_folder_name'])
+      {
+      name = form.elements['_folder_name'].value;
+
+      if (name.indexOf(this.env.delimiter)>=0)
+        {
+        alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')');
+        return false;
+        }
+
+      if (this.env.folder && name != '')
+        name = this.env.folder+this.env.delimiter+name;
+
+      this.set_busy(true, 'foldercreating');
+      this.http_post('create-folder', '_name='+urlencode(name), true);
+      }
+    else if (form.elements['_folder_name'])
+      form.elements['_folder_name'].focus();
+    };
+
+  // start renaming the mailbox name.
+  // this will replace the name string with an input field
+  this.rename_folder = function(id)
+    {
+    var temp, row, form;
+
+    // reset current renaming
+    if (temp = this.edit_folder)
+      {
+      this.reset_folder_rename();
+      if (temp == id)
+        return;
+      }
+
+    if (id && this.env.subscriptionrows[id] && (row = document.getElementById(id)))
+      {
+      var reg = new RegExp('.*['+RegExp.escape(this.env.delimiter)+']');
+      this.name_input = document.createElement('input');
+      this.name_input.type = 'text';
+      this.name_input.value = this.env.subscriptionrows[id][0].replace(reg, '');
+
+      reg = new RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
+      this.name_input.__parent = this.env.subscriptionrows[id][0].replace(reg, '');
+      this.name_input.onkeypress = function(e){ rcmail.name_input_keypress(e); };
+      
+      row.cells[0].replaceChild(this.name_input, row.cells[0].firstChild);
+      this.edit_folder = id;
+      this.name_input.select();
+      
+      if (form = this.gui_objects.editform)
+        form.onsubmit = function(){ return false; };
+      }
+    };
+
+  // remove the input field and write the current mailbox name to the table cell
+  this.reset_folder_rename = function()
+    {
+    var cell = this.name_input ? this.name_input.parentNode : null;
+
+    if (cell && this.edit_folder && this.env.subscriptionrows[this.edit_folder])
+      $(cell).html(this.env.subscriptionrows[this.edit_folder][1]);
+      
+    this.edit_folder = null;
+    };
+
+  // handler for keyboard events on the input field
+  this.name_input_keypress = function(e)
+    {
+    var key = rcube_event.get_keycode(e);
+
+    // enter
+    if (key==13)
+      {
+      var newname = this.name_input ? this.name_input.value : null;
+      if (this.edit_folder && newname)
+        {
+        if (newname.indexOf(this.env.delimiter)>=0)
+          {
+          alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')');
+          return false;
+          }
+
+        if (this.name_input.__parent)
+          newname = this.name_input.__parent + this.env.delimiter + newname;
+
+        this.set_busy(true, 'folderrenaming');
+        this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname), true);
+        }
+      }
+    // escape
+    else if (key==27)
+      this.reset_folder_rename();
+    };
+
+  // delete a specific mailbox with all its messages
+  this.delete_folder = function(id)
+    {
+    var folder = this.env.subscriptionrows[id][0];
+
+    if (this.edit_folder)
+      this.reset_folder_rename();
+
+    if (folder && confirm(this.get_label('deletefolderconfirm')))
+      {
+      this.set_busy(true, 'folderdeleting');
+      this.http_post('delete-folder', '_mboxes='+urlencode(folder), true);
+      this.set_env('folder', null);
+
+      $(this.gui_objects.createfolderhint).html('');
+      }
+    };
+
+  // add a new folder to the subscription list by cloning a folder row
+  this.add_folder_row = function(name, display_name, replace, before)
+    {
+    if (!this.gui_objects.subscriptionlist)
+      return false;
+
+    // find not protected folder    
+    for (var refid in this.env.subscriptionrows)
+      if (this.env.subscriptionrows[refid]!=null && !this.env.subscriptionrows[refid][2])
+        break;
+
+    var refrow, form;
+    var tbody = this.gui_objects.subscriptionlist.tBodies[0];
+    var id = 'rcmrow'+(tbody.childNodes.length+1);
+    var selection = this.subscription_list.get_single_selection();
+    
+    if (replace && replace.id)
+    {
+      id = replace.id;
+      refid = replace.id;
+    }
+
+    if (!id || !(refrow = document.getElementById(refid)))
+      {
+      // Refresh page if we don't have a table row to clone
+      this.goto_url('folders');
+      }
+    else
+      {
+      // clone a table row if there are existing rows
+      var row = this.clone_table_row(refrow);
+      row.id = id;
+
+      if (before && (before = this.get_folder_row_id(before)))
+        tbody.insertBefore(row, document.getElementById(before));
+      else
+        tbody.appendChild(row);
+      
+      if (replace)
+        tbody.removeChild(replace);
+      }
+
+    // add to folder/row-ID map
+    this.env.subscriptionrows[row.id] = [name, display_name, 0];
+
+    // set folder name
+    row.cells[0].innerHTML = display_name;
+    
+    // set messages count to zero
+    if (!replace)
+      row.cells[1].innerHTML = '*';
+    
+    if (!replace && row.cells[2] && row.cells[2].firstChild.tagName.toLowerCase()=='input')
+      {
+      row.cells[2].firstChild.value = name;
+      row.cells[2].firstChild.checked = true;
+      }
+    
+    // add new folder to rename-folder list and clear input field
+    if (!replace && (form = this.gui_objects.editform))
+      {
+      if (form.elements['_folder_oldname'])
+        form.elements['_folder_oldname'].options[form.elements['_folder_oldname'].options.length] = new Option(name,name);
+      if (form.elements['_folder_name'])
+        form.elements['_folder_name'].value = ''; 
+      }
+
+    this.init_subscription_list();
+    if (selection && document.getElementById('rcmrow'+selection))
+      this.subscription_list.select_row(selection);
+
+    if (document.getElementById(id).scrollIntoView)
+      document.getElementById(id).scrollIntoView();
+    };
+
+  // replace an existing table row with a new folder line
+  this.replace_folder_row = function(oldfolder, newfolder, display_name, before)
+    {
+    var id = this.get_folder_row_id(oldfolder);
+    var row = document.getElementById(id);
+    
+    // replace an existing table row (if found)
+    this.add_folder_row(newfolder, display_name, row, before);
+    
+    // rename folder in rename-folder dropdown
+    var form, elm;
+    if ((form = this.gui_objects.editform) && (elm = form.elements['_folder_oldname']))
+      {
+      for (var i=0;i<elm.options.length;i++)
+        {
+        if (elm.options[i].value == oldfolder)
+          {
+          elm.options[i].text = display_name;
+          elm.options[i].value = newfolder;
+          break;
+          }
+        }
+
+      form.elements['_folder_newname'].value = '';
+      }
+    };
+
+  // remove the table row of a specific mailbox from the table
+  // (the row will not be removed, just hidden)
+  this.remove_folder_row = function(folder)
+    {
+    var row;
+    var id = this.get_folder_row_id(folder);
+    if (id && (row = document.getElementById(id)))
+      row.style.display = 'none';
+
+    // remove folder from rename-folder list
+    var form;
+    if ((form = this.gui_objects.editform) && form.elements['_folder_oldname'])
+      {
+      for (var i=0;i<form.elements['_folder_oldname'].options.length;i++)
+        {
+        if (form.elements['_folder_oldname'].options[i].value == folder) 
+          {
+          form.elements['_folder_oldname'].options[i] = null;
+          break;
+          }
+        }
+      }
+    
+    if (form && form.elements['_folder_newname'])
+      form.elements['_folder_newname'].value = '';
+    };
+
+  this.subscribe_folder = function(folder)
+    {
+    if (folder)
+      this.http_post('subscribe', '_mbox='+urlencode(folder));
+    };
+
+  this.unsubscribe_folder = function(folder)
+    {
+    if (folder)
+      this.http_post('unsubscribe', '_mbox='+urlencode(folder));
+    };
+    
+  // helper method to find a specific mailbox row ID
+  this.get_folder_row_id = function(folder)
+    {
+    for (var id in this.env.subscriptionrows)
+      if (this.env.subscriptionrows[id] && this.env.subscriptionrows[id][0] == folder)
+        break;
+        
+    return id;
+    };
+
+  // duplicate a specific table row
+  this.clone_table_row = function(row)
+    {
+    var cell, td;
+    var new_row = document.createElement('tr');
+    for(var n=0; n<row.cells.length; n++)
+      {
+      cell = row.cells[n];
+      td = document.createElement('td');
+
+      if (cell.className)
+        td.className = cell.className;
+      if (cell.align)
+        td.setAttribute('align', cell.align);
+        
+      td.innerHTML = cell.innerHTML;
+      new_row.appendChild(td);
+      }
+    
+    return new_row;
+    };
+
+
+  /*********************************************************/
+  /*********           GUI functionality           *********/
+  /*********************************************************/
+
+  // eable/disable buttons for page shifting
+  this.set_page_buttons = function()
+  {
+    this.enable_command('nextpage', (this.env.pagecount > this.env.current_page));
+    this.enable_command('lastpage', (this.env.pagecount > this.env.current_page));
+    this.enable_command('previouspage', (this.env.current_page > 1));
+    this.enable_command('firstpage', (this.env.current_page > 1));
+  };
+  
+  // set event handlers on registered buttons
+  this.init_buttons = function()
+  {
+    for (var cmd in this.buttons) {
+      if (typeof cmd != 'string')
+        continue;
+      
+      for (var i=0; i< this.buttons[cmd].length; i++) {
+        var prop = this.buttons[cmd][i];
+        var elm = document.getElementById(prop.id);
+        if (!elm)
+          continue;
+
+        var preload = false;
+        if (prop.type == 'image') {
+          elm = elm.parentNode;
+          preload = true;
+        }
+        
+        elm._command = cmd;
+        elm._id = prop.id;
+        if (prop.sel) {
+          elm.onmousedown = function(e){ return rcmail.button_sel(this._command, this._id); };
+          elm.onmouseup = function(e){ return rcmail.button_out(this._command, this._id); };
+          if (preload)
+            new Image().src = prop.sel;
+        }
+        if (prop.over) {
+          elm.onmouseover = function(e){ return rcmail.button_over(this._command, this._id); };
+          elm.onmouseout = function(e){ return rcmail.button_out(this._command, this._id); };
+          if (preload)
+            new Image().src = prop.over;
+        }
+      }
+    }
+  };
+
+  // set button to a specific state
+  this.set_button = function(command, state)
+    {
+    var a_buttons = this.buttons[command];
+    var button, obj;
+
+    if(!a_buttons || !a_buttons.length)
+      return false;
+
+    for(var n=0; n<a_buttons.length; n++)
+      {
+      button = a_buttons[n];
+      obj = document.getElementById(button.id);
+
+      // get default/passive setting of the button
+      if (obj && button.type=='image' && !button.status) {
+        button.pas = obj._original_src ? obj._original_src : obj.src;
+        // respect PNG fix on IE browsers
+        if (obj.runtimeStyle && obj.runtimeStyle.filter && obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/))
+          button.pas = RegExp.$1;
+      }
+      else if (obj && !button.status)
+        button.pas = String(obj.className);
+
+      // set image according to button state
+      if (obj && button.type=='image' && button[state])
+        {
+        button.status = state;        
+        obj.src = button[state];
+        }
+      // set class name according to button state
+      else if (obj && typeof(button[state])!='undefined')
+        {
+        button.status = state;        
+        obj.className = button[state];        
+        }
+      // disable/enable input buttons
+      if (obj && button.type=='input')
+        {
+        button.status = state;
+        obj.disabled = !state;
+        }
+      }
+    };
+
+  // display a specific alttext
+  this.set_alttext = function(command, label)
+    {
+      if (!this.buttons[command] || !this.buttons[command].length)
+        return;
+      
+      var button, obj, link;
+      for (var n=0; n<this.buttons[command].length; n++)
+      {
+        button = this.buttons[command][n];
+        obj = document.getElementById(button.id);
+        
+        if (button.type=='image' && obj)
+        {
+          obj.setAttribute('alt', this.get_label(label));
+          if ((link = obj.parentNode) && link.tagName.toLowerCase() == 'a')
+            link.setAttribute('title', this.get_label(label));
+        }
+        else if (obj)
+          obj.setAttribute('title', this.get_label(label));
+      }
+    };
+
+  // mouse over button
+  this.button_over = function(command, id)
+  {
+    var a_buttons = this.buttons[command];
+    var button, elm;
+
+    if(!a_buttons || !a_buttons.length)
+      return false;
+
+    for(var n=0; n<a_buttons.length; n++)
+    {
+      button = a_buttons[n];
+      if(button.id==id && button.status=='act')
+      {
+        elm = document.getElementById(button.id);
+        if (elm && button.over) {
+          if (button.type == 'image')
+            elm.src = button.over;
+          else
+            elm.className = button.over;
+        }
+      }
+    }
+  };
+
+  // mouse down on button
+  this.button_sel = function(command, id)
+  {
+    var a_buttons = this.buttons[command];
+    var button, elm;
+
+    if(!a_buttons || !a_buttons.length)
+      return;
+
+    for(var n=0; n<a_buttons.length; n++)
+    {
+      button = a_buttons[n];
+      if(button.id==id && button.status=='act')
+      {
+        elm = document.getElementById(button.id);
+        if (elm && button.sel) {
+          if (button.type == 'image')
+            elm.src = button.sel;
+          else
+            elm.className = button.sel;
+        }
+        this.buttons_sel[id] = command;
+      }
+    }
+  };
+
+  // mouse out of button
+  this.button_out = function(command, id)
+  {
+    var a_buttons = this.buttons[command];
+    var button, elm;
+
+    if(!a_buttons || !a_buttons.length)
+      return;
+
+    for(var n=0; n<a_buttons.length; n++)
+    {
+      button = a_buttons[n];
+      if(button.id==id && button.status=='act')
+      {
+        elm = document.getElementById(button.id);
+        if (elm && button.act) {
+          if (button.type == 'image')
+            elm.src = button.act;
+          else
+            elm.className = button.act;
+        }
+      }
+    }
+  };
+
+  // write to the document/window title
+  this.set_pagetitle = function(title)
+  {
+    if (title && document.title)
+      document.title = title;
+  }
+
+  // display a system message
+  this.display_message = function(msg, type, hold)
+    {
+    if (!this.loaded)  // save message in order to display after page loaded
+      {
+      this.pending_message = new Array(msg, type);
+      return true;
+      }
+
+    // pass command to parent window
+    if (this.env.framed && parent.rcmail)
+      return parent.rcmail.display_message(msg, type, hold);
+
+    if (!this.gui_objects.message)
+      return false;
+
+    if (this.message_timer)
+      clearTimeout(this.message_timer);
+    
+    var cont = msg;
+    if (type)
+      cont = '<div class="'+type+'">'+cont+'</div>';
+
+    var obj = $(this.gui_objects.message).html(cont).show();
+    
+    if (type!='loading')
+      obj.bind('mousedown', function(){ ref.hide_message(); return true; });
+    
+    if (!hold)
+      this.message_timer = window.setTimeout(function(){ ref.hide_message(true); }, this.message_time);
+    };
+
+  // make a message row disapear
+  this.hide_message = function(fade)
+    {
+    if (this.gui_objects.message)
+      $(this.gui_objects.message).unbind()[(fade?'fadeOut':'hide')]();
+    };
+
+  // mark a mailbox as selected and set environment variable
+  this.select_folder = function(name, old)
+  {
+    if (this.gui_objects.folderlist)
+    {
+      var current_li, target_li;
+      
+      if ((current_li = this.get_folder_li(old))) {
+        $(current_li).removeClass('selected').removeClass('unfocused');
+      }
+      if ((target_li = this.get_folder_li(name))) {
+        $(target_li).removeClass('unfocused').addClass('selected');
+      }
+      
+      // trigger event hook
+      this.triggerEvent('selectfolder', { folder:name, old:old });
+    }
+  };
+
+  // helper method to find a folder list item
+  this.get_folder_li = function(name)
+  {
+    if (this.gui_objects.folderlist)
+    {
+      name = String(name).replace(this.identifier_expr, '_');
+      return document.getElementById('rcmli'+name);
+    }
+
+    return null;
+  };
+
+  // for reordering column array, Konqueror workaround
+  this.set_message_coltypes = function(coltypes) 
+  { 
+    this.coltypes = coltypes;
+    
+    // set correct list titles
+    var cell, col;
+    var thead = this.gui_objects.messagelist ? this.gui_objects.messagelist.tHead : null;
+    for (var n=0; thead && n<this.coltypes.length; n++) 
+      {
+      col = this.coltypes[n];
+      if ((cell = thead.rows[0].cells[n+1]) && (col=='from' || col=='to'))
+        {
+        // if we have links for sorting, it's a bit more complicated...
+        if (cell.firstChild && cell.firstChild.tagName.toLowerCase()=='a')
+          {
+          cell.firstChild.innerHTML = this.get_label(this.coltypes[n]);
+          cell.firstChild.onclick = function(){ return rcmail.command('sort', this.__col, this); };
+          cell.firstChild.__col = col;
+          }
+        else
+          cell.innerHTML = this.get_label(this.coltypes[n]);
+
+        cell.id = 'rcm'+col;
+        }
+      else if (col == 'subject' && this.message_list)
+        this.message_list.subject_col = n+1;
+      }
+  };
+
+  // create a table row in the message list
+  this.add_message_row = function(uid, cols, flags, attachment, attop)
+    {
+    if (!this.gui_objects.messagelist || !this.message_list)
+      return false;
+
+    if (this.message_list.background)
+      var tbody = this.message_list.background;
+    else
+      var tbody = this.gui_objects.messagelist.tBodies[0];
+    
+    var rowcount = tbody.rows.length;
+    var even = rowcount%2;
+    
+    this.env.messages[uid] = {
+      deleted: flags.deleted?1:0,
+      replied: flags.replied?1:0,
+      unread: flags.unread?1:0,
+      forwarded: flags.forwarded?1:0,
+      flagged:flags.flagged?1:0
+    };
+
+    var css_class = 'message'
+        + (even ? ' even' : ' odd')
+        + (flags.unread ? ' unread' : '')
+        + (flags.deleted ? ' deleted' : '')
+        + (flags.flagged ? ' flagged' : '')
+        + (this.message_list.in_selection(uid) ? ' selected' : '');
+
+    // for performance use DOM instead of jQuery here
+    var row = document.createElement('tr');
+    row.id = 'rcmrow'+uid;
+    row.className = css_class;
+    
+    var icon = this.env.messageicon;
+    if (flags.deleted && this.env.deletedicon)
+      icon = this.env.deletedicon;
+    else if (flags.replied && this.env.repliedicon)
+      {
+      if (flags.forwarded && this.env.forwardedrepliedicon)
+        icon = this.env.forwardedrepliedicon;
+      else
+        icon = this.env.repliedicon;
+      }
+    else if (flags.forwarded && this.env.forwardedicon)
+      icon = this.env.forwardedicon;
+    else if(flags.unread && this.env.unreadicon)
+      icon = this.env.unreadicon;
+    
+    // add icon col
+    var col = document.createElement('td');
+    col.className = 'icon';
+    col.innerHTML = icon ? '<img src="'+icon+'" alt="" />' : '';
+    row.appendChild(col);
+                 
+    // add each submitted col
+    for (var n = 0; n < this.coltypes.length; n++) {
+      var c = this.coltypes[n];
+      col = document.createElement('td');
+      col.className = String(c).toLowerCase();
+            
+      if (c=='flag') {
+        if (flags.flagged && this.env.flaggedicon)
+          col.innerHTML = '<img src="'+this.env.flaggedicon+'" alt="" />';
+        else if(!flags.flagged && this.env.unflaggedicon)
+          col.innerHTML = '<img src="'+this.env.unflaggedicon+'" alt="" />';
+        }
+      else if (c=='attachment')
+        col.innerHTML = (attachment && this.env.attachmenticon ? '<img src="'+this.env.attachmenticon+'" alt="" />' : '&nbsp;');
+      else
+        col.innerHTML = cols[c];
+
+      row.appendChild(col);
+      }
+
+    this.message_list.insert_row(row, attop);
+
+    // remove 'old' row
+    if (attop && this.env.pagesize && this.message_list.rowcount > this.env.pagesize) {
+      var uid = this.message_list.get_last_row();
+      this.message_list.remove_row(uid);
+      this.message_list.clear_selection(uid);
+      }
+    };
+
+  // messages list handling in background (for performance)
+  this.offline_message_list = function(flag)
+    {
+      if (this.message_list)
+       this.message_list.set_background_mode(flag);
+    };
+
+  // replace content of row count display
+  this.set_rowcount = function(text)
+    {
+    $(this.gui_objects.countdisplay).html(text);
+
+    // update page navigation buttons
+    this.set_page_buttons();
+    };
+
+  // replace content of mailboxname display
+  this.set_mailboxname = function(content)
+    {
+    if (this.gui_objects.mailboxname && content)
+      this.gui_objects.mailboxname.innerHTML = content;
+    };
+
+  // replace content of quota display
+  this.set_quota = function(content)
+    {
+    if (content && this.gui_objects.quotadisplay)
+      $(this.gui_objects.quotadisplay).html(content);
+    };
+
+  // update the mailboxlist
+  this.set_unread_count = function(mbox, count, set_title)
+    {
+    if (!this.gui_objects.mailboxlist)
+      return false;
+
+    this.env.unread_counts[mbox] = count;
+    this.set_unread_count_display(mbox, set_title);
+    }
+
+  // update the mailbox count display
+  this.set_unread_count_display = function(mbox, set_title)
+    {
+    var reg, text_obj, item, mycount, childcount, div;
+    if (item = this.get_folder_li(mbox))
+      {
+      mycount = this.env.unread_counts[mbox] ? this.env.unread_counts[mbox] : 0;
+      text_obj = item.getElementsByTagName('a')[0];
+      reg = /\s+\([0-9]+\)$/i;
+
+      childcount = 0;
+      if ((div = item.getElementsByTagName('div')[0]) &&
+          div.className.match(/collapsed/))
+        {
+        // add children's counters
+        for (var k in this.env.unread_counts) 
+          if (k.indexOf(mbox + this.env.delimiter) == 0)
+            childcount += this.env.unread_counts[k];
+        }
+
+      if (mycount && text_obj.innerHTML.match(reg))
+        text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+mycount+')');
+      else if (mycount)
+        text_obj.innerHTML += ' ('+mycount+')';
+      else
+        text_obj.innerHTML = text_obj.innerHTML.replace(reg, '');
+
+      // set parent's display
+      reg = new RegExp(RegExp.escape(this.env.delimiter) + '[^' + RegExp.escape(this.env.delimiter) + ']+$');
+      if (mbox.match(reg))
+        this.set_unread_count_display(mbox.replace(reg, ''), false);
+
+      // set the right classes
+      if ((mycount+childcount)>0)
+        $(item).addClass('unread');
+      else
+        $(item).removeClass('unread');
+      }
+
+    // set unread count to window title
+    reg = /^\([0-9]+\)\s+/i;
+    if (set_title && document.title)
+      {
+      var doc_title = String(document.title);
+      var new_title = "";
+
+      if (mycount && doc_title.match(reg))
+        new_title = doc_title.replace(reg, '('+mycount+') ');
+      else if (mycount)
+        new_title = '('+mycount+') '+doc_title;
+      else
+        new_title = doc_title.replace(reg, '');
+        
+      this.set_pagetitle(new_title);
+      }
+    };
+
+  // notifies that a new message(s) has hit the mailbox
+  this.new_message_focus = function()
+    {
+    // focus main window
+    if (this.env.framed && window.parent)
+      window.parent.focus();
+    else
+      window.focus();
+    }
+
+  this.toggle_prefer_html = function(checkbox)
+    {
+    var addrbook_show_images;
+    if (addrbook_show_images = document.getElementById('rcmfd_addrbook_show_images'))
+      addrbook_show_images.disabled = !checkbox.checked;
+    }
+
+  // display fetched raw headers
+  this.set_headers = function(content)
+  {
+    if (this.gui_objects.all_headers_row && this.gui_objects.all_headers_box && content) {
+      $(this.gui_objects.all_headers_box).html(content).show();
+
+      if (this.env.framed && parent.rcmail)
+        parent.rcmail.set_busy(false);
+      else
+        this.set_busy(false);
+    }
+  };
+
+  // display all-headers row and fetch raw message headers
+  this.load_headers = function(elem)
+    {
+    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid)
+      return;
+    
+    $(elem).removeClass('show-headers').addClass('hide-headers');
+    $(this.gui_objects.all_headers_row).show();
+    elem.onclick = function() { rcmail.hide_headers(elem); }
+
+    // fetch headers only once
+    if (!this.gui_objects.all_headers_box.innerHTML)
+      {
+      this.display_message(this.get_label('loading'), 'loading', true);
+      this.http_post('headers', '_uid='+this.env.uid);
+      }
+    }
+
+  // hide all-headers row
+  this.hide_headers = function(elem)
+    {
+    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box)
+      return;
+
+    $(elem).removeClass('hide-headers').addClass('show-headers');
+    $(this.gui_objects.all_headers_row).hide();
+    elem.onclick = function() { rcmail.load_headers(elem); }
+    }
+
+
+  /********************************************************/
+  /*********  html to text conversion functions   *********/
+  /********************************************************/
+
+  this.html2plain = function(htmlText, id)
+    {
+    var url = this.env.bin_path+'html2text.php';
+    var rcmail = this;
+
+    this.set_busy(true, 'converting');
+    console.log('HTTP POST: '+url);
+
+    $.ajax({ type: 'POST', url: url, data: htmlText, contentType: 'application/octet-stream',
+      error: function(o) { rcmail.http_error(o); },
+      success: function(data) { rcmail.set_busy(false); $(document.getElementById(id)).val(data); console.log(data); }
+      });
+    }
+
+  this.plain2html = function(plainText, id)
+    {
+    this.set_busy(true, 'converting');
+    $(document.getElementById(id)).val('<pre>'+plainText+'</pre>');
+    this.set_busy(false);
+    }
+
+
+  /********************************************************/
+  /*********        remote request methods        *********/
+  /********************************************************/
+
+  this.redirect = function(url, lock)
+    {
+    if (lock || lock === null)
+      this.set_busy(true);
+
+    if (this.env.framed && window.parent)
+      parent.location.href = url;
+    else  
+      location.href = url;
+    };
+
+  this.goto_url = function(action, query, lock)
+    {
+    var querystring = query ? '&'+query : '';
+    this.redirect(this.env.comm_path+'&_action='+action+querystring, lock);
+    };
+
+  // send a http request to the server
+  this.http_request = function(action, querystring, lock)
+  {
+    querystring += (querystring ? '&' : '') + '_remote=1';
+    var url = this.env.comm_path + '&_action=' + action + '&' + querystring
+    
+    // send request
+    console.log('HTTP POST: ' + url);
+    jQuery.get(url, { _unlock:(lock?1:0) }, function(data){ ref.http_response(data); }, 'json');
+  };
+
+  // send a http POST request to the server
+  this.http_post = function(action, postdata, lock)
+  {
+    var url = this.env.comm_path+'&_action=' + action;
+    
+    if (postdata && typeof(postdata) == 'object') {
+      postdata._remote = 1;
+      postdata._unlock = (lock ? 1 : 0);
+    }
+    else
+      postdata += (postdata ? '&' : '') + '_remote=1' + (lock ? '&_unlock=1' : '');
+
+    // send request
+    console.log('HTTP POST: ' + url);
+    jQuery.post(url, postdata, function(data){ ref.http_response(data); }, 'json');
+  };
+
+  // handle HTTP response
+  this.http_response = function(response)
+  {
+    var console_msg = '';
+    
+    if (response.unlock)
+      this.set_busy(false);
+
+    // set env vars
+    if (response.env)
+      this.set_env(response.env);
+
+    // we have labels to add
+    if (typeof response.texts == 'object') {
+      for (var name in response.texts)
+        if (typeof response.texts[name] == 'string')
+          this.add_label(name, response.texts[name]);
+    }
+
+    // if we get javascript code from server -> execute it
+    if (response.exec) {
+      console.log(response.exec);
+      eval(response.exec);
+    }
+    
+    // execute callback functions of plugins
+    if (response.callbacks && response.callbacks.length) {
+      for (var i=0; i < response.callbacks.length; i++)
+        this.triggerEvent(response.callbacks[i][0], response.callbacks[i][1]);
+    }
+    // process the response data according to the sent action
+    switch (response.action) {
+      case 'delete':
+        if (this.task == 'addressbook') {
+          var uid = this.contact_list.get_selection();
+          this.enable_command('compose', (uid && this.contact_list.rows[uid]));
+          this.enable_command('delete', 'edit', (uid && this.contact_list.rows[uid] && 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') {
+         // re-enable commands on move/delete error
+         this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', 'open', 'edit', 'viewsource', 'download', true);
+        } else if (this.message_list)
+          this.message_list.init();
+        break;
+        
+      case 'purge':
+      case 'expunge':
+        if (!this.env.messagecount && this.task == 'mail') {
+          // clear preview pane content
+          if (this.env.contentframe)
+            this.show_contentframe(false);
+          // disable commands useless when mailbox is empty
+          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 
+           'mark', 'viewsource', 'open', 'edit', 'download', 'print', 'load-attachment', 
+           'purge', 'expunge', 'select-all', 'select-none', 'sort', false);
+        }
+        break;
+
+      case 'check-recent':
+      case 'getunread':
+      case 'list':
+        if (this.task == 'mail') {
+          if (this.message_list && response.action == 'list')
+            this.msglist_select(this.message_list);
+          this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0));
+          this.enable_command('purge', this.purge_mailbox_test());
+          
+          if (response.action == '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 (response.action == 'list')
+            this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
+        }
+        break;
+    }
+  };
+
+  // handle HTTP request errors
+  this.http_error = function(request, status, err)
+    {
+    var errmsg = request.statusText;
+
+    this.set_busy(false);
+    request.abort();
+    
+    if (errmsg)
+      this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', 'error');
+    };
+
+  // use an image to send a keep-alive siganl to the server
+  this.send_keep_alive = function()
+    {
+    var d = new Date();
+    this.http_request('keep-alive', '_t='+d.getTime());
+    };
+
+  // send periodic request to check for recent messages
+  this.check_for_recent = function(setbusy)
+    {
+    if (this.busy)
+      return;
+
+    if (setbusy)
+      this.set_busy(true, 'checkingmail');
+
+    var addurl = '_t=' + (new Date().getTime());
+
+    if (this.gui_objects.messagelist)
+      addurl += '&_list=1';
+    if (this.gui_objects.quotadisplay)
+      addurl += '&_quota=1';
+    if (this.env.search_request)
+      addurl += '&_search=' + this.env.search_request;
+
+    this.http_request('check-recent', addurl, true);
+    };
+
+
+  /********************************************************/
+  /*********            helper methods            *********/
+  /********************************************************/
+  
+  // check if we're in show mode or if we have a unique selection
+  // and return the message uid
+  this.get_single_uid = function()
+    {
+    return this.env.uid ? this.env.uid : (this.message_list ? this.message_list.get_single_selection() : null);
+    };
+
+  // same as above but for contacts
+  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(obj)
+    {
+    if (typeof(obj.selectionEnd)!='undefined')
+      return obj.selectionEnd;
+    else if (document.selection && document.selection.createRange)
+      {
+      var range = document.selection.createRange();
+      if (range.parentElement()!=obj)
+        return 0;
+
+      var gm = range.duplicate();
+      if (obj.tagName=='TEXTAREA')
+        gm.moveToElementText(obj);
+      else
+        gm.expand('textedit');
+      
+      gm.setEndPoint('EndToStart', range);
+      var p = gm.text.length;
+
+      return p<=obj.value.length ? p : -1;
+      }
+    else
+      return obj.value.length;
+    };
+
+  this.set_caret_pos = function(obj, pos)
+    {
+    if (obj.setSelectionRange)
+      obj.setSelectionRange(pos, pos);
+    else if (obj.createTextRange)
+      {
+      var range = obj.createTextRange();
+      range.collapse(true);
+      range.moveEnd('character', pos);
+      range.moveStart('character', pos);
+      range.select();
+      }
+    }
+
+  // set all fields of a form disabled
+  this.lock_form = function(form, lock)
+    {
+    if (!form || !form.elements)
+      return;
+    
+    var type;
+    for (var n=0; n<form.elements.length; n++)
+      {
+      type = form.elements[n];
+      if (type=='hidden')
+        continue;
+        
+      form.elements[n].disabled = lock;
+      }
+    };
+    
+}  // end object rcube_webmail
+
+
+// copy event engine prototype
+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;
 
diff --git a/program/js/app.js.src b/program/js/app.js.src
deleted file mode 100644 (file)
index fcffdbc..0000000
+++ /dev/null
@@ -1,4226 +0,0 @@
-/*
- +-----------------------------------------------------------------------+
- | RoundCube Webmail Client Script                                       |
- |                                                                       |
- | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2009, RoundCube Dev, - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
- |          Charles McNulty <charles@charlesmcnulty.com>                 |
- +-----------------------------------------------------------------------+
- | Requires: common.js, list.js                                          |
- +-----------------------------------------------------------------------+
-
-  $Id: app.js 2483 2009-05-15 10:22:29Z thomasb $
-*/
-
-
-var rcube_webmail_client;
-
-function rcube_webmail()
-  {
-  this.env = new Object();
-  this.labels = new Object();
-  this.buttons = new Object();
-  this.gui_objects = new Object();
-  this.commands = new Object();
-  this.onloads = new Array();
-
-  // create protected reference to myself
-  rcube_webmail_client = this;
-  this.ref = 'rcube_webmail_client';
-  var ref = this;
-  // webmail client settings
-  this.dblclick_time = 500;
-  this.message_time = 3000;
-  
-  this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi');
-  
-  // mimetypes supported by the browser (default settings)
-  this.mimetypes = new Array('text/plain', 'text/html', 'text/xml',
-                             'image/jpeg', 'image/gif', 'image/png',
-                             'application/x-javascript', 'application/pdf',
-                             'application/x-shockwave-flash');
-
-  // default environment vars
-  this.env.keep_alive = 60;        // seconds
-  this.env.request_timeout = 180;  // seconds
-  this.env.draft_autosave = 0;     // seconds
-  this.env.comm_path = './';
-  this.env.bin_path = './bin/';
-  this.env.blankpage = 'program/blank.gif';
-
-  // set environment variable(s)
-  this.set_env = function(p, value)
-    {
-    if (p != null && typeof(p) == 'object' && !value)
-      for (var n in p)
-        this.env[n] = p[n];
-    else
-      this.env[p] = value;
-    };
-
-  // add a localized label to the client environment
-  this.add_label = function(key, value)
-    {
-    this.labels[key] = value;
-    };
-
-  // add a button to the button list
-  this.register_button = function(command, id, type, act, sel, over)
-    {
-    if (!this.buttons[command])
-      this.buttons[command] = new Array();
-      
-    var button_prop = {id:id, type:type};
-    if (act) button_prop.act = act;
-    if (sel) button_prop.sel = sel;
-    if (over) button_prop.over = over;
-
-    this.buttons[command][this.buttons[command].length] = button_prop;    
-    };
-
-  // register a specific gui object
-  this.gui_object = function(name, id)
-    {
-    this.gui_objects[name] = id;
-    };
-  
-  // execute the given script on load
-  this.add_onload = function(f)
-    {
-      this.onloads[this.onloads.length] = f;
-    };
-
-  // initialize webmail client
-  this.init = function()
-    {
-    var p = this;
-    this.task = this.env.task;
-    
-    // check browser
-    if (!bw.dom || !bw.xmlhttp_test())
-      {
-      this.goto_url('error', '_code=0x199');
-      return;
-      }
-    
-    // find all registered gui objects
-    for (var n in this.gui_objects)
-      this.gui_objects[n] = rcube_find_object(this.gui_objects[n]);
-
-    // tell parent window that this frame is loaded
-    if (this.env.framed && parent.rcmail && parent.rcmail.set_busy)
-      parent.rcmail.set_busy(false);
-
-    // enable general commands
-    this.enable_command('logout', 'mail', 'addressbook', 'settings', true);
-    
-    if (this.env.permaurl)
-      this.enable_command('permaurl', true);
-    
-    switch (this.task)
-      {
-      case 'mail':
-        if (this.gui_objects.messagelist)
-          {
-          this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {multiselect:true, draggable:true, keyboard:true, dblclick_time:this.dblclick_time});
-          this.message_list.row_init = function(o){ p.init_message_row(o); };
-          this.message_list.addEventListener('dblclick', function(o){ p.msglist_dbl_click(o); });
-          this.message_list.addEventListener('keypress', function(o){ p.msglist_keypress(o); });
-          this.message_list.addEventListener('select', function(o){ p.msglist_select(o); });
-          this.message_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
-          this.message_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); });
-          this.message_list.addEventListener('dragend', function(o){ p.drag_active = false; });
-
-          this.message_list.init();
-          this.enable_command('toggle_status', 'toggle_flag', true);
-          
-          if (this.gui_objects.mailcontframe)
-            {
-            this.gui_objects.mailcontframe.onmousedown = function(e){ return p.click_on_list(e); };
-            document.onmouseup = function(e){ return p.doc_mouse_up(e); };
-            }
-          else
-            this.message_list.focus();
-          }
-          
-        if (this.env.coltypes)
-          this.set_message_coltypes(this.env.coltypes);
-
-        // enable mail commands
-        this.enable_command('list', 'checkmail', 'compose', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
-
-        if (this.env.search_text != null && document.getElementById('quicksearchbox') != null)
-          document.getElementById('quicksearchbox').value = this.env.search_text;
-        
-        if (this.env.action=='show' || this.env.action=='preview')
-          {
-          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource', 'print', 'load-attachment', 'load-headers', true);
-          if (this.env.next_uid)
-            {
-            this.enable_command('nextmessage', true);
-            this.enable_command('lastmessage', true);
-            }
-          if (this.env.prev_uid)
-            {
-            this.enable_command('previousmessage', true);
-            this.enable_command('firstmessage', true);
-            }
-          }
-
-        if (this.env.trash_mailbox && this.env.mailbox != this.env.trash_mailbox)
-          this.set_alttext('delete', 'movemessagetotrash');
-        
-        // make preview/message frame visible
-        if (this.env.action == 'preview' && this.env.framed && parent.rcmail)
-          {
-          this.enable_command('compose', 'add-contact', false);
-          parent.rcmail.show_contentframe(true);
-          }
-
-        if ((this.env.action=='show' || this.env.action=='preview') && 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=='compose')
-          {
-          this.enable_command('add-attachment', 'send-attachment', 'remove-attachment', 'send', true);
-          if (this.env.spellcheck)
-            {
-            this.env.spellcheck.spelling_state_observer = function(s){ ref.set_spellcheck_state(s); };
-            this.set_spellcheck_state('ready');
-            if (rcube_find_object('_is_html').value == '1')
-              this.display_spellcheck_controls(false);
-            }
-          if (this.env.drafts_mailbox)
-            this.enable_command('savedraft', true);
-            
-          document.onmouseup = function(e){ return p.doc_mouse_up(e); };
-          }
-
-        if (this.env.messagecount)
-          this.enable_command('select-all', 'select-none', 'expunge', true);
-
-        if (this.purge_mailbox_test())
-          this.enable_command('purge', true);
-
-        this.set_page_buttons();
-
-        // init message compose form
-        if (this.env.action=='compose')
-          this.init_messageform();
-
-        // show printing dialog
-        if (this.env.action=='print')
-          window.print();
-
-        // get unread count for each mailbox
-        if (this.gui_objects.mailboxlist)
-        {
-          this.env.unread_counts = {};
-          this.gui_objects.folderlist = this.gui_objects.mailboxlist;
-          this.http_request('getunread', '');
-        }
-        
-        // ask user to send MDN
-        if (this.env.mdn_request && this.env.uid)
-        {
-          var mdnurl = '_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox);
-          if (confirm(this.get_label('mdnrequest')))
-            this.http_post('sendmdn', mdnurl);
-          else
-            this.http_post('mark', mdnurl+'&_flag=mdnsent');
-        }
-
-        break;
-
-
-      case 'addressbook':
-        if (this.gui_objects.contactslist)
-          {
-          this.contact_list = new rcube_list_widget(this.gui_objects.contactslist, {multiselect:true, draggable:true, keyboard:true});
-          this.contact_list.addEventListener('keypress', function(o){ p.contactlist_keypress(o); });
-          this.contact_list.addEventListener('select', function(o){ p.contactlist_select(o); });
-          this.contact_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
-          this.contact_list.addEventListener('dragmove', function(o, e){ p.drag_move(e); });
-          this.contact_list.addEventListener('dragend', function(o){ p.drag_active = false; });
-          this.contact_list.init();
-
-          if (this.env.cid)
-            this.contact_list.highlight_row(this.env.cid);
-
-          if (this.gui_objects.contactslist.parentNode)
-            {
-            this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
-            document.onmouseup = function(e){ return p.doc_mouse_up(e); };
-            }
-          else
-            this.contact_list.focus();
-          }
-
-        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', true);
-        
-        if (this.env.cid)
-          this.enable_command('show', 'edit', true);
-
-        if ((this.env.action=='add' || this.env.action=='edit') && this.gui_objects.editform)
-          this.enable_command('save', true);
-        else
-          this.enable_command('search', 'reset-search', 'moveto', 'import', true);
-          
-        if (this.contact_list && this.contact_list.rowcount > 0)
-          this.enable_command('export', true);
-
-        this.enable_command('list', true);
-        break;
-
-
-      case 'settings':
-        this.enable_command('preferences', 'identities', 'save', 'folders', true);
-        
-        if (this.env.action=='identities' || this.env.action=='edit-identity' || this.env.action=='add-identity') {
-          this.enable_command('add', this.env.identities_level < 2);
-          this.enable_command('delete', 'edit', true);
-        }
-
-        if (this.env.action=='edit-identity' || this.env.action=='add-identity')
-          this.enable_command('save', true);
-          
-        if (this.env.action=='folders')
-          this.enable_command('subscribe', 'unsubscribe', 'create-folder', 'rename-folder', 'delete-folder', true);
-
-        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(o){ p.identity_select(o); });
-          this.identity_list.init();
-          this.identity_list.focus();
-
-          if (this.env.iid)
-            this.identity_list.highlight_row(this.env.iid);
-          }
-
-        if (this.gui_objects.subscriptionlist)
-          this.init_subscription_list();
-
-        break;
-
-      case 'login':
-        var input_user = rcube_find_object('rcmloginuser');
-        var input_pass = rcube_find_object('rcmloginpwd');
-        var input_tz = rcube_find_object('rcmlogintz');
-
-        if (input_user)
-          input_user.onkeyup = function(e){ return rcmail.login_user_keyup(e); };
-        if (input_user && input_user.value=='')
-          input_user.focus();
-        else if (input_pass)
-          input_pass.focus();
-
-        // detect client timezone
-        if (input_tz)
-          input_tz.value = new Date().getTimezoneOffset() / -60;
-
-        this.enable_command('login', true);
-        break;
-      
-      default:
-        break;
-      }
-
-    // enable basic commands
-    this.enable_command('logout', true);
-
-    // flag object as complete
-    this.loaded = true;
-
-    // show message
-    if (this.pending_message)
-      this.display_message(this.pending_message[0], this.pending_message[1]);
-
-    // start keep-alive interval
-    this.start_keepalive();
-    
-    // execute all foreign onload scripts
-    for (var i=0; i<this.onloads.length; i++)
-      {
-      if (typeof(this.onloads[i]) == 'string')
-        eval(this.onloads[i]);
-      else if (typeof(this.onloads[i]) == 'function')
-        this.onloads[i]();
-      }
-    };
-
-  // start interval for keep-alive/recent_check signal
-  this.start_keepalive = function()
-    {
-    if (this.env.keep_alive && !this.env.framed && this.task=='mail' && this.gui_objects.mailboxlist)
-      this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000);
-    else if (this.env.keep_alive && !this.env.framed && this.task!='login')
-      this._int = setInterval(function(){ ref.send_keep_alive(); }, this.env.keep_alive * 1000);
-    }
-
-  this.init_message_row = function(row)
-  {
-    var uid = row.uid;
-    if (uid && this.env.messages[uid])
-      {
-      row.deleted = this.env.messages[uid].deleted ? true : false;
-      row.unread = this.env.messages[uid].unread ? true : false;
-      row.replied = this.env.messages[uid].replied ? true : false;
-      row.flagged = this.env.messages[uid].flagged ? true : false;
-      row.forwarded = this.env.messages[uid].forwarded ? true : false;
-      }
-
-    // set eventhandler to message icon
-    if ((row.icon = row.obj.cells[0].childNodes[0]) && row.icon.nodeName=='IMG')
-      {
-      var p = this;
-      row.icon.id = 'msgicn_'+row.uid;
-      row.icon._row = row.obj;
-      row.icon.onmousedown = function(e) { p.command('toggle_status', this); };
-      }
-
-    // global variable 'flagged_col' may be not defined yet
-    if (!this.env.flagged_col && this.env.coltypes)
-      {
-      var found;
-      if((found = find_in_array('flag', this.env.coltypes)) >= 0)
-          this.set_env('flagged_col', found+1);
-      }
-
-    // set eventhandler to flag icon, if icon found
-    if (this.env.flagged_col && (row.flagged_icon = row.obj.cells[this.env.flagged_col].childNodes[0]) 
-       && row.flagged_icon.nodeName=='IMG')
-      {
-      var p = this;
-      row.flagged_icon.id = 'flaggedicn_'+row.uid;
-      row.flagged_icon._row = row.obj;
-      row.flagged_icon.onmousedown = function(e) { p.command('toggle_flag', this); };
-      }
-  };
-
-  // init message compose form: set focus and eventhandlers
-  this.init_messageform = function()
-    {
-    if (!this.gui_objects.messageform)
-      return false;
-    
-    //this.messageform = this.gui_objects.messageform;
-    var input_from = rcube_find_object('_from');
-    var input_to = rcube_find_object('_to');
-    var input_cc = rcube_find_object('_cc');
-    var input_bcc = rcube_find_object('_bcc');
-    var input_replyto = rcube_find_object('_replyto');
-    var input_subject = rcube_find_object('_subject');
-    var input_message = rcube_find_object('_message');
-    var draftid = rcube_find_object('_draft_saveid');
-
-    // init live search events
-    if (input_to)
-      this.init_address_input_events(input_to);
-    if (input_cc)
-      this.init_address_input_events(input_cc);
-    if (input_bcc)
-      this.init_address_input_events(input_bcc);
-
-    // add signature according to selected identity
-    if (input_from && input_from.type=='select-one' && (!draftid || draftid.value=='')
-       // if we have HTML editor, signature is added in callback
-       && rcube_find_object('_is_html').value != '1')
-      {
-      this.change_identity(input_from);
-      }
-
-    if (input_to && input_to.value=='')
-      input_to.focus();
-    else if (input_subject && input_subject.value=='')
-      input_subject.focus();
-    else if (input_message)
-      this.set_caret2start(input_message);
-
-    // get summary of all field values
-    this.compose_field_hash(true);
-    // start the auto-save timer
-    this.auto_save_start();
-    };
-
-  this.init_address_input_events = function(obj)
-    {
-    var handler = function(e){ return ref.ksearch_keypress(e,this); };
-    
-    if (obj.addEventListener)
-      obj.addEventListener(bw.safari ? 'keydown' : 'keypress', handler, false);
-    else
-      obj.onkeydown = handler;
-
-    obj.setAttribute('autocomplete', 'off');
-    };
-
-
-  /*********************************************************/
-  /*********       client command interface        *********/
-  /*********************************************************/
-
-  // execute a specific command on the web client
-  this.command = function(command, props, obj)
-    {
-    if (obj && obj.blur)
-      obj.blur();
-
-    if (this.busy)
-      return false;
-
-    // command not supported or allowed
-    if (!this.commands[command])
-      {
-      // pass command to parent window
-      if (this.env.framed && parent.rcmail && parent.rcmail.command)
-        parent.rcmail.command(command, props);
-
-      return false;
-      }
-      
-   // check input before leaving compose step
-   if (this.task=='mail' && this.env.action=='compose' && (command=='list' || command=='mail' || command=='addressbook' || command=='settings'))
-     {
-     if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
-        return false;
-     }
-
-    // process command
-    switch (command)
-      {
-      case 'login':
-        if (this.gui_objects.loginform)
-          this.gui_objects.loginform.submit();
-        break;
-
-      case 'logout':
-        this.goto_url('logout', '', true);
-        break;      
-
-      // commands to switch task
-      case 'mail':
-      case 'addressbook':
-      case 'settings':
-        this.switch_task(command);
-        break;
-
-      case 'permaurl':
-        if (obj && obj.href && obj.target)
-          return true;
-        else if (this.env.permaurl)
-          parent.location.href = this.env.permaurl;
-          break;
-
-      // misc list commands
-      case 'list':
-        if (this.task=='mail')
-          {
-          if (this.env.search_request<0 || (props != '' && (this.env.search_request && props != this.env.mailbox)))
-            this.reset_qsearch();
-
-          this.list_mailbox(props);
-
-          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<0 || (this.env.search_request && props != this.env.source))
-            this.reset_qsearch();
-
-          this.list_contacts(props);
-          this.enable_command('add', (this.env.address_sources && !this.env.address_sources[props].readonly));
-          }
-        break;
-
-
-      case 'load-headers':
-        this.load_headers(obj);
-        break;
-
-
-      case 'sort':
-        // get the type of sorting
-        var a_sort = props.split('_');
-        var sort_col = a_sort[0];
-        var sort_order = a_sort[1] ? a_sort[1].toUpperCase() : null;
-        var header;
-
-        // no sort order specified: toggle
-        if (sort_order==null)
-          {
-          if (this.env.sort_col==sort_col)
-            sort_order = this.env.sort_order=='ASC' ? 'DESC' : 'ASC';
-          else
-            sort_order = this.env.sort_order;
-          }
-
-        if (this.env.sort_col==sort_col && this.env.sort_order==sort_order)
-          break;
-
-        // set table header class
-        if (header = document.getElementById('rcm'+this.env.sort_col))
-          this.set_classname(header, 'sorted'+(this.env.sort_order.toUpperCase()), false);
-        if (header = document.getElementById('rcm'+sort_col))
-          this.set_classname(header, 'sorted'+sort_order, true);
-
-        // save new sort properties
-        this.env.sort_col = sort_col;
-        this.env.sort_order = sort_order;
-
-        // reload message list
-        this.list_mailbox('', '', sort_col+'_'+sort_order);
-        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':
-        if (this.env.messagecount)
-          this.expunge_mailbox(this.env.mailbox);
-        break;
-
-      case 'purge':
-      case 'empty-mailbox':
-        if (this.env.messagecount)
-          this.purge_mailbox(this.env.mailbox);
-        break;
-
-
-      // common commands used in multiple tasks
-      case 'show':
-        if (this.task=='mail')
-          {
-          var uid = this.get_single_uid();
-          if (uid && (!this.env.uid || uid != this.env.uid))
-            {
-            if (this.env.mailbox == this.env.drafts_mailbox)
-              this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
-            else
-              this.show_message(uid);
-            }
-          }
-        else if (this.task=='addressbook')
-          {
-          var cid = props ? props : this.get_single_cid();
-          if (cid && !(this.env.action=='show' && cid==this.env.cid))
-            this.load_contact(cid, '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':
-        var cid;
-        if (this.task=='addressbook' && (cid = this.get_single_cid()))
-          this.load_contact(cid, 'edit');
-        else if (this.task=='settings' && props)
-          this.load_identity(props, 'edit-identity');
-        break;
-
-      case 'save-identity':
-      case 'save':
-        if (this.gui_objects.editform)
-          {
-          var input_pagesize = rcube_find_object('_pagesize');
-          var input_name  = rcube_find_object('_name');
-          var input_email = rcube_find_object('_email');
-
-          // user prefs
-          if (input_pagesize && isNaN(parseInt(input_pagesize.value)))
-            {
-            alert(this.get_label('nopagesizewarning'));
-            input_pagesize.focus();
-            break;
-            }
-          // contacts/identities
-          else
-            {
-            if (input_name && input_name.value == '')
-              {
-              alert(this.get_label('nonamewarning'));
-              input_name.focus();
-              break;
-              }
-            else if (input_email && !rcube_check_email(input_email.value))
-              {
-              alert(this.get_label('noemailwarning'));
-              input_email.focus();
-              break;
-              }
-            }
-
-          this.gui_objects.editform.submit();
-          }
-        break;
-
-      case 'delete':
-        // mail task
-        if (this.task=='mail')
-          this.delete_messages();
-        // addressbook task
-        else if (this.task=='addressbook')
-          this.delete_contacts();
-        // user settings task
-        else if (this.task=='settings')
-          this.delete_identity();
-        break;
-
-
-      // mail task commands
-      case 'move':
-      case 'moveto':
-        if (this.task == 'mail')
-          this.move_messages(props);
-        else if (this.task == 'addressbook' && this.drag_active)
-          this.copy_contact(null, props);
-        break;
-
-      case 'mark':
-        if (props)
-          this.mark_message(props);
-        break;
-      
-      case 'toggle_status':
-        if (props && !props._row)
-          break;
-        
-        var uid;
-        var flag = 'read';
-        
-        if (props._row.uid)
-          {
-          uid = props._row.uid;
-          
-          // toggle read/unread
-          if (this.message_list.rows[uid].deleted) {
-            flag = 'undelete';
-          } else if (!this.message_list.rows[uid].unread)
-            flag = 'unread';
-          }
-          
-        this.mark_message(flag, uid);
-        break;
-        
-      case 'toggle_flag':
-        if (props && !props._row)
-          break;
-
-        var uid;
-        var flag = 'flagged';
-
-        if (props._row.uid)
-          {
-          uid = props._row.uid;
-          // toggle flagged/unflagged
-          if (this.message_list.rows[uid].flagged)
-            flag = 'unflagged';
-          }
-        this.mark_message(flag, uid);
-        break;
-
-      case 'always-load':
-        if (this.env.uid && this.env.sender) {
-          this.add_contact(urlencode(this.env.sender));
-          window.setTimeout(function(){ ref.command('load-images'); }, 300);
-          break;
-        }
-        
-      case 'load-images':
-        if (this.env.uid)
-          this.show_message(this.env.uid, true, this.env.action=='preview');
-        break;
-
-      case 'load-attachment':
-        var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part;
-        
-        // open attachment in frame if it's of a supported mimetype
-        if (this.env.uid && props.mimetype && find_in_array(props.mimetype, this.mimetypes)>=0)
-          {
-          if (props.mimetype == 'text/html')
-            qstring += '&_safe=1';
-          this.attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment');
-          if (this.attachment_win)
-            {
-            window.setTimeout(function(){ ref.attachment_win.focus(); }, 10);
-            break;
-            }
-          }
-
-        this.goto_url('get', qstring+'&_download=1', false);
-        break;
-        
-      case 'select-all':
-        this.message_list.select_all(props);
-        break;
-
-      case 'select-none':
-        this.message_list.clear_selection();
-        break;
-
-      case 'nextmessage':
-        if (this.env.next_uid)
-          this.show_message(this.env.next_uid, false, this.env.action=='preview');
-        break;
-
-      case 'lastmessage':
-        if (this.env.last_uid)
-          this.show_message(this.env.last_uid);
-        break;
-
-      case 'previousmessage':
-        if (this.env.prev_uid)
-          this.show_message(this.env.prev_uid, false, this.env.action=='preview');
-        break;
-
-      case 'firstmessage':
-        if (this.env.first_uid)
-          this.show_message(this.env.first_uid);
-        break;
-      
-      case 'checkmail':
-        this.check_for_recent(true);
-        break;
-      
-      case 'compose':
-        var url = this.env.comm_path+'&_action=compose';
-       
-        if (this.task=='mail')
-        {
-          url += '&_mbox='+urlencode(this.env.mailbox);
-          
-          if (this.env.mailbox==this.env.drafts_mailbox)
-          {
-            var uid;
-            if (uid = this.get_single_uid())
-              url += '&_draft_uid='+uid;
-          }
-          else if (props)
-             url += '&_to='+urlencode(props);
-        }
-        // modify url if we're in addressbook
-        else if (this.task=='addressbook')
-          {
-          // switch to mail compose step directly
-          if (props && props.indexOf('@') > 0)
-            {
-            url = this.get_task_url('mail', url);
-            this.redirect(url + '&_to='+urlencode(props));
-            break;
-            }
-          
-          // use contact_id passed as command parameter
-          var a_cids = new Array();
-          if (props)
-            a_cids[a_cids.length] = props;
-          // get selected contacts
-          else if (this.contact_list)
-            {
-            var selection = this.contact_list.get_selection();
-            for (var n=0; n<selection.length; n++)
-              a_cids[a_cids.length] = selection[n];
-            }
-            
-          if (a_cids.length)
-            this.http_request('mailto', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source), true);
-
-          break;
-          }
-
-        // don't know if this is necessary...
-        url = url.replace(/&_framed=1/, "");
-
-        this.redirect(url);
-        break;
-        
-      case 'spellcheck':
-        if (window.tinyMCE && tinyMCE.get('compose-body')) {
-          tinyMCE.execCommand('mceSpellCheck', true);
-        }
-        else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) {
-          this.env.spellcheck.spellCheck(this.env.spellcheck.check_link);
-          this.set_spellcheck_state('checking');
-        }
-        break;
-
-      case 'savedraft':
-        // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
-
-        if (!this.gui_objects.messageform)
-          break;
-
-        // if saving Drafts is disabled in main.inc.php
-        // or if compose form did not change
-        if (!this.env.drafts_mailbox || this.cmp_hash == this.compose_field_hash())
-          break;
-
-        this.set_busy(true, 'savingmessage');
-        var form = this.gui_objects.messageform;
-        form.target = "savetarget";
-        form._draft.value = '1';
-        form.submit();
-        break;
-
-      case 'send':
-        if (!this.gui_objects.messageform)
-          break;
-
-        if (!this.check_compose_input())
-          break;
-
-        // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
-
-        // all checks passed, send message
-        this.set_busy(true, 'sendingmessage');
-        var form = this.gui_objects.messageform;
-        form.target = "savetarget";     
-        form._draft.value = '';
-        form.submit();
-        
-        // clear timeout (sending could take longer)
-        clearTimeout(this.request_timer);
-        break;
-
-      case 'add-attachment':
-        this.show_attachment_form(true);
-        
-      case 'send-attachment':
-        // Reset the auto-save timer
-        self.clearTimeout(this.save_timer);
-
-        this.upload_file(props)      
-        break;
-      
-      case 'remove-attachment':
-        this.remove_attachment(props);
-        break;
-
-      case 'reply-all':
-      case 'reply':
-        var uid;
-        if (uid = this.get_single_uid())
-          this.goto_url('compose', '_reply_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(command=='reply-all' ? '&_all=1' : ''), true);
-        break;      
-
-      case 'forward':
-        var uid;
-        if (uid = this.get_single_uid())
-          this.goto_url('compose', '_forward_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
-        break;
-        
-      case 'print':
-        var uid;
-        if (uid = this.get_single_uid())
-        {
-          ref.printwin = window.open(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : ''));
-          if (this.printwin)
-          {
-            window.setTimeout(function(){ ref.printwin.focus(); }, 20);
-            if (this.env.action != 'show')
-              this.mark_message('read', uid);
-          }
-        }
-        break;
-
-      case 'viewsource':
-        var uid;
-        if (uid = this.get_single_uid())
-          {
-          ref.sourcewin = window.open(this.env.comm_path+'&_action=viewsource&_uid='+this.env.uid+'&_mbox='+urlencode(this.env.mailbox));
-          if (this.sourcewin)
-            window.setTimeout(function(){ ref.sourcewin.focus(); }, 20);
-          }
-        break;
-
-      case 'add-contact':
-        this.add_contact(props);
-        break;
-      
-      // quicksearch
-      case 'search':
-        if (!props && this.gui_objects.qsearchbox)
-          props = this.gui_objects.qsearchbox.value;
-        if (props)
-        {
-          this.qsearch(props);
-          break;
-        }
-
-      // reset quicksearch
-      case 'reset-search':
-        var s = this.env.search_request;
-        this.reset_qsearch();
-        
-        if (s && this.env.mailbox)
-          this.list_mailbox(this.env.mailbox);
-        else if (s && this.task == 'addressbook')
-          this.list_contacts(this.env.source);
-        break;
-
-      case 'import':
-        if (this.env.action == 'import' && this.gui_objects.importform) {
-          var file = document.getElementById('rcmimportfile');
-          if (file && !file.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');
-        break;
-        
-      case 'export':
-        if (this.contact_list.rowcount > 0) {
-          var add_url = (this.env.source ? '_source='+urlencode(this.env.source)+'&' : '');
-          if (this.env.search_request)
-            add_url += '_search='+this.env.search_request;
-        
-          this.goto_url('export', add_url);
-        }
-        break;
-
-      // collapse/expand folder
-      case 'collapse-folder':
-        if (props)
-          this.collapse_folder(props);
-        break;
-
-      // user settings commands
-      case 'preferences':
-        this.goto_url('');
-        break;
-
-      case 'identities':
-        this.goto_url('identities');
-        break;
-          
-      case 'delete-identity':
-        this.delete_identity();
-        
-      case 'folders':
-        this.goto_url('folders');
-        break;
-
-      case 'subscribe':
-        this.subscribe_folder(props);
-        break;
-
-      case 'unsubscribe':
-        this.unsubscribe_folder(props);
-        break;
-        
-      case 'create-folder':
-        this.create_folder(props);
-        break;
-
-      case 'rename-folder':
-        this.rename_folder(props);
-        break;
-
-      case 'delete-folder':
-        this.delete_folder(props);
-        break;
-
-      }
-
-    return obj ? false : true;
-    };
-
-  // set command enabled or disabled
-  this.enable_command = function()
-    {
-    var args = arguments;
-    if(!args.length) return -1;
-
-    var command;
-    var enable = args[args.length-1];
-    
-    for(var n=0; n<args.length-1; n++)
-      {
-      command = args[n];
-      this.commands[command] = enable;
-      this.set_button(command, (enable ? 'act' : 'pas'));
-      }
-      return true;
-    };
-
-  // lock/unlock interface
-  this.set_busy = function(a, message)
-    {
-    if (a && message)
-      {
-      var msg = this.get_label(message);
-      if (msg==message)        
-        msg = 'Loading...';
-
-      this.display_message(msg, 'loading', true);
-      }
-    else if (!a)
-      this.hide_message();
-
-    this.busy = a;
-    //document.body.style.cursor = a ? 'wait' : 'default';
-    
-    if (this.gui_objects.editform)
-      this.lock_form(this.gui_objects.editform, a);
-      
-    // clear pending timer
-    if (this.request_timer)
-      clearTimeout(this.request_timer);
-
-    // set timer for requests
-    if (a && this.env.request_timeout)
-      this.request_timer = window.setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000);
-    };
-
-  // return a localized string
-  this.get_label = function(name)
-    {
-    if (this.labels[name])
-      return this.labels[name];
-    else
-      return name;
-    };
-
-  // switch to another application task
-  this.switch_task = function(task)
-    {
-    if (this.task===task && task!='mail')
-      return;
-
-    var url = this.get_task_url(task);
-    if (task=='mail')
-      url += '&_mbox=INBOX';
-
-    this.redirect(url);
-    };
-
-  this.get_task_url = function(task, url)
-    {
-    if (!url)
-      url = this.env.comm_path;
-
-    return url.replace(/_task=[a-z]+/, '_task='+task);
-    };
-    
-  // called when a request timed out
-  this.request_timed_out = function()
-    {
-    this.set_busy(false);
-    this.display_message('Request timed out!', 'error');
-    };
-
-
-  /*********************************************************/
-  /*********        event handling methods         *********/
-  /*********************************************************/
-
-  this.doc_mouse_up = function(e)
-  {
-    var model, li;
-
-    if (this.message_list) {
-      if (!rcube_mouse_is_over(e, this.message_list.list))
-        this.message_list.blur();
-      model = this.env.mailboxes;
-    }
-    else if (this.contact_list) {
-      if (!rcube_mouse_is_over(e, this.contact_list.list))
-        this.contact_list.blur();
-      model = this.env.address_sources;
-    }
-    else if (this.ksearch_value) {
-      this.ksearch_blur();
-    }
-
-    // handle mouse release when dragging
-    if (this.drag_active && model && this.env.last_folder_target) {
-      this.set_classname(this.get_folder_li(this.env.last_folder_target), 'droptarget', false);
-      this.command('moveto', model[this.env.last_folder_target].id);
-      this.env.last_folder_target = null;
-    }
-  };
-
-  this.drag_start = function(list)
-  {
-    this.initialBodyScrollTop = bw.ie ? 0 : window.pageYOffset;
-    this.initialMailBoxScrollTop = document.getElementById("mailboxlist-container").scrollTop;
-
-    var model = this.task == 'mail' ? this.env.mailboxes : this.env.address_sources;
-
-    this.drag_active = true;
-    if (this.preview_timer)
-      clearTimeout(this.preview_timer);
-    
-    // save folderlist and folders location/sizes for droptarget calculation in drag_move()
-    if (this.gui_objects.folderlist && model)
-      {
-      var li, pos, list, height;
-      list = rcube_find_object(this.task == 'mail' ? 'mailboxlist' : 'directorylist');
-      pos = rcube_get_object_pos(list);
-      this.env.folderlist_coords = {x1:pos.x, y1:pos.y, x2:pos.x + list.offsetWidth, y2:pos.y + list.offsetHeight};
-
-      this.env.folder_coords = new Array();
-      for (var k in model) {
-        if (li = this.get_folder_li(k))
-         {
-         pos = rcube_get_object_pos(li.firstChild);
-         // only visible folders
-         if (height = li.firstChild.offsetHeight)
-           this.env.folder_coords[k] = {x1:pos.x, y1:pos.y, x2:pos.x + li.firstChild.offsetWidth, y2:pos.y + height};
-          }
-        }
-      }
-  };
-
-  this.drag_move = function(e)
-    {
-    if (this.gui_objects.folderlist && this.env.folder_coords)
-      {
-      // offsets to compensate for scrolling while dragging a message
-      var boffset = bw.ie ? -document.documentElement.scrollTop : this.initialBodyScrollTop;
-      var moffset = this.initialMailBoxScrollTop-document.getElementById('mailboxlist-container').scrollTop;
-      var toffset = -moffset-boffset;
-
-      var li, pos, mouse;
-      mouse = rcube_event.get_mouse_pos(e);
-      pos = this.env.folderlist_coords;
-
-      mouse.y += toffset;
-
-      // if mouse pointer is outside of folderlist
-      if (mouse.x < pos.x1 || mouse.x >= pos.x2 
-           || mouse.y < pos.y1 || mouse.y >= pos.y2)
-       {
-       if (this.env.last_folder_target) {
-         this.set_classname(this.get_folder_li(this.env.last_folder_target), 'droptarget', false);
-          this.env.last_folder_target = null;
-         }
-       return;
-        }
-
-      // over the folders
-      for (var k in this.env.folder_coords)
-        {
-       pos = this.env.folder_coords[k];
-       if (this.check_droptarget(k) && ((mouse.x >= pos.x1) && (mouse.x < pos.x2) 
-           && (mouse.y >= pos.y1) && (mouse.y < pos.y2)))
-         {
-          this.set_classname(this.get_folder_li(k), 'droptarget', true);
-         this.env.last_folder_target = k;
-         }
-       else
-         this.set_classname(this.get_folder_li(k), 'droptarget', false);
-        }
-      }
-    };
-  
-  this.collapse_folder = function(id)
-    {
-    var div;
-    if ((li = this.get_folder_li(id)) &&
-        (div = li.getElementsByTagName("div")[0]) &&
-        (div.className.match(/collapsed/) || div.className.match(/expanded/)))
-      {
-      var ul = li.getElementsByTagName("ul")[0];
-      if (div.className.match(/collapsed/))
-        {
-        ul.style.display = '';
-        this.set_classname(div, 'collapsed', false);
-        this.set_classname(div, 'expanded', true);
-        var reg = new RegExp('&'+urlencode(id)+'&');
-        this.set_env('collapsed_folders', this.env.collapsed_folders.replace(reg, ''));
-        }
-      else
-        {
-        ul.style.display = 'none';
-        this.set_classname(div, 'expanded', false);
-        this.set_classname(div, 'collapsed', true);
-        this.set_env('collapsed_folders', this.env.collapsed_folders+'&'+urlencode(id)+'&');
-
-        // select parent folder if one of its childs is currently selected
-        if (this.env.mailbox.indexOf(id + this.env.delimiter) == 0)
-          this.command('list', id);
-        }
-
-      // Work around a bug in IE6 and IE7, see #1485309
-      if ((bw.ie6 || bw.ie7) &&
-          li.nextSibling &&
-          (li.nextSibling.getElementsByTagName("ul").length>0) &&
-          li.nextSibling.getElementsByTagName("ul")[0].style &&
-          (li.nextSibling.getElementsByTagName("ul")[0].style.display!='none'))
-        {
-          li.nextSibling.getElementsByTagName("ul")[0].style.display = 'none';
-          li.nextSibling.getElementsByTagName("ul")[0].style.display = '';
-        }
-
-      this.http_post('save-pref', '_name=collapsed_folders&_value='+urlencode(this.env.collapsed_folders));
-      this.set_unread_count_display(id, false);
-      }
-    }
-
-  this.click_on_list = function(e)
-    {
-    if (this.gui_objects.qsearchbox)
-      this.gui_objects.qsearchbox.blur();
-
-    if (this.message_list)
-      this.message_list.focus();
-    else if (this.contact_list)
-      this.contact_list.focus();
-
-    var mbox_li;
-    if (mbox_li = this.get_folder_li())
-      this.set_classname(mbox_li, 'unfocused', true);
-
-    return rcube_event.get_button(e) == 2 ? true : rcube_event.cancel(e);
-    };
-
-  this.msglist_select = function(list)
-    {
-    if (this.preview_timer)
-      clearTimeout(this.preview_timer);
-
-    var selected = list.selection.length==1;
-
-    // Hide certain command buttons when Drafts folder is selected
-    if (this.env.mailbox == this.env.drafts_mailbox)
-      {
-      this.enable_command('reply', 'reply-all', 'forward', false);
-      this.enable_command('show', 'print', selected);
-      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
-      }
-    else
-      {
-      this.enable_command('show', 'reply', 'reply-all', 'forward', 'print', selected);
-      this.enable_command('delete', 'moveto', 'mark', (list.selection.length > 0 ? true : false));
-      }
-
-    // start timer for message preview (wait for double click)
-    if (selected && this.env.contentframe && !list.multi_selecting)
-      this.preview_timer = window.setTimeout(function(){ ref.msglist_get_preview(); }, 200);
-    else if (this.env.contentframe)
-      this.show_contentframe(false);
-    };
-
-  this.msglist_dbl_click = function(list)
-    {
-      if (this.preview_timer)
-        clearTimeout(this.preview_timer);
-
-    var uid = list.get_single_selection();
-    if (uid && this.env.mailbox == this.env.drafts_mailbox)
-      this.goto_url('compose', '_draft_uid='+uid+'&_mbox='+urlencode(this.env.mailbox), true);
-    else if (uid)
-      this.show_message(uid, false, false);
-    };
-
-  this.msglist_keypress = function(list)
-    {
-    if (list.key_pressed == list.ENTER_KEY)
-      this.command('show');
-    else if (list.key_pressed == list.DELETE_KEY)
-      this.command('delete');
-    else if (list.key_pressed == list.BACKSPACE_KEY)
-      this.command('delete');
-    else
-      list.shiftkey = false;
-    };
-
-  this.msglist_get_preview = function()
-  {
-    var uid = this.get_single_uid();
-    if (uid && this.env.contentframe && !this.drag_active)
-      this.show_message(uid, false, true);
-    else if (this.env.contentframe)
-      this.show_contentframe(false);
-  };
-  
-  this.check_droptarget = function(id)
-  {
-    if (this.task == 'mail')
-      return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual);
-    else if (this.task == 'addressbook')
-      return (id != this.env.source && this.env.address_sources[id] && !this.env.address_sources[id].readonly);
-    else if (this.task == 'settings')
-      return (id != this.env.folder);
-  };
-
-
-  /*********************************************************/
-  /*********     (message) list functionality      *********/
-  /*********************************************************/
-
-  // when user doble-clicks on a row
-  this.show_message = function(id, safe, preview)
-    {
-    if (!id) return;
-    
-    var add_url = '';
-    var action = preview ? 'preview': 'show';
-    var target = window;
-    
-    if (preview && this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      target = window.frames[this.env.contentframe];
-      add_url = '&_framed=1';
-      }
-
-    if (safe)
-      add_url = '&_safe=1';
-
-    // also send search request to get the right messages
-    if (this.env.search_request)
-      add_url += '&_search='+this.env.search_request;
-    var url = '&_action='+action+'&_uid='+id+'&_mbox='+urlencode(this.env.mailbox)+add_url;
-    if (action == 'preview' && String(target.location.href).indexOf(url) >= 0)
-      this.show_contentframe(true);
-    else
-      {
-      this.set_busy(true, 'loading');
-      target.location.href = this.env.comm_path+url;
-
-      // mark as read and change mbox unread counter
-      if (action == 'preview' && this.message_list && this.message_list.rows[id] && this.message_list.rows[id].unread)
-        {
-        this.set_message(id, 'unread', false);
-       if (this.env.unread_counts[this.env.mailbox])
-         {
-         this.env.unread_counts[this.env.mailbox] -= 1;
-         this.set_unread_count(this.env.mailbox, this.env.unread_counts[this.env.mailbox], this.env.mailbox == 'INBOX');
-         }
-       }
-      }
-    };
-
-  this.show_contentframe = function(show)
-    {
-    var frm;
-    if (this.env.contentframe && (frm = rcube_find_object(this.env.contentframe)))
-      {
-      if (!show && window.frames[this.env.contentframe])
-        {
-        if (window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)<0)
-          window.frames[this.env.contentframe].location.href = this.env.blankpage;
-        }
-      else if (!bw.safari && !bw.konq)
-        frm.style.display = show ? 'block' : 'none';
-      }
-
-    if (!show && this.busy)
-      this.set_busy(false);
-    };
-
-  // list a specific page
-  this.list_page = function(page)
-    {
-    if (page=='next')
-      page = this.env.current_page+1;
-    if (page=='last')
-      page = this.env.pagecount;
-    if (page=='prev' && this.env.current_page>1)
-      page = this.env.current_page-1;
-    if (page=='first' && this.env.current_page>1)
-      page = 1;
-      
-    if (page > 0 && page <= this.env.pagecount)
-      {
-      this.env.current_page = page;
-      
-      if (this.task=='mail')
-        this.list_mailbox(this.env.mailbox, page);
-      else if (this.task=='addressbook')
-        this.list_contacts(this.env.source, page);
-      }
-    };
-
-  // list messages of a specific mailbox using filter
-  this.filter_mailbox = function(filter)
-    {
-      var search;
-      if (this.gui_objects.qsearchbox)
-        search = this.gui_objects.qsearchbox.value;
-      
-      this.message_list.clear();
-
-      // reset vars
-      this.env.current_page = 1;
-      this.set_busy(true, 'searching');
-      this.http_request('search', '_filter='+filter
-           + (search ? '&_q='+urlencode(search) : '')
-           + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : ''), true);
-    }
-
-
-  // list messages of a specific mailbox
-  this.list_mailbox = function(mbox, page, sort)
-    {
-    this.last_selected = 0;
-    var add_url = '';
-    var target = window;
-
-    if (!mbox)
-      mbox = this.env.mailbox;
-
-    // add sort to url if set
-    if (sort)
-      add_url += '&_sort=' + sort;
-
-    // also send search request to get the right messages
-    if (this.env.search_request)
-      add_url += '&_search='+this.env.search_request;
-      
-    // set page=1 if changeing to another mailbox
-    if (!page && mbox != this.env.mailbox)
-      {
-      page = 1;
-      this.env.current_page = page;
-      if (this.message_list)
-        this.message_list.clear_selection();
-      this.show_contentframe(false);
-      }
-    
-    if (mbox != this.env.mailbox || (mbox == this.env.mailbox && !page && !sort))
-      add_url += '&_refresh=1';
-    
-    this.select_folder(mbox, this.env.mailbox);
-    this.env.mailbox = mbox;
-
-    // load message list remotely
-    if (this.gui_objects.messagelist)
-      {
-      this.list_mailbox_remote(mbox, page, add_url);
-      return;
-      }
-    
-    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      target = window.frames[this.env.contentframe];
-      add_url += '&_framed=1';
-      }
-
-    // load message list to target frame/window
-    if (mbox)
-      {
-      this.set_busy(true, 'loading');
-      target.location.href = this.env.comm_path+'&_mbox='+urlencode(mbox)+(page ? '&_page='+page : '')+add_url;
-      }
-    };
-
-  // send remote request to load message list
-  this.list_mailbox_remote = function(mbox, page, add_url)
-    {
-    // clear message list first
-    this.message_list.clear();
-
-    // send request to server
-    var url = '_mbox='+urlencode(mbox)+(page ? '&_page='+page : '');
-    this.set_busy(true, 'loading');
-    this.http_request('list', url+add_url, true);
-    };
-
-  this.expunge_mailbox = function(mbox)
-    {
-    var lock = false;
-    var add_url = '';
-    
-    // lock interface if it's the active mailbox
-    if (mbox == this.env.mailbox)
-       {
-       lock = true;
-       this.set_busy(true, 'loading');
-       add_url = '&_reload=1';
-       }
-
-    // send request to server
-    var url = '_mbox='+urlencode(mbox);
-    this.http_post('expunge', url+add_url, lock);
-    };
-
-  this.purge_mailbox = function(mbox)
-    {
-    var lock = false;
-    var add_url = '';
-    
-    if (!confirm(this.get_label('purgefolderconfirm')))
-      return false;
-    
-    // lock interface if it's the active mailbox
-    if (mbox == this.env.mailbox)
-       {
-       lock = true;
-       this.set_busy(true, 'loading');
-       add_url = '&_reload=1';
-       }
-
-    // send request to server
-    var url = '_mbox='+urlencode(mbox);
-    this.http_post('purge', url+add_url, lock);
-    return true;
-    };
-
-  // test if purge command is allowed
-  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))));
-  };
-
-  // set message icon
-  this.set_message_icon = function(uid)
-  {
-    var icn_src;
-    var rows = this.message_list.rows;
-
-    if (!rows[uid])
-      return false;
-
-    if (rows[uid].deleted && this.env.deletedicon)
-      icn_src = this.env.deletedicon;
-    else if (rows[uid].replied && this.env.repliedicon)
-      {
-      if (rows[uid].forwarded && this.env.forwardedrepliedicon)
-        icn_src = this.env.forwardedrepliedicon;
-      else
-        icn_src = this.env.repliedicon;
-      }
-    else if (rows[uid].forwarded && this.env.forwardedicon)
-      icn_src = this.env.forwardedicon;
-    else if (rows[uid].unread && this.env.unreadicon)
-      icn_src = this.env.unreadicon;
-    else if (this.env.messageicon)
-      icn_src = this.env.messageicon;
-      
-    if (icn_src && rows[uid].icon)
-      rows[uid].icon.src = icn_src;
-
-    icn_src = '';
-    
-    if (rows[uid].flagged && this.env.flaggedicon)
-      icn_src = this.env.flaggedicon;
-    else if (!rows[uid].flagged && this.env.unflaggedicon)
-      icn_src = this.env.unflaggedicon;
-
-    if (rows[uid].flagged_icon && icn_src)
-      rows[uid].flagged_icon.src = icn_src;
-  }
-
-  // set message status
-  this.set_message_status = function(uid, flag, status)
-    {
-    var rows = this.message_list.rows;
-
-    if (!rows[uid]) return false;
-
-    if (flag == 'unread')
-      rows[uid].unread = status;
-    else if(flag == 'deleted')
-      rows[uid].deleted = status;
-    else if (flag == 'replied')
-      rows[uid].replied = status;
-    else if (flag == 'forwarded')
-      rows[uid].forwarded = status;
-    else if (flag == 'flagged')
-      rows[uid].flagged = status;
-
-    this.env.messages[uid] = rows[uid];
-    }
-
-  // set message row status, class and icon
-  this.set_message = function(uid, flag, status)
-    {
-    var rows = this.message_list.rows;
-
-    if (!rows[uid]) return false;
-    
-    if (flag)
-      this.set_message_status(uid, flag, status);
-    
-    if (rows[uid].unread && rows[uid].classname.indexOf('unread')<0)
-      {
-      rows[uid].classname += ' unread';
-      this.set_classname(rows[uid].obj, 'unread', true);
-      }
-    else if (!rows[uid].unread && rows[uid].classname.indexOf('unread')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*unread/, '');
-      this.set_classname(rows[uid].obj, 'unread', false);
-      }
-    
-    if (rows[uid].deleted && rows[uid].classname.indexOf('deleted')<0)
-      {
-      rows[uid].classname += ' deleted';
-      this.set_classname(rows[uid].obj, 'deleted', true);
-      }
-    else if (!rows[uid].deleted && rows[uid].classname.indexOf('deleted')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*deleted/, '');
-      this.set_classname(rows[uid].obj, 'deleted', false);
-      }
-
-    if (rows[uid].flagged && rows[uid].classname.indexOf('flagged')<0)
-      {
-      rows[uid].classname += ' flagged';
-      this.set_classname(rows[uid].obj, 'flagged', true);
-      }
-    else if (!rows[uid].flagged && rows[uid].classname.indexOf('flagged')>=0)
-      {
-      rows[uid].classname = rows[uid].classname.replace(/\s*flagged/, '');
-      this.set_classname(rows[uid].obj, 'flagged', false);
-      }
-
-    this.set_message_icon(uid);
-    }
-
-  // move selected messages to the specified mailbox
-  this.move_messages = function(mbox)
-    {
-    // exit if current or no mailbox specified or if selection is empty
-    if (!mbox || mbox == this.env.mailbox || (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length)))
-      return;
-
-    var lock = false;
-    var add_url = '&_target_mbox='+urlencode(mbox)+'&_from='+(this.env.action ? this.env.action : '');
-
-    // show wait message
-    if (this.env.action=='show')
-      {
-      lock = true;
-      this.set_busy(true, 'movingmessage');
-      }
-    else if (!this.env.flag_for_deletion)
-      this.show_contentframe(false);
-
-    // Hide message command buttons until a message is selected
-    this.enable_command('reply', 'reply-all', 'forward', 'delete', 'mark', 'print', false);
-
-    this._with_selected_messages('moveto', lock, add_url, (this.env.flag_for_deletion ? false : true));
-    };
-
-  // delete selected messages from the current mailbox
-  this.delete_messages = function()
-    {
-    var selection = this.message_list ? this.message_list.get_selection() : new Array();
-
-    // exit if no mailbox specified or if selection is empty
-    if (!this.env.uid && !selection.length)
-        return;
-
-    // if there is a trash mailbox defined and we're not currently in it:
-    if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() != String(this.env.trash_mailbox).toLowerCase())
-      {
-      // if shift was pressed delete it immediately
-      if (this.message_list && this.message_list.shiftkey)
-        {
-        if (confirm(this.get_label('deletemessagesconfirm')))
-          this.permanently_remove_messages();
-        }
-      else
-        this.move_messages(this.env.trash_mailbox);
-      }
-    // if there is a trash mailbox defined but we *are* in it:
-    else if (this.env.trash_mailbox && String(this.env.mailbox).toLowerCase() == String(this.env.trash_mailbox).toLowerCase())
-      this.permanently_remove_messages();
-    // if there isn't a defined trash mailbox and the config is set to flag for deletion
-    else if (!this.env.trash_mailbox && this.env.flag_for_deletion)
-      {
-      this.mark_message('delete');
-      if(this.env.action=="show")
-        this.command('nextmessage','',this);
-      else if (selection.length == 1)
-        this.message_list.select_next();
-      }
-    // if there isn't a defined trash mailbox and the config is set NOT to flag for deletion
-    else if (!this.env.trash_mailbox) 
-      this.permanently_remove_messages();
-  };
-
-  // delete the selected messages permanently
-  this.permanently_remove_messages = function()
-    {
-    // exit if no mailbox specified or if selection is empty
-    if (!this.env.uid && (!this.message_list || !this.message_list.get_selection().length))
-      return;
-      
-    this.show_contentframe(false);
-    this._with_selected_messages('delete', false, '&_from='+(this.env.action ? this.env.action : ''), true);
-    };
-
-  // Send a specifc request with UIDs of all selected messages
-  // @private
-  this._with_selected_messages = function(action, lock, add_url, remove)
-  {
-    var a_uids = new Array();
-
-    if (this.env.uid)
-      a_uids[0] = this.env.uid;
-    else
-    {
-      var selection = this.message_list.get_selection();
-      var rows = this.message_list.rows;
-      var id;
-      for (var n=0; n<selection.length; n++)
-        {
-        id = selection[n];
-        a_uids[a_uids.length] = id;
-
-        if (remove)
-          this.message_list.remove_row(id, (n == selection.length-1));
-        else
-        {
-          this.set_message_status(id, 'deleted', true);
-          if (this.env.read_when_deleted)
-           this.set_message_status(id, 'unread', false);
-         this.set_message(id);
-        }
-      }
-    }
-
-    // also send search request to get the right messages 
-    if (this.env.search_request) 
-      add_url += '&_search='+this.env.search_request;
-
-    // send request to server
-    this.http_post(action, '_uid='+a_uids.join(',')+'&_mbox='+urlencode(this.env.mailbox)+add_url, lock);
-  };
-
-  // set a specific flag to one or more messages
-  this.mark_message = function(flag, uid)
-    {
-    var a_uids = new Array();
-    var r_uids = new Array();
-    var selection = this.message_list ? this.message_list.get_selection() : new Array();
-
-    if (uid)
-      a_uids[0] = uid;
-    else if (this.env.uid)
-      a_uids[0] = this.env.uid;
-    else if (this.message_list)
-      {
-      for (var n=0; n<selection.length; n++)
-        {
-          a_uids[a_uids.length] = selection[n];
-        }
-      }
-
-    if (!this.message_list)
-      r_uids = a_uids;
-    else
-      for (var id, n=0; n<a_uids.length; n++)
-      {
-        id = a_uids[n];
-        if ((flag=='read' && this.message_list.rows[id].unread) 
-            || (flag=='unread' && !this.message_list.rows[id].unread)
-            || (flag=='delete' && !this.message_list.rows[id].deleted)
-            || (flag=='undelete' && this.message_list.rows[id].deleted)
-            || (flag=='flagged' && !this.message_list.rows[id].flagged)
-            || (flag=='unflagged' && this.message_list.rows[id].flagged))
-        {
-          r_uids[r_uids.length] = id;
-        }
-      }
-
-    // nothing to do
-    if (!r_uids.length)
-      return;
-
-    switch (flag)
-      {
-        case 'read':
-        case 'unread':
-          this.toggle_read_status(flag, r_uids);
-          break;
-        case 'delete':
-        case 'undelete':
-          this.toggle_delete_status(r_uids);
-          break;
-        case 'flagged':
-        case 'unflagged':
-          this.toggle_flagged_status(flag, a_uids);
-          break;
-      }
-    };
-
-  // set class to read/unread
-  this.toggle_read_status = function(flag, a_uids)
-  {
-    // mark all message rows as read/unread
-    for (var i=0; i<a_uids.length; i++)
-      this.set_message(a_uids[i], 'unread', (flag=='unread' ? true : false));
-
-    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
-  };
-
-  // set image to flagged or unflagged
-  this.toggle_flagged_status = function(flag, a_uids)
-  {
-    // mark all message rows as flagged/unflagged
-    for (var i=0; i<a_uids.length; i++)
-      this.set_message(a_uids[i], 'flagged', (flag=='flagged' ? true : false));
-
-    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag='+flag);
-  };
-  
-  // mark all message rows as deleted/undeleted
-  this.toggle_delete_status = function(a_uids)
-  {
-    var rows = this.message_list ? this.message_list.rows : new Array();
-    
-    if (a_uids.length==1)
-    {
-      if (!rows.length || (rows[a_uids[0]] && !rows[a_uids[0]].deleted))
-        this.flag_as_deleted(a_uids);
-      else
-        this.flag_as_undeleted(a_uids);
-
-      return true;
-    }
-    
-    var all_deleted = true;
-    for (var i=0; i<a_uids.length; i++)
-    {
-      uid = a_uids[i];
-      if (rows[uid]) {
-        if (!rows[uid].deleted)
-        {
-          all_deleted = false;
-          break;
-        }
-      }
-    }
-    
-    if (all_deleted)
-      this.flag_as_undeleted(a_uids);
-    else
-      this.flag_as_deleted(a_uids);
-    
-    return true;
-  };
-
-  this.flag_as_undeleted = function(a_uids)
-  {
-    for (var i=0; i<a_uids.length; i++)
-      this.set_message(a_uids[i], 'deleted', false);
-
-    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=undelete');
-    return true;
-  };
-
-  this.flag_as_deleted = function(a_uids)
-  {
-    var add_url = '';
-    var r_uids = new Array();
-    var rows = this.message_list ? this.message_list.rows : new Array();
-    
-    for (var i=0; i<a_uids.length; i++)
-      {
-      uid = a_uids[i];
-      if (rows[uid])
-        {
-       this.set_message(uid, 'deleted', true);
-        if (rows[uid].unread)
-          r_uids[r_uids.length] = uid;
-        }
-      }
-
-    if (r_uids.length)
-      add_url = '&_ruid='+r_uids.join(',');
-
-    this.http_post('mark', '_uid='+a_uids.join(',')+'&_flag=delete'+add_url);
-    return true;  
-  };
-
-  // flag as read without mark request (called from backend)
-  // argument should be a coma-separated list of uids
-  this.flag_deleted_as_read = function(uids)
-  {
-    var icn_src;
-    var rows = this.message_list ? this.message_list.rows : new Array();
-    var str = String(uids);
-    var a_uids = new Array();
-
-    a_uids = str.split(',');
-
-    for (var uid, i=0; i<a_uids.length; i++)
-      {
-      uid = a_uids[i];
-      if (rows[uid])
-        this.set_message(uid, 'unread', false);
-      }
-  };
-  
-  
-  /*********************************************************/
-  /*********           login form methods          *********/
-  /*********************************************************/
-
-  // handler for keyboard events on the _user field
-  this.login_user_keyup = function(e)
-  {
-    var key = rcube_event.get_keycode(e);
-    var elm;
-
-    // enter
-    if ((key==13) && (elm = rcube_find_object('_pass')))
-    {
-      elm.focus();
-      return false;
-    }
-  };
-
-
-  /*********************************************************/
-  /*********        message compose methods        *********/
-  /*********************************************************/
-  
-  // checks the input fields before sending a message
-  this.check_compose_input = function()
-    {
-    // check input fields
-    var input_to = rcube_find_object('_to');
-    var input_cc = rcube_find_object('_cc');
-    var input_bcc = rcube_find_object('_bcc');
-    var input_from = rcube_find_object('_from');
-    var input_subject = rcube_find_object('_subject');
-    var input_message = rcube_find_object('_message');
-
-    // check sender (if have no identities)
-    if (input_from.type == 'text' && !rcube_check_email(input_from.value, true))
-      {
-      alert(this.get_label('nosenderwarning'));
-      input_from.focus();
-      return false;
-      }
-
-    // check for empty recipient
-    var recipients = input_to.value ? input_to.value : (input_cc.value ? input_cc.value : input_bcc.value);
-    if (!rcube_check_email(recipients.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true))
-      {
-      alert(this.get_label('norecipientwarning'));
-      input_to.focus();
-      return false;
-      }
-
-    // display localized warning for missing subject
-    if (input_subject && input_subject.value == '')
-      {
-      var subject = prompt(this.get_label('nosubjectwarning'), this.get_label('nosubject'));
-
-      // user hit cancel, so don't send
-      if (!subject && subject !== '')
-        {
-        input_subject.focus();
-        return false;
-        }
-      else
-        {
-        input_subject.value = subject ? subject : this.get_label('nosubject');            
-        }
-      }
-
-    // check for empty body
-    if ((!window.tinyMCE || !tinyMCE.get('compose-body')) && input_message.value == '' && !confirm(this.get_label('nobodywarning')))
-      {
-      input_message.focus();
-      return false;
-      }
-    else if (window.tinyMCE && tinyMCE.get('compose-body') && !tinyMCE.get('compose-body').getContent() && !confirm(this.get_label('nobodywarning')))
-      {
-      tinyMCE.get('compose-body').focus();
-      return false;
-      }
-
-    // Apply spellcheck changes if spell checker is active
-    this.stop_spellchecking();
-
-    return true;
-    };
-
-  this.stop_spellchecking = function()
-    {
-    if (this.env.spellcheck && !this.spellcheck_ready) {
-      exec_event(this.env.spellcheck.check_link, 'click');
-      this.set_spellcheck_state('ready');
-      }
-    };
-
-  this.display_spellcheck_controls = function(vis)
-    {
-    if (this.env.spellcheck) {
-      // stop spellchecking process
-      if (!vis)
-       this.stop_spellchecking();
-                             
-      this.env.spellcheck.check_link.style.visibility = vis ? 'visible' : 'hidden';
-      this.env.spellcheck.switch_lan_pic.style.visibility = vis ? 'visible' : 'hidden';
-      }
-    };
-
-  this.set_spellcheck_state = function(s)
-    {
-    this.spellcheck_ready = (s=='check_spelling' || s=='ready');
-    this.enable_command('spellcheck', this.spellcheck_ready);
-    };
-
-  this.set_draft_id = function(id)
-    {
-    var f;
-    if (f = rcube_find_object('_draft_saveid'))
-      f.value = id;
-    };
-
-  this.auto_save_start = function()
-    {
-    if (this.env.draft_autosave)
-      this.save_timer = self.setTimeout(function(){ ref.command("savedraft"); }, this.env.draft_autosave * 1000);
-
-    // Unlock interface now that saving is complete
-    this.busy = false;
-    };
-
-  this.compose_field_hash = function(save)
-    {
-    // check input fields
-    var input_to = rcube_find_object('_to');
-    var input_cc = rcube_find_object('_cc');
-    var input_bcc = rcube_find_object('_bcc');
-    var input_subject = rcube_find_object('_subject');
-    var editor, input_message;
-    var str = '';
-    
-    if (input_to && input_to.value)
-      str += input_to.value+':';
-    if (input_cc && input_cc.value)
-      str += input_cc.value+':';
-    if (input_bcc && input_bcc.value)
-      str += input_bcc.value+':';
-    if (input_subject && input_subject.value)
-      str += input_subject.value+':';
-    
-    if (editor = tinyMCE.get('compose-body'))
-      str += editor.getContent();
-    else
-      {
-      input_message = rcube_find_object('_message');
-      str += input_message.value;
-      }
-    
-    if (save)
-      this.cmp_hash = str;
-    
-    return str;
-    };
-    
-  this.change_identity = function(obj)
-    {
-    if (!obj || !obj.options)
-      return false;
-
-    var id = obj.options[obj.selectedIndex].value;
-    var input_message = rcube_find_object('_message');
-    var message = input_message ? input_message.value : '';
-    var is_html = (rcube_find_object('_is_html').value == '1');
-    var sig, p;
-
-    if (!this.env.identity)
-      this.env.identity = id
-  
-    if (!is_html)
-      {
-      // remove the 'old' signature
-      if (this.env.identity && this.env.signatures && this.env.signatures[this.env.identity])
-        {
-        if (this.env.signatures[this.env.identity]['is_html'])
-          sig = this.env.signatures[this.env.identity]['plain_text'];
-        else
-         sig = this.env.signatures[this.env.identity]['text'];
-        
-       if (sig.indexOf('-- ')!=0)
-          sig = '-- \n'+sig;
-
-        p = message.lastIndexOf(sig);
-        if (p>=0)
-          message = message.substring(0, p-1) + message.substring(p+sig.length, message.length);
-        }
-
-      message = message.replace(/[\r\n]+$/, '');
-      
-      // add the new signature string
-      if (this.env.signatures && this.env.signatures[id])
-        {
-        sig = this.env.signatures[id]['text'];
-        if (this.env.signatures[id]['is_html'])
-          {
-          sig = this.env.signatures[id]['plain_text'];
-          }
-        if (sig.indexOf('-- ')!=0)
-          sig = '-- \n'+sig;
-        message += '\n\n'+sig;
-        }
-      }
-    else
-      {
-      var editor = tinyMCE.get('compose-body');
-
-      if (this.env.signatures)
-        {
-        // Append the signature as a div within the body
-        var sigElem = editor.dom.get('_rc_sig');
-       var newsig = '';
-       var htmlsig = true;
-
-        if (!sigElem)
-          {
-         // add empty line before signature on IE
-         if (bw.ie)
-            editor.getBody().appendChild(editor.getDoc().createElement('br'));
-
-         sigElem = editor.getDoc().createElement('div');
-          sigElem.setAttribute('id', '_rc_sig');
-          editor.getBody().appendChild(sigElem);
-          }
-
-       if (this.env.signatures[id])
-         {
-         newsig = this.env.signatures[id]['text'];
-         htmlsig = this.env.signatures[id]['is_html'];
-        
-         if (newsig) {
-           if (htmlsig && this.env.signatures[id]['plain_text'].indexOf('-- ')!=0)
-              newsig = '<p>-- </p>' + newsig;
-           else if (!htmlsig && newsig.indexOf('-- ')!=0)
-              newsig = '-- \n' + newsig;
-           }
-         }
-
-        if (htmlsig)
-          sigElem.innerHTML = newsig;
-        else
-          sigElem.innerHTML = '<pre>' + newsig + '</pre>';
-        }
-      }
-
-    if (input_message)
-      input_message.value = message;
-
-    this.env.identity = id;
-    return true;
-    };
-
-  this.show_attachment_form = function(a)
-    {
-    if (!this.gui_objects.uploadbox)
-      return false;
-      
-    var elm, list;
-    if (elm = this.gui_objects.uploadbox)
-      {
-      if (a &&  (list = this.gui_objects.attachmentlist))
-        {
-        var pos = rcube_get_object_pos(list);
-        var left = pos.x;
-        var top = pos.y + list.offsetHeight + 10;
-      
-        elm.style.top = top+'px';
-        elm.style.left = left+'px';
-        }
-      
-      elm.style.visibility = a ? 'visible' : 'hidden';
-      }
-      
-    // clear upload form
-       try {
-      if (!a && this.gui_objects.attachmentform != this.gui_objects.messageform)
-       this.gui_objects.attachmentform.reset();
-       }
-       catch(e){}  // ignore errors
-    
-    return true;  
-    };
-
-  // upload attachment file
-  this.upload_file = function(form)
-    {
-    if (!form)
-      return false;
-      
-    // get file input fields
-    var send = false;
-    for (var n=0; n<form.elements.length; n++)
-      if (form.elements[n].type=='file' && form.elements[n].value)
-        {
-        send = true;
-        break;
-        }
-    
-    // create hidden iframe and post upload form
-    if (send)
-      {
-      var ts = new Date().getTime();
-      var frame_name = 'rcmupload'+ts;
-
-      // have to do it this way for IE
-      // otherwise the form will be posted to a new window
-      if(document.all)
-        {
-        var html = '<iframe name="'+frame_name+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>';
-        document.body.insertAdjacentHTML('BeforeEnd',html);
-        }
-      else  // for standards-compilant browsers
-        {
-        var frame = document.createElement('IFRAME');
-        frame.name = frame_name;
-        frame.style.border = 'none';
-        frame.style.width = 0;
-        frame.style.height = 0;
-        frame.style.visibility = 'hidden';
-        document.body.appendChild(frame);
-        }
-
-      form.target = frame_name;
-      form.action = this.env.comm_path+'&_action=upload';
-      form.setAttribute('enctype', 'multipart/form-data');
-      form.submit();
-      }
-    
-    // set reference to the form object
-    this.gui_objects.attachmentform = form;
-    return true;
-    };
-
-  // add file name to attachment list
-  // called from upload page
-  this.add2attachment_list = function(name, content)
-    {
-    if (!this.gui_objects.attachmentlist)
-      return false;
-      
-    var li = document.createElement('LI');
-    li.id = name;
-    li.innerHTML = content;
-    this.gui_objects.attachmentlist.appendChild(li);
-    return true;
-    };
-
-  this.remove_from_attachment_list = function(name)
-    {
-    if (!this.gui_objects.attachmentlist)
-      return false;
-
-    var list = this.gui_objects.attachmentlist.getElementsByTagName("li");
-    for (i=0;i<list.length;i++)
-      if (list[i].id == name)
-        this.gui_objects.attachmentlist.removeChild(list[i]);
-    };
-
-  this.remove_attachment = function(name)
-    {
-    if (name)
-      this.http_post('remove-attachment', '_file='+urlencode(name));
-
-    return true;
-    };
-
-  // send remote request to add a new contact
-  this.add_contact = function(value)
-    {
-    if (value)
-      this.http_post('addcontact', '_address='+value);
-    
-    return true;
-    };
-
-  // send remote request to search mail or contacts
-  this.qsearch = function(value, addurl)
-    {
-    if (value != '')
-      {
-      if (this.message_list)
-        this.message_list.clear();
-      else if (this.contact_list) {
-        this.contact_list.clear(true);
-        this.show_contentframe(false);
-        }
-
-      if (this.gui_objects.search_filter)
-      addurl = '&_filter=' + this.gui_objects.search_filter.value;
-
-      // reset vars
-      this.env.current_page = 1;
-      this.set_busy(true, 'searching');
-      this.http_request('search', '_q='+urlencode(value)
-        + (this.env.mailbox ? '&_mbox='+urlencode(this.env.mailbox) : '')
-        + (this.env.source ? '&_source='+urlencode(this.env.source) : '')
-        + (addurl ? addurl : ''), true);
-      }
-    return true;
-    };
-
-  // reset quick-search form
-  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(type, msg)
-    {
-    this.list_mailbox();
-    this.display_message(msg, type, true);
-    }
-
-
-  /*********************************************************/
-  /*********     keyboard live-search methods      *********/
-  /*********************************************************/
-
-  // handler for keyboard events on address-fields
-  this.ksearch_keypress = function(e, obj)
-  {
-    if (this.ksearch_timer)
-      clearTimeout(this.ksearch_timer);
-
-    var highlight;
-    var key = rcube_event.get_keycode(e);
-    var mod = rcube_event.get_modifier(e);
-
-    switch (key)
-      {
-      case 38:  // key up
-      case 40:  // key down
-        if (!this.ksearch_pane)
-          break;
-          
-        var dir = key==38 ? 1 : 0;
-        
-        highlight = document.getElementById('rcmksearchSelected');
-        if (!highlight)
-          highlight = this.ksearch_pane.ul.firstChild;
-        
-        if (highlight)
-          this.ksearch_select(dir ? highlight.previousSibling : highlight.nextSibling);
-
-        return rcube_event.cancel(e);
-
-      case 9:  // tab
-        if(mod == SHIFT_KEY)
-          break;
-
-      case 13:  // enter
-        if (this.ksearch_selected===null || !this.ksearch_input || !this.ksearch_value)
-          break;
-
-        // insert selected address and hide ksearch pane
-        this.insert_recipient(this.ksearch_selected);
-        this.ksearch_hide();
-
-        return rcube_event.cancel(e);
-
-      case 27:  // escape
-        this.ksearch_hide();
-        break;
-      
-      case 37:  // left
-      case 39:  // right
-        if (mod != SHIFT_KEY)
-         return;
-      }
-
-    // start timer
-    this.ksearch_timer = window.setTimeout(function(){ ref.ksearch_get_results(); }, 200);
-    this.ksearch_input = obj;
-    
-    return true;
-  };
-  
-  this.ksearch_select = function(node)
-  {
-    var current = document.getElementById('rcmksearchSelected');
-    if (current && node) {
-      current.removeAttribute('id');
-      this.set_classname(current, 'selected', false);
-    }
-
-    if (node) {
-      node.setAttribute('id', 'rcmksearchSelected');
-      this.set_classname(node, 'selected', true);
-      this.ksearch_selected = node._rcm_id;
-    }
-  };
-
-  this.insert_recipient = function(id)
-  {
-    if (!this.env.contacts[id] || !this.ksearch_input)
-      return;
-    
-    // get cursor pos
-    var inp_value = this.ksearch_input.value.toLowerCase();
-    var cpos = this.get_caret_pos(this.ksearch_input);
-    var p = inp_value.lastIndexOf(this.ksearch_value, cpos);
-
-    // replace search string with full address
-    var pre = this.ksearch_input.value.substring(0, p);
-    var end = this.ksearch_input.value.substring(p+this.ksearch_value.length, this.ksearch_input.value.length);
-    var insert  = this.env.contacts[id]+', ';
-    this.ksearch_input.value = pre + insert + end;
-
-    // set caret to insert pos
-    cpos = p+insert.length;
-    if (this.ksearch_input.setSelectionRange)
-      this.ksearch_input.setSelectionRange(cpos, cpos);
-  };
-
-  // address search processor
-  this.ksearch_get_results = function()
-  {
-    var inp_value = this.ksearch_input ? this.ksearch_input.value : null;
-    if (inp_value === null)
-      return;
-      
-    if (this.ksearch_pane && this.ksearch_pane.visible)
-      this.ksearch_pane.show(0);
-
-    // get string from current cursor pos to last comma
-    var cpos = this.get_caret_pos(this.ksearch_input);
-    var p = inp_value.lastIndexOf(',', cpos-1);
-    var q = inp_value.substring(p+1, cpos);
-
-    // trim query string
-    q = q.replace(/(^\s+|\s+$)/g, '').toLowerCase();
-
-    // Don't (re-)search if string is empty or if the last results are still active
-    if (!q.length || q == this.ksearch_value)
-      return;
-
-    this.ksearch_value = q;
-    
-    this.display_message(this.get_label('searching'), 'loading', true);
-    this.http_post('autocomplete', '_search='+q);
-  };
-
-  this.ksearch_query_results = function(results, search)
-  {
-    // ignore this outdated search response
-    if (search != this.ksearch_value)
-      return;
-      
-    this.hide_message();
-    this.env.contacts = results ? results : [];
-    this.ksearch_display_results(this.env.contacts);
-  };
-
-  this.ksearch_display_results = function (a_results)
-  {
-    // display search results
-    if (a_results.length && this.ksearch_input) {
-      var p, ul, li;
-      
-      // create results pane if not present
-      if (!this.ksearch_pane) {
-        ul = document.createElement('UL');
-        this.ksearch_pane = new rcube_layer('rcmKSearchpane', {vis:0, zindex:30000});
-        this.ksearch_pane.elm.appendChild(ul);
-        this.ksearch_pane.ul = ul;
-      }
-      else
-        ul = this.ksearch_pane.ul;
-
-      // remove all search results
-      ul.innerHTML = '';
-            
-      // add each result line to list
-      for (i=0; i<a_results.length; i++) {
-        li = document.createElement('LI');
-        li.innerHTML = a_results[i].replace(new RegExp('('+this.ksearch_value+')', 'ig'), '##$1%%').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/##([^%]+)%%/g, '<b>$1</b>');
-        li.onmouseover = function(){ ref.ksearch_select(this); };
-        li.onmouseup = function(){ ref.ksearch_click(this) };
-        li._rcm_id = i;
-        ul.appendChild(li);
-      }
-
-      // select the first
-      ul.firstChild.setAttribute('id', 'rcmksearchSelected');
-      this.set_classname(ul.firstChild, 'selected', true);
-      this.ksearch_selected = 0;
-
-      // move the results pane right under the input box and make it visible
-      var pos = rcube_get_object_pos(this.ksearch_input);
-      this.ksearch_pane.move(pos.x, pos.y+this.ksearch_input.offsetHeight);
-      this.ksearch_pane.show(1);
-    }
-    // hide results pane
-    else
-      this.ksearch_hide();
-  };
-  
-  this.ksearch_click = function(node)
-  {
-    if (this.ksearch_input)
-      this.ksearch_input.focus();
-
-    this.insert_recipient(node._rcm_id);
-    this.ksearch_hide();
-  };
-
-  this.ksearch_blur = function()
-    {
-    if (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;
-    
-    if (this.ksearch_pane)
-      this.ksearch_pane.show(0);
-    };
-
-
-  /*********************************************************/
-  /*********         address book methods          *********/
-  /*********************************************************/
-
-  this.contactlist_keypress = function(list)
-    {
-      if (list.key_pressed == list.DELETE_KEY)
-        this.command('delete');
-    };
-
-  this.contactlist_select = function(list)
-    {
-      if (this.preview_timer)
-        clearTimeout(this.preview_timer);
-
-      var id, frame, ref = this;
-      if (id = list.get_single_selection())
-        this.preview_timer = window.setTimeout(function(){ ref.load_contact(id, 'show'); }, 200);
-      else if (this.env.contentframe)
-        this.show_contentframe(false);
-
-      this.enable_command('compose', list.selection.length > 0);
-      this.enable_command('edit', (id && this.env.address_sources && !this.env.address_sources[this.env.source].readonly) ? true : false);
-      this.enable_command('delete', list.selection.length && this.env.address_sources && !this.env.address_sources[this.env.source].readonly);
-
-      return false;
-    };
-
-  this.list_contacts = function(src, page)
-    {
-    var add_url = '';
-    var target = window;
-    
-    if (!src)
-      src = this.env.source;
-    
-    if (page && this.current_page==page && src == this.env.source)
-      return false;
-      
-    if (src != this.env.source)
-      {
-      page = 1;
-      this.env.current_page = page;
-      this.reset_qsearch();
-      }
-
-    this.select_folder(src, this.env.source);
-    this.env.source = src;
-
-    // load contacts remotely
-    if (this.gui_objects.contactslist)
-      {
-      this.list_contacts_remote(src, page);
-      return;
-      }
-
-    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      target = window.frames[this.env.contentframe];
-      add_url = '&_framed=1';
-      }
-
-    // also send search request to get the correct listing
-    if (this.env.search_request)
-      add_url += '&_search='+this.env.search_request;
-
-    this.set_busy(true, 'loading');
-    target.location.href = this.env.comm_path+(src ? '&_source='+urlencode(src) : '')+(page ? '&_page='+page : '')+add_url;
-    };
-
-  // send remote request to load contacts list
-  this.list_contacts_remote = function(src, page)
-    {
-    // clear message list first
-    this.contact_list.clear(true);
-    this.show_contentframe(false);
-    this.enable_command('delete', 'compose', false);
-
-    // send request to server
-    var url = (src ? '_source='+urlencode(src) : '') + (page ? (src?'&':'') + '_page='+page : '');
-    this.env.source = src;
-    
-    // also send search request to get the right messages 
-    if (this.env.search_request) 
-      url += '&_search='+this.env.search_request;
-
-    this.set_busy(true, 'loading');
-    this.http_request('list', url, true);
-    };
-
-  // load contact record
-  this.load_contact = function(cid, action, framed)
-    {
-    var add_url = '';
-    var target = window;
-    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      add_url = '&_framed=1';
-      target = window.frames[this.env.contentframe];
-      this.show_contentframe(true);
-      }
-    else if (framed)
-      return false;
-      
-    if (action && (cid || action=='add') && !this.drag_active)
-      {
-      this.set_busy(true);
-      target.location.href = this.env.comm_path+'&_action='+action+'&_source='+urlencode(this.env.source)+'&_cid='+urlencode(cid) + add_url;
-      }
-    return true;
-    };
-
-  // copy a contact to the specified target (group or directory)
-  this.copy_contact = function(cid, to)
-    {
-    if (!cid)
-      cid = this.contact_list.get_selection().join(',');
-
-    if (to != this.env.source && cid && this.env.address_sources[to] && !this.env.address_sources[to].readonly)
-      this.http_post('copy', '_cid='+urlencode(cid)+'&_source='+urlencode(this.env.source)+'&_to='+urlencode(to));
-    };
-
-
-  this.delete_contacts = function()
-    {
-    // exit if no mailbox specified or if selection is empty
-    var selection = this.contact_list.get_selection();
-    if (!(selection.length || this.env.cid) || !confirm(this.get_label('deletecontactconfirm')))
-      return;
-      
-    var a_cids = new Array();
-    var qs = '';
-
-    if (this.env.cid)
-      a_cids[a_cids.length] = this.env.cid;
-    else
-      {
-      var id;
-      for (var n=0; n<selection.length; n++)
-        {
-        id = selection[n];
-        a_cids[a_cids.length] = id;
-        this.contact_list.remove_row(id, (n == selection.length-1));
-        }
-
-      // hide content frame if we delete the currently displayed contact
-      if (selection.length == 1)
-        this.show_contentframe(false);
-      }
-
-    // also send search request to get the right records from the next page
-    if (this.env.search_request) 
-      qs += '&_search='+this.env.search_request;
-
-    // send request to server
-    this.http_post('delete', '_cid='+urlencode(a_cids.join(','))+'&_source='+urlencode(this.env.source)+'&_from='+(this.env.action ? this.env.action : '')+qs);
-    return true;
-    };
-
-  // update a contact record in the list
-  this.update_contact_row = function(cid, cols_arr)
-    {
-    var row;
-    if (this.contact_list.rows[cid] && (row = this.contact_list.rows[cid].obj))
-      {
-      for (var c=0; c<cols_arr.length; c++)
-        if (row.cells[c])
-          row.cells[c].innerHTML = cols_arr[c];
-
-      return true;
-      }
-
-    return false;
-    };
-
-
-  /*********************************************************/
-  /*********        user settings methods          *********/
-  /*********************************************************/
-
-  this.init_subscription_list = function()
-    {
-    var p = 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(o){ p.subscription_select(o); });
-    this.subscription_list.addEventListener('dragstart', function(o){ p.drag_active = true; });
-    this.subscription_list.addEventListener('dragend', function(o){ p.subscription_move_folder(o); });
-    this.subscription_list.row_init = function (row)
-      {
-      var anchors = row.obj.getElementsByTagName('A');
-      if (anchors[0])
-        anchors[0].onclick = function() { p.rename_folder(row.id); return false; };
-      if (anchors[1])
-        anchors[1].onclick = function() { p.delete_folder(row.id); return false; };
-      row.obj.onmouseover = function() { p.focus_subscription(row.id); };
-      row.obj.onmouseout = function() { p.unfocus_subscription(row.id); };
-      }
-    this.subscription_list.init();
-    }
-
-  this.identity_select = function(list)
-    {
-    var id;
-    if (id = list.get_single_selection())
-      this.load_identity(id, 'edit-identity');
-    };
-
-  // load contact record
-  this.load_identity = function(id, action)
-    {
-    if (action=='edit-identity' && (!id || id==this.env.iid))
-      return false;
-
-    var add_url = '';
-    var target = window;
-    if (this.env.contentframe && window.frames && window.frames[this.env.contentframe])
-      {
-      add_url = '&_framed=1';
-      target = window.frames[this.env.contentframe];
-      document.getElementById(this.env.contentframe).style.visibility = 'inherit';
-      }
-
-    if (action && (id || action=='add-identity'))
-      {
-      this.set_busy(true);
-      target.location.href = this.env.comm_path+'&_action='+action+'&_iid='+id+add_url;
-      }
-    return true;
-    };
-
-  this.delete_identity = function(id)
-    {
-    // exit if no mailbox specified or if selection is empty
-    var selection = this.identity_list.get_selection();
-    if (!(selection.length || this.env.iid))
-      return;
-    
-    if (!id)
-      id = this.env.iid ? this.env.iid : selection[0];
-
-    // if (this.env.framed && id)
-    this.goto_url('delete-identity', '_iid='+id, true);
-    return true;
-    };
-
-  this.focus_subscription = function(id)
-    {
-    var row, folder;
-    var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
-
-    if (this.drag_active && this.env.folder && (row = document.getElementById(id)))
-      if (this.env.subscriptionrows[id] &&
-          (folder = this.env.subscriptionrows[id][0]))
-        {
-        if (this.check_droptarget(folder) &&
-           !this.env.subscriptionrows[this.get_folder_row_id(this.env.folder)][2] &&    
-           (folder != this.env.folder.replace(reg, '')) &&
-            (!folder.match(new RegExp('^'+RegExp.escape(this.env.folder+this.env.delimiter)))))
-          {
-          this.set_env('dstfolder', folder);
-          this.set_classname(row, 'droptarget', true);
-          }
-        }
-      else if (this.env.folder.match(new RegExp(RegExp.escape(this.env.delimiter))))
-        {
-        this.set_env('dstfolder', this.env.delimiter);
-        this.set_classname(this.subscription_list.frame, 'droptarget', true);
-        }
-    }
-
-  this.unfocus_subscription = function(id)
-    {
-      var row;
-      this.set_env('dstfolder', null);
-      if (this.env.subscriptionrows[id] &&
-          (row = document.getElementById(id)))
-        this.set_classname(row, 'droptarget', false);
-      else
-        this.set_classname(this.subscription_list.frame, 'droptarget', false);
-    }
-
-  this.subscription_select = function(list)
-    {
-    var id, folder;
-    if ((id = list.get_single_selection()) &&
-        this.env.subscriptionrows['rcmrow'+id] &&
-        (folder = this.env.subscriptionrows['rcmrow'+id][0]))
-      this.set_env('folder', folder);
-    else
-      this.set_env('folder', null);
-      
-    if (this.gui_objects.createfolderhint)
-      this.gui_objects.createfolderhint.innerHTML = this.env.folder ? this.get_label('addsubfolderhint') : '';
-    };
-
-  this.subscription_move_folder = function(list)
-    {
-    var reg = RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
-    if (this.env.folder && this.env.dstfolder && (this.env.dstfolder != this.env.folder) &&
-        (this.env.dstfolder != this.env.folder.replace(reg, '')))
-      {
-      var reg = new RegExp('[^'+RegExp.escape(this.env.delimiter)+']*['+RegExp.escape(this.env.delimiter)+']', 'g');
-      var basename = this.env.folder.replace(reg, '');
-      var newname = this.env.dstfolder==this.env.delimiter ? basename : this.env.dstfolder+this.env.delimiter+basename;
-
-      this.set_busy(true, 'foldermoving');
-      this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.folder)+'&_folder_newname='+urlencode(newname), true);
-      }
-    this.drag_active = false;
-    this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder));
-    };
-
-  // tell server to create and subscribe a new mailbox
-  this.create_folder = function(name)
-    {
-    if (this.edit_folder)
-      this.reset_folder_rename();
-
-    var form;
-    if ((form = this.gui_objects.editform) && form.elements['_folder_name'])
-      {
-      name = form.elements['_folder_name'].value;
-
-      if (name.indexOf(this.env.delimiter)>=0)
-        {
-        alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')');
-        return false;
-        }
-
-      if (this.env.folder && name != '')
-        name = this.env.folder+this.env.delimiter+name;
-
-      this.set_busy(true, 'foldercreating');
-      this.http_post('create-folder', '_name='+urlencode(name), true);
-      }
-    else if (form.elements['_folder_name'])
-      form.elements['_folder_name'].focus();
-    };
-
-  // start renaming the mailbox name.
-  // this will replace the name string with an input field
-  this.rename_folder = function(id)
-    {
-    var temp, row, form;
-
-    // reset current renaming
-    if (temp = this.edit_folder)
-      {
-      this.reset_folder_rename();
-      if (temp == id)
-        return;
-      }
-
-    if (id && this.env.subscriptionrows[id] && (row = document.getElementById(id)))
-      {
-      var reg = new RegExp('.*['+RegExp.escape(this.env.delimiter)+']');
-      this.name_input = document.createElement('INPUT');
-      this.name_input.value = this.env.subscriptionrows[id][0].replace(reg, '');
-      this.name_input.style.width = '100%';
-
-      reg = new RegExp('['+RegExp.escape(this.env.delimiter)+']?[^'+RegExp.escape(this.env.delimiter)+']+$');
-      this.name_input.__parent = this.env.subscriptionrows[id][0].replace(reg, '');
-      this.name_input.onkeypress = function(e){ rcmail.name_input_keypress(e); };
-      
-      row.cells[0].replaceChild(this.name_input, row.cells[0].firstChild);
-      this.edit_folder = id;
-      this.name_input.select();
-      
-      if (form = this.gui_objects.editform)
-        form.onsubmit = function(){ return false; };
-      }
-    };
-
-  // remove the input field and write the current mailbox name to the table cell
-  this.reset_folder_rename = function()
-    {
-    var cell = this.name_input ? this.name_input.parentNode : null;
-
-    if (cell && this.edit_folder && this.env.subscriptionrows[this.edit_folder])
-      cell.innerHTML = this.env.subscriptionrows[this.edit_folder][1];
-      
-    this.edit_folder = null;
-    };
-
-  // handler for keyboard events on the input field
-  this.name_input_keypress = function(e)
-    {
-    var key = rcube_event.get_keycode(e);
-
-    // enter
-    if (key==13)
-      {
-      var newname = this.name_input ? this.name_input.value : null;
-      if (this.edit_folder && newname)
-        {
-        if (newname.indexOf(this.env.delimiter)>=0)
-          {
-          alert(this.get_label('forbiddencharacter')+' ('+this.env.delimiter+')');
-          return false;
-          }
-
-        if (this.name_input.__parent)
-          newname = this.name_input.__parent + this.env.delimiter + newname;
-
-        this.set_busy(true, 'folderrenaming');
-        this.http_post('rename-folder', '_folder_oldname='+urlencode(this.env.subscriptionrows[this.edit_folder][0])+'&_folder_newname='+urlencode(newname), true);
-        }
-      }
-    // escape
-    else if (key==27)
-      this.reset_folder_rename();
-    };
-
-  // delete a specific mailbox with all its messages
-  this.delete_folder = function(id)
-    {
-    var folder = this.env.subscriptionrows[id][0];
-
-    if (this.edit_folder)
-      this.reset_folder_rename();
-
-    if (folder && confirm(this.get_label('deletefolderconfirm')))
-      {
-      this.set_busy(true, 'folderdeleting');
-      this.http_post('delete-folder', '_mboxes='+urlencode(folder), true);
-      this.set_env('folder', null);
-
-      if (this.gui_objects.createfolderhint)
-        this.gui_objects.createfolderhint.innerHTML = '';
-      }
-    };
-
-  // add a new folder to the subscription list by cloning a folder row
-  this.add_folder_row = function(name, display_name, replace, before)
-    {
-    if (!this.gui_objects.subscriptionlist)
-      return false;
-
-    // find not protected folder    
-    for (var refid in this.env.subscriptionrows)
-      if (this.env.subscriptionrows[refid]!=null && !this.env.subscriptionrows[refid][2])
-        break;
-
-    var refrow, form;
-    var tbody = this.gui_objects.subscriptionlist.tBodies[0];
-    var id = 'rcmrow'+(tbody.childNodes.length+1);
-    var selection = this.subscription_list.get_single_selection();
-    
-    if (replace && replace.id)
-    {
-      id = replace.id;
-      refid = replace.id;
-    }
-
-    if (!id || !(refrow = document.getElementById(refid)))
-      {
-      // Refresh page if we don't have a table row to clone
-      this.goto_url('folders');
-      }
-    else
-      {
-      // clone a table row if there are existing rows
-      var row = this.clone_table_row(refrow);
-      row.id = id;
-
-      if (before && (before = this.get_folder_row_id(before)))
-        tbody.insertBefore(row, document.getElementById(before));
-      else
-        tbody.appendChild(row);
-      
-      if (replace)
-        tbody.removeChild(replace);
-      }
-
-    // add to folder/row-ID map
-    this.env.subscriptionrows[row.id] = [name, display_name, 0];
-
-    // set folder name
-    row.cells[0].innerHTML = display_name;
-    
-    // set messages count to zero
-    if (!replace)
-      row.cells[1].innerHTML = '*';
-    
-    if (!replace && row.cells[2] && row.cells[2].firstChild.tagName=='INPUT')
-      {
-      row.cells[2].firstChild.value = name;
-      row.cells[2].firstChild.checked = true;
-      }
-    
-    // add new folder to rename-folder list and clear input field
-    if (!replace && (form = this.gui_objects.editform))
-      {
-      if (form.elements['_folder_oldname'])
-        form.elements['_folder_oldname'].options[form.elements['_folder_oldname'].options.length] = new Option(name,name);
-      if (form.elements['_folder_name'])
-        form.elements['_folder_name'].value = ''; 
-      }
-
-    this.init_subscription_list();
-    if (selection && document.getElementById('rcmrow'+selection))
-      this.subscription_list.select_row(selection);
-
-    if (document.getElementById(id).scrollIntoView)
-      document.getElementById(id).scrollIntoView();
-    };
-
-  // replace an existing table row with a new folder line
-  this.replace_folder_row = function(oldfolder, newfolder, display_name, before)
-    {
-    var id = this.get_folder_row_id(oldfolder);
-    var row = document.getElementById(id);
-    
-    // replace an existing table row (if found)
-    this.add_folder_row(newfolder, display_name, row, before);
-    
-    // rename folder in rename-folder dropdown
-    var form, elm;
-    if ((form = this.gui_objects.editform) && (elm = form.elements['_folder_oldname']))
-      {
-      for (var i=0;i<elm.options.length;i++)
-        {
-        if (elm.options[i].value == oldfolder)
-          {
-          elm.options[i].text = display_name;
-          elm.options[i].value = newfolder;
-          break;
-          }
-        }
-
-      form.elements['_folder_newname'].value = '';
-      }
-    };
-
-  // remove the table row of a specific mailbox from the table
-  // (the row will not be removed, just hidden)
-  this.remove_folder_row = function(folder)
-    {
-    var row;
-    var id = this.get_folder_row_id(folder);
-    if (id && (row = document.getElementById(id)))
-      row.style.display = 'none';
-
-    // remove folder from rename-folder list
-    var form;
-    if ((form = this.gui_objects.editform) && form.elements['_folder_oldname'])
-      {
-      for (var i=0;i<form.elements['_folder_oldname'].options.length;i++)
-        {
-        if (form.elements['_folder_oldname'].options[i].value == folder) 
-          {
-          form.elements['_folder_oldname'].options[i] = null;
-          break;
-          }
-        }
-      }
-    
-    if (form && form.elements['_folder_newname'])
-      form.elements['_folder_newname'].value = '';
-    };
-
-  this.subscribe_folder = function(folder)
-    {
-    if (folder)
-      this.http_post('subscribe', '_mbox='+urlencode(folder));
-    };
-
-  this.unsubscribe_folder = function(folder)
-    {
-    if (folder)
-      this.http_post('unsubscribe', '_mbox='+urlencode(folder));
-    };
-    
-  // helper method to find a specific mailbox row ID
-  this.get_folder_row_id = function(folder)
-    {
-    for (var id in this.env.subscriptionrows)
-      if (this.env.subscriptionrows[id] && this.env.subscriptionrows[id][0] == folder)
-        break;
-        
-    return id;
-    };
-
-  // duplicate a specific table row
-  this.clone_table_row = function(row)
-    {
-    var cell, td;
-    var new_row = document.createElement('TR');
-    for(var n=0; n<row.cells.length; n++)
-      {
-      cell = row.cells[n];
-      td = document.createElement('TD');
-
-      if (cell.className)
-        td.className = cell.className;
-      if (cell.align)
-        td.setAttribute('align', cell.align);
-        
-      td.innerHTML = cell.innerHTML;
-      new_row.appendChild(td);
-      }
-    
-    return new_row;
-    };
-
-
-  /*********************************************************/
-  /*********           GUI functionality           *********/
-  /*********************************************************/
-
-  // eable/disable buttons for page shifting
-  this.set_page_buttons = function()
-    {
-    this.enable_command('nextpage', (this.env.pagecount > this.env.current_page));
-    this.enable_command('lastpage', (this.env.pagecount > this.env.current_page));
-    this.enable_command('previouspage', (this.env.current_page > 1));
-    this.enable_command('firstpage', (this.env.current_page > 1));
-    }
-
-  // set button to a specific state
-  this.set_button = function(command, state)
-    {
-    var a_buttons = this.buttons[command];
-    var button, obj;
-
-    if(!a_buttons || !a_buttons.length)
-      return false;
-
-    for(var n=0; n<a_buttons.length; n++)
-      {
-      button = a_buttons[n];
-      obj = document.getElementById(button.id);
-
-      // get default/passive setting of the button
-      if (obj && button.type=='image' && !button.status) {
-        button.pas = obj._original_src ? obj._original_src : obj.src;
-        // respect PNG fix on IE browsers
-        if (obj.runtimeStyle && obj.runtimeStyle.filter && obj.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/))
-          button.pas = RegExp.$1;
-      }
-      else if (obj && !button.status)
-        button.pas = String(obj.className);
-
-      // set image according to button state
-      if (obj && button.type=='image' && button[state])
-        {
-        button.status = state;        
-        obj.src = button[state];
-        }
-      // set class name according to button state
-      else if (obj && typeof(button[state])!='undefined')
-        {
-        button.status = state;        
-        obj.className = button[state];        
-        }
-      // disable/enable input buttons
-      if (obj && button.type=='input')
-        {
-        button.status = state;
-        obj.disabled = !state;
-        }
-      }
-    };
-
-  // display a specific alttext
-  this.set_alttext = function(command, label)
-    {
-      if (!this.buttons[command] || !this.buttons[command].length)
-        return;
-      
-      var button, obj, link;
-      for (var n=0; n<this.buttons[command].length; n++)
-      {
-        button = this.buttons[command][n];
-        obj = document.getElementById(button.id);
-        
-        if (button.type=='image' && obj)
-        {
-          obj.setAttribute('alt', this.get_label(label));
-          if ((link = obj.parentNode) && link.tagName == 'A')
-            link.setAttribute('title', this.get_label(label));
-        }
-        else if (obj)
-          obj.setAttribute('title', this.get_label(label));
-      }
-    };
-
-  // mouse over button
-  this.button_over = function(command, id)
-    {
-    var a_buttons = this.buttons[command];
-    var button, img;
-
-    if(!a_buttons || !a_buttons.length)
-      return false;
-
-    for(var n=0; n<a_buttons.length; n++)
-      {
-      button = a_buttons[n];
-      if(button.id==id && button.status=='act')
-        {
-        img = document.getElementById(button.id);
-        if (img && button.over)
-          img.src = button.over;
-        }
-      }
-      
-    };
-
-  // mouse down on button
-  this.button_sel = function(command, id)
-    {
-    var a_buttons = this.buttons[command];
-    var button, img;
-
-    if(!a_buttons || !a_buttons.length)
-      return;
-
-    for(var n=0; n<a_buttons.length; n++)
-      {
-      button = a_buttons[n];
-      if(button.id==id && button.status=='act')
-        {
-        img = document.getElementById(button.id);
-        if (img && button.sel)
-          img.src = button.sel;
-        }
-      }
-    };
-
-  // mouse out of button
-  this.button_out = function(command, id)
-    {
-    var a_buttons = this.buttons[command];
-    var button, img;
-
-    if(!a_buttons || !a_buttons.length)
-      return;
-
-    for(var n=0; n<a_buttons.length; n++)
-      {
-      button = a_buttons[n];
-      if(button.id==id && button.status=='act')
-        {
-        img = document.getElementById(button.id);
-        if (img && button.act)
-          img.src = button.act;
-        }
-      }
-    };
-
-  // set/unset a specific class name
-  this.set_classname = function(obj, classname, set)
-    {
-    var reg = new RegExp('\s*'+classname, 'i');
-    if (!set && obj.className.match(reg))
-      obj.className = obj.className.replace(reg, '');
-    else if (set && !obj.className.match(reg))
-      obj.className += ' '+classname;
-    };
-
-  // write to the document/window title
-  this.set_pagetitle = function(title)
-  {
-    if (title && document.title)
-      document.title = title;
-  }
-
-  // display a system message
-  this.display_message = function(msg, type, hold)
-    {
-    if (!this.loaded)  // save message in order to display after page loaded
-      {
-      this.pending_message = new Array(msg, type);
-      return true;
-      }
-
-    // pass command to parent window
-    if (this.env.framed && parent.rcmail)
-      return parent.rcmail.display_message(msg, type, hold);
-
-    if (!this.gui_objects.message)
-      return false;
-
-    if (this.message_timer)
-      clearTimeout(this.message_timer);
-    
-    var cont = msg;
-    if (type)
-      cont = '<div class="'+type+'">'+cont+'</div>';
-
-    var _rcube = this;
-    this.gui_objects.message.innerHTML = cont;
-    this.gui_objects.message.style.display = 'block';
-    
-    if (type!='loading')
-      this.gui_objects.message.onmousedown = function(){ _rcube.hide_message(); return true; };
-    
-    if (!hold)
-      this.message_timer = window.setTimeout(function(){ ref.hide_message(); }, this.message_time);
-    };
-
-  // make a message row disapear
-  this.hide_message = function()
-    {
-    if (this.gui_objects.message)
-      {
-      this.gui_objects.message.style.display = 'none';
-      this.gui_objects.message.onmousedown = null;
-      }
-    };
-
-  // mark a mailbox as selected and set environment variable
-  this.select_folder = function(name, old)
-  {
-    if (this.gui_objects.folderlist)
-    {
-      var current_li, target_li;
-      
-      if ((current_li = this.get_folder_li(old)))
-      {
-        this.set_classname(current_li, 'selected', false);
-        this.set_classname(current_li, 'unfocused', false);
-      }
-
-      if ((target_li = this.get_folder_li(name)))
-      {
-        this.set_classname(target_li, 'unfocused', false);
-        this.set_classname(target_li, 'selected', true);
-      }
-    }
-  };
-
-  // helper method to find a folder list item
-  this.get_folder_li = function(name)
-  {
-    if (this.gui_objects.folderlist)
-    {
-      name = String(name).replace(this.identifier_expr, '');
-      return document.getElementById('rcmli'+name);
-    }
-
-    return null;
-  };
-
-  // for reordering column array, Konqueror workaround
-  this.set_message_coltypes = function(coltypes) 
-  { 
-    this.coltypes = coltypes;
-    
-    // set correct list titles
-    var cell, col;
-    var thead = this.gui_objects.messagelist ? this.gui_objects.messagelist.tHead : null;
-    for (var n=0; thead && n<this.coltypes.length; n++) 
-      {
-      col = this.coltypes[n];
-      if ((cell = thead.rows[0].cells[n+1]) && (col=='from' || col=='to'))
-        {
-        // if we have links for sorting, it's a bit more complicated...
-        if (cell.firstChild && cell.firstChild.tagName=='A')
-          {
-          cell.firstChild.innerHTML = this.get_label(this.coltypes[n]);
-          cell.firstChild.onclick = function(){ return rcmail.command('sort', this.__col, this); };
-          cell.firstChild.__col = col;
-          }
-        else
-          cell.innerHTML = this.get_label(this.coltypes[n]);
-
-        cell.id = 'rcm'+col;
-        }
-      else if (col == 'subject' && this.message_list)
-        this.message_list.subject_col = n+1;
-      }
-  };
-
-  // create a table row in the message list
-  this.add_message_row = function(uid, cols, flags, attachment, attop)
-    {
-    if (!this.gui_objects.messagelist || !this.message_list)
-      return false;
-
-    var tbody = this.gui_objects.messagelist.tBodies[0];
-    var rowcount = tbody.rows.length;
-    var even = rowcount%2;
-    
-    this.env.messages[uid] = {deleted:flags.deleted?1:0,
-                              replied:flags.replied?1:0,
-                              unread:flags.unread?1:0,
-                             forwarded:flags.forwarded?1:0,
-                              flagged:flags.flagged?1:0};
-    
-    var row = document.createElement('TR');
-    row.id = 'rcmrow'+uid;
-    row.className = 'message'
-       + (even ? ' even' : ' odd')
-        + (flags.unread ? ' unread' : '')
-       + (flags.deleted ? ' deleted' : '')
-       + (flags.flagged ? ' flagged' : '');                
-
-    if (this.message_list.in_selection(uid))
-      row.className += ' selected';
-
-    var icon = this.env.messageicon;
-    if (flags.deleted && this.env.deletedicon)
-      icon = this.env.deletedicon;
-    else if (flags.replied && this.env.repliedicon)
-      {
-      if (flags.forwarded && this.env.forwardedrepliedicon)
-        icon = this.env.forwardedrepliedicon;
-      else
-        icon = this.env.repliedicon;
-      }
-    else if (flags.forwarded && this.env.forwardedicon)
-      icon = this.env.forwardedicon;
-    else if(flags.unread && this.env.unreadicon)
-      icon = this.env.unreadicon;
-    
-    var col = document.createElement('TD');
-    col.className = 'icon';
-    col.innerHTML = icon ? '<img src="'+icon+'" alt="" />' : '';
-    row.appendChild(col);
-
-    // add each submitted col
-    for (var n = 0; n < this.coltypes.length; n++) 
-      { 
-      var c = this.coltypes[n];
-      col = document.createElement('TD');
-      col.className = String(c).toLowerCase();
-      
-      if (c=='flag')
-        {
-        if (flags.flagged && this.env.flaggedicon)
-          col.innerHTML = '<img src="'+this.env.flaggedicon+'" alt="" />';
-        else if(!flags.flagged && this.env.unflaggedicon)
-          col.innerHTML = '<img src="'+this.env.unflaggedicon+'" alt="" />';
-      }
-      else if (c=='attachment')
-        col.innerHTML = attachment && this.env.attachmenticon ? '<img src="'+this.env.attachmenticon+'" alt="" />' : '&nbsp;';
-      else
-        col.innerHTML = cols[c];
-
-      row.appendChild(col);
-      }
-
-    this.message_list.insert_row(row, attop);
-
-    // remove 'old' row
-    if (attop && this.env.pagesize && this.message_list.rowcount > this.env.pagesize)
-      {
-       var uid = this.message_list.get_last_row();
-        this.message_list.remove_row(uid);
-       this.message_list.clear_selection(uid);
-      }
-    };
-
-  // replace content of row count display
-  this.set_rowcount = function(text)
-    {
-    if (this.gui_objects.countdisplay)
-      this.gui_objects.countdisplay.innerHTML = text;
-
-    // update page navigation buttons
-    this.set_page_buttons();
-    };
-
-  // replace content of mailboxname display
-  this.set_mailboxname = function(content)
-    {
-    if (this.gui_objects.mailboxname && content)
-      this.gui_objects.mailboxname.innerHTML = content;
-    };
-
-  // replace content of quota display
-  this.set_quota = function(content)
-    {
-    if (this.gui_objects.quotadisplay && content)
-      this.gui_objects.quotadisplay.innerHTML = content;
-    };
-
-  // update the mailboxlist
-  this.set_unread_count = function(mbox, count, set_title)
-    {
-    if (!this.gui_objects.mailboxlist)
-      return false;
-
-    this.env.unread_counts[mbox] = count;
-    this.set_unread_count_display(mbox, set_title);
-    }
-
-  // update the mailbox count display
-  this.set_unread_count_display = function(mbox, set_title)
-    {
-    var reg, text_obj, item, mycount, childcount, div;
-    if (item = this.get_folder_li(mbox))
-      {
-      mycount = this.env.unread_counts[mbox] ? this.env.unread_counts[mbox] : 0;
-      text_obj = item.getElementsByTagName('a')[0];
-      reg = /\s+\([0-9]+\)$/i;
-
-      childcount = 0;
-      if ((div = item.getElementsByTagName('div')[0]) &&
-          div.className.match(/collapsed/))
-        {
-        // add children's counters
-        for (var k in this.env.unread_counts) 
-          if (k.indexOf(mbox + this.env.delimiter) == 0) {
-            childcount += this.env.unread_counts[k];
-         }
-        }
-
-      if (mycount && text_obj.innerHTML.match(reg))
-        text_obj.innerHTML = text_obj.innerHTML.replace(reg, ' ('+mycount+')');
-      else if (mycount)
-        text_obj.innerHTML += ' ('+mycount+')';
-      else
-        text_obj.innerHTML = text_obj.innerHTML.replace(reg, '');
-
-      // set parent's display
-      reg = new RegExp(RegExp.escape(this.env.delimiter) + '[^' + RegExp.escape(this.env.delimiter) + ']+$');
-      if (mbox.match(reg))
-        this.set_unread_count_display(mbox.replace(reg, ''), false);
-
-      // set the right classes
-      this.set_classname(item, 'unread', (mycount+childcount)>0 ? true : false);
-      }
-
-    // set unread count to window title
-    reg = /^\([0-9]+\)\s+/i;
-    if (set_title && document.title)
-      {
-      var doc_title = String(document.title);
-      var new_title = "";
-
-      if (mycount && doc_title.match(reg))
-        new_title = doc_title.replace(reg, '('+mycount+') ');
-      else if (mycount)
-        new_title = '('+mycount+') '+doc_title;
-      else
-        new_title = doc_title.replace(reg, '');
-        
-      this.set_pagetitle(new_title);
-      }
-    };
-
-  // notifies that a new message(s) has hit the mailbox
-  this.new_message_focus = function()
-    {
-    // focus main window
-    if (this.env.framed && window.parent)
-      window.parent.focus();
-    else
-      window.focus();
-    }
-
-  // add row to contacts list
-  this.add_contact_row = function(cid, cols, select)
-    {
-    if (!this.gui_objects.contactslist || !this.gui_objects.contactslist.tBodies[0])
-      return false;
-    
-    var tbody = this.gui_objects.contactslist.tBodies[0];
-    var rowcount = tbody.rows.length;
-    var even = rowcount%2;
-    
-    var row = document.createElement('TR');
-    row.id = 'rcmrow'+cid;
-    row.className = 'contact '+(even ? 'even' : 'odd');
-    
-    if (this.contact_list.in_selection(cid))
-      row.className += ' selected';
-
-    // add each submitted col
-    for (var c in cols)
-      {
-      col = document.createElement('TD');
-      col.className = String(c).toLowerCase();
-      col.innerHTML = cols[c];
-      row.appendChild(col);
-      }
-    
-    this.contact_list.insert_row(row);
-    this.enable_command('export', (this.contact_list.rowcount > 0));
-    };
-
-  this.toggle_prefer_html = function(checkbox)
-    {
-    var addrbook_show_images;
-    if (addrbook_show_images = document.getElementById('rcmfd_addrbook_show_images'))
-      addrbook_show_images.disabled = !checkbox.checked;
-    }
-
-  // display fetched raw headers
-  this.set_headers = function(content)
-    {
-    if (this.gui_objects.all_headers_row && this.gui_objects.all_headers_box && content)
-      {
-      var box = this.gui_objects.all_headers_box;
-      box.innerHTML = content;
-      box.style.display = 'block';
-
-      if (this.env.framed && parent.rcmail)
-       parent.rcmail.set_busy(false);
-      else
-        this.set_busy(false);
-      }
-    };
-
-  // display all-headers row and fetch raw message headers
-  this.load_headers = function(elem)
-    {
-    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box || !this.env.uid)
-      return;
-    
-    this.set_classname(elem, 'show-headers', false);
-    this.set_classname(elem, 'hide-headers', true);
-    this.gui_objects.all_headers_row.style.display = bw.ie ? 'block' : 'table-row';
-    elem.onclick = function() { rcmail.hide_headers(elem); }
-
-    // fetch headers only once
-    if (!this.gui_objects.all_headers_box.innerHTML)
-      {
-      this.display_message(this.get_label('loading'), 'loading', true); 
-      this.http_post('headers', '_uid='+this.env.uid);
-      }
-    }
-
-  // hide all-headers row
-  this.hide_headers = function(elem)
-    {
-    if (!this.gui_objects.all_headers_row || !this.gui_objects.all_headers_box)
-      return;
-
-    this.set_classname(elem, 'hide-headers', false);
-    this.set_classname(elem, 'show-headers', true);
-    this.gui_objects.all_headers_row.style.display = 'none';
-    elem.onclick = function() { rcmail.load_headers(elem); }
-    }
-
-
-  /********************************************************/
-  /*********  html to text conversion functions   *********/
-  /********************************************************/
-
-  this.html2plain = function(htmlText, id)
-    {
-    var http_request = new rcube_http_request();
-    var url = this.env.bin_path+'html2text.php';
-    var rcmail = this;
-
-    this.set_busy(true, 'converting');
-    console.log('HTTP POST: '+url);
-
-    http_request.onerror = function(o) { rcmail.http_error(o); };
-    http_request.oncomplete = function(o) { rcmail.set_text_value(o, id); };
-    http_request.POST(url, htmlText, 'application/octet-stream');
-    }
-
-  this.set_text_value = function(httpRequest, id)
-    {
-    this.set_busy(false);
-    document.getElementById(id).value = httpRequest.get_text();
-    console.log(httpRequest.get_text());
-    }
-
-
-  /********************************************************/
-  /*********        remote request methods        *********/
-  /********************************************************/
-
-  this.redirect = function(url, lock)
-    {
-    if (lock || lock === null)
-      this.set_busy(true);
-
-    if (this.env.framed && window.parent)
-      parent.location.href = url;
-    else  
-      location.href = url;
-    };
-
-  this.goto_url = function(action, query, lock)
-    {
-    var querystring = query ? '&'+query : '';
-    this.redirect(this.env.comm_path+'&_action='+action+querystring, lock);
-    };
-
-  this.http_sockets = new Array();
-  
-  // find a non-busy socket or create a new one
-  this.get_request_obj = function()
-    {
-    for (var n=0; n<this.http_sockets.length; n++)
-      {
-      if (!this.http_sockets[n].busy)
-        return this.http_sockets[n];
-      }
-    
-    // create a new XMLHTTP object
-    var i = this.http_sockets.length;
-    this.http_sockets[i] = new rcube_http_request();
-
-    return this.http_sockets[i];
-    };
-  
-  // send a http request to the server
-  this.http_request = function(action, querystring, lock)
-    {
-    var request_obj = this.get_request_obj();
-    querystring += (querystring ? '&' : '') + '_remote=1';
-    
-    // add timestamp to request url to avoid cacheing problems in Safari
-    if (bw.safari)
-      querystring += '&_ts='+(new Date().getTime());
-
-    // send request
-    if (request_obj)
-      {
-      console.log('HTTP request: '+this.env.comm_path+'&_action='+action+'&'+querystring);
-
-      if (lock)
-        this.set_busy(true);
-
-      var rcm = this;
-      request_obj.__lock = lock ? true : false;
-      request_obj.__action = action;
-      request_obj.onerror = function(o){ ref.http_error(o); };
-      request_obj.oncomplete = function(o){ ref.http_response(o); };
-      request_obj.GET(this.env.comm_path+'&_action='+action+'&'+querystring);
-      }
-    };
-
-    // send a http POST request to the server
-    this.http_post = function(action, postdata, lock)
-      {
-      var request_obj;
-      if (postdata && typeof(postdata) == 'object')
-        postdata._remote = 1;
-      else
-        postdata += (postdata ? '&' : '') + '_remote=1';
-
-      // send request
-      if (request_obj = this.get_request_obj())
-        {
-        console.log('HTTP POST: '+this.env.comm_path+'&_action='+action);
-
-        if (lock)
-          this.set_busy(true);
-
-        var rcm = this;
-        request_obj.__lock = lock ? true : false;
-        request_obj.__action = action;
-        request_obj.onerror = function(o){ rcm.http_error(o); };
-        request_obj.oncomplete = function(o){ rcm.http_response(o); };
-        request_obj.POST(this.env.comm_path+'&_action='+action, postdata);
-        }
-      };
-
-  // handle HTTP response
-  this.http_response = function(request_obj)
-    {
-    var ctype = request_obj.get_header('Content-Type');
-    if (ctype)
-      {
-      ctype = String(ctype).toLowerCase();
-      var ctype_array=ctype.split(";");
-      ctype = ctype_array[0];
-      }
-
-    if (request_obj.__lock)
-      this.set_busy(false);
-
-    console.log(request_obj.get_text());
-
-    // if we get javascript code from server -> execute it
-    if (request_obj.get_text() && (ctype=='text/javascript' || ctype=='application/x-javascript'))
-      eval(request_obj.get_text());
-
-    // process the response data according to the sent action
-    switch (request_obj.__action) {
-      case 'delete':
-        if (this.task == 'addressbook') {
-          var uid = this.contact_list.get_selection();
-          this.enable_command('compose', (uid && this.contact_list.rows[uid]));
-          this.enable_command('delete', 'edit', (uid && this.contact_list.rows[uid] && 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.command('list');
-        else if (this.message_list)
-          this.message_list.init();
-        break;
-        
-      case 'purge':
-      case 'expunge':      
-        if (!this.env.messagecount && this.task == 'mail') {
-          // clear preview pane content
-          if (this.env.contentframe)
-            this.show_contentframe(false);
-          // disable commands useless when mailbox is empty
-          this.enable_command('show', 'reply', 'reply-all', 'forward', 'moveto', 'delete', 'mark', 'viewsource',
-            'print', 'load-attachment', 'purge', 'expunge', 'select-all', 'select-none', 'sort', false);
-        }
-        break;
-
-      case 'check-recent':
-      case 'getunread':
-      case 'list':
-        if (this.task == 'mail') {
-          if (this.message_list && request_obj.__action == 'list')
-            this.msglist_select(this.message_list);
-          this.enable_command('show', 'expunge', 'select-all', 'select-none', 'sort', (this.env.messagecount > 0));
-          this.enable_command('purge', this.purge_mailbox_test());
-        }
-        else if (this.task == 'addressbook')
-          this.enable_command('export', (this.contact_list && this.contact_list.rowcount > 0));
-
-        break;
-      }
-
-    request_obj.reset();
-    };
-
-  // handle HTTP request errors
-  this.http_error = function(request_obj)
-    {
-    //alert('Error sending request: '+request_obj.url+' => HTTP '+request_obj.xmlhttp.status);
-    if (request_obj.__lock)
-      this.set_busy(false);
-
-    request_obj.reset();
-    request_obj.__lock = false;
-    this.display_message('Unknown Server Error!', 'error');
-    };
-
-  // use an image to send a keep-alive siganl to the server
-  this.send_keep_alive = function()
-    {
-    var d = new Date();
-    this.http_request('keep-alive', '_t='+d.getTime());
-    };
-
-  // send periodic request to check for recent messages
-  this.check_for_recent = function(setbusy)
-    {
-    if (this.busy)
-      return;
-
-    if (setbusy)
-      this.set_busy(true, 'checkingmail');
-
-    var addurl = '_t=' + (new Date().getTime());
-
-    if (this.gui_objects.messagelist)
-      addurl += '&_list=1';
-    if (this.gui_objects.quotadisplay)
-      addurl += '&_quota=1';
-    if (this.env.search_request)
-      addurl += '&_search=' + this.env.search_request;
-
-    this.http_request('check-recent', addurl, true);
-    };
-
-
-  /********************************************************/
-  /*********            helper methods            *********/
-  /********************************************************/
-  
-  // check if we're in show mode or if we have a unique selection
-  // and return the message uid
-  this.get_single_uid = function()
-    {
-    return this.env.uid ? this.env.uid : (this.message_list ? this.message_list.get_single_selection() : null);
-    };
-
-  // same as above but for contacts
-  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(obj)
-    {
-    if (typeof(obj.selectionEnd)!='undefined')
-      return obj.selectionEnd;
-    else if (document.selection && document.selection.createRange)
-      {
-      var range = document.selection.createRange();
-      if (range.parentElement()!=obj)
-        return 0;
-
-      var gm = range.duplicate();
-      if (obj.tagName=='TEXTAREA')
-        gm.moveToElementText(obj);
-      else
-        gm.expand('textedit');
-      
-      gm.setEndPoint('EndToStart', range);
-      var p = gm.text.length;
-
-      return p<=obj.value.length ? p : -1;
-      }
-    else
-      return obj.value.length;
-    };
-
-  this.set_caret2start = function(obj)
-    {
-    if (obj.createTextRange)
-      {
-      var range = obj.createTextRange();
-      range.collapse(true);
-      range.select();
-      }
-    else if (obj.setSelectionRange)
-      obj.setSelectionRange(0,0);
-
-    obj.focus();
-    };
-
-  // set all fields of a form disabled
-  this.lock_form = function(form, lock)
-    {
-    if (!form || !form.elements)
-      return;
-    
-    var type;
-    for (var n=0; n<form.elements.length; n++)
-      {
-      type = form.elements[n];
-      if (type=='hidden')
-        continue;
-        
-      form.elements[n].disabled = lock;
-      }
-    };
-    
-  }  // end object rcube_webmail
-
-
-/**
- * Class for sending HTTP requests
- * @constructor
- */
-function rcube_http_request()
-  {
-  this.url = '';
-  this.busy = false;
-  this.xmlhttp = null;
-
-  // reset object properties
-  this.reset = function()
-    {
-    // set unassigned event handlers
-    this.onloading = function(){ };
-    this.onloaded = function(){ };
-    this.oninteractive = function(){ };
-    this.oncomplete = function(){ };
-    this.onabort = function(){ };
-    this.onerror = function(){ };
-    
-    this.url = '';
-    this.busy = false;
-    this.xmlhttp = null;
-    }
-
-  // create HTMLHTTP object
-  this.build = function()
-    {
-    if (window.XMLHttpRequest)
-      this.xmlhttp = new XMLHttpRequest();
-    else if (window.ActiveXObject)
-      {
-      try { this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
-      catch(e) { this.xmlhttp = null; }
-      }
-    else
-      {
-      
-      }
-    }
-
-  // send GET request
-  this.GET = function(url)
-    {
-    this.build();
-
-    if (!this.xmlhttp)
-      {
-      this.onerror(this);
-      return false;
-      }
-
-    var _ref = this;
-    this.url = url;
-    this.busy = true;
-
-    this.xmlhttp.onreadystatechange = function(){ _ref.xmlhttp_onreadystatechange(); };
-    this.xmlhttp.open('GET', url, true);
-    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid'));
-    this.xmlhttp.send(null);
-    };
-
-  this.POST = function(url, body, contentType)
-    {
-    // default value for contentType if not provided
-    if (typeof(contentType) == 'undefined')
-      contentType = 'application/x-www-form-urlencoded';
-
-    this.build();
-    
-    if (!this.xmlhttp)
-    {
-       this.onerror(this);
-       return false;
-    }
-    
-    var req_body = body;
-    if (typeof(body) == 'object')
-    {
-      req_body = '';
-      for (var p in body)
-        req_body += (req_body ? '&' : '') + p+'='+urlencode(body[p]);
-    }
-
-    var ref = this;
-    this.url = url;
-    this.busy = true;
-    
-    this.xmlhttp.onreadystatechange = function() { ref.xmlhttp_onreadystatechange(); };
-    this.xmlhttp.open('POST', url, true);
-    this.xmlhttp.setRequestHeader('Content-Type', contentType);
-    this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('roundcube_sessid'));
-    this.xmlhttp.send(req_body);
-    };
-
-  // handle onreadystatechange event
-  this.xmlhttp_onreadystatechange = function()
-    {
-    if(this.xmlhttp.readyState == 1)
-      this.onloading(this);
-
-    else if(this.xmlhttp.readyState == 2)
-      this.onloaded(this);
-
-    else if(this.xmlhttp.readyState == 3)
-      this.oninteractive(this);
-
-    else if(this.xmlhttp.readyState == 4)
-      {
-      try {
-        if (this.xmlhttp.status == 0)
-          this.onabort(this);
-        else if(this.xmlhttp.status == 200)
-          this.oncomplete(this);
-        else
-          this.onerror(this);
-
-        this.busy = false;
-        }
-      catch(err)
-        {
-        this.onerror(this);
-        this.busy = false;
-        }
-      }
-    }
-
-  // getter method for HTTP headers
-  this.get_header = function(name)
-    {
-    return this.xmlhttp.getResponseHeader(name);
-    };
-
-  this.get_text = function()
-    {
-    return this.xmlhttp.responseText;
-    };
-
-  this.get_xml = function()
-    {
-    return this.xmlhttp.responseXML;
-    };
-
-  this.reset();
-  
-  }  // end class rcube_http_request
-
-// helper function to call the init method with a delay
-function call_init(o)
-  {
-    window.setTimeout('if (window[\''+o+'\'] && window[\''+o+'\'].init) { '+o+'.init(); }',
-        bw.win ? 500 : 200);
-  }
-
index f6ab5692987937270897b02636d65e9b43cda8f3..cf3a8659a871d26ff7593f9607a9a748deb1217a 100644 (file)
-var CONTROL_KEY=1;
-var SHIFT_KEY=2;
-var CONTROL_SHIFT_KEY=3;
-function roundcube_browser(){
-this.ver=parseFloat(navigator.appVersion);
-this.appver=navigator.appVersion;
-this.agent=navigator.userAgent;
-this.name=navigator.appName;
-this.vendor=navigator.vendor?navigator.vendor:"";
-this.vendver=navigator.vendorSub?parseFloat(navigator.vendorSub):0;
-this.product=navigator.product?navigator.product:"";
-this.platform=String(navigator.platform).toLowerCase();
-this.lang=(navigator.language)?navigator.language.substring(0,2):(navigator.browserLanguage)?navigator.browserLanguage.substring(0,2):(navigator.systemLanguage)?navigator.systemLanguage.substring(0,2):"en";
-this.win=(this.platform.indexOf("win")>=0)?true:false;
-this.mac=(this.platform.indexOf("mac")>=0)?true:false;
-this.linux=(this.platform.indexOf("linux")>=0)?true:false;
-this.unix=(this.platform.indexOf("unix")>=0)?true:false;
-this.dom=document.getElementById?true:false;
-this.dom2=(document.addEventListener&&document.removeEventListener);
-this.ie=(document.all)?true:false;
-this.ie4=(this.ie&&!this.dom);
-this.ie5=(this.dom&&this.appver.indexOf("MSIE 5")>0);
-this.ie6=(this.dom&&this.appver.indexOf("MSIE 6")>0);
-this.ie7=(this.dom&&this.appver.indexOf("MSIE 7")>0);
-this.mz=(this.dom&&this.ver>=5);
-this.ns=((this.ver<5&&this.name=="Netscape")||(this.ver>=5&&this.vendor.indexOf("Netscape")>=0));
-this.ns6=(this.ns&&parseInt(this.vendver)==6);
-this.ns7=(this.ns&&parseInt(this.vendver)==7);
-this.safari=(this.agent.toLowerCase().indexOf("safari")>0||this.agent.toLowerCase().indexOf("applewebkit")>0);
-this.konq=(this.agent.toLowerCase().indexOf("konqueror")>0);
-this.opera=(window.opera)?true:false;
-if(this.opera&&window.RegExp){
-this.vendver=(/opera(\s|\/)([0-9\.]+)/i.test(navigator.userAgent))?parseFloat(RegExp.$2):-1;
-}else{
-if(!this.vendver&&this.safari){
-this.vendver=(/(safari|applewebkit)\/([0-9]+)/i.test(this.agent))?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\.]+)/i.test(this.agent))?parseFloat(RegExp.$1):0;
-}else{
-if(this.konq&&window.RegExp){
-this.vendver=(/khtml\/([0-9\.]+)/i.test(this.agent))?parseFloat(RegExp.$1):0;
-}
-}
-}
-}
-}
-if(this.safari&&(/;\s+([a-z]{2})-[a-z]{2}\)/i.test(this.agent))){
-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=navigator.cookieEnabled;
-this.xmlhttp_test=function(){
-var _1=new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");
-this.xmlhttp=(window.XMLHttpRequest||(window.ActiveXObject&&_1()))?true:false;
-return this.xmlhttp;
-};
-};
-var rcube_event={get_target:function(e){
-e=e||window.event;
-return e&&e.target?e.target:e.srcElement;
-},get_keycode:function(e){
-e=e||window.event;
-return e&&e.keyCode?e.keyCode:(e&&e.which?e.which:0);
-},get_button:function(e){
-e=e||window.event;
-return e&&(typeof e.button!="undefined")?e.button:(e&&e.which?e.which:0);
-},get_modifier:function(e){
-var _6=0;
-e=e||window.event;
-if(bw.mac&&e){
-_6+=(e.metaKey&&CONTROL_KEY)+(e.shiftKey&&SHIFT_KEY);
-return _6;
-}
-if(e){
-_6+=(e.ctrlKey&&CONTROL_KEY)+(e.shiftKey&&SHIFT_KEY);
-return _6;
-}
-},get_mouse_pos:function(e){
-if(!e){
-e=window.event;
-}
-var mX=(e.pageX)?e.pageX:e.clientX;
-var mY=(e.pageY)?e.pageY:e.clientY;
-if(document.body&&document.all){
-mX+=document.body.scrollLeft;
-mY+=document.body.scrollTop;
-}
-if(e._offset){
-mX+=e._offset.x;
-mY+=e._offset.y;
-}
-return {x:mX,y:mY};
-},add_listener:function(p){
-if(!p.object||!p.method){
-return;
-}
-if(!p.element){
-p.element=document;
-}
-if(!p.object._rc_events){
-p.object._rc_events=[];
-}
-var _b=p.event+"*"+p.method;
-if(!p.object._rc_events[_b]){
-p.object._rc_events[_b]=function(e){
-return p.object[p.method](e);
-};
-}
-if(p.element.addEventListener){
-p.element.addEventListener(p.event,p.object._rc_events[_b],false);
-}else{
-if(p.element.attachEvent){
-p.element.detachEvent("on"+p.event,p.object._rc_events[_b]);
-p.element.attachEvent("on"+p.event,p.object._rc_events[_b]);
-}else{
-p.element["on"+p.event]=p.object._rc_events[_b];
-}
-}
-},remove_listener:function(p){
-if(!p.element){
-p.element=document;
-}
-var _e=p.event+"*"+p.method;
-if(p.object&&p.object._rc_events&&p.object._rc_events[_e]){
-if(p.element.removeEventListener){
-p.element.removeEventListener(p.event,p.object._rc_events[_e],false);
-}else{
-if(p.element.detachEvent){
-p.element.detachEvent("on"+p.event,p.object._rc_events[_e]);
-}else{
-p.element["on"+p.event]=null;
-}
-}
-}
-},cancel:function(_f){
-var e=_f?_f:window.event;
-if(e.preventDefault){
-e.preventDefault();
-}
-if(e.stopPropagation){
-e.stopPropagation();
-}
-e.cancelBubble=true;
-e.returnValue=false;
-return false;
-}};
-var rcube_layer_objects=new Array();
-function rcube_layer(id,_12){
-this.name=id;
-this.create=function(arg){
-var l=(arg.x)?arg.x:0;
-var t=(arg.y)?arg.y:0;
-var w=arg.width;
-var h=arg.height;
-var z=arg.zindex;
-var vis=arg.vis;
-var _1a=arg.parent;
-var obj;
-obj=document.createElement("DIV");
-with(obj){
-id=this.name;
-with(style){
-position="absolute";
-visibility=(vis)?(vis==2)?"inherit":"visible":"hidden";
-left=l+"px";
-top=t+"px";
-if(w){
-width=w.toString().match(/\%$/)?w:w+"px";
-}
-if(h){
-height=h.toString().match(/\%$/)?h:h+"px";
-}
-if(z){
-zIndex=z;
-}
-}
-}
-if(_1a){
-_1a.appendChild(obj);
-}else{
-document.body.appendChild(obj);
-}
-this.elm=obj;
-};
-if(_12!=null){
-this.create(_12);
-this.name=this.elm.id;
-}else{
-this.elm=document.getElementById(id);
-}
-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.id=rcube_layer_objects.length;
-this.obj="rcube_layer_objects["+this.id+"]";
-rcube_layer_objects[this.id]=this;
-this.move=function(x,y){
-this.x=x;
-this.y=y;
-this.css.left=Math.round(this.x)+"px";
-this.css.top=Math.round(this.y)+"px";
-};
-this.shift=function(x,y){
-x=Math.round(x*100)/100;
-y=Math.round(y*100)/100;
-this.move(this.x+x,this.y+y);
-};
-this.resize=function(w,h){
-this.css.width=w+"px";
-this.css.height=h+"px";
-this.width=w;
-this.height=h;
-};
-this.clip=function(t,w,h,l){
-this.css.clip="rect("+t+" "+w+" "+h+" "+l+")";
-this.clip_height=h;
-this.clip_width=w;
-};
-this.show=function(a){
-if(a==1){
-this.css.visibility="visible";
-this.visible=true;
-}else{
-if(a==2){
-this.css.visibility="inherit";
-this.visible=true;
-}else{
-this.css.visibility="hidden";
-this.visible=false;
-}
-}
-};
-this.write=function(_27){
-this.elm.innerHTML=_27;
-};
-this.set_bgcolor=function(c){
-if(!c||c=="#"){
-c="transparent";
-}
-this.css.backgroundColor=c;
-};
-this.set_opacity=function(v){
-if(!bw.opacity){
-return;
-}
-var op=v<=1?Math.round(v*100):parseInt(v);
-if(bw.ie){
-this.css.filter="alpha(opacity:"+op+")";
-}else{
-if(bw.safari){
-this.css.opacity=op/100;
-this.css.KhtmlOpacity=op/100;
-}else{
-if(bw.mz){
-this.css.MozOpacity=op/100;
-}
-}
-}
-};
-};
-function rcube_check_email(_2b,_2c){
-if(_2b&&window.RegExp){
-var _2d="[^\\x0d\\x22\\x5c\\x80-\\xff]";
-var _2e="[^\\x0d\\x5b-\\x5d\\x80-\\xff]";
-var _2f="[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+";
-var _30="\\x5c[\\x00-\\x7f]";
-var _31="\\x5b("+_2e+"|"+_30+")*\\x5d";
-var _32="\\x22("+_2d+"|"+_30+")*\\x22";
-var _33="("+_2f+"|"+_31+")";
-var _34="("+_2f+"|"+_32+")";
-var _35=_33+"(\\x2e"+_33+")*";
-var _36=_34+"(\\x2e"+_34+")*";
-var _37=_36+"\\x40"+_35;
-var _38="[,;s\n]";
-var _39=_2c?new RegExp("(^|<|"+_38+")"+_37+"($|>|"+_38+")","i"):new RegExp("^"+_37+"$","i");
-return _39.test(_2b)?true:false;
-}
-return false;
-};
-function find_in_array(){
-var _3a=find_in_array.arguments;
-if(!_3a.length){
-return -1;
-}
-var _3b=typeof (_3a[0])=="object"?_3a[0]:_3a.length>1&&typeof (_3a[1])=="object"?_3a[1]:new Array();
-var _3c=typeof (_3a[0])!="object"?_3a[0]:_3a.length>1&&typeof (_3a[1])!="object"?_3a[1]:"";
-var _3d=_3a.length==3?_3a[2]:false;
-if(!_3b.length){
-return -1;
-}
-for(var i=0;i<_3b.length;i++){
-if(_3d&&_3b[i].toLowerCase()==_3c.toLowerCase()){
-return i;
-}else{
-if(_3b[i]==_3c){
-return i;
-}
-}
-}
-return -1;
-};
-function urlencode(str){
-return window.encodeURIComponent?encodeURIComponent(str):escape(str);
-};
-function rcube_find_object(id,d){
-var n,f,obj,e;
-if(!d){
-d=document;
-}
-if(d.getElementsByName&&(e=d.getElementsByName(id))){
-obj=e[0];
-}
-if(!obj&&d.getElementById){
-obj=d.getElementById(id);
-}
-if(!obj&&d.all){
-obj=d.all[id];
-}
-if(!obj&&d.images.length){
-obj=d.images[id];
-}
-if(!obj&&d.forms.length){
-for(f=0;f<d.forms.length;f++){
-if(d.forms[f].name==id){
-obj=d.forms[f];
-}else{
-if(d.forms[f].elements[id]){
-obj=d.forms[f].elements[id];
-}
-}
-}
-}
-if(!obj&&d.layers){
-if(d.layers[id]){
-obj=d.layers[id];
-}
-for(n=0;!obj&&n<d.layers.length;n++){
-obj=rcube_find_object(id,d.layers[n].document);
-}
-}
-return obj;
-};
-function rcube_get_object_pos(obj,_47){
-if(typeof (obj)=="string"){
-obj=rcube_find_object(obj);
-}
-if(!obj){
-return {x:0,y:0};
-}
-var iX=(bw.layers)?obj.x:obj.offsetLeft;
-var iY=(bw.layers)?obj.y:obj.offsetTop;
-if(!_47&&(bw.ie||bw.mz)){
-var elm=obj.offsetParent;
-while(elm&&elm!=null){
-iX+=elm.offsetLeft-(elm.parentNode&&elm.parentNode.scrollLeft?elm.parentNode.scrollLeft:0);
-iY+=elm.offsetTop-(elm.parentNode&&elm.parentNode.scrollTop?elm.parentNode.scrollTop:0);
-elm=elm.offsetParent;
-}
-}
-return {x:iX,y:iY};
-};
-function rcube_mouse_is_over(ev,obj){
-var _4d=rcube_event.get_mouse_pos(ev);
-var pos=rcube_get_object_pos(obj);
-return ((_4d.x>=pos.x)&&(_4d.x<(pos.x+obj.offsetWidth))&&(_4d.y>=pos.y)&&(_4d.y<(pos.y+obj.offsetHeight)));
-};
-function get_elements_computed_style(_4f,_50,_51){
-if(arguments.length==2){
-_51=_50;
-}
-var el=_4f;
-if(typeof (_4f)=="string"){
-el=rcube_find_object(_4f);
-}
-if(el&&el.currentStyle){
-return el.currentStyle[_50];
-}else{
-if(el&&document.defaultView&&document.defaultView.getComputedStyle){
-return document.defaultView.getComputedStyle(el,null).getPropertyValue(_51);
-}else{
-return false;
-}
-}
-};
-function setCookie(_53,_54,_55,_56,_57,_58){
-var _59=_53+"="+escape(_54)+(_55?"; expires="+_55.toGMTString():"")+(_56?"; path="+_56:"")+(_57?"; domain="+_57:"")+(_58?"; secure":"");
-document.cookie=_59;
-};
-roundcube_browser.prototype.set_cookie=setCookie;
-function getCookie(_5a){
-var dc=document.cookie;
-var _5c=_5a+"=";
-var _5d=dc.indexOf("; "+_5c);
-if(_5d==-1){
-_5d=dc.indexOf(_5c);
-if(_5d!=0){
-return null;
-}
-}else{
-_5d+=2;
-}
-var end=document.cookie.indexOf(";",_5d);
-if(end==-1){
-end=dc.length;
+/*
+ +-----------------------------------------------------------------------+
+ | RoundCube common js library                                           |
+ |                                                                       |
+ | This file is part of the RoundCube web development suite              |
+ | Copyright (C) 2005-2007, RoundCube Dev, - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+ $Id: common.js 2721 2009-07-07 17:23:55Z alec $
+*/
+
+// Constants
+var CONTROL_KEY = 1;
+var SHIFT_KEY = 2;
+var CONTROL_SHIFT_KEY = 3;
+
+
+/**
+ * Default browser check class
+ * @construcotr
+ */
+function roundcube_browser()
+  {
+  this.ver = parseFloat(navigator.appVersion);
+  this.appver = navigator.appVersion;
+  this.agent = navigator.userAgent;
+  this.name = navigator.appName;
+  this.vendor = navigator.vendor ? navigator.vendor : '';
+  this.vendver = navigator.vendorSub ? parseFloat(navigator.vendorSub) : 0;
+  this.product = navigator.product ? navigator.product : '';
+  this.platform = String(navigator.platform).toLowerCase();
+  this.lang = (navigator.language) ? navigator.language.substring(0,2) :
+              (navigator.browserLanguage) ? navigator.browserLanguage.substring(0,2) :
+              (navigator.systemLanguage) ? navigator.systemLanguage.substring(0,2) : 'en';
+
+  this.win = (this.platform.indexOf('win')>=0) ? true : false;
+  this.mac = (this.platform.indexOf('mac')>=0) ? true : false;
+  this.linux = (this.platform.indexOf('linux')>=0) ? true : false;
+  this.unix = (this.platform.indexOf('unix')>=0) ? true : false;
+
+  this.dom = document.getElementById ? true : false;
+  this.dom2 = (document.addEventListener && document.removeEventListener);
+
+  this.ie = (document.all) ? true : false;
+  this.ie4 = (this.ie && !this.dom);
+  this.ie5 = (this.dom && this.appver.indexOf('MSIE 5')>0);
+  this.ie6 = (this.dom && this.appver.indexOf('MSIE 6')>0);
+  this.ie7 = (this.dom && this.appver.indexOf('MSIE 7')>0);
+
+  this.mz = (this.dom && this.ver>=5);  // (this.dom && this.product=='Gecko')
+  this.ns = ((this.ver<5 && this.name=='Netscape') || (this.ver>=5 && this.vendor.indexOf('Netscape')>=0));
+  this.ns6 = (this.ns && parseInt(this.vendver)==6);  // (this.mz && this.ns) ? true : false;
+  this.ns7 = (this.ns && parseInt(this.vendver)==7);  // this.agent.indexOf('Netscape/7')>0);
+  this.safari = (this.agent.toLowerCase().indexOf('safari')>0 || this.agent.toLowerCase().indexOf('applewebkit')>0);
+  this.konq   = (this.agent.toLowerCase().indexOf('konqueror')>0);
+
+  this.opera = (window.opera) ? true : false;
+
+  if(this.opera && window.RegExp)
+    this.vendver = (/opera(\s|\/)([0-9\.]+)/i.test(navigator.userAgent)) ? parseFloat(RegExp.$2) : -1;
+  else if(!this.vendver && this.safari)
+    this.vendver = (/(safari|applewebkit)\/([0-9]+)/i.test(this.agent)) ? 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\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
+  else if(this.konq && window.RegExp)
+    this.vendver = (/khtml\/([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
+
+
+  // get real language out of safari's user agent
+  if(this.safari && (/;\s+([a-z]{2})-[a-z]{2}\)/i.test(this.agent)))
+    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 = navigator.cookieEnabled;
+  
+  // test for XMLHTTP support
+  this.xmlhttp_test = function()
+    {
+    var activeX_test = new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");
+    this.xmlhttp = (window.XMLHttpRequest || (window.ActiveXObject && activeX_test())) ? true : false;
+    return this.xmlhttp;
+    }
+  }
+
+
+// static functions for DOM event handling
+var rcube_event = {
+
+/**
+ * returns the event target element
+ */
+get_target: function(e)
+{
+  e = e || window.event;
+  return e && e.target ? e.target : e.srcElement;
+},
+
+/**
+ * returns the event key code
+ */
+get_keycode: function(e)
+{
+  e = e || window.event;
+  return e && e.keyCode ? e.keyCode : (e && e.which ? e.which : 0);
+},
+
+/**
+ * returns the event key code
+ */
+get_button: function(e)
+{
+  e = e || window.event;
+  return e && (typeof e.button != 'undefined') ? e.button : (e && e.which ? e.which : 0);
+},
+
+/**
+ * returns modifier key (constants defined at top of file)
+ */
+get_modifier: function(e)
+{
+  var opcode = 0;
+  e = e || window.event;
+
+  if (bw.mac && e)
+    {
+    opcode += (e.metaKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
+    return opcode;    
+    }
+  if (e)
+    {
+    opcode += (e.ctrlKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
+    return opcode;
+    }
+},
+
+/**
+ * Return absolute mouse position of an event
+ */
+get_mouse_pos: function(e)
+{
+  if (!e) e = window.event;
+  var mX = (e.pageX) ? e.pageX : e.clientX;
+  var mY = (e.pageY) ? e.pageY : e.clientY;
+
+  if (document.body && document.all)
+  {
+    mX += document.body.scrollLeft;
+    mY += document.body.scrollTop;
+  }
+
+  if (e._offset) {
+    mX += e._offset.left;
+    mY += e._offset.top;
+  }
+
+  return { x:mX, y:mY };
+},
+
+/**
+ * Add an object method as event listener to a certain element
+ */
+add_listener: function(p)
+{
+  if (!p.object || !p.method)  // not enough arguments
+    return;
+  if (!p.element)
+    p.element = document;
+
+  if (!p.object._rc_events)
+    p.object._rc_events = [];
+  
+  var key = p.event + '*' + p.method;
+  if (!p.object._rc_events[key])
+    p.object._rc_events[key] = function(e){ return p.object[p.method](e); };
+
+  if (p.element.addEventListener)
+    p.element.addEventListener(p.event, p.object._rc_events[key], false);
+  else if (p.element.attachEvent)
+    {
+    // IE allows multiple events with the same function to be applied to the same object
+    // forcibly detach the event, then attach
+    p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
+    p.element.attachEvent('on'+p.event, p.object._rc_events[key]);
+    }
+  else
+    p.element['on'+p.event] = p.object._rc_events[key];
+},
+
+/**
+ * Remove event listener
+ */
+remove_listener: function(p)
+{
+  if (!p.element)
+    p.element = document;
+
+  var key = p.event + '*' + p.method;
+  if (p.object && p.object._rc_events && p.object._rc_events[key]) {
+    if (p.element.removeEventListener)
+      p.element.removeEventListener(p.event, p.object._rc_events[key], false);
+    else if (p.element.detachEvent)
+      p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
+    else
+      p.element['on'+p.event] = null;
+  }
+},
+
+/**
+ * Prevent event propagation and bubbeling
+ */
+cancel: function(evt)
+{
+  var e = evt ? evt : window.event;
+  if (e.preventDefault)
+    e.preventDefault();
+  if (e.stopPropagation)
+    e.stopPropagation();
+
+  e.cancelBubble = true;
+  e.returnValue = false;
+  return false;
 }
-return unescape(dc.substring(_5d+_5c.length,end));
+
 };
-roundcube_browser.prototype.get_cookie=getCookie;
-function rcube_console(){
-this.log=function(msg){
-var box=rcube_find_object("console");
-if(box){
-if(msg.charAt(msg.length-1)=="\n"){
-msg+="--------------------------------------\n";
-}else{
-msg+="\n--------------------------------------\n";
-}
-if(bw.konq){
-box.innerText+=msg;
-box.value=box.innerText;
-}else{
-box.value+=msg;
-}
+
+
+/**
+ * rcmail objects event interface
+ */
+function rcube_event_engine()
+{
+  this._events = {};
 }
-};
-this.reset=function(){
-var box=rcube_find_object("console");
-if(box){
-box.innerText=box.value="";
+
+rcube_event_engine.prototype = {
+
+/**
+ * Setter for object event handlers
+ *
+ * @param {String}   Event name
+ * @param {Function} Handler function
+ * @return Listener ID (used to remove this handler later on)
+ */
+addEventListener: function(evt, func, obj)
+{
+  if (!this._events)
+    this._events = {};
+  if (!this._events[evt])
+    this._events[evt] = [];
+    
+  var e = {func:func, obj:obj ? obj : window};
+  this._events[evt][this._events[evt].length] = e;
+},
+
+/**
+ * Removes a specific event listener
+ *
+ * @param {String} Event name
+ * @param {Int}    Listener ID to remove
+ */
+removeEventListener: function(evt, func, obj)
+{
+  if (typeof obj == 'undefined')
+    obj = window;
+    
+  for (var h,i=0; this._events && this._events[evt] && i < this._events[evt].length; i++)
+    if ((h = this._events[evt][i]) && h.func == func && h.obj == obj)
+      this._events[evt][i] = null;
+},
+
+/**
+ * This will execute all registered event handlers
+ *
+ * @param {String} Event to trigger
+ * @param {Object} Event object/arguments
+ */
+triggerEvent: function(evt, e)
+{
+  var ret, h;
+  if (typeof e == 'undefined')
+    e = this;
+  else if (typeof e == 'object')
+    e.event = evt;
+  
+  if (this._events && this._events[evt] && !this._event_exec) {
+    this._event_exec = true;
+    for (var i=0; i < this._events[evt].length; i++) {
+      if ((h = this._events[evt][i])) {
+        if (typeof h.func == 'function')
+          ret = h.func.call ? h.func.call(h.obj, e) : h.func(e);
+        else if (typeof h.obj[h.func] == 'function')
+          ret = h.obj[h.func](e);
+              
+        // cancel event execution
+        if (typeof ret != 'undefined' && !ret)
+          break;
+      }
+    }
+  }
+
+  this._event_exec = false;
+  return ret;
 }
-};
-};
-var bw=new roundcube_browser();
-if(!window.console){
-var console=new rcube_console();
+
+}  // end rcube_event_engine.prototype
+
+
+
+/**
+ * RoundCube generic layer (floating box) class
+ *
+ * @constructor
+ */
+function rcube_layer(id, attributes)
+{
+  this.name = id;
+  
+  // create a new layer in the current document
+  this.create = function(arg)
+    {
+    var l = (arg.x) ? arg.x : 0;
+    var t = (arg.y) ? arg.y : 0;
+    var w = arg.width;
+    var h = arg.height;
+    var z = arg.zindex;
+    var vis = arg.vis;
+    var parent = arg.parent;
+    var obj;
+
+    obj = document.createElement('DIV');
+
+    with(obj)
+      {
+      id = this.name;
+      with(style)
+        {
+       position = 'absolute';
+        visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden';
+        left = l+'px';
+        top = t+'px';
+        if (w)
+         width = w.toString().match(/\%$/) ? w : w+'px';
+        if (h)
+         height = h.toString().match(/\%$/) ? h : h+'px';
+        if(z) zIndex = z;
+       }
+      }
+
+    if (parent)
+      parent.appendChild(obj);
+    else
+      document.body.appendChild(obj);
+
+    this.elm = obj;
+    };
+
+
+  // create new layer
+  if(attributes!=null)
+    {
+    this.create(attributes);
+    this.name = this.elm.id;
+    }
+  else  // just refer to the object
+    this.elm = document.getElementById(id);
+
+
+  if(!this.elm)
+    return false;
+
+
+  // ********* layer object properties *********
+
+  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;
+
+
+  // ********* layer object methods *********
+
+
+  // move the layer to a specific position
+  this.move = function(x, y)
+    {
+    this.x = x;
+    this.y = y;
+    this.css.left = Math.round(this.x)+'px';
+    this.css.top = Math.round(this.y)+'px';
+    }
+
+  // change the layers width and height
+  this.resize = function(w,h)
+    {
+    this.css.width  = w+'px';
+    this.css.height = h+'px';
+    this.width = w;
+    this.height = h;
+    }
+
+
+  // show or hide the layer
+  this.show = function(a)
+    {
+    if(a==1)
+      {
+      this.css.visibility = 'visible';
+      this.visible = true;
+      }
+    else if(a==2)
+      {
+      this.css.visibility = 'inherit';
+      this.visible = true;
+      }
+    else
+      {
+      this.css.visibility = 'hidden';
+      this.visible = false;
+      }
+    }
+
+
+  // write new content into a Layer
+  this.write = function(cont)
+    {
+    this.elm.innerHTML = cont;
+    }
+
 }
-RegExp.escape=function(str){
-return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1");
-};
-if(bw.ie){
-document._getElementById=document.getElementById;
-document.getElementById=function(id){
-var i=0;
-var o=document._getElementById(id);
-if(!o||o.id!=id){
-while((o=document.all[i])&&o.id!=id){
-i++;
+
+
+// check if input is a valid email address
+// By Cal Henderson <cal@iamcal.com>
+// http://code.iamcal.com/php/rfc822/
+function rcube_check_email(input, inline)
+  {
+  if (input && window.RegExp)
+    {
+    var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
+    var dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
+    var atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
+    var quoted_pair = '\\x5c[\\x00-\\x7f]';
+    var domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d';
+    var quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22';
+    var sub_domain = '('+atom+'|'+domain_literal+')';
+    var word = '('+atom+'|'+quoted_string+')';
+    var domain = sub_domain+'(\\x2e'+sub_domain+')*';
+    var local_part = word+'(\\x2e'+word+')*';
+    var addr_spec = local_part+'\\x40'+domain;
+    var delim = '[,;\s\n]';
+    var reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i');
+    return reg1.test(input) ? true : false;
+    }
+  return false;
+  }
+  
+
+// find a value in a specific array and returns the index
+function find_in_array()
+  {
+  var args = find_in_array.arguments;
+  if(!args.length) return -1;
+
+  var haystack = typeof(args[0])=='object' ? args[0] : args.length>1 && typeof(args[1])=='object' ? args[1] : new Array();
+  var needle = typeof(args[0])!='object' ? args[0] : args.length>1 && typeof(args[1])!='object' ? args[1] : '';
+  var nocase = args.length==3 ? args[2] : false;
+
+  if(!haystack.length) return -1;
+
+  for(var i=0; i<haystack.length; i++)
+    if(nocase && haystack[i].toLowerCase()==needle.toLowerCase())
+      return i;
+    else if(haystack[i]==needle)
+      return i;
+
+  return -1;
+  }
+
+
+// make a string URL safe
+function urlencode(str)
+{
+  return window.encodeURIComponent ? encodeURIComponent(str) : escape(str);
 }
+
+
+// get any type of html objects by id/name
+function rcube_find_object(id, d)
+{
+  var n, f, obj, e;
+  if(!d) d = document;
+
+  if(d.getElementsByName && (e = d.getElementsByName(id)))
+    obj = e[0];
+  if(!obj && d.getElementById)
+    obj = d.getElementById(id);
+  if(!obj && d.all)
+    obj = d.all[id];
+
+  if(!obj && d.images.length)
+    obj = d.images[id];
+
+  if (!obj && d.forms.length) {
+    for (f=0; f<d.forms.length; f++) {
+      if(d.forms[f].name == id)
+        obj = d.forms[f];
+      else if(d.forms[f].elements[id])
+        obj = d.forms[f].elements[id];
+    }
+  }
+
+  if (!obj && d.layers) {
+    if (d.layers[id]) obj = d.layers[id];
+    for (n=0; !obj && n<d.layers.length; n++)
+      obj = rcube_find_object(id, d.layers[n].document);
+  }
+
+  return obj;
 }
-return o;
-};
+
+// determine whether the mouse is over the given object or not
+function rcube_mouse_is_over(ev, obj)
+{
+  var mouse = rcube_event.get_mouse_pos(ev);
+  var pos = $(obj).offset();
+
+  return ((mouse.x >= pos.left) && (mouse.x < (pos.left + obj.offsetWidth)) &&
+    (mouse.y >= pos.top) && (mouse.y < (pos.top + obj.offsetHeight)));
 }
-function exec_event(_66,_67){
-if(document.createEventObject){
-var evt=document.createEventObject();
-return _66.fireEvent("on"+_67,evt);
-}else{
-var evt=document.createEvent("HTMLEvents");
-evt.initEvent(_67,true,true);
-return !_66.dispatchEvent(evt);
+
+
+// cookie functions by GoogieSpell
+function setCookie(name, value, expires, path, domain, secure)
+  {
+  var curCookie = name + "=" + escape(value) +
+      (expires ? "; expires=" + expires.toGMTString() : "") +
+      (path ? "; path=" + path : "") +
+      (domain ? "; domain=" + domain : "") +
+      (secure ? "; secure" : "");
+  document.cookie = curCookie;
+  }
+
+roundcube_browser.prototype.set_cookie = setCookie;
+
+function getCookie(name)
+  {
+  var dc = document.cookie;
+  var prefix = name + "=";
+  var begin = dc.indexOf("; " + prefix);
+  if (begin == -1)
+    {
+    begin = dc.indexOf(prefix);
+    if (begin != 0) return null;
+    }
+  else
+    begin += 2;  
+  var end = document.cookie.indexOf(";", begin);
+  if (end == -1)
+    end = dc.length;
+  return unescape(dc.substring(begin + prefix.length, end));
+  }
+
+roundcube_browser.prototype.get_cookie = getCookie;
+
+// tiny replacement for Firebox functionality
+function rcube_console()
+{
+  this.log = function(msg)
+  {
+    var box = rcube_find_object('dbgconsole');
+
+    if (box) {
+      if (msg.charAt(msg.length-1)=='\n')
+        msg += '--------------------------------------\n';
+      else
+        msg += '\n--------------------------------------\n';
+
+      // Konqueror doesn't allows to just change value of hidden element
+      if (bw.konq) {
+        box.innerText += msg;
+        box.value = box.innerText;
+      } else
+        box.value += msg;
+    }
+  };
+
+  this.reset = function()
+  {
+    var box = rcube_find_object('dbgconsole');
+    if (box)
+      box.innerText = box.value = '';
+  };
 }
-};
 
+var bw = new roundcube_browser();
+if (!window.console) 
+  console = new rcube_console();
+
+
+// Add escape() method to RegExp object
+// http://dev.rubyonrails.org/changeset/7271
+RegExp.escape = function(str)
+  {
+  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+  }
+
+
+// Make getElementById() case-sensitive on IE
+if (bw.ie)
+  {
+  document._getElementById = document.getElementById;
+  document.getElementById = function(id)
+    {
+    var i = 0;
+    var o = document._getElementById(id);
+
+    if (!o || o.id != id)
+      while ((o = document.all[i]) && o.id != id)
+        i++;
+
+    return o;
+    }
+  }
diff --git a/program/js/common.js.src b/program/js/common.js.src
deleted file mode 100644 (file)
index 3f00fa4..0000000
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- +-----------------------------------------------------------------------+
- | RoundCube common js library                                           |
- |                                                                       |
- | This file is part of the RoundCube web development suite              |
- | Copyright (C) 2005-2007, RoundCube Dev, - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Thomas Bruederli <roundcube@gmail.com>                        |
- +-----------------------------------------------------------------------+
- $Id: common.js 2483 2009-05-15 10:22:29Z thomasb $
-*/
-
-// Constants
-var CONTROL_KEY = 1;
-var SHIFT_KEY = 2;
-var CONTROL_SHIFT_KEY = 3;
-
-
-/**
- * Default browser check class
- * @construcotr
- */
-function roundcube_browser()
-  {
-  this.ver = parseFloat(navigator.appVersion);
-  this.appver = navigator.appVersion;
-  this.agent = navigator.userAgent;
-  this.name = navigator.appName;
-  this.vendor = navigator.vendor ? navigator.vendor : '';
-  this.vendver = navigator.vendorSub ? parseFloat(navigator.vendorSub) : 0;
-  this.product = navigator.product ? navigator.product : '';
-  this.platform = String(navigator.platform).toLowerCase();
-  this.lang = (navigator.language) ? navigator.language.substring(0,2) :
-              (navigator.browserLanguage) ? navigator.browserLanguage.substring(0,2) :
-              (navigator.systemLanguage) ? navigator.systemLanguage.substring(0,2) : 'en';
-
-  this.win = (this.platform.indexOf('win')>=0) ? true : false;
-  this.mac = (this.platform.indexOf('mac')>=0) ? true : false;
-  this.linux = (this.platform.indexOf('linux')>=0) ? true : false;
-  this.unix = (this.platform.indexOf('unix')>=0) ? true : false;
-
-  this.dom = document.getElementById ? true : false;
-  this.dom2 = (document.addEventListener && document.removeEventListener);
-
-  this.ie = (document.all) ? true : false;
-  this.ie4 = (this.ie && !this.dom);
-  this.ie5 = (this.dom && this.appver.indexOf('MSIE 5')>0);
-  this.ie6 = (this.dom && this.appver.indexOf('MSIE 6')>0);
-  this.ie7 = (this.dom && this.appver.indexOf('MSIE 7')>0);
-
-  this.mz = (this.dom && this.ver>=5);  // (this.dom && this.product=='Gecko')
-  this.ns = ((this.ver<5 && this.name=='Netscape') || (this.ver>=5 && this.vendor.indexOf('Netscape')>=0));
-  this.ns6 = (this.ns && parseInt(this.vendver)==6);  // (this.mz && this.ns) ? true : false;
-  this.ns7 = (this.ns && parseInt(this.vendver)==7);  // this.agent.indexOf('Netscape/7')>0);
-  this.safari = (this.agent.toLowerCase().indexOf('safari')>0 || this.agent.toLowerCase().indexOf('applewebkit')>0);
-  this.konq   = (this.agent.toLowerCase().indexOf('konqueror')>0);
-
-  this.opera = (window.opera) ? true : false;
-
-  if(this.opera && window.RegExp)
-    this.vendver = (/opera(\s|\/)([0-9\.]+)/i.test(navigator.userAgent)) ? parseFloat(RegExp.$2) : -1;
-  else if(!this.vendver && this.safari)
-    this.vendver = (/(safari|applewebkit)\/([0-9]+)/i.test(this.agent)) ? 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\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
-  else if(this.konq && window.RegExp)
-    this.vendver = (/khtml\/([0-9\.]+)/i.test(this.agent)) ? parseFloat(RegExp.$1) : 0;
-
-
-  // get real language out of safari's user agent
-  if(this.safari && (/;\s+([a-z]{2})-[a-z]{2}\)/i.test(this.agent)))
-    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 = navigator.cookieEnabled;
-  
-  // test for XMLHTTP support
-  this.xmlhttp_test = function()
-    {
-    var activeX_test = new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");
-    this.xmlhttp = (window.XMLHttpRequest || (window.ActiveXObject && activeX_test())) ? true : false;
-    return this.xmlhttp;
-    }
-  }
-
-
-// static functions for event handling
-var rcube_event = {
-
-/**
- * returns the event target element
- */
-get_target: function(e)
-{
-  e = e || window.event;
-  return e && e.target ? e.target : e.srcElement;
-},
-
-/**
- * returns the event key code
- */
-get_keycode: function(e)
-{
-  e = e || window.event;
-  return e && e.keyCode ? e.keyCode : (e && e.which ? e.which : 0);
-},
-
-/**
- * returns the event key code
- */
-get_button: function(e)
-{
-  e = e || window.event;
-  return e && (typeof e.button != 'undefined') ? e.button : (e && e.which ? e.which : 0);
-},
-
-/**
- * returns modifier key (constants defined at top of file)
- */
-get_modifier: function(e)
-{
-  var opcode = 0;
-  e = e || window.event;
-
-  if (bw.mac && e)
-    {
-    opcode += (e.metaKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
-    return opcode;    
-    }
-  if (e)
-    {
-    opcode += (e.ctrlKey && CONTROL_KEY) + (e.shiftKey && SHIFT_KEY);
-    return opcode;
-    }
-},
-
-/**
- * Return absolute mouse position of an event
- */
-get_mouse_pos: function(e)
-{
-  if (!e) e = window.event;
-  var mX = (e.pageX) ? e.pageX : e.clientX;
-  var mY = (e.pageY) ? e.pageY : e.clientY;
-
-  if (document.body && document.all)
-  {
-    mX += document.body.scrollLeft;
-    mY += document.body.scrollTop;
-  }
-
-  if (e._offset) {
-    mX += e._offset.x;
-    mY += e._offset.y;
-  }
-
-  return { x:mX, y:mY };
-},
-
-/**
- * Add an object method as event listener to a certain element
- */
-add_listener: function(p)
-{
-  if (!p.object || !p.method)  // not enough arguments
-    return;
-  if (!p.element)
-    p.element = document;
-
-  if (!p.object._rc_events)
-    p.object._rc_events = [];
-  
-  var key = p.event + '*' + p.method;
-  if (!p.object._rc_events[key])
-    p.object._rc_events[key] = function(e){ return p.object[p.method](e); };
-
-  if (p.element.addEventListener)
-    p.element.addEventListener(p.event, p.object._rc_events[key], false);
-  else if (p.element.attachEvent)
-    {
-    // IE allows multiple events with the same function to be applied to the same object
-    // forcibly detach the event, then attach
-    p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
-    p.element.attachEvent('on'+p.event, p.object._rc_events[key]);
-    }
-  else
-    p.element['on'+p.event] = p.object._rc_events[key];
-},
-
-/**
- * Remove event listener
- */
-remove_listener: function(p)
-{
-  if (!p.element)
-    p.element = document;
-
-  var key = p.event + '*' + p.method;
-  if (p.object && p.object._rc_events && p.object._rc_events[key]) {
-    if (p.element.removeEventListener)
-      p.element.removeEventListener(p.event, p.object._rc_events[key], false);
-    else if (p.element.detachEvent)
-      p.element.detachEvent('on'+p.event, p.object._rc_events[key]);
-    else
-      p.element['on'+p.event] = null;
-  }
-},
-
-/**
- * Prevent event propagation and bubbeling
- */
-cancel: function(evt)
-{
-  var e = evt ? evt : window.event;
-  if (e.preventDefault)
-    e.preventDefault();
-  if (e.stopPropagation)
-    e.stopPropagation();
-
-  e.cancelBubble = true;
-  e.returnValue = false;
-  return false;
-}
-
-};
-
-
-var rcube_layer_objects = new Array();
-
-
-/**
- * RoundCube generic layer (floating box) class
- *
- * @constructor
- */
-function rcube_layer(id, attributes)
-  {
-  this.name = id;
-  
-  // create a new layer in the current document
-  this.create = function(arg)
-    {
-    var l = (arg.x) ? arg.x : 0;
-    var t = (arg.y) ? arg.y : 0;
-    var w = arg.width;
-    var h = arg.height;
-    var z = arg.zindex;
-    var vis = arg.vis;
-    var parent = arg.parent;
-    var obj;
-
-    obj = document.createElement('DIV');
-
-    with(obj)
-      {
-      id = this.name;
-      with(style)
-        {
-       position = 'absolute';
-        visibility = (vis) ? (vis==2) ? 'inherit' : 'visible' : 'hidden';
-        left = l+'px';
-        top = t+'px';
-        if (w)
-         width = w.toString().match(/\%$/) ? w : w+'px';
-        if (h)
-         height = h.toString().match(/\%$/) ? h : h+'px';
-        if(z) zIndex = z;
-       }
-      }
-
-    if (parent)
-      parent.appendChild(obj);
-    else
-      document.body.appendChild(obj);
-
-    this.elm = obj;
-    };
-
-
-  // create new layer
-  if(attributes!=null)
-    {
-    this.create(attributes);
-    this.name = this.elm.id;
-    }
-  else  // just refer to the object
-    this.elm = document.getElementById(id);
-
-
-  if(!this.elm)
-    return false;
-
-
-  // ********* layer object properties *********
-
-  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.id = rcube_layer_objects.length;
-  this.obj = 'rcube_layer_objects['+this.id+']';
-  rcube_layer_objects[this.id] = this;
-
-
-  // ********* layer object methods *********
-
-
-  // move the layer to a specific position
-  this.move = function(x, y)
-    {
-    this.x = x;
-    this.y = y;
-    this.css.left = Math.round(this.x)+'px';
-    this.css.top = Math.round(this.y)+'px';
-    }
-
-
-  // move the layer for a specific step
-  this.shift = function(x,y)
-    {
-    x = Math.round(x*100)/100;
-    y = Math.round(y*100)/100;
-    this.move(this.x+x, this.y+y);
-    }
-
-
-  // change the layers width and height
-  this.resize = function(w,h)
-    {
-    this.css.width  = w+'px';
-    this.css.height = h+'px';
-    this.width = w;
-    this.height = h;
-    }
-
-
-  // cut the layer (top,width,height,left)
-  this.clip = function(t,w,h,l)
-    {
-    this.css.clip='rect('+t+' '+w+' '+h+' '+l+')';
-    this.clip_height = h;
-    this.clip_width = w;
-    }
-
-
-  // show or hide the layer
-  this.show = function(a)
-    {
-    if(a==1)
-      {
-      this.css.visibility = 'visible';
-      this.visible = true;
-      }
-    else if(a==2)
-      {
-      this.css.visibility = 'inherit';
-      this.visible = true;
-      }
-    else
-      {
-      this.css.visibility = 'hidden';
-      this.visible = false;
-      }
-    }
-
-
-  // write new content into a Layer
-  this.write = function(cont)
-    {
-    this.elm.innerHTML = cont;
-    }
-
-
-  // set the given color to the layer background
-  this.set_bgcolor = function(c)
-    {
-    if(!c || c=='#')
-      c = 'transparent';
-
-    this.css.backgroundColor = c;
-    }
-
-
-  // set the opacity of a layer to the given ammount (in %)
-  this.set_opacity = function(v)
-    {
-    if(!bw.opacity)
-      return;
-
-    var op = v<=1 ? Math.round(v*100) : parseInt(v);
-
-    if(bw.ie)
-      this.css.filter = 'alpha(opacity:'+op+')';
-    else if(bw.safari)
-      {
-      this.css.opacity = op/100;
-      this.css.KhtmlOpacity = op/100;
-      }
-    else if(bw.mz)
-      this.css.MozOpacity = op/100;
-    }
-  }
-
-
-// check if input is a valid email address
-// By Cal Henderson <cal@iamcal.com>
-// http://code.iamcal.com/php/rfc822/
-function rcube_check_email(input, inline)
-  {
-  if (input && window.RegExp)
-    {
-    var qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
-    var dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
-    var atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
-    var quoted_pair = '\\x5c[\\x00-\\x7f]';
-    var domain_literal = '\\x5b('+dtext+'|'+quoted_pair+')*\\x5d';
-    var quoted_string = '\\x22('+qtext+'|'+quoted_pair+')*\\x22';
-    var sub_domain = '('+atom+'|'+domain_literal+')';
-    var word = '('+atom+'|'+quoted_string+')';
-    var domain = sub_domain+'(\\x2e'+sub_domain+')*';
-    var local_part = word+'(\\x2e'+word+')*';
-    var addr_spec = local_part+'\\x40'+domain;
-    var delim = '[,;\s\n]';
-    var reg1 = inline ? new RegExp('(^|<|'+delim+')'+addr_spec+'($|>|'+delim+')', 'i') : new RegExp('^'+addr_spec+'$', 'i');
-    return reg1.test(input) ? true : false;
-    }
-  return false;
-  }
-  
-
-// find a value in a specific array and returns the index
-function find_in_array()
-  {
-  var args = find_in_array.arguments;
-  if(!args.length) return -1;
-
-  var haystack = typeof(args[0])=='object' ? args[0] : args.length>1 && typeof(args[1])=='object' ? args[1] : new Array();
-  var needle = typeof(args[0])!='object' ? args[0] : args.length>1 && typeof(args[1])!='object' ? args[1] : '';
-  var nocase = args.length==3 ? args[2] : false;
-
-  if(!haystack.length) return -1;
-
-  for(var i=0; i<haystack.length; i++)
-    if(nocase && haystack[i].toLowerCase()==needle.toLowerCase())
-      return i;
-    else if(haystack[i]==needle)
-      return i;
-
-  return -1;
-  }
-
-
-// make a string URL safe
-function urlencode(str)
-{
-  return window.encodeURIComponent ? encodeURIComponent(str) : escape(str);
-}
-
-
-// get any type of html objects by id/name
-function rcube_find_object(id, d)
-  {
-  var n, f, obj, e;
-  if(!d) d = document;
-
-  if(d.getElementsByName && (e = d.getElementsByName(id)))
-    obj = e[0];
-  if(!obj && d.getElementById)
-    obj = d.getElementById(id);
-  if(!obj && d.all)
-    obj = d.all[id];
-
-  if(!obj && d.images.length)
-    obj = d.images[id];
-
-  if(!obj && d.forms.length)
-    for(f=0; f<d.forms.length; f++)
-      {
-      if(d.forms[f].name == id)
-        obj = d.forms[f];
-      else if(d.forms[f].elements[id])
-        obj = d.forms[f].elements[id];
-      }
-
-  if(!obj && d.layers)
-    {
-    if(d.layers[id]) obj = d.layers[id];
-    for(n=0; !obj && n<d.layers.length; n++)
-      obj = rcube_find_object(id, d.layers[n].document);
-    }
-
-  return obj;
-  }
-
-
-// return the absolute position of an object within the document
-function rcube_get_object_pos(obj, relative)
-  {
-  if(typeof(obj)=='string')
-    obj = rcube_find_object(obj);
-
-  if(!obj) return {x:0, y:0};
-
-  var iX = (bw.layers) ? obj.x : obj.offsetLeft;
-  var iY = (bw.layers) ? obj.y : obj.offsetTop;
-
-  if(!relative && (bw.ie || bw.mz))
-    {
-    var elm = obj.offsetParent;
-    while(elm && elm!=null)
-      {
-      iX += elm.offsetLeft - (elm.parentNode && elm.parentNode.scrollLeft ? elm.parentNode.scrollLeft : 0);
-      iY += elm.offsetTop - (elm.parentNode && elm.parentNode.scrollTop ? elm.parentNode.scrollTop : 0);
-      elm = elm.offsetParent;
-      }
-    }
-
-  return {x:iX, y:iY};
-  }
-
-// determine whether the mouse is over the given object or not
-function rcube_mouse_is_over(ev, obj)
-{
-  var mouse = rcube_event.get_mouse_pos(ev);
-  var pos = rcube_get_object_pos(obj);
-  
-  return ((mouse.x >= pos.x) && (mouse.x < (pos.x + obj.offsetWidth)) &&
-    (mouse.y >= pos.y) && (mouse.y < (pos.y + obj.offsetHeight)));
-}
-
-
-/**
- * Return the currently applied value of a css property
- *
- * @param {Object} html_element  Node reference
- * @param {String} css_property  Property name to read in Javascript notation (eg. 'textAlign')
- * @param {String} mozilla_equivalent  Equivalent property name in CSS notation (eg. 'text-align')
- * @return CSS property value
- * @type String
- */
-function get_elements_computed_style(html_element, css_property, mozilla_equivalent)
-  {
-  if (arguments.length==2)
-    mozilla_equivalent = css_property;
-
-  var el = html_element;
-  if (typeof(html_element)=='string')
-    el = rcube_find_object(html_element);
-
-  if (el && el.currentStyle)
-    return el.currentStyle[css_property];
-  else if (el && document.defaultView && document.defaultView.getComputedStyle)
-    return document.defaultView.getComputedStyle(el, null).getPropertyValue(mozilla_equivalent);
-  else
-    return false;
-  }
-  
-
-// cookie functions by GoogieSpell
-function setCookie(name, value, expires, path, domain, secure)
-  {
-  var curCookie = name + "=" + escape(value) +
-      (expires ? "; expires=" + expires.toGMTString() : "") +
-      (path ? "; path=" + path : "") +
-      (domain ? "; domain=" + domain : "") +
-      (secure ? "; secure" : "");
-  document.cookie = curCookie;
-  }
-
-roundcube_browser.prototype.set_cookie = setCookie;
-
-function getCookie(name)
-  {
-  var dc = document.cookie;
-  var prefix = name + "=";
-  var begin = dc.indexOf("; " + prefix);
-  if (begin == -1)
-    {
-    begin = dc.indexOf(prefix);
-    if (begin != 0) return null;
-    }
-  else
-    begin += 2;  
-  var end = document.cookie.indexOf(";", begin);
-  if (end == -1)
-    end = dc.length;
-  return unescape(dc.substring(begin + prefix.length, end));
-  }
-
-roundcube_browser.prototype.get_cookie = getCookie;
-
-// tiny replacement for Firebox functionality
-function rcube_console()
-{
-  this.log = function(msg)
-  {
-    var box = rcube_find_object('console');
-
-    if (box) {
-      if (msg.charAt(msg.length-1)=='\n')
-       msg += '--------------------------------------\n';
-      else
-        msg += '\n--------------------------------------\n';
-
-      // Konqueror doesn't allows to just change value of hidden element
-      if (bw.konq) {
-        box.innerText += msg;
-        box.value = box.innerText;
-      } else
-        box.value += msg;
-    }
-  };
-
-  this.reset = function()
-  {
-    var box = rcube_find_object('console');
-    if (box)
-      box.innerText = box.value = '';
-  };
-}
-
-var bw = new roundcube_browser();
-if (!window.console)
-  var console = new rcube_console();
-
-
-// Add escape() method to RegExp object
-// http://dev.rubyonrails.org/changeset/7271
-RegExp.escape = function(str)
-{
-  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
-}
-
-
-// Make getElementById() case-sensitive on IE
-if (bw.ie)
-  {
-  document._getElementById = document.getElementById;
-  document.getElementById = function(id)
-    {
-    var i = 0;
-    var o = document._getElementById(id);
-
-    if (!o || o.id != id)
-      while ((o = document.all[i]) && o.id != id)
-        i++;
-
-    return o;
-    }
-  }
-
-
-// Fire event on specified element
-function exec_event(element,event)
-{  
-  if (document.createEventObject) {
-    // dispatch for IE  
-    var evt = document.createEventObject();
-    return element.fireEvent('on'+event,evt)
-  }
-  else {  
-    // dispatch for firefox + others  
-    var evt = document.createEvent("HTMLEvents");
-    evt.initEvent(event, true, true); // event type,bubbling,cancelable
-    return !element.dispatchEvent(evt);
-   }
-}
index 6b847ba0007d946314028a042042ab7556a88aba..eeb16ec96eae9244ecd7cd27fc580b8678bbf0e6 100644 (file)
@@ -17,7 +17,8 @@
 function rcmail_editor_init(skin_path, editor_lang, spellcheck, mode)
 {
   if (mode == 'identity')
-    tinyMCE.init({ mode : 'textareas',
+    tinyMCE.init({
+      mode : 'textareas',
       editor_selector : 'mce_editor',
       apply_source_formatting : true,
       theme : 'advanced',
@@ -52,8 +53,8 @@ function rcmail_editor_init(skin_path, editor_lang, spellcheck, mode)
       spellchecker_languages : (rcmail.env.spellcheck_langs ? rcmail.env.spellcheck_langs : 'Dansk=da,Deutsch=de,+English=en,Espanol=es,Francais=fr,Italiano=it,Nederlands=nl,Polski=pl,Portugues=pt,Suomi=fi,Svenska=sv'),
       gecko_spellcheck : true,
       relative_urls : false,
-      remove_script_host : false ,
-      rc_client: rcube_webmail_client,
+      remove_script_host : false,
+      rc_client: rcmail,
       oninit : 'rcmail_editor_callback'
     });
 }
@@ -62,8 +63,22 @@ function rcmail_editor_init(skin_path, editor_lang, spellcheck, mode)
 function rcmail_editor_callback(editor)
 {
   var input_from = rcube_find_object('_from');
-  if(input_from && input_from.type=='select-one')
+  if (input_from && input_from.type=='select-one')
     rcmail.change_identity(input_from);
+  // set tabIndex
+  rcmail_editor_tabindex()
+}
+
+// set tabIndex on tinyMCE editor
+function rcmail_editor_tabindex()
+{
+  if (rcmail.env.task == 'mail') {
+    var editor = tinyMCE.get(rcmail.env.composebody);
+    var textarea = editor.getElement();
+    var node = editor.getContentAreaContainer().childNodes[0];
+    if (textarea && node)
+      node.tabIndex = textarea.tabIndex;
+  }
 }
 
 // switch html/plain mode
@@ -75,10 +90,10 @@ function rcmail_toggle_editor(ishtml, textAreaId, flagElement)
   if (ishtml)
     {
     rcmail.display_spellcheck_controls(false);
-    var htmlText = "<pre>" + composeElement.value + "</pre>";
 
-    composeElement.value = htmlText;
+    rcmail.plain2html(composeElement.value, textAreaId);
     tinyMCE.execCommand('mceAddControl', true, textAreaId);
+    rcmail_editor_tabindex();
     if (flagElement && (flag = rcube_find_object(flagElement)))
       flag.value = '1';
     }
index eb103e7acef938d3753c7a3b40b8b52874d8fc96..abd3462ecd267cb9f0b143529369631f14150460 100644 (file)
-var AJS={getElement:function(id){
-if(typeof (id)=="string"){
-return document.getElementById(id);
-}else{
-return id;
-}
-},getElements:function(){
-var _2=new Array();
-for(var i=0;i<arguments.length;i++){
-var _4=this.getElement(arguments[i]);
-_2.push(_4);
-}
-return _2;
-},getQueryArgument:function(_5){
-var _6=window.location.search.substring(1);
-var _7=_6.split("&");
-for(var i=0;i<_7.length;i++){
-var _9=_7[i].split("=");
-if(_9[0]==_5){
-return _9[1];
-}
-}
-return null;
-},isIe:function(){
-return (navigator.userAgent.toLowerCase().indexOf("msie")!=-1&&navigator.userAgent.toLowerCase().indexOf("opera")==-1);
-},getBody:function(){
-return this.getElementsByTagAndClassName("body")[0];
-},getElementsByTagAndClassName:function(_a,_b,_c){
-var _d=new Array();
-if(!this.isDefined(_c)){
-_c=document;
-}
-if(!this.isDefined(_a)){
-_a="*";
-}
-var _e=_c.getElementsByTagName(_a);
-var _f=_e.length;
-var _10=new RegExp("(^|\\s)"+_b+"(\\s|$)");
-for(i=0,j=0;i<_f;i++){
-if(_10.test(_e[i].className)||_b==null){
-_d[j]=_e[i];
-j++;
-}
-}
-return _d;
-},appendChildNodes:function(_11){
-if(arguments.length>=2){
-for(var i=1;i<arguments.length;i++){
-var n=arguments[i];
-if(typeof (n)=="string"){
-n=document.createTextNode(n);
-}
-if(this.isDefined(n)){
-_11.appendChild(n);
-}
-}
-}
-return _11;
-},replaceChildNodes:function(_14){
-var _15;
-while((_15=_14.firstChild)){
-_14.removeChild(_15);
-}
-if(arguments.length<2){
-return _14;
-}else{
-return this.appendChildNodes.apply(this,arguments);
-}
-},insertAfter:function(_16,_17){
-_17.parentNode.insertBefore(_16,_17.nextSibling);
-},insertBefore:function(_18,_19){
-_19.parentNode.insertBefore(_18,_19);
-},showElement:function(elm){
-elm.style.display="";
-},hideElement:function(elm){
-elm.style.display="none";
-},isElementHidden:function(elm){
-return elm.style.visibility=="hidden";
-},swapDOM:function(_1d,src){
-_1d=this.getElement(_1d);
-var _1f=_1d.parentNode;
-if(src){
-src=this.getElement(src);
-_1f.replaceChild(src,_1d);
-}else{
-_1f.removeChild(_1d);
-}
-return src;
-},removeElement:function(elm){
-this.swapDOM(elm,null);
-},isDict:function(o){
-var _22=String(o);
-return _22.indexOf(" Object")!=-1;
-},createDOM:function(_23,_24){
-var i=0;
-elm=document.createElement(_23);
-if(this.isDict(_24[i])){
-for(k in _24[0]){
-if(k=="style"){
-elm.style.cssText=_24[0][k];
-}else{
-if(k=="class"){
-elm.className=_24[0][k];
-}else{
-elm.setAttribute(k,_24[0][k]);
-}
-}
-}
-i++;
-}
-if(_24[0]==null){
-i=1;
-}
-for(i;i<_24.length;i++){
-var n=_24[i];
-if(this.isDefined(n)){
-if(typeof (n)=="string"){
-n=document.createTextNode(n);
-}
-elm.appendChild(n);
-}
-}
-return elm;
-},UL:function(){
-return this.createDOM.apply(this,["ul",arguments]);
-},LI:function(){
-return this.createDOM.apply(this,["li",arguments]);
-},TD:function(){
-return this.createDOM.apply(this,["td",arguments]);
-},TR:function(){
-return this.createDOM.apply(this,["tr",arguments]);
-},TH:function(){
-return this.createDOM.apply(this,["th",arguments]);
-},TBODY:function(){
-return this.createDOM.apply(this,["tbody",arguments]);
-},TABLE:function(){
-return this.createDOM.apply(this,["table",arguments]);
-},INPUT:function(){
-return this.createDOM.apply(this,["input",arguments]);
-},SPAN:function(){
-return this.createDOM.apply(this,["span",arguments]);
-},B:function(){
-return this.createDOM.apply(this,["b",arguments]);
-},A:function(){
-return this.createDOM.apply(this,["a",arguments]);
-},DIV:function(){
-return this.createDOM.apply(this,["div",arguments]);
-},IMG:function(){
-return this.createDOM.apply(this,["img",arguments]);
-},BUTTON:function(){
-return this.createDOM.apply(this,["button",arguments]);
-},H1:function(){
-return this.createDOM.apply(this,["h1",arguments]);
-},H2:function(){
-return this.createDOM.apply(this,["h2",arguments]);
-},H3:function(){
-return this.createDOM.apply(this,["h3",arguments]);
-},BR:function(){
-return this.createDOM.apply(this,["br",arguments]);
-},TEXTAREA:function(){
-return this.createDOM.apply(this,["textarea",arguments]);
-},FORM:function(){
-return this.createDOM.apply(this,["form",arguments]);
-},P:function(){
-return this.createDOM.apply(this,["p",arguments]);
-},SELECT:function(){
-return this.createDOM.apply(this,["select",arguments]);
-},OPTION:function(){
-return this.createDOM.apply(this,["option",arguments]);
-},TN:function(_27){
-return document.createTextNode(_27);
-},IFRAME:function(){
-return this.createDOM.apply(this,["iframe",arguments]);
-},SCRIPT:function(){
-return this.createDOM.apply(this,["script",arguments]);
-},getXMLHttpRequest:function(){
-var _28=[function(){
-return new XMLHttpRequest();
-},function(){
-return new ActiveXObject("Msxml2.XMLHTTP");
-},function(){
-return new ActiveXObject("Microsoft.XMLHTTP");
-},function(){
-return new ActiveXObject("Msxml2.XMLHTTP.4.0");
-},function(){
-throw "Browser does not support XMLHttpRequest";
-}];
-for(var i=0;i<_28.length;i++){
-var _2a=_28[i];
-try{
-return _2a();
-}
-catch(e){
-}
-}
-},doSimpleXMLHttpRequest:function(url){
-var req=this.getXMLHttpRequest();
-req.open("GET",url,true);
-return this.sendXMLHttpRequest(req);
-},getRequest:function(url,_2e){
-var req=this.getXMLHttpRequest();
-req.open("POST",url,true);
-req.setRequestHeader("Content-type","application/x-www-form-urlencoded");
-return this.sendXMLHttpRequest(req);
-},sendXMLHttpRequest:function(req,_31){
-var d=new AJSDeferred(req);
-var _33=function(){
-if(req.readyState==4){
-try{
-var _34=req.status;
-}
-catch(e){
-}
-if(_34==200||_34==304||req.responseText==null){
-d.callback(req,_31);
-}else{
-d.errback();
+/*
+ SpellCheck
+    jQuery'fied spell checker based on GoogieSpell 4.0
+ Copyright Amir Salihefendic 2006
+ Copyright Aleksander Machniak 2009
+     LICENSE
+         GPL
+     AUTHORS
+         4mir Salihefendic (http://amix.dk) - amix@amix.dk
+        Aleksander Machniak - alec [at] alec.pl
+*/
+
+var SPELL_CUR_LANG = null;
+var GOOGIE_DEFAULT_LANG = 'en';
+
+function GoogieSpell(img_dir, server_url) {
+    var ref = this;
+
+    this.array_keys = function(arr) {
+       var res = [];
+       for (var key in arr) { res.push([key]); }
+       return res;
+    }
+    
+    var cookie_value = getCookie('language');
+    GOOGIE_CUR_LANG = cookie_value != null ? cookie_value : GOOGIE_DEFAULT_LANG;
+
+    this.img_dir = img_dir;
+    this.server_url = server_url;
+
+    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.lang_to_word = this.org_lang_to_word;
+    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.ta_scroll_top = 0;
+    this.el_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; // roundcube mod.
+    this.decoration = true;
+    this.use_close_btn = true;
+    this.edit_layer_dbl_click = true;
+    this.report_ta_not_found = true;
+
+    //Extensions
+    this.custom_ajax_error = null;
+    this.custom_no_spelling_error = null;
+    this.custom_menu_builder = []; //Should take an eval function and a build menu function
+    this.custom_item_evaulator = null; //Should take an eval function and a build menu function
+    this.extra_menu_items = [];
+    this.custom_spellcheck_starter = null;
+    this.main_controller = true;
+
+    //Observers
+    this.lang_state_observer = null;
+    this.spelling_state_observer = null;
+    this.show_menu_observer = null;
+    this.all_errors_fixed_observer = null;
+
+    //Focus links - used to give the text box focus
+    this.use_focus = false;
+    this.focus_link_t = null;
+    this.focus_link_b = null;
+
+    //Counters
+    this.cnt_errors = 0;
+    this.cnt_errors_fixed = 0;
+    
+    //Set document on click to hide the language and error menu
+    $(document).bind('click', function(e) {
+        if($(e.target).attr('googie_action_btn') != '1' && ref.isLangWindowShown())
+           ref.hideLangWindow();
+       if($(e.target).attr('googie_action_btn') != '1' && ref.isErrorWindowShown())
+            ref.hideErrorWindow();
+    });
+
+
+this.decorateTextarea = function(id) {
+    this.text_area = typeof(id) == 'string' ? document.getElementById(id) : id;
+
+    if (this.text_area) {
+        if (!this.spell_container && this.decoration) {
+            var table = document.createElement('table');
+            var tbody = document.createElement('tbody');
+            var tr = document.createElement('tr');
+            var spell_container = document.createElement('td');
+
+            var r_width = this.isDefined(this.force_width) ? this.force_width : this.text_area.offsetWidth;
+            var r_height = this.isDefined(this.force_height) ? this.force_height : 16;
+
+            tr.appendChild(spell_container);
+            tbody.appendChild(tr);
+            $(table).append(tbody).insertBefore(this.text_area).width('100%').height(r_height);
+            $(spell_container).height(r_height).width(r_width).css('text-align', 'right');
+
+            this.spell_container = spell_container;
+        }
+
+        this.checkSpellingState();
+    }
+    else 
+        if (this.report_ta_not_found)
+            alert('Text area not found');
 }
+
+//////
+// API Functions (the ones that you can call)
+/////
+this.setSpellContainer = function(id) {
+    this.spell_container = typeof(id) == 'string' ? document.getElementById(id) : id;
+
 }
-};
-req.onreadystatechange=_33;
-return d;
-},reprString:function(o){
-return ("\""+o.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");
-},serializeJSON:function(o){
-var _37=typeof (o);
-if(_37=="undefined"){
-return "undefined";
-}else{
-if(_37=="number"||_37=="boolean"){
-return o+"";
-}else{
-if(o===null){
-return "null";
-}
-}
-}
-if(_37=="string"){
-return this.reprString(o);
-}
-var me=arguments.callee;
-var _39;
-if(typeof (o.__json__)=="function"){
-_39=o.__json__();
-if(o!==_39){
-return me(_39);
-}
-}
-if(typeof (o.json)=="function"){
-_39=o.json();
-if(o!==_39){
-return me(_39);
-}
-}
-if(_37!="function"&&typeof (o.length)=="number"){
-var res=[];
-for(var i=0;i<o.length;i++){
-var val=me(o[i]);
-if(typeof (val)!="string"){
-val="undefined";
-}
-res.push(val);
-}
-return "["+res.join(",")+"]";
-}
-res=[];
-for(var k in o){
-var _3e;
-if(typeof (k)=="number"){
-_3e="\""+k+"\"";
-}else{
-if(typeof (k)=="string"){
-_3e=this.reprString(k);
-}else{
-continue;
-}
-}
-val=me(o[k]);
-if(typeof (val)!="string"){
-continue;
-}
-res.push(_3e+":"+val);
-}
-return "{"+res.join(",")+"}";
-},loadJSONDoc:function(url){
-var d=this.getRequest(url);
-var _41=function(req){
-var _43=req.responseText;
-return eval("("+_43+")");
-};
-d.addCallback(_41);
-return d;
-},keys:function(obj){
-var _45=[];
-for(var _46 in obj){
-_45.push(_46);
-}
-return _45;
-},urlencode:function(str){
-return encodeURIComponent(str.toString());
-},isDefined:function(o){
-return (o!="undefined"&&o!=null);
-},isArray:function(obj){
-try{
-return (typeof (obj.length)=="undefined")?false:true;
-}
-catch(e){
-return false;
-}
-},isObject:function(obj){
-return (obj&&typeof obj=="object");
-},exportDOMElements:function(){
-UL=this.UL;
-LI=this.LI;
-TD=this.TD;
-TR=this.TR;
-TH=this.TH;
-TBODY=this.TBODY;
-TABLE=this.TABLE;
-INPUT=this.INPUT;
-SPAN=this.SPAN;
-B=this.B;
-A=this.A;
-DIV=this.DIV;
-IMG=this.IMG;
-BUTTON=this.BUTTON;
-H1=this.H1;
-H2=this.H2;
-H3=this.H3;
-BR=this.BR;
-TEXTAREA=this.TEXTAREA;
-FORM=this.FORM;
-P=this.P;
-SELECT=this.SELECT;
-OPTION=this.OPTION;
-TN=this.TN;
-IFRAME=this.IFRAME;
-SCRIPT=this.SCRIPT;
-},exportToGlobalScope:function(){
-getElement=this.getElement;
-getQueryArgument=this.getQueryArgument;
-isIe=this.isIe;
-$=this.getElement;
-getElements=this.getElements;
-getBody=this.getBody;
-getElementsByTagAndClassName=this.getElementsByTagAndClassName;
-appendChildNodes=this.appendChildNodes;
-ACN=appendChildNodes;
-replaceChildNodes=this.replaceChildNodes;
-RCN=replaceChildNodes;
-insertAfter=this.insertAfter;
-insertBefore=this.insertBefore;
-showElement=this.showElement;
-hideElement=this.hideElement;
-isElementHidden=this.isElementHidden;
-swapDOM=this.swapDOM;
-removeElement=this.removeElement;
-isDict=this.isDict;
-createDOM=this.createDOM;
-this.exportDOMElements();
-getXMLHttpRequest=this.getXMLHttpRequest;
-doSimpleXMLHttpRequest=this.doSimpleXMLHttpRequest;
-getRequest=this.getRequest;
-sendXMLHttpRequest=this.sendXMLHttpRequest;
-reprString=this.reprString;
-serializeJSON=this.serializeJSON;
-loadJSONDoc=this.loadJSONDoc;
-keys=this.keys;
-isDefined=this.isDefined;
-isArray=this.isArray;
-}};
-AJSDeferred=function(req){
-this.callbacks=[];
-this.req=req;
-this.callback=function(res){
-while(this.callbacks.length>0){
-var fn=this.callbacks.pop();
-res=fn(res);
+
+this.setLanguages = function(lang_dict) {
+    this.lang_to_word = lang_dict;
+    this.langlist_codes = this.array_keys(lang_dict);
 }
-};
-this.errback=function(e){
-alert("Error encountered:\n"+e);
-};
-this.addErrback=function(fn){
-this.errback=fn;
-};
-this.addCallback=function(fn){
-this.callbacks.unshift(fn);
-};
-this.addCallbacks=function(fn1,fn2){
-this.addCallback(fn1);
-this.addErrback(fn2);
-};
-this.sendReq=function(_53){
-if(AJS.isObject(_53)){
-var _54=[];
-for(k in _53){
-_54.push(k+"="+AJS.urlencode(_53[k]));
+
+this.setCurrentLanguage = function(lan_code) {
+    GOOGIE_CUR_LANG = lan_code;
+
+    //Set cookie
+    var now = new Date();
+    now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
+    setCookie('language', lan_code, now);
 }
-_54=_54.join("&");
-this.req.send(_54);
-}else{
-if(AJS.isDefined(_53)){
-this.req.send(_53);
-}else{
-this.req.send("");
+
+this.setForceWidthHeight = function(width, height) {
+    // Set to null if you want to use one of them
+    this.force_width = width;
+    this.force_height = height;
 }
+
+this.setDecoration = function(bool) {
+    this.decoration = bool;
 }
-};
-};
-AJSDeferred.prototype=new AJSDeferred();
-var GOOGIE_CUR_LANG="en";
-function GoogieSpell(_55,_56){
-var _57;
-var _58;
-_57=getCookie("language");
-if(_57!=null){
-GOOGIE_CUR_LANG=_57;
-}
-this.img_dir=_55;
-this.server_url=_56;
-this.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=AJS.keys(this.lang_to_word);
-this.show_change_lang_pic=true;
-this.lang_state_observer=null;
-this.spelling_state_observer=null;
-this.request=null;
-this.error_window=null;
-this.language_window=null;
-this.edit_layer=null;
-this.orginal_text=null;
-this.results=null;
-this.text_area=null;
-this.gselm=null;
-this.ta_scroll_top=0;
-this.el_scroll_top=0;
-this.lang_chck_spell="Check spelling";
-this.lang_rsm_edt="Resume editing";
-this.lang_close="Close";
-this.lang_no_error_found="No spelling errors found";
-this.lang_revert="Revert to";
-this.show_spell_img=false;
-};
-GoogieSpell.prototype.setStateChanged=function(_59){
-if(this.spelling_state_observer!=null){
-this.spelling_state_observer(_59);
+
+this.dontUseCloseButtons = function() {
+    this.use_close_btn = false;
 }
-};
-GoogieSpell.item_onmouseover=function(e){
-var elm=GoogieSpell.getEventElm(e);
-if(elm.className!="googie_list_close"&&elm.className!="googie_list_revert"){
-elm.className="googie_list_onhover";
-}else{
-elm.parentNode.className="googie_list_onhover";
+
+this.appendNewMenuItem = function(name, call_back_fn, checker) {
+    this.extra_menu_items.push([name, call_back_fn, checker]);
 }
-};
-GoogieSpell.item_onmouseout=function(e){
-var elm=GoogieSpell.getEventElm(e);
-if(elm.className!="googie_list_close"&&elm.className!="googie_list_revert"){
-elm.className="googie_list_onout";
-}else{
-elm.parentNode.className="googie_list_onout";
+
+this.appendCustomMenuBuilder = function(eval, builder) {
+    this.custom_menu_builder.push([eval, builder]);
 }
-};
-GoogieSpell.prototype.getGoogleUrl=function(){
-return this.server_url+GOOGIE_CUR_LANG;
-};
-GoogieSpell.prototype.spellCheck=function(elm,_5f){
-this.ta_scroll_top=this.text_area.scrollTop;
-this.appendIndicator(elm);
-try{
-this.hideLangWindow();
-}
-catch(e){
-}
-this.gselm=elm;
-this.createEditLayer(this.text_area.offsetWidth,this.text_area.offsetHeight);
-this.createErrorWindow();
-AJS.getBody().appendChild(this.error_window);
-try{
-netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
-}
-catch(e){
-}
-this.gselm.onclick=null;
-this.orginal_text=this.text_area.value;
-var me=this;
-var d=AJS.getRequest(this.getGoogleUrl());
-var _62=function(req){
-var _64=req.responseText;
-if(_64.match(/<c.*>/)!=null){
-var _65=GoogieSpell.parseResult(_64);
-me.results=_65;
-me.showErrorsInIframe(_65);
-me.resumeEditingState();
-}else{
-me.flashNoSpellingErrorState();
-}
-me.removeIndicator();
-};
-var _66=function(req){
-alert("An error was encountered on the server. Please try again later.");
-AJS.removeElement(me.gselm);
-me.checkSpellingState();
-me.removeIndicator();
-};
-d.addCallback(_62);
-d.addErrback(_66);
-var _68=GoogieSpell.escapeSepcial(this.orginal_text);
-d.sendReq(GoogieSpell.createXMLReq(_68));
-};
-GoogieSpell.escapeSepcial=function(val){
-return val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
-};
-GoogieSpell.createXMLReq=function(_6a){
-return "<?xml version=\"1.0\" encoding=\"utf-8\" ?><spellrequest textalreadyclipped=\"0\" ignoredups=\"0\" ignoredigits=\"1\" ignoreallcaps=\"1\"><text>"+_6a+"</text></spellrequest>";
-};
-GoogieSpell.parseResult=function(_6b){
-var _6c=/\w="\d+"/g;
-var _6d=/\t/g;
-var _6e=_6b.match(/<c[^>]*>[^<]*<\/c>/g);
-var _6f=new Array();
-for(var i=0;i<_6e.length;i++){
-var _71=new Array();
-_71["attrs"]=new Array();
-var _72=_6e[i].match(_6c);
-for(var j=0;j<_72.length;j++){
-var _74=_72[j].split(/=/);
-_71["attrs"][_74[0]]=parseInt(_74[1].replace("\"",""));
-}
-_71["suggestions"]=new Array();
-var _75=_6e[i].replace(/<[^>]*>/g,"");
-var _76=_75.split(_6d);
-for(var k=0;k<_76.length;k++){
-if(_76[k]!=""){
-_71["suggestions"].push(_76[k]);
-}
-}
-_6f.push(_71);
-}
-return _6f;
-};
-GoogieSpell.prototype.createErrorWindow=function(){
-this.error_window=AJS.DIV();
-this.error_window.className="googie_window";
-};
-GoogieSpell.prototype.hideErrorWindow=function(){
-this.error_window.style.visibility="hidden";
-};
-GoogieSpell.prototype.updateOrginalText=function(_78,_79,_7a,id){
-var _7c=this.orginal_text.substring(0,_78);
-var _7d=this.orginal_text.substring(_78+_79.length);
-this.orginal_text=_7c+_7a+_7d;
-var _7e=_7a.length-_79.length;
-for(var j=0;j<this.results.length;j++){
-if(j!=id&&j>id){
-this.results[j]["attrs"]["o"]+=_7e;
+
+this.setFocus = function() {
+    try {
+        this.focus_link_b.focus();
+        this.focus_link_t.focus();
+        return true;
+    }
+    catch(e) {
+        return false;
+    }
 }
+
+
+//////
+// Set functions (internal)
+/////
+this.setStateChanged = function(current_state) {
+    this.state = current_state;
+    if (this.spelling_state_observer != null && this.report_state_change)
+        this.spelling_state_observer(current_state, this);
 }
-};
-GoogieSpell.prototype.saveOldValue=function(id,_81){
-this.results[id]["is_changed"]=true;
-this.results[id]["old_value"]=_81;
-};
-GoogieSpell.prototype.showErrorWindow=function(elm,id){
-var me=this;
-var _85=GoogieSpell.absolutePosition(elm);
-_85.y-=this.edit_layer.scrollTop;
-this.error_window.style.visibility="visible";
-this.error_window.style.top=(_85.y+20)+"px";
-this.error_window.style.left=(_85.x)+"px";
-this.error_window.innerHTML="";
-var _86=AJS.TABLE({"class":"googie_list"});
-var _87=AJS.TBODY();
-var _88=this.results[id]["suggestions"];
-var _89=this.results[id]["attrs"]["o"];
-var len=this.results[id]["attrs"]["l"];
-if(_88.length==0){
-var row=AJS.TR();
-var _8c=AJS.TD();
-var _8d=AJS.SPAN();
-_8c.appendChild(AJS.TN("No suggestions :("));
-row.appendChild(_8c);
-_87.appendChild(row);
-}
-for(i=0;i<_88.length;i++){
-var row=AJS.TR();
-var _8c=AJS.TD();
-var _8d=AJS.SPAN();
-_8d.innerHTML=_88[i];
-_8c.appendChild(AJS.TN(_8d.innerHTML));
-_8c.onclick=function(e){
-var _8f=GoogieSpell.getEventElm(e);
-var _90=elm.innerHTML;
-var _91=_8f.innerHTML;
-elm.style.color="green";
-elm.innerHTML=_8f.innerHTML;
-me.hideErrorWindow();
-me.updateOrginalText(_89,_90,_91,id);
-me.results[id]["attrs"]["l"]=_91.length;
-me.saveOldValue(id,_90);
-};
-_8c.onmouseover=GoogieSpell.item_onmouseover;
-_8c.onmouseout=GoogieSpell.item_onmouseout;
-row.appendChild(_8c);
-_87.appendChild(row);
-}
-if(this.results[id]["is_changed"]){
-var _92=this.results[id]["old_value"];
-var _89=this.results[id]["attrs"]["o"];
-var _93=AJS.TR();
-var _94=AJS.TD();
-_94.onmouseover=GoogieSpell.item_onmouseover;
-_94.onmouseout=GoogieSpell.item_onmouseout;
-var _95=AJS.SPAN({"class":"googie_list_revert"});
-_95.innerHTML=this.lang_revert+" "+_92;
-_94.appendChild(_95);
-_94.onclick=function(e){
-me.updateOrginalText(_89,elm.innerHTML,_92,id);
-elm.style.color="#b91414";
-elm.innerHTML=_92;
-me.hideErrorWindow();
-};
-_93.appendChild(_94);
-_87.appendChild(_93);
-}
-var _97=AJS.TR();
-var _98=AJS.TD();
-var _99=AJS.INPUT({"style":"width: 120px; margin:0; padding:0"});
-var _9a=function(){
-if(_99.value!=""){
-me.saveOldValue(id,elm.innerHTML);
-me.updateOrginalText(_89,elm.innerHTML,_99.value,id);
-elm.style.color="green";
-elm.innerHTML=_99.value;
-me.hideErrorWindow();
-return false;
+
+this.setReportStateChange = function(bool) {
+    this.report_state_change = bool;
 }
-};
-var _9b=AJS.IMG({"src":this.img_dir+"ok.gif","style":"width: 32px; height: 16px; margin-left: 2px; margin-right: 2px;"});
-var _9c=AJS.FORM({"style":"margin: 0; padding: 0"},_99,_9b);
-_9b.onclick=_9a;
-_9c.onsubmit=_9a;
-_98.appendChild(_9c);
-_97.appendChild(_98);
-_87.appendChild(_97);
-var _9d=AJS.TR();
-var _9e=AJS.TD();
-_9e.onmouseover=GoogieSpell.item_onmouseover;
-_9e.onmouseout=GoogieSpell.item_onmouseout;
-var _9f=AJS.SPAN({"class":"googie_list_close"});
-_9f.innerHTML=this.lang_close;
-_9e.appendChild(_9f);
-_9e.onclick=function(){
-me.hideErrorWindow();
-};
-_9d.appendChild(_9e);
-_87.appendChild(_9d);
-_86.appendChild(_87);
-this.error_window.appendChild(_86);
-};
-GoogieSpell.prototype.createEditLayer=function(_a0,_a1){
-this.edit_layer=AJS.DIV({"class":"googie_edit_layer"});
-this.edit_layer.className=this.text_area.className;
-this.edit_layer.style.border="1px solid #999";
-this.edit_layer.style.overflow="auto";
-this.edit_layer.style.backgroundColor="#F1EDFE";
-this.edit_layer.style.padding="3px";
-this.edit_layer.style.width=(_a0-8)+"px";
-this.edit_layer.style.height=_a1+"px";
-};
-GoogieSpell.prototype.resumeEditing=function(e,me){
-this.setStateChanged("check_spelling");
-me.switch_lan_pic.style.display="inline";
-this.el_scroll_top=me.edit_layer.scrollTop;
-var elm=GoogieSpell.getEventElm(e);
-AJS.replaceChildNodes(elm,this.createSpellDiv());
-elm.onclick=function(e){
-me.spellCheck(elm,me.text_area.id);
-};
-me.hideErrorWindow();
-me.edit_layer.parentNode.removeChild(me.edit_layer);
-me.text_area.value=me.orginal_text;
-AJS.showElement(me.text_area);
-me.gselm.className="googie_no_style";
-me.text_area.scrollTop=this.el_scroll_top;
-elm.onmouseout=null;
-};
-GoogieSpell.prototype.createErrorLink=function(_a6,id){
-var elm=AJS.SPAN({"class":"googie_link"});
-var me=this;
-elm.onclick=function(){
-me.showErrorWindow(elm,id);
-};
-elm.innerHTML=_a6;
-return elm;
-};
-GoogieSpell.createPart=function(_aa){
-if(_aa==" "){
-return AJS.TN(" ");
-}
-var _ab=AJS.SPAN();
-var _ac=true;
-var _ad=(navigator.userAgent.toLowerCase().indexOf("safari")!=-1);
-var _ae=AJS.SPAN();
-_aa=GoogieSpell.escapeSepcial(_aa);
-_aa=_aa.replace(/\n/g,"<br>");
-_aa=_aa.replace(/  /g," &nbsp;");
-_aa=_aa.replace(/^ /g,"&nbsp;");
-_aa=_aa.replace(/ $/g,"&nbsp;");
-_ae.innerHTML=_aa;
-return _ae;
-};
-GoogieSpell.prototype.showErrorsInIframe=function(_af){
-var _b0=AJS.DIV();
-_b0.style.textAlign="left";
-var _b1=0;
-for(var i=0;i<_af.length;i++){
-var _b3=_af[i]["attrs"]["o"];
-var len=_af[i]["attrs"]["l"];
-var _b5=this.orginal_text.substring(_b1,_b3);
-var _b6=GoogieSpell.createPart(_b5);
-_b0.appendChild(_b6);
-_b1+=_b3-_b1;
-_b0.appendChild(this.createErrorLink(this.orginal_text.substr(_b3,len),i));
-_b1+=len;
-}
-var _b7=this.orginal_text.substr(_b1,this.orginal_text.length);
-var _b8=GoogieSpell.createPart(_b7);
-_b0.appendChild(_b8);
-this.edit_layer.appendChild(_b0);
-AJS.hideElement(this.text_area);
-this.text_area.parentNode.insertBefore(this.edit_layer,this.text_area.nextSibling);
-this.edit_layer.scrollTop=this.ta_scroll_top;
-};
-GoogieSpell.Position=function(x,y){
-this.x=x;
-this.y=y;
-};
-GoogieSpell.absolutePosition=function(_bb){
-var _bc=new GoogieSpell.Position(_bb.offsetLeft,_bb.offsetTop);
-if(_bb.offsetParent){
-var _bd=GoogieSpell.absolutePosition(_bb.offsetParent);
-_bc.x+=_bd.x;
-_bc.y+=_bd.y;
-}
-return _bc;
-};
-GoogieSpell.getEventElm=function(e){
-var _bf;
-if(!e){
-var e=window.event;
+
+
+//////
+// Request functions
+/////
+this.getUrl = function() {
+    return this.server_url + GOOGIE_CUR_LANG;
 }
-if(e.target){
-_bf=e.target;
-}else{
-if(e.srcElement){
-_bf=e.srcElement;
+
+this.escapeSpecial = function(val) {
+    return val.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
 }
+
+this.createXMLReq = function (text) {
+    return '<?xml version="1.0" encoding="utf-8" ?>'
+       + '<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">'
+       + '<text>' + text + '</text></spellrequest>';
 }
-if(_bf.nodeType==3){
-_bf=_bf.parentNode;
+
+this.spellCheck = function(ignore) {
+    this.cnt_errors_fixed = 0;
+    this.cnt_errors = 0;
+    this.setStateChanged('checking_spell');
+
+    if (this.main_controller)
+        this.appendIndicator(this.spell_span);
+
+    this.error_links = [];
+    this.ta_scroll_top = this.text_area.scrollTop;
+    this.ignore = ignore;
+    this.hideLangWindow();
+
+    if ($(this.text_area).val() == '' || ignore) {
+        if (!this.custom_no_spelling_error)
+            this.flashNoSpellingErrorState();
+        else
+            this.custom_no_spelling_error(this);
+        this.removeIndicator();
+        return;
+    }
+    
+    this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight);
+    this.createErrorWindow();
+    $('body').append(this.error_window);
+
+    try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } 
+    catch (e) { }
+
+    if (this.main_controller)
+        $(this.spell_span).unbind('click');
+
+    this.orginal_text = $(this.text_area).val();
+    var req_text = this.escapeSpecial(this.orginal_text);
+    var ref = this;
+
+    $.ajax({ type: 'POST', url: this.getUrl(),
+       data: this.createXMLReq(req_text), dataType: 'text',
+       error: function(o) {
+           if (ref.custom_ajax_error)
+               ref.custom_ajax_error(ref);
+           else
+               alert('An error was encountered on the server. Please try again later.');
+           if (ref.main_controller) {
+               $(ref.spell_span).remove();
+               ref.removeIndicator();
+           }
+           ref.checkSpellingState();
+       },
+        success: function(data) {
+           var r_text = data;
+           ref.results = ref.parseResult(r_text);
+           if (r_text.match(/<c.*>/) != null) {
+               //Before parsing be sure that errors were found
+               ref.showErrorsInIframe();
+               ref.resumeEditingState();
+           } else {
+               if (!ref.custom_no_spelling_error)
+                   ref.flashNoSpellingErrorState();
+               else
+                   ref.custom_no_spelling_error(ref);
+           }
+           ref.removeIndicator();
+       }
+    });
 }
-return _bf;
-};
-GoogieSpell.prototype.removeIndicator=function(elm){
-if(window.rcube_webmail_client){
-rcube_webmail_client.set_busy(false);
+
+
+//////
+// Spell checking functions
+/////
+this.parseResult = function(r_text) {
+    // Returns an array: result[item] -> ['attrs'], ['suggestions']
+    var re_split_attr_c = /\w+="(\d+|true)"/g;
+    var re_split_text = /\t/g;
+
+    var matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g);
+    var results = new Array();
+
+    if (matched_c == null)
+        return results;
+    
+    for (var i=0; i < matched_c.length; i++) {
+        var item = new Array();
+        this.errorFound();
+
+        //Get attributes
+        item['attrs'] = new Array();
+        var split_c = matched_c[i].match(re_split_attr_c);
+        for (var j=0; j < split_c.length; j++) {
+            var c_attr = split_c[j].split(/=/);
+            var val = c_attr[1].replace(/"/g, '');
+            item['attrs'][c_attr[0]] = val != 'true' ? parseInt(val) : val;
+        }
+
+        //Get suggestions
+        item['suggestions'] = new Array();
+        var only_text = matched_c[i].replace(/<[^>]*>/g, '');
+        var split_t = only_text.split(re_split_text);
+        for (var k=0; k < split_t.length; k++) {
+           if(split_t[k] != '')
+               item['suggestions'].push(split_t[k]);
+       }
+        results.push(item);
+    }
+    return results;
 }
-};
-GoogieSpell.prototype.appendIndicator=function(elm){
-if(window.rcube_webmail_client){
-rcube_webmail_client.set_busy(true,"checking");
+
+
+//////
+// Error menu functions
+/////
+this.createErrorWindow = function() {
+    this.error_window = document.createElement('div');
+    $(this.error_window).addClass('googie_window').attr('googie_action_btn', '1');
 }
-};
-GoogieSpell.prototype.createLangWindow=function(){
-this.language_window=AJS.DIV({"class":"googie_window"});
-this.language_window.style.width="130px";
-var _c2=AJS.TABLE({"class":"googie_list"});
-var _c3=AJS.TBODY();
-this.lang_elms=new Array();
-for(i=0;i<this.langlist_codes.length;i++){
-var row=AJS.TR();
-var _c5=AJS.TD();
-_c5.googieId=this.langlist_codes[i];
-this.lang_elms.push(_c5);
-var _c6=AJS.SPAN();
-_c6.innerHTML=this.lang_to_word[this.langlist_codes[i]];
-_c5.appendChild(AJS.TN(_c6.innerHTML));
-var me=this;
-_c5.onclick=function(e){
-var elm=GoogieSpell.getEventElm(e);
-me.deHighlightCurSel();
-me.setCurrentLanguage(elm.googieId);
-if(me.lang_state_observer!=null){
-me.lang_state_observer();
-}
-me.highlightCurSel();
-me.hideLangWindow();
-};
-_c5.onmouseover=function(e){
-var _cb=GoogieSpell.getEventElm(e);
-if(_cb.className!="googie_list_selected"){
-_cb.className="googie_list_onhover";
+
+this.isErrorWindowShown = function() {
+    return $(this.error_window).is(':visible');
 }
-};
-_c5.onmouseout=function(e){
-var _cd=GoogieSpell.getEventElm(e);
-if(_cd.className!="googie_list_selected"){
-_cd.className="googie_list_onout";
+
+this.hideErrorWindow = function() {
+    $(this.error_window).css('visibility', 'hidden');
+    $(this.error_window_iframe).css('visibility', 'hidden');
 }
-};
-row.appendChild(_c5);
-_c3.appendChild(row);
-}
-this.highlightCurSel();
-var _ce=AJS.TR();
-var _cf=AJS.TD();
-_cf.onmouseover=GoogieSpell.item_onmouseover;
-_cf.onmouseout=GoogieSpell.item_onmouseout;
-var _d0=AJS.SPAN({"class":"googie_list_close"});
-_d0.innerHTML=this.lang_close;
-_cf.appendChild(_d0);
-var me=this;
-_cf.onclick=function(e){
-me.hideLangWindow();
-GoogieSpell.item_onmouseout(e);
-};
-_ce.appendChild(_cf);
-_c3.appendChild(_ce);
-_c2.appendChild(_c3);
-this.language_window.appendChild(_c2);
-};
-GoogieSpell.prototype.setCurrentLanguage=function(_d2){
-GOOGIE_CUR_LANG=_d2;
-var now=new Date();
-now.setTime(now.getTime()+365*24*60*60*1000);
-setCookie("language",_d2,now);
-};
-GoogieSpell.prototype.hideLangWindow=function(){
-this.language_window.style.visibility="hidden";
-this.switch_lan_pic.className="googie_lang_3d_on";
-};
-GoogieSpell.prototype.deHighlightCurSel=function(){
-this.lang_cur_elm.className="googie_list_onout";
-};
-GoogieSpell.prototype.highlightCurSel=function(){
-for(var i=0;i<this.lang_elms.length;i++){
-if(this.lang_elms[i].googieId==GOOGIE_CUR_LANG){
-this.lang_elms[i].className="googie_list_selected";
-this.lang_cur_elm=this.lang_elms[i];
-}else{
-this.lang_elms[i].className="googie_list_onout";
+
+this.updateOrginalText = function(offset, old_value, new_value, id) {
+    var part_1 = this.orginal_text.substring(0, offset);
+    var part_2 = this.orginal_text.substring(offset+old_value.length);
+    this.orginal_text = part_1 + new_value + part_2;
+    $(this.text_area).val(this.orginal_text);
+    var add_2_offset = new_value.length - old_value.length;
+    for (var j=0; j < this.results.length; j++) {
+        //Don't edit the offset of the current item
+        if (j != id && j > id)
+            this.results[j]['attrs']['o'] += add_2_offset;
+    }
 }
+
+this.saveOldValue = function(elm, old_value) {
+    elm.is_changed = true;
+    elm.old_value = old_value;
 }
-};
-GoogieSpell.prototype.showLangWindow=function(elm,_d6,_d7){
-if(!AJS.isDefined(_d6)){
-_d6=20;
-}
-if(!AJS.isDefined(_d7)){
-_d7=50;
-}
-this.createLangWindow();
-AJS.getBody().appendChild(this.language_window);
-var _d8=GoogieSpell.absolutePosition(elm);
-AJS.showElement(this.language_window);
-this.language_window.style.top=(_d8.y+_d6)+"px";
-this.language_window.style.left=(_d8.x+_d7-this.language_window.offsetWidth)+"px";
-this.highlightCurSel();
-this.language_window.style.visibility="visible";
-};
-GoogieSpell.prototype.flashNoSpellingErrorState=function(){
-this.setStateChanged("no_error_found");
-var me=this;
-AJS.hideElement(this.switch_lan_pic);
-this.gselm.innerHTML=this.lang_no_error_found;
-this.gselm.className="googie_check_spelling_ok";
-this.gselm.style.textDecoration="none";
-this.gselm.style.cursor="default";
-var fu=function(){
-AJS.removeElement(me.gselm);
-me.checkSpellingState();
-};
-setTimeout(fu,1000);
-};
-GoogieSpell.prototype.resumeEditingState=function(){
-this.setStateChanged("resume_editing");
-var me=this;
-AJS.hideElement(me.switch_lan_pic);
-me.gselm.innerHTML=this.lang_rsm_edt;
-me.gselm.onclick=function(e){
-me.resumeEditing(e,me);
-};
-me.gselm.className="googie_check_spelling_ok";
-me.edit_layer.scrollTop=me.ta_scroll_top;
-};
-GoogieSpell.prototype.createChangeLangPic=function(){
-var _dd=AJS.A({"class":"googie_lang_3d_on","style":"padding-left: 6px;"},AJS.IMG({"src":this.img_dir+"change_lang.gif","alt":"Change language"}));
-_dd.onmouseover=function(){
-if(this.className!="googie_lang_3d_click"){
-this.className="googie_lang_3d_on";
+
+this.createListSeparator = function() {
+    var td = document.createElement('td');
+    var tr = document.createElement('tr');
+
+    $(td).html(' ').attr('googie_action_btn', '1')
+       .css({'cursor': 'default', 'font-size': '3px', 'border-top': '1px solid #ccc', 'padding-top': '3px'});
+    tr.appendChild(td);
+
+    return tr;
 }
-};
-var me=this;
-_dd.onclick=function(){
-if(this.className=="googie_lang_3d_click"){
-me.hideLangWindow();
-}else{
-me.showLangWindow(_dd);
-this.className="googie_lang_3d_click";
+
+this.correctError = function(id, elm, l_elm, rm_pre_space) {
+    var old_value = elm.innerHTML;
+    var new_value = l_elm.nodeType == 3 ? l_elm.nodeValue : l_elm.innerHTML;
+    var offset = this.results[id]['attrs']['o'];
+
+    if (rm_pre_space) {
+        var pre_length = elm.previousSibling.innerHTML;
+        elm.previousSibling.innerHTML = pre_length.slice(0, pre_length.length-1);
+        old_value = " " + old_value;
+        offset--;
+    }
+
+    this.hideErrorWindow();
+    this.updateOrginalText(offset, old_value, new_value, id);
+
+    $(elm).html(new_value).css('color', 'green').attr('is_corrected', true);
+
+    this.results[id]['attrs']['l'] = new_value.length;
+
+    if (!this.isDefined(elm.old_value))
+        this.saveOldValue(elm, old_value);
+    
+    this.errorFixed();
 }
-};
-return _dd;
-};
-GoogieSpell.prototype.createSpellDiv=function(){
-var _df=AJS.SPAN({"class":"googie_check_spelling_link"});
-_df.innerHTML=this.lang_chck_spell;
-var _e0=null;
-if(this.show_spell_img){
-_e0=AJS.IMG({"src":this.img_dir+"spellc.gif"});
-}
-return AJS.SPAN(_e0," ",_df);
-};
-GoogieSpell.prototype.checkSpellingState=function(){
-this.setStateChanged("check_spelling");
-var me=this;
-if(this.show_change_lang_pic){
-this.switch_lan_pic=this.createChangeLangPic();
-}else{
-this.switch_lan_pic=AJS.SPAN();
-}
-var _e2=this.createSpellDiv();
-_e2.onclick=function(){
-me.spellCheck(_e2);
-};
-AJS.appendChildNodes(this.spell_container,_e2," ",this.switch_lan_pic);
-this.check_link=_e2;
-};
-GoogieSpell.prototype.setLanguages=function(_e3){
-this.lang_to_word=_e3;
-this.langlist_codes=AJS.keys(_e3);
-};
-GoogieSpell.prototype.decorateTextarea=function(id,_e5,_e6){
-var me=this;
-if(typeof (id)=="string"){
-this.text_area=AJS.getElement(id);
-}else{
-this.text_area=id;
-}
-var _e8;
-if(this.text_area!=null){
-if(AJS.isDefined(_e5)){
-if(typeof (_e5)=="string"){
-this.spell_container=AJS.getElement(_e5);
-}else{
-this.spell_container=_e5;
-}
-}else{
-var _e9=AJS.TABLE();
-var _ea=AJS.TBODY();
-var tr=AJS.TR();
-if(AJS.isDefined(_e6)){
-_e8=_e6;
-}else{
-_e8=this.text_area.offsetWidth+"px";
-}
-var _ec=AJS.TD();
-this.spell_container=_ec;
-tr.appendChild(_ec);
-_ea.appendChild(tr);
-_e9.appendChild(_ea);
-AJS.insertBefore(_e9,this.text_area);
-_e9.style.width="100%";
-_ec.style.width=_e8;
-_ec.style.textAlign="right";
-}
-this.checkSpellingState();
-}else{
-alert("Text area not found");
+
+this.showErrorWindow = function(elm, id) {
+    if (this.show_menu_observer)
+        this.show_menu_observer(this);
+
+    var ref = this;
+    var pos = $(elm).offset();
+    pos.top -= this.edit_layer.scrollTop;
+
+    $(this.error_window).css({'visibility': 'visible',
+       'top': (pos.top+20)+'px', 'left': (pos.left)+'px'}).html('');
+
+    var table = document.createElement('table');
+    var list = document.createElement('tbody');
+
+    $(table).addClass('googie_list').attr('googie_action_btn', '1');
+
+    //Check if we should use custom menu builder, if not we use the default
+    var changed = false;
+    if (this.custom_menu_builder != []) {
+        for (var k=0; k<this.custom_menu_builder.length; k++) {
+            var eb = this.custom_menu_builder[k];
+            if(eb[0]((this.results[id]))){
+                changed = eb[1](this, list, elm);
+                break;
+            }
+        }
+    }
+    if (!changed) {
+        //Build up the result list
+        var suggestions = this.results[id]['suggestions'];
+        var offset = this.results[id]['attrs']['o'];
+        var len = this.results[id]['attrs']['l'];
+
+        if (suggestions.length == 0) {
+            var row = document.createElement('tr');
+            var item = document.createElement('td');
+            var dummy = document.createElement('span');
+
+            $(dummy).text(this.lang_no_suggestions);
+            $(item).attr('googie_action_btn', '1').css('cursor', 'default');
+
+            item.appendChild(dummy);
+            row.appendChild(item);
+            list.appendChild(row);
+        }
+
+        for (i=0; i < suggestions.length; i++) {
+            var row = document.createElement('tr');
+            var item = document.createElement('td');
+            var dummy = document.createElement('span');
+
+            $(dummy).html(suggestions[i]);
+            
+            $(item).bind('mouseover', this.item_onmouseover)
+               .bind('mouseout', this.item_onmouseout)
+               .bind('click', function(e) { ref.correctError(id, elm, e.target.firstChild) });
+
+            item.appendChild(dummy);
+            row.appendChild(item);
+            list.appendChild(row);
+        }
+
+        //The element is changed, append the revert
+        if (elm.is_changed && elm.innerHTML != elm.old_value) {
+            var old_value = elm.old_value;
+            var revert_row = document.createElement('tr');
+            var revert = document.createElement('td');
+            var rev_span = document.createElement('span');
+           
+           $(rev_span).addClass('googie_list_revert').html(this.lang_revert + ' ' + old_value);
+
+            $(revert).bind('mouseover', this.item_onmouseover)
+               .bind('mouseout', this.item_onmouseout)
+               .bind('click', function(e) {
+                   ref.updateOrginalText(offset, elm.innerHTML, old_value, id);
+                   $(elm).attr('is_corrected', true).css('color', '#b91414').html(old_value);
+                   ref.hideErrorWindow();
+               });
+
+            revert.appendChild(rev_span);
+            revert_row.appendChild(revert);
+            list.appendChild(revert_row);
+        }
+        
+        //Append the edit box
+        var edit_row = document.createElement('tr');
+        var edit = document.createElement('td');
+        var edit_input = document.createElement('input');
+        var ok_pic = document.createElement('img');
+       var edit_form = document.createElement('form');
+
+        var onsub = function () {
+            if (edit_input.value != '') {
+                if (!ref.isDefined(elm.old_value))
+                    ref.saveOldValue(elm, elm.innerHTML);
+
+                ref.updateOrginalText(offset, elm.innerHTML, edit_input.value, id);
+               $(elm).attr('is_corrected', true).css('color', 'green').html(edit_input.value);
+                ref.hideErrorWindow();
+            }
+            return false;
+        };
+
+       $(edit_input).width(120).css({'margin': 0, 'padding': 0});
+       $(edit_input).val(elm.innerHTML).attr('googie_action_btn', '1');
+       $(edit).css('cursor', 'default').attr('googie_action_btn', '1');
+
+       $(ok_pic).attr('src', this.img_dir + 'ok.gif')
+           .width(32).height(16)
+           .css({'cursor': 'pointer', 'margin-left': '2px', 'margin-right': '2px'})
+           .bind('click', onsub);
+
+        $(edit_form).attr('googie_action_btn', '1')
+           .css({'margin': 0, 'padding': 0, 'cursor': 'default', 'white-space': 'nowrap'})
+           .bind('submit', onsub);
+        
+       edit_form.appendChild(edit_input);
+       edit_form.appendChild(ok_pic);
+        edit.appendChild(edit_form);
+        edit_row.appendChild(edit);
+        list.appendChild(edit_row);
+
+        //Append extra menu items
+        if (this.extra_menu_items.length > 0)
+           list.appendChild(this.createListSeparator());
+       
+        var loop = function(i) {
+                if (i < ref.extra_menu_items.length) {
+                    var e_elm = ref.extra_menu_items[i];
+
+                    if (!e_elm[2] || e_elm[2](elm, ref)) {
+                        var e_row = document.createElement('tr');
+                        var e_col = document.createElement('td');
+
+                       $(e_col).html(e_elm[0])
+                           .bind('mouseover', ref.item_onmouseover)
+                           .bind('mouseout', ref.item_onmouseout)
+                           .bind('click', function() { return e_elm[1](elm, ref) });
+                       
+                       e_row.appendChild(e_col);
+                        list.appendChild(e_row);
+                    }
+                    loop(i+1);
+                }
+        }
+       
+        loop(0);
+        loop = null;
+
+        //Close button
+        if (this.use_close_btn) {
+           list.appendChild(this.createCloseButton(this.hideErrorWindow));
+        }
+    }
+
+    table.appendChild(list);
+    this.error_window.appendChild(table);
+
+    //Dummy for IE - dropdown bug fix
+    if ($.browser.msie) {
+       if (!this.error_window_iframe) {
+            var iframe = $('<iframe>').css('position', 'absolute').css('z-index', 0);
+           $('body').append(iframe);
+           this.error_window_iframe = iframe;
+        }
+       
+       $(this.error_window_iframe).css({'visibility': 'visible',
+           'top': this.error_window.offsetTop, 'left': this.error_window.offsetLeft,
+           'width': this.error_window.offsetWidth, 'height': this.error_window.offsetHeight});
+    }
 }
-};
 
+
+//////
+// Edit layer (the layer where the suggestions are stored)
+//////
+this.createEditLayer = function(width, height) {
+    this.edit_layer = document.createElement('div');
+    $(this.edit_layer).addClass('googie_edit_layer').width(width-10).height(height);
+
+    if (this.text_area.nodeName.toLowerCase() != 'input' || $(this.text_area).val() == '') {
+        $(this.edit_layer).css('overflow', 'auto').height(height-4);
+    } else {
+        $(this.edit_layer).css('overflow', 'hidden');
+    }
+
+    var ref = this;
+    if (this.edit_layer_dbl_click) {
+        $(this.edit_layer).bind('click', function(e) {
+            if (e.target.className != 'googie_link' && !ref.isErrorWindowShown()) {
+                ref.resumeEditing();
+                var fn1 = function() {
+                    $(ref.text_area).focus();
+                    fn1 = null;
+                };
+                window.setTimeout(fn1, 10);
+            }
+            return false;
+        });
+    }
+}
+
+this.resumeEditing = function() {
+    this.setStateChanged('ready');
+
+    if (this.edit_layer)
+        this.el_scroll_top = this.edit_layer.scrollTop;
+
+    this.hideErrorWindow();
+
+    if (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(text, id) {
+    var elm = document.createElement('span');
+    var ref = this;
+    var d = function (e) {
+           ref.showErrorWindow(elm, id);
+           d = null;
+           return false;
+    };
+    
+    $(elm).html(text).addClass('googie_link').bind('click', d)
+       .attr({'googie_action_btn' : '1', 'g_id' : id, 'is_corrected' : false});
+
+    return elm;
+}
+
+this.createPart = function(txt_part) {
+    if (txt_part == " ")
+        return document.createTextNode(" ");
+
+    txt_part = this.escapeSpecial(txt_part);
+    txt_part = txt_part.replace(/\n/g, "<br>");
+    txt_part = txt_part.replace(/    /g, " &nbsp;");
+    txt_part = txt_part.replace(/^ /g, "&nbsp;");
+    txt_part = txt_part.replace(/ $/g, "&nbsp;");
+    
+    var span = document.createElement('span');
+    $(span).html(txt_part);
+    return span;
+}
+
+this.showErrorsInIframe = function() {
+    var output = document.createElement('div')
+    var pointer = 0;
+    var results = this.results;
+
+    if (results.length > 0) {
+        for (var i=0; i < results.length; i++) {
+            var offset = results[i]['attrs']['o'];
+            var len = results[i]['attrs']['l'];
+            var part_1_text = this.orginal_text.substring(pointer, offset);
+            var part_1 = this.createPart(part_1_text);
+    
+            output.appendChild(part_1);
+            pointer += offset - pointer;
+            
+            //If the last child was an error, then insert some space
+            var err_link = this.createErrorLink(this.orginal_text.substr(offset, len), i);
+            this.error_links.push(err_link);
+            output.appendChild(err_link);
+            pointer += len;
+        }
+        //Insert the rest of the orginal text
+        var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length);
+        var part_2 = this.createPart(part_2_text);
+
+        output.appendChild(part_2);
+    }
+    else
+        output.innerHTML = this.orginal_text;
+
+    $(output).css('text-align', 'left');
+
+    var me = this;
+    if (this.custom_item_evaulator)
+        $.map(this.error_links, function(elm){me.custom_item_evaulator(me, elm)});
+    
+    $(this.edit_layer).append(output);
+
+    //Hide text area and show edit layer
+    $(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.edit_layer.scrollTop = this.ta_scroll_top;
+}
+
+
+//////
+// Choose language menu
+//////
+this.createLangWindow = function() {
+    this.language_window = document.createElement('div');
+    $(this.language_window).addClass('googie_window')
+       .width(100).attr('googie_action_btn', '1');
+
+    //Build up the result list
+    var table = document.createElement('table');
+    var list = document.createElement('tbody');
+    var ref = this;
+
+    $(table).addClass('googie_list').width('100%');
+    this.lang_elms = new Array();
+
+    for (i=0; i < this.langlist_codes.length; i++) {
+        var row = document.createElement('tr');
+        var item = document.createElement('td');
+        var span = document.createElement('span');
+       
+       $(span).text(this.lang_to_word[this.langlist_codes[i]]);
+        this.lang_elms.push(item);
+
+        $(item).attr('googieId', this.langlist_codes[i])
+           .bind('click', function(e) {
+               ref.deHighlightCurSel();
+               ref.setCurrentLanguage($(this).attr('googieId'));
+
+               if (ref.lang_state_observer != null) {
+                   ref.lang_state_observer();
+               }
+
+               ref.highlightCurSel();
+               ref.hideLangWindow();
+           })
+           .bind('mouseover', function(e) { 
+               if (this.className != "googie_list_selected")
+                   this.className = "googie_list_onhover";
+           })
+           .bind('mouseout', function(e) { 
+               if (this.className != "googie_list_selected")
+                   this.className = "googie_list_onout"; 
+           });
+
+       item.appendChild(span);
+        row.appendChild(item);
+        list.appendChild(row);
+    }
+
+    //Close button
+    if (this.use_close_btn) {
+        list.appendChild(this.createCloseButton(function () { ref.hideLangWindow.apply(ref) }));
+    }
+
+    this.highlightCurSel();
+
+    table.appendChild(list);
+    this.language_window.appendChild(table);
+}
+
+this.isLangWindowShown = function() {
+    return $(this.language_window).is(':hidden');
+}
+
+this.hideLangWindow = function() {
+    $(this.language_window).css('visibility', 'hidden');
+    $(this.switch_lan_pic).removeClass().addClass('googie_lang_3d_on');
+}
+
+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 i=0; i < this.lang_elms.length; i++) {
+        if ($(this.lang_elms[i]).attr('googieId') == GOOGIE_CUR_LANG) {
+            this.lang_elms[i].className = "googie_list_selected";
+            this.lang_cur_elm = this.lang_elms[i];
+        }
+        else {
+            this.lang_elms[i].className = "googie_list_onout";
+        }
+    }
+}
+
+this.showLangWindow = function(elm) {
+    if (this.show_menu_observer)
+        this.show_menu_observer(this);
+
+    this.createLangWindow();
+    $('body').append(this.language_window);
+
+    var pos = $(elm).offset();
+    var top = pos.top + $(elm).height();
+    var left = this.change_lang_pic_placement == 'right' ? 
+       pos.left - 100 + $(elm).width() : pos.left + $(elm).width();
+
+    $(this.language_window).css({'visibility': 'visible', 'top' : top+'px','left' : left+'px'});
+
+    this.highlightCurSel();
+}
+
+this.createChangeLangPic = function() {
+    var img = $('<img>')
+       .attr({src: this.img_dir + 'change_lang.gif', 'alt': 'Change language', 'googie_action_btn': '1'});
+
+    var switch_lan = document.createElement('span');
+    var ref = this;
+
+    $(switch_lan).addClass('googie_lang_3d_on')
+       .append(img)
+       .bind('click', function(e) {
+           var elm = this.tagName.toLowerCase() == 'img' ? this.parentNode : this;
+           if($(elm).hasClass('googie_lang_3d_click')) {
+               elm.className = 'googie_lang_3d_on';
+               ref.hideLangWindow();
+           }
+           else {
+               elm.className = 'googie_lang_3d_click';
+               ref.showLangWindow(elm);
+           }
+       });
+
+    return switch_lan;
+}
+
+this.createSpellDiv = function() {
+    var span = document.createElement('span');
+
+    $(span).addClass('googie_check_spelling_link').text(this.lang_chck_spell);
+
+    if (this.show_spell_img) {
+       $(span).append(' ').append($('<img>').attr('src', this.img_dir + 'spellc.gif'));
+    }
+    return span;
+}
+
+
+//////
+// State functions
+/////
+this.flashNoSpellingErrorState = function(on_finish) {
+    this.setStateChanged('no_error_found');
+
+    var ref = this;
+    if (this.main_controller) {
+       var no_spell_errors;
+       if (on_finish) {
+           var fn = function() {
+               on_finish();
+               ref.checkSpellingState();
+           };
+           no_spell_errors = fn;
+       }
+       else
+           no_spell_errors = function () { ref.checkSpellingState() };
+
+        var rsm = $('<span>').text(this.lang_no_error_found);
+        
+        $(this.switch_lan_pic).hide();
+       $(this.spell_span).empty().append(rsm)
+           .removeClass().addClass('googie_check_spelling_ok');
+
+        window.setTimeout(no_spell_errors, 1000);
+    }
+}
+
+this.resumeEditingState = function() {
+    this.setStateChanged('resume_editing');
+
+    //Change link text to resume
+    if (this.main_controller) {
+        var rsm = $('<span>').text(this.lang_rsm_edt);
+       var ref = this;
+
+        $(this.switch_lan_pic).hide();
+        $(this.spell_span).empty().unbind().append(rsm)
+           .bind('click', function() { ref.resumeEditing() })
+           .removeClass().addClass('googie_resume_editing');
+    }
+
+    try { this.edit_layer.scrollTop = this.ta_scroll_top; }
+    catch (e) {};
+}
+
+this.checkSpellingState = function(fire) {
+    if (fire)
+        this.setStateChanged('ready');
+
+    if (this.show_change_lang_pic)
+        this.switch_lan_pic = this.createChangeLangPic();
+    else
+        this.switch_lan_pic = document.createElement('span');
+
+    var span_chck = this.createSpellDiv();
+    var ref = this;
+
+    if (this.custom_spellcheck_starter)
+        $(span_chck).bind('click', function(e) { ref.custom_spellcheck_starter() });
+    else {
+        $(span_chck).bind('click', function(e) { ref.spellCheck() });
+    }
+
+    if (this.main_controller) {
+        if (this.change_lang_pic_placement == 'left') {
+           $(this.spell_container).empty().append(this.switch_lan_pic).append(' ').append(span_chck);
+        } else {
+           $(this.spell_container).empty().append(span_chck).append(' ').append(this.switch_lan_pic);
+       }
+    }
+
+    this.spell_span = span_chck;
+}
+
+
+//////
+// Misc. functions
+/////
+this.isDefined = function(o) {
+    return (o != 'undefined' && o != 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(c_fn) {
+    return this.createButton(this.lang_close, 'googie_list_close', c_fn);
+}
+
+this.createButton = function(name, css_class, c_fn) {
+    var btn_row = document.createElement('tr');
+    var btn = document.createElement('td');
+    var spn_btn;
+
+    if (css_class) {
+        spn_btn = document.createElement('span');
+       $(spn_btn).addClass(css_class).html(name);
+    } else {
+        spn_btn = document.createTextNode(name);
+    }
+
+    $(btn).bind('click', c_fn)
+       .bind('mouseover', this.item_onmouseover)
+       .bind('mouseout', this.item_onmouseout);
+
+    btn.appendChild(spn_btn);
+    btn_row.appendChild(btn);
+
+    return btn_row;
+}
+
+this.removeIndicator = function(elm) {
+    //$(this.indicator).remove();
+    // roundcube mod.
+    if (window.rcmail)
+       rcmail.set_busy(false);
+}
+
+this.appendIndicator = function(elm) {
+    // modified by roundcube
+    if (window.rcmail)
+       rcmail.set_busy(true, 'checking');
+/*    
+    this.indicator = document.createElement('img');
+    $(this.indicator).attr('src', this.img_dir + 'indicator.gif')
+       .css({'margin-right': '5px', 'text-decoration': 'none'}).width(16).height(16);
+    
+    if (elm)
+       $(this.indicator).insertBefore(elm);
+    else
+       $('body').append(this.indicator);
+*/                                 
+}
+
+this.createFocusLink = function(name) {
+    var link = document.createElement('a');
+    $(link).attr({'href': 'javascript:;', 'name': name});
+    return link;
+}
+
+this.item_onmouseover = function(e) {
+    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(e) {
+    if (this.className != "googie_list_revert" && this.className != "googie_list_close")
+        this.className = "googie_list_onout";
+    else
+        this.parentNode.className = "googie_list_onout";
+}
+
+
+};
diff --git a/program/js/googiespell.js.src b/program/js/googiespell.js.src
deleted file mode 100644 (file)
index 8b9d1cc..0000000
+++ /dev/null
@@ -1,1308 +0,0 @@
-/*
-Last Modified: 28/04/06 16:28:09
-
-  AmiJs library
-    A very small library with DOM and Ajax functions.
-    For a much larger script look on http://www.mochikit.com/
-  AUTHOR
-    4mir Salihefendic (http://amix.dk) - amix@amix.dk
-  LICENSE
-    Copyright (c) 2006 Amir Salihefendic. All rights reserved.
-    Copyright (c) 2005 Bob Ippolito. All rights reserved.
-    http://www.opensource.org/licenses/mit-license.php
-  VERSION
-    2.1
-  SITE
-    http://amix.dk/amijs
-**/
-
-var AJS = {
-////
-// Accessor functions
-////
-  /**
-   * @returns The element with the id
-   */
-  getElement: function(id) {
-    if(typeof(id) == "string") 
-      return document.getElementById(id);
-    else
-      return id;
-  },
-
-  /**
-   * @returns The elements with the ids
-   */
-  getElements: function(/*id1, id2, id3*/) {
-    var elements = new Array();
-      for (var i = 0; i < arguments.length; i++) {
-        var element = this.getElement(arguments[i]);
-        elements.push(element);
-      }
-      return elements;
-  },
-
-  /**
-   * @returns The GET query argument
-   */
-  getQueryArgument: function(var_name) {
-    var query = window.location.search.substring(1);
-    var vars = query.split("&");
-    for (var i=0;i<vars.length;i++) {
-      var pair = vars[i].split("=");
-      if (pair[0] == var_name) {
-        return pair[1];
-      }
-    }
-    return null;
-  },
-
-  /**
-   * @returns If the browser is Internet Explorer
-   */
-  isIe: function() {
-    return (navigator.userAgent.toLowerCase().indexOf("msie") != -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1);
-  },
-
-  /**
-   * @returns The document body   
-   */
-  getBody: function() {
-    return this.getElementsByTagAndClassName('body')[0] 
-  },
-
-  /**
-   * @returns All the elements that have a specific tag name or class name
-   */
-  getElementsByTagAndClassName: function(tag_name, class_name, /*optional*/ parent) {
-    var class_elements = new Array();
-    if(!this.isDefined(parent))
-      parent = document;
-    if(!this.isDefined(tag_name))
-      tag_name = '*';
-
-    var els = parent.getElementsByTagName(tag_name);
-    var els_len = els.length;
-    var pattern = new RegExp("(^|\\s)" + class_name + "(\\s|$)");
-
-    for (i = 0, j = 0; i < els_len; i++) {
-      if ( pattern.test(els[i].className) || class_name == null ) {
-        class_elements[j] = els[i];
-        j++;
-      }
-    }
-    return class_elements;
-  },
-
-
-////
-// DOM manipulation
-////
-  /**
-   * Appends some nodes to a node
-   */
-  appendChildNodes: function(node/*, nodes...*/) {
-    if(arguments.length >= 2) {
-      for(var i=1; i < arguments.length; i++) {
-        var n = arguments[i];
-        if(typeof(n) == "string")
-          n = document.createTextNode(n);
-        if(this.isDefined(n))
-          node.appendChild(n);
-      }
-    }
-    return node;
-  },
-
-  /**
-   * Replaces a nodes children with another node(s)
-   */
-  replaceChildNodes: function(node/*, nodes...*/) {
-    var child;
-    while ((child = node.firstChild)) {
-      node.removeChild(child);
-    }
-    if (arguments.length < 2) {
-      return node;
-    } else {
-      return this.appendChildNodes.apply(this, arguments);
-    }
-  },
-
-  /**
-   * Insert a node after another node
-   */
-  insertAfter: function(node, referenceNode) {
-    referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
-  },
-  
-  /**
-   * Insert a node before another node
-   */
-  insertBefore: function(node, referenceNode) {
-    referenceNode.parentNode.insertBefore(node, referenceNode);
-  },
-  
-  /**
-   * Shows the element
-   */
-  showElement: function(elm) {
-    elm.style.display = '';
-  },
-  
-  /**
-   * Hides the element
-   */
-  hideElement: function(elm) {
-    elm.style.display = 'none';
-  },
-
-  isElementHidden: function(elm) {
-    return elm.style.visibility == "hidden";
-  },
-  
-  /**
-   * Swaps one element with another. To delete use swapDOM(elm, null)
-   */
-  swapDOM: function(dest, src) {
-    dest = this.getElement(dest);
-    var parent = dest.parentNode;
-    if (src) {
-      src = this.getElement(src);
-      parent.replaceChild(src, dest);
-    } else {
-      parent.removeChild(dest);
-    }
-    return src;
-  },
-
-  /**
-   * Removes an element from the world
-   */
-  removeElement: function(elm) {
-    this.swapDOM(elm, null);
-  },
-
-  /**
-   * @returns Is an object a dictionary?
-   */
-  isDict: function(o) {
-    var str_repr = String(o);
-    return str_repr.indexOf(" Object") != -1;
-  },
-  
-  /**
-   * Creates a DOM element
-   * @param {String} name The elements DOM name
-   * @param {Dict} attrs Attributes sent to the function
-   */
-  createDOM: function(name, attrs) {
-    var i=0;
-    elm = document.createElement(name);
-
-    if(this.isDict(attrs[i])) {
-      for(k in attrs[0]) {
-        if(k == "style")
-          elm.style.cssText = attrs[0][k];
-        else if(k == "class")
-          elm.className = attrs[0][k];
-        else
-          elm.setAttribute(k, attrs[0][k]);
-      }
-      i++;
-    }
-
-    if(attrs[0] == null)
-      i = 1;
-
-    for(i; i < attrs.length; i++) {
-      var n = attrs[i];
-      if(this.isDefined(n)) {
-        if(typeof(n) == "string")
-          n = document.createTextNode(n);
-        elm.appendChild(n);
-      }
-    }
-    return elm;
-  },
-
-  UL: function() { return this.createDOM.apply(this, ["ul", arguments]); },
-  LI: function() { return this.createDOM.apply(this, ["li", arguments]); },
-  TD: function() { return this.createDOM.apply(this, ["td", arguments]); },
-  TR: function() { return this.createDOM.apply(this, ["tr", arguments]); },
-  TH: function() { return this.createDOM.apply(this, ["th", arguments]); },
-  TBODY: function() { return this.createDOM.apply(this, ["tbody", arguments]); },
-  TABLE: function() { return this.createDOM.apply(this, ["table", arguments]); },
-  INPUT: function() { return this.createDOM.apply(this, ["input", arguments]); },
-  SPAN: function() { return this.createDOM.apply(this, ["span", arguments]); },
-  B: function() { return this.createDOM.apply(this, ["b", arguments]); },
-  A: function() { return this.createDOM.apply(this, ["a", arguments]); },
-  DIV: function() { return this.createDOM.apply(this, ["div", arguments]); },
-  IMG: function() { return this.createDOM.apply(this, ["img", arguments]); },
-  BUTTON: function() { return this.createDOM.apply(this, ["button", arguments]); },
-  H1: function() { return this.createDOM.apply(this, ["h1", arguments]); },
-  H2: function() { return this.createDOM.apply(this, ["h2", arguments]); },
-  H3: function() { return this.createDOM.apply(this, ["h3", arguments]); },
-  BR: function() { return this.createDOM.apply(this, ["br", arguments]); },
-  TEXTAREA: function() { return this.createDOM.apply(this, ["textarea", arguments]); },
-  FORM: function() { return this.createDOM.apply(this, ["form", arguments]); },
-  P: function() { return this.createDOM.apply(this, ["p", arguments]); },
-  SELECT: function() { return this.createDOM.apply(this, ["select", arguments]); },
-  OPTION: function() { return this.createDOM.apply(this, ["option", arguments]); },
-  TN: function(text) { return document.createTextNode(text); },
-  IFRAME: function() { return this.createDOM.apply(this, ["iframe", arguments]); },
-  SCRIPT: function() { return this.createDOM.apply(this, ["script", arguments]); },
-
-////
-// Ajax functions
-////
-  /**
-   * @returns A new XMLHttpRequest object 
-   */
-  getXMLHttpRequest: function() {
-    var try_these = [
-      function () { return new XMLHttpRequest(); },
-      function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
-      function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
-      function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
-      function () { throw "Browser does not support XMLHttpRequest"; }
-    ];
-    for (var i = 0; i < try_these.length; i++) {
-      var func = try_these[i];
-      try {
-        return func();
-      } catch (e) {
-      }
-    }
-  },
-  
-  /**
-   * Use this function to do a simple HTTP Request
-   */
-  doSimpleXMLHttpRequest: function(url) {
-    var req = this.getXMLHttpRequest();
-    req.open("GET", url, true);
-    return this.sendXMLHttpRequest(req);
-  },
-
-  getRequest: function(url, data) {
-    var req = this.getXMLHttpRequest();
-    req.open("POST", url, true);
-    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
-    return this.sendXMLHttpRequest(req);
-  },
-
-  /**
-   * Send a XMLHttpRequest
-   */
-  sendXMLHttpRequest: function(req, data) {
-    var d = new AJSDeferred(req);
-
-    var onreadystatechange = function () {
-      if (req.readyState == 4) {
-        try {
-          var status = req.status;
-        }
-        catch(e) {};
-        if(status == 200 || status == 304 || req.responseText == null) {
-          d.callback(req, data);
-        }
-        else {
-          d.errback();
-        }
-      }
-    }
-    req.onreadystatechange = onreadystatechange;
-    return d;
-  },
-  
-  /**
-   * Represent an object as a string
-   */
-  reprString: function(o) {
-    return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
-    ).replace(/[\f]/g, "\\f"
-    ).replace(/[\b]/g, "\\b"
-    ).replace(/[\n]/g, "\\n"
-    ).replace(/[\t]/g, "\\t"
-    ).replace(/[\r]/g, "\\r");
-  },
-  
-  /**
-   * Serialize an object to JSON notation
-   */
-  serializeJSON: function(o) {
-    var objtype = typeof(o);
-    if (objtype == "undefined") {
-      return "undefined";
-    } else if (objtype == "number" || objtype == "boolean") {
-      return o + "";
-    } else if (o === null) {
-      return "null";
-    }
-    if (objtype == "string") {
-      return this.reprString(o);
-    }
-    var me = arguments.callee;
-    var newObj;
-    if (typeof(o.__json__) == "function") {
-      newObj = o.__json__();
-      if (o !== newObj) {
-        return me(newObj);
-      }
-    }
-    if (typeof(o.json) == "function") {
-      newObj = o.json();
-      if (o !== newObj) {
-        return me(newObj);
-      }
-    }
-    if (objtype != "function" && typeof(o.length) == "number") {
-      var res = [];
-      for (var i = 0; i < o.length; i++) {
-        var val = me(o[i]);
-        if (typeof(val) != "string") {
-          val = "undefined";
-        }
-        res.push(val);
-      }
-      return "[" + res.join(",") + "]";
-    }
-    res = [];
-    for (var k in o) {
-      var useKey;
-      if (typeof(k) == "number") {
-        useKey = '"' + k + '"';
-      } else if (typeof(k) == "string") {
-        useKey = this.reprString(k);
-      } else {
-        // skip non-string or number keys
-        continue;
-      }
-      val = me(o[k]);
-      if (typeof(val) != "string") {
-        // skip non-serializable values
-        continue;
-      }
-      res.push(useKey + ":" + val);
-    }
-    return "{" + res.join(",") + "}";
-  },
-
-  /**
-   * Send and recive JSON using GET
-   */
-  loadJSONDoc: function(url) {
-    var d = this.getRequest(url);
-    var eval_req = function(req) {
-      var text = req.responseText;
-      return eval('(' + text + ')');
-    };
-    d.addCallback(eval_req);
-    return d;
-  },
-  
-  
-////
-// Misc.
-////
-  /**
-   * Alert the objects key attrs 
-   */
-  keys: function(obj) {
-    var rval = [];
-    for (var prop in obj) {
-      rval.push(prop);
-    }
-    return rval;
-  },
-
-  urlencode: function(str) {
-    return encodeURIComponent(str.toString());
-  },
-
-  /**
-   * @returns True if the object is defined, otherwise false
-   */
-  isDefined: function(o) {
-    return (o != "undefined" && o != null)
-  },
-  
-  /**
-   * @returns True if an object is a array, false otherwise
-   */
-  isArray: function(obj) {
-    try { return (typeof(obj.length) == "undefined") ? false : true; }
-    catch(e)
-    { return false; }
-  },
-
-  isObject: function(obj) {
-    return (obj && typeof obj == 'object');
-  },
-
-  /**
-   * Export DOM elements to the global namespace
-   */
-  exportDOMElements: function() {
-    UL = this.UL;
-    LI = this.LI;
-    TD = this.TD;
-    TR = this.TR;
-    TH = this.TH;
-    TBODY = this.TBODY;
-    TABLE = this.TABLE;
-    INPUT = this.INPUT;
-    SPAN = this.SPAN;
-    B = this.B;
-    A = this.A;
-    DIV = this.DIV;
-    IMG = this.IMG;
-    BUTTON = this.BUTTON;
-    H1 = this.H1;
-    H2 = this.H2;
-    H3 = this.H3;
-    BR = this.BR;
-    TEXTAREA = this.TEXTAREA;
-    FORM = this.FORM;
-    P = this.P;
-    SELECT = this.SELECT;
-    OPTION = this.OPTION;
-    TN = this.TN;
-    IFRAME = this.IFRAME;
-    SCRIPT = this.SCRIPT;
-  },
-
-  /**
-   * Export AmiJS functions to the global namespace
-   */
-  exportToGlobalScope: function() {
-    getElement = this.getElement;
-    getQueryArgument = this.getQueryArgument;
-    isIe = this.isIe;
-    $ = this.getElement;
-    getElements = this.getElements;
-    getBody = this.getBody;
-    getElementsByTagAndClassName = this.getElementsByTagAndClassName;
-    appendChildNodes = this.appendChildNodes;
-    ACN = appendChildNodes;
-    replaceChildNodes = this.replaceChildNodes;
-    RCN = replaceChildNodes;
-    insertAfter = this.insertAfter;
-    insertBefore = this.insertBefore;
-    showElement = this.showElement;
-    hideElement = this.hideElement;
-    isElementHidden = this.isElementHidden;
-    swapDOM = this.swapDOM;
-    removeElement = this.removeElement;
-    isDict = this.isDict;
-    createDOM = this.createDOM;
-    this.exportDOMElements();
-    getXMLHttpRequest = this.getXMLHttpRequest;
-    doSimpleXMLHttpRequest = this.doSimpleXMLHttpRequest;
-    getRequest = this.getRequest;
-    sendXMLHttpRequest = this.sendXMLHttpRequest;
-    reprString = this.reprString;
-    serializeJSON = this.serializeJSON;
-    loadJSONDoc = this.loadJSONDoc;
-    keys = this.keys;
-    isDefined = this.isDefined;
-    isArray = this.isArray;
-  }
-}
-
-
-
-AJSDeferred = function(req) {
-  this.callbacks = [];
-  this.req = req;
-
-  this.callback = function (res) {
-    while (this.callbacks.length > 0) {
-      var fn = this.callbacks.pop();
-      res = fn(res);
-    }
-  };
-
-  this.errback = function(e){
-    alert("Error encountered:\n" + e);
-  };
-
-  this.addErrback = function(fn) {
-    this.errback = fn;
-  };
-
-  this.addCallback = function(fn) {
-    this.callbacks.unshift(fn);
-  };
-
-  this.addCallbacks = function(fn1, fn2) {
-    this.addCallback(fn1);
-    this.addErrback(fn2);
-  };
-
-  this.sendReq = function(data) {
-    if(AJS.isObject(data)) {
-      var post_data = [];
-      for(k in data) {
-        post_data.push(k + "=" + AJS.urlencode(data[k]));
-      }
-      post_data = post_data.join("&");
-      this.req.send(post_data);
-    }
-    else if(AJS.isDefined(data))
-      this.req.send(data);
-    else {
-      this.req.send("");
-    }
-  };
-};
-AJSDeferred.prototype = new AJSDeferred();
-
-
-
-
-
-
-/****
-Last Modified: 28/04/06 15:26:06
-
- GoogieSpell
-   Google spell checker for your own web-apps :)
-   Copyright Amir Salihefendic 2006
- LICENSE
-  GPL (see gpl.txt for more information)
-  This basically means that you can't use this script with/in proprietary software!
-  There is another license that permits you to use this script with proprietary software. Check out:... for more info.
-  AUTHOR
-   4mir Salihefendic (http://amix.dk) - amix@amix.dk
- VERSION
-        3.22
-****/
-var GOOGIE_CUR_LANG = "en";
-
-function GoogieSpell(img_dir, server_url) {
-  var cookie_value;
-  var lang;
-  cookie_value = getCookie('language');
-
-  if(cookie_value != null)
-    GOOGIE_CUR_LANG = cookie_value;
-
-  this.img_dir = img_dir;
-  this.server_url = server_url;
-
-  this.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 = AJS.keys(this.lang_to_word);
-
-  this.show_change_lang_pic = true;
-
-  this.lang_state_observer = null;
-
-  this.spelling_state_observer = null;
-
-  this.request = null;
-  this.error_window = null;
-  this.language_window = null;
-  this.edit_layer = null;
-  this.orginal_text = null;
-  this.results = null;
-  this.text_area = null;
-  this.gselm = null;
-  this.ta_scroll_top = 0;
-  this.el_scroll_top = 0;
-
-  this.lang_chck_spell = "Check spelling";
-  this.lang_rsm_edt = "Resume editing";
-  this.lang_close = "Close";
-  this.lang_no_error_found = "No spelling errors found";
-  this.lang_revert = "Revert to";
-  this.show_spell_img = false;  // modified by roundcube
-}
-
-GoogieSpell.prototype.setStateChanged = function(current_state) {
-  if(this.spelling_state_observer != null)
-    this.spelling_state_observer(current_state);
-}
-
-GoogieSpell.item_onmouseover = function(e) {
-  var elm = GoogieSpell.getEventElm(e);
-  if(elm.className != "googie_list_close" && elm.className != "googie_list_revert")
-    elm.className = "googie_list_onhover";
-  else
-    elm.parentNode.className = "googie_list_onhover";
-}
-
-GoogieSpell.item_onmouseout = function(e) {
-  var elm = GoogieSpell.getEventElm(e);
-  if(elm.className != "googie_list_close" && elm.className != "googie_list_revert")
-    elm.className = "googie_list_onout";
-  else
-    elm.parentNode.className = "googie_list_onout";
-}
-
-GoogieSpell.prototype.getGoogleUrl = function() {
-  return this.server_url + GOOGIE_CUR_LANG;
-}
-
-GoogieSpell.prototype.spellCheck = function(elm, name) {
-  this.ta_scroll_top = this.text_area.scrollTop;
-
-  this.appendIndicator(elm);
-
-  try {
-    this.hideLangWindow();
-  }
-  catch(e) {}
-  
-  this.gselm = elm;
-
-  this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight);
-
-  this.createErrorWindow();
-  AJS.getBody().appendChild(this.error_window);
-
-  try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } 
-  catch (e) { }
-
-  this.gselm.onclick = null;
-
-  this.orginal_text = this.text_area.value;
-  var me = this;
-
-  //Create request
-  var d = AJS.getRequest(this.getGoogleUrl());
-  var reqdone = function(req) {
-    var r_text = req.responseText;
-    if(r_text.match(/<c.*>/) != null) {
-      var results = GoogieSpell.parseResult(r_text);
-      //Before parsing be sure that errors were found
-      me.results = results;
-      me.showErrorsInIframe(results);
-      me.resumeEditingState();
-    }
-    else {
-      me.flashNoSpellingErrorState();
-    }
-    me.removeIndicator();
-  };
-
-  var reqfailed = function(req) {
-    alert("An error was encountered on the server. Please try again later.");
-    AJS.removeElement(me.gselm);
-    me.checkSpellingState();
-    me.removeIndicator();
-  };
-  
-  d.addCallback(reqdone);
-  d.addErrback(reqfailed);
-
-  var req_text = GoogieSpell.escapeSepcial(this.orginal_text);
-  d.sendReq(GoogieSpell.createXMLReq(req_text));
-}
-
-GoogieSpell.escapeSepcial = function(val) {
-  return val.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
-}
-
-GoogieSpell.createXMLReq = function (text) {
-  return '<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>' + text + '</text></spellrequest>';
-}
-
-//Retunrs an array
-//result[item] -> ['attrs']
-//                ['suggestions']
-GoogieSpell.parseResult = function(r_text) {
-  var re_split_attr_c = /\w="\d+"/g;
-  var re_split_text = /\t/g;
-
-  var matched_c = r_text.match(/<c[^>]*>[^<]*<\/c>/g);
-  var results = new Array();
-  
-  for(var i=0; i < matched_c.length; i++) {
-    var item = new Array();
-
-    //Get attributes
-    item['attrs'] = new Array();
-    var split_c = matched_c[i].match(re_split_attr_c);
-    for(var j=0; j < split_c.length; j++) {
-      var c_attr = split_c[j].split(/=/);
-      item['attrs'][c_attr[0]] = parseInt(c_attr[1].replace('"', ''));
-    }
-
-    //Get suggestions
-    item['suggestions'] = new Array();
-    var only_text = matched_c[i].replace(/<[^>]*>/g, "");
-    var split_t = only_text.split(re_split_text);
-    for(var k=0; k < split_t.length; k++) {
-    if(split_t[k] != "")
-      item['suggestions'].push(split_t[k]);
-    }
-    results.push(item);
-  }
-  return results;
-}
-
-/****
- Error window (the drop-down window)
-****/
-GoogieSpell.prototype.createErrorWindow = function() {
-  this.error_window = AJS.DIV();
-  this.error_window.className = "googie_window";
-}
-
-GoogieSpell.prototype.hideErrorWindow = function() {
-  this.error_window.style.visibility = "hidden";
-}
-
-GoogieSpell.prototype.updateOrginalText = function(offset, old_value, new_value, id) {
-  var part_1 = this.orginal_text.substring(0, offset);
-  var part_2 = this.orginal_text.substring(offset+old_value.length);
-  this.orginal_text = part_1 + new_value + part_2;
-  var add_2_offset = new_value.length - old_value.length;
-  for(var j=0; j < this.results.length; j++) {
-    //Don't edit the offset of the current item
-    if(j != id && j > id){
-      this.results[j]['attrs']['o'] += add_2_offset;
-    }
-  }
-}
-
-GoogieSpell.prototype.saveOldValue = function (id, old_value) {
-  this.results[id]['is_changed'] = true;
-  this.results[id]['old_value'] = old_value;
-}
-
-GoogieSpell.prototype.showErrorWindow = function(elm, id) {
-  var me = this;
-
-  var abs_pos = GoogieSpell.absolutePosition(elm);
-  abs_pos.y -= this.edit_layer.scrollTop;
-  this.error_window.style.visibility = "visible";
-  this.error_window.style.top = (abs_pos.y+20) + "px";
-  this.error_window.style.left = (abs_pos.x) + "px";
-  this.error_window.innerHTML = "";
-
-  //Build up the result list
-  var table = AJS.TABLE({'class': 'googie_list'});
-  var list = AJS.TBODY();
-
-  var suggestions = this.results[id]['suggestions'];
-  var offset = this.results[id]['attrs']['o'];
-  var len = this.results[id]['attrs']['l'];
-
-  if(suggestions.length == 0) {
-    var row = AJS.TR();
-    var item = AJS.TD();
-    var dummy = AJS.SPAN();
-    item.appendChild(AJS.TN("No suggestions :("));
-    row.appendChild(item);
-    list.appendChild(row);
-  }
-
-  for(i=0; i < suggestions.length; i++) {
-    var row = AJS.TR();
-    var item = AJS.TD();
-    var dummy = AJS.SPAN();
-    dummy.innerHTML = suggestions[i];
-    item.appendChild(AJS.TN(dummy.innerHTML));
-    
-    item.onclick = function(e) {
-      var l_elm = GoogieSpell.getEventElm(e);
-      var old_value = elm.innerHTML;
-      var new_value = l_elm.innerHTML;
-
-      elm.style.color = "green";
-      elm.innerHTML = l_elm.innerHTML;
-      me.hideErrorWindow();
-
-      me.updateOrginalText(offset, old_value, new_value, id);
-
-      //Update to the new length
-      me.results[id]['attrs']['l'] = new_value.length;
-      me.saveOldValue(id, old_value);
-    };
-    item.onmouseover = GoogieSpell.item_onmouseover;
-    item.onmouseout = GoogieSpell.item_onmouseout;
-    row.appendChild(item);
-    list.appendChild(row);
-  }
-  
-  //The element is changed, append the revert
-  if(this.results[id]['is_changed']) {
-    var old_value = this.results[id]['old_value'];
-    var offset = this.results[id]['attrs']['o'];
-    var revert_row = AJS.TR();
-    var revert = AJS.TD();
-
-    revert.onmouseover = GoogieSpell.item_onmouseover;
-    revert.onmouseout = GoogieSpell.item_onmouseout;
-    var rev_span = AJS.SPAN({'class': 'googie_list_revert'});
-    rev_span.innerHTML = this.lang_revert + " " + old_value;
-    revert.appendChild(rev_span);
-
-    revert.onclick = function(e) { 
-      me.updateOrginalText(offset, elm.innerHTML, old_value, id);
-      elm.style.color = "#b91414";
-      elm.innerHTML = old_value;
-      me.hideErrorWindow();
-    };
-
-    revert_row.appendChild(revert);
-    list.appendChild(revert_row);
-  }
-
-  //Append the edit box
-  var edit_row = AJS.TR();
-  var edit = AJS.TD();
-
-  var edit_input = AJS.INPUT({'style': 'width: 120px; margin:0; padding:0'});
-
-  var onsub = function () {
-    if(edit_input.value != "") {
-      me.saveOldValue(id, elm.innerHTML);
-      me.updateOrginalText(offset, elm.innerHTML, edit_input.value, id);
-      elm.style.color = "green"
-      elm.innerHTML = edit_input.value;
-      
-      me.hideErrorWindow();
-      return false;
-    }
-  };
-  
-  var ok_pic = AJS.IMG({'src': this.img_dir + "ok.gif", 'style': 'width: 32px; height: 16px; margin-left: 2px; margin-right: 2px;'});
-  var edit_form = AJS.FORM({'style': 'margin: 0; padding: 0'}, edit_input, ok_pic);
-  ok_pic.onclick = onsub;
-  edit_form.onsubmit = onsub;
-  
-  edit.appendChild(edit_form);
-  edit_row.appendChild(edit);
-  list.appendChild(edit_row);
-
-  //Close button
-  var close_row = AJS.TR();
-  var close = AJS.TD();
-
-  close.onmouseover = GoogieSpell.item_onmouseover;
-  close.onmouseout = GoogieSpell.item_onmouseout;
-
-  var spn_close = AJS.SPAN({'class': 'googie_list_close'});
-  spn_close.innerHTML = this.lang_close;
-  close.appendChild(spn_close);
-  close.onclick = function() { me.hideErrorWindow()};
-  close_row.appendChild(close);
-  list.appendChild(close_row);
-
-  table.appendChild(list);
-  this.error_window.appendChild(table);
-}
-
-
-/****
-  Edit layer (the layer where the suggestions are stored)
-****/
-GoogieSpell.prototype.createEditLayer = function(width, height) {
-  this.edit_layer = AJS.DIV({'class': 'googie_edit_layer'});
-  
-  //Set the style so it looks like edit areas
-  this.edit_layer.className = this.text_area.className;
-  this.edit_layer.style.border = "1px solid #999";
-  this.edit_layer.style.overflow = "auto";
-  this.edit_layer.style.backgroundColor = "#F1EDFE";
-  this.edit_layer.style.padding = "3px";
-
-  this.edit_layer.style.width = (width-8) + "px";
-  this.edit_layer.style.height = height + "px";
-}
-
-GoogieSpell.prototype.resumeEditing = function(e, me) {
-  this.setStateChanged("check_spelling");
-  me.switch_lan_pic.style.display = "inline";
-
-  this.el_scroll_top = me.edit_layer.scrollTop;
-
-  var elm = GoogieSpell.getEventElm(e);
-  AJS.replaceChildNodes(elm, this.createSpellDiv());
-
-  elm.onclick = function(e) {
-    me.spellCheck(elm, me.text_area.id);
-  };
-  me.hideErrorWindow();
-
-  //Remove the EDIT_LAYER
-  me.edit_layer.parentNode.removeChild(me.edit_layer);
-
-  me.text_area.value = me.orginal_text;
-  AJS.showElement(me.text_area);
-  me.gselm.className = "googie_no_style";
-
-  me.text_area.scrollTop = this.el_scroll_top;
-
-  elm.onmouseout = null;
-}
-
-GoogieSpell.prototype.createErrorLink = function(text, id) {
-  var elm = AJS.SPAN({'class': 'googie_link'});
-  var me = this;
-  elm.onclick = function () {
-    me.showErrorWindow(elm, id);
-  };
-  elm.innerHTML = text;
-  return elm;
-}
-
-GoogieSpell.createPart = function(txt_part) {
-  if(txt_part == " ")
-    return AJS.TN(" ");
-  var result = AJS.SPAN();
-
-  var is_first = true;
-  var is_safari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1);
-
-  var part = AJS.SPAN();
-  txt_part = GoogieSpell.escapeSepcial(txt_part);
-  txt_part = txt_part.replace(/\n/g, "<br>");
-  txt_part = txt_part.replace(/  /g, " &nbsp;");
-  txt_part = txt_part.replace(/^ /g, "&nbsp;");
-  txt_part = txt_part.replace(/ $/g, "&nbsp;");
-  
-  part.innerHTML = txt_part;
-
-  return part;
-}
-
-GoogieSpell.prototype.showErrorsInIframe = function(results) {
-  var output = AJS.DIV();
-  output.style.textAlign = "left";
-  var pointer = 0;
-  for(var i=0; i < results.length; i++) {
-    var offset = results[i]['attrs']['o'];
-    var len = results[i]['attrs']['l'];
-    
-    var part_1_text = this.orginal_text.substring(pointer, offset);
-    var part_1 = GoogieSpell.createPart(part_1_text);
-    output.appendChild(part_1);
-    pointer += offset - pointer;
-    
-    //If the last child was an error, then insert some space
-    output.appendChild(this.createErrorLink(this.orginal_text.substr(offset, len), i));
-    pointer += len;
-  }
-  //Insert the rest of the orginal text
-  var part_2_text = this.orginal_text.substr(pointer, this.orginal_text.length);
-
-  var part_2 = GoogieSpell.createPart(part_2_text);
-  output.appendChild(part_2);
-
-  this.edit_layer.appendChild(output);
-
-  //Hide text area
-  AJS.hideElement(this.text_area);
-  this.text_area.parentNode.insertBefore(this.edit_layer, this.text_area.nextSibling);
-  this.edit_layer.scrollTop = this.ta_scroll_top;
-}
-
-GoogieSpell.Position = function(x, y) {
-  this.x = x;
-  this.y = y;
-}      
-
-//Get the absolute position of menu_slide
-GoogieSpell.absolutePosition = function(element) {
-  //Create a new object that has elements y and x pos...
-  var posObj = new GoogieSpell.Position(element.offsetLeft, element.offsetTop);
-
-  //Check if the element has an offsetParent - if it has .. loop until it has not
-  if(element.offsetParent) {
-    var temp_pos =     GoogieSpell.absolutePosition(element.offsetParent);
-    posObj.x += temp_pos.x;
-    posObj.y += temp_pos.y;
-  }
-  return posObj;
-}
-
-GoogieSpell.getEventElm = function(e) {
-       var targ;
-       if (!e) var e = window.event;
-       if (e.target) targ = e.target;
-       else if (e.srcElement) targ = e.srcElement;
-       if (targ.nodeType == 3) // defeat Safari bug
-               targ = targ.parentNode;
-  return targ;
-}
-
-GoogieSpell.prototype.removeIndicator = function(elm) {
-  // modified by roundcube
-  if (window.rcube_webmail_client)
-    rcube_webmail_client.set_busy(false);
-  //AJS.removeElement(this.indicator);
-}
-
-GoogieSpell.prototype.appendIndicator = function(elm) {
-  // modified by roundcube
-  if (window.rcube_webmail_client)
-    rcube_webmail_client.set_busy(true, 'checking');
-/*
-  var img = AJS.IMG({'src': this.img_dir + 'indicator.gif', 'style': 'margin-right: 5px;'});
-  img.style.width = "16px";
-  img.style.height = "16px";
-  this.indicator = img;
-  img.style.textDecoration = "none";
-  AJS.insertBefore(img, elm);
-  */
-}
-
-/****
- Choose language
-****/
-GoogieSpell.prototype.createLangWindow = function() {
-  this.language_window = AJS.DIV({'class': 'googie_window'});
-  this.language_window.style.width = "130px";
-
-  //Build up the result list
-  var table = AJS.TABLE({'class': 'googie_list'});
-  var list = AJS.TBODY();
-
-  this.lang_elms = new Array();
-
-  for(i=0; i < this.langlist_codes.length; i++) {
-    var row = AJS.TR();
-    var item = AJS.TD();
-    item.googieId = this.langlist_codes[i];
-    this.lang_elms.push(item);
-    var lang_span = AJS.SPAN();
-    lang_span.innerHTML = this.lang_to_word[this.langlist_codes[i]];
-    item.appendChild(AJS.TN(lang_span.innerHTML));
-
-    var me = this;
-    
-    item.onclick = function(e) {
-      var elm = GoogieSpell.getEventElm(e);
-      me.deHighlightCurSel();
-
-      me.setCurrentLanguage(elm.googieId);
-
-      if(me.lang_state_observer != null) {
-        me.lang_state_observer();
-      }
-
-      me.highlightCurSel();
-      me.hideLangWindow();
-    };
-
-    item.onmouseover = function(e) { 
-      var i_it = GoogieSpell.getEventElm(e);
-      if(i_it.className != "googie_list_selected")
-        i_it.className = "googie_list_onhover";
-    };
-    item.onmouseout = function(e) { 
-      var i_it = GoogieSpell.getEventElm(e);
-      if(i_it.className != "googie_list_selected")
-        i_it.className = "googie_list_onout"; 
-    };
-
-    row.appendChild(item);
-    list.appendChild(row);
-  }
-
-  this.highlightCurSel();
-
-  //Close button
-  var close_row = AJS.TR();
-  var close = AJS.TD();
-  close.onmouseover = GoogieSpell.item_onmouseover;
-  close.onmouseout = GoogieSpell.item_onmouseout;
-  var spn_close = AJS.SPAN({'class': 'googie_list_close'});
-  spn_close.innerHTML = this.lang_close;
-  close.appendChild(spn_close);
-  var me = this;
-  close.onclick = function(e) {
-    me.hideLangWindow(); GoogieSpell.item_onmouseout(e);
-  };
-  close_row.appendChild(close);
-  list.appendChild(close_row);
-
-  table.appendChild(list);
-  this.language_window.appendChild(table);
-}
-
-GoogieSpell.prototype.setCurrentLanguage = function(lan_code) {
-  GOOGIE_CUR_LANG = lan_code;
-
-  //Set cookie
-  var now = new Date();
-  now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
-  setCookie('language', lan_code, now);
-}
-
-GoogieSpell.prototype.hideLangWindow = function() {
-  this.language_window.style.visibility = "hidden";
-  this.switch_lan_pic.className = "googie_lang_3d_on";
-}
-
-GoogieSpell.prototype.deHighlightCurSel = function() {
-  this.lang_cur_elm.className = "googie_list_onout";
-}
-
-GoogieSpell.prototype.highlightCurSel = function() {
-  for(var i=0; i < this.lang_elms.length; i++) {
-    if(this.lang_elms[i].googieId == GOOGIE_CUR_LANG) {
-      this.lang_elms[i].className = "googie_list_selected";
-      this.lang_cur_elm = this.lang_elms[i];
-    }
-    else {
-      this.lang_elms[i].className = "googie_list_onout";
-    }
-  }
-}
-
-GoogieSpell.prototype.showLangWindow = function(elm, ofst_top, ofst_left) {
-  if(!AJS.isDefined(ofst_top))
-    ofst_top = 20;
-  if(!AJS.isDefined(ofst_left))
-    ofst_left = 50;
-
-  this.createLangWindow();
-  AJS.getBody().appendChild(this.language_window);
-
-  var abs_pos = GoogieSpell.absolutePosition(elm);
-  AJS.showElement(this.language_window);
-  this.language_window.style.top = (abs_pos.y+ofst_top) + "px";
-  this.language_window.style.left = (abs_pos.x+ofst_left-this.language_window.offsetWidth) + "px";
-  this.highlightCurSel();
-  this.language_window.style.visibility = "visible";
-}
-
-GoogieSpell.prototype.flashNoSpellingErrorState = function() {
-  this.setStateChanged("no_error_found");
-  var me = this;
-  AJS.hideElement(this.switch_lan_pic);
-  this.gselm.innerHTML = this.lang_no_error_found;
-  this.gselm.className = "googie_check_spelling_ok";
-  this.gselm.style.textDecoration = "none";
-  this.gselm.style.cursor = "default";
-  var fu = function() {
-    AJS.removeElement(me.gselm);
-    me.checkSpellingState();
-  };
-  setTimeout(fu, 1000);
-}
-
-GoogieSpell.prototype.resumeEditingState = function() {
-  this.setStateChanged("resume_editing");
-  var me = this;
-  AJS.hideElement(me.switch_lan_pic);
-
-  //Change link text to resume
-  me.gselm.innerHTML = this.lang_rsm_edt;
-  me.gselm.onclick = function(e) {
-    me.resumeEditing(e, me);
-  }
-  me.gselm.className = "googie_check_spelling_ok";
-  me.edit_layer.scrollTop = me.ta_scroll_top;
-}
-
-GoogieSpell.prototype.createChangeLangPic = function() {
-  var switch_lan = AJS.A({'class': 'googie_lang_3d_on', 'style': 'padding-left: 6px;'}, AJS.IMG({'src': this.img_dir + 'change_lang.gif', 'alt': "Change language"}));
-  switch_lan.onmouseover = function() {
-    if(this.className != "googie_lang_3d_click")
-      this.className = "googie_lang_3d_on";
-  }
-
-  var me = this;
-  switch_lan.onclick = function() {
-    if(this.className == "googie_lang_3d_click") {
-      me.hideLangWindow();
-    }
-    else {
-      me.showLangWindow(switch_lan);
-      this.className = "googie_lang_3d_click";
-    }
-  }
-  return switch_lan;
-}
-
-GoogieSpell.prototype.createSpellDiv = function() {
-  var chk_spell = AJS.SPAN({'class': 'googie_check_spelling_link'});
-  chk_spell.innerHTML = this.lang_chck_spell;
-  var spell_img = null;
-  if(this.show_spell_img)
-    spell_img = AJS.IMG({'src': this.img_dir + "spellc.gif"});
-  return AJS.SPAN(spell_img, " ", chk_spell);
-}
-
-GoogieSpell.prototype.checkSpellingState = function() {
-  this.setStateChanged("check_spelling");
-  var me = this;
-  if(this.show_change_lang_pic)
-    this.switch_lan_pic = this.createChangeLangPic();
-  else
-    this.switch_lan_pic = AJS.SPAN();
-
-  var span_chck = this.createSpellDiv();
-  span_chck.onclick = function() {
-    me.spellCheck(span_chck);
-  }
-  AJS.appendChildNodes(this.spell_container, span_chck, " ", this.switch_lan_pic);
-  // modified by roundcube
-  this.check_link = span_chck;
-}
-
-GoogieSpell.prototype.setLanguages = function(lang_dict) {
-  this.lang_to_word = lang_dict;
-  this.langlist_codes = AJS.keys(lang_dict);
-}
-
-GoogieSpell.prototype.decorateTextarea = function(id, /*optional*/spell_container_id, force_width) {
-  var me = this;
-
-  if(typeof(id) == "string")
-    this.text_area = AJS.getElement(id);
-  else
-    this.text_area = id;
-
-  var r_width;
-
-  if(this.text_area != null) {
-    if(AJS.isDefined(spell_container_id)) {
-      if(typeof(spell_container_id) == "string")
-        this.spell_container = AJS.getElement(spell_container_id);
-      else
-        this.spell_container = spell_container_id;
-    }
-    else {
-      var table = AJS.TABLE();
-      var tbody = AJS.TBODY();
-      var tr = AJS.TR();
-      if(AJS.isDefined(force_width)) {
-        r_width = force_width;
-      }
-      else {
-        r_width = this.text_area.offsetWidth + "px";
-      }
-
-      var spell_container = AJS.TD();
-      this.spell_container = spell_container;
-
-      tr.appendChild(spell_container);
-
-      tbody.appendChild(tr);
-      table.appendChild(tbody);
-
-      AJS.insertBefore(table, this.text_area);
-
-      //Set width
-      table.style.width = '100%';  // modified by roundcube (old: r_width)
-      spell_container.style.width = r_width;
-      spell_container.style.textAlign = "right";
-    }
-
-    this.checkSpellingState();
-  }
-  else {
-    alert("Text area not found");
-  }
-}
diff --git a/program/js/jquery-1.3.min.js b/program/js/jquery-1.3.min.js
new file mode 100644 (file)
index 0000000..b1ae21d
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.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\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file
index 32fb917c8c2659131c7d43404be420ed1b1b62e6..2588556eea2c131f2fc692c02de28f5fd845dc31 100644 (file)
-function rcube_list_widget(_1,p){
-this.ENTER_KEY=13;
-this.DELETE_KEY=46;
-this.BACKSPACE_KEY=8;
-this.list=_1?_1:null;
-this.frame=null;
-this.rows=[];
-this.selection=[];
-this.rowcount=0;
-this.subject_col=-1;
-this.shiftkey=false;
-this.multiselect=false;
-this.multi_selecting=false;
-this.draggable=false;
-this.keyboard=false;
-this.toggleselect=false;
-this.dont_select=false;
-this.drag_active=false;
-this.last_selected=0;
-this.shift_start=0;
-this.in_selection_before=false;
-this.focused=false;
-this.drag_mouse_start=null;
-this.dblclick_time=600;
-this.row_init=function(){
-};
-this.events={click:[],dblclick:[],select:[],keypress:[],dragstart:[],dragmove:[],dragend:[]};
-if(p&&typeof (p)=="object"){
-for(var n in p){
-this[n]=p[n];
-}
-}
-};
-rcube_list_widget.prototype={init:function(){
-if(this.list&&this.list.tBodies[0]){
-this.rows=new Array();
-this.rowcount=0;
-var _4;
-for(var r=0;r<this.list.tBodies[0].childNodes.length;r++){
-_4=this.list.tBodies[0].childNodes[r];
-while(_4&&(_4.nodeType!=1||_4.style.display=="none")){
-_4=_4.nextSibling;
-r++;
-}
-this.init_row(_4);
-this.rowcount++;
-}
-this.frame=this.list.parentNode;
-if(this.keyboard){
-rcube_event.add_listener({element:document,event:"keyup",object:this,method:"key_press"});
-rcube_event.add_listener({element:document,event:"keydown",object:this,method:"key_down"});
-}
-}
-},init_row:function(_6){
-if(_6&&String(_6.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)){
-var p=this;
-var _8=RegExp.$1;
-_6.uid=_8;
-this.rows[_8]={uid:_8,id:_6.id,obj:_6,classname:_6.className};
-_6.onmousedown=function(e){
-return p.drag_row(e,this.uid);
-};
-_6.onmouseup=function(e){
-return p.click_row(e,this.uid);
-};
-if(document.all){
-_6.onselectstart=function(){
-return false;
-};
-}
-this.row_init(this.rows[_8]);
-}
-},clear:function(_b){
-var _c=document.createElement("TBODY");
-this.list.insertBefore(_c,this.list.tBodies[0]);
-this.list.removeChild(this.list.tBodies[1]);
-this.rows=new Array();
-this.rowcount=0;
-if(_b){
-this.clear_selection();
-}
-},remove_row:function(_d,_e){
-if(this.rows[_d].obj){
-this.rows[_d].obj.style.display="none";
-}
-if(_e){
-this.select_next();
-}
-this.rows[_d]=null;
-this.rowcount--;
-},insert_row:function(_f,_10){
-var _11=this.list.tBodies[0];
-if(_10&&_11.rows.length){
-_11.insertBefore(_f,_11.firstChild);
-}else{
-_11.appendChild(_f);
-}
-this.init_row(_f);
-this.rowcount++;
-},focus:function(e){
-this.focused=true;
-for(var n=0;n<this.selection.length;n++){
-id=this.selection[n];
-if(this.rows[id]&&this.rows[id].obj){
-this.set_classname(this.rows[id].obj,"selected",true);
-this.set_classname(this.rows[id].obj,"unfocused",false);
-}
-}
-if(e||(e=window.event)){
-rcube_event.cancel(e);
-}
-},blur:function(){
-var id;
-this.focused=false;
-for(var n=0;n<this.selection.length;n++){
-id=this.selection[n];
-if(this.rows[id]&&this.rows[id].obj){
-this.set_classname(this.rows[id].obj,"selected",false);
-this.set_classname(this.rows[id].obj,"unfocused",true);
-}
-}
-},drag_row:function(e,id){
-var _18=rcube_event.get_target(e);
-if(this.dont_select||(_18&&(_18.tagName=="INPUT"||_18.tagName=="IMG"))){
-return true;
-}
-if(rcube_event.get_button(e)==2){
-return true;
-}
-this.in_selection_before=this.in_selection(id)?id:false;
-if(!this.in_selection_before){
-var _19=rcube_event.get_modifier(e);
-this.select_row(id,_19,false);
-}
-if(this.draggable&&this.selection.length){
-this.drag_start=true;
-this.drag_mouse_start=rcube_event.get_mouse_pos(e);
-rcube_event.add_listener({element:document,event:"mousemove",object:this,method:"drag_mouse_move"});
-rcube_event.add_listener({element:document,event:"mouseup",object:this,method:"drag_mouse_up"});
-var _1a=document.getElementsByTagName("IFRAME");
-this.iframe_events=Object();
-for(var n in _1a){
-var _1c=null;
-if(_1a[n].contentDocument){
-_1c=_1a[n].contentDocument;
-}else{
-if(_1a[n].contentWindow){
-_1c=_1a[n].contentWindow.document;
-}else{
-if(_1a[n].document){
-_1c=_1a[n].document;
-}
-}
+/*
+ +-----------------------------------------------------------------------+
+ | RoundCube List Widget                                                 |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2006-2009, RoundCube Dev, - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
+ |          Charles McNulty <charles@charlesmcnulty.com>                 |
+ +-----------------------------------------------------------------------+
+ | Requires: common.js                                                   |
+ +-----------------------------------------------------------------------+
+
+  $Id: list.js 2761 2009-07-17 08:46:59Z alec $
+*/
+
+
+/**
+ * RoundCube List Widget class
+ * @contructor
+ */
+function rcube_list_widget(list, p)
+  {
+  // static contants
+  this.ENTER_KEY = 13;
+  this.DELETE_KEY = 46;
+  this.BACKSPACE_KEY = 8;
+  
+  this.list = list ? list : null;
+  this.frame = null;
+  this.rows = [];
+  this.selection = [];
+  this.rowcount = 0;
+  
+  this.subject_col = -1;
+  this.shiftkey = false;
+  this.multiselect = false;
+  this.multi_selecting = false;
+  this.draggable = false;
+  this.keyboard = false;
+  this.toggleselect = false;
+  
+  this.dont_select = false;
+  this.drag_active = false;
+  this.last_selected = 0;
+  this.shift_start = 0;
+  this.in_selection_before = false;
+  this.focused = false;
+  this.drag_mouse_start = null;
+  this.dblclick_time = 600;
+  this.row_init = function(){};
+  
+  // overwrite default paramaters
+  if (p && typeof(p)=='object')
+    for (var n in p)
+      this[n] = p[n];
+  }
+
+
+rcube_list_widget.prototype = {
+
+
+/**
+ * get all message rows from HTML table and init each row
+ */
+init: function()
+{
+  if (this.list && this.list.tBodies[0])
+  {
+    this.rows = new Array();
+    this.rowcount = 0;
+
+    var row;
+    for(var r=0; r<this.list.tBodies[0].childNodes.length; r++)
+    {
+      row = this.list.tBodies[0].childNodes[r];
+      while (row && (row.nodeType != 1 || row.style.display == 'none'))
+      {
+        row = row.nextSibling;
+        r++;
+      }
+
+      this.init_row(row);
+      this.rowcount++;
+    }
+
+    this.frame = this.list.parentNode;
+
+    // set body events
+    if (this.keyboard) {
+      rcube_event.add_listener({element:document, event:bw.opera?'keypress':'keydown', object:this, method:'key_press'});
+      rcube_event.add_listener({element:document, event:'keydown', object:this, method:'key_down'});
+    }
+  }
+},
+
+
+/**
+ * Init list row and set mouse events on it
+ */
+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 p = this;
+    var uid = RegExp.$1;
+    row.uid = uid;
+    this.rows[uid] = {uid:uid, id:row.id, obj:row, classname:row.className};
+
+    // set eventhandlers to table row
+    row.onmousedown = function(e){ return p.drag_row(e, this.uid); };
+    row.onmouseup = function(e){ return p.click_row(e, this.uid); };
+
+    if (document.all)
+      row.onselectstart = function() { return false; };
+
+    this.row_init(this.rows[uid]);
+  }
+},
+
+
+/**
+ * Remove all list rows
+ */
+clear: function(sel)
+{
+  var tbody = document.createElement('tbody');
+  this.list.insertBefore(tbody, this.list.tBodies[0]);
+  this.list.removeChild(this.list.tBodies[1]);
+  this.rows = new Array();
+  this.rowcount = 0;
+  
+  if (sel) this.clear_selection();
+},
+
+
+/**
+ * 'remove' message row from list (just hide it)
+ */
+remove_row: function(uid, sel_next)
+{
+  if (this.rows[uid].obj)
+    this.rows[uid].obj.style.display = 'none';
+
+  if (sel_next)
+    this.select_next();
+
+  this.rows[uid] = null;
+  this.rowcount--;
+},
+
+
+/**
+ * Add row to the list and initialize it
+ */
+insert_row: function(row, attop)
+{
+  if (this.background)
+    var tbody = this.background;
+  else
+    var tbody = this.list.tBodies[0];
+
+  if (attop && tbody.rows.length)
+    tbody.insertBefore(row, tbody.firstChild);
+  else
+    tbody.appendChild(row);
+
+  this.init_row(row);
+  this.rowcount++;
+},
+
+
+
+/**
+ * Set focus to the list
+ */
+focus: function(e)
+{
+  this.focused = true;
+  for (var n=0; n<this.selection.length; n++)
+  {
+    id = this.selection[n];
+    if (this.rows[id] && this.rows[id].obj) {
+      $(this.rows[id].obj).addClass('selected').removeClass('unfocused');
+    }
+  }
+
+  if (e || (e = window.event))
+    rcube_event.cancel(e);
+},
+
+
+/**
+ * remove focus from the list
+ */
+blur: function()
+{
+  var id;
+  this.focused = false;
+  for (var n=0; n<this.selection.length; n++)
+  {
+    id = this.selection[n];
+    if (this.rows[id] && this.rows[id].obj) {
+      $(this.rows[id].obj).removeClass('selected').addClass('unfocused');
+    }
+  }
+},
+
+
+/**
+ * onmousedown-handler of message list row
+ */
+drag_row: function(e, id)
+{
+  // don't do anything (another action processed before)
+  var evtarget = rcube_event.get_target(e);
+  var tagname = evtarget.tagName.toLowerCase();
+  if (this.dont_select || (evtarget && (tagname == 'input' || tagname == 'img')))
+    return true;
+    
+  // accept right-clicks
+  if (rcube_event.get_button(e) == 2)
+    return true;
+  
+  this.in_selection_before = this.in_selection(id) ? id : false;
+
+  // selects currently unselected row
+  if (!this.in_selection_before)
+  {
+    var mod_key = rcube_event.get_modifier(e);
+    this.select_row(id, mod_key, false);
+  }
+
+  if (this.draggable && this.selection.length)
+  {
+    this.drag_start = true;
+    this.drag_mouse_start = rcube_event.get_mouse_pos(e);
+    rcube_event.add_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
+    rcube_event.add_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
+
+    // add listener for iframes
+    var iframes = document.getElementsByTagName('iframe');
+    this.iframe_events = Object();
+    for (var n in iframes)
+    {
+      var iframedoc = null;
+      if (iframes[n].contentDocument)
+        iframedoc = iframes[n].contentDocument;
+      else if (iframes[n].contentWindow)
+        iframedoc = iframes[n].contentWindow.document;
+      else if (iframes[n].document)
+        iframedoc = iframes[n].document;
+
+      if (iframedoc)
+      {
+        var list = this;
+        var pos = $('#'+iframes[n].id).offset();
+        this.iframe_events[n] = function(e) { e._offset = pos; return list.drag_mouse_move(e); }
+
+        if (iframedoc.addEventListener)
+          iframedoc.addEventListener('mousemove', this.iframe_events[n], false);
+        else if (iframes[n].attachEvent)
+          iframedoc.attachEvent('onmousemove', this.iframe_events[n]);
+        else
+          iframedoc['onmousemove'] = this.iframe_events[n];
+
+        rcube_event.add_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
+      }
+    }
+  }
+
+  return false;
+},
+
+
+/**
+ * onmouseup-handler of message list row
+ */
+click_row: function(e, id)
+{
+  var now = new Date().getTime();
+  var mod_key = rcube_event.get_modifier(e);
+  var evtarget = rcube_event.get_target(e);
+  var tagname = evtarget.tagName.toLowerCase();
+
+  if ((evtarget && (tagname == 'input' || tagname == 'img')))
+    return true;
+
+  // don't do anything (another action processed before)
+  if (this.dont_select)
+    {
+    this.dont_select = false;
+    return false;
+    }
+    
+  var dblclicked = now - this.rows[id].clicked < this.dblclick_time;
+
+  // unselects currently selected row
+  if (!this.drag_active && this.in_selection_before == id && !dblclicked)
+    this.select_row(id, mod_key, false);
+
+  this.drag_start = false;
+  this.in_selection_before = false;
+
+  // row was double clicked
+  if (this.rows && dblclicked && this.in_selection(id))
+    this.triggerEvent('dblclick');
+  else
+    this.triggerEvent('click');
+
+  if (!this.drag_active)
+    rcube_event.cancel(e);
+
+  this.rows[id].clicked = now;
+  return false;
+},
+
+
+/**
+ * get next/previous/last rows that are not hidden
+ */
+get_next_row: function()
+{
+  if (!this.rows)
+    return false;
+
+  var last_selected_row = this.rows[this.last_selected];
+  var new_row = last_selected_row ? last_selected_row.obj.nextSibling : null;
+  while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
+    new_row = new_row.nextSibling;
+
+  return new_row;
+},
+
+get_prev_row: function()
+{
+  if (!this.rows)
+    return false;
+
+  var last_selected_row = this.rows[this.last_selected];
+  var new_row = last_selected_row ? last_selected_row.obj.previousSibling : null;
+  while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
+    new_row = new_row.previousSibling;
+
+  return new_row;
+},
+
+get_last_row: function()
+{
+  if (this.rowcount)
+    {
+    var rows = this.list.tBodies[0].rows;
+
+    for(var i=rows.length-1; i>=0; i--)
+      if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
+       return RegExp.$1;
+    }
+
+  return null;
+},
+
+
+/**
+ * selects or unselects the proper row depending on the modifier key pressed
+ */
+select_row: function(id, mod_key, with_mouse)
+{
+  var select_before = this.selection.join(',');
+  if (!this.multiselect)
+    mod_key = 0;
+    
+  if (!this.shift_start)
+    this.shift_start = id
+
+  if (!mod_key)
+  {
+    this.shift_start = id;
+    this.highlight_row(id, false);
+    this.multi_selecting = false;
+  }
+  else
+  {
+    switch (mod_key)
+    {
+      case SHIFT_KEY:
+        this.shift_select(id, false);
+        break;
+
+      case CONTROL_KEY:
+        if (!with_mouse)
+          this.highlight_row(id, true);
+        break; 
+
+      case CONTROL_SHIFT_KEY:
+        this.shift_select(id, true);
+        break;
+
+      default:
+        this.highlight_row(id, false);
+        break;
+    }
+    this.multi_selecting = true;
+  }
+
+  // trigger event if selection changed
+  if (this.selection.join(',') != select_before)
+    this.triggerEvent('select');
+
+  if (this.last_selected != 0 && this.rows[this.last_selected])
+    $(this.rows[this.last_selected].obj).removeClass('focused');
+
+  // unselect if toggleselect is active and the same row was clicked again
+  if (this.toggleselect && this.last_selected == id)
+  {
+    this.clear_selection();
+    id = null;
+  }
+  else
+    $(this.rows[id].obj).addClass('focused');
+
+  if (!this.selection.length)
+    this.shift_start = null;
+
+  this.last_selected = id;
+},
+
+
+/**
+ * Alias method for select_row
+ */
+select: function(id)
+{
+  this.select_row(id, false);
+  this.scrollto(id);
+},
+
+
+/**
+ * Select row next to the last selected one.
+ * Either below or above.
+ */
+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;
+  if (new_row)
+    this.select_row(new_row.uid, false, false);  
+},
+
+
+/**
+ * Perform selection when shift key is pressed
+ */
+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 to_rowIndex = this.rows[id].obj.rowIndex;
+
+  var i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex);
+  var j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex);
+
+  // iterate through the entire message list
+  for (var 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)
+        this.highlight_row(n, true);
+    }
+  }
+},
+
+
+/**
+ * Check if given id is part of the current selection
+ */
+in_selection: function(id)
+{
+  for(var n in this.selection)
+    if (this.selection[n]==id)
+      return true;
+
+  return false;    
+},
+
+
+/**
+ * Select each row in list
+ */
+select_all: function(filter)
+{
+  if (!this.rows || !this.rows.length)
+    return false;
+
+  // reset but remember selection first
+  var select_before = this.selection.join(',');
+  this.selection = new Array();
+  
+  for (var n in this.rows)
+  {
+    if (!filter || (this.rows[n] && this.rows[n][filter] == true))
+    {
+      this.last_selected = n;
+      this.highlight_row(n, true);
+    }
+    else if (this.rows[n])
+    {
+      $(this.rows[n].obj).removeClass('selected').removeClass('unfocused');
+    }
+  }
+
+  // trigger event if selection changed
+  if (this.selection.join(',') != select_before)
+    this.triggerEvent('select');
+
+  this.focus();
+
+  return true;
+},
+
+
+/**
+ * Invert selection
+ */
+invert_selection: function()
+{
+  if (!this.rows || !this.rows.length)
+    return false;
+
+  // remember old selection
+  var select_before = this.selection.join(',');
+  
+  for (var n in this.rows)
+    this.highlight_row(n, true);    
+
+  // trigger event if selection changed
+  if (this.selection.join(',') != select_before)
+    this.triggerEvent('select');
+
+  this.focus();
+
+  return true;
+},
+
+
+/**
+ * Unselect selected row(s)
+ */
+clear_selection: function(id)
+{
+  var num_select = this.selection.length;
+
+  // one row
+  if (id)
+    {
+    for (var n=0; n<this.selection.length; n++)
+      if (this.selection[n] == id) {
+        this.selection.splice(n,1);
+        break;
+      }
+    }
+  // all rows
+  else
+    {
+    for (var n=0; n<this.selection.length; n++)
+      if (this.rows[this.selection[n]]) {
+        $(this.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused');
+        }
+    
+    this.selection = new Array();
+    }
+
+  if (num_select && !this.selection.length)
+    this.triggerEvent('select');
+},
+
+
+/**
+ * Getter for the selection array
+ */
+get_selection: function()
+{
+  return this.selection;
+},
+
+
+/**
+ * Return the ID if only one row is selected
+ */
+get_single_selection: function()
+{
+  if (this.selection.length == 1)
+    return this.selection[0];
+  else
+    return null;
+},
+
+
+/**
+ * Highlight/unhighlight a row
+ */
+highlight_row: function(id, multiple)
+{
+  if (this.rows[id] && !multiple)
+  {
+    if (this.selection.length > 1 || !this.in_selection(id))
+    {
+      this.clear_selection();
+      this.selection[0] = id;
+      $(this.rows[id].obj).addClass('selected');
+    }
+  }
+  else if (this.rows[id])
+  {
+    if (!this.in_selection(id))  // select row
+    {
+      this.selection[this.selection.length] = id;
+      $(this.rows[id].obj).addClass('selected');
+    }
+    else  // unselect row
+    {
+      var p = find_in_array(id, this.selection);
+      var a_pre = this.selection.slice(0, p);
+      var 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');
+    }
+  }
+},
+
+
+/**
+ * Handler for keyboard events
+ */
+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);
+
+  switch (keyCode)
+  {
+    case 40:
+    case 38: 
+    case 63233: // "down", in safari keypress
+    case 63232: // "up", in safari keypress
+      // Stop propagation so that the browser doesn't scroll
+      rcube_event.cancel(e);
+      return this.use_arrow_key(keyCode, mod_key);
+    default:
+      this.shiftkey = e.shiftKey;
+      this.key_pressed = keyCode;
+      this.triggerEvent('keypress');
+      
+      if (this.key_pressed == this.BACKSPACE_KEY)
+        return rcube_event.cancel(e);
+  }
+  
+  return true;
+},
+
+/**
+ * Handler for keydown events
+ */
+key_down: function(e)
+{
+  switch (rcube_event.get_keycode(e))
+  {
+    case 27:
+      if (this.drag_active)
+       return this.drag_mouse_up(e);
+       
+    case 40:
+    case 38: 
+    case 63233:
+    case 63232:
+      if (!rcube_event.get_modifier(e) && this.focused)
+        return rcube_event.cancel(e);
+        
+    default:
+  }
+  
+  return true;
+},
+
+
+/**
+ * Special handling method for arrow keys
+ */
+use_arrow_key: function(keyCode, mod_key)
+{
+  var new_row;
+  // Safari uses the nonstandard keycodes 63232/63233 for up/down, if we're
+  // using the keypress event (but not the keydown or keyup event).
+  if (keyCode == 40 || keyCode == 63233) // down arrow key pressed
+    new_row = this.get_next_row();
+  else if (keyCode == 38 || keyCode == 63232) // up arrow key pressed
+    new_row = this.get_prev_row();
+
+  if (new_row)
+  {
+    this.select_row(new_row.uid, mod_key, true);
+    this.scrollto(new_row.uid);
+  }
+
+  return false;
+},
+
+
+/**
+ * Try to scroll the list to make the specified row visible
+ */
+scrollto: function(id)
+{
+  var row = this.rows[id].obj;
+  if (row && this.frame)
+  {
+    var scroll_to = Number(row.offsetTop);
+
+    if (scroll_to < Number(this.frame.scrollTop))
+      this.frame.scrollTop = scroll_to;
+    else if (scroll_to + Number(row.offsetHeight) > Number(this.frame.scrollTop) + Number(this.frame.offsetHeight))
+      this.frame.scrollTop = (scroll_to + Number(row.offsetHeight)) - Number(this.frame.offsetHeight);
+  }
+},
+
+
+/**
+ * Handler for mouse move events
+ */
+drag_mouse_move: function(e)
+{
+  if (this.drag_start)
+  {
+    // check mouse movement, of less than 3 pixels, don't start dragging
+    var m = rcube_event.get_mouse_pos(e);
+
+    if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.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':2000 }).appendTo(document.body);
+
+    // get subjects of selectedd messages
+    var names = '';
+    var c, i, node, subject, obj;
+    for(var n=0; n<this.selection.length; n++)
+    {
+      if (n>12)  // only show 12 lines
+      {
+        names += '...';
+        break;
+      }
+
+      if (this.rows[this.selection[n]].obj)
+      {
+        obj = this.rows[this.selection[n]].obj;
+        subject = '';
+
+        for(c=0, i=0; i<obj.childNodes.length; i++)
+        {
+          if (obj.childNodes[i].nodeName == 'TD')
+          {
+            if (((node = obj.childNodes[i].firstChild) && (node.nodeType==3 || node.nodeName=='A')) &&
+              (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c)))
+            {
+             if (n == 0) {
+               if (node.nodeType == 3)
+                 this.drag_start_pos = $(obj.childNodes[i]).offset();
+               else
+                  this.drag_start_pos = $(node).offset();
+             }
+              subject = node.nodeType==3 ? node.data : node.innerHTML;
+             // remove leading spaces
+             subject = subject.replace(/^\s+/i, '');
+              // truncate line to 50 characters
+             names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />';
+              break;
+            }
+            c++;
+          }
+        }
+      }
+    }
+
+    this.draglayer.html(names);
+    this.draglayer.show();
+
+    this.drag_active = true;
+    this.triggerEvent('dragstart');
+  }
+
+  if (this.drag_active && this.draglayer)
+  {
+    var pos = rcube_event.get_mouse_pos(e);
+    this.draglayer.css({ left:(pos.x+20)+'px', top:(pos.y-5 + (bw.ie ? document.documentElement.scrollTop : 0))+'px' });
+    this.triggerEvent('dragmove', e?e:window.event);
+  }
+
+  this.drag_start = false;
+
+  return false;
+},
+
+
+/**
+ * Handler for mouse up events
+ */
+drag_mouse_up: function(e)
+{
+  document.onmousemove = null;
+
+  if (this.draglayer && this.draglayer.is(':visible')) {
+    if (this.drag_start_pos)
+      this.draglayer.animate(this.drag_start_pos, 300, 'swing').hide(20);
+    else
+      this.draglayer.hide();
+  }
+
+  this.drag_active = false;
+  this.triggerEvent('dragend');
+
+  rcube_event.remove_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
+  rcube_event.remove_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
+
+  var iframes = document.getElementsByTagName('iframe');
+  for (var n in iframes) {
+    var iframedoc;
+    
+    if (iframes[n].contentDocument)
+      iframedoc = iframes[n].contentDocument;
+    else if (iframes[n].contentWindow)
+      iframedoc = iframes[n].contentWindow.document;
+    else if (iframes[n].document)
+      iframedoc = iframes[n].document;
+
+    if (iframedoc) {
+      if (this.iframe_events[n]) {
+       if (iframedoc.removeEventListener)
+         iframedoc.removeEventListener('mousemove', this.iframe_events[n], false);
+       else if (iframedoc.detachEvent)
+         iframedoc.detachEvent('onmousemove', this.iframe_events[n]);
+       else
+         iframedoc['onmousemove'] = null;
+       }
+      rcube_event.remove_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
+      }
+    }
+
+  return rcube_event.cancel(e);
+},
+
+
+/**
+ * Creating the list in background
+ */
+set_background_mode: function(flag)
+{
+  if (flag) {
+    this.background = document.createElement('tbody');
+  } else if (this.background) {
+    this.list.replaceChild(this.background, this.list.tBodies[0]);
+    this.background = null;
+  }
 }
-if(_1c){
-var _1d=this;
-var pos=rcube_get_object_pos(document.getElementById(_1a[n].id));
-this.iframe_events[n]=function(e){
-e._offset=pos;
-return _1d.drag_mouse_move(e);
+
 };
-if(_1c.addEventListener){
-_1c.addEventListener("mousemove",this.iframe_events[n],false);
-}else{
-if(_1a[n].attachEvent){
-_1c.attachEvent("onmousemove",this.iframe_events[n]);
-}else{
-_1c["onmousemove"]=this.iframe_events[n];
-}
-}
-rcube_event.add_listener({element:_1c,event:"mouseup",object:this,method:"drag_mouse_up"});
-}
-}
-}
-return false;
-},click_row:function(e,id){
-var now=new Date().getTime();
-var _23=rcube_event.get_modifier(e);
-var _24=rcube_event.get_target(e);
-if((_24&&(_24.tagName=="INPUT"||_24.tagName=="IMG"))){
-return true;
-}
-if(this.dont_select){
-this.dont_select=false;
-return false;
-}
-var _25=now-this.rows[id].clicked<this.dblclick_time;
-if(!this.drag_active&&this.in_selection_before==id&&!_25){
-this.select_row(id,_23,false);
-}
-this.drag_start=false;
-this.in_selection_before=false;
-if(this.rows&&_25&&this.in_selection(id)){
-this.trigger_event("dblclick");
-}else{
-this.trigger_event("click");
-}
-if(!this.drag_active){
-rcube_event.cancel(e);
-}
-this.rows[id].clicked=now;
-return false;
-},get_next_row:function(){
-if(!this.rows){
-return false;
-}
-var _26=this.rows[this.last_selected];
-var _27=_26?_26.obj.nextSibling:null;
-while(_27&&(_27.nodeType!=1||_27.style.display=="none")){
-_27=_27.nextSibling;
-}
-return _27;
-},get_prev_row:function(){
-if(!this.rows){
-return false;
-}
-var _28=this.rows[this.last_selected];
-var _29=_28?_28.obj.previousSibling:null;
-while(_29&&(_29.nodeType!=1||_29.style.display=="none")){
-_29=_29.previousSibling;
-}
-return _29;
-},get_last_row:function(){
-if(this.rowcount){
-var _2a=this.list.tBodies[0].rows;
-for(var i=_2a.length-1;i>=0;i--){
-if(_2a[i].id&&String(_2a[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null){
-return RegExp.$1;
-}
-}
-}
-return null;
-},select_row:function(id,_2d,_2e){
-var _2f=this.selection.join(",");
-if(!this.multiselect){
-_2d=0;
-}
-if(!this.shift_start){
-this.shift_start=id;
-}
-if(!_2d){
-this.shift_start=id;
-this.highlight_row(id,false);
-this.multi_selecting=false;
-}else{
-switch(_2d){
-case SHIFT_KEY:
-this.shift_select(id,false);
-break;
-case CONTROL_KEY:
-if(!_2e){
-this.highlight_row(id,true);
-}
-break;
-case CONTROL_SHIFT_KEY:
-this.shift_select(id,true);
-break;
-default:
-this.highlight_row(id,false);
-break;
-}
-this.multi_selecting=true;
-}
-if(this.selection.join(",")!=_2f){
-this.trigger_event("select");
-}
-if(this.last_selected!=0&&this.rows[this.last_selected]){
-this.set_classname(this.rows[this.last_selected].obj,"focused",false);
-}
-if(this.toggleselect&&this.last_selected==id){
-this.clear_selection();
-id=null;
-}else{
-this.set_classname(this.rows[id].obj,"focused",true);
-}
-if(!this.selection.length){
-this.shift_start=null;
-}
-this.last_selected=id;
-},select:function(id){
-this.select_row(id,false);
-this.scrollto(id);
-},select_next:function(){
-var _31=this.get_next_row();
-var _32=this.get_prev_row();
-var _33=(_31)?_31:_32;
-if(_33){
-this.select_row(_33.uid,false,false);
-}
-},shift_select:function(id,_35){
-if(!this.rows[this.shift_start]||!this.selection.length){
-this.shift_start=id;
-}
-var _36=this.rows[this.shift_start].obj.rowIndex;
-var _37=this.rows[id].obj.rowIndex;
-var i=((_36<_37)?_36:_37);
-var j=((_36>_37)?_36:_37);
-for(var 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)&&!_35){
-this.highlight_row(n,true);
-}
-}
-}
-},in_selection:function(id){
-for(var n in this.selection){
-if(this.selection[n]==id){
-return true;
-}
-}
-return false;
-},select_all:function(_3d){
-if(!this.rows||!this.rows.length){
-return false;
-}
-var _3e=this.selection.join(",");
-this.selection=new Array();
-for(var n in this.rows){
-if(!_3d||(this.rows[n]&&this.rows[n][_3d]==true)){
-this.last_selected=n;
-this.highlight_row(n,true);
-}else{
-if(this.rows[n]){
-this.set_classname(this.rows[n].obj,"selected",false);
-this.set_classname(this.rows[n].obj,"unfocused",false);
-}
-}
-}
-if(this.selection.join(",")!=_3e){
-this.trigger_event("select");
-}
-this.focus();
-return true;
-},clear_selection:function(id){
-var _41=this.selection.length;
-if(id){
-for(var n=0;n<this.selection.length;n++){
-if(this.selection[n]==id){
-this.selection.splice(n,1);
-break;
-}
-}
-}else{
-for(var n=0;n<this.selection.length;n++){
-if(this.rows[this.selection[n]]){
-this.set_classname(this.rows[this.selection[n]].obj,"selected",false);
-this.set_classname(this.rows[this.selection[n]].obj,"unfocused",false);
-}
-}
-this.selection=new Array();
-}
-if(_41&&!this.selection.length){
-this.trigger_event("select");
-}
-},get_selection:function(){
-return this.selection;
-},get_single_selection:function(){
-if(this.selection.length==1){
-return this.selection[0];
-}else{
-return null;
-}
-},highlight_row:function(id,_44){
-if(this.rows[id]&&!_44){
-if(this.selection.length>1||!this.in_selection(id)){
-this.clear_selection();
-this.selection[0]=id;
-this.set_classname(this.rows[id].obj,"selected",true);
-}
-}else{
-if(this.rows[id]){
-if(!this.in_selection(id)){
-this.selection[this.selection.length]=id;
-this.set_classname(this.rows[id].obj,"selected",true);
-}else{
-var p=find_in_array(id,this.selection);
-var _46=this.selection.slice(0,p);
-var _47=this.selection.slice(p+1,this.selection.length);
-this.selection=_46.concat(_47);
-this.set_classname(this.rows[id].obj,"selected",false);
-this.set_classname(this.rows[id].obj,"unfocused",false);
-}
-}
-}
-},key_press:function(e){
-if(this.focused!=true){
-return true;
-}
-var _49=rcube_event.get_keycode(e);
-var _4a=rcube_event.get_modifier(e);
-switch(_49){
-case 40:
-case 38:
-case 63233:
-case 63232:
-rcube_event.cancel(e);
-return this.use_arrow_key(_49,_4a);
-default:
-this.shiftkey=e.shiftKey;
-this.key_pressed=_49;
-this.trigger_event("keypress");
-if(this.key_pressed==this.BACKSPACE_KEY){
-return rcube_event.cancel(e);
-}
-}
-return true;
-},key_down:function(e){
-switch(rcube_event.get_keycode(e)){
-case 40:
-case 38:
-case 63233:
-case 63232:
-if(!rcube_event.get_modifier(e)&&this.focused){
-return rcube_event.cancel(e);
-}
-default:
-}
-return true;
-},use_arrow_key:function(_4c,_4d){
-var _4e;
-if(_4c==40||_4c==63233){
-_4e=this.get_next_row();
-}else{
-if(_4c==38||_4c==63232){
-_4e=this.get_prev_row();
-}
-}
-if(_4e){
-this.select_row(_4e.uid,_4d,true);
-this.scrollto(_4e.uid);
-}
-return false;
-},scrollto:function(id){
-var row=this.rows[id].obj;
-if(row&&this.frame){
-var _51=Number(row.offsetTop);
-if(_51<Number(this.frame.scrollTop)){
-this.frame.scrollTop=_51;
-}else{
-if(_51+Number(row.offsetHeight)>Number(this.frame.scrollTop)+Number(this.frame.offsetHeight)){
-this.frame.scrollTop=(_51+Number(row.offsetHeight))-Number(this.frame.offsetHeight);
-}
-}
-}
-},drag_mouse_move:function(e){
-if(this.drag_start){
-var m=rcube_event.get_mouse_pos(e);
-if(!this.drag_mouse_start||(Math.abs(m.x-this.drag_mouse_start.x)<3&&Math.abs(m.y-this.drag_mouse_start.y)<3)){
-return false;
-}
-if(!this.draglayer){
-this.draglayer=new rcube_layer("rcmdraglayer",{x:0,y:0,vis:0,zindex:2000});
-}
-var _54="";
-var c,i,_57,_58,obj;
-for(var n=0;n<this.selection.length;n++){
-if(n>12){
-_54+="...";
-break;
-}
-if(this.rows[this.selection[n]].obj){
-obj=this.rows[this.selection[n]].obj;
-_58="";
-for(c=0,i=0;i<obj.childNodes.length;i++){
-if(obj.childNodes[i].nodeName=="TD"){
-if(((_57=obj.childNodes[i].firstChild)&&(_57.nodeType==3||_57.nodeName=="A"))&&(this.subject_col<0||(this.subject_col>=0&&this.subject_col==c))){
-_58=_57.nodeType==3?_57.data:_57.innerHTML;
-_58=_58.replace(/^\s+/i,"");
-_54+=(_58.length>50?_58.substring(0,50)+"...":_58)+"<br />";
-break;
-}
-c++;
-}
-}
-}
-}
-this.draglayer.write(_54);
-this.draglayer.show(1);
-this.drag_active=true;
-this.trigger_event("dragstart");
-}
-if(this.drag_active&&this.draglayer){
-var pos=rcube_event.get_mouse_pos(e);
-this.draglayer.move(pos.x+20,bw.ie?pos.y-5+document.documentElement.scrollTop:pos.y-5);
-this.trigger_event("dragmove",e);
-}
-this.drag_start=false;
-return false;
-},drag_mouse_up:function(e){
-document.onmousemove=null;
-if(this.draglayer&&this.draglayer.visible){
-this.draglayer.show(0);
-}
-this.drag_active=false;
-this.trigger_event("dragend");
-rcube_event.remove_listener({element:document,event:"mousemove",object:this,method:"drag_mouse_move"});
-rcube_event.remove_listener({element:document,event:"mouseup",object:this,method:"drag_mouse_up"});
-var _5d=document.getElementsByTagName("IFRAME");
-for(var n in _5d){
-var _5f;
-if(_5d[n].contentDocument){
-_5f=_5d[n].contentDocument;
-}else{
-if(_5d[n].contentWindow){
-_5f=_5d[n].contentWindow.document;
-}else{
-if(_5d[n].document){
-_5f=_5d[n].document;
-}
-}
-}
-if(_5f){
-if(this.iframe_events[n]){
-if(_5f.removeEventListener){
-_5f.removeEventListener("mousemove",this.iframe_events[n],false);
-}else{
-if(_5f.detachEvent){
-_5f.detachEvent("onmousemove",this.iframe_events[n]);
-}else{
-_5f["onmousemove"]=null;
-}
-}
-}
-rcube_event.remove_listener({element:_5f,event:"mouseup",object:this,method:"drag_mouse_up"});
-}
-}
-return rcube_event.cancel(e);
-},set_classname:function(obj,_61,set){
-var reg=new RegExp("s*"+_61,"i");
-if(!set&&obj.className.match(reg)){
-obj.className=obj.className.replace(reg,"");
-}else{
-if(set&&!obj.className.match(reg)){
-obj.className+=" "+_61;
-}
-}
-},addEventListener:function(evt,_65){
-if(this.events[evt]){
-var _66=this.events[evt].length;
-this.events[evt][_66]=_65;
-return _66;
-}else{
-return false;
-}
-},removeEventListener:function(evt,_68){
-if(this.events[evt]&&this.events[evt][_68]){
-this.events[evt][_68]=null;
-}
-},trigger_event:function(evt,p){
-if(this.events[evt]&&this.events[evt].length){
-for(var i=0;i<this.events[evt].length;i++){
-if(typeof (this.events[evt][i])=="function"){
-this.events[evt][i](this,p);
-}
-}
-}
-}};
 
+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;
diff --git a/program/js/list.js.src b/program/js/list.js.src
deleted file mode 100644 (file)
index 5a1c35a..0000000
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
- +-----------------------------------------------------------------------+
- | RoundCube List Widget                                                 |
- |                                                                       |
- | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2006-2009, RoundCube Dev, - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Authors: Thomas Bruederli <roundcube@gmail.com>                       |
- |          Charles McNulty <charles@charlesmcnulty.com>                 |
- +-----------------------------------------------------------------------+
- | Requires: common.js                                                   |
- +-----------------------------------------------------------------------+
-
-  $Id: list.js 2483 2009-05-15 10:22:29Z thomasb $
-*/
-
-
-/**
- * RoundCube List Widget class
- * @contructor
- */
-function rcube_list_widget(list, p)
-  {
-  // static contants
-  this.ENTER_KEY = 13;
-  this.DELETE_KEY = 46;
-  this.BACKSPACE_KEY = 8;
-  
-  this.list = list ? list : null;
-  this.frame = null;
-  this.rows = [];
-  this.selection = [];
-  this.rowcount = 0;
-  
-  this.subject_col = -1;
-  this.shiftkey = false;
-  this.multiselect = false;
-  this.multi_selecting = false;
-  this.draggable = false;
-  this.keyboard = false;
-  this.toggleselect = false;
-  
-  this.dont_select = false;
-  this.drag_active = false;
-  this.last_selected = 0;
-  this.shift_start = 0;
-  this.in_selection_before = false;
-  this.focused = false;
-  this.drag_mouse_start = null;
-  this.dblclick_time = 600;
-  this.row_init = function(){};
-  this.events = { click:[], dblclick:[], select:[], keypress:[], dragstart:[], dragmove:[], dragend:[] };
-  
-  // overwrite default paramaters
-  if (p && typeof(p)=='object')
-    for (var n in p)
-      this[n] = p[n];
-  }
-
-
-rcube_list_widget.prototype = {
-
-
-/**
- * get all message rows from HTML table and init each row
- */
-init: function()
-{
-  if (this.list && this.list.tBodies[0])
-  {
-    this.rows = new Array();
-    this.rowcount = 0;
-
-    var row;
-    for(var r=0; r<this.list.tBodies[0].childNodes.length; r++)
-    {
-      row = this.list.tBodies[0].childNodes[r];
-      while (row && (row.nodeType != 1 || row.style.display == 'none'))
-      {
-        row = row.nextSibling;
-        r++;
-      }
-
-      this.init_row(row);
-      this.rowcount++;
-    }
-
-    this.frame = this.list.parentNode;
-
-    // set body events
-    if (this.keyboard) {
-      rcube_event.add_listener({element:document, event:'keyup', object:this, method:'key_press'});
-      rcube_event.add_listener({element:document, event:'keydown', object:this, method:'key_down'});
-    }
-  }
-},
-
-
-/**
- *
- */
-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 p = this;
-    var uid = RegExp.$1;
-    row.uid = uid;
-    this.rows[uid] = {uid:uid, id:row.id, obj:row, classname:row.className};
-
-    // set eventhandlers to table row
-    row.onmousedown = function(e){ return p.drag_row(e, this.uid); };
-    row.onmouseup = function(e){ return p.click_row(e, this.uid); };
-
-    if (document.all)
-      row.onselectstart = function() { return false; };
-
-    this.row_init(this.rows[uid]);
-  }
-},
-
-
-/**
- *
- */
-clear: function(sel)
-{
-  var tbody = document.createElement('TBODY');
-  this.list.insertBefore(tbody, this.list.tBodies[0]);
-  this.list.removeChild(this.list.tBodies[1]);
-  this.rows = new Array();
-  this.rowcount = 0;
-  
-  if (sel) this.clear_selection();
-},
-
-
-/**
- * 'remove' message row from list (just hide it)
- */
-remove_row: function(uid, sel_next)
-{
-  if (this.rows[uid].obj)
-    this.rows[uid].obj.style.display = 'none';
-
-  if (sel_next)
-    this.select_next();
-
-  this.rows[uid] = null;
-  this.rowcount--;
-},
-
-
-/**
- *
- */
-insert_row: function(row, attop)
-{
-  var tbody = this.list.tBodies[0];
-
-  if (attop && tbody.rows.length)
-    tbody.insertBefore(row, tbody.firstChild);
-  else
-    tbody.appendChild(row);
-
-  this.init_row(row);
-  this.rowcount++;
-},
-
-
-
-/**
- * Set focus to the list
- */
-focus: function(e)
-{
-  this.focused = true;
-  for (var n=0; n<this.selection.length; n++)
-  {
-    id = this.selection[n];
-    if (this.rows[id] && this.rows[id].obj)
-    {
-      this.set_classname(this.rows[id].obj, 'selected', true);
-      this.set_classname(this.rows[id].obj, 'unfocused', false);
-    }
-  }
-
-  if (e || (e = window.event))
-    rcube_event.cancel(e);
-},
-
-
-/**
- * remove focus from the list
- */
-blur: function()
-{
-  var id;
-  this.focused = false;
-  for (var n=0; n<this.selection.length; n++)
-  {
-    id = this.selection[n];
-    if (this.rows[id] && this.rows[id].obj)
-    {
-      this.set_classname(this.rows[id].obj, 'selected', false);
-      this.set_classname(this.rows[id].obj, 'unfocused', true);
-    }
-  }
-},
-
-
-/**
- * onmousedown-handler of message list row
- */
-drag_row: function(e, id)
-{
-  // don't do anything (another action processed before)
-  var evtarget = rcube_event.get_target(e);
-  if (this.dont_select || (evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG')))
-    return true;
-    
-  // accept right-clicks
-  if (rcube_event.get_button(e) == 2)
-    return true;
-  
-  this.in_selection_before = this.in_selection(id) ? id : false;
-
-  // selects currently unselected row
-  if (!this.in_selection_before)
-  {
-    var mod_key = rcube_event.get_modifier(e);
-    this.select_row(id, mod_key, false);
-  }
-
-  if (this.draggable && this.selection.length)
-  {
-    this.drag_start = true;
-    this.drag_mouse_start = rcube_event.get_mouse_pos(e);
-    rcube_event.add_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
-    rcube_event.add_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
-
-    // add listener for iframes
-    var iframes = document.getElementsByTagName('IFRAME');
-    this.iframe_events = Object();
-    for (var n in iframes)
-    {
-      var iframedoc = null;
-      if (iframes[n].contentDocument)
-        iframedoc = iframes[n].contentDocument;
-      else if (iframes[n].contentWindow)
-       iframedoc = iframes[n].contentWindow.document;
-      else if (iframes[n].document)
-        iframedoc = iframes[n].document;
-
-      if (iframedoc)
-      {
-       var list = this;
-       var pos = rcube_get_object_pos(document.getElementById(iframes[n].id));
-       this.iframe_events[n] = function(e) { e._offset = pos; return list.drag_mouse_move(e); }
-       
-       if (iframedoc.addEventListener)
-         iframedoc.addEventListener('mousemove', this.iframe_events[n], false);
-       else if (iframes[n].attachEvent)
-         iframedoc.attachEvent('onmousemove', this.iframe_events[n]);
-       else
-         iframedoc['onmousemove'] = this.iframe_events[n];
-
-        rcube_event.add_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
-      }
-    }                                                            
-  }
-
-  return false;
-},
-
-
-/**
- * onmouseup-handler of message list row
- */
-click_row: function(e, id)
-{
-  var now = new Date().getTime();
-  var mod_key = rcube_event.get_modifier(e);
-  var evtarget = rcube_event.get_target(e);
-
-  if ((evtarget && (evtarget.tagName == 'INPUT' || evtarget.tagName == 'IMG')))
-    return true;
-
-  // don't do anything (another action processed before)
-  if (this.dont_select)
-    {
-    this.dont_select = false;
-    return false;
-    }
-    
-  var dblclicked = now - this.rows[id].clicked < this.dblclick_time;
-
-  // unselects currently selected row
-  if (!this.drag_active && this.in_selection_before == id && !dblclicked)
-    this.select_row(id, mod_key, false);
-
-  this.drag_start = false;
-  this.in_selection_before = false;
-
-  // row was double clicked
-  if (this.rows && dblclicked && this.in_selection(id))
-    this.trigger_event('dblclick');
-  else
-    this.trigger_event('click');
-
-  if (!this.drag_active)
-    rcube_event.cancel(e);
-
-  this.rows[id].clicked = now;
-  return false;
-},
-
-
-/**
- * get next/previous/last rows that are not hidden
- */
-get_next_row: function()
-{
-  if (!this.rows)
-    return false;
-
-  var last_selected_row = this.rows[this.last_selected];
-  var new_row = last_selected_row ? last_selected_row.obj.nextSibling : null;
-  while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
-    new_row = new_row.nextSibling;
-
-  return new_row;
-},
-
-get_prev_row: function()
-{
-  if (!this.rows)
-    return false;
-
-  var last_selected_row = this.rows[this.last_selected];
-  var new_row = last_selected_row ? last_selected_row.obj.previousSibling : null;
-  while (new_row && (new_row.nodeType != 1 || new_row.style.display == 'none'))
-    new_row = new_row.previousSibling;
-
-  return new_row;
-},
-
-get_last_row: function()
-{
-  if (this.rowcount)
-    {
-    var rows = this.list.tBodies[0].rows;
-
-    for(var i=rows.length-1; i>=0; i--)
-      if(rows[i].id && String(rows[i].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i) && this.rows[RegExp.$1] != null)
-       return RegExp.$1;
-    }
-
-  return null;
-},
-
-
-/**
- * selects or unselects the proper row depending on the modifier key pressed
- */
-select_row: function(id, mod_key, with_mouse)
-{
-  var select_before = this.selection.join(',');
-  if (!this.multiselect)
-    mod_key = 0;
-    
-  if (!this.shift_start)
-    this.shift_start = id
-
-  if (!mod_key)
-  {
-    this.shift_start = id;
-    this.highlight_row(id, false);
-    this.multi_selecting = false;
-  }
-  else
-  {
-    switch (mod_key)
-    {
-      case SHIFT_KEY:
-        this.shift_select(id, false);
-        break;
-
-      case CONTROL_KEY:
-        if (!with_mouse)
-          this.highlight_row(id, true);
-        break; 
-
-      case CONTROL_SHIFT_KEY:
-        this.shift_select(id, true);
-        break;
-
-      default:
-        this.highlight_row(id, false);
-        break;
-    }
-    this.multi_selecting = true;
-  }
-
-  // trigger event if selection changed
-  if (this.selection.join(',') != select_before)
-    this.trigger_event('select');
-
-  if (this.last_selected != 0 && this.rows[this.last_selected])
-    this.set_classname(this.rows[this.last_selected].obj, 'focused', false);
-
-  // unselect if toggleselect is active and the same row was clicked again
-  if (this.toggleselect && this.last_selected == id)
-  {
-    this.clear_selection();
-    id = null;
-  }
-  else
-    this.set_classname(this.rows[id].obj, 'focused', true);
-
-  if (!this.selection.length)
-    this.shift_start = null;
-
-  this.last_selected = id;
-},
-
-
-/**
- * Alias method for select_row
- */
-select: function(id)
-{
-  this.select_row(id, false);
-  this.scrollto(id);
-},
-
-
-/**
- * Select row next to the last selected one.
- * Either below or above.
- */
-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;
-  if (new_row)
-    this.select_row(new_row.uid, false, false);  
-},
-
-
-/**
- * Perform selection when shift key is pressed
- */
-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 to_rowIndex = this.rows[id].obj.rowIndex;
-
-  var i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex);
-  var j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex);
-
-  // iterate through the entire message list
-  for (var 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)
-        this.highlight_row(n, true);
-    }
-  }
-},
-
-
-/**
- * Check if given id is part of the current selection
- */
-in_selection: function(id)
-{
-  for(var n in this.selection)
-    if (this.selection[n]==id)
-      return true;
-
-  return false;    
-},
-
-
-/**
- * Select each row in list
- */
-select_all: function(filter)
-{
-  if (!this.rows || !this.rows.length)
-    return false;
-
-  // reset but remember selection first
-  var select_before = this.selection.join(',');
-  this.selection = new Array();
-  
-  for (var n in this.rows)
-  {
-    if (!filter || (this.rows[n] && this.rows[n][filter] == true))
-    {
-      this.last_selected = n;
-      this.highlight_row(n, true);
-    }
-    else if (this.rows[n])
-    {
-      this.set_classname(this.rows[n].obj, 'selected', false);
-      this.set_classname(this.rows[n].obj, 'unfocused', false);
-    }
-  }
-
-  // trigger event if selection changed
-  if (this.selection.join(',') != select_before)
-    this.trigger_event('select');
-
-  this.focus();
-
-  return true;
-},
-
-
-/**
- * Unselect selected row(s)
- */
-clear_selection: function(id)
-{
-  var num_select = this.selection.length;
-
-  // one row
-  if (id)
-    {
-    for (var n=0; n<this.selection.length; n++)
-      if (this.selection[n] == id)
-        {
-       this.selection.splice(n,1);
-       break;
-       }
-    }
-  // all rows
-  else
-    {
-    for (var n=0; n<this.selection.length; n++)
-      if (this.rows[this.selection[n]])
-        {
-        this.set_classname(this.rows[this.selection[n]].obj, 'selected', false);
-        this.set_classname(this.rows[this.selection[n]].obj, 'unfocused', false);
-        }
-    
-    this.selection = new Array();
-    }
-
-  if (num_select && !this.selection.length)
-    this.trigger_event('select');
-},
-
-
-/**
- * Getter for the selection array
- */
-get_selection: function()
-{
-  return this.selection;
-},
-
-
-/**
- * Return the ID if only one row is selected
- */
-get_single_selection: function()
-{
-  if (this.selection.length == 1)
-    return this.selection[0];
-  else
-    return null;
-},
-
-
-/**
- * Highlight/unhighlight a row
- */
-highlight_row: function(id, multiple)
-{
-  if (this.rows[id] && !multiple)
-  {
-    if (this.selection.length > 1 || !this.in_selection(id))
-    {
-      this.clear_selection();
-      this.selection[0] = id;
-      this.set_classname(this.rows[id].obj, 'selected', true);
-    }
-  }
-  else if (this.rows[id])
-  {
-    if (!this.in_selection(id))  // select row
-    {
-      this.selection[this.selection.length] = id;
-      this.set_classname(this.rows[id].obj, 'selected', true);
-    }
-    else  // unselect row
-    {
-      var p = find_in_array(id, this.selection);
-      var a_pre = this.selection.slice(0, p);
-      var a_post = this.selection.slice(p+1, this.selection.length);
-      this.selection = a_pre.concat(a_post);
-      this.set_classname(this.rows[id].obj, 'selected', false);
-      this.set_classname(this.rows[id].obj, 'unfocused', false);
-    }
-  }
-},
-
-
-/**
- * Handler for keyboard events
- */
-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);
-  switch (keyCode)
-  {
-    case 40:
-    case 38: 
-    case 63233: // "down", in safari keypress
-    case 63232: // "up", in safari keypress
-      // Stop propagation so that the browser doesn't scroll
-      rcube_event.cancel(e);
-      return this.use_arrow_key(keyCode, mod_key);
-    default:
-      this.shiftkey = e.shiftKey;
-      this.key_pressed = keyCode;
-      this.trigger_event('keypress');
-      
-      if (this.key_pressed == this.BACKSPACE_KEY)
-        return rcube_event.cancel(e);
-  }
-  
-  return true;
-},
-
-/**
- * Handler for keydown events
- */
-key_down: function(e)
-{
-  switch (rcube_event.get_keycode(e))
-  {
-    case 40:
-    case 38: 
-    case 63233:
-    case 63232:
-      if (!rcube_event.get_modifier(e) && this.focused)
-        return rcube_event.cancel(e);
-        
-    default:
-  }
-  
-  return true;
-},
-
-
-/**
- * Special handling method for arrow keys
- */
-use_arrow_key: function(keyCode, mod_key)
-{
-  var new_row;
-  // Safari uses the nonstandard keycodes 63232/63233 for up/down, if we're
-  // using the keypress event (but not the keydown or keyup event).
-  if (keyCode == 40 || keyCode == 63233) // down arrow key pressed
-    new_row = this.get_next_row();
-  else if (keyCode == 38 || keyCode == 63232) // up arrow key pressed
-    new_row = this.get_prev_row();
-
-  if (new_row)
-  {
-    this.select_row(new_row.uid, mod_key, true);
-    this.scrollto(new_row.uid);
-  }
-
-  return false;
-},
-
-
-/**
- * Try to scroll the list to make the specified row visible
- */
-scrollto: function(id)
-{
-  var row = this.rows[id].obj;
-  if (row && this.frame)
-  {
-    var scroll_to = Number(row.offsetTop);
-
-    if (scroll_to < Number(this.frame.scrollTop))
-      this.frame.scrollTop = scroll_to;
-    else if (scroll_to + Number(row.offsetHeight) > Number(this.frame.scrollTop) + Number(this.frame.offsetHeight))
-      this.frame.scrollTop = (scroll_to + Number(row.offsetHeight)) - Number(this.frame.offsetHeight);
-  }
-},
-
-
-/**
- * Handler for mouse move events
- */
-drag_mouse_move: function(e)
-{
-  if (this.drag_start)
-  {
-    // check mouse movement, of less than 3 pixels, don't start dragging
-    var m = rcube_event.get_mouse_pos(e);
-
-    if (!this.drag_mouse_start || (Math.abs(m.x - this.drag_mouse_start.x) < 3 && Math.abs(m.y - this.drag_mouse_start.y) < 3))
-      return false;
-  
-    if (!this.draglayer)
-      this.draglayer = new rcube_layer('rcmdraglayer', {x:0, y:0, vis:0, zindex:2000});
-  
-    // get subjects of selectedd messages
-    var names = '';
-    var c, i, node, subject, obj;
-    for(var n=0; n<this.selection.length; n++)
-    {
-      if (n>12)  // only show 12 lines
-      {
-        names += '...';
-        break;
-      }
-
-      if (this.rows[this.selection[n]].obj)
-      {
-        obj = this.rows[this.selection[n]].obj;
-        subject = '';
-
-        for(c=0, i=0; i<obj.childNodes.length; i++)
-        {
-          if (obj.childNodes[i].nodeName == 'TD')
-          {
-            if (((node = obj.childNodes[i].firstChild) && (node.nodeType==3 || node.nodeName=='A')) &&
-              (this.subject_col < 0 || (this.subject_col >= 0 && this.subject_col == c)))
-            {
-              subject = node.nodeType==3 ? node.data : node.innerHTML;
-             // remove leading spaces
-             subject = subject.replace(/^\s+/i, '');
-              // truncate line to 50 characters
-             names += (subject.length > 50 ? subject.substring(0, 50)+'...' : subject) + '<br />';
-              break;
-            }
-            c++;
-          }
-        }
-      }
-    }
-
-    this.draglayer.write(names);
-    this.draglayer.show(1);
-
-    this.drag_active = true;
-    this.trigger_event('dragstart');
-  }
-
-  if (this.drag_active && this.draglayer)
-  {
-    var pos = rcube_event.get_mouse_pos(e);
-    this.draglayer.move(pos.x+20, bw.ie ? pos.y-5+document.documentElement.scrollTop : pos.y-5);
-    this.trigger_event('dragmove', e);
-  }
-
-  this.drag_start = false;
-
-  return false;
-},
-
-
-/**
- * Handler for mouse up events
- */
-drag_mouse_up: function(e)
-{
-  document.onmousemove = null;
-
-  if (this.draglayer && this.draglayer.visible)
-    this.draglayer.show(0);
-
-  this.drag_active = false;
-  this.trigger_event('dragend');
-
-  rcube_event.remove_listener({element:document, event:'mousemove', object:this, method:'drag_mouse_move'});
-  rcube_event.remove_listener({element:document, event:'mouseup', object:this, method:'drag_mouse_up'});
-
-  var iframes = document.getElementsByTagName('IFRAME');
-  for (var n in iframes) {
-    var iframedoc;
-    
-    if (iframes[n].contentDocument)
-      iframedoc = iframes[n].contentDocument;
-    else if (iframes[n].contentWindow)
-      iframedoc = iframes[n].contentWindow.document;
-    else if (iframes[n].document)
-      iframedoc = iframes[n].document;
-
-    if (iframedoc) {
-      if (this.iframe_events[n]) {
-       if (iframedoc.removeEventListener)
-         iframedoc.removeEventListener('mousemove', this.iframe_events[n], false);
-       else if (iframedoc.detachEvent)
-         iframedoc.detachEvent('onmousemove', this.iframe_events[n]);
-       else
-         iframedoc['onmousemove'] = null;
-       }
-      rcube_event.remove_listener({element:iframedoc, event:'mouseup', object:this, method:'drag_mouse_up'});
-      }
-    }
-
-  return rcube_event.cancel(e);
-},
-
-
-
-/**
- * set/unset a specific class name
- */
-set_classname: function(obj, classname, set)
-{
-  var reg = new RegExp('\s*'+classname, 'i');
-  if (!set && obj.className.match(reg))
-    obj.className = obj.className.replace(reg, '');
-  else if (set && !obj.className.match(reg))
-    obj.className += ' '+classname;
-},
-
-
-/**
- * Setter for object event handlers
- *
- * @param {String}   Event name
- * @param {Function} Handler function
- * @return Listener ID (used to remove this handler later on)
- */
-addEventListener: function(evt, handler)
-{
-  if (this.events[evt]) {
-    var handle = this.events[evt].length;
-    this.events[evt][handle] = handler;
-    return handle;
-  }
-  else
-    return false;
-},
-
-
-/**
- * Removes a specific event listener
- *
- * @param {String} Event name
- * @param {Int}    Listener ID to remove
- */
-removeEventListener: function(evt, handle)
-{
-  if (this.events[evt] && this.events[evt][handle])
-    this.events[evt][handle] = null;
-},
-
-
-/**
- * This will execute all registered event handlers
- * @private
- */
-trigger_event: function(evt, p)
-{
-  if (this.events[evt] && this.events[evt].length) {
-    for (var i=0; i<this.events[evt].length; i++)
-      if (typeof(this.events[evt][i]) == 'function')
-        this.events[evt][i](this, p);
-  }
-}
-
-
-};
-
index 02a1da8b42f684925e020c230e17362afd7af541..d921728fcb60e5526a100025afac7f1ca3db044e 100644 (file)
@@ -1 +1 @@
-(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,each=tinymce.each,is=tinymce.is;tinymce.create('tinymce.plugins.Compat2x',{getInfo:function(){return{longname:'Compat2x',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/compat2x',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion};}});(function(){tinymce.extend(tinyMCE,{addToLang:function(p,l){each(l,function(v,k){tinyMCE.i18n[(tinyMCE.settings.language||'en')+'.'+(p?p+'_':'')+k]=v;});},getInstanceById:function(n){return this.get(n);}});})();(function(){var EditorManager=tinymce.EditorManager;tinyMCE.instances={};tinyMCE.plugins={};tinymce.PluginManager.onAdd.add(function(pm,n,p){tinyMCE.plugins[n]=p;});tinyMCE.majorVersion=tinymce.majorVersion;tinyMCE.minorVersion=tinymce.minorVersion;tinyMCE.releaseDate=tinymce.releaseDate;tinyMCE.baseURL=tinymce.baseURL;tinyMCE.isIE=tinyMCE.isMSIE=tinymce.isIE||tinymce.isOpera;tinyMCE.isMSIE5=tinymce.isIE;tinyMCE.isMSIE5_0=tinymce.isIE;tinyMCE.isMSIE7=tinymce.isIE;tinyMCE.isGecko=tinymce.isGecko;tinyMCE.isSafari=tinymce.isWebKit;tinyMCE.isOpera=tinymce.isOpera;tinyMCE.isMac=false;tinyMCE.isNS7=false;tinyMCE.isNS71=false;tinyMCE.compat=true;TinyMCE_Engine=tinyMCE;tinymce.extend(tinyMCE,{getParam:function(n,dv){return this.activeEditor.getParam(n,dv);},addEvent:function(e,na,f,sc){tinymce.dom.Event.add(e,na,f,sc||this);},getControlHTML:function(n){return EditorManager.activeEditor.controlManager.createControl(n);},loadCSS:function(u){tinymce.DOM.loadCSS(u);},importCSS:function(doc,u){if(doc==document)this.loadCSS(u);else new tinymce.dom.DOMUtils(doc).loadCSS(u);},log:function(){console.debug.apply(console,arguments);},getLang:function(n,dv){var v=EditorManager.activeEditor.getLang(n.replace(/^lang_/g,''),dv);if(/^[0-9\-.]+$/g.test(v))return parseInt(v);return v;},isInstance:function(o){return o!=null&&typeof(o)=="object"&&o.execCommand;},triggerNodeChange:function(){EditorManager.activeEditor.nodeChanged();},regexpReplace:function(in_str,reg_exp,replace_str,opts){var re;if(in_str==null)return in_str;if(typeof(opts)=="undefined")opts='g';re=new RegExp(reg_exp,opts);return in_str.replace(re,replace_str);},trim:function(s){return tinymce.trim(s);},xmlEncode:function(s){return tinymce.DOM.encode(s);},explode:function(s,d){var o=[];tinymce.each(s.split(d),function(v){if(v!='')o.push(v);});return o;},switchClass:function(id,cls){var b;if(/^mceButton/.test(cls)){b=EditorManager.activeEditor.controlManager.get(id);if(!b)return;switch(cls){case"mceButtonNormal":b.setDisabled(false);b.setActive(false);return;case"mceButtonDisabled":b.setDisabled(true);return;case"mceButtonSelected":b.setActive(true);b.setDisabled(false);return;}}},addCSSClass:function(e,n,b){return tinymce.DOM.addClass(e,n,b);},hasCSSClass:function(e,n){return tinymce.DOM.hasClass(e,n);},removeCSSClass:function(e,n){return tinymce.DOM.removeClass(e,n);},getCSSClasses:function(){var cl=EditorManager.activeEditor.dom.getClasses(),o=[];each(cl,function(c){o.push(c['class']);});return o;},setWindowArg:function(n,v){EditorManager.activeEditor.windowManager.params[n]=v;},getWindowArg:function(n,dv){var wm=EditorManager.activeEditor.windowManager,v;v=wm.getParam(n);if(v==='')return'';return v||wm.getFeature(n)||dv;},getParentNode:function(n,f){return this._getDOM().getParent(n,f);},selectElements:function(n,na,f){var i,a=[],nl,x;for(x=0,na=na.split(',');x<na.length;x++)for(i=0,nl=n.getElementsByTagName(na[x]);i<nl.length;i++)(!f||f(nl[i]))&&a.push(nl[i]);return a;},getNodeTree:function(n,na,t,nn){return this.selectNodes(n,function(n){return(!t||n.nodeType==t)&&(!nn||n.nodeName==nn);},na?na:[]);},getAttrib:function(e,n,dv){return this._getDOM().getAttrib(e,n,dv);},setAttrib:function(e,n,v){return this._getDOM().setAttrib(e,n,v);},getElementsByAttributeValue:function(n,e,a,v){var i,nl=n.getElementsByTagName(e),o=[];for(i=0;i<nl.length;i++){if(tinyMCE.getAttrib(nl[i],a).indexOf(v)!=-1)o[o.length]=nl[i];}return o;},selectNodes:function(n,f,a){var i;if(!a)a=[];if(f(n))a[a.length]=n;if(n.hasChildNodes()){for(i=0;i<n.childNodes.length;i++)tinyMCE.selectNodes(n.childNodes[i],f,a);}return a;},getContent:function(){return EditorManager.activeEditor.getContent();},getParentElement:function(n,na,f){if(na)na=new RegExp('^('+na.toUpperCase().replace(/,/g,'|')+')$','g');return this._getDOM().getParent(n,function(n){return n.nodeType==1&&(!na||na.test(n.nodeName))&&(!f||f(n));},this.activeEditor.getBody());},importPluginLanguagePack:function(n){tinymce.PluginManager.requireLangPack(n);},getButtonHTML:function(cn,lang,img,c,u,v){var ed=EditorManager.activeEditor;img=img.replace(/\{\$pluginurl\}/g,tinyMCE.pluginURL);img=img.replace(/\{\$themeurl\}/g,tinyMCE.themeURL);lang=lang.replace(/^lang_/g,'');return ed.controlManager.createButton(cn,{title:lang,command:c,ui:u,value:v,scope:this,'class':'compat',image:img});},addSelectAccessibility:function(e,s,w){if(!s._isAccessible){s.onkeydown=tinyMCE.accessibleEventHandler;s.onblur=tinyMCE.accessibleEventHandler;s._isAccessible=true;s._win=w;}return false;},accessibleEventHandler:function(e){var elm,win=this._win;e=tinymce.isIE?win.event:e;elm=tinymce.isIE?e.srcElement:e.target;if(e.type=="blur"){if(elm.oldonchange){elm.onchange=elm.oldonchange;elm.oldonchange=null;}return true;}if(elm.nodeName=="SELECT"&&!elm.oldonchange){elm.oldonchange=elm.onchange;elm.onchange=null;}if(e.keyCode==13||e.keyCode==32){elm.onchange=elm.oldonchange;elm.onchange();elm.oldonchange=null;tinyMCE.cancelEvent(e);return false;}return true;},cancelEvent:function(e){return tinymce.dom.Event.cancel(e);},handleVisualAid:function(e){EditorManager.activeEditor.addVisual(e);},getAbsPosition:function(n,r){return tinymce.DOM.getPos(n,r);},cleanupEventStr:function(s){s=""+s;s=s.replace('function anonymous()\n{\n','');s=s.replace('\n}','');s=s.replace(/^return true;/gi,'');return s;},getVisualAidClass:function(s){return s;},parseStyle:function(s){return this._getDOM().parseStyle(s);},serializeStyle:function(s){return this._getDOM().serializeStyle(s);},openWindow:function(tpl,args){var ed=EditorManager.activeEditor,o={},n;for(n in tpl)o[n]=tpl[n];tpl=o;args=args||{};tpl.url=new tinymce.util.URI(tinymce.ThemeManager.themeURLs[ed.settings.theme]).toAbsolute(tpl.file);tpl.inline=tpl.inline||args.inline;ed.windowManager.open(tpl,args);},closeWindow:function(win){EditorManager.activeEditor.windowManager.close(win);},getOuterHTML:function(e){return tinymce.DOM.getOuterHTML(e);},setOuterHTML:function(e,h,d){return tinymce.DOM.setOuterHTML(e,h,d);},hasPlugin:function(n){return tinymce.PluginManager.get(n)!=null;},_setEventsEnabled:function(){},addPlugin:function(pn,f){var t=this;function PluginWrapper(ed){tinyMCE.selectedInstance=ed;ed.onInit.add(function(){t.settings=ed.settings;t.settings['base_href']=tinyMCE.documentBasePath;tinyMCE.settings=t.settings;tinyMCE.documentBasePath=ed.documentBasePath;if(f.initInstance)f.initInstance(ed);ed.contentDocument=ed.getDoc();ed.contentWindow=ed.getWin();ed.undoRedo=ed.undoManager;ed.startContent=ed.getContent({format:'raw'});tinyMCE.instances[ed.id]=ed;tinyMCE.loadedFiles=[];});ed.onActivate.add(function(){tinyMCE.settings=ed.settings;tinyMCE.selectedInstance=ed;});if(f.handleNodeChange){ed.onNodeChange.add(function(ed,cm,n){f.handleNodeChange(ed.id,n,0,0,false,!ed.selection.isCollapsed());});}if(f.onChange){ed.onChange.add(function(ed,n){return f.onChange(ed);});}if(f.cleanup){ed.onGetContent.add(function(){});}this.getInfo=function(){return f.getInfo();};this.createControl=function(n){tinyMCE.pluginURL=tinymce.baseURL+'/plugins/'+pn;tinyMCE.themeURL=tinymce.baseURL+'/themes/'+tinyMCE.activeEditor.settings.theme;if(f.getControlHTML)return f.getControlHTML(n);return null;};this.execCommand=function(cmd,ui,val){if(f.execCommand)return f.execCommand(ed.id,ed.getBody(),cmd,ui,val);return false;};};tinymce.PluginManager.add(pn,PluginWrapper);},_getDOM:function(){return tinyMCE.activeEditor?tinyMCE.activeEditor.dom:tinymce.DOM;},convertRelativeToAbsoluteURL:function(b,u){return new tinymce.util.URI(b).toAbsolute(u);},convertAbsoluteURLToRelativeURL:function(b,u){return new tinymce.util.URI(b).toRelative(u);}});tinymce.extend(tinymce.Editor.prototype,{getFocusElement:function(){return this.selection.getNode();},getData:function(n){if(!this.data)this.data=[];if(!this.data[n])this.data[n]=[];return this.data[n];},hasPlugin:function(n){return this.plugins[n]!=null;},getContainerWin:function(){return window;},getHTML:function(raw){return this.getContent({format:raw?'raw':'html'});},setHTML:function(h){this.setContent(h);},getSel:function(){return this.selection.getSel();},getRng:function(){return this.selection.getRng();},isHidden:function(){var s;if(!tinymce.isGecko)return false;s=this.getSel();return(!s||!s.rangeCount||s.rangeCount==0);},translate:function(s){var c=this.settings.language,o;if(!s)return s;o=tinymce.EditorManager.i18n[c+'.'+s]||s.replace(/{\#([^}]+)\}/g,function(a,b){return tinymce.EditorManager.i18n[c+'.'+b]||'{#'+b+'}';});o=o.replace(/{\$lang_([^}]+)\}/g,function(a,b){return tinymce.EditorManager.i18n[c+'.'+b]||'{$lang_'+b+'}';});return o;},repaint:function(){this.execCommand('mceRepaint');}});tinymce.extend(tinymce.dom.Selection.prototype,{getSelectedText:function(){return this.getContent({format:'text'});},getSelectedHTML:function(){return this.getContent({format:'html'});},getFocusElement:function(){return this.getNode();},selectNode:function(node,collapse,select_text_node,to_start){var t=this;t.select(node,select_text_node||0);if(!is(collapse))collapse=true;if(collapse){if(!is(to_start))to_start=true;t.collapse(to_start);}}});}).call(this);tinymce.PluginManager.add('compat2x',tinymce.plugins.Compat2x);})();
\ No newline at end of file
+(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.is;tinymce.create("tinymce.plugins.Compat2x",{getInfo:function(){return{longname:"Compat2x",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/compat2x",version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}}});(function(){tinymce.extend(tinyMCE,{addToLang:function(f,e){d(e,function(h,g){tinyMCE.i18n[(tinyMCE.settings.language||"en")+"."+(f?f+"_":"")+g]=h})},getInstanceById:function(e){return this.get(e)}})})();(function(){var e=tinymce.EditorManager;tinyMCE.instances={};tinyMCE.plugins={};tinymce.PluginManager.onAdd.add(function(f,h,g){tinyMCE.plugins[h]=g});tinyMCE.majorVersion=tinymce.majorVersion;tinyMCE.minorVersion=tinymce.minorVersion;tinyMCE.releaseDate=tinymce.releaseDate;tinyMCE.baseURL=tinymce.baseURL;tinyMCE.isIE=tinyMCE.isMSIE=tinymce.isIE||tinymce.isOpera;tinyMCE.isMSIE5=tinymce.isIE;tinyMCE.isMSIE5_0=tinymce.isIE;tinyMCE.isMSIE7=tinymce.isIE;tinyMCE.isGecko=tinymce.isGecko;tinyMCE.isSafari=tinymce.isWebKit;tinyMCE.isOpera=tinymce.isOpera;tinyMCE.isMac=false;tinyMCE.isNS7=false;tinyMCE.isNS71=false;tinyMCE.compat=true;TinyMCE_Engine=tinyMCE;tinymce.extend(tinyMCE,{getParam:function(g,f){return this.activeEditor.getParam(g,f)},addEvent:function(i,g,h,j){tinymce.dom.Event.add(i,g,h,j||this)},getControlHTML:function(f){return e.activeEditor.controlManager.createControl(f)},loadCSS:function(f){tinymce.DOM.loadCSS(f)},importCSS:function(g,f){if(g==document){this.loadCSS(f)}else{new tinymce.dom.DOMUtils(g).loadCSS(f)}},log:function(){console.debug.apply(console,arguments)},getLang:function(h,g){var f=e.activeEditor.getLang(h.replace(/^lang_/g,""),g);if(/^[0-9\-.]+$/g.test(f)){return parseInt(f)}return f},isInstance:function(f){return f!=null&&typeof(f)=="object"&&f.execCommand},triggerNodeChange:function(){e.activeEditor.nodeChanged()},regexpReplace:function(j,f,h,i){var g;if(j==null){return j}if(typeof(i)=="undefined"){i="g"}g=new RegExp(f,i);return j.replace(g,h)},trim:function(f){return tinymce.trim(f)},xmlEncode:function(f){return tinymce.DOM.encode(f)},explode:function(f,h){var g=[];tinymce.each(f.split(h),function(i){if(i!=""){g.push(i)}});return g},switchClass:function(h,g){var f;if(/^mceButton/.test(g)){f=e.activeEditor.controlManager.get(h);if(!f){return}switch(g){case"mceButtonNormal":f.setDisabled(false);f.setActive(false);return;case"mceButtonDisabled":f.setDisabled(true);return;case"mceButtonSelected":f.setActive(true);f.setDisabled(false);return}}},addCSSClass:function(g,h,f){return tinymce.DOM.addClass(g,h,f)},hasCSSClass:function(f,g){return tinymce.DOM.hasClass(f,g)},removeCSSClass:function(f,g){return tinymce.DOM.removeClass(f,g)},getCSSClasses:function(){var f=e.activeEditor.dom.getClasses(),g=[];d(f,function(h){g.push(h["class"])});return g},setWindowArg:function(g,f){e.activeEditor.windowManager.params[g]=f},getWindowArg:function(i,g){var h=e.activeEditor.windowManager,f;f=h.getParam(i);if(f===""){return""}return f||h.getFeature(i)||g},getParentNode:function(h,g){return this._getDOM().getParent(h,g)},selectElements:function(o,k,m){var l,j=[],h,g;for(g=0,k=k.split(",");g<k.length;g++){for(l=0,h=o.getElementsByTagName(k[g]);l<h.length;l++){(!m||m(h[l]))&&j.push(h[l])}}return j},getNodeTree:function(i,f,g,h){return this.selectNodes(i,function(j){return(!g||j.nodeType==g)&&(!h||j.nodeName==h)},f?f:[])},getAttrib:function(g,h,f){return this._getDOM().getAttrib(g,h,f)},setAttrib:function(g,h,f){return this._getDOM().setAttrib(g,h,f)},getElementsByAttributeValue:function(m,k,g,h){var j,f=m.getElementsByTagName(k),l=[];for(j=0;j<f.length;j++){if(tinyMCE.getAttrib(f[j],g).indexOf(h)!=-1){l[l.length]=f[j]}}return l},selectNodes:function(k,j,g){var h;if(!g){g=[]}if(j(k)){g[g.length]=k}if(k.hasChildNodes()){for(h=0;h<k.childNodes.length;h++){tinyMCE.selectNodes(k.childNodes[h],j,g)}}return g},getContent:function(){return e.activeEditor.getContent()},getParentElement:function(i,g,h){if(g){g=new RegExp("^("+g.toUpperCase().replace(/,/g,"|")+")$","g")}return this._getDOM().getParent(i,function(f){return f.nodeType==1&&(!g||g.test(f.nodeName))&&(!h||h(f))},this.activeEditor.getBody())},importPluginLanguagePack:function(f){tinymce.PluginManager.requireLangPack(f)},getButtonHTML:function(l,j,h,k,i,g){var f=e.activeEditor;h=h.replace(/\{\$pluginurl\}/g,tinyMCE.pluginURL);h=h.replace(/\{\$themeurl\}/g,tinyMCE.themeURL);j=j.replace(/^lang_/g,"");return f.controlManager.createButton(l,{title:j,command:k,ui:i,value:g,scope:this,"class":"compat",image:h})},addSelectAccessibility:function(h,g,f){if(!g._isAccessible){g.onkeydown=tinyMCE.accessibleEventHandler;g.onblur=tinyMCE.accessibleEventHandler;g._isAccessible=true;g._win=f}return false},accessibleEventHandler:function(g){var h,f=this._win;g=tinymce.isIE?f.event:g;h=tinymce.isIE?g.srcElement:g.target;if(g.type=="blur"){if(h.oldonchange){h.onchange=h.oldonchange;h.oldonchange=null}return true}if(h.nodeName=="SELECT"&&!h.oldonchange){h.oldonchange=h.onchange;h.onchange=null}if(g.keyCode==13||g.keyCode==32){h.onchange=h.oldonchange;h.onchange();h.oldonchange=null;tinyMCE.cancelEvent(g);return false}return true},cancelEvent:function(f){return tinymce.dom.Event.cancel(f)},handleVisualAid:function(f){e.activeEditor.addVisual(f)},getAbsPosition:function(g,f){return tinymce.DOM.getPos(g,f)},cleanupEventStr:function(f){f=""+f;f=f.replace("function anonymous()\n{\n","");f=f.replace("\n}","");f=f.replace(/^return true;/gi,"");return f},getVisualAidClass:function(f){return f},parseStyle:function(f){return this._getDOM().parseStyle(f)},serializeStyle:function(f){return this._getDOM().serializeStyle(f)},openWindow:function(h,g){var f=e.activeEditor,i={},j;for(j in h){i[j]=h[j]}h=i;g=g||{};h.url=new tinymce.util.URI(tinymce.ThemeManager.themeURLs[f.settings.theme]).toAbsolute(h.file);h.inline=h.inline||g.inline;f.windowManager.open(h,g)},closeWindow:function(f){e.activeEditor.windowManager.close(f)},getOuterHTML:function(f){return tinymce.DOM.getOuterHTML(f)},setOuterHTML:function(g,f,i){return tinymce.DOM.setOuterHTML(g,f,i)},hasPlugin:function(f){return tinymce.PluginManager.get(f)!=null},_setEventsEnabled:function(){},addPlugin:function(g,i){var h=this;function j(f){tinyMCE.selectedInstance=f;f.onInit.add(function(){h.settings=f.settings;h.settings.base_href=tinyMCE.documentBasePath;tinyMCE.settings=h.settings;tinyMCE.documentBasePath=f.documentBasePath;if(i.initInstance){i.initInstance(f)}f.contentDocument=f.getDoc();f.contentWindow=f.getWin();f.undoRedo=f.undoManager;f.startContent=f.getContent({format:"raw"});tinyMCE.instances[f.id]=f;tinyMCE.loadedFiles=[]});f.onActivate.add(function(){tinyMCE.settings=f.settings;tinyMCE.selectedInstance=f});if(i.handleNodeChange){f.onNodeChange.add(function(l,k,m){i.handleNodeChange(l.id,m,0,0,false,!l.selection.isCollapsed())})}if(i.onChange){f.onChange.add(function(k,l){return i.onChange(k)})}if(i.cleanup){f.onGetContent.add(function(){})}this.getInfo=function(){return i.getInfo()};this.createControl=function(k){tinyMCE.pluginURL=tinymce.baseURL+"/plugins/"+g;tinyMCE.themeURL=tinymce.baseURL+"/themes/"+tinyMCE.activeEditor.settings.theme;if(i.getControlHTML){return i.getControlHTML(k)}return null};this.execCommand=function(l,k,m){if(i.execCommand){return i.execCommand(f.id,f.getBody(),l,k,m)}return false}}tinymce.PluginManager.add(g,j)},_getDOM:function(){return tinyMCE.activeEditor?tinyMCE.activeEditor.dom:tinymce.DOM},convertRelativeToAbsoluteURL:function(f,g){return new tinymce.util.URI(f).toAbsolute(g)},convertAbsoluteURLToRelativeURL:function(f,g){return new tinymce.util.URI(f).toRelative(g)}});tinymce.extend(tinymce.Editor.prototype,{getFocusElement:function(){return this.selection.getNode()},getData:function(f){if(!this.data){this.data=[]}if(!this.data[f]){this.data[f]=[]}return this.data[f]},hasPlugin:function(f){return this.plugins[f]!=null},getContainerWin:function(){return window},getHTML:function(f){return this.getContent({format:f?"raw":"html"})},setHTML:function(f){this.setContent(f)},getSel:function(){return this.selection.getSel()},getRng:function(){return this.selection.getRng()},isHidden:function(){var f;if(!tinymce.isGecko){return false}f=this.getSel();return(!f||!f.rangeCount||f.rangeCount==0)},translate:function(f){var h=this.settings.language,g;if(!f){return f}g=tinymce.EditorManager.i18n[h+"."+f]||f.replace(/{\#([^}]+)\}/g,function(j,i){return tinymce.EditorManager.i18n[h+"."+i]||"{#"+i+"}"});g=g.replace(/{\$lang_([^}]+)\}/g,function(j,i){return tinymce.EditorManager.i18n[h+"."+i]||"{$lang_"+i+"}"});return g},repaint:function(){this.execCommand("mceRepaint")}});tinymce.extend(tinymce.dom.Selection.prototype,{getSelectedText:function(){return this.getContent({format:"text"})},getSelectedHTML:function(){return this.getContent({format:"html"})},getFocusElement:function(){return this.getNode()},selectNode:function(i,j,g,f){var h=this;h.select(i,g||0);if(!b(j)){j=true}if(j){if(!b(f)){f=true}h.collapse(f)}}})}).call(this);tinymce.PluginManager.add("compat2x",tinymce.plugins.Compat2x)})();
\ No newline at end of file
index f68744d07d6631b1c620b63600731a12e3be4e03..24ee2eb4a0b60d20c7685e1bba3e5584747ab312 100644 (file)
@@ -1 +1 @@
-(function(){var Event=tinymce.dom.Event,each=tinymce.each,DOM=tinymce.DOM;tinymce.create('tinymce.plugins.ContextMenu',{init:function(ed){var t=this;t.editor=ed;t.onContextMenu=new tinymce.util.Dispatcher(this);ed.onContextMenu.add(function(ed,e){if(!e.ctrlKey){t._getMenu(ed).showMenu(e.clientX,e.clientY);Event.add(ed.getDoc(),'click',hide);Event.cancel(e);}});function hide(){if(t._menu){t._menu.removeAll();t._menu.destroy();Event.remove(ed.getDoc(),'click',hide);}};ed.onMouseDown.add(hide);ed.onKeyDown.add(hide);},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(ed){var t=this,m=t._menu,se=ed.selection,col=se.isCollapsed(),el=se.getNode()||ed.getBody(),am,p1,p2;if(m){m.removeAll();m.destroy();}p1=DOM.getPos(ed.getContentAreaContainer());p2=DOM.getPos(ed.getContainer());m=ed.controlManager.createDropMenu('contextmenu',{offset_x:p1.x+ed.getParam('contextmenu_offset_x',0),offset_y:p1.y+ed.getParam('contextmenu_offset_y',0),constrain:1});t._menu=m;m.add({title:'advanced.cut_desc',icon:'cut',cmd:'Cut'}).setDisabled(col);m.add({title:'advanced.copy_desc',icon:'copy',cmd:'Copy'}).setDisabled(col);m.add({title:'advanced.paste_desc',icon:'paste',cmd:'Paste'});if((el.nodeName=='A'&&!ed.dom.getAttrib(el,'name'))||!col){m.addSeparator();m.add({title:'advanced.link_desc',icon:'link',cmd:ed.plugins.advlink?'mceAdvLink':'mceLink',ui:true});m.add({title:'advanced.unlink_desc',icon:'unlink',cmd:'UnLink'});}m.addSeparator();m.add({title:'advanced.image_desc',icon:'image',cmd:ed.plugins.advimage?'mceAdvImage':'mceImage',ui:true});m.addSeparator();am=m.addMenu({title:'contextmenu.align'});am.add({title:'contextmenu.left',icon:'justifyleft',cmd:'JustifyLeft'});am.add({title:'contextmenu.center',icon:'justifycenter',cmd:'JustifyCenter'});am.add({title:'contextmenu.right',icon:'justifyright',cmd:'JustifyRight'});am.add({title:'contextmenu.full',icon:'justifyfull',cmd:'JustifyFull'});t.onContextMenu.dispatch(t,m,el,col);return m;}});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(d){var f=this;f.editor=d;f.onContextMenu=new tinymce.util.Dispatcher(this);d.onContextMenu.add(function(g,h){if(!h.ctrlKey){f._getMenu(g).showMenu(h.clientX,h.clientY);a.add(g.getDoc(),"click",e);a.cancel(h)}});function e(){if(f._menu){f._menu.removeAll();f._menu.destroy();a.remove(d.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
index 6966d80af49716199816005abbcded88ca67cef5..bce8e73995d05c6bdd18f476a595be3e633b9782 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create('tinymce.plugins.Directionality',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceDirectionLTR',function(){var e=ed.dom.getParent(ed.selection.getNode(),ed.dom.isBlock);if(e){if(ed.dom.getAttrib(e,"dir")!="ltr")ed.dom.setAttrib(e,"dir","ltr");else ed.dom.setAttrib(e,"dir","");}ed.nodeChanged();});ed.addCommand('mceDirectionRTL',function(){var e=ed.dom.getParent(ed.selection.getNode(),ed.dom.isBlock);if(e){if(ed.dom.getAttrib(e,"dir")!="rtl")ed.dom.setAttrib(e,"dir","rtl");else ed.dom.setAttrib(e,"dir","");}ed.nodeChanged();});ed.addButton('ltr',{title:'directionality.ltr_desc',cmd:'mceDirectionLTR'});ed.addButton('rtl',{title:'directionality.rtl_desc',cmd:'mceDirectionRTL'});ed.onNodeChange.add(t._nodeChange,t);},getInfo:function(){return{longname:'Directionality',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_nodeChange:function(ed,cm,n){var dom=ed.dom,dir;n=dom.getParent(n,dom.isBlock);if(!n){cm.setDisabled('ltr',1);cm.setDisabled('rtl',1);return;}dir=dom.getAttrib(n,'dir');cm.setActive('ltr',dir=="ltr");cm.setDisabled('ltr',0);cm.setActive('rtl',dir=="rtl");cm.setDisabled('rtl',0);}});tinymce.PluginManager.add('directionality',tinymce.plugins.Directionality);})();
\ No newline at end of file
+(function(){tinymce.create("tinymce.plugins.Directionality",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceDirectionLTR",function(){var d=a.dom.getParent(a.selection.getNode(),a.dom.isBlock);if(d){if(a.dom.getAttrib(d,"dir")!="ltr"){a.dom.setAttrib(d,"dir","ltr")}else{a.dom.setAttrib(d,"dir","")}}a.nodeChanged()});a.addCommand("mceDirectionRTL",function(){var d=a.dom.getParent(a.selection.getNode(),a.dom.isBlock);if(d){if(a.dom.getAttrib(d,"dir")!="rtl"){a.dom.setAttrib(d,"dir","rtl")}else{a.dom.setAttrib(d,"dir","")}}a.nodeChanged()});a.addButton("ltr",{title:"directionality.ltr_desc",cmd:"mceDirectionLTR"});a.addButton("rtl",{title:"directionality.rtl_desc",cmd:"mceDirectionRTL"});a.onNodeChange.add(c._nodeChange,c)},getInfo:function(){return{longname:"Directionality",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_nodeChange:function(b,a,e){var d=b.dom,c;e=d.getParent(e,d.isBlock);if(!e){a.setDisabled("ltr",1);a.setDisabled("rtl",1);return}c=d.getAttrib(e,"dir");a.setActive("ltr",c=="ltr");a.setDisabled("ltr",0);a.setActive("rtl",c=="rtl");a.setDisabled("rtl",0)}});tinymce.PluginManager.add("directionality",tinymce.plugins.Directionality)})();
\ No newline at end of file
index 87fac106d44b7f181cabb8feb3ee916440136200..4783bc371677400b356f6a29622c9aafdd4497cd 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create('tinymce.plugins.EmotionsPlugin',{init:function(ed,url){ed.addCommand('mceEmotion',function(){ed.windowManager.open({file:url+'/emotions.htm',width:250+parseInt(ed.getLang('emotions.delta_width',0)),height:160+parseInt(ed.getLang('emotions.delta_height',0)),inline:1},{plugin_url:url});});ed.addButton('emotions',{title:'emotions.emotions_desc',cmd:'mceEmotion'});},getInfo:function(){return{longname:'Emotions',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/emotions',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('emotions',tinymce.plugins.EmotionsPlugin);})();
\ No newline at end of file
+(function(){tinymce.create("tinymce.plugins.EmotionsPlugin",{init:function(a,b){a.addCommand("mceEmotion",function(){a.windowManager.open({file:b+"/emotions.htm",width:250+parseInt(a.getLang("emotions.delta_width",0)),height:160+parseInt(a.getLang("emotions.delta_height",0)),inline:1},{plugin_url:b})});a.addButton("emotions",{title:"emotions.emotions_desc",cmd:"mceEmotion"})},getInfo:function(){return{longname:"Emotions",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/emotions",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("emotions",tinymce.plugins.EmotionsPlugin)})();
\ No newline at end of file
index 8110ee029a668ad024cbfb8e5a40ab34ada41117..55a1d72fa7f87cf051eaf6e45e4a00af8578a609 100644 (file)
@@ -1,10 +1,9 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
 <html xmlns="http://www.w3.org/1999/xhtml">\r
 <head>\r
        <title>{#emotions_dlg.title}</title>\r
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="js/emotions.js"></script>\r
-       <base target="_self" />\r
 </head>\r
 <body style="display: none">\r
        <div align="center">\r
index 9c2c4bbf9bc574eb9a99d9bc30370f08e7060148..951d1e43ad23534230e458a5b0c6a1fd44eaddb8 100644 (file)
@@ -1 +1 @@
-(function(){var each=tinymce.each;tinymce.create('tinymce.plugins.MediaPlugin',{init:function(ed,url){var t=this;t.editor=ed;t.url=url;function isMediaElm(n){return/^(mceItemFlash|mceItemShockWave|mceItemWindowsMedia|mceItemQuickTime|mceItemRealMedia)$/.test(n.className);};ed.onPreInit.add(function(){ed.serializer.addRules('param[name|value|_value]');});ed.addCommand('mceMedia',function(){ed.windowManager.open({file:url+'/media.htm',width:430+parseInt(ed.getLang('media.delta_width',0)),height:470+parseInt(ed.getLang('media.delta_height',0)),inline:1},{plugin_url:url});});ed.addButton('media',{title:'media.desc',cmd:'mceMedia'});ed.onNodeChange.add(function(ed,cm,n){cm.setActive('media',n.nodeName=='IMG'&&isMediaElm(n));});ed.onInit.add(function(){var lo={mceItemFlash:'flash',mceItemShockWave:'shockwave',mceItemWindowsMedia:'windowsmedia',mceItemQuickTime:'quicktime',mceItemRealMedia:'realmedia'};if(ed.settings.content_css!==false)ed.dom.loadCSS(url+"/css/content.css");if(ed.theme.onResolveName){ed.theme.onResolveName.add(function(th,o){if(o.name=='img'){each(lo,function(v,k){if(ed.dom.hasClass(o.node,k)){o.name=v;o.title=ed.dom.getAttrib(o.node,'title');return false;}});}});}if(ed&&ed.plugins.contextmenu){ed.plugins.contextmenu.onContextMenu.add(function(th,m,e){if(e.nodeName=='IMG'&&/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(e.className)){m.add({title:'media.edit',icon:'media',cmd:'mceMedia'});}});}});ed.onBeforeSetContent.add(function(ed,o){var h=o.content;h=h.replace(/<script[^>]*>\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\(\{([^\)]*)\}\);\s*<\/script>/gi,function(a,b,c){var o=t._parse(c);return'<img class="mceItem'+b+'" title="'+ed.dom.encode(c)+'" src="'+url+'/img/trans.gif" width="'+o.width+'" height="'+o.height+'" />'});h=h.replace(/<object([^>]*)>/gi,'<span class="mceItemObject" $1>');h=h.replace(/<embed([^>]*)\/>/gi,'<span class="mceItemEmbed" $1>');h=h.replace(/<embed([^>]*)>/gi,'<span class="mceItemEmbed" $1>');h=h.replace(/<\/(object|embed)([^>]*)>/gi,'</span>');h=h.replace(/<param([^>]*)>/gi,function(a,b){return'<span '+b.replace(/value=/gi,'_value=')+' class="mceItemParam"></span>'});h=h.replace(/\/ class=\"mceItemParam\"><\/span>/gi,'class="mceItemParam"></span>');o.content=h;});ed.onSetContent.add(function(){t._spansToImgs(ed.getBody());});ed.onPreProcess.add(function(ed,o){var dom=ed.dom;if(o.set){t._spansToImgs(o.node);each(dom.select('IMG',o.node),function(n){var p;if(isMediaElm(n)){p=t._parse(n.title);dom.setAttrib(n,'width',dom.getAttrib(n,'width',p.width||100));dom.setAttrib(n,'height',dom.getAttrib(n,'height',p.height||100));}});}if(o.get){each(dom.select('IMG',o.node),function(n){var ci,cb,mt;if(ed.getParam('media_use_script')){if(isMediaElm(n))n.className=n.className.replace(/mceItem/g,'mceTemp');return;}switch(n.className){case'mceItemFlash':ci='d27cdb6e-ae6d-11cf-96b8-444553540000';cb='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0';mt='application/x-shockwave-flash';break;case'mceItemShockWave':ci='166b1bca-3f9c-11cf-8075-444553540000';cb='http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0';mt='application/x-director';break;case'mceItemWindowsMedia':ci=ed.getParam('media_wmp6_compatible')?'05589fa1-c356-11ce-bf01-00aa0055595a':'6bf52a52-394a-11d3-b153-00c04f79faa6';cb='http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701';mt='application/x-mplayer2';break;case'mceItemQuickTime':ci='02bf25d5-8c17-4b23-bc80-d3488abddc6b';cb='http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0';mt='video/quicktime';break;case'mceItemRealMedia':ci='cfcdaa03-8be4-11cf-b84b-0020afbbccfa';cb='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0';mt='audio/x-pn-realaudio-plugin';break;}if(ci){dom.replace(t._buildObj({classid:ci,codebase:cb,type:mt},n),n);}});}});ed.onPostProcess.add(function(ed,o){o.content=o.content.replace(/_value=/g,'value=');});if(ed.getParam('media_use_script')){function getAttr(s,n){n=new RegExp(n+'=\"([^\"]+)\"','g').exec(s);return n?ed.dom.decode(n[1]):'';};ed.onPostProcess.add(function(ed,o){o.content=o.content.replace(/<img[^>]+>/g,function(im){var cl=getAttr(im,'class');if(/^(mceTempFlash|mceTempShockWave|mceTempWindowsMedia|mceTempQuickTime|mceTempRealMedia)$/.test(cl)){at=t._parse(getAttr(im,'title'));at.width=getAttr(im,'width');at.height=getAttr(im,'height');im='<script type="text/javascript">write'+cl.substring(7)+'({'+t._serialize(at)+'});</script>';}return im;});});}},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};},_buildObj:function(o,n){var ob,ed=this.editor,dom=ed.dom,p=this._parse(n.title);p.width=o.width=dom.getAttrib(n,'width')||100;p.height=o.height=dom.getAttrib(n,'height')||100;ob=dom.create('span',{mce_name:'object',classid:"clsid:"+o.classid,codebase:o.codebase,width:o.width,height:o.height});if(p.src)p.src=ed.convertURL(p.src,'src',n);each(p,function(v,k){if(!/^(width|height|codebase|classid)$/.test(k)){if(o.type=='application/x-mplayer2'&&k=='src')k='url';dom.add(ob,'span',{mce_name:'param',name:k,'_value':v});}});dom.add(ob,'span',tinymce.extend({mce_name:'embed',type:o.type},p));return ob;},_spansToImgs:function(p){var t=this,dom=t.editor.dom,im,ci;each(dom.select('span',p),function(n){if(dom.getAttrib(n,'class')=='mceItemObject'){ci=dom.getAttrib(n,"classid").toLowerCase().replace(/\s+/g,'');switch(ci){case'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000':dom.replace(t._createImg('mceItemFlash',n),n);break;case'clsid:166b1bca-3f9c-11cf-8075-444553540000':dom.replace(t._createImg('mceItemShockWave',n),n);break;case'clsid:6bf52a52-394a-11d3-b153-00c04f79faa6':case'clsid:22d6f312-b0f6-11d0-94ab-0080c74c7e95':case'clsid:05589fa1-c356-11ce-bf01-00aa0055595a':dom.replace(t._createImg('mceItemWindowsMedia',n),n);break;case'clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b':dom.replace(t._createImg('mceItemQuickTime',n),n);break;case'clsid:cfcdaa03-8be4-11cf-b84b-0020afbbccfa':dom.replace(t._createImg('mceItemRealMedia',n),n);break;default:dom.replace(t._createImg('mceItemFlash',n),n);}return;}if(dom.getAttrib(n,'class')=='mceItemEmbed'){switch(dom.getAttrib(n,'type')){case'application/x-shockwave-flash':dom.replace(t._createImg('mceItemFlash',n),n);break;case'application/x-director':dom.replace(t._createImg('mceItemShockWave',n),n);break;case'application/x-mplayer2':dom.replace(t._createImg('mceItemWindowsMedia',n),n);break;case'video/quicktime':dom.replace(t._createImg('mceItemQuickTime',n),n);break;case'audio/x-pn-realaudio-plugin':dom.replace(t._createImg('mceItemRealMedia',n),n);break;default:dom.replace(t._createImg('mceItemFlash',n),n);}}});},_createImg:function(cl,n){var im,dom=this.editor.dom,pa={},ti='';im=dom.create('img',{src:this.url+'/img/trans.gif',width:dom.getAttrib(n,'width')||100,height:dom.getAttrib(n,'height')||100,'class':cl});each(['id','name','width','height','bgcolor','align','flashvars','src','wmode'],function(na){var v=dom.getAttrib(n,na);if(v)pa[na]=v;});each(dom.select('span',n),function(n){if(dom.hasClass(n,'mceItemParam'))pa[dom.getAttrib(n,'name')]=dom.getAttrib(n,'_value');});if(pa.movie){pa.src=pa.movie;delete pa.movie;}delete pa.width;delete pa.height;im.title=this._serialize(pa);return im;},_parse:function(s){return tinymce.util.JSON.parse('{'+s+'}');},_serialize:function(o){return tinymce.util.JSON.serialize(o).replace(/[{}]/g,'');}});tinymce.PluginManager.add('media',tinymce.plugins.MediaPlugin);})();
\ No newline at end of file
+(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.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"];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}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
index ebedd127341390e5f25aca0fd3bf955b9717fb50..faa0cf73032ffb58f4f166316a26923e82e7f2ee 100644 (file)
@@ -1,5 +1,5 @@
 /**\r
- * $Id: editor_plugin_src.js 870 2008-06-13 09:25:41Z spocke $\r
+ * $Id: editor_plugin_src.js 1037 2009-03-02 16:41:15Z spocke $\r
  *\r
  * @author Moxiecode\r
  * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.\r
@@ -21,7 +21,7 @@
 \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|_value]');\r
+                               ed.serializer.addRules('param[name|value|_mce_value]');\r
                        });\r
 \r
                        // Register commands\r
                                        mceItemRealMedia : 'realmedia'\r
                                };\r
 \r
+                               ed.selection.onSetContent.add(function() {\r
+                                       t._spansToImgs(ed.getBody());\r
+                               });\r
+\r
+                               ed.selection.onBeforeSetContent.add(t._objectsToSpans, t);\r
+\r
                                if (ed.settings.content_css !== false)\r
                                        ed.dom.loadCSS(url + "/css/content.css");\r
 \r
                                }\r
                        });\r
 \r
-                       ed.onBeforeSetContent.add(function(ed, o) {\r
-                               var h = o.content;\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
-\r
-                                       return '<img class="mceItem' + b + '" title="' + ed.dom.encode(c) + '" src="' + url + '/img/trans.gif" width="' + o.width + '" height="' + o.height + '" />'\r
-                               });\r
-\r
-                               h = h.replace(/<object([^>]*)>/gi, '<span class="mceItemObject" $1>');\r
-                               h = h.replace(/<embed([^>]*)\/>/gi, '<span class="mceItemEmbed" $1>');\r
-                               h = h.replace(/<embed([^>]*)>/gi, '<span class="mceItemEmbed" $1>');\r
-                               h = h.replace(/<\/(object|embed)([^>]*)>/gi, '</span>');\r
-                               h = h.replace(/<param([^>]*)>/gi, function(a, b) {return '<span ' + b.replace(/value=/gi, '_value=') + ' class="mceItemParam"></span>'});\r
-                               h = h.replace(/\/ class=\"mceItemParam\"><\/span>/gi, 'class="mceItemParam"></span>');\r
-\r
-                               o.content = h;\r
-                       });\r
+                       ed.onBeforeSetContent.add(t._objectsToSpans, t);\r
 \r
                        ed.onSetContent.add(function() {\r
                                t._spansToImgs(ed.getBody());\r
                        });\r
 \r
                        ed.onPostProcess.add(function(ed, o) {\r
-                               o.content = o.content.replace(/_value=/g, 'value=');\r
+                               o.content = o.content.replace(/_mce_value=/g, 'value=');\r
                        });\r
 \r
-                       if (ed.getParam('media_use_script')) {\r
-                               function getAttr(s, n) {\r
-                                       n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s);\r
+                       function getAttr(s, n) {\r
+                               n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s);\r
 \r
-                                       return n ? ed.dom.decode(n[1]) : '';\r
-                               };\r
+                               return n ? ed.dom.decode(n[1]) : '';\r
+                       };\r
 \r
-                               ed.onPostProcess.add(function(ed, o) {\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
 \r
 \r
                                                return im;\r
                                        });\r
-                               });\r
-                       }\r
+                               }\r
+                       });\r
                },\r
 \r
                getInfo : function() {\r
                },\r
 \r
                // Private methods\r
+               _objectsToSpans : function(ed, o) {\r
+                       var t = this, h = o.content;\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
+\r
+                               return '<img class="mceItem' + b + '" title="' + ed.dom.encode(c) + '" src="' + t.url + '/img/trans.gif" width="' + o.width + '" height="' + o.height + '" />'\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
+\r
+                       o.content = h;\r
+               },\r
 \r
                _buildObj : function(o, n) {\r
-                       var ob, ed = this.editor, dom = ed.dom, p = this._parse(n.title);\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
-                       ob = dom.create('span', {\r
-                               mce_name : 'object',\r
-                               classid : "clsid:" + o.classid,\r
-                               codebase : o.codebase,\r
-                               width : o.width,\r
-                               height : o.height\r
-                       });\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
+                       }\r
+\r
                        each (p, function(v, k) {\r
-                               if (!/^(width|height|codebase|classid)$/.test(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')\r
+                                       if (o.type == 'application/x-mplayer2' && k == 'src' && !p.url)\r
                                                k = 'url';\r
 \r
-                                       dom.add(ob, 'span', {mce_name : 'param', name : k, '_value' : v});\r
+                                       if (v)\r
+                                               dom.add(ob, 'span', {mce_name : 'param', name : k, '_mce_value' : v});\r
                                }\r
                        });\r
 \r
-                       dom.add(ob, 'span', tinymce.extend({mce_name : 'embed', type : o.type}, p));\r
+                       if (!stc)\r
+                               dom.add(ob, 'span', tinymce.extend({mce_name : 'embed', type : o.type, style : dom.getAttrib(n, 'style')}, p));\r
 \r
                        return ob;\r
                },\r
                },\r
 \r
                _createImg : function(cl, n) {\r
-                       var im, dom = this.editor.dom, pa = {}, ti = '';\r
+                       var im, dom = this.editor.dom, pa = {}, ti = '', args;\r
+\r
+                       args = ['id', 'name', 'width', 'height', 'bgcolor', 'align', 'flashvars', 'src', 'wmode', 'allowfullscreen', 'quality'];        \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
 \r
                        // Setup base parameters\r
-                       each(['id', 'name', 'width', 'height', 'bgcolor', 'align', 'flashvars', 'src', 'wmode'], function(na) {\r
+                       each(args, function(na) {\r
                                var v = dom.getAttrib(n, na);\r
 \r
                                if (v)\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, '_value');\r
+                                       pa[dom.getAttrib(n, 'name')] = dom.getAttrib(n, '_mce_value');\r
                        });\r
 \r
                        // Use src not movie\r
                                delete pa.movie;\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
+\r
+                                       if (v && !pa[na])\r
+                                               pa[na] = v;\r
+                               });\r
+                       }\r
+\r
                        delete pa.width;\r
                        delete pa.height;\r
 \r
index f04d5d9c31ce2a8224058412502f1d250e3a1cb1..86cfa98563d829fed029f6bc164bc4bc6493b0ef 100644 (file)
@@ -183,7 +183,7 @@ function insertMedia() {
        tinyMCEPopup.restoreSelection();\r
 \r
        if (!AutoValidator.validate(f)) {\r
-               alert(ed.getLang('invalid_data'));\r
+               tinyMCEPopup.alert(ed.getLang('invalid_data'));\r
                return false;\r
        }\r
 \r
@@ -218,7 +218,7 @@ function insertMedia() {
                                break;\r
                }\r
 \r
-               if (fe.width != f.width.value || fe.height != f.height.height)\r
+               if (fe.width != f.width.value || fe.height != f.height.value)\r
                        ed.execCommand('mceRepaint');\r
 \r
                fe.title = serializeParameters();\r
@@ -359,7 +359,9 @@ function changedType(t) {
        d.getElementById('shockwave_options').style.display = 'none';\r
        d.getElementById('wmp_options').style.display = 'none';\r
        d.getElementById('rmp_options').style.display = 'none';\r
-       d.getElementById(t + '_options').style.display = 'block';\r
+\r
+       if (t)\r
+               d.getElementById(t + '_options').style.display = 'block';\r
 }\r
 \r
 function serializeParameters() {\r
@@ -467,7 +469,7 @@ function setBool(pl, p, n) {
        if (typeof(pl[n]) == "undefined")\r
                return;\r
 \r
-       document.forms[0].elements[p + "_" + n].checked = pl[n];\r
+       document.forms[0].elements[p + "_" + n].checked = pl[n] != 'false';\r
 }\r
 \r
 function setStr(pl, p, n) {\r
@@ -488,7 +490,7 @@ function getBool(p, n, d, tv, fv) {
        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
+       return (v == d) ? '' : n + (v ? ':' + tv + ',' : ":\'" + fv + "\',");\r
 }\r
 \r
 function getStr(p, n, d) {\r
@@ -600,7 +602,7 @@ function generatePreview(c) {
 \r
        // Avoid annoying warning about insecure items\r
        if (!tinymce.isIE || document.location.protocol != 'https:') {\r
-               h += '<object classid="clsid:' + cls + '" codebase="' + codebase + '" width="' + pl.width + '" height="' + pl.height + '" id="' + pl.id + '" name="' + pl.name + '" align="' + pl.align + '">';\r
+               h += '<object classid="' + cls + '" codebase="' + codebase + '" width="' + pl.width + '" height="' + pl.height + '" id="' + pl.id + '" name="' + pl.name + '" align="' + pl.align + '">';\r
 \r
                for (n in pl) {\r
                        h += '<param name="' + n + '" value="' + pl[n] + '">';\r
index 8b3bc1d6b6afa28bf80a2c8111914e8833f99410..911c03dcc59e4757f0cbddda361e0fa6d5a5dac4 100644 (file)
@@ -9,7 +9,6 @@
        <script type="text/javascript" src="../../utils/form_utils.js"></script>\r
        <script type="text/javascript" src="../../utils/editable_selects.js"></script>\r
        <link href="css/media.css" rel="stylesheet" type="text/css" />\r
-       <base target="_self" />\r
 </head>\r
 <body style="display: none">\r
     <form onsubmit="insertMedia();return false;" action="#">\r
@@ -52,7 +51,7 @@
                                                        </tr>\r
                                                        <tr id="linklistrow">\r
                                                                <td><label for="linklist">{#media_dlg.list}</label></td>\r
-                                                               <td id="linklistcontainer">&nbsp;</td>\r
+                                                               <td id="linklistcontainer"><select id="linklist"><option value=""></option></select></td>\r
                                                        </tr>\r
                                                        <tr>\r
                                                                <td><label for="width">{#media_dlg.size}</label></td>\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
-                                                       <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
+\r
                                                </tr>\r
 \r
                                                <tr>\r
index 4fce503c15f747d0ed84affb629f3737a85dbd94..f2dbbff2bba374860fde9c94744857adb35c1b45 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create('tinymce.plugins.Nonbreaking',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceNonBreaking',function(){ed.execCommand('mceInsertContent',false,(ed.plugins.visualchars&&ed.plugins.visualchars.state)?'<span class="mceItemHidden mceVisualNbsp">&middot;</span>':'&nbsp;');});ed.addButton('nonbreaking',{title:'nonbreaking.nonbreaking_desc',cmd:'mceNonBreaking'});if(ed.getParam('nonbreaking_force_tab')){ed.onKeyDown.add(function(ed,e){if(tinymce.isIE&&e.keyCode==9){ed.execCommand('mceNonBreaking');ed.execCommand('mceNonBreaking');ed.execCommand('mceNonBreaking');tinymce.dom.Event.cancel(e);}});}},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 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
index 4a35002b46e34c0ebbfd2cba8964c1ebb1c6b44a..93848bf787574b15efd57c8ee71d694e208fefc6 100644 (file)
@@ -1 +1 @@
-(function(){var Event=tinymce.dom.Event;tinymce.create('tinymce.plugins.PastePlugin',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mcePasteText',function(ui,v){if(ui){if((ed.getParam('paste_use_dialog',true))||(!tinymce.isIE)){ed.windowManager.open({file:url+'/pastetext.htm',width:450,height:400,inline:1},{plugin_url:url});}else t._insertText(clipboardData.getData("Text"),true);}else t._insertText(v.html,v.linebreaks);});ed.addCommand('mcePasteWord',function(ui,v){if(ui){if((ed.getParam('paste_use_dialog',true))||(!tinymce.isIE)){ed.windowManager.open({file:url+'/pasteword.htm',width:450,height:400,inline:1},{plugin_url:url});}else t._insertText(t._clipboardHTML());}else t._insertWordContent(v);});ed.addCommand('mceSelectAll',function(){ed.execCommand('selectall');});ed.addButton('pastetext',{title:'paste.paste_text_desc',cmd:'mcePasteText',ui:true});ed.addButton('pasteword',{title:'paste.paste_word_desc',cmd:'mcePasteWord',ui:true});ed.addButton('selectall',{title:'paste.selectall_desc',cmd:'mceSelectAll'});if(ed.getParam("paste_auto_cleanup_on_paste",false)){ed.onPaste.add(function(ed,e){return t._handlePasteEvent(e)});}if(!tinymce.isIE&&ed.getParam("paste_auto_cleanup_on_paste",false)){ed.onKeyDown.add(function(ed,e){if(e.ctrlKey&&e.keyCode==86){window.setTimeout(function(){ed.execCommand("mcePasteText",true);},1);Event.cancel(e);}});}},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};},_handlePasteEvent:function(e){var html=this._clipboardHTML(),ed=this.editor,sel=ed.selection,r;if(ed&&(r=sel.getRng())&&r.text.length>0)ed.execCommand('delete');if(html&&html.length>0)ed.execCommand('mcePasteWord',false,html);return Event.cancel(e);},_insertText:function(content,bLinebreaks){content=this.editor.dom.encode(content);if(content&&content.length>0){if(bLinebreaks){if(this.editor.getParam("paste_create_paragraphs",true)){var rl=this.editor.getParam("paste_replace_list",'\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');for(var i=0;i<rl.length;i+=2)content=content.replace(new RegExp(rl[i],'gi'),rl[i+1]);content=content.replace(/\r\n\r\n/g,'</p><p>');content=content.replace(/\r\r/g,'</p><p>');content=content.replace(/\n\n/g,'</p><p>');if((pos=content.indexOf('</p><p>'))!=-1){this.editor.execCommand("Delete");var node=this.editor.selection.getNode();var breakElms=[];do{if(node.nodeType==1){if(node.nodeName=="TD"||node.nodeName=="BODY")break;breakElms[breakElms.length]=node;}}while(node=node.parentNode);var before="",after="</p>";before+=content.substring(0,pos);for(var i=0;i<breakElms.length;i++){before+="</"+breakElms[i].nodeName+">";after+="<"+breakElms[(breakElms.length-1)-i].nodeName+">";}before+="<p>";content=before+content.substring(pos+7)+after;}}if(this.editor.getParam("paste_create_linebreaks",true)){content=content.replace(/\r\n/g,'<br />');content=content.replace(/\r/g,'<br />');content=content.replace(/\n/g,'<br />');}}this.editor.execCommand("mceInsertRawHTML",false,content);}},_insertWordContent:function(content){var t=this,ed=t.editor;if(content&&content.length>0){var bull=String.fromCharCode(8226);var middot=String.fromCharCode(183);if(ed.getParam('paste_insert_word_content_callback'))content=ed.execCallback('paste_insert_word_content_callback','before',content);var rl=ed.getParam("paste_replace_list",'\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');for(var i=0;i<rl.length;i+=2)content=content.replace(new RegExp(rl[i],'gi'),rl[i+1]);if(this.editor.getParam("paste_convert_headers_to_strong",false)){content=content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>','gi'),'<p><b>$1</b></p>');}content=content.replace(new RegExp('tab-stops: list [0-9]+.0pt">','gi'),'">'+"--list--");content=content.replace(new RegExp(bull+"(.*?)<BR>","gi"),"<p>"+middot+"$1</p>");content=content.replace(new RegExp('<SPAN style="mso-list: Ignore">','gi'),"<span>"+bull);content=content.replace(/<o:p><\/o:p>/gi,"");content=content.replace(new RegExp('<br style="page-break-before: always;.*>','gi'),'-- page break --');content=content.replace(new RegExp('<(!--)([^>]*)(--)>','g'),"");if(this.editor.getParam("paste_remove_spans",true))content=content.replace(/<\/?span[^>]*>/gi,"");if(this.editor.getParam("paste_remove_styles",true))content=content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)','gi'),"<$1$3");content=content.replace(/<\/?font[^>]*>/gi,"");switch(this.editor.getParam("paste_strip_class_attributes","all")){case"all":content=content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi,"<$1$3");break;case"mso":content=content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)','gi'),"<$1$3");break;}content=content.replace(new RegExp('href="?'+this._reEscape(""+document.location)+'','gi'),'href="'+this.editor.documentBaseURI.getURI());content=content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi,"<$1$3");content=content.replace(/<\\?\?xml[^>]*>/gi,"");content=content.replace(/<\/?\w+:[^>]*>/gi,"");content=content.replace(/-- page break --\s*<p>&nbsp;<\/p>/gi,"");content=content.replace(/-- page break --/gi,"");if(!this.editor.getParam('force_p_newlines')){content=content.replace('','','gi');content=content.replace('</p>','<br /><br />','gi');}if(!tinymce.isIE&&!this.editor.getParam('force_p_newlines')){content=content.replace(/<\/?p[^>]*>/gi,"");}content=content.replace(/<\/?div[^>]*>/gi,"");if(this.editor.getParam("paste_convert_middot_lists",true)){var div=ed.dom.create("div",null,content);var className=this.editor.getParam("paste_unindented_list_class","unIndentedList");while(this._convertMiddots(div,"--list--"));while(this._convertMiddots(div,middot,className));while(this._convertMiddots(div,bull));content=div.innerHTML;}if(this.editor.getParam("paste_convert_headers_to_strong",false)){content=content.replace(/<h[1-6]>&nbsp;<\/h[1-6]>/gi,'<p>&nbsp;&nbsp;</p>');content=content.replace(/<h[1-6]>/gi,'<p><b>');content=content.replace(/<\/h[1-6]>/gi,'</b></p>');content=content.replace(/<b>&nbsp;<\/b>/gi,'<b>&nbsp;&nbsp;</b>');content=content.replace(/^(&nbsp;)*/gi,'');}content=content.replace(/--list--/gi,"");if(ed.getParam('paste_insert_word_content_callback'))content=ed.execCallback('paste_insert_word_content_callback','after',content);this.editor.execCommand("mceInsertContent",false,content);if(this.editor.getParam('paste_force_cleanup_wordpaste',true)){var ed=this.editor;window.setTimeout(function(){ed.execCommand("mceCleanup");},1);}}},_reEscape:function(s){var l="?.\\*[](){}+^$:";var o="";for(var i=0;i<s.length;i++){var c=s.charAt(i);if(l.indexOf(c)!=-1)o+='\\'+c;else o+=c;}return o;},_convertMiddots:function(div,search,class_name){var ed=this.editor,mdot=String.fromCharCode(183),bull=String.fromCharCode(8226);var nodes,prevul,i,p,ul,li,np,cp,li;nodes=div.getElementsByTagName("p");for(i=0;i<nodes.length;i++){p=nodes[i];if(p.innerHTML.indexOf(search)==0){ul=ed.dom.create("ul");if(class_name)ul.className=class_name;li=ed.dom.create("li");li.innerHTML=p.innerHTML.replace(new RegExp(''+mdot+'|'+bull+'|--list--|&nbsp;',"gi"),'');ul.appendChild(li);np=p.nextSibling;while(np){if(np.nodeType==3&&new RegExp('^\\s$','m').test(np.nodeValue)){np=np.nextSibling;continue;}if(search==mdot){if(np.nodeType==1&&new RegExp('^o(\\s+|&nbsp;)').test(np.innerHTML)){if(!prevul){prevul=ul;ul=ed.dom.create("ul");prevul.appendChild(ul);}np.innerHTML=np.innerHTML.replace(/^o/,'');}else{if(prevul){ul=prevul;prevul=null;}if(np.nodeType!=1||np.innerHTML.indexOf(search)!=0)break;}}else{if(np.nodeType!=1||np.innerHTML.indexOf(search)!=0)break;}cp=np.nextSibling;li=ed.dom.create("li");li.innerHTML=np.innerHTML.replace(new RegExp(''+mdot+'|'+bull+'|--list--|&nbsp;',"gi"),'');np.parentNode.removeChild(np);ul.appendChild(li);np=cp;}p.parentNode.replaceChild(ul,p);return true;}}return false;},_clipboardHTML:function(){var div=document.getElementById('_TinyMCE_clipboardHTML');if(!div){var div=document.createElement('DIV');div.id='_TinyMCE_clipboardHTML';with(div.style){visibility='hidden';overflow='hidden';position='absolute';width=1;height=1;}document.body.appendChild(div);}div.innerHTML='';var rng=document.body.createTextRange();rng.moveToElementText(div);rng.execCommand('Paste');var html=div.innerHTML;div.innerHTML='';return html;}});tinymce.PluginManager.add('paste',tinymce.plugins.PastePlugin);})();
\ No newline at end of file
+(function(){var a=tinymce.each;tinymce.create("tinymce.plugins.PastePlugin",{init:function(c,d){var e=this,b;e.editor=c;e.url=d;e.onPreProcess=new tinymce.util.Dispatcher(e);e.onPostProcess=new tinymce.util.Dispatcher(e);e.onPreProcess.add(e._preProcess);e.onPostProcess.add(e._postProcess);e.onPreProcess.add(function(h,i){c.execCallback("paste_preprocess",h,i)});e.onPostProcess.add(function(h,i){c.execCallback("paste_postprocess",h,i)});function g(i){var k=c.dom,j={content:i};e.onPreProcess.dispatch(e,j);j.node=k.create("div",0,j.content);e.onPostProcess.dispatch(e,j);j.content=c.serializer.serialize(j.node,{getInner:1});if(/<(p|h[1-6]|ul|ol)/.test(j.content)){e._insertBlockContent(c,k,j.content)}else{e._insert(j.content)}}c.addCommand("mceInsertClipboardContent",function(i,h){g(h)});function f(l){var p,k,i,j=c.selection,o=c.dom,h=c.getBody(),m;if(o.get("_mcePaste")){return}p=o.add(h,"div",{id:"_mcePaste"},"&nbsp;");if(h!=c.getDoc().body){m=o.getPos(c.selection.getStart(),h).y}else{m=h.scrollTop}o.setStyles(p,{position:"absolute",left:-10000,top:m,width:1,height:1,overflow:"hidden"});if(tinymce.isIE){i=o.doc.body.createTextRange();i.moveToElementText(p);i.execCommand("Paste");o.remove(p);g(p.innerHTML);return tinymce.dom.Event.cancel(l)}else{k=c.selection.getRng();p=p.firstChild;i=c.getDoc().createRange();i.setStart(p,0);i.setEnd(p,1);j.setRng(i);window.setTimeout(function(){var r=o.get("_mcePaste"),q;r.id="_mceRemoved";o.remove(r);r=o.get("_mcePaste")||r;q=(o.select("> span.Apple-style-span div",r)[0]||o.select("> span.Apple-style-span",r)[0]||r).innerHTML;o.remove(r);if(k){j.setRng(k)}g(q)},0)}}if(c.getParam("paste_auto_cleanup_on_paste",true)){if(tinymce.isOpera||/Firefox\/2/.test(navigator.userAgent)){c.onKeyDown.add(function(h,i){if(((tinymce.isMac?i.metaKey:i.ctrlKey)&&i.keyCode==86)||(i.shiftKey&&i.keyCode==45)){f(i)}})}else{c.onPaste.addToTop(function(h,i){return f(i)})}}e._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(c,e){var b=e.content,d;function d(f){a(f,function(g){if(g.constructor==RegExp){b=b.replace(g,"")}else{b=b.replace(g[0],g[1])}})}d([/^\s*(&nbsp;)+/g,/(&nbsp;|<br[^>]*>)+\s*$/g]);if(/(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/.test(b)){e.wordContent=true;d([/<!--[\s\S]+?-->/gi,/<\/?(img|font|meta|link|style|span|div|v:\w+)[^>]*>/gi,/<\\?\?xml[^>]*>/gi,/<\/?o:[^>]*>/gi,/ (id|name|class|language|type|on\w+|v:\w+)=\"([^\"]*)\"/gi,/ (id|name|class|language|type|on\w+|v:\w+)=(\w+)/gi,[/<(\/?)s>/gi,"<$1strike>"],/<script[^>]+>[\s\S]*?<\/script>/gi,[/&nbsp;/g,"\u00a0"]])}e.content=b},_postProcess:function(c,e){var b=this,d=b.editor.dom;if(e.wordContent){a(d.select("a",e.node),function(f){if(!f.href||f.href.indexOf("#_Toc")!=-1){d.remove(f,1)}});if(b.editor.getParam("paste_convert_middot_lists",true)){b._convertLists(c,e)}a(d.select("*",e.node),function(f){d.setAttrib(f,"style","")})}if(tinymce.isWebKit){a(d.select("*",e.node),function(f){f.removeAttribute("mce_style")})}},_convertLists:function(e,c){var g=e.editor.dom,f,i,b=-1,d,j=[],h;a(g.select("p",c.node),function(q){var m,r="",o,n,k,l;for(m=q.firstChild;m&&m.nodeType==3;m=m.nextSibling){r+=m.nodeValue}if(/^[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0\u00a0*/.test(r)){o="ul"}if(/^[\s\S]*\w+\.[\s\S]*\u00a0{2,}/.test(r)){o="ol"}if(o){d=parseFloat(q.style.marginLeft||0);if(d>b){j.push(d)}if(!f||o!=h){f=g.create(o);g.insertAfter(f,q)}else{if(d>b){f=i.appendChild(g.create(o))}else{if(d<b){k=tinymce.inArray(j,d);l=g.getParents(f.parentNode,o);f=l[l.length-1-k]||f}}}if(o=="ul"){n=q.innerHTML.replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*(&nbsp;|\u00a0)+\s*/,"")}else{n=q.innerHTML.replace(/^[\s\S]*\w+\.(&nbsp;|\u00a0)+\s*/,"")}i=f.appendChild(g.create("li",0,n));g.remove(q);b=d;h=o}else{f=b=0}})},_insertBlockContent:function(h,e,i){var c,g,d=h.selection,m,j,b,k,f;function l(p){var o;if(tinymce.isIE){o=h.getDoc().body.createTextRange();o.moveToElementText(p);o.collapse(false);o.select()}else{d.select(p,1);d.collapse(false)}}this._insert('<span id="_marker">&nbsp;</span>',1);g=e.get("_marker");c=e.getParent(g,"p,h1,h2,h3,h4,h5,h6,ul,ol");if(c){g=e.split(c,g);a(e.create("div",0,i).childNodes,function(o){m=g.parentNode.insertBefore(o.cloneNode(true),g)});l(m)}else{e.setOuterHTML(g,i);d.select(h.getBody(),1);d.collapse(0)}e.remove("_marker");j=d.getStart();b=e.getViewPort(h.getWin());k=h.dom.getPos(j).y;f=j.clientHeight;if(k<b.y||k+f>b.y+b.h){h.getDoc().body.scrollTop=k<b.y?k:k-b.h+25}},_insert:function(d,b){var c=this.editor;c.execCommand("Delete");c.execCommand(tinymce.isGecko?"insertHTML":"mceInsertContent",false,d,{skip_undo:b})},_legacySupport:function(){var c=this,b=c.editor;a(["mcePasteText","mcePasteWord"],function(d){b.addCommand(d,function(){b.windowManager.open({file:c.url+(d=="mcePasteText"?"/pastetext.htm":"/pasteword.htm"),width:450,height:400,inline:1})})});b.addButton("pastetext",{title:"paste.paste_text_desc",cmd:"mcePasteText"});b.addButton("pasteword",{title:"paste.paste_word_desc",cmd:"mcePasteWord"});b.addButton("selectall",{title:"paste.selectall_desc",cmd:"selectall"})}});tinymce.PluginManager.add("paste",tinymce.plugins.PastePlugin)})();
\ No newline at end of file
index f271758f9d09d30a6a73cb2940289106fce754c1..14d86a957ab77014b99a643abdde46cf8ebeeb5f 100644 (file)
 /**\r
- * $Id: editor_plugin_src.js 862 2008-06-02 20:09:06Z spocke $\r
+ * $Id: editor_plugin_src.js 1104 2009-04-22 12:16:47Z spocke $\r
  *\r
  * @author Moxiecode\r
  * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.\r
  */\r
 \r
 (function() {\r
-       var Event = tinymce.dom.Event;\r
+       var each = tinymce.each;\r
 \r
        tinymce.create('tinymce.plugins.PastePlugin', {\r
                init : function(ed, url) {\r
-                       var t = this;\r
-\r
-                       t.editor = ed; \r
-\r
-                       // Register commands\r
-                       ed.addCommand('mcePasteText', function(ui, v) {\r
-                               if (ui) {\r
-                                       if ((ed.getParam('paste_use_dialog', true)) || (!tinymce.isIE)) {\r
-                                               ed.windowManager.open({\r
-                                                       file : url + '/pastetext.htm',\r
-                                                       width : 450,\r
-                                                       height : 400,\r
-                                                       inline : 1\r
-                                               }, {\r
-                                                       plugin_url : url\r
-                                               });\r
-                                       } else\r
-                                               t._insertText(clipboardData.getData("Text"), true);\r
-                               } else\r
-                                       t._insertText(v.html, v.linebreaks);\r
-                       });\r
+                       var t = this, cb;\r
 \r
-                       ed.addCommand('mcePasteWord', function(ui, v) {\r
-                               if (ui) {\r
-                                       if ((ed.getParam('paste_use_dialog', true)) || (!tinymce.isIE)) {\r
-                                               ed.windowManager.open({\r
-                                                       file : url + '/pasteword.htm',\r
-                                                       width : 450,\r
-                                                       height : 400,\r
-                                                       inline : 1\r
-                                               }, {\r
-                                                       plugin_url : url\r
-                                               });\r
-                                       } else\r
-                                               t._insertText(t._clipboardHTML());\r
-                               } else\r
-                                       t._insertWordContent(v);\r
-                       });\r
+                       t.editor = ed;\r
+                       t.url = url;\r
 \r
-                       ed.addCommand('mceSelectAll', function() {\r
-                               ed.execCommand('selectall'); \r
-                       });\r
+                       // Setup plugin events\r
+                       t.onPreProcess = new tinymce.util.Dispatcher(t);\r
+                       t.onPostProcess = new tinymce.util.Dispatcher(t);\r
 \r
-                       // Register buttons\r
-                       ed.addButton('pastetext', {title : 'paste.paste_text_desc', cmd : 'mcePasteText', ui : true});\r
-                       ed.addButton('pasteword', {title : 'paste.paste_word_desc', cmd : 'mcePasteWord', ui : true});\r
-                       ed.addButton('selectall', {title : 'paste.selectall_desc', cmd : 'mceSelectAll'});\r
+                       // Register default handlers\r
+                       t.onPreProcess.add(t._preProcess);\r
+                       t.onPostProcess.add(t._postProcess);\r
 \r
-                       if (ed.getParam("paste_auto_cleanup_on_paste", false)) {\r
-                               ed.onPaste.add(function(ed, e) {\r
-                                       return t._handlePasteEvent(e)\r
-                               });\r
-                       }\r
-\r
-                       if (!tinymce.isIE && ed.getParam("paste_auto_cleanup_on_paste", false)) {\r
-                               // Force paste dialog if non IE browser\r
-                               ed.onKeyDown.add(function(ed, e) {\r
-                                       if (e.ctrlKey && e.keyCode == 86) {\r
-                                               window.setTimeout(function() {\r
-                                                       ed.execCommand("mcePasteText", true);\r
-                                               }, 1);\r
+                       // Register optional preprocess handler\r
+                       t.onPreProcess.add(function(pl, o) {\r
+                               ed.execCallback('paste_preprocess', pl, o);\r
+                       });\r
 \r
-                                               Event.cancel(e);\r
-                                       }\r
-                               });\r
-                       }\r
-               },\r
+                       // Register optional postprocess\r
+                       t.onPostProcess.add(function(pl, o) {\r
+                               ed.execCallback('paste_postprocess', pl, o);\r
+                       });\r
 \r
-               getInfo : function() {\r
-                       return {\r
-                               longname : 'Paste text/word',\r
-                               author : 'Moxiecode Systems AB',\r
-                               authorurl : 'http://tinymce.moxiecode.com',\r
-                               infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste',\r
-                               version : tinymce.majorVersion + "." + tinymce.minorVersion\r
-                       };\r
-               },\r
+                       // This function executes the process handlers and inserts the contents\r
+                       function process(h) {\r
+                               var dom = ed.dom, o = {content : h};\r
 \r
-               // Private methods\r
+                               // Execute pre process handlers\r
+                               t.onPreProcess.dispatch(t, o);\r
 \r
-               _handlePasteEvent : function(e) {\r
-                       var html = this._clipboardHTML(), ed = this.editor, sel = ed.selection, r;\r
+                               // Create DOM structure\r
+                               o.node = dom.create('div', 0, o.content);\r
 \r
-                       // Removes italic, strong etc, the if was needed due to bug #1437114\r
-                       if (ed && (r = sel.getRng()) && r.text.length > 0)\r
-                               ed.execCommand('delete');\r
+                               // Execute post process handlers\r
+                               t.onPostProcess.dispatch(t, o);\r
 \r
-                       if (html && html.length > 0)\r
-                               ed.execCommand('mcePasteWord', false, html);\r
+                               // Serialize content\r
+                               o.content = ed.serializer.serialize(o.node, {getInner : 1});\r
 \r
-                       return Event.cancel(e);\r
-               },\r
+                               // Insert cleaned content. We need to handle insertion of contents containing block elements separatly\r
+                               if (/<(p|h[1-6]|ul|ol)/.test(o.content))\r
+                                       t._insertBlockContent(ed, dom, o.content);\r
+                               else\r
+                                       t._insert(o.content);\r
+                       };\r
 \r
-               _insertText : function(content, bLinebreaks) {\r
-                       content = this.editor.dom.encode(content);\r
-\r
-                       if (content && content.length > 0) {\r
-                               if (bLinebreaks) { \r
-                                       // Special paragraph treatment \r
-                                       if (this.editor.getParam("paste_create_paragraphs", true)) {\r
-                                               var rl = this.editor.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');\r
-                                               for (var i=0; i<rl.length; i+=2)\r
-                                                       content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]);\r
-\r
-                                               content = content.replace(/\r\n\r\n/g, '</p><p>');\r
-                                               content = content.replace(/\r\r/g, '</p><p>');\r
-                                               content = content.replace(/\n\n/g, '</p><p>');\r
-\r
-                                               // Has paragraphs \r
-                                               if ((pos = content.indexOf('</p><p>')) != -1) { \r
-                                                       this.editor.execCommand("Delete"); \r
-\r
-                                                       var node = this.editor.selection.getNode(); \r
-\r
-                                                       // Get list of elements to break \r
-                                                       var breakElms = [];\r
-\r
-                                                       do { \r
-                                                               if (node.nodeType == 1) { \r
-                                                                       // Don't break tables and break at body \r
-                                                                       if (node.nodeName == "TD" || node.nodeName == "BODY") \r
-                                                                               break; \r
-                       \r
-                                                                       breakElms[breakElms.length] = node; \r
-                                                               } \r
-                                                       } while(node = node.parentNode); \r
-\r
-                                                       var before = "", after = "</p>"; \r
-                                                       before += content.substring(0, pos); \r
-\r
-                                                       for (var i=0; i<breakElms.length; i++) { \r
-                                                               before += "</" + breakElms[i].nodeName + ">"; \r
-                                                               after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; \r
-                                                       } \r
-\r
-                                                       before += "<p>"; \r
-                                                       content = before + content.substring(pos+7) + after; \r
-                                               } \r
-                                       } \r
-\r
-                                       if (this.editor.getParam("paste_create_linebreaks", true)) {\r
-                                               content = content.replace(/\r\n/g, '<br />');\r
-                                               content = content.replace(/\r/g, '<br />');\r
-                                               content = content.replace(/\n/g, '<br />');\r
-                                       }\r
-                               } \r
+                       // Add command for external usage\r
+                       ed.addCommand('mceInsertClipboardContent', function(u, v) {\r
+                               process(v);\r
+                       });\r
 \r
-                               this.editor.execCommand("mceInsertRawHTML", false, content); \r
-                       }\r
-               },\r
+                       // This function grabs the contents from the clipboard by adding a\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
 \r
-               _insertWordContent : function(content) { \r
-                       var t = this, ed = t.editor;\r
+                               if (dom.get('_mcePaste'))\r
+                                       return;\r
 \r
-                       if (content && content.length > 0) {\r
-                               // Cleanup Word content\r
-                               var bull = String.fromCharCode(8226);\r
-                               var middot = String.fromCharCode(183);\r
+                               // Create container to paste into\r
+                               n = dom.add(body, 'div', {id : '_mcePaste'}, '&nbsp;');\r
 \r
-                               if (ed.getParam('paste_insert_word_content_callback'))\r
-                                       content = ed.execCallback('paste_insert_word_content_callback', 'before', content);\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
+\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
+                                       position : 'absolute',\r
+                                       left : -10000,\r
+                                       top : posY,\r
+                                       width : 1,\r
+                                       height : 1,\r
+                                       overflow : 'hidden'\r
+                               });\r
 \r
-                               var rl = ed.getParam("paste_replace_list", '\u2122,<sup>TM</sup>,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');\r
-                               for (var i=0; i<rl.length; i+=2)\r
-                                       content = content.replace(new RegExp(rl[i], 'gi'), rl[i+1]);\r
+                               if (tinymce.isIE) {\r
+                                       // Select the container\r
+                                       rng = dom.doc.body.createTextRange();\r
+                                       rng.moveToElementText(n);\r
+                                       rng.execCommand('Paste');\r
 \r
-                               if (this.editor.getParam("paste_convert_headers_to_strong", false)) {\r
-                                       content = content.replace(new RegExp('<p class=MsoHeading.*?>(.*?)<\/p>', 'gi'), '<p><b>$1</b></p>');\r
-                               }\r
+                                       // Remove container\r
+                                       dom.remove(n);\r
 \r
-                               content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--");\r
-                               content = content.replace(new RegExp(bull + "(.*?)<BR>", "gi"), "<p>" + middot + "$1</p>");\r
-                               content = content.replace(new RegExp('<SPAN style="mso-list: Ignore">', 'gi'), "<span>" + bull); // Covert to bull list\r
-                               content = content.replace(/<o:p><\/o:p>/gi, "");\r
-                               content = content.replace(new RegExp('<br style="page-break-before: always;.*>', 'gi'), '-- page break --'); // Replace pagebreaks\r
-                               content = content.replace(new RegExp('<(!--)([^>]*)(--)>', 'g'), "");  // Word comments\r
+                                       // Process contents\r
+                                       process(n.innerHTML);\r
 \r
-                               if (this.editor.getParam("paste_remove_spans", true))\r
-                                       content = content.replace(/<\/?span[^>]*>/gi, "");\r
+                                       return tinymce.dom.Event.cancel(e);\r
+                               } else {\r
+                                       or = ed.selection.getRng();\r
 \r
-                               if (this.editor.getParam("paste_remove_styles", true))\r
-                                       content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3");\r
+                                       // Move caret into hidden div\r
+                                       n = n.firstChild;\r
+                                       rng = ed.getDoc().createRange();\r
+                                       rng.setStart(n, 0);\r
+                                       rng.setEnd(n, 1);\r
+                                       sel.setRng(rng);\r
 \r
-                               content = content.replace(/<\/?font[^>]*>/gi, "");\r
+                                       // Wait a while and grab the pasted contents\r
+                                       window.setTimeout(function() {\r
+                                               var n = dom.get('_mcePaste'), h;\r
 \r
-                               // Strips class attributes.\r
-                               switch (this.editor.getParam("paste_strip_class_attributes", "all")) {\r
-                                       case "all":\r
-                                               content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");\r
-                                               break;\r
+                                               // Webkit clones the _mcePaste div for some odd reason so this will ensure that we get the real new div not the old empty one\r
+                                               n.id = '_mceRemoved';\r
+                                               dom.remove(n);\r
+                                               n = dom.get('_mcePaste') || n;\r
 \r
-                                       case "mso":\r
-                                               content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3");\r
-                                               break;\r
-                               }\r
+                                               // Grab the HTML contents\r
+                                               // We need to look for a apple style wrapper on webkit it also adds a div wrapper if you copy/paste the body of the editor\r
+                                               // It's amazing how strange the contentEditable mode works in WebKit\r
+                                               h = (dom.select('> span.Apple-style-span div', n)[0] || dom.select('> span.Apple-style-span', n)[0] || n).innerHTML;\r
 \r
-                               content = content.replace(new RegExp('href="?' + this._reEscape("" + document.location) + '', 'gi'), 'href="' + this.editor.documentBaseURI.getURI());\r
-                               content = content.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");\r
-                               content = content.replace(/<\\?\?xml[^>]*>/gi, "");\r
-                               content = content.replace(/<\/?\w+:[^>]*>/gi, "");\r
-                               content = content.replace(/-- page break --\s*<p>&nbsp;<\/p>/gi, ""); // Remove pagebreaks\r
-                               content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks\r
+                                               // Remove hidden div and restore selection\r
+                                               dom.remove(n);\r
 \r
-               //              content = content.replace(/\/?&nbsp;*/gi, ""); &nbsp;\r
-               //              content = content.replace(/<p>&nbsp;<\/p>/gi, '');\r
+                                               // Restore the old selection\r
+                                               if (or)\r
+                                                       sel.setRng(or);\r
 \r
-                               if (!this.editor.getParam('force_p_newlines')) {\r
-                                       content = content.replace('', '' ,'gi');\r
-                                       content = content.replace('</p>', '<br /><br />' ,'gi');\r
+                                               process(h);\r
+                                       }, 0);\r
                                }\r
+                       };\r
 \r
-                               if (!tinymce.isIE && !this.editor.getParam('force_p_newlines')) {\r
-                                       content = content.replace(/<\/?p[^>]*>/gi, "");\r
+                       // Check if we should use the new auto process method                   \r
+                       if (ed.getParam('paste_auto_cleanup_on_paste', true)) {\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
+                                               if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45))\r
+                                                       grabContent(e);\r
+                                       });\r
+                               } else {\r
+                                       // Grab contents on paste event on Gecko and WebKit\r
+                                       ed.onPaste.addToTop(function(ed, e) {\r
+                                               return grabContent(e);\r
+                                       });\r
                                }\r
+                       }\r
 \r
-                               content = content.replace(/<\/?div[^>]*>/gi, "");\r
+                       // Add legacy support\r
+                       t._legacySupport();\r
+               },\r
 \r
-                               // Convert all middlot lists to UL lists\r
-                               if (this.editor.getParam("paste_convert_middot_lists", true)) {\r
-                                       var div = ed.dom.create("div", null, content);\r
+               getInfo : function() {\r
+                       return {\r
+                               longname : 'Paste text/word',\r
+                               author : 'Moxiecode Systems AB',\r
+                               authorurl : 'http://tinymce.moxiecode.com',\r
+                               infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste',\r
+                               version : tinymce.majorVersion + "." + tinymce.minorVersion\r
+                       };\r
+               },\r
 \r
-                                       // Convert all middot paragraphs to li elements\r
-                                       var className = this.editor.getParam("paste_unindented_list_class", "unIndentedList");\r
+               _preProcess : function(pl, o) {\r
+                       var h = o.content, process;\r
 \r
-                                       while (this._convertMiddots(div, "--list--")) ; // bull\r
-                                       while (this._convertMiddots(div, middot, className)) ; // Middot\r
-                                       while (this._convertMiddots(div, bull)) ; // bull\r
+                       //console.log('Before preprocess:' + o.content);\r
 \r
-                                       content = div.innerHTML;\r
-                               }\r
+                       function process(items) {\r
+                               each(items, function(v) {\r
+                                       // Remove or replace\r
+                                       if (v.constructor == RegExp)\r
+                                               h = h.replace(v, '');\r
+                                       else\r
+                                               h = h.replace(v[0], v[1]);\r
+                               });\r
+                       };\r
 \r
-                               // Replace all headers with strong and fix some other issues\r
-                               if (this.editor.getParam("paste_convert_headers_to_strong", false)) {\r
-                                       content = content.replace(/<h[1-6]>&nbsp;<\/h[1-6]>/gi, '<p>&nbsp;&nbsp;</p>');\r
-                                       content = content.replace(/<h[1-6]>/gi, '<p><b>');\r
-                                       content = content.replace(/<\/h[1-6]>/gi, '</b></p>');\r
-                                       content = content.replace(/<b>&nbsp;<\/b>/gi, '<b>&nbsp;&nbsp;</b>');\r
-                                       content = content.replace(/^(&nbsp;)*/gi, '');\r
-                               }\r
+                       // Process away some basic content\r
+                       process([\r
+                               /^\s*(&nbsp;)+/g,                                                                                       // nbsp entities at the start of contents\r
+                               /(&nbsp;|<br[^>]*>)+\s*$/g                                                                      // nbsp entities at the end of contents\r
+                       ]);\r
+\r
+                       // Detect Word content and process it more agressive\r
+                       if (/(class=\"?Mso|style=\"[^\"]*\bmso\-|w:WordDocument)/.test(h)) {\r
+                               o.wordContent = true; // Mark the pasted contents as word specific content\r
+                               //console.log('Word contents detected.');\r
+\r
+                               process([\r
+                                       /<!--[\s\S]+?-->/gi,                                                                                            // Word comments\r
+                                       /<\/?(img|font|meta|link|style|span|div|v:\w+)[^>]*>/gi,                        // Remove some tags including VML content\r
+                                       /<\\?\?xml[^>]*>/gi,                                                                                            // XML namespace declarations\r
+                                       /<\/?o:[^>]*>/gi,                                                                                                       // MS namespaced elements <o:tag>\r
+                                       / (id|name|class|language|type|on\w+|v:\w+)=\"([^\"]*)\"/gi,    // on.., class, style and language attributes with quotes\r
+                                       / (id|name|class|language|type|on\w+|v:\w+)=(\w+)/gi,                   // on.., class, style and language attributes without quotes (IE)\r
+                                       [/<(\/?)s>/gi, '<$1strike>'],                                                                           // Convert <s> into <strike> for line-though\r
+                                       /<script[^>]+>[\s\S]*?<\/script>/gi,                                                            // All scripts elements for msoShowComment for example\r
+                                       [/&nbsp;/g, '\u00a0']                                                                                           // Replace nsbp entites to char since it's easier to handle\r
+                               ]);\r
+                       }\r
 \r
-                               content = content.replace(/--list--/gi, ""); // Remove --list--\r
+                       //console.log('After preprocess:' + h);\r
 \r
-                               if (ed.getParam('paste_insert_word_content_callback'))\r
-                                       content = ed.execCallback('paste_insert_word_content_callback', 'after', content);\r
+                       o.content = h;\r
+               },\r
 \r
-                               // Insert cleaned content\r
-                               this.editor.execCommand("mceInsertContent", false, content);\r
+               /**\r
+                * Various post process items.\r
+                */\r
+               _postProcess : function(pl, o) {\r
+                       var t = this, dom = t.editor.dom;\r
+\r
+                       if (o.wordContent) {\r
+                               // Remove named anchors or TOC links\r
+                               each(dom.select('a', o.node), function(a) {\r
+                                       if (!a.href || a.href.indexOf('#_Toc') != -1)\r
+                                               dom.remove(a, 1);\r
+                               });\r
 \r
-                               if (this.editor.getParam('paste_force_cleanup_wordpaste', true)) {\r
-                                       var ed = this.editor;\r
+                               if (t.editor.getParam('paste_convert_middot_lists', true))\r
+                                       t._convertLists(pl, o);\r
 \r
-                                       window.setTimeout(function() {\r
-                                               ed.execCommand("mceCleanup");\r
-                                       }, 1); // Do normal cleanup detached from this thread\r
-                               }\r
+                               // Remove all styles\r
+                               each(dom.select('*', o.node), function(el) {\r
+                                       dom.setAttrib(el, 'style', '');\r
+                               });\r
+                       }\r
+\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
+                               });\r
                        }\r
                },\r
 \r
-               _reEscape : function(s) {\r
-                       var l = "?.\\*[](){}+^$:";\r
-                       var o = "";\r
+               /**\r
+                * Converts the most common bullet and number formats in Office into a real semantic UL/LI list.\r
+                */\r
+               _convertLists : function(pl, o) {\r
+                       var dom = pl.editor.dom, listElm, li, lastMargin = -1, margin, levels = [], lastType;\r
+\r
+                       // Convert middot lists into real scemantic lists\r
+                       each(dom.select('p', o.node), function(p) {\r
+                               var sib, val = '', type, html, idx, parents;\r
+\r
+                               // Get text node value at beginning of paragraph\r
+                               for (sib = p.firstChild; sib && sib.nodeType == 3; sib = sib.nextSibling)\r
+                                       val += sib.nodeValue;\r
+\r
+                               // Detect unordered lists look for bullets\r
+                               if (/^[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0\u00a0*/.test(val))\r
+                                       type = 'ul';\r
+\r
+                               // Detect ordered lists 1., a. or ixv.\r
+                               if (/^[\s\S]*\w+\.[\s\S]*\u00a0{2,}/.test(val))\r
+                                       type = 'ol';\r
+\r
+                               // Check if node value matches the list pattern: o&nbsp;&nbsp;\r
+                               if (type) {\r
+                                       margin = parseFloat(p.style.marginLeft || 0);\r
+\r
+                                       if (margin > lastMargin)\r
+                                               levels.push(margin);\r
+\r
+                                       if (!listElm || type != lastType) {\r
+                                               listElm = dom.create(type);\r
+                                               dom.insertAfter(listElm, p);\r
+                                       } else {\r
+                                               // Nested list element\r
+                                               if (margin > lastMargin) {\r
+                                                       listElm = li.appendChild(dom.create(type));\r
+                                               } else if (margin < lastMargin) {\r
+                                                       // Find parent level based on margin value\r
+                                                       idx = tinymce.inArray(levels, margin);\r
+                                                       parents = dom.getParents(listElm.parentNode, type);\r
+                                                       listElm = parents[parents.length - 1 - idx] || listElm;\r
+                                               }\r
+                                       }\r
 \r
-                       for (var i=0; i<s.length; i++) {\r
-                               var c = s.charAt(i);\r
+                                       if (type == 'ul')\r
+                                               html = p.innerHTML.replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*(&nbsp;|\u00a0)+\s*/, '');\r
+                                       else\r
+                                               html = p.innerHTML.replace(/^[\s\S]*\w+\.(&nbsp;|\u00a0)+\s*/, '');\r
 \r
-                               if (l.indexOf(c) != -1)\r
-                                       o += '\\' + c;\r
-                               else\r
-                                       o += c;\r
-                       }\r
+                                       li = listElm.appendChild(dom.create('li', 0, html));\r
+                                       dom.remove(p);\r
 \r
-                       return o;\r
+                                       lastMargin = margin;\r
+                                       lastType = type;\r
+                               } else\r
+                                       listElm = lastMargin = 0; // End list element\r
+                       });\r
                },\r
 \r
-               _convertMiddots : function(div, search, class_name) {\r
-                       var ed = this.editor, mdot = String.fromCharCode(183), bull = String.fromCharCode(8226);\r
-                       var nodes, prevul, i, p, ul, li, np, cp, li;\r
-\r
-                       nodes = div.getElementsByTagName("p");\r
-                       for (i=0; i<nodes.length; i++) {\r
-                               p = nodes[i];\r
-\r
-                               // Is middot\r
-                               if (p.innerHTML.indexOf(search) == 0) {\r
-                                       ul = ed.dom.create("ul");\r
-\r
-                                       if (class_name)\r
-                                               ul.className = class_name;\r
-\r
-                                       // Add the first one\r
-                                       li = ed.dom.create("li");\r
-                                       li.innerHTML = p.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--|&nbsp;', "gi"), '');\r
-                                       ul.appendChild(li);\r
-\r
-                                       // Add the rest\r
-                                       np = p.nextSibling;\r
-                                       while (np) {\r
-                                               // If the node is whitespace, then\r
-                                               // ignore it and continue on.\r
-                                               if (np.nodeType == 3 && new RegExp('^\\s$', 'm').test(np.nodeValue)) {\r
-                                                               np = np.nextSibling;\r
-                                                               continue;\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;\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
-                                               if (search == mdot) {\r
-                                                               if (np.nodeType == 1 && new RegExp('^o(\\s+|&nbsp;)').test(np.innerHTML)) {\r
-                                                                               // Second level of nesting\r
-                                                                               if (!prevul) {\r
-                                                                                               prevul = ul;\r
-                                                                                               ul = ed.dom.create("ul");\r
-                                                                                               prevul.appendChild(ul);\r
-                                                                               }\r
-                                                                               np.innerHTML = np.innerHTML.replace(/^o/, '');\r
-                                                               } else {\r
-                                                                               // Pop the stack if we're going back up to the first level\r
-                                                                               if (prevul) {\r
-                                                                                               ul = prevul;\r
-                                                                                               prevul = null;\r
-                                                                               }\r
-                                                                               // Not element or middot paragraph\r
-                                                                               if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0)\r
-                                                                                               break;\r
-                                                               }\r
-                                               } else {\r
-                                                               // Not element or middot paragraph\r
-                                                               if (np.nodeType != 1 || np.innerHTML.indexOf(search) != 0)\r
-                                                                               break;\r
-                                                       }\r
-\r
-                                               cp = np.nextSibling;\r
-                                               li = ed.dom.create("li");\r
-                                               li.innerHTML = np.innerHTML.replace(new RegExp('' + mdot + '|' + bull + '|--list--|&nbsp;', "gi"), '');\r
-                                               np.parentNode.removeChild(np);\r
-                                               ul.appendChild(li);\r
-                                               np = cp;\r
-                                       }\r
+                       // Insert a marker for the caret position\r
+                       this._insert('<span id="_marker">&nbsp;</span>', 1);\r
+                       marker = dom.get('_marker');\r
+                       parentBlock = dom.getParent(marker, 'p,h1,h2,h3,h4,h5,h6,ul,ol');\r
 \r
-                                       p.parentNode.replaceChild(ul, p);\r
+                       if (parentBlock) {\r
+                               // Split parent block\r
+                               marker = dom.split(parentBlock, marker);\r
 \r
-                                       return true;\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
-                       return false;\r
+                       dom.remove('_marker'); // Remove marker if it's left\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
-               _clipboardHTML : function() {\r
-                       var div = document.getElementById('_TinyMCE_clipboardHTML');\r
+               /**\r
+                * Inserts the specified contents at the caret position.\r
+                */\r
+               _insert : function(h, skip_undo) {\r
+                       var ed = this.editor;\r
 \r
-                       if (!div) {\r
-                               var div = document.createElement('DIV');\r
-                               div.id = '_TinyMCE_clipboardHTML';\r
+                       // First delete the contents seems to work better on WebKit\r
+                       ed.execCommand('Delete');\r
 \r
-                               with (div.style) {\r
-                                       visibility = 'hidden';\r
-                                       overflow = 'hidden';\r
-                                       position = 'absolute';\r
-                                       width = 1;\r
-                                       height = 1;\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
+               },\r
 \r
-                               document.body.appendChild(div);\r
-                       }\r
+               /**\r
+                * This method will open the old style paste dialogs. Some users might want the old behavior but still use the new cleanup engine.\r
+                */\r
+               _legacySupport : function() {\r
+                       var t = this, ed = t.editor;\r
+\r
+                       // Register commands for backwards compatibility\r
+                       each(['mcePasteText', 'mcePasteWord'], function(cmd) {\r
+                               ed.addCommand(cmd, function() {\r
+                                       ed.windowManager.open({\r
+                                               file : t.url + (cmd == 'mcePasteText' ? '/pastetext.htm' : '/pasteword.htm'),\r
+                                               width : 450,\r
+                                               height : 400,\r
+                                               inline : 1\r
+                                       });\r
+                               });\r
+                       });\r
 \r
-                       div.innerHTML = '';\r
-                       var rng = document.body.createTextRange();\r
-                       rng.moveToElementText(div);\r
-                       rng.execCommand('Paste');\r
-                       var html = div.innerHTML;\r
-                       div.innerHTML = '';\r
-                       return html;\r
+                       // Register buttons for backwards compatibility\r
+                       ed.addButton('pastetext', {title : 'paste.paste_text_desc', cmd : 'mcePasteText'});\r
+                       ed.addButton('pasteword', {title : 'paste.paste_word_desc', cmd : 'mcePasteWord'});\r
+                       ed.addButton('selectall', {title : 'paste.selectall_desc', cmd : 'selectall'});\r
                }\r
        });\r
 \r
index 326bb16a2af7367a8fd4500139e92036740fdbb7..303439b336285d4c40454dd1ab7441e4567b1e97 100644 (file)
@@ -1,42 +1,36 @@
 tinyMCEPopup.requireLangPack();\r
 \r
-function saveContent() {\r
-       if (document.forms[0].htmlSource.value == '') {\r
+var PasteTextDialog = {\r
+       init : function() {\r
+               this.resize();\r
+       },\r
+\r
+       insert : function() {\r
+               var h = tinyMCEPopup.dom.encode(document.getElementById('content').value), lines;\r
+\r
+               // Convert linebreaks into paragraphs\r
+               if (document.getElementById('linebreaks').checked) {\r
+                       lines = h.split(/\r?\n/);\r
+                       if (lines.length > 1) {\r
+                               h = '';\r
+                               tinymce.each(lines, function(row) {\r
+                                       h += '<p>' + row + '</p>';\r
+                               });\r
+                       }\r
+               }\r
+\r
+               tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, h);\r
                tinyMCEPopup.close();\r
-               return false;\r
-       }\r
-\r
-       tinyMCEPopup.execCommand('mcePasteText', false, {\r
-               html : document.forms[0].htmlSource.value,\r
-               linebreaks : document.forms[0].linebreaks.checked\r
-       });\r
-\r
-       tinyMCEPopup.close();\r
-}\r
+       },\r
 \r
-function onLoadInit() {\r
-       tinyMCEPopup.resizeToInnerSize();\r
+       resize : function() {\r
+               var vp = tinyMCEPopup.dom.getViewPort(window), el;\r
 \r
-       // Remove Gecko spellchecking\r
-       if (tinymce.isGecko)\r
-               document.body.spellcheck = tinyMCEPopup.getParam("gecko_spellcheck");\r
+               el = document.getElementById('content');\r
 \r
-       resizeInputs();\r
-}\r
-\r
-var wHeight=0, wWidth=0, owHeight=0, owWidth=0;\r
-\r
-function resizeInputs() {\r
-       if (!tinymce.isIE) {\r
-               wHeight = self.innerHeight-80;\r
-               wWidth = self.innerWidth-17;\r
-       } else {\r
-               wHeight = document.body.clientHeight-80;\r
-               wWidth = document.body.clientWidth-17;\r
+               el.style.width  = (vp.w - 20) + 'px';\r
+               el.style.height = (vp.h - 90) + 'px';\r
        }\r
+};\r
 \r
-       document.forms[0].htmlSource.style.height = Math.abs(wHeight) + 'px';\r
-       document.forms[0].htmlSource.style.width  = Math.abs(wWidth) + 'px';\r
-}\r
-\r
-tinyMCEPopup.onInit.add(onLoadInit);
\ No newline at end of file
+tinyMCEPopup.onInit.add(PasteTextDialog.init, PasteTextDialog);\r
index 6701b99fc8ccf78b843c25a7bf9a4b923106c68b..fe053a7213eb9ee66c52398d46441a719c63e6a1 100644 (file)
@@ -1,56 +1,51 @@
 tinyMCEPopup.requireLangPack();\r
 \r
-function saveContent() {\r
-       var html = document.getElementById("frmData").contentWindow.document.body.innerHTML;\r
-\r
-       if (html == ''){\r
+var PasteWordDialog = {\r
+       init : function() {\r
+               var ed = tinyMCEPopup.editor, el = document.getElementById('iframecontainer'), ifr, doc, css, cssHTML = '';\r
+\r
+               // Create iframe\r
+               el.innerHTML = '<iframe id="iframe" src="javascript:\'\';" frameBorder="0" style="border: 1px solid gray"></iframe>';\r
+               ifr = document.getElementById('iframe');\r
+               doc = ifr.contentWindow.document;\r
+\r
+               // Force absolute CSS urls\r
+               css = [ed.baseURI.toAbsolute("themes/" + ed.settings.theme + "/skins/" + ed.settings.skin + "/content.css")];\r
+               css = css.concat(tinymce.explode(ed.settings.content_css) || []);\r
+               tinymce.each(css, function(u) {\r
+                       cssHTML += '<link href="' + ed.documentBaseURI.toAbsolute(u) + '" rel="stylesheet" type="text/css" />';\r
+               });\r
+\r
+               // Write content into iframe\r
+               doc.open();\r
+               doc.write('<html><head>' + cssHTML + '</head><body spellcheck="false"></body></html>');\r
+               doc.close();\r
+\r
+               doc.designMode = 'on';\r
+               this.resize();\r
+\r
+               window.setTimeout(function() {\r
+                       ifr.contentWindow.focus();\r
+               }, 10);\r
+       },\r
+\r
+       insert : function() {\r
+               var h = document.getElementById('iframe').contentWindow.document.body.innerHTML;\r
+\r
+               tinyMCEPopup.editor.execCommand('mceInsertClipboardContent', false, h);\r
                tinyMCEPopup.close();\r
-               return false;\r
-       }\r
-\r
-       tinyMCEPopup.execCommand('mcePasteWord', false, html);\r
-       tinyMCEPopup.close();\r
-}\r
-\r
-function onLoadInit() {\r
-       tinyMCEPopup.resizeToInnerSize();\r
-\r
-       // Fix for endless reloading in FF\r
-       window.setTimeout(createIFrame, 10);\r
-}\r
-\r
-function createIFrame() {\r
-       document.getElementById('iframecontainer').innerHTML = '<iframe id="frmData" name="frmData" class="sourceIframe" src="blank.htm" height="280" width="400" frameborder="0" style="background-color:#FFFFFF; width:100%;" dir="ltr" wrap="soft"></iframe>';\r
-}\r
+       },\r
 \r
-var wHeight=0, wWidth=0, owHeight=0, owWidth=0;\r
+       resize : function() {\r
+               var vp = tinyMCEPopup.dom.getViewPort(window), el;\r
 \r
-function initIframe(doc) {\r
-       var dir = tinyMCEPopup.editor.settings.directionality;\r
-\r
-       doc.body.dir = dir;\r
-\r
-       // Remove Gecko spellchecking\r
-       if (tinymce.isGecko)\r
-               doc.body.spellcheck = tinyMCEPopup.getParam("gecko_spellcheck");\r
-\r
-       resizeInputs();\r
-}\r
-\r
-function resizeInputs() {\r
-       if (!tinymce.isIE) {\r
-               wHeight = self.innerHeight - 80;\r
-               wWidth = self.innerWidth - 18;\r
-       } else {\r
-               wHeight = document.body.clientHeight - 80;\r
-               wWidth = document.body.clientWidth - 18;\r
-       }\r
+               el = document.getElementById('iframe');\r
 \r
-       var elm = document.getElementById('frmData');\r
-       if (elm) {\r
-               elm.style.height = Math.abs(wHeight) + 'px';\r
-               elm.style.width  = Math.abs(wWidth) + 'px';\r
+               if (el) {\r
+                       el.style.width  = (vp.w - 20) + 'px';\r
+                       el.style.height = (vp.h - 90) + 'px';\r
+               }\r
        }\r
-}\r
+};\r
 \r
-tinyMCEPopup.onInit.add(onLoadInit);\r
+tinyMCEPopup.onInit.add(PasteWordDialog.init, PasteWordDialog);\r
index 2f2b341a11bb50337163d6f78522ea21f8e7f137..42c3d9c849fa6245a58027e128eb80d94629c00d 100644 (file)
@@ -4,31 +4,30 @@
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />\r
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="js/pastetext.js"></script>\r
-       <base target="_self" />\r
 </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">{#paste.paste_text_desc}</div>\r
+<body onresize="PasteTextDialog.resize();" style="display:none; overflow:hidden;">\r
+       <form name="source" onsubmit="return PasteTextDialog.insert();" action="#">\r
+               <div style="float: left" class="title">{#paste.paste_text_desc}</div>\r
 \r
-       <div style="float: right">\r
-               <input type="checkbox" name="linebreaks" id="linebreaks" class="wordWrapCode" checked="checked" /><label for="linebreaks">{#paste_dlg.text_linebreaks}</label>\r
-       </div>\r
+               <div style="float: right">\r
+                       <input type="checkbox" name="linebreaks" id="linebreaks" class="wordWrapCode" checked="checked" /><label for="linebreaks">{#paste_dlg.text_linebreaks}</label>\r
+               </div>\r
 \r
-       <br style="clear: both" />\r
+               <br style="clear: both" />\r
 \r
-       <div>{#paste_dlg.text_title}</div>\r
+               <div>{#paste_dlg.text_title}</div>\r
 \r
-       <textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,mono; font-size: 12px;" dir="ltr" wrap="soft" class="mceFocus"></textarea>\r
+               <textarea id="content" name="content" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,mono; font-size: 12px;" dir="ltr" wrap="soft" class="mceFocus"></textarea>\r
 \r
-       <div class="mceActionPanel">\r
-               <div style="float: left">\r
-                       <input type="submit" name="insert" value="{#insert}" id="insert" />\r
-               </div>\r
+               <div class="mceActionPanel">\r
+                       <div style="float: left">\r
+                               <input type="submit" name="insert" value="{#insert}" id="insert" />\r
+                       </div>\r
 \r
-               <div style="float: right">\r
-                       <input type="button" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" id="cancel" />\r
+                       <div style="float: right">\r
+                               <input type="button" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" id="cancel" />\r
+                       </div>\r
                </div>\r
-       </div>\r
-</form>\r
+       </form>\r
 </body> \r
 </html>
\ No newline at end of file
index 9e5ab1b5b5869e1922cca7bd4460d465a2371d93..f4a9b3db3fa2113c899659b38f655b5f996c802f 100644 (file)
@@ -4,11 +4,9 @@
        <title>{#paste.paste_word_desc}</title>\r
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="js/pasteword.js"></script>\r
-       <link href="css/pasteword.css" rel="stylesheet" type="text/css" />\r
-       <base target="_self" />\r
 </head>\r
-<body onresize="resizeInputs();" style="display:none; overflow:hidden;">\r
-       <form name="source" onsubmit="saveContent();" action="#">\r
+<body onresize="PasteWordDialog.resize();" style="display:none; overflow:hidden;">\r
+       <form name="source" onsubmit="return PasteWordDialog.insert();" action="#">\r
                <div class="title">{#paste.paste_word_desc}</div>\r
 \r
                <div>{#paste_dlg.word_title}</div>\r
@@ -17,7 +15,7 @@
 \r
                <div class="mceActionPanel">\r
                        <div style="float: left">\r
-                               <input type="button" id="insert" name="insert" value="{#insert}" onclick="saveContent();" />\r
+                               <input type="submit" id="insert" name="insert" value="{#insert}" />\r
                        </div>\r
 \r
                        <div style="float: right">\r
index 7fd913b2b8bf77fb916a6dad3b84848f4ba77710..c3f8358c61dd9eccb700b64ef329d1edb1e5ac97 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create('tinymce.plugins.SearchReplacePlugin',{init:function(ed,url){function open(m){ed.windowManager.open({file:url+'/searchreplace.htm',width:420+parseInt(ed.getLang('searchreplace.delta_width',0)),height:160+parseInt(ed.getLang('searchreplace.delta_height',0)),inline:1,auto_focus:0},{mode:m,search_string:ed.selection.getContent({format:'text'}),plugin_url:url});};ed.addCommand('mceSearch',function(){open('search');});ed.addCommand('mceReplace',function(){open('replace');});ed.addButton('search',{title:'searchreplace.search_desc',cmd:'mceSearch'});ed.addButton('replace',{title:'searchreplace.replace_desc',cmd:'mceReplace'});ed.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){a.windowManager.open({file:c+"/searchreplace.htm",width:420+parseInt(a.getLang("searchreplace.delta_width",0)),height:160+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 890eb37f1abb8e12b8f3ebfdb32c23dcc9cf87c2..a8585cccce9d1342ef37a3a6e40845680f906f11 100644 (file)
@@ -42,6 +42,9 @@ var SearchReplaceDialog = {
                ca = f[m + '_panel_casesensitivebox'].checked;\r
                rs = f['replace_panel_replacestring'].value;\r
 \r
+               if (s == '')\r
+                       return;\r
+\r
                function fix() {\r
                        // Correct Firefox graphics glitches\r
                        r = se.getRng().cloneRange();\r
@@ -62,6 +65,10 @@ var SearchReplaceDialog = {
 \r
                switch (a) {\r
                        case 'all':\r
+                               // Move caret to beginning of text\r
+                               ed.execCommand('SelectAll');\r
+                               ed.selection.collapse(true);\r
+\r
                                if (tinymce.isIE) {\r
                                        while (r.findText(s, b ? -1 : 1, fl)) {\r
                                                r.scrollIntoView();\r
@@ -79,14 +86,16 @@ var SearchReplaceDialog = {
                                }\r
 \r
                                if (fo)\r
-                                       wm.alert(ed.getLang('searchreplace_dlg.allreplaced'));\r
+                                       tinyMCEPopup.alert(ed.getLang('searchreplace_dlg.allreplaced'));\r
                                else\r
-                                       wm.alert(ed.getLang('searchreplace_dlg.notfound'));\r
+                                       tinyMCEPopup.alert(ed.getLang('searchreplace_dlg.notfound'));\r
 \r
                                return;\r
 \r
                        case 'current':\r
-                               replace();\r
+                               if (!ed.selection.isCollapsed())\r
+                                       replace();\r
+\r
                                break;\r
                }\r
 \r
@@ -102,12 +111,12 @@ var SearchReplaceDialog = {
                                r.scrollIntoView();\r
                                r.select();\r
                        } else\r
-                               wm.alert(ed.getLang('searchreplace_dlg.notfound'));\r
+                               tinyMCEPopup.alert(ed.getLang('searchreplace_dlg.notfound'));\r
 \r
                        tinyMCEPopup.storeSelection();\r
                } else {\r
                        if (!w.find(s, ca, b, false, false, false, false))\r
-                               wm.alert(ed.getLang('searchreplace_dlg.notfound'));\r
+                               tinyMCEPopup.alert(ed.getLang('searchreplace_dlg.notfound'));\r
                        else\r
                                fix();\r
                }\r
index 9c95a6a30b90098948b216e8f601d0586cf38b48..0b42486b6fc9045244c411de2a9868007c18f2bf 100644 (file)
@@ -7,7 +7,6 @@
        <script type="text/javascript" src="../../utils/form_utils.js"></script>\r
        <script type="text/javascript" src="js/searchreplace.js"></script>\r
        <link rel="stylesheet" type="text/css" href="css/searchreplace.css" />\r
-       <base target="_self" />\r
 </head>\r
 <body style="display:none;">\r
 <form onsubmit="SearchReplaceDialog.searchNext('none');return false;" action="#">\r
index 60264db8e4685427feac135bda95422975c7b8c0..1fabc8dc211e19c2a6243498894f69d382112498 100644 (file)
@@ -8,7 +8,6 @@
        <script type="text/javascript" src="../../utils/editable_selects.js"></script>\r
        <script type="text/javascript" src="js/cell.js"></script>\r
        <link href="css/cell.css" rel="stylesheet" type="text/css" />\r
-       <base target="_self" />\r
 </head>\r
 <body id="tablecell" style="display: none">\r
        <form onsubmit="updateAction();return false;" action="#">\r
index 085882a5b4c9c051c1fb38266edc4969e51b277f..95d599e90b2c8f3215769d7854028ce4a6347d36 100644 (file)
@@ -1 +1 @@
-(function(){var each=tinymce.each;tinymce.create('tinymce.plugins.TablePlugin',{init:function(ed,url){var t=this;t.editor=ed;t.url=url;each([['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(c){ed.addButton(c[0],{title:c[1],cmd:c[2],ui:c[3]});});ed.onInit.add(function(){if(ed&&ed.plugins.contextmenu){ed.plugins.contextmenu.onContextMenu.add(function(th,m,e){var sm,se=ed.selection,el=se.getNode()||ed.getBody();if(ed.dom.getParent(e,'td')||ed.dom.getParent(e,'th')){m.removeAll();if(el.nodeName=='A'&&!ed.dom.getAttrib(el,'name')){m.add({title:'advanced.link_desc',icon:'link',cmd:ed.plugins.advlink?'mceAdvLink':'mceLink',ui:true});m.add({title:'advanced.unlink_desc',icon:'unlink',cmd:'UnLink'});m.addSeparator();}if(el.nodeName=='IMG'&&el.className.indexOf('mceItem')==-1){m.add({title:'advanced.image_desc',icon:'image',cmd:ed.plugins.advimage?'mceAdvImage':'mceImage',ui:true});m.addSeparator();}m.add({title:'table.desc',icon:'table',cmd:'mceInsertTable',ui:true,value:{action:'insert'}});m.add({title:'table.props_desc',icon:'table_props',cmd:'mceInsertTable',ui:true});m.add({title:'table.del',icon:'delete_table',cmd:'mceTableDelete',ui:true});m.addSeparator();sm=m.addMenu({title:'table.cell'});sm.add({title:'table.cell_desc',icon:'cell_props',cmd:'mceTableCellProps',ui:true});sm.add({title:'table.split_cells_desc',icon:'split_cells',cmd:'mceTableSplitCells',ui:true});sm.add({title:'table.merge_cells_desc',icon:'merge_cells',cmd:'mceTableMergeCells',ui:true});sm=m.addMenu({title:'table.row'});sm.add({title:'table.row_desc',icon:'row_props',cmd:'mceTableRowProps',ui:true});sm.add({title:'table.row_before_desc',icon:'row_before',cmd:'mceTableInsertRowBefore'});sm.add({title:'table.row_after_desc',icon:'row_after',cmd:'mceTableInsertRowAfter'});sm.add({title:'table.delete_row_desc',icon:'delete_row',cmd:'mceTableDeleteRow'});sm.addSeparator();sm.add({title:'table.cut_row_desc',icon:'cut',cmd:'mceTableCutRow'});sm.add({title:'table.copy_row_desc',icon:'copy',cmd:'mceTableCopyRow'});sm.add({title:'table.paste_row_before_desc',icon:'paste',cmd:'mceTablePasteRowBefore'});sm.add({title:'table.paste_row_after_desc',icon:'paste',cmd:'mceTablePasteRowAfter'});sm=m.addMenu({title:'table.col'});sm.add({title:'table.col_before_desc',icon:'col_before',cmd:'mceTableInsertColBefore'});sm.add({title:'table.col_after_desc',icon:'col_after',cmd:'mceTableInsertColAfter'});sm.add({title:'table.delete_col_desc',icon:'delete_col',cmd:'mceTableDeleteCol'});}else m.add({title:'table.desc',icon:'table',cmd:'mceInsertTable',ui:true});});}});ed.onKeyDown.add(function(ed,e){if(e.keyCode==9&&ed.dom.getParent(ed.selection.getNode(),'TABLE')){if(!tinymce.isGecko&&!tinymce.isOpera){tinyMCE.execInstanceCommand(ed.editorId,"mceTableMoveToNextRow",true);return tinymce.dom.Event.cancel(e);}ed.undoManager.add();}});if(!tinymce.isIE){if(ed.getParam('table_selection',true)){ed.onClick.add(function(ed,e){e=e.target;if(e.nodeName==='TABLE')ed.selection.select(e);});}}ed.onNodeChange.add(function(ed,cm,n){var p=ed.dom.getParent(n,'td,th,caption');cm.setActive('table',n.nodeName==='TABLE'||!!p);if(p&&p.nodeName==='CAPTION')p=null;cm.setDisabled('delete_table',!p);cm.setDisabled('delete_col',!p);cm.setDisabled('delete_table',!p);cm.setDisabled('delete_row',!p);cm.setDisabled('col_after',!p);cm.setDisabled('col_before',!p);cm.setDisabled('row_after',!p);cm.setDisabled('row_before',!p);cm.setDisabled('row_props',!p);cm.setDisabled('cell_props',!p);cm.setDisabled('split_cells',!p||(parseInt(ed.dom.getAttrib(p,'colspan','1'))<2&&parseInt(ed.dom.getAttrib(p,'rowspan','1'))<2));cm.setDisabled('merge_cells',!p);});if(!tinymce.isIE){ed.onBeforeSetContent.add(function(ed,o){if(o.initial)o.content=o.content.replace(/<(td|th)([^>]+|)>\s*<\/(td|th)>/g,tinymce.isOpera?'<$1$2>&nbsp;</$1>':'<$1$2><br mce_bogus="1" /></$1>');});}},execCommand:function(cmd,ui,val){var ed=this.editor,b;switch(cmd){case"mceTableMoveToNextRow":case"mceInsertTable":case"mceTableRowProps":case"mceTableCellProps":case"mceTableSplitCells":case"mceTableMergeCells":case"mceTableInsertRowBefore":case"mceTableInsertRowAfter":case"mceTableDeleteRow":case"mceTableInsertColBefore":case"mceTableInsertColAfter":case"mceTableDeleteCol":case"mceTableCutRow":case"mceTableCopyRow":case"mceTablePasteRowBefore":case"mceTablePasteRowAfter":case"mceTableDelete":ed.execCommand('mceBeginUndoLevel');this._doExecCommand(cmd,ui,val);ed.execCommand('mceEndUndoLevel');return true;}return false;},getInfo:function(){return{longname:'Tables',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/table',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_doExecCommand:function(command,user_interface,value){var inst=this.editor,ed=inst,url=this.url;var focusElm=inst.selection.getNode();var trElm=inst.dom.getParent(focusElm,"tr");var tdElm=inst.dom.getParent(focusElm,"td,th");var tableElm=inst.dom.getParent(focusElm,"table");var doc=inst.contentWindow.document;var tableBorder=tableElm?tableElm.getAttribute("border"):"";if(trElm&&tdElm==null)tdElm=trElm.cells[0];function inArray(ar,v){for(var i=0;i<ar.length;i++){if(ar[i].length>0&&inArray(ar[i],v))return true;if(ar[i]==v)return true;}return false;}function select(dx,dy){var td;grid=getTableGrid(tableElm);dx=dx||0;dy=dy||0;dx=Math.max(cpos.cellindex+dx,0);dy=Math.max(cpos.rowindex+dy,0);inst.execCommand('mceRepaint');td=getCell(grid,dy,dx);if(td){inst.selection.select(td.firstChild||td);inst.selection.collapse(1);}};function makeTD(){var newTD=doc.createElement("td");if(!tinymce.isIE)newTD.innerHTML='<br mce_bogus="1"/>';}function getColRowSpan(td){var colspan=inst.dom.getAttrib(td,"colspan");var rowspan=inst.dom.getAttrib(td,"rowspan");colspan=colspan==""?1:parseInt(colspan);rowspan=rowspan==""?1:parseInt(rowspan);return{colspan:colspan,rowspan:rowspan};}function getCellPos(grid,td){var x,y;for(y=0;y<grid.length;y++){for(x=0;x<grid[y].length;x++){if(grid[y][x]==td)return{cellindex:x,rowindex:y};}}return null;}function getCell(grid,row,col){if(grid[row]&&grid[row][col])return grid[row][col];return null;}function getNextCell(table,cell){var cells=[],x=0,i,j,cell,nextCell;for(i=0;i<table.rows.length;i++)for(j=0;j<table.rows[i].cells.length;j++,x++)cells[x]=table.rows[i].cells[j];for(i=0;i<cells.length;i++)if(cells[i]==cell)if(nextCell=cells[i+1])return nextCell;}function getTableGrid(table){var grid=[],rows=table.rows,x,y,td,sd,xstart,x2,y2;for(y=0;y<rows.length;y++){for(x=0;x<rows[y].cells.length;x++){td=rows[y].cells[x];sd=getColRowSpan(td);for(xstart=x;grid[y]&&grid[y][xstart];xstart++);for(y2=y;y2<y+sd['rowspan'];y2++){if(!grid[y2])grid[y2]=[];for(x2=xstart;x2<xstart+sd['colspan'];x2++)grid[y2][x2]=td;}}}return grid;}function trimRow(table,tr,td,new_tr){var grid=getTableGrid(table),cpos=getCellPos(grid,td);var cells,lastElm;if(new_tr.cells.length!=tr.childNodes.length){cells=tr.childNodes;lastElm=null;for(var x=0;td=getCell(grid,cpos.rowindex,x);x++){var remove=true;var sd=getColRowSpan(td);if(inArray(cells,td)){new_tr.childNodes[x]._delete=true;}else if((lastElm==null||td!=lastElm)&&sd.colspan>1){for(var i=x;i<x+td.colSpan;i++)new_tr.childNodes[i]._delete=true;}if((lastElm==null||td!=lastElm)&&sd.rowspan>1)td.rowSpan=sd.rowspan+1;lastElm=td;}deleteMarked(tableElm);}}function prevElm(node,name){while((node=node.previousSibling)!=null){if(node.nodeName==name)return node;}return null;}function nextElm(node,names){var namesAr=names.split(',');while((node=node.nextSibling)!=null){for(var i=0;i<namesAr.length;i++){if(node.nodeName.toLowerCase()==namesAr[i].toLowerCase())return node;}}return null;}function deleteMarked(tbl){if(tbl.rows==0)return;var tr=tbl.rows[0];do{var next=nextElm(tr,"TR");if(tr._delete){tr.parentNode.removeChild(tr);continue;}var td=tr.cells[0];if(td.cells>1){do{var nexttd=nextElm(td,"TD,TH");if(td._delete)td.parentNode.removeChild(td);}while((td=nexttd)!=null);}}while((tr=next)!=null);}function addRows(td_elm,tr_elm,rowspan){td_elm.rowSpan=1;var trNext=nextElm(tr_elm,"TR");for(var i=1;i<rowspan&&trNext;i++){var newTD=doc.createElement("td");if(!tinymce.isIE)newTD.innerHTML='<br mce_bogus="1"/>';if(tinymce.isIE)trNext.insertBefore(newTD,trNext.cells(td_elm.cellIndex));else trNext.insertBefore(newTD,trNext.cells[td_elm.cellIndex]);trNext=nextElm(trNext,"TR");}}function copyRow(doc,table,tr){var grid=getTableGrid(table);var newTR=tr.cloneNode(false);var cpos=getCellPos(grid,tr.cells[0]);var lastCell=null;var tableBorder=inst.dom.getAttrib(table,"border");var tdElm=null;for(var x=0;tdElm=getCell(grid,cpos.rowindex,x);x++){var newTD=null;if(lastCell!=tdElm){for(var i=0;i<tr.cells.length;i++){if(tdElm==tr.cells[i]){newTD=tdElm.cloneNode(true);break;}}}if(newTD==null){newTD=doc.createElement("td");if(!tinymce.isIE)newTD.innerHTML='<br mce_bogus="1"/>';}newTD.colSpan=1;newTD.rowSpan=1;newTR.appendChild(newTD);lastCell=tdElm;}return newTR;}switch(command){case"mceTableMoveToNextRow":var nextCell=getNextCell(tableElm,tdElm);if(!nextCell){inst.execCommand("mceTableInsertRowAfter",tdElm);nextCell=getNextCell(tableElm,tdElm);}inst.selection.select(nextCell);inst.selection.collapse(true);return true;case"mceTableRowProps":if(trElm==null)return true;if(user_interface){inst.windowManager.open({url:url+'/row.htm',width:400+parseInt(inst.getLang('table.rowprops_delta_width',0)),height:295+parseInt(inst.getLang('table.rowprops_delta_height',0)),inline:1},{plugin_url:url});}return true;case"mceTableCellProps":if(tdElm==null)return true;if(user_interface){inst.windowManager.open({url:url+'/cell.htm',width:400+parseInt(inst.getLang('table.cellprops_delta_width',0)),height:295+parseInt(inst.getLang('table.cellprops_delta_height',0)),inline:1},{plugin_url:url});}return true;case"mceInsertTable":if(user_interface){inst.windowManager.open({url:url+'/table.htm',width:400+parseInt(inst.getLang('table.table_delta_width',0)),height:320+parseInt(inst.getLang('table.table_delta_height',0)),inline:1},{plugin_url:url,action:value?value.action:0});}return true;case"mceTableDelete":var table=inst.dom.getParent(inst.selection.getNode(),"table");if(table){table.parentNode.removeChild(table);inst.execCommand('mceRepaint');}return true;case"mceTableSplitCells":case"mceTableMergeCells":case"mceTableInsertRowBefore":case"mceTableInsertRowAfter":case"mceTableDeleteRow":case"mceTableInsertColBefore":case"mceTableInsertColAfter":case"mceTableDeleteCol":case"mceTableCutRow":case"mceTableCopyRow":case"mceTablePasteRowBefore":case"mceTablePasteRowAfter":if(!tableElm)return true;if(trElm&&tableElm!=trElm.parentNode)tableElm=trElm.parentNode;if(tableElm&&trElm){switch(command){case"mceTableCutRow":if(!trElm||!tdElm)return true;inst.tableRowClipboard=copyRow(doc,tableElm,trElm);inst.execCommand("mceTableDeleteRow");break;case"mceTableCopyRow":if(!trElm||!tdElm)return true;inst.tableRowClipboard=copyRow(doc,tableElm,trElm);break;case"mceTablePasteRowBefore":if(!trElm||!tdElm)return true;var newTR=inst.tableRowClipboard.cloneNode(true);var prevTR=prevElm(trElm,"TR");if(prevTR!=null)trimRow(tableElm,prevTR,prevTR.cells[0],newTR);trElm.parentNode.insertBefore(newTR,trElm);break;case"mceTablePasteRowAfter":if(!trElm||!tdElm)return true;var nextTR=nextElm(trElm,"TR");var newTR=inst.tableRowClipboard.cloneNode(true);trimRow(tableElm,trElm,tdElm,newTR);if(nextTR==null)trElm.parentNode.appendChild(newTR);else nextTR.parentNode.insertBefore(newTR,nextTR);break;case"mceTableInsertRowBefore":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var newTR=doc.createElement("tr");var lastTDElm=null;cpos.rowindex--;if(cpos.rowindex<0)cpos.rowindex=0;for(var x=0;tdElm=getCell(grid,cpos.rowindex,x);x++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['rowspan']==1){var newTD=doc.createElement("td");if(!tinymce.isIE)newTD.innerHTML='<br mce_bogus="1"/>';newTD.colSpan=tdElm.colSpan;newTR.appendChild(newTD);}else tdElm.rowSpan=sd['rowspan']+1;lastTDElm=tdElm;}}trElm.parentNode.insertBefore(newTR,trElm);select(0,1);break;case"mceTableInsertRowAfter":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var newTR=doc.createElement("tr");var lastTDElm=null;for(var x=0;tdElm=getCell(grid,cpos.rowindex,x);x++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['rowspan']==1){var newTD=doc.createElement("td");if(!tinymce.isIE)newTD.innerHTML='<br mce_bogus="1"/>';newTD.colSpan=tdElm.colSpan;newTR.appendChild(newTD);}else tdElm.rowSpan=sd['rowspan']+1;lastTDElm=tdElm;}}if(newTR.hasChildNodes()){var nextTR=nextElm(trElm,"TR");if(nextTR)nextTR.parentNode.insertBefore(newTR,nextTR);else tableElm.appendChild(newTR);}select(0,1);break;case"mceTableDeleteRow":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);if(grid.length==1&&tableElm.nodeName=='TBODY'){inst.dom.remove(inst.dom.getParent(tableElm,"table"));return true;}var cells=trElm.cells;var nextTR=nextElm(trElm,"TR");for(var x=0;x<cells.length;x++){if(cells[x].rowSpan>1){var newTD=cells[x].cloneNode(true);var sd=getColRowSpan(cells[x]);newTD.rowSpan=sd.rowspan-1;var nextTD=nextTR.cells[x];if(nextTD==null)nextTR.appendChild(newTD);else nextTR.insertBefore(newTD,nextTD);}}var lastTDElm=null;for(var x=0;tdElm=getCell(grid,cpos.rowindex,x);x++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd.rowspan>1){tdElm.rowSpan=sd.rowspan-1;}else{trElm=tdElm.parentNode;if(trElm.parentNode)trElm._delete=true;}lastTDElm=tdElm;}}deleteMarked(tableElm);select(0,-1);break;case"mceTableInsertColBefore":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var lastTDElm=null;for(var y=0;tdElm=getCell(grid,y,cpos.cellindex);y++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['colspan']==1){var newTD=doc.createElement(tdElm.nodeName);if(!tinymce.isIE)newTD.innerHTML='<br mce_bogus="1"/>';newTD.rowSpan=tdElm.rowSpan;tdElm.parentNode.insertBefore(newTD,tdElm);}else tdElm.colSpan++;lastTDElm=tdElm;}}select();break;case"mceTableInsertColAfter":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var lastTDElm=null;for(var y=0;tdElm=getCell(grid,y,cpos.cellindex);y++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['colspan']==1){var newTD=doc.createElement(tdElm.nodeName);if(!tinymce.isIE)newTD.innerHTML='<br mce_bogus="1"/>';newTD.rowSpan=tdElm.rowSpan;var nextTD=nextElm(tdElm,"TD,TH");if(nextTD==null)tdElm.parentNode.appendChild(newTD);else nextTD.parentNode.insertBefore(newTD,nextTD);}else tdElm.colSpan++;lastTDElm=tdElm;}}select(1);break;case"mceTableDeleteCol":if(!trElm||!tdElm)return true;var grid=getTableGrid(tableElm);var cpos=getCellPos(grid,tdElm);var lastTDElm=null;if((grid.length>1&&grid[0].length<=1)&&tableElm.nodeName=='TBODY'){inst.dom.remove(inst.dom.getParent(tableElm,"table"));return true;}for(var y=0;tdElm=getCell(grid,y,cpos.cellindex);y++){if(tdElm!=lastTDElm){var sd=getColRowSpan(tdElm);if(sd['colspan']>1)tdElm.colSpan=sd['colspan']-1;else{if(tdElm.parentNode)tdElm.parentNode.removeChild(tdElm);}lastTDElm=tdElm;}}select(-1);break;case"mceTableSplitCells":if(!trElm||!tdElm)return true;var spandata=getColRowSpan(tdElm);var colspan=spandata["colspan"];var rowspan=spandata["rowspan"];if(colspan>1||rowspan>1){tdElm.colSpan=1;for(var i=1;i<colspan;i++){var newTD=doc.createElement("td");if(!tinymce.isIE)newTD.innerHTML='<br mce_bogus="1"/>';trElm.insertBefore(newTD,nextElm(tdElm,"TD,TH"));if(rowspan>1)addRows(newTD,trElm,rowspan);}addRows(tdElm,trElm,rowspan);}tableElm=inst.dom.getParent(inst.selection.getNode(),"table");break;case"mceTableMergeCells":var rows=[];var sel=inst.selection.getSel();var grid=getTableGrid(tableElm);if(tinymce.isIE||sel.rangeCount==1){if(user_interface){var sp=getColRowSpan(tdElm);inst.windowManager.open({url:url+'/merge_cells.htm',width:240+parseInt(inst.getLang('table.merge_cells_delta_width',0)),height:110+parseInt(inst.getLang('table.merge_cells_delta_height',0)),inline:1},{action:"update",numcols:sp.colspan,numrows:sp.rowspan,plugin_url:url});return true;}else{var numRows=parseInt(value['numrows']);var numCols=parseInt(value['numcols']);var cpos=getCellPos(grid,tdElm);if((""+numRows)=="NaN")numRows=1;if((""+numCols)=="NaN")numCols=1;var tRows=tableElm.rows;for(var y=cpos.rowindex;y<grid.length;y++){var rowCells=[];for(var x=cpos.cellindex;x<grid[y].length;x++){var td=getCell(grid,y,x);if(td&&!inArray(rows,td)&&!inArray(rowCells,td)){var cp=getCellPos(grid,td);if(cp.cellindex<cpos.cellindex+numCols&&cp.rowindex<cpos.rowindex+numRows)rowCells[rowCells.length]=td;}}if(rowCells.length>0)rows[rows.length]=rowCells;var td=getCell(grid,cpos.rowindex,cpos.cellindex);each(ed.dom.select('br',td),function(e,i){if(i>0&&ed.dom.getAttrib('mce_bogus'))ed.dom.remove(e);});}}}else{var cells=[];var sel=inst.selection.getSel();var lastTR=null;var curRow=null;var x1=-1,y1=-1,x2,y2;if(sel.rangeCount<2)return true;for(var i=0;i<sel.rangeCount;i++){var rng=sel.getRangeAt(i);var tdElm=rng.startContainer.childNodes[rng.startOffset];if(!tdElm)break;if(tdElm.nodeName=="TD"||tdElm.nodeName=="TH")cells[cells.length]=tdElm;}var tRows=tableElm.rows;for(var y=0;y<tRows.length;y++){var rowCells=[];for(var x=0;x<tRows[y].cells.length;x++){var td=tRows[y].cells[x];for(var i=0;i<cells.length;i++){if(td==cells[i]){rowCells[rowCells.length]=td;}}}if(rowCells.length>0)rows[rows.length]=rowCells;}var curRow=[];var lastTR=null;for(var y=0;y<grid.length;y++){for(var x=0;x<grid[y].length;x++){grid[y][x]._selected=false;for(var i=0;i<cells.length;i++){if(grid[y][x]==cells[i]){if(x1==-1){x1=x;y1=y;}x2=x;y2=y;grid[y][x]._selected=true;}}}}for(var y=y1;y<=y2;y++){for(var x=x1;x<=x2;x++){if(!grid[y][x]._selected){alert("Invalid selection for merge.");return true;}}}}var rowSpan=1,colSpan=1;var lastRowSpan=-1;for(var y=0;y<rows.length;y++){var rowColSpan=0;for(var x=0;x<rows[y].length;x++){var sd=getColRowSpan(rows[y][x]);rowColSpan+=sd['colspan'];if(lastRowSpan!=-1&&sd['rowspan']!=lastRowSpan){alert("Invalid selection for merge.");return true;}lastRowSpan=sd['rowspan'];}if(rowColSpan>colSpan)colSpan=rowColSpan;lastRowSpan=-1;}var lastColSpan=-1;for(var x=0;x<rows[0].length;x++){var colRowSpan=0;for(var y=0;y<rows.length;y++){var sd=getColRowSpan(rows[y][x]);colRowSpan+=sd['rowspan'];if(lastColSpan!=-1&&sd['colspan']!=lastColSpan){alert("Invalid selection for merge.");return true;}lastColSpan=sd['colspan'];}if(colRowSpan>rowSpan)rowSpan=colRowSpan;lastColSpan=-1;}tdElm=rows[0][0];tdElm.rowSpan=rowSpan;tdElm.colSpan=colSpan;for(var y=0;y<rows.length;y++){for(var x=0;x<rows[y].length;x++){var html=rows[y][x].innerHTML;var chk=html.replace(/[ \t\r\n]/g,"");if(chk!="<br/>"&&chk!="<br>"&&chk!='<br mce_bogus="1"/>'&&(x+y>0))tdElm.innerHTML+=html;if(rows[y][x]!=tdElm&&!rows[y][x]._deleted){var cpos=getCellPos(grid,rows[y][x]);var tr=rows[y][x].parentNode;tr.removeChild(rows[y][x]);rows[y][x]._deleted=true;if(!tr.hasChildNodes()){tr.parentNode.removeChild(tr);var lastCell=null;for(var x=0;cellElm=getCell(grid,cpos.rowindex,x);x++){if(cellElm!=lastCell&&cellElm.rowSpan>1)cellElm.rowSpan--;lastCell=cellElm;}if(tdElm.rowSpan>1)tdElm.rowSpan--;}}}}each(ed.dom.select('br',tdElm),function(e,i){if(i>0&&ed.dom.getAttrib(e,'mce_bogus'))ed.dom.remove(e);});break;}tableElm=inst.dom.getParent(inst.selection.getNode(),"table");inst.addVisual(tableElm);inst.nodeChanged();}return true;}return false;}});tinymce.PluginManager.add('table',tinymce.plugins.TablePlugin);})();
\ No newline at end of file
+(function(){var a=tinymce.each;tinymce.create("tinymce.plugins.TablePlugin",{init:function(b,c){var d=this;d.editor=b;d.url=c;a([["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(e){b.addButton(e[0],{title:e[1],cmd:e[2],ui:e[3]})});if(b.getParam("inline_styles")){b.onPreProcess.add(function(e,g){var f=e.dom;a(f.select("table",g.node),function(i){var h;if(h=f.getAttrib(i,"width")){f.setStyle(i,"width",h);f.setAttrib(i,"width")}if(h=f.getAttrib(i,"height")){f.setStyle(i,"height",h);f.setAttrib(i,"height")}})})}b.onInit.add(function(){if(b&&b.plugins.contextmenu){b.plugins.contextmenu.onContextMenu.add(function(h,f,j){var k,i=b.selection,g=i.getNode()||b.getBody();if(b.dom.getParent(j,"td")||b.dom.getParent(j,"th")){f.removeAll();if(g.nodeName=="A"&&!b.dom.getAttrib(g,"name")){f.add({title:"advanced.link_desc",icon:"link",cmd:b.plugins.advlink?"mceAdvLink":"mceLink",ui:true});f.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"});f.addSeparator()}if(g.nodeName=="IMG"&&g.className.indexOf("mceItem")==-1){f.add({title:"advanced.image_desc",icon:"image",cmd:b.plugins.advimage?"mceAdvImage":"mceImage",ui:true});f.addSeparator()}f.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",ui:true,value:{action:"insert"}});f.add({title:"table.props_desc",icon:"table_props",cmd:"mceInsertTable",ui:true});f.add({title:"table.del",icon:"delete_table",cmd:"mceTableDelete",ui:true});f.addSeparator();k=f.addMenu({title:"table.cell"});k.add({title:"table.cell_desc",icon:"cell_props",cmd:"mceTableCellProps",ui:true});k.add({title:"table.split_cells_desc",icon:"split_cells",cmd:"mceTableSplitCells",ui:true});k.add({title:"table.merge_cells_desc",icon:"merge_cells",cmd:"mceTableMergeCells",ui:true});k=f.addMenu({title:"table.row"});k.add({title:"table.row_desc",icon:"row_props",cmd:"mceTableRowProps",ui:true});k.add({title:"table.row_before_desc",icon:"row_before",cmd:"mceTableInsertRowBefore"});k.add({title:"table.row_after_desc",icon:"row_after",cmd:"mceTableInsertRowAfter"});k.add({title:"table.delete_row_desc",icon:"delete_row",cmd:"mceTableDeleteRow"});k.addSeparator();k.add({title:"table.cut_row_desc",icon:"cut",cmd:"mceTableCutRow"});k.add({title:"table.copy_row_desc",icon:"copy",cmd:"mceTableCopyRow"});k.add({title:"table.paste_row_before_desc",icon:"paste",cmd:"mceTablePasteRowBefore"});k.add({title:"table.paste_row_after_desc",icon:"paste",cmd:"mceTablePasteRowAfter"});k=f.addMenu({title:"table.col"});k.add({title:"table.col_before_desc",icon:"col_before",cmd:"mceTableInsertColBefore"});k.add({title:"table.col_after_desc",icon:"col_after",cmd:"mceTableInsertColAfter"});k.add({title:"table.delete_col_desc",icon:"delete_col",cmd:"mceTableDeleteCol"})}else{f.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",ui:true})}})}});b.onKeyDown.add(function(f,g){if(g.keyCode==9&&f.dom.getParent(f.selection.getNode(),"TABLE")){if(!tinymce.isGecko&&!tinymce.isOpera){tinyMCE.execInstanceCommand(f.editorId,"mceTableMoveToNextRow",true);return tinymce.dom.Event.cancel(g)}f.undoManager.add()}});if(!tinymce.isIE){if(b.getParam("table_selection",true)){b.onClick.add(function(f,g){g=g.target;if(g.nodeName==="TABLE"){f.selection.select(g)}})}}b.onNodeChange.add(function(f,e,h){var g=f.dom.getParent(h,"td,th,caption");e.setActive("table",h.nodeName==="TABLE"||!!g);if(g&&g.nodeName==="CAPTION"){g=null}e.setDisabled("delete_table",!g);e.setDisabled("delete_col",!g);e.setDisabled("delete_table",!g);e.setDisabled("delete_row",!g);e.setDisabled("col_after",!g);e.setDisabled("col_before",!g);e.setDisabled("row_after",!g);e.setDisabled("row_before",!g);e.setDisabled("row_props",!g);e.setDisabled("cell_props",!g);e.setDisabled("split_cells",!g||(parseInt(f.dom.getAttrib(g,"colspan","1"))<2&&parseInt(f.dom.getAttrib(g,"rowspan","1"))<2));e.setDisabled("merge_cells",!g)});if(!tinymce.isIE){b.onBeforeSetContent.add(function(e,f){if(f.initial){f.content=f.content.replace(/<(td|th)([^>]+|)>\s*<\/(td|th)>/g,tinymce.isOpera?"<$1$2>&nbsp;</$1>":'<$1$2><br mce_bogus="1" /></$1>')}})}},execCommand:function(f,e,g){var d=this.editor,c;switch(f){case"mceTableMoveToNextRow":case"mceInsertTable":case"mceTableRowProps":case"mceTableCellProps":case"mceTableSplitCells":case"mceTableMergeCells":case"mceTableInsertRowBefore":case"mceTableInsertRowAfter":case"mceTableDeleteRow":case"mceTableInsertColBefore":case"mceTableInsertColAfter":case"mceTableDeleteCol":case"mceTableCutRow":case"mceTableCopyRow":case"mceTablePasteRowBefore":case"mceTablePasteRowAfter":case"mceTableDelete":d.execCommand("mceBeginUndoLevel");this._doExecCommand(f,e,g);d.execCommand("mceEndUndoLevel");return true}return false},getInfo:function(){return{longname:"Tables",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/table",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_doExecCommand:function(r,Z,ae){var V=this.editor,au=V,g=this.url;var n=V.selection.getNode();var W=V.dom.getParent(n,"tr");var aq=V.dom.getParent(n,"td,th");var F=V.dom.getParent(n,"table");var k=V.contentWindow.document;var av=F?F.getAttribute("border"):"";if(W&&aq==null){aq=W.cells[0]}function ap(y,x){for(var ax=0;ax<y.length;ax++){if(y[ax].length>0&&ap(y[ax],x)){return true}if(y[ax]==x){return true}}return false}function aj(x,i){var y;ad=e(F);x=x||0;i=i||0;x=Math.max(o.cellindex+x,0);i=Math.max(o.rowindex+i,0);V.execCommand("mceRepaint");y=d(ad,i,x);if(y){V.selection.select(y.firstChild||y);V.selection.collapse(1)}}function ah(){var i=k.createElement("td");if(!tinymce.isIE){i.innerHTML='<br mce_bogus="1"/>'}}function j(y){var x=V.dom.getAttrib(y,"colspan");var i=V.dom.getAttrib(y,"rowspan");x=x==""?1:parseInt(x);i=i==""?1:parseInt(i);return{colspan:x,rowspan:i}}function al(ax,az){var i,ay;for(ay=0;ay<ax.length;ay++){for(i=0;i<ax[ay].length;i++){if(ax[ay][i]==az){return{cellindex:i,rowindex:ay}}}}return null}function d(x,y,i){if(x[y]&&x[y][i]){return x[y][i]}return null}function A(aC,ax){var az=[],y=0,aA,ay,ax,aB;for(aA=0;aA<aC.rows.length;aA++){for(ay=0;ay<aC.rows[aA].cells.length;ay++,y++){az[y]=aC.rows[aA].cells[ay]}}for(aA=0;aA<az.length;aA++){if(az[aA]==ax){if(aB=az[aA+1]){return aB}}}}function e(aE){var i=[],aF=aE.rows,aC,aB,ay,az,aD,ax,aA;for(aB=0;aB<aF.length;aB++){for(aC=0;aC<aF[aB].cells.length;aC++){ay=aF[aB].cells[aC];az=j(ay);for(aD=aC;i[aB]&&i[aB][aD];aD++){}for(aA=aB;aA<aB+az.rowspan;aA++){if(!i[aA]){i[aA]=[]}for(ax=aD;ax<aD+az.colspan;ax++){i[aA][ax]=ay}}}}return i}function m(aG,aD,ay,ax){var y=e(aG),aF=al(y,ay);var aH,aC;if(ax.cells.length!=aD.childNodes.length){aH=aD.childNodes;aC=null;for(var aE=0;ay=d(y,aF.rowindex,aE);aE++){var aA=true;var aB=j(ay);if(ap(aH,ay)){ax.childNodes[aE]._delete=true}else{if((aC==null||ay!=aC)&&aB.colspan>1){for(var az=aE;az<aE+ay.colSpan;az++){ax.childNodes[az]._delete=true}}}if((aC==null||ay!=aC)&&aB.rowspan>1){ay.rowSpan=aB.rowspan+1}aC=ay}B(F)}}function O(x,i){while((x=x.previousSibling)!=null){if(x.nodeName==i){return x}}return null}function af(ax,ay){var x=ay.split(",");while((ax=ax.nextSibling)!=null){for(var y=0;y<x.length;y++){if(ax.nodeName.toLowerCase()==x[y].toLowerCase()){return ax}}}return null}function B(ax){if(ax.rows==0){return}var y=ax.rows[0];do{var x=af(y,"TR");if(y._delete){y.parentNode.removeChild(y);continue}var ay=y.cells[0];if(ay.cells>1){do{var i=af(ay,"TD,TH");if(ay._delete){ay.parentNode.removeChild(ay)}}while((ay=i)!=null)}}while((y=x)!=null)}function p(ax,aA,az){ax.rowSpan=1;var x=af(aA,"TR");for(var ay=1;ay<az&&x;ay++){var y=k.createElement("td");if(!tinymce.isIE){y.innerHTML='<br mce_bogus="1"/>'}if(tinymce.isIE){x.insertBefore(y,x.cells(ax.cellIndex))}else{x.insertBefore(y,x.cells[ax.cellIndex])}x=af(x,"TR")}}function S(aF,aH,aB){var y=e(aH);var ax=aB.cloneNode(false);var aG=al(y,aB.cells[0]);var aC=null;var aA=V.dom.getAttrib(aH,"border");var az=null;for(var aE=0;az=d(y,aG.rowindex,aE);aE++){var aD=null;if(aC!=az){for(var ay=0;ay<aB.cells.length;ay++){if(az==aB.cells[ay]){aD=az.cloneNode(true);break}}}if(aD==null){aD=aF.createElement("td");if(!tinymce.isIE){aD.innerHTML='<br mce_bogus="1"/>'}}aD.colSpan=1;aD.rowSpan=1;ax.appendChild(aD);aC=az}return ax}switch(r){case"mceTableMoveToNextRow":var L=A(F,aq);if(!L){V.execCommand("mceTableInsertRowAfter",aq);L=A(F,aq)}V.selection.select(L);V.selection.collapse(true);return true;case"mceTableRowProps":if(W==null){return true}if(Z){V.windowManager.open({url:g+"/row.htm",width:400+parseInt(V.getLang("table.rowprops_delta_width",0)),height:295+parseInt(V.getLang("table.rowprops_delta_height",0)),inline:1},{plugin_url:g})}return true;case"mceTableCellProps":if(aq==null){return true}if(Z){V.windowManager.open({url:g+"/cell.htm",width:400+parseInt(V.getLang("table.cellprops_delta_width",0)),height:295+parseInt(V.getLang("table.cellprops_delta_height",0)),inline:1},{plugin_url:g})}return true;case"mceInsertTable":if(Z){V.windowManager.open({url:g+"/table.htm",width:400+parseInt(V.getLang("table.table_delta_width",0)),height:320+parseInt(V.getLang("table.table_delta_height",0)),inline:1},{plugin_url:g,action:ae?ae.action:0})}return true;case"mceTableDelete":var G=V.dom.getParent(V.selection.getNode(),"table");if(G){G.parentNode.removeChild(G);V.execCommand("mceRepaint")}return true;case"mceTableSplitCells":case"mceTableMergeCells":case"mceTableInsertRowBefore":case"mceTableInsertRowAfter":case"mceTableDeleteRow":case"mceTableInsertColBefore":case"mceTableInsertColAfter":case"mceTableDeleteCol":case"mceTableCutRow":case"mceTableCopyRow":case"mceTablePasteRowBefore":case"mceTablePasteRowAfter":if(!F){return true}if(W&&F!=W.parentNode){F=W.parentNode}if(F&&W){switch(r){case"mceTableCutRow":if(!W||!aq){return true}V.tableRowClipboard=S(k,F,W);V.execCommand("mceTableDeleteRow");break;case"mceTableCopyRow":if(!W||!aq){return true}V.tableRowClipboard=S(k,F,W);break;case"mceTablePasteRowBefore":if(!W||!aq){return true}var v=V.tableRowClipboard.cloneNode(true);var h=O(W,"TR");if(h!=null){m(F,h,h.cells[0],v)}W.parentNode.insertBefore(v,W);break;case"mceTablePasteRowAfter":if(!W||!aq){return true}var X=af(W,"TR");var v=V.tableRowClipboard.cloneNode(true);m(F,W,aq,v);if(X==null){W.parentNode.appendChild(v)}else{X.parentNode.insertBefore(v,X)}break;case"mceTableInsertRowBefore":if(!W||!aq){return true}var ad=e(F);var o=al(ad,aq);var v=k.createElement("tr");var u=null;o.rowindex--;if(o.rowindex<0){o.rowindex=0}for(var ac=0;aq=d(ad,o.rowindex,ac);ac++){if(aq!=u){var E=j(aq);if(E.rowspan==1){var J=k.createElement("td");if(!tinymce.isIE){J.innerHTML='<br mce_bogus="1"/>'}J.colSpan=aq.colSpan;v.appendChild(J)}else{aq.rowSpan=E.rowspan+1}u=aq}}W.parentNode.insertBefore(v,W);aj(0,1);break;case"mceTableInsertRowAfter":if(!W||!aq){return true}var ad=e(F);var o=al(ad,aq);var v=k.createElement("tr");var u=null;for(var ac=0;aq=d(ad,o.rowindex,ac);ac++){if(aq!=u){var E=j(aq);if(E.rowspan==1){var J=k.createElement("td");if(!tinymce.isIE){J.innerHTML='<br mce_bogus="1"/>'}J.colSpan=aq.colSpan;v.appendChild(J)}else{aq.rowSpan=E.rowspan+1}u=aq}}if(v.hasChildNodes()){var X=af(W,"TR");if(X){X.parentNode.insertBefore(v,X)}else{F.appendChild(v)}}aj(0,1);break;case"mceTableDeleteRow":if(!W||!aq){return true}var ad=e(F);var o=al(ad,aq);if(ad.length==1&&F.nodeName=="TBODY"){V.dom.remove(V.dom.getParent(F,"table"));return true}var D=W.cells;var X=af(W,"TR");for(var ac=0;ac<D.length;ac++){if(D[ac].rowSpan>1){var J=D[ac].cloneNode(true);var E=j(D[ac]);J.rowSpan=E.rowspan-1;var ak=X.cells[ac];if(ak==null){X.appendChild(J)}else{X.insertBefore(J,ak)}}}var u=null;for(var ac=0;aq=d(ad,o.rowindex,ac);ac++){if(aq!=u){var E=j(aq);if(E.rowspan>1){aq.rowSpan=E.rowspan-1}else{W=aq.parentNode;if(W.parentNode){W._delete=true}}u=aq}}B(F);aj(0,-1);break;case"mceTableInsertColBefore":if(!W||!aq){return true}var ad=e(V.dom.getParent(F,"table"));var o=al(ad,aq);var u=null;for(var aa=0;aq=d(ad,aa,o.cellindex);aa++){if(aq!=u){var E=j(aq);if(E.colspan==1){var J=k.createElement(aq.nodeName);if(!tinymce.isIE){J.innerHTML='<br mce_bogus="1"/>'}J.rowSpan=aq.rowSpan;aq.parentNode.insertBefore(J,aq)}else{aq.colSpan++}u=aq}}aj();break;case"mceTableInsertColAfter":if(!W||!aq){return true}var ad=e(V.dom.getParent(F,"table"));var o=al(ad,aq);var u=null;for(var aa=0;aq=d(ad,aa,o.cellindex);aa++){if(aq!=u){var E=j(aq);if(E.colspan==1){var J=k.createElement(aq.nodeName);if(!tinymce.isIE){J.innerHTML='<br mce_bogus="1"/>'}J.rowSpan=aq.rowSpan;var ak=af(aq,"TD,TH");if(ak==null){aq.parentNode.appendChild(J)}else{ak.parentNode.insertBefore(J,ak)}}else{aq.colSpan++}u=aq}}aj(1);break;case"mceTableDeleteCol":if(!W||!aq){return true}var ad=e(F);var o=al(ad,aq);var u=null;if((ad.length>1&&ad[0].length<=1)&&F.nodeName=="TBODY"){V.dom.remove(V.dom.getParent(F,"table"));return true}for(var aa=0;aq=d(ad,aa,o.cellindex);aa++){if(aq!=u){var E=j(aq);if(E.colspan>1){aq.colSpan=E.colspan-1}else{if(aq.parentNode){aq.parentNode.removeChild(aq)}}u=aq}}aj(-1);break;case"mceTableSplitCells":if(!W||!aq){return true}var l=j(aq);var C=l.colspan;var H=l.rowspan;if(C>1||H>1){aq.colSpan=1;for(var am=1;am<C;am++){var J=k.createElement("td");if(!tinymce.isIE){J.innerHTML='<br mce_bogus="1"/>'}W.insertBefore(J,af(aq,"TD,TH"));if(H>1){p(J,W,H)}}p(aq,W,H)}F=V.dom.getParent(V.selection.getNode(),"table");break;case"mceTableMergeCells":var ao=[];var R=V.selection.getSel();var ad=e(F);if(tinymce.isIE||R.rangeCount==1){if(Z){var t=j(aq);V.windowManager.open({url:g+"/merge_cells.htm",width:240+parseInt(V.getLang("table.merge_cells_delta_width",0)),height:110+parseInt(V.getLang("table.merge_cells_delta_height",0)),inline:1},{action:"update",numcols:t.colspan,numrows:t.rowspan,plugin_url:g});return true}else{var U=parseInt(ae.numrows);var c=parseInt(ae.numcols);var o=al(ad,aq);if((""+U)=="NaN"){U=1}if((""+c)=="NaN"){c=1}var b=F.rows;for(var aa=o.rowindex;aa<ad.length;aa++){var ag=[];for(var ac=o.cellindex;ac<ad[aa].length;ac++){var f=d(ad,aa,ac);if(f&&!ap(ao,f)&&!ap(ag,f)){var N=al(ad,f);if(N.cellindex<o.cellindex+c&&N.rowindex<o.rowindex+U){ag[ag.length]=f}}}if(ag.length>0){ao[ao.length]=ag}var f=d(ad,o.rowindex,o.cellindex);a(au.dom.select("br",f),function(y,x){if(x>0&&au.dom.getAttrib("mce_bogus")){au.dom.remove(y)}})}}}else{var D=[];var R=V.selection.getSel();var Y=null;var an=null;var z=-1,aw=-1,w,at;if(R.rangeCount<2){return true}for(var am=0;am<R.rangeCount;am++){var ai=R.getRangeAt(am);var aq=ai.startContainer.childNodes[ai.startOffset];if(!aq){break}if(aq.nodeName=="TD"||aq.nodeName=="TH"){D[D.length]=aq}}var b=F.rows;for(var aa=0;aa<b.length;aa++){var ag=[];for(var ac=0;ac<b[aa].cells.length;ac++){var f=b[aa].cells[ac];for(var am=0;am<D.length;am++){if(f==D[am]){ag[ag.length]=f}}}if(ag.length>0){ao[ao.length]=ag}}var an=[];var Y=null;for(var aa=0;aa<ad.length;aa++){for(var ac=0;ac<ad[aa].length;ac++){ad[aa][ac]._selected=false;for(var am=0;am<D.length;am++){if(ad[aa][ac]==D[am]){if(z==-1){z=ac;aw=aa}w=ac;at=aa;ad[aa][ac]._selected=true}}}}for(var aa=aw;aa<=at;aa++){for(var ac=z;ac<=w;ac++){if(!ad[aa][ac]._selected){alert("Invalid selection for merge.");return true}}}}var s=1,q=1;var T=-1;for(var aa=0;aa<ao.length;aa++){var I=0;for(var ac=0;ac<ao[aa].length;ac++){var E=j(ao[aa][ac]);I+=E.colspan;if(T!=-1&&E.rowspan!=T){alert("Invalid selection for merge.");return true}T=E.rowspan}if(I>q){q=I}T=-1}var Q=-1;for(var ac=0;ac<ao[0].length;ac++){var M=0;for(var aa=0;aa<ao.length;aa++){var E=j(ao[aa][ac]);M+=E.rowspan;if(Q!=-1&&E.colspan!=Q){alert("Invalid selection for merge.");return true}Q=E.colspan}if(M>s){s=M}Q=-1}aq=ao[0][0];aq.rowSpan=s;aq.colSpan=q;for(var aa=0;aa<ao.length;aa++){for(var ac=0;ac<ao[aa].length;ac++){var P=ao[aa][ac].innerHTML;var K=P.replace(/[ \t\r\n]/g,"");if(K!="<br/>"&&K!="<br>"&&K!='<br mce_bogus="1"/>'&&(ac+aa>0)){aq.innerHTML+=P}if(ao[aa][ac]!=aq&&!ao[aa][ac]._deleted){var o=al(ad,ao[aa][ac]);var ar=ao[aa][ac].parentNode;ar.removeChild(ao[aa][ac]);ao[aa][ac]._deleted=true;if(!ar.hasChildNodes()){ar.parentNode.removeChild(ar);var ab=null;for(var ac=0;cellElm=d(ad,o.rowindex,ac);ac++){if(cellElm!=ab&&cellElm.rowSpan>1){cellElm.rowSpan--}ab=cellElm}if(aq.rowSpan>1){aq.rowSpan--}}}}}a(au.dom.select("br",aq),function(y,x){if(x>0&&au.dom.getAttrib(y,"mce_bogus")){au.dom.remove(y)}});break}F=V.dom.getParent(V.selection.getNode(),"table");V.addVisual(F);V.nodeChanged()}return true}return false}});tinymce.PluginManager.add("table",tinymce.plugins.TablePlugin)})();
\ No newline at end of file
index 24635826f57169bc6c8eea21db6b2759946d0b1b..80cf748a305b86bd6bff86a75a006ed0f048286f 100644 (file)
@@ -1,5 +1,5 @@
 /**\r
- * $Id: editor_plugin_src.js 853 2008-05-27 08:05:35Z spocke $\r
+ * $Id: editor_plugin_src.js 953 2008-11-04 10:16:50Z spocke $\r
  *\r
  * @author Moxiecode\r
  * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.\r
                                ed.addButton(c[0], {title : c[1], cmd : c[2], ui : c[3]});\r
                        });\r
 \r
+                       if (ed.getParam('inline_styles')) {\r
+                               // Force move of attribs to styles in strict mode\r
+                               ed.onPreProcess.add(function(ed, o) {\r
+                                       var dom = ed.dom;\r
+\r
+                                       each(dom.select('table', o.node), function(n) {\r
+                                               var v;\r
+\r
+                                               if (v = dom.getAttrib(n, 'width')) {\r
+                                                       dom.setStyle(n, 'width', v);\r
+                                                       dom.setAttrib(n, 'width');\r
+                                               }\r
+\r
+                                               if (v = dom.getAttrib(n, 'height')) {\r
+                                                       dom.setStyle(n, 'height', v);\r
+                                                       dom.setAttrib(n, 'height');\r
+                                               }\r
+                                       });\r
+                               });\r
+                       }\r
+\r
                        ed.onInit.add(function() {\r
                                if (ed && ed.plugins.contextmenu) {\r
                                        ed.plugins.contextmenu.onContextMenu.add(function(th, m, e) {\r
                                                                if (!trElm || !tdElm)\r
                                                                        return true;\r
 \r
-                                                               var grid = getTableGrid(tableElm);\r
+                                                               var grid = getTableGrid(inst.dom.getParent(tableElm, "table"));\r
                                                                var cpos = getCellPos(grid, tdElm);\r
                                                                var lastTDElm = null;\r
 \r
                                                                if (!trElm || !tdElm)\r
                                                                        return true;\r
 \r
-                                                               var grid = getTableGrid(tableElm);\r
+                                                               var grid = getTableGrid(inst.dom.getParent(tableElm, "table"));\r
                                                                var cpos = getCellPos(grid, tdElm);\r
                                                                var lastTDElm = null;\r
 \r
index 7d7f977fa4b044cfd7f789439164e82338e14d63..f23b06751d1f2831d2a46746192259163e213a57 100644 (file)
@@ -73,14 +73,24 @@ function updateAction() {
                        var celltype = getSelectValue(formObj, 'celltype');\r
                        var scope = getSelectValue(formObj, 'scope');\r
 \r
-                       if (ed.getParam("accessibility_warnings")) {\r
+                       function doUpdate(s) {\r
+                               if (s) {\r
+                                       updateCell(tdElm);\r
+\r
+                                       ed.addVisual();\r
+                                       ed.nodeChanged();\r
+                                       inst.execCommand('mceEndUndoLevel');\r
+                                       tinyMCEPopup.close();\r
+                               }\r
+                       };\r
+\r
+                       if (ed.getParam("accessibility_warnings", 1)) {\r
                                if (celltype == "th" && scope == "")\r
-                                       var answer = confirm(ed.getLang('table_dlg.missing_scope', '', true));\r
+                                       tinyMCEPopup.confirm(ed.getLang('table_dlg.missing_scope', '', true), doUpdate);\r
                                else\r
-                                       var answer = true;\r
+                                       doUpdate(1);\r
 \r
-                               if (!answer)\r
-                                       return;\r
+                               return;\r
                        }\r
 \r
                        updateCell(tdElm);\r
index dc99a1bdd2584cb141d97bed8fca934782b92edf..31d6df0abcb2f70c55f3319912e0dc8507b79021 100644 (file)
@@ -15,7 +15,7 @@ function mergeCells() {
        tinyMCEPopup.restoreSelection();\r
 \r
        if (!AutoValidator.validate(f)) {\r
-               alert(tinyMCEPopup.getLang('invalid_data'));\r
+               tinyMCEPopup.alert(tinyMCEPopup.getLang('invalid_data'));\r
                return false;\r
        }\r
 \r
index a8e112c2ff99f4a2a3b87dffd5dcc54ca27118fb..2b6fd1f7020a896ce8717921e5d88111c367a0cb 100644 (file)
@@ -12,7 +12,7 @@ function insertTable() {
        tinyMCEPopup.restoreSelection();\r
 \r
        if (!AutoValidator.validate(formObj)) {\r
-               alert(inst.getLang('invalid_data'));\r
+               tinyMCEPopup.alert(inst.getLang('invalid_data'));\r
                return false;\r
        }\r
 \r
@@ -46,13 +46,13 @@ function insertTable() {
 \r
        // Validate table size\r
        if (colLimit && cols > colLimit) {\r
-               inst.windowManager.alert(inst.getLang('table_dlg.col_limit').replace(/\{\$cols\}/g, colLimit));\r
+               tinyMCEPopup.alert(inst.getLang('table_dlg.col_limit').replace(/\{\$cols\}/g, colLimit));\r
                return false;\r
        } else if (rowLimit && rows > rowLimit) {\r
-               inst.windowManager.alert(inst.getLang('table_dlg.row_limit').replace(/\{\$rows\}/g, rowLimit));\r
+               tinyMCEPopup.alert(inst.getLang('table_dlg.row_limit').replace(/\{\$rows\}/g, rowLimit));\r
                return false;\r
        } else if (cellLimit && cols * rows > cellLimit) {\r
-               inst.windowManager.alert(inst.getLang('table_dlg.cell_limit').replace(/\{\$cells\}/g, cellLimit));\r
+               tinyMCEPopup.alert(inst.getLang('table_dlg.cell_limit').replace(/\{\$cells\}/g, cellLimit));\r
                return false;\r
        }\r
 \r
@@ -87,7 +87,7 @@ function insertTable() {
                        elm.insertBefore(capEl, elm.firstChild);\r
                }\r
 \r
-               if (width && /(pt|em|cm)$/.test(width)) {\r
+               if (width && inst.settings.inline_styles) {\r
                        dom.setStyle(elm, 'width', width);\r
                        dom.setAttrib(elm, 'width', '');\r
                } else {\r
@@ -100,10 +100,13 @@ function insertTable() {
                dom.setAttrib(elm, 'bgColor', '');\r
                dom.setAttrib(elm, 'background', '');\r
 \r
-               if (height) {\r
+               if (height && inst.settings.inline_styles) {\r
                        dom.setStyle(elm, 'height', height);\r
                        dom.setAttrib(elm, 'height', '');\r
-               }\r
+               } else {\r
+                       dom.setAttrib(elm, 'height', height, true);\r
+                       dom.setStyle(elm, 'height', '');\r
+               }\r
 \r
                if (background != '')\r
                        elm.style.backgroundImage = "url('" + background + "')";\r
@@ -149,10 +152,14 @@ function insertTable() {
        html += makeAttrib('cellpadding', cellpadding);\r
        html += makeAttrib('cellspacing', cellspacing);\r
 \r
-       if (width && /(pt|em|cm)$/.test(width)) {\r
+       if (width && inst.settings.inline_styles) {\r
                if (style)\r
                        style += '; ';\r
 \r
+               // Force px\r
+               if (/[0-9\.]+/.test(width))\r
+                       width += 'px';\r
+\r
                style += 'width: ' + width;\r
        } else\r
                html += makeAttrib('width', width);\r
@@ -200,7 +207,30 @@ function insertTable() {
        html += "</table>";\r
 \r
        inst.execCommand('mceBeginUndoLevel');\r
-       inst.execCommand('mceInsertContent', false, html);\r
+\r
+       // Move table\r
+       if (inst.settings.fix_table_elements) {\r
+               var bm = inst.selection.getBookmark(), patt = '';\r
+\r
+               inst.execCommand('mceInsertContent', false, '<br class="_mce_marker" />');\r
+\r
+               tinymce.each('h1,h2,h3,h4,h5,h6,p'.split(','), function(n) {\r
+                       if (patt)\r
+                               patt += ',';\r
+\r
+                       patt += n + ' ._mce_marker';\r
+               });\r
+\r
+               tinymce.each(inst.dom.select(patt), function(n) {\r
+                       inst.dom.split(inst.dom.getParent(n, 'h1,h2,h3,h4,h5,h6,p'), n);\r
+               });\r
+\r
+               dom.setOuterHTML(dom.select('._mce_marker')[0], html);\r
+\r
+               inst.selection.moveToBookmark(bm);\r
+       } else\r
+               inst.execCommand('mceInsertContent', false, html);\r
+\r
        inst.addVisual();\r
        inst.execCommand('mceEndUndoLevel');\r
 \r
index 9d34a886b08449c961ff636a7ed3ede8f214f1e5..25d42eb6574b976c7a6c93e1c16b18a01fac8b22 100644 (file)
@@ -6,9 +6,8 @@
        <script type="text/javascript" src="../../utils/mctabs.js"></script>\r
        <script type="text/javascript" src="../../utils/validate.js"></script>\r
        <script type="text/javascript" src="js/merge_cells.js"></script>\r
-       <base target="_self" />\r
 </head>\r
-<body style="margin: 8px" style="display: none">\r
+<body style="margin: 8px">\r
 <form onsubmit="mergeCells();return false;" action="#">\r
        <fieldset>\r
                <legend>{#table_dlg.merge_cells_title}</legend>\r
index fe75bf607207c4b47ea5bf826b31db942207e0af..07ca13c983249a7a4b313540f46ac0b4d5974297 100644 (file)
@@ -8,10 +8,9 @@
        <script type="text/javascript" src="../../utils/editable_selects.js"></script>\r
        <script type="text/javascript" src="js/row.js"></script>\r
        <link href="css/row.css" rel="stylesheet" type="text/css" />\r
-       <base target="_self" />\r
 </head>\r
 <body id="tablerow" style="display: none">\r
-       <form onsubmit="updateAction();return false;">\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
index 75136e607ed77c3b778d5a93ae1f1ba49adcc8b5..2a138513cb58a7caff91b8f7cd59f9b80281321c 100644 (file)
@@ -9,7 +9,6 @@
        <script type="text/javascript" src="../../utils/editable_selects.js"></script>\r
        <script type="text/javascript" src="js/table.js"></script>\r
        <link href="css/table.css" rel="stylesheet" type="text/css" />\r
-       <base target="_self" />\r
 </head>\r
 <body id="table" style="display: none">\r
        <form onsubmit="insertTable();return false;" action="#">\r
@@ -58,7 +57,7 @@
                                                                <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>{#not_set}</option>\r
+                                                                       <option value="" selected="selected">{#not_set}</option>\r
                                                                 </select></td>\r
                                                          </tr>\r
                                                          <tr>\r
index e1e4238a3b5f42bcd9f9eb2fc575bcce7d4fbdd1..53d31c44faf0c13ab35f56815525e1a4c9b24b53 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create('tinymce.plugins.VisualChars',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceVisualChars',t._toggleVisualChars,t);ed.addButton('visualchars',{title:'visualchars.desc',cmd:'mceVisualChars'});ed.onBeforeGetContent.add(function(ed,o){if(t.state){t.state=true;t._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 t=this,ed=t.editor,nl,i,h,d=ed.getDoc(),b=ed.getBody(),nv,s=ed.selection,bo;t.state=!t.state;ed.controlManager.setActive('visualchars',t.state);if(t.state){nl=[];tinymce.walk(b,function(n){if(n.nodeType==3&&n.nodeValue&&n.nodeValue.indexOf('\u00a0')!=-1)nl.push(n);},'childNodes');for(i=0;i<nl.length;i++){nv=nl[i].nodeValue;nv=nv.replace(/(\u00a0+)/g,'<span class="mceItemHidden mceVisualNbsp">$1</span>');nv=nv.replace(/\u00a0/g,'\u00b7');ed.dom.setOuterHTML(nl[i],nv,d);}}else{nl=tinymce.grep(ed.dom.select('span',b),function(n){return ed.dom.hasClass(n,'mceVisualNbsp');});for(i=0;i<nl.length;i++)ed.dom.setOuterHTML(nl[i],nl[i].innerHTML.replace(/(&middot;|\u00b7)/g,'&nbsp;'),d);}}});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){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
index 580028432f64175e2852fa8f273bb1b9922071e4..3928a17e14b4c18629af550f7b4c3d42f5e85701 100644 (file)
@@ -9,7 +9,6 @@
        <script type="text/javascript" src="js/element_common.js"></script>\r
        <script type="text/javascript" src="js/abbr.js"></script>\r
        <link rel="stylesheet" type="text/css" href="css/popup.css" />\r
-       <base target="_self" />\r
 </head>\r
 <body style="display: none">\r
 <form onsubmit="insertAbbr();return false;" action="#">\r
index 54e4c9d9ec5deeedca4b89318a16baa8b59f1407..4d4ebaac0aeca7f9881dfe68fa1c9b6a9f85949a 100644 (file)
@@ -9,7 +9,6 @@
        <script type="text/javascript" src="js/element_common.js"></script>\r
        <script type="text/javascript" src="js/acronym.js"></script>\r
        <link rel="stylesheet" type="text/css" href="css/popup.css" />\r
-       <base target="_self" />\r
 </head>\r
 <body style="display: none">\r
 <form onsubmit="insertAcronym();return false;" action="#">\r
index cfbb409ab692d0206f7798894e563910f6533277..322b468e38b71a04b25052bed3cbac5551ec4a1c 100644 (file)
@@ -8,7 +8,6 @@
        <script type="text/javascript" src="../../utils/form_utils.js"></script>\r
        <script type="text/javascript" src="js/attributes.js"></script>\r
        <link rel="stylesheet" type="text/css" href="css/attributes.css" />\r
-       <base target="_self" />\r
 </head>\r
 <body style="display: none">\r
 <form onsubmit="insertAction();return false;" action="#">\r
                                                <td><label id="classlabel" for="classlist">{#class_name}</label></td>\r
                                                <td>\r
                                                        <select id="classlist" name="classlist" class="mceEditableSelect">\r
-                                                               <option value="" selected>{#not_set}</option>\r
+                                                               <option value="" selected="selected">{#not_set}</option>\r
                                                        </select>\r
                                                </td>\r
                                        </tr>\r
                                        <tr>\r
-                                               <td class="label"><label id="stylelabel" for="class">{#xhtmlxtras_dlg.attribute_label_style}</label>:</td> \r
+                                               <td class="label"><label id="stylelabel" for="style">{#xhtmlxtras_dlg.attribute_label_style}</label>:</td> \r
                                                <td><input id="style" name="style" type="text" value="" /></td> \r
                                        </tr>\r
                                        <tr>\r
index 7d9eaba4d2ea03c38de1fa86b0992ddd46b45aaf..cdfaf4e854649f682569ff8c9b442560d6fc9c78 100644 (file)
@@ -9,7 +9,6 @@
        <script type="text/javascript" src="js/element_common.js"></script>\r
        <script type="text/javascript" src="js/cite.js"></script>\r
        <link rel="stylesheet" type="text/css" href="css/popup.css" />\r
-       <base target="_self" />\r
 </head>\r
 <body style="display: none">\r
 <form onsubmit="insertCite();return false;" action="#">\r
index d03c4568aaac1ea6d6b2bbd8301c66f65f6e99c9..f45676e3d4741c5ab45a5d3148e849e16870d606 100644 (file)
@@ -9,7 +9,6 @@
        <script type="text/javascript" src="js/element_common.js"></script>\r
        <script type="text/javascript" src="js/del.js"></script>\r
        <link rel="stylesheet" type="text/css" href="css/popup.css" />\r
-       <base target="_self" />\r
 </head>\r
 <body id="xhtmlxtrasins" style="display: none">\r
 <form onsubmit="insertDel();return false;" action="#">\r
@@ -31,7 +30,7 @@
                                                        <table border="0" cellspacing="0" cellpadding="0">\r
                                                                <tr> \r
                                                                        <td><input id="datetime" name="datetime" type="text" value="" maxlength="19" class="field mceFocus" /></td> \r
-                                                                       <td><a href="javascript:insertDateTime('datetime');" onmousedown="return false;" class="browse"><span class="datetime" alt="{#xhtmlxtras_dlg.insert_date}" title="{#xhtmlxtras_dlg.insert_date}"></span></a></td>\r
+                                                                       <td><a href="javascript:insertDateTime('datetime');" onmousedown="return false;" class="browse"><span class="datetime" title="{#xhtmlxtras_dlg.insert_date}"></span></a></td>\r
                                                                </tr>\r
                                                        </table>\r
                                                </td>\r
index 6a3270d3536becd93579512f1651a1d313e3fbec..8c7f48e6920f6c8d9e69460c0036a64dbd1a4c24 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create('tinymce.plugins.XHTMLXtrasPlugin',{init:function(ed,url){ed.addCommand('mceCite',function(){ed.windowManager.open({file:url+'/cite.htm',width:350+parseInt(ed.getLang('xhtmlxtras.cite_delta_width',0)),height:250+parseInt(ed.getLang('xhtmlxtras.cite_delta_height',0)),inline:1},{plugin_url:url});});ed.addCommand('mceAcronym',function(){ed.windowManager.open({file:url+'/acronym.htm',width:350+parseInt(ed.getLang('xhtmlxtras.acronym_delta_width',0)),height:250+parseInt(ed.getLang('xhtmlxtras.acronym_delta_width',0)),inline:1},{plugin_url:url});});ed.addCommand('mceAbbr',function(){ed.windowManager.open({file:url+'/abbr.htm',width:350+parseInt(ed.getLang('xhtmlxtras.abbr_delta_width',0)),height:250+parseInt(ed.getLang('xhtmlxtras.abbr_delta_width',0)),inline:1},{plugin_url:url});});ed.addCommand('mceDel',function(){ed.windowManager.open({file:url+'/del.htm',width:340+parseInt(ed.getLang('xhtmlxtras.del_delta_width',0)),height:310+parseInt(ed.getLang('xhtmlxtras.del_delta_width',0)),inline:1},{plugin_url:url});});ed.addCommand('mceIns',function(){ed.windowManager.open({file:url+'/ins.htm',width:340+parseInt(ed.getLang('xhtmlxtras.ins_delta_width',0)),height:310+parseInt(ed.getLang('xhtmlxtras.ins_delta_width',0)),inline:1},{plugin_url:url});});ed.addCommand('mceAttributes',function(){ed.windowManager.open({file:url+'/attributes.htm',width:380,height:370,inline:1},{plugin_url:url});});ed.addButton('cite',{title:'xhtmlxtras.cite_desc',cmd:'mceCite'});ed.addButton('acronym',{title:'xhtmlxtras.acronym_desc',cmd:'mceAcronym'});ed.addButton('abbr',{title:'xhtmlxtras.abbr_desc',cmd:'mceAbbr'});ed.addButton('del',{title:'xhtmlxtras.del_desc',cmd:'mceDel'});ed.addButton('ins',{title:'xhtmlxtras.ins_desc',cmd:'mceIns'});ed.addButton('attribs',{title:'xhtmlxtras.attribs_desc',cmd:'mceAttributes'});if(tinymce.isIE){function fix(ed,o){if(o.set){o.content=o.content.replace(/<abbr([^>]+)>/gi,'<html:abbr $1>');o.content=o.content.replace(/<\/abbr>/gi,'</html:abbr>');}};ed.onBeforeSetContent.add(fix);ed.onPostProcess.add(fix);}ed.onNodeChange.add(function(ed,cm,n,co){n=ed.dom.getParent(n,'CITE,ACRONYM,ABBR,DEL,INS');cm.setDisabled('cite',co);cm.setDisabled('acronym',co);cm.setDisabled('abbr',co);cm.setDisabled('del',co);cm.setDisabled('ins',co);cm.setDisabled('attribs',n&&n.nodeName=='BODY');if(n){cm.setDisabled(n.nodeName.toLowerCase(),0);cm.setActive(n.nodeName.toLowerCase(),1);}else{cm.setActive('cite',0);cm.setActive('acronym',0);cm.setActive('abbr',0);cm.setActive('del',0);cm.setActive('ins',0);}});},getInfo:function(){return{longname:'XHTML Xtras Plugin',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/xhtmlxtras',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('xhtmlxtras',tinymce.plugins.XHTMLXtrasPlugin);})();
\ No newline at end of file
+(function(){tinymce.create("tinymce.plugins.XHTMLXtrasPlugin",{init:function(b,c){b.addCommand("mceCite",function(){b.windowManager.open({file:c+"/cite.htm",width:350+parseInt(b.getLang("xhtmlxtras.cite_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.cite_delta_height",0)),inline:1},{plugin_url:c})});b.addCommand("mceAcronym",function(){b.windowManager.open({file:c+"/acronym.htm",width:350+parseInt(b.getLang("xhtmlxtras.acronym_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.acronym_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceAbbr",function(){b.windowManager.open({file:c+"/abbr.htm",width:350+parseInt(b.getLang("xhtmlxtras.abbr_delta_width",0)),height:250+parseInt(b.getLang("xhtmlxtras.abbr_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceDel",function(){b.windowManager.open({file:c+"/del.htm",width:340+parseInt(b.getLang("xhtmlxtras.del_delta_width",0)),height:310+parseInt(b.getLang("xhtmlxtras.del_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceIns",function(){b.windowManager.open({file:c+"/ins.htm",width:340+parseInt(b.getLang("xhtmlxtras.ins_delta_width",0)),height:310+parseInt(b.getLang("xhtmlxtras.ins_delta_width",0)),inline:1},{plugin_url:c})});b.addCommand("mceAttributes",function(){b.windowManager.open({file:c+"/attributes.htm",width:380,height:370,inline:1},{plugin_url:c})});b.addButton("cite",{title:"xhtmlxtras.cite_desc",cmd:"mceCite"});b.addButton("acronym",{title:"xhtmlxtras.acronym_desc",cmd:"mceAcronym"});b.addButton("abbr",{title:"xhtmlxtras.abbr_desc",cmd:"mceAbbr"});b.addButton("del",{title:"xhtmlxtras.del_desc",cmd:"mceDel"});b.addButton("ins",{title:"xhtmlxtras.ins_desc",cmd:"mceIns"});b.addButton("attribs",{title:"xhtmlxtras.attribs_desc",cmd:"mceAttributes"});if(tinymce.isIE){function a(d,e){if(e.set){e.content=e.content.replace(/<abbr([^>]+)>/gi,"<html:abbr $1>");e.content=e.content.replace(/<\/abbr>/gi,"</html:abbr>")}}b.onBeforeSetContent.add(a);b.onPostProcess.add(a)}b.onNodeChange.add(function(e,d,g,f){g=e.dom.getParent(g,"CITE,ACRONYM,ABBR,DEL,INS");d.setDisabled("cite",f);d.setDisabled("acronym",f);d.setDisabled("abbr",f);d.setDisabled("del",f);d.setDisabled("ins",f);d.setDisabled("attribs",g&&g.nodeName=="BODY");d.setActive("cite",0);d.setActive("acronym",0);d.setActive("abbr",0);d.setActive("del",0);d.setActive("ins",0);if(g){do{d.setDisabled(g.nodeName.toLowerCase(),0);d.setActive(g.nodeName.toLowerCase(),1)}while(g=g.parentNode)}})},getInfo:function(){return{longname:"XHTML Xtras Plugin",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/xhtmlxtras",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("xhtmlxtras",tinymce.plugins.XHTMLXtrasPlugin)})();
\ No newline at end of file
index 143ed92164bca3f8deed28233016a05c48f7c5eb..bef06f2d24e7abbda3a07d21b38c52e68dafdcf7 100644 (file)
                                cm.setDisabled('del', co);\r
                                cm.setDisabled('ins', co);\r
                                cm.setDisabled('attribs', n && n.nodeName == 'BODY');\r
+                               cm.setActive('cite', 0);\r
+                               cm.setActive('acronym', 0);\r
+                               cm.setActive('abbr', 0);\r
+                               cm.setActive('del', 0);\r
+                               cm.setActive('ins', 0);\r
 \r
+                               // Activate all\r
                                if (n) {\r
-                                       cm.setDisabled(n.nodeName.toLowerCase(), 0);\r
-                                       cm.setActive(n.nodeName.toLowerCase(), 1);\r
-                               } else {\r
-                                       cm.setActive('cite', 0);\r
-                                       cm.setActive('acronym', 0);\r
-                                       cm.setActive('abbr', 0);\r
-                                       cm.setActive('del', 0);\r
-                                       cm.setActive('ins', 0);\r
+                                       do {\r
+                                               cm.setDisabled(n.nodeName.toLowerCase(), 0);\r
+                                               cm.setActive(n.nodeName.toLowerCase(), 1);\r
+                                       } while (n = n.parentNode);\r
                                }\r
                        });\r
                },\r
index c0f056ff34b175799b393e91c3261b72d7901e5e..9fa21c4338641a833a74d5d3c604051de0f93fd3 100644 (file)
@@ -9,7 +9,6 @@
        <script type="text/javascript" src="js/element_common.js"></script>\r
        <script type="text/javascript" src="js/ins.js"></script>\r
        <link rel="stylesheet" type="text/css" href="css/popup.css" />\r
-       <base target="_self" />\r
 </head>\r
 <body id="xhtmlxtrasins" style="display: none">\r
 <form onsubmit="insertIns();return false;" action="#">\r
@@ -31,7 +30,7 @@
                                                        <table border="0" cellspacing="0" cellpadding="0">\r
                                                                <tr> \r
                                                                        <td><input id="datetime" name="datetime" type="text" value="" maxlength="19" class="field mceFocus" /></td> \r
-                                                                       <td><a href="javascript:insertDateTime('datetime');" onmousedown="return false;" class="browse"><span class="datetime" alt="{#xhtmlxtras_dlg.insert_date}" title="{#xhtmlxtras_dlg.insert_date}"></span></a></td>\r
+                                                                       <td><a href="javascript:insertDateTime('datetime');" onmousedown="return false;" class="browse"><span class="datetime" title="{#xhtmlxtras_dlg.insert_date}"></span></a></td>\r
                                                                </tr>\r
                                                        </table>\r
                                                </td>\r
index 005a619c720184120bd4121edcd2add168bd40d1..7049f2beb4e18e5b85b35a484623cf65716b5fd3 100644 (file)
@@ -27,7 +27,7 @@ function insertDel() {
        if (elm == null) {\r
                var s = SXE.inst.selection.getContent();\r
                if(s.length > 0) {\r
-                       tinyMCEPopup.execCommand('mceInsertContent', false, '<del id="#sxe_temp_del#">' + s + '</del>');\r
+                       insertInlineElement('del');\r
                        var elementArray = tinymce.grep(SXE.inst.dom.select('del'), function(n) {return n.id == '#sxe_temp_del#';});\r
                        for (var i=0; i<elementArray.length; i++) {\r
                                var elm = elementArray[i];\r
@@ -42,6 +42,16 @@ function insertDel() {
        tinyMCEPopup.close();\r
 }\r
 \r
+function insertInlineElement(en) {\r
+       var ed = tinyMCEPopup.editor, dom = ed.dom;\r
+\r
+       ed.getDoc().execCommand('FontName', false, 'mceinline');\r
+       tinymce.each(dom.select(tinymce.isWebKit ? 'span' : 'font'), function(n) {\r
+               if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline')\r
+                       dom.replace(dom.create(en), n, 1);\r
+       });\r
+}\r
+\r
 function removeDel() {\r
        SXE.removeElement('del');\r
        tinyMCEPopup.close();\r
index cc11835fa1402302f57ec561fcf8877d1a1f4228..70f168a6b5f03999e5d29808edf4f82ac577fd8a 100644 (file)
@@ -160,19 +160,19 @@ SXE.insertElement = function(element_name) {
                        if (tinymce.isIE && element_name.indexOf('html:') == 0)\r
                                element_name = element_name.substring(5).toLowerCase();\r
 \r
-                       h = '<' + tagName + ' id="#sxe_temp_' + element_name + '#">' + s + '</' + tagName + '>';\r
-\r
-                       tinyMCEPopup.execCommand('mceInsertContent', false, h);\r
-\r
-                       var elementArray = tinymce.grep(SXE.inst.dom.select(element_name), function(n) {return n.id == '#sxe_temp_' + element_name + '#';});\r
+                       insertInlineElement(element_name);\r
+                       var elementArray = tinymce.grep(SXE.inst.dom.select(element_name));\r
                        for (var i=0; i<elementArray.length; i++) {\r
                                var elm = elementArray[i];\r
 \r
-                               elm.id = '';\r
-                               elm.setAttribute('id', '');\r
-                               elm.removeAttribute('id');\r
+                               if (SXE.inst.dom.getAttrib(elm, '_mce_new')) {\r
+                                       elm.id = '';\r
+                                       elm.setAttribute('id', '');\r
+                                       elm.removeAttribute('id');\r
+                                       elm.removeAttribute('_mce_new');\r
 \r
-                               setAllCommonAttribs(elm);\r
+                                       setAllCommonAttribs(elm);\r
+                               }\r
                        }\r
                }\r
        } else {\r
@@ -218,4 +218,14 @@ SXE.removeClass = function(elm,cl) {
 SXE.addClass = function(elm,cl) {\r
        if(!SXE.containsClass(elm,cl)) elm.className ? elm.className += " " + cl : elm.className = cl;\r
        return true;\r
-}
\ No newline at end of file
+}\r
+\r
+function insertInlineElement(en) {\r
+       var ed = tinyMCEPopup.editor, dom = ed.dom;\r
+\r
+       ed.getDoc().execCommand('FontName', false, 'mceinline');\r
+       tinymce.each(dom.select('span,font'), function(n) {\r
+               if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline')\r
+                       dom.replace(dom.create(en, {_mce_new : 1}), n, 1);\r
+       });\r
+}\r
index b03ca1b5e47091644a233131862da41fd7e0da16..4fcc998256fb902ec0f9b9c6f47b6f4afefd4927 100644 (file)
@@ -26,7 +26,7 @@ function insertIns() {
        if (elm == null) {\r
                var s = SXE.inst.selection.getContent();\r
                if(s.length > 0) {\r
-                       tinyMCEPopup.execCommand('mceInsertContent', false, '<ins id="#sxe_temp_ins#">' + s + '</ins>');\r
+                       insertInlineElement('INS');\r
                        var elementArray = tinymce.grep(SXE.inst.dom.select('ins'), function(n) {return n.id == '#sxe_temp_ins#';});\r
                        for (var i=0; i<elementArray.length; i++) {\r
                                var elm = elementArray[i];\r
@@ -46,4 +46,14 @@ function removeIns() {
        tinyMCEPopup.close();\r
 }\r
 \r
+function insertInlineElement(en) {\r
+       var ed = tinyMCEPopup.editor, dom = ed.dom;\r
+\r
+       ed.getDoc().execCommand('FontName', false, 'mceinline');\r
+       tinymce.each(dom.select(tinymce.isWebKit ? 'span' : 'font'), function(n) {\r
+               if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline')\r
+                       dom.replace(dom.create(en), n, 1);\r
+       });\r
+}\r
+\r
 tinyMCEPopup.onInit.add(init);\r
index 4ef2a29c5d536d73a025fad8c854a52b5f8c549d..e5df7aa5aca5b9b6d138569f4d2f8626b0d3652b 100644 (file)
@@ -1,4 +1,4 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> \r
 <html xmlns="http://www.w3.org/1999/xhtml">\r
 <head>\r
        <title>{#advanced_dlg.about_title}</title>\r
index 9e4c0b91ae7393f780a02d7073c403260fe8e743..42095a1c0cabd4db2666cbdefd2666cfa68e00b0 100644 (file)
@@ -4,7 +4,6 @@
        <title>{#advanced_dlg.anchor_title}</title>\r
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="js/anchor.js"></script>\r
-       <base target="_self" />\r
 </head>\r
 <body style="display: none">\r
 <form onsubmit="AnchorDialog.update();return false;" action="#">\r
@@ -13,7 +12,7 @@
                        <td colspan="2" class="title">{#advanced_dlg.anchor_title}</td>\r
                </tr>\r
                <tr>\r
-                       <td nowrap="nowrap">{#advanced_dlg.anchor_name}:</td>\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
                </tr>\r
        </table>\r
index e4c7344848ffe297c147d37d2f481c8402e15c88..f11a38ad8a2a8038b7809b76c499e73b09b89c0e 100644 (file)
@@ -1,11 +1,10 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r
 <html xmlns="http://www.w3.org/1999/xhtml">\r
 <head>\r
        <title>{#advanced_dlg.charmap_title}</title>\r
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />\r
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="js/charmap.js"></script>\r
-       <base target="_self" />\r
 </head>\r
 <body id="charmap" style="display:none">\r
 <table align="center" border="0" cellspacing="0" cellpadding="2">\r
index a8f297c6038adb555386335aff4956e2cb6a4b8d..90eb4c2ee1fc66b458f718c8e78f3b9b3fb375d2 100644 (file)
@@ -5,7 +5,6 @@
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="../../utils/mctabs.js"></script>\r
        <script type="text/javascript" src="js/color_picker.js"></script>\r
-       <base target="_self" />\r
 </head>\r
 <body id="colorpicker" style="display: none">\r
 <form onsubmit="insertAction();return false" action="#">\r
@@ -22,7 +21,7 @@
                        <fieldset>\r
                                <legend>{#advanced_dlg.colorpicker_picker_title}</legend>\r
                                <div id="picker">\r
-                                       <img id="colors" src="img/colorpicker.jpg" onclick="computeColor(event)" onmousedown="isMouseDown = true;return false;" onmouseup="isMouseDown = false;" onmousemove="if (isMouseDown && isMouseOver) computeColor(event); return false;" onmouseover="isMouseOver=true;" onmouseout="isMouseOver=false;" />\r
+                                       <img id="colors" src="img/colorpicker.jpg" onclick="computeColor(event)" onmousedown="isMouseDown = true;return false;" onmouseup="isMouseDown = false;" onmousemove="if (isMouseDown && isMouseOver) computeColor(event); return false;" onmouseover="isMouseOver=true;" onmouseout="isMouseOver=false;" alt=" " />\r
 \r
                                        <div id="light">\r
                                                <!-- Will be filled with divs -->\r
index eea384f751aac2080c8f229e7a60f142f8c6cbdf..628c793cc7961c7e22d2e1c04940aa2bf66f7132 100644 (file)
@@ -1 +1 @@
-(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,extend=tinymce.extend,each=tinymce.each,Cookie=tinymce.util.Cookie,lastExtID,explode=tinymce.explode;tinymce.ThemeManager.requireLangPack('advanced');tinymce.create('tinymce.themes.AdvancedTheme',{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(ed,url){var t=this,s,v;t.editor=ed;t.url=url;t.onResolveName=new tinymce.util.Dispatcher(this);t.settings=s=extend({theme_advanced_path:true,theme_advanced_toolbar_location:'bottom',theme_advanced_buttons1:"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,|,sub,sup,|,charmap",theme_advanced_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_font_sizes:"1,2,3,4,5,6,7",theme_advanced_more_colors:1,theme_advanced_row_height:23,theme_advanced_resize_horizontal:1,theme_advanced_resizing_use_cookie:1},ed.settings);if((v=s.theme_advanced_path_location)&&v!='none')s.theme_advanced_statusbar_location=s.theme_advanced_path_location;if(s.theme_advanced_statusbar_location=='none')s.theme_advanced_statusbar_location=0;ed.onInit.add(function(){ed.onNodeChange.add(t._nodeChanged,t);if(ed.settings.content_css!==false)ed.dom.loadCSS(ed.baseURI.toAbsolute("themes/advanced/skins/"+ed.settings.skin+"/content.css"));});ed.onSetProgressState.add(function(ed,b,ti){var co,id=ed.id,tb;if(b){t.progressTimer=setTimeout(function(){co=ed.getContainer();co=co.insertBefore(DOM.create('DIV',{style:'position:relative'}),co.firstChild);tb=DOM.get(ed.id+'_tbl');DOM.add(co,'div',{id:id+'_blocker','class':'mceBlocker',style:{width:tb.clientWidth+2,height:tb.clientHeight+2}});DOM.add(co,'div',{id:id+'_progress','class':'mceProgress',style:{left:tb.clientWidth/ 2, top : tb.clientHeight /2}});},ti||0);}else{DOM.remove(id+'_blocker');DOM.remove(id+'_progress');clearTimeout(t.progressTimer);}});DOM.loadCSS(ed.baseURI.toAbsolute(s.editor_css||"themes/advanced/skins/"+ed.settings.skin+"/ui.css"));if(s.skin_variant)DOM.loadCSS(ed.baseURI.toAbsolute(s.editor_css||"themes/advanced/skins/"+ed.settings.skin+"/ui_"+s.skin_variant+".css"));},createControl:function(n,cf){var cd,c;if(c=cf.createControl(n))return c;switch(n){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((cd=this.controls[n]))return cf.createButton(n,{title:"advanced."+cd[0],cmd:cd[1],ui:cd[2],value:cd[3]});},execCommand:function(cmd,ui,val){var f=this['_'+cmd];if(f){f.call(this,ui,val);return true;}return false;},_importClasses:function(e){var ed=this.editor,c=ed.controlManager.get('styleselect');if(c.getLength()==0){each(ed.dom.getClasses(),function(o){c.add(o['class'],o['class']);});}},_createStyleSelect:function(n){var t=this,ed=t.editor,cf=ed.controlManager,c=cf.createListBox('styleselect',{title:'advanced.style_select',onselect:function(v){if(c.selectedValue===v){ed.execCommand('mceSetStyleInfo',0,{command:'removeformat'});c.select();return false;}else ed.execCommand('mceSetCSSClass',0,v);}});if(c){each(ed.getParam('theme_advanced_styles','','hash'),function(v,k){if(v)c.add(t.editor.translate(k),v);});c.onPostRender.add(function(ed,n){Event.add(n.id+'_text','focus',t._importClasses,t);Event.add(n.id+'_text','mousedown',t._importClasses,t);});}return c;},_createFontSelect:function(){var c,t=this,ed=t.editor;c=ed.controlManager.createListBox('fontselect',{title:'advanced.fontdefault',cmd:'FontName'});if(c){each(ed.getParam('theme_advanced_fonts',t.settings.theme_advanced_fonts,'hash'),function(v,k){c.add(ed.translate(k),v,{style:v.indexOf('dings')==-1?'font-family:'+v:''});});}return c;},_createFontSizeSelect:function(){var t=this,ed=t.editor,c,lo=["1 (8 pt)","2 (10 pt)","3 (12 pt)","4 (14 pt)","5 (18 pt)","6 (24 pt)","7 (36 pt)"],fz=[8,10,12,14,18,24,36];c=ed.controlManager.createListBox('fontsizeselect',{title:'advanced.font_size',cmd:'FontSize'});if(c){each(ed.getParam('theme_advanced_font_sizes',t.settings.theme_advanced_font_sizes,'hash'),function(v,k){c.add(k!=v?k:lo[parseInt(v)-1],v,{'style':'font-size:'+fz[v-1]+'pt','class':'mceFontSize'+v});});}return c;},_createBlockFormats:function(){var c,fmts={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'},t=this;c=t.editor.controlManager.createListBox('formatselect',{title:'advanced.block',cmd:'FormatBlock'});if(c){each(t.editor.getParam('theme_advanced_blockformats',t.settings.theme_advanced_blockformats,'hash'),function(v,k){c.add(t.editor.translate(k!=v?k:fmts[v]),v,{'class':'mce_formatPreview mce_'+v});});}return c;},_createForeColorMenu:function(){var c,t=this,s=t.settings,o={},v;if(s.theme_advanced_more_colors){o.more_colors_func=function(){t._mceColorPicker(0,{color:c.value,func:function(co){c.setColor(co);}});};}if(v=s.theme_advanced_text_colors)o.colors=v;o.title='advanced.forecolor_desc';o.cmd='ForeColor';o.scope=this;c=t.editor.controlManager.createColorSplitButton('forecolor',o);return c;},_createBackColorMenu:function(){var c,t=this,s=t.settings,o={},v;if(s.theme_advanced_more_colors){o.more_colors_func=function(){t._mceColorPicker(0,{color:c.value,func:function(co){c.setColor(co);}});};}if(v=s.theme_advanced_background_colors)o.colors=v;o.title='advanced.backcolor_desc';o.cmd='HiliteColor';o.scope=this;c=t.editor.controlManager.createColorSplitButton('backcolor',o);return c;},renderUI:function(o){var n,ic,tb,t=this,ed=t.editor,s=t.settings,sc,p,nl;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):'')});if(!DOM.boxModel)n=DOM.add(n,'div',{'class':'mceOldBoxModel'});n=sc=DOM.add(n,'table',{id:ed.id+'_tbl','class':'mceLayout',cellSpacing:0,cellPadding:0});n=tb=DOM.add(n,'tbody');switch((s.theme_advanced_layout_manager||'').toLowerCase()){case"rowlayout":ic=t._rowLayout(s,tb,o);break;case"customlayout":ic=ed.execCallback("theme_advanced_custom_layout",s,tb,o,p);break;default:ic=t._simpleLayout(s,tb,o,p);}n=o.targetNode;nl=DOM.stdMode?sc.getElementsByTagName('tr'):sc.rows;DOM.addClass(nl[0],'mceFirst');DOM.addClass(nl[nl.length-1],'mceLast');each(DOM.select('tr',tb),function(n){DOM.addClass(n.firstChild,'mceFirst');DOM.addClass(n.childNodes[n.childNodes.length-1],'mceLast');});if(DOM.get(s.theme_advanced_toolbar_container))DOM.get(s.theme_advanced_toolbar_container).appendChild(p);else DOM.insertAfter(p,n);Event.add(ed.id+'_path_row','click',function(e){e=e.target;if(e.nodeName=='A'){t._sel(e.className.replace(/^.*mcePath_([0-9]+).*$/,'$1'));return Event.cancel(e);}});if(!ed.getParam('accessibility_focus')||ed.getParam('tab_focus'))Event.add(DOM.add(p,'a',{href:'#'},'<!-- IE -->'),'focus',function(){tinyMCE.get(ed.id).focus();});if(s.theme_advanced_toolbar_location=='external')o.deltaHeight=0;t.deltaHeight=o.deltaHeight;o.targetNode=null;return{iframeContainer:ic,editorContainer:ed.id+'_parent',sizeContainer:sc,deltaHeight:o.deltaHeight};},getInfo:function(){return{longname:'Advanced theme',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',version:tinymce.majorVersion+"."+tinymce.minorVersion}},resizeBy:function(dw,dh){var e=DOM.get(this.editor.id+'_tbl');this.resizeTo(e.clientWidth+dw,e.clientHeight+dh);},resizeTo:function(w,h){var ed=this.editor,s=ed.settings,e=DOM.get(ed.id+'_tbl'),ifr=DOM.get(ed.id+'_ifr'),dh;w=Math.max(s.theme_advanced_resizing_min_width||100,w);h=Math.max(s.theme_advanced_resizing_min_height||100,h);w=Math.min(s.theme_advanced_resizing_max_width||0xFFFF,w);h=Math.min(s.theme_advanced_resizing_max_height||0xFFFF,h);dh=e.clientHeight-ifr.clientHeight;DOM.setStyle(ifr,'height',h-dh);DOM.setStyles(e,{width:w,height:h});},destroy:function(){var id=this.editor.id;Event.clear(id+'_resize');Event.clear(id+'_path_row');Event.clear(id+'_external_close');},_simpleLayout:function(s,tb,o,p){var t=this,ed=t.editor,lo=s.theme_advanced_toolbar_location,sl=s.theme_advanced_statusbar_location,n,ic,etb,c;if(lo=='top')t._addToolbars(tb,o);if(lo=='external'){n=c=DOM.create('div',{style:'position:relative'});n=DOM.add(n,'div',{id:ed.id+'_external','class':'mceExternalToolbar'});DOM.add(n,'a',{id:ed.id+'_external_close',href:'javascript:;','class':'mceExternalClose'});n=DOM.add(n,'table',{id:ed.id+'_tblext',cellSpacing:0,cellPadding:0});etb=DOM.add(n,'tbody');if(p.firstChild.className=='mceOldBoxModel')p.firstChild.appendChild(c);else p.insertBefore(c,p.firstChild);t._addToolbars(etb,o);ed.onMouseUp.add(function(){var e=DOM.get(ed.id+'_external');DOM.show(e);DOM.hide(lastExtID);var f=Event.add(ed.id+'_external_close','click',function(){DOM.hide(ed.id+'_external');Event.remove(ed.id+'_external_close','click',f);});DOM.show(e);DOM.setStyle(e,'top',0-DOM.getRect(ed.id+'_tblext').h-1);DOM.hide(e);DOM.show(e);e.style.filter='';lastExtID=ed.id+'_external';e=null;});}if(sl=='top')t._addStatusBar(tb,o);if(!s.theme_advanced_toolbar_container){n=DOM.add(tb,'tr');n=ic=DOM.add(n,'td',{'class':'mceIframeContainer'});}if(lo=='bottom')t._addToolbars(tb,o);if(sl=='bottom')t._addStatusBar(tb,o);return ic;},_rowLayout:function(s,tb,o){var t=this,ed=t.editor,dc,da,cf=ed.controlManager,n,ic,to,a;dc=s.theme_advanced_containers_default_class||'';da=s.theme_advanced_containers_default_align||'center';each(explode(s.theme_advanced_containers||''),function(c,i){var v=s['theme_advanced_container_'+c]||'';switch(v.toLowerCase()){case'mceeditor':n=DOM.add(tb,'tr');n=ic=DOM.add(n,'td',{'class':'mceIframeContainer'});break;case'mceelementpath':t._addStatusBar(tb,o);break;default:a=(s['theme_advanced_container_'+c+'_align']||da).toLowerCase();a='mce'+t._ufirst(a);n=DOM.add(DOM.add(tb,'tr'),'td',{'class':'mceToolbar '+(s['theme_advanced_container_'+c+'_class']||dc)+' '+a||da});to=cf.createToolbar("toolbar"+i);t._addControls(v,to);DOM.setHTML(n,to.renderHTML());o.deltaHeight-=s.theme_advanced_row_height;}});return ic;},_addControls:function(v,tb){var t=this,s=t.settings,di,cf=t.editor.controlManager;if(s.theme_advanced_disable&&!t._disabled){di={};each(explode(s.theme_advanced_disable),function(v){di[v]=1;});t._disabled=di;}else di=t._disabled;each(explode(v),function(n){var c;if(di&&di[n])return;if(n=='tablecontrols'){each(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"],function(n){n=t.createControl(n,cf);if(n)tb.add(n);});return;}c=t.createControl(n,cf);if(c)tb.add(c);});},_addToolbars:function(c,o){var t=this,i,tb,ed=t.editor,s=t.settings,v,cf=ed.controlManager,di,n,h=[],a;a=s.theme_advanced_toolbar_align.toLowerCase();a='mce'+t._ufirst(a);n=DOM.add(DOM.add(c,'tr'),'td',{'class':'mceToolbar '+a});if(!ed.getParam('accessibility_focus')||ed.getParam('tab_focus'))h.push(DOM.createHTML('a',{href:'#',onfocus:'tinyMCE.get(\''+ed.id+'\').focus();'},'<!-- IE -->'));h.push(DOM.createHTML('a',{href:'#',accesskey:'q',title:ed.getLang("advanced.toolbar_focus")},'<!-- IE -->'));for(i=1;(v=s['theme_advanced_buttons'+i]);i++){tb=cf.createToolbar("toolbar"+i,{'class':'mceToolbarRow'+i});if(s['theme_advanced_buttons'+i+'_add'])v+=','+s['theme_advanced_buttons'+i+'_add'];if(s['theme_advanced_buttons'+i+'_add_before'])v=s['theme_advanced_buttons'+i+'_add_before']+','+v;t._addControls(v,tb);h.push(tb.renderHTML());o.deltaHeight-=s.theme_advanced_row_height;}h.push(DOM.createHTML('a',{href:'#',accesskey:'z',title:ed.getLang("advanced.toolbar_focus"),onfocus:'tinyMCE.getInstanceById(\''+ed.id+'\').focus();'},'<!-- IE -->'));DOM.setHTML(n,h.join(''));},_addStatusBar:function(tb,o){var n,t=this,ed=t.editor,s=t.settings,r,mf,me,td;n=DOM.add(tb,'tr');n=td=DOM.add(n,'td',{'class':'mceStatusbar'});n=DOM.add(n,'div',{id:ed.id+'_path_row'},s.theme_advanced_path?ed.translate('advanced.path')+': ':'&nbsp;');DOM.add(n,'a',{href:'#',accesskey:'x'});if(s.theme_advanced_resizing&&!tinymce.isOldWebKit){DOM.add(td,'a',{id:ed.id+'_resize',href:'javascript:;',onclick:"return false;",'class':'mceResize'});if(s.theme_advanced_resizing_use_cookie){ed.onPostRender.add(function(){var o=Cookie.getHash("TinyMCE_"+ed.id+"_size"),c=DOM.get(ed.id+'_tbl');if(!o)return;if(s.theme_advanced_resize_horizontal)c.style.width=Math.max(10,o.cw)+'px';c.style.height=Math.max(10,o.ch)+'px';DOM.get(ed.id+'_ifr').style.height=Math.max(10,parseInt(o.ch)+t.deltaHeight)+'px';});}ed.onPostRender.add(function(){Event.add(ed.id+'_resize','mousedown',function(e){var c,p,w,h,n,pa;c=DOM.get(ed.id+'_tbl');w=c.clientWidth;h=c.clientHeight;miw=s.theme_advanced_resizing_min_width||100;mih=s.theme_advanced_resizing_min_height||100;maw=s.theme_advanced_resizing_max_width||0xFFFF;mah=s.theme_advanced_resizing_max_height||0xFFFF;p=DOM.add(DOM.get(ed.id+'_parent'),'div',{'class':'mcePlaceHolder'});DOM.setStyles(p,{width:w,height:h});DOM.hide(c);DOM.show(p);r={x:e.screenX,y:e.screenY,w:w,h:h,dx:null,dy:null};mf=Event.add(DOM.doc,'mousemove',function(e){var w,h;r.dx=e.screenX-r.x;r.dy=e.screenY-r.y;w=Math.max(miw,r.w+r.dx);h=Math.max(mih,r.h+r.dy);w=Math.min(maw,w);h=Math.min(mah,h);if(s.theme_advanced_resize_horizontal)p.style.width=w+'px';p.style.height=h+'px';return Event.cancel(e);});me=Event.add(DOM.doc,'mouseup',function(e){var ifr;Event.remove(DOM.doc,'mousemove',mf);Event.remove(DOM.doc,'mouseup',me);c.style.display='';DOM.remove(p);if(r.dx===null)return;ifr=DOM.get(ed.id+'_ifr');if(s.theme_advanced_resize_horizontal)c.style.width=Math.max(10,r.w+r.dx)+'px';c.style.height=Math.max(10,r.h+r.dy)+'px';ifr.style.height=Math.max(10,ifr.clientHeight+r.dy)+'px';if(s.theme_advanced_resizing_use_cookie){Cookie.setHash("TinyMCE_"+ed.id+"_size",{cw:r.w+r.dx,ch:r.h+r.dy});}});return Event.cancel(e);});});}o.deltaHeight-=21;n=tb=null;},_nodeChanged:function(ed,cm,n,co){var t=this,p,de=0,v,c,s=t.settings;tinymce.each(t.stateControls,function(c){cm.setActive(c,ed.queryCommandState(t.controls[c][1]));});cm.setActive('visualaid',ed.hasVisual);cm.setDisabled('undo',!ed.undoManager.hasUndo()&&!ed.typing);cm.setDisabled('redo',!ed.undoManager.hasRedo());cm.setDisabled('outdent',!ed.queryCommandState('Outdent'));p=DOM.getParent(n,'A');if(c=cm.get('link')){if(!p||!p.name){c.setDisabled(!p&&co);c.setActive(!!p);}}if(c=cm.get('unlink')){c.setDisabled(!p&&co);c.setActive(!!p&&!p.name);}if(c=cm.get('anchor')){c.setActive(!!p&&p.name);if(tinymce.isWebKit){p=DOM.getParent(n,'IMG');c.setActive(!!p&&DOM.getAttrib(p,'mce_name')=='a');}}p=DOM.getParent(n,'IMG');if(c=cm.get('image'))c.setActive(!!p&&n.className.indexOf('mceItem')==-1);if(c=cm.get('styleselect')){if(n.className){t._importClasses();c.select(n.className);}else c.select();}if(c=cm.get('formatselect')){p=DOM.getParent(n,DOM.isBlock);if(p)c.select(p.nodeName.toLowerCase());}if(c=cm.get('fontselect'))c.select(ed.queryCommandValue('FontName'));if(c=cm.get('fontsizeselect'))c.select(''+ed.queryCommandValue('FontSize'));if(s.theme_advanced_path&&s.theme_advanced_statusbar_location){p=DOM.get(ed.id+'_path')||DOM.add(ed.id+'_path_row','span',{id:ed.id+'_path'});DOM.setHTML(p,'');ed.dom.getParent(n,function(n){var na=n.nodeName.toLowerCase(),u,pi,ti='';if(n.nodeType!=1||(DOM.hasClass(n,'mceItemHidden')||DOM.hasClass(n,'mceItemRemoved')))return;if(v=DOM.getAttrib(n,'mce_name'))na=v;if(tinymce.isIE&&n.scopeName!=='HTML')na=n.scopeName+':'+na;na=na.replace(/mce\:/g,'');switch(na){case'b':na='strong';break;case'i':na='em';break;case'img':if(v=DOM.getAttrib(n,'src'))ti+='src: '+v+' ';break;case'a':if(v=DOM.getAttrib(n,'name')){ti+='name: '+v+' ';na+='#'+v;}if(v=DOM.getAttrib(n,'href'))ti+='href: '+v+' ';break;case'font':if(s.convert_fonts_to_spans)na='span';if(v=DOM.getAttrib(n,'face'))ti+='font: '+v+' ';if(v=DOM.getAttrib(n,'size'))ti+='size: '+v+' ';if(v=DOM.getAttrib(n,'color'))ti+='color: '+v+' ';break;case'span':if(v=DOM.getAttrib(n,'style'))ti+='style: '+v+' ';break;}if(v=DOM.getAttrib(n,'id'))ti+='id: '+v+' ';if(v=n.className){v=v.replace(/(webkit-[\w\-]+|Apple-[\w\-]+|mceItem\w+|mceVisualAid)/g,'');if(v&&v.indexOf('mceItem')==-1){ti+='class: '+v+' ';if(DOM.isBlock(n)||na=='img'||na=='span')na+='.'+v;}}na=na.replace(/(html:)/g,'');na={name:na,node:n,title:ti};t.onResolveName.dispatch(t,na);ti=na.title;na=na.name;pi=DOM.create('a',{'href':"javascript:;",onmousedown:"return false;",title:ti,'class':'mcePath_'+(de++)},na);if(p.hasChildNodes()){p.insertBefore(DOM.doc.createTextNode(' \u00bb '),p.firstChild);p.insertBefore(pi,p.firstChild);}else p.appendChild(pi);},ed.getBody());}},_sel:function(v){this.editor.execCommand('mceSelectNodeDepth',false,v);},_mceInsertAnchor:function(ui,v){var ed=this.editor;ed.windowManager.open({url:tinymce.baseURL+'/themes/advanced/anchor.htm',width:320+parseInt(ed.getLang('advanced.anchor_delta_width',0)),height:90+parseInt(ed.getLang('advanced.anchor_delta_height',0)),inline:true},{theme_url:this.url});},_mceCharMap:function(){var ed=this.editor;ed.windowManager.open({url:tinymce.baseURL+'/themes/advanced/charmap.htm',width:550+parseInt(ed.getLang('advanced.charmap_delta_width',0)),height:250+parseInt(ed.getLang('advanced.charmap_delta_height',0)),inline:true},{theme_url:this.url});},_mceHelp:function(){var ed=this.editor;ed.windowManager.open({url:tinymce.baseURL+'/themes/advanced/about.htm',width:480,height:380,inline:true},{theme_url:this.url});},_mceColorPicker:function(u,v){var ed=this.editor;v=v||{};ed.windowManager.open({url:tinymce.baseURL+'/themes/advanced/color_picker.htm',width:375+parseInt(ed.getLang('advanced.colorpicker_delta_width',0)),height:250+parseInt(ed.getLang('advanced.colorpicker_delta_height',0)),close_previous:false,inline:true},{input_color:v.color,func:v.func,theme_url:this.url});},_mceCodeEditor:function(ui,val){var ed=this.editor;ed.windowManager.open({url:tinymce.baseURL+'/themes/advanced/source_editor.htm',width:parseInt(ed.getParam("theme_advanced_source_editor_width",720)),height:parseInt(ed.getParam("theme_advanced_source_editor_height",580)),inline:true,resizable:true,maximizable:true},{theme_url:this.url});},_mceImage:function(ui,val){var ed=this.editor;if(ed.dom.getAttrib(ed.selection.getNode(),'class').indexOf('mceItem')!=-1)return;ed.windowManager.open({url:tinymce.baseURL+'/themes/advanced/image.htm',width:355+parseInt(ed.getLang('advanced.image_delta_width',0)),height:275+parseInt(ed.getLang('advanced.image_delta_height',0)),inline:true},{theme_url:this.url});},_mceLink:function(ui,val){var ed=this.editor;ed.windowManager.open({url:tinymce.baseURL+'/themes/advanced/link.htm',width:310+parseInt(ed.getLang('advanced.link_delta_width',0)),height:200+parseInt(ed.getLang('advanced.link_delta_height',0)),inline:true},{theme_url:this.url});},_mceNewDocument:function(){var ed=this.editor;ed.windowManager.confirm('advanced.newdocument',function(s){if(s)ed.execCommand('mceSetContent',false,'');});},_mceForeColor:function(){var t=this;this._mceColorPicker(0,{color:t.fgColor,func:function(co){t.fgColor=co;t.editor.execCommand('ForeColor',false,co);}});},_mceBackColor:function(){var t=this;this._mceColorPicker(0,{color:t.bgColor,func:function(co){t.bgColor=co;t.editor.execCommand('HiliteColor',false,co);}});},_ufirst:function(s){return s.substring(0,1).toUpperCase()+s.substring(1);}});tinymce.ThemeManager.add('advanced',tinymce.themes.AdvancedTheme);}());
\ 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);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)";if(j.settings.convert_fonts_to_spans){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(){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(j){var i=this.editor,k=i.controlManager.get("styleselect");if(k.getLength()==0){f(i.dom.getClasses(),function(l){k.add(l["class"],l["class"])})}},_createStyleSelect:function(m){var j=this,i=j.editor,k=i.controlManager,l=k.createListBox("styleselect",{title:"advanced.style_select",onselect:function(n){if(l.selectedValue===n){i.execCommand("mceSetStyleInfo",0,{command:"removeformat"});l.select();return false}else{i.execCommand("mceSetCSSClass",0,n)}}});if(l){f(i.getParam("theme_advanced_styles","","hash"),function(o,n){if(o){l.add(j.editor.translate(n),o)}});l.onPostRender.add(function(o,p){if(!l.NativeListBox){b.add(p.id+"_text","focus",j._importClasses,j);b.add(p.id+"_text","mousedown",j._importClasses,j);b.add(p.id+"_open","focus",j._importClasses,j);b.add(p.id+"_open","mousedown",j._importClasses,j)}else{b.add(p.id,"focus",j._importClasses,j)}})}return l},_createFontSelect:function(){var k,j=this,i=j.editor;k=i.controlManager.createListBox("fontselect",{title:"advanced.fontdefault",cmd:"FontName"});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.fontSize){k.execCommand("FontSize",false,i.fontSize)}else{f(m.settings.theme_advanced_font_sizes,function(p,o){if(p["class"]){j.push(p["class"])}});k.editorCommands._applyInlineStyle("span",{"class":i["class"]},{check_classes:j})}}});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=j.settings,n=d.get(j.id+"_tbl"),o=d.get(j.id+"_ifr"),m;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);m=n.clientHeight-o.clientHeight;d.setStyle(o,"height",l-m);d.setStyles(n,{width:i,height:l})},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}if(w.theme_advanced_resize_horizontal){r.style.width=Math.max(10,n.cw)+"px"}r.style.height=Math.max(10,n.ch)+"px";d.get(p.id+"_ifr").style.height=Math.max(10,parseInt(n.ch)+v.deltaHeight)+"px"})}p.onPostRender.add(function(){b.add(p.id+"_resize","mousedown",function(x){var z,t,o,s,y,r;z=d.get(p.id+"_tbl");o=z.clientWidth;s=z.clientHeight;miw=w.theme_advanced_resizing_min_width||100;mih=w.theme_advanced_resizing_min_height||100;maw=w.theme_advanced_resizing_max_width||65535;mah=w.theme_advanced_resizing_max_height||65535;t=d.add(d.get(p.id+"_parent"),"div",{"class":"mcePlaceHolder"});d.setStyles(t,{width:o,height:s});d.hide(z);d.show(t);i={x:x.screenX,y:x.screenY,w:o,h:s,dx:null,dy:null};q=b.add(d.doc,"mousemove",function(B){var n,A;i.dx=B.screenX-i.x;i.dy=B.screenY-i.y;n=Math.max(miw,i.w+i.dx);A=Math.max(mih,i.h+i.dy);n=Math.min(maw,n);A=Math.min(mah,A);if(w.theme_advanced_resize_horizontal){t.style.width=n+"px"}t.style.height=A+"px";return b.cancel(B)});u=b.add(d.doc,"mouseup",function(n){var A;b.remove(d.doc,"mousemove",q);b.remove(d.doc,"mouseup",u);z.style.display="";d.remove(t);if(i.dx===null){return}A=d.get(p.id+"_ifr");if(w.theme_advanced_resize_horizontal){z.style.width=Math.max(10,i.w+i.dx)+"px"}z.style.height=Math.max(10,i.h+i.dy)+"px";A.style.height=Math.max(10,A.clientHeight+i.dy)+"px";if(w.theme_advanced_resizing_use_cookie){a.setHash("TinyMCE_"+p.id+"_size",{cw:i.w+i.dx,ch:i.h+i.dy})}});return b.cancel(x)})})}j.deltaHeight-=21;k=m=null},_nodeChanged:function(l,u,k,q){var y=this,i,r=0,x,m,z=y.settings,w,j,o;if(z.readonly){return}e.each(y.stateControls,function(n){u.setActive(n,l.queryCommandState(y.controls[n][1]))});u.setActive("visualaid",l.hasVisual);u.setDisabled("undo",!l.undoManager.hasUndo()&&!l.typing);u.setDisabled("redo",!l.undoManager.hasRedo());u.setDisabled("outdent",!l.queryCommandState("Outdent"));i=d.getParent(k,"A");if(m=u.get("link")){if(!i||!i.name){m.setDisabled(!i&&q);m.setActive(!!i)}}if(m=u.get("unlink")){m.setDisabled(!i&&q);m.setActive(!!i&&!i.name)}if(m=u.get("anchor")){m.setActive(!!i&&i.name);if(e.isWebKit){i=d.getParent(k,"IMG");m.setActive(!!i&&d.getAttrib(i,"mce_name")=="a")}}i=d.getParent(k,"IMG");if(m=u.get("image")){m.setActive(!!i&&k.className.indexOf("mceItem")==-1)}if(m=u.get("styleselect")){if(k.className){y._importClasses();m.select(k.className)}else{m.select()}}if(m=u.get("formatselect")){i=d.getParent(k,d.isBlock);if(i){m.select(i.nodeName.toLowerCase())}}if(l.settings.convert_fonts_to_spans){l.dom.getParent(k,function(p){if(p.nodeName==="SPAN"){if(!w&&p.className){w=p.className}if(!j&&p.style.fontSize){j=p.style.fontSize}if(!o&&p.style.fontFamily){o=p.style.fontFamily.replace(/[\"\']+/g,"").replace(/^([^,]+).*/,"$1").toLowerCase()}}return false});if(m=u.get("fontselect")){m.select(function(n){return n.replace(/^([^,]+).*/,"$1").toLowerCase()==o})}if(m=u.get("fontsizeselect")){m.select(function(n){if(n.fontSize&&n.fontSize===j){return true}if(n["class"]&&n["class"]===w){return true}})}}else{if(m=u.get("fontselect")){m.select(l.queryCommandValue("FontName"))}if(m=u.get("fontsizeselect")){x=l.queryCommandValue("FontSize");m.select(function(n){return n.fontSize==x})}}if(z.theme_advanced_path&&z.theme_advanced_statusbar_location){i=d.get(l.id+"_path")||d.add(l.id+"_path_row","span",{id:l.id+"_path"});d.setHTML(i,"");l.dom.getParent(k,function(A){var p=A.nodeName.toLowerCase(),s,v,t="";if(A.nodeType!=1||A.nodeName==="BR"||(d.hasClass(A,"mceItemHidden")||d.hasClass(A,"mceItemRemoved"))){return}if(x=d.getAttrib(A,"mce_name")){p=x}if(e.isIE&&A.scopeName!=="HTML"){p=A.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(A,"src")){t+="src: "+x+" "}break;case"a":if(x=d.getAttrib(A,"name")){t+="name: "+x+" ";p+="#"+x}if(x=d.getAttrib(A,"href")){t+="href: "+x+" "}break;case"font":if(z.convert_fonts_to_spans){p="span"}if(x=d.getAttrib(A,"face")){t+="font: "+x+" "}if(x=d.getAttrib(A,"size")){t+="size: "+x+" "}if(x=d.getAttrib(A,"color")){t+="color: "+x+" "}break;case"span":if(x=d.getAttrib(A,"style")){t+="style: "+x+" "}break}if(x=d.getAttrib(A,"id")){t+="id: "+x+" "}if(x=A.className){x=x.replace(/(webkit-[\w\-]+|Apple-[\w\-]+|mceItem\w+|mceVisualAid)/g,"");if(x&&x.indexOf("mceItem")==-1){t+="class: "+x+" ";if(d.isBlock(A)||p=="img"||p=="span"){p+="."+x}}}p=p.replace(/(html:)/g,"");p={name:p,node:A,title:t};y.onResolveName.dispatch(y,p);t=p.title;p=p.name;v=d.create("a",{href:"javascript:;",onmousedown:"return false;",title:t,"class":"mcePath_"+(r++)},p);if(i.hasChildNodes()){i.insertBefore(d.doc.createTextNode(" \u00bb "),i.firstChild);i.insertBefore(v,i.firstChild)}else{i.appendChild(v)}},l.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
index 757b633e1e9a492cf634295625e87d719eab810a..21eb259a205a9da0d3c46f24deb13b0b309b8ff9 100644 (file)
@@ -1,17 +1,19 @@
 /**\r
- * $Id: editor_template_src.js 852 2008-05-27 05:52:09Z spocke $\r
+ * $Id: editor_template_src.js 1045 2009-03-04 20:03:18Z spocke $\r
  *\r
  * @author Moxiecode\r
  * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.\r
  */\r
 \r
-(function() {\r
+(function(tinymce) {\r
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID, explode = tinymce.explode;\r
 \r
        // Tell it to load theme specific language pack(s)\r
        tinymce.ThemeManager.requireLangPack('advanced');\r
 \r
        tinymce.create('tinymce.themes.AdvancedTheme', {\r
+               sizes : [8, 10, 12, 14, 18, 24, 36],\r
+\r
                // Control name lookup, format: title, command\r
                controls : {\r
                        bold : ['bold_desc', 'Bold'],\r
@@ -55,7 +57,7 @@
                stateControls : ['bold', 'italic', 'underline', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'sub', 'sup', 'blockquote'],\r
 \r
                init : function(ed, url) {\r
-                       var t = this, s, v;\r
+                       var t = this, s, v, o;\r
        \r
                        t.editor = ed;\r
                        t.url = url;\r
                                theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6",\r
                                theme_advanced_toolbar_align : "center",\r
                                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",\r
-                               theme_advanced_font_sizes : "1,2,3,4,5,6,7",\r
                                theme_advanced_more_colors : 1,\r
                                theme_advanced_row_height : 23,\r
                                theme_advanced_resize_horizontal : 1,\r
-                               theme_advanced_resizing_use_cookie : 1\r
+                               theme_advanced_resizing_use_cookie : 1,\r
+                               theme_advanced_font_sizes : "1,2,3,4,5,6,7",\r
+                               readonly : ed.settings.readonly\r
                        }, ed.settings);\r
 \r
+                       // Setup default font_size_style_values\r
+                       if (!s.font_size_style_values)\r
+                               s.font_size_style_values = "8pt,10pt,12pt,14pt,18pt,24pt,36pt";\r
+\r
+                       if (tinymce.is(s.theme_advanced_font_sizes, 'string')) {\r
+                               s.font_size_style_values = tinymce.explode(s.font_size_style_values);\r
+                               s.font_size_classes = tinymce.explode(s.font_size_classes || '');\r
+\r
+                               // Parse string value\r
+                               o = {};\r
+                               ed.settings.theme_advanced_font_sizes = s.theme_advanced_font_sizes;\r
+                               each(ed.getParam('theme_advanced_font_sizes', '', 'hash'), function(v, k) {\r
+                                       var cl;\r
+\r
+                                       if (k == v && v >= 1 && v <= 7) {\r
+                                               k = v + ' (' + t.sizes[v - 1] + 'pt)';\r
+\r
+                                               if (ed.settings.convert_fonts_to_spans) {\r
+                                                       cl = s.font_size_classes[v - 1];\r
+                                                       v = s.font_size_style_values[v - 1] || (t.sizes[v - 1] + 'pt');\r
+                                               }\r
+                                       }\r
+\r
+                                       if (/^\s*\./.test(v))\r
+                                               cl = v.replace(/\./g, '');\r
+\r
+                                       o[k] = cl ? {'class' : cl} : {fontSize : v};\r
+                               });\r
+\r
+                               s.theme_advanced_font_sizes = o;\r
+                       }\r
+\r
                        if ((v = s.theme_advanced_path_location) && v != 'none')\r
                                s.theme_advanced_statusbar_location = s.theme_advanced_path_location;\r
 \r
                                }\r
                        });\r
 \r
-                       DOM.loadCSS(ed.baseURI.toAbsolute(s.editor_css || "themes/advanced/skins/" + ed.settings.skin + "/ui.css"));\r
+                       DOM.loadCSS(s.editor_css ? ed.documentBaseURI.toAbsolute(s.editor_css) : url + "/skins/" + ed.settings.skin + "/ui.css");\r
 \r
                        if (s.skin_variant)\r
-                               DOM.loadCSS(ed.baseURI.toAbsolute(s.editor_css || "themes/advanced/skins/" + ed.settings.skin + "/ui_" + s.skin_variant + ".css"));\r
+                               DOM.loadCSS(url + "/skins/" + ed.settings.skin + "/ui_" + s.skin_variant + ".css");\r
                },\r
 \r
                createControl : function(n, cf) {\r
                                });\r
 \r
                                c.onPostRender.add(function(ed, n) {\r
-                                       Event.add(n.id + '_text', 'focus', t._importClasses, t);\r
-                                       Event.add(n.id + '_text', 'mousedown', t._importClasses, t);\r
+                                       if (!c.NativeListBox) {\r
+                                               Event.add(n.id + '_text', 'focus', t._importClasses, t);\r
+                                               Event.add(n.id + '_text', 'mousedown', t._importClasses, t);\r
+                                               Event.add(n.id + '_open', 'focus', t._importClasses, t);\r
+                                               Event.add(n.id + '_open', 'mousedown', t._importClasses, t);\r
+                                       } else\r
+                                               Event.add(n.id, 'focus', t._importClasses, t);\r
                                });\r
                        }\r
 \r
                },\r
 \r
                _createFontSizeSelect : function() {\r
-                       var t = this, ed = t.editor, c, lo = [\r
-                               "1 (8 pt)",\r
-                               "2 (10 pt)",\r
-                               "3 (12 pt)",\r
-                               "4 (14 pt)",\r
-                               "5 (18 pt)",\r
-                               "6 (24 pt)",\r
-                               "7 (36 pt)"\r
-                       ], fz = [8, 10, 12, 14, 18, 24, 36];\r
-\r
-                       c = ed.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', cmd : 'FontSize'});\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
+                               if (v.fontSize)\r
+                                       ed.execCommand('FontSize', false, v.fontSize);\r
+                               else {\r
+                                       each(t.settings.theme_advanced_font_sizes, function(v, k) {\r
+                                               if (v['class'])\r
+                                                       cl.push(v['class']);\r
+                                       });\r
+\r
+                                       ed.editorCommands._applyInlineStyle('span', {'class' : v['class']}, {check_classes : cl});\r
+                               }\r
+                       }});\r
+\r
                        if (c) {\r
-                               each(ed.getParam('theme_advanced_font_sizes', t.settings.theme_advanced_font_sizes, 'hash'), function(v, k) {\r
-                                       c.add(k != v ? k : lo[parseInt(v) - 1], v, {'style' : 'font-size:' + fz[v - 1] + 'pt', 'class' : 'mceFontSize' + v});\r
+                               each(t.settings.theme_advanced_font_sizes, function(v, k) {\r
+                                       var fz = v.fontSize;\r
+\r
+                                       if (fz >= 1 && fz <= 7)\r
+                                               fz = t.sizes[parseInt(fz) - 1] + 'pt';\r
+\r
+                                       c.add(k, v, {'style' : 'font-size:' + fz, 'class' : 'mceFontSize' + (i++) + (' ' + (v['class'] || ''))});\r
                                });\r
                        }\r
 \r
                        if (v = s.theme_advanced_text_colors)\r
                                o.colors = v;\r
 \r
+                       if (s.theme_advanced_default_foreground_color)\r
+                               o.default_color = s.theme_advanced_default_foreground_color;\r
+\r
                        o.title = 'advanced.forecolor_desc';\r
                        o.cmd = 'ForeColor';\r
                        o.scope = this;\r
                        if (v = s.theme_advanced_background_colors)\r
                                o.colors = v;\r
 \r
+                       if (s.theme_advanced_default_background_color)\r
+                               o.default_color = s.theme_advanced_default_background_color;\r
+\r
                        o.title = 'advanced.backcolor_desc';\r
                        o.cmd = 'HiliteColor';\r
                        o.scope = this;\r
                        }\r
 */\r
 \r
-                       if (!ed.getParam('accessibility_focus') || ed.getParam('tab_focus'))\r
+                       if (!ed.getParam('accessibility_focus'))\r
                                Event.add(DOM.add(p, 'a', {href : '#'}, '<!-- IE -->'), 'focus', function() {tinyMCE.get(ed.id).focus();});\r
 \r
                        if (s.theme_advanced_toolbar_location == 'external')\r
                _simpleLayout : function(s, tb, o, p) {\r
                        var t = this, ed = t.editor, lo = s.theme_advanced_toolbar_location, sl = s.theme_advanced_statusbar_location, n, ic, etb, c;\r
 \r
+                       if (s.readonly) {\r
+                               n = DOM.add(tb, 'tr');\r
+                               n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'});\r
+                               return ic;\r
+                       }\r
+\r
                        // Create toolbar container at top\r
                        if (lo == 'top')\r
                                t._addToolbars(tb, o);\r
 \r
                        n = DOM.add(DOM.add(c, 'tr'), 'td', {'class' : 'mceToolbar ' + a});\r
 \r
-                       if (!ed.getParam('accessibility_focus') || ed.getParam('tab_focus'))\r
+                       if (!ed.getParam('accessibility_focus'))\r
                                h.push(DOM.createHTML('a', {href : '#', onfocus : 'tinyMCE.get(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));\r
 \r
                        h.push(DOM.createHTML('a', {href : '#', accesskey : 'q', title : ed.getLang("advanced.toolbar_focus")}, '<!-- IE -->'));\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') + ': ' : '&nbsp;');\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
 \r
-                       if (s.theme_advanced_resizing && !tinymce.isOldWebKit) {\r
+                       if (s.theme_advanced_resizing) {\r
                                DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize'});\r
 \r
                                if (s.theme_advanced_resizing_use_cookie) {\r
                },\r
 \r
                _nodeChanged : function(ed, cm, n, co) {\r
-                       var t = this, p, de = 0, v, c, s = t.settings;\r
+                       var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn;\r
+\r
+                       if (s.readonly)\r
+                               return;\r
 \r
                        tinymce.each(t.stateControls, function(c) {\r
                                cm.setActive(c, ed.queryCommandState(t.controls[c][1]));\r
                                        c.select(p.nodeName.toLowerCase());\r
                        }\r
 \r
-                       if (c = cm.get('fontselect'))\r
-                               c.select(ed.queryCommandValue('FontName'));\r
+                       if (ed.settings.convert_fonts_to_spans) {\r
+                               ed.dom.getParent(n, function(n) {\r
+                                       if (n.nodeName === 'SPAN') {\r
+                                               if (!cl && n.className)\r
+                                                       cl = n.className;\r
+\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
 \r
-                       if (c = cm.get('fontsizeselect'))\r
-                               c.select('' + ed.queryCommandValue('FontSize'));\r
+                                       return false;\r
+                               });\r
+\r
+                               if (c = cm.get('fontselect')) {\r
+                                       c.select(function(v) {\r
+                                               return v.replace(/^([^,]+).*/, '$1').toLowerCase() == fn;\r
+                                       });\r
+                               }\r
+\r
+                               if (c = cm.get('fontsizeselect')) {\r
+                                       c.select(function(v) {\r
+                                               if (v.fontSize && v.fontSize === fz)\r
+                                                       return true;\r
+\r
+                                               if (v['class'] && v['class'] === cl)\r
+                                                       return true;\r
+                                       });\r
+                               }\r
+                       } else {\r
+                               if (c = cm.get('fontselect'))\r
+                                       c.select(ed.queryCommandValue('FontName'));\r
+\r
+                               if (c = cm.get('fontsizeselect')) {\r
+                                       v = ed.queryCommandValue('FontSize');\r
+                                       c.select(function(iv) {\r
+                                               return iv.fontSize == v;\r
+                                       });\r
+                               }\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
                                        var na = n.nodeName.toLowerCase(), u, pi, ti = '';\r
 \r
                                        // Ignore non element and hidden elements\r
-                                       if (n.nodeType != 1 || (DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved')))\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
+\r
                                        // Handle prefix\r
                                        if (tinymce.isIE && n.scopeName !== 'HTML')\r
                                                na = n.scopeName + ':' + na;\r
        });\r
 \r
        tinymce.ThemeManager.add('advanced', tinymce.themes.AdvancedTheme);\r
-}());
\ No newline at end of file
+}(tinymce));
\ No newline at end of file
index 6c366469c3ec341814cf376c9cc96aebd7d92caa..7ec1052ba54a6813ce9ddb4820037bca3fb10680 100644 (file)
@@ -6,7 +6,6 @@
        <script type="text/javascript" src="../../utils/mctabs.js"></script>\r
        <script type="text/javascript" src="../../utils/form_utils.js"></script>\r
        <script type="text/javascript" src="js/image.js"></script>\r
-       <base target="_self" />\r
 </head>\r
 <body id="image" style="display: none">\r
 <form onsubmit="ImageDialog.update();return false;" action="#">\r
@@ -20,7 +19,7 @@
                <div id="general_panel" class="panel current">\r
      <table border="0" cellpadding="4" cellspacing="0">\r
           <tr>\r
-            <td nowrap="nowrap"><label for="src">{#advanced_dlg.image_src}</label></td>\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><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 nowrap="nowrap"><label for="alt">{#advanced_dlg.image_alt}</label></td>\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 nowrap="nowrap"><label for="align">{#advanced_dlg.image_align}</label></td>\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
               </select></td>\r
           </tr>\r
           <tr>\r
-            <td nowrap="nowrap"><label for="width">{#advanced_dlg.image_dimensions}</label></td>\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 nowrap="nowrap"><label for="border">{#advanced_dlg.image_border}</label></td>\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 nowrap="nowrap"><label for="vspace">{#advanced_dlg.image_vspace}</label></td>\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 nowrap="nowrap"><label for="hspace">{#advanced_dlg.image_hspace}</label></td>\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
index 9081e1ddc0cd2056f44c5f530a0b7d312b01ab4f..5cee9ed863cdb6ffaf6cc44979375c1beb9cd920 100644 (file)
@@ -7,7 +7,7 @@ function init() {
        ed = tinyMCEPopup.editor;\r
 \r
        // Give FF some time\r
-       window.setTimeout('insertHelpIFrame();', 10);\r
+       window.setTimeout(insertHelpIFrame, 10);\r
 \r
        tcont = document.getElementById('plugintablecontainer');\r
        document.getElementById('plugins_tab').style.display = 'none';\r
index 2974878e1e18c7e1a77545f336bbec847944bba3..21aae6cbf88d18f497fe093e95422656365d7a15 100644 (file)
@@ -53,6 +53,7 @@ var LinkDialog = {
 \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
 \r
                        tinymce.each(ed.dom.select("a"), function(n) {\r
@@ -92,7 +93,7 @@ var LinkDialog = {
                if (n.value && Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_email')))\r
                        n.value = 'mailto:' + n.value;\r
 \r
-               if (/^\s*www./i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_external')))\r
+               if (/^\s*www\./i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_external')))\r
                        n.value = 'http://' + n.value;\r
        },\r
 \r
index af2231cad57d78dacbeb616c231e58a4669ecadb..279328614c5ee8a0077295a0ff7814a24d723922 100644 (file)
@@ -2,7 +2,7 @@ tinyMCEPopup.requireLangPack();
 tinyMCEPopup.onInit.add(onLoadInit);\r
 \r
 function saveContent() {\r
-       tinyMCEPopup.editor.setContent(document.getElementById('htmlSource').value);\r
+       tinyMCEPopup.editor.setContent(document.getElementById('htmlSource').value, {source_view : true});\r
        tinyMCEPopup.close();\r
 }\r
 \r
@@ -13,7 +13,7 @@ function onLoadInit() {
        if (tinymce.isGecko)\r
                document.body.spellcheck = tinyMCEPopup.editor.getParam("gecko_spellcheck");\r
 \r
-       document.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent();\r
+       document.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent({source_view : true});\r
 \r
        if (tinyMCEPopup.editor.getParam("theme_advanced_source_editor_wrap", true)) {\r
                setWrap('soft');\r
index 286cc92479c80f95a03ce04dc8589b21bb43655e..a78bd334d5ec42983537585b90c3ecba287cf908 100644 (file)
@@ -7,7 +7,6 @@
        <script type="text/javascript" src="../../utils/form_utils.js"></script>\r
        <script type="text/javascript" src="../../utils/validate.js"></script>\r
        <script type="text/javascript" src="js/link.js"></script>\r
-       <base target="_self" />\r
 </head>\r
 <body id="link" style="display: none">\r
 <form onsubmit="LinkDialog.update();return false;" action="#">\r
@@ -22,7 +21,7 @@
 \r
                <table border="0" cellpadding="4" cellspacing="0">\r
           <tr>\r
-            <td nowrap="nowrap"><label for="href">{#advanced_dlg.link_url}</label></td>\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
@@ -39,7 +38,7 @@
                        <td><select id="target_list" name="target_list"></select></td>\r
                </tr>\r
           <tr>\r
-            <td nowrap="nowrap"><label for="linktitle">{#advanced_dlg.link_titlefield}</label></td>\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
index c944a60ba03a91192e345e12ef79028ac6d89608..873c67e3c449b3a9386cee5a6f296ce45a2cdafb 100644 (file)
@@ -19,6 +19,7 @@ td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;}
 textarea {resize:none;outline:none;}\r
 a:link, a:visited {color:black;}\r
 a:hover {color:#2B6FB6;}\r
+.nowrap {white-space: nowrap}\r
 \r
 /* Forms */\r
 fieldset {margin:0; padding:4px; border:1px solid #919B9C; font-family:Verdana, Arial; font-size:10px;}\r
@@ -47,10 +48,11 @@ padding-bottom:2px;
 #cancel {background:url(img/buttons.png) 0 0;}\r
 \r
 /* Browse */\r
+a.pickcolor, a.browse {text-decoration:none}\r
 a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;}\r
 .mceOldBoxModel a.browse span {width:22px; height:20px;}\r
 a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;}\r
-a.browse span.disabled {border:1px solid white; -moz-opacity:0.3; opacity:0.3; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);}\r
+a.browse span.disabled {border:1px solid white; opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\r
 a.browse:hover span.disabled {border:1px solid white; background-color:transparent;}\r
 a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;}\r
 .mceOldBoxModel a.pickcolor span {width:21px; height:17px;}\r
index 7e202a71a38b70a6fa2eb7f36d00ff1825e243ad..230a2ee288dacbbe3bb029a1b442b6cc974fddfc 100644 (file)
@@ -37,7 +37,7 @@
 .defaultSkin .mceButton {display:block; border:1px solid #F0F0EE; width:20px; height:20px; margin-right:1px}\r
 .defaultSkin a.mceButtonEnabled:hover {border:1px solid #0A246A; background-color:#B2BBD0}\r
 .defaultSkin a.mceButtonActive, .defaultSkin a.mceButtonSelected {border:1px solid #0A246A; background-color:#C2CBE0}\r
-.defaultSkin .mceButtonDisabled .mceIcon {opacity:0.3; filter:alpha(opacity=30)}\r
+.defaultSkin .mceButtonDisabled .mceIcon {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\r
 .defaultSkin .mceButtonLabeled {width:auto}\r
 .defaultSkin .mceButtonLabeled span.mceIcon {float:left}\r
 .defaultSkin span.mceButtonLabel {display:block; font-size:10px; padding:4px 6px 0 22px; font-family:Tahoma,Verdana,Arial,Helvetica}\r
 .defaultSkin .mceSplitButton a, .defaultSkin .mceSplitButton span {height:20px; display:block}\r
 .defaultSkin .mceSplitButton a.mceAction {width:20px; border:1px solid #F0F0EE; border-right:0;}\r
 .defaultSkin .mceSplitButton span.mceAction {width:20px; background:url(../../img/icons.gif) 20px 20px;}\r
-.defaultSkin .mceSplitButton a.mceOpen {width:9px; border:1px solid #F0F0EE;}\r
-.defaultSkin .mceSplitButton span.mceOpen {width:9px; background:url(../../img/icons.gif) -741px 0;}\r
+.defaultSkin .mceSplitButton a.mceOpen {width:9px; background:url(../../img/icons.gif) -741px 0; border:1px solid #F0F0EE;}\r
+.defaultSkin .mceSplitButton span.mceOpen {display:none}\r
 .defaultSkin table.mceSplitButtonEnabled:hover a.mceAction, .defaultSkin .mceSplitButtonHover a.mceAction, .defaultSkin .mceSplitButtonSelected a.mceAction {border:1px solid #0A246A; border-right:0; background-color:#B2BBD0}\r
-.defaultSkin table.mceSplitButtonEnabled:hover a.mceOpen, .defaultSkin .mceSplitButtonHover a.mceOpen, .defaultSkin .mceSplitButtonSelected a.mceOpen {border:1px solid #0A246A;}\r
-.defaultSkin table.mceSplitButtonEnabled:hover span.mceOpen, .defaultSkin .mceSplitButtonHover span.mceOpen, .defaultSkin .mceSplitButtonSelected span.mceOpen {background-color:#B2BBD0}\r
-.defaultSkin .mceSplitButtonDisabled .mceAction, .defaultSkin .mceSplitButtonDisabled span.mceOpen {opacity:0.3; filter:alpha(opacity=30)}\r
+.defaultSkin table.mceSplitButtonEnabled:hover a.mceOpen, .defaultSkin .mceSplitButtonHover a.mceOpen, .defaultSkin .mceSplitButtonSelected a.mceOpen {background-color:#B2BBD0; border:1px solid #0A246A;}\r
+.defaultSkin .mceSplitButtonDisabled .mceAction, .defaultSkin .mceSplitButtonDisabled a.mceOpen {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\r
 .defaultSkin .mceSplitButtonActive a.mceAction {border:1px solid #0A246A; background-color:#C2CBE0}\r
 .defaultSkin .mceSplitButtonActive a.mceOpen {border-left:0;}\r
 \r
 .defaultSkin .mceMenuItemSub a {background:url(img/menu_arrow.gif) no-repeat top right;}\r
 \r
 /* Progress,Resize */\r
-.defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; filter:alpha(opacity=50); background:#FFF}\r
+.defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50); background:#FFF}\r
 .defaultSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}\r
 .defaultSkin .mcePlaceHolder {border:1px dotted gray}\r
 \r
index e36042e645e0f7d2cefa2ace09f48ab3e4d62410..6c37d6fb8395556422d93a9668f68c93f82b7b55 100644 (file)
@@ -19,6 +19,7 @@ td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;}
 textarea {resize:none;outline:none;}\r
 a:link, a:visited {color:black;}\r
 a:hover {color:#2B6FB6;}\r
+.nowrap {white-space: nowrap}\r
 \r
 /* Forms */\r
 fieldset {margin:0; padding:4px; border:1px solid #919B9C; font-family:Verdana, Arial; font-size:10px;}\r
@@ -47,10 +48,11 @@ padding-bottom:2px;
 #cancel {background:url(../default/img/buttons.png) 0 0;}\r
 \r
 /* Browse */\r
+a.pickcolor, a.browse {text-decoration:none}\r
 a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;}\r
 .mceOldBoxModel a.browse span {width:22px; height:20px;}\r
 a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;}\r
-a.browse span.disabled {border:1px solid white; -moz-opacity:0.3; opacity:0.3; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);}\r
+a.browse span.disabled {border:1px solid white; opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\r
 a.browse:hover span.disabled {border:1px solid white; background-color:transparent;}\r
 a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;}\r
 .mceOldBoxModel a.pickcolor span {width:21px; height:17px;}\r
index 0da56e9112e7704d3654d0895cbb327dac31ec84..c10a3f0161f642bd3fee6da3538aaf44abefd921 100644 (file)
@@ -40,7 +40,7 @@
 .o2k7Skin .mceOldBoxModel a.mceButton span, .o2k7Skin .mceOldBoxModel a.mceButton img {margin:0 0 0 1px}\r
 .o2k7Skin a.mceButtonEnabled:hover {background-color:#B2BBD0; background-position:0 -22px}\r
 .o2k7Skin a.mceButtonActive, .o2k7Skin a.mceButtonSelected {background-position:0 -44px}\r
-.o2k7Skin .mceButtonDisabled .mceIcon {opacity:0.3; filter:alpha(opacity=30)}\r
+.o2k7Skin .mceButtonDisabled .mceIcon {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\r
 .o2k7Skin .mceButtonLabeled {width:auto}\r
 .o2k7Skin .mceButtonLabeled span.mceIcon {float:left}\r
 .o2k7Skin span.mceButtonLabel {display:block; font-size:10px; padding:4px 6px 0 22px; font-family:Tahoma,Verdana,Arial,Helvetica}\r
 .o2k7Skin .mceSplitButton {background:url(img/button_bg.png)}\r
 .o2k7Skin .mceSplitButton a.mceAction {width:22px}\r
 .o2k7Skin .mceSplitButton span.mceAction {width:22px; background:url(../../img/icons.gif) 20px 20px}\r
-.o2k7Skin .mceSplitButton a.mceOpen {width:10px}\r
-.o2k7Skin .mceSplitButton span.mceOpen {width:10px; background:url(img/button_bg.png) -44px 0}\r
+.o2k7Skin .mceSplitButton a.mceOpen {width:10px; background:url(img/button_bg.png) -44px 0}\r
+.o2k7Skin .mceSplitButton span.mceOpen {display:none}\r
 .o2k7Skin table.mceSplitButtonEnabled:hover a.mceAction, .o2k7Skin .mceSplitButtonHover a.mceAction, .o2k7Skin .mceSplitButtonSelected {background:url(img/button_bg.png) 0 -22px}\r
-.o2k7Skin table.mceSplitButtonEnabled:hover span.mceOpen, .o2k7Skin .mceSplitButtonHover span.mceOpen, .o2k7Skin .mceSplitButtonSelected span.mceOpen {background-position:-44px -44px}\r
-.o2k7Skin .mceSplitButtonDisabled .mceAction {opacity:0.3; filter:alpha(opacity=30)}\r
+.o2k7Skin table.mceSplitButtonEnabled:hover a.mceOpen, .o2k7Skin .mceSplitButtonHover a.mceOpen, .o2k7Skin .mceSplitButtonSelected a.mceOpen {background-position:-44px -44px}\r
+.o2k7Skin .mceSplitButtonDisabled .mceAction {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\r
 .o2k7Skin .mceSplitButtonActive {background-position:0 -44px}\r
 \r
 /* ColorSplitButton */\r
 .o2k7Skin .mceMenuItemSub a {background:url(../default/img/menu_arrow.gif) no-repeat top right;}\r
 \r
 /* Progress,Resize */\r
-.o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; filter:alpha(opacity=50); background:#FFF}\r
+.o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}\r
 .o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}\r
 .o2k7Skin .mcePlaceHolder {border:1px dotted gray}\r
 \r
index a42a727abc0689962ba859d93bcb55f098ff6de6..153f0c38a6c69b897b9d7dbb5fd66a75991048bc 100644 (file)
@@ -1,8 +1,8 @@
 /* Black */\r
-.o2k7SkinBlack .mceToolbar .mceToolbarStart span, .o2k7SkinBlack .mceToolbar .mceToolbarEnd span, .o2k7SkinBlack .mceButton, .o2k7SkinBlack .mceSplitButton, .o2k7SkinBlack .mceSeparator, .o2k7SkinBlack .mceSplitButton span.mceOpen, .o2k7SkinBlack .mceListBox .mceOpen {background-image:url(img/button_bg_black.png)}\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 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, .o2k7Skin .mceListBoxHover .mceText, .o2k7Skin .mceListBoxSelected .mceText {background:#FFF; border:1px solid #FFBD69; 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
-.o2k7SkinBlack table.mceSplitButtonEnabled:hover a.mceAction, .o2k7Skin .mceSplitButtonHover a.mceAction, .o2k7Skin .mceSplitButtonSelected {background-image:url(img/button_bg_black.png)}\r
-.o2k7SkinBlack .mceMenu .mceMenuItemEnabled a:hover, .o2k7Skin .mceMenu .mceMenuItemActive {background-color:#FFE7A1}
\ No newline at end of file
+.o2k7SkinBlack table.mceSplitButtonEnabled:hover a.mceAction, .o2k7SkinBlack .mceSplitButtonHover a.mceAction, .o2k7SkinBlack .mceSplitButtonSelected {background-image:url(img/button_bg_black.png)}\r
+.o2k7SkinBlack .mceMenu .mceMenuItemEnabled a:hover, .o2k7SkinBlack .mceMenu .mceMenuItemActive {background-color:#FFE7A1}
\ No newline at end of file
index 548b1b852b2288c242da265b14b11225ca4259bb..7fe3b45e1264ad10f89c696ecc3b0e0801a96653 100644 (file)
@@ -1,5 +1,5 @@
 /* Silver */\r
-.o2k7SkinSilver .mceToolbar .mceToolbarStart span, .o2k7SkinSilver .mceButton, .o2k7SkinSilver .mceSplitButton, .o2k7SkinSilver .mceSeparator, .o2k7SkinSilver .mceSplitButton span.mceOpen, .o2k7SkinSilver .mceListBox .mceOpen {background-image:url(img/button_bg_silver.png)}\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 .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 119a913c93062ebc345b9caed7843a3c0538326f..553e7bb2bc734587ba964e703bd2e2374abe8b0b 100644 (file)
@@ -4,7 +4,6 @@
        <title>{#advanced_dlg.code_title}</title>\r
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="js/source_editor.js"></script>\r
-       <base target="_self" />\r
 </head>\r
 <body onresize="resizeInputs();" style="display:none; overflow:hidden;">\r
        <form name="source" onsubmit="saveContent();return false;" action="#">\r
index 3a25c04d648d4511598185f8c13e7c1d7bf38577..ed89abc067613b25c124f6e39af8b7d498ad0714 100644 (file)
@@ -1 +1 @@
-(function(){var DOM=tinymce.DOM;tinymce.ThemeManager.requireLangPack('simple');tinymce.create('tinymce.themes.SimpleTheme',{init:function(ed,url){var t=this,states=['Bold','Italic','Underline','Strikethrough','InsertUnorderedList','InsertOrderedList'],s=ed.settings;t.editor=ed;ed.onInit.add(function(){ed.onNodeChange.add(function(ed,cm){tinymce.each(states,function(c){cm.get(c.toLowerCase()).setActive(ed.queryCommandState(c));});});ed.dom.loadCSS(url+"/skins/"+s.skin+"/content.css");});DOM.loadCSS((s.editor_css?ed.baseURI.toAbsolute(s.editor_css):'')||url+"/skins/"+s.skin+"/ui.css");},renderUI:function(o){var t=this,n=o.targetNode,ic,tb,ed=t.editor,cf=ed.controlManager,sc;n=DOM.insertAfter(DOM.create('span',{id:ed.id+'_container','class':'mceEditor '+ed.settings.skin+'SimpleSkin'}),n);n=sc=DOM.add(n,'table',{cellPadding:0,cellSpacing:0,'class':'mceLayout'});n=tb=DOM.add(n,'tbody');n=DOM.add(tb,'tr');n=ic=DOM.add(DOM.add(n,'td'),'div',{'class':'mceIframeContainer'});n=DOM.add(DOM.add(tb,'tr',{'class':'last'}),'td',{'class':'mceToolbar mceLast',align:'center'});tb=t.toolbar=cf.createToolbar("tools1");tb.add(cf.createButton('bold',{title:'simple.bold_desc',cmd:'Bold'}));tb.add(cf.createButton('italic',{title:'simple.italic_desc',cmd:'Italic'}));tb.add(cf.createButton('underline',{title:'simple.underline_desc',cmd:'Underline'}));tb.add(cf.createButton('strikethrough',{title:'simple.striketrough_desc',cmd:'Strikethrough'}));tb.add(cf.createSeparator());tb.add(cf.createButton('undo',{title:'simple.undo_desc',cmd:'Undo'}));tb.add(cf.createButton('redo',{title:'simple.redo_desc',cmd:'Redo'}));tb.add(cf.createSeparator());tb.add(cf.createButton('cleanup',{title:'simple.cleanup_desc',cmd:'mceCleanup'}));tb.add(cf.createSeparator());tb.add(cf.createButton('insertunorderedlist',{title:'simple.bullist_desc',cmd:'InsertUnorderedList'}));tb.add(cf.createButton('insertorderedlist',{title:'simple.numlist_desc',cmd:'InsertOrderedList'}));tb.renderTo(n);return{iframeContainer:ic,editorContainer:ed.id+'_container',sizeContainer:sc,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.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
index adc4492ab1d2f45d20ec5ee068e8b3faa4f47fb5..fb0bd7893b9bfb2db17c33c309a46cbd54b0791f 100644 (file)
@@ -1,5 +1,5 @@
 /**\r
- * $Id: editor_template_src.js 752 2008-03-27 21:51:25Z spocke $\r
+ * $Id: editor_template_src.js 920 2008-09-09 14:05:33Z spocke $\r
  *\r
  * This file is meant to showcase how to create a simple theme. The advanced\r
  * theme is more suitable for production use.\r
@@ -30,7 +30,7 @@
                                ed.dom.loadCSS(url + "/skins/" + s.skin + "/content.css");\r
                        });\r
 \r
-                       DOM.loadCSS((s.editor_css ? ed.baseURI.toAbsolute(s.editor_css) : '') || url + "/skins/" + s.skin + "/ui.css");\r
+                       DOM.loadCSS((s.editor_css ? ed.documentBaseURI.toAbsolute(s.editor_css) : '') || url + "/skins/" + s.skin + "/ui.css");\r
                },\r
 \r
                renderUI : function(o) {\r
index 1cf64b8dc365c9b71da381d835fcc1b4c99216a3..076fe84e3440ee67baccc93a4f42943b419bb2a9 100644 (file)
@@ -15,7 +15,7 @@
 .defaultSimpleSkin .mceButton {display:block; border:1px solid #F0F0EE; width:20px; height:20px}\r
 .defaultSimpleSkin a.mceButtonEnabled:hover {border:1px solid #0A246A; background-color:#B2BBD0}\r
 .defaultSimpleSkin a.mceButtonActive {border:1px solid #0A246A; background-color:#C2CBE0}\r
-.defaultSimpleSkin .mceButtonDisabled span {opacity:0.3; filter:alpha(opacity=30)}\r
+.defaultSimpleSkin .mceButtonDisabled span {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\r
 \r
 /* Separator */\r
 .defaultSimpleSkin .mceSeparator {display:block; background:url(../../img/icons.gif) -180px 0; width:2px; height:20px; margin:0 2px 0 4px}\r
index bfae96e2d0a4cdd6d6d076ad24bd77f9d9104cde..cf6c35d109346c5e66d7fcbfe37830eec881d73b 100644 (file)
@@ -18,7 +18,7 @@
 .o2k7SimpleSkin a.mceButton span, .o2k7SimpleSkin a.mceButton img {margin:1px 0 0 1px}\r
 .o2k7SimpleSkin a.mceButtonEnabled:hover {background-color:#B2BBD0; background-position:0 -22px}\r
 .o2k7SimpleSkin a.mceButtonActive {background-position:0 -44px}\r
-.o2k7SimpleSkin .mceButtonDisabled span {opacity:0.3; filter:alpha(opacity=30)}\r
+.o2k7SimpleSkin .mceButtonDisabled span {opacity:0.3; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=30)}\r
 \r
 /* Separator */\r
 .o2k7SimpleSkin .mceSeparator {display:block; background:url(img/button_bg.png) -22px 0; width:5px; height:22px}\r
index 72087e80aa035b40369abd226108f089c2b98f30..447ea07ed55065beed55b1ee3acc555baaa05177 100644 (file)
@@ -1 +1 @@
-var tinymce={majorVersion:'3',minorVersion:'1.0.1',releaseDate:'2008-06-18',_init:function(){var t=this,d=document,w=window,na=navigator,ua=na.userAgent,i,nl,n,base,p,v;t.isOpera=w.opera&&opera.buildNumber;t.isWebKit=/WebKit/.test(ua);t.isOldWebKit=t.isWebKit&&!w.getSelection().getRangeAt;t.isIE=!t.isWebKit&&!t.isOpera&&(/MSIE/gi).test(ua)&&(/Explorer/gi).test(na.appName);t.isIE6=t.isIE&&/MSIE [56]/.test(ua);t.isGecko=!t.isWebKit&&/Gecko/.test(ua);t.isMac=ua.indexOf('Mac')!=-1;if(w.tinyMCEPreInit){t.suffix=tinyMCEPreInit.suffix;t.baseURL=tinyMCEPreInit.base;t.query=tinyMCEPreInit.query;return;}t.suffix='';nl=d.getElementsByTagName('base');for(i=0;i<nl.length;i++){if(v=nl[i].href){if(/^https?:\/\/[^\/]+$/.test(v))v+='/';base=v?v.match(/.*\//)[0]:'';}}function getBase(n){if(n.src&&/tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(n.src)){if(/_(src|dev)\.js/g.test(n.src))t.suffix='_src';if((p=n.src.indexOf('?'))!=-1)t.query=n.src.substring(p+1);t.baseURL=n.src.substring(0,n.src.lastIndexOf('/'));if(base&&t.baseURL.indexOf('://')==-1)t.baseURL=base+t.baseURL;return t.baseURL;}return null;};nl=d.getElementsByTagName('script');for(i=0;i<nl.length;i++){if(getBase(nl[i]))return;}n=d.getElementsByTagName('head')[0];if(n){nl=n.getElementsByTagName('script');for(i=0;i<nl.length;i++){if(getBase(nl[i]))return;}}return;},is:function(o,t){var n=typeof(o);if(!t)return n!='undefined';if(t=='array'&&(o instanceof Array))return true;return n==t;},each:function(o,cb,s){var n,l;if(!o)return 0;s=s||o;if(typeof(o.length)!='undefined'){for(n=0,l=o.length;n<l;n++){if(cb.call(s,o[n],n,o)===false)return 0;}}else{for(n in o){if(o.hasOwnProperty(n)){if(cb.call(s,o[n],n,o)===false)return 0;}}}return 1;},map:function(a,f){var o=[];tinymce.each(a,function(v){o.push(f(v));});return o;},grep:function(a,f){var o=[];tinymce.each(a,function(v){if(!f||f(v))o.push(v);});return o;},inArray:function(a,v){var i,l;if(a){for(i=0,l=a.length;i<l;i++){if(a[i]===v)return i;}}return-1;},extend:function(o,e){var i,a=arguments;for(i=1;i<a.length;i++){e=a[i];tinymce.each(e,function(v,n){if(typeof(v)!=='undefined')o[n]=v;});}return o;},trim:function(s){return(s?''+s:'').replace(/^\s*|\s*$/g,'');},create:function(s,p){var t=this,sp,ns,cn,scn,c,de=0;s=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);cn=s[3].match(/(^|\.)(\w+)$/i)[2];ns=t.createNS(s[3].replace(/\.\w+$/,''));if(ns[cn])return;if(s[2]=='static'){ns[cn]=p;if(this.onCreate)this.onCreate(s[2],s[3],ns[cn]);return;}if(!p[cn]){p[cn]=function(){};de=1;}ns[cn]=p[cn];t.extend(ns[cn].prototype,p);if(s[5]){sp=t.resolve(s[5]).prototype;scn=s[5].match(/\.(\w+)$/i)[1];c=ns[cn];if(de){ns[cn]=function(){return sp[scn].apply(this,arguments);};}else{ns[cn]=function(){this.parent=sp[scn];return c.apply(this,arguments);};}ns[cn].prototype[cn]=ns[cn];t.each(sp,function(f,n){ns[cn].prototype[n]=sp[n];});t.each(p,function(f,n){if(sp[n]){ns[cn].prototype[n]=function(){this.parent=sp[n];return f.apply(this,arguments);};}else{if(n!=cn)ns[cn].prototype[n]=f;}});}t.each(p['static'],function(f,n){ns[cn][n]=f;});if(this.onCreate)this.onCreate(s[2],s[3],ns[cn].prototype);},walk:function(o,f,n,s){s=s||this;if(o){if(n)o=o[n];tinymce.each(o,function(o,i){if(f.call(s,o,i,n)===false)return false;tinymce.walk(o,f,n,s);});}},createNS:function(n,o){var i,v;o=o||window;n=n.split('.');for(i=0;i<n.length;i++){v=n[i];if(!o[v])o[v]={};o=o[v];}return o;},resolve:function(n,o){var i,l;o=o||window;n=n.split('.');for(i=0,l=n.length;i<l;i++){o=o[n[i]];if(!o)break;}return o;},addUnload:function(f,s){var t=this,w=window;f={func:f,scope:s||this};if(!t.unloads){function unload(){var li=t.unloads,o,n;if(li){for(n in li){o=li[n];if(o&&o.func)o.func.call(o.scope,1);}if(w.detachEvent){w.detachEvent('onbeforeunload',fakeUnload);w.detachEvent('onunload',unload);}else if(w.removeEventListener)w.removeEventListener('unload',unload,false);t.unloads=o=li=w=unload=null;if(window.CollectGarbage)window.CollectGarbage();}};function fakeUnload(){var d=document;if(d.readyState=='interactive'){function stop(){d.detachEvent('onstop',stop);unload();d=null;};d.attachEvent('onstop',stop);window.setTimeout(function(){d.detachEvent('onstop',stop);},0);}};if(w.attachEvent){w.attachEvent('onunload',unload);w.attachEvent('onbeforeunload',fakeUnload);}else if(w.addEventListener)w.addEventListener('unload',unload,false);t.unloads=[f];}else t.unloads.push(f);return f;},removeUnload:function(f){var u=this.unloads,r=null;tinymce.each(u,function(o,i){if(o&&o.func==f){u.splice(i,1);r=f;return false;}});return r;},explode:function(s,d){return s?tinymce.map(s.split(d||','),tinymce.trim):s;},_addVer:function(u){var v;if(!this.query)return u;v=(u.indexOf('?')==-1?'?':'&')+this.query;if(u.indexOf('#')==-1)return u+v;return u.replace('#',v+'#');}};window.tinymce=tinymce;tinymce._init();tinymce.create('tinymce.util.Dispatcher',{scope:null,listeners:null,Dispatcher:function(s){this.scope=s||this;this.listeners=[];},add:function(cb,s){this.listeners.push({cb:cb,scope:s||this.scope});return cb;},addToTop:function(cb,s){this.listeners.unshift({cb:cb,scope:s||this.scope});return cb;},remove:function(cb){var l=this.listeners,o=null;tinymce.each(l,function(c,i){if(cb==c.cb){o=cb;l.splice(i,1);return false;}});return o;},dispatch:function(){var s,a=arguments,i,li=this.listeners,c;for(i=0;i<li.length;i++){c=li[i];s=c.cb.apply(c.scope,a);if(s===false)break;}return s;}});(function(){var each=tinymce.each;tinymce.create('tinymce.util.URI',{URI:function(u,s){var t=this,o,a,b;s=t.settings=s||{};if(/^(mailto|news|javascript|about):/i.test(u)||/^\s*#/.test(u)){t.source=u;return;}if(u.indexOf('/')===0&&u.indexOf('//')!==0)u=(s.base_uri?s.base_uri.protocol||'http':'http')+'://mce_host'+u;if(u.indexOf('://')===-1&&u.indexOf('//')!==0)u=(s.base_uri.protocol||'http')+'://mce_host'+t.toAbsPath(s.base_uri.path,u);u=u.replace(/@@/g,'(mce_at)');u=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(u);each(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(v,i){var s=u[i];if(s)s=s.replace(/\(mce_at\)/g,'@@');t[v]=s;});if(b=s.base_uri){if(!t.protocol)t.protocol=b.protocol;if(!t.userInfo)t.userInfo=b.userInfo;if(!t.port&&t.host=='mce_host')t.port=b.port;if(!t.host||t.host=='mce_host')t.host=b.host;t.source='';}},setPath:function(p){var t=this;p=/^(.*?)\/?(\w+)?$/.exec(p);t.path=p[0];t.directory=p[1];t.file=p[2];t.source='';t.getURI();},toRelative:function(u){var t=this,o;u=new tinymce.util.URI(u,{base_uri:t});if((u.host!='mce_host'&&t.host!=u.host&&u.host)||t.port!=u.port||t.protocol!=u.protocol)return u.getURI();o=t.toRelPath(t.path,u.path);if(u.query)o+='?'+u.query;if(u.anchor)o+='#'+u.anchor;return o;},toAbsolute:function(u,nh){var u=new tinymce.util.URI(u,{base_uri:this});return u.getURI(this.host==u.host?nh:0);},toRelPath:function(base,path){var items,bp=0,out='',i;base=base.substring(0,base.lastIndexOf('/'));base=base.split('/');items=path.split('/');if(base.length>=items.length){for(i=0;i<base.length;i++){if(i>=items.length||base[i]!=items[i]){bp=i+1;break;}}}if(base.length<items.length){for(i=0;i<items.length;i++){if(i>=base.length||base[i]!=items[i]){bp=i+1;break;}}}if(bp==1)return path;for(i=0;i<base.length-(bp-1);i++)out+="../";for(i=bp-1;i<items.length;i++){if(i!=bp-1)out+="/"+items[i];else out+=items[i];}return out;},toAbsPath:function(base,path){var i,nb=0,o=[];base=base.split('/');path=path.split('/');each(base,function(k){if(k)o.push(k);});base=o;for(i=path.length-1,o=[];i>=0;i--){if(path[i].length==0||path[i]==".")continue;if(path[i]=='..'){nb++;continue;}if(nb>0){nb--;continue;}o.push(path[i]);}i=base.length-nb;if(i<=0)return'/'+o.reverse().join('/');return'/'+base.slice(0,i).join('/')+'/'+o.reverse().join('/');},getURI:function(nh){var s,t=this;if(!t.source||nh){s='';if(!nh){if(t.protocol)s+=t.protocol+'://';if(t.userInfo)s+=t.userInfo+'@';if(t.host)s+=t.host;if(t.port)s+=':'+t.port;}if(t.path)s+=t.path;if(t.query)s+='?'+t.query;if(t.anchor)s+='#'+t.anchor;t.source=s;}return t.source;}});})();(function(){var each=tinymce.each;tinymce.create('static tinymce.util.Cookie',{getHash:function(n){var v=this.get(n),h;if(v){each(v.split('&'),function(v){v=v.split('=');h=h||{};h[unescape(v[0])]=unescape(v[1]);});}return h;},setHash:function(n,v,e,p,d,s){var o='';each(v,function(v,k){o+=(!o?'':'&')+escape(k)+'='+escape(v);});this.set(n,o,e,p,d,s);},get:function(n){var c=document.cookie,e,p=n+"=",b;if(!c)return;b=c.indexOf("; "+p);if(b==-1){b=c.indexOf(p);if(b!=0)return null;}else b+=2;e=c.indexOf(";",b);if(e==-1)e=c.length;return unescape(c.substring(b+p.length,e));},set:function(n,v,e,p,d,s){document.cookie=n+"="+escape(v)+((e)?"; expires="+e.toGMTString():"")+((p)?"; path="+escape(p):"")+((d)?"; domain="+d:"")+((s)?"; secure":"");},remove:function(n,p){var d=new Date();d.setTime(d.getTime()-1000);this.set(n,'',d,p,d);}});})();tinymce.create('static tinymce.util.JSON',{serialize:function(o){var i,v,s=tinymce.util.JSON.serialize,t;if(o==null)return'null';t=typeof o;if(t=='string'){v='\bb\tt\nn\ff\rr\""\'\'\\\\';return'"'+o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'])/g,function(a,b){i=v.indexOf(b);if(i+1)return'\\'+v.charAt(i+1);a=b.charCodeAt().toString(16);return'\\u'+'0000'.substring(a.length)+a;})+'"';}if(t=='object'){if(o instanceof Array){for(i=0,v='[';i<o.length;i++)v+=(i>0?',':'')+s(o[i]);return v+']';}v='{';for(i in o)v+=typeof o[i]!='function'?(v.length>1?',"':'"')+i+'":'+s(o[i]):'';return v+'}';}return''+o;},parse:function(s){try{return eval('('+s+')');}catch(ex){}}});tinymce.create('static tinymce.util.XHR',{send:function(o){var x,t,w=window,c=0;o.scope=o.scope||this;o.success_scope=o.success_scope||o.scope;o.error_scope=o.error_scope||o.scope;o.async=o.async===false?false:true;o.data=o.data||'';function get(s){x=0;try{x=new ActiveXObject(s);}catch(ex){}return x;};x=w.XMLHttpRequest?new XMLHttpRequest():get('Microsoft.XMLHTTP')||get('Msxml2.XMLHTTP');if(x){if(x.overrideMimeType)x.overrideMimeType(o.content_type);x.open(o.type||(o.data?'POST':'GET'),o.url,o.async);if(o.content_type)x.setRequestHeader('Content-Type',o.content_type);x.send(o.data);function ready(){if(!o.async||x.readyState==4||c++>10000){if(o.success&&c<10000&&x.status==200)o.success.call(o.success_scope,''+x.responseText,x,o);else if(o.error)o.error.call(o.error_scope,c>10000?'TIMED_OUT':'GENERAL',x,o);x=null;}else w.setTimeout(ready,10);};if(!o.async)return ready();t=w.setTimeout(ready,10);}}});(function(){var extend=tinymce.extend,JSON=tinymce.util.JSON,XHR=tinymce.util.XHR;tinymce.create('tinymce.util.JSONRequest',{JSONRequest:function(s){this.settings=extend({},s);this.count=0;},send:function(o){var ecb=o.error,scb=o.success;o=extend(this.settings,o);o.success=function(c,x){c=JSON.parse(c);if(typeof(c)=='undefined'){c={error:'JSON Parse error.'};}if(c.error)ecb.call(o.error_scope||o.scope,c.error,x);else scb.call(o.success_scope||o.scope,c.result);};o.error=function(ty,x){ecb.call(o.error_scope||o.scope,ty,x);};o.data=JSON.serialize({id:o.id||'c'+(this.count++),method:o.method,params:o.params});o.content_type='application/json';XHR.send(o);},'static':{sendRPC:function(o){return new tinymce.util.JSONRequest().send(o);}}});}());(function(){var each=tinymce.each,is=tinymce.is;var isWebKit=tinymce.isWebKit,isIE=tinymce.isIE;tinymce.create('tinymce.dom.DOMUtils',{doc:null,root:null,files:null,listeners:{},pixelStyles:/^(top|left|bottom|right|width|height|borderWidth)$/,cache:{},idPattern:/^#[\w]+$/,elmPattern:/^[\w_*]+$/,elmClassPattern:/^([\w_]*)\.([\w_]+)$/,DOMUtils:function(d,s){var t=this;t.doc=d;t.win=window;t.files={};t.cssFlicker=false;t.counter=0;t.boxModel=!tinymce.isIE||d.compatMode=="CSS1Compat";t.stdMode=d.documentMode===8;this.settings=s=tinymce.extend({keep_values:false,hex_colors:1,process_html:1},s);if(tinymce.isIE6){try{d.execCommand('BackgroundImageCache',false,true);}catch(e){t.cssFlicker=true;}}tinymce.addUnload(t.destroy,t);},getRoot:function(){var t=this,s=t.settings;return(s&&t.get(s.root_element))||t.doc.body;},getViewPort:function(w){var d,b;w=!w?this.win:w;d=w.document;b=this.boxModel?d.documentElement:d.body;return{x:w.pageXOffset||b.scrollLeft,y:w.pageYOffset||b.scrollTop,w:w.innerWidth||b.clientWidth,h:w.innerHeight||b.clientHeight};},getRect:function(e){var p,t=this,w,h;e=t.get(e);p=t.getPos(e);w=t.getStyle(e,'width');h=t.getStyle(e,'height');if(w.indexOf('px')===-1)w=0;if(h.indexOf('px')===-1)h=0;return{x:p.x,y:p.y,w:parseInt(w)||e.offsetWidth||e.clientWidth,h:parseInt(h)||e.offsetHeight||e.clientHeight};},getParent:function(n,f,r){var na,se=this.settings;n=this.get(n);if(se.strict_root)r=r||this.getRoot();if(is(f,'string')){na=f.toUpperCase();f=function(n){var s=false;if(n.nodeType==1&&na==='*'){s=true;return false;}each(na.split(','),function(v){if(n.nodeType==1&&((se.strict&&n.nodeName.toUpperCase()==v)||n.nodeName.toUpperCase()==v)){s=true;return false;}});return s;};}while(n){if(n==r)return null;if(f(n))return n;n=n.parentNode;}return null;},get:function(e){var n;if(e&&this.doc&&typeof(e)=='string'){n=e;e=this.doc.getElementById(e);if(e&&e.id!==n)return this.doc.getElementsByName(n)[1];}return e;},select:function(pa,s){var t=this,cs,c,pl,o=[],x,i,l,n;s=t.get(s)||t.doc;if(s.querySelectorAll){if(s!=t.doc){i=s.id;s.id='_mc_tmp';pa='#_mc_tmp '+pa;}l=tinymce.grep(s.querySelectorAll(pa));s.id=i;return l;}if(t.settings.strict){function get(s,n){return s.getElementsByTagName(n.toLowerCase());};}else{function get(s,n){return s.getElementsByTagName(n);};}if(t.elmPattern.test(pa)){x=get(s,pa);for(i=0,l=x.length;i<l;i++)o.push(x[i]);return o;}if(t.elmClassPattern.test(pa)){pl=t.elmClassPattern.exec(pa);x=get(s,pl[1]||'*');c=' '+pl[2]+' ';for(i=0,l=x.length;i<l;i++){n=x[i];if(n.className&&(' '+n.className+' ').indexOf(c)!==-1)o.push(n);}return o;}function collect(n){if(!n.mce_save){n.mce_save=1;o.push(n);}};function collectIE(n){if(!n.getAttribute('mce_save')){n.setAttribute('mce_save','1');o.push(n);}};function find(n,f,r){var i,l,nl=get(r,n);for(i=0,l=nl.length;i<l;i++)f(nl[i]);};each(pa.split(','),function(v,i){v=tinymce.trim(v);if(t.elmPattern.test(v)){each(get(s,v),function(n){collect(n);});return;}if(t.elmClassPattern.test(v)){x=t.elmClassPattern.exec(v);each(get(s,x[1]),function(n){if(t.hasClass(n,x[2]))collect(n);});return;}if(!(cs=t.cache[pa])){cs='x=(function(cf, s) {';pl=v.split(' ');each(pl,function(v){var p=/^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i.exec(v);p[1]=p[1]||'*';cs+='find("'+p[1]+'", function(n) {';if(p[2])cs+='if (n.id !== "'+p[2]+'") return;';if(p[3]){cs+='var c = " " + n.className + " ";';cs+='if (';c='';each(p[3].split('.'),function(v){if(v)c+=(c?'||':'')+'c.indexOf(" '+v+' ") === -1';});cs+=c+') return;';}});cs+='cf(n);';for(i=pl.length-1;i>=0;i--)cs+='}, '+(i?'n':'s')+');';cs+='})';t.cache[pa]=cs=eval(cs);}cs(isIE?collectIE:collect,s);});each(o,function(n){if(isIE)n.removeAttribute('mce_save');else delete n.mce_save;});return o;},add:function(p,n,a,h,c){var t=this;return this.run(p,function(p){var e,k;e=is(n,'string')?t.doc.createElement(n):n;if(a){for(k in a){if(a.hasOwnProperty(k)&&!is(a[k],'object'))t.setAttrib(e,k,''+a[k]);}if(a.style&&!is(a.style,'string')){each(a.style,function(v,n){t.setStyle(e,n,v);});}}if(h){if(h.nodeType)e.appendChild(h);else t.setHTML(e,h);}return!c?p.appendChild(e):e;});},create:function(n,a,h){return this.add(this.doc.createElement(n),n,a,h,1);},createHTML:function(n,a,h){var o='',t=this,k;o+='<'+n;for(k in a){if(a.hasOwnProperty(k))o+=' '+k+'="'+t.encode(a[k])+'"';}if(tinymce.is(h))return o+'>'+h+'</'+n+'>';return o+' />';},remove:function(n,k){return this.run(n,function(n){var p,g;p=n.parentNode;if(!p)return null;if(k){each(n.childNodes,function(c){p.insertBefore(c.cloneNode(true),n);});}return p.removeChild(n);});},setStyle:function(n,na,v){var t=this;return t.run(n,function(e){var s,i;s=e.style;na=na.replace(/-(\D)/g,function(a,b){return b.toUpperCase();});if(t.pixelStyles.test(na)&&(tinymce.is(v,'number')||/^[\-0-9\.]+$/.test(v)))v+='px';switch(na){case'opacity':if(isIE){s.filter=v===''?'':"alpha(opacity="+(v*100)+")";if(!n.currentStyle||!n.currentStyle.hasLayout)s.display='inline-block';}s[na]=s['-moz-opacity']=s['-khtml-opacity']=v||'';break;case'float':isIE?s.styleFloat=v:s.cssFloat=v;break;default:s[na]=v||'';}if(t.settings.update_styles)t.setAttrib(e,'mce_style');});},getStyle:function(n,na,c){n=this.get(n);if(!n)return false;if(this.doc.defaultView&&c){na=na.replace(/[A-Z]/g,function(a){return'-'+a;});try{return this.doc.defaultView.getComputedStyle(n,null).getPropertyValue(na);}catch(ex){return null;}}na=na.replace(/-(\D)/g,function(a,b){return b.toUpperCase();});if(na=='float')na=isIE?'styleFloat':'cssFloat';if(n.currentStyle&&c)return n.currentStyle[na];return n.style[na];},setStyles:function(e,o){var t=this,s=t.settings,ol;ol=s.update_styles;s.update_styles=0;each(o,function(v,n){t.setStyle(e,n,v);});s.update_styles=ol;if(s.update_styles)t.setAttrib(e,s.cssText);},setAttrib:function(e,n,v){var t=this;if(t.settings.strict)n=n.toLowerCase();return this.run(e,function(e){var s=t.settings;switch(n){case"style":if(s.keep_values){if(v&&!t._isRes(v))e.setAttribute('mce_style',v,2);else e.removeAttribute('mce_style',2);}e.style.cssText=v;break;case"class":e.className=v||'';break;case"src":case"href":if(s.keep_values){if(s.url_converter)v=s.url_converter.call(s.url_converter_scope||t,v,n,e);t.setAttrib(e,'mce_'+n,v,2);}break;case"shape":e.setAttribute('mce_style',v);break;}if(is(v)&&v!==null&&v.length!==0)e.setAttribute(n,''+v,2);else e.removeAttribute(n,2);});},setAttribs:function(e,o){var t=this;return this.run(e,function(e){each(o,function(v,n){t.setAttrib(e,n,v);});});},getAttrib:function(e,n,dv){var v,t=this;e=t.get(e);if(!e||e.nodeType!==1)return false;if(!is(dv))dv="";if(/^(src|href|style|coords|shape)$/.test(n)){v=e.getAttribute("mce_"+n);if(v)return v;}v=e.getAttribute(n,2);if(!v){switch(n){case'class':v=e.className;break;default:if(isIE&&n==='name'&&e.nodeName==='A'){v=e.name;break;}v=e.attributes[n];v=v&&is(v.nodeValue)?v.nodeValue:v;}}switch(n){case'style':v=v||e.style.cssText;if(v){v=t.serializeStyle(t.parseStyle(v));if(t.settings.keep_values&&!t._isRes(v))e.setAttribute('mce_style',v);}break;}if(isWebKit&&n==="class"&&v)v=v.replace(/(apple|webkit)\-[a-z\-]+/gi,'');if(isIE){switch(n){case'rowspan':case'colspan':if(v===1)v='';break;case'size':if(v==='+0')v='';break;case'hspace':if(v===-1)v='';break;case'tabindex':if(v===32768)v='';break;case'maxlength':if(v===2147483647)v='';break;case'shape':v=v.toLowerCase();break;default:if(n.indexOf('on')===0&&v)v=(''+v).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/,'$1');}}return(v&&v!='')?''+v:dv;},getPos:function(n){var t=this,x=0,y=0,e,d=t.doc,r;n=t.get(n);if(n&&isIE){n=n.getBoundingClientRect();e=t.boxModel?d.documentElement:d.body;x=t.getStyle(t.select('html')[0],'borderWidth');x=(x=='medium'||t.boxModel&&!t.isIE6)&&2||x;n.top+=t.win.self!=t.win.top?2:0;return{x:n.left+e.scrollLeft-x,y:n.top+e.scrollTop-x};}r=n;while(r){x+=r.offsetLeft||0;y+=r.offsetTop||0;r=r.offsetParent;}r=n;while(r){if(!/^table-row|inline.*/i.test(t.getStyle(r,"display",1))){x-=r.scrollLeft||0;y-=r.scrollTop||0;}r=r.parentNode;if(r==d.body)break;}return{x:x,y:y};},parseStyle:function(st){var t=this,s=t.settings,o={};if(!st)return o;function compress(p,s,ot){var t,r,b,l;t=o[p+'-top'+s];if(!t)return;r=o[p+'-right'+s];if(t!=r)return;b=o[p+'-bottom'+s];if(r!=b)return;l=o[p+'-left'+s];if(b!=l)return;o[ot]=l;delete o[p+'-top'+s];delete o[p+'-right'+s];delete o[p+'-bottom'+s];delete o[p+'-left'+s];};function compress2(ta,a,b,c){var t;t=o[a];if(!t)return;t=o[b];if(!t)return;t=o[c];if(!t)return;o[ta]=o[a]+' '+o[b]+' '+o[c];delete o[a];delete o[b];delete o[c];};st=st.replace(/&(#?[a-z0-9]+);/g,'&$1_MCE_SEMI_');each(st.split(';'),function(v){var sv,ur=[];if(v){v=v.replace(/_MCE_SEMI_/g,';');v=v.replace(/url\([^\)]+\)/g,function(v){ur.push(v);return'url('+ur.length+')';});v=v.split(':');sv=tinymce.trim(v[1]);sv=sv.replace(/url\(([^\)]+)\)/g,function(a,b){return ur[parseInt(b)-1];});sv=sv.replace(/rgb\([^\)]+\)/g,function(v){return t.toHex(v);});if(s.url_converter){sv=sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g,function(x,c){return'url('+s.url_converter.call(s.url_converter_scope||t,t.decode(c),'style',null)+')';});}o[tinymce.trim(v[0]).toLowerCase()]=sv;}});compress("border","","border");compress("border","-width","border-width");compress("border","-color","border-color");compress("border","-style","border-style");compress("padding","","padding");compress("margin","","margin");compress2('border','border-width','border-style','border-color');if(isIE){if(o.border=='medium none')o.border='';}return o;},serializeStyle:function(o){var s='';each(o,function(v,k){if(k&&v){if(tinymce.isGecko&&k.indexOf('-moz-')===0)return;switch(k){case'color':case'background-color':v=v.toLowerCase();break;}s+=(s?' ':'')+k+': '+v+';';}});return s;},loadCSS:function(u){var t=this,d=t.doc;if(!u)u='';each(u.split(','),function(u){if(t.files[u])return;t.files[u]=true;t.add(t.select('head')[0],'link',{rel:'stylesheet',href:tinymce._addVer(u)});});},addClass:function(e,c){return this.run(e,function(e){var o;if(!c)return 0;if(this.hasClass(e,c))return e.className;o=this.removeClass(e,c);return e.className=(o!=''?(o+' '):'')+c;});},removeClass:function(e,c){var t=this,re;return t.run(e,function(e){var v;if(t.hasClass(e,c)){if(!re)re=new RegExp("(^|\\s+)"+c+"(\\s+|$)","g");v=e.className.replace(re,' ');return e.className=tinymce.trim(v!=' '?v:'');}return e.className;});},hasClass:function(n,c){n=this.get(n);if(!n||!c)return false;return(' '+n.className+' ').indexOf(' '+c+' ')!==-1;},show:function(e){return this.setStyle(e,'display','block');},hide:function(e){return this.setStyle(e,'display','none');},isHidden:function(e){e=this.get(e);return e.style.display=='none'||this.getStyle(e,'display')=='none';},uniqueId:function(p){return(!p?'mce_':p)+(this.counter++);},setHTML:function(e,h){var t=this;return this.run(e,function(e){var x,i,nl,n,p,x;h=t.processHTML(h);if(isIE){function set(){try{e.innerHTML='<br />'+h;e.removeChild(e.firstChild);}catch(ex){while(e.firstChild)e.firstChild.removeNode();x=t.create('div');x.innerHTML='<br />'+h;each(x.childNodes,function(n,i){if(i)e.appendChild(n);});}};if(t.settings.fix_ie_paragraphs)h=h.replace(/<p><\/p>|<p([^>]+)><\/p>|<p[^\/+]\/>/gi,'<p$1 mce_keep="true">&nbsp;</p>');set();if(t.settings.fix_ie_paragraphs){nl=e.getElementsByTagName("p");for(i=nl.length-1,x=0;i>=0;i--){n=nl[i];if(!n.hasChildNodes()){if(!n.mce_keep){x=1;break;}n.removeAttribute('mce_keep');}}}if(x){h=h.replace(/<p([^>]+)>|<p>/g,'<div$1 mce_tmp="1">');h=h.replace(/<\/p>/g,'</div>');set();if(t.settings.fix_ie_paragraphs){nl=e.getElementsByTagName("DIV");for(i=nl.length-1;i>=0;i--){n=nl[i];if(n.mce_tmp){p=t.doc.createElement('p');n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi,function(a,b){var v;if(b!=='mce_tmp'){v=n.getAttribute(b);if(!v&&b==='class')v=n.className;p.setAttribute(b,v);}});for(x=0;x<n.childNodes.length;x++)p.appendChild(n.childNodes[x].cloneNode(true));n.swapNode(p);}}}}}else e.innerHTML=h;return h;});},processHTML:function(h){var t=this,s=t.settings;if(!s.process_html)return h;if(tinymce.isGecko){h=h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi,'<$1b$2>');h=h.replace(/<(\/?)em>|<em( [^>]+)>/gi,'<$1i$2>');}else if(isIE)h=h.replace(/&apos;/g,'&#39;');h=h.replace(/<a( )([^>]+)\/>|<a\/>/gi,'<a$1$2></a>');if(s.keep_values){if(/<script|style/.test(h)){function trim(s){s=s.replace(/^[\r\n]*|[\r\n]*$/g,'');s=s.replace(/^\s*(\/\/\s*<!--|\/\/\s*<\[CDATA\[|<!--|<\[CDATA\[)[\r\n]*/g,'');s=s.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->)\s*$/g,'');return s;};h=h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/g,function(v,a,b){b=trim(b);if(!a)a=' type="text/javascript"';if(b)b='<!--\n'+b+'\n// -->';return'<mce:script'+a+'>'+b+'</mce:script>';});h=h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/g,function(v,a,b){b=trim(b);return'<mce:style'+a+'><!--\n'+b+'\n--></mce:style><style'+a+' mce_bogus="1">'+b+'</style>';});}h=h.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi,function(a,n){function handle(m,b,c){var u=c;if(a.indexOf('mce_'+b)!=-1)return m;if(b=='style'){if(t._isRes(c))return m;if(s.hex_colors){u=u.replace(/rgb\([^\)]+\)/g,function(v){return t.toHex(v);});}if(s.url_converter){u=u.replace(/url\([\'\"]?([^\)\'\"]+)\)/g,function(x,c){return'url('+t.encode(s.url_converter.call(s.url_converter_scope||t,t.decode(c),b,n))+')';});}}else if(b!='coords'&&b!='shape'){if(s.url_converter)u=t.encode(s.url_converter.call(s.url_converter_scope||t,t.decode(c),b,n));}return' '+b+'="'+c+'" mce_'+b+'="'+u+'"';};a=a.replace(/ (src|href|style|coords|shape)=[\"]([^\"]+)[\"]/gi,handle);a=a.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi,handle);return a.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi,handle);});}return h;},getOuterHTML:function(e){var d;e=this.get(e);if(!e)return null;if(isIE)return e.outerHTML;d=(e.ownerDocument||this.doc).createElement("body");d.appendChild(e.cloneNode(true));return d.innerHTML;},setOuterHTML:function(e,h,d){var t=this;return this.run(e,function(e){var n,tp;e=t.get(e);d=d||e.ownerDocument||t.doc;if(isIE&&e.nodeType==1)e.outerHTML=h;else{tp=d.createElement("body");tp.innerHTML=h;n=tp.lastChild;while(n){t.insertAfter(n.cloneNode(true),e);n=n.previousSibling;}t.remove(e);}});},decode:function(s){var e;if(/&[^;]+;/.test(s)){e=this.doc.createElement("div");e.innerHTML=s;return!e.firstChild?s:e.firstChild.nodeValue;}return s;},encode:function(s){return s?(''+s).replace(/[<>&\"]/g,function(c,b){switch(c){case'&':return'&amp;';case'"':return'&quot;';case'<':return'&lt;';case'>':return'&gt;';}return c;}):s;},insertAfter:function(n,r){var t=this;r=t.get(r);return this.run(n,function(n){var p,ns;p=r.parentNode;ns=r.nextSibling;if(ns)p.insertBefore(n,ns);else p.appendChild(n);return n;});},isBlock:function(n){if(n.nodeType&&n.nodeType!==1)return false;n=n.nodeName||n;return/^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);},replace:function(n,o,k){if(is(o,'array'))n=n.cloneNode(true);return this.run(o,function(o){if(k){each(o.childNodes,function(c){n.appendChild(c.cloneNode(true));});}return o.parentNode.replaceChild(n,o);});},toHex:function(s){var c=/^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);function hex(s){s=parseInt(s).toString(16);return s.length>1?s:'0'+s;};if(c){s='#'+hex(c[1])+hex(c[2])+hex(c[3]);return s;}return s;},getClasses:function(){var t=this,cl=[],i,lo={},f=t.settings.class_filter,ov;if(t.classes)return t.classes;function addClasses(s){each(s.imports,function(r){addClasses(r);});each(s.cssRules||s.rules,function(r){switch(r.type||1){case 1:if(r.selectorText){each(r.selectorText.split(','),function(v){v=v.replace(/^\s*|\s*$|^\s\./g,"");if(/\.mce/.test(v)||!/\.[\w\-]+$/.test(v))return;ov=v;v=v.replace(/.*\.([a-z0-9_\-]+).*/i,'$1');if(f&&!(v=f(v,ov)))return;if(!lo[v]){cl.push({'class':v});lo[v]=1;}});}break;case 3:addClasses(r.styleSheet);break;}});};try{each(t.doc.styleSheets,addClasses);}catch(ex){}if(cl.length>0)t.classes=cl;return cl;},run:function(e,f,s){var t=this,o;if(t.doc&&typeof(e)==='string')e=t.doc.getElementById(e);if(!e)return false;s=s||this;if(!e.nodeType&&(e.length||e.length===0)){o=[];each(e,function(e,i){if(e){if(typeof(e)=='string')e=t.doc.getElementById(e);o.push(f.call(s,e,i));}});return o;}return f.call(s,e);},getAttribs:function(n){var o;n=this.get(n);if(!n)return[];if(isIE){o=[];if(n.nodeName=='OBJECT')return n.attributes;n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi,function(a,b){o.push({specified:1,nodeName:b});});return o;}return n.attributes;},destroy:function(s){var t=this;t.win=t.doc=t.root=null;if(!s)tinymce.removeUnload(t.destroy);},_isRes:function(c){return/^(top|left|bottom|right|width|height)/i.test(c)||/;\s*(top|left|bottom|right|width|height)/i.test(c);}});tinymce.DOM=new tinymce.dom.DOMUtils(document,{process_html:0});})();(function(){var each=tinymce.each,DOM=tinymce.DOM,isIE=tinymce.isIE,isWebKit=tinymce.isWebKit,Event;tinymce.create('static tinymce.dom.Event',{inits:[],events:[],add:function(o,n,f,s){var cb,t=this,el=t.events,r;if(o&&o instanceof Array){r=[];each(o,function(o){o=DOM.get(o);r.push(t.add(o,n,f,s));});return r;}o=DOM.get(o);if(!o)return;cb=function(e){e=e||window.event;if(e&&!e.target&&isIE)e.target=e.srcElement;if(!s)return f(e);return f.call(s,e);};if(n=='unload'){tinymce.unloads.unshift({func:cb});return cb;}if(n=='init'){if(t.domLoaded)cb();else t.inits.push(cb);return cb;}el.push({obj:o,name:n,func:f,cfunc:cb,scope:s});t._add(o,n,cb);return f;},remove:function(o,n,f){var t=this,a=t.events,s=false,r;if(o&&o instanceof Array){r=[];each(o,function(o){o=DOM.get(o);r.push(t.remove(o,n,f));});return r;}o=DOM.get(o);each(a,function(e,i){if(e.obj==o&&e.name==n&&(!f||(e.func==f||e.cfunc==f))){a.splice(i,1);t._remove(o,n,e.cfunc);s=true;return false;}});return s;},clear:function(o){var t=this,a=t.events,i,e;if(o){o=DOM.get(o);for(i=a.length-1;i>=0;i--){e=a[i];if(e.obj===o){t._remove(e.obj,e.name,e.cfunc);e.obj=e.cfunc=null;a.splice(i,1);}}}},cancel:function(e){if(!e)return false;this.stop(e);return this.prevent(e);},stop:function(e){if(e.stopPropagation)e.stopPropagation();else e.cancelBubble=true;return false;},prevent:function(e){if(e.preventDefault)e.preventDefault();else e.returnValue=false;return false;},_unload:function(){var t=Event;each(t.events,function(e,i){t._remove(e.obj,e.name,e.cfunc);e.obj=e.cfunc=null;});t.events=[];t=null;},_add:function(o,n,f){if(o.attachEvent)o.attachEvent('on'+n,f);else if(o.addEventListener)o.addEventListener(n,f,false);else o['on'+n]=f;},_remove:function(o,n,f){if(o){try{if(o.detachEvent)o.detachEvent('on'+n,f);else if(o.removeEventListener)o.removeEventListener(n,f,false);else o['on'+n]=null;}catch(ex){}}},_pageInit:function(){var e=Event;e._remove(window,'DOMContentLoaded',e._pageInit);e.domLoaded=true;each(e.inits,function(c){c();});e.inits=[];},_wait:function(){var t;if(window.tinyMCE_GZ&&tinyMCE_GZ.loaded){Event.domLoaded=1;return;}if(isIE&&document.location.protocol!='https:'){document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');DOM.get("__ie_onload").onreadystatechange=function(){if(this.readyState=="complete"){Event._pageInit();DOM.get("__ie_onload").onreadystatechange=null;}};}else{Event._add(window,'DOMContentLoaded',Event._pageInit,Event);if(isIE||isWebKit){t=setInterval(function(){if(/loaded|complete/.test(document.readyState)){clearInterval(t);Event._pageInit();}},10);}}}});Event=tinymce.dom.Event;Event._wait();tinymce.addUnload(Event._unload);})();(function(){var each=tinymce.each;tinymce.create('tinymce.dom.Element',{Element:function(id,s){var t=this,dom,el;s=s||{};t.id=id;t.dom=dom=s.dom||tinymce.DOM;t.settings=s;if(!tinymce.isIE)el=t.dom.get(t.id);each(['getPos','getRect','getParent','add','setStyle','getStyle','setStyles','setAttrib','setAttribs','getAttrib','addClass','removeClass','hasClass','getOuterHTML','setOuterHTML','remove','show','hide','isHidden','setHTML','get'],function(k){t[k]=function(){var a=arguments,o;if(tinymce.isOpera){a=[id];each(arguments,function(v){a.push(v);});}else Array.prototype.unshift.call(a,el||id);o=dom[k].apply(dom,a);t.update(k);return o;};});},on:function(n,f,s){return tinymce.dom.Event.add(this.id,n,f,s);},getXY:function(){return{x:parseInt(this.getStyle('left')),y:parseInt(this.getStyle('top'))};},getSize:function(){var n=this.dom.get(this.id);return{w:parseInt(this.getStyle('width')||n.clientWidth),h:parseInt(this.getStyle('height')||n.clientHeight)};},moveTo:function(x,y){this.setStyles({left:x,top:y});},moveBy:function(x,y){var p=this.getXY();this.moveTo(p.x+x,p.y+y);},resizeTo:function(w,h){this.setStyles({width:w,height:h});},resizeBy:function(w,h){var s=this.getSize();this.resizeTo(s.w+w,s.h+h);},update:function(k){var t=this,b,dom=t.dom;if(tinymce.isIE6&&t.settings.blocker){k=k||'';if(k.indexOf('get')===0||k.indexOf('has')===0||k.indexOf('is')===0)return;if(k=='remove'){dom.remove(t.blocker);return;}if(!t.blocker){t.blocker=dom.uniqueId();b=dom.add(t.settings.container||dom.getRoot(),'iframe',{id:t.blocker,style:'position:absolute;',frameBorder:0,src:'javascript:""'});dom.setStyle(b,'opacity',0);}else b=dom.get(t.blocker);dom.setStyle(b,'left',t.getStyle('left',1));dom.setStyle(b,'top',t.getStyle('top',1));dom.setStyle(b,'width',t.getStyle('width',1));dom.setStyle(b,'height',t.getStyle('height',1));dom.setStyle(b,'display',t.getStyle('display',1));dom.setStyle(b,'zIndex',parseInt(t.getStyle('zIndex',1)||0)-1);}}});})();(function(){function trimNl(s){return s.replace(/[\n\r]+/g,'');};var is=tinymce.is,isIE=tinymce.isIE,each=tinymce.each;tinymce.create('tinymce.dom.Selection',{Selection:function(dom,win,serializer){var t=this;t.dom=dom;t.win=win;t.serializer=serializer;tinymce.addUnload(t.destroy,t);},getContent:function(s){var t=this,r=t.getRng(),e=t.dom.create("body"),se=t.getSel(),wb,wa,n;s=s||{};wb=wa='';s.get=true;s.format=s.format||'html';if(s.format=='text')return t.isCollapsed()?'':(r.text||(se.toString?se.toString():''));if(r.cloneContents){n=r.cloneContents();if(n)e.appendChild(n);}else if(is(r.item)||is(r.htmlText))e.innerHTML=r.item?r.item(0).outerHTML:r.htmlText;else e.innerHTML=r.toString();if(/^\s/.test(e.innerHTML))wb=' ';if(/\s+$/.test(e.innerHTML))wa=' ';s.getInner=true;return t.isCollapsed()?'':wb+t.serializer.serialize(e,s)+wa;},setContent:function(h,s){var t=this,r=t.getRng(),d=t.win.document;s=s||{format:'html'};s.set=true;h=t.dom.processHTML(h);if(r.insertNode){if(tinymce.isGecko&&h.indexOf('<')==-1){r.deleteContents();r.insertNode(t.getRng().createContextualFragment(h+'<span id="__caret">_</span>'));t.select(t.dom.get('__caret'));t.getRng().deleteContents();return;}try{if(d.queryCommandEnabled('InsertHTML'))return d.execCommand('InsertHTML',false,h);}catch(ex){r.deleteContents();r.insertNode(t.getRng().createContextualFragment(h));}}else{if(r.item){d.execCommand('Delete',false,null);r=t.getRng();}r.pasteHTML(h);}},getStart:function(){var t=this,r=t.getRng(),e;if(isIE){if(r.item)return r.item(0);r=r.duplicate();r.collapse(1);e=r.parentElement();if(e&&e.nodeName=='BODY')return e.firstChild;return e;}else{e=r.startContainer;if(e.nodeName=='BODY')return e.firstChild;return t.dom.getParent(e,function(n){return n.nodeType==1;});}},getEnd:function(){var t=this,r=t.getRng(),e;if(isIE){if(r.item)return r.item(0);r=r.duplicate();r.collapse(0);e=r.parentElement();if(e&&e.nodeName=='BODY')return e.lastChild;return e;}else{e=r.endContainer;if(e.nodeName=='BODY')return e.lastChild;return t.dom.getParent(e,function(n){return n.nodeType==1;});}},getBookmark:function(si){var t=this,r=t.getRng(),tr,sx,sy,vp=t.dom.getViewPort(t.win),e,sp,bp,le,c=-0xFFFFFF,s,ro=t.dom.getRoot(),wb=0,wa=0,nv;sx=vp.x;sy=vp.y;if(si=='simple')return{rng:r,scrollX:sx,scrollY:sy};if(isIE){if(r.item){e=r.item(0);each(t.dom.select(e.nodeName),function(n,i){if(e==n){sp=i;return false;}});return{tag:e.nodeName,index:sp,scrollX:sx,scrollY:sy};}tr=t.dom.doc.body.createTextRange();tr.moveToElementText(ro);tr.collapse(true);bp=Math.abs(tr.move('character',c));tr=r.duplicate();tr.collapse(true);sp=Math.abs(tr.move('character',c));tr=r.duplicate();tr.collapse(false);le=Math.abs(tr.move('character',c))-sp;return{start:sp-bp,length:le,scrollX:sx,scrollY:sy};}e=t.getNode();s=t.getSel();if(!s)return null;if(e&&e.nodeName=='IMG'){return{scrollX:sx,scrollY:sy};}function getPos(r,sn,en){var w=t.dom.doc.createTreeWalker(r,NodeFilter.SHOW_TEXT,null,false),n,p=0,d={};while((n=w.nextNode())!=null){if(n==sn)d.start=p;if(n==en){d.end=p;return d;}p+=trimNl(n.nodeValue||'').length;}return null;};if(s.anchorNode==s.focusNode&&s.anchorOffset==s.focusOffset){e=getPos(ro,s.anchorNode,s.focusNode);if(!e)return{scrollX:sx,scrollY:sy};trimNl(s.anchorNode.nodeValue||'').replace(/^\s+/,function(a){wb=a.length;});return{start:Math.max(e.start+s.anchorOffset-wb,0),end:Math.max(e.end+s.focusOffset-wb,0),scrollX:sx,scrollY:sy,beg:s.anchorOffset-wb==0};}else{e=getPos(ro,r.startContainer,r.endContainer);if(!e)return{scrollX:sx,scrollY:sy};return{start:Math.max(e.start+r.startOffset-wb,0),end:Math.max(e.end+r.endOffset-wa,0),scrollX:sx,scrollY:sy,beg:r.startOffset-wb==0};}},moveToBookmark:function(b){var t=this,r=t.getRng(),s=t.getSel(),ro=t.dom.getRoot(),sd,nvl,nv;function getPos(r,sp,ep){var w=t.dom.doc.createTreeWalker(r,NodeFilter.SHOW_TEXT,null,false),n,p=0,d={},o,v,wa,wb;while((n=w.nextNode())!=null){wa=wb=0;nv=n.nodeValue||'';nvl=trimNl(nv).length;p+=nvl;if(p>=sp&&!d.startNode){o=sp-(p-nvl);if(b.beg&&o>=nvl)continue;d.startNode=n;d.startOffset=o+wb;}if(p>=ep){d.endNode=n;d.endOffset=ep-(p-nvl)+wb;return d;}}return null;};if(!b)return false;t.win.scrollTo(b.scrollX,b.scrollY);if(isIE){if(r=b.rng){try{r.select();}catch(ex){}return true;}t.win.focus();if(b.tag){r=ro.createControlRange();each(t.dom.select(b.tag),function(n,i){if(i==b.index)r.addElement(n);});}else{try{if(b.start<0)return true;r=s.createRange();r.moveToElementText(ro);r.collapse(true);r.moveStart('character',b.start);r.moveEnd('character',b.length);}catch(ex2){return true;}}try{r.select();}catch(ex){}return true;}if(!s)return false;if(b.rng){s.removeAllRanges();s.addRange(b.rng);}else{if(is(b.start)&&is(b.end)){try{sd=getPos(ro,b.start,b.end);if(sd){r=t.dom.doc.createRange();r.setStart(sd.startNode,sd.startOffset);r.setEnd(sd.endNode,sd.endOffset);s.removeAllRanges();s.addRange(r);}if(!tinymce.isOpera)t.win.focus();}catch(ex){}}}},select:function(n,c){var t=this,r=t.getRng(),s=t.getSel(),b,fn,ln,d=t.win.document;function first(n){return n?d.createTreeWalker(n,NodeFilter.SHOW_TEXT,null,false).nextNode():null;};function last(n){var c,o,w;if(!n)return null;w=d.createTreeWalker(n,NodeFilter.SHOW_TEXT,null,false);while(c=w.nextNode())o=c;return o;};if(isIE){try{b=d.body;if(/^(IMG|TABLE)$/.test(n.nodeName)){r=b.createControlRange();r.addElement(n);}else{r=b.createTextRange();r.moveToElementText(n);}r.select();}catch(ex){}}else{if(c){fn=first(n);ln=last(n);if(fn&&ln){r=d.createRange();r.setStart(fn,0);r.setEnd(ln,ln.nodeValue.length);}else r.selectNode(n);}else r.selectNode(n);t.setRng(r);}return n;},isCollapsed:function(){var t=this,r=t.getRng(),s=t.getSel();if(!r||r.item)return false;return!s||r.boundingWidth==0||s.isCollapsed;},collapse:function(b){var t=this,r=t.getRng(),n;if(r.item){n=r.item(0);r=this.win.document.body.createTextRange();r.moveToElementText(n);}r.collapse(!!b);t.setRng(r);},getSel:function(){var t=this,w=this.win;return w.getSelection?w.getSelection():w.document.selection;},getRng:function(){var t=this,s=t.getSel(),r;try{if(s)r=s.rangeCount>0?s.getRangeAt(0):(s.createRange?s.createRange():t.win.document.createRange());}catch(ex){}if(!r)r=isIE?t.win.document.body.createTextRange():t.win.document.createRange();return r;},setRng:function(r){var s;if(!isIE){s=this.getSel();if(s){s.removeAllRanges();s.addRange(r);}}else{try{r.select();}catch(ex){}}},setNode:function(n){var t=this;t.setContent(t.dom.getOuterHTML(n));return n;},getNode:function(){var t=this,r=t.getRng(),s=t.getSel(),e;if(!isIE){if(!r)return t.dom.getRoot();e=r.commonAncestorContainer;if(!r.collapsed){if(r.startContainer==r.endContainer||(tinymce.isWebKit&&r.startContainer==r.endContainer.parentNode)){if(r.startOffset-r.endOffset<2||tinymce.isWebKit){if(r.startContainer.hasChildNodes())e=r.startContainer.childNodes[r.startOffset];}}}return t.dom.getParent(e,function(n){return n.nodeType==1;});}return r.item?r.item(0):r.parentElement();},destroy:function(s){var t=this;t.win=null;if(!s)tinymce.removeUnload(t.destroy);}});})();(function(){tinymce.create('tinymce.dom.XMLWriter',{node:null,XMLWriter:function(s){function getXML(){var i=document.implementation;if(!i||!i.createDocument){try{return new ActiveXObject('MSXML2.DOMDocument');}catch(ex){}try{return new ActiveXObject('Microsoft.XmlDom');}catch(ex){}}else return i.createDocument('','',null);};this.doc=getXML();this.valid=tinymce.isOpera||tinymce.isWebKit;this.reset();},reset:function(){var t=this,d=t.doc;if(d.firstChild)d.removeChild(d.firstChild);t.node=d.appendChild(d.createElement("html"));},writeStartElement:function(n){var t=this;t.node=t.node.appendChild(t.doc.createElement(n));},writeAttribute:function(n,v){if(this.valid)v=v.replace(/>/g,'%MCGT%');this.node.setAttribute(n,v);},writeEndElement:function(){this.node=this.node.parentNode;},writeFullEndElement:function(){var t=this,n=t.node;n.appendChild(t.doc.createTextNode(""));t.node=n.parentNode;},writeText:function(v){if(this.valid)v=v.replace(/>/g,'%MCGT%');this.node.appendChild(this.doc.createTextNode(v));},writeCDATA:function(v){this.node.appendChild(this.doc.createCDATA(v));},writeComment:function(v){this.node.appendChild(this.doc.createComment(v.replace(/\-\-/g,' ')));},getContent:function(){var h;h=this.doc.xml||new XMLSerializer().serializeToString(this.doc);h=h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g,'');h=h.replace(/ ?\/>/g,' />');if(this.valid)h=h.replace(/\%MCGT%/g,'&gt;');return h;}});})();(function(){tinymce.create('tinymce.dom.StringWriter',{str:null,tags:null,count:0,settings:null,indent:null,StringWriter:function(s){this.settings=tinymce.extend({indent_char:' ',indentation:1},s);this.reset();},reset:function(){this.indent='';this.str="";this.tags=[];this.count=0;},writeStartElement:function(n){this._writeAttributesEnd();this.writeRaw('<'+n);this.tags.push(n);this.inAttr=true;this.count++;this.elementCount=this.count;},writeAttribute:function(n,v){var t=this;t.writeRaw(" "+t.encode(n)+'="'+t.encode(v)+'"');},writeEndElement:function(){var n;if(this.tags.length>0){n=this.tags.pop();if(this._writeAttributesEnd(1))this.writeRaw('</'+n+'>');if(this.settings.indentation>0)this.writeRaw('\n');}},writeFullEndElement:function(){if(this.tags.length>0){this._writeAttributesEnd();this.writeRaw('</'+this.tags.pop()+'>');if(this.settings.indentation>0)this.writeRaw('\n');}},writeText:function(v){this._writeAttributesEnd();this.writeRaw(this.encode(v));this.count++;},writeCDATA:function(v){this._writeAttributesEnd();this.writeRaw('<![CDATA['+v+']]>');this.count++;},writeComment:function(v){this._writeAttributesEnd();this.writeRaw('<!-- '+v+'-->');this.count++;},writeRaw:function(v){this.str+=v;},encode:function(s){return s.replace(/[<>&"]/g,function(v){switch(v){case'<':return'&lt;';case'>':return'&gt;';case'&':return'&amp;';case'"':return'&quot;';}return v;});},getContent:function(){return this.str;},_writeAttributesEnd:function(s){if(!this.inAttr)return;this.inAttr=false;if(s&&this.elementCount==this.count){this.writeRaw(' />');return false;}this.writeRaw('>');return true;}});})();(function(){var extend=tinymce.extend,each=tinymce.each,Dispatcher=tinymce.util.Dispatcher,isIE=tinymce.isIE,isGecko=tinymce.isGecko;function getIEAtts(n){var o=[];if(n.nodeName=='OBJECT')return n.attributes;n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi,function(a,b){o.push({specified:1,nodeName:b});});return o;};function wildcardToRE(s){return s.replace(/([?+*])/g,'.$1');};tinymce.create('tinymce.dom.Serializer',{Serializer:function(s){var t=this;t.key=0;t.onPreProcess=new Dispatcher(t);t.onPostProcess=new Dispatcher(t);if(tinymce.relaxedDomain&&tinymce.isGecko){t.writer=new tinymce.dom.StringWriter();}else{try{t.writer=new tinymce.dom.XMLWriter();}catch(ex){t.writer=new tinymce.dom.StringWriter();}}t.settings=s=extend({dom:tinymce.DOM,valid_nodes:0,node_filter:0,attr_filter:0,invalid_attrs:/^(mce_|_moz_)/,closed:/(br|hr|input|meta|img|link|param)/,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,valid_child_elements:0,invalid_elements:0,fix_table_elements:0,fix_list_elements:true,fix_content_duplication:true,convert_fonts_to_spans:false,font_size_classes:0,font_size_style_values:0,apply_source_formatting:0,indent_mode:'simple',indent_char:'\t',indent_levels:1,remove_linebreaks:1},s);t.dom=s.dom;if(s.fix_list_elements){t.onPreProcess.add(function(se,o){var nl,x,a=['ol','ul'],i,n,p,r=/^(OL|UL)$/,np;function prevNode(e,n){var a=n.split(','),i;while((e=e.previousSibling)!=null){for(i=0;i<a.length;i++){if(e.nodeName==a[i])return e;}}return null;};for(x=0;x<a.length;x++){nl=t.dom.select(a[x],o.node);for(i=0;i<nl.length;i++){n=nl[i];p=n.parentNode;if(r.test(p.nodeName)){np=prevNode(n,'LI');if(!np){np=t.dom.create('li');np.innerHTML='&nbsp;';np.appendChild(n);p.insertBefore(np,p.firstChild);}else np.appendChild(n);}}}});}if(s.fix_table_elements){t.onPreProcess.add(function(se,o){each(t.dom.select('table',o.node),function(e){var pa=t.dom.getParent(e,'H1,H2,H3,H4,H5,H6,P'),pa2,n,tm,pl=[],i,ns;if(pa){pa2=pa.cloneNode(false);pl.push(e);for(n=e;n=n.parentNode;){pl.push(n);if(n==pa)break;}tm=pa2;for(i=pl.length-1;i>=0;i--){if(i==pl.length-1){while(ns=pl[i-1].nextSibling)tm.appendChild(ns.parentNode.removeChild(ns));}else{n=pl[i].cloneNode(false);if(i!=0){while(ns=pl[i-1].nextSibling)n.appendChild(ns.parentNode.removeChild(ns));}tm=tm.appendChild(n);}}e=t.dom.insertAfter(e.parentNode.removeChild(e),pa);t.dom.insertAfter(e,pa);t.dom.insertAfter(pa2,e);}});});}},setEntities:function(s){var t=this,a,i,l={},re='',v;if(t.entityLookup)return;a=s.split(',');for(i=0;i<a.length;i+=2){v=a[i];if(v==34||v==38||v==60||v==62)continue;l[String.fromCharCode(a[i])]=a[i+1];v=parseInt(a[i]).toString(16);re+='\\u'+'0000'.substring(v.length)+v;}if(!re){t.settings.entity_encoding='raw';return;}t.entitiesRE=new RegExp('['+re+']','g');t.entityLookup=l;},setValidChildRules:function(s){this.childRules=null;this.addValidChildRules(s);},addValidChildRules:function(s){var t=this,inst,intr,bloc;if(!s)return;inst='A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment';intr='A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment';bloc='H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP';each(s.split(','),function(s){var p=s.split(/\[|\]/),re;s='';each(p[1].split('|'),function(v){if(s)s+='|';switch(v){case'%itrans':v=intr;break;case'%itrans_na':v=intr.substring(2);break;case'%istrict':v=inst;break;case'%istrict_na':v=inst.substring(2);break;case'%btrans':v=bloc;break;case'%bstrict':v=bloc;break;}s+=v;});re=new RegExp('^('+s.toLowerCase()+')$','i');each(p[0].split('/'),function(s){t.childRules=t.childRules||{};t.childRules[s]=re;});});s='';each(t.childRules,function(v,k){if(s)s+='|';s+=k;});t.parentElementsRE=new RegExp('^('+s.toLowerCase()+')$','i');},setRules:function(s){var t=this;t._setup();t.rules={};t.wildRules=[];t.validElements={};return t.addRules(s);},addRules:function(s){var t=this,dr;if(!s)return;t._setup();each(s.split(','),function(s){var p=s.split(/\[|\]/),tn=p[0].split('/'),ra,at,wat,va=[];if(dr)at=tinymce.extend([],dr.attribs);if(p.length>1){each(p[1].split('|'),function(s){var ar={},i;at=at||[];s=s.replace(/::/g,'~');s=/^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(s);s[2]=s[2].replace(/~/g,':');if(s[1]=='!'){ra=ra||[];ra.push(s[2]);}if(s[1]=='-'){for(i=0;i<at.length;i++){if(at[i].name==s[2]){at.splice(i,1);return;}}}switch(s[3]){case'=':ar.defaultVal=s[4]||'';break;case':':ar.forcedVal=s[4];break;case'<':ar.validVals=s[4].split('?');break;}if(/[*.?]/.test(s[2])){wat=wat||[];ar.nameRE=new RegExp('^'+wildcardToRE(s[2])+'$');wat.push(ar);}else{ar.name=s[2];at.push(ar);}va.push(s[2]);});}each(tn,function(s,i){var pr=s.charAt(0),x=1,ru={};if(dr){if(dr.noEmpty)ru.noEmpty=dr.noEmpty;if(dr.fullEnd)ru.fullEnd=dr.fullEnd;if(dr.padd)ru.padd=dr.padd;}switch(pr){case'-':ru.noEmpty=true;break;case'+':ru.fullEnd=true;break;case'#':ru.padd=true;break;default:x=0;}tn[i]=s=s.substring(x);t.validElements[s]=1;if(/[*.?]/.test(tn[0])){ru.nameRE=new RegExp('^'+wildcardToRE(tn[0])+'$');t.wildRules=t.wildRules||{};t.wildRules.push(ru);}else{ru.name=tn[0];if(tn[0]=='@')dr=ru;t.rules[s]=ru;}ru.attribs=at;if(ra)ru.requiredAttribs=ra;if(wat){s='';each(va,function(v){if(s)s+='|';s+='('+wildcardToRE(v)+')';});ru.validAttribsRE=new RegExp('^'+s.toLowerCase()+'$');ru.wildAttribs=wat;}});});s='';each(t.validElements,function(v,k){if(s)s+='|';if(k!='@')s+=k;});t.validElementsRE=new RegExp('^('+wildcardToRE(s.toLowerCase())+')$');},findRule:function(n){var t=this,rl=t.rules,i,r;t._setup();r=rl[n];if(r)return r;rl=t.wildRules;for(i=0;i<rl.length;i++){if(rl[i].nameRE.test(n))return rl[i];}return null;},findAttribRule:function(ru,n){var i,wa=ru.wildAttribs;for(i=0;i<wa.length;i++){if(wa[i].nameRE.test(n))return wa[i];}return null;},serialize:function(n,o){var h,t=this;t._setup();o=o||{};o.format=o.format||'html';t.processObj=o;n=n.cloneNode(true);t.key=''+(parseInt(t.key)+1);if(!o.no_events){o.node=n;t.onPreProcess.dispatch(t,o);}t.writer.reset();t._serializeNode(n,o.getInner);o.content=t.writer.getContent();if(!o.no_events)t.onPostProcess.dispatch(t,o);t._postProcess(o);o.node=null;return tinymce.trim(o.content);},_postProcess:function(o){var t=this,s=t.settings,h=o.content,sc=[],p;if(o.format=='html'){p=t._protect({content:h,patterns:[{pattern:/(<script[^>]*>)(.*?)(<\/script>)/g},{pattern:/(<style[^>]*>)(.*?)(<\/style>)/g},{pattern:/(<pre[^>]*>)(.*?)(<\/pre>)/g,encode:1}]});h=p.content;if(s.entity_encoding!=='raw')h=t._encode(h);if(!o.set){h=h.replace(/<p>\s+<\/p>|<p([^>]+)>\s+<\/p>/g,s.entity_encoding=='numeric'?'<p$1>&#160;</p>':'<p$1>&nbsp;</p>');if(s.remove_linebreaks){h=h.replace(/\r?\n|\r/g,' ');h=h.replace(/(<[^>]+>)\s+/g,'$1 ');h=h.replace(/\s+(<\/[^>]+>)/g,' $1');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>');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>');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>');}if(s.apply_source_formatting&&s.indent_mode=='simple'){h=h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g,'\n<$1$2$3>\n');h=h.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g,'\n<$1$2>');h=h.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g,'</$1>\n');h=h.replace(/\n\n/g,'\n');}}h=t._unprotect(h,p);if(s.entity_encoding=='raw')h=h.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g,'<p$1>\u00a0</p>');}o.content=h;},_serializeNode:function(n,inn){var t=this,s=t.settings,w=t.writer,hc,el,cn,i,l,a,at,no,v,nn,ru,ar,iv;if(!s.node_filter||s.node_filter(n)){switch(n.nodeType){case 1:if(n.hasAttribute?n.hasAttribute('mce_bogus'):n.getAttribute('mce_bogus'))return;iv=false;hc=n.hasChildNodes();nn=n.getAttribute('mce_name')||n.nodeName.toLowerCase();if(isIE){if(n.scopeName!=='HTML'&&n.scopeName!=='html')nn=n.scopeName+':'+nn;}if(nn.indexOf('mce:')===0)nn=nn.substring(4);if(!t.validElementsRE.test(nn)||(t.invalidElementsRE&&t.invalidElementsRE.test(nn))||inn){iv=true;break;}if(isIE){if(s.fix_content_duplication){if(n.mce_serialized==t.key)return;n.mce_serialized=t.key;}if(nn.charAt(0)=='/')nn=nn.substring(1);}else if(isGecko){if(n.nodeName==='BR'&&n.getAttribute('type')=='_moz')return;}if(t.childRules){if(t.parentElementsRE.test(t.elementName)){if(!t.childRules[t.elementName].test(nn)){iv=true;break;}}t.elementName=nn;}ru=t.findRule(nn);nn=ru.name||nn;if((!hc&&ru.noEmpty)||(isIE&&!nn)){iv=true;break;}if(ru.requiredAttribs){a=ru.requiredAttribs;for(i=a.length-1;i>=0;i--){if(this.dom.getAttrib(n,a[i])!=='')break;}if(i==-1){iv=true;break;}}w.writeStartElement(nn);if(ru.attribs){for(i=0,at=ru.attribs,l=at.length;i<l;i++){a=at[i];v=t._getAttrib(n,a);if(v!==null)w.writeAttribute(a.name,v);}}if(ru.validAttribsRE){at=isIE?getIEAtts(n):n.attributes;for(i=at.length-1;i>-1;i--){no=at[i];if(no.specified){a=no.nodeName.toLowerCase();if(s.invalid_attrs.test(a)||!ru.validAttribsRE.test(a))continue;ar=t.findAttribRule(ru,a);v=t._getAttrib(n,ar,a);if(v!==null)w.writeAttribute(a,v);}}}if(!hc&&ru.padd)w.writeText('\u00a0');break;case 3:if(t.childRules&&t.parentElementsRE.test(t.elementName)){if(!t.childRules[t.elementName].test(n.nodeName))return;}return w.writeText(n.nodeValue);case 4:return w.writeCDATA(n.nodeValue);case 8:return w.writeComment(n.nodeValue);}}else if(n.nodeType==1)hc=n.hasChildNodes();if(hc){cn=n.firstChild;while(cn){t._serializeNode(cn);t.elementName=nn;cn=cn.nextSibling;}}if(!iv){if(hc||!s.closed.test(nn))w.writeFullEndElement();else w.writeEndElement();}},_protect:function(o){var t=this;o.items=o.items||[];function enc(s){return s.replace(/[\r\n\\]/g,function(c){if(c==='\n')return'\\n';else if(c==='\\')return'\\\\';return'\\r';});};function dec(s){return s.replace(/\\[\\rn]/g,function(c){if(c==='\\n')return'\n';else if(c==='\\\\')return'\\';return'\r';});};each(o.patterns,function(p){o.content=dec(enc(o.content).replace(p.pattern,function(x,a,b,c){b=dec(b);if(p.encode)b=t._encode(b);o.items.push(b);return a+'<!--mce:'+(o.items.length-1)+'-->'+c;}));});return o;},_unprotect:function(h,o){h=h.replace(/\<!--mce:([0-9]+)--\>/g,function(a,b){return o.items[parseInt(b)];});o.items=[];return h;},_encode:function(h){var t=this,s=t.settings,l;if(s.entity_encoding!=='raw'){if(s.entity_encoding.indexOf('named')!=-1){t.setEntities(s.entities);l=t.entityLookup;h=h.replace(t.entitiesRE,function(a){var v;if(v=l[a])a='&'+v+';';return a;});}if(s.entity_encoding.indexOf('numeric')!=-1){h=h.replace(/[\u007E-\uFFFF]/g,function(a){return'&#'+a.charCodeAt(0)+';';});}}return h;},_setup:function(){var t=this,s=this.settings;if(t.done)return;t.done=1;t.setRules(s.valid_elements);t.addRules(s.extended_valid_elements);t.addValidChildRules(s.valid_child_elements);if(s.invalid_elements)t.invalidElementsRE=new RegExp('^('+wildcardToRE(s.invalid_elements.replace(/,/g,'|').toLowerCase())+')$');if(s.attrib_value_filter)t.attribValueFilter=s.attribValueFilter;},_getAttrib:function(n,a,na){var i,v;na=na||a.name;if(a.forcedVal&&(v=a.forcedVal)){if(v==='{$uid}')return this.dom.uniqueId();return v;}v=this.dom.getAttrib(n,na);switch(na){case'rowspan':case'colspan':if(v=='1')v='';break;}if(this.attribValueFilter)v=this.attribValueFilter(na,v,n);if(a.validVals){for(i=a.validVals.length-1;i>=0;i--){if(v==a.validVals[i])break;}if(i==-1)return null;}if(v===''&&typeof(a.defaultVal)!='undefined'){v=a.defaultVal;if(v==='{$uid}')return this.dom.uniqueId();return v;}else{if(na=='class'&&this.processObj.get)v=v.replace(/\s?mceItem\w+\s?/g,'');}if(v==='')return null;return v;}});})();(function(){var each=tinymce.each;tinymce.create('tinymce.dom.ScriptLoader',{ScriptLoader:function(s){this.settings=s||{};this.queue=[];this.lookup={};},isDone:function(u){return this.lookup[u]?this.lookup[u].state==2:0;},markDone:function(u){this.lookup[u]={state:2,url:u};},add:function(u,cb,s,pr){var t=this,lo=t.lookup,o;if(o=lo[u]){if(cb&&o.state==2)cb.call(s||this);return o;}o={state:0,url:u,func:cb,scope:s||this};if(pr)t.queue.unshift(o);else t.queue.push(o);lo[u]=o;return o;},load:function(u,cb,s){var t=this,o;if(o=t.lookup[u]){if(cb&&o.state==2)cb.call(s||t);return o;}function loadScript(u){if(tinymce.dom.Event.domLoaded||t.settings.strict_mode){tinymce.util.XHR.send({url:tinymce._addVer(u),error:t.settings.error,async:false,success:function(co){t.eval(co);}});}else document.write('<script type="text/javascript" src="'+tinymce._addVer(u)+'"></script>');};if(!tinymce.is(u,'string')){each(u,function(u){loadScript(u);});if(cb)cb.call(s||t);}else{loadScript(u);if(cb)cb.call(s||t);}},loadQueue:function(cb,s){var t=this;if(!t.queueLoading){t.queueLoading=1;t.queueCallbacks=[];t.loadScripts(t.queue,function(){t.queueLoading=0;if(cb)cb.call(s||t);each(t.queueCallbacks,function(o){o.func.call(o.scope);});});}else if(cb)t.queueCallbacks.push({func:cb,scope:s||t});},eval:function(co){var w=window;if(!w.execScript){try{eval.call(w,co);}catch(ex){eval(co,w);}}else w.execScript(co);},loadScripts:function(sc,cb,s){var t=this,lo=t.lookup;function done(o){o.state=2;if(o.func)o.func.call(o.scope||t);};function allDone(){var l;l=sc.length;each(sc,function(o){o=lo[o.url];if(o.state===2){done(o);l--;}else load(o);});if(l===0&&cb){cb.call(s||t);cb=0;}};function load(o){if(o.state>0)return;o.state=1;tinymce.util.XHR.send({url:o.url,error:t.settings.error,success:function(co){t.eval(co);done(o);allDone();}});};each(sc,function(o){var u=o.url;if(!lo[u]){lo[u]=o;t.queue.push(o);}else o=lo[u];if(o.state>0)return;if(!tinymce.dom.Event.domLoaded&&!t.settings.strict_mode){var ix,ol='';if(cb||o.func){o.state=1;ix=tinymce.dom.ScriptLoader._addOnLoad(function(){done(o);allDone();});if(tinymce.isIE)ol=' onreadystatechange="';else ol=' onload="';ol+='tinymce.dom.ScriptLoader._onLoad(this,\''+u+'\','+ix+');"';}document.write('<script type="text/javascript" src="'+tinymce._addVer(u)+'"'+ol+'></script>');if(!o.func)done(o);}else load(o);});allDone();},'static':{_addOnLoad:function(f){var t=this;t._funcs=t._funcs||[];t._funcs.push(f);return t._funcs.length-1;},_onLoad:function(e,u,ix){if(!tinymce.isIE||e.readyState=='complete')this._funcs[ix].call(this);}}});tinymce.ScriptLoader=new tinymce.dom.ScriptLoader();})();(function(){var DOM=tinymce.DOM,is=tinymce.is;tinymce.create('tinymce.ui.Control',{Control:function(id,s){this.id=id;this.settings=s=s||{};this.rendered=false;this.onRender=new tinymce.util.Dispatcher(this);this.classPrefix='';this.scope=s.scope||this;this.disabled=0;this.active=0;},setDisabled:function(s){var e;if(s!=this.disabled){e=DOM.get(this.id);if(e&&this.settings.unavailable_prefix){if(s){this.prevTitle=e.title;e.title=this.settings.unavailable_prefix+": "+e.title;}else e.title=this.prevTitle;}this.setState('Disabled',s);this.setState('Enabled',!s);this.disabled=s;}},isDisabled:function(){return this.disabled;},setActive:function(s){if(s!=this.active){this.setState('Active',s);this.active=s;}},isActive:function(){return this.active;},setState:function(c,s){var n=DOM.get(this.id);c=this.classPrefix+c;if(s)DOM.addClass(n,c);else DOM.removeClass(n,c);},isRendered:function(){return this.rendered;},renderHTML:function(){},renderTo:function(n){DOM.setHTML(n,this.renderHTML());},postRender:function(){var t=this,b;if(is(t.disabled)){b=t.disabled;t.disabled=-1;t.setDisabled(b);}if(is(t.active)){b=t.active;t.active=-1;t.setActive(b);}},remove:function(){DOM.remove(this.id);this.destroy();},destroy:function(){tinymce.dom.Event.clear(this.id);}});})();tinymce.create('tinymce.ui.Container:tinymce.ui.Control',{Container:function(id,s){this.parent(id,s);this.controls=[];this.lookup={};},add:function(c){this.lookup[c.id]=c;this.controls.push(c);return c;},get:function(n){return this.lookup[n];}});tinymce.create('tinymce.ui.Separator:tinymce.ui.Control',{Separator:function(id,s){this.parent(id,s);this.classPrefix='mceSeparator';},renderHTML:function(){return tinymce.DOM.createHTML('span',{'class':this.classPrefix});}});(function(){var is=tinymce.is,DOM=tinymce.DOM,each=tinymce.each,walk=tinymce.walk;tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control',{MenuItem:function(id,s){this.parent(id,s);this.classPrefix='mceMenuItem';},setSelected:function(s){this.setState('Selected',s);this.selected=s;},isSelected:function(){return this.selected;},postRender:function(){var t=this;t.parent();if(is(t.selected))t.setSelected(t.selected);}});})();(function(){var is=tinymce.is,DOM=tinymce.DOM,each=tinymce.each,walk=tinymce.walk;tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem',{Menu:function(id,s){var t=this;t.parent(id,s);t.items={};t.collapsed=false;t.menuCount=0;t.onAddItem=new tinymce.util.Dispatcher(this);},expand:function(d){var t=this;if(d){walk(t,function(o){if(o.expand)o.expand();},'items',t);}t.collapsed=false;},collapse:function(d){var t=this;if(d){walk(t,function(o){if(o.collapse)o.collapse();},'items',t);}t.collapsed=true;},isCollapsed:function(){return this.collapsed;},add:function(o){if(!o.settings)o=new tinymce.ui.MenuItem(o.id||DOM.uniqueId(),o);this.onAddItem.dispatch(this,o);return this.items[o.id]=o;},addSeparator:function(){return this.add({separator:true});},addMenu:function(o){if(!o.collapse)o=this.createMenu(o);this.menuCount++;return this.add(o);},hasMenus:function(){return this.menuCount!==0;},remove:function(o){delete this.items[o.id];},removeAll:function(){var t=this;walk(t,function(o){if(o.removeAll)o.removeAll();else o.remove();o.destroy();},'items',t);t.items={};},createMenu:function(o){var m=new tinymce.ui.Menu(o.id||DOM.uniqueId(),o);m.onAddItem.add(this.onAddItem.dispatch,this.onAddItem);return m;}});})();(function(){var is=tinymce.is,DOM=tinymce.DOM,each=tinymce.each,Event=tinymce.dom.Event,Element=tinymce.dom.Element;tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu',{DropMenu:function(id,s){s=s||{};s.container=s.container||DOM.doc.body;s.offset_x=s.offset_x||0;s.offset_y=s.offset_y||0;s.vp_offset_x=s.vp_offset_x||0;s.vp_offset_y=s.vp_offset_y||0;if(is(s.icons)&&!s.icons)s['class']+=' mceNoIcons';this.parent(id,s);this.onShowMenu=new tinymce.util.Dispatcher(this);this.onHideMenu=new tinymce.util.Dispatcher(this);this.classPrefix='mceMenu';},createMenu:function(s){var t=this,cs=t.settings,m;s.container=s.container||cs.container;s.parent=t;s.constrain=s.constrain||cs.constrain;s['class']=s['class']||cs['class'];s.vp_offset_x=s.vp_offset_x||cs.vp_offset_x;s.vp_offset_y=s.vp_offset_y||cs.vp_offset_y;m=new tinymce.ui.DropMenu(s.id||DOM.uniqueId(),s);m.onAddItem.add(t.onAddItem.dispatch,t.onAddItem);return m;},update:function(){var t=this,s=t.settings,tb=DOM.get('menu_'+t.id+'_tbl'),co=DOM.get('menu_'+t.id+'_co'),tw,th;tw=s.max_width?Math.min(tb.clientWidth,s.max_width):tb.clientWidth;th=s.max_height?Math.min(tb.clientHeight,s.max_height):tb.clientHeight;if(!DOM.boxModel)t.element.setStyles({width:tw+2,height:th+2});else t.element.setStyles({width:tw,height:th});if(s.max_width)DOM.setStyle(co,'width',tw);if(s.max_height){DOM.setStyle(co,'height',th);if(tb.clientHeight<s.max_height)DOM.setStyle(co,'overflow','hidden');}},showMenu:function(x,y,px){var t=this,s=t.settings,co,vp=DOM.getViewPort(),w,h,mx,my,ot=2,dm,tb,cp=t.classPrefix;t.collapse(1);if(t.isMenuVisible)return;if(!t.rendered){co=DOM.add(t.settings.container,t.renderNode());each(t.items,function(o){o.postRender();});t.element=new Element('menu_'+t.id,{blocker:1,container:s.container});}else co=DOM.get('menu_'+t.id);if(!tinymce.isOpera)DOM.setStyles(co,{left:-0xFFFF,top:-0xFFFF});DOM.show(co);t.update();x+=s.offset_x||0;y+=s.offset_y||0;vp.w-=4;vp.h-=4;if(s.constrain){w=co.clientWidth-ot;h=co.clientHeight-ot;mx=vp.x+vp.w;my=vp.y+vp.h;if((x+s.vp_offset_x+w)>mx)x=px?px-w:Math.max(0,(mx-s.vp_offset_x)-w);if((y+s.vp_offset_y+h)>my)y=Math.max(0,(my-s.vp_offset_y)-h);}DOM.setStyles(co,{left:x,top:y});t.element.update();t.isMenuVisible=1;t.mouseClickFunc=Event.add(co,'click',function(e){var m;e=e.target;if(e&&(e=DOM.getParent(e,'TR'))&&!DOM.hasClass(e,cp+'ItemSub')){m=t.items[e.id];if(m.isDisabled())return;dm=t;while(dm){if(dm.hideMenu)dm.hideMenu();dm=dm.settings.parent;}if(m.settings.onclick)m.settings.onclick(e);return Event.cancel(e);}});if(t.hasMenus()){t.mouseOverFunc=Event.add(co,'mouseover',function(e){var m,r,mi;e=e.target;if(e&&(e=DOM.getParent(e,'TR'))){m=t.items[e.id];if(t.lastMenu)t.lastMenu.collapse(1);if(m.isDisabled())return;if(e&&DOM.hasClass(e,cp+'ItemSub')){r=DOM.getRect(e);m.showMenu((r.x+r.w-ot),r.y-ot,r.x);t.lastMenu=m;DOM.addClass(DOM.get(m.id).firstChild,cp+'ItemActive');}}});}t.onShowMenu.dispatch(t);if(s.keyboard_focus){Event.add(co,'keydown',t._keyHandler,t);DOM.select('a','menu_'+t.id)[0].focus();t._focusIdx=0;}},hideMenu:function(c){var t=this,co=DOM.get('menu_'+t.id),e;if(!t.isMenuVisible)return;Event.remove(co,'mouseover',t.mouseOverFunc);Event.remove(co,'click',t.mouseClickFunc);Event.remove(co,'keydown',t._keyHandler);DOM.hide(co);t.isMenuVisible=0;if(!c)t.collapse(1);if(t.element)t.element.hide();if(e=DOM.get(t.id))DOM.removeClass(e.firstChild,t.classPrefix+'ItemActive');t.onHideMenu.dispatch(t);},add:function(o){var t=this,co;o=t.parent(o);if(t.isRendered&&(co=DOM.get('menu_'+t.id)))t._add(DOM.select('tbody',co)[0],o);return o;},collapse:function(d){this.parent(d);this.hideMenu(1);},remove:function(o){DOM.remove(o.id);this.destroy();return this.parent(o);},destroy:function(){var t=this,co=DOM.get('menu_'+t.id);Event.remove(co,'mouseover',t.mouseOverFunc);Event.remove(co,'click',t.mouseClickFunc);if(t.element)t.element.remove();DOM.remove(co);},renderNode:function(){var t=this,s=t.settings,n,tb,co,w;w=DOM.create('div',{id:'menu_'+t.id,'class':s['class'],'style':'position:absolute;left:0;top:0;z-index:200000'});co=DOM.add(w,'div',{id:'menu_'+t.id+'_co','class':t.classPrefix+(s['class']?' '+s['class']:'')});t.element=new Element('menu_'+t.id,{blocker:1,container:s.container});if(s.menu_line)DOM.add(co,'span',{'class':t.classPrefix+'Line'});n=DOM.add(co,'table',{id:'menu_'+t.id+'_tbl',border:0,cellPadding:0,cellSpacing:0});tb=DOM.add(n,'tbody');each(t.items,function(o){t._add(tb,o);});t.rendered=true;return w;},_keyHandler:function(e){var t=this,kc=e.keyCode;function focus(d){var i=t._focusIdx+d,e=DOM.select('a','menu_'+t.id)[i];if(e){t._focusIdx=i;e.focus();}};switch(kc){case 38:focus(-1);return;case 40:focus(1);return;case 13:return;case 27:return this.hideMenu();}},_add:function(tb,o){var n,s=o.settings,a,ro,it,cp=this.classPrefix;if(s.separator){ro=DOM.add(tb,'tr',{id:o.id,'class':cp+'ItemSeparator'});DOM.add(ro,'td',{'class':cp+'ItemSeparator'});if(n=ro.previousSibling)DOM.addClass(n,'mceLast');return;}n=ro=DOM.add(tb,'tr',{id:o.id,'class':cp+'Item '+cp+'ItemEnabled'});n=it=DOM.add(n,'td');n=a=DOM.add(n,'a',{href:'javascript:;',onclick:"return false;",onmousedown:'return false;'});DOM.addClass(it,s['class']);DOM.add(n,'span',{'class':'mceIcon'+(s.icon?' mce_'+s.icon:'')});n=DOM.add(n,s.element||'span',{'class':'mceText',title:o.settings.title},o.settings.title);if(o.settings.style)DOM.setAttrib(n,'style',o.settings.style);if(tb.childNodes.length==1)DOM.addClass(ro,'mceFirst');if((n=ro.previousSibling)&&DOM.hasClass(n,cp+'ItemSeparator'))DOM.addClass(ro,'mceFirst');if(o.collapse)DOM.addClass(ro,cp+'ItemSub');if(n=ro.previousSibling)DOM.removeClass(n,'mceLast');DOM.addClass(ro,'mceLast');}});})();(function(){var DOM=tinymce.DOM;tinymce.create('tinymce.ui.Button:tinymce.ui.Control',{Button:function(id,s){this.parent(id,s);this.classPrefix='mceButton';},renderHTML:function(){var cp=this.classPrefix,s=this.settings,h,l;l=DOM.encode(s.label||'');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)+'">';if(s.image)h+='<img class="mceIcon" src="'+s.image+'" />'+l+'</a>';else h+='<span class="mceIcon '+s['class']+'"></span>'+(l?'<span class="'+cp+'Label">'+l+'</span>':'')+'</a>';return h;},postRender:function(){var t=this,s=t.settings;tinymce.dom.Event.add(t.id,'click',function(e){if(!t.isDisabled())return s.onclick.call(s.scope,e);});}});})();(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,each=tinymce.each,Dispatcher=tinymce.util.Dispatcher;tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control',{ListBox:function(id,s){var t=this;t.parent(id,s);t.items=[];t.onChange=new Dispatcher(t);t.onPostRender=new Dispatcher(t);t.onAdd=new Dispatcher(t);t.onRenderMenu=new tinymce.util.Dispatcher(this);t.classPrefix='mceListBox';},select:function(v){var t=this,e,fv;if(v!=t.selectedValue){e=DOM.get(t.id+'_text');t.selectedValue=v;each(t.items,function(o){if(o.value==v){DOM.setHTML(e,DOM.encode(o.title));fv=1;return false;}});if(!fv){DOM.setHTML(e,DOM.encode(t.settings.title));DOM.addClass(e,'mceTitle');e=0;return;}else DOM.removeClass(e,'mceTitle');}e=0;},add:function(n,v,o){var t=this;o=o||{};o=tinymce.extend(o,{title:n,value:v});t.items.push(o);t.onAdd.dispatch(t,o);},getLength:function(){return this.items.length;},renderHTML:function(){var h='',t=this,s=t.settings,cp=t.classPrefix;h='<table id="'+t.id+'" cellpadding="0" cellspacing="0" class="'+cp+' '+cp+'Enabled'+(s['class']?(' '+s['class']):'')+'"><tbody><tr>';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>';h+='<td>'+DOM.createHTML('a',{id:t.id+'_open',tabindex:-1,href:'javascript:;','class':'mceOpen',onclick:"return false;",onmousedown:'return false;'},'<span></span>')+'</td>';h+='</tr></tbody></table>';return h;},showMenu:function(){var t=this,p1,p2,e=DOM.get(this.id),m;if(t.isDisabled()||t.items.length==0)return;if(t.menu&&t.menu.isMenuVisible)return t.hideMenu();if(!t.isMenuRendered){t.renderMenu();t.isMenuRendered=true;}p1=DOM.getPos(this.settings.menu_container);p2=DOM.getPos(e);m=t.menu;m.settings.offset_x=p2.x;m.settings.offset_y=p2.y;m.settings.keyboard_focus=!tinymce.isOpera;if(t.oldID)m.items[t.oldID].setSelected(0);each(t.items,function(o){if(o.value===t.selectedValue){m.items[o.id].setSelected(1);t.oldID=o.id;}});m.showMenu(0,e.clientHeight);Event.add(DOM.doc,'mousedown',t.hideMenu,t);DOM.addClass(t.id,t.classPrefix+'Selected');},hideMenu:function(e){var t=this;if(e&&e.type=="mousedown"&&(e.target.id==t.id+'_text'||e.target.id==t.id+'_open'))return;if(!e||!DOM.getParent(e.target,function(n){return DOM.hasClass(n,'mceMenu');})){DOM.removeClass(t.id,t.classPrefix+'Selected');Event.remove(DOM.doc,'mousedown',t.hideMenu,t);if(t.menu)t.menu.hideMenu();}},renderMenu:function(){var t=this,m;m=t.settings.control_manager.createDropMenu(t.id+'_menu',{menu_line:1,'class':t.classPrefix+'Menu mceNoIcons',max_width:150,max_height:150});m.onHideMenu.add(t.hideMenu,t);m.add({title:t.settings.title,'class':'mceMenuItemTitle',onclick:function(){if(t.settings.onselect('')!==false)t.select('');}});each(t.items,function(o){o.id=DOM.uniqueId();o.onclick=function(){if(t.settings.onselect(o.value)!==false)t.select(o.value);};m.add(o);});t.onRenderMenu.dispatch(t,m);t.menu=m;},postRender:function(){var t=this,cp=t.classPrefix;Event.add(t.id,'click',t.showMenu,t);Event.add(t.id+'_text','focus',function(e){if(!t._focused){t.keyDownHandler=Event.add(t.id+'_text','keydown',function(e){var idx=-1,v,kc=e.keyCode;each(t.items,function(v,i){if(t.selectedValue==v.value)idx=i;});if(kc==38)v=t.items[idx-1];else if(kc==40)v=t.items[idx+1];else if(kc==13){v=t.selectedValue;t.selectedValue=null;t.settings.onselect(v);return Event.cancel(e);}if(v){t.hideMenu();t.select(v.value);}});}t._focused=1;});Event.add(t.id+'_text','blur',function(){Event.remove(t.id+'_text','keydown',t.keyDownHandler);t._focused=0;});if(tinymce.isIE6||!DOM.boxModel){Event.add(t.id,'mouseover',function(){if(!DOM.hasClass(t.id,cp+'Disabled'))DOM.addClass(t.id,cp+'Hover');});Event.add(t.id,'mouseout',function(){if(!DOM.hasClass(t.id,cp+'Disabled'))DOM.removeClass(t.id,cp+'Hover');});}t.onPostRender.dispatch(t,DOM.get(t.id));},destroy:function(){this.parent();Event.clear(this.id+'_text');}});})();(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,each=tinymce.each,Dispatcher=tinymce.util.Dispatcher;tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox',{NativeListBox:function(id,s){this.parent(id,s);this.classPrefix='mceNativeListBox';},setDisabled:function(s){DOM.get(this.id).disabled=s;},isDisabled:function(){return DOM.get(this.id).disabled;},select:function(v){var e=DOM.get(this.id),ol=e.options;v=''+(v||'');e.selectedIndex=0;each(ol,function(o,i){if(o.value==v){e.selectedIndex=i;return false;}});},add:function(n,v,a){var o,t=this;a=a||{};a.value=v;if(t.isRendered())DOM.add(DOM.get(this.id),'option',a,n);o={title:n,value:v,attribs:a};t.items.push(o);t.onAdd.dispatch(t,o);},getLength:function(){return DOM.get(this.id).options.length-1;},renderHTML:function(){var h,t=this;h=DOM.createHTML('option',{value:''},'-- '+t.settings.title+' --');each(t.items,function(it){h+=DOM.createHTML('option',{value:it.value},it.title);});h=DOM.createHTML('select',{id:t.id,'class':'mceNativeListBox'},h);return h;},postRender:function(){var t=this,ch;t.rendered=true;function onChange(e){var v=e.target.options[e.target.selectedIndex].value;t.onChange.dispatch(t,v);if(t.settings.onselect)t.settings.onselect(v);};Event.add(t.id,'change',onChange);Event.add(t.id,'keydown',function(e){var bf;Event.remove(t.id,'change',ch);bf=Event.add(t.id,'blur',function(){Event.add(t.id,'change',onChange);Event.remove(t.id,'blur',bf);});if(e.keyCode==13||e.keyCode==32){onChange(e);return Event.cancel(e);}});t.onPostRender.dispatch(t,DOM.get(t.id));}});})();(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,each=tinymce.each;tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button',{MenuButton:function(id,s){this.parent(id,s);this.onRenderMenu=new tinymce.util.Dispatcher(this);s.menu_container=s.menu_container||DOM.doc.body;},showMenu:function(){var t=this,p1,p2,e=DOM.get(t.id),m;if(t.isDisabled())return;if(!t.isMenuRendered){t.renderMenu();t.isMenuRendered=true;}if(t.isMenuVisible)return t.hideMenu();p1=DOM.getPos(t.settings.menu_container);p2=DOM.getPos(e);m=t.menu;m.settings.offset_x=p2.x;m.settings.offset_y=p2.y;m.settings.vp_offset_x=p2.x;m.settings.vp_offset_y=p2.y;m.settings.keyboard_focus=t._focused;m.showMenu(0,e.clientHeight);Event.add(DOM.doc,'mousedown',t.hideMenu,t);t.setState('Selected',1);t.isMenuVisible=1;},renderMenu:function(){var t=this,m;m=t.settings.control_manager.createDropMenu(t.id+'_menu',{menu_line:1,'class':this.classPrefix+'Menu',icons:t.settings.icons});m.onHideMenu.add(t.hideMenu,t);t.onRenderMenu.dispatch(t,m);t.menu=m;},hideMenu:function(e){var t=this;if(e&&e.type=="mousedown"&&DOM.getParent(e.target,function(e){return e.id===t.id||e.id===t.id+'_open';}))return;if(!e||!DOM.getParent(e.target,function(n){return DOM.hasClass(n,'mceMenu');})){t.setState('Selected',0);Event.remove(DOM.doc,'mousedown',t.hideMenu,t);if(t.menu)t.menu.hideMenu();}t.isMenuVisible=0;},postRender:function(){var t=this,s=t.settings;Event.add(t.id,'click',function(){if(!t.isDisabled()){if(s.onclick)s.onclick(t.value);t.showMenu();}});}});})();(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,each=tinymce.each;tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton',{SplitButton:function(id,s){this.parent(id,s);this.classPrefix='mceSplitButton';},renderHTML:function(){var h,t=this,s=t.settings,h1;h='<tbody><tr>';if(s.image)h1=DOM.createHTML('img ',{src:s.image,'class':'mceAction '+s['class']});else h1=DOM.createHTML('span',{'class':'mceAction '+s['class']},'');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>';h1=DOM.createHTML('span',{'class':'mceOpen '+s['class']});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>';h+='</tr></tbody>';return DOM.createHTML('table',{id:t.id,'class':'mceSplitButton mceSplitButtonEnabled '+s['class'],cellpadding:'0',cellspacing:'0',onmousedown:'return false;',title:s.title},h);},postRender:function(){var t=this,s=t.settings;if(s.onclick){Event.add(t.id+'_action','click',function(){if(!t.isDisabled())s.onclick(t.value);});}Event.add(t.id+'_open','click',t.showMenu,t);Event.add(t.id+'_open','focus',function(){t._focused=1;});Event.add(t.id+'_open','blur',function(){t._focused=0;});if(tinymce.isIE6||!DOM.boxModel){Event.add(t.id,'mouseover',function(){if(!DOM.hasClass(t.id,'mceSplitButtonDisabled'))DOM.addClass(t.id,'mceSplitButtonHover');});Event.add(t.id,'mouseout',function(){if(!DOM.hasClass(t.id,'mceSplitButtonDisabled'))DOM.removeClass(t.id,'mceSplitButtonHover');});}},destroy:function(){this.parent();Event.clear(this.id+'_action');Event.clear(this.id+'_open');}});})();(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,is=tinymce.is,each=tinymce.each;tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton',{ColorSplitButton:function(id,s){var t=this;t.parent(id,s);t.settings=s=tinymce.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'},t.settings);t.onShowMenu=new tinymce.util.Dispatcher(t);t.onHideMenu=new tinymce.util.Dispatcher(t);t.value=s.default_color;},showMenu:function(){var t=this,r,p,e,p2;if(t.isDisabled())return;if(!t.isMenuRendered){t.renderMenu();t.isMenuRendered=true;}if(t.isMenuVisible)return t.hideMenu();e=DOM.get(t.id);DOM.show(t.id+'_menu');DOM.addClass(e,'mceSplitButtonSelected');p2=DOM.getPos(e);DOM.setStyles(t.id+'_menu',{left:p2.x,top:p2.y+e.clientHeight,zIndex:200000});e=0;Event.add(DOM.doc,'mousedown',t.hideMenu,t);if(t._focused){t._keyHandler=Event.add(t.id+'_menu','keydown',function(e){if(e.keyCode==27)t.hideMenu();});DOM.select('a',t.id+'_menu')[0].focus();}t.onShowMenu.dispatch(t);t.isMenuVisible=1;},hideMenu:function(e){var t=this;if(e&&e.type=="mousedown"&&DOM.getParent(e.target,function(e){return e.id===t.id+'_open';}))return;if(!e||!DOM.getParent(e.target,function(n){return DOM.hasClass(n,'mceSplitButtonMenu');})){DOM.removeClass(t.id,'mceSplitButtonSelected');Event.remove(DOM.doc,'mousedown',t.hideMenu,t);Event.remove(t.id+'_menu','keydown',t._keyHandler);DOM.hide(t.id+'_menu');}t.onHideMenu.dispatch(t);t.isMenuVisible=0;},renderMenu:function(){var t=this,m,i=0,s=t.settings,n,tb,tr,w;w=DOM.add(s.menu_container,'div',{id:t.id+'_menu','class':s['menu_class']+' '+s['class'],style:'position:absolute;left:0;top:-1000px;'});m=DOM.add(w,'div',{'class':s['class']+' mceSplitButtonMenu'});DOM.add(m,'span',{'class':'mceMenuLine'});n=DOM.add(m,'table',{'class':'mceColorSplitMenu'});tb=DOM.add(n,'tbody');i=0;each(is(s.colors,'array')?s.colors:s.colors.split(','),function(c){c=c.replace(/^#/,'');if(!i--){tr=DOM.add(tb,'tr');i=s.grid_width-1;}n=DOM.add(tr,'td');n=DOM.add(n,'a',{href:'javascript:;',style:{backgroundColor:'#'+c},mce_color:'#'+c});});if(s.more_colors_func){n=DOM.add(tb,'tr');n=DOM.add(n,'td',{colspan:s.grid_width,'class':'mceMoreColors'});n=DOM.add(n,'a',{id:t.id+'_more',href:'javascript:;',onclick:'return false;','class':'mceMoreColors'},s.more_colors_title);Event.add(n,'click',function(e){s.more_colors_func.call(s.more_colors_scope||this);return Event.cancel(e);});}DOM.addClass(m,'mceColorSplitMenu');Event.add(t.id+'_menu','click',function(e){var c;e=e.target;if(e.nodeName=='A'&&(c=e.getAttribute('mce_color')))t.setColor(c);return Event.cancel(e);});return w;},setColor:function(c){var t=this;DOM.setStyle(t.id+'_preview','backgroundColor',c);t.value=c;t.hideMenu();t.settings.onselect(c);},postRender:function(){var t=this,id=t.id;t.parent();DOM.add(id+'_action','div',{id:id+'_preview','class':'mceColorPreview'});},destroy:function(){this.parent();Event.clear(this.id+'_menu');Event.clear(this.id+'_more');DOM.remove(this.id+'_menu');}});})();tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container',{renderHTML:function(){var t=this,h='',c,co,dom=tinymce.DOM,s=t.settings,i,pr,nx,cl;cl=t.controls;for(i=0;i<cl.length;i++){co=cl[i];pr=cl[i-1];nx=cl[i+1];if(i===0){c='mceToolbarStart';if(co.Button)c+=' mceToolbarStartButton';else if(co.SplitButton)c+=' mceToolbarStartSplitButton';else if(co.ListBox)c+=' mceToolbarStartListBox';h+=dom.createHTML('td',{'class':c},dom.createHTML('span',null,'<!-- IE -->'));}if(pr&&co.ListBox){if(pr.Button||pr.SplitButton)h+=dom.createHTML('td',{'class':'mceToolbarEnd'},dom.createHTML('span',null,'<!-- IE -->'));}if(dom.stdMode)h+='<td style="position: relative">'+co.renderHTML()+'</td>';else h+='<td>'+co.renderHTML()+'</td>';if(nx&&co.ListBox){if(nx.Button||nx.SplitButton)h+=dom.createHTML('td',{'class':'mceToolbarStart'},dom.createHTML('span',null,'<!-- IE -->'));}}c='mceToolbarEnd';if(co.Button)c+=' mceToolbarEndButton';else if(co.SplitButton)c+=' mceToolbarEndSplitButton';else if(co.ListBox)c+=' mceToolbarEndListBox';h+=dom.createHTML('td',{'class':c},dom.createHTML('span',null,'<!-- IE -->'));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>');}});(function(){var Dispatcher=tinymce.util.Dispatcher,each=tinymce.each;tinymce.create('tinymce.AddOnManager',{items:[],urls:{},lookup:{},onAdd:new Dispatcher(this),get:function(n){return this.lookup[n];},requireLangPack:function(n){var u,s;if(tinymce.EditorManager.settings){u=this.urls[n]+'/langs/'+tinymce.EditorManager.settings.language+'.js';s=tinymce.EditorManager.settings;if(s){if(!tinymce.dom.Event.domLoaded&&!s.strict_mode)tinymce.ScriptLoader.load(u);else tinymce.ScriptLoader.add(u);}}},add:function(id,o){this.items.push(o);this.lookup[id]=o;this.onAdd.dispatch(this,id,o);return o;},load:function(n,u,cb,s){var t=this;if(t.urls[n])return;if(u.indexOf('/')!=0&&u.indexOf('://')==-1)u=tinymce.baseURL+'/'+u;t.urls[n]=u.substring(0,u.lastIndexOf('/'));tinymce.ScriptLoader.add(u,cb,s);}});tinymce.PluginManager=new tinymce.AddOnManager();tinymce.ThemeManager=new tinymce.AddOnManager();}());(function(){var each=tinymce.each,extend=tinymce.extend,DOM=tinymce.DOM,Event=tinymce.dom.Event,ThemeManager=tinymce.ThemeManager,PluginManager=tinymce.PluginManager,explode=tinymce.explode;tinymce.create('static tinymce.EditorManager',{editors:{},i18n:{},activeEditor:null,preInit:function(){var t=this,lo=window.location;tinymce.documentBaseURL=lo.href.replace(/[\?#].*$/,'').replace(/[\/\\][^\/]+$/,'');if(!/[\/\\]$/.test(tinymce.documentBaseURL))tinymce.documentBaseURL+='/';tinymce.baseURL=new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);tinymce.EditorManager.baseURI=new tinymce.util.URI(tinymce.baseURL);if(tinymce.EditorManager.baseURI.host!=lo.hostname&&lo.hostname)document.domain=tinymce.relaxedDomain=lo.hostname.replace(/.*\.(.+\..+)$/,'$1');t.onBeforeUnload=new tinymce.util.Dispatcher(t);Event.add(window,'beforeunload',function(e){t.onBeforeUnload.dispatch(t,e);});},init:function(s){var t=this,pl,sl=tinymce.ScriptLoader,c,e;function execCallback(se,n,s){var f=se[n];if(!f)return;if(tinymce.is(f,'string')){s=f.replace(/\.\w+$/,'');s=s?tinymce.resolve(s):0;f=tinymce.resolve(f);}return f.apply(s||this,Array.prototype.slice.call(arguments,2));};s=extend({theme:"simple",language:"en",strict_loading_mode:document.contentType=='application/xhtml+xml'},s);t.settings=s;if(!Event.domLoaded&&!s.strict_loading_mode){if(s.language)sl.add(tinymce.baseURL+'/langs/'+s.language+'.js');if(s.theme&&s.theme.charAt(0)!='-'&&!ThemeManager.urls[s.theme])ThemeManager.load(s.theme,'themes/'+s.theme+'/editor_template'+tinymce.suffix+'.js');if(s.plugins){pl=explode(s.plugins);if(tinymce.inArray(pl,'compat2x')!=-1)PluginManager.load('compat2x','plugins/compat2x/editor_plugin'+tinymce.suffix+'.js');each(pl,function(v){if(v&&v.charAt(0)!='-'&&!PluginManager.urls[v]){if(!tinymce.isWebKit&&v=='safari')return;PluginManager.load(v,'plugins/'+v+'/editor_plugin'+tinymce.suffix+'.js');}});}sl.loadQueue();}Event.add(document,'init',function(){var l,co;execCallback(s,'onpageload');if(s.browsers){l=false;each(explode(s.browsers),function(v){switch(v){case'ie':case'msie':if(tinymce.isIE)l=true;break;case'gecko':if(tinymce.isGecko)l=true;break;case'safari':case'webkit':if(tinymce.isWebKit)l=true;break;case'opera':if(tinymce.isOpera)l=true;break;}});if(!l)return;}switch(s.mode){case"exact":l=s.elements||'';if(l.length>0){each(explode(l),function(v){if(DOM.get(v))new tinymce.Editor(v,s).render(1);else{c=0;each(document.forms,function(f){each(f.elements,function(e){if(e.name===v){v='mce_editor_'+c;DOM.setAttrib(e,'id',v);new tinymce.Editor(v,s).render(1);}});});}});}break;case"textareas":case"specific_textareas":function hasClass(n,c){return c.constructor===RegExp?c.test(n.className):DOM.hasClass(n,c);};each(DOM.select('textarea'),function(v){if(s.editor_deselector&&hasClass(v,s.editor_deselector))return;if(!s.editor_selector||hasClass(v,s.editor_selector)){e=DOM.get(v.name);if(!v.id&&!e)v.id=v.name;if(!v.id||t.get(v.id))v.id=DOM.uniqueId();new tinymce.Editor(v.id,s).render(1);}});break;}if(s.oninit){l=co=0;each(t.editors,function(ed){co++;if(!ed.initialized){ed.onInit.add(function(){l++;if(l==co)execCallback(s,'oninit');});}else l++;if(l==co)execCallback(s,'oninit');});}});},get:function(id){return this.editors[id];},getInstanceById:function(id){return this.get(id);},add:function(e){this.editors[e.id]=e;this._setActive(e);return e;},remove:function(e){var t=this;if(!t.editors[e.id])return null;delete t.editors[e.id];if(t.activeEditor==e){each(t.editors,function(e){t._setActive(e);return false;});}e.destroy();return e;},execCommand:function(c,u,v){var t=this,ed=t.get(v),w;switch(c){case"mceFocus":ed.focus();return true;case"mceAddEditor":case"mceAddControl":if(!t.get(v))new tinymce.Editor(v,t.settings).render();return true;case"mceAddFrameControl":w=v.window;w.tinyMCE=tinyMCE;w.tinymce=tinymce;tinymce.DOM.doc=w.document;tinymce.DOM.win=w;ed=new tinymce.Editor(v.element_id,v);ed.render();if(tinymce.isIE){function clr(){ed.destroy();w.detachEvent('onunload',clr);w=w.tinyMCE=w.tinymce=null;};w.attachEvent('onunload',clr);}v.page_window=null;return true;case"mceRemoveEditor":case"mceRemoveControl":ed.remove();return true;case'mceToggleEditor':if(!ed){t.execCommand('mceAddControl',0,v);return true;}if(ed.isHidden())ed.show();else ed.hide();return true;}if(t.activeEditor)return t.activeEditor.execCommand(c,u,v);return false;},execInstanceCommand:function(id,c,u,v){var ed=this.get(id);if(ed)return ed.execCommand(c,u,v);return false;},triggerSave:function(){each(this.editors,function(e){e.save();});},addI18n:function(p,o){var lo,i18n=this.i18n;if(!tinymce.is(p,'string')){each(p,function(o,lc){each(o,function(o,g){each(o,function(o,k){if(g==='common')i18n[lc+'.'+k]=o;else i18n[lc+'.'+g+'.'+k]=o;});});});}else{each(o,function(o,k){i18n[p+'.'+k]=o;});}},_setActive:function(e){this.selectedInstance=this.activeEditor=e;}});tinymce.EditorManager.preInit();})();var tinyMCE=window.tinyMCE=tinymce.EditorManager;(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,extend=tinymce.extend,Dispatcher=tinymce.util.Dispatcher;var each=tinymce.each,isGecko=tinymce.isGecko,isIE=tinymce.isIE,isWebKit=tinymce.isWebKit;var is=tinymce.is,ThemeManager=tinymce.ThemeManager,PluginManager=tinymce.PluginManager,EditorManager=tinymce.EditorManager;var inArray=tinymce.inArray,grep=tinymce.grep,explode=tinymce.explode;tinymce.create('tinymce.Editor',{Editor:function(id,s){var t=this;t.id=t.editorId=id;t.execCommands={};t.queryStateCommands={};t.queryValueCommands={};t.plugins={};each(['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(e){t[e]=new Dispatcher(t);});t.settings=s=extend({id:id,language:'en',docs_language:'en',theme:'simple',skin:'default',delta_width:0,delta_height:0,popup_css:'',plugins:'',document_base_url:tinymce.documentBaseURL,add_form_submit_trigger:1,submit_patch:1,add_unload_trigger:1,convert_urls:1,relative_urls:1,remove_script_host:1,table_inline_editing:0,object_resizing:1,cleanup:1,accessibility_focus:1,custom_shortcuts:1,custom_undo_redo_keyboard_shortcuts:1,custom_undo_redo_restore_selection:1,custom_undo_redo:1,doctype:'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',visual_table_class:'mceItemTable',visual:1,inline_styles:true,convert_fonts_to_spans:true,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[align],-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=0|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],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'},s);t.documentBaseURI=new tinymce.util.URI(s.document_base_url||tinymce.documentBaseURL,{base_uri:tinyMCE.baseURI});t.baseURI=EditorManager.baseURI;t.execCallback('setup',t);},render:function(nst){var t=this,s=t.settings,id=t.id,sl=tinymce.ScriptLoader;if(!Event.domLoaded){Event.add(document,'init',function(){t.render();});return;}if(!nst){s.strict_loading_mode=1;tinyMCE.settings=s;}if(!t.getElement())return;if(s.strict_loading_mode){sl.settings.strict_mode=s.strict_loading_mode;tinymce.DOM.settings.strict=1;}if(!/TEXTAREA|INPUT/i.test(t.getElement().nodeName)&&s.hidden_input&&DOM.getParent(id,'form'))DOM.insertAfter(DOM.create('input',{type:'hidden',name:id}),id);t.windowManager=new tinymce.WindowManager(t);if(s.encoding=='xml'){t.onGetContent.add(function(ed,o){if(o.save)o.content=DOM.encode(o.content);});}if(s.add_form_submit_trigger){t.onSubmit.addToTop(function(){if(t.initialized){t.save();t.isNotDirty=1;}});}if(s.add_unload_trigger&&!s.ask){t._beforeUnload=tinyMCE.onBeforeUnload.add(function(){if(t.initialized&&!t.destroyed&&!t.isHidden())t.save({format:'raw',no_events:true});});}tinymce.addUnload(t.destroy,t);if(s.submit_patch){t.onBeforeRenderUI.add(function(){var n=t.getElement().form;if(!n)return;if(n._mceOldSubmit)return;if(!n.submit.nodeType&&!n.submit.length){t.formElement=n;n._mceOldSubmit=n.submit;n.submit=function(){EditorManager.triggerSave();t.isNotDirty=1;return this._mceOldSubmit(this);};}n=null;});}function loadScripts(){if(s.language)sl.add(tinymce.baseURL+'/langs/'+s.language+'.js');if(s.theme.charAt(0)!='-'&&!ThemeManager.urls[s.theme])ThemeManager.load(s.theme,'themes/'+s.theme+'/editor_template'+tinymce.suffix+'.js');each(explode(s.plugins),function(p){if(p&&p.charAt(0)!='-'&&!PluginManager.urls[p]){if(!isWebKit&&p=='safari')return;PluginManager.load(p,'plugins/'+p+'/editor_plugin'+tinymce.suffix+'.js');}});sl.loadQueue(function(){if(s.ask){function ask(){window.setTimeout(function(){Event.remove(t.id,'focus',ask);t.windowManager.confirm(t.getLang('edit_confirm'),function(s){if(s)t.init();});},0);};Event.add(t.id,'focus',ask);return;}if(!t.removed)t.init();});};if(s.plugins.indexOf('compat2x')!=-1){PluginManager.load('compat2x','plugins/compat2x/editor_plugin'+tinymce.suffix+'.js');sl.loadQueue(loadScripts);}else loadScripts();},init:function(){var n,t=this,s=t.settings,w,h,e=t.getElement(),o,ti,u,bi,bc,re;EditorManager.add(t);s.theme=s.theme.replace(/-/,'');o=ThemeManager.get(s.theme);t.theme=new o();if(t.theme.init&&s.init_theme)t.theme.init(t,ThemeManager.urls[s.theme]||tinymce.documentBaseURL.replace(/\/$/,''));each(explode(s.plugins.replace(/\-/g,'')),function(p){var c=PluginManager.get(p),u=PluginManager.urls[p]||tinymce.documentBaseURL.replace(/\/$/,''),po;if(c){po=new c(t,u);t.plugins[p]=po;if(po.init)po.init(t,u);}});if(s.popup_css)s.popup_css=t.documentBaseURI.toAbsolute(s.popup_css);else s.popup_css=t.baseURI.toAbsolute("themes/"+s.theme+"/skins/"+s.skin+"/dialog.css");if(s.popup_css_add)s.popup_css+=','+t.documentBaseURI.toAbsolute(s.popup_css_add);t.controlManager=new tinymce.ControlManager(t);t.undoManager=new tinymce.UndoManager(t);t.undoManager.onAdd.add(function(um,l){if(!l.initial)return t.onChange.dispatch(t,l,um);});t.undoManager.onUndo.add(function(um,l){return t.onUndo.dispatch(t,l,um);});t.undoManager.onRedo.add(function(um,l){return t.onRedo.dispatch(t,l,um);});if(s.custom_undo_redo){t.onExecCommand.add(function(ed,cmd,ui,val,a){if(cmd!='Undo'&&cmd!='Redo'&&cmd!='mceRepaint'&&(!a||!a.skip_undo))t.undoManager.add();});}t.onExecCommand.add(function(ed,c){if(!/^(FontName|FontSize)$/.test(c))t.nodeChanged();});if(isGecko){function repaint(a,o){if(!o||!o.initial)t.execCommand('mceRepaint');};t.onUndo.add(repaint);t.onRedo.add(repaint);t.onSetContent.add(repaint);}t.onBeforeRenderUI.dispatch(t,t.controlManager);if(s.render_ui){w=s.width||e.style.width||e.offsetWidth;h=s.height||e.style.height||e.offsetHeight;t.orgDisplay=e.style.display;re=/^[0-9\.]+(|px)$/i;if(re.test(''+w))w=Math.max(parseInt(w)+(o.deltaWidth||0),100);if(re.test(''+h))h=Math.max(parseInt(h)+(o.deltaHeight||0),100);o=t.theme.renderUI({targetNode:e,width:w,height:h,deltaWidth:s.delta_width,deltaHeight:s.delta_height});t.editorContainer=o.editorContainer;}DOM.setStyles(o.sizeContainer||o.editorContainer,{width:w,height:h});h=(o.iframeHeight||h)+((h+'').indexOf('%')==-1?(o.deltaHeight||0):'');if(h<100)h=100;t.iframeHTML=s.doctype+'<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="'+t.documentBaseURI.getURI()+'" />';t.iframeHTML+='<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';if(tinymce.relaxedDomain)t.iframeHTML+='<script type="text/javascript">document.domain = "'+tinymce.relaxedDomain+'";</script>';bi=s.body_id||'tinymce';if(bi.indexOf('=')!=-1){bi=t.getParam('body_id','','hash');bi=bi[t.id]||bi;}bc=s.body_class||'';if(bc.indexOf('=')!=-1){bc=t.getParam('body_class','','hash');bc=bc[t.id]||'';}t.iframeHTML+='</head><body id="'+bi+'" class="mceContentBody '+bc+'"></body></html>';if(tinymce.relaxedDomain){if(isIE)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();})()';else if(tinymce.isOpera)u='javascript:(function(){document.open();document.domain="'+document.domain+'";document.close();ed.setupIframe();})()';}n=DOM.add(o.iframeContainer,'iframe',{id:t.id+"_ifr",src:u||'javascript:""',frameBorder:'0',style:{width:'100%',height:h}});t.contentAreaContainer=o.iframeContainer;DOM.get(o.editorContainer).style.display=t.orgDisplay;DOM.get(t.id).style.display='none';if(tinymce.isOldWebKit){Event.add(n,'load',t.setupIframe,t);n.src=tinymce.baseURL+'/plugins/safari/blank.htm';}else{if(!isIE||!tinymce.relaxedDomain)t.setupIframe();e=n=o=null;}},setupIframe:function(){var t=this,s=t.settings,e=DOM.get(t.id),d=t.getDoc(),h,b;if(!isIE||!tinymce.relaxedDomain){d.open();d.write(t.iframeHTML);d.close();}if(!isIE){try{d.designMode='On';}catch(ex){}}if(isIE){b=t.getBody();DOM.hide(b);b.contentEditable=true;DOM.show(b);}t.dom=new tinymce.DOM.DOMUtils(t.getDoc(),{keep_values:true,url_converter:t.convertURL,url_converter_scope:t,hex_colors:s.force_hex_style_colors,class_filter:s.class_filter,update_styles:1,fix_ie_paragraphs:1});t.serializer=new tinymce.dom.Serializer({entity_encoding:s.entity_encoding,entities:s.entities,valid_elements:s.verify_html===false?'*[*]':s.valid_elements,extended_valid_elements:s.extended_valid_elements,valid_child_elements:s.valid_child_elements,invalid_elements:s.invalid_elements,fix_table_elements:s.fix_table_elements,fix_list_elements:s.fix_list_elements,fix_content_duplication:s.fix_content_duplication,convert_fonts_to_spans:s.convert_fonts_to_spans,font_size_classes:s.font_size_classes,font_size_style_values:s.font_size_style_values,apply_source_formatting:s.apply_source_formatting,remove_linebreaks:s.remove_linebreaks,dom:t.dom});t.selection=new tinymce.dom.Selection(t.dom,t.getWin(),t.serializer);t.forceBlocks=new tinymce.ForceBlocks(t,{forced_root_block:s.forced_root_block});t.editorCommands=new tinymce.EditorCommands(t);t.serializer.onPreProcess.add(function(se,o){return t.onPreProcess.dispatch(t,o,se);});t.serializer.onPostProcess.add(function(se,o){return t.onPostProcess.dispatch(t,o,se);});t.onPreInit.dispatch(t);if(!s.gecko_spellcheck)t.getBody().spellcheck=0;t._addEvents();t.controlManager.onPostRender.dispatch(t,t.controlManager);t.onPostRender.dispatch(t);if(s.directionality)t.getBody().dir=s.directionality;if(s.nowrap)t.getBody().style.whiteSpace="nowrap";if(s.auto_resize)t.onNodeChange.add(t.resizeToContent,t);if(s.custom_elements){function handleCustom(ed,o){each(explode(s.custom_elements),function(v){var n;if(v.indexOf('~')===0){v=v.substring(1);n='span';}else n='div';o.content=o.content.replace(new RegExp('<('+v+')([^>]*)>','g'),'<'+n+' mce_name="$1"$2>');o.content=o.content.replace(new RegExp('</('+v+')>','g'),'</'+n+'>');});};t.onBeforeSetContent.add(handleCustom);t.onPostProcess.add(function(ed,o){if(o.set)handleCustom(ed,o)});}if(s.handle_node_change_callback){t.onNodeChange.add(function(ed,cm,n){t.execCallback('handle_node_change_callback',t.id,n,-1,-1,true,t.selection.isCollapsed());});}if(s.save_callback){t.onSaveContent.add(function(ed,o){var h=t.execCallback('save_callback',t.id,o.content,t.getBody());if(h)o.content=h;});}if(s.onchange_callback){t.onChange.add(function(ed,l){t.execCallback('onchange_callback',t,l);});}if(s.convert_newlines_to_brs){t.onBeforeSetContent.add(function(ed,o){if(o.initial)o.content=o.content.replace(/\r?\n/g,'<br />');});}if(s.fix_nesting&&isIE){t.onBeforeSetContent.add(function(ed,o){o.content=t._fixNesting(o.content);});}if(s.preformatted){t.onPostProcess.add(function(ed,o){o.content=o.content.replace(/^\s*<pre.*?>/,'');o.content=o.content.replace(/<\/pre>\s*$/,'');if(o.set)o.content='<pre class="mceItemHidden">'+o.content+'</pre>';});}if(s.verify_css_classes){t.serializer.attribValueFilter=function(n,v){var s,cl;if(n=='class'){if(!t.classesRE){cl=t.dom.getClasses();if(cl.length>0){s='';each(cl,function(o){s+=(s?'|':'')+o['class'];});t.classesRE=new RegExp('('+s+')','gi');}}return!t.classesRE||/(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v)||t.classesRE.test(v)?v:'';}return v;};}if(s.convert_fonts_to_spans)t._convertFonts();if(s.inline_styles)t._convertInlineElements();if(s.cleanup_callback){t.onBeforeSetContent.add(function(ed,o){o.content=t.execCallback('cleanup_callback','insert_to_editor',o.content,o);});t.onPreProcess.add(function(ed,o){if(o.set)t.execCallback('cleanup_callback','insert_to_editor_dom',o.node,o);if(o.get)t.execCallback('cleanup_callback','get_from_editor_dom',o.node,o);});t.onPostProcess.add(function(ed,o){if(o.set)o.content=t.execCallback('cleanup_callback','insert_to_editor',o.content,o);if(o.get)o.content=t.execCallback('cleanup_callback','get_from_editor',o.content,o);});}if(s.save_callback){t.onGetContent.add(function(ed,o){if(o.save)o.content=t.execCallback('save_callback',t.id,o.content,t.getBody());});}if(s.handle_event_callback){t.onEvent.add(function(ed,e,o){if(t.execCallback('handle_event_callback',e,ed,o)===false)Event.cancel(e);});}t.onSetContent.add(function(){t.addVisual(t.getBody());});if(s.padd_empty_editor){t.onPostProcess.add(function(ed,o){o.content=o.content.replace(/^(<p>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/,'');});}if(isGecko){try{d.designMode='Off';d.designMode='On';}catch(ex){}}setTimeout(function(){if(t.removed)return;t.load({initial:true,format:(s.cleanup_on_startup?'html':'raw')});t.startContent=t.getContent({format:'raw'});t.undoManager.add({initial:true});t.initialized=true;t.onInit.dispatch(t);t.execCallback('setupcontent_callback',t.id,t.getBody(),t.getDoc());t.execCallback('init_instance_callback',t);t.focus(true);t.nodeChanged({initial:1});if(s.content_css){tinymce.each(explode(s.content_css),function(u){t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));});}if(s.auto_focus){setTimeout(function(){var ed=EditorManager.get(s.auto_focus);ed.selection.select(ed.getBody(),1);ed.selection.collapse(1);ed.getWin().focus();},100);}},1);e=null;},focus:function(sf){var oed,t=this,ce=t.settings.content_editable;if(!sf){if(!ce&&(!isIE||t.selection.getNode().ownerDocument!=t.getDoc()))t.getWin().focus();}if(EditorManager.activeEditor!=t){if((oed=EditorManager.activeEditor)!=null)oed.onDeactivate.dispatch(oed,t);t.onActivate.dispatch(t,oed);}EditorManager._setActive(t);},execCallback:function(n){var t=this,f=t.settings[n],s;if(!f)return;if(t.callbackLookup&&(s=t.callbackLookup[n])){f=s.func;s=s.scope;}if(is(f,'string')){s=f.replace(/\.\w+$/,'');s=s?tinymce.resolve(s):0;f=tinymce.resolve(f);t.callbackLookup=t.callbackLookup||{};t.callbackLookup[n]={func:f,scope:s};}return f.apply(s||t,Array.prototype.slice.call(arguments,1));},translate:function(s){var c=this.settings.language,i18n=EditorManager.i18n;if(!s)return'';return i18n[c+'.'+s]||s.replace(/{\#([^}]+)\}/g,function(a,b){return i18n[c+'.'+b]||'{#'+b+'}';});},getLang:function(n,dv){return EditorManager.i18n[this.settings.language+'.'+n]||(is(dv)?dv:'{#'+n+'}');},getParam:function(n,dv,ty){var tr=tinymce.trim,v=is(this.settings[n])?this.settings[n]:dv,o;if(ty==='hash'){o={};if(is(v,'string')){each(v.indexOf('=')>0?v.split(/[;,](?![^=;,]*(?:[;,]|$))/):v.split(','),function(v){v=v.split('=');if(v.length>1)o[tr(v[0])]=tr(v[1]);else o[tr(v[0])]=tr(v);});}else o=v;return o;}return v;},nodeChanged:function(o){var t=this,s=t.selection,n=s.getNode()||t.getBody();if(t.initialized){t.onNodeChange.dispatch(t,o?o.controlManager||t.controlManager:t.controlManager,isIE&&n.ownerDocument!=t.getDoc()?t.getBody():n,s.isCollapsed(),o);}},addButton:function(n,s){var t=this;t.buttons=t.buttons||{};t.buttons[n]=s;},addCommand:function(n,f,s){this.execCommands[n]={func:f,scope:s||this};},addQueryStateHandler:function(n,f,s){this.queryStateCommands[n]={func:f,scope:s||this};},addQueryValueHandler:function(n,f,s){this.queryValueCommands[n]={func:f,scope:s||this};},addShortcut:function(pa,desc,cmd_func,sc){var t=this,c;if(!t.settings.custom_shortcuts)return false;t.shortcuts=t.shortcuts||{};if(is(cmd_func,'string')){c=cmd_func;cmd_func=function(){t.execCommand(c,false,null);};}if(is(cmd_func,'object')){c=cmd_func;cmd_func=function(){t.execCommand(c[0],c[1],c[2]);};}each(explode(pa),function(pa){var o={func:cmd_func,scope:sc||this,desc:desc,alt:false,ctrl:false,shift:false};each(explode(pa,'+'),function(v){switch(v){case'alt':case'ctrl':case'shift':o[v]=true;break;default:o.charCode=v.charCodeAt(0);o.keyCode=v.toUpperCase().charCodeAt(0);}});t.shortcuts[(o.ctrl?'ctrl':'')+','+(o.alt?'alt':'')+','+(o.shift?'shift':'')+','+o.keyCode]=o;});return true;},execCommand:function(cmd,ui,val,a){var t=this,s=0,o,st;if(!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(cmd)&&(!a||!a.skip_focus))t.focus();o={};t.onBeforeExecCommand.dispatch(t,cmd,ui,val,o);if(o.terminate)return false;if(t.execCallback('execcommand_callback',t.id,t.selection.getNode(),cmd,ui,val)){t.onExecCommand.dispatch(t,cmd,ui,val,a);return true;}if(o=t.execCommands[cmd]){st=o.func.call(o.scope,ui,val);if(st!==true){t.onExecCommand.dispatch(t,cmd,ui,val,a);return st;}}each(t.plugins,function(p){if(p.execCommand&&p.execCommand(cmd,ui,val)){t.onExecCommand.dispatch(t,cmd,ui,val,a);s=1;return false;}});if(s)return true;if(t.theme.execCommand&&t.theme.execCommand(cmd,ui,val)){t.onExecCommand.dispatch(t,cmd,ui,val,a);return true;}if(t.editorCommands.execCommand(cmd,ui,val)){t.onExecCommand.dispatch(t,cmd,ui,val,a);return true;}t.getDoc().execCommand(cmd,ui,val);t.onExecCommand.dispatch(t,cmd,ui,val,a);},queryCommandState:function(c){var t=this,o,s;if(t._isHidden())return;if(o=t.queryStateCommands[c]){s=o.func.call(o.scope);if(s!==true)return s;}o=t.editorCommands.queryCommandState(c);if(o!==-1)return o;try{return this.getDoc().queryCommandState(c);}catch(ex){}},queryCommandValue:function(c){var t=this,o,s;if(t._isHidden())return;if(o=t.queryValueCommands[c]){s=o.func.call(o.scope);if(s!==true)return s;}o=t.editorCommands.queryCommandValue(c);if(is(o))return o;try{return this.getDoc().queryCommandValue(c);}catch(ex){}},show:function(){var t=this;DOM.show(t.getContainer());DOM.hide(t.id);t.load();},hide:function(){var t=this,d=t.getDoc();if(isIE&&d)d.execCommand('SelectAll');t.save();DOM.hide(t.getContainer());DOM.setStyle(t.id,'display',t.orgDisplay);},isHidden:function(){return!DOM.isHidden(this.id);},setProgressState:function(b,ti,o){this.onSetProgressState.dispatch(this,b,ti,o);return b;},resizeToContent:function(){var t=this;DOM.setStyle(t.id+"_ifr",'height',t.getBody().scrollHeight);},load:function(o){var t=this,e=t.getElement(),h;o=o||{};o.load=true;h=t.setContent(is(e.value)?e.value:e.innerHTML,o);o.element=e;if(!o.no_events)t.onLoadContent.dispatch(t,o);o.element=e=null;return h;},save:function(o){var t=this,e=t.getElement(),h,f;if(!t.initialized)return;o=o||{};o.save=true;if(!o.no_events){t.undoManager.typing=0;t.undoManager.add();}o.element=e;h=o.content=t.getContent(o);if(!o.no_events)t.onSaveContent.dispatch(t,o);h=o.content;if(!/TEXTAREA|INPUT/i.test(e.nodeName)){e.innerHTML=h;if(f=DOM.getParent(t.id,'form')){each(f.elements,function(e){if(e.name==t.id){e.value=h;return false;}});}}else e.value=h;o.element=e=null;return h;},setContent:function(h,o){var t=this;o=o||{};o.format=o.format||'html';o.set=true;o.content=h;if(!o.no_events)t.onBeforeSetContent.dispatch(t,o);if(!tinymce.isIE&&(h.length===0||/^\s+$/.test(h))){o.content=t.dom.setHTML(t.getBody(),'<br mce_bogus="1" />');o.format='raw';}o.content=t.dom.setHTML(t.getBody(),tinymce.trim(o.content));if(o.format!='raw'&&t.settings.cleanup){o.getInner=true;o.content=t.dom.setHTML(t.getBody(),t.serializer.serialize(t.getBody(),o));}if(!o.no_events)t.onSetContent.dispatch(t,o);return o.content;},getContent:function(o){var t=this,h;o=o||{};o.format=o.format||'html';o.get=true;if(!o.no_events)t.onBeforeGetContent.dispatch(t,o);if(o.format!='raw'&&t.settings.cleanup){o.getInner=true;h=t.serializer.serialize(t.getBody(),o);}else h=t.getBody().innerHTML;h=h.replace(/^\s*|\s*$/g,'');o.content=h;if(!o.no_events)t.onGetContent.dispatch(t,o);return o.content;},isDirty:function(){var t=this;return tinymce.trim(t.startContent)!=tinymce.trim(t.getContent({format:'raw',no_events:1}))&&!t.isNotDirty;},getContainer:function(){var t=this;if(!t.container)t.container=DOM.get(t.editorContainer||t.id+'_parent');return t.container;},getContentAreaContainer:function(){return this.contentAreaContainer;},getElement:function(){return DOM.get(this.settings.content_element||this.id);},getWin:function(){var t=this,e;if(!t.contentWindow){e=DOM.get(t.id+"_ifr");if(e)t.contentWindow=e.contentWindow;}return t.contentWindow;},getDoc:function(){var t=this,w;if(!t.contentDocument){w=t.getWin();if(w)t.contentDocument=w.document;}return t.contentDocument;},getBody:function(){return this.bodyElement||this.getDoc().body;},convertURL:function(u,n,e){var t=this,s=t.settings;if(s.urlconverter_callback)return t.execCallback('urlconverter_callback',u,e,true,n);if(!s.convert_urls||(e&&e.nodeName=='LINK')||u.indexOf('file:')===0)return u;if(s.relative_urls)return t.documentBaseURI.toRelative(u);u=t.documentBaseURI.toAbsolute(u,s.remove_script_host);return u;},addVisual:function(e){var t=this,s=t.settings;e=e||t.getBody();if(!is(t.hasVisual))t.hasVisual=s.visual;each(t.dom.select('table,a',e),function(e){var v;switch(e.nodeName){case'TABLE':v=t.dom.getAttrib(e,'border');if(!v||v=='0'){if(t.hasVisual)t.dom.addClass(e,s.visual_table_class);else t.dom.removeClass(e,s.visual_table_class);}return;case'A':v=t.dom.getAttrib(e,'name');if(v){if(t.hasVisual)t.dom.addClass(e,'mceItemAnchor');else t.dom.removeClass(e,'mceItemAnchor');}return;}});t.onVisualAid.dispatch(t,e,t.hasVisual);},remove:function(){var t=this,e=t.getContainer();t.removed=1;t.hide();t.execCallback('remove_instance_callback',t);t.onRemove.dispatch(t);t.onExecCommand.listeners=[];EditorManager.remove(t);DOM.remove(e);},destroy:function(s){var t=this;if(t.destroyed)return;if(!s){tinymce.removeUnload(t.destroy);tinyMCE.onBeforeUnload.remove(t._beforeUnload);if(t.theme.destroy)t.theme.destroy();t.controlManager.destroy();t.selection.destroy();t.dom.destroy();if(!t.settings.content_editable){Event.clear(t.getWin());Event.clear(t.getDoc());}Event.clear(t.getBody());Event.clear(t.formElement);}if(t.formElement){t.formElement.submit=t.formElement._mceOldSubmit;t.formElement._mceOldSubmit=null;}t.contentAreaContainer=t.formElement=t.container=t.settings.content_element=t.bodyElement=t.contentDocument=t.contentWindow=null;if(t.selection)t.selection=t.selection.win=t.selection.dom=t.selection.dom.doc=null;t.destroyed=1;},_addEvents:function(){var t=this,i,s=t.settings,lo={mouseup:'onMouseUp',mousedown:'onMouseDown',click:'onClick',keyup:'onKeyUp',keydown:'onKeyDown',keypress:'onKeyPress',submit:'onSubmit',reset:'onReset',contextmenu:'onContextMenu',dblclick:'onDblClick',paste:'onPaste'};function eventHandler(e,o){var ty=e.type;if(t.removed)return;if(t.onEvent.dispatch(t,e,o)!==false){t[lo[e.fakeType||e.type]].dispatch(t,e,o);}};each(lo,function(v,k){switch(k){case'contextmenu':if(tinymce.isOpera){Event.add(t.getBody(),'mousedown',function(e){if(e.ctrlKey){e.fakeType='contextmenu';eventHandler(e);}});}else Event.add(t.getBody(),k,eventHandler);break;case'paste':Event.add(t.getBody(),k,function(e){var tx,h,el,r;if(e.clipboardData)tx=e.clipboardData.getData('text/plain');else if(tinymce.isIE)tx=t.getWin().clipboardData.getData('Text');eventHandler(e,{text:tx,html:h});});break;case'submit':case'reset':Event.add(t.getElement().form||DOM.getParent(t.id,'form'),k,eventHandler);break;default:Event.add(s.content_editable?t.getBody():t.getDoc(),k,eventHandler);}});Event.add(s.content_editable?t.getBody():(isGecko?t.getDoc():t.getWin()),'focus',function(e){t.focus(true);});if(tinymce.isGecko){Event.add(t.getDoc(),'DOMNodeInserted',function(e){var v;e=e.target;if(e.nodeType===1&&e.nodeName==='IMG'&&(v=e.getAttribute('mce_src')))e.src=t.documentBaseURI.toAbsolute(v);});}if(isGecko){function setOpts(){var t=this,d=t.getDoc(),s=t.settings;if(isGecko){if(t._isHidden()){try{if(!s.content_editable)d.designMode='On';}catch(ex){}}try{d.execCommand("styleWithCSS",0,false);}catch(ex){if(!t._isHidden())try{d.execCommand("useCSS",0,true);}catch(ex){}}if(!s.table_inline_editing)try{d.execCommand('enableInlineTableEditing',false,false);}catch(ex){}if(!s.object_resizing)try{d.execCommand('enableObjectResizing',false,false);}catch(ex){}}};t.onBeforeExecCommand.add(setOpts);t.onMouseDown.add(setOpts);}t.onMouseUp.add(t.nodeChanged);t.onClick.add(t.nodeChanged);t.onKeyUp.add(function(ed,e){if((e.keyCode>=33&&e.keyCode<=36)||(e.keyCode>=37&&e.keyCode<=40)||e.keyCode==13||e.keyCode==45||e.keyCode==46||e.keyCode==8||e.ctrlKey)t.nodeChanged();});t.onReset.add(function(){t.setContent(t.startContent,{format:'raw'});});if(t.getParam('tab_focus')){function tabCancel(ed,e){if(e.keyCode===9)return Event.cancel(e);};function tabHandler(ed,e){var x,i,f,el,v;function find(d){f=DOM.getParent(ed.id,'form');el=f.elements;if(f){each(el,function(e,i){if(e.id==ed.id){x=i;return false;}});if(d>0){for(i=x+1;i<el.length;i++){if(el[i].type!='hidden')return el[i];}}else{for(i=x-1;i>=0;i--){if(el[i].type!='hidden')return el[i];}}}return null;};if(e.keyCode===9){v=explode(ed.getParam('tab_focus'));if(v.length==1){v[1]=v[0];v[0]=':prev';}if(e.shiftKey){if(v[0]==':prev')el=find(-1);else el=DOM.get(v[0]);}else{if(v[1]==':next')el=find(1);else el=DOM.get(v[1]);}if(el){if(ed=EditorManager.get(el.id||el.name))ed.focus();else window.setTimeout(function(){window.focus();el.focus();},10);return Event.cancel(e);}}};t.onKeyUp.add(tabCancel);if(isGecko){t.onKeyPress.add(tabHandler);t.onKeyDown.add(tabCancel);}else t.onKeyDown.add(tabHandler);}if(s.custom_shortcuts){if(s.custom_undo_redo_keyboard_shortcuts){t.addShortcut('ctrl+z',t.getLang('undo_desc'),'Undo');t.addShortcut('ctrl+y',t.getLang('redo_desc'),'Redo');}if(isGecko){t.addShortcut('ctrl+b',t.getLang('bold_desc'),'Bold');t.addShortcut('ctrl+i',t.getLang('italic_desc'),'Italic');t.addShortcut('ctrl+u',t.getLang('underline_desc'),'Underline');}for(i=1;i<=6;i++)t.addShortcut('ctrl+'+i,'',['FormatBlock',false,'<h'+i+'>']);t.addShortcut('ctrl+7','',['FormatBlock',false,'<p>']);t.addShortcut('ctrl+8','',['FormatBlock',false,'<div>']);t.addShortcut('ctrl+9','',['FormatBlock',false,'<address>']);function find(e){var v=null;if(!e.altKey&&!e.ctrlKey&&!e.metaKey)return v;each(t.shortcuts,function(o){if(o.ctrl!=e.ctrlKey&&(!tinymce.isMac||o.ctrl==e.metaKey))return;if(o.alt!=e.altKey)return;if(o.shift!=e.shiftKey)return;if(e.keyCode==o.keyCode||(e.charCode&&e.charCode==o.charCode)){v=o;return false;}});return v;};t.onKeyUp.add(function(ed,e){var o=find(e);if(o)return Event.cancel(e);});t.onKeyPress.add(function(ed,e){var o=find(e);if(o)return Event.cancel(e);});t.onKeyDown.add(function(ed,e){var o=find(e);if(o){o.func.call(o.scope);return Event.cancel(e);}});}if(tinymce.isIE){Event.add(t.getDoc(),'controlselect',function(e){var re=t.resizeInfo,cb;e=e.target;if(e.nodeName!=='IMG')return;if(re)Event.remove(re.node,re.ev,re.cb);if(!t.dom.hasClass(e,'mceItemNoResize')){ev='resizeend';cb=Event.add(e,ev,function(e){var v;e=e.target;if(v=t.dom.getStyle(e,'width')){t.dom.setAttrib(e,'width',v.replace(/[^0-9%]+/g,''));t.dom.setStyle(e,'width','');}if(v=t.dom.getStyle(e,'height')){t.dom.setAttrib(e,'height',v.replace(/[^0-9%]+/g,''));t.dom.setStyle(e,'height','');}});}else{ev='resizestart';cb=Event.add(e,'resizestart',Event.cancel,Event);}re=t.resizeInfo={node:e,ev:ev,cb:cb};});t.onKeyDown.add(function(ed,e){switch(e.keyCode){case 8:if(t.selection.getRng().item){t.selection.getRng().item(0).removeNode();return Event.cancel(e);}}});}if(tinymce.isOpera){t.onClick.add(function(ed,e){Event.prevent(e);});}if(s.custom_undo_redo){function addUndo(){t.undoManager.typing=0;t.undoManager.add();};if(tinymce.isIE){Event.add(t.getWin(),'blur',function(e){var n;if(t.selection){n=t.selection.getNode();if(!t.removed&&n.ownerDocument&&n.ownerDocument!=t.getDoc())addUndo();}});}else{Event.add(t.getDoc(),'blur',function(){if(t.selection&&!t.removed)addUndo();});}t.onMouseDown.add(addUndo);t.onKeyUp.add(function(ed,e){if((e.keyCode>=33&&e.keyCode<=36)||(e.keyCode>=37&&e.keyCode<=40)||e.keyCode==13||e.keyCode==45||e.ctrlKey){t.undoManager.typing=0;t.undoManager.add();}});t.onKeyDown.add(function(ed,e){if((e.keyCode>=33&&e.keyCode<=36)||(e.keyCode>=37&&e.keyCode<=40)||e.keyCode==13||e.keyCode==45){if(t.undoManager.typing){t.undoManager.add();t.undoManager.typing=0;}return;}if(!t.undoManager.typing){t.undoManager.add();t.undoManager.typing=1;}});}},_convertInlineElements:function(){var t=this,s=t.settings,dom=t.dom,v,e,na,st,sp;function convert(ed,o){if(!s.inline_styles)return;if(o.get){each(t.dom.select('table,u,strike',o.node),function(n){switch(n.nodeName){case'TABLE':if(v=dom.getAttrib(n,'height')){dom.setStyle(n,'height',v);dom.setAttrib(n,'height','');}break;case'U':case'STRIKE':n.style.textDecoration=n.nodeName=='U'?'underline':'line-through';dom.setAttrib(n,'mce_style','');dom.setAttrib(n,'mce_name','span');break;}});}else if(o.set){each(t.dom.select('table,span',o.node).reverse(),function(n){if(n.nodeName=='TABLE'){if(v=dom.getStyle(n,'height'))dom.setAttrib(n,'height',v.replace(/[^0-9%]+/g,''));}else{if(n.style.textDecoration=='underline')na='u';else if(n.style.textDecoration=='line-through')na='strike';else na='';if(na){n.style.textDecoration='';dom.setAttrib(n,'mce_style','');e=dom.create(na,{style:dom.getAttrib(n,'style')});dom.replace(e,n,1);}}});}};t.onPreProcess.add(convert);if(!s.cleanup_on_startup){t.onSetContent.add(function(ed,o){if(o.initial)convert(t,{node:t.getBody(),set:1});});}},_convertFonts:function(){var t=this,s=t.settings,dom=t.dom,fz,fzn,sl,cl;if(!s.inline_styles)return;fz=[8,10,12,14,18,24,36];fzn=['xx-small','x-small','small','medium','large','x-large','xx-large'];if(sl=s.font_size_style_values)sl=explode(sl);if(cl=s.font_size_classes)cl=explode(cl);function convertToFonts(no){var n,f,nl,x,i,v,st;if(tinymce.isWebKit||!s.inline_styles)return;nl=t.dom.select('span',no);for(x=nl.length-1;x>=0;x--){n=nl[x];f=dom.create('font',{color:dom.toHex(dom.getStyle(n,'color')),face:dom.getStyle(n,'fontFamily'),style:dom.getAttrib(n,'style'),'class':dom.getAttrib(n,'class')});st=f.style;if(st.color||st.fontFamily){st.color=st.fontFamily='';dom.setAttrib(f,'mce_style','');}if(sl){i=inArray(sl,dom.getStyle(n,'fontSize'));if(i!=-1){dom.setAttrib(f,'size',''+(i+1||1));}}else if(cl){i=inArray(cl,dom.getAttrib(n,'class'));v=dom.getStyle(n,'fontSize');if(i==-1&&v.indexOf('pt')>0)i=inArray(fz,parseInt(v));if(i==-1)i=inArray(fzn,v);if(i!=-1){dom.setAttrib(f,'size',''+(i+1||1));f.style.fontSize='';}}if(f.color||f.face||f.size){f.style.fontFamily='';dom.setAttrib(f,'mce_style','');dom.replace(f,n,1);}f=n=null;}};t.onSetContent.add(function(ed,o){convertToFonts(ed.getBody());});t.onPreProcess.add(function(ed,o){var n,sp,nl,x;if(!s.inline_styles)return;if(o.get){nl=t.dom.select('font',o.node);for(x=nl.length-1;x>=0;x--){n=nl[x];sp=dom.create('span',{style:dom.getAttrib(n,'style'),'class':dom.getAttrib(n,'class')});dom.setStyles(sp,{fontFamily:dom.getAttrib(n,'face'),color:dom.getAttrib(n,'color'),backgroundColor:n.style.backgroundColor});if(n.size){if(sl)dom.setStyle(sp,'fontSize',sl[parseInt(n.size)-1]);else dom.setAttrib(sp,'class',cl[parseInt(n.size)-1]);}dom.setAttrib(sp,'mce_style','');dom.replace(sp,n,1);}}});},_isHidden:function(){var s;if(!isGecko)return 0;s=this.selection.getSel();return(!s||!s.rangeCount||s.rangeCount==0);},_fixNesting:function(s){var d=[],i;s=s.replace(/<(\/)?([^\s>]+)[^>]*?>/g,function(a,b,c){var e;if(b==='/'){if(!d.length)return'';if(c!==d[d.length-1].tag){for(i=d.length-1;i>=0;i--){if(d[i].tag===c){d[i].close=1;break;}}return'';}else{d.pop();if(d.length&&d[d.length-1].close){a=a+'</'+d[d.length-1].tag+'>';d.pop();}}}else{if(/^(br|hr|input|meta|img|link|param)$/i.test(c))return a;if(/\/>$/.test(a))return a;d.push({tag:c});}return a;});for(i=d.length-1;i>=0;i--)s+='</'+d[i].tag+'>';return s;}});})();(function(){var each=tinymce.each,isIE=tinymce.isIE,isGecko=tinymce.isGecko,isOpera=tinymce.isOpera,isWebKit=tinymce.isWebKit;tinymce.create('tinymce.EditorCommands',{EditorCommands:function(ed){this.editor=ed;},execCommand:function(cmd,ui,val){var t=this,ed=t.editor,f;switch(cmd){case'Cut':case'Copy':case'Paste':try{ed.getDoc().execCommand(cmd,ui,val);}catch(ex){if(isGecko){ed.windowManager.confirm(ed.getLang('clipboard_msg'),function(s){if(s)window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html','mceExternal');});}else ed.windowManager.alert(ed.getLang('clipboard_no_support'));}return true;case'mceResetDesignMode':case'mceBeginUndoLevel':return true;case'unlink':t.UnLink();return true;case'JustifyLeft':case'JustifyCenter':case'JustifyRight':case'JustifyFull':t.mceJustify(cmd,cmd.substring(7).toLowerCase());return true;case'mceEndUndoLevel':case'mceAddUndoLevel':ed.undoManager.add();return true;default:f=this[cmd];if(f){f.call(this,ui,val);return true;}}return false;},Indent:function(){var ed=this.editor,d=ed.dom,s=ed.selection,e,iv,iu;iv=ed.settings.indentation;iu=/[a-z%]+$/i.exec(iv);iv=parseInt(iv);if(ed.settings.inline_styles&&(!this.queryStateInsertUnorderedList()&&!this.queryStateInsertOrderedList())){each(this._getSelectedBlocks(),function(e){d.setStyle(e,'paddingLeft',(parseInt(e.style.paddingLeft||0)+iv)+iu);});return;}ed.getDoc().execCommand('Indent',false,null);if(isIE){d.getParent(s.getNode(),function(n){if(n.nodeName=='BLOCKQUOTE'){n.dir=n.style.cssText='';}});}},Outdent:function(){var ed=this.editor,d=ed.dom,s=ed.selection,e,v,iv,iu;iv=ed.settings.indentation;iu=/[a-z%]+$/i.exec(iv);iv=parseInt(iv);if(ed.settings.inline_styles&&(!this.queryStateInsertUnorderedList()&&!this.queryStateInsertOrderedList())){each(this._getSelectedBlocks(),function(e){v=Math.max(0,parseInt(e.style.paddingLeft||0)-iv);d.setStyle(e,'paddingLeft',v?v+iu:'');});return;}ed.getDoc().execCommand('Outdent',false,null);},mceSetAttribute:function(u,v){var ed=this.editor,d=ed.dom,e;if(e=d.getParent(ed.selection.getNode(),d.isBlock))d.setAttrib(e,v.name,v.value);},mceSetContent:function(u,v){this.editor.setContent(v);},mceToggleVisualAid:function(){var ed=this.editor;ed.hasVisual=!ed.hasVisual;ed.addVisual();},mceReplaceContent:function(u,v){var s=this.editor.selection;s.setContent(v.replace(/\{\$selection\}/g,s.getContent({format:'text'})));},mceInsertLink:function(u,v){var ed=this.editor,s=ed.selection,e=ed.dom.getParent(s.getNode(),'A');if(tinymce.is(v,'string'))v={href:v};function set(e){each(v,function(v,k){ed.dom.setAttrib(e,k,v);});};if(!e){ed.execCommand('CreateLink',false,'javascript:mctmp(0);');each(ed.dom.select('a'),function(e){if(e.href=='javascript:mctmp(0);')set(e);});}else{if(v.href)set(e);else ed.dom.remove(e,1);}},UnLink:function(){var ed=this.editor,s=ed.selection;if(s.isCollapsed())s.select(s.getNode());ed.getDoc().execCommand('unlink',false,null);s.collapse(0);},FontName:function(u,v){var t=this,ed=t.editor,s=ed.selection,e;if(!v){if(s.isCollapsed())s.select(s.getNode());t.RemoveFormat();}else ed.getDoc().execCommand('FontName',false,v);},FontSize:function(u,v){var ed=this.editor,s=ed.settings,fz=tinymce.explode(s.font_size_style_values),fzc=tinymce.explode(s.font_size_classes),h,bm;each(ed.dom.select('font'),function(e){e.style.fontSize='';});ed.getDoc().execCommand('FontSize',false,v);if(s.inline_styles){each(ed.dom.select('font'),function(e){if(e.parentNode.nodeName=='FONT'&&e.size==e.parentNode.size){if(!bm)bm=ed.selection.getBookmark();ed.dom.remove(e,1);return;}if(v=e.size){if(fzc&&fzc.length>0)ed.dom.setAttrib(e,'class',fzc[parseInt(v)-1]);else ed.dom.setStyle(e,'fontSize',fz[parseInt(v)-1]);}});}ed.selection.moveToBookmark(bm);},queryCommandValue:function(c){var f=this['queryValue'+c];if(f)return f.call(this,c);return false;},queryCommandState:function(cmd){var f;switch(cmd){case'JustifyLeft':case'JustifyCenter':case'JustifyRight':case'JustifyFull':return this.queryStateJustify(cmd,cmd.substring(7).toLowerCase());default:if(f=this['queryState'+cmd])return f.call(this,cmd);}return-1;},_queryState:function(c){try{return this.editor.getDoc().queryCommandState(c);}catch(ex){}},_queryVal:function(c){try{return this.editor.getDoc().queryCommandValue(c);}catch(ex){}},queryValueFontSize:function(){var ed=this.editor,v=0,p;if(isOpera||isWebKit){if(p=ed.dom.getParent(ed.selection.getNode(),'FONT'))v=p.size;return v;}return this._queryVal('FontSize');},queryValueFontName:function(){var ed=this.editor,v=0,p;if(p=ed.dom.getParent(ed.selection.getNode(),'FONT'))v=p.face;if(!v)v=this._queryVal('FontName');return v;},mceJustify:function(c,v){var ed=this.editor,se=ed.selection,n=se.getNode(),nn=n.nodeName,bl,nb,dom=ed.dom,rm;if(ed.settings.inline_styles&&this.queryStateJustify(c,v))rm=1;bl=dom.getParent(n,ed.dom.isBlock);if(nn=='IMG'){if(v=='full')return;if(rm){if(v=='center')dom.setStyle(n.parentNode,'textAlign','');dom.setStyle(n,'float','');this.mceRepaint();return;}if(v=='center'){if(/^(TD|TH)$/.test(bl.nodeName))bl=0;if(!bl||bl.childNodes.length>1){nb=dom.create('p');nb.appendChild(n.cloneNode(false));if(bl)dom.insertAfter(nb,bl);else dom.insertAfter(nb,n);dom.remove(n);n=nb.firstChild;bl=nb;}dom.setStyle(bl,'textAlign',v);dom.setStyle(n,'float','');}else{dom.setStyle(n,'float',v);dom.setStyle(n.parentNode,'textAlign','');}this.mceRepaint();return;}if(ed.settings.inline_styles&&ed.settings.forced_root_block){if(rm)v='';each(this._getSelectedBlocks(dom.getParent(se.getStart(),dom.isBlock),dom.getParent(se.getEnd(),dom.isBlock)),function(e){dom.setAttrib(e,'align','');dom.setStyle(e,'textAlign',v=='full'?'justify':v);});return;}else if(!rm)ed.getDoc().execCommand(c,false,null);if(ed.settings.inline_styles){if(rm){dom.getParent(ed.selection.getNode(),function(n){if(n.style&&n.style.textAlign)dom.setStyle(n,'textAlign','');});return;}each(dom.select('*'),function(n){var v=n.align;if(v){if(v=='full')v='justify';dom.setStyle(n,'textAlign',v);dom.setAttrib(n,'align','');}});}},mceSetCSSClass:function(u,v){this.mceSetStyleInfo(0,{command:'setattrib',name:'class',value:v});},getSelectedElement:function(){var t=this,ed=t.editor,dom=ed.dom,se=ed.selection,r=se.getRng(),r1,r2,sc,ec,so,eo,e,sp,ep,re;if(se.isCollapsed()||r.item)return se.getNode();re=ed.settings.merge_styles_invalid_parents;if(tinymce.is(re,'string'))re=new RegExp(re,'i');if(isIE){r1=r.duplicate();r1.collapse(true);sc=r1.parentElement();r2=r.duplicate();r2.collapse(false);ec=r2.parentElement();if(sc!=ec){r1.move('character',1);sc=r1.parentElement();}if(sc==ec){r1=r.duplicate();r1.moveToElementText(sc);if(r1.compareEndPoints('StartToStart',r)==0&&r1.compareEndPoints('EndToEnd',r)==0)return re&&re.test(sc.nodeName)?null:sc;}}else{function getParent(n){return dom.getParent(n,function(n){return n.nodeType==1;});};sc=r.startContainer;ec=r.endContainer;so=r.startOffset;eo=r.endOffset;if(!r.collapsed){if(sc==ec){if(so-eo<2){if(sc.hasChildNodes()){sp=sc.childNodes[so];return re&&re.test(sp.nodeName)?null:sp;}}}}if(sc.nodeType!=3||ec.nodeType!=3)return null;if(so==0){sp=getParent(sc);if(sp&&sp.firstChild!=sc)sp=null;}if(so==sc.nodeValue.length){e=sc.nextSibling;if(e&&e.nodeType==1)sp=sc.nextSibling;}if(eo==0){e=ec.previousSibling;if(e&&e.nodeType==1)ep=e;}if(eo==ec.nodeValue.length){ep=getParent(ec);if(ep&&ep.lastChild!=ec)ep=null;}if(sp==ep)return re&&sp&&re.test(sp.nodeName)?null:sp;}return null;},InsertHorizontalRule:function(){if(isGecko||isIE)this.editor.selection.setContent('<hr />');else this.editor.getDoc().execCommand('InsertHorizontalRule',false,'');},RemoveFormat:function(){var t=this,ed=t.editor,s=ed.selection,b;if(isWebKit)s.setContent(s.getContent({format:'raw'}).replace(/(<(span|b|i|strong|em|strike) [^>]+>|<(span|b|i|strong|em|strike)>|<\/(span|b|i|strong|em|strike)>|)/g,''),{format:'raw'});else ed.getDoc().execCommand('RemoveFormat',false,null);t.mceSetStyleInfo(0,{command:'removeformat'});ed.addVisual();},mceSetStyleInfo:function(u,v){var t=this,ed=t.editor,d=ed.getDoc(),dom=ed.dom,e,b,s=ed.selection,nn=v.wrapper||'span',b=s.getBookmark(),re;function set(n,e){if(n.nodeType==1){switch(v.command){case'setattrib':return dom.setAttrib(n,v.name,v.value);case'setstyle':return dom.setStyle(n,v.name,v.value);case'removeformat':return dom.setAttrib(n,'class','');}}};re=ed.settings.merge_styles_invalid_parents;if(tinymce.is(re,'string'))re=new RegExp(re,'i');if(e=t.getSelectedElement())set(e,1);else{d.execCommand('FontName',false,'__');each(isWebKit?dom.select('span'):dom.select('font'),function(n){var sp,e;if(dom.getAttrib(n,'face')=='__'||n.style.fontFamily==='__'){sp=dom.create(nn,{mce_new:'1'});set(sp);each(n.childNodes,function(n){sp.appendChild(n.cloneNode(true));});dom.replace(sp,n);}});}each(dom.select(nn).reverse(),function(n){var p=n.parentNode;if(!dom.getAttrib(n,'mce_new')){p=dom.getParent(n,function(n){return n.nodeType==1&&dom.getAttrib(n,'mce_new');});if(p)dom.remove(n,1);}});each(dom.select(nn).reverse(),function(n){var p=n.parentNode;if(!p||!dom.getAttrib(n,'mce_new'))return;if(p.nodeName==nn.toUpperCase()&&p.childNodes.length==1)return dom.remove(p,1);if(n.nodeType==1&&(!re||!re.test(p.nodeName))&&p.childNodes.length==1){set(p);dom.setAttrib(n,'class','');}});each(dom.select(nn).reverse(),function(n){if(dom.getAttrib(n,'mce_new')||(dom.getAttribs(n).length<=1&&n.className==='')){if(!dom.getAttrib(n,'class')&&!dom.getAttrib(n,'style'))return dom.remove(n,1);dom.setAttrib(n,'mce_new','');}});s.moveToBookmark(b);},queryStateJustify:function(c,v){var ed=this.editor,n=ed.selection.getNode(),dom=ed.dom;if(n&&n.nodeName=='IMG'){if(dom.getStyle(n,'float')==v)return 1;return n.parentNode.style.textAlign==v;}n=dom.getParent(ed.selection.getStart(),function(n){return n.nodeType==1&&n.style.textAlign;});if(v=='full')v='justify';if(ed.settings.inline_styles)return(n&&n.style.textAlign==v);return this._queryState(c);},HiliteColor:function(ui,val){var t=this,ed=t.editor,d=ed.getDoc();function set(s){if(!isGecko)return;try{d.execCommand("styleWithCSS",0,s);}catch(ex){d.execCommand("useCSS",0,!s);}};if(isGecko||isOpera){set(true);d.execCommand('hilitecolor',false,val);set(false);}else d.execCommand('BackColor',false,val);},Undo:function(){var ed=this.editor;if(ed.settings.custom_undo_redo){ed.undoManager.undo();ed.nodeChanged();}else ed.getDoc().execCommand('Undo',false,null);},Redo:function(){var ed=this.editor;if(ed.settings.custom_undo_redo){ed.undoManager.redo();ed.nodeChanged();}else ed.getDoc().execCommand('Redo',false,null);},FormatBlock:function(ui,val){var t=this,ed=t.editor,s=ed.selection,dom=ed.dom,bl,nb,b;function isBlock(n){return/^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(n.nodeName);};bl=dom.getParent(s.getNode(),function(n){return isBlock(n);});if(bl){if((isIE&&isBlock(bl.parentNode))||bl.nodeName=='DIV'){nb=ed.dom.create(val);each(dom.getAttribs(bl),function(v){dom.setAttrib(nb,v.nodeName,dom.getAttrib(bl,v.nodeName));});b=s.getBookmark();dom.replace(nb,bl,1);s.moveToBookmark(b);ed.nodeChanged();return;}}val=ed.settings.forced_root_block?(val||'<p>'):val;if(val.indexOf('<')==-1)val='<'+val+'>';if(tinymce.isGecko)val=val.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi,'$1');ed.getDoc().execCommand('FormatBlock',false,val);},mceCleanup:function(){var ed=this.editor,s=ed.selection,b=s.getBookmark();ed.setContent(ed.getContent());s.moveToBookmark(b);},mceRemoveNode:function(ui,val){var ed=this.editor,s=ed.selection,b,n=val||s.getNode();if(n==ed.getBody())return;b=s.getBookmark();ed.dom.remove(n,1);s.moveToBookmark(b);ed.nodeChanged();},mceSelectNodeDepth:function(ui,val){var ed=this.editor,s=ed.selection,c=0;ed.dom.getParent(s.getNode(),function(n){if(n.nodeType==1&&c++==val){s.select(n);ed.nodeChanged();return false;}},ed.getBody());},mceSelectNode:function(u,v){this.editor.selection.select(v);},mceInsertContent:function(ui,val){this.editor.selection.setContent(val);},mceInsertRawHTML:function(ui,val){var ed=this.editor;ed.selection.setContent('tiny_mce_marker');ed.setContent(ed.getContent().replace(/tiny_mce_marker/g,val));},mceRepaint:function(){var s,b,e=this.editor;if(tinymce.isGecko){try{s=e.selection;b=s.getBookmark(true);if(s.getSel())s.getSel().selectAllChildren(e.getBody());s.collapse(true);s.moveToBookmark(b);}catch(ex){}}},queryStateUnderline:function(){var ed=this.editor,n=ed.selection.getNode();if(n&&n.nodeName=='A')return false;return this._queryState('Underline');},queryStateOutdent:function(){var ed=this.editor,n;if(ed.settings.inline_styles){if((n=ed.dom.getParent(ed.selection.getStart(),ed.dom.isBlock))&&parseInt(n.style.paddingLeft)>0)return true;if((n=ed.dom.getParent(ed.selection.getEnd(),ed.dom.isBlock))&&parseInt(n.style.paddingLeft)>0)return true;}else return!!ed.dom.getParent(ed.selection.getNode(),'BLOCKQUOTE');return this.queryStateInsertUnorderedList()||this.queryStateInsertOrderedList();},queryStateInsertUnorderedList:function(){return this.editor.dom.getParent(this.editor.selection.getNode(),'UL');},queryStateInsertOrderedList:function(){return this.editor.dom.getParent(this.editor.selection.getNode(),'OL');},queryStatemceBlockQuote:function(){return!!this.editor.dom.getParent(this.editor.selection.getStart(),function(n){return n.nodeName==='BLOCKQUOTE';});},mceBlockQuote:function(){var t=this,ed=t.editor,s=ed.selection,dom=ed.dom,sb,eb,n,bm,bq,r,bq2,i,nl;function getBQ(e){return dom.getParent(e,function(n){return n.nodeName==='BLOCKQUOTE';});};sb=dom.getParent(s.getStart(),dom.isBlock);eb=dom.getParent(s.getEnd(),dom.isBlock);if(bq=getBQ(sb)){if(sb!=eb||sb.childNodes.length>1||(sb.childNodes.length==1&&sb.firstChild.nodeName!='BR'))bm=s.getBookmark();if(getBQ(eb)){bq2=bq.cloneNode(false);while(n=eb.nextSibling)bq2.appendChild(n.parentNode.removeChild(n));}if(bq2)dom.insertAfter(bq2,bq);nl=t._getSelectedBlocks(sb,eb);for(i=nl.length-1;i>=0;i--){dom.insertAfter(nl[i],bq);}if(/^\s*$/.test(bq.innerHTML))dom.remove(bq,1);if(bq2&&/^\s*$/.test(bq2.innerHTML))dom.remove(bq2,1);if(!bm){if(!isIE){r=ed.getDoc().createRange();r.setStart(sb,0);r.setEnd(sb,0);s.setRng(r);}else{s.select(sb);s.collapse(0);if(dom.getParent(s.getStart(),dom.isBlock)!=sb){r=s.getRng();r.move('character',-1);r.select();}}}else t.editor.selection.moveToBookmark(bm);return;}if(isIE&&!sb&&!eb){t.editor.getDoc().execCommand('Indent');n=getBQ(s.getNode());n.style.margin=n.dir='';return;}if(!sb||!eb)return;if(sb!=eb||sb.childNodes.length>1||(sb.childNodes.length==1&&sb.firstChild.nodeName!='BR'))bm=s.getBookmark();each(t._getSelectedBlocks(getBQ(s.getStart()),getBQ(s.getEnd())),function(e){if(e.nodeName=='BLOCKQUOTE'&&!bq){bq=e;return;}if(!bq){bq=dom.create('blockquote');e.parentNode.insertBefore(bq,e);}if(e.nodeName=='BLOCKQUOTE'&&bq){n=e.firstChild;while(n){bq.appendChild(n.cloneNode(true));n=n.nextSibling;}dom.remove(e);return;}bq.appendChild(dom.remove(e));});if(!bm){if(!isIE){r=ed.getDoc().createRange();r.setStart(sb,0);r.setEnd(sb,0);s.setRng(r);}else{s.select(sb);s.collapse(1);}}else s.moveToBookmark(bm);},_getSelectedBlocks:function(st,en){var ed=this.editor,dom=ed.dom,s=ed.selection,sb,eb,n,bl=[];sb=dom.getParent(st||s.getStart(),dom.isBlock);eb=dom.getParent(en||s.getEnd(),dom.isBlock);if(sb)bl.push(sb);if(sb&&eb&&sb!=eb){n=sb;while((n=n.nextSibling)&&n!=eb){if(dom.isBlock(n))bl.push(n);}}if(eb&&sb!=eb)bl.push(eb);return bl;}});})();tinymce.create('tinymce.UndoManager',{index:0,data:null,typing:0,UndoManager:function(ed){var t=this,Dispatcher=tinymce.util.Dispatcher;t.editor=ed;t.data=[];t.onAdd=new Dispatcher(this);t.onUndo=new Dispatcher(this);t.onRedo=new Dispatcher(this);},add:function(l){var t=this,i,ed=t.editor,b,s=ed.settings,la;l=l||{};l.content=l.content||ed.getContent({format:'raw',no_events:1});l.content=l.content.replace(/^\s*|\s*$/g,'');la=t.data[t.index>0&&(t.index==0||t.index==t.data.length)?t.index-1:t.index];if(!l.initial&&la&&l.content==la.content)return null;if(s.custom_undo_redo_levels){if(t.data.length>s.custom_undo_redo_levels){for(i=0;i<t.data.length-1;i++)t.data[i]=t.data[i+1];t.data.length--;t.index=t.data.length;}}if(s.custom_undo_redo_restore_selection&&!l.initial)l.bookmark=b=l.bookmark||ed.selection.getBookmark();if(t.index<t.data.length)t.index++;if(t.data.length===0&&!l.initial)return null;t.data.length=t.index+1;t.data[t.index++]=l;if(l.initial)t.index=0;if(t.data.length==2&&t.data[0].initial)t.data[0].bookmark=b;t.onAdd.dispatch(t,l);ed.isNotDirty=0;return l;},undo:function(){var t=this,ed=t.editor,l=l,i;if(t.typing){t.add();t.typing=0;}if(t.index>0){if(t.index==t.data.length&&t.index>1){i=t.index;t.typing=0;if(!t.add())t.index=i;--t.index;}l=t.data[--t.index];ed.setContent(l.content,{format:'raw'});ed.selection.moveToBookmark(l.bookmark);t.onUndo.dispatch(t,l);}return l;},redo:function(){var t=this,ed=t.editor,l=null;if(t.index<t.data.length-1){l=t.data[++t.index];ed.setContent(l.content,{format:'raw'});ed.selection.moveToBookmark(l.bookmark);t.onRedo.dispatch(t,l);}return l;},clear:function(){var t=this;t.data=[];t.index=0;t.typing=0;t.add({initial:true});},hasUndo:function(){return this.index!=0||this.typing;},hasRedo:function(){return this.index<this.data.length-1;}});(function(){var Event,isIE,isGecko,isOpera,each,extend;Event=tinymce.dom.Event;isIE=tinymce.isIE;isGecko=tinymce.isGecko;isOpera=tinymce.isOpera;each=tinymce.each;extend=tinymce.extend;tinymce.create('tinymce.ForceBlocks',{ForceBlocks:function(ed){var t=this,s=ed.settings,elm;t.editor=ed;t.dom=ed.dom;elm=(s.forced_root_block||'p').toLowerCase();s.element=elm.toUpperCase();ed.onPreInit.add(t.setup,t);t.reOpera=new RegExp('(\\u00a0|&#160;|&nbsp;)<\/'+elm+'>','gi');t.rePadd=new RegExp('<p( )([^>]+)><\\\/p>|<p( )([^>]+)\\\/>|<p( )([^>]+)>\\s+<\\\/p>|<p><\\\/p>|<p\\\/>|<p>\\s+<\\\/p>'.replace(/p/g,elm),'gi');t.reNbsp2BR1=new RegExp('<p( )([^>]+)>[\\s\\u00a0]+<\\\/p>|<p>[\\s\\u00a0]+<\\\/p>'.replace(/p/g,elm),'gi');t.reNbsp2BR2=new RegExp('<p( )([^>]+)>(&nbsp;|&#160;)<\\\/p>|<p>(&nbsp;|&#160;)<\\\/p>'.replace(/p/g,elm),'gi');t.reBR2Nbsp=new RegExp('<p( )([^>]+)>\\s*<br \\\/>\\s*<\\\/p>|<p>\\s*<br \\\/>\\s*<\\\/p>'.replace(/p/g,elm),'gi');t.reTrailBr=new RegExp('\\s*<br \\/>\\s*<\\\/p>'.replace(/p/g,elm),'gi');function padd(ed,o){if(isOpera)o.content=o.content.replace(t.reOpera,'</'+elm+'>');o.content=o.content.replace(t.rePadd,'<'+elm+'$1$2$3$4$5$6>\u00a0</'+elm+'>');if(!isIE&&!isOpera&&o.set){o.content=o.content.replace(t.reNbsp2BR1,'<'+elm+'$1$2><br /></'+elm+'>');o.content=o.content.replace(t.reNbsp2BR2,'<'+elm+'$1$2><br /></'+elm+'>');}else{o.content=o.content.replace(t.reBR2Nbsp,'<'+elm+'$1$2>\u00a0</'+elm+'>');o.content=o.content.replace(t.reTrailBr,'</'+elm+'>');}};ed.onBeforeSetContent.add(padd);ed.onPostProcess.add(padd);if(s.forced_root_block){ed.onInit.add(t.forceRoots,t);ed.onSetContent.add(t.forceRoots,t);ed.onBeforeGetContent.add(t.forceRoots,t);}},setup:function(){var t=this,ed=t.editor,s=ed.settings;if(s.forced_root_block){ed.onKeyUp.add(t.forceRoots,t);ed.onPreProcess.add(t.forceRoots,t);}if(s.force_br_newlines){if(isIE){ed.onKeyPress.add(function(ed,e){var n,s=ed.selection;if(e.keyCode==13&&s.getNode().nodeName!='LI'){s.setContent('<br id="__" /> ',{format:'raw'});n=ed.dom.get('__');n.removeAttribute('id');s.select(n);s.collapse();return Event.cancel(e);}});}return;}if(!isIE&&s.force_p_newlines){ed.onKeyPress.add(function(ed,e){if(e.keyCode==13&&!e.shiftKey){if(!t.insertPara(e))Event.cancel(e);}});if(isGecko){ed.onKeyDown.add(function(ed,e){if((e.keyCode==8||e.keyCode==46)&&!e.shiftKey)t.backspaceDelete(e,e.keyCode==8);});}}function ren(rn,na){var ne=ed.dom.create(na);each(rn.attributes,function(a){if(a.specified&&a.nodeValue)ne.setAttribute(a.nodeName.toLowerCase(),a.nodeValue);});each(rn.childNodes,function(n){ne.appendChild(n.cloneNode(true));});rn.parentNode.replaceChild(ne,rn);return ne;};if(isIE&&s.element!='P'){ed.onKeyPress.add(function(ed,e){t.lastElm=ed.selection.getNode().nodeName;});ed.onKeyUp.add(function(ed,e){var bl,sel=ed.selection,n=sel.getNode(),b=ed.getBody();if(b.childNodes.length===1&&n.nodeName=='P'){n=ren(n,s.element);sel.select(n);sel.collapse();ed.nodeChanged();}else if(e.keyCode==13&&!e.shiftKey&&t.lastElm!='P'){bl=ed.dom.getParent(n,'P');if(bl){ren(bl,s.element);ed.nodeChanged();}}});}},find:function(n,t,s){var ed=this.editor,w=ed.getDoc().createTreeWalker(n,4,null,false),c=-1;while(n=w.nextNode()){c++;if(t==0&&n==s)return c;if(t==1&&c==s)return n;}return-1;},forceRoots:function(ed,e){var t=this,ed=t.editor,b=ed.getBody(),d=ed.getDoc(),se=ed.selection,s=se.getSel(),r=se.getRng(),si=-2,ei,so,eo,tr,c=-0xFFFFFF;var nx,bl,bp,sp,le,nl=b.childNodes,i;if(e&&e.keyCode==13)return true;for(i=nl.length-1;i>=0;i--){nx=nl[i];if(nx.nodeType==3||(!t.dom.isBlock(nx)&&nx.nodeType!=8)){if(!bl){if(nx.nodeType!=3||/[^\s]/g.test(nx.nodeValue)){if(si==-2&&r){if(!isIE){if(ed.dom.getParent(r.startContainer,function(e){return e===b;})){so=r.startOffset;eo=r.endOffset;si=t.find(b,0,r.startContainer);ei=t.find(b,0,r.endContainer);}}else{tr=d.body.createTextRange();tr.moveToElementText(b);tr.collapse(1);bp=tr.move('character',c)*-1;tr=r.duplicate();tr.collapse(1);sp=tr.move('character',c)*-1;tr=r.duplicate();tr.collapse(0);le=(tr.move('character',c)*-1)-sp;si=sp-bp;ei=le;}}bl=ed.dom.create(ed.settings.forced_root_block);bl.appendChild(nx.cloneNode(1));nx.parentNode.replaceChild(bl,nx);}}else{if(bl.hasChildNodes())bl.insertBefore(nx,bl.firstChild);else bl.appendChild(nx);}}else bl=null;}if(si!=-2){if(!isIE){bl=b.getElementsByTagName(ed.settings.element)[0];r=d.createRange();if(si!=-1)r.setStart(t.find(b,1,si),so);else r.setStart(bl,0);if(ei!=-1)r.setEnd(t.find(b,1,ei),eo);else r.setEnd(bl,0);if(s){s.removeAllRanges();s.addRange(r);}}else{try{r=s.createRange();r.moveToElementText(b);r.collapse(1);r.moveStart('character',si);r.moveEnd('character',ei);r.select();}catch(ex){}}}},getParentBlock:function(n){var d=this.dom;return d.getParent(n,d.isBlock);},insertPara:function(e){var t=this,ed=t.editor,dom=ed.dom,d=ed.getDoc(),se=ed.settings,s=ed.selection.getSel(),r=s.getRangeAt(0),b=d.body;var rb,ra,dir,sn,so,en,eo,sb,eb,bn,bef,aft,sc,ec,n,vp=dom.getViewPort(ed.getWin()),y,ch;function isEmpty(n){n=n.innerHTML;n=n.replace(/<(img|hr|table)/gi,'-');n=n.replace(/<[^>]+>/g,'');return n.replace(/[ \t\r\n]+/g,'')=='';};rb=d.createRange();rb.setStart(s.anchorNode,s.anchorOffset);rb.collapse(true);ra=d.createRange();ra.setStart(s.focusNode,s.focusOffset);ra.collapse(true);dir=rb.compareBoundaryPoints(rb.START_TO_END,ra)<0;sn=dir?s.anchorNode:s.focusNode;so=dir?s.anchorOffset:s.focusOffset;en=dir?s.focusNode:s.anchorNode;eo=dir?s.focusOffset:s.anchorOffset;if(sn===en&&/^(TD|TH)$/.test(sn.nodeName)){dom.remove(sn.firstChild);ed.dom.add(sn,se.element,null,'<br />');aft=ed.dom.add(sn,se.element,null,'<br />');r=d.createRange();r.selectNodeContents(aft);r.collapse(1);ed.selection.setRng(r);return false;}if(sn==b&&en==b&&b.firstChild&&ed.dom.isBlock(b.firstChild)){sn=en=sn.firstChild;so=eo=0;rb=d.createRange();rb.setStart(sn,0);ra=d.createRange();ra.setStart(en,0);}sn=sn.nodeName=="HTML"?d.body:sn;sn=sn.nodeName=="BODY"?sn.firstChild:sn;en=en.nodeName=="HTML"?d.body:en;en=en.nodeName=="BODY"?en.firstChild:en;sb=t.getParentBlock(sn);eb=t.getParentBlock(en);bn=sb?sb.nodeName:se.element;if(t.dom.getParent(sb,function(n){return/OL|UL|PRE/.test(n.nodeName);}))return true;if(sb&&(sb.nodeName=='CAPTION'||/absolute|relative|static/gi.test(sb.style.position))){bn=se.element;sb=null;}if(eb&&(eb.nodeName=='CAPTION'||/absolute|relative|static/gi.test(eb.style.position))){bn=se.element;eb=null;}if(/(TD|TABLE|TH|CAPTION)/.test(bn)||(sb&&bn=="DIV"&&/left|right/gi.test(sb.style.cssFloat))){bn=se.element;sb=eb=null;}bef=(sb&&sb.nodeName==bn)?sb.cloneNode(0):ed.dom.create(bn);aft=(eb&&eb.nodeName==bn)?eb.cloneNode(0):ed.dom.create(bn);aft.removeAttribute('id');if(/^(H[1-6])$/.test(bn)&&sn.nodeValue&&so==sn.nodeValue.length)aft=ed.dom.create(se.element);n=sc=sn;do{if(n==b||n.nodeType==9||t.dom.isBlock(n)||/(TD|TABLE|TH|CAPTION)/.test(n.nodeName))break;sc=n;}while((n=n.previousSibling?n.previousSibling:n.parentNode));n=ec=en;do{if(n==b||n.nodeType==9||t.dom.isBlock(n)||/(TD|TABLE|TH|CAPTION)/.test(n.nodeName))break;ec=n;}while((n=n.nextSibling?n.nextSibling:n.parentNode));if(sc.nodeName==bn)rb.setStart(sc,0);else rb.setStartBefore(sc);rb.setEnd(sn,so);bef.appendChild(rb.cloneContents()||d.createTextNode(''));try{ra.setEndAfter(ec);}catch(ex){}ra.setStart(en,eo);aft.appendChild(ra.cloneContents()||d.createTextNode(''));r=d.createRange();if(!sc.previousSibling&&sc.parentNode.nodeName==bn){r.setStartBefore(sc.parentNode);}else{if(rb.startContainer.nodeName==bn&&rb.startOffset==0)r.setStartBefore(rb.startContainer);else r.setStart(rb.startContainer,rb.startOffset);}if(!ec.nextSibling&&ec.parentNode.nodeName==bn)r.setEndAfter(ec.parentNode);else r.setEnd(ra.endContainer,ra.endOffset);r.deleteContents();if(isOpera)ed.getWin().scrollTo(0,vp.y);if(bef.firstChild&&bef.firstChild.nodeName==bn)bef.innerHTML=bef.firstChild.innerHTML;if(aft.firstChild&&aft.firstChild.nodeName==bn)aft.innerHTML=aft.firstChild.innerHTML;if(isEmpty(bef))bef.innerHTML='<br />';if(isEmpty(aft))aft.innerHTML=isOpera?'&nbsp;':'<br />';if(isOpera&&parseFloat(opera.version())<9.5){r.insertNode(bef);r.insertNode(aft);}else{r.insertNode(aft);r.insertNode(bef);}aft.normalize();bef.normalize();function first(n){return d.createTreeWalker(n,NodeFilter.SHOW_TEXT,null,false).nextNode()||n;};r=d.createRange();r.selectNodeContents(isGecko?first(aft):aft);r.collapse(1);s.removeAllRanges();s.addRange(r);y=ed.dom.getPos(aft).y;ch=aft.clientHeight;if(y<vp.y||y+ch>vp.y+vp.h){ed.getWin().scrollTo(0,y<vp.y?y:y-vp.h+ch);}return false;},backspaceDelete:function(e,bs){var t=this,ed=t.editor,b=ed.getBody(),n,se=ed.selection,r=se.getRng(),sc=r.startContainer,n,w,tn;if(sc&&ed.dom.isBlock(sc)&&!/^(TD|TH)$/.test(sc.nodeName)&&bs){if(sc.childNodes.length==0||(sc.childNodes.length==1&&sc.firstChild.nodeName=='BR')){n=sc;while((n=n.previousSibling)&&!ed.dom.isBlock(n));if(n){if(sc!=b.firstChild){w=ed.dom.doc.createTreeWalker(n,NodeFilter.SHOW_TEXT,null,false);while(tn=w.nextNode())n=tn;r=ed.getDoc().createRange();r.setStart(n,n.nodeValue?n.nodeValue.length:0);r.setEnd(n,n.nodeValue?n.nodeValue.length:0);se.setRng(r);ed.dom.remove(sc);}return Event.cancel(e);}}}function handler(e){e=e.target;if(e&&e.parentNode&&e.nodeName=='BR'&&(n=t.getParentBlock(e))){Event.remove(b,'DOMNodeInserted',handler);if(e.previousSibling||e.nextSibling)ed.dom.remove(e);}};Event._add(b,'DOMNodeInserted',handler);window.setTimeout(function(){Event._remove(b,'DOMNodeInserted',handler);},1);}});})();(function(){var DOM=tinymce.DOM,Event=tinymce.dom.Event,each=tinymce.each,extend=tinymce.extend;tinymce.create('tinymce.ControlManager',{ControlManager:function(ed,s){var t=this,i;s=s||{};t.editor=ed;t.controls={};t.onAdd=new tinymce.util.Dispatcher(t);t.onPostRender=new tinymce.util.Dispatcher(t);t.prefix=s.prefix||ed.id+'_';t._cls={};t.onPostRender.add(function(){each(t.controls,function(c){c.postRender();});});},get:function(id){return this.controls[this.prefix+id]||this.controls[id];},setActive:function(id,s){var c=null;if(c=this.get(id))c.setActive(s);return c;},setDisabled:function(id,s){var c=null;if(c=this.get(id))c.setDisabled(s);return c;},add:function(c){var t=this;if(c){t.controls[c.id]=c;t.onAdd.dispatch(c,t);}return c;},createControl:function(n){var c,t=this,ed=t.editor;each(ed.plugins,function(p){if(p.createControl){c=p.createControl(n,t);if(c)return false;}});switch(n){case"|":case"separator":return t.createSeparator();}if(!c&&ed.buttons&&(c=ed.buttons[n]))return t.createButton(n,c);return t.add(c);},createDropMenu:function(id,s,cc){var t=this,ed=t.editor,c,bm,v,cls;s=extend({'class':'mceDropDown',constrain:ed.settings.constrain_menus},s);s['class']=s['class']+' '+ed.getParam('skin')+'Skin';if(v=ed.getParam('skin_variant'))s['class']+=' '+ed.getParam('skin')+'Skin'+v.substring(0,1).toUpperCase()+v.substring(1);id=t.prefix+id;cls=cc||t._cls.dropmenu||tinymce.ui.DropMenu;c=t.controls[id]=new cls(id,s);c.onAddItem.add(function(c,o){var s=o.settings;s.title=ed.getLang(s.title,s.title);if(!s.onclick){s.onclick=function(v){ed.execCommand(s.cmd,s.ui||false,s.value);};}});ed.onRemove.add(function(){c.destroy();});if(tinymce.isIE){c.onShowMenu.add(function(){bm=ed.selection.getBookmark(1);});c.onHideMenu.add(function(){if(bm)ed.selection.moveToBookmark(bm);});}return t.add(c);},createListBox:function(id,s,cc){var t=this,ed=t.editor,cmd,c,cls;if(t.get(id))return null;s.title=ed.translate(s.title);s.scope=s.scope||ed;if(!s.onselect){s.onselect=function(v){ed.execCommand(s.cmd,s.ui||false,v||s.value);};}s=extend({title:s.title,'class':'mce_'+id,scope:s.scope,control_manager:t},s);id=t.prefix+id;if(ed.settings.use_native_selects)c=new tinymce.ui.NativeListBox(id,s);else{cls=cc||t._cls.listbox||tinymce.ui.ListBox;c=new cls(id,s);}t.controls[id]=c;if(tinymce.isWebKit){c.onPostRender.add(function(c,n){Event.add(n,'mousedown',function(){ed.bookmark=ed.selection.getBookmark('simple');});Event.add(n,'focus',function(){ed.selection.moveToBookmark(ed.bookmark);ed.bookmark=null;});});}if(c.hideMenu)ed.onMouseDown.add(c.hideMenu,c);return t.add(c);},createButton:function(id,s,cc){var t=this,ed=t.editor,o,c,cls;if(t.get(id))return null;s.title=ed.translate(s.title);s.label=ed.translate(s.label);s.scope=s.scope||ed;if(!s.onclick&&!s.menu_button){s.onclick=function(){ed.execCommand(s.cmd,s.ui||false,s.value);};}s=extend({title:s.title,'class':'mce_'+id,unavailable_prefix:ed.getLang('unavailable',''),scope:s.scope,control_manager:t},s);id=t.prefix+id;if(s.menu_button){cls=cc||t._cls.menubutton||tinymce.ui.MenuButton;c=new cls(id,s);ed.onMouseDown.add(c.hideMenu,c);}else{cls=t._cls.button||tinymce.ui.Button;c=new cls(id,s);}return t.add(c);},createMenuButton:function(id,s){s=s||{};s.menu_button=1;return this.createButton(id,s);},createSplitButton:function(id,s,cc){var t=this,ed=t.editor,cmd,c,cls;if(t.get(id))return null;s.title=ed.translate(s.title);s.scope=s.scope||ed;if(!s.onclick){s.onclick=function(v){ed.execCommand(s.cmd,s.ui||false,v||s.value);};}if(!s.onselect){s.onselect=function(v){ed.execCommand(s.cmd,s.ui||false,v||s.value);};}s=extend({title:s.title,'class':'mce_'+id,scope:s.scope,control_manager:t},s);id=t.prefix+id;cls=cc||t._cls.splitbutton||tinymce.ui.SplitButton;c=t.add(new cls(id,s));ed.onMouseDown.add(c.hideMenu,c);return c;},createColorSplitButton:function(id,s,cc){var t=this,ed=t.editor,cmd,c,cls,bm;if(t.get(id))return null;s.title=ed.translate(s.title);s.scope=s.scope||ed;if(!s.onclick){s.onclick=function(v){ed.execCommand(s.cmd,s.ui||false,v||s.value);};}if(!s.onselect){s.onselect=function(v){ed.execCommand(s.cmd,s.ui||false,v||s.value);};}s=extend({title:s.title,'class':'mce_'+id,'menu_class':ed.getParam('skin')+'Skin',scope:s.scope,more_colors_title:ed.getLang('more_colors')},s);id=t.prefix+id;cls=cc||t._cls.colorsplitbutton||tinymce.ui.ColorSplitButton;c=new cls(id,s);ed.onMouseDown.add(c.hideMenu,c);ed.onRemove.add(function(){c.destroy();});if(tinymce.isIE){c.onShowMenu.add(function(){bm=ed.selection.getBookmark(1);});c.onHideMenu.add(function(){if(bm){ed.selection.moveToBookmark(bm);bm=0;}});}return t.add(c);},createToolbar:function(id,s,cc){var c,t=this,cls;id=t.prefix+id;cls=cc||t._cls.toolbar||tinymce.ui.Toolbar;c=new cls(id,s);if(t.get(id))return null;return t.add(c);},createSeparator:function(cc){var cls=cc||this._cls.separator||tinymce.ui.Separator;return new cls();},setControlType:function(n,c){return this._cls[n.toLowerCase()]=c;},destroy:function(){each(this.controls,function(c){c.destroy();});this.controls=null;}});})();(function(){var Dispatcher=tinymce.util.Dispatcher,each=tinymce.each,isIE=tinymce.isIE,isOpera=tinymce.isOpera;tinymce.create('tinymce.WindowManager',{WindowManager:function(ed){var t=this;t.editor=ed;t.onOpen=new Dispatcher(t);t.onClose=new Dispatcher(t);t.params={};t.features={};},open:function(s,p){var t=this,f='',x,y,mo=t.editor.settings.dialog_type=='modal',w,sw,sh,vp=tinymce.DOM.getViewPort(),u;s=s||{};p=p||{};sw=isOpera?vp.w:screen.width;sh=isOpera?vp.h:screen.height;s.name=s.name||'mc_'+new Date().getTime();s.width=parseInt(s.width||320);s.height=parseInt(s.height||240);s.resizable=true;s.left=s.left||parseInt(sw/ 2.0) - (s.width /2.0);s.top=s.top||parseInt(sh/ 2.0) - (s.height /2.0);p.inline=false;p.mce_width=s.width;p.mce_height=s.height;p.mce_auto_focus=s.auto_focus;if(mo){if(isIE){s.center=true;s.help=false;s.dialogWidth=s.width+'px';s.dialogHeight=s.height+'px';s.scroll=s.scrollbars||false;}}each(s,function(v,k){if(tinymce.is(v,'boolean'))v=v?'yes':'no';if(!/^(name|url)$/.test(k)){if(isIE&&mo)f+=(f?';':'')+k+':'+v;else f+=(f?',':'')+k+'='+v;}});t.features=s;t.params=p;t.onOpen.dispatch(t,s,p);u=s.url||s.file;if(tinymce.relaxedDomain)u+=(u.indexOf('?')==-1?'?':'&')+'mce_rdomain='+tinymce.relaxedDomain;u=tinymce._addVer(u);try{if(isIE&&mo){w=1;window.showModalDialog(u,window,f);}else w=window.open(u,s.name,f);}catch(ex){}if(!w)alert(t.editor.getLang('popup_blocked'));},close:function(w){w.close();this.onClose.dispatch(this);},createInstance:function(cl,a,b,c,d,e){var f=tinymce.resolve(cl);return new f(a,b,c,d,e);},confirm:function(t,cb,s){cb.call(s||this,confirm(this._decode(this.editor.getLang(t,t))));},alert:function(tx,cb,s){var t=this;alert(t._decode(t.editor.getLang(tx,tx)));if(cb)cb.call(s||t);},_decode:function(s){return tinymce.DOM.decode(s).replace(/\\n/g,'\n');}});}());
\ No newline at end of file
+var tinymce={majorVersion:"3",minorVersion:"2.3",releaseDate:"2009-04-23",_init:function(){var o=this,k=document,l=window,j=navigator,b=j.userAgent,h,a,g,f,e,m;o.isOpera=l.opera&&opera.buildNumber;o.isWebKit=/WebKit/.test(b);o.isIE=!o.isWebKit&&!o.isOpera&&(/MSIE/gi).test(b)&&(/Explorer/gi).test(j.appName);o.isIE6=o.isIE&&/MSIE [56]/.test(b);o.isGecko=!o.isWebKit&&/Gecko/.test(b);o.isMac=b.indexOf("Mac")!=-1;o.isAir=/adobeair/i.test(b);if(l.tinyMCEPreInit){o.suffix=tinyMCEPreInit.suffix;o.baseURL=tinyMCEPreInit.base;o.query=tinyMCEPreInit.query;return}o.suffix="";a=k.getElementsByTagName("base");for(h=0;h<a.length;h++){if(m=a[h].href){if(/^https?:\/\/[^\/]+$/.test(m)){m+="/"}f=m?m.match(/.*\//)[0]:""}}function c(d){if(d.src&&/tiny_mce(|_dev|_src|_gzip|_jquery|_prototype).js/.test(d.src)){if(/_(src|dev)\.js/g.test(d.src)){o.suffix="_src"}if((e=d.src.indexOf("?"))!=-1){o.query=d.src.substring(e+1)}o.baseURL=d.src.substring(0,d.src.lastIndexOf("/"));if(f&&o.baseURL.indexOf("://")==-1){o.baseURL=f+o.baseURL}return o.baseURL}return null}a=k.getElementsByTagName("script");for(h=0;h<a.length;h++){if(c(a[h])){return}}g=k.getElementsByTagName("head")[0];if(g){a=g.getElementsByTagName("script");for(h=0;h<a.length;h++){if(c(a[h])){return}}}return},is:function(b,a){var c=typeof(b);if(!a){return c!="undefined"}if(a=="array"&&(b.hasOwnProperty&&b instanceof Array)){return true}return c==a},each:function(d,a,c){var e,b;if(!d){return 0}c=c||d;if(typeof(d.length)!="undefined"){for(e=0,b=d.length;e<b;e++){if(a.call(c,d[e],e,d)===false){return 0}}}else{for(e in d){if(d.hasOwnProperty(e)){if(a.call(c,d[e],e,d)===false){return 0}}}}return 1},map:function(b,c){var d=[];tinymce.each(b,function(a){d.push(c(a))});return d},grep:function(b,c){var d=[];tinymce.each(b,function(a){if(!c||c(a)){d.push(a)}});return d},inArray:function(c,d){var e,b;if(c){for(e=0,b=c.length;e<b;e++){if(c[e]===d){return e}}}return -1},extend:function(f,d){var c,b=arguments;for(c=1;c<b.length;c++){d=b[c];tinymce.each(d,function(a,e){if(typeof(a)!=="undefined"){f[e]=a}})}return f},trim:function(a){return(a?""+a:"").replace(/^\s*|\s*$/g,"")},create:function(j,a){var i=this,b,e,f,g,d,h=0;j=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(j);f=j[3].match(/(^|\.)(\w+)$/i)[2];e=i.createNS(j[3].replace(/\.\w+$/,""));if(e[f]){return}if(j[2]=="static"){e[f]=a;if(this.onCreate){this.onCreate(j[2],j[3],e[f])}return}if(!a[f]){a[f]=function(){};h=1}e[f]=a[f];i.extend(e[f].prototype,a);if(j[5]){b=i.resolve(j[5]).prototype;g=j[5].match(/\.(\w+)$/i)[1];d=e[f];if(h){e[f]=function(){return b[g].apply(this,arguments)}}else{e[f]=function(){this.parent=b[g];return d.apply(this,arguments)}}e[f].prototype[f]=e[f];i.each(b,function(c,k){e[f].prototype[k]=b[k]});i.each(a,function(c,k){if(b[k]){e[f].prototype[k]=function(){this.parent=b[k];return c.apply(this,arguments)}}else{if(k!=f){e[f].prototype[k]=c}}})}i.each(a["static"],function(c,k){e[f][k]=c});if(this.onCreate){this.onCreate(j[2],j[3],e[f].prototype)}},walk:function(c,b,d,a){a=a||this;if(c){if(d){c=c[d]}tinymce.each(c,function(f,e){if(b.call(a,f,e,d)===false){return false}tinymce.walk(f,b,d,a)})}},createNS:function(d,c){var b,a;c=c||window;d=d.split(".");for(b=0;b<d.length;b++){a=d[b];if(!c[a]){c[a]={}}c=c[a]}return c},resolve:function(d,c){var b,a;c=c||window;d=d.split(".");for(b=0,a=d.length;b<a;b++){c=c[d[b]];if(!c){break}}return c},addUnload:function(e,d){var c=this,a=window;e={func:e,scope:d||this};if(!c.unloads){function b(){var f=c.unloads,h,i;if(f){for(i in f){h=f[i];if(h&&h.func){h.func.call(h.scope,1)}}if(a.detachEvent){a.detachEvent("onbeforeunload",g);a.detachEvent("onunload",b)}else{if(a.removeEventListener){a.removeEventListener("unload",b,false)}}c.unloads=h=f=a=b=0;if(window.CollectGarbage){window.CollectGarbage()}}}function g(){var h=document;if(h.readyState=="interactive"){function f(){h.detachEvent("onstop",f);if(b){b()}h=0}if(h){h.attachEvent("onstop",f)}window.setTimeout(function(){if(h){h.detachEvent("onstop",f)}},0)}}if(a.attachEvent){a.attachEvent("onunload",b);a.attachEvent("onbeforeunload",g)}else{if(a.addEventListener){a.addEventListener("unload",b,false)}}c.unloads=[e]}else{c.unloads.push(e)}return e},removeUnload:function(c){var a=this.unloads,b=null;tinymce.each(a,function(e,d){if(e&&e.func==c){a.splice(d,1);b=c;return false}});return b},explode:function(a,b){return a?tinymce.map(a.split(b||","),tinymce.trim):a},_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+"#")}};window.tinymce=tinymce;tinymce._init();tinymce.create("tinymce.util.Dispatcher",{scope:null,listeners:null,Dispatcher:function(a){this.scope=a||this;this.listeners=[]},add:function(a,b){this.listeners.push({cb:a,scope:b||this.scope});return a},addToTop:function(a,b){this.listeners.unshift({cb:a,scope:b||this.scope});return a},remove:function(a){var b=this.listeners,c=null;tinymce.each(b,function(e,d){if(a==e.cb){c=a;b.splice(d,1);return false}});return c},dispatch:function(){var f,d=arguments,e,b=this.listeners,g;for(e=0;e<b.length;e++){g=b[e];f=g.cb.apply(g.scope,d);if(f===false){break}}return f}});(function(){var a=tinymce.each;tinymce.create("tinymce.util.URI",{URI:function(e,g){var f=this,h,d,c;g=f.settings=g||{};if(/^(mailto|tel|news|javascript|about):/i.test(e)||/^\s*#/.test(e)){f.source=e;return}if(e.indexOf("/")===0&&e.indexOf("//")!==0){e=(g.base_uri?g.base_uri.protocol||"http":"http")+"://mce_host"+e}if(e.indexOf(":/")===-1&&e.indexOf("//")!==0){e=(g.base_uri.protocol||"http")+"://mce_host"+f.toAbsPath(g.base_uri.path,e)}e=e.replace(/@@/g,"(mce_at)");e=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e);a(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(b,j){var k=e[j];if(k){k=k.replace(/\(mce_at\)/g,"@@")}f[b]=k});if(c=g.base_uri){if(!f.protocol){f.protocol=c.protocol}if(!f.userInfo){f.userInfo=c.userInfo}if(!f.port&&f.host=="mce_host"){f.port=c.port}if(!f.host||f.host=="mce_host"){f.host=c.host}f.source=""}},setPath:function(c){var b=this;c=/^(.*?)\/?(\w+)?$/.exec(c);b.path=c[0];b.directory=c[1];b.file=c[2];b.source="";b.getURI()},toRelative:function(b){var c=this,d;if(b==="./"){return b}b=new tinymce.util.URI(b,{base_uri:c});if((b.host!="mce_host"&&c.host!=b.host&&b.host)||c.port!=b.port||c.protocol!=b.protocol){return b.getURI()}d=c.toRelPath(c.path,b.path);if(b.query){d+="?"+b.query}if(b.anchor){d+="#"+b.anchor}return d},toAbsolute:function(b,c){var b=new tinymce.util.URI(b,{base_uri:this});return b.getURI(this.host==b.host?c:0)},toRelPath:function(g,h){var c,f=0,d="",e,b;g=g.substring(0,g.lastIndexOf("/"));g=g.split("/");c=h.split("/");if(g.length>=c.length){for(e=0,b=g.length;e<b;e++){if(e>=c.length||g[e]!=c[e]){f=e+1;break}}}if(g.length<c.length){for(e=0,b=c.length;e<b;e++){if(e>=g.length||g[e]!=c[e]){f=e+1;break}}}if(f==1){return h}for(e=0,b=g.length-(f-1);e<b;e++){d+="../"}for(e=f-1,b=c.length;e<b;e++){if(e!=f-1){d+="/"+c[e]}else{d+=c[e]}}return d},toAbsPath:function(e,f){var c,b=0,g=[],d;d=/\/$/.test(f)?"/":"";e=e.split("/");f=f.split("/");a(e,function(h){if(h){g.push(h)}});e=g;for(c=f.length-1,g=[];c>=0;c--){if(f[c].length==0||f[c]=="."){continue}if(f[c]==".."){b++;continue}if(b>0){b--;continue}g.push(f[c])}c=e.length-b;if(c<=0){return"/"+g.reverse().join("/")+d}return"/"+e.slice(0,c).join("/")+"/"+g.reverse().join("/")+d},getURI:function(d){var c,b=this;if(!b.source||d){c="";if(!d){if(b.protocol){c+=b.protocol+"://"}if(b.userInfo){c+=b.userInfo+"@"}if(b.host){c+=b.host}if(b.port){c+=":"+b.port}}if(b.path){c+=b.path}if(b.query){c+="?"+b.query}if(b.anchor){c+="#"+b.anchor}b.source=c}return b.source}})})();(function(){var a=tinymce.each;tinymce.create("static tinymce.util.Cookie",{getHash:function(d){var b=this.get(d),c;if(b){a(b.split("&"),function(e){e=e.split("=");c=c||{};c[unescape(e[0])]=unescape(e[1])})}return c},setHash:function(j,b,g,f,i,c){var h="";a(b,function(e,d){h+=(!h?"":"&")+escape(d)+"="+escape(e)});this.set(j,h,g,f,i,c)},get:function(i){var h=document.cookie,g,f=i+"=",d;if(!h){return}d=h.indexOf("; "+f);if(d==-1){d=h.indexOf(f);if(d!=0){return null}}else{d+=2}g=h.indexOf(";",d);if(g==-1){g=h.length}return unescape(h.substring(d+f.length,g))},set:function(i,b,g,f,h,c){document.cookie=i+"="+escape(b)+((g)?"; expires="+g.toGMTString():"")+((f)?"; path="+escape(f):"")+((h)?"; domain="+h:"")+((c)?"; secure":"")},remove:function(e,b){var c=new Date();c.setTime(c.getTime()-1000);this.set(e,"",c,b,c)}})})();tinymce.create("static tinymce.util.JSON",{serialize:function(e){var c,a,d=tinymce.util.JSON.serialize,b;if(e==null){return"null"}b=typeof e;if(b=="string"){a="\bb\tt\nn\ff\rr\"\"''\\\\";return'"'+e.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(g,f){c=a.indexOf(f);if(c+1){return"\\"+a.charAt(c+1)}g=f.charCodeAt().toString(16);return"\\u"+"0000".substring(g.length)+g})+'"'}if(b=="object"){if(e.hasOwnProperty&&e instanceof Array){for(c=0,a="[";c<e.length;c++){a+=(c>0?",":"")+d(e[c])}return a+"]"}a="{";for(c in e){a+=typeof e[c]!="function"?(a.length>1?',"':'"')+c+'":'+d(e[c]):""}return a+"}"}return""+e},parse:function(s){try{return eval("("+s+")")}catch(ex){}}});tinymce.create("static tinymce.util.XHR",{send:function(g){var a,e,b=window,h=0;g.scope=g.scope||this;g.success_scope=g.success_scope||g.scope;g.error_scope=g.error_scope||g.scope;g.async=g.async===false?false:true;g.data=g.data||"";function d(i){a=0;try{a=new ActiveXObject(i)}catch(c){}return a}a=b.XMLHttpRequest?new XMLHttpRequest():d("Microsoft.XMLHTTP")||d("Msxml2.XMLHTTP");if(a){if(a.overrideMimeType){a.overrideMimeType(g.content_type)}a.open(g.type||(g.data?"POST":"GET"),g.url,g.async);if(g.content_type){a.setRequestHeader("Content-Type",g.content_type)}a.send(g.data);function f(){if(!g.async||a.readyState==4||h++>10000){if(g.success&&h<10000&&a.status==200){g.success.call(g.success_scope,""+a.responseText,a,g)}else{if(g.error){g.error.call(g.error_scope,h>10000?"TIMED_OUT":"GENERAL",a,g)}}a=null}else{b.setTimeout(f,10)}}if(!g.async){return f()}e=b.setTimeout(f,10)}}});(function(){var c=tinymce.extend,b=tinymce.util.JSON,a=tinymce.util.XHR;tinymce.create("tinymce.util.JSONRequest",{JSONRequest:function(d){this.settings=c({},d);this.count=0},send:function(f){var e=f.error,d=f.success;f=c(this.settings,f);f.success=function(h,g){h=b.parse(h);if(typeof(h)=="undefined"){h={error:"JSON Parse error."}}if(h.error){e.call(f.error_scope||f.scope,h.error,g)}else{d.call(f.success_scope||f.scope,h.result)}};f.error=function(h,g){e.call(f.error_scope||f.scope,h,g)};f.data=b.serialize({id:f.id||"c"+(this.count++),method:f.method,params:f.params});f.content_type="application/json";a.send(f)},"static":{sendRPC:function(d){return new tinymce.util.JSONRequest().send(d)}}})}());(function(c){var e=c.each,b=c.is;var d=c.isWebKit,a=c.isIE;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(i,g){var f=this;f.doc=i;f.win=window;f.files={};f.cssFlicker=false;f.counter=0;f.boxModel=!c.isIE||i.compatMode=="CSS1Compat";f.stdMode=i.documentMode===8;this.settings=g=c.extend({keep_values:false,hex_colors:1,process_html:1},g);if(c.isIE6){try{i.execCommand("BackgroundImageCache",false,true)}catch(h){f.cssFlicker=true}}c.addUnload(f.destroy,f)},getRoot:function(){var f=this,g=f.settings;return(g&&f.get(g.root_element))||f.doc.body},getViewPort:function(g){var h,f;g=!g?this.win:g;h=g.document;f=this.boxModel?h.documentElement:h.body;return{x:g.pageXOffset||f.scrollLeft,y:g.pageYOffset||f.scrollTop,w:g.innerWidth||f.clientWidth,h:g.innerHeight||f.clientHeight}},getRect:function(i){var h,f=this,g;i=f.get(i);h=f.getPos(i);g=f.getSize(i);return{x:h.x,y:h.y,w:g.w,h:g.h}},getSize:function(j){var g=this,f,i;j=g.get(j);f=g.getStyle(j,"width");i=g.getStyle(j,"height");if(f.indexOf("px")===-1){f=0}if(i.indexOf("px")===-1){i=0}return{w:parseInt(f)||j.offsetWidth||j.clientWidth,h:parseInt(i)||j.offsetHeight||j.clientHeight}},is:function(g,f){return c.dom.Sizzle.matches(f,g.nodeType?[g]:g).length>0},getParent:function(i,h,g){return this.getParents(i,h,g,false)},getParents:function(p,k,i,m){var h=this,g,j=h.settings,l=[];p=h.get(p);m=m===undefined;if(j.strict_root){i=i||h.getRoot()}if(b(k,"string")){g=k;if(k==="*"){k=function(f){return f.nodeType==1}}else{k=function(f){return h.is(f,g)}}}while(p){if(p==i||!p.nodeType||p.nodeType===9){break}if(!k||k(p)){if(m){l.push(p)}else{return p}}p=p.parentNode}return m?l:null},get:function(f){var g;if(f&&this.doc&&typeof(f)=="string"){g=f;f=this.doc.getElementById(f);if(f&&f.id!==g){return this.doc.getElementsByName(g)[1]}}return f},select:function(h,g){var f=this;return c.dom.Sizzle(h,f.get(g)||f.get(f.settings.root_element)||f.doc,[])},add:function(j,l,f,i,k){var g=this;return this.run(j,function(n){var m,h;m=b(l,"string")?g.doc.createElement(l):l;g.setAttribs(m,f);if(i){if(i.nodeType){m.appendChild(i)}else{g.setHTML(m,i)}}return !k?n.appendChild(m):m})},create:function(i,f,g){return this.add(this.doc.createElement(i),i,f,g,1)},createHTML:function(m,f,j){var l="",i=this,g;l+="<"+m;for(g in f){if(f.hasOwnProperty(g)){l+=" "+g+'="'+i.encode(f[g])+'"'}}if(c.is(j)){return l+">"+j+"</"+m+">"}return l+" />"},remove:function(h,f){var g=this;return this.run(h,function(m){var l,k,j;l=m.parentNode;if(!l){return null}if(f){for(j=m.childNodes.length-1;j>=0;j--){g.insertAfter(m.childNodes[j],m)}}if(g.fixPsuedoLeaks){l=m.cloneNode(true);f="IELeakGarbageBin";k=g.get(f)||g.add(g.doc.body,"div",{id:f,style:"display:none"});k.appendChild(m);k.innerHTML="";return l}return l.removeChild(m)})},setStyle:function(i,f,g){var h=this;return h.run(i,function(l){var k,j;k=l.style;f=f.replace(/-(\D)/g,function(n,m){return m.toUpperCase()});if(h.pixelStyles.test(f)&&(c.is(g,"number")||/^[\-0-9\.]+$/.test(g))){g+="px"}switch(f){case"opacity":if(a){k.filter=g===""?"":"alpha(opacity="+(g*100)+")";if(!i.currentStyle||!i.currentStyle.hasLayout){k.display="inline-block"}}k[f]=k["-moz-opacity"]=k["-khtml-opacity"]=g||"";break;case"float":a?k.styleFloat=g:k.cssFloat=g;break;default:k[f]=g||""}if(h.settings.update_styles){h.setAttrib(l,"mce_style")}})},getStyle:function(i,f,h){i=this.get(i);if(!i){return false}if(this.doc.defaultView&&h){f=f.replace(/[A-Z]/g,function(j){return"-"+j});try{return this.doc.defaultView.getComputedStyle(i,null).getPropertyValue(f)}catch(g){return null}}f=f.replace(/-(\D)/g,function(k,j){return j.toUpperCase()});if(f=="float"){f=a?"styleFloat":"cssFloat"}if(i.currentStyle&&h){return i.currentStyle[f]}return i.style[f]},setStyles:function(i,j){var g=this,h=g.settings,f;f=h.update_styles;h.update_styles=0;e(j,function(k,l){g.setStyle(i,l,k)});h.update_styles=f;if(h.update_styles){g.setAttrib(i,h.cssText)}},setAttrib:function(h,i,f){var g=this;if(!h||!i){return}if(g.settings.strict){i=i.toLowerCase()}return this.run(h,function(k){var j=g.settings;switch(i){case"style":if(!b(f,"string")){e(f,function(l,m){g.setStyle(k,m,l)});return}if(j.keep_values){if(f&&!g._isRes(f)){k.setAttribute("mce_style",f,2)}else{k.removeAttribute("mce_style",2)}}k.style.cssText=f;break;case"class":k.className=f||"";break;case"src":case"href":if(j.keep_values){if(j.url_converter){f=j.url_converter.call(j.url_converter_scope||g,f,i,k)}g.setAttrib(k,"mce_"+i,f,2)}break;case"shape":k.setAttribute("mce_style",f);break}if(b(f)&&f!==null&&f.length!==0){k.setAttribute(i,""+f,2)}else{k.removeAttribute(i,2)}})},setAttribs:function(g,h){var f=this;return this.run(g,function(i){e(h,function(j,k){f.setAttrib(i,k,j)})})},getAttrib:function(i,j,h){var f,g=this;i=g.get(i);if(!i||i.nodeType!==1){return false}if(!b(h)){h=""}if(/^(src|href|style|coords|shape)$/.test(j)){f=i.getAttribute("mce_"+j);if(f){return f}}if(a&&g.props[j]){f=i[g.props[j]];f=f&&f.nodeValue?f.nodeValue:f}if(!f){f=i.getAttribute(j,2)}if(j==="style"){f=f||i.style.cssText;if(f){f=g.serializeStyle(g.parseStyle(f));if(g.settings.keep_values&&!g._isRes(f)){i.setAttribute("mce_style",f)}}}if(d&&j==="class"&&f){f=f.replace(/(apple|webkit)\-[a-z\-]+/gi,"")}if(a){switch(j){case"rowspan":case"colspan":if(f===1){f=""}break;case"size":if(f==="+0"||f===20||f===0){f=""}break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":if(f===0){f=""}break;case"hspace":if(f===-1){f=""}break;case"maxlength":case"tabindex":if(f===32768||f===2147483647||f==="32768"){f=""}break;case"multiple":case"compact":case"noshade":case"nowrap":if(f===65535){return j}return h;case"shape":f=f.toLowerCase();break;default:if(j.indexOf("on")===0&&f){f=(""+f).replace(/^function\s+anonymous\(\)\s+\{\s+(.*)\s+\}$/,"$1")}}}return(f!==undefined&&f!==null&&f!=="")?""+f:h},getPos:function(m,i){var g=this,f=0,l=0,j,k=g.doc,h;m=g.get(m);i=i||k.body;if(m){if(a&&!g.stdMode){m=m.getBoundingClientRect();j=g.boxModel?k.documentElement:k.body;f=g.getStyle(g.select("html")[0],"borderWidth");f=(f=="medium"||g.boxModel&&!g.isIE6)&&2||f;m.top+=g.win.self!=g.win.top?2:0;return{x:m.left+j.scrollLeft-f,y:m.top+j.scrollTop-f}}h=m;while(h&&h!=i&&h.nodeType){f+=h.offsetLeft||0;l+=h.offsetTop||0;h=h.offsetParent}h=m.parentNode;while(h&&h!=i&&h.nodeType){f-=h.scrollLeft||0;l-=h.scrollTop||0;h=h.parentNode}}return{x:f,y:l}},parseStyle:function(h){var i=this,j=i.settings,k={};if(!h){return k}function f(w,q,v){var o,u,m,n;o=k[w+"-top"+q];if(!o){return}u=k[w+"-right"+q];if(o!=u){return}m=k[w+"-bottom"+q];if(u!=m){return}n=k[w+"-left"+q];if(m!=n){return}k[v]=n;delete k[w+"-top"+q];delete k[w+"-right"+q];delete k[w+"-bottom"+q];delete k[w+"-left"+q]}function g(n,m,l,p){var o;o=k[m];if(!o){return}o=k[l];if(!o){return}o=k[p];if(!o){return}k[n]=k[m]+" "+k[l]+" "+k[p];delete k[m];delete k[l];delete k[p]}h=h.replace(/&(#?[a-z0-9]+);/g,"&$1_MCE_SEMI_");e(h.split(";"),function(m){var l,n=[];if(m){m=m.replace(/_MCE_SEMI_/g,";");m=m.replace(/url\([^\)]+\)/g,function(o){n.push(o);return"url("+n.length+")"});m=m.split(":");l=c.trim(m[1]);l=l.replace(/url\(([^\)]+)\)/g,function(p,o){return n[parseInt(o)-1]});l=l.replace(/rgb\([^\)]+\)/g,function(o){return i.toHex(o)});if(j.url_converter){l=l.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g,function(o,p){return"url("+j.url_converter.call(j.url_converter_scope||i,i.decode(p),"style",null)+")"})}k[c.trim(m[0]).toLowerCase()]=l}});f("border","","border");f("border","-width","border-width");f("border","-color","border-color");f("border","-style","border-style");f("padding","","padding");f("margin","","margin");g("border","border-width","border-style","border-color");if(a){if(k.border=="medium none"){k.border=""}}return k},serializeStyle:function(g){var f="";e(g,function(i,h){if(h&&i){if(c.isGecko&&h.indexOf("-moz-")===0){return}switch(h){case"color":case"background-color":i=i.toLowerCase();break}f+=(f?" ":"")+h+": "+i+";"}});return f},loadCSS:function(f){var g=this,h=g.doc;if(!f){f=""}e(f.split(","),function(i){if(g.files[i]){return}g.files[i]=true;g.add(g.select("head")[0],"link",{rel:"stylesheet",href:c._addVer(i)})})},addClass:function(f,g){return this.run(f,function(h){var i;if(!g){return 0}if(this.hasClass(h,g)){return h.className}i=this.removeClass(h,g);return h.className=(i!=""?(i+" "):"")+g})},removeClass:function(h,i){var f=this,g;return f.run(h,function(k){var j;if(f.hasClass(k,i)){if(!g){g=new RegExp("(^|\\s+)"+i+"(\\s+|$)","g")}j=k.className.replace(g," ");return k.className=c.trim(j!=" "?j:"")}return k.className})},hasClass:function(g,f){g=this.get(g);if(!g||!f){return false}return(" "+g.className+" ").indexOf(" "+f+" ")!==-1},show:function(f){return this.setStyle(f,"display","block")},hide:function(f){return this.setStyle(f,"display","none")},isHidden:function(f){f=this.get(f);return !f||f.style.display=="none"||this.getStyle(f,"display")=="none"},uniqueId:function(f){return(!f?"mce_":f)+(this.counter++)},setHTML:function(i,g){var f=this;return this.run(i,function(m){var h,k,j,q,l,h;g=f.processHTML(g);if(a){function o(){try{m.innerHTML="<br />"+g;m.removeChild(m.firstChild)}catch(n){while(m.firstChild){m.firstChild.removeNode()}h=f.create("div");h.innerHTML="<br />"+g;e(h.childNodes,function(r,p){if(p){m.appendChild(r)}})}}if(f.settings.fix_ie_paragraphs){g=g.replace(/<p><\/p>|<p([^>]+)><\/p>|<p[^\/+]\/>/gi,'<p$1 mce_keep="true">&nbsp;</p>')}o();if(f.settings.fix_ie_paragraphs){j=m.getElementsByTagName("p");for(k=j.length-1,h=0;k>=0;k--){q=j[k];if(!q.hasChildNodes()){if(!q.mce_keep){h=1;break}q.removeAttribute("mce_keep")}}}if(h){g=g.replace(/<p ([^>]+)>|<p>/g,'<div $1 mce_tmp="1">');g=g.replace(/<\/p>/g,"</div>");o();if(f.settings.fix_ie_paragraphs){j=m.getElementsByTagName("DIV");for(k=j.length-1;k>=0;k--){q=j[k];if(q.mce_tmp){l=f.doc.createElement("p");q.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi,function(p,n){var r;if(n!=="mce_tmp"){r=q.getAttribute(n);if(!r&&n==="class"){r=q.className}l.setAttribute(n,r)}});for(h=0;h<q.childNodes.length;h++){l.appendChild(q.childNodes[h].cloneNode(true))}q.swapNode(l)}}}}}else{m.innerHTML=g}return g})},processHTML:function(j){var g=this,i=g.settings;if(!i.process_html){return j}if(c.isGecko){j=j.replace(/<(\/?)strong>|<strong( [^>]+)>/gi,"<$1b$2>");j=j.replace(/<(\/?)em>|<em( [^>]+)>/gi,"<$1i$2>")}else{if(a){j=j.replace(/&apos;/g,"&#39;");j=j.replace(/\s+(disabled|checked|readonly|selected)\s*=\s*[\"\']?(false|0)[\"\']?/gi,"")}}j=j.replace(/<a( )([^>]+)\/>|<a\/>/gi,"<a$1$2></a>");if(i.keep_values){if(/<script|style/.test(j)){function f(h){h=h.replace(/(<!--\[CDATA\[|\]\]-->)/g,"\n");h=h.replace(/^[\r\n]*|[\r\n]*$/g,"");h=h.replace(/^\s*(\/\/\s*<!--|\/\/\s*<!\[CDATA\[|<!--|<!\[CDATA\[)[\r\n]*/g,"");h=h.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->|\]\]-->)\s*$/g,"");return h}j=j.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/g,function(l,k,h){h=f(h);if(!k){k=' type="text/javascript"'}if(h){h="<!--\n"+h+"\n// -->"}return"<mce:script"+k+">"+h+"</mce:script>"});j=j.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/g,function(l,k,h){h=f(h);return"<mce:style"+k+"><!--\n"+h+"\n--></mce:style><style"+k+' mce_bogus="1">'+h+"</style>"})}j=j.replace(/<!\[CDATA\[([\s\S]+)\]\]>/g,"<!--[CDATA[$1]]-->");j=j.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi,function(h,l){function k(o,n,q){var p=q;if(h.indexOf("mce_"+n)!=-1){return o}if(n=="style"){if(g._isRes(q)){return o}if(i.hex_colors){p=p.replace(/rgb\([^\)]+\)/g,function(m){return g.toHex(m)})}if(i.url_converter){p=p.replace(/url\([\'\"]?([^\)\'\"]+)\)/g,function(m,r){return"url("+g.encode(i.url_converter.call(i.url_converter_scope||g,g.decode(r),n,l))+")"})}}else{if(n!="coords"&&n!="shape"){if(i.url_converter){p=g.encode(i.url_converter.call(i.url_converter_scope||g,g.decode(q),n,l))}}}return" "+n+'="'+q+'" mce_'+n+'="'+p+'"'}h=h.replace(/ (src|href|style|coords|shape)=[\"]([^\"]+)[\"]/gi,k);h=h.replace(/ (src|href|style|coords|shape)=[\']([^\']+)[\']/gi,k);return h.replace(/ (src|href|style|coords|shape)=([^\s\"\'>]+)/gi,k)})}return j},getOuterHTML:function(f){var g;f=this.get(f);if(!f){return null}if(f.outerHTML!==undefined){return f.outerHTML}g=(f.ownerDocument||this.doc).createElement("body");g.appendChild(f.cloneNode(true));return g.innerHTML},setOuterHTML:function(i,g,j){var f=this;return this.run(i,function(h){var l,k;h=f.get(h);j=j||h.ownerDocument||f.doc;if(a&&h.nodeType==1){h.outerHTML=g}else{k=j.createElement("body");k.innerHTML=g;l=k.lastChild;while(l){f.insertAfter(l.cloneNode(true),h);l=l.previousSibling}f.remove(h)}})},decode:function(g){var h,i,f;if(/&[^;]+;/.test(g)){h=this.doc.createElement("div");h.innerHTML=g;i=h.firstChild;f="";if(i){do{f+=i.nodeValue}while(i.nextSibling)}return f||g}return g},encode:function(f){return f?(""+f).replace(/[<>&\"]/g,function(h,g){switch(h){case"&":return"&amp;";case'"':return"&quot;";case"<":return"&lt;";case">":return"&gt;"}return h}):f},insertAfter:function(h,g){var f=this;g=f.get(g);return this.run(h,function(k){var j,i;j=g.parentNode;i=g.nextSibling;if(i){j.insertBefore(k,i)}else{j.appendChild(k)}return k})},isBlock:function(f){if(f.nodeType&&f.nodeType!==1){return false}f=f.nodeName||f;return/^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TR|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(f)},replace:function(i,h,f){var g=this;if(b(h,"array")){i=i.cloneNode(true)}return g.run(h,function(j){if(f){e(j.childNodes,function(k){i.appendChild(k.cloneNode(true))})}if(g.fixPsuedoLeaks&&j.nodeType===1){j.parentNode.insertBefore(i,j);g.remove(j);return i}return j.parentNode.replaceChild(i,j)})},findCommonAncestor:function(h,f){var i=h,g;while(i){g=f;while(g&&i!=g){g=g.parentNode}if(i==g){break}i=i.parentNode}if(!i&&h.ownerDocument){return h.ownerDocument.documentElement}return i},toHex:function(f){var h=/^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(f);function g(i){i=parseInt(i).toString(16);return i.length>1?i:"0"+i}if(h){f="#"+g(h[1])+g(h[2])+g(h[3]);return f}return f},getClasses:function(){var l=this,g=[],k,m={},n=l.settings.class_filter,j;if(l.classes){return l.classes}function o(f){e(f.imports,function(i){o(i)});e(f.cssRules||f.rules,function(i){switch(i.type||1){case 1:if(i.selectorText){e(i.selectorText.split(","),function(p){p=p.replace(/^\s*|\s*$|^\s\./g,"");if(/\.mce/.test(p)||!/\.[\w\-]+$/.test(p)){return}j=p;p=p.replace(/.*\.([a-z0-9_\-]+).*/i,"$1");if(n&&!(p=n(p,j))){return}if(!m[p]){g.push({"class":p});m[p]=1}})}break;case 3:o(i.styleSheet);break}})}try{e(l.doc.styleSheets,o)}catch(h){}if(g.length>0){l.classes=g}return g},run:function(j,i,h){var g=this,k;if(g.doc&&typeof(j)==="string"){j=g.get(j)}if(!j){return false}h=h||this;if(!j.nodeType&&(j.length||j.length===0)){k=[];e(j,function(l,f){if(l){if(typeof(l)=="string"){l=g.doc.getElementById(l)}k.push(i.call(h,l,f))}});return k}return i.call(h,j)},getAttribs:function(g){var f;g=this.get(g);if(!g){return[]}if(a){f=[];if(g.nodeName=="OBJECT"){return g.attributes}g.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi,function(i,h){f.push({specified:1,nodeName:h})});return f}return g.attributes},destroy:function(g){var f=this;f.win=f.doc=f.root=null;if(!g){c.removeUnload(f.destroy)}},createRng:function(){var f=this.doc;return f.createRange?f.createRange():new c.dom.Range(this)},split:function(k,j,n){var o=this,f=o.createRng(),l,i,m;function g(q,p){q=q[p];if(q&&q[p]&&q[p].nodeType==1&&h(q[p])){o.remove(q[p])}}function h(p){p=o.getOuterHTML(p);p=p.replace(/<(img|hr|table)/gi,"-");p=p.replace(/<[^>]+>/g,"");return p.replace(/[ \t\r\n]+|&nbsp;|&#160;/g,"")==""}if(k&&j){f.setStartBefore(k);f.setEndBefore(j);l=f.extractContents();f=o.createRng();f.setStartAfter(j);f.setEndAfter(k);i=f.extractContents();m=k.parentNode;g(l,"lastChild");if(!h(l)){m.insertBefore(l,k)}if(n){m.replaceChild(n,j)}else{m.insertBefore(j,k)}g(i,"firstChild");if(!h(i)){m.insertBefore(i,k)}o.remove(k);return n||j}},_isRes:function(f){return/^(top|left|bottom|right|width|height)/i.test(f)||/;\s*(top|left|bottom|right|width|height)/i.test(f)}});c.DOM=new c.dom.DOMUtils(document,{process_html:0})})(tinymce);(function(f){var h=0,c=1,e=2,d=tinymce.extend;function g(m,k){var j,l;if(m.parentNode!=k){return -1}for(l=k.firstChild,j=0;l!=m;l=l.nextSibling){j++}return j}function b(k){var j=0;while(k.previousSibling){j++;k=k.previousSibling}return j}function i(j,k){var l;if(j.nodeType==3){return j}if(k<0){return j}l=j.firstChild;while(l!=null&&k>0){--k;l=l.nextSibling}if(l!=null){return l}return j}function a(k){var j=k.doc;d(this,{dom:k,startContainer:j,startOffset:0,endContainer:j,endOffset:0,collapsed:true,commonAncestorContainer:j,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3})}d(a.prototype,{setStart:function(k,j){this._setEndPoint(true,k,j)},setEnd:function(k,j){this._setEndPoint(false,k,j)},setStartBefore:function(j){this.setStart(j.parentNode,b(j))},setStartAfter:function(j){this.setStart(j.parentNode,b(j)+1)},setEndBefore:function(j){this.setEnd(j.parentNode,b(j))},setEndAfter:function(j){this.setEnd(j.parentNode,b(j)+1)},collapse:function(k){var j=this;if(k){j.endContainer=j.startContainer;j.endOffset=j.startOffset}else{j.startContainer=j.endContainer;j.startOffset=j.endOffset}j.collapsed=true},selectNode:function(j){this.setStartBefore(j);this.setEndAfter(j)},selectNodeContents:function(j){this.setStart(j,0);this.setEnd(j,j.nodeType===1?j.childNodes.length:j.nodeValue.length)},compareBoundaryPoints:function(m,n){var l=this,p=l.startContainer,o=l.startOffset,k=l.endContainer,j=l.endOffset;if(m===0){return l._compareBoundaryPoints(p,o,p,o)}if(m===1){return l._compareBoundaryPoints(p,o,k,j)}if(m===2){return l._compareBoundaryPoints(k,j,k,j)}if(m===3){return l._compareBoundaryPoints(k,j,p,o)}},deleteContents:function(){this._traverse(e)},extractContents:function(){return this._traverse(h)},cloneContents:function(){return this._traverse(c)},insertNode:function(m){var j=this,l,k;if(m.nodeType===3||m.nodeType===4){l=j.startContainer.splitText(j.startOffset);j.startContainer.parentNode.insertBefore(m,l)}else{if(j.startContainer.childNodes.length>0){k=j.startContainer.childNodes[j.startOffset]}j.startContainer.insertBefore(m,k)}},surroundContents:function(l){var j=this,k=j.extractContents();j.insertNode(l);l.appendChild(k);j.selectNode(l)},cloneRange:function(){var j=this;return d(new a(j.dom),{startContainer:j.startContainer,startOffset:j.startOffset,endContainer:j.endContainer,endOffset:j.endOffset,collapsed:j.collapsed,commonAncestorContainer:j.commonAncestorContainer})},_isCollapsed:function(){return(this.startContainer==this.endContainer&&this.startOffset==this.endOffset)},_compareBoundaryPoints:function(m,p,k,o){var q,l,j,r,t,s;if(m==k){if(p==o){return 0}else{if(p<o){return -1}else{return 1}}}q=k;while(q&&q.parentNode!=m){q=q.parentNode}if(q){l=0;j=m.firstChild;while(j!=q&&l<p){l++;j=j.nextSibling}if(p<=l){return -1}else{return 1}}q=m;while(q&&q.parentNode!=k){q=q.parentNode}if(q){l=0;j=k.firstChild;while(j!=q&&l<o){l++;j=j.nextSibling}if(l<o){return -1}else{return 1}}r=this.dom.findCommonAncestor(m,k);t=m;while(t&&t.parentNode!=r){t=t.parentNode}if(!t){t=r}s=k;while(s&&s.parentNode!=r){s=s.parentNode}if(!s){s=r}if(t==s){return 0}j=r.firstChild;while(j){if(j==t){return -1}if(j==s){return 1}j=j.nextSibling}},_setEndPoint:function(k,q,p){var l=this,j,m;if(k){l.startContainer=q;l.startOffset=p}else{l.endContainer=q;l.endOffset=p}j=l.endContainer;while(j.parentNode){j=j.parentNode}m=l.startContainer;while(m.parentNode){m=m.parentNode}if(m!=j){l.collapse(k)}else{if(l._compareBoundaryPoints(l.startContainer,l.startOffset,l.endContainer,l.endOffset)>0){l.collapse(k)}}l.collapsed=l._isCollapsed();l.commonAncestorContainer=l.dom.findCommonAncestor(l.startContainer,l.endContainer)},_traverse:function(r){var s=this,q,m=0,v=0,k,o,l,n,j,u;if(s.startContainer==s.endContainer){return s._traverseSameContainer(r)}for(q=s.endContainer,k=q.parentNode;k!=null;q=k,k=k.parentNode){if(k==s.startContainer){return s._traverseCommonStartContainer(q,r)}++m}for(q=s.startContainer,k=q.parentNode;k!=null;q=k,k=k.parentNode){if(k==s.endContainer){return s._traverseCommonEndContainer(q,r)}++v}o=v-m;l=s.startContainer;while(o>0){l=l.parentNode;o--}n=s.endContainer;while(o<0){n=n.parentNode;o++}for(j=l.parentNode,u=n.parentNode;j!=u;j=j.parentNode,u=u.parentNode){l=j;n=u}return s._traverseCommonAncestors(l,n,r)},_traverseSameContainer:function(o){var r=this,q,u,j,k,l,p,m;if(o!=e){q=r.dom.doc.createDocumentFragment()}if(r.startOffset==r.endOffset){return q}if(r.startContainer.nodeType==3){u=r.startContainer.nodeValue;j=u.substring(r.startOffset,r.endOffset);if(o!=c){r.startContainer.deleteData(r.startOffset,r.endOffset-r.startOffset);r.collapse(true)}if(o==e){return null}q.appendChild(r.dom.doc.createTextNode(j));return q}k=i(r.startContainer,r.startOffset);l=r.endOffset-r.startOffset;while(l>0){p=k.nextSibling;m=r._traverseFullySelected(k,o);if(q){q.appendChild(m)}--l;k=p}if(o!=c){r.collapse(true)}return q},_traverseCommonStartContainer:function(j,p){var s=this,r,k,l,m,q,o;if(p!=e){r=s.dom.doc.createDocumentFragment()}k=s._traverseRightBoundary(j,p);if(r){r.appendChild(k)}l=g(j,s.startContainer);m=l-s.startOffset;if(m<=0){if(p!=c){s.setEndBefore(j);s.collapse(false)}return r}k=j.previousSibling;while(m>0){q=k.previousSibling;o=s._traverseFullySelected(k,p);if(r){r.insertBefore(o,r.firstChild)}--m;k=q}if(p!=c){s.setEndBefore(j);s.collapse(false)}return r},_traverseCommonEndContainer:function(m,p){var s=this,r,o,j,k,q,l;if(p!=e){r=s.dom.doc.createDocumentFragment()}j=s._traverseLeftBoundary(m,p);if(r){r.appendChild(j)}o=g(m,s.endContainer);++o;k=s.endOffset-o;j=m.nextSibling;while(k>0){q=j.nextSibling;l=s._traverseFullySelected(j,p);if(r){r.appendChild(l)}--k;j=q}if(p!=c){s.setStartAfter(m);s.collapse(true)}return r},_traverseCommonAncestors:function(p,j,s){var w=this,l,v,o,q,r,k,u,m;if(s!=e){v=w.dom.doc.createDocumentFragment()}l=w._traverseLeftBoundary(p,s);if(v){v.appendChild(l)}o=p.parentNode;q=g(p,o);r=g(j,o);++q;k=r-q;u=p.nextSibling;while(k>0){m=u.nextSibling;l=w._traverseFullySelected(u,s);if(v){v.appendChild(l)}u=m;--k}l=w._traverseRightBoundary(j,s);if(v){v.appendChild(l)}if(s!=c){w.setStartAfter(p);w.collapse(true)}return v},_traverseRightBoundary:function(p,q){var s=this,l=i(s.endContainer,s.endOffset-1),r,o,n,j,k;var m=l!=s.endContainer;if(l==p){return s._traverseNode(l,m,false,q)}r=l.parentNode;o=s._traverseNode(r,false,false,q);while(r!=null){while(l!=null){n=l.previousSibling;j=s._traverseNode(l,m,false,q);if(q!=e){o.insertBefore(j,o.firstChild)}m=true;l=n}if(r==p){return o}l=r.previousSibling;r=r.parentNode;k=s._traverseNode(r,false,false,q);if(q!=e){k.appendChild(o)}o=k}return null},_traverseLeftBoundary:function(p,q){var s=this,m=i(s.startContainer,s.startOffset);var n=m!=s.startContainer,r,o,l,j,k;if(m==p){return s._traverseNode(m,n,true,q)}r=m.parentNode;o=s._traverseNode(r,false,true,q);while(r!=null){while(m!=null){l=m.nextSibling;j=s._traverseNode(m,n,true,q);if(q!=e){o.appendChild(j)}n=true;m=l}if(r==p){return o}m=r.nextSibling;r=r.parentNode;k=s._traverseNode(r,false,true,q);if(q!=e){k.appendChild(o)}o=k}return null},_traverseNode:function(j,o,r,s){var u=this,m,l,p,k,q;if(o){return u._traverseFullySelected(j,s)}if(j.nodeType==3){m=j.nodeValue;if(r){k=u.startOffset;l=m.substring(k);p=m.substring(0,k)}else{k=u.endOffset;l=m.substring(0,k);p=m.substring(k)}if(s!=c){j.nodeValue=p}if(s==e){return null}q=j.cloneNode(false);q.nodeValue=l;return q}if(s==e){return null}return j.cloneNode(false)},_traverseFullySelected:function(l,k){var j=this;if(k!=e){return k==c?l.cloneNode(true):l}l.parentNode.removeChild(l);return null}});f.Range=a})(tinymce.dom);(function(){function a(e){var d=this,h="\uFEFF",b,g;function c(j,i){if(j&&i){if(j.item&&i.item&&j.item(0)===i.item(0)){return 1}if(j.isEqual&&i.isEqual&&i.isEqual(j)){return 1}}return 0}function f(){var m=e.dom,j=e.getRng(),s=m.createRng(),p,k,n,q,o,l;function i(v){var t=v.parentNode.childNodes,u;for(u=t.length-1;u>=0;u--){if(t[u]==v){return u}}return -1}function r(v){var t=j.duplicate(),B,y,u,w,x=0,z=0,A,C;t.collapse(v);B=t.parentElement();t.pasteHTML(h);u=B.childNodes;for(y=0;y<u.length;y++){w=u[y];if(y>0&&(w.nodeType!==3||u[y-1].nodeType!==3)){z++}if(w.nodeType===3){A=w.nodeValue.indexOf(h);if(A!==-1){x+=A;break}x+=w.nodeValue.length}else{x=0}}t.moveStart("character",-1);t.text="";return{index:z,offset:x,parent:B}}n=j.item?j.item(0):j.parentElement();if(n.ownerDocument!=m.doc){return s}if(j.item||!n.hasChildNodes()){s.setStart(n.parentNode,i(n));s.setEnd(s.startContainer,s.startOffset+1);return s}l=e.isCollapsed();p=r(true);k=r(false);p.parent.normalize();k.parent.normalize();q=p.parent.childNodes[Math.min(p.index,p.parent.childNodes.length-1)];if(q.nodeType!=3){s.setStart(p.parent,p.index)}else{s.setStart(p.parent.childNodes[p.index],p.offset)}o=k.parent.childNodes[Math.min(k.index,k.parent.childNodes.length-1)];if(o.nodeType!=3){if(!l){k.index++}s.setEnd(k.parent,k.index)}else{s.setEnd(k.parent.childNodes[k.index],k.offset)}if(!l){q=s.startContainer;if(q.nodeType==1){s.setStart(q,Math.min(s.startOffset,q.childNodes.length))}o=s.endContainer;if(o.nodeType==1){s.setEnd(o,Math.min(s.endOffset,o.childNodes.length))}}d.addRange(s);return s}this.addRange=function(j){var o,m=e.dom.doc.body,p,k,q,l,n,i;q=j.startContainer;l=j.startOffset;n=j.endContainer;i=j.endOffset;o=m.createTextRange();q=q.nodeType==1?q.childNodes[Math.min(l,q.childNodes.length-1)]:q;n=n.nodeType==1?n.childNodes[Math.min(l==i?i:i-1,n.childNodes.length-1)]:n;if(q==n&&q.nodeType==1){if(/^(IMG|TABLE)$/.test(q.nodeName)&&l!=i){o=m.createControlRange();o.addElement(q)}else{o=m.createTextRange();if(!q.hasChildNodes()&&q.canHaveHTML){q.innerHTML=h}o.moveToElementText(q);if(q.innerHTML==h){o.collapse(true);q.removeChild(q.firstChild)}}if(l==i){o.collapse(i<=j.endContainer.childNodes.length-1)}o.select();return}function r(t,v){var u,s,w;if(t.nodeType!=3){return -1}u=t.nodeValue;s=m.createTextRange();t.nodeValue=u.substring(0,v)+h+u.substring(v);s.moveToElementText(t.parentNode);s.findText(h);w=Math.abs(s.moveStart("character",-1048575));t.nodeValue=u;return w}if(j.collapsed){pos=r(q,l);o=m.createTextRange();o.move("character",pos);o.select();return}else{if(q==n&&q.nodeType==3){p=r(q,l);o.move("character",p);o.moveEnd("character",i-l);o.select();return}p=r(q,l);k=r(n,i);o=m.createTextRange();if(p==-1){o.moveToElementText(q);p=0}else{o.move("character",p)}tmpRng=m.createTextRange();if(k==-1){tmpRng.moveToElementText(n)}else{tmpRng.move("character",k)}o.setEndPoint("EndToEnd",tmpRng);o.select();return}};this.getRangeAt=function(){if(!b||!c(g,e.getRng())){b=f();g=e.getRng()}return b};this.destroy=function(){g=b=null}}tinymce.dom.TridentSelection=a})();(function(){var p=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,i=0,d=Object.prototype.toString,n=false;var b=function(D,t,A,v){A=A||[];var e=t=t||document;if(t.nodeType!==1&&t.nodeType!==9){return[]}if(!D||typeof D!=="string"){return A}var B=[],C,y,G,F,z,s,r=true,w=o(t);p.lastIndex=0;while((C=p.exec(D))!==null){B.push(C[1]);if(C[2]){s=RegExp.rightContext;break}}if(B.length>1&&j.exec(D)){if(B.length===2&&f.relative[B[0]]){y=g(B[0]+B[1],t)}else{y=f.relative[B[0]]?[t]:b(B.shift(),t);while(B.length){D=B.shift();if(f.relative[D]){D+=B.shift()}y=g(D,y)}}}else{if(!v&&B.length>1&&t.nodeType===9&&!w&&f.match.ID.test(B[0])&&!f.match.ID.test(B[B.length-1])){var H=b.find(B.shift(),t,w);t=H.expr?b.filter(H.expr,H.set)[0]:H.set[0]}if(t){var H=v?{expr:B.pop(),set:a(v)}:b.find(B.pop(),B.length===1&&(B[0]==="~"||B[0]==="+")&&t.parentNode?t.parentNode:t,w);y=H.expr?b.filter(H.expr,H.set):H.set;if(B.length>0){G=a(y)}else{r=false}while(B.length){var u=B.pop(),x=u;if(!f.relative[u]){u=""}else{x=B.pop()}if(x==null){x=t}f.relative[u](G,x,w)}}else{G=B=[]}}if(!G){G=y}if(!G){throw"Syntax error, unrecognized expression: "+(u||D)}if(d.call(G)==="[object Array]"){if(!r){A.push.apply(A,G)}else{if(t&&t.nodeType===1){for(var E=0;G[E]!=null;E++){if(G[E]&&(G[E]===true||G[E].nodeType===1&&h(t,G[E]))){A.push(y[E])}}}else{for(var E=0;G[E]!=null;E++){if(G[E]&&G[E].nodeType===1){A.push(y[E])}}}}}else{a(G,A)}if(s){b(s,e,A,v);b.uniqueSort(A)}return A};b.uniqueSort=function(r){if(c){n=false;r.sort(c);if(n){for(var e=1;e<r.length;e++){if(r[e]===r[e-1]){r.splice(e--,1)}}}}};b.matches=function(e,r){return b(e,null,null,r)};b.find=function(x,e,y){var w,u;if(!x){return[]}for(var t=0,s=f.order.length;t<s;t++){var v=f.order[t],u;if((u=f.match[v].exec(x))){var r=RegExp.leftContext;if(r.substr(r.length-1)!=="\\"){u[1]=(u[1]||"").replace(/\\/g,"");w=f.find[v](u,e,y);if(w!=null){x=x.replace(f.match[v],"");break}}}}if(!w){w=e.getElementsByTagName("*")}return{set:w,expr:x}};b.filter=function(A,z,D,t){var s=A,F=[],x=z,v,e,w=z&&z[0]&&o(z[0]);while(A&&z.length){for(var y in f.filter){if((v=f.match[y].exec(A))!=null){var r=f.filter[y],E,C;e=false;if(x==F){F=[]}if(f.preFilter[y]){v=f.preFilter[y](v,x,D,F,t,w);if(!v){e=E=true}else{if(v===true){continue}}}if(v){for(var u=0;(C=x[u])!=null;u++){if(C){E=r(C,v,u,x);var B=t^!!E;if(D&&E!=null){if(B){e=true}else{x[u]=false}}else{if(B){F.push(C);e=true}}}}}if(E!==undefined){if(!D){x=F}A=A.replace(f.match[y],"");if(!e){return[]}break}}}if(A==s){if(e==null){throw"Syntax error, unrecognized expression: "+A}else{break}}s=A}return x};var f=b.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(e){return e.getAttribute("href")}},relative:{"+":function(x,e,w){var u=typeof e==="string",y=u&&!/\W/.test(e),v=u&&!y;if(y&&!w){e=e.toUpperCase()}for(var t=0,s=x.length,r;t<s;t++){if((r=x[t])){while((r=r.previousSibling)&&r.nodeType!==1){}x[t]=v||r&&r.nodeName===e?r||false:r===e}}if(v){b.filter(e,x,true)}},">":function(w,r,x){var u=typeof r==="string";if(u&&!/\W/.test(r)){r=x?r:r.toUpperCase();for(var s=0,e=w.length;s<e;s++){var v=w[s];if(v){var t=v.parentNode;w[s]=t.nodeName===r?t:false}}}else{for(var s=0,e=w.length;s<e;s++){var v=w[s];if(v){w[s]=u?v.parentNode:v.parentNode===r}}if(u){b.filter(r,w,true)}}},"":function(t,r,v){var s=i++,e=q;if(!r.match(/\W/)){var u=r=v?r:r.toUpperCase();e=m}e("parentNode",r,s,t,u,v)},"~":function(t,r,v){var s=i++,e=q;if(typeof r==="string"&&!r.match(/\W/)){var u=r=v?r:r.toUpperCase();e=m}e("previousSibling",r,s,t,u,v)}},find:{ID:function(r,s,t){if(typeof s.getElementById!=="undefined"&&!t){var e=s.getElementById(r[1]);return e?[e]:[]}},NAME:function(s,v,w){if(typeof v.getElementsByName!=="undefined"){var r=[],u=v.getElementsByName(s[1]);for(var t=0,e=u.length;t<e;t++){if(u[t].getAttribute("name")===s[1]){r.push(u[t])}}return r.length===0?null:r}},TAG:function(e,r){return r.getElementsByTagName(e[1])}},preFilter:{CLASS:function(t,r,s,e,w,x){t=" "+t[1].replace(/\\/g,"")+" ";if(x){return t}for(var u=0,v;(v=r[u])!=null;u++){if(v){if(w^(v.className&&(" "+v.className+" ").indexOf(t)>=0)){if(!s){e.push(v)}}else{if(s){r[u]=false}}}}return false},ID:function(e){return e[1].replace(/\\/g,"")},TAG:function(r,e){for(var s=0;e[s]===false;s++){}return e[s]&&o(e[s])?r[1]:r[1].toUpperCase()},CHILD:function(e){if(e[1]=="nth"){var r=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(e[2]=="even"&&"2n"||e[2]=="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(r[1]+(r[2]||1))-0;e[3]=r[3]-0}e[0]=i++;return e},ATTR:function(u,r,s,e,v,w){var t=u[1].replace(/\\/g,"");if(!w&&f.attrMap[t]){u[1]=f.attrMap[t]}if(u[2]==="~="){u[4]=" "+u[4]+" "}return u},PSEUDO:function(u,r,s,e,v){if(u[1]==="not"){if(u[3].match(p).length>1||/^\w/.test(u[3])){u[3]=b(u[3],null,null,r)}else{var t=b.filter(u[3],r,s,true^v);if(!s){e.push.apply(e,t)}return false}}else{if(f.match.POS.test(u[0])||f.match.CHILD.test(u[0])){return true}}return u},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){e.parentNode.selectedIndex;return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(s,r,e){return !!b(e[3],s).length},header:function(e){return/h\d/i.test(e.nodeName)},text:function(e){return"text"===e.type},radio:function(e){return"radio"===e.type},checkbox:function(e){return"checkbox"===e.type},file:function(e){return"file"===e.type},password:function(e){return"password"===e.type},submit:function(e){return"submit"===e.type},image:function(e){return"image"===e.type},reset:function(e){return"reset"===e.type},button:function(e){return"button"===e.type||e.nodeName.toUpperCase()==="BUTTON"},input:function(e){return/input|select|textarea|button/i.test(e.nodeName)}},setFilters:{first:function(r,e){return e===0},last:function(s,r,e,t){return r===t.length-1},even:function(r,e){return e%2===0},odd:function(r,e){return e%2===1},lt:function(s,r,e){return r<e[3]-0},gt:function(s,r,e){return r>e[3]-0},nth:function(s,r,e){return e[3]-0==r},eq:function(s,r,e){return e[3]-0==r}},filter:{PSEUDO:function(w,s,t,x){var r=s[1],u=f.filters[r];if(u){return u(w,t,s,x)}else{if(r==="contains"){return(w.textContent||w.innerText||"").indexOf(s[3])>=0}else{if(r==="not"){var v=s[3];for(var t=0,e=v.length;t<e;t++){if(v[t]===w){return false}}return true}}}},CHILD:function(e,t){var w=t[1],r=e;switch(w){case"only":case"first":while(r=r.previousSibling){if(r.nodeType===1){return false}}if(w=="first"){return true}r=e;case"last":while(r=r.nextSibling){if(r.nodeType===1){return false}}return true;case"nth":var s=t[2],z=t[3];if(s==1&&z==0){return true}var v=t[0],y=e.parentNode;if(y&&(y.sizcache!==v||!e.nodeIndex)){var u=0;for(r=y.firstChild;r;r=r.nextSibling){if(r.nodeType===1){r.nodeIndex=++u}}y.sizcache=v}var x=e.nodeIndex-z;if(s==0){return x==0}else{return(x%s==0&&x/s>=0)}}},ID:function(r,e){return r.nodeType===1&&r.getAttribute("id")===e},TAG:function(r,e){return(e==="*"&&r.nodeType===1)||r.nodeName===e},CLASS:function(r,e){return(" "+(r.className||r.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(v,t){var s=t[1],e=f.attrHandle[s]?f.attrHandle[s](v):v[s]!=null?v[s]:v.getAttribute(s),w=e+"",u=t[2],r=t[4];return e==null?u==="!=":u==="="?w===r:u==="*="?w.indexOf(r)>=0:u==="~="?(" "+w+" ").indexOf(r)>=0:!r?w&&e!==false:u==="!="?w!=r:u==="^="?w.indexOf(r)===0:u==="$="?w.substr(w.length-r.length)===r:u==="|="?w===r||w.substr(0,r.length+1)===r+"-":false},POS:function(u,r,s,v){var e=r[2],t=f.setFilters[e];if(t){return t(u,s,r,v)}}}};var j=f.match.POS;for(var l in f.match){f.match[l]=new RegExp(f.match[l].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var a=function(r,e){r=Array.prototype.slice.call(r);if(e){e.push.apply(e,r);return e}return r};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(k){a=function(u,t){var r=t||[];if(d.call(u)==="[object Array]"){Array.prototype.push.apply(r,u)}else{if(typeof u.length==="number"){for(var s=0,e=u.length;s<e;s++){r.push(u[s])}}else{for(var s=0;u[s];s++){r.push(u[s])}}}return r}}var c;if(document.documentElement.compareDocumentPosition){c=function(r,e){var s=r.compareDocumentPosition(e)&4?-1:r===e?0:1;if(s===0){n=true}return s}}else{if("sourceIndex" in document.documentElement){c=function(r,e){var s=r.sourceIndex-e.sourceIndex;if(s===0){n=true}return s}}else{if(document.createRange){c=function(t,r){var s=t.ownerDocument.createRange(),e=r.ownerDocument.createRange();s.setStart(t,0);s.setEnd(t,0);e.setStart(r,0);e.setEnd(r,0);var u=s.compareBoundaryPoints(Range.START_TO_END,e);if(u===0){n=true}return u}}}}(function(){var r=document.createElement("div"),s="script"+(new Date).getTime();r.innerHTML="<a name='"+s+"'/>";var e=document.documentElement;e.insertBefore(r,e.firstChild);if(!!document.getElementById(s)){f.find.ID=function(u,v,w){if(typeof v.getElementById!=="undefined"&&!w){var t=v.getElementById(u[1]);return t?t.id===u[1]||typeof t.getAttributeNode!=="undefined"&&t.getAttributeNode("id").nodeValue===u[1]?[t]:undefined:[]}};f.filter.ID=function(v,t){var u=typeof v.getAttributeNode!=="undefined"&&v.getAttributeNode("id");return v.nodeType===1&&u&&u.nodeValue===t}}e.removeChild(r)})();(function(){var e=document.createElement("div");e.appendChild(document.createComment(""));if(e.getElementsByTagName("*").length>0){f.find.TAG=function(r,v){var u=v.getElementsByTagName(r[1]);if(r[1]==="*"){var t=[];for(var s=0;u[s];s++){if(u[s].nodeType===1){t.push(u[s])}}u=t}return u}}e.innerHTML="<a href='#'></a>";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){f.attrHandle.href=function(r){return r.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var e=b,s=document.createElement("div");s.innerHTML="<p class='TEST'></p>";if(s.querySelectorAll&&s.querySelectorAll(".TEST").length===0){return}b=function(w,v,t,u){v=v||document;if(!u&&v.nodeType===9&&!o(v)){try{return a(v.querySelectorAll(w),t)}catch(x){}}return e(w,v,t,u)};for(var r in e){b[r]=e[r]}})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var e=document.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>";if(e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}f.order.splice(1,0,"CLASS");f.find.CLASS=function(r,s,t){if(typeof s.getElementsByClassName!=="undefined"&&!t){return s.getElementsByClassName(r[1])}}})()}function m(r,w,v,A,x,z){var y=r=="previousSibling"&&!z;for(var t=0,s=A.length;t<s;t++){var e=A[t];if(e){if(y&&e.nodeType===1){e.sizcache=v;e.sizset=t}e=e[r];var u=false;while(e){if(e.sizcache===v){u=A[e.sizset];break}if(e.nodeType===1&&!z){e.sizcache=v;e.sizset=t}if(e.nodeName===w){u=e;break}e=e[r]}A[t]=u}}}function q(r,w,v,A,x,z){var y=r=="previousSibling"&&!z;for(var t=0,s=A.length;t<s;t++){var e=A[t];if(e){if(y&&e.nodeType===1){e.sizcache=v;e.sizset=t}e=e[r];var u=false;while(e){if(e.sizcache===v){u=A[e.sizset];break}if(e.nodeType===1){if(!z){e.sizcache=v;e.sizset=t}if(typeof w!=="string"){if(e===w){u=true;break}}else{if(b.filter(w,[e]).length>0){u=e;break}}}e=e[r]}A[t]=u}}}var h=document.compareDocumentPosition?function(r,e){return r.compareDocumentPosition(e)&16}:function(r,e){return r!==e&&(r.contains?r.contains(e):true)};var o=function(e){return e.nodeType===9&&e.documentElement.nodeName!=="HTML"||!!e.ownerDocument&&e.ownerDocument.documentElement.nodeName!=="HTML"};var g=function(e,x){var t=[],u="",v,s=x.nodeType?[x]:x;while((v=f.match.PSEUDO.exec(e))){u+=v[0];e=e.replace(f.match.PSEUDO,"")}e=f.relative[e]?e+"*":e;for(var w=0,r=s.length;w<r;w++){b(e,s[w],t)}return b.filter(u,t)};window.tinymce.dom.Sizzle=b})();(function(d){var f=d.each,c=d.DOM,b=d.isIE,e=d.isWebKit,a;d.create("static tinymce.dom.Event",{inits:[],events:[],add:function(m,p,l,j){var g,h=this,i=h.events,k;if(m&&m.hasOwnProperty&&m instanceof Array){k=[];f(m,function(n){n=c.get(n);k.push(h.add(n,p,l,j))});return k}m=c.get(m);if(!m){return}g=function(n){n=n||window.event;if(n&&!n.target&&b){n.target=n.srcElement}if(!j){return l(n)}return l.call(j,n)};if(p=="unload"){d.unloads.unshift({func:g});return g}if(p=="init"){if(h.domLoaded){g()}else{h.inits.push(g)}return g}i.push({obj:m,name:p,func:l,cfunc:g,scope:j});h._add(m,p,g);return l},remove:function(l,m,k){var h=this,g=h.events,i=false,j;if(l&&l.hasOwnProperty&&l instanceof Array){j=[];f(l,function(n){n=c.get(n);j.push(h.remove(n,m,k))});return j}l=c.get(l);f(g,function(o,n){if(o.obj==l&&o.name==m&&(!k||(o.func==k||o.cfunc==k))){g.splice(n,1);h._remove(l,m,o.cfunc);i=true;return false}});return i},clear:function(l){var j=this,g=j.events,h,k;if(l){l=c.get(l);for(h=g.length-1;h>=0;h--){k=g[h];if(k.obj===l){j._remove(k.obj,k.name,k.cfunc);k.obj=k.cfunc=null;g.splice(h,1)}}}},cancel:function(g){if(!g){return false}this.stop(g);return this.prevent(g)},stop:function(g){if(g.stopPropagation){g.stopPropagation()}else{g.cancelBubble=true}return false},prevent:function(g){if(g.preventDefault){g.preventDefault()}else{g.returnValue=false}return false},_unload:function(){var g=a;f(g.events,function(j,h){g._remove(j.obj,j.name,j.cfunc);j.obj=j.cfunc=null});g.events=[];g=null},_add:function(h,i,g){if(h.attachEvent){h.attachEvent("on"+i,g)}else{if(h.addEventListener){h.addEventListener(i,g,false)}else{h["on"+i]=g}}},_remove:function(i,j,h){if(i){try{if(i.detachEvent){i.detachEvent("on"+j,h)}else{if(i.removeEventListener){i.removeEventListener(j,h,false)}else{i["on"+j]=null}}}catch(g){}}},_pageInit:function(){var g=a;if(g.domLoaded){return}g._remove(window,"DOMContentLoaded",g._pageInit);g.domLoaded=true;f(g.inits,function(h){h()});g.inits=[]},_wait:function(){if(window.tinyMCE_GZ&&tinyMCE_GZ.loaded){a.domLoaded=1;return}if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);a._pageInit()}});if(document.documentElement.doScroll&&window==window.top){(function(){if(a.domLoaded){return}try{document.documentElement.doScroll("left")}catch(g){setTimeout(arguments.callee,0);return}a._pageInit()})()}}else{if(document.addEventListener){a._add(window,"DOMContentLoaded",a._pageInit,a)}}a._add(window,"load",a._pageInit,a)}});a=d.dom.Event;a._wait();d.addUnload(a._unload)})(tinymce);(function(a){var b=a.each;a.create("tinymce.dom.Element",{Element:function(g,e){var c=this,f,d;e=e||{};c.id=g;c.dom=f=e.dom||a.DOM;c.settings=e;if(!a.isIE){d=c.dom.get(c.id)}b(["getPos","getRect","getParent","add","setStyle","getStyle","setStyles","setAttrib","setAttribs","getAttrib","addClass","removeClass","hasClass","getOuterHTML","setOuterHTML","remove","show","hide","isHidden","setHTML","get"],function(h){c[h]=function(){var j=[g],k;for(k=0;k<arguments.length;k++){j.push(arguments[k])}j=f[h].apply(f,j);c.update(h);return j}})},on:function(e,d,c){return a.dom.Event.add(this.id,e,d,c)},getXY:function(){return{x:parseInt(this.getStyle("left")),y:parseInt(this.getStyle("top"))}},getSize:function(){var c=this.dom.get(this.id);return{w:parseInt(this.getStyle("width")||c.clientWidth),h:parseInt(this.getStyle("height")||c.clientHeight)}},moveTo:function(c,d){this.setStyles({left:c,top:d})},moveBy:function(c,e){var d=this.getXY();this.moveTo(d.x+c,d.y+e)},resizeTo:function(c,d){this.setStyles({width:c,height:d})},resizeBy:function(c,e){var d=this.getSize();this.resizeTo(d.w+c,d.h+e)},update:function(d){var e=this,c,f=e.dom;if(a.isIE6&&e.settings.blocker){d=d||"";if(d.indexOf("get")===0||d.indexOf("has")===0||d.indexOf("is")===0){return}if(d=="remove"){f.remove(e.blocker);return}if(!e.blocker){e.blocker=f.uniqueId();c=f.add(e.settings.container||f.getRoot(),"iframe",{id:e.blocker,style:"position:absolute;",frameBorder:0,src:'javascript:""'});f.setStyle(c,"opacity",0)}else{c=f.get(e.blocker)}f.setStyle(c,"left",e.getStyle("left",1));f.setStyle(c,"top",e.getStyle("top",1));f.setStyle(c,"width",e.getStyle("width",1));f.setStyle(c,"height",e.getStyle("height",1));f.setStyle(c,"display",e.getStyle("display",1));f.setStyle(c,"zIndex",parseInt(e.getStyle("zIndex",1)||0)-1)}}})})(tinymce);(function(c){function e(f){return f.replace(/[\n\r]+/g,"")}var b=c.is,a=c.isIE,d=c.each;c.create("tinymce.dom.Selection",{Selection:function(i,h,g){var f=this;f.dom=i;f.win=h;f.serializer=g;d(["onBeforeSetContent","onBeforeGetContent","onSetContent","onGetContent"],function(j){f[j]=new c.util.Dispatcher(f)});if(!f.win.getSelection){f.tridentSel=new c.dom.TridentSelection(f)}c.addUnload(f.destroy,f)},getContent:function(g){var f=this,h=f.getRng(),l=f.dom.create("body"),j=f.getSel(),i,k,m;g=g||{};i=k="";g.get=true;g.format=g.format||"html";f.onBeforeGetContent.dispatch(f,g);if(g.format=="text"){return f.isCollapsed()?"":(h.text||(j.toString?j.toString():""))}if(h.cloneContents){m=h.cloneContents();if(m){l.appendChild(m)}}else{if(b(h.item)||b(h.htmlText)){l.innerHTML=h.item?h.item(0).outerHTML:h.htmlText}else{l.innerHTML=h.toString()}}if(/^\s/.test(l.innerHTML)){i=" "}if(/\s+$/.test(l.innerHTML)){k=" "}g.getInner=true;g.content=f.isCollapsed()?"":i+f.serializer.serialize(l,g)+k;f.onGetContent.dispatch(f,g);return g.content},setContent:function(i,g){var f=this,j=f.getRng(),l,k=f.win.document;g=g||{format:"html"};g.set=true;i=g.content=f.dom.processHTML(i);f.onBeforeSetContent.dispatch(f,g);i=g.content;if(j.insertNode){i+='<span id="__caret">_</span>';j.deleteContents();j.insertNode(f.getRng().createContextualFragment(i));l=f.dom.get("__caret");j=k.createRange();j.setStartBefore(l);j.setEndAfter(l);f.setRng(j);f.dom.remove("__caret")}else{if(j.item){k.execCommand("Delete",false,null);j=f.getRng()}j.pasteHTML(i)}f.onSetContent.dispatch(f,g)},getStart:function(){var f=this,g=f.getRng(),h;if(a){if(g.item){return g.item(0)}g=g.duplicate();g.collapse(1);h=g.parentElement();if(h&&h.nodeName=="BODY"){return h.firstChild}return h}else{h=g.startContainer;if(h.nodeName=="BODY"){return h.firstChild}return f.dom.getParent(h,"*")}},getEnd:function(){var f=this,g=f.getRng(),h;if(a){if(g.item){return g.item(0)}g=g.duplicate();g.collapse(0);h=g.parentElement();if(h&&h.nodeName=="BODY"){return h.lastChild}return h}else{h=g.endContainer;if(h.nodeName=="BODY"){return h.lastChild}return f.dom.getParent(h,"*")}},getBookmark:function(x){var j=this,m=j.getRng(),f,n,l,u=j.dom.getViewPort(j.win),v,p,z,o,w=-16777215,k,h=j.dom.getRoot(),g=0,i=0,y;n=u.x;l=u.y;if(x=="simple"){return{rng:m,scrollX:n,scrollY:l}}if(a){if(m.item){v=m.item(0);d(j.dom.select(v.nodeName),function(s,r){if(v==s){p=r;return false}});return{tag:v.nodeName,index:p,scrollX:n,scrollY:l}}f=j.dom.doc.body.createTextRange();f.moveToElementText(h);f.collapse(true);z=Math.abs(f.move("character",w));f=m.duplicate();f.collapse(true);p=Math.abs(f.move("character",w));f=m.duplicate();f.collapse(false);o=Math.abs(f.move("character",w))-p;return{start:p-z,length:o,scrollX:n,scrollY:l}}v=j.getNode();k=j.getSel();if(!k){return null}if(v&&v.nodeName=="IMG"){return{scrollX:n,scrollY:l}}function q(A,D,t){var s=j.dom.doc.createTreeWalker(A,NodeFilter.SHOW_TEXT,null,false),E,B=0,C={};while((E=s.nextNode())!=null){if(E==D){C.start=B}if(E==t){C.end=B;return C}B+=e(E.nodeValue||"").length}return null}if(k.anchorNode==k.focusNode&&k.anchorOffset==k.focusOffset){v=q(h,k.anchorNode,k.focusNode);if(!v){return{scrollX:n,scrollY:l}}e(k.anchorNode.nodeValue||"").replace(/^\s+/,function(r){g=r.length});return{start:Math.max(v.start+k.anchorOffset-g,0),end:Math.max(v.end+k.focusOffset-g,0),scrollX:n,scrollY:l,beg:k.anchorOffset-g==0}}else{v=q(h,m.startContainer,m.endContainer);if(!v){return{scrollX:n,scrollY:l}}return{start:Math.max(v.start+m.startOffset-g,0),end:Math.max(v.end+m.endOffset-i,0),scrollX:n,scrollY:l,beg:m.startOffset-g==0}}},moveToBookmark:function(n){var o=this,g=o.getRng(),p=o.getSel(),j=o.dom.getRoot(),m,h,k;function i(q,t,D){var B=o.dom.doc.createTreeWalker(q,NodeFilter.SHOW_TEXT,null,false),x,s=0,A={},u,C,z,y;while((x=B.nextNode())!=null){z=y=0;k=x.nodeValue||"";h=e(k).length;s+=h;if(s>=t&&!A.startNode){u=t-(s-h);if(n.beg&&u>=h){continue}A.startNode=x;A.startOffset=u+y}if(s>=D){A.endNode=x;A.endOffset=D-(s-h)+y;return A}}return null}if(!n){return false}o.win.scrollTo(n.scrollX,n.scrollY);if(a){if(g=n.rng){try{g.select()}catch(l){}return true}o.win.focus();if(n.tag){g=j.createControlRange();d(o.dom.select(n.tag),function(r,q){if(q==n.index){g.addElement(r)}})}else{try{if(n.start<0){return true}g=p.createRange();g.moveToElementText(j);g.collapse(true);g.moveStart("character",n.start);g.moveEnd("character",n.length)}catch(f){return true}}try{g.select()}catch(l){}return true}if(!p){return false}if(n.rng){p.removeAllRanges();p.addRange(n.rng)}else{if(b(n.start)&&b(n.end)){try{m=i(j,n.start,n.end);if(m){g=o.dom.doc.createRange();g.setStart(m.startNode,m.startOffset);g.setEnd(m.endNode,m.endOffset);p.removeAllRanges();p.addRange(g)}if(!c.isOpera){o.win.focus()}}catch(l){}}}},select:function(g,l){var p=this,f=p.getRng(),q=p.getSel(),o,m,k,j=p.win.document;function h(u,t){var s,r;if(u){s=j.createTreeWalker(u,NodeFilter.SHOW_TEXT,null,false);while(u=s.nextNode()){r=u;if(c.trim(u.nodeValue).length!=0){if(t){return u}else{r=u}}}}return r}if(a){try{o=j.body;if(/^(IMG|TABLE)$/.test(g.nodeName)){f=o.createControlRange();f.addElement(g)}else{f=o.createTextRange();f.moveToElementText(g)}f.select()}catch(i){}}else{if(l){m=h(g,1)||p.dom.select("br:first",g)[0];k=h(g,0)||p.dom.select("br:last",g)[0];if(m&&k){f=j.createRange();if(m.nodeName=="BR"){f.setStartBefore(m)}else{f.setStart(m,0)}if(k.nodeName=="BR"){f.setEndBefore(k)}else{f.setEnd(k,k.nodeValue.length)}}else{f.selectNode(g)}}else{f.selectNode(g)}p.setRng(f)}return g},isCollapsed:function(){var f=this,h=f.getRng(),g=f.getSel();if(!h||h.item){return false}return !g||h.boundingWidth==0||h.collapsed},collapse:function(f){var g=this,h=g.getRng(),i;if(h.item){i=h.item(0);h=this.win.document.body.createTextRange();h.moveToElementText(i)}h.collapse(!!f);g.setRng(h)},getSel:function(){var g=this,f=this.win;return f.getSelection?f.getSelection():f.document.selection},getRng:function(j){var g=this,h,i;if(j&&g.tridentSel){return g.tridentSel.getRangeAt(0)}try{if(h=g.getSel()){i=h.rangeCount>0?h.getRangeAt(0):(h.createRange?h.createRange():g.win.document.createRange())}}catch(f){}if(!i){i=a?g.win.document.body.createTextRange():g.win.document.createRange()}return i},setRng:function(i){var h,g=this;if(!g.tridentSel){h=g.getSel();if(h){h.removeAllRanges();h.addRange(i)}}else{if(i.cloneRange){g.tridentSel.addRange(i);return}try{i.select()}catch(f){}}},setNode:function(g){var f=this;f.setContent(f.dom.getOuterHTML(g));return g},getNode:function(){var f=this,h=f.getRng(),g=f.getSel(),i;if(!a){if(!h){return f.dom.getRoot()}i=h.commonAncestorContainer;if(!h.collapsed){if(c.isWebKit&&g.anchorNode&&g.anchorNode.nodeType==1){return g.anchorNode.childNodes[g.anchorOffset]}if(h.startContainer==h.endContainer){if(h.startOffset-h.endOffset<2){if(h.startContainer.hasChildNodes()){i=h.startContainer.childNodes[h.startOffset]}}}}return f.dom.getParent(i,"*")}return h.item?h.item(0):h.parentElement()},getSelectedBlocks:function(g,f){var i=this,j=i.dom,m,h,l,k=[];m=j.getParent(g||i.getStart(),j.isBlock);h=j.getParent(f||i.getEnd(),j.isBlock);if(m){k.push(m)}if(m&&h&&m!=h){l=m;while((l=l.nextSibling)&&l!=h){if(j.isBlock(l)){k.push(l)}}}if(h&&m!=h){k.push(h)}return k},destroy:function(g){var f=this;f.win=null;if(f.tridentSel){f.tridentSel.destroy()}if(!g){c.removeUnload(f.destroy)}}})})(tinymce);(function(a){a.create("tinymce.dom.XMLWriter",{node:null,XMLWriter:function(c){function b(){var e=document.implementation;if(!e||!e.createDocument){try{return new ActiveXObject("MSXML2.DOMDocument")}catch(d){}try{return new ActiveXObject("Microsoft.XmlDom")}catch(d){}}else{return e.createDocument("","",null)}}this.doc=b();this.valid=a.isOpera||a.isWebKit;this.reset()},reset:function(){var b=this,c=b.doc;if(c.firstChild){c.removeChild(c.firstChild)}b.node=c.appendChild(c.createElement("html"))},writeStartElement:function(c){var b=this;b.node=b.node.appendChild(b.doc.createElement(c))},writeAttribute:function(c,b){if(this.valid){b=b.replace(/>/g,"%MCGT%")}this.node.setAttribute(c,b)},writeEndElement:function(){this.node=this.node.parentNode},writeFullEndElement:function(){var b=this,c=b.node;c.appendChild(b.doc.createTextNode(""));b.node=c.parentNode},writeText:function(b){if(this.valid){b=b.replace(/>/g,"%MCGT%")}this.node.appendChild(this.doc.createTextNode(b))},writeCDATA:function(b){this.node.appendChild(this.doc.createCDATA(b))},writeComment:function(b){if(a.isIE){b=b.replace(/^\-|\-$/g," ")}this.node.appendChild(this.doc.createComment(b.replace(/\-\-/g," ")))},getContent:function(){var b;b=this.doc.xml||new XMLSerializer().serializeToString(this.doc);b=b.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g,"");b=b.replace(/ ?\/>/g," />");if(this.valid){b=b.replace(/\%MCGT%/g,"&gt;")}return b}})})(tinymce);(function(a){a.create("tinymce.dom.StringWriter",{str:null,tags:null,count:0,settings:null,indent:null,StringWriter:function(b){this.settings=a.extend({indent_char:" ",indentation:1},b);this.reset()},reset:function(){this.indent="";this.str="";this.tags=[];this.count=0},writeStartElement:function(b){this._writeAttributesEnd();this.writeRaw("<"+b);this.tags.push(b);this.inAttr=true;this.count++;this.elementCount=this.count},writeAttribute:function(d,b){var c=this;c.writeRaw(" "+c.encode(d)+'="'+c.encode(b)+'"')},writeEndElement:function(){var b;if(this.tags.length>0){b=this.tags.pop();if(this._writeAttributesEnd(1)){this.writeRaw("</"+b+">")}if(this.settings.indentation>0){this.writeRaw("\n")}}},writeFullEndElement:function(){if(this.tags.length>0){this._writeAttributesEnd();this.writeRaw("</"+this.tags.pop()+">");if(this.settings.indentation>0){this.writeRaw("\n")}}},writeText:function(b){this._writeAttributesEnd();this.writeRaw(this.encode(b));this.count++},writeCDATA:function(b){this._writeAttributesEnd();this.writeRaw("<![CDATA["+b+"]]>");this.count++},writeComment:function(b){this._writeAttributesEnd();this.writeRaw("<!-- "+b+"-->");this.count++},writeRaw:function(b){this.str+=b},encode:function(b){return b.replace(/[<>&"]/g,function(c){switch(c){case"<":return"&lt;";case">":return"&gt;";case"&":return"&amp;";case'"':return"&quot;"}return c})},getContent:function(){return this.str},_writeAttributesEnd:function(b){if(!this.inAttr){return}this.inAttr=false;if(b&&this.elementCount==this.count){this.writeRaw(" />");return false}this.writeRaw(">");return true}})})(tinymce);(function(e){var g=e.extend,f=e.each,b=e.util.Dispatcher,d=e.isIE,a=e.isGecko;function c(h){return h.replace(/([?+*])/g,".$1")}e.create("tinymce.dom.Serializer",{Serializer:function(j){var i=this;i.key=0;i.onPreProcess=new b(i);i.onPostProcess=new b(i);try{i.writer=new e.dom.XMLWriter()}catch(h){i.writer=new e.dom.StringWriter()}i.settings=j=g({dom:e.DOM,valid_nodes:0,node_filter:0,attr_filter:0,invalid_attrs:/^(mce_|_moz_)/,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",bool_attrs:/(checked|disabled|readonly|selected|nowrap)/,valid_elements:"*[*]",extended_valid_elements:0,valid_child_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,font_size_style_values:0,apply_source_formatting:0,indent_mode:"simple",indent_char:"\t",indent_levels:1,remove_linebreaks:1,remove_redundant_brs:1,element_format:"xhtml"},j);i.dom=j.dom;if(j.remove_redundant_brs){i.onPostProcess.add(function(k,l){l.content=l.content.replace(/(<br \/>\s*)+<\/(p|h[1-6]|div|li)>/gi,function(n,m,o){if(/^<br \/>\s*<\//.test(n)){return"</"+o+">"}return n})})}if(j.element_format=="html"){i.onPostProcess.add(function(k,l){l.content=l.content.replace(/<([^>]+) \/>/g,"<$1>")})}if(j.fix_list_elements){i.onPreProcess.add(function(v,s){var l,y,w=["ol","ul"],u,t,q,k=/^(OL|UL)$/,z;function m(r,x){var o=x.split(","),p;while((r=r.previousSibling)!=null){for(p=0;p<o.length;p++){if(r.nodeName==o[p]){return r}}}return null}for(y=0;y<w.length;y++){l=i.dom.select(w[y],s.node);for(u=0;u<l.length;u++){t=l[u];q=t.parentNode;if(k.test(q.nodeName)){z=m(t,"LI");if(!z){z=i.dom.create("li");z.innerHTML="&nbsp;";z.appendChild(t);q.insertBefore(z,q.firstChild)}else{z.appendChild(t)}}}}})}if(j.fix_table_elements){i.onPreProcess.add(function(k,l){f(i.dom.select("p table",l.node),function(m){i.dom.split(i.dom.getParent(m,"p"),m)})})}},setEntities:function(p){var n=this,j,m,h={},o="",k;if(n.entityLookup){return}j=p.split(",");for(m=0;m<j.length;m+=2){k=j[m];if(k==34||k==38||k==60||k==62){continue}h[String.fromCharCode(j[m])]=j[m+1];k=parseInt(j[m]).toString(16);o+="\\u"+"0000".substring(k.length)+k}if(!o){n.settings.entity_encoding="raw";return}n.entitiesRE=new RegExp("["+o+"]","g");n.entityLookup=h},setValidChildRules:function(h){this.childRules=null;this.addValidChildRules(h)},addValidChildRules:function(k){var j=this,l,h,i;if(!k){return}l="A|BR|SPAN|BDO|MAP|OBJECT|IMG|TT|I|B|BIG|SMALL|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|#text|#comment";h="A|BR|SPAN|BDO|OBJECT|APPLET|IMG|MAP|IFRAME|TT|I|B|U|S|STRIKE|BIG|SMALL|FONT|BASEFONT|EM|STRONG|DFN|CODE|Q|SAMP|KBD|VAR|CITE|ABBR|ACRONYM|SUB|SUP|INPUT|SELECT|TEXTAREA|LABEL|BUTTON|#text|#comment";i="H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP";f(k.split(","),function(n){var o=n.split(/\[|\]/),m;n="";f(o[1].split("|"),function(p){if(n){n+="|"}switch(p){case"%itrans":p=h;break;case"%itrans_na":p=h.substring(2);break;case"%istrict":p=l;break;case"%istrict_na":p=l.substring(2);break;case"%btrans":p=i;break;case"%bstrict":p=i;break}n+=p});m=new RegExp("^("+n.toLowerCase()+")$","i");f(o[0].split("/"),function(p){j.childRules=j.childRules||{};j.childRules[p]=m})});k="";f(j.childRules,function(n,m){if(k){k+="|"}k+=m});j.parentElementsRE=new RegExp("^("+k.toLowerCase()+")$","i")},setRules:function(i){var h=this;h._setup();h.rules={};h.wildRules=[];h.validElements={};return h.addRules(i)},addRules:function(i){var h=this,j;if(!i){return}h._setup();f(i.split(","),function(m){var q=m.split(/\[|\]/),l=q[0].split("/"),r,k,o,n=[];if(j){k=e.extend([],j.attribs)}if(q.length>1){f(q[1].split("|"),function(u){var p={},t;k=k||[];u=u.replace(/::/g,"~");u=/^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(u);u[2]=u[2].replace(/~/g,":");if(u[1]=="!"){r=r||[];r.push(u[2])}if(u[1]=="-"){for(t=0;t<k.length;t++){if(k[t].name==u[2]){k.splice(t,1);return}}}switch(u[3]){case"=":p.defaultVal=u[4]||"";break;case":":p.forcedVal=u[4];break;case"<":p.validVals=u[4].split("?");break}if(/[*.?]/.test(u[2])){o=o||[];p.nameRE=new RegExp("^"+c(u[2])+"$");o.push(p)}else{p.name=u[2];k.push(p)}n.push(u[2])})}f(l,function(v,u){var w=v.charAt(0),t=1,p={};if(j){if(j.noEmpty){p.noEmpty=j.noEmpty}if(j.fullEnd){p.fullEnd=j.fullEnd}if(j.padd){p.padd=j.padd}}switch(w){case"-":p.noEmpty=true;break;case"+":p.fullEnd=true;break;case"#":p.padd=true;break;default:t=0}l[u]=v=v.substring(t);h.validElements[v]=1;if(/[*.?]/.test(l[0])){p.nameRE=new RegExp("^"+c(l[0])+"$");h.wildRules=h.wildRules||{};h.wildRules.push(p)}else{p.name=l[0];if(l[0]=="@"){j=p}h.rules[v]=p}p.attribs=k;if(r){p.requiredAttribs=r}if(o){v="";f(n,function(s){if(v){v+="|"}v+="("+c(s)+")"});p.validAttribsRE=new RegExp("^"+v.toLowerCase()+"$");p.wildAttribs=o}})});i="";f(h.validElements,function(m,l){if(i){i+="|"}if(l!="@"){i+=l}});h.validElementsRE=new RegExp("^("+c(i.toLowerCase())+")$")},findRule:function(m){var j=this,l=j.rules,h,k;j._setup();k=l[m];if(k){return k}l=j.wildRules;for(h=0;h<l.length;h++){if(l[h].nameRE.test(m)){return l[h]}}return null},findAttribRule:function(h,l){var j,k=h.wildAttribs;for(j=0;j<k.length;j++){if(k[j].nameRE.test(l)){return k[j]}}return null},serialize:function(l,k){var j,i=this;i._setup();k=k||{};k.format=k.format||"html";i.processObj=k;l=l.cloneNode(true);i.key=""+(parseInt(i.key)+1);if(!k.no_events){k.node=l;i.onPreProcess.dispatch(i,k)}i.writer.reset();i._serializeNode(l,k.getInner);k.content=i.writer.getContent();if(!k.no_events){i.onPostProcess.dispatch(i,k)}i._postProcess(k);k.node=null;return e.trim(k.content)},_postProcess:function(n){var i=this,k=i.settings,j=n.content,m=[],l;if(n.format=="html"){l=i._protect({content:j,patterns:[{pattern:/(<script[^>]*>)(.*?)(<\/script>)/g},{pattern:/(<style[^>]*>)(.*?)(<\/style>)/g},{pattern:/(<pre[^>]*>)(.*?)(<\/pre>)/g,encode:1},{pattern:/(<!--\[CDATA\[)(.*?)(\]\]-->)/g}]});j=l.content;if(k.entity_encoding!=="raw"){j=i._encode(j)}if(!n.set){j=j.replace(/<p>\s+<\/p>|<p([^>]+)>\s+<\/p>/g,k.entity_encoding=="numeric"?"<p$1>&#160;</p>":"<p$1>&nbsp;</p>");if(k.remove_linebreaks){j=j.replace(/\r?\n|\r/g," ");j=j.replace(/(<[^>]+>)\s+/g,"$1 ");j=j.replace(/\s+(<\/[^>]+>)/g," $1");j=j.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>");j=j.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>");j=j.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(k.apply_source_formatting&&k.indent_mode=="simple"){j=j.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g,"\n<$1$2$3>\n");j=j.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g,"\n<$1$2>");j=j.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g,"</$1>\n");j=j.replace(/\n\n/g,"\n")}}j=i._unprotect(j,l);j=j.replace(/<!--\[CDATA\[([\s\S]+)\]\]-->/g,"<![CDATA[$1]]>");if(k.entity_encoding=="raw"){j=j.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g,"<p$1>\u00a0</p>")}}n.content=j},_serializeNode:function(C,m){var y=this,z=y.settings,u=y.writer,p,j,r,E,D,F,A,h,x,k,q,B,o;if(!z.node_filter||z.node_filter(C)){switch(C.nodeType){case 1:if(C.hasAttribute?C.hasAttribute("mce_bogus"):C.getAttribute("mce_bogus")){return}o=false;p=C.hasChildNodes();k=C.getAttribute("mce_name")||C.nodeName.toLowerCase();if(d){if(C.scopeName!=="HTML"&&C.scopeName!=="html"){k=C.scopeName+":"+k}}if(k.indexOf("mce:")===0){k=k.substring(4)}if(!y.validElementsRE.test(k)||(y.invalidElementsRE&&y.invalidElementsRE.test(k))||m){o=true;break}if(d){if(z.fix_content_duplication){if(C.mce_serialized==y.key){return}C.mce_serialized=y.key}if(k.charAt(0)=="/"){k=k.substring(1)}}else{if(a){if(C.nodeName==="BR"&&C.getAttribute("type")=="_moz"){return}}}if(y.childRules){if(y.parentElementsRE.test(y.elementName)){if(!y.childRules[y.elementName].test(k)){o=true;break}}y.elementName=k}q=y.findRule(k);k=q.name||k;if((!p&&q.noEmpty)||(d&&!k)){o=true;break}if(q.requiredAttribs){F=q.requiredAttribs;for(E=F.length-1;E>=0;E--){if(this.dom.getAttrib(C,F[E])!==""){break}}if(E==-1){o=true;break}}u.writeStartElement(k);if(q.attribs){for(E=0,A=q.attribs,D=A.length;E<D;E++){F=A[E];x=y._getAttrib(C,F);if(x!==null){u.writeAttribute(F.name,x)}}}if(q.validAttribsRE){A=y.dom.getAttribs(C);for(E=A.length-1;E>-1;E--){h=A[E];if(h.specified){F=h.nodeName.toLowerCase();if(z.invalid_attrs.test(F)||!q.validAttribsRE.test(F)){continue}B=y.findAttribRule(q,F);x=y._getAttrib(C,B,F);if(x!==null){u.writeAttribute(F,x)}}}}if(q.padd){if(p&&(r=C.firstChild)&&r.nodeType===1&&C.childNodes.length===1){if(r.hasAttribute?r.hasAttribute("mce_bogus"):r.getAttribute("mce_bogus")){u.writeText("\u00a0")}}else{if(!p){u.writeText("\u00a0")}}}break;case 3:if(y.childRules&&y.parentElementsRE.test(y.elementName)){if(!y.childRules[y.elementName].test(C.nodeName)){return}}return u.writeText(C.nodeValue);case 4:return u.writeCDATA(C.nodeValue);case 8:return u.writeComment(C.nodeValue)}}else{if(C.nodeType==1){p=C.hasChildNodes()}}if(p){r=C.firstChild;while(r){y._serializeNode(r);y.elementName=k;r=r.nextSibling}}if(!o){if(p||!z.closed.test(k)){u.writeFullEndElement()}else{u.writeEndElement()}}},_protect:function(j){var i=this;j.items=j.items||[];function h(l){return l.replace(/[\r\n\\]/g,function(m){if(m==="\n"){return"\\n"}else{if(m==="\\"){return"\\\\"}}return"\\r"})}function k(l){return l.replace(/\\[\\rn]/g,function(m){if(m==="\\n"){return"\n"}else{if(m==="\\\\"){return"\\"}}return"\r"})}f(j.patterns,function(l){j.content=k(h(j.content).replace(l.pattern,function(n,o,m,p){m=k(m);if(l.encode){m=i._encode(m)}j.items.push(m);return o+"<!--mce:"+(j.items.length-1)+"-->"+p}))});return j},_unprotect:function(i,j){i=i.replace(/\<!--mce:([0-9]+)--\>/g,function(k,h){return j.items[parseInt(h)]});j.items=[];return i},_encode:function(m){var j=this,k=j.settings,i;if(k.entity_encoding!=="raw"){if(k.entity_encoding.indexOf("named")!=-1){j.setEntities(k.entities);i=j.entityLookup;m=m.replace(j.entitiesRE,function(h){var l;if(l=i[h]){h="&"+l+";"}return h})}if(k.entity_encoding.indexOf("numeric")!=-1){m=m.replace(/[\u007E-\uFFFF]/g,function(h){return"&#"+h.charCodeAt(0)+";"})}}return m},_setup:function(){var h=this,i=this.settings;if(h.done){return}h.done=1;h.setRules(i.valid_elements);h.addRules(i.extended_valid_elements);h.addValidChildRules(i.valid_child_elements);if(i.invalid_elements){h.invalidElementsRE=new RegExp("^("+c(i.invalid_elements.replace(/,/g,"|").toLowerCase())+")$")}if(i.attrib_value_filter){h.attribValueFilter=i.attribValueFilter}},_getAttrib:function(m,j,h){var l,k;h=h||j.name;if(j.forcedVal&&(k=j.forcedVal)){if(k==="{$uid}"){return this.dom.uniqueId()}return k}k=this.dom.getAttrib(m,h);if(this.settings.bool_attrs.test(h)&&k){k=(""+k).toLowerCase();if(k==="false"||k==="0"){return null}k=h}switch(h){case"rowspan":case"colspan":if(k=="1"){k=""}break}if(this.attribValueFilter){k=this.attribValueFilter(h,k,m)}if(j.validVals){for(l=j.validVals.length-1;l>=0;l--){if(k==j.validVals[l]){break}}if(l==-1){return null}}if(k===""&&typeof(j.defaultVal)!="undefined"){k=j.defaultVal;if(k==="{$uid}"){return this.dom.uniqueId()}return k}else{if(h=="class"&&this.processObj.get){k=k.replace(/\s?mceItem\w+\s?/g,"")}}if(k===""){return null}return k}})})(tinymce);(function(tinymce){var each=tinymce.each,Event=tinymce.dom.Event;tinymce.create("tinymce.dom.ScriptLoader",{ScriptLoader:function(s){this.settings=s||{};this.queue=[];this.lookup={}},isDone:function(u){return this.lookup[u]?this.lookup[u].state==2:0},markDone:function(u){this.lookup[u]={state:2,url:u}},add:function(u,cb,s,pr){var t=this,lo=t.lookup,o;if(o=lo[u]){if(cb&&o.state==2){cb.call(s||this)}return o}o={state:0,url:u,func:cb,scope:s||this};if(pr){t.queue.unshift(o)}else{t.queue.push(o)}lo[u]=o;return o},load:function(u,cb,s){var t=this,o;if(o=t.lookup[u]){if(cb&&o.state==2){cb.call(s||t)}return o}function loadScript(u){if(Event.domLoaded||t.settings.strict_mode){tinymce.util.XHR.send({url:tinymce._addVer(u),error:t.settings.error,async:false,success:function(co){t.eval(co)}})}else{document.write('<script type="text/javascript" src="'+tinymce._addVer(u)+'"><\/script>')}}if(!tinymce.is(u,"string")){each(u,function(u){loadScript(u)});if(cb){cb.call(s||t)}}else{loadScript(u);if(cb){cb.call(s||t)}}},loadQueue:function(cb,s){var t=this;if(!t.queueLoading){t.queueLoading=1;t.queueCallbacks=[];t.loadScripts(t.queue,function(){t.queueLoading=0;if(cb){cb.call(s||t)}each(t.queueCallbacks,function(o){o.func.call(o.scope)})})}else{if(cb){t.queueCallbacks.push({func:cb,scope:s||t})}}},eval:function(co){var w=window;if(!w.execScript){try{eval.call(w,co)}catch(ex){eval(co,w)}}else{w.execScript(co)}},loadScripts:function(sc,cb,s){var t=this,lo=t.lookup;function done(o){o.state=2;if(o.func){o.func.call(o.scope||t)}}function allDone(){var l;l=sc.length;each(sc,function(o){o=lo[o.url];if(o.state===2){done(o);l--}else{load(o)}});if(l===0&&cb){cb.call(s||t);cb=0}}function load(o){if(o.state>0){return}o.state=1;tinymce.dom.ScriptLoader.loadScript(o.url,function(){done(o);allDone()})}each(sc,function(o){var u=o.url;if(!lo[u]){lo[u]=o;t.queue.push(o)}else{o=lo[u]}if(o.state>0){return}if(!Event.domLoaded&&!t.settings.strict_mode){var ix,ol="";if(cb||o.func){o.state=1;ix=tinymce.dom.ScriptLoader._addOnLoad(function(){done(o);allDone()});if(tinymce.isIE){ol=' onreadystatechange="'}else{ol=' onload="'}ol+="tinymce.dom.ScriptLoader._onLoad(this,'"+u+"',"+ix+');"'}document.write('<script type="text/javascript" src="'+tinymce._addVer(u)+'"'+ol+"><\/script>");if(!o.func){done(o)}}else{load(o)}});allDone()},"static":{_addOnLoad:function(f){var t=this;t._funcs=t._funcs||[];t._funcs.push(f);return t._funcs.length-1},_onLoad:function(e,u,ix){if(!tinymce.isIE||e.readyState=="complete"){this._funcs[ix].call(this)}},loadScript:function(u,cb){var id=tinymce.DOM.uniqueId(),e;function done(){Event.clear(id);tinymce.DOM.remove(id);if(cb){cb.call(document,u);cb=0}}if(tinymce.isIE){tinymce.util.XHR.send({url:tinymce._addVer(u),async:false,success:function(co){window.execScript(co);done()}})}else{e=tinymce.DOM.create("script",{id:id,type:"text/javascript",src:tinymce._addVer(u)});Event.add(e,"load",done);(document.getElementsByTagName("head")[0]||document.body).appendChild(e)}}}});tinymce.ScriptLoader=new tinymce.dom.ScriptLoader()})(tinymce);(function(c){var b=c.DOM,a=c.is;c.create("tinymce.ui.Control",{Control:function(e,d){this.id=e;this.settings=d=d||{};this.rendered=false;this.onRender=new c.util.Dispatcher(this);this.classPrefix="";this.scope=d.scope||this;this.disabled=0;this.active=0},setDisabled:function(d){var f;if(d!=this.disabled){f=b.get(this.id);if(f&&this.settings.unavailable_prefix){if(d){this.prevTitle=f.title;f.title=this.settings.unavailable_prefix+": "+f.title}else{f.title=this.prevTitle}}this.setState("Disabled",d);this.setState("Enabled",!d);this.disabled=d}},isDisabled:function(){return this.disabled},setActive:function(d){if(d!=this.active){this.setState("Active",d);this.active=d}},isActive:function(){return this.active},setState:function(f,d){var e=b.get(this.id);f=this.classPrefix+f;if(d){b.addClass(e,f)}else{b.removeClass(e,f)}},isRendered:function(){return this.rendered},renderHTML:function(){},renderTo:function(d){b.setHTML(d,this.renderHTML())},postRender:function(){var e=this,d;if(a(e.disabled)){d=e.disabled;e.disabled=-1;e.setDisabled(d)}if(a(e.active)){d=e.active;e.active=-1;e.setActive(d)}},remove:function(){b.remove(this.id);this.destroy()},destroy:function(){c.dom.Event.clear(this.id)}})})(tinymce);tinymce.create("tinymce.ui.Container:tinymce.ui.Control",{Container:function(b,a){this.parent(b,a);this.controls=[];this.lookup={}},add:function(a){this.lookup[a.id]=a;this.controls.push(a);return a},get:function(a){return this.lookup[a]}});tinymce.create("tinymce.ui.Separator:tinymce.ui.Control",{Separator:function(b,a){this.parent(b,a);this.classPrefix="mceSeparator"},renderHTML:function(){return tinymce.DOM.createHTML("span",{"class":this.classPrefix})}});(function(d){var c=d.is,b=d.DOM,e=d.each,a=d.walk;d.create("tinymce.ui.MenuItem:tinymce.ui.Control",{MenuItem:function(g,f){this.parent(g,f);this.classPrefix="mceMenuItem"},setSelected:function(f){this.setState("Selected",f);this.selected=f},isSelected:function(){return this.selected},postRender:function(){var f=this;f.parent();if(c(f.selected)){f.setSelected(f.selected)}}})})(tinymce);(function(d){var c=d.is,b=d.DOM,e=d.each,a=d.walk;d.create("tinymce.ui.Menu:tinymce.ui.MenuItem",{Menu:function(h,g){var f=this;f.parent(h,g);f.items={};f.collapsed=false;f.menuCount=0;f.onAddItem=new d.util.Dispatcher(this)},expand:function(g){var f=this;if(g){a(f,function(h){if(h.expand){h.expand()}},"items",f)}f.collapsed=false},collapse:function(g){var f=this;if(g){a(f,function(h){if(h.collapse){h.collapse()}},"items",f)}f.collapsed=true},isCollapsed:function(){return this.collapsed},add:function(f){if(!f.settings){f=new d.ui.MenuItem(f.id||b.uniqueId(),f)}this.onAddItem.dispatch(this,f);return this.items[f.id]=f},addSeparator:function(){return this.add({separator:true})},addMenu:function(f){if(!f.collapse){f=this.createMenu(f)}this.menuCount++;return this.add(f)},hasMenus:function(){return this.menuCount!==0},remove:function(f){delete this.items[f.id]},removeAll:function(){var f=this;a(f,function(g){if(g.removeAll){g.removeAll()}else{g.remove()}g.destroy()},"items",f);f.items={}},createMenu:function(g){var f=new d.ui.Menu(g.id||b.uniqueId(),g);f.onAddItem.add(this.onAddItem.dispatch,this.onAddItem);return f}})})(tinymce);(function(e){var d=e.is,c=e.DOM,f=e.each,a=e.dom.Event,b=e.dom.Element;e.create("tinymce.ui.DropMenu:tinymce.ui.Menu",{DropMenu:function(h,g){g=g||{};g.container=g.container||c.doc.body;g.offset_x=g.offset_x||0;g.offset_y=g.offset_y||0;g.vp_offset_x=g.vp_offset_x||0;g.vp_offset_y=g.vp_offset_y||0;if(d(g.icons)&&!g.icons){g["class"]+=" mceNoIcons"}this.parent(h,g);this.onShowMenu=new e.util.Dispatcher(this);this.onHideMenu=new e.util.Dispatcher(this);this.classPrefix="mceMenu"},createMenu:function(j){var h=this,i=h.settings,g;j.container=j.container||i.container;j.parent=h;j.constrain=j.constrain||i.constrain;j["class"]=j["class"]||i["class"];j.vp_offset_x=j.vp_offset_x||i.vp_offset_x;j.vp_offset_y=j.vp_offset_y||i.vp_offset_y;g=new e.ui.DropMenu(j.id||c.uniqueId(),j);g.onAddItem.add(h.onAddItem.dispatch,h.onAddItem);return g},update:function(){var i=this,j=i.settings,g=c.get("menu_"+i.id+"_tbl"),l=c.get("menu_"+i.id+"_co"),h,k;h=j.max_width?Math.min(g.clientWidth,j.max_width):g.clientWidth;k=j.max_height?Math.min(g.clientHeight,j.max_height):g.clientHeight;if(!c.boxModel){i.element.setStyles({width:h+2,height:k+2})}else{i.element.setStyles({width:h,height:k})}if(j.max_width){c.setStyle(l,"width",h)}if(j.max_height){c.setStyle(l,"height",k);if(g.clientHeight<j.max_height){c.setStyle(l,"overflow","hidden")}}},showMenu:function(p,n,r){var z=this,A=z.settings,o,g=c.getViewPort(),u,l,v,q,i=2,k,j,m=z.classPrefix;z.collapse(1);if(z.isMenuVisible){return}if(!z.rendered){o=c.add(z.settings.container,z.renderNode());f(z.items,function(h){h.postRender()});z.element=new b("menu_"+z.id,{blocker:1,container:A.container})}else{o=c.get("menu_"+z.id)}if(!e.isOpera){c.setStyles(o,{left:-65535,top:-65535})}c.show(o);z.update();p+=A.offset_x||0;n+=A.offset_y||0;g.w-=4;g.h-=4;if(A.constrain){u=o.clientWidth-i;l=o.clientHeight-i;v=g.x+g.w;q=g.y+g.h;if((p+A.vp_offset_x+u)>v){p=r?r-u:Math.max(0,(v-A.vp_offset_x)-u)}if((n+A.vp_offset_y+l)>q){n=Math.max(0,(q-A.vp_offset_y)-l)}}c.setStyles(o,{left:p,top:n});z.element.update();z.isMenuVisible=1;z.mouseClickFunc=a.add(o,"click",function(s){var h;s=s.target;if(s&&(s=c.getParent(s,"tr"))&&!c.hasClass(s,m+"ItemSub")){h=z.items[s.id];if(h.isDisabled()){return}k=z;while(k){if(k.hideMenu){k.hideMenu()}k=k.settings.parent}if(h.settings.onclick){h.settings.onclick(s)}return a.cancel(s)}});if(z.hasMenus()){z.mouseOverFunc=a.add(o,"mouseover",function(w){var h,t,s;w=w.target;if(w&&(w=c.getParent(w,"tr"))){h=z.items[w.id];if(z.lastMenu){z.lastMenu.collapse(1)}if(h.isDisabled()){return}if(w&&c.hasClass(w,m+"ItemSub")){t=c.getRect(w);h.showMenu((t.x+t.w-i),t.y-i,t.x);z.lastMenu=h;c.addClass(c.get(h.id).firstChild,m+"ItemActive")}}})}z.onShowMenu.dispatch(z);if(A.keyboard_focus){a.add(o,"keydown",z._keyHandler,z);c.select("a","menu_"+z.id)[0].focus();z._focusIdx=0}},hideMenu:function(j){var g=this,i=c.get("menu_"+g.id),h;if(!g.isMenuVisible){return}a.remove(i,"mouseover",g.mouseOverFunc);a.remove(i,"click",g.mouseClickFunc);a.remove(i,"keydown",g._keyHandler);c.hide(i);g.isMenuVisible=0;if(!j){g.collapse(1)}if(g.element){g.element.hide()}if(h=c.get(g.id)){c.removeClass(h.firstChild,g.classPrefix+"ItemActive")}g.onHideMenu.dispatch(g)},add:function(i){var g=this,h;i=g.parent(i);if(g.isRendered&&(h=c.get("menu_"+g.id))){g._add(c.select("tbody",h)[0],i)}return i},collapse:function(g){this.parent(g);this.hideMenu(1)},remove:function(g){c.remove(g.id);this.destroy();return this.parent(g)},destroy:function(){var g=this,h=c.get("menu_"+g.id);a.remove(h,"mouseover",g.mouseOverFunc);a.remove(h,"click",g.mouseClickFunc);if(g.element){g.element.remove()}c.remove(h)},renderNode:function(){var i=this,j=i.settings,l,h,k,g;g=c.create("div",{id:"menu_"+i.id,"class":j["class"],style:"position:absolute;left:0;top:0;z-index:200000"});k=c.add(g,"div",{id:"menu_"+i.id+"_co","class":i.classPrefix+(j["class"]?" "+j["class"]:"")});i.element=new b("menu_"+i.id,{blocker:1,container:j.container});if(j.menu_line){c.add(k,"span",{"class":i.classPrefix+"Line"})}l=c.add(k,"table",{id:"menu_"+i.id+"_tbl",border:0,cellPadding:0,cellSpacing:0});h=c.add(l,"tbody");f(i.items,function(m){i._add(h,m)});i.rendered=true;return g},_keyHandler:function(j){var i=this,h=j.keyCode;function g(m){var k=i._focusIdx+m,l=c.select("a","menu_"+i.id)[k];if(l){i._focusIdx=k;l.focus()}}switch(h){case 38:g(-1);return;case 40:g(1);return;case 13:return;case 27:return this.hideMenu()}},_add:function(j,h){var i,q=h.settings,p,l,k,m=this.classPrefix,g;if(q.separator){l=c.add(j,"tr",{id:h.id,"class":m+"ItemSeparator"});c.add(l,"td",{"class":m+"ItemSeparator"});if(i=l.previousSibling){c.addClass(i,"mceLast")}return}i=l=c.add(j,"tr",{id:h.id,"class":m+"Item "+m+"ItemEnabled"});i=k=c.add(i,"td");i=p=c.add(i,"a",{href:"javascript:;",onclick:"return false;",onmousedown:"return false;"});c.addClass(k,q["class"]);g=c.add(i,"span",{"class":"mceIcon"+(q.icon?" mce_"+q.icon:"")});if(q.icon_src){c.add(g,"img",{src:q.icon_src})}i=c.add(i,q.element||"span",{"class":"mceText",title:h.settings.title},h.settings.title);if(h.settings.style){c.setAttrib(i,"style",h.settings.style)}if(j.childNodes.length==1){c.addClass(l,"mceFirst")}if((i=l.previousSibling)&&c.hasClass(i,m+"ItemSeparator")){c.addClass(l,"mceFirst")}if(h.collapse){c.addClass(l,m+"ItemSub")}if(i=l.previousSibling){c.removeClass(i,"mceLast")}c.addClass(l,"mceLast")}})})(tinymce);(function(b){var a=b.DOM;b.create("tinymce.ui.Button:tinymce.ui.Control",{Button:function(d,c){this.parent(d,c);this.classPrefix="mceButton"},renderHTML:function(){var f=this.classPrefix,e=this.settings,d,c;c=a.encode(e.label||"");d='<a id="'+this.id+'" href="javascript:;" class="'+f+" "+f+"Enabled "+e["class"]+(c?" "+f+"Labeled":"")+'" onmousedown="return false;" onclick="return false;" title="'+a.encode(e.title)+'">';if(e.image){d+='<img class="mceIcon" src="'+e.image+'" />'+c+"</a>"}else{d+='<span class="mceIcon '+e["class"]+'"></span>'+(c?'<span class="'+f+'Label">'+c+"</span>":"")+"</a>"}return d},postRender:function(){var c=this,d=c.settings;b.dom.Event.add(c.id,"click",function(f){if(!c.isDisabled()){return d.onclick.call(d.scope,f)}})}})})(tinymce);(function(d){var c=d.DOM,b=d.dom.Event,e=d.each,a=d.util.Dispatcher;d.create("tinymce.ui.ListBox:tinymce.ui.Control",{ListBox:function(h,g){var f=this;f.parent(h,g);f.items=[];f.onChange=new a(f);f.onPostRender=new a(f);f.onAdd=new a(f);f.onRenderMenu=new d.util.Dispatcher(this);f.classPrefix="mceListBox"},select:function(h){var g=this,j,i;if(h==undefined){return g.selectByIndex(-1)}if(h&&h.call){i=h}else{i=function(f){return f==h}}if(h!=g.selectedValue){e(g.items,function(k,f){if(i(k.value)){j=1;g.selectByIndex(f);return false}});if(!j){g.selectByIndex(-1)}}},selectByIndex:function(f){var g=this,h,i;if(f!=g.selectedIndex){h=c.get(g.id+"_text");i=g.items[f];if(i){g.selectedValue=i.value;g.selectedIndex=f;c.setHTML(h,c.encode(i.title));c.removeClass(h,"mceTitle")}else{c.setHTML(h,c.encode(g.settings.title));c.addClass(h,"mceTitle");g.selectedValue=g.selectedIndex=null}h=0}},add:function(i,f,h){var g=this;h=h||{};h=d.extend(h,{title:i,value:f});g.items.push(h);g.onAdd.dispatch(g,h)},getLength:function(){return this.items.length},renderHTML:function(){var i="",f=this,g=f.settings,j=f.classPrefix;i='<table id="'+f.id+'" cellpadding="0" cellspacing="0" class="'+j+" "+j+"Enabled"+(g["class"]?(" "+g["class"]):"")+'"><tbody><tr>';i+="<td>"+c.createHTML("a",{id:f.id+"_text",href:"javascript:;","class":"mceText",onclick:"return false;",onmousedown:"return false;"},c.encode(f.settings.title))+"</td>";i+="<td>"+c.createHTML("a",{id:f.id+"_open",tabindex:-1,href:"javascript:;","class":"mceOpen",onclick:"return false;",onmousedown:"return false;"},"<span></span>")+"</td>";i+="</tr></tbody></table>";return i},showMenu:function(){var g=this,j,i,h=c.get(this.id),f;if(g.isDisabled()||g.items.length==0){return}if(g.menu&&g.menu.isMenuVisible){return g.hideMenu()}if(!g.isMenuRendered){g.renderMenu();g.isMenuRendered=true}j=c.getPos(this.settings.menu_container);i=c.getPos(h);f=g.menu;f.settings.offset_x=i.x;f.settings.offset_y=i.y;f.settings.keyboard_focus=!d.isOpera;if(g.oldID){f.items[g.oldID].setSelected(0)}e(g.items,function(k){if(k.value===g.selectedValue){f.items[k.id].setSelected(1);g.oldID=k.id}});f.showMenu(0,h.clientHeight);b.add(c.doc,"mousedown",g.hideMenu,g);c.addClass(g.id,g.classPrefix+"Selected")},hideMenu:function(g){var f=this;if(g&&g.type=="mousedown"&&(g.target.id==f.id+"_text"||g.target.id==f.id+"_open")){return}if(!g||!c.getParent(g.target,".mceMenu")){c.removeClass(f.id,f.classPrefix+"Selected");b.remove(c.doc,"mousedown",f.hideMenu,f);if(f.menu){f.menu.hideMenu()}}},renderMenu:function(){var g=this,f;f=g.settings.control_manager.createDropMenu(g.id+"_menu",{menu_line:1,"class":g.classPrefix+"Menu mceNoIcons",max_width:150,max_height:150});f.onHideMenu.add(g.hideMenu,g);f.add({title:g.settings.title,"class":"mceMenuItemTitle",onclick:function(){if(g.settings.onselect("")!==false){g.select("")}}});e(g.items,function(h){h.id=c.uniqueId();h.onclick=function(){if(g.settings.onselect(h.value)!==false){g.select(h.value)}};f.add(h)});g.onRenderMenu.dispatch(g,f);g.menu=f},postRender:function(){var f=this,g=f.classPrefix;b.add(f.id,"click",f.showMenu,f);b.add(f.id+"_text","focus",function(h){if(!f._focused){f.keyDownHandler=b.add(f.id+"_text","keydown",function(l){var i=-1,j,k=l.keyCode;e(f.items,function(m,n){if(f.selectedValue==m.value){i=n}});if(k==38){j=f.items[i-1]}else{if(k==40){j=f.items[i+1]}else{if(k==13){j=f.selectedValue;f.selectedValue=null;f.settings.onselect(j);return b.cancel(l)}}}if(j){f.hideMenu();f.select(j.value)}})}f._focused=1});b.add(f.id+"_text","blur",function(){b.remove(f.id+"_text","keydown",f.keyDownHandler);f._focused=0});if(d.isIE6||!c.boxModel){b.add(f.id,"mouseover",function(){if(!c.hasClass(f.id,g+"Disabled")){c.addClass(f.id,g+"Hover")}});b.add(f.id,"mouseout",function(){if(!c.hasClass(f.id,g+"Disabled")){c.removeClass(f.id,g+"Hover")}})}f.onPostRender.dispatch(f,c.get(f.id))},destroy:function(){this.parent();b.clear(this.id+"_text")}})})(tinymce);(function(d){var c=d.DOM,b=d.dom.Event,e=d.each,a=d.util.Dispatcher;d.create("tinymce.ui.NativeListBox:tinymce.ui.ListBox",{NativeListBox:function(g,f){this.parent(g,f);this.classPrefix="mceNativeListBox"},setDisabled:function(f){c.get(this.id).disabled=f},isDisabled:function(){return c.get(this.id).disabled},select:function(h){var g=this,j,i;if(h==undefined){return g.selectByIndex(-1)}if(h&&h.call){i=h}else{i=function(f){return f==h}}if(h!=g.selectedValue){e(g.items,function(k,f){if(i(k.value)){j=1;g.selectByIndex(f);return false}});if(!j){g.selectByIndex(-1)}}},selectByIndex:function(f){c.get(this.id).selectedIndex=f+1;this.selectedValue=this.items[f]?this.items[f].value:null},add:function(j,g,f){var i,h=this;f=f||{};f.value=g;if(h.isRendered()){c.add(c.get(this.id),"option",f,j)}i={title:j,value:g,attribs:f};h.items.push(i);h.onAdd.dispatch(h,i)},getLength:function(){return c.get(this.id).options.length-1},renderHTML:function(){var g,f=this;g=c.createHTML("option",{value:""},"-- "+f.settings.title+" --");e(f.items,function(h){g+=c.createHTML("option",{value:h.value},h.title)});g=c.createHTML("select",{id:f.id,"class":"mceNativeListBox"},g);return g},postRender:function(){var g=this,h;g.rendered=true;function f(j){var i=g.items[j.target.selectedIndex-1];if(i&&(i=i.value)){g.onChange.dispatch(g,i);if(g.settings.onselect){g.settings.onselect(i)}}}b.add(g.id,"change",f);b.add(g.id,"keydown",function(j){var i;b.remove(g.id,"change",h);i=b.add(g.id,"blur",function(){b.add(g.id,"change",f);b.remove(g.id,"blur",i)});if(j.keyCode==13||j.keyCode==32){f(j);return b.cancel(j)}});g.onPostRender.dispatch(g,c.get(g.id))}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each;c.create("tinymce.ui.MenuButton:tinymce.ui.Button",{MenuButton:function(f,e){this.parent(f,e);this.onRenderMenu=new c.util.Dispatcher(this);e.menu_container=e.menu_container||b.doc.body},showMenu:function(){var g=this,j,i,h=b.get(g.id),f;if(g.isDisabled()){return}if(!g.isMenuRendered){g.renderMenu();g.isMenuRendered=true}if(g.isMenuVisible){return g.hideMenu()}j=b.getPos(g.settings.menu_container);i=b.getPos(h);f=g.menu;f.settings.offset_x=i.x;f.settings.offset_y=i.y;f.settings.vp_offset_x=i.x;f.settings.vp_offset_y=i.y;f.settings.keyboard_focus=g._focused;f.showMenu(0,h.clientHeight);a.add(b.doc,"mousedown",g.hideMenu,g);g.setState("Selected",1);g.isMenuVisible=1},renderMenu:function(){var f=this,e;e=f.settings.control_manager.createDropMenu(f.id+"_menu",{menu_line:1,"class":this.classPrefix+"Menu",icons:f.settings.icons});e.onHideMenu.add(f.hideMenu,f);f.onRenderMenu.dispatch(f,e);f.menu=e},hideMenu:function(g){var f=this;if(g&&g.type=="mousedown"&&b.getParent(g.target,function(h){return h.id===f.id||h.id===f.id+"_open"})){return}if(!g||!b.getParent(g.target,".mceMenu")){f.setState("Selected",0);a.remove(b.doc,"mousedown",f.hideMenu,f);if(f.menu){f.menu.hideMenu()}}f.isMenuVisible=0},postRender:function(){var e=this,f=e.settings;a.add(e.id,"click",function(){if(!e.isDisabled()){if(f.onclick){f.onclick(e.value)}e.showMenu()}})}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each;c.create("tinymce.ui.SplitButton:tinymce.ui.MenuButton",{SplitButton:function(f,e){this.parent(f,e);this.classPrefix="mceSplitButton"},renderHTML:function(){var i,f=this,g=f.settings,e;i="<tbody><tr>";if(g.image){e=b.createHTML("img ",{src:g.image,"class":"mceAction "+g["class"]})}else{e=b.createHTML("span",{"class":"mceAction "+g["class"]},"")}i+="<td>"+b.createHTML("a",{id:f.id+"_action",href:"javascript:;","class":"mceAction "+g["class"],onclick:"return false;",onmousedown:"return false;",title:g.title},e)+"</td>";e=b.createHTML("span",{"class":"mceOpen "+g["class"]});i+="<td>"+b.createHTML("a",{id:f.id+"_open",href:"javascript:;","class":"mceOpen "+g["class"],onclick:"return false;",onmousedown:"return false;",title:g.title},e)+"</td>";i+="</tr></tbody>";return b.createHTML("table",{id:f.id,"class":"mceSplitButton mceSplitButtonEnabled "+g["class"],cellpadding:"0",cellspacing:"0",onmousedown:"return false;",title:g.title},i)},postRender:function(){var e=this,f=e.settings;if(f.onclick){a.add(e.id+"_action","click",function(){if(!e.isDisabled()){f.onclick(e.value)}})}a.add(e.id+"_open","click",e.showMenu,e);a.add(e.id+"_open","focus",function(){e._focused=1});a.add(e.id+"_open","blur",function(){e._focused=0});if(c.isIE6||!b.boxModel){a.add(e.id,"mouseover",function(){if(!b.hasClass(e.id,"mceSplitButtonDisabled")){b.addClass(e.id,"mceSplitButtonHover")}});a.add(e.id,"mouseout",function(){if(!b.hasClass(e.id,"mceSplitButtonDisabled")){b.removeClass(e.id,"mceSplitButtonHover")}})}},destroy:function(){this.parent();a.clear(this.id+"_action");a.clear(this.id+"_open")}})})(tinymce);(function(d){var c=d.DOM,a=d.dom.Event,b=d.is,e=d.each;d.create("tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton",{ColorSplitButton:function(h,g){var f=this;f.parent(h,g);f.settings=g=d.extend({colors:"000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF",grid_width:8,default_color:"#888888"},f.settings);f.onShowMenu=new d.util.Dispatcher(f);f.onHideMenu=new d.util.Dispatcher(f);f.value=g.default_color},showMenu:function(){var f=this,g,j,i,h;if(f.isDisabled()){return}if(!f.isMenuRendered){f.renderMenu();f.isMenuRendered=true}if(f.isMenuVisible){return f.hideMenu()}i=c.get(f.id);c.show(f.id+"_menu");c.addClass(i,"mceSplitButtonSelected");h=c.getPos(i);c.setStyles(f.id+"_menu",{left:h.x,top:h.y+i.clientHeight,zIndex:200000});i=0;a.add(c.doc,"mousedown",f.hideMenu,f);if(f._focused){f._keyHandler=a.add(f.id+"_menu","keydown",function(k){if(k.keyCode==27){f.hideMenu()}});c.select("a",f.id+"_menu")[0].focus()}f.onShowMenu.dispatch(f);f.isMenuVisible=1},hideMenu:function(g){var f=this;if(g&&g.type=="mousedown"&&c.getParent(g.target,function(h){return h.id===f.id+"_open"})){return}if(!g||!c.getParent(g.target,".mceSplitButtonMenu")){c.removeClass(f.id,"mceSplitButtonSelected");a.remove(c.doc,"mousedown",f.hideMenu,f);a.remove(f.id+"_menu","keydown",f._keyHandler);c.hide(f.id+"_menu")}f.onHideMenu.dispatch(f);f.isMenuVisible=0},renderMenu:function(){var k=this,f,j=0,l=k.settings,p,h,o,g;g=c.add(l.menu_container,"div",{id:k.id+"_menu","class":l.menu_class+" "+l["class"],style:"position:absolute;left:0;top:-1000px;"});f=c.add(g,"div",{"class":l["class"]+" mceSplitButtonMenu"});c.add(f,"span",{"class":"mceMenuLine"});p=c.add(f,"table",{"class":"mceColorSplitMenu"});h=c.add(p,"tbody");j=0;e(b(l.colors,"array")?l.colors:l.colors.split(","),function(i){i=i.replace(/^#/,"");if(!j--){o=c.add(h,"tr");j=l.grid_width-1}p=c.add(o,"td");p=c.add(p,"a",{href:"javascript:;",style:{backgroundColor:"#"+i},mce_color:"#"+i})});if(l.more_colors_func){p=c.add(h,"tr");p=c.add(p,"td",{colspan:l.grid_width,"class":"mceMoreColors"});p=c.add(p,"a",{id:k.id+"_more",href:"javascript:;",onclick:"return false;","class":"mceMoreColors"},l.more_colors_title);a.add(p,"click",function(i){l.more_colors_func.call(l.more_colors_scope||this);return a.cancel(i)})}c.addClass(f,"mceColorSplitMenu");a.add(k.id+"_menu","click",function(i){var m;i=i.target;if(i.nodeName=="A"&&(m=i.getAttribute("mce_color"))){k.setColor(m)}return a.cancel(i)});return g},setColor:function(g){var f=this;c.setStyle(f.id+"_preview","backgroundColor",g);f.value=g;f.hideMenu();f.settings.onselect(g)},postRender:function(){var f=this,g=f.id;f.parent();c.add(g+"_action","div",{id:g+"_preview","class":"mceColorPreview"});c.setStyle(f.id+"_preview","backgroundColor",f.value)},destroy:function(){this.parent();a.clear(this.id+"_menu");a.clear(this.id+"_more");c.remove(this.id+"_menu")}})})(tinymce);tinymce.create("tinymce.ui.Toolbar:tinymce.ui.Container",{renderHTML:function(){var l=this,e="",g,j,b=tinymce.DOM,m=l.settings,d,a,f,k;k=l.controls;for(d=0;d<k.length;d++){j=k[d];a=k[d-1];f=k[d+1];if(d===0){g="mceToolbarStart";if(j.Button){g+=" mceToolbarStartButton"}else{if(j.SplitButton){g+=" mceToolbarStartSplitButton"}else{if(j.ListBox){g+=" mceToolbarStartListBox"}}}e+=b.createHTML("td",{"class":g},b.createHTML("span",null,"<!-- IE -->"))}if(a&&j.ListBox){if(a.Button||a.SplitButton){e+=b.createHTML("td",{"class":"mceToolbarEnd"},b.createHTML("span",null,"<!-- IE -->"))}}if(b.stdMode){e+='<td style="position: relative">'+j.renderHTML()+"</td>"}else{e+="<td>"+j.renderHTML()+"</td>"}if(f&&j.ListBox){if(f.Button||f.SplitButton){e+=b.createHTML("td",{"class":"mceToolbarStart"},b.createHTML("span",null,"<!-- IE -->"))}}}g="mceToolbarEnd";if(j.Button){g+=" mceToolbarEndButton"}else{if(j.SplitButton){g+=" mceToolbarEndSplitButton"}else{if(j.ListBox){g+=" mceToolbarEndListBox"}}}e+=b.createHTML("td",{"class":g},b.createHTML("span",null,"<!-- IE -->"));return b.createHTML("table",{id:l.id,"class":"mceToolbar"+(m["class"]?" "+m["class"]:""),cellpadding:"0",cellspacing:"0",align:l.settings.align||""},"<tbody><tr>"+e+"</tr></tbody>")}});(function(b){var a=b.util.Dispatcher,c=b.each;b.create("tinymce.AddOnManager",{items:[],urls:{},lookup:{},onAdd:new a(this),get:function(d){return this.lookup[d]},requireLangPack:function(f){var d,e=b.EditorManager.settings;if(e&&e.language){d=this.urls[f]+"/langs/"+e.language+".js";if(!b.dom.Event.domLoaded&&!e.strict_mode){b.ScriptLoader.load(d)}else{b.ScriptLoader.add(d)}}},add:function(e,d){this.items.push(d);this.lookup[e]=d;this.onAdd.dispatch(this,e,d);return d},load:function(h,e,d,g){var f=this;if(f.urls[h]){return}if(e.indexOf("/")!=0&&e.indexOf("://")==-1){e=b.baseURL+"/"+e}f.urls[h]=e.substring(0,e.lastIndexOf("/"));b.ScriptLoader.add(e,d,g)}});b.PluginManager=new b.AddOnManager();b.ThemeManager=new b.AddOnManager()}(tinymce));(function(f){var g=f.each,h=f.extend,e=f.DOM,a=f.dom.Event,c=f.ThemeManager,b=f.PluginManager,d=f.explode;f.create("static tinymce.EditorManager",{editors:{},i18n:{},activeEditor:null,preInit:function(){var i=this,j=window.location;f.documentBaseURL=j.href.replace(/[\?#].*$/,"").replace(/[\/\\][^\/]+$/,"");if(!/[\/\\]$/.test(f.documentBaseURL)){f.documentBaseURL+="/"}f.baseURL=new f.util.URI(f.documentBaseURL).toAbsolute(f.baseURL);f.EditorManager.baseURI=new f.util.URI(f.baseURL);if(document.domain&&j.hostname!=document.domain){f.relaxedDomain=document.domain}i.onBeforeUnload=new f.util.Dispatcher(i);a.add(window,"beforeunload",function(k){i.onBeforeUnload.dispatch(i,k)})},init:function(q){var p=this,l,k=f.ScriptLoader,o,n,i=[],m;function j(u,v,r){var t=u[v];if(!t){return}if(f.is(t,"string")){r=t.replace(/\.\w+$/,"");r=r?f.resolve(r):0;t=f.resolve(t)}return t.apply(r||this,Array.prototype.slice.call(arguments,2))}q=h({theme:"simple",language:"en",strict_loading_mode:document.contentType=="application/xhtml+xml"},q);p.settings=q;if(!a.domLoaded&&!q.strict_loading_mode){if(q.language){k.add(f.baseURL+"/langs/"+q.language+".js")}if(q.theme&&q.theme.charAt(0)!="-"&&!c.urls[q.theme]){c.load(q.theme,"themes/"+q.theme+"/editor_template"+f.suffix+".js")}if(q.plugins){l=d(q.plugins);if(f.inArray(l,"compat2x")!=-1){b.load("compat2x","plugins/compat2x/editor_plugin"+f.suffix+".js")}g(l,function(r){if(r&&r.charAt(0)!="-"&&!b.urls[r]){if(!f.isWebKit&&r=="safari"){return}b.load(r,"plugins/"+r+"/editor_plugin"+f.suffix+".js")}})}k.loadQueue()}a.add(document,"init",function(){var r,t;j(q,"onpageload");if(q.browsers){r=false;g(d(q.browsers),function(u){switch(u){case"ie":case"msie":if(f.isIE){r=true}break;case"gecko":if(f.isGecko){r=true}break;case"safari":case"webkit":if(f.isWebKit){r=true}break;case"opera":if(f.isOpera){r=true}break}});if(!r){return}}switch(q.mode){case"exact":r=q.elements||"";if(r.length>0){g(d(r),function(u){if(e.get(u)){m=new f.Editor(u,q);i.push(m);m.render(1)}else{o=0;g(document.forms,function(v){g(v.elements,function(w){if(w.name===u){u="mce_editor_"+o;e.setAttrib(w,"id",u);m=new f.Editor(u,q);i.push(m);m.render(1)}})})}})}break;case"textareas":case"specific_textareas":function s(v,u){return u.constructor===RegExp?u.test(v.className):e.hasClass(v,u)}g(e.select("textarea"),function(u){if(q.editor_deselector&&s(u,q.editor_deselector)){return}if(!q.editor_selector||s(u,q.editor_selector)){n=e.get(u.name);if(!u.id&&!n){u.id=u.name}if(!u.id||p.get(u.id)){u.id=e.uniqueId()}m=new f.Editor(u.id,q);i.push(m);m.render(1)}});break}if(q.oninit){r=t=0;g(i,function(u){t++;if(!u.initialized){u.onInit.add(function(){r++;if(r==t){j(q,"oninit")}})}else{r++}if(r==t){j(q,"oninit")}})}})},get:function(i){return this.editors[i]},getInstanceById:function(i){return this.get(i)},add:function(i){this.editors[i.id]=i;this._setActive(i);return i},remove:function(j){var i=this;if(!i.editors[j.id]){return null}delete i.editors[j.id];if(i.activeEditor==j){g(i.editors,function(k){i._setActive(k);return false})}j.destroy();return j},execCommand:function(o,m,l){var n=this,k=n.get(l),i;switch(o){case"mceFocus":k.focus();return true;case"mceAddEditor":case"mceAddControl":if(!n.get(l)){new f.Editor(l,n.settings).render()}return true;case"mceAddFrameControl":i=l.window;i.tinyMCE=tinyMCE;i.tinymce=f;f.DOM.doc=i.document;f.DOM.win=i;k=new f.Editor(l.element_id,l);k.render();if(f.isIE){function j(){k.destroy();i.detachEvent("onunload",j);i=i.tinyMCE=i.tinymce=null}i.attachEvent("onunload",j)}l.page_window=null;return true;case"mceRemoveEditor":case"mceRemoveControl":if(k){k.remove()}return true;case"mceToggleEditor":if(!k){n.execCommand("mceAddControl",0,l);return true}if(k.isHidden()){k.show()}else{k.hide()}return true}if(n.activeEditor){return n.activeEditor.execCommand(o,m,l)}return false},execInstanceCommand:function(m,l,k,j){var i=this.get(m);if(i){return i.execCommand(l,k,j)}return false},triggerSave:function(){g(this.editors,function(i){i.save()})},addI18n:function(k,l){var i,j=this.i18n;if(!f.is(k,"string")){g(k,function(n,m){g(n,function(q,p){g(q,function(s,r){if(p==="common"){j[m+"."+r]=s}else{j[m+"."+p+"."+r]=s}})})})}else{g(l,function(n,m){j[k+"."+m]=n})}},_setActive:function(i){this.selectedInstance=this.activeEditor=i}});f.EditorManager.preInit()})(tinymce);var tinyMCE=window.tinyMCE=tinymce.EditorManager;(function(n){var o=n.DOM,k=n.dom.Event,f=n.extend,l=n.util.Dispatcher;var j=n.each,a=n.isGecko,b=n.isIE,e=n.isWebKit;var d=n.is,h=n.ThemeManager,c=n.PluginManager,i=n.EditorManager;var p=n.inArray,m=n.grep,g=n.explode;n.create("tinymce.Editor",{Editor:function(u,r){var q=this;q.id=q.editorId=u;q.execCommands={};q.queryStateCommands={};q.queryValueCommands={};q.plugins={};j(["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(s){q[s]=new l(q)});q.settings=r=f({id:u,language:"en",docs_language:"en",theme:"simple",skin:"default",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:n.documentBaseURL,add_form_submit_trigger:1,submit_patch:1,add_unload_trigger:1,convert_urls:1,relative_urls:1,remove_script_host:1,table_inline_editing:0,object_resizing:1,cleanup:1,accessibility_focus:1,custom_shortcuts:1,custom_undo_redo_keyboard_shortcuts:1,custom_undo_redo_restore_selection:1,custom_undo_redo:1,doctype:'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',visual_table_class:"mceItemTable",visual:1,inline_styles:true,convert_fonts_to_spans:true,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[align],-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=0|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,removeformat_selector:"span,b,strong,em,i,font,u,strike"},r);q.documentBaseURI=new n.util.URI(r.document_base_url||n.documentBaseURL,{base_uri:tinyMCE.baseURI});q.baseURI=i.baseURI;q.execCallback("setup",q)},render:function(u){var v=this,w=v.settings,x=v.id,q=n.ScriptLoader;if(!k.domLoaded){k.add(document,"init",function(){v.render()});return}if(!u){w.strict_loading_mode=1;tinyMCE.settings=w}if(!v.getElement()){return}if(w.strict_loading_mode){q.settings.strict_mode=w.strict_loading_mode;n.DOM.settings.strict=1}if(!/TEXTAREA|INPUT/i.test(v.getElement().nodeName)&&w.hidden_input&&o.getParent(x,"form")){o.insertAfter(o.create("input",{type:"hidden",name:x}),x)}if(n.WindowManager){v.windowManager=new n.WindowManager(v)}if(w.encoding=="xml"){v.onGetContent.add(function(s,t){if(t.save){t.content=o.encode(t.content)}})}if(w.add_form_submit_trigger){v.onSubmit.addToTop(function(){if(v.initialized){v.save();v.isNotDirty=1}})}if(w.add_unload_trigger){v._beforeUnload=tinyMCE.onBeforeUnload.add(function(){if(v.initialized&&!v.destroyed&&!v.isHidden()){v.save({format:"raw",no_events:true})}})}n.addUnload(v.destroy,v);if(w.submit_patch){v.onBeforeRenderUI.add(function(){var s=v.getElement().form;if(!s){return}if(s._mceOldSubmit){return}if(!s.submit.nodeType&&!s.submit.length){v.formElement=s;s._mceOldSubmit=s.submit;s.submit=function(){i.triggerSave();v.isNotDirty=1;return v.formElement._mceOldSubmit(v.formElement)}}s=null})}function r(){if(w.language){q.add(n.baseURL+"/langs/"+w.language+".js")}if(w.theme&&w.theme.charAt(0)!="-"&&!h.urls[w.theme]){h.load(w.theme,"themes/"+w.theme+"/editor_template"+n.suffix+".js")}j(g(w.plugins),function(s){if(s&&s.charAt(0)!="-"&&!c.urls[s]){if(!e&&s=="safari"){return}c.load(s,"plugins/"+s+"/editor_plugin"+n.suffix+".js")}});q.loadQueue(function(){if(!v.removed){v.init()}})}if(w.plugins.indexOf("compat2x")!=-1){c.load("compat2x","plugins/compat2x/editor_plugin"+n.suffix+".js");q.loadQueue(r)}else{r()}},init:function(){var v,F=this,G=F.settings,C,z,B=F.getElement(),r,q,D,y,A,E;i.add(F);if(G.theme){G.theme=G.theme.replace(/-/,"");r=h.get(G.theme);F.theme=new r();if(F.theme.init&&G.init_theme){F.theme.init(F,h.urls[G.theme]||n.documentBaseURL.replace(/\/$/,""))}}j(g(G.plugins.replace(/\-/g,"")),function(w){var H=c.get(w),t=c.urls[w]||n.documentBaseURL.replace(/\/$/,""),s;if(H){s=new H(F,t);F.plugins[w]=s;if(s.init){s.init(F,t)}}});if(G.popup_css!==false){if(G.popup_css){G.popup_css=F.documentBaseURI.toAbsolute(G.popup_css)}else{G.popup_css=F.baseURI.toAbsolute("themes/"+G.theme+"/skins/"+G.skin+"/dialog.css")}}if(G.popup_css_add){G.popup_css+=","+F.documentBaseURI.toAbsolute(G.popup_css_add)}F.controlManager=new n.ControlManager(F);F.undoManager=new n.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)});if(G.custom_undo_redo){F.onExecCommand.add(function(t,w,u,H,s){if(w!="Undo"&&w!="Redo"&&w!="mceRepaint"&&(!s||!s.skip_undo)){F.undoManager.add()}})}F.onExecCommand.add(function(s,t){if(!/^(FontName|FontSize)$/.test(t)){F.nodeChanged()}});if(a){function x(s,t){if(!t||!t.initial){F.execCommand("mceRepaint")}}F.onUndo.add(x);F.onRedo.add(x);F.onSetContent.add(x)}F.onBeforeRenderUI.dispatch(F,F.controlManager);if(G.render_ui){C=G.width||B.style.width||B.offsetWidth;z=G.height||B.style.height||B.offsetHeight;F.orgDisplay=B.style.display;E=/^[0-9\.]+(|px)$/i;if(E.test(""+C)){C=Math.max(parseInt(C)+(r.deltaWidth||0),100)}if(E.test(""+z)){z=Math.max(parseInt(z)+(r.deltaHeight||0),100)}r=F.theme.renderUI({targetNode:B,width:C,height:z,deltaWidth:G.delta_width,deltaHeight:G.delta_height});F.editorContainer=r.editorContainer}o.setStyles(r.sizeContainer||r.editorContainer,{width:C,height:z});z=(r.iframeHeight||z)+(typeof(z)=="number"?(r.deltaHeight||0):"");if(z<100){z=100}F.iframeHTML=G.doctype+'<html><head xmlns="http://www.w3.org/1999/xhtml"><base href="'+F.documentBaseURI.getURI()+'" />';F.iframeHTML+='<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';if(n.relaxedDomain){F.iframeHTML+='<script type="text/javascript">document.domain = "'+n.relaxedDomain+'";<\/script>'}y=G.body_id||"tinymce";if(y.indexOf("=")!=-1){y=F.getParam("body_id","","hash");y=y[F.id]||y}A=G.body_class||"";if(A.indexOf("=")!=-1){A=F.getParam("body_class","","hash");A=A[F.id]||""}F.iframeHTML+='</head><body id="'+y+'" class="mceContentBody '+A+'"></body></html>';if(n.relaxedDomain){if(b||(n.isOpera&&parseFloat(opera.version())>=9.5)){D='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(n.isOpera){D='javascript:(function(){document.open();document.domain="'+document.domain+'";document.close();ed.setupIframe();})()'}}}v=o.add(r.iframeContainer,"iframe",{id:F.id+"_ifr",src:D||'javascript:""',frameBorder:"0",style:{width:"100%",height:z}});F.contentAreaContainer=r.iframeContainer;o.get(r.editorContainer).style.display=F.orgDisplay;o.get(F.id).style.display="none";if(!b||!n.relaxedDomain){F.setupIframe()}B=v=r=null},setupIframe:function(){var z=this,A=z.settings,u=o.get(z.id),v=z.getDoc(),r,x;if(!b||!n.relaxedDomain){v.open();v.write(z.iframeHTML);v.close()}if(!b){try{if(!A.readonly){v.designMode="On"}}catch(w){}}if(b){x=z.getBody();o.hide(x);if(!A.readonly){x.contentEditable=true}o.show(x)}z.dom=new n.DOM.DOMUtils(z.getDoc(),{keep_values:true,url_converter:z.convertURL,url_converter_scope:z,hex_colors:A.force_hex_style_colors,class_filter:A.class_filter,update_styles:1,fix_ie_paragraphs:1});z.serializer=new n.dom.Serializer({entity_encoding:A.entity_encoding,entities:A.entities,valid_elements:A.verify_html===false?"*[*]":A.valid_elements,extended_valid_elements:A.extended_valid_elements,valid_child_elements:A.valid_child_elements,invalid_elements:A.invalid_elements,fix_table_elements:A.fix_table_elements,fix_list_elements:A.fix_list_elements,fix_content_duplication:A.fix_content_duplication,convert_fonts_to_spans:A.convert_fonts_to_spans,font_size_classes:A.font_size_classes,font_size_style_values:A.font_size_style_values,apply_source_formatting:A.apply_source_formatting,remove_linebreaks:A.remove_linebreaks,element_format:A.element_format,dom:z.dom});z.selection=new n.dom.Selection(z.dom,z.getWin(),z.serializer);z.forceBlocks=new n.ForceBlocks(z,{forced_root_block:A.forced_root_block});z.editorCommands=new n.EditorCommands(z);z.serializer.onPreProcess.add(function(s,t){return z.onPreProcess.dispatch(z,t,s)});z.serializer.onPostProcess.add(function(s,t){return z.onPostProcess.dispatch(z,t,s)});z.onPreInit.dispatch(z);if(!A.gecko_spellcheck){z.getBody().spellcheck=0}if(!A.readonly){z._addEvents()}z.controlManager.onPostRender.dispatch(z,z.controlManager);z.onPostRender.dispatch(z);if(A.directionality){z.getBody().dir=A.directionality}if(A.nowrap){z.getBody().style.whiteSpace="nowrap"}if(A.auto_resize){z.onNodeChange.add(z.resizeToContent,z)}if(A.custom_elements){function y(s,t){j(g(A.custom_elements),function(B){var C;if(B.indexOf("~")===0){B=B.substring(1);C="span"}else{C="div"}t.content=t.content.replace(new RegExp("<("+B+")([^>]*)>","g"),"<"+C+' mce_name="$1"$2>');t.content=t.content.replace(new RegExp("</("+B+")>","g"),"</"+C+">")})}z.onBeforeSetContent.add(y);z.onPostProcess.add(function(s,t){if(t.set){y(s,t)}})}if(A.handle_node_change_callback){z.onNodeChange.add(function(t,s,B){z.execCallback("handle_node_change_callback",z.id,B,-1,-1,true,z.selection.isCollapsed())})}if(A.save_callback){z.onSaveContent.add(function(s,B){var t=z.execCallback("save_callback",z.id,B.content,z.getBody());if(t){B.content=t}})}if(A.onchange_callback){z.onChange.add(function(t,s){z.execCallback("onchange_callback",z,s)})}if(A.convert_newlines_to_brs){z.onBeforeSetContent.add(function(s,t){if(t.initial){t.content=t.content.replace(/\r?\n/g,"<br />")}})}if(A.fix_nesting&&b){z.onBeforeSetContent.add(function(s,t){t.content=z._fixNesting(t.content)})}if(A.preformatted){z.onPostProcess.add(function(s,t){t.content=t.content.replace(/^\s*<pre.*?>/,"");t.content=t.content.replace(/<\/pre>\s*$/,"");if(t.set){t.content='<pre class="mceItemHidden">'+t.content+"</pre>"}})}if(A.verify_css_classes){z.serializer.attribValueFilter=function(D,B){var C,t;if(D=="class"){if(!z.classesRE){t=z.dom.getClasses();if(t.length>0){C="";j(t,function(s){C+=(C?"|":"")+s["class"]});z.classesRE=new RegExp("("+C+")","gi")}}return !z.classesRE||/(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(B)||z.classesRE.test(B)?B:""}return B}}if(A.convert_fonts_to_spans){z._convertFonts()}if(A.inline_styles){z._convertInlineElements()}if(A.cleanup_callback){z.onBeforeSetContent.add(function(s,t){t.content=z.execCallback("cleanup_callback","insert_to_editor",t.content,t)});z.onPreProcess.add(function(s,t){if(t.set){z.execCallback("cleanup_callback","insert_to_editor_dom",t.node,t)}if(t.get){z.execCallback("cleanup_callback","get_from_editor_dom",t.node,t)}});z.onPostProcess.add(function(s,t){if(t.set){t.content=z.execCallback("cleanup_callback","insert_to_editor",t.content,t)}if(t.get){t.content=z.execCallback("cleanup_callback","get_from_editor",t.content,t)}})}if(A.save_callback){z.onGetContent.add(function(s,t){if(t.save){t.content=z.execCallback("save_callback",z.id,t.content,z.getBody())}})}if(A.handle_event_callback){z.onEvent.add(function(s,t,B){if(z.execCallback("handle_event_callback",t,s,B)===false){k.cancel(t)}})}z.onSetContent.add(function(){z.addVisual(z.getBody())});if(A.padd_empty_editor){z.onPostProcess.add(function(s,t){t.content=t.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/,"")})}if(a){function q(s,t){j(s.dom.select("a"),function(C){var B=C.parentNode;if(s.dom.isBlock(B)&&B.lastChild===C){s.dom.add(B,"br",{mce_bogus:1})}})}z.onExecCommand.add(function(s,t){if(t==="CreateLink"){q(s)}});z.onSetContent.add(z.selection.onSetContent.add(q));if(!A.readonly){try{v.designMode="Off";v.designMode="On"}catch(w){}}}setTimeout(function(){if(z.removed){return}z.load({initial:true,format:(A.cleanup_on_startup?"html":"raw")});z.startContent=z.getContent({format:"raw"});z.undoManager.add({initial:true});z.initialized=true;z.onInit.dispatch(z);z.execCallback("setupcontent_callback",z.id,z.getBody(),z.getDoc());z.execCallback("init_instance_callback",z);z.focus(true);z.nodeChanged({initial:1});if(A.content_css){n.each(g(A.content_css),function(s){z.dom.loadCSS(z.documentBaseURI.toAbsolute(s))})}if(A.auto_focus){setTimeout(function(){var s=i.get(A.auto_focus);s.selection.select(s.getBody(),1);s.selection.collapse(1);s.getWin().focus()},100)}},1);u=null},focus:function(r){var u,q=this,s=q.settings.content_editable;if(!r){if(!s&&(!b||q.selection.getNode().ownerDocument!=q.getDoc())){q.getWin().focus()}}if(i.activeEditor!=q){if((u=i.activeEditor)!=null){u.onDeactivate.dispatch(u,q)}q.onActivate.dispatch(q,u)}i._setActive(q)},execCallback:function(v){var q=this,u=q.settings[v],r;if(!u){return}if(q.callbackLookup&&(r=q.callbackLookup[v])){u=r.func;r=r.scope}if(d(u,"string")){r=u.replace(/\.\w+$/,"");r=r?n.resolve(r):0;u=n.resolve(u);q.callbackLookup=q.callbackLookup||{};q.callbackLookup[v]={func:u,scope:r}}return u.apply(r||q,Array.prototype.slice.call(arguments,1))},translate:function(q){var t=this.settings.language||"en",r=i.i18n;if(!q){return""}return r[t+"."+q]||q.replace(/{\#([^}]+)\}/g,function(u,s){return r[t+"."+s]||"{#"+s+"}"})},getLang:function(r,q){return i.i18n[(this.settings.language||"en")+"."+r]||(d(q)?q:"{#"+r+"}")},getParam:function(w,s,q){var t=n.trim,r=d(this.settings[w])?this.settings[w]:s,u;if(q==="hash"){u={};if(d(r,"string")){j(r.indexOf("=")>0?r.split(/[;,](?![^=;,]*(?:[;,]|$))/):r.split(","),function(x){x=x.split("=");if(x.length>1){u[t(x[0])]=t(x[1])}else{u[t(x[0])]=t(x)}})}else{u=r}return u}return r},nodeChanged:function(u){var q=this,r=q.selection,v=r.getNode()||q.getBody();if(q.initialized){q.onNodeChange.dispatch(q,u?u.controlManager||q.controlManager:q.controlManager,b&&v.ownerDocument!=q.getDoc()?q.getBody():v,r.isCollapsed(),u)}},addButton:function(u,r){var q=this;q.buttons=q.buttons||{};q.buttons[u]=r},addCommand:function(t,r,q){this.execCommands[t]={func:r,scope:q||this}},addQueryStateHandler:function(t,r,q){this.queryStateCommands[t]={func:r,scope:q||this}},addQueryValueHandler:function(t,r,q){this.queryValueCommands[t]={func:r,scope:q||this}},addShortcut:function(s,v,q,u){var r=this,w;if(!r.settings.custom_shortcuts){return false}r.shortcuts=r.shortcuts||{};if(d(q,"string")){w=q;q=function(){r.execCommand(w,false,null)}}if(d(q,"object")){w=q;q=function(){r.execCommand(w[0],w[1],w[2])}}j(g(s),function(t){var x={func:q,scope:u||this,desc:v,alt:false,ctrl:false,shift:false};j(g(t,"+"),function(y){switch(y){case"alt":case"ctrl":case"shift":x[y]=true;break;default:x.charCode=y.charCodeAt(0);x.keyCode=y.toUpperCase().charCodeAt(0)}});r.shortcuts[(x.ctrl?"ctrl":"")+","+(x.alt?"alt":"")+","+(x.shift?"shift":"")+","+x.keyCode]=x});return true},execCommand:function(x,w,z,q){var u=this,v=0,y,r;if(!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(x)&&(!q||!q.skip_focus)){u.focus()}y={};u.onBeforeExecCommand.dispatch(u,x,w,z,y);if(y.terminate){return false}if(u.execCallback("execcommand_callback",u.id,u.selection.getNode(),x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);return true}if(y=u.execCommands[x]){r=y.func.call(y.scope,w,z);if(r!==true){u.onExecCommand.dispatch(u,x,w,z,q);return r}}j(u.plugins,function(s){if(s.execCommand&&s.execCommand(x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);v=1;return false}});if(v){return true}if(u.theme&&u.theme.execCommand&&u.theme.execCommand(x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);return true}if(n.GlobalCommands.execCommand(u,x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);return true}if(u.editorCommands.execCommand(x,w,z)){u.onExecCommand.dispatch(u,x,w,z,q);return true}u.getDoc().execCommand(x,w,z);u.onExecCommand.dispatch(u,x,w,z,q)},queryCommandState:function(w){var r=this,v,u;if(r._isHidden()){return}if(v=r.queryStateCommands[w]){u=v.func.call(v.scope);if(u!==true){return u}}v=r.editorCommands.queryCommandState(w);if(v!==-1){return v}try{return this.getDoc().queryCommandState(w)}catch(q){}},queryCommandValue:function(w){var r=this,v,u;if(r._isHidden()){return}if(v=r.queryValueCommands[w]){u=v.func.call(v.scope);if(u!==true){return u}}v=r.editorCommands.queryCommandValue(w);if(d(v)){return v}try{return this.getDoc().queryCommandValue(w)}catch(q){}},show:function(){var q=this;o.show(q.getContainer());o.hide(q.id);q.load()},hide:function(){var q=this,r=q.getDoc();if(b&&r){r.execCommand("SelectAll")}q.save();o.hide(q.getContainer());o.setStyle(q.id,"display",q.orgDisplay)},isHidden:function(){return !o.isHidden(this.id)},setProgressState:function(q,r,s){this.onSetProgressState.dispatch(this,q,r,s);return q},resizeToContent:function(){var q=this;o.setStyle(q.id+"_ifr","height",q.getBody().scrollHeight)},load:function(u){var q=this,s=q.getElement(),r;if(s){u=u||{};u.load=true;r=q.setContent(d(s.value)?s.value:s.innerHTML,u);u.element=s;if(!u.no_events){q.onLoadContent.dispatch(q,u)}u.element=s=null;return r}},save:function(v){var q=this,u=q.getElement(),r,s;if(!u||!q.initialized){return}v=v||{};v.save=true;if(!v.no_events){q.undoManager.typing=0;q.undoManager.add()}v.element=u;r=v.content=q.getContent(v);if(!v.no_events){q.onSaveContent.dispatch(q,v)}r=v.content;if(!/TEXTAREA|INPUT/i.test(u.nodeName)){u.innerHTML=r;if(s=o.getParent(q.id,"form")){j(s.elements,function(t){if(t.name==q.id){t.value=r;return false}})}}else{u.value=r}v.element=u=null;return r},setContent:function(r,s){var q=this;s=s||{};s.format=s.format||"html";s.set=true;s.content=r;if(!s.no_events){q.onBeforeSetContent.dispatch(q,s)}if(!n.isIE&&(r.length===0||/^\s+$/.test(r))){s.content=q.dom.setHTML(q.getBody(),'<br mce_bogus="1" />');s.format="raw"}s.content=q.dom.setHTML(q.getBody(),n.trim(s.content));if(s.format!="raw"&&q.settings.cleanup){s.getInner=true;s.content=q.dom.setHTML(q.getBody(),q.serializer.serialize(q.getBody(),s))}if(!s.no_events){q.onSetContent.dispatch(q,s)}return s.content},getContent:function(s){var q=this,r;s=s||{};s.format=s.format||"html";s.get=true;if(!s.no_events){q.onBeforeGetContent.dispatch(q,s)}if(s.format!="raw"&&q.settings.cleanup){s.getInner=true;r=q.serializer.serialize(q.getBody(),s)}else{r=q.getBody().innerHTML}r=r.replace(/^\s*|\s*$/g,"");s.content=r;if(!s.no_events){q.onGetContent.dispatch(q,s)}return s.content},isDirty:function(){var q=this;return n.trim(q.startContent)!=n.trim(q.getContent({format:"raw",no_events:1}))&&!q.isNotDirty},getContainer:function(){var q=this;if(!q.container){q.container=o.get(q.editorContainer||q.id+"_parent")}return q.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return o.get(this.settings.content_element||this.id)},getWin:function(){var q=this,r;if(!q.contentWindow){r=o.get(q.id+"_ifr");if(r){q.contentWindow=r.contentWindow}}return q.contentWindow},getDoc:function(){var r=this,q;if(!r.contentDocument){q=r.getWin();if(q){r.contentDocument=q.document}}return r.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(q,x,w){var r=this,v=r.settings;if(v.urlconverter_callback){return r.execCallback("urlconverter_callback",q,w,true,x)}if(!v.convert_urls||(w&&w.nodeName=="LINK")||q.indexOf("file:")===0){return q}if(v.relative_urls){return r.documentBaseURI.toRelative(q)}q=r.documentBaseURI.toAbsolute(q,v.remove_script_host);return q},addVisual:function(u){var q=this,r=q.settings;u=u||q.getBody();if(!d(q.hasVisual)){q.hasVisual=r.visual}j(q.dom.select("table,a",u),function(t){var s;switch(t.nodeName){case"TABLE":s=q.dom.getAttrib(t,"border");if(!s||s=="0"){if(q.hasVisual){q.dom.addClass(t,r.visual_table_class)}else{q.dom.removeClass(t,r.visual_table_class)}}return;case"A":s=q.dom.getAttrib(t,"name");if(s){if(q.hasVisual){q.dom.addClass(t,"mceItemAnchor")}else{q.dom.removeClass(t,"mceItemAnchor")}}return}});q.onVisualAid.dispatch(q,u,q.hasVisual)},remove:function(){var q=this,r=q.getContainer();q.removed=1;q.hide();q.execCallback("remove_instance_callback",q);q.onRemove.dispatch(q);q.onExecCommand.listeners=[];i.remove(q);o.remove(r)},destroy:function(r){var q=this;if(q.destroyed){return}if(!r){n.removeUnload(q.destroy);tinyMCE.onBeforeUnload.remove(q._beforeUnload);if(q.theme&&q.theme.destroy){q.theme.destroy()}q.controlManager.destroy();q.selection.destroy();q.dom.destroy();if(!q.settings.content_editable){k.clear(q.getWin());k.clear(q.getDoc())}k.clear(q.getBody());k.clear(q.formElement)}if(q.formElement){q.formElement.submit=q.formElement._mceOldSubmit;q.formElement._mceOldSubmit=null}q.contentAreaContainer=q.formElement=q.container=q.settings.content_element=q.bodyElement=q.contentDocument=q.contentWindow=null;if(q.selection){q.selection=q.selection.win=q.selection.dom=q.selection.dom.doc=null}q.destroyed=1},_addEvents:function(){var w=this,v,y=w.settings,x={mouseup:"onMouseUp",mousedown:"onMouseDown",click:"onClick",keyup:"onKeyUp",keydown:"onKeyDown",keypress:"onKeyPress",submit:"onSubmit",reset:"onReset",contextmenu:"onContextMenu",dblclick:"onDblClick",paste:"onPaste"};function u(t,A){var s=t.type;if(w.removed){return}if(w.onEvent.dispatch(w,t,A)!==false){w[x[t.fakeType||t.type]].dispatch(w,t,A)}}j(x,function(t,s){switch(s){case"contextmenu":if(n.isOpera){k.add(w.getBody(),"mousedown",function(A){if(A.ctrlKey){A.fakeType="contextmenu";u(A)}})}else{k.add(w.getBody(),s,u)}break;case"paste":k.add(w.getBody(),s,function(A){u(A)});break;case"submit":case"reset":k.add(w.getElement().form||o.getParent(w.id,"form"),s,u);break;default:k.add(y.content_editable?w.getBody():w.getDoc(),s,u)}});k.add(y.content_editable?w.getBody():(a?w.getDoc():w.getWin()),"focus",function(s){w.focus(true)});if(n.isGecko){k.add(w.getDoc(),"DOMNodeInserted",function(t){var s;t=t.target;if(t.nodeType===1&&t.nodeName==="IMG"&&(s=t.getAttribute("mce_src"))){t.src=w.documentBaseURI.toAbsolute(s)}})}if(a){function q(){var B=this,D=B.getDoc(),C=B.settings;if(a&&!C.readonly){if(B._isHidden()){try{if(!C.content_editable){D.designMode="On"}}catch(A){}}try{D.execCommand("styleWithCSS",0,false)}catch(A){if(!B._isHidden()){try{D.execCommand("useCSS",0,true)}catch(A){}}}if(!C.table_inline_editing){try{D.execCommand("enableInlineTableEditing",false,false)}catch(A){}}if(!C.object_resizing){try{D.execCommand("enableObjectResizing",false,false)}catch(A){}}}}w.onBeforeExecCommand.add(q);w.onMouseDown.add(q)}w.onMouseUp.add(w.nodeChanged);w.onClick.add(w.nodeChanged);w.onKeyUp.add(function(s,t){var A=t.keyCode;if((A>=33&&A<=36)||(A>=37&&A<=40)||A==13||A==45||A==46||A==8||(n.isMac&&(A==91||A==93))||t.ctrlKey){w.nodeChanged()}});w.onReset.add(function(){w.setContent(w.startContent,{format:"raw"})});if(y.custom_shortcuts){if(y.custom_undo_redo_keyboard_shortcuts){w.addShortcut("ctrl+z",w.getLang("undo_desc"),"Undo");w.addShortcut("ctrl+y",w.getLang("redo_desc"),"Redo")}if(a){w.addShortcut("ctrl+b",w.getLang("bold_desc"),"Bold");w.addShortcut("ctrl+i",w.getLang("italic_desc"),"Italic");w.addShortcut("ctrl+u",w.getLang("underline_desc"),"Underline")}for(v=1;v<=6;v++){w.addShortcut("ctrl+"+v,"",["FormatBlock",false,"<h"+v+">"])}w.addShortcut("ctrl+7","",["FormatBlock",false,"<p>"]);w.addShortcut("ctrl+8","",["FormatBlock",false,"<div>"]);w.addShortcut("ctrl+9","",["FormatBlock",false,"<address>"]);function z(t){var s=null;if(!t.altKey&&!t.ctrlKey&&!t.metaKey){return s}j(w.shortcuts,function(A){if(n.isMac&&A.ctrl!=t.metaKey){return}else{if(!n.isMac&&A.ctrl!=t.ctrlKey){return}}if(A.alt!=t.altKey){return}if(A.shift!=t.shiftKey){return}if(t.keyCode==A.keyCode||(t.charCode&&t.charCode==A.charCode)){s=A;return false}});return s}w.onKeyUp.add(function(s,t){var A=z(t);if(A){return k.cancel(t)}});w.onKeyPress.add(function(s,t){var A=z(t);if(A){return k.cancel(t)}});w.onKeyDown.add(function(s,t){var A=z(t);if(A){A.func.call(A.scope);return k.cancel(t)}})}if(n.isIE){k.add(w.getDoc(),"controlselect",function(A){var t=w.resizeInfo,s;A=A.target;if(A.nodeName!=="IMG"){return}if(t){k.remove(t.node,t.ev,t.cb)}if(!w.dom.hasClass(A,"mceItemNoResize")){ev="resizeend";s=k.add(A,ev,function(C){var B;C=C.target;if(B=w.dom.getStyle(C,"width")){w.dom.setAttrib(C,"width",B.replace(/[^0-9%]+/g,""));w.dom.setStyle(C,"width","")}if(B=w.dom.getStyle(C,"height")){w.dom.setAttrib(C,"height",B.replace(/[^0-9%]+/g,""));w.dom.setStyle(C,"height","")}})}else{ev="resizestart";s=k.add(A,"resizestart",k.cancel,k)}t=w.resizeInfo={node:A,ev:ev,cb:s}});w.onKeyDown.add(function(s,t){switch(t.keyCode){case 8:if(w.selection.getRng().item){w.selection.getRng().item(0).removeNode();return k.cancel(t)}}})}if(n.isOpera){w.onClick.add(function(s,t){k.prevent(t)})}if(y.custom_undo_redo){function r(){w.undoManager.typing=0;w.undoManager.add()}if(n.isIE){k.add(w.getWin(),"blur",function(s){var t;if(w.selection){t=w.selection.getNode();if(!w.removed&&t.ownerDocument&&t.ownerDocument!=w.getDoc()){r()}}})}else{k.add(w.getDoc(),"blur",function(){if(w.selection&&!w.removed){r()}})}w.onMouseDown.add(r);w.onKeyUp.add(function(s,t){if((t.keyCode>=33&&t.keyCode<=36)||(t.keyCode>=37&&t.keyCode<=40)||t.keyCode==13||t.keyCode==45||t.ctrlKey){w.undoManager.typing=0;w.undoManager.add()}});w.onKeyDown.add(function(s,t){if((t.keyCode>=33&&t.keyCode<=36)||(t.keyCode>=37&&t.keyCode<=40)||t.keyCode==13||t.keyCode==45){if(w.undoManager.typing){w.undoManager.add();w.undoManager.typing=0}return}if(!w.undoManager.typing){w.undoManager.add();w.undoManager.typing=1}})}},_convertInlineElements:function(){var z=this,B=z.settings,r=z.dom,y,w,u,A,q;function x(s,t){if(!B.inline_styles){return}if(t.get){j(z.dom.select("table,u,strike",t.node),function(v){switch(v.nodeName){case"TABLE":if(y=r.getAttrib(v,"height")){r.setStyle(v,"height",y);r.setAttrib(v,"height","")}break;case"U":case"STRIKE":v.style.textDecoration=v.nodeName=="U"?"underline":"line-through";r.setAttrib(v,"mce_style","");r.setAttrib(v,"mce_name","span");break}})}else{if(t.set){j(z.dom.select("table,span",t.node).reverse(),function(v){if(v.nodeName=="TABLE"){if(y=r.getStyle(v,"height")){r.setAttrib(v,"height",y.replace(/[^0-9%]+/g,""))}}else{if(v.style.textDecoration=="underline"){u="u"}else{if(v.style.textDecoration=="line-through"){u="strike"}else{u=""}}if(u){v.style.textDecoration="";r.setAttrib(v,"mce_style","");w=r.create(u,{style:r.getAttrib(v,"style")});r.replace(w,v,1)}}})}}}z.onPreProcess.add(x);if(!B.cleanup_on_startup){z.onSetContent.add(function(s,t){if(t.initial){x(z,{node:z.getBody(),set:1})}})}},_convertFonts:function(){var w=this,x=w.settings,z=w.dom,v,r,q,u;if(!x.inline_styles){return}v=[8,10,12,14,18,24,36];r=["xx-small","x-small","small","medium","large","x-large","xx-large"];if(q=x.font_size_style_values){q=g(q)}if(u=x.font_size_classes){u=g(u)}function y(B){var C,A,t,s;if(!x.inline_styles){return}t=w.dom.select("font",B);for(s=t.length-1;s>=0;s--){C=t[s];A=z.create("span",{style:z.getAttrib(C,"style"),"class":z.getAttrib(C,"class")});z.setStyles(A,{fontFamily:z.getAttrib(C,"face"),color:z.getAttrib(C,"color"),backgroundColor:C.style.backgroundColor});if(C.size){if(q){z.setStyle(A,"fontSize",q[parseInt(C.size)-1])}else{z.setAttrib(A,"class",u[parseInt(C.size)-1])}}z.setAttrib(A,"mce_style","");z.replace(A,C,1)}}w.onPreProcess.add(function(s,t){if(t.get){y(t.node)}});w.onSetContent.add(function(s,t){if(t.initial){y(t.node)}})},_isHidden:function(){var q;if(!a){return 0}q=this.selection.getSel();return(!q||!q.rangeCount||q.rangeCount==0)},_fixNesting:function(r){var t=[],q;r=r.replace(/<(\/)?([^\s>]+)[^>]*?>/g,function(u,s,w){var v;if(s==="/"){if(!t.length){return""}if(w!==t[t.length-1].tag){for(q=t.length-1;q>=0;q--){if(t[q].tag===w){t[q].close=1;break}}return""}else{t.pop();if(t.length&&t[t.length-1].close){u=u+"</"+t[t.length-1].tag+">";t.pop()}}}else{if(/^(br|hr|input|meta|img|link|param)$/i.test(w)){return u}if(/\/>$/.test(u)){return u}t.push({tag:w})}return u});for(q=t.length-1;q>=0;q--){r+="</"+t[q].tag+">"}return r}})})(tinymce);(function(d){var f=d.each,c=d.isIE,a=d.isGecko,b=d.isOpera,e=d.isWebKit;d.create("tinymce.EditorCommands",{EditorCommands:function(g){this.editor=g},execCommand:function(k,j,l){var h=this,g=h.editor,i;switch(k){case"mceResetDesignMode":case"mceBeginUndoLevel":return true;case"unlink":h.UnLink();return true;case"JustifyLeft":case"JustifyCenter":case"JustifyRight":case"JustifyFull":h.mceJustify(k,k.substring(7).toLowerCase());return true;default:i=this[k];if(i){i.call(this,j,l);return true}}return false},Indent:function(){var g=this.editor,l=g.dom,j=g.selection,k,h,i;h=g.settings.indentation;i=/[a-z%]+$/i.exec(h);h=parseInt(h);if(g.settings.inline_styles&&(!this.queryStateInsertUnorderedList()&&!this.queryStateInsertOrderedList())){f(j.getSelectedBlocks(),function(m){l.setStyle(m,"paddingLeft",(parseInt(m.style.paddingLeft||0)+h)+i)});return}g.getDoc().execCommand("Indent",false,null);if(c){l.getParent(j.getNode(),function(m){if(m.nodeName=="BLOCKQUOTE"){m.dir=m.style.cssText=""}})}},Outdent:function(){var h=this.editor,m=h.dom,k=h.selection,l,g,i,j;i=h.settings.indentation;j=/[a-z%]+$/i.exec(i);i=parseInt(i);if(h.settings.inline_styles&&(!this.queryStateInsertUnorderedList()&&!this.queryStateInsertOrderedList())){f(k.getSelectedBlocks(),function(n){g=Math.max(0,parseInt(n.style.paddingLeft||0)-i);m.setStyle(n,"paddingLeft",g?g+j:"")});return}h.getDoc().execCommand("Outdent",false,null)},mceSetContent:function(h,g){this.editor.setContent(g)},mceToggleVisualAid:function(){var g=this.editor;g.hasVisual=!g.hasVisual;g.addVisual()},mceReplaceContent:function(h,g){var i=this.editor.selection;i.setContent(g.replace(/\{\$selection\}/g,i.getContent({format:"text"})))},mceInsertLink:function(i,h){var g=this.editor,j=g.selection,k=g.dom.getParent(j.getNode(),"a");if(d.is(h,"string")){h={href:h}}function l(m){f(h,function(o,n){g.dom.setAttrib(m,n,o)})}if(!k){g.execCommand("CreateLink",false,"javascript:mctmp(0);");f(g.dom.select("a[href=javascript:mctmp(0);]"),function(m){l(m)})}else{if(h.href){l(k)}else{g.dom.remove(k,1)}}},UnLink:function(){var g=this.editor,h=g.selection;if(h.isCollapsed()){h.select(h.getNode())}g.getDoc().execCommand("unlink",false,null);h.collapse(0)},FontName:function(i,h){var j=this,g=j.editor,k=g.selection,l;if(!h){if(k.isCollapsed()){k.select(k.getNode())}}else{if(g.settings.convert_fonts_to_spans){j._applyInlineStyle("span",{style:{fontFamily:h}})}else{g.getDoc().execCommand("FontName",false,h)}}},FontSize:function(j,i){var h=this.editor,l=h.settings,k,g;if(l.convert_fonts_to_spans&&i>=1&&i<=7){g=d.explode(l.font_size_style_values);k=d.explode(l.font_size_classes);if(k){i=k[i-1]||i}else{i=g[i-1]||i}}if(i>=1&&i<=7){h.getDoc().execCommand("FontSize",false,i)}else{this._applyInlineStyle("span",{style:{fontSize:i}})}},queryCommandValue:function(h){var g=this["queryValue"+h];if(g){return g.call(this,h)}return false},queryCommandState:function(h){var g;switch(h){case"JustifyLeft":case"JustifyCenter":case"JustifyRight":case"JustifyFull":return this.queryStateJustify(h,h.substring(7).toLowerCase());default:if(g=this["queryState"+h]){return g.call(this,h)}}return -1},_queryState:function(h){try{return this.editor.getDoc().queryCommandState(h)}catch(g){}},_queryVal:function(h){try{return this.editor.getDoc().queryCommandValue(h)}catch(g){}},queryValueFontSize:function(){var h=this.editor,g=0,i;if(i=h.dom.getParent(h.selection.getNode(),"span")){g=i.style.fontSize}if(!g&&(b||e)){if(i=h.dom.getParent(h.selection.getNode(),"font")){g=i.size}return g}return g||this._queryVal("FontSize")},queryValueFontName:function(){var h=this.editor,g=0,i;if(i=h.dom.getParent(h.selection.getNode(),"font")){g=i.face}if(i=h.dom.getParent(h.selection.getNode(),"span")){g=i.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase()}if(!g){g=this._queryVal("FontName")}return g},mceJustify:function(o,p){var k=this.editor,m=k.selection,g=m.getNode(),q=g.nodeName,h,j,i=k.dom,l;if(k.settings.inline_styles&&this.queryStateJustify(o,p)){l=1}h=i.getParent(g,k.dom.isBlock);if(q=="IMG"){if(p=="full"){return}if(l){if(p=="center"){i.setStyle(h||g.parentNode,"textAlign","")}i.setStyle(g,"float","");this.mceRepaint();return}if(p=="center"){if(h&&/^(TD|TH)$/.test(h.nodeName)){h=0}if(!h||h.childNodes.length>1){j=i.create("p");j.appendChild(g.cloneNode(false));if(h){i.insertAfter(j,h)}else{i.insertAfter(j,g)}i.remove(g);g=j.firstChild;h=j}i.setStyle(h,"textAlign",p);i.setStyle(g,"float","")}else{i.setStyle(g,"float",p);i.setStyle(h||g.parentNode,"textAlign","")}this.mceRepaint();return}if(k.settings.inline_styles&&k.settings.forced_root_block){if(l){p=""}f(m.getSelectedBlocks(i.getParent(m.getStart(),i.isBlock),i.getParent(m.getEnd(),i.isBlock)),function(n){i.setAttrib(n,"align","");i.setStyle(n,"textAlign",p=="full"?"justify":p)});return}else{if(!l){k.getDoc().execCommand(o,false,null)}}if(k.settings.inline_styles){if(l){i.getParent(k.selection.getNode(),function(r){if(r.style&&r.style.textAlign){i.setStyle(r,"textAlign","")}});return}f(i.select("*"),function(s){var r=s.align;if(r){if(r=="full"){r="justify"}i.setStyle(s,"textAlign",r);i.setAttrib(s,"align","")}})}},mceSetCSSClass:function(h,g){this.mceSetStyleInfo(0,{command:"setattrib",name:"class",value:g})},getSelectedElement:function(){var w=this,o=w.editor,n=o.dom,s=o.selection,h=s.getRng(),l,k,u,p,j,g,q,i,x,v;if(s.isCollapsed()||h.item){return s.getNode()}v=o.settings.merge_styles_invalid_parents;if(d.is(v,"string")){v=new RegExp(v,"i")}if(c){l=h.duplicate();l.collapse(true);u=l.parentElement();k=h.duplicate();k.collapse(false);p=k.parentElement();if(u!=p){l.move("character",1);u=l.parentElement()}if(u==p){l=h.duplicate();l.moveToElementText(u);if(l.compareEndPoints("StartToStart",h)==0&&l.compareEndPoints("EndToEnd",h)==0){return v&&v.test(u.nodeName)?null:u}}}else{function m(r){return n.getParent(r,"*")}u=h.startContainer;p=h.endContainer;j=h.startOffset;g=h.endOffset;if(!h.collapsed){if(u==p){if(j-g<2){if(u.hasChildNodes()){i=u.childNodes[j];return v&&v.test(i.nodeName)?null:i}}}}if(u.nodeType!=3||p.nodeType!=3){return null}if(j==0){i=m(u);if(i&&i.firstChild!=u){i=null}}if(j==u.nodeValue.length){q=u.nextSibling;if(q&&q.nodeType==1){i=u.nextSibling}}if(g==0){q=p.previousSibling;if(q&&q.nodeType==1){x=q}}if(g==p.nodeValue.length){x=m(p);if(x&&x.lastChild!=p){x=null}}if(i==x){return v&&i&&v.test(i.nodeName)?null:i}}return null},mceSetStyleInfo:function(n,m){var q=this,h=q.editor,j=h.getDoc(),g=h.dom,i,k,r=h.selection,p=m.wrapper||"span",k=r.getBookmark(),o;function l(t,s){if(t.nodeType==1){switch(m.command){case"setattrib":return g.setAttrib(t,m.name,m.value);case"setstyle":return g.setStyle(t,m.name,m.value);case"removeformat":return g.setAttrib(t,"class","")}}}o=h.settings.merge_styles_invalid_parents;if(d.is(o,"string")){o=new RegExp(o,"i")}if((i=q.getSelectedElement())&&!h.settings.force_span_wrappers){l(i,1)}else{j.execCommand("FontName",false,"__");f(g.select("span,font"),function(u){var s,t;if(g.getAttrib(u,"face")=="__"||u.style.fontFamily==="__"){s=g.create(p,{mce_new:"1"});l(s);f(u.childNodes,function(v){s.appendChild(v.cloneNode(true))});g.replace(s,u)}})}f(g.select(p).reverse(),function(t){var s=t.parentNode;if(!g.getAttrib(t,"mce_new")){s=g.getParent(t,"*[mce_new]");if(s){g.remove(t,1)}}});f(g.select(p).reverse(),function(t){var s=t.parentNode;if(!s||!g.getAttrib(t,"mce_new")){return}if(h.settings.force_span_wrappers&&s.nodeName!="SPAN"){return}if(s.nodeName==p.toUpperCase()&&s.childNodes.length==1){return g.remove(s,1)}if(t.nodeType==1&&(!o||!o.test(s.nodeName))&&s.childNodes.length==1){l(s);g.setAttrib(t,"class","")}});f(g.select(p).reverse(),function(s){if(g.getAttrib(s,"mce_new")||(g.getAttribs(s).length<=1&&s.className==="")){if(!g.getAttrib(s,"class")&&!g.getAttrib(s,"style")){return g.remove(s,1)}g.setAttrib(s,"mce_new","")}});r.moveToBookmark(k)},queryStateJustify:function(k,h){var g=this.editor,j=g.selection.getNode(),i=g.dom;if(j&&j.nodeName=="IMG"){if(i.getStyle(j,"float")==h){return 1}return j.parentNode.style.textAlign==h}j=i.getParent(g.selection.getStart(),function(l){return l.nodeType==1&&l.style.textAlign});if(h=="full"){h="justify"}if(g.settings.inline_styles){return(j&&j.style.textAlign==h)}return this._queryState(k)},ForeColor:function(i,h){var g=this.editor;if(g.settings.convert_fonts_to_spans){this._applyInlineStyle("span",{style:{color:h}});return}else{g.getDoc().execCommand("ForeColor",false,h)}},HiliteColor:function(i,k){var h=this,g=h.editor,j=g.getDoc();if(g.settings.convert_fonts_to_spans){this._applyInlineStyle("span",{style:{backgroundColor:k}});return}function l(n){if(!a){return}try{j.execCommand("styleWithCSS",0,n)}catch(m){j.execCommand("useCSS",0,!n)}}if(a||b){l(true);j.execCommand("hilitecolor",false,k);l(false)}else{j.execCommand("BackColor",false,k)}},FormatBlock:function(n,h){var o=this,l=o.editor,p=l.selection,j=l.dom,g,k,m;function i(q){return/^(P|DIV|H[1-6]|ADDRESS|BLOCKQUOTE|PRE)$/.test(q.nodeName)}g=j.getParent(p.getNode(),function(q){return i(q)});if(g){if((c&&i(g.parentNode))||g.nodeName=="DIV"){k=l.dom.create(h);f(j.getAttribs(g),function(q){j.setAttrib(k,q.nodeName,j.getAttrib(g,q.nodeName))});m=p.getBookmark();j.replace(k,g,1);p.moveToBookmark(m);l.nodeChanged();return}}h=l.settings.forced_root_block?(h||"<p>"):h;if(h.indexOf("<")==-1){h="<"+h+">"}if(d.isGecko){h=h.replace(/<(div|blockquote|code|dt|dd|dl|samp)>/gi,"$1")}l.getDoc().execCommand("FormatBlock",false,h)},mceCleanup:function(){var h=this.editor,i=h.selection,g=i.getBookmark();h.setContent(h.getContent());i.moveToBookmark(g)},mceRemoveNode:function(j,k){var h=this.editor,i=h.selection,g,l=k||i.getNode();if(l==h.getBody()){return}g=i.getBookmark();h.dom.remove(l,1);i.moveToBookmark(g);h.nodeChanged()},mceSelectNodeDepth:function(i,j){var g=this.editor,h=g.selection,k=0;g.dom.getParent(h.getNode(),function(l){if(l.nodeType==1&&k++==j){h.select(l);g.nodeChanged();return false}},g.getBody())},mceSelectNode:function(h,g){this.editor.selection.select(g)},mceInsertContent:function(g,h){this.editor.selection.setContent(h)},mceInsertRawHTML:function(h,i){var g=this.editor;g.selection.setContent("tiny_mce_marker");g.setContent(g.getContent().replace(/tiny_mce_marker/g,i))},mceRepaint:function(){var i,g,j=this.editor;if(d.isGecko){try{i=j.selection;g=i.getBookmark(true);if(i.getSel()){i.getSel().selectAllChildren(j.getBody())}i.collapse(true);i.moveToBookmark(g)}catch(h){}}},queryStateUnderline:function(){var g=this.editor,h=g.selection.getNode();if(h&&h.nodeName=="A"){return false}return this._queryState("Underline")},queryStateOutdent:function(){var g=this.editor,h;if(g.settings.inline_styles){if((h=g.dom.getParent(g.selection.getStart(),g.dom.isBlock))&&parseInt(h.style.paddingLeft)>0){return true}if((h=g.dom.getParent(g.selection.getEnd(),g.dom.isBlock))&&parseInt(h.style.paddingLeft)>0){return true}}return this.queryStateInsertUnorderedList()||this.queryStateInsertOrderedList()||(!g.settings.inline_styles&&!!g.dom.getParent(g.selection.getNode(),"BLOCKQUOTE"))},queryStateInsertUnorderedList:function(){return this.editor.dom.getParent(this.editor.selection.getNode(),"UL")},queryStateInsertOrderedList:function(){return this.editor.dom.getParent(this.editor.selection.getNode(),"OL")},queryStatemceBlockQuote:function(){return !!this.editor.dom.getParent(this.editor.selection.getStart(),function(g){return g.nodeName==="BLOCKQUOTE"})},_applyInlineStyle:function(o,j,m){var q=this,n=q.editor,l=n.dom,i,p={},k,r;o=o.toUpperCase();if(m&&m.check_classes&&j["class"]){m.check_classes.push(j["class"])}function h(){f(l.select(o).reverse(),function(t){var s=0;f(l.getAttribs(t),function(u){if(u.nodeName.substring(0,1)!="_"&&l.getAttrib(t,u.nodeName)!=""){s++}});if(s==0){l.remove(t,1)}})}function g(){var s;f(l.select("span,font"),function(t){if(t.style.fontFamily=="mceinline"||t.face=="mceinline"){if(!s){s=n.selection.getBookmark()}j._mce_new="1";l.replace(l.create(o,j),t,1)}});f(l.select(o+"[_mce_new]"),function(u){function t(v){if(v.nodeType==1){f(j.style,function(x,w){l.setStyle(v,w,"")});if(j["class"]&&v.className&&m){f(m.check_classes,function(w){if(l.hasClass(v,w)){l.removeClass(v,w)}})}}}f(l.select(o,u),t);if(u.parentNode&&u.parentNode.nodeType==1&&u.parentNode.childNodes.length==1){t(u.parentNode)}l.getParent(u.parentNode,function(v){if(v.nodeType==1){if(j.style){f(j.style,function(y,x){var w;if(!p[x]&&(w=l.getStyle(v,x))){if(w===y){l.setStyle(u,x,"")}p[x]=1}})}if(j["class"]&&v.className&&m){f(m.check_classes,function(w){if(l.hasClass(v,w)){l.removeClass(u,w)}})}}return false});u.removeAttribute("_mce_new")});h();n.selection.moveToBookmark(s);return !!s}n.focus();n.getDoc().execCommand("FontName",false,"mceinline");g();if(k=q._applyInlineStyle.keyhandler){n.onKeyUp.remove(k);n.onKeyPress.remove(k);n.onKeyDown.remove(k);n.onSetContent.remove(q._applyInlineStyle.chandler)}if(n.selection.isCollapsed()){if(!c){f(l.getParents(n.selection.getNode(),"span"),function(s){f(j.style,function(u,t){var w;if(w=l.getStyle(s,t)){if(w==u){l.setStyle(s,t,"");r=2;return false}r=1;return false}});if(r){return false}});if(r==2){i=n.selection.getBookmark();h();n.selection.moveToBookmark(i);window.setTimeout(function(){n.nodeChanged()},1);return}}q._pendingStyles=d.extend(q._pendingStyles||{},j.style);q._applyInlineStyle.chandler=n.onSetContent.add(function(){delete q._pendingStyles});q._applyInlineStyle.keyhandler=k=function(s){if(q._pendingStyles){j.style=q._pendingStyles;delete q._pendingStyles}if(g()){n.onKeyDown.remove(q._applyInlineStyle.keyhandler);n.onKeyPress.remove(q._applyInlineStyle.keyhandler)}if(s.type=="keyup"){n.onKeyUp.remove(q._applyInlineStyle.keyhandler)}};n.onKeyDown.add(k);n.onKeyPress.add(k);n.onKeyUp.add(k)}else{q._pendingStyles=0}}})})(tinymce);(function(a){a.create("tinymce.UndoManager",{index:0,data:null,typing:0,UndoManager:function(c){var d=this,b=a.util.Dispatcher;d.editor=c;d.data=[];d.onAdd=new b(this);d.onUndo=new b(this);d.onRedo=new b(this)},add:function(d){var g=this,f,e=g.editor,c,h=e.settings,j;d=d||{};d.content=d.content||e.getContent({format:"raw",no_events:1});d.content=d.content.replace(/^\s*|\s*$/g,"");j=g.data[g.index>0&&(g.index==0||g.index==g.data.length)?g.index-1:g.index];if(!d.initial&&j&&d.content==j.content){return null}if(h.custom_undo_redo_levels){if(g.data.length>h.custom_undo_redo_levels){for(f=0;f<g.data.length-1;f++){g.data[f]=g.data[f+1]}g.data.length--;g.index=g.data.length}}if(h.custom_undo_redo_restore_selection&&!d.initial){d.bookmark=c=d.bookmark||e.selection.getBookmark()}if(g.index<g.data.length){g.index++}if(g.data.length===0&&!d.initial){return null}g.data.length=g.index+1;g.data[g.index++]=d;if(d.initial){g.index=0}if(g.data.length==2&&g.data[0].initial){g.data[0].bookmark=c}g.onAdd.dispatch(g,d);e.isNotDirty=0;return d},undo:function(){var e=this,c=e.editor,b=b,d;if(e.typing){e.add();e.typing=0}if(e.index>0){if(e.index==e.data.length&&e.index>1){d=e.index;e.typing=0;if(!e.add()){e.index=d}--e.index}b=e.data[--e.index];c.setContent(b.content,{format:"raw"});c.selection.moveToBookmark(b.bookmark);e.onUndo.dispatch(e,b)}return b},redo:function(){var d=this,c=d.editor,b=null;if(d.index<d.data.length-1){b=d.data[++d.index];c.setContent(b.content,{format:"raw"});c.selection.moveToBookmark(b.bookmark);d.onRedo.dispatch(d,b)}return b},clear:function(){var b=this;b.data=[];b.index=0;b.typing=0;b.add({initial:true})},hasUndo:function(){return this.index!=0||this.typing},hasRedo:function(){return this.index<this.data.length-1}})})(tinymce);(function(e){var b,d,a,c,f,h;b=e.dom.Event;d=e.isIE;a=e.isGecko;c=e.isOpera;f=e.each;h=e.extend;function g(i){i=i.innerHTML;i=i.replace(/<\w+ .*?mce_\w+\"?=.*?>/gi,"-");i=i.replace(/<(img|hr|table)/gi,"-");i=i.replace(/<[^>]+>/g,"");return i.replace(/[ \t\r\n]+/g,"")==""}e.create("tinymce.ForceBlocks",{ForceBlocks:function(j){var k=this,l=j.settings,m;k.editor=j;k.dom=j.dom;m=(l.forced_root_block||"p").toLowerCase();l.element=m.toUpperCase();j.onPreInit.add(k.setup,k);k.reOpera=new RegExp("(\\u00a0|&#160;|&nbsp;)</"+m+">","gi");k.rePadd=new RegExp("<p( )([^>]+)><\\/p>|<p( )([^>]+)\\/>|<p( )([^>]+)>\\s+<\\/p>|<p><\\/p>|<p\\/>|<p>\\s+<\\/p>".replace(/p/g,m),"gi");k.reNbsp2BR1=new RegExp("<p( )([^>]+)>[\\s\\u00a0]+<\\/p>|<p>[\\s\\u00a0]+<\\/p>".replace(/p/g,m),"gi");k.reNbsp2BR2=new RegExp("<%p()([^>]+)>(&nbsp;|&#160;)<\\/%p>|<%p>(&nbsp;|&#160;)<\\/%p>".replace(/%p/g,m),"gi");k.reBR2Nbsp=new RegExp("<p( )([^>]+)>\\s*<br \\/>\\s*<\\/p>|<p>\\s*<br \\/>\\s*<\\/p>".replace(/p/g,m),"gi");function i(n,p){if(c){p.content=p.content.replace(k.reOpera,"</"+m+">")}p.content=p.content.replace(k.rePadd,"<"+m+"$1$2$3$4$5$6>\u00a0</"+m+">");if(!d&&!c&&p.set){p.content=p.content.replace(k.reNbsp2BR1,"<"+m+"$1$2><br /></"+m+">");p.content=p.content.replace(k.reNbsp2BR2,"<"+m+"$1$2><br /></"+m+">")}else{p.content=p.content.replace(k.reBR2Nbsp,"<"+m+"$1$2>\u00a0</"+m+">")}}j.onBeforeSetContent.add(i);j.onPostProcess.add(i);if(l.forced_root_block){j.onInit.add(k.forceRoots,k);j.onSetContent.add(k.forceRoots,k);j.onBeforeGetContent.add(k.forceRoots,k)}},setup:function(){var j=this,i=j.editor,k=i.settings;if(k.forced_root_block){i.onKeyUp.add(j.forceRoots,j);i.onPreProcess.add(j.forceRoots,j)}if(k.force_br_newlines){if(d){i.onKeyPress.add(function(m,p){var q,o=m.selection;if(p.keyCode==13&&o.getNode().nodeName!="LI"){o.setContent('<br id="__" /> ',{format:"raw"});q=m.dom.get("__");q.removeAttribute("id");o.select(q);o.collapse();return b.cancel(p)}})}return}if(!d&&k.force_p_newlines){i.onKeyPress.add(function(m,n){if(n.keyCode==13&&!n.shiftKey){if(!j.insertPara(n)){b.cancel(n)}}});if(a){i.onKeyDown.add(function(m,n){if((n.keyCode==8||n.keyCode==46)&&!n.shiftKey){j.backspaceDelete(n,n.keyCode==8)}})}}function l(n,m){var o=i.dom.create(m);f(n.attributes,function(p){if(p.specified&&p.nodeValue){o.setAttribute(p.nodeName.toLowerCase(),p.nodeValue)}});f(n.childNodes,function(p){o.appendChild(p.cloneNode(true))});n.parentNode.replaceChild(o,n);return o}if(d){i.onPreProcess.add(function(m,n){f(m.dom.select("p,h1,h2,h3,h4,h5,h6,div",n.node),function(o){if(g(o)){o.innerHTML=""}})});if(k.element!="P"){i.onKeyPress.add(function(m,n){j.lastElm=m.selection.getNode().nodeName});i.onKeyUp.add(function(o,q){var s,p=o.selection,r=p.getNode(),m=o.getBody();if(m.childNodes.length===1&&r.nodeName=="P"){r=l(r,k.element);p.select(r);p.collapse();o.nodeChanged()}else{if(q.keyCode==13&&!q.shiftKey&&j.lastElm!="P"){s=o.dom.getParent(r,"p");if(s){l(s,k.element);o.nodeChanged()}}}})}}},find:function(o,k,l){var j=this.editor,i=j.getDoc().createTreeWalker(o,4,null,false),m=-1;while(o=i.nextNode()){m++;if(k==0&&o==l){return m}if(k==1&&m==l){return o}}return -1},forceRoots:function(p,D){var u=this,p=u.editor,H=p.getBody(),E=p.getDoc(),K=p.selection,v=K.getSel(),w=K.getRng(),I=-2,o,B,j,k,F=-16777215;var G,l,J,A,x,m=H.childNodes,z,y,q;for(z=m.length-1;z>=0;z--){G=m[z];if(G.nodeType==3||(!u.dom.isBlock(G)&&G.nodeType!=8)){if(!l){if(G.nodeType!=3||/[^\s]/g.test(G.nodeValue)){if(I==-2&&w){if(!d){if(w.startContainer.nodeType==1&&(y=w.startContainer.childNodes[w.startOffset])&&y.nodeType==1){q=y.getAttribute("id");y.setAttribute("id","__mce")}else{if(p.dom.getParent(w.startContainer,function(i){return i===H})){B=w.startOffset;j=w.endOffset;I=u.find(H,0,w.startContainer);o=u.find(H,0,w.endContainer)}}}else{k=E.body.createTextRange();k.moveToElementText(H);k.collapse(1);J=k.move("character",F)*-1;k=w.duplicate();k.collapse(1);A=k.move("character",F)*-1;k=w.duplicate();k.collapse(0);x=(k.move("character",F)*-1)-A;I=A-J;o=x}}l=p.dom.create(p.settings.forced_root_block);l.appendChild(G.cloneNode(1));G.parentNode.replaceChild(l,G)}}else{if(l.hasChildNodes()){l.insertBefore(G,l.firstChild)}else{l.appendChild(G)}}}else{l=null}}if(I!=-2){if(!d){l=H.getElementsByTagName(p.settings.element)[0];w=E.createRange();if(I!=-1){w.setStart(u.find(H,1,I),B)}else{w.setStart(l,0)}if(o!=-1){w.setEnd(u.find(H,1,o),j)}else{w.setEnd(l,0)}if(v){v.removeAllRanges();v.addRange(w)}}else{try{w=v.createRange();w.moveToElementText(H);w.collapse(1);w.moveStart("character",I);w.moveEnd("character",o);w.select()}catch(C){}}}else{if(!d&&(y=p.dom.get("__mce"))){if(q){y.setAttribute("id",q)}else{y.removeAttribute("id")}w=E.createRange();w.setStartBefore(y);w.setEndBefore(y);K.setRng(w)}}},getParentBlock:function(j){var i=this.dom;return i.getParent(j,i.isBlock)},insertPara:function(M){var A=this,o=A.editor,I=o.dom,N=o.getDoc(),R=o.settings,B=o.selection.getSel(),C=B.getRangeAt(0),Q=N.body;var F,G,D,K,J,l,j,m,q,i,x,P,k,p,E,H=I.getViewPort(o.getWin()),w,z,v;F=N.createRange();F.setStart(B.anchorNode,B.anchorOffset);F.collapse(true);G=N.createRange();G.setStart(B.focusNode,B.focusOffset);G.collapse(true);D=F.compareBoundaryPoints(F.START_TO_END,G)<0;K=D?B.anchorNode:B.focusNode;J=D?B.anchorOffset:B.focusOffset;l=D?B.focusNode:B.anchorNode;j=D?B.focusOffset:B.anchorOffset;if(K===l&&/^(TD|TH)$/.test(K.nodeName)){I.remove(K.firstChild);o.dom.add(K,R.element,null,"<br />");P=o.dom.add(K,R.element,null,"<br />");C=N.createRange();C.selectNodeContents(P);C.collapse(1);o.selection.setRng(C);return false}if(K==Q&&l==Q&&Q.firstChild&&o.dom.isBlock(Q.firstChild)){K=l=K.firstChild;J=j=0;F=N.createRange();F.setStart(K,0);G=N.createRange();G.setStart(l,0)}K=K.nodeName=="HTML"?N.body:K;K=K.nodeName=="BODY"?K.firstChild:K;l=l.nodeName=="HTML"?N.body:l;l=l.nodeName=="BODY"?l.firstChild:l;m=A.getParentBlock(K);q=A.getParentBlock(l);i=m?m.nodeName:R.element;if(A.dom.getParent(m,"ol,ul,pre")){return true}if(m&&(m.nodeName=="CAPTION"||/absolute|relative|fixed/gi.test(I.getStyle(m,"position",1)))){i=R.element;m=null}if(q&&(q.nodeName=="CAPTION"||/absolute|relative|fixed/gi.test(I.getStyle(m,"position",1)))){i=R.element;q=null}if(/(TD|TABLE|TH|CAPTION)/.test(i)||(m&&i=="DIV"&&/left|right/gi.test(I.getStyle(m,"float",1)))){i=R.element;m=q=null}x=(m&&m.nodeName==i)?m.cloneNode(0):o.dom.create(i);P=(q&&q.nodeName==i)?q.cloneNode(0):o.dom.create(i);P.removeAttribute("id");if(/^(H[1-6])$/.test(i)&&K.nodeValue&&J==K.nodeValue.length){P=o.dom.create(R.element)}E=k=K;do{if(E==Q||E.nodeType==9||A.dom.isBlock(E)||/(TD|TABLE|TH|CAPTION)/.test(E.nodeName)){break}k=E}while((E=E.previousSibling?E.previousSibling:E.parentNode));E=p=l;do{if(E==Q||E.nodeType==9||A.dom.isBlock(E)||/(TD|TABLE|TH|CAPTION)/.test(E.nodeName)){break}p=E}while((E=E.nextSibling?E.nextSibling:E.parentNode));if(k.nodeName==i){F.setStart(k,0)}else{F.setStartBefore(k)}F.setEnd(K,J);x.appendChild(F.cloneContents()||N.createTextNode(""));try{G.setEndAfter(p)}catch(L){}G.setStart(l,j);P.appendChild(G.cloneContents()||N.createTextNode(""));C=N.createRange();if(!k.previousSibling&&k.parentNode.nodeName==i){C.setStartBefore(k.parentNode)}else{if(F.startContainer.nodeName==i&&F.startOffset==0){C.setStartBefore(F.startContainer)}else{C.setStart(F.startContainer,F.startOffset)}}if(!p.nextSibling&&p.parentNode.nodeName==i){C.setEndAfter(p.parentNode)}else{C.setEnd(G.endContainer,G.endOffset)}C.deleteContents();if(c){o.getWin().scrollTo(0,H.y)}if(x.firstChild&&x.firstChild.nodeName==i){x.innerHTML=x.firstChild.innerHTML}if(P.firstChild&&P.firstChild.nodeName==i){P.innerHTML=P.firstChild.innerHTML}if(g(x)){x.innerHTML="<br />"}function O(y,s){var r=[],T,S,t;y.innerHTML="";if(R.keep_styles){S=s;do{if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(S.nodeName)){T=S.cloneNode(false);I.setAttrib(T,"id","");r.push(T)}}while(S=S.parentNode)}if(r.length>0){for(t=r.length-1,T=y;t>=0;t--){T=T.appendChild(r[t])}r[0].innerHTML=c?"&nbsp;":"<br />";return r[0]}else{y.innerHTML=c?"&nbsp;":"<br />"}}if(g(P)){v=O(P,l)}if(c&&parseFloat(opera.version())<9.5){C.insertNode(x);C.insertNode(P)}else{C.insertNode(P);C.insertNode(x)}P.normalize();x.normalize();function u(r){return N.createTreeWalker(r,NodeFilter.SHOW_TEXT,null,false).nextNode()||r}C=N.createRange();C.selectNodeContents(a?u(v||P):v||P);C.collapse(1);B.removeAllRanges();B.addRange(C);w=o.dom.getPos(P).y;z=P.clientHeight;if(w<H.y||w+z>H.y+H.h){o.getWin().scrollTo(0,w<H.y?w:w-H.h+25)}return false},backspaceDelete:function(l,u){var x=this,k=x.editor,p=k.getBody(),j,m=k.selection,i=m.getRng(),o=i.startContainer,j,q,s;if(o&&k.dom.isBlock(o)&&!/^(TD|TH)$/.test(o.nodeName)&&u){if(o.childNodes.length==0||(o.childNodes.length==1&&o.firstChild.nodeName=="BR")){j=o;while((j=j.previousSibling)&&!k.dom.isBlock(j)){}if(j){if(o!=p.firstChild){q=k.dom.doc.createTreeWalker(j,NodeFilter.SHOW_TEXT,null,false);while(s=q.nextNode()){j=s}i=k.getDoc().createRange();i.setStart(j,j.nodeValue?j.nodeValue.length:0);i.setEnd(j,j.nodeValue?j.nodeValue.length:0);m.setRng(i);k.dom.remove(o)}return b.cancel(l)}}}function v(n){var r;n=n.target;if(n&&n.parentNode&&n.nodeName=="BR"&&(j=x.getParentBlock(n))){r=n.previousSibling;b.remove(p,"DOMNodeInserted",v);if(r&&r.nodeType==3&&/\s+$/.test(r.nodeValue)){return}if(n.previousSibling||n.nextSibling){k.dom.remove(n)}}}b._add(p,"DOMNodeInserted",v);window.setTimeout(function(){b._remove(p,"DOMNodeInserted",v)},1)}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each,e=c.extend;c.create("tinymce.ControlManager",{ControlManager:function(f,j){var h=this,g;j=j||{};h.editor=f;h.controls={};h.onAdd=new c.util.Dispatcher(h);h.onPostRender=new c.util.Dispatcher(h);h.prefix=j.prefix||f.id+"_";h._cls={};h.onPostRender.add(function(){d(h.controls,function(i){i.postRender()})})},get:function(f){return this.controls[this.prefix+f]||this.controls[f]},setActive:function(h,f){var g=null;if(g=this.get(h)){g.setActive(f)}return g},setDisabled:function(h,f){var g=null;if(g=this.get(h)){g.setDisabled(f)}return g},add:function(g){var f=this;if(g){f.controls[g.id]=g;f.onAdd.dispatch(g,f)}return g},createControl:function(i){var h,g=this,f=g.editor;d(f.plugins,function(j){if(j.createControl){h=j.createControl(i,g);if(h){return false}}});switch(i){case"|":case"separator":return g.createSeparator()}if(!h&&f.buttons&&(h=f.buttons[i])){return g.createButton(i,h)}return g.add(h)},createDropMenu:function(f,n,h){var m=this,i=m.editor,j,g,k,l;n=e({"class":"mceDropDown",constrain:i.settings.constrain_menus},n);n["class"]=n["class"]+" "+i.getParam("skin")+"Skin";if(k=i.getParam("skin_variant")){n["class"]+=" "+i.getParam("skin")+"Skin"+k.substring(0,1).toUpperCase()+k.substring(1)}f=m.prefix+f;l=h||m._cls.dropmenu||c.ui.DropMenu;j=m.controls[f]=new l(f,n);j.onAddItem.add(function(r,q){var p=q.settings;p.title=i.getLang(p.title,p.title);if(!p.onclick){p.onclick=function(o){i.execCommand(p.cmd,p.ui||false,p.value)}}});i.onRemove.add(function(){j.destroy()});if(c.isIE){j.onShowMenu.add(function(){i.focus();g=i.selection.getBookmark(1)});j.onHideMenu.add(function(){if(g){i.selection.moveToBookmark(g);g=0}})}return m.add(j)},createListBox:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.scope=i.scope||g;if(!i.onselect){i.onselect=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}i=e({title:i.title,"class":"mce_"+m,scope:i.scope,control_manager:h},i);m=h.prefix+m;if(g.settings.use_native_selects){k=new c.ui.NativeListBox(m,i)}else{f=l||h._cls.listbox||c.ui.ListBox;k=new f(m,i)}h.controls[m]=k;if(c.isWebKit){k.onPostRender.add(function(p,o){a.add(o,"mousedown",function(){g.bookmark=g.selection.getBookmark("simple")});a.add(o,"focus",function(){g.selection.moveToBookmark(g.bookmark);g.bookmark=null})})}if(k.hideMenu){g.onMouseDown.add(k.hideMenu,k)}return h.add(k)},createButton:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.label=g.translate(i.label);i.scope=i.scope||g;if(!i.onclick&&!i.menu_button){i.onclick=function(){g.execCommand(i.cmd,i.ui||false,i.value)}}i=e({title:i.title,"class":"mce_"+m,unavailable_prefix:g.getLang("unavailable",""),scope:i.scope,control_manager:h},i);m=h.prefix+m;if(i.menu_button){f=l||h._cls.menubutton||c.ui.MenuButton;k=new f(m,i);g.onMouseDown.add(k.hideMenu,k)}else{f=h._cls.button||c.ui.Button;k=new f(m,i)}return h.add(k)},createMenuButton:function(h,f,g){f=f||{};f.menu_button=1;return this.createButton(h,f,g)},createSplitButton:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.scope=i.scope||g;if(!i.onclick){i.onclick=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}if(!i.onselect){i.onselect=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}i=e({title:i.title,"class":"mce_"+m,scope:i.scope,control_manager:h},i);m=h.prefix+m;f=l||h._cls.splitbutton||c.ui.SplitButton;k=h.add(new f(m,i));g.onMouseDown.add(k.hideMenu,k);return k},createColorSplitButton:function(f,n,h){var l=this,j=l.editor,i,k,m,g;if(l.get(f)){return null}n.title=j.translate(n.title);n.scope=n.scope||j;if(!n.onclick){n.onclick=function(o){if(c.isIE){g=j.selection.getBookmark(1)}j.execCommand(n.cmd,n.ui||false,o||n.value)}}if(!n.onselect){n.onselect=function(o){j.execCommand(n.cmd,n.ui||false,o||n.value)}}n=e({title:n.title,"class":"mce_"+f,menu_class:j.getParam("skin")+"Skin",scope:n.scope,more_colors_title:j.getLang("more_colors")},n);f=l.prefix+f;m=h||l._cls.colorsplitbutton||c.ui.ColorSplitButton;k=new m(f,n);j.onMouseDown.add(k.hideMenu,k);j.onRemove.add(function(){k.destroy()});if(c.isIE){k.onHideMenu.add(function(){if(g){j.selection.moveToBookmark(g);g=0}})}return l.add(k)},createToolbar:function(k,h,j){var i,g=this,f;k=g.prefix+k;f=j||g._cls.toolbar||c.ui.Toolbar;i=new f(k,h);if(g.get(k)){return null}return g.add(i)},createSeparator:function(g){var f=g||this._cls.separator||c.ui.Separator;return new f()},setControlType:function(g,f){return this._cls[g.toLowerCase()]=f},destroy:function(){d(this.controls,function(f){f.destroy()});this.controls=null}})})(tinymce);(function(d){var a=d.util.Dispatcher,e=d.each,c=d.isIE,b=d.isOpera;d.create("tinymce.WindowManager",{WindowManager:function(f){var g=this;g.editor=f;g.onOpen=new a(g);g.onClose=new a(g);g.params={};g.features={}},open:function(z,h){var v=this,k="",n,m,i=v.editor.settings.dialog_type=="modal",q,o,j,g=d.DOM.getViewPort(),r;z=z||{};h=h||{};o=b?g.w:screen.width;j=b?g.h:screen.height;z.name=z.name||"mc_"+new Date().getTime();z.width=parseInt(z.width||320);z.height=parseInt(z.height||240);z.resizable=true;z.left=z.left||parseInt(o/2)-(z.width/2);z.top=z.top||parseInt(j/2)-(z.height/2);h.inline=false;h.mce_width=z.width;h.mce_height=z.height;h.mce_auto_focus=z.auto_focus;if(i){if(c){z.center=true;z.help=false;z.dialogWidth=z.width+"px";z.dialogHeight=z.height+"px";z.scroll=z.scrollbars||false}}e(z,function(p,f){if(d.is(p,"boolean")){p=p?"yes":"no"}if(!/^(name|url)$/.test(f)){if(c&&i){k+=(k?";":"")+f+":"+p}else{k+=(k?",":"")+f+"="+p}}});v.features=z;v.params=h;v.onOpen.dispatch(v,z,h);r=z.url||z.file;r=d._addVer(r);try{if(c&&i){q=1;window.showModalDialog(r,window,k)}else{q=window.open(r,z.name,k)}}catch(l){}if(!q){alert(v.editor.getLang("popup_blocked"))}},close:function(f){f.close();this.onClose.dispatch(this)},createInstance:function(i,h,g,m,l,k){var j=d.resolve(i);return new j(h,g,m,l,k)},confirm:function(h,f,i,g){g=g||window;f.call(i||this,g.confirm(this._decode(this.editor.getLang(h,h))))},alert:function(h,f,j,g){var i=this;g=g||window;g.alert(i._decode(i.editor.getLang(h,h)));if(f){f.call(j||i)}},_decode:function(f){return d.DOM.decode(f).replace(/\\n/g,"\n")}})}(tinymce));(function(a){a.CommandManager=function(){var c={},b={},d={};function e(i,h,g,f){if(typeof(h)=="string"){h=[h]}a.each(h,function(j){i[j.toLowerCase()]={func:g,scope:f}})}a.extend(this,{add:function(h,g,f){e(c,h,g,f)},addQueryStateHandler:function(h,g,f){e(b,h,g,f)},addQueryValueHandler:function(h,g,f){e(d,h,g,f)},execCommand:function(g,j,i,h,f){if(j=c[j.toLowerCase()]){if(j.func.call(g||j.scope,i,h,f)!==false){return true}}},queryCommandValue:function(){if(cmd=d[cmd.toLowerCase()]){return cmd.func.call(scope||cmd.scope,ui,value,args)}},queryCommandState:function(){if(cmd=b[cmd.toLowerCase()]){return cmd.func.call(scope||cmd.scope,ui,value,args)}}})};a.GlobalCommands=new a.CommandManager()})(tinymce);(function(b){function a(i,d,h,m){var j,g,e,l,f;function k(p,o){do{if(p.parentNode==o){return p}p=p.parentNode}while(p)}function c(o){m(o);b.walk(o,m,"childNodes")}j=i.findCommonAncestor(d,h);e=k(d,j)||d;l=k(h,j)||h;for(g=d;g&&g!=e;g=g.parentNode){for(f=g.nextSibling;f;f=f.nextSibling){c(f)}}if(e!=l){for(g=e.nextSibling;g&&g!=l;g=g.nextSibling){c(g)}}else{c(e)}for(g=h;g&&g!=l;g=g.parentNode){for(f=g.previousSibling;f;f=f.previousSibling){c(f)}}}b.GlobalCommands.add("RemoveFormat",function(){var m=this,l=m.dom,u=m.selection,d=u.getRng(1),e=[],h,f,j,q,g,o,c,i;function k(s){var r;l.getParent(s,function(v){if(l.is(v,m.getParam("removeformat_selector"))){r=v}return l.isBlock(v)},m.getBody());return r}function p(r){if(l.is(r,m.getParam("removeformat_selector"))){e.push(r)}}function t(r){p(r);b.walk(r,p,"childNodes")}h=u.getBookmark();q=d.startContainer;o=d.endContainer;g=d.startOffset;c=d.endOffset;q=q.nodeType==1?q.childNodes[Math.min(g,q.childNodes.length-1)]:q;o=o.nodeType==1?o.childNodes[Math.min(g==c?c:c-1,o.childNodes.length-1)]:o;if(q==o){f=k(q);if(q.nodeType==3){if(f&&f.nodeType==1){i=q.splitText(g);i.splitText(c-g);l.split(f,i);u.moveToBookmark(h)}return}t(l.split(f,q)||q)}else{f=k(q);j=k(o);if(f){if(q.nodeType==3){if(g==q.nodeValue.length){q.nodeValue+="\uFEFF"}q=q.splitText(g)}}if(j){if(o.nodeType==3){o.splitText(c)}}if(f&&f==j){l.replace(l.create("span",{id:"__end"},o.cloneNode(true)),o)}if(f){f=l.split(f,q)}else{f=q}if(i=l.get("__end")){o=i;j=k(o)}if(j){j=l.split(j,o)}else{j=o}a(l,f,j,p);if(q.nodeValue=="\uFEFF"){q.nodeValue=""}t(o);t(q)}b.each(e,function(r){l.remove(r,1)});l.remove("__end",1);u.moveToBookmark(h)})})(tinymce);(function(a){a.GlobalCommands.add("mceBlockQuote",function(){var j=this,o=j.selection,f=j.dom,l,k,e,d,p,c,m,h,b;function g(i){return f.getParent(i,function(q){return q.nodeName==="BLOCKQUOTE"})}l=f.getParent(o.getStart(),f.isBlock);k=f.getParent(o.getEnd(),f.isBlock);if(p=g(l)){if(l!=k||l.childNodes.length>1||(l.childNodes.length==1&&l.firstChild.nodeName!="BR")){d=o.getBookmark()}if(g(k)){m=p.cloneNode(false);while(e=k.nextSibling){m.appendChild(e.parentNode.removeChild(e))}}if(m){f.insertAfter(m,p)}b=o.getSelectedBlocks(l,k);for(h=b.length-1;h>=0;h--){f.insertAfter(b[h],p)}if(/^\s*$/.test(p.innerHTML)){f.remove(p,1)}if(m&&/^\s*$/.test(m.innerHTML)){f.remove(m,1)}if(!d){if(!a.isIE){c=j.getDoc().createRange();c.setStart(l,0);c.setEnd(l,0);o.setRng(c)}else{o.select(l);o.collapse(0);if(f.getParent(o.getStart(),f.isBlock)!=l){c=o.getRng();c.move("character",-1);c.select()}}}else{j.selection.moveToBookmark(d)}return}if(a.isIE&&!l&&!k){j.getDoc().execCommand("Indent");e=g(o.getNode());e.style.margin=e.dir="";return}if(!l||!k){return}if(l!=k||l.childNodes.length>1||(l.childNodes.length==1&&l.firstChild.nodeName!="BR")){d=o.getBookmark()}a.each(o.getSelectedBlocks(g(o.getStart()),g(o.getEnd())),function(i){if(i.nodeName=="BLOCKQUOTE"&&!p){p=i;return}if(!p){p=f.create("blockquote");i.parentNode.insertBefore(p,i)}if(i.nodeName=="BLOCKQUOTE"&&p){e=i.firstChild;while(e){p.appendChild(e.cloneNode(true));e=e.nextSibling}f.remove(i);return}p.appendChild(f.remove(i))});if(!d){if(!a.isIE){c=j.getDoc().createRange();c.setStart(l,0);c.setEnd(l,0);o.setRng(c)}else{o.select(l);o.collapse(1)}}else{o.moveToBookmark(d)}})})(tinymce);(function(a){a.each(["Cut","Copy","Paste"],function(b){a.GlobalCommands.add(b,function(){var c=this,e=c.getDoc();try{e.execCommand(b,false,null);if(!e.queryCommandSupported(b)){throw"Error"}}catch(d){c.windowManager.alert(c.getLang("clipboard_no_support"))}})})})(tinymce);(function(a){a.GlobalCommands.add("InsertHorizontalRule",function(){if(a.isOpera){return this.getDoc().execCommand("InsertHorizontalRule",false,"")}this.selection.setContent("<hr />")})})(tinymce);(function(){var a=tinymce.GlobalCommands;a.add(["mceEndUndoLevel","mceAddUndoLevel"],function(){this.undoManager.add()});a.add("Undo",function(){var b=this;if(b.settings.custom_undo_redo){b.undoManager.undo();b.nodeChanged();return true}return false});a.add("Redo",function(){var b=this;if(b.settings.custom_undo_redo){b.undoManager.redo();b.nodeChanged();return true}return false})})();
\ No newline at end of file
index 09345eaac21d68650dd30c8503c8c0079881ab36..d235abd58637e82302ad2f3edbca41abfebad9a3 100644 (file)
@@ -1,275 +1,5 @@
-// Some global instances\r
-var tinymce = null, tinyMCEPopup, tinyMCE;\r
-\r
-tinyMCEPopup = {\r
-       init : function() {\r
-               var t = this, w, ti, li, q, i, it;\r
-\r
-               li = ('' + document.location.search).replace(/^\?/, '').split('&');\r
-               q = {};\r
-               for (i=0; i<li.length; i++) {\r
-                       it = li[i].split('=');\r
-                       q[unescape(it[0])] = unescape(it[1]);\r
-               }\r
-\r
-               if (q.mce_rdomain)\r
-                       document.domain = q.mce_rdomain;\r
-\r
-               // Find window & API\r
-               w = t.getWin();\r
-               tinymce = w.tinymce;\r
-               tinyMCE = w.tinyMCE;\r
-               t.editor = tinymce.EditorManager.activeEditor;\r
-               t.params = t.editor.windowManager.params;\r
-\r
-               // Setup local DOM\r
-               t.dom = t.editor.windowManager.createInstance('tinymce.dom.DOMUtils', document);\r
-               t.dom.loadCSS(t.editor.settings.popup_css);\r
-\r
-               // Setup on init listeners\r
-               t.listeners = [];\r
-               t.onInit = {\r
-                       add : function(f, s) {\r
-                               t.listeners.push({func : f, scope : s});\r
-                       }\r
-               };\r
-\r
-               t.isWindow = !t.getWindowArg('mce_inline');\r
-               t.id = t.getWindowArg('mce_window_id');\r
-               t.editor.windowManager.onOpen.dispatch(t.editor.windowManager, window);\r
-       },\r
-\r
-       getWin : function() {\r
-               return window.dialogArguments || opener || parent || top;\r
-       },\r
-\r
-       getWindowArg : function(n, dv) {\r
-               var v = this.params[n];\r
-\r
-               return tinymce.is(v) ? v : dv;\r
-       },\r
-\r
-       getParam : function(n, dv) {\r
-               return this.editor.getParam(n, dv);\r
-       },\r
-\r
-       getLang : function(n, dv) {\r
-               return this.editor.getLang(n, dv);\r
-       },\r
-\r
-       execCommand : function(cmd, ui, val, a) {\r
-               a = a || {};\r
-               a.skip_focus = 1;\r
-\r
-               this.restoreSelection();\r
-               return this.editor.execCommand(cmd, ui, val, a);\r
-       },\r
-\r
-       resizeToInnerSize : function() {\r
-               var t = this, n, b = document.body, vp = t.dom.getViewPort(window), dw, dh;\r
-\r
-               dw = t.getWindowArg('mce_width') - vp.w;\r
-               dh = t.getWindowArg('mce_height') - vp.h;\r
-\r
-               if (t.isWindow)\r
-                       window.resizeBy(dw, dh);\r
-               else\r
-                       t.editor.windowManager.resizeBy(dw, dh, t.id);\r
-       },\r
-\r
-       executeOnLoad : function(s) {\r
-               this.onInit.add(function() {\r
-                       eval(s);\r
-               });\r
-       },\r
-\r
-       storeSelection : function() {\r
-               this.editor.windowManager.bookmark = tinyMCEPopup.editor.selection.getBookmark('simple');\r
-       },\r
-\r
-       restoreSelection : function() {\r
-               var t = tinyMCEPopup;\r
-\r
-               if (!t.isWindow && tinymce.isIE)\r
-                       t.editor.selection.moveToBookmark(t.editor.windowManager.bookmark);\r
-       },\r
-\r
-       requireLangPack : function() {\r
-               var u = this.getWindowArg('plugin_url') || this.getWindowArg('theme_url');\r
-\r
-               if (u && this.editor.settings.language) {\r
-                       u += '/langs/' + this.editor.settings.language + '_dlg.js';\r
-\r
-                       if (!tinymce.ScriptLoader.isDone(u)) {\r
-                               document.write('<script type="text/javascript" src="' + tinymce._addVer(u) + '"></script>');\r
-                               tinymce.ScriptLoader.markDone(u);\r
-                       }\r
-               }\r
-       },\r
-\r
-       pickColor : function(e, element_id) {\r
-               this.execCommand('mceColorPicker', true, {\r
-                       color : document.getElementById(element_id).value,\r
-                       func : function(c) {\r
-                               document.getElementById(element_id).value = c;\r
-\r
-                               try {\r
-                                       document.getElementById(element_id).onchange();\r
-                               } catch (ex) {\r
-                                       // Try fire event, ignore errors\r
-                               }\r
-                       }\r
-               });\r
-       },\r
-\r
-       openBrowser : function(element_id, type, option) {\r
-               tinyMCEPopup.restoreSelection();\r
-               this.editor.execCallback('file_browser_callback', element_id, document.getElementById(element_id).value, type, window);\r
-       },\r
-\r
-       close : function() {\r
-               var t = this;\r
-\r
-               // To avoid domain relaxing issue in Opera\r
-               function close() {\r
-                       t.editor.windowManager.close(window);\r
-                       tinymce = tinyMCE = t.editor = t.params = t.dom = t.dom.doc = null; // Cleanup\r
-               };\r
-\r
-               if (tinymce.isOpera)\r
-                       t.getWin().setTimeout(close, 0);\r
-               else\r
-                       close();\r
-       },\r
-\r
-       // Internal functions   \r
-\r
-       _restoreSelection : function() {\r
-               var e = window.event.srcElement;\r
-\r
-               if (e.nodeName == 'INPUT' && (e.type == 'submit' || e.type == 'button'))\r
-                       tinyMCEPopup.restoreSelection();\r
-       },\r
-\r
-/*     _restoreSelection : function() {\r
-               var e = window.event.srcElement;\r
-\r
-               // If user focus a non text input or textarea\r
-               if ((e.nodeName != 'INPUT' && e.nodeName != 'TEXTAREA') || e.type != 'text')\r
-                       tinyMCEPopup.restoreSelection();\r
-       },*/\r
-\r
-       _onDOMLoaded : function() {\r
-               var t = this, ti = document.title, bm, h;\r
-\r
-               // Translate page\r
-               h = document.body.innerHTML;\r
-\r
-               // Replace a=x with a="x" in IE\r
-               if (tinymce.isIE)\r
-                       h = h.replace(/ (value|title|alt)=([^"][^\s>]+)/gi, ' $1="$2"')\r
-\r
-               document.dir = t.editor.getParam('directionality','');\r
-               document.body.innerHTML = t.editor.translate(h);\r
-               document.title = ti = t.editor.translate(ti);\r
-               document.body.style.display = '';\r
-\r
-               // Restore selection in IE when focus is placed on a non textarea or input element of the type text\r
-               if (tinymce.isIE)\r
-                       document.attachEvent('onmouseup', tinyMCEPopup._restoreSelection);\r
-\r
-               t.restoreSelection();\r
-               t.resizeToInnerSize();\r
-\r
-               // Set inline title\r
-               if (!t.isWindow)\r
-                       t.editor.windowManager.setTitle(window, ti);\r
-               else\r
-                       window.focus();\r
-\r
-               if (!tinymce.isIE && !t.isWindow) {\r
-                       tinymce.dom.Event._add(document, 'focus', function() {\r
-                               t.editor.windowManager.focus(t.id)\r
-                       });\r
-               }\r
-\r
-               // Patch for accessibility\r
-               tinymce.each(t.dom.select('select'), function(e) {\r
-                       e.onkeydown = tinyMCEPopup._accessHandler;\r
-               });\r
-\r
-               // Call onInit\r
-               // Init must be called before focus so the selection won't get lost by the focus call\r
-               tinymce.each(t.listeners, function(o) {\r
-                       o.func.call(o.scope, t.editor);\r
-               });\r
-\r
-               // Move focus to window\r
-               if (t.getWindowArg('mce_auto_focus', true)) {\r
-                       window.focus();\r
-\r
-                       // Focus element with mceFocus class\r
-                       tinymce.each(document.forms, function(f) {\r
-                               tinymce.each(f.elements, function(e) {\r
-                                       if (t.dom.hasClass(e, 'mceFocus') && !e.disabled) {\r
-                                               e.focus();\r
-                                               return false; // Break loop\r
-                                       }\r
-                               });\r
-                       });\r
-               }\r
-\r
-               document.onkeyup = tinyMCEPopup._closeWinKeyHandler;\r
-       },\r
-\r
-       _accessHandler : function(e) {\r
-               e = e || window.event;\r
-\r
-               if (e.keyCode == 13 || e.keyCode == 32) {\r
-                       e = e.target || e.srcElement;\r
-\r
-                       if (e.onchange)\r
-                               e.onchange();\r
-\r
-                       return tinymce.dom.Event.cancel(e);\r
-               }\r
-       },\r
-\r
-       _closeWinKeyHandler : function(e) {\r
-               e = e || window.event;\r
-\r
-               if (e.keyCode == 27)\r
-                       tinyMCEPopup.close();\r
-       },\r
-\r
-       _wait : function() {\r
-               var t = this, ti;\r
-\r
-               if (tinymce.isIE && document.location.protocol != 'https:') {\r
-                       // Fake DOMContentLoaded on IE\r
-                       document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');\r
-                       document.getElementById("__ie_onload").onreadystatechange = function() {\r
-                               if (this.readyState == "complete") {\r
-                                       t._onDOMLoaded();\r
-                                       document.getElementById("__ie_onload").onreadystatechange = null; // Prevent leak\r
-                               }\r
-                       };\r
-               } else {\r
-                       if (tinymce.isIE || tinymce.isWebKit) {\r
-                               ti = setInterval(function() {\r
-                                       if (/loaded|complete/.test(document.readyState)) {\r
-                                               clearInterval(ti);\r
-                                               t._onDOMLoaded();\r
-                                       }\r
-                               }, 10);\r
-                       } else {\r
-                               window.addEventListener('DOMContentLoaded', function() {\r
-                                       t._onDOMLoaded();\r
-                               }, false);\r
-                       }\r
-               }\r
-       }\r
-};\r
-\r
-tinyMCEPopup.init();\r
-tinyMCEPopup._wait(); // Wait for DOM Content Loaded\r
+
+// 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.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 e=this,g,a=document.body,c=e.dom.getViewPort(window),d,f;d=e.getWindowArg("mce_width")-c.w;f=e.getWindowArg("mce_height")-c.h;if(e.isWindow){window.resizeBy(d,f)}else{e.editor.windowManager.resizeBy(d,f,e.id)}},executeOnLoad:function(s){this.onInit.add(function(){eval(s)})},storeSelection:function(){this.editor.windowManager.bookmark=tinyMCEPopup.editor.selection.getBookmark("simple")},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
index eeaab3b1e4643b979022361cf7b1cddb5d699c0c..48384991576f30173e4f68eb64106f4634ee87a9 100644 (file)
@@ -1,10 +1,7 @@
-\r
-/* file:jscripts/tiny_mce/classes/tinymce.js */\r
-\r
 var tinymce = {\r
        majorVersion : '3',\r
-       minorVersion : '1.0.1',\r
-       releaseDate : '2008-06-18',\r
+       minorVersion : '2.3',\r
+       releaseDate : '2009-04-23',\r
 \r
        _init : function() {\r
                var t = this, d = document, w = window, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;\r
@@ -12,11 +9,11 @@ var tinymce = {
                // Browser checks\r
                t.isOpera = w.opera && opera.buildNumber;\r
                t.isWebKit = /WebKit/.test(ua);\r
-               t.isOldWebKit = t.isWebKit && !w.getSelection().getRangeAt;\r
                t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);\r
                t.isIE6 = t.isIE && /MSIE [56]/.test(ua);\r
                t.isGecko = !t.isWebKit && /Gecko/.test(ua);\r
                t.isMac = ua.indexOf('Mac') != -1;\r
+               t.isAir = /adobeair/i.test(ua);\r
 \r
                // TinyMCE .NET webcontrol might be setting the values for TinyMCE\r
                if (w.tinyMCEPreInit) {\r
@@ -87,13 +84,12 @@ var tinymce = {
                if (!t)\r
                        return n != 'undefined';\r
 \r
-               if (t == 'array' && (o instanceof Array))\r
+               if (t == 'array' && (o.hasOwnProperty && o instanceof Array))\r
                        return true;\r
 \r
                return n == t;\r
        },\r
 \r
-       // #if !jquery\r
 \r
        each : function(o, cb, s) {\r
                var n, l;\r
@@ -175,7 +171,6 @@ var tinymce = {
                return (s ? '' + s : '').replace(/^\s*|\s*$/g, '');\r
        },\r
 \r
-       // #endif\r
 \r
        create : function(s, p) {\r
                var t = this, sp, ns, cn, scn, c, de = 0;\r
@@ -337,7 +332,7 @@ var tinymce = {
                                                w.removeEventListener('unload', unload, false);\r
 \r
                                        // Destroy references\r
-                                       t.unloads = o = li = w = unload = null;\r
+                                       t.unloads = o = li = w = unload = 0;\r
 \r
                                        // Run garbarge collector on IE\r
                                        if (window.CollectGarbage)\r
@@ -355,19 +350,22 @@ var tinymce = {
                                                d.detachEvent('onstop', stop);\r
 \r
                                                // Call unload handler\r
-                                               unload();\r
+                                               if (unload)\r
+                                                       unload();\r
 \r
-                                               d = null;\r
+                                               d = 0;\r
                                        };\r
 \r
                                        // Fire unload when the currently loading page is stopped\r
-                                       d.attachEvent('onstop', stop);\r
+                                       if (d)\r
+                                               d.attachEvent('onstop', stop);\r
 \r
                                        // Remove onstop listener after a while to prevent the unload function\r
                                        // to execute if the user presses cancel in an onbeforeunload\r
                                        // confirm dialog and then presses the browser stop button\r
                                        window.setTimeout(function() {\r
-                                               d.detachEvent('onstop', stop);\r
+                                               if (d)\r
+                                                       d.detachEvent('onstop', stop);\r
                                        }, 0);\r
                                }\r
                        };\r
@@ -426,15 +424,6 @@ window.tinymce = tinymce;
 \r
 // Initialize the API\r
 tinymce._init();\r
-\r
-/* file:jscripts/tiny_mce/classes/adapter/jquery/adapter.js */\r
-\r
-\r
-/* file:jscripts/tiny_mce/classes/adapter/prototype/adapter.js */\r
-\r
-\r
-/* file:jscripts/tiny_mce/classes/util/Dispatcher.js */\r
-\r
 tinymce.create('tinymce.util.Dispatcher', {\r
        scope : null,\r
        listeners : null,\r
@@ -487,9 +476,6 @@ tinymce.create('tinymce.util.Dispatcher', {
        }\r
 \r
        });\r
-\r
-/* file:jscripts/tiny_mce/classes/util/URI.js */\r
-\r
 (function() {\r
        var each = tinymce.each;\r
 \r
@@ -501,7 +487,7 @@ tinymce.create('tinymce.util.Dispatcher', {
                        s = t.settings = s || {};\r
 \r
                        // Strange app protocol or local anchor\r
-                       if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {\r
+                       if (/^(mailto|tel|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) {\r
                                t.source = u;\r
                                return;\r
                        }\r
@@ -511,7 +497,7 @@ tinymce.create('tinymce.util.Dispatcher', {
                                u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;\r
 \r
                        // Relative path\r
-                       if (u.indexOf('://') === -1 && u.indexOf('//') !== 0)\r
+                       if (u.indexOf(':/') === -1 && u.indexOf('//') !== 0)\r
                                u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u);\r
 \r
                        // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri)\r
@@ -564,6 +550,9 @@ tinymce.create('tinymce.util.Dispatcher', {
                toRelative : function(u) {\r
                        var t = this, o;\r
 \r
+                       if (u === "./")\r
+                               return u;\r
+\r
                        u = new tinymce.util.URI(u, {base_uri : t});\r
 \r
                        // Not on same domain/port or protocol\r
@@ -590,7 +579,7 @@ tinymce.create('tinymce.util.Dispatcher', {
                },\r
 \r
                toRelPath : function(base, path) {\r
-                       var items, bp = 0, out = '', i;\r
+                       var items, bp = 0, out = '', i, l;\r
 \r
                        // Split the paths\r
                        base = base.substring(0, base.lastIndexOf('/'));\r
@@ -598,7 +587,7 @@ tinymce.create('tinymce.util.Dispatcher', {
                        items = path.split('/');\r
 \r
                        if (base.length >= items.length) {\r
-                               for (i = 0; i < base.length; i++) {\r
+                               for (i = 0, l = base.length; i < l; i++) {\r
                                        if (i >= items.length || base[i] != items[i]) {\r
                                                bp = i + 1;\r
                                                break;\r
@@ -607,7 +596,7 @@ tinymce.create('tinymce.util.Dispatcher', {
                        }\r
 \r
                        if (base.length < items.length) {\r
-                               for (i = 0; i < items.length; i++) {\r
+                               for (i = 0, l = items.length; i < l; i++) {\r
                                        if (i >= base.length || base[i] != items[i]) {\r
                                                bp = i + 1;\r
                                                break;\r
@@ -618,10 +607,10 @@ tinymce.create('tinymce.util.Dispatcher', {
                        if (bp == 1)\r
                                return path;\r
 \r
-                       for (i = 0; i < base.length - (bp - 1); i++)\r
+                       for (i = 0, l = base.length - (bp - 1); i < l; i++)\r
                                out += "../";\r
 \r
-                       for (i = bp - 1; i < items.length; i++) {\r
+                       for (i = bp - 1, l = items.length; i < l; i++) {\r
                                if (i != bp - 1)\r
                                        out += "/" + items[i];\r
                                else\r
@@ -632,9 +621,10 @@ tinymce.create('tinymce.util.Dispatcher', {
                },\r
 \r
                toAbsPath : function(base, path) {\r
-                       var i, nb = 0, o = [];\r
+                       var i, nb = 0, o = [], tr;\r
 \r
                        // Split paths\r
+                       tr = /\/$/.test(path) ? '/' : '';\r
                        base = base.split('/');\r
                        path = path.split('/');\r
 \r
@@ -671,9 +661,9 @@ tinymce.create('tinymce.util.Dispatcher', {
 \r
                        // If /a/b/c or /\r
                        if (i <= 0)\r
-                               return '/' + o.reverse().join('/');\r
+                               return '/' + o.reverse().join('/') + tr;\r
 \r
-                       return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/');\r
+                       return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/') + tr;\r
                },\r
 \r
                getURI : function(nh) {\r
@@ -714,9 +704,6 @@ tinymce.create('tinymce.util.Dispatcher', {
 \r
                });\r
 })();\r
-\r
-/* file:jscripts/tiny_mce/classes/util/Cookie.js */\r
-\r
 (function() {\r
        var each = tinymce.each;\r
 \r
@@ -788,9 +775,6 @@ tinymce.create('tinymce.util.Dispatcher', {
 \r
                });\r
 })();\r
-\r
-/* file:jscripts/tiny_mce/classes/util/JSON.js */\r
-\r
 tinymce.create('static tinymce.util.JSON', {\r
        serialize : function(o) {\r
                var i, v, s = tinymce.util.JSON.serialize, t;\r
@@ -803,7 +787,7 @@ 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 '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g, function(a, b) {\r
                                i = v.indexOf(b);\r
 \r
                                if (i + 1)\r
@@ -816,7 +800,7 @@ tinymce.create('static tinymce.util.JSON', {
                }\r
 \r
                if (t == 'object') {\r
-                       if (o instanceof Array) {\r
+                       if (o.hasOwnProperty && o instanceof Array) {\r
                                        for (i=0, v = '['; i<o.length; i++)\r
                                                v += (i > 0 ? ',' : '') + s(o[i]);\r
 \r
@@ -843,9 +827,6 @@ tinymce.create('static tinymce.util.JSON', {
        }\r
 \r
        });\r
-\r
-/* file:jscripts/tiny_mce/classes/util/XHR.js */\r
-\r
 tinymce.create('static tinymce.util.XHR', {\r
        send : function(o) {\r
                var x, t, w = window, c = 0;\r
@@ -903,9 +884,6 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                }\r
 });\r
-\r
-/* file:jscripts/tiny_mce/classes/util/JSONRequest.js */\r
-\r
 (function() {\r
        var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;\r
 \r
@@ -959,10 +937,7 @@ tinymce.create('static tinymce.util.XHR', {
                }\r
 \r
                });\r
-}());\r
-/* file:jscripts/tiny_mce/classes/dom/DOMUtils.js */\r
-\r
-(function() {\r
+}());(function(tinymce) {\r
        // Shorten names\r
        var each = tinymce.each, is = tinymce.is;\r
        var isWebKit = tinymce.isWebKit, isIE = tinymce.isIE;\r
@@ -971,12 +946,21 @@ tinymce.create('static tinymce.util.XHR', {
                doc : null,\r
                root : null,\r
                files : null,\r
-               listeners : {},\r
                pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,\r
-               cache : {},\r
-               idPattern : /^#[\w]+$/,\r
-               elmPattern : /^[\w_*]+$/,\r
-               elmClassPattern : /^([\w_]*)\.([\w_]+)$/,\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
                DOMUtils : function(d, s) {\r
                        var t = this;\r
@@ -1030,10 +1014,24 @@ tinymce.create('static tinymce.util.XHR', {
                },\r
 \r
                getRect : function(e) {\r
-                       var p, t = this, w, h;\r
+                       var p, t = this, sr;\r
 \r
                        e = t.get(e);\r
                        p = t.getPos(e);\r
+                       sr = t.getSize(e);\r
+\r
+                       return {\r
+                               x : p.x,\r
+                               y : p.y,\r
+                               w : sr.w,\r
+                               h : sr.h\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
 \r
@@ -1046,56 +1044,56 @@ tinymce.create('static tinymce.util.XHR', {
                                h = 0;\r
 \r
                        return {\r
-                               x : p.x,\r
-                               y : p.y,\r
                                w : parseInt(w) || e.offsetWidth || e.clientWidth,\r
                                h : parseInt(h) || e.offsetHeight || e.clientHeight\r
                        };\r
                },\r
 \r
+               is : function(n, patt) {\r
+                       return tinymce.dom.Sizzle.matches(patt, n.nodeType ? [n] : n).length > 0;\r
+               },\r
+\r
                getParent : function(n, f, r) {\r
-                       var na, se = this.settings;\r
+                       return this.getParents(n, f, r, false);\r
+               },\r
 \r
-                       n = this.get(n);\r
+               getParents : function(n, f, r, c) {\r
+                       var t = this, na, se = t.settings, o = [];\r
+\r
+                       n = t.get(n);\r
+                       c = c === undefined;\r
 \r
                        if (se.strict_root)\r
-                               r = r || this.getRoot();\r
+                               r = r || t.getRoot();\r
 \r
                        // Wrap node name as func\r
                        if (is(f, 'string')) {\r
-                               na = f.toUpperCase();\r
-\r
-                               f = function(n) {\r
-                                       var s = false;\r
-\r
-                                       // Any element\r
-                                       if (n.nodeType == 1 && na === '*') {\r
-                                               s = true;\r
-                                               return false;\r
-                                       }\r
-\r
-                                       each(na.split(','), function(v) {\r
-                                               if (n.nodeType == 1 && ((se.strict && n.nodeName.toUpperCase() == v) || n.nodeName.toUpperCase() == v)) {\r
-                                                       s = true;\r
-                                                       return false; // Break loop\r
-                                               }\r
-                                       });\r
+                               na = f;\r
 \r
-                                       return s;\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
+                               }\r
                        }\r
 \r
                        while (n) {\r
-                               if (n == r)\r
-                                       return null;\r
+                               if (n == r || !n.nodeType || n.nodeType === 9)\r
+                                       break;\r
 \r
-                               if (f(n))\r
-                                       return n;\r
+                               if (!f || f(n)) {\r
+                                       if (c)\r
+                                               o.push(n);\r
+                                       else\r
+                                               return n;\r
+                               }\r
 \r
                                n = n.parentNode;\r
                        }\r
 \r
-                       return null;\r
+                       return c ? o : null;\r
                },\r
 \r
                get : function(e) {\r
@@ -1113,169 +1111,13 @@ tinymce.create('static tinymce.util.XHR', {
                        return e;\r
                },\r
 \r
-               // #if !jquery\r
 \r
                select : function(pa, s) {\r
-                       var t = this, cs, c, pl, o = [], x, i, l, n;\r
-\r
-                       s = t.get(s) || t.doc;\r
-\r
-                       // Look for native support and use that if it's found\r
-                       if (s.querySelectorAll) {\r
-                               // Element scope then use temp id\r
-                               // We need to do this to be compatible with other implementations\r
-                               // See bug report: http://bugs.webkit.org/show_bug.cgi?id=17461\r
-                               if (s != t.doc) {\r
-                                       i = s.id;\r
-                                       s.id = '_mc_tmp';\r
-                                       pa = '#_mc_tmp ' + pa;\r
-                               }\r
-\r
-                               // Select elements\r
-                               l = tinymce.grep(s.querySelectorAll(pa));\r
-\r
-                               // Restore old id\r
-                               s.id = i;\r
-\r
-                               return l;\r
-                       }\r
-\r
-                       if (t.settings.strict) {\r
-                               function get(s, n) {\r
-                                       return s.getElementsByTagName(n.toLowerCase());\r
-                               };\r
-                       } else {\r
-                               function get(s, n) {\r
-                                       return s.getElementsByTagName(n);\r
-                               };\r
-                       }\r
-\r
-                       // Simple element pattern. For example: "p" or "*"\r
-                       if (t.elmPattern.test(pa)) {\r
-                               x = get(s, pa);\r
-\r
-                               for (i = 0, l = x.length; i<l; i++)\r
-                                       o.push(x[i]);\r
-\r
-                               return o;\r
-                       }\r
-\r
-                       // Simple class pattern. For example: "p.class" or ".class"\r
-                       if (t.elmClassPattern.test(pa)) {\r
-                               pl = t.elmClassPattern.exec(pa);\r
-                               x = get(s, pl[1] || '*');\r
-                               c = ' ' + pl[2] + ' ';\r
-\r
-                               for (i = 0, l = x.length; i<l; i++) {\r
-                                       n = x[i];\r
-\r
-                                       if (n.className && (' ' + n.className + ' ').indexOf(c) !== -1)\r
-                                               o.push(n);\r
-                               }\r
-\r
-                               return o;\r
-                       }\r
-\r
-                       function collect(n) {\r
-                               if (!n.mce_save) {\r
-                                       n.mce_save = 1;\r
-                                       o.push(n);\r
-                               }\r
-                       };\r
-\r
-                       function collectIE(n) {\r
-                               if (!n.getAttribute('mce_save')) {\r
-                                       n.setAttribute('mce_save', '1');\r
-                                       o.push(n);\r
-                               }\r
-                       };\r
-\r
-                       function find(n, f, r) {\r
-                               var i, l, nl = get(r, n);\r
-\r
-                               for (i = 0, l = nl.length; i < l; i++)\r
-                                       f(nl[i]);\r
-                       };\r
-\r
-                       each(pa.split(','), function(v, i) {\r
-                               v = tinymce.trim(v);\r
-\r
-                               // Simple element pattern, most common in TinyMCE\r
-                               if (t.elmPattern.test(v)) {\r
-                                       each(get(s, v), function(n) {\r
-                                               collect(n);\r
-                                       });\r
-\r
-                                       return;\r
-                               }\r
-\r
-                               // Simple element pattern with class, fairly common in TinyMCE\r
-                               if (t.elmClassPattern.test(v)) {\r
-                                       x = t.elmClassPattern.exec(v);\r
-\r
-                                       each(get(s, x[1]), function(n) {\r
-                                               if (t.hasClass(n, x[2]))\r
-                                                       collect(n);\r
-                                       });\r
-\r
-                                       return;\r
-                               }\r
-\r
-                               if (!(cs = t.cache[pa])) {\r
-                                       cs = 'x=(function(cf, s) {';\r
-                                       pl = v.split(' ');\r
-\r
-                                       each(pl, function(v) {\r
-                                               var p = /^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@([\w\\]+)([\^\$\*!]?=)([\w\\]+)\])?(?:\:([\w\\]+))?/i.exec(v);\r
-\r
-                                               // Find elements\r
-                                               p[1] = p[1] || '*';\r
-                                               cs += 'find("' + p[1] + '", function(n) {';\r
-\r
-                                               // Check id\r
-                                               if (p[2])\r
-                                                       cs += 'if (n.id !== "' + p[2] + '") return;';\r
-\r
-                                               // Check classes\r
-                                               if (p[3]) {\r
-                                                       cs += 'var c = " " + n.className + " ";';\r
-                                                       cs += 'if (';\r
-                                                       c = '';\r
-                                                       each(p[3].split('.'), function(v) {\r
-                                                               if (v)\r
-                                                                       c += (c ? '||' : '') + 'c.indexOf(" ' + v + ' ") === -1';\r
-                                                       });\r
-                                                       cs += c + ') return;';\r
-                                               }\r
-                                       });\r
-\r
-                                       cs += 'cf(n);';\r
-\r
-                                       for (i = pl.length - 1; i >= 0; i--)\r
-                                               cs += '}, ' + (i ? 'n' : 's') + ');';\r
-\r
-                                       cs += '})';\r
-\r
-                                       // Compile CSS pattern function\r
-                                       t.cache[pa] = cs = eval(cs);\r
-                               }\r
-\r
-                               // Run selector function\r
-                               cs(isIE ? collectIE : collect, s);\r
-                       });\r
-\r
-                       // Cleanup\r
-                       each(o, function(n) {\r
-                               if (isIE)\r
-                                       n.removeAttribute('mce_save');\r
-                               else\r
-                                       delete n.mce_save;\r
-                       });\r
+                       var t = this;\r
 \r
-                       return o;\r
+                       return tinymce.dom.Sizzle(pa, t.get(s) || t.get(t.settings.root_element) || t.doc, []);\r
                },\r
 \r
-               // #endif\r
 \r
                add : function(p, n, a, h, c) {\r
                        var t = this;\r
@@ -1284,19 +1126,7 @@ tinymce.create('static tinymce.util.XHR', {
                                var e, k;\r
 \r
                                e = is(n, 'string') ? t.doc.createElement(n) : n;\r
-\r
-                               if (a) {\r
-                                       for (k in a) {\r
-                                               if (a.hasOwnProperty(k) && !is(a[k], 'object'))\r
-                                                       t.setAttrib(e, k, '' + a[k]);\r
-                                       }\r
-\r
-                                       if (a.style && !is(a.style, 'string')) {\r
-                                               each(a.style, function(v, n) {\r
-                                                       t.setStyle(e, n, v);\r
-                                               });\r
-                                       }\r
-                               }\r
+                               t.setAttribs(e, a);\r
 \r
                                if (h) {\r
                                        if (h.nodeType)\r
@@ -1330,8 +1160,10 @@ tinymce.create('static tinymce.util.XHR', {
                },\r
 \r
                remove : function(n, k) {\r
+                       var t = this;\r
+\r
                        return this.run(n, function(n) {\r
-                               var p, g;\r
+                               var p, g, i;\r
 \r
                                p = n.parentNode;\r
 \r
@@ -1339,24 +1171,29 @@ tinymce.create('static tinymce.util.XHR', {
                                        return null;\r
 \r
                                if (k) {\r
-                                       each (n.childNodes, function(c) {\r
-                                               p.insertBefore(c.cloneNode(true), n);\r
-                                       });\r
+                                       for (i = n.childNodes.length - 1; i >= 0; i--)\r
+                                               t.insertAfter(n.childNodes[i], n);\r
+\r
+                                       //each(n.childNodes, function(c) {\r
+                                       //      p.insertBefore(c.cloneNode(true), n);\r
+                                       //});\r
                                }\r
 \r
                                // Fix IE psuedo leak\r
-               /*              if (isIE) {\r
+                               if (t.fixPsuedoLeaks) {\r
                                        p = n.cloneNode(true);\r
-                                       n.outerHTML = '';\r
+                                       k = 'IELeakGarbageBin';\r
+                                       g = t.get(k) || t.add(t.doc.body, 'div', {id : k, style : 'display:none'});\r
+                                       g.appendChild(n);\r
+                                       g.innerHTML = '';\r
 \r
                                        return p;\r
-                               }*/\r
+                               }\r
 \r
                                return p.removeChild(n);\r
                        });\r
                },\r
 \r
-               // #if !jquery\r
 \r
                setStyle : function(n, na, v) {\r
                        var t = this;\r
@@ -1458,6 +1295,10 @@ tinymce.create('static tinymce.util.XHR', {
                setAttrib : function(e, n, v) {\r
                        var t = this;\r
 \r
+                       // Whats the point\r
+                       if (!e || !n)\r
+                               return;\r
+\r
                        // Strict XML mode\r
                        if (t.settings.strict)\r
                                n = n.toLowerCase();\r
@@ -1467,6 +1308,14 @@ tinymce.create('static tinymce.util.XHR', {
 \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
+                                                       return;\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
@@ -1515,7 +1364,6 @@ tinymce.create('static tinymce.util.XHR', {
                        });\r
                },\r
 \r
-               // #endif\r
 \r
                getAttrib : function(e, n, dv) {\r
                        var v, t = this;\r
@@ -1526,7 +1374,7 @@ tinymce.create('static tinymce.util.XHR', {
                                return false;\r
 \r
                        if (!is(dv))\r
-                               dv = "";\r
+                               dv = '';\r
 \r
                        // Try the mce variant for these\r
                        if (/^(src|href|style|coords|shape)$/.test(n)) {\r
@@ -1536,38 +1384,23 @@ tinymce.create('static tinymce.util.XHR', {
                                        return v;\r
                        }\r
 \r
-                       v = e.getAttribute(n, 2);\r
-\r
-                       if (!v) {\r
-                               switch (n) {\r
-                                       case 'class':\r
-                                               v = e.className;\r
-                                               break;\r
-\r
-                                       default:\r
-                                               // Fix for IE crash Bug: #1884376 probably due to invalid DOM structure\r
-                                               if (isIE && n === 'name' && e.nodeName === 'A') {\r
-                                                       v = e.name;\r
-                                                       break;\r
-                                               }\r
-\r
-                                               v = e.attributes[n];\r
-                                               v = v && is(v.nodeValue) ? v.nodeValue : v;\r
-                               }\r
+                       if (isIE && t.props[n]) {\r
+                               v = e[t.props[n]];\r
+                               v = v && v.nodeValue ? v.nodeValue : v;\r
                        }\r
 \r
-                       switch (n) {\r
-                               case 'style':\r
-                                       v = v || e.style.cssText;\r
+                       if (!v)\r
+                               v = e.getAttribute(n, 2);\r
 \r
-                                       if (v) {\r
-                                               v = t.serializeStyle(t.parseStyle(v));\r
+                       if (n === 'style') {\r
+                               v = v || e.style.cssText;\r
 \r
-                                               if (t.settings.keep_values && !t._isRes(v))\r
-                                                       e.setAttribute('mce_style', v);\r
-                                       }\r
+                               if (v) {\r
+                                       v = t.serializeStyle(t.parseStyle(v));\r
 \r
-                                       break;\r
+                                       if (t.settings.keep_values && !t._isRes(v))\r
+                                               e.setAttribute('mce_style', v);\r
+                               }\r
                        }\r
 \r
                        // Remove Apple and WebKit stuff\r
@@ -1587,7 +1420,18 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                                        case 'size':\r
                                                // IE returns +0 as default value for size\r
-                                               if (v === '+0')\r
+                                               if (v === '+0' || v === 20 || v === 0)\r
+                                                       v = '';\r
+\r
+                                               break;\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
                                                break;\r
@@ -1599,19 +1443,22 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                                                break;\r
 \r
+                                       case 'maxlength':\r
                                        case 'tabindex':\r
                                                // IE returns default value\r
-                                               if (v === 32768)\r
+                                               if (v === 32768 || v === 2147483647 || v === '32768')\r
                                                        v = '';\r
 \r
                                                break;\r
 \r
-                                       case 'maxlength':\r
-                                               // IE returns  default value\r
-                                               if (v === 2147483647)\r
-                                                       v = '';\r
+                                       case 'multiple':\r
+                                       case 'compact':\r
+                                       case 'noshade':\r
+                                       case 'nowrap':\r
+                                               if (v === 65535)\r
+                                                       return n;\r
 \r
-                                               break;\r
+                                               return dv;\r
 \r
                                        case 'shape':\r
                                                v = v.toLowerCase();\r
@@ -1624,44 +1471,40 @@ tinymce.create('static tinymce.util.XHR', {
                                }\r
                        }\r
 \r
-                       return (v && v != '') ? '' + v : dv;\r
+                       return (v !== undefined && v !== null && v !== '') ? '' + v : dv;\r
                },\r
 \r
-               getPos : function(n) {\r
+               getPos : function(n, ro) {\r
                        var t = this, x = 0, y = 0, e, d = t.doc, r;\r
 \r
                        n = t.get(n);\r
+                       ro = ro || d.body;\r
 \r
-                       // Use getBoundingClientRect on IE, Opera has it but it's not perfect\r
-                       if (n && isIE) {\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
+                       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
 \r
-                               return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};\r
-                       }\r
+                                       return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};\r
+                               }\r
 \r
-                       r = n;\r
-                       while (r) {\r
-                               x += r.offsetLeft || 0;\r
-                               y += r.offsetTop || 0;\r
-                               r = r.offsetParent;\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
 \r
-                       r = n;\r
-                       while (r) {\r
-                               // Opera 9.25 bug fix, fixed in 9.50\r
-                               if (!/^table-row|inline.*/i.test(t.getStyle(r, "display", 1))) {\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 = r.parentNode;\r
-\r
-                               if (r == d.body)\r
-                                       break;\r
                        }\r
 \r
                        return {x : x, y : y};\r
@@ -1803,7 +1646,6 @@ tinymce.create('static tinymce.util.XHR', {
                        });\r
                },\r
 \r
-               // #if !jquery\r
 \r
                addClass : function(e, c) {\r
                        return this.run(e, function(e) {\r
@@ -1860,10 +1702,9 @@ tinymce.create('static tinymce.util.XHR', {
                isHidden : function(e) {\r
                        e = this.get(e);\r
 \r
-                       return e.style.display == 'none' || this.getStyle(e, 'display') == 'none';\r
+                       return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none';\r
                },\r
 \r
-               // #endif\r
 \r
                uniqueId : function(p) {\r
                        return (!p ? 'mce_' : p) + (this.counter++);\r
@@ -1934,7 +1775,7 @@ tinymce.create('static tinymce.util.XHR', {
                                        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>/g, '<div$1 mce_tmp="1">');\r
+                                               h = h.replace(/<p ([^>]+)>|<p>/g, '<div $1 mce_tmp="1">');\r
                                                h = h.replace(/<\/p>/g, '</div>');\r
 \r
                                                // Set the new HTML with DIVs\r
@@ -1994,8 +1835,10 @@ tinymce.create('static tinymce.util.XHR', {
                        if (tinymce.isGecko) {\r
                                h = h.replace(/<(\/?)strong>|<strong( [^>]+)>/gi, '<$1b$2>');\r
                                h = h.replace(/<(\/?)em>|<em( [^>]+)>/gi, '<$1i$2>');\r
-                       } else if (isIE)\r
+                       } else 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
+                       }\r
 \r
                        // Fix some issues\r
                        h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open\r
@@ -2006,9 +1849,10 @@ tinymce.create('static tinymce.util.XHR', {
                                if (/<script|style/.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
+                                               s = s.replace(/^\s*(\/\/\s*<!--|\/\/\s*<!\[CDATA\[|<!--|<!\[CDATA\[)[\r\n]*/g, '');\r
+                                               s = s.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->|\]\]-->)\s*$/g, '');\r
 \r
                                                return s;\r
                                        };\r
@@ -2037,6 +1881,8 @@ tinymce.create('static tinymce.util.XHR', {
                                        });\r
                                }\r
 \r
+                               h = h.replace(/<!\[CDATA\[([\s\S]+)\]\]>/g, '<!--[CDATA[$1]]-->');\r
+\r
                                // Process all tags with src, href or style\r
                                h = h.replace(/<([\w:]+) [^>]*(src|href|style|shape|coords)[^>]*>/gi, function(a, n) {\r
                                        function handle(m, b, c) {\r
@@ -2047,10 +1893,6 @@ tinymce.create('static tinymce.util.XHR', {
                                                        return m;\r
 \r
                                                if (b == 'style') {\r
-                                                       // Why did I need this one?\r
-                                                       //if (isIE)\r
-                                                       //      u = t.serializeStyle(t.parseStyle(u));\r
-\r
                                                        // No mce_style for elements with these since they might get resized by the user\r
                                                        if (t._isRes(c))\r
                                                                return m;\r
@@ -2092,7 +1934,7 @@ tinymce.create('static tinymce.util.XHR', {
                        if (!e)\r
                                return null;\r
 \r
-                       if (isIE)\r
+                       if (e.outerHTML !== undefined)\r
                                return e.outerHTML;\r
 \r
                        d = (e.ownerDocument || this.doc).createElement("body");\r
@@ -2128,15 +1970,23 @@ tinymce.create('static tinymce.util.XHR', {
                },\r
 \r
                decode : function(s) {\r
-                       var e;\r
+                       var e, n, v;\r
 \r
                        // Look for entities to decode\r
                        if (/&[^;]+;/.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
+\r
+                               if (n) {\r
+                                       do {\r
+                                               v += n.nodeValue;\r
+                                       } while (n.nextSibling);\r
+                               }\r
 \r
-                               return !e.firstChild ? s : e.firstChild.nodeValue;\r
+                               return v || s;\r
                        }\r
 \r
                        return s;\r
@@ -2162,7 +2012,6 @@ tinymce.create('static tinymce.util.XHR', {
                        }) : s;\r
                },\r
 \r
-               // #if !jquery\r
 \r
                insertAfter : function(n, r) {\r
                        var t = this;\r
@@ -2184,7 +2033,6 @@ tinymce.create('static tinymce.util.XHR', {
                        });\r
                },\r
 \r
-               // #endif\r
 \r
                isBlock : function(n) {\r
                        if (n.nodeType && n.nodeType !== 1)\r
@@ -2192,16 +2040,17 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                        n = n.nodeName || n;\r
 \r
-                       return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);\r
+                       return /^(H[1-6]|HR|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TR|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP)$/.test(n);\r
                },\r
 \r
-               // #if !jquery\r
 \r
                replace : function(n, o, k) {\r
+                       var t = this;\r
+\r
                        if (is(o, 'array'))\r
                                n = n.cloneNode(true);\r
 \r
-                       return this.run(o, function(o) {\r
+                       return t.run(o, function(o) {\r
                                if (k) {\r
                                        each(o.childNodes, function(c) {\r
                                                n.appendChild(c.cloneNode(true));\r
@@ -2210,17 +2059,37 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                                // Fix IE psuedo leak for elements since replacing elements if fairly common\r
                                // Will break parentNode for some unknown reason\r
-       /*                      if (isIE && o.nodeType === 1) {\r
+                               if (t.fixPsuedoLeaks && o.nodeType === 1) {\r
                                        o.parentNode.insertBefore(n, o);\r
-                                       o.outerHTML = '';\r
+                                       t.remove(o);\r
                                        return n;\r
-                               }*/\r
+                               }\r
 \r
                                return o.parentNode.replaceChild(n, o);\r
                        });\r
                },\r
 \r
-               // #endif\r
+\r
+               findCommonAncestor : function(a, b) {\r
+                       var ps = a, pe;\r
+\r
+                       while (ps) {\r
+                               pe = b;\r
+\r
+                               while (pe && ps != pe)\r
+                                       pe = pe.parentNode;\r
+\r
+                               if (ps == pe)\r
+                                       break;\r
+\r
+                               ps = ps.parentNode;\r
+                       }\r
+\r
+                       if (!ps && a.ownerDocument)\r
+                               return a.ownerDocument.documentElement;\r
+\r
+                       return ps;\r
+               },\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
@@ -2305,7 +2174,7 @@ tinymce.create('static tinymce.util.XHR', {
                        var t = this, o;\r
 \r
                        if (t.doc && typeof(e) === 'string')\r
-                               e = t.doc.getElementById(e);\r
+                               e = t.get(e);\r
 \r
                        if (!e)\r
                                return false;\r
@@ -2365,6 +2234,77 @@ tinymce.create('static tinymce.util.XHR', {
                                tinymce.removeUnload(t.destroy);\r
                },\r
 \r
+               createRng : function() {\r
+                       var d = this.doc;\r
+\r
+                       return d.createRange ? d.createRange() : new tinymce.dom.Range(this);\r
+               },\r
+\r
+               split : function(pe, e, re) {\r
+                       var t = this, r = t.createRng(), bef, aft, pa;\r
+\r
+                       // W3C valid browsers tend to leave empty nodes to the left/right side of the contents, this makes sence\r
+                       // but we don't want that in our code since it serves no purpose\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 trimEdge(n, na) {\r
+                               n = n[na];\r
+\r
+                               if (n && n[na] && n[na].nodeType == 1 && isEmpty(n[na]))\r
+                                       t.remove(n[na]);\r
+                       };\r
+\r
+                       function isEmpty(n) {\r
+                               n = t.getOuterHTML(n);\r
+                               n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars\r
+                               n = n.replace(/<[^>]+>/g, ''); // Remove all tags\r
+\r
+                               return n.replace(/[ \t\r\n]+|&nbsp;|&#160;/g, '') == '';\r
+                       };\r
+\r
+                       if (pe && e) {\r
+                               // Get before chunk\r
+                               r.setStartBefore(pe);\r
+                               r.setEndBefore(e);\r
+                               bef = r.extractContents();\r
+\r
+                               // Get after chunk\r
+                               r = t.createRng();\r
+                               r.setStartAfter(e);\r
+                               r.setEndAfter(pe);\r
+                               aft = r.extractContents();\r
+\r
+                               // Insert chunks and remove parent\r
+                               pa = pe.parentNode;\r
+\r
+                               // Remove right side edge of the before contents\r
+                               trimEdge(bef, 'lastChild');\r
+\r
+                               if (!isEmpty(bef))\r
+                                       pa.insertBefore(bef, pe);\r
+\r
+                               if (re)\r
+                                       pa.replaceChild(re, e);\r
+                               else\r
+                                       pa.insertBefore(e, pe);\r
+\r
+                               // Remove left site edge of the after contents\r
+                               trimEdge(aft, 'firstChild');\r
+\r
+                               if (!isEmpty(aft))\r
+                                       pa.insertBefore(aft, pe);\r
+\r
+                               t.remove(pe);\r
+\r
+                               return re || e;\r
+                       }\r
+               },\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
@@ -2404,47 +2344,1978 @@ tinymce.create('static tinymce.util.XHR', {
 \r
        // Setup page DOM\r
        tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});\r
-})();\r
+})(tinymce);\r
+(function(ns) {\r
+       // Traverse constants\r
+       var EXTRACT = 0, CLONE = 1, DELETE = 2, extend = tinymce.extend;\r
 \r
-/* file:jscripts/tiny_mce/classes/dom/Event.js */\r
+       function indexOf(child, parent) {\r
+               var i, node;\r
 \r
-(function() {\r
-       // Shorten names\r
-       var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;\r
+               if (child.parentNode != parent)\r
+                       return -1;\r
 \r
-       tinymce.create('static tinymce.dom.Event', {\r
-               inits : [],\r
-               events : [],\r
+               for (node = parent.firstChild, i = 0; node != child; node = node.nextSibling)\r
+                       i++;\r
 \r
-               // #if !jquery\r
+               return i;\r
+       };\r
 \r
-               add : function(o, n, f, s) {\r
-                       var cb, t = this, el = t.events, r;\r
+       function nodeIndex(n) {\r
+               var i = 0;\r
 \r
-                       // Handle array\r
-                       if (o && o instanceof Array) {\r
-                               r = [];\r
+               while (n.previousSibling) {\r
+                       i++;\r
+                       n = n.previousSibling;\r
+               }\r
 \r
-                               each(o, function(o) {\r
-                                       o = DOM.get(o);\r
-                                       r.push(t.add(o, n, f, s));\r
-                               });\r
+               return i;\r
+       };\r
 \r
-                               return r;\r
-                       }\r
+       function getSelectedNode(container, offset) {\r
+               var child;\r
 \r
-                       o = DOM.get(o);\r
+               if (container.nodeType == 3 /* TEXT_NODE */)\r
+                       return container;\r
 \r
-                       if (!o)\r
-                               return;\r
+               if (offset < 0)\r
+                       return container;\r
 \r
-                       // Setup event callback\r
-                       cb = function(e) {\r
-                               e = e || window.event;\r
+               child = container.firstChild;\r
+               while (child != null && offset > 0) {\r
+                       --offset;\r
+                       child = child.nextSibling;\r
+               }\r
 \r
-                               // Patch in target in IE it's W3C valid\r
-                               if (e && !e.target && isIE)\r
-                                       e.target = e.srcElement;\r
+               if (child != null)\r
+                       return child;\r
+\r
+               return container;\r
+       };\r
+\r
+       // Range constructor\r
+       function Range(dom) {\r
+               var d = dom.doc;\r
+\r
+               extend(this, {\r
+                       dom : dom,\r
+\r
+                       // Inital states\r
+                       startContainer : d,\r
+                       startOffset : 0,\r
+                       endContainer : d,\r
+                       endOffset : 0,\r
+                       collapsed : true,\r
+                       commonAncestorContainer : d,\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
+       };\r
+\r
+       // Add range methods\r
+       extend(Range.prototype, {\r
+               setStart : function(n, o) {\r
+                       this._setEndPoint(true, n, o);\r
+               },\r
+\r
+               setEnd : function(n, o) {\r
+                       this._setEndPoint(false, n, o);\r
+               },\r
+\r
+               setStartBefore : function(n) {\r
+                       this.setStart(n.parentNode, nodeIndex(n));\r
+               },\r
+\r
+               setStartAfter : function(n) {\r
+                       this.setStart(n.parentNode, nodeIndex(n) + 1);\r
+               },\r
+\r
+               setEndBefore : function(n) {\r
+                       this.setEnd(n.parentNode, nodeIndex(n));\r
+               },\r
+\r
+               setEndAfter : function(n) {\r
+                       this.setEnd(n.parentNode, nodeIndex(n) + 1);\r
+               },\r
+\r
+               collapse : function(ts) {\r
+                       var t = this;\r
+\r
+                       if (ts) {\r
+                               t.endContainer = t.startContainer;\r
+                               t.endOffset = t.startOffset;\r
+                       } else {\r
+                               t.startContainer = t.endContainer;\r
+                               t.startOffset = t.endOffset;\r
+                       }\r
+\r
+                       t.collapsed = true;\r
+               },\r
+\r
+               selectNode : function(n) {\r
+                       this.setStartBefore(n);\r
+                       this.setEndAfter(n);\r
+               },\r
+\r
+               selectNodeContents : function(n) {\r
+                       this.setStart(n, 0);\r
+                       this.setEnd(n, n.nodeType === 1 ? n.childNodes.length : n.nodeValue.length);\r
+               },\r
+\r
+               compareBoundaryPoints : function(h, r) {\r
+                       var t = this, sc = t.startContainer, so = t.startOffset, ec = t.endContainer, eo = t.endOffset;\r
+\r
+                       // Check START_TO_START\r
+                       if (h === 0)\r
+                               return t._compareBoundaryPoints(sc, so, sc, so);\r
+\r
+                       // Check START_TO_END\r
+                       if (h === 1)\r
+                               return t._compareBoundaryPoints(sc, so, ec, eo);\r
+\r
+                       // Check END_TO_END\r
+                       if (h === 2)\r
+                               return t._compareBoundaryPoints(ec, eo, ec, eo);\r
+\r
+                       // Check END_TO_START\r
+                       if (h === 3)\r
+                               return t._compareBoundaryPoints(ec, eo, sc, so);\r
+               },\r
+\r
+               deleteContents : function() {\r
+                       this._traverse(DELETE);\r
+               },\r
+\r
+               extractContents : function() {\r
+                       return this._traverse(EXTRACT);\r
+               },\r
+\r
+               cloneContents : function() {\r
+                       return this._traverse(CLONE);\r
+               },\r
+\r
+               insertNode : function(n) {\r
+                       var t = this, nn, o;\r
+\r
+                       // Node is TEXT_NODE or CDATA\r
+                       if (n.nodeType === 3 || n.nodeType === 4) {\r
+                               nn = t.startContainer.splitText(t.startOffset);\r
+                               t.startContainer.parentNode.insertBefore(n, nn);\r
+                       } else {\r
+                               // Insert element node\r
+                               if (t.startContainer.childNodes.length > 0)\r
+                                       o = t.startContainer.childNodes[t.startOffset];\r
+\r
+                               t.startContainer.insertBefore(n, o);\r
+                       }\r
+               },\r
+\r
+               surroundContents : function(n) {\r
+                       var t = this, f = t.extractContents();\r
+\r
+                       t.insertNode(n);\r
+                       n.appendChild(f);\r
+                       t.selectNode(n);\r
+               },\r
+\r
+               cloneRange : function() {\r
+                       var t = this;\r
+\r
+                       return extend(new Range(t.dom), {\r
+                               startContainer : t.startContainer,\r
+                               startOffset : t.startOffset,\r
+                               endContainer : t.endContainer,\r
+                               endOffset : t.endOffset,\r
+                               collapsed : t.collapsed,\r
+                               commonAncestorContainer : t.commonAncestorContainer\r
+                       });\r
+               },\r
+\r
+/*\r
+               detach : function() {\r
+                       // Not implemented\r
+               },\r
+*/\r
+               // Internal methods\r
+\r
+               _isCollapsed : function() {\r
+                       return (this.startContainer == this.endContainer && this.startOffset == this.endOffset);\r
+               },\r
+\r
+               _compareBoundaryPoints : function (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
+                               } else if (offsetA < offsetB) {\r
+                                       return -1; // before\r
+                               } else {\r
+                                       return 1; // after\r
+                               }\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
+                               } else {\r
+                                       return 1; // after\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
+\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
+                               } else {\r
+                                       return 1; // after\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 = this.dom.findCommonAncestor(containerA, containerB);\r
+                       childA = containerA;\r
+\r
+                       while (childA && childA.parentNode != cmnRoot) {\r
+                               childA = childA.parentNode;  \r
+                       }\r
+\r
+                       if (!childA) {\r
+                               childA = cmnRoot;\r
+                       }\r
+\r
+                       childB = containerB;\r
+                       while (childB && childB.parentNode != cmnRoot) {\r
+                               childB = childB.parentNode;\r
+                       }\r
+\r
+                       if (!childB) {\r
+                               childB = cmnRoot;\r
+                       }\r
+\r
+                       if (childA == childB) {\r
+                               return 0; // equal\r
+                       }\r
+\r
+                       n = cmnRoot.firstChild;\r
+                       while (n) {\r
+                               if (n == childA) {\r
+                                       return -1; // before\r
+                               }\r
+\r
+                               if (n == childB) {\r
+                                       return 1; // after\r
+                               }\r
+\r
+                               n = n.nextSibling;\r
+                       }\r
+               },\r
+\r
+               _setEndPoint : function(st, n, o) {\r
+                       var t = this, ec, sc;\r
+\r
+                       if (st) {\r
+                               t.startContainer = n;\r
+                               t.startOffset = o;\r
+                       } else {\r
+                               t.endContainer = n;\r
+                               t.endOffset = 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.endContainer;\r
+                       while (ec.parentNode)\r
+                               ec = ec.parentNode;\r
+\r
+                       sc = t.startContainer;\r
+                       while (sc.parentNode)\r
+                               sc = sc.parentNode;\r
+\r
+                       if (sc != ec) {\r
+                               t.collapse(st);\r
+                       } else {\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 (t._compareBoundaryPoints(t.startContainer, t.startOffset, t.endContainer, t.endOffset) > 0)\r
+                                       t.collapse(st);\r
+                       }\r
+\r
+                       t.collapsed = t._isCollapsed();\r
+                       t.commonAncestorContainer = t.dom.findCommonAncestor(t.startContainer, t.endContainer);\r
+               },\r
+\r
+               // This code is heavily "inspired" by the Apache Xerces implementation. I hope they don't mind. :)\r
+\r
+               _traverse : function(how) {\r
+                       var t = this, c, endContainerDepth = 0, startContainerDepth = 0, p, depthDiff, startNode, endNode, sp, ep;\r
+\r
+                       if (t.startContainer == t.endContainer)\r
+                               return t._traverseSameContainer(how);\r
+\r
+                       for (c = t.endContainer, p = c.parentNode; p != null; c = p, p = p.parentNode) {\r
+                               if (p == t.startContainer)\r
+                                       return t._traverseCommonStartContainer(c, how);\r
+\r
+                               ++endContainerDepth;\r
+                       }\r
+\r
+                       for (c = t.startContainer, p = c.parentNode; p != null; c = p, p = p.parentNode) {\r
+                               if (p == t.endContainer)\r
+                                       return t._traverseCommonEndContainer(c, how);\r
+\r
+                               ++startContainerDepth;\r
+                       }\r
+\r
+                       depthDiff = startContainerDepth - endContainerDepth;\r
+\r
+                       startNode = t.startContainer;\r
+                       while (depthDiff > 0) {\r
+                               startNode = startNode.parentNode;\r
+                               depthDiff--;\r
+                       }\r
+\r
+                       endNode = t.endContainer;\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 t._traverseCommonAncestors(startNode, endNode, how);\r
+               },\r
+\r
+               _traverseSameContainer : function(how) {\r
+                       var t = this, frag, s, sub, n, cnt, sibling, xferNode;\r
+\r
+                       if (how != DELETE)\r
+                               frag = t.dom.doc.createDocumentFragment();\r
+\r
+                       // If selection is empty, just return the fragment\r
+                       if (t.startOffset == t.endOffset)\r
+                               return frag;\r
+\r
+                       // Text node needs special case handling\r
+                       if (t.startContainer.nodeType == 3 /* TEXT_NODE */) {\r
+                               // get the substring\r
+                               s = t.startContainer.nodeValue;\r
+                               sub = s.substring(t.startOffset, t.endOffset);\r
+\r
+                               // set the original text node to its new value\r
+                               if (how != CLONE) {\r
+                                       t.startContainer.deleteData(t.startOffset, t.endOffset - t.startOffset);\r
+\r
+                                       // Nothing is partially selected, so collapse to start point\r
+                                       t.collapse(true);\r
+                               }\r
+\r
+                               if (how == DELETE)\r
+                                       return null;\r
+\r
+                               frag.appendChild(t.dom.doc.createTextNode(sub));\r
+                               return frag;\r
+                       }\r
+\r
+                       // Copy nodes between the start/end offsets.\r
+                       n = getSelectedNode(t.startContainer, t.startOffset);\r
+                       cnt = t.endOffset - t.startOffset;\r
+\r
+                       while (cnt > 0) {\r
+                               sibling = n.nextSibling;\r
+                               xferNode = t._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
+               _traverseCommonStartContainer : function(endAncestor, how) {\r
+                       var t = this, frag, n, endIdx, cnt, sibling, xferNode;\r
+\r
+                       if (how != DELETE)\r
+                               frag = t.dom.doc.createDocumentFragment();\r
+\r
+                       n = t._traverseRightBoundary(endAncestor, how);\r
+\r
+                       if (frag)\r
+                               frag.appendChild(n);\r
+\r
+                       endIdx = indexOf(endAncestor, t.startContainer);\r
+                       cnt = endIdx - t.startOffset;\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 = t._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
+               _traverseCommonEndContainer : function(startAncestor, how) {\r
+                       var t = this, frag, startIdx, n, cnt, sibling, xferNode;\r
+\r
+                       if (how != DELETE)\r
+                               frag = t.dom.doc.createDocumentFragment();\r
+\r
+                       n = t._traverseLeftBoundary(startAncestor, how);\r
+                       if (frag)\r
+                               frag.appendChild(n);\r
+\r
+                       startIdx = indexOf(startAncestor, t.endContainer);\r
+                       ++startIdx;  // Because we already traversed it....\r
+\r
+                       cnt = t.endOffset - startIdx;\r
+                       n = startAncestor.nextSibling;\r
+                       while (cnt > 0) {\r
+                               sibling = n.nextSibling;\r
+                               xferNode = t._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
+               _traverseCommonAncestors : function(startAncestor, endAncestor, how) {\r
+                       var t = this, n, frag, commonParent, startOffset, endOffset, cnt, sibling, nextSibling;\r
+\r
+                       if (how != DELETE)\r
+                               frag = t.dom.doc.createDocumentFragment();\r
+\r
+                       n = t._traverseLeftBoundary(startAncestor, how);\r
+                       if (frag)\r
+                               frag.appendChild(n);\r
+\r
+                       commonParent = startAncestor.parentNode;\r
+                       startOffset = indexOf(startAncestor, commonParent);\r
+                       endOffset = indexOf(endAncestor, commonParent);\r
+                       ++startOffset;\r
+\r
+                       cnt = endOffset - startOffset;\r
+                       sibling = startAncestor.nextSibling;\r
+\r
+                       while (cnt > 0) {\r
+                               nextSibling = sibling.nextSibling;\r
+                               n = t._traverseFullySelected(sibling, how);\r
+\r
+                               if (frag)\r
+                                       frag.appendChild(n);\r
+\r
+                               sibling = nextSibling;\r
+                               --cnt;\r
+                       }\r
+\r
+                       n = t._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
+               _traverseRightBoundary : function(root, how) {\r
+                       var t = this, next = getSelectedNode(t.endContainer, t.endOffset - 1), parent, clonedParent, prevSibling, clonedChild, clonedGrandParent;\r
+                       var isFullySelected = next != t.endContainer;\r
+\r
+                       if (next == root)\r
+                               return t._traverseNode(next, isFullySelected, false, how);\r
+\r
+                       parent = next.parentNode;\r
+                       clonedParent = t._traverseNode(parent, false, false, how);\r
+\r
+                       while (parent != null) {\r
+                               while (next != null) {\r
+                                       prevSibling = next.previousSibling;\r
+                                       clonedChild = t._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 (parent == root)\r
+                                       return clonedParent;\r
+\r
+                               next = parent.previousSibling;\r
+                               parent = parent.parentNode;\r
+\r
+                               clonedGrandParent = t._traverseNode(parent, false, false, how);\r
+\r
+                               if (how != DELETE)\r
+                                       clonedGrandParent.appendChild(clonedParent);\r
+\r
+                               clonedParent = clonedGrandParent;\r
+                       }\r
+\r
+                       // should never occur\r
+                       return null;\r
+               },\r
+\r
+               _traverseLeftBoundary : function(root, how) {\r
+                       var t = this, next = getSelectedNode(t.startContainer, t.startOffset);\r
+                       var isFullySelected = next != t.startContainer, parent, clonedParent, nextSibling, clonedChild, clonedGrandParent;\r
+\r
+                       if (next == root)\r
+                               return t._traverseNode(next, isFullySelected, true, how);\r
+\r
+                       parent = next.parentNode;\r
+                       clonedParent = t._traverseNode(parent, false, true, how);\r
+\r
+                       while (parent != null) {\r
+                               while (next != null) {\r
+                                       nextSibling = next.nextSibling;\r
+                                       clonedChild = t._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 = t._traverseNode(parent, false, true, how);\r
+\r
+                               if (how != DELETE)\r
+                                       clonedGrandParent.appendChild(clonedParent);\r
+\r
+                               clonedParent = clonedGrandParent;\r
+                       }\r
+\r
+                       // should never occur\r
+                       return null;\r
+               },\r
+\r
+               _traverseNode : function(n, isFullySelected, isLeft, how) {\r
+                       var t = this, txtValue, newNodeValue, oldNodeValue, offset, newNode;\r
+\r
+                       if (isFullySelected)\r
+                               return t._traverseFullySelected(n, how);\r
+\r
+                       if (n.nodeType == 3 /* TEXT_NODE */) {\r
+                               txtValue = n.nodeValue;\r
+\r
+                               if (isLeft) {\r
+                                       offset = t.startOffset;\r
+                                       newNodeValue = txtValue.substring(offset);\r
+                                       oldNodeValue = txtValue.substring(0, offset);\r
+                               } else {\r
+                                       offset = t.endOffset;\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 null;\r
+\r
+                               newNode = n.cloneNode(false);\r
+                               newNode.nodeValue = newNodeValue;\r
+\r
+                               return newNode;\r
+                       }\r
+\r
+                       if (how == DELETE)\r
+                               return null;\r
+\r
+                       return n.cloneNode(false);\r
+               },\r
+\r
+               _traverseFullySelected : function(n, how) {\r
+                       var t = this;\r
+\r
+                       if (how != DELETE)\r
+                               return how == CLONE ? n.cloneNode(true) : n;\r
+\r
+                       n.parentNode.removeChild(n);\r
+                       return null;\r
+               }\r
+       });\r
+\r
+       ns.Range = Range;\r
+})(tinymce.dom);\r
+(function() {\r
+       function Selection(selection) {\r
+               var t = this, invisibleChar = '\uFEFF', range, lastIERng;\r
+\r
+               function compareRanges(rng1, rng2) {\r
+                       if (rng1 && rng2) {\r
+                               // Both are control ranges and the selected element matches\r
+                               if (rng1.item && rng2.item && rng1.item(0) === rng2.item(0))\r
+                                       return 1;\r
+\r
+                               // Both are text ranges and the range matches\r
+                               if (rng1.isEqual && rng2.isEqual && rng2.isEqual(rng1))\r
+                                       return 1;\r
+                       }\r
+\r
+                       return 0;\r
+               };\r
+\r
+               function getRange() {\r
+                       var dom = selection.dom, ieRange = selection.getRng(), domRange = dom.createRng(), startPos, endPos, element, sc, ec, collapsed;\r
+\r
+                       function findIndex(element) {\r
+                               var nl = element.parentNode.childNodes, i;\r
+\r
+                               for (i = nl.length - 1; i >= 0; i--) {\r
+                                       if (nl[i] == element)\r
+                                               return i;\r
+                               }\r
+\r
+                               return -1;\r
+                       };\r
+\r
+                       function findEndPoint(start) {\r
+                               var rng = ieRange.duplicate(), parent, i, nl, n, offset = 0, index = 0, pos, tmpRng;\r
+\r
+                               // Insert marker character\r
+                               rng.collapse(start);\r
+                               parent = rng.parentElement();\r
+                               rng.pasteHTML(invisibleChar); // Needs to be a pasteHTML instead of .text = since IE has a bug with nodeValue\r
+\r
+                               // Find marker character\r
+                               nl = parent.childNodes;\r
+                               for (i = 0; i < nl.length; i++) {\r
+                                       n = nl[i];\r
+\r
+                                       // Calculate node index excluding text node fragmentation\r
+                                       if (i > 0 && (n.nodeType !== 3 || nl[i - 1].nodeType !== 3))\r
+                                               index++;\r
+\r
+                                       // If text node then calculate offset\r
+                                       if (n.nodeType === 3) {\r
+                                               // Look for marker\r
+                                               pos = n.nodeValue.indexOf(invisibleChar);\r
+                                               if (pos !== -1) {\r
+                                                       offset += pos;\r
+                                                       break;\r
+                                               }\r
+\r
+                                               offset += n.nodeValue.length;\r
+                                       } else\r
+                                               offset = 0;\r
+                               }\r
+\r
+                               // Remove marker character\r
+                               rng.moveStart('character', -1);\r
+                               rng.text = '';\r
+\r
+                               return {index : index, offset : offset, parent : parent};\r
+                       };\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
+\r
+                       // Handle control selection or text selection of a image\r
+                       if (ieRange.item || !element.hasChildNodes()) {\r
+                               domRange.setStart(element.parentNode, findIndex(element));\r
+                               domRange.setEnd(domRange.startContainer, domRange.startOffset + 1);\r
+\r
+                               return domRange;\r
+                       }\r
+\r
+                       // Check collapsed state\r
+                       collapsed = selection.isCollapsed();\r
+\r
+                       // Find start and end pos index and offset\r
+                       startPos = findEndPoint(true);\r
+                       endPos = findEndPoint(false);\r
+\r
+                       // Normalize the elements to avoid fragmented dom\r
+                       startPos.parent.normalize();\r
+                       endPos.parent.normalize();\r
+\r
+                       // Set start container and offset\r
+                       sc = startPos.parent.childNodes[Math.min(startPos.index, startPos.parent.childNodes.length - 1)];\r
+\r
+                       if (sc.nodeType != 3)\r
+                               domRange.setStart(startPos.parent, startPos.index);\r
+                       else\r
+                               domRange.setStart(startPos.parent.childNodes[startPos.index], startPos.offset);\r
+\r
+                       // Set end container and offset\r
+                       ec = endPos.parent.childNodes[Math.min(endPos.index, endPos.parent.childNodes.length - 1)];\r
+\r
+                       if (ec.nodeType != 3) {\r
+                               if (!collapsed)\r
+                                       endPos.index++;\r
+\r
+                               domRange.setEnd(endPos.parent, endPos.index);\r
+                       } else\r
+                               domRange.setEnd(endPos.parent.childNodes[endPos.index], endPos.offset);\r
+\r
+                       // If not collapsed then make sure offsets are valid\r
+                       if (!collapsed) {\r
+                               sc = domRange.startContainer;\r
+                               if (sc.nodeType == 1)\r
+                                       domRange.setStart(sc, Math.min(domRange.startOffset, sc.childNodes.length));\r
+\r
+                               ec = domRange.endContainer;\r
+                               if (ec.nodeType == 1)\r
+                                       domRange.setEnd(ec, Math.min(domRange.endOffset, ec.childNodes.length));\r
+                       }\r
+\r
+                       // Restore selection to new range\r
+                       t.addRange(domRange);\r
+\r
+                       return domRange;\r
+               };\r
+\r
+               this.addRange = function(rng) {\r
+                       var ieRng, body = selection.dom.doc.body, startPos, endPos, sc, so, ec, eo;\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
+\r
+                       // Find element\r
+                       sc = sc.nodeType == 1 ? sc.childNodes[Math.min(so, sc.childNodes.length - 1)] : sc;\r
+                       ec = ec.nodeType == 1 ? ec.childNodes[Math.min(so == eo ? eo : eo - 1, ec.childNodes.length - 1)] : ec;\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
+\r
+                                       // Padd empty elements with invisible character\r
+                                       if (!sc.hasChildNodes() && sc.canHaveHTML)\r
+                                               sc.innerHTML = invisibleChar;\r
+\r
+                                       // Select element contents\r
+                                       ieRng.moveToElementText(sc);\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
+                                       }\r
+                               }\r
+\r
+                               if (so == eo)\r
+                                       ieRng.collapse(eo <= rng.endContainer.childNodes.length - 1);\r
+\r
+                               ieRng.select();\r
+\r
+                               return;\r
+                       }\r
+\r
+                       function getCharPos(container, offset) {\r
+                               var nodeVal, rng, pos;\r
+\r
+                               if (container.nodeType != 3)\r
+                                       return -1;\r
+\r
+                               nodeVal = container.nodeValue;\r
+                               rng = body.createTextRange();\r
+\r
+                               // Insert marker at offset position\r
+                               container.nodeValue = nodeVal.substring(0, offset) + invisibleChar + nodeVal.substring(offset);\r
+\r
+                               // Find char pos of marker and remove it\r
+                               rng.moveToElementText(container.parentNode);\r
+                               rng.findText(invisibleChar);\r
+                               pos = Math.abs(rng.moveStart('character', -0xFFFFF));\r
+                               container.nodeValue = nodeVal;\r
+\r
+                               return pos;\r
+                       };\r
+\r
+                       // Collapsed range\r
+                       if (rng.collapsed) {\r
+                               pos = getCharPos(sc, so);\r
+\r
+                               ieRng = body.createTextRange();\r
+                               ieRng.move('character', pos);\r
+                               ieRng.select();\r
+\r
+                               return;\r
+                       } else {\r
+                               // If same text container\r
+                               if (sc == ec && sc.nodeType == 3) {\r
+                                       startPos = getCharPos(sc, so);\r
+\r
+                                       ieRng.move('character', startPos);\r
+                                       ieRng.moveEnd('character', eo - so);\r
+                                       ieRng.select();\r
+\r
+                                       return;\r
+                               }\r
+\r
+                               // Get caret positions\r
+                               startPos = getCharPos(sc, so);\r
+                               endPos = getCharPos(ec, eo);\r
+                               ieRng = body.createTextRange();\r
+\r
+                               // Move start of range to start character position or start element\r
+                               if (startPos == -1) {\r
+                                       ieRng.moveToElementText(sc);\r
+                                       startPos = 0;\r
+                               } else\r
+                                       ieRng.move('character', startPos);\r
+\r
+                               // Move end of range to end character position or end element\r
+                               tmpRng = body.createTextRange();\r
+\r
+                               if (endPos == -1)\r
+                                       tmpRng.moveToElementText(ec);\r
+                               else\r
+                                       tmpRng.move('character', endPos);\r
+\r
+                               ieRng.setEndPoint('EndToEnd', tmpRng);\r
+                               ieRng.select();\r
+\r
+                               return;\r
+                       }\r
+               };\r
+\r
+               this.getRangeAt = function() {\r
+                       // Setup new range if the cache is empty\r
+                       if (!range || !compareRanges(lastIERng, selection.getRng())) {\r
+                               range = getRange();\r
+\r
+                               // Store away text range for next call\r
+                               lastIERng = selection.getRng();\r
+                       }\r
+\r
+                       // Return cached range\r
+                       return range;\r
+               };\r
+\r
+               this.destroy = function() {\r
+                       // Destroy cached range and last IE range to avoid memory leaks\r
+                       lastIERng = range = null;\r
+               };\r
+       };\r
+\r
+       // Expose the selection object\r
+       tinymce.dom.TridentSelection = Selection;\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
+\r
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,\r
+       done = 0,\r
+       toString = Object.prototype.toString,\r
+       hasDuplicate = false;\r
+\r
+var Sizzle = function(selector, context, results, seed) {\r
+       results = results || [];\r
+       var origContext = context = context || document;\r
+\r
+       if ( context.nodeType !== 1 && context.nodeType !== 9 ) {\r
+               return [];\r
+       }\r
+       \r
+       if ( !selector || typeof selector !== "string" ) {\r
+               return results;\r
+       }\r
+\r
+       var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context);\r
+       \r
+       // Reset the position of the chunker regexp (start from head)\r
+       chunker.lastIndex = 0;\r
+       \r
+       while ( (m = chunker.exec(selector)) !== null ) {\r
+               parts.push( m[1] );\r
+               \r
+               if ( m[2] ) {\r
+                       extra = RegExp.rightContext;\r
+                       break;\r
+               }\r
+       }\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
+\r
+                       while ( parts.length ) {\r
+                               selector = parts.shift();\r
+\r
+                               if ( Expr.relative[ selector ] )\r
+                                       selector += parts.shift();\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
+                       var 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
+                       var 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
+                       if ( parts.length > 0 ) {\r
+                               checkSet = makeArray(set);\r
+                       } else {\r
+                               prune = false;\r
+                       }\r
+\r
+                       while ( parts.length ) {\r
+                               var cur = parts.pop(), pop = cur;\r
+\r
+                               if ( !Expr.relative[ cur ] ) {\r
+                                       cur = "";\r
+                               } else {\r
+                                       pop = parts.pop();\r
+                               }\r
+\r
+                               if ( pop == null ) {\r
+                                       pop = context;\r
+                               }\r
+\r
+                               Expr.relative[ cur ]( checkSet, pop, contextXML );\r
+                       }\r
+               } else {\r
+                       checkSet = parts = [];\r
+               }\r
+       }\r
+\r
+       if ( !checkSet ) {\r
+               checkSet = set;\r
+       }\r
+\r
+       if ( !checkSet ) {\r
+               throw "Syntax error, unrecognized expression: " + (cur || selector);\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 ( var i = 0; checkSet[i] != null; i++ ) {\r
+                               if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {\r
+                                       results.push( set[i] );\r
+                               }\r
+                       }\r
+               } else {\r
+                       for ( var 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
+       if ( extra ) {\r
+               Sizzle( extra, origContext, results, seed );\r
+               Sizzle.uniqueSort( results );\r
+       }\r
+\r
+       return results;\r
+};\r
+\r
+Sizzle.uniqueSort = function(results){\r
+       if ( sortOrder ) {\r
+               hasDuplicate = false;\r
+               results.sort(sortOrder);\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
+                       }\r
+               }\r
+       }\r
+};\r
+\r
+Sizzle.matches = function(expr, set){\r
+       return Sizzle(expr, null, null, set);\r
+};\r
+\r
+Sizzle.find = function(expr, context, isXML){\r
+       var set, match;\r
+\r
+       if ( !expr ) {\r
+               return [];\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.match[ type ].exec( expr )) ) {\r
+                       var left = RegExp.leftContext;\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
+       if ( !set ) {\r
+               set = context.getElementsByTagName("*");\r
+       }\r
+\r
+       return {set: set, expr: expr};\r
+};\r
+\r
+Sizzle.filter = function(expr, set, inplace, not){\r
+       var old = expr, result = [], curLoop = set, match, anyFound,\r
+               isXMLFilter = set && set[0] && isXML(set[0]);\r
+\r
+       while ( expr && set.length ) {\r
+               for ( var type in Expr.filter ) {\r
+                       if ( (match = Expr.match[ type ].exec( expr )) != null ) {\r
+                               var filter = Expr.filter[ type ], found, item;\r
+                               anyFound = false;\r
+\r
+                               if ( curLoop == result ) {\r
+                                       result = [];\r
+                               }\r
+\r
+                               if ( Expr.preFilter[ type ] ) {\r
+                                       match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );\r
+\r
+                                       if ( !match ) {\r
+                                               anyFound = found = true;\r
+                                       } else if ( match === true ) {\r
+                                               continue;\r
+                                       }\r
+                               }\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
+\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 ( found !== undefined ) {\r
+                                       if ( !inplace ) {\r
+                                               curLoop = result;\r
+                                       }\r
+\r
+                                       expr = expr.replace( Expr.match[ type ], "" );\r
+\r
+                                       if ( !anyFound ) {\r
+                                               return [];\r
+                                       }\r
+\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // Improper expression\r
+               if ( expr == old ) {\r
+                       if ( anyFound == null ) {\r
+                               throw "Syntax error, unrecognized expression: " + expr;\r
+                       } else {\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               old = expr;\r
+       }\r
+\r
+       return curLoop;\r
+};\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\(\)]*)+)\2\))?/\r
+       },\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, isXML){\r
+                       var isPartStr = typeof part === "string",\r
+                               isTag = isPartStr && !/\W/.test(part),\r
+                               isPartStrNotTag = isPartStr && !isTag;\r
+\r
+                       if ( isTag && !isXML ) {\r
+                               part = part.toUpperCase();\r
+                       }\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
+                                       checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?\r
+                                               elem || false :\r
+                                               elem === part;\r
+                               }\r
+                       }\r
+\r
+                       if ( isPartStrNotTag ) {\r
+                               Sizzle.filter( part, checkSet, true );\r
+                       }\r
+               },\r
+               ">": function(checkSet, part, isXML){\r
+                       var isPartStr = typeof part === "string";\r
+\r
+                       if ( isPartStr && !/\W/.test(part) ) {\r
+                               part = isXML ? part : part.toUpperCase();\r
+\r
+                               for ( var i = 0, l = checkSet.length; i < l; i++ ) {\r
+                                       var elem = checkSet[i];\r
+                                       if ( elem ) {\r
+                                               var parent = elem.parentNode;\r
+                                               checkSet[i] = parent.nodeName === part ? parent : false;\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               for ( var i = 0, l = checkSet.length; i < l; i++ ) {\r
+                                       var elem = checkSet[i];\r
+                                       if ( elem ) {\r
+                                               checkSet[i] = isPartStr ?\r
+                                                       elem.parentNode :\r
+                                                       elem.parentNode === part;\r
+                                       }\r
+                               }\r
+\r
+                               if ( isPartStr ) {\r
+                                       Sizzle.filter( part, checkSet, true );\r
+                               }\r
+                       }\r
+               },\r
+               "": function(checkSet, part, isXML){\r
+                       var doneName = done++, checkFn = dirCheck;\r
+\r
+                       if ( !part.match(/\W/) ) {\r
+                               var nodeCheck = part = isXML ? part : part.toUpperCase();\r
+                               checkFn = dirNodeCheck;\r
+                       }\r
+\r
+                       checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);\r
+               },\r
+               "~": function(checkSet, part, isXML){\r
+                       var doneName = done++, checkFn = dirCheck;\r
+\r
+                       if ( typeof part === "string" && !part.match(/\W/) ) {\r
+                               var nodeCheck = part = isXML ? part : part.toUpperCase();\r
+                               checkFn = dirNodeCheck;\r
+                       }\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
+               },\r
+               NAME: function(match, context, isXML){\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
+                               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
+                       if ( isXML ) {\r
+                               return match;\r
+                       }\r
+\r
+                       for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {\r
+                               if ( elem ) {\r
+                                       if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {\r
+                                               if ( !inplace )\r
+                                                       result.push( elem );\r
+                                       } else if ( inplace ) {\r
+                                               curLoop[i] = false;\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       return false;\r
+               },\r
+               ID: function(match){\r
+                       return match[1].replace(/\\/g, "");\r
+               },\r
+               TAG: function(match, curLoop){\r
+                       for ( var i = 0; curLoop[i] === false; i++ ){}\r
+                       return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();\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
+\r
+                       // TODO: Move to normal caching system\r
+                       match[0] = done++;\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
+\r
+                       if ( match[2] === "~=" ) {\r
+                               match[4] = " " + match[4] + " ";\r
+                       }\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 ( match[3].match(chunker).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
+                                       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.toUpperCase() === "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
+                       if ( filter ) {\r
+                               return filter( elem, i, match, array );\r
+                       } else if ( name === "contains" ) {\r
+                               return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;\r
+                       } else if ( name === "not" ) {\r
+                               var not = match[3];\r
+\r
+                               for ( var i = 0, l = not.length; i < l; i++ ) {\r
+                                       if ( not[i] === elem ) {\r
+                                               return false;\r
+                                       }\r
+                               }\r
+\r
+                               return true;\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 ) return false;\r
+                                       }\r
+                                       if ( type == 'first') return true;\r
+                                       node = elem;\r
+                               case 'last':\r
+                                       while (node = node.nextSibling)  {\r
+                                               if ( node.nodeType === 1 ) return false;\r
+                                       }\r
+                                       return true;\r
+                               case 'nth':\r
+                                       var first = match[2], last = match[3];\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 === 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
+                       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
+                       if ( filter ) {\r
+                               return filter( elem, i, match, array );\r
+                       }\r
+               }\r
+       }\r
+};\r
+\r
+var origPOS = Expr.match.POS;\r
+\r
+for ( var type in Expr.match ) {\r
+       Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );\r
+}\r
+\r
+var makeArray = function(array, results) {\r
+       array = Array.prototype.slice.call( array );\r
+\r
+       if ( results ) {\r
+               results.push.apply( results, array );\r
+               return results;\r
+       }\r
+       \r
+       return array;\r
+};\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
+try {\r
+       Array.prototype.slice.call( document.documentElement.childNodes );\r
+\r
+// Provide a fallback method if it does not work\r
+} catch(e){\r
+       makeArray = function(array, results) {\r
+               var ret = results || [];\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 i = 0, l = array.length; i < l; i++ ) {\r
+                                       ret.push( array[i] );\r
+                               }\r
+                       } else {\r
+                               for ( var i = 0; array[i]; i++ ) {\r
+                                       ret.push( array[i] );\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return ret;\r
+       };\r
+}\r
+\r
+var sortOrder;\r
+\r
+if ( document.documentElement.compareDocumentPosition ) {\r
+       sortOrder = function( a, b ) {\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
+               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
+               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
+// 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
+       // 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
+       // 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
+               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
+       root.removeChild( form );\r
+})();\r
+\r
+(function(){\r
+       // Check to see if the browser returns only elements\r
+       // when doing getElementsByTagName("*")\r
+\r
+       // Create a fake element\r
+       var div = document.createElement("div");\r
+       div.appendChild( document.createComment("") );\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
+\r
+                       // Filter out possible comments\r
+                       if ( match[1] === "*" ) {\r
+                               var tmp = [];\r
+\r
+                               for ( var i = 0; results[i]; i++ ) {\r
+                                       if ( results[i].nodeType === 1 ) {\r
+                                               tmp.push( results[i] );\r
+                                       }\r
+                               }\r
+\r
+                               results = tmp;\r
+                       }\r
+\r
+                       return results;\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
+               };\r
+       }\r
+})();\r
+\r
+if ( document.querySelectorAll ) (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 && !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
+       for ( var prop in oldSizzle ) {\r
+               Sizzle[ prop ] = oldSizzle[ prop ];\r
+       }\r
+})();\r
+\r
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){\r
+       var div = document.createElement("div");\r
+       div.innerHTML = "<div class='test e'></div><div class='test'></div>";\r
+\r
+       // Opera can't find a second classname (in 9.6)\r
+       if ( div.getElementsByClassName("e").length === 0 )\r
+               return;\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
+       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
+\r
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\r
+       var sibDir = dir == "previousSibling" && !isXML;\r
+       for ( var i = 0, l = checkSet.length; i < l; i++ ) {\r
+               var elem = checkSet[i];\r
+               if ( elem ) {\r
+                       if ( sibDir && elem.nodeType === 1 ){\r
+                               elem.sizcache = doneName;\r
+                               elem.sizset = i;\r
+                       }\r
+                       elem = elem[dir];\r
+                       var match = false;\r
+\r
+                       while ( elem ) {\r
+                               if ( elem.sizcache === doneName ) {\r
+                                       match = checkSet[elem.sizset];\r
+                                       break;\r
+                               }\r
+\r
+                               if ( elem.nodeType === 1 && !isXML ){\r
+                                       elem.sizcache = doneName;\r
+                                       elem.sizset = i;\r
+                               }\r
+\r
+                               if ( elem.nodeName === cur ) {\r
+                                       match = elem;\r
+                                       break;\r
+                               }\r
+\r
+                               elem = elem[dir];\r
+                       }\r
+\r
+                       checkSet[i] = match;\r
+               }\r
+       }\r
+}\r
+\r
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\r
+       var sibDir = dir == "previousSibling" && !isXML;\r
+       for ( var i = 0, l = checkSet.length; i < l; i++ ) {\r
+               var elem = checkSet[i];\r
+               if ( elem ) {\r
+                       if ( sibDir && elem.nodeType === 1 ) {\r
+                               elem.sizcache = doneName;\r
+                               elem.sizset = i;\r
+                       }\r
+                       elem = elem[dir];\r
+                       var match = false;\r
+\r
+                       while ( elem ) {\r
+                               if ( elem.sizcache === doneName ) {\r
+                                       match = checkSet[elem.sizset];\r
+                                       break;\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
+                               }\r
+\r
+                               elem = elem[dir];\r
+                       }\r
+\r
+                       checkSet[i] = match;\r
+               }\r
+       }\r
+}\r
+\r
+var 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
+var isXML = function(elem){\r
+       return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||\r
+               !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";\r
+};\r
+\r
+var posProcess = function(selector, context){\r
+       var tmpSet = [], later = "", match,\r
+               root = context.nodeType ? [context] : context;\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
+       selector = Expr.relative[selector] ? selector + "*" : selector;\r
+\r
+       for ( var i = 0, l = root.length; i < l; i++ ) {\r
+               Sizzle( selector, root[i], tmpSet );\r
+       }\r
+\r
+       return Sizzle.filter( later, tmpSet );\r
+};\r
+\r
+// EXPOSE\r
+\r
+window.tinymce.dom.Sizzle = Sizzle;\r
+\r
+})();\r
+\r
+(function(tinymce) {\r
+       // Shorten names\r
+       var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;\r
+\r
+       tinymce.create('static tinymce.dom.Event', {\r
+               inits : [],\r
+               events : [],\r
+\r
+\r
+               add : function(o, n, f, s) {\r
+                       var cb, t = this, el = t.events, r;\r
+\r
+                       // Handle array\r
+                       if (o && o.hasOwnProperty && o instanceof Array) {\r
+                               r = [];\r
+\r
+                               each(o, function(o) {\r
+                                       o = DOM.get(o);\r
+                                       r.push(t.add(o, n, f, s));\r
+                               });\r
+\r
+                               return r;\r
+                       }\r
+\r
+                       o = DOM.get(o);\r
+\r
+                       if (!o)\r
+                               return;\r
+\r
+                       // Setup event callback\r
+                       cb = function(e) {\r
+                               e = e || window.event;\r
+\r
+                               // Patch in target in IE it's W3C valid\r
+                               if (e && !e.target && isIE)\r
+                                       e.target = e.srcElement;\r
 \r
                                if (!s)\r
                                        return f(e);\r
@@ -2484,7 +4355,7 @@ tinymce.create('static tinymce.util.XHR', {
                        var t = this, a = t.events, s = false, r;\r
 \r
                        // Handle array\r
-                       if (o && o instanceof Array) {\r
+                       if (o && o.hasOwnProperty && o instanceof Array) {\r
                                r = [];\r
 \r
                                each(o, function(o) {\r
@@ -2527,7 +4398,6 @@ tinymce.create('static tinymce.util.XHR', {
                        }\r
                },\r
 \r
-               // #endif\r
 \r
                cancel : function(e) {\r
                        if (!e)\r
@@ -2594,6 +4464,10 @@ tinymce.create('static tinymce.util.XHR', {
                _pageInit : function() {\r
                        var e = Event;\r
 \r
+                       // Keep it from running more than once\r
+                       if (e.domLoaded)\r
+                               return;\r
+\r
                        e._remove(window, 'DOMContentLoaded', e._pageInit);\r
                        e.domLoaded = true;\r
 \r
@@ -2605,35 +4479,42 @@ tinymce.create('static tinymce.util.XHR', {
                },\r
 \r
                _wait : function() {\r
-                       var t;\r
-\r
                        // No need since the document is already loaded\r
                        if (window.tinyMCE_GZ && tinyMCE_GZ.loaded) {\r
                                Event.domLoaded = 1;\r
                                return;\r
                        }\r
 \r
-                       if (isIE && document.location.protocol != 'https:') {\r
-                               // Fake DOMContentLoaded on IE\r
-                               document.write('<script id=__ie_onload defer src=\'javascript:""\';><\/script>');\r
-                               DOM.get("__ie_onload").onreadystatechange = function() {\r
-                                       if (this.readyState == "complete") {\r
+                       // Use IE method\r
+                       if (document.attachEvent) {\r
+                               document.attachEvent("onreadystatechange", function() {\r
+                                       if (document.readyState === "complete") {\r
+                                               document.detachEvent("onreadystatechange", arguments.callee);\r
                                                Event._pageInit();\r
-                                               DOM.get("__ie_onload").onreadystatechange = null; // Prevent leak\r
                                        }\r
-                               };\r
-                       } else {\r
-                               Event._add(window, 'DOMContentLoaded', Event._pageInit, Event);\r
+                               });\r
+\r
+                               if (document.documentElement.doScroll && window == window.top) {\r
+                                       (function() {\r
+                                               if (Event.domLoaded)\r
+                                                       return;\r
 \r
-                               if (isIE || isWebKit) {\r
-                                       t = setInterval(function() {\r
-                                               if (/loaded|complete/.test(document.readyState)) {\r
-                                                       clearInterval(t);\r
-                                                       Event._pageInit();\r
+                                               try {\r
+                                                       // If IE is used, use the trick by Diego Perini\r
+                                                       // http://javascript.nwbox.com/IEContentLoaded/\r
+                                                       document.documentElement.doScroll("left");\r
+                                               } catch (ex) {\r
+                                                       setTimeout(arguments.callee, 0);\r
+                                                       return;\r
                                                }\r
-                                       }, 10);\r
+\r
+                                               Event._pageInit();\r
+                                       })();\r
                                }\r
-                       }\r
+                       } else if (document.addEventListener)\r
+                               Event._add(window, 'DOMContentLoaded', Event._pageInit, Event);\r
+\r
+                       Event._add(window, 'load', Event._pageInit, Event);\r
                }\r
 \r
                });\r
@@ -2644,11 +4525,8 @@ tinymce.create('static tinymce.util.XHR', {
        // Dispatch DOM content loaded event for IE and Safari\r
        Event._wait();\r
        tinymce.addUnload(Event._unload);\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/dom/Element.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        var each = tinymce.each;\r
 \r
        tinymce.create('tinymce.dom.Element', {\r
@@ -2688,22 +4566,15 @@ tinymce.create('static tinymce.util.XHR', {
                                'get'\r
                        ], function(k) {\r
                                t[k] = function() {\r
-                                       var a = arguments, o;\r
-\r
-                                       // Opera fails\r
-                                       if (tinymce.isOpera) {\r
-                                               a = [id];\r
+                                       var a = [id], i;\r
 \r
-                                               each(arguments, function(v) {\r
-                                                       a.push(v);\r
-                                               });\r
-                                       } else\r
-                                               Array.prototype.unshift.call(a, el || id);\r
+                                       for (i = 0; i < arguments.length; i++)\r
+                                               a.push(arguments[i]);\r
 \r
-                                       o = dom[k].apply(dom, a);\r
+                                       a = dom[k].apply(dom, a);\r
                                        t.update(k);\r
 \r
-                                       return o;\r
+                                       return a;\r
                                };\r
                        });\r
                },\r
@@ -2781,11 +4652,8 @@ tinymce.create('static tinymce.util.XHR', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/dom/Selection.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        function trimNl(s) {\r
                return s.replace(/[\n\r]+/g, '');\r
        };\r
@@ -2801,6 +4669,20 @@ tinymce.create('static tinymce.util.XHR', {
                        t.win = win;\r
                        t.serializer = serializer;\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
+\r
+                       // No W3C Range support\r
+                       if (!t.win.getSelection)\r
+                               t.tridentSel = new tinymce.dom.TridentSelection(t);\r
+\r
                        // Prevent leaks\r
                        tinymce.addUnload(t.destroy, t);\r
                },\r
@@ -2812,6 +4694,7 @@ tinymce.create('static tinymce.util.XHR', {
                        wb = wa = '';\r
                        s.get = true;\r
                        s.format = s.format || 'html';\r
+                       t.onBeforeGetContent.dispatch(t, s);\r
 \r
                        if (s.format == 'text')\r
                                return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : ''));\r
@@ -2835,37 +4718,47 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                        s.getInner = true;\r
 \r
-                       return t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;\r
+                       s.content = t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;\r
+                       t.onGetContent.dispatch(t, s);\r
+\r
+                       return s.content;\r
                },\r
 \r
                setContent : function(h, s) {\r
-                       var t = this, r = t.getRng(), d = t.win.document;\r
+                       var t = this, r = t.getRng(), c, d = t.win.document;\r
 \r
                        s = s || {format : 'html'};\r
                        s.set = true;\r
-                       h = t.dom.processHTML(h);\r
+                       h = s.content = t.dom.processHTML(h);\r
+\r
+                       // Dispatch before set content event\r
+                       t.onBeforeSetContent.dispatch(t, s);\r
+                       h = s.content;\r
 \r
                        if (r.insertNode) {\r
-                               // Gecko has a bug where if you insert &nbsp; using InsertHTML it will insert a space instead\r
-                               // So we simply check if the input is HTML or text and then insert text using the insertNode method\r
-                               if (tinymce.isGecko && h.indexOf('<') == -1) {\r
-                                       r.deleteContents();\r
-                                       r.insertNode(t.getRng().createContextualFragment(h + '<span id="__caret">_</span>'));\r
-                                       t.select(t.dom.get('__caret'));\r
-                                       t.getRng().deleteContents();\r
-                                       return;\r
-                               }\r
+                               // Make caret marker since insertNode places the caret in the beginning of text after insert\r
+                               h += '<span id="__caret">_</span>';\r
 \r
-                               // Use insert HTML if it exists (places cursor after content)\r
-                               try {\r
-                                       // This might fail with an exception see bug #1893736\r
-                                       if (d.queryCommandEnabled('InsertHTML'))\r
-                                               return d.execCommand('InsertHTML', false, h);\r
-                               } catch (ex) {\r
-                                       // Use old school method\r
-                                       r.deleteContents();\r
-                                       r.insertNode(t.getRng().createContextualFragment(h));\r
-                               }\r
+                               // Delete and insert new node\r
+                               r.deleteContents();\r
+                               r.insertNode(t.getRng().createContextualFragment(h));\r
+\r
+                               // Move to caret marker\r
+                               c = t.dom.get('__caret');\r
+\r
+                               // Make sure we wrap it compleatly, Opera fails with a simple select call\r
+                               r = d.createRange();\r
+                               r.setStartBefore(c);\r
+                               r.setEndAfter(c);\r
+                               t.setRng(r);\r
+\r
+                               // Delete the marker, and hopefully the caret gets placed in the right location\r
+                               // Removed this since it seems to remove &nbsp; in FF and simply deleting it\r
+                               // doesn't seem to affect the caret position in any browser\r
+                               //d.execCommand('Delete', false, null);\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
@@ -2875,6 +4768,9 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                                r.pasteHTML(h);\r
                        }\r
+\r
+                       // Dispatch set content event\r
+                       t.onSetContent.dispatch(t, s);\r
                },\r
 \r
                getStart : function() {\r
@@ -2898,7 +4794,7 @@ tinymce.create('static tinymce.util.XHR', {
                                if (e.nodeName == 'BODY')\r
                                        return e.firstChild;\r
 \r
-                               return t.dom.getParent(e, function(n) {return n.nodeType == 1;});\r
+                               return t.dom.getParent(e, '*');\r
                        }\r
                },\r
 \r
@@ -2923,7 +4819,7 @@ tinymce.create('static tinymce.util.XHR', {
                                if (e.nodeName == 'BODY')\r
                                        return e.lastChild;\r
 \r
-                               return t.dom.getParent(e, function(n) {return n.nodeType == 1;});\r
+                               return t.dom.getParent(e, '*');\r
                        }\r
                },\r
 \r
@@ -3175,19 +5071,24 @@ tinymce.create('static tinymce.util.XHR', {
                select : function(n, c) {\r
                        var t = this, r = t.getRng(), s = t.getSel(), b, fn, ln, d = t.win.document;\r
 \r
-                       function first(n) {\r
-                               return n ? d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false).nextNode() : null;\r
-                       };\r
+                       function find(n, start) {\r
+                               var walker, o;\r
 \r
-                       function last(n) {\r
-                               var c, o, w;\r
+                               if (n) {\r
+                                       walker = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
 \r
-                               if (!n)\r
-                                       return null;\r
+                                       // Find first/last non empty text node\r
+                                       while (n = walker.nextNode()) {\r
+                                               o = n;\r
 \r
-                               w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
-                               while (c = w.nextNode())\r
-                                       o = c;\r
+                                               if (tinymce.trim(n.nodeValue).length != 0) {\r
+                                                       if (start)\r
+                                                               return n;\r
+                                                       else\r
+                                                               o = n;\r
+                                               }\r
+                                       }\r
+                               }\r
 \r
                                return o;\r
                        };\r
@@ -3210,14 +5111,21 @@ tinymce.create('static tinymce.util.XHR', {
                                }\r
                        } else {\r
                                if (c) {\r
-                                       fn = first(n);\r
-                                       ln = last(n);\r
+                                       fn = find(n, 1) || t.dom.select('br:first', n)[0];\r
+                                       ln = find(n, 0) || t.dom.select('br:last', n)[0];\r
 \r
                                        if (fn && ln) {\r
-                                               //console.debug(fn, ln);\r
                                                r = d.createRange();\r
-                                               r.setStart(fn, 0);\r
-                                               r.setEnd(ln, ln.nodeValue.length);\r
+\r
+                                               if (fn.nodeName == 'BR')\r
+                                                       r.setStartBefore(fn);\r
+                                               else\r
+                                                       r.setStart(fn, 0);\r
+\r
+                                               if (ln.nodeName == 'BR')\r
+                                                       r.setEndBefore(ln);\r
+                                               else\r
+                                                       r.setEnd(ln, ln.nodeValue.length);\r
                                        } else\r
                                                r.selectNode(n);\r
                                } else\r
@@ -3235,7 +5143,7 @@ tinymce.create('static tinymce.util.XHR', {
                        if (!r || r.item)\r
                                return false;\r
 \r
-                       return !s || r.boundingWidth == 0 || s.isCollapsed;\r
+                       return !s || r.boundingWidth == 0 || r.collapsed;\r
                },\r
 \r
                collapse : function(b) {\r
@@ -3258,11 +5166,15 @@ tinymce.create('static tinymce.util.XHR', {
                        return w.getSelection ? w.getSelection() : w.document.selection;\r
                },\r
 \r
-               getRng : function() {\r
-                       var t = this, s = t.getSel(), r;\r
+               getRng : function(w3c) {\r
+                       var t = this, s, r;\r
+\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)\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
@@ -3278,16 +5190,23 @@ tinymce.create('static tinymce.util.XHR', {
                },\r
 \r
                setRng : function(r) {\r
-                       var s;\r
+                       var s, t = this;\r
 \r
-                       if (!isIE) {\r
-                               s = this.getSel();\r
+                       if (!t.tridentSel) {\r
+                               s = t.getSel();\r
 \r
                                if (s) {\r
                                        s.removeAllRanges();\r
                                        s.addRange(r);\r
                                }\r
                        } else {\r
+                               // Is W3C Range\r
+                               if (r.cloneRange) {\r
+                                       t.tridentSel.addRange(r);\r
+                                       return;\r
+                               }\r
+\r
+                               // Is IE specific range\r
                                try {\r
                                        r.select();\r
                                } catch (ex) {\r
@@ -3316,38 +5235,64 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                                // Handle selection a image or other control like element such as anchors\r
                                if (!r.collapsed) {\r
-                                       if (r.startContainer == r.endContainer || (tinymce.isWebKit && r.startContainer == r.endContainer.parentNode)) {\r
-                                               if (r.startOffset - r.endOffset < 2 || tinymce.isWebKit) {\r
+                                       // If the anchor node is a element instead of a text node then return this element\r
+                                       if (tinymce.isWebKit && s.anchorNode && s.anchorNode.nodeType == 1) \r
+                                               return s.anchorNode.childNodes[s.anchorOffset]; \r
+\r
+                                       if (r.startContainer == r.endContainer) {\r
+                                               if (r.startOffset - r.endOffset < 2) {\r
                                                        if (r.startContainer.hasChildNodes())\r
                                                                e = r.startContainer.childNodes[r.startOffset];\r
                                                }\r
                                        }\r
                                }\r
 \r
-                               return t.dom.getParent(e, function(n) {\r
-                                       return n.nodeType == 1;\r
-                               });\r
+                               return t.dom.getParent(e, '*');\r
                        }\r
 \r
                        return r.item ? r.item(0) : r.parentElement();\r
                },\r
 \r
+               getSelectedBlocks : function(st, en) {\r
+                       var t = this, dom = t.dom, sb, eb, n, bl = [];\r
+\r
+                       sb = dom.getParent(st || t.getStart(), dom.isBlock);\r
+                       eb = dom.getParent(en || t.getEnd(), dom.isBlock);\r
+\r
+                       if (sb)\r
+                               bl.push(sb);\r
+\r
+                       if (sb && eb && sb != eb) {\r
+                               n = sb;\r
+\r
+                               while ((n = n.nextSibling) && n != eb) {\r
+                                       if (dom.isBlock(n))\r
+                                               bl.push(n);\r
+                               }\r
+                       }\r
+\r
+                       if (eb && sb != eb)\r
+                               bl.push(eb);\r
+\r
+                       return bl;\r
+               },\r
+\r
                destroy : function(s) {\r
                        var t = this;\r
 \r
                        t.win = null;\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
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/dom/XMLWriter.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        tinymce.create('tinymce.dom.XMLWriter', {\r
                node : null,\r
 \r
@@ -3417,6 +5362,10 @@ tinymce.create('static tinymce.util.XHR', {
                },\r
 \r
                writeComment : function(v) {\r
+                       // Fix for bug #2035694\r
+                       if (tinymce.isIE)\r
+                               v = v.replace(/^\-|\-$/g, ' ');\r
+\r
                        this.node.appendChild(this.doc.createComment(v.replace(/\-\-/g, ' ')));\r
                },\r
 \r
@@ -3434,11 +5383,8 @@ tinymce.create('static tinymce.util.XHR', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/dom/StringWriter.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        tinymce.create('tinymce.dom.StringWriter', {\r
                str : null,\r
                tags : null,\r
@@ -3564,29 +5510,11 @@ tinymce.create('static tinymce.util.XHR', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/dom/Serializer.js */\r
-\r
-(function() {\r
+})(tinymce);\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
 \r
-       // Returns only attribites that have values not all attributes in IE\r
-       function getIEAtts(n) {\r
-               var o = [];\r
-\r
-               // Object will throw exception in IE\r
-               if (n.nodeName == 'OBJECT')\r
-                       return n.attributes;\r
-\r
-               n.cloneNode(false).outerHTML.replace(/([a-z0-9\:\-_]+)=/gi, function(a, b) {\r
-                       o.push({specified : 1, nodeName : b});\r
-               });\r
-\r
-               return o;\r
-       };\r
-\r
        function wildcardToRE(s) {\r
                return s.replace(/([?+*])/g, '.$1');\r
        };\r
@@ -3599,16 +5527,11 @@ tinymce.create('static tinymce.util.XHR', {
                        t.onPreProcess = new Dispatcher(t);\r
                        t.onPostProcess = new Dispatcher(t);\r
 \r
-                       if (tinymce.relaxedDomain && tinymce.isGecko) {\r
-                               // Gecko has a bug where we can't create a new XML document if domain relaxing is used\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
-                       } else {\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
                        }\r
 \r
                        // Default settings\r
@@ -3618,14 +5541,15 @@ tinymce.create('static tinymce.util.XHR', {
                                node_filter : 0,\r
                                attr_filter : 0,\r
                                invalid_attrs : /^(mce_|_moz_)/,\r
-                               closed : /(br|hr|input|meta|img|link|param)/,\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
+                               bool_attrs : /(checked|disabled|readonly|selected|nowrap)/,\r
                                valid_elements : '*[*]',\r
                                extended_valid_elements : 0,\r
                                valid_child_elements : 0,\r
                                invalid_elements : 0,\r
-                               fix_table_elements : 0,\r
+                               fix_table_elements : 1,\r
                                fix_list_elements : true,\r
                                fix_content_duplication : true,\r
                                convert_fonts_to_spans : false,\r
@@ -3635,10 +5559,32 @@ tinymce.create('static tinymce.util.XHR', {
                                indent_mode : 'simple',\r
                                indent_char : '\t',\r
                                indent_levels : 1,\r
-                               remove_linebreaks : 1\r
+                               remove_linebreaks : 1,\r
+                               remove_redundant_brs : 1,\r
+                               element_format : 'xhtml'\r
                        }, s);\r
 \r
-                       t.dom = s.dom;\r
+                       t.dom = s.dom;\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
+\r
+                                               return a;\r
+                                       });\r
+                               });\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
+                       }\r
 \r
                        if (s.fix_list_elements) {\r
                                t.onPreProcess.add(function(se, o) {\r
@@ -3682,41 +5628,8 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                        if (s.fix_table_elements) {\r
                                t.onPreProcess.add(function(se, o) {\r
-                                       each(t.dom.select('table', o.node), function(e) {\r
-                                               var pa = t.dom.getParent(e, 'H1,H2,H3,H4,H5,H6,P'), pa2, n, tm, pl = [], i, ns;\r
-\r
-                                               if (pa) {\r
-                                                       pa2 = pa.cloneNode(false);\r
-\r
-                                                       pl.push(e);\r
-                                                       for (n = e; n = n.parentNode;) {\r
-                                                               pl.push(n);\r
-\r
-                                                               if (n == pa)\r
-                                                                       break;\r
-                                                       }\r
-\r
-                                                       tm = pa2;\r
-                                                       for (i = pl.length - 1; i >= 0; i--) {\r
-                                                               if (i == pl.length - 1) {\r
-                                                                       while (ns = pl[i - 1].nextSibling)\r
-                                                                               tm.appendChild(ns.parentNode.removeChild(ns));\r
-                                                               } else {\r
-                                                                       n = pl[i].cloneNode(false);\r
-\r
-                                                                       if (i != 0) {\r
-                                                                               while (ns = pl[i - 1].nextSibling)\r
-                                                                                       n.appendChild(ns.parentNode.removeChild(ns));\r
-                                                                       }\r
-\r
-                                                                       tm = tm.appendChild(n);\r
-                                                               }\r
-                                                       }\r
-\r
-                                                       e = t.dom.insertAfter(e.parentNode.removeChild(e), pa);\r
-                                                       t.dom.insertAfter(e, pa);\r
-                                                       t.dom.insertAfter(pa2, e);\r
-                                               }\r
+                                       each(t.dom.select('p table', o.node), function(n) {\r
+                                               t.dom.split(t.dom.getParent(n, 'p'), n);\r
                                        });\r
                                });\r
                        }\r
@@ -4076,7 +5989,8 @@ tinymce.create('static tinymce.util.XHR', {
                                        patterns : [\r
                                                {pattern : /(<script[^>]*>)(.*?)(<\/script>)/g},\r
                                                {pattern : /(<style[^>]*>)(.*?)(<\/style>)/g},\r
-                                               {pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1}\r
+                                               {pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1},\r
+                                               {pattern : /(<!--\[CDATA\[)(.*?)(\]\]-->)/g}\r
                                        ]\r
                                });\r
 \r
@@ -4120,6 +6034,9 @@ tinymce.create('static tinymce.util.XHR', {
 \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
@@ -4227,7 +6144,7 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                                                // Add wild attributes\r
                                                if (ru.validAttribsRE) {\r
-                                                       at = isIE ? getIEAtts(n) : n.attributes;\r
+                                                       at = t.dom.getAttribs(n);\r
                                                        for (i=at.length-1; i>-1; i--) {\r
                                                                no = at[i];\r
 \r
@@ -4247,8 +6164,14 @@ tinymce.create('static tinymce.util.XHR', {
                                                }\r
 \r
                                                // Padd empty nodes with a &nbsp;\r
-                                               if (!hc && ru.padd)\r
-                                                       w.writeText('\u00a0');\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
 \r
                                                break;\r
 \r
@@ -4403,6 +6326,16 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                        v = this.dom.getAttrib(n, na);\r
 \r
+                       // Bool attr\r
+                       if (this.settings.bool_attrs.test(na) && v) {\r
+                               v = ('' + v).toLowerCase();\r
+\r
+                               if (v === 'false' || v === '0')\r
+                                       return null;\r
+\r
+                               v = na;\r
+                       }\r
+\r
                        switch (na) {\r
                                case 'rowspan':\r
                                case 'colspan':\r
@@ -4447,12 +6380,9 @@ tinymce.create('static tinymce.util.XHR', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/dom/ScriptLoader.js */\r
-\r
-(function() {\r
-       var each = tinymce.each;\r
+})(tinymce);\r
+(function(tinymce) {\r
+       var each = tinymce.each, Event = tinymce.dom.Event;\r
 \r
        tinymce.create('tinymce.dom.ScriptLoader', {\r
                ScriptLoader : function(s) {\r
@@ -4504,7 +6434,7 @@ tinymce.create('static tinymce.util.XHR', {
                        }\r
 \r
                        function loadScript(u) {\r
-                               if (tinymce.dom.Event.domLoaded || t.settings.strict_mode) {\r
+                               if (Event.domLoaded || t.settings.strict_mode) {\r
                                        tinymce.util.XHR.send({\r
                                                url : tinymce._addVer(u),\r
                                                error : t.settings.error,\r
@@ -4606,6 +6536,12 @@ tinymce.create('static tinymce.util.XHR', {
 \r
                                o.state = 1; // Is loading\r
 \r
+                               tinymce.dom.ScriptLoader.loadScript(o.url, function() {\r
+                                       done(o);\r
+                                       allDone();\r
+                               });\r
+\r
+                               /*\r
                                tinymce.util.XHR.send({\r
                                        url : o.url,\r
                                        error : t.settings.error,\r
@@ -4615,6 +6551,7 @@ tinymce.create('static tinymce.util.XHR', {
                                                allDone();\r
                                        }\r
                                });\r
+                               */\r
                        };\r
 \r
                        each(sc, function(o) {\r
@@ -4631,7 +6568,7 @@ tinymce.create('static tinymce.util.XHR', {
                                if (o.state > 0)\r
                                        return;\r
 \r
-                               if (!tinymce.dom.Event.domLoaded && !t.settings.strict_mode) {\r
+                               if (!Event.domLoaded && !t.settings.strict_mode) {\r
                                        var ix, ol = '';\r
 \r
                                        // Add onload events\r
@@ -4676,6 +6613,42 @@ tinymce.create('static tinymce.util.XHR', {
                        _onLoad : function(e, u, ix) {\r
                                if (!tinymce.isIE || e.readyState == 'complete')\r
                                        this._funcs[ix].call(this);\r
+                       },\r
+\r
+                       loadScript : function(u, cb) {\r
+                               var id = tinymce.DOM.uniqueId(), e;\r
+\r
+                               function done() {\r
+                                       Event.clear(id);\r
+                                       tinymce.DOM.remove(id);\r
+\r
+                                       if (cb) {\r
+                                               cb.call(document, u);\r
+                                               cb = 0;\r
+                                       }\r
+                               };\r
+\r
+                               if (tinymce.isIE) {\r
+/*                                     Event.add(e, 'readystatechange', function(e) {\r
+                                               if (e.target && e.target.readyState == 'complete')\r
+                                                       done();\r
+                                       });*/\r
+\r
+                                       tinymce.util.XHR.send({\r
+                                               url : tinymce._addVer(u),\r
+                                               async : false,\r
+                                               success : function(co) {\r
+                                                       window.execScript(co);\r
+                                                       done();\r
+                                               }\r
+                                       });\r
+                               } else {\r
+                                       e = tinymce.DOM.create('script', {id : id, type : 'text/javascript', src : tinymce._addVer(u)});\r
+                                       Event.add(e, 'load', done);\r
+\r
+                                       // Check for head or body\r
+                                       (document.getElementsByTagName('head')[0] || document.body).appendChild(e);\r
+                               }\r
                        }\r
                }\r
 \r
@@ -4683,11 +6656,8 @@ tinymce.create('static tinymce.util.XHR', {
 \r
        // Global script loader\r
        tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/ui/Control.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        // Shorten class names\r
        var DOM = tinymce.DOM, is = tinymce.is;\r
 \r
@@ -4788,10 +6758,7 @@ tinymce.create('static tinymce.util.XHR', {
                }\r
 \r
                });\r
-})();\r
-/* file:jscripts/tiny_mce/classes/ui/Container.js */\r
-\r
-tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {\r
+})(tinymce);tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {\r
        Container : function(id, s) {\r
                this.parent(id, s);\r
                this.controls = [];\r
@@ -4811,9 +6778,6 @@ tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {
 \r
        });\r
 \r
-\r
-/* file:jscripts/tiny_mce/classes/ui/Separator.js */\r
-\r
 tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {\r
        Separator : function(id, s) {\r
                this.parent(id, s);\r
@@ -4825,10 +6789,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
        }\r
 \r
        });\r
-\r
-/* file:jscripts/tiny_mce/classes/ui/MenuItem.js */\r
-\r
-(function() {\r
+(function(tinymce) {\r
        var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;\r
 \r
        tinymce.create('tinymce.ui.MenuItem:tinymce.ui.Control', {\r
@@ -4857,11 +6818,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/ui/Menu.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, walk = tinymce.walk;\r
 \r
        tinymce.create('tinymce.ui.Menu:tinymce.ui.MenuItem', {\r
@@ -4959,10 +6917,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-/* file:jscripts/tiny_mce/classes/ui/DropMenu.js */\r
-\r
-(function() {\r
+})(tinymce);(function(tinymce) {\r
        var is = tinymce.is, DOM = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event, Element = tinymce.dom.Element;\r
 \r
        tinymce.create('tinymce.ui.DropMenu:tinymce.ui.Menu', {\r
@@ -5075,7 +7030,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
 \r
                                e = e.target;\r
 \r
-                               if (e && (e = DOM.getParent(e, 'TR')) && !DOM.hasClass(e, cp + 'ItemSub')) {\r
+                               if (e && (e = DOM.getParent(e, 'tr')) && !DOM.hasClass(e, cp + 'ItemSub')) {\r
                                        m = t.items[e.id];\r
 \r
                                        if (m.isDisabled())\r
@@ -5102,7 +7057,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                                        var m, r, mi;\r
 \r
                                        e = e.target;\r
-                                       if (e && (e = DOM.getParent(e, 'TR'))) {\r
+                                       if (e && (e = DOM.getParent(e, 'tr'))) {\r
                                                m = t.items[e.id];\r
 \r
                                                if (t.lastMenu)\r
@@ -5245,7 +7200,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                },\r
 \r
                _add : function(tb, o) {\r
-                       var n, s = o.settings, a, ro, it, cp = this.classPrefix;\r
+                       var n, s = o.settings, a, ro, it, cp = this.classPrefix, ic;\r
 \r
                        if (s.separator) {\r
                                ro = DOM.add(tb, 'tr', {id : o.id, 'class' : cp + 'ItemSeparator'});\r
@@ -5263,7 +7218,12 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
 \r
                        DOM.addClass(it, s['class']);\r
 //                     n = DOM.add(n, 'span', {'class' : 'item'});\r
-                       DOM.add(n, 'span', {'class' : 'mceIcon' + (s.icon ? ' mce_' + s.icon : '')});\r
+\r
+                       ic = DOM.add(n, 'span', {'class' : 'mceIcon' + (s.icon ? ' mce_' + s.icon : '')});\r
+\r
+                       if (s.icon_src)\r
+                               DOM.add(ic, 'img', {src : s.icon_src});\r
+\r
                        n = DOM.add(n, s.element || 'span', {'class' : 'mceText', title : o.settings.title}, o.settings.title);\r
 \r
                        if (o.settings.style)\r
@@ -5285,10 +7245,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-/* file:jscripts/tiny_mce/classes/ui/Button.js */\r
-\r
-(function() {\r
+})(tinymce);(function(tinymce) {\r
        var DOM = tinymce.DOM;\r
 \r
        tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {\r
@@ -5321,11 +7278,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/ui/ListBox.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        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
@@ -5341,34 +7295,57 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        t.classPrefix = 'mceListBox';\r
                },\r
 \r
-               select : function(v) {\r
-                       var t = this, e, fv;\r
+               select : function(va) {\r
+                       var t = this, fv, f;\r
 \r
-                       // Do we need to do something?\r
-                       if (v != t.selectedValue) {\r
-                               e = DOM.get(t.id + '_text');\r
-                               t.selectedValue = v;\r
+                       if (va == undefined)\r
+                               return t.selectByIndex(-1);\r
+\r
+                       // Is string or number make function selector\r
+                       if (va && va.call)\r
+                               f = va;\r
+                       else {\r
+                               f = function(v) {\r
+                                       return v == va;\r
+                               };\r
+                       }\r
 \r
+                       // Do we need to do something?\r
+                       if (va != t.selectedValue) {\r
                                // Find item\r
-                               each(t.items, function(o) {\r
-                                       if (o.value == v) {\r
-                                               DOM.setHTML(e, DOM.encode(o.title));\r
+                               each(t.items, function(o, i) {\r
+                                       if (f(o.value)) {\r
                                                fv = 1;\r
+                                               t.selectByIndex(i);\r
                                                return false;\r
                                        }\r
                                });\r
 \r
-                               // If no item was found then present title\r
-                               if (!fv) {\r
+                               if (!fv)\r
+                                       t.selectByIndex(-1);\r
+                       }\r
+               },\r
+\r
+               selectByIndex : function(idx) {\r
+                       var t = this, e, o;\r
+\r
+                       if (idx != t.selectedIndex) {\r
+                               e = DOM.get(t.id + '_text');\r
+                               o = t.items[idx];\r
+\r
+                               if (o) {\r
+                                       t.selectedValue = o.value;\r
+                                       t.selectedIndex = idx;\r
+                                       DOM.setHTML(e, DOM.encode(o.title));\r
+                                       DOM.removeClass(e, 'mceTitle');\r
+                               } else {\r
                                        DOM.setHTML(e, DOM.encode(t.settings.title));\r
                                        DOM.addClass(e, 'mceTitle');\r
-                                       e = 0;\r
-                                       return;\r
-                               } else\r
-                                       DOM.removeClass(e, 'mceTitle');\r
-                       }\r
+                                       t.selectedValue = t.selectedIndex = null;\r
+                               }\r
 \r
-                       e = 0;\r
+                               e = 0;\r
+                       }\r
                },\r
 \r
                add : function(n, v, o) {\r
@@ -5447,7 +7424,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open'))\r
                                return;\r
 \r
-                       if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {\r
+                       if (!e || !DOM.getParent(e.target, '.mceMenu')) {\r
                                DOM.removeClass(t.id, t.classPrefix + 'Selected');\r
                                Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
 \r
@@ -5553,10 +7530,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-/* file:jscripts/tiny_mce/classes/ui/NativeListBox.js */\r
-\r
-(function() {\r
+})(tinymce);(function(tinymce) {\r
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;\r
 \r
        tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {\r
@@ -5573,18 +7547,40 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        return DOM.get(this.id).disabled;\r
                },\r
 \r
-               select : function(v) {\r
-                       var e = DOM.get(this.id), ol = e.options;\r
+               select : function(va) {\r
+                       var t = this, fv, f;\r
 \r
-                       v = '' + (v || '');\r
+                       if (va == undefined)\r
+                               return t.selectByIndex(-1);\r
 \r
-                       e.selectedIndex = 0;\r
-                       each(ol, function(o, i) {\r
-                               if (o.value == v) {\r
-                                       e.selectedIndex = i;\r
-                                       return false;\r
-                               }\r
-                       });\r
+                       // Is string or number make function selector\r
+                       if (va && va.call)\r
+                               f = va;\r
+                       else {\r
+                               f = function(v) {\r
+                                       return v == va;\r
+                               };\r
+                       }\r
+\r
+                       // Do we need to do something?\r
+                       if (va != t.selectedValue) {\r
+                               // Find item\r
+                               each(t.items, function(o, i) {\r
+                                       if (f(o.value)) {\r
+                                               fv = 1;\r
+                                               t.selectByIndex(i);\r
+                                               return false;\r
+                                       }\r
+                               });\r
+\r
+                               if (!fv)\r
+                                       t.selectByIndex(-1);\r
+                       }\r
+               },\r
+\r
+               selectByIndex : function(idx) {\r
+                       DOM.get(this.id).selectedIndex = idx + 1;\r
+                       this.selectedValue = this.items[idx] ? this.items[idx].value : null;\r
                },\r
 \r
                add : function(n, v, a) {\r
@@ -5630,12 +7626,14 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        t.rendered = true;\r
 \r
                        function onChange(e) {\r
-                               var v = e.target.options[e.target.selectedIndex].value;\r
+                               var v = t.items[e.target.selectedIndex - 1];\r
 \r
-                               t.onChange.dispatch(t, v);\r
+                               if (v && (v = v.value)) {\r
+                                       t.onChange.dispatch(t, v);\r
 \r
-                               if (t.settings.onselect)\r
-                                       t.settings.onselect(v);\r
+                                       if (t.settings.onselect)\r
+                                               t.settings.onselect(v);\r
+                               }\r
                        };\r
 \r
                        Event.add(t.id, 'change', onChange);\r
@@ -5661,10 +7659,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-/* file:jscripts/tiny_mce/classes/ui/MenuButton.js */\r
-\r
-(function() {\r
+})(tinymce);(function(tinymce) {\r
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
 \r
        tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {\r
@@ -5727,7 +7722,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id || e.id === t.id + '_open';}))\r
                                return;\r
 \r
-                       if (!e || !DOM.getParent(e.target, function(n) {return DOM.hasClass(n, 'mceMenu');})) {\r
+                       if (!e || !DOM.getParent(e.target, '.mceMenu')) {\r
                                t.setState('Selected', 0);\r
                                Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
                                if (t.menu)\r
@@ -5751,11 +7746,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/ui/SplitButton.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
 \r
        tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {\r
@@ -5820,11 +7812,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/ui/ColorSplitButton.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        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
@@ -5893,7 +7882,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        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, function(n) {return DOM.hasClass(n, 'mceSplitButtonMenu');})) {\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
@@ -5978,6 +7967,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
 \r
                        t.parent();\r
                        DOM.add(id + '_action', 'div', {id : id + '_preview', 'class' : 'mceColorPreview'});\r
+                       DOM.setStyle(t.id + '_preview', 'backgroundColor', t.value);\r
                },\r
 \r
                destroy : function() {\r
@@ -5989,10 +7979,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/ui/Toolbar.js */\r
-\r
+})(tinymce);\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
@@ -6056,10 +8043,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
        }\r
 \r
        });\r
-\r
-/* file:jscripts/tiny_mce/classes/AddOnManager.js */\r
-\r
-(function() {\r
+(function(tinymce) {\r
        var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;\r
 \r
        tinymce.create('tinymce.AddOnManager', {\r
@@ -6073,18 +8057,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                },\r
 \r
                requireLangPack : function(n) {\r
-                       var u, s;\r
+                       var u, s = tinymce.EditorManager.settings;\r
 \r
-                       if (tinymce.EditorManager.settings) {\r
-                               u = this.urls[n] + '/langs/' + tinymce.EditorManager.settings.language + '.js';\r
-                               s = tinymce.EditorManager.settings;\r
+                       if (s && s.language) {\r
+                               u = this.urls[n] + '/langs/' + s.language + '.js';\r
 \r
-                               if (s) {\r
-                                       if (!tinymce.dom.Event.domLoaded && !s.strict_mode)\r
-                                               tinymce.ScriptLoader.load(u);\r
-                                       else\r
-                                               tinymce.ScriptLoader.add(u);\r
-                               }\r
+                               if (!tinymce.dom.Event.domLoaded && !s.strict_mode)\r
+                                       tinymce.ScriptLoader.load(u);\r
+                               else\r
+                                       tinymce.ScriptLoader.add(u);\r
                        }\r
                },\r
 \r
@@ -6114,10 +8095,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
        // Create plugin and theme managers\r
        tinymce.PluginManager = new tinymce.AddOnManager();\r
        tinymce.ThemeManager = new tinymce.AddOnManager();\r
-}());\r
-/* file:jscripts/tiny_mce/classes/EditorManager.js */\r
-\r
-(function() {\r
+}(tinymce));(function(tinymce) {\r
        // Shorten names\r
        var each = tinymce.each, extend = tinymce.extend, DOM = tinymce.DOM, Event = tinymce.dom.Event, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, explode = tinymce.explode;\r
 \r
@@ -6137,9 +8115,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        tinymce.baseURL = new tinymce.util.URI(tinymce.documentBaseURL).toAbsolute(tinymce.baseURL);\r
                        tinymce.EditorManager.baseURI = new tinymce.util.URI(tinymce.baseURL);\r
 \r
-                       // Setup document domain\r
-                       if (tinymce.EditorManager.baseURI.host != lo.hostname && lo.hostname)\r
-                               document.domain = tinymce.relaxedDomain = lo.hostname.replace(/.*\.(.+\..+)$/, '$1');\r
+                       // User specified a document.domain value\r
+                       if (document.domain && lo.hostname != document.domain)\r
+                               tinymce.relaxedDomain = document.domain;\r
 \r
                        // Add before unload listener\r
                        // This was required since IE was leaking memory if you added and removed beforeunload listeners\r
@@ -6153,7 +8131,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                },\r
 \r
                init : function(s) {\r
-                       var t = this, pl, sl = tinymce.ScriptLoader, c, e;\r
+                       var t = this, pl, sl = tinymce.ScriptLoader, c, e, el = [], ed;\r
 \r
                        function execCallback(se, n, s) {\r
                                var f = se[n];\r
@@ -6259,9 +8237,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                                if(l.length > 0) {\r
                                                        each(explode(l), function(v) {\r
-                                                               if (DOM.get(v))\r
-                                                                       new tinymce.Editor(v, s).render(1);\r
-                                                               else {\r
+                                                               if (DOM.get(v)) {\r
+                                                                       ed = new tinymce.Editor(v, s);\r
+                                                                       el.push(ed);\r
+                                                                       ed.render(1);\r
+                                                               } else {\r
                                                                        c = 0;\r
 \r
                                                                        each(document.forms, function(f) {\r
@@ -6269,7 +8249,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                                                        if (e.name === v) {\r
                                                                                                v = 'mce_editor_' + c;\r
                                                                                                DOM.setAttrib(e, 'id', v);\r
-                                                                                               new tinymce.Editor(v, s).render(1);\r
+\r
+                                                                                               ed = new tinymce.Editor(v, s);\r
+                                                                                               el.push(ed);\r
+                                                                                               ed.render(1);\r
                                                                                        }\r
                                                                                });\r
                                                                        });\r
@@ -6298,7 +8281,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                                if (!v.id || t.get(v.id))\r
                                                                        v.id = DOM.uniqueId();\r
 \r
-                                                               new tinymce.Editor(v.id, s).render(1);\r
+                                                               ed = new tinymce.Editor(v.id, s);\r
+                                                               el.push(ed);\r
+                                                               ed.render(1);\r
                                                        }\r
                                                });\r
                                                break;\r
@@ -6308,7 +8293,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                if (s.oninit) {\r
                                        l = co = 0;\r
 \r
-                                       each (t.editors, function(ed) {\r
+                                       each (el, function(ed) {\r
                                                co++;\r
 \r
                                                if (!ed.initialized) {\r
@@ -6414,7 +8399,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                case "mceRemoveEditor":\r
                                case "mceRemoveControl":\r
-                                       ed.remove();\r
+                                       if (ed)\r
+                                               ed.remove();\r
+\r
                                        return true;\r
 \r
                                case 'mceToggleEditor':\r
@@ -6483,14 +8470,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                });\r
 \r
        tinymce.EditorManager.preInit();\r
-})();\r
+})(tinymce);\r
 \r
 // Short for editor manager window.tinyMCE is needed when TinyMCE gets loaded though a XHR call\r
 var tinyMCE = window.tinyMCE = tinymce.EditorManager;\r
-\r
-/* file:jscripts/tiny_mce/classes/Editor.js */\r
-\r
-(function() {\r
+(function(tinymce) {\r
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, Dispatcher = tinymce.util.Dispatcher;\r
        var each = tinymce.each, isGecko = tinymce.isGecko, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit;\r
        var is = tinymce.is, ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager, EditorManager = tinymce.EditorManager;\r
@@ -6582,13 +8566,16 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                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[align],-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=0|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],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
+                               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[align],-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=0|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
                                init_theme : 1,\r
                                force_p_newlines : 1,\r
-                               indentation : '30px'\r
+                               indentation : '30px',\r
+                               keep_styles : 1,\r
+                               fix_table_elements : 1,\r
+                               removeformat_selector : 'span,b,strong,em,i,font,u,strike'\r
                        }, s);\r
 \r
                        // Setup URIs\r
@@ -6631,7 +8618,8 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))\r
                                DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);\r
 \r
-                       t.windowManager = new tinymce.WindowManager(t);\r
+                       if (tinymce.WindowManager)\r
+                               t.windowManager = new tinymce.WindowManager(t);\r
 \r
                        if (s.encoding == 'xml') {\r
                                t.onGetContent.add(function(ed, o) {\r
@@ -6649,7 +8637,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                });\r
                        }\r
 \r
-                       if (s.add_unload_trigger && !s.ask) {\r
+                       if (s.add_unload_trigger) {\r
                                t._beforeUnload = tinyMCE.onBeforeUnload.add(function() {\r
                                        if (t.initialized && !t.destroyed && !t.isHidden())\r
                                                t.save({format : 'raw', no_events : true});\r
@@ -6678,7 +8666,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                                        EditorManager.triggerSave();\r
                                                        t.isNotDirty = 1;\r
 \r
-                                                       return this._mceOldSubmit(this);\r
+                                                       return t.formElement._mceOldSubmit(t.formElement);\r
                                                };\r
                                        }\r
 \r
@@ -6691,7 +8679,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                if (s.language)\r
                                        sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');\r
 \r
-                               if (s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
+                               if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
                                        ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');\r
 \r
                                each(explode(s.plugins), function(p) {\r
@@ -6706,23 +8694,6 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
 \r
                                // Init when que is loaded\r
                                sl.loadQueue(function() {\r
-                                       if (s.ask) {\r
-                                               function ask() {\r
-                                                       // Yield for awhile to avoid focus bug on FF 3 when cancel is pressed\r
-                                                       window.setTimeout(function() {\r
-                                                               Event.remove(t.id, 'focus', ask);\r
-\r
-                                                               t.windowManager.confirm(t.getLang('edit_confirm'), function(s) {\r
-                                                                       if (s)\r
-                                                                               t.init();\r
-                                                               });\r
-                                                       }, 0);\r
-                                               };\r
-\r
-                                               Event.add(t.id, 'focus', ask);\r
-                                               return;\r
-                                       }\r
-\r
                                        if (!t.removed)\r
                                                t.init();\r
                                });\r
@@ -6742,12 +8713,14 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        EditorManager.add(t);\r
 \r
                        // Create theme\r
-                       s.theme = s.theme.replace(/-/, '');\r
-                       o = ThemeManager.get(s.theme);\r
-                       t.theme = new o();\r
+                       if (s.theme) {\r
+                               s.theme = s.theme.replace(/-/, '');\r
+                               o = ThemeManager.get(s.theme);\r
+                               t.theme = new o();\r
 \r
-                       if (t.theme.init && s.init_theme)\r
-                               t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));\r
+                               if (t.theme.init && s.init_theme)\r
+                                       t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));\r
+                       }\r
 \r
                        // Create all plugins\r
                        each(explode(s.plugins.replace(/\-/g, '')), function(p) {\r
@@ -6764,10 +8737,12 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        });\r
 \r
                        // Setup popup CSS path(s)\r
-                       if (s.popup_css)\r
-                               s.popup_css = t.documentBaseURI.toAbsolute(s.popup_css);\r
-                       else\r
-                               s.popup_css = t.baseURI.toAbsolute("themes/" + s.theme + "/skins/" + s.skin + "/dialog.css");\r
+                       if (s.popup_css !== false) {\r
+                               if (s.popup_css)\r
+                                       s.popup_css = t.documentBaseURI.toAbsolute(s.popup_css);\r
+                               else\r
+                                       s.popup_css = t.baseURI.toAbsolute("themes/" + s.theme + "/skins/" + s.skin + "/dialog.css");\r
+                       }\r
 \r
                        if (s.popup_css_add)\r
                                s.popup_css += ',' + t.documentBaseURI.toAbsolute(s.popup_css_add);\r
@@ -6843,14 +8818,14 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                t.editorContainer = o.editorContainer;\r
                        }\r
 \r
-                       \r
+\r
                        // Resize editor\r
                        DOM.setStyles(o.sizeContainer || o.editorContainer, {\r
                                width : w,\r
                                height : h\r
                        });\r
 \r
-                       h = (o.iframeHeight || h) + ((h + '').indexOf('%') == -1 ? (o.deltaHeight || 0) : '');\r
+                       h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : '');\r
                        if (h < 100)\r
                                h = 100;\r
 \r
@@ -6877,7 +8852,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        // Domain relaxing enabled, then set document domain\r
                        if (tinymce.relaxedDomain) {\r
                                // We need to write the contents here in IE since multiple writes messes up refresh button and back button\r
-                               if (isIE)\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
@@ -6898,16 +8873,10 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        DOM.get(o.editorContainer).style.display = t.orgDisplay;\r
                        DOM.get(t.id).style.display = 'none';\r
 \r
-                       // Safari 2.x requires us to wait for the load event and load a real HTML doc\r
-                       if (tinymce.isOldWebKit) {\r
-                               Event.add(n, 'load', t.setupIframe, t);\r
-                               n.src = tinymce.baseURL + '/plugins/safari/blank.htm';\r
-                       } else {\r
-                               if (!isIE || !tinymce.relaxedDomain)\r
-                                       t.setupIframe();\r
+                       if (!isIE || !tinymce.relaxedDomain)\r
+                               t.setupIframe();\r
 \r
-                               e = n = o = null; // Cleanup\r
-                       }\r
+                       e = n = o = null; // Cleanup\r
                },\r
 \r
                setupIframe : function() {\r
@@ -6923,7 +8892,8 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        // Design mode needs to be added here Ctrl+A will fail otherwise\r
                        if (!isIE) {\r
                                try {\r
-                                       d.designMode = 'On';\r
+                                       if (!s.readonly)\r
+                                               d.designMode = 'On';\r
                                } catch (ex) {\r
                                        // Will fail on Gecko if the editor is placed in an hidden container element\r
                                        // The design mode will be set ones the editor is focused\r
@@ -6935,7 +8905,10 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                // It will not steal focus if we hide it while setting contentEditable\r
                                b = t.getBody();\r
                                DOM.hide(b);\r
-                               b.contentEditable = true;\r
+\r
+                               if (!s.readonly)\r
+                                       b.contentEditable = true;\r
+\r
                                DOM.show(b);\r
                        }\r
 \r
@@ -6965,6 +8938,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                font_size_style_values : s.font_size_style_values,\r
                                apply_source_formatting : s.apply_source_formatting,\r
                                remove_linebreaks : s.remove_linebreaks,\r
+                               element_format : s.element_format,\r
                                dom : t.dom\r
                        });\r
 \r
@@ -6988,7 +8962,8 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        if (!s.gecko_spellcheck)\r
                                t.getBody().spellcheck = 0;\r
 \r
-                       t._addEvents();\r
+                       if (!s.readonly)\r
+                               t._addEvents();\r
 \r
                        t.controlManager.onPostRender.dispatch(t, t.controlManager);\r
                        t.onPostRender.dispatch(t);\r
@@ -7138,30 +9113,47 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                });\r
                        }\r
 \r
+                       // Add visual aids when new contents is added\r
                        t.onSetContent.add(function() {\r
-                               // Safari needs some time, it will crash the browser when a link is created otherwise\r
-                               // I think this crash issue is resolved in the latest 3.0.4\r
-                               //window.setTimeout(function() {\r
-                                       t.addVisual(t.getBody());\r
-                               //}, 1);\r
+                               t.addVisual(t.getBody());\r
                        });\r
 \r
                        // Remove empty contents\r
                        if (s.padd_empty_editor) {\r
                                t.onPostProcess.add(function(ed, o) {\r
-                                       o.content = o.content.replace(/^(<p>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');\r
+                                       o.content = o.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');\r
                                });\r
                        }\r
 \r
                        if (isGecko) {\r
-                               try {\r
-                                       // Design mode must be set here once again to fix a bug where\r
-                                       // Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again\r
-                                       d.designMode = 'Off';\r
-                                       d.designMode = 'On';\r
-                               } catch (ex) {\r
-                                       // Will fail on Gecko if the editor is placed in an hidden container element\r
-                                       // The design mode will be set ones the editor is focused\r
+                               // Fix gecko link bug, when a link is placed at the end of block elements there is\r
+                               // no way to move the caret behind the link. This fix adds a bogus br element after the link\r
+                               function fixLinks(ed, o) {\r
+                                       each(ed.dom.select('a'), function(n) {\r
+                                               var pn = n.parentNode;\r
+\r
+                                               if (ed.dom.isBlock(pn) && pn.lastChild === n)\r
+                                                       ed.dom.add(pn, 'br', {'mce_bogus' : 1});\r
+                                       });\r
+                               };\r
+\r
+                               t.onExecCommand.add(function(ed, cmd) {\r
+                                       if (cmd === 'CreateLink')\r
+                                               fixLinks(ed);\r
+                               });\r
+\r
+                               t.onSetContent.add(t.selection.onSetContent.add(fixLinks));\r
+\r
+                               if (!s.readonly) {\r
+                                       try {\r
+                                               // Design mode must be set here once again to fix a bug where\r
+                                               // Ctrl+A/Delete/Backspace didn't work if the editor was added using mceAddControl then removed then added again\r
+                                               d.designMode = 'Off';\r
+                                               d.designMode = 'On';\r
+                                       } catch (ex) {\r
+                                               // Will fail on Gecko if the editor is placed in an hidden container element\r
+                                               // The design mode will be set ones the editor is focused\r
+                                       }\r
                                }\r
                        }\r
 \r
@@ -7203,7 +9195,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        e = null;\r
                },\r
 \r
-               \r
+\r
                focus : function(sf) {\r
                        var oed, t = this, ce = t.settings.content_editable;\r
 \r
@@ -7214,7 +9206,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                if (!ce && (!isIE || t.selection.getNode().ownerDocument != t.getDoc()))\r
                                        t.getWin().focus();\r
 \r
-                                                       }\r
+                       }\r
 \r
                        if (EditorManager.activeEditor != t) {\r
                                if ((oed = EditorManager.activeEditor) != null)\r
@@ -7250,7 +9242,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                },\r
 \r
                translate : function(s) {\r
-                       var c = this.settings.language, i18n = EditorManager.i18n;\r
+                       var c = this.settings.language || 'en', i18n = EditorManager.i18n;\r
 \r
                        if (!s)\r
                                return '';\r
@@ -7261,7 +9253,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                },\r
 \r
                getLang : function(n, dv) {\r
-                       return EditorManager.i18n[this.settings.language + '.' + n] || (is(dv) ? dv : '{#' + n + '}');\r
+                       return EditorManager.i18n[(this.settings.language || 'en') + '.' + n] || (is(dv) ? dv : '{#' + n + '}');\r
                },\r
 \r
                getParam : function(n, dv, ty) {\r
@@ -7417,7 +9409,13 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                return true;\r
 \r
                        // Theme commands\r
-                       if (t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {\r
+                       if (t.theme && t.theme.execCommand && t.theme.execCommand(cmd, ui, val)) {\r
+                               t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
+                               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
@@ -7531,24 +9529,27 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                load : function(o) {\r
                        var t = this, e = t.getElement(), h;\r
 \r
-                       o = o || {};\r
-                       o.load = true;\r
+                       if (e) {\r
+                               o = o || {};\r
+                               o.load = true;\r
 \r
-                       h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);\r
-                       o.element = e;\r
+                               // Double encode existing entities in the value\r
+                               h = t.setContent(is(e.value) ? e.value : e.innerHTML, o);\r
+                               o.element = e;\r
 \r
-                       if (!o.no_events)\r
-                               t.onLoadContent.dispatch(t, o);\r
+                               if (!o.no_events)\r
+                                       t.onLoadContent.dispatch(t, o);\r
 \r
-                       o.element = e = null;\r
+                               o.element = e = null;\r
 \r
-                       return h;\r
+                               return h;\r
+                       }\r
                },\r
 \r
                save : function(o) {\r
                        var t = this, e = t.getElement(), h, f;\r
 \r
-                       if (!t.initialized)\r
+                       if (!e || !t.initialized)\r
                                return;\r
 \r
                        o = o || {};\r
@@ -7787,7 +9788,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                tinyMCE.onBeforeUnload.remove(t._beforeUnload);\r
 \r
                                // Manual destroy\r
-                               if (t.theme.destroy)\r
+                               if (t.theme && t.theme.destroy)\r
                                        t.theme.destroy();\r
 \r
                                // Destroy controls, selection and dom\r
@@ -7871,25 +9872,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
 \r
                                        case 'paste':\r
                                                Event.add(t.getBody(), k, function(e) {\r
-                                                       var tx, h, el, r;\r
-\r
-                                                       // Get plain text data\r
-                                                       if (e.clipboardData)\r
-                                                               tx = e.clipboardData.getData('text/plain');\r
-                                                       else if (tinymce.isIE)\r
-                                                               tx = t.getWin().clipboardData.getData('Text');\r
-\r
-                                                       // Get HTML data\r
-                                                       /*if (tinymce.isIE) {\r
-                                                               el = DOM.add(DOM.doc.body, 'div', {style : 'visibility:hidden;overflow:hidden;position:absolute;width:1px;height:1px'});\r
-                                                               r = DOM.doc.body.createTextRange();\r
-                                                               r.moveToElementText(el);\r
-                                                               r.execCommand('Paste');\r
-                                                               h = el.innerHTML;\r
-                                                               DOM.remove(el);\r
-                                                       }*/\r
-\r
-                                                       eventHandler(e, {text : tx, html : h});\r
+                                                       eventHandler(e);\r
                                                });\r
                                                break;\r
 \r
@@ -7907,7 +9890,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                t.focus(true);\r
                        });\r
 \r
-                       \r
+\r
                        // 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
@@ -7936,7 +9919,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                function setOpts() {\r
                                        var t = this, d = t.getDoc(), s = t.settings;\r
 \r
-                                       if (isGecko) {\r
+                                       if (isGecko && !s.readonly) {\r
                                                if (t._isHidden()) {\r
                                                        try {\r
                                                                if (!s.content_editable)\r
@@ -7949,115 +9932,39 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                                try {\r
                                                        // Try new Gecko method\r
                                                        d.execCommand("styleWithCSS", 0, false);\r
-                                               } catch (ex) {\r
-                                                       // Use old method\r
-                                                       if (!t._isHidden())\r
-                                                               try {d.execCommand("useCSS", 0, true);} catch (ex) {}\r
-                                               }\r
-\r
-                                               if (!s.table_inline_editing)\r
-                                                       try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}\r
-\r
-                                               if (!s.object_resizing)\r
-                                                       try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {}\r
-                                       }\r
-                               };\r
-\r
-                               t.onBeforeExecCommand.add(setOpts);\r
-                               t.onMouseDown.add(setOpts);\r
-                       }\r
-\r
-                       // Add node change handlers\r
-                       t.onMouseUp.add(t.nodeChanged);\r
-                       t.onClick.add(t.nodeChanged);\r
-                       t.onKeyUp.add(function(ed, e) {\r
-                               if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.keyCode == 46 || e.keyCode == 8 || e.ctrlKey)\r
-                                       t.nodeChanged();\r
-                       });\r
-\r
-                       // Add reset handler\r
-                       t.onReset.add(function() {\r
-                               t.setContent(t.startContent, {format : 'raw'});\r
-                       });\r
-\r
-                       if (t.getParam('tab_focus')) {\r
-                               function tabCancel(ed, e) {\r
-                                       if (e.keyCode === 9)\r
-                                               return Event.cancel(e);\r
-                               };\r
-\r
-                               function tabHandler(ed, e) {\r
-                                       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
-                                                       }\r
-                                               }\r
-\r
-                                               return null;\r
-                                       };\r
-\r
-                                       if (e.keyCode === 9) {\r
-                                               v = explode(ed.getParam('tab_focus'));\r
-\r
-                                               if (v.length == 1) {\r
-                                                       v[1] = v[0];\r
-                                                       v[0] = ':prev';\r
-                                               }\r
-\r
-                                               // Find element to focus\r
-                                               if (e.shiftKey) {\r
-                                                       if (v[0] == ':prev')\r
-                                                               el = find(-1);\r
-                                                       else\r
-                                                               el = DOM.get(v[0]);\r
-                                               } else {\r
-                                                       if (v[1] == ':next')\r
-                                                               el = find(1);\r
-                                                       else\r
-                                                               el = DOM.get(v[1]);\r
+                                               } catch (ex) {\r
+                                                       // Use old method\r
+                                                       if (!t._isHidden())\r
+                                                               try {d.execCommand("useCSS", 0, true);} catch (ex) {}\r
                                                }\r
 \r
-                                               if (el) {\r
-                                                       if (ed = EditorManager.get(el.id || el.name))\r
-                                                               ed.focus();\r
-                                                       else\r
-                                                               window.setTimeout(function() {window.focus();el.focus();}, 10);\r
+                                               if (!s.table_inline_editing)\r
+                                                       try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}\r
 \r
-                                                       return Event.cancel(e);\r
-                                               }\r
+                                               if (!s.object_resizing)\r
+                                                       try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {}\r
                                        }\r
                                };\r
 \r
-                               t.onKeyUp.add(tabCancel);\r
-\r
-                               if (isGecko) {\r
-                                       t.onKeyPress.add(tabHandler);\r
-                                       t.onKeyDown.add(tabCancel);\r
-                               } else\r
-                                       t.onKeyDown.add(tabHandler);\r
+                               t.onBeforeExecCommand.add(setOpts);\r
+                               t.onMouseDown.add(setOpts);\r
                        }\r
 \r
+                       // Add node change handlers\r
+                       t.onMouseUp.add(t.nodeChanged);\r
+                       t.onClick.add(t.nodeChanged);\r
+                       t.onKeyUp.add(function(ed, e) {\r
+                               var c = e.keyCode;\r
+\r
+                               if ((c >= 33 && c <= 36) || (c >= 37 && c <= 40) || c == 13 || c == 45 || c == 46 || c == 8 || (tinymce.isMac && (c == 91 || c == 93)) || e.ctrlKey)\r
+                                       t.nodeChanged();\r
+                       });\r
+\r
+                       // Add reset handler\r
+                       t.onReset.add(function() {\r
+                               t.setContent(t.startContent, {format : 'raw'});\r
+                       });\r
+\r
                        // Add shortcuts\r
                        if (s.custom_shortcuts) {\r
                                if (s.custom_undo_redo_keyboard_shortcuts) {\r
@@ -8087,7 +9994,9 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                                return v;\r
 \r
                                        each(t.shortcuts, function(o) {\r
-                                               if (o.ctrl != e.ctrlKey && (!tinymce.isMac || o.ctrl == e.metaKey))\r
+                                               if (tinymce.isMac && o.ctrl != e.metaKey)\r
+                                                       return;\r
+                                               else if (!tinymce.isMac && o.ctrl != e.ctrlKey)\r
                                                        return;\r
 \r
                                                if (o.alt != e.altKey)\r
@@ -8183,6 +10092,16 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                                        }\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
@@ -8329,104 +10248,49 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        if (cl = s.font_size_classes)\r
                                cl = explode(cl);\r
 \r
-                       function convertToFonts(no) {\r
-                               var n, f, nl, x, i, v, st;\r
+                       function process(no) {\r
+                               var n, sp, nl, x;\r
 \r
-                               // Convert spans to fonts on non WebKit browsers\r
-                               if (tinymce.isWebKit || !s.inline_styles)\r
+                               // Keep unit tests happy\r
+                               if (!s.inline_styles)\r
                                        return;\r
 \r
-                               nl = t.dom.select('span', no);\r
+                               nl = t.dom.select('font', no);\r
                                for (x = nl.length - 1; x >= 0; x--) {\r
                                        n = nl[x];\r
 \r
-                                       f = dom.create('font', {\r
-                                               color : dom.toHex(dom.getStyle(n, 'color')),\r
-                                               face : dom.getStyle(n, 'fontFamily'),\r
+                                       sp = dom.create('span', {\r
                                                style : dom.getAttrib(n, 'style'),\r
                                                'class' : dom.getAttrib(n, 'class')\r
                                        });\r
 \r
-                                       // Clear color and font family\r
-                                       st = f.style;\r
-                                       if (st.color || st.fontFamily) {\r
-                                               st.color = st.fontFamily = '';\r
-                                               dom.setAttrib(f, 'mce_style', ''); // Remove cached style data\r
-                                       }\r
-\r
-                                       if (sl) {\r
-                                               i = inArray(sl, dom.getStyle(n, 'fontSize'));\r
-\r
-                                               if (i != -1) {\r
-                                                       dom.setAttrib(f, 'size', '' + (i + 1 || 1));\r
-                                                       //f.style.fontSize = '';\r
-                                               }\r
-                                       } else if (cl) {\r
-                                               i = inArray(cl, dom.getAttrib(n, 'class'));\r
-                                               v = dom.getStyle(n, 'fontSize');\r
-\r
-                                               if (i == -1 && v.indexOf('pt') > 0)\r
-                                                       i = inArray(fz, parseInt(v));\r
-\r
-                                               if (i == -1)\r
-                                                       i = inArray(fzn, v);\r
-\r
-                                               if (i != -1) {\r
-                                                       dom.setAttrib(f, 'size', '' + (i + 1 || 1));\r
-                                                       f.style.fontSize = '';\r
-                                               }\r
-                                       }\r
+                                       dom.setStyles(sp, {\r
+                                               fontFamily : dom.getAttrib(n, 'face'),\r
+                                               color : dom.getAttrib(n, 'color'),\r
+                                               backgroundColor : n.style.backgroundColor\r
+                                       });\r
 \r
-                                       if (f.color || f.face || f.size) {\r
-                                               f.style.fontFamily = '';\r
-                                               dom.setAttrib(f, 'mce_style', '');\r
-                                               dom.replace(f, n, 1);\r
+                                       if (n.size) {\r
+                                               if (sl)\r
+                                                       dom.setStyle(sp, 'fontSize', sl[parseInt(n.size) - 1]);\r
+                                               else\r
+                                                       dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]);\r
                                        }\r
 \r
-                                       f = n = null;\r
+                                       dom.setAttrib(sp, 'mce_style', '');\r
+                                       dom.replace(sp, n, 1);\r
                                }\r
                        };\r
 \r
-                       // Run on setup\r
-                       t.onSetContent.add(function(ed, o) {\r
-                               convertToFonts(ed.getBody());\r
-                       });\r
-\r
                        // Run on cleanup\r
                        t.onPreProcess.add(function(ed, o) {\r
-                               var n, sp, nl, x;\r
-\r
-                               // Keep unit tests happy\r
-                               if (!s.inline_styles)\r
-                                       return;\r
-\r
-                               if (o.get) {\r
-                                       nl = t.dom.select('font', o.node);\r
-                                       for (x = nl.length - 1; x >= 0; x--) {\r
-                                               n = nl[x];\r
-\r
-                                               sp = dom.create('span', {\r
-                                                       style : dom.getAttrib(n, 'style'),\r
-                                                       'class' : dom.getAttrib(n, 'class')\r
-                                               });\r
-\r
-                                               dom.setStyles(sp, {\r
-                                                       fontFamily : dom.getAttrib(n, 'face'),\r
-                                                       color : dom.getAttrib(n, 'color'),\r
-                                                       backgroundColor : n.style.backgroundColor\r
-                                               });\r
-\r
-                                               if (n.size) {\r
-                                                       if (sl)\r
-                                                               dom.setStyle(sp, 'fontSize', sl[parseInt(n.size) - 1]);\r
-                                                       else\r
-                                                               dom.setAttrib(sp, 'class', cl[parseInt(n.size) - 1]);\r
-                                               }\r
+                               if (o.get)\r
+                                       process(o.node);\r
+                       });\r
 \r
-                                               dom.setAttrib(sp, 'mce_style', '');\r
-                                               dom.replace(sp, n, 1);\r
-                                       }\r
-                               }\r
+                       t.onSetContent.add(function(ed, o) {\r
+                               if (o.initial)\r
+                                       process(o.node);\r
                        });\r
                },\r
 \r
@@ -8493,11 +10357,8 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/EditorCommands.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        var each = tinymce.each, isIE = tinymce.isIE, isGecko = tinymce.isGecko, isOpera = tinymce.isOpera, isWebKit = tinymce.isWebKit;\r
 \r
        tinymce.create('tinymce.EditorCommands', {\r
@@ -8509,23 +10370,6 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        var t = this, ed = t.editor, f;\r
 \r
                        switch (cmd) {\r
-                               case 'Cut':\r
-                               case 'Copy':\r
-                               case 'Paste':\r
-                                       try {\r
-                                               ed.getDoc().execCommand(cmd, ui, val);\r
-                                       } catch (ex) {\r
-                                               if (isGecko) {\r
-                                                       ed.windowManager.confirm(ed.getLang('clipboard_msg'), function(s) {\r
-                                                               if (s)\r
-                                                                       window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html', 'mceExternal');\r
-                                                       });\r
-                                               } else\r
-                                                       ed.windowManager.alert(ed.getLang('clipboard_no_support'));\r
-                                       }\r
-\r
-                                       return true;\r
-\r
                                // Ignore these\r
                                case 'mceResetDesignMode':\r
                                case 'mceBeginUndoLevel':\r
@@ -8544,11 +10388,6 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                        t.mceJustify(cmd, cmd.substring(7).toLowerCase());\r
                                        return true;\r
 \r
-                               case 'mceEndUndoLevel':\r
-                               case 'mceAddUndoLevel':\r
-                                       ed.undoManager.add();\r
-                                       return true;\r
-\r
                                default:\r
                                        f = this[cmd];\r
 \r
@@ -8570,7 +10409,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        iv = parseInt(iv);\r
 \r
                        if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {\r
-                               each(this._getSelectedBlocks(), function(e) {\r
+                               each(s.getSelectedBlocks(), function(e) {\r
                                        d.setStyle(e, 'paddingLeft', (parseInt(e.style.paddingLeft || 0) + iv) + iu);\r
                                });\r
 \r
@@ -8597,7 +10436,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        iv = parseInt(iv);\r
 \r
                        if (ed.settings.inline_styles && (!this.queryStateInsertUnorderedList() && !this.queryStateInsertOrderedList())) {\r
-                               each(this._getSelectedBlocks(), function(e) {\r
+                               each(s.getSelectedBlocks(), function(e) {\r
                                        v = Math.max(0, parseInt(e.style.paddingLeft || 0) - iv);\r
                                        d.setStyle(e, 'paddingLeft', v ? v + iu : '');\r
                                });\r
@@ -8608,13 +10447,14 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        ed.getDoc().execCommand('Outdent', false, null);\r
                },\r
 \r
+/*\r
                mceSetAttribute : function(u, v) {\r
                        var ed = this.editor, d = ed.dom, e;\r
 \r
                        if (e = d.getParent(ed.selection.getNode(), d.isBlock))\r
                                d.setAttrib(e, v.name, v.value);\r
                },\r
-\r
+*/\r
                mceSetContent : function(u, v) {\r
                        this.editor.setContent(v);\r
                },\r
@@ -8633,7 +10473,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                },\r
 \r
                mceInsertLink : function(u, v) {\r
-                       var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'A');\r
+                       var ed = this.editor, s = ed.selection, e = ed.dom.getParent(s.getNode(), 'a');\r
 \r
                        if (tinymce.is(v, 'string'))\r
                                v = {href : v};\r
@@ -8646,9 +10486,8 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
 \r
                        if (!e) {\r
                                ed.execCommand('CreateLink', false, 'javascript:mctmp(0);');\r
-                               each(ed.dom.select('a'), function(e) {\r
-                                       if (e.href == 'javascript:mctmp(0);')\r
-                                               set(e);\r
+                               each(ed.dom.select('a[href=javascript:mctmp(0);]'), function(e) {\r
+                                       set(e);\r
                                });\r
                        } else {\r
                                if (v.href)\r
@@ -8674,46 +10513,32 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        if (!v) {\r
                                if (s.isCollapsed())\r
                                        s.select(s.getNode());\r
-\r
-                               t.RemoveFormat();\r
-                       } else\r
-                               ed.getDoc().execCommand('FontName', false, v);\r
+                       } else {\r
+                               if (ed.settings.convert_fonts_to_spans)\r
+                                       t._applyInlineStyle('span', {style : {fontFamily : v}});\r
+                               else\r
+                                       ed.getDoc().execCommand('FontName', false, v);\r
+                       }\r
                },\r
 \r
                FontSize : function(u, v) {\r
-                       var ed = this.editor, s = ed.settings, fz = tinymce.explode(s.font_size_style_values), fzc = tinymce.explode(s.font_size_classes), h, bm;\r
-\r
-                       // Remove style sizes\r
-                       each(ed.dom.select('font'), function(e) {\r
-                               e.style.fontSize = '';\r
-                       });\r
-\r
-                       // Let the browser add new size it will remove unneded ones in some browsers\r
-                       ed.getDoc().execCommand('FontSize', false, v);\r
+                       var ed = this.editor, s = ed.settings, fc, fs;\r
 \r
-                       // Add style values\r
-                       if (s.inline_styles) {\r
-                               each(ed.dom.select('font'), function(e) {\r
-                                       // Try remove redundant font elements\r
-                                       if (e.parentNode.nodeName == 'FONT' && e.size == e.parentNode.size) {\r
-                                               if (!bm)\r
-                                                       bm = ed.selection.getBookmark();\r
-\r
-                                               ed.dom.remove(e, 1);\r
-                                               return;\r
-                                       }\r
+                       // Use style options instead\r
+                       if (s.convert_fonts_to_spans && v >= 1 && v <= 7) {\r
+                               fs = tinymce.explode(s.font_size_style_values);\r
+                               fc = tinymce.explode(s.font_size_classes);\r
 \r
-                                       // Setup font size based on font size value\r
-                                       if (v = e.size) {\r
-                                               if (fzc && fzc.length > 0)\r
-                                                       ed.dom.setAttrib(e, 'class', fzc[parseInt(v) - 1]);\r
-                                               else\r
-                                                       ed.dom.setStyle(e, 'fontSize', fz[parseInt(v) - 1]);\r
-                                       }\r
-                               });\r
+                               if (fc)\r
+                                       v = fc[v - 1] || v;\r
+                               else\r
+                                       v = fs[v - 1] || v;\r
                        }\r
 \r
-                       ed.selection.moveToBookmark(bm);\r
+                       if (v >= 1 && v <= 7)\r
+                               ed.getDoc().execCommand('FontSize', false, v);\r
+                       else\r
+                               this._applyInlineStyle('span', {style : {fontSize : v}});\r
                },\r
 \r
                queryCommandValue : function(c) {\r
@@ -8763,22 +10588,28 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                queryValueFontSize : function() {\r
                        var ed = this.editor, v = 0, p;\r
 \r
-                       if (isOpera || isWebKit) {\r
-                               if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))\r
+                       if (p = ed.dom.getParent(ed.selection.getNode(), 'span'))\r
+                               v = p.style.fontSize;\r
+\r
+                       if (!v && (isOpera || isWebKit)) {\r
+                               if (p = ed.dom.getParent(ed.selection.getNode(), 'font'))\r
                                        v = p.size;\r
 \r
                                return v;\r
                        }\r
 \r
-                       return this._queryVal('FontSize');\r
+                       return v || this._queryVal('FontSize');\r
                },\r
 \r
                queryValueFontName : function() {\r
                        var ed = this.editor, v = 0, p;\r
 \r
-                       if (p = ed.dom.getParent(ed.selection.getNode(), 'FONT'))\r
+                       if (p = ed.dom.getParent(ed.selection.getNode(), 'font'))\r
                                v = p.face;\r
 \r
+                       if (p = ed.dom.getParent(ed.selection.getNode(), 'span'))\r
+                               v = p.style.fontFamily.replace(/, /g, ',').replace(/[\'\"]/g, '').toLowerCase();\r
+\r
                        if (!v)\r
                                v = this._queryVal('FontName');\r
 \r
@@ -8799,7 +10630,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
 \r
                                if (rm) {\r
                                        if (v == 'center')\r
-                                               dom.setStyle(n.parentNode, 'textAlign', '');\r
+                                               dom.setStyle(bl || n.parentNode, 'textAlign', '');\r
 \r
                                        dom.setStyle(n, 'float', '');\r
                                        this.mceRepaint();\r
@@ -8808,7 +10639,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
 \r
                                if (v == 'center') {\r
                                        // Do not change table elements\r
-                                       if (/^(TD|TH)$/.test(bl.nodeName))\r
+                                       if (bl && /^(TD|TH)$/.test(bl.nodeName))\r
                                                bl = 0;\r
 \r
                                        if (!bl || bl.childNodes.length > 1) {\r
@@ -8829,7 +10660,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                        dom.setStyle(n, 'float', '');\r
                                } else {\r
                                        dom.setStyle(n, 'float', v);\r
-                                       dom.setStyle(n.parentNode, 'textAlign', '');\r
+                                       dom.setStyle(bl || n.parentNode, 'textAlign', '');\r
                                }\r
 \r
                                this.mceRepaint();\r
@@ -8841,7 +10672,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                if (rm)\r
                                        v = '';\r
 \r
-                               each(this._getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {\r
+                               each(se.getSelectedBlocks(dom.getParent(se.getStart(), dom.isBlock), dom.getParent(se.getEnd(), dom.isBlock)), function(e) {\r
                                        dom.setAttrib(e, 'align', '');\r
                                        dom.setStyle(e, 'textAlign', v == 'full' ? 'justify' : v);\r
                                });\r
@@ -8912,7 +10743,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                }\r
                        } else {\r
                                function getParent(n) {\r
-                                       return dom.getParent(n, function(n) {return n.nodeType == 1;});\r
+                                       return dom.getParent(n, '*');\r
                                };\r
 \r
                                sc = r.startContainer;\r
@@ -8970,27 +10801,6 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        return null;\r
                },\r
 \r
-               InsertHorizontalRule : function() {\r
-                       // Fix for Gecko <hr size="1" /> issue and IE bug rep(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]");\r
-                       if (isGecko || isIE)\r
-                               this.editor.selection.setContent('<hr />');\r
-                       else\r
-                               this.editor.getDoc().execCommand('InsertHorizontalRule', false, '');\r
-               },\r
-\r
-               RemoveFormat : function() {\r
-                       var t = this, ed = t.editor, s = ed.selection, b;\r
-\r
-                       // Safari breaks tables\r
-                       if (isWebKit)\r
-                               s.setContent(s.getContent({format : 'raw'}).replace(/(<(span|b|i|strong|em|strike) [^>]+>|<(span|b|i|strong|em|strike)>|<\/(span|b|i|strong|em|strike)>|)/g, ''), {format : 'raw'});\r
-                       else\r
-                               ed.getDoc().execCommand('RemoveFormat', false, null);\r
-\r
-                       t.mceSetStyleInfo(0, {command : 'removeformat'});\r
-                       ed.addVisual();\r
-               },\r
-\r
                mceSetStyleInfo : function(u, v) {\r
                        var t = this, ed = t.editor, d = ed.getDoc(), dom = ed.dom, e, b, s = ed.selection, nn = v.wrapper || 'span', b = s.getBookmark(), re;\r
 \r
@@ -9015,12 +10825,12 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                re = new RegExp(re, 'i');\r
 \r
                        // Set style info on selected element\r
-                       if (e = t.getSelectedElement())\r
+                       if ((e = t.getSelectedElement()) && !ed.settings.force_span_wrappers)\r
                                set(e, 1);\r
                        else {\r
                                // Generate wrappers and set styles on them\r
                                d.execCommand('FontName', false, '__');\r
-                               each(isWebKit ? dom.select('span') : dom.select('font'), function(n) {\r
+                               each(dom.select('span,font'), function(n) {\r
                                        var sp, e;\r
 \r
                                        if (dom.getAttrib(n, 'face') == '__' || n.style.fontFamily === '__') {\r
@@ -9044,9 +10854,7 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                // Check if it's an old span in a new wrapper\r
                                if (!dom.getAttrib(n, 'mce_new')) {\r
                                        // Find new wrapper\r
-                                       p = dom.getParent(n, function(n) {\r
-                                               return n.nodeType == 1 && dom.getAttrib(n, 'mce_new');\r
-                                       });\r
+                                       p = dom.getParent(n, '*[mce_new]');\r
 \r
                                        if (p)\r
                                                dom.remove(n, 1);\r
@@ -9060,6 +10868,9 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                if (!p || !dom.getAttrib(n, 'mce_new'))\r
                                        return;\r
 \r
+                               if (ed.settings.force_span_wrappers && p.nodeName != 'SPAN')\r
+                                       return;\r
+\r
                                // Has parent of the same type and only child\r
                                if (p.nodeName == nn.toUpperCase() && p.childNodes.length == 1)\r
                                        return dom.remove(p, 1);\r
@@ -9107,9 +10918,24 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        return this._queryState(c);\r
                },\r
 \r
+               ForeColor : function(ui, v) {\r
+                       var ed = this.editor;\r
+\r
+                       if (ed.settings.convert_fonts_to_spans) {\r
+                               this._applyInlineStyle('span', {style : {color : v}});\r
+                               return;\r
+                       } else\r
+                               ed.getDoc().execCommand('ForeColor', false, v);\r
+               },\r
+\r
                HiliteColor : function(ui, val) {\r
                        var t = this, ed = t.editor, d = ed.getDoc();\r
 \r
+                       if (ed.settings.convert_fonts_to_spans) {\r
+                               this._applyInlineStyle('span', {style : {backgroundColor : val}});\r
+                               return;\r
+                       }\r
+\r
                        function set(s) {\r
                                if (!isGecko)\r
                                        return;\r
@@ -9131,26 +10957,6 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                                d.execCommand('BackColor', false, val);\r
                },\r
 \r
-               Undo : function() {\r
-                       var ed = this.editor;\r
-\r
-                       if (ed.settings.custom_undo_redo) {\r
-                               ed.undoManager.undo();\r
-                               ed.nodeChanged();\r
-                       } else\r
-                               ed.getDoc().execCommand('Undo', false, null);\r
-               },\r
-\r
-               Redo : function() {\r
-                       var ed = this.editor;\r
-\r
-                       if (ed.settings.custom_undo_redo) {\r
-                               ed.undoManager.redo();\r
-                               ed.nodeChanged();\r
-                       } else\r
-                               ed.getDoc().execCommand('Redo', false, null);\r
-               },\r
-\r
                FormatBlock : function(ui, val) {\r
                        var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, bl, nb, b;\r
 \r
@@ -9275,10 +11081,9 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
 \r
                                if ((n = ed.dom.getParent(ed.selection.getEnd(), ed.dom.isBlock)) && parseInt(n.style.paddingLeft) > 0)\r
                                        return true;\r
-                       } else\r
-                               return !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE');\r
+                       }\r
 \r
-                       return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList();\r
+                       return this.queryStateInsertUnorderedList() || this.queryStateInsertOrderedList() || (!ed.settings.inline_styles && !!ed.dom.getParent(ed.selection.getNode(), 'BLOCKQUOTE'));\r
                },\r
 \r
                queryStateInsertUnorderedList : function() {\r
@@ -9293,350 +11098,322 @@ var tinyMCE = window.tinyMCE = tinymce.EditorManager;
                        return !!this.editor.dom.getParent(this.editor.selection.getStart(), function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
                },\r
 \r
-               mceBlockQuote : function() {\r
-                       var t = this, ed = t.editor, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;\r
-\r
-                       function getBQ(e) {\r
-                               return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
-                       };\r
-\r
-                       // Get start/end block\r
-                       sb = dom.getParent(s.getStart(), dom.isBlock);\r
-                       eb = dom.getParent(s.getEnd(), dom.isBlock);\r
+               _applyInlineStyle : function(na, at, op) {\r
+                       var t = this, ed = t.editor, dom = ed.dom, bm, lo = {}, kh, found;\r
 \r
-                       // Remove blockquote(s)\r
-                       if (bq = getBQ(sb)) {\r
-                               if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
-                                       bm = s.getBookmark();\r
+                       na = na.toUpperCase();\r
 \r
-                               // Move all elements after the end block into new bq\r
-                               if (getBQ(eb)) {\r
-                                       bq2 = bq.cloneNode(false);\r
+                       if (op && op.check_classes && at['class'])\r
+                               op.check_classes.push(at['class']);\r
 \r
-                                       while (n = eb.nextSibling)\r
-                                               bq2.appendChild(n.parentNode.removeChild(n));\r
-                               }\r
+                       function removeEmpty() {\r
+                               each(dom.select(na).reverse(), function(n) {\r
+                                       var c = 0;\r
 \r
-                               // Add new bq after\r
-                               if (bq2)\r
-                                       dom.insertAfter(bq2, bq);\r
+                                       // Check if there is any attributes\r
+                                       each(dom.getAttribs(n), function(an) {\r
+                                               if (an.nodeName.substring(0, 1) != '_' && dom.getAttrib(n, an.nodeName) != '') {\r
+                                                       //console.log(dom.getOuterHTML(n), dom.getAttrib(n, an.nodeName));\r
+                                                       c++;\r
+                                               }\r
+                                       });\r
 \r
-                               // Move all selected blocks after the current bq\r
-                               nl = t._getSelectedBlocks(sb, eb);\r
-                               for (i = nl.length - 1; i >= 0; i--) {\r
-                                       dom.insertAfter(nl[i], bq);\r
-                               }\r
+                                       // No attributes then remove the element and keep the children\r
+                                       if (c == 0)\r
+                                               dom.remove(n, 1);\r
+                               });\r
+                       };\r
 \r
-                               // Empty bq, then remove it\r
-                               if (/^\s*$/.test(bq.innerHTML))\r
-                                       dom.remove(bq, 1); // Keep children so boomark restoration works correctly\r
+                       function replaceFonts() {\r
+                               var bm;\r
 \r
-                               // Empty bq, then remote it\r
-                               if (bq2 && /^\s*$/.test(bq2.innerHTML))\r
-                                       dom.remove(bq2, 1); // Keep children so boomark restoration works correctly\r
+                               each(dom.select('span,font'), function(n) {\r
+                                       if (n.style.fontFamily == 'mceinline' || n.face == 'mceinline') {\r
+                                               if (!bm)\r
+                                                       bm = ed.selection.getBookmark();\r
 \r
-                               if (!bm) {\r
-                                       // Move caret inside empty block element\r
-                                       if (!isIE) {\r
-                                               r = ed.getDoc().createRange();\r
-                                               r.setStart(sb, 0);\r
-                                               r.setEnd(sb, 0);\r
-                                               s.setRng(r);\r
-                                       } else {\r
-                                               s.select(sb);\r
-                                               s.collapse(0);\r
-\r
-                                               // IE misses the empty block some times element so we must move back the caret\r
-                                               if (dom.getParent(s.getStart(), dom.isBlock) != sb) {\r
-                                                       r = s.getRng();\r
-                                                       r.move('character', -1);\r
-                                                       r.select();\r
-                                               }\r
+                                               at._mce_new = '1';\r
+                                               dom.replace(dom.create(na, at), n, 1);\r
                                        }\r
-                               } else\r
-                                       t.editor.selection.moveToBookmark(bm);\r
+                               });\r
 \r
-                               return;\r
-                       }\r
+                               // Remove redundant elements\r
+                               each(dom.select(na + '[_mce_new]'), function(n) {\r
+                                       function removeStyle(n) {\r
+                                               if (n.nodeType == 1) {\r
+                                                       each(at.style, function(v, k) {\r
+                                                               dom.setStyle(n, k, '');\r
+                                                       });\r
 \r
-                       // Since IE can start with a totally empty document we need to add the first bq and paragraph\r
-                       if (isIE && !sb && !eb) {\r
-                               t.editor.getDoc().execCommand('Indent');\r
-                               n = getBQ(s.getNode());\r
-                               n.style.margin = n.dir = ''; // IE adds margin and dir to bq\r
-                               return;\r
-                       }\r
+                                                       // Remove spans with the same class or marked classes\r
+                                                       if (at['class'] && n.className && op) {\r
+                                                               each(op.check_classes, function(c) {\r
+                                                                       if (dom.hasClass(n, c))\r
+                                                                               dom.removeClass(n, c);\r
+                                                               });\r
+                                                       }\r
+                                               }\r
+                                       };\r
 \r
-                       if (!sb || !eb)\r
-                               return;\r
+                                       // Remove specified style information from child elements\r
+                                       each(dom.select(na, n), removeStyle);\r
 \r
-                       // If empty paragraph node then do not use bookmark\r
-                       if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
-                               bm = s.getBookmark();\r
+                                       // Remove the specified style information on parent if current node is only child (IE)\r
+                                       if (n.parentNode && n.parentNode.nodeType == 1 && n.parentNode.childNodes.length == 1)\r
+                                               removeStyle(n.parentNode);\r
 \r
-                       // Move selected block elements into a bq\r
-                       each(t._getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {\r
-                               // Found existing BQ add to this one\r
-                               if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
-                                       bq = e;\r
-                                       return;\r
-                               }\r
+                                       // Remove the child elements style info if a parent already has it\r
+                                       dom.getParent(n.parentNode, function(pn) {\r
+                                               if (pn.nodeType == 1) {\r
+                                                       if (at.style) {\r
+                                                               each(at.style, function(v, k) {\r
+                                                                       var sv;\r
 \r
-                               // No BQ found, create one\r
-                               if (!bq) {\r
-                                       bq = dom.create('blockquote');\r
-                                       e.parentNode.insertBefore(bq, e);\r
-                               }\r
+                                                                       if (!lo[k] && (sv = dom.getStyle(pn, k))) {\r
+                                                                               if (sv === v)\r
+                                                                                       dom.setStyle(n, k, '');\r
 \r
-                               // Add children from existing BQ\r
-                               if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
-                                       n = e.firstChild;\r
+                                                                               lo[k] = 1;\r
+                                                                       }\r
+                                                               });\r
+                                                       }\r
 \r
-                                       while (n) {\r
-                                               bq.appendChild(n.cloneNode(true));\r
-                                               n = n.nextSibling;\r
-                                       }\r
+                                                       // Remove spans with the same class or marked classes\r
+                                                       if (at['class'] && pn.className && op) {\r
+                                                               each(op.check_classes, function(c) {\r
+                                                                       if (dom.hasClass(pn, c))\r
+                                                                               dom.removeClass(n, c);\r
+                                                               });\r
+                                                       }\r
+                                               }\r
 \r
-                                       dom.remove(e);\r
-                                       return;\r
-                               }\r
+                                               return false;\r
+                                       });\r
 \r
-                               // Add non BQ element to BQ\r
-                               bq.appendChild(dom.remove(e));\r
-                       });\r
+                                       n.removeAttribute('_mce_new');\r
+                               });\r
 \r
-                       if (!bm) {\r
-                               // Move caret inside empty block element\r
-                               if (!isIE) {\r
-                                       r = ed.getDoc().createRange();\r
-                                       r.setStart(sb, 0);\r
-                                       r.setEnd(sb, 0);\r
-                                       s.setRng(r);\r
-                               } else {\r
-                                       s.select(sb);\r
-                                       s.collapse(1);\r
-                               }\r
-                       } else\r
-                               s.moveToBookmark(bm);\r
-               },\r
-/*\r
-               _mceBlockQuote : function() {\r
-                       var t = this, s = t.editor.selection, b = s.getBookmark(), bq, dom = t.editor.dom;\r
+                               removeEmpty();\r
+                               ed.selection.moveToBookmark(bm);\r
 \r
-                       function findBQ(e) {\r
-                               return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
+                               return !!bm;\r
                        };\r
 \r
-                       // Remove blockquote(s)\r
-                       if (findBQ(s.getStart())) {\r
-                               each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {\r
-                                       // Found BQ lets remove it\r
-                                       if (e.nodeName == 'BLOCKQUOTE')\r
-                                               dom.remove(e, 1);\r
-                               });\r
+                       // Create inline elements\r
+                       ed.focus();\r
+                       ed.getDoc().execCommand('FontName', false, 'mceinline');\r
+                       replaceFonts();\r
 \r
-                               t.editor.selection.moveToBookmark(b);\r
-                               return;\r
+                       if (kh = t._applyInlineStyle.keyhandler) {\r
+                               ed.onKeyUp.remove(kh);\r
+                               ed.onKeyPress.remove(kh);\r
+                               ed.onKeyDown.remove(kh);\r
+                               ed.onSetContent.remove(t._applyInlineStyle.chandler);\r
                        }\r
 \r
-                       each(t._getSelectedBlocks(findBQ(s.getStart()), findBQ(s.getEnd())), function(e) {\r
-                               var n;\r
-\r
-                               // Found existing BQ add to this one\r
-                               if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
-                                       bq = e;\r
-                                       return;\r
-                               }\r
+                       if (ed.selection.isCollapsed()) {\r
+                               // IE will format the current word so this code can't be executed on that browser\r
+                               if (!isIE) {\r
+                                       each(dom.getParents(ed.selection.getNode(), 'span'), function(n) {\r
+                                               each(at.style, function(v, k) {\r
+                                                       var kv;\r
+\r
+                                                       if (kv = dom.getStyle(n, k)) {\r
+                                                               if (kv == v) {\r
+                                                                       dom.setStyle(n, k, '');\r
+                                                                       found = 2;\r
+                                                                       return false;\r
+                                                               }\r
 \r
-                               // No BQ found, create one\r
-                               if (!bq) {\r
-                                       bq = dom.create('blockquote');\r
-                                       e.parentNode.insertBefore(bq, e);\r
-                               }\r
+                                                               found = 1;\r
+                                                               return false;\r
+                                                       }\r
+                                               });\r
 \r
-                               // Add children from existing BQ\r
-                               if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
-                                       n = e.firstChild;\r
+                                               if (found)\r
+                                                       return false;\r
+                                       });\r
 \r
-                                       while (n) {\r
-                                               bq.appendChild(n.cloneNode(true));\r
-                                               n = n.nextSibling;\r
-                                       }\r
+                                       if (found == 2) {\r
+                                               bm = ed.selection.getBookmark();\r
 \r
-                                       dom.remove(e);\r
+                                               removeEmpty();\r
 \r
-                                       return;\r
-                               }\r
+                                               ed.selection.moveToBookmark(bm);\r
 \r
-                               // Add non BQ element to BQ\r
-                               bq.appendChild(dom.remove(e));\r
-                       });\r
+                                               // Node change needs to be detached since the onselect event\r
+                                               // for the select box will run the onclick handler after onselect call. Todo: Add a nicer fix!\r
+                                               window.setTimeout(function() {\r
+                                                       ed.nodeChanged();\r
+                                               }, 1);\r
 \r
-                       t.editor.selection.moveToBookmark(b);\r
-               },\r
-*/\r
-               _getSelectedBlocks : function(st, en) {\r
-                       var ed = this.editor, dom = ed.dom, s = ed.selection, sb, eb, n, bl = [];\r
+                                               return;\r
+                                       }\r
+                               }\r
 \r
-                       sb = dom.getParent(st || s.getStart(), dom.isBlock);\r
-                       eb = dom.getParent(en || s.getEnd(), dom.isBlock);\r
+                               // Start collecting styles\r
+                               t._pendingStyles = tinymce.extend(t._pendingStyles || {}, at.style);\r
 \r
-                       if (sb)\r
-                               bl.push(sb);\r
+                               t._applyInlineStyle.chandler = ed.onSetContent.add(function() {\r
+                                       delete t._pendingStyles;\r
+                               });\r
 \r
-                       if (sb && eb && sb != eb) {\r
-                               n = sb;\r
+                               t._applyInlineStyle.keyhandler = kh = function(e) {\r
+                                       // Use pending styles\r
+                                       if (t._pendingStyles) {\r
+                                               at.style = t._pendingStyles;\r
+                                               delete t._pendingStyles;\r
+                                       }\r
 \r
-                               while ((n = n.nextSibling) && n != eb) {\r
-                                       if (dom.isBlock(n))\r
-                                               bl.push(n);\r
-                               }\r
-                       }\r
+                                       if (replaceFonts()) {\r
+                                               ed.onKeyDown.remove(t._applyInlineStyle.keyhandler);\r
+                                               ed.onKeyPress.remove(t._applyInlineStyle.keyhandler);\r
+                                       }\r
 \r
-                       if (eb && sb != eb)\r
-                               bl.push(eb);\r
+                                       if (e.type == 'keyup')\r
+                                               ed.onKeyUp.remove(t._applyInlineStyle.keyhandler);\r
+                               };\r
 \r
-                       return bl;\r
+                               ed.onKeyDown.add(kh);\r
+                               ed.onKeyPress.add(kh);\r
+                               ed.onKeyUp.add(kh);\r
+                       } else\r
+                               t._pendingStyles = 0;\r
                }\r
        });\r
-})();\r
-\r
+})(tinymce);(function(tinymce) {\r
+       tinymce.create('tinymce.UndoManager', {\r
+               index : 0,\r
+               data : null,\r
+               typing : 0,\r
 \r
-/* file:jscripts/tiny_mce/classes/UndoManager.js */\r
+               UndoManager : function(ed) {\r
+                       var t = this, Dispatcher = tinymce.util.Dispatcher;\r
 \r
-tinymce.create('tinymce.UndoManager', {\r
-       index : 0,\r
-       data : null,\r
-       typing : 0,\r
-\r
-       UndoManager : function(ed) {\r
-               var t = this, Dispatcher = tinymce.util.Dispatcher;\r
-\r
-               t.editor = ed;\r
-               t.data = [];\r
-               t.onAdd = new Dispatcher(this);\r
-               t.onUndo = new Dispatcher(this);\r
-               t.onRedo = new Dispatcher(this);\r
-       },\r
+                       t.editor = ed;\r
+                       t.data = [];\r
+                       t.onAdd = new Dispatcher(this);\r
+                       t.onUndo = new Dispatcher(this);\r
+                       t.onRedo = new Dispatcher(this);\r
+               },\r
 \r
-       add : function(l) {\r
-               var t = this, i, ed = t.editor, b, s = ed.settings, la;\r
+               add : function(l) {\r
+                       var t = this, i, ed = t.editor, b, s = ed.settings, la;\r
 \r
-               l = l || {};\r
-               l.content = l.content || ed.getContent({format : 'raw', no_events : 1});\r
+                       l = l || {};\r
+                       l.content = l.content || ed.getContent({format : 'raw', no_events : 1});\r
 \r
-               // Add undo level if needed\r
-               l.content = l.content.replace(/^\s*|\s*$/g, '');\r
-               la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index];\r
-               if (!l.initial && la && l.content == la.content)\r
-                       return null;\r
+                       // Add undo level if needed\r
+                       l.content = l.content.replace(/^\s*|\s*$/g, '');\r
+                       la = t.data[t.index > 0 && (t.index == 0 || t.index == t.data.length) ? t.index - 1 : t.index];\r
+                       if (!l.initial && la && l.content == la.content)\r
+                               return null;\r
 \r
-               // Time to compress\r
-               if (s.custom_undo_redo_levels) {\r
-                       if (t.data.length > s.custom_undo_redo_levels) {\r
-                               for (i = 0; i < t.data.length - 1; i++)\r
-                                       t.data[i] = t.data[i + 1];\r
+                       // Time to compress\r
+                       if (s.custom_undo_redo_levels) {\r
+                               if (t.data.length > s.custom_undo_redo_levels) {\r
+                                       for (i = 0; i < t.data.length - 1; i++)\r
+                                               t.data[i] = t.data[i + 1];\r
 \r
-                               t.data.length--;\r
-                               t.index = t.data.length;\r
+                                       t.data.length--;\r
+                                       t.index = t.data.length;\r
+                               }\r
                        }\r
-               }\r
-\r
-               if (s.custom_undo_redo_restore_selection && !l.initial)\r
-                       l.bookmark = b = l.bookmark || ed.selection.getBookmark();\r
 \r
-               if (t.index < t.data.length)\r
-                       t.index++;\r
+                       if (s.custom_undo_redo_restore_selection && !l.initial)\r
+                               l.bookmark = b = l.bookmark || ed.selection.getBookmark();\r
 \r
-               // Only initial marked undo levels should be allowed as first item\r
-               // This to workaround a bug with Firefox and the blur event\r
-               if (t.data.length === 0 && !l.initial)\r
-                       return null;\r
+                       if (t.index < t.data.length)\r
+                               t.index++;\r
 \r
-               // Add level\r
-               t.data.length = t.index + 1;\r
-               t.data[t.index++] = l;\r
+                       // Only initial marked undo levels should be allowed as first item\r
+                       // This to workaround a bug with Firefox and the blur event\r
+                       if (t.data.length === 0 && !l.initial)\r
+                               return null;\r
 \r
-               if (l.initial)\r
-                       t.index = 0;\r
+                       // Add level\r
+                       t.data.length = t.index + 1;\r
+                       t.data[t.index++] = l;\r
 \r
-               // Set initial bookmark use first real undo level\r
-               if (t.data.length == 2 && t.data[0].initial)\r
-                       t.data[0].bookmark = b;\r
+                       if (l.initial)\r
+                               t.index = 0;\r
 \r
-               t.onAdd.dispatch(t, l);\r
-               ed.isNotDirty = 0;\r
+                       // Set initial bookmark use first real undo level\r
+                       if (t.data.length == 2 && t.data[0].initial)\r
+                               t.data[0].bookmark = b;\r
 \r
-               //console.dir(t.data);\r
+                       t.onAdd.dispatch(t, l);\r
+                       ed.isNotDirty = 0;\r
 \r
-               return l;\r
-       },\r
+                       //console.dir(t.data);\r
 \r
-       undo : function() {\r
-               var t = this, ed = t.editor, l = l, i;\r
+                       return l;\r
+               },\r
 \r
-               if (t.typing) {\r
-                       t.add();\r
-                       t.typing = 0;\r
-               }\r
+               undo : function() {\r
+                       var t = this, ed = t.editor, l = l, i;\r
 \r
-               if (t.index > 0) {\r
-                       // If undo on last index then take snapshot\r
-                       if (t.index == t.data.length && t.index > 1) {\r
-                               i = t.index;\r
+                       if (t.typing) {\r
+                               t.add();\r
                                t.typing = 0;\r
+                       }\r
 \r
-                               if (!t.add())\r
-                                       t.index = i;\r
+                       if (t.index > 0) {\r
+                               // If undo on last index then take snapshot\r
+                               if (t.index == t.data.length && t.index > 1) {\r
+                                       i = t.index;\r
+                                       t.typing = 0;\r
 \r
-                               --t.index;\r
-                       }\r
+                                       if (!t.add())\r
+                                               t.index = i;\r
 \r
-                       l = t.data[--t.index];\r
-                       ed.setContent(l.content, {format : 'raw'});\r
-                       ed.selection.moveToBookmark(l.bookmark);\r
+                                       --t.index;\r
+                               }\r
 \r
-                       t.onUndo.dispatch(t, l);\r
-               }\r
+                               l = t.data[--t.index];\r
+                               ed.setContent(l.content, {format : 'raw'});\r
+                               ed.selection.moveToBookmark(l.bookmark);\r
 \r
-               return l;\r
-       },\r
+                               t.onUndo.dispatch(t, l);\r
+                       }\r
 \r
-       redo : function() {\r
-               var t = this, ed = t.editor, l = null;\r
+                       return l;\r
+               },\r
 \r
-               if (t.index < t.data.length - 1) {\r
-                       l = t.data[++t.index];\r
-                       ed.setContent(l.content, {format : 'raw'});\r
-                       ed.selection.moveToBookmark(l.bookmark);\r
+               redo : function() {\r
+                       var t = this, ed = t.editor, l = null;\r
 \r
-                       t.onRedo.dispatch(t, l);\r
-               }\r
+                       if (t.index < t.data.length - 1) {\r
+                               l = t.data[++t.index];\r
+                               ed.setContent(l.content, {format : 'raw'});\r
+                               ed.selection.moveToBookmark(l.bookmark);\r
 \r
-               return l;\r
-       },\r
+                               t.onRedo.dispatch(t, l);\r
+                       }\r
 \r
-       clear : function() {\r
-               var t = this;\r
+                       return l;\r
+               },\r
 \r
-               t.data = [];\r
-               t.index = 0;\r
-               t.typing = 0;\r
-               t.add({initial : true});\r
-       },\r
+               clear : function() {\r
+                       var t = this;\r
 \r
-       hasUndo : function() {\r
-               return this.index != 0 || this.typing;\r
-       },\r
+                       t.data = [];\r
+                       t.index = 0;\r
+                       t.typing = 0;\r
+                       t.add({initial : true});\r
+               },\r
 \r
-       hasRedo : function() {\r
-               return this.index < this.data.length - 1;\r
-       }\r
+               hasUndo : function() {\r
+                       return this.index != 0 || this.typing;\r
+               },\r
 \r
-       });\r
-/* file:jscripts/tiny_mce/classes/ForceBlocks.js */\r
+               hasRedo : function() {\r
+                       return this.index < this.data.length - 1;\r
+               }\r
 \r
-(function() {\r
+               });\r
+})(tinymce);\r
+(function(tinymce) {\r
        // Shorten names\r
        var Event, isIE, isGecko, isOpera, each, extend;\r
 \r
@@ -9647,6 +11424,15 @@ tinymce.create('tinymce.UndoManager', {
        each = tinymce.each;\r
        extend = tinymce.extend;\r
 \r
+       function isEmpty(n) {\r
+               n = n.innerHTML;\r
+               n = n.replace(/<\w+ .*?mce_\w+\"?=.*?>/gi, '-'); // Keep tags with mce_ attribs\r
+               n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars\r
+               n = n.replace(/<[^>]+>/g, ''); // Remove all tags\r
+\r
+               return n.replace(/[ \t\r\n]+/g, '') == '';\r
+       };\r
+\r
        tinymce.create('tinymce.ForceBlocks', {\r
                ForceBlocks : function(ed) {\r
                        var t = this, s = ed.settings, elm;\r
@@ -9661,9 +11447,8 @@ tinymce.create('tinymce.UndoManager', {
                        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.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
-                       t.reTrailBr = new RegExp('\\s*<br \\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');\r
 \r
                        function padd(ed, o) {\r
                                if (isOpera)\r
@@ -9675,10 +11460,8 @@ tinymce.create('tinymce.UndoManager', {
                                        // 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
+                               } else\r
                                        o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0</' + elm + '>');\r
-                                       o.content = o.content.replace(t.reTrailBr, '</' + elm + '>');\r
-                               }\r
                        };\r
 \r
                        ed.onBeforeSetContent.add(padd);\r
@@ -9764,29 +11547,41 @@ tinymce.create('tinymce.UndoManager', {
                                return ne;\r
                        };\r
 \r
-                       // Replaces IE:s auto generated paragraphs with the specified element name\r
-                       if (isIE && s.element != 'P') {\r
-                               ed.onKeyPress.add(function(ed, e) {\r
-                                       t.lastElm = ed.selection.getNode().nodeName;\r
+                       // IE specific fixes\r
+                       if (isIE) {\r
+                               // Remove empty inline elements within block elements\r
+                               // For example: <p><strong><em></em></strong></p>\r
+                               ed.onPreProcess.add(function(ed, o) {\r
+                                       each(ed.dom.select('p,h1,h2,h3,h4,h5,h6,div', o.node), function(p) {\r
+                                               if (isEmpty(p))\r
+                                                       p.innerHTML = '';\r
+                                       });\r
                                });\r
 \r
-                               ed.onKeyUp.add(function(ed, e) {\r
-                                       var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();\r
+                               // Replaces IE:s auto generated paragraphs with the specified element name\r
+                               if (s.element != 'P') {\r
+                                       ed.onKeyPress.add(function(ed, e) {\r
+                                               t.lastElm = ed.selection.getNode().nodeName;\r
+                                       });\r
 \r
-                                       if (b.childNodes.length === 1 && n.nodeName == 'P') {\r
-                                               n = ren(n, s.element);\r
-                                               sel.select(n);\r
-                                               sel.collapse();\r
-                                               ed.nodeChanged();\r
-                                       } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {\r
-                                               bl = ed.dom.getParent(n, 'P');\r
+                                       ed.onKeyUp.add(function(ed, e) {\r
+                                               var bl, sel = ed.selection, n = sel.getNode(), b = ed.getBody();\r
 \r
-                                               if (bl) {\r
-                                                       ren(bl, s.element);\r
+                                               if (b.childNodes.length === 1 && n.nodeName == 'P') {\r
+                                                       n = ren(n, s.element);\r
+                                                       sel.select(n);\r
+                                                       sel.collapse();\r
                                                        ed.nodeChanged();\r
+                                               } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') {\r
+                                                       bl = ed.dom.getParent(n, 'p');\r
+\r
+                                                       if (bl) {\r
+                                                               ren(bl, s.element);\r
+                                                               ed.nodeChanged();\r
+                                                       }\r
                                                }\r
-                                       }\r
-                               });\r
+                                       });\r
+                               }\r
                        }\r
                },\r
 \r
@@ -9810,11 +11605,11 @@ tinymce.create('tinymce.UndoManager', {
 \r
                forceRoots : function(ed, e) {\r
                        var t = this, ed = t.editor, b = ed.getBody(), d = ed.getDoc(), se = ed.selection, s = se.getSel(), r = se.getRng(), si = -2, ei, so, eo, tr, c = -0xFFFFFF;\r
-                       var nx, bl, bp, sp, le, nl = b.childNodes, i;\r
+                       var nx, bl, bp, sp, le, nl = b.childNodes, i, n, eid;\r
 \r
                        // Fix for bug #1863847\r
-                       if (e && e.keyCode == 13)\r
-                               return true;\r
+                       //if (e && e.keyCode == 13)\r
+                       //      return true;\r
 \r
                        // Wrap non blocks into blocks\r
                        for (i = nl.length - 1; i >= 0; i--) {\r
@@ -9828,12 +11623,19 @@ tinymce.create('tinymce.UndoManager', {
                                                        // Store selection\r
                                                        if (si == -2 && r) {\r
                                                                if (!isIE) {\r
-                                                                       // If element is inside body, might not be the case in contentEdiable mode\r
-                                                                       if (ed.dom.getParent(r.startContainer, function(e) {return e === b;})) {\r
-                                                                               so = r.startOffset;\r
-                                                                               eo = r.endOffset;\r
-                                                                               si = t.find(b, 0, r.startContainer);\r
-                                                                               ei = t.find(b, 0, r.endContainer);\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
+                                                                               eid = n.getAttribute("id");\r
+                                                                               n.setAttribute("id", "__mce");\r
+                                                                       } else {\r
+                                                                               // If element is inside body, might not be the case in contentEdiable mode\r
+                                                                               if (ed.dom.getParent(r.startContainer, function(e) {return e === b;})) {\r
+                                                                                       so = r.startOffset;\r
+                                                                                       eo = r.endOffset;\r
+                                                                                       si = t.find(b, 0, r.startContainer);\r
+                                                                                       ei = t.find(b, 0, r.endContainer);\r
+                                                                               }\r
                                                                        }\r
                                                                } else {\r
                                                                        tr = d.body.createTextRange();\r
@@ -9902,6 +11704,18 @@ tinymce.create('tinymce.UndoManager', {
                                                // Ignore\r
                                        }\r
                                }\r
+                       } else if (!isIE && (n = ed.dom.get('__mce'))) {\r
+                               // Restore the id of the selected element\r
+                               if (eid)\r
+                                       n.setAttribute('id', eid);\r
+                               else\r
+                                       n.removeAttribute('id');\r
+\r
+                               // Move caret before selected element\r
+                               r = d.createRange();\r
+                               r.setStartBefore(n);\r
+                               r.setEndBefore(n);\r
+                               se.setRng(r);\r
                        }\r
                },\r
 \r
@@ -9913,15 +11727,7 @@ tinymce.create('tinymce.UndoManager', {
 \r
                insertPara : function(e) {\r
                        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;\r
-\r
-                       function isEmpty(n) {\r
-                               n = n.innerHTML;\r
-                               n = n.replace(/<(img|hr|table)/gi, '-'); // Keep these convert them to - chars\r
-                               n = n.replace(/<[^>]+>/g, ''); // Remove all tags\r
-\r
-                               return n.replace(/[ \t\r\n]+/g, '') == '';\r
-                       };\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
                        // If root blocks are forced then use Operas default behavior since it's really good\r
 // Removed due to bug: #1853816\r
@@ -9988,23 +11794,23 @@ tinymce.create('tinymce.UndoManager', {
                        bn = sb ? sb.nodeName : se.element; // Get block name to create\r
 \r
                        // Return inside list use default browser behavior\r
-                       if (t.dom.getParent(sb, function(n) { return /OL|UL|PRE/.test(n.nodeName); }))\r
+                       if (t.dom.getParent(sb, 'ol,ul,pre'))\r
                                return true;\r
 \r
                        // If caption or absolute layers then always generate new blocks within\r
-                       if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(sb.style.position))) {\r
+                       if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) {\r
                                bn = se.element;\r
                                sb = null;\r
                        }\r
 \r
                        // If caption or absolute layers then always generate new blocks within\r
-                       if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|static/gi.test(eb.style.position))) {\r
+                       if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) {\r
                                bn = se.element;\r
                                eb = null;\r
                        }\r
 \r
                        // Use P instead\r
-                       if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(sb.style.cssFloat))) {\r
+                       if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(dom.getStyle(sb, 'float', 1)))) {\r
                                bn = se.element;\r
                                sb = eb = null;\r
                        }\r
@@ -10090,8 +11896,39 @@ tinymce.create('tinymce.UndoManager', {
                        if (isEmpty(bef))\r
                                bef.innerHTML = '<br />';\r
 \r
+                       function appendStyles(e, en) {\r
+                               var nl = [], nn, n, i;\r
+\r
+                               e.innerHTML = '';\r
+\r
+                               // Make clones of style elements\r
+                               if (se.keep_styles) {\r
+                                       n = en;\r
+                                       do {\r
+                                               // We only want style specific elements\r
+                                               if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(n.nodeName)) {\r
+                                                       nn = n.cloneNode(false);\r
+                                                       dom.setAttrib(nn, 'id', ''); // Remove ID since it needs to be unique\r
+                                                       nl.push(nn);\r
+                                               }\r
+                                       } while (n = n.parentNode);\r
+                               }\r
+\r
+                               // Append style elements to aft\r
+                               if (nl.length > 0) {\r
+                                       for (i = nl.length - 1, nn = e; i >= 0; i--)\r
+                                               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
+                                       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
+                       };\r
+\r
+                       // Fill empty afterblook with current style\r
                        if (isEmpty(aft))\r
-                               aft.innerHTML = isOpera ? '&nbsp;' : '<br />'; // Extra space for Opera so that the caret can move there\r
+                               car = appendStyles(aft, en);\r
 \r
                        // Opera needs this one backwards for older versions\r
                        if (isOpera && parseFloat(opera.version()) < 9.5) {\r
@@ -10112,7 +11949,7 @@ tinymce.create('tinymce.UndoManager', {
 \r
                        // Move cursor and scroll into view\r
                        r = d.createRange();\r
-                       r.selectNodeContents(isGecko ? first(aft) : aft);\r
+                       r.selectNodeContents(isGecko ? first(car || aft) : car || aft);\r
                        r.collapse(1);\r
                        s.removeAllRanges();\r
                        s.addRange(r);\r
@@ -10123,7 +11960,7 @@ tinymce.create('tinymce.UndoManager', {
 \r
                        // Is element within viewport\r
                        if (y < vp.y || y + ch > vp.y + vp.h) {\r
-                               ed.getWin().scrollTo(0, y < vp.y ? y : y - vp.h + ch);\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
 \r
@@ -10165,12 +12002,21 @@ tinymce.create('tinymce.UndoManager', {
 \r
                        // Gecko generates BR elements here and there, we don't like those so lets remove them\r
                        function handler(e) {\r
+                               var pr;\r
+\r
                                e = e.target;\r
 \r
                                // A new BR was created in a block element, remove it\r
                                if (e && e.parentNode && e.nodeName == 'BR' && (n = t.getParentBlock(e))) {\r
+                                       pr = e.previousSibling;\r
+\r
                                        Event.remove(b, 'DOMNodeInserted', handler);\r
 \r
+                                       // Is there whitespace at the end of the node before then we might need the pesky BR\r
+                                       // to place the caret at a correct location see bug: #2013943\r
+                                       if (pr && pr.nodeType == 3 && /\s+$/.test(pr.nodeValue))\r
+                                               return;\r
+\r
                                        // Only remove BR elements that got inserted in the middle of the text\r
                                        if (e.previousSibling || e.nextSibling)\r
                                                ed.dom.remove(e);\r
@@ -10186,11 +12032,8 @@ tinymce.create('tinymce.UndoManager', {
                        }, 1);\r
                }\r
        });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/ControlManager.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        // Shorten names\r
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, extend = tinymce.extend;\r
 \r
@@ -10304,12 +12147,17 @@ tinymce.create('tinymce.UndoManager', {
                        // Fix for bug #1897785, #1898007\r
                        if (tinymce.isIE) {\r
                                c.onShowMenu.add(function() {\r
+                                       // IE 8 needs focus in order to store away a range with the current collapsed caret location\r
+                                       ed.focus();\r
+\r
                                        bm = ed.selection.getBookmark(1);\r
                                });\r
 \r
                                c.onHideMenu.add(function() {\r
-                                       if (bm)\r
+                                       if (bm) {\r
                                                ed.selection.moveToBookmark(bm);\r
+                                               bm = 0;\r
+                                       }\r
                                });\r
                        }\r
 \r
@@ -10409,11 +12257,11 @@ tinymce.create('tinymce.UndoManager', {
                        return t.add(c);\r
                },\r
 \r
-               createMenuButton : function(id, s) {\r
+               createMenuButton : function(id, s, cc) {\r
                        s = s || {};\r
                        s.menu_button = 1;\r
 \r
-                       return this.createButton(id, s);\r
+                       return this.createButton(id, s, cc);\r
                },\r
 \r
                createSplitButton : function(id, s, cc) {\r
@@ -10463,6 +12311,9 @@ tinymce.create('tinymce.UndoManager', {
 \r
                        if (!s.onclick) {\r
                                s.onclick = function(v) {\r
+                                       if (tinymce.isIE)\r
+                                               bm = ed.selection.getBookmark(1);\r
+       \r
                                        ed.execCommand(s.cmd, s.ui || false, v || s.value);\r
                                };\r
                        }\r
@@ -10493,10 +12344,6 @@ tinymce.create('tinymce.UndoManager', {
 \r
                        // Fix for bug #1897785, #1898007\r
                        if (tinymce.isIE) {\r
-                               c.onShowMenu.add(function() {\r
-                                       bm = ed.selection.getBookmark(1);\r
-                               });\r
-\r
                                c.onHideMenu.add(function() {\r
                                        if (bm) {\r
                                                ed.selection.moveToBookmark(bm);\r
@@ -10540,11 +12387,8 @@ tinymce.create('tinymce.UndoManager', {
                }\r
 \r
                });\r
-})();\r
-\r
-/* file:jscripts/tiny_mce/classes/WindowManager.js */\r
-\r
-(function() {\r
+})(tinymce);\r
+(function(tinymce) {\r
        var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isIE = tinymce.isIE, isOpera = tinymce.isOpera;\r
 \r
        tinymce.create('tinymce.WindowManager', {\r
@@ -10605,9 +12449,6 @@ tinymce.create('tinymce.UndoManager', {
                        t.onOpen.dispatch(t, s, p);\r
 \r
                        u = s.url || s.file;\r
-                       if (tinymce.relaxedDomain)\r
-                               u += (u.indexOf('?') == -1 ? '?' : '&') + 'mce_rdomain=' + tinymce.relaxedDomain;\r
-\r
                        u = tinymce._addVer(u);\r
 \r
                        try {\r
@@ -10635,14 +12476,17 @@ tinymce.create('tinymce.UndoManager', {
                        return new f(a, b, c, d, e);\r
                },\r
 \r
-               confirm : function(t, cb, s) {\r
-                       cb.call(s || this, confirm(this._decode(this.editor.getLang(t, t))));\r
+               confirm : function(t, cb, s, w) {\r
+                       w = w || window;\r
+\r
+                       cb.call(s || this, w.confirm(this._decode(this.editor.getLang(t, t))));\r
                },\r
 \r
-               alert : function(tx, cb, s) {\r
+               alert : function(tx, cb, s, w) {\r
                        var t = this;\r
-       \r
-                       alert(t._decode(t.editor.getLang(tx, tx)));\r
+\r
+                       w = w || window;\r
+                       w.alert(t._decode(t.editor.getLang(tx, tx)));\r
 \r
                        if (cb)\r
                                cb.call(s || t);\r
@@ -10655,4 +12499,399 @@ tinymce.create('tinymce.UndoManager', {
                }\r
 \r
                });\r
-}());
\ No newline at end of file
+}(tinymce));(function(tinymce) {\r
+       tinymce.CommandManager = function() {\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 tinymce.CommandManager();\r
+})(tinymce);(function(tinymce) {\r
+       function processRange(dom, start, end, callback) {\r
+               var ancestor, n, startPoint, endPoint, sib;\r
+\r
+               function findEndPoint(n, c) {\r
+                       do {\r
+                               if (n.parentNode == c)\r
+                                       return n;\r
+\r
+                               n = n.parentNode;\r
+                       } while(n);\r
+               };\r
+\r
+               function process(n) {\r
+                       callback(n);\r
+                       tinymce.walk(n, callback, 'childNodes');\r
+               };\r
+\r
+               // Find common ancestor and end points\r
+               ancestor = dom.findCommonAncestor(start, end);\r
+               startPoint = findEndPoint(start, ancestor) || start;\r
+               endPoint = findEndPoint(end, ancestor) || end;\r
+\r
+               // Process left leaf\r
+               for (n = start; n && n != startPoint; n = n.parentNode) {\r
+                       for (sib = n.nextSibling; sib; sib = sib.nextSibling)\r
+                               process(sib);\r
+               }\r
+\r
+               // Process middle from start to end point\r
+               if (startPoint != endPoint) {\r
+                       for (n = startPoint.nextSibling; n && n != endPoint; n = n.nextSibling)\r
+                               process(n);\r
+               } else\r
+                       process(startPoint);\r
+\r
+               // Process right leaf\r
+               for (n = end; n && n != endPoint; n = n.parentNode) {\r
+                       for (sib = n.previousSibling; sib; sib = sib.previousSibling)\r
+                               process(sib);\r
+               }\r
+       };\r
+\r
+       tinymce.GlobalCommands.add('RemoveFormat', function() {\r
+               var ed = this, dom = ed.dom, s = ed.selection, r = s.getRng(1), nodes = [], bm, start, end, sc, so, ec, eo, n;\r
+\r
+               function findFormatRoot(n) {\r
+                       var sp;\r
+\r
+                       dom.getParent(n, function(n) {\r
+                               if (dom.is(n, ed.getParam('removeformat_selector')))\r
+                                       sp = n;\r
+\r
+                               return dom.isBlock(n);\r
+                       }, ed.getBody());\r
+\r
+                       return sp;\r
+               };\r
+\r
+               function collect(n) {\r
+                       if (dom.is(n, ed.getParam('removeformat_selector')))\r
+                               nodes.push(n);\r
+               };\r
+\r
+               function walk(n) {\r
+                       collect(n);\r
+                       tinymce.walk(n, collect, 'childNodes');\r
+               };\r
+\r
+               bm = s.getBookmark();\r
+               sc = r.startContainer;\r
+               ec = r.endContainer;\r
+               so = r.startOffset;\r
+               eo = r.endOffset;\r
+               sc = sc.nodeType == 1 ? sc.childNodes[Math.min(so, sc.childNodes.length - 1)] : sc;\r
+               ec = ec.nodeType == 1 ? ec.childNodes[Math.min(so == eo ? eo : eo - 1, ec.childNodes.length - 1)] : ec;\r
+\r
+               // Same container\r
+               if (sc == ec) { // TEXT_NODE\r
+                       start = findFormatRoot(sc);\r
+\r
+                       // Handle single text node\r
+                       if (sc.nodeType == 3) {\r
+                               if (start && start.nodeType == 1) { // ELEMENT\r
+                                       n = sc.splitText(so);\r
+                                       n.splitText(eo - so);\r
+                                       dom.split(start, n);\r
+\r
+                                       s.moveToBookmark(bm);\r
+                               }\r
+\r
+                               return;\r
+                       }\r
+\r
+                       // Handle single element\r
+                       walk(dom.split(start, sc) || sc);\r
+               } else {\r
+                       // Find start/end format root\r
+                       start = findFormatRoot(sc);\r
+                       end = findFormatRoot(ec);\r
+\r
+                       // Split start text node\r
+                       if (start) {\r
+                               if (sc.nodeType == 3) { // TEXT\r
+                                       // Since IE doesn't support white space nodes in the DOM we need to\r
+                                       // add this invisible character so that the splitText function can split the contents\r
+                                       if (so == sc.nodeValue.length)\r
+                                               sc.nodeValue += '\uFEFF'; // Yet another pesky IE fix\r
+\r
+                                       sc = sc.splitText(so);\r
+                               }\r
+                       }\r
+\r
+                       // Split end text node\r
+                       if (end) {\r
+                               if (ec.nodeType == 3) // TEXT\r
+                                       ec.splitText(eo);\r
+                       }\r
+\r
+                       // If the start and end format root is the same then we need to wrap\r
+                       // the end node in a span since the split calls might change the reference\r
+                       // Example: <p><b><em>x[yz<span>---</span>12]3</em></b></p>\r
+                       if (start && start == end)\r
+                               dom.replace(dom.create('span', {id : '__end'}, ec.cloneNode(true)), ec);\r
+\r
+                       // Split all start containers down to the format root\r
+                       if (start)\r
+                               start = dom.split(start, sc);\r
+                       else\r
+                               start = sc;\r
+\r
+                       // If there is a span wrapper use that one instead\r
+                       if (n = dom.get('__end')) {\r
+                               ec = n;\r
+                               end = findFormatRoot(ec);\r
+                       }\r
+\r
+                       // Split all end containers down to the format root\r
+                       if (end)\r
+                               end = dom.split(end, ec);\r
+                       else\r
+                               end = ec;\r
+\r
+                       // Collect nodes in between\r
+                       processRange(dom, start, end, collect);\r
+\r
+                       // Remove invisible character for IE workaround if we find it\r
+                       if (sc.nodeValue == '\uFEFF')\r
+                               sc.nodeValue = '';\r
+\r
+                       // Process start/end container elements\r
+                       walk(ec);\r
+                       walk(sc);\r
+               }\r
+\r
+               // Remove all collected nodes\r
+               tinymce.each(nodes, function(n) {\r
+                       dom.remove(n, 1);\r
+               });\r
+\r
+               // Remove leftover wrapper\r
+               dom.remove('__end', 1);\r
+\r
+               s.moveToBookmark(bm);\r
+       });\r
+})(tinymce);\r
+(function(tinymce) {\r
+       tinymce.GlobalCommands.add('mceBlockQuote', function() {\r
+               var ed = this, s = ed.selection, dom = ed.dom, sb, eb, n, bm, bq, r, bq2, i, nl;\r
+\r
+               function getBQ(e) {\r
+                       return dom.getParent(e, function(n) {return n.nodeName === 'BLOCKQUOTE';});\r
+               };\r
+\r
+               // Get start/end block\r
+               sb = dom.getParent(s.getStart(), dom.isBlock);\r
+               eb = dom.getParent(s.getEnd(), dom.isBlock);\r
+\r
+               // Remove blockquote(s)\r
+               if (bq = getBQ(sb)) {\r
+                       if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
+                               bm = s.getBookmark();\r
+\r
+                       // Move all elements after the end block into new bq\r
+                       if (getBQ(eb)) {\r
+                               bq2 = bq.cloneNode(false);\r
+\r
+                               while (n = eb.nextSibling)\r
+                                       bq2.appendChild(n.parentNode.removeChild(n));\r
+                       }\r
+\r
+                       // Add new bq after\r
+                       if (bq2)\r
+                               dom.insertAfter(bq2, bq);\r
+\r
+                       // Move all selected blocks after the current bq\r
+                       nl = s.getSelectedBlocks(sb, eb);\r
+                       for (i = nl.length - 1; i >= 0; i--) {\r
+                               dom.insertAfter(nl[i], bq);\r
+                       }\r
+\r
+                       // Empty bq, then remove it\r
+                       if (/^\s*$/.test(bq.innerHTML))\r
+                               dom.remove(bq, 1); // Keep children so boomark restoration works correctly\r
+\r
+                       // Empty bq, then remote it\r
+                       if (bq2 && /^\s*$/.test(bq2.innerHTML))\r
+                               dom.remove(bq2, 1); // Keep children so boomark restoration works correctly\r
+\r
+                       if (!bm) {\r
+                               // Move caret inside empty block element\r
+                               if (!tinymce.isIE) {\r
+                                       r = ed.getDoc().createRange();\r
+                                       r.setStart(sb, 0);\r
+                                       r.setEnd(sb, 0);\r
+                                       s.setRng(r);\r
+                               } else {\r
+                                       s.select(sb);\r
+                                       s.collapse(0);\r
+\r
+                                       // IE misses the empty block some times element so we must move back the caret\r
+                                       if (dom.getParent(s.getStart(), dom.isBlock) != sb) {\r
+                                               r = s.getRng();\r
+                                               r.move('character', -1);\r
+                                               r.select();\r
+                                       }\r
+                               }\r
+                       } else\r
+                               ed.selection.moveToBookmark(bm);\r
+\r
+                       return;\r
+               }\r
+\r
+               // Since IE can start with a totally empty document we need to add the first bq and paragraph\r
+               if (tinymce.isIE && !sb && !eb) {\r
+                       ed.getDoc().execCommand('Indent');\r
+                       n = getBQ(s.getNode());\r
+                       n.style.margin = n.dir = ''; // IE adds margin and dir to bq\r
+                       return;\r
+               }\r
+\r
+               if (!sb || !eb)\r
+                       return;\r
+\r
+               // If empty paragraph node then do not use bookmark\r
+               if (sb != eb || sb.childNodes.length > 1 || (sb.childNodes.length == 1 && sb.firstChild.nodeName != 'BR'))\r
+                       bm = s.getBookmark();\r
+\r
+               // Move selected block elements into a bq\r
+               tinymce.each(s.getSelectedBlocks(getBQ(s.getStart()), getBQ(s.getEnd())), function(e) {\r
+                       // Found existing BQ add to this one\r
+                       if (e.nodeName == 'BLOCKQUOTE' && !bq) {\r
+                               bq = e;\r
+                               return;\r
+                       }\r
+\r
+                       // No BQ found, create one\r
+                       if (!bq) {\r
+                               bq = dom.create('blockquote');\r
+                               e.parentNode.insertBefore(bq, e);\r
+                       }\r
+\r
+                       // Add children from existing BQ\r
+                       if (e.nodeName == 'BLOCKQUOTE' && bq) {\r
+                               n = e.firstChild;\r
+\r
+                               while (n) {\r
+                                       bq.appendChild(n.cloneNode(true));\r
+                                       n = n.nextSibling;\r
+                               }\r
+\r
+                               dom.remove(e);\r
+                               return;\r
+                       }\r
+\r
+                       // Add non BQ element to BQ\r
+                       bq.appendChild(dom.remove(e));\r
+               });\r
+\r
+               if (!bm) {\r
+                       // Move caret inside empty block element\r
+                       if (!tinymce.isIE) {\r
+                               r = ed.getDoc().createRange();\r
+                               r.setStart(sb, 0);\r
+                               r.setEnd(sb, 0);\r
+                               s.setRng(r);\r
+                       } else {\r
+                               s.select(sb);\r
+                               s.collapse(1);\r
+                       }\r
+               } else\r
+                       s.moveToBookmark(bm);\r
+       });\r
+})(tinymce);\r
+(function(tinymce) {\r
+       tinymce.each(['Cut', 'Copy', 'Paste'], function(cmd) {\r
+               tinymce.GlobalCommands.add(cmd, function() {\r
+                       var ed = this, doc = ed.getDoc();\r
+\r
+                       try {\r
+                               doc.execCommand(cmd, false, null);\r
+\r
+                               // On WebKit the command will just be ignored if it's not enabled\r
+                               if (!doc.queryCommandSupported(cmd))\r
+                                       throw 'Error';\r
+                       } catch (ex) {\r
+                               ed.windowManager.alert(ed.getLang('clipboard_no_support'));\r
+                       }\r
+               });\r
+       });\r
+})(tinymce);\r
+(function(tinymce) {\r
+       tinymce.GlobalCommands.add('InsertHorizontalRule', function() {\r
+               if (tinymce.isOpera)\r
+                       return this.getDoc().execCommand('InsertHorizontalRule', false, '');\r
+\r
+               this.selection.setContent('<hr />');\r
+       });\r
+})(tinymce);\r
+(function() {\r
+       var cmds = tinymce.GlobalCommands;\r
+\r
+       cmds.add(['mceEndUndoLevel', 'mceAddUndoLevel'], function() {\r
+               this.undoManager.add();\r
+       });\r
+\r
+       cmds.add('Undo', function() {\r
+               var ed = this;\r
+\r
+               if (ed.settings.custom_undo_redo) {\r
+                       ed.undoManager.undo();\r
+                       ed.nodeChanged();\r
+                       return true;\r
+               }\r
+\r
+               return false; // Run browser command\r
+       });\r
+\r
+       cmds.add('Redo', function() {\r
+               var ed = this;\r
+\r
+               if (ed.settings.custom_undo_redo) {\r
+                       ed.undoManager.redo();\r
+                       ed.nodeChanged();\r
+                       return true;\r
+               }\r
+\r
+               return false; // Run browser command\r
+       });\r
+})();\r
index c1f14090473feaf7bfb85a0b8650e9d789d36be1..dd45e730de2c72c5af2278f1ed117b327c5f1755 100644 (file)
@@ -1,5 +1,5 @@
 /**\r
- * $Id: form_utils.js 673 2008-03-06 13:26:20Z spocke $\r
+ * $Id: form_utils.js 996 2009-02-06 17:32:20Z spocke $\r
  *\r
  * Various form utilitiy functions.\r
  *\r
@@ -13,7 +13,7 @@ function getColorPickerHTML(id, target_form_element) {
        var h = "";\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') + '"></span></a>';\r
+       h += '<span id="' + id + '" title="' + tinyMCEPopup.getLang('browse') + '">&nbsp;</span></a>';\r
 \r
        return h;\r
 }\r
@@ -50,7 +50,7 @@ function getBrowserHTML(id, target_form_element, type, prefix) {
 \r
        html = "";\r
        html += '<a id="' + id + '_link" href="javascript:openBrowser(\'' + id + '\',\'' + target_form_element + '\', \'' + type + '\',\'' + option + '\');" onmousedown="return false;" class="browse">';\r
-       html += '<span id="' + id + '" title="' + tinyMCEPopup.getLang('browse') + '"></span></a>';\r
+       html += '<span id="' + id + '" title="' + tinyMCEPopup.getLang('browse') + '">&nbsp;</span></a>';\r
 \r
        return html;\r
 }\r
index 2435a8233dbec3b67b8307ea0e04e71e0e4fcbcd..e3abd8c4fa186d623af7025907159761331e7564 100644 (file)
@@ -45,7 +45,7 @@ function enriched_convert_formatting($body){
                        '</indentright>'=>'</span>');
        
        while(list($find,$replace)=each($a)){
-               $body = eregi_replace($find,$replace,$body);
+               $body = preg_replace('#'.$find.'#i', $replace, $body);
        }
        return $body;
 }
diff --git a/program/lib/icl_commons.inc b/program/lib/icl_commons.inc
deleted file mode 100644 (file)
index 5992051..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-function mod_b64_decode($data){
-       return base64_decode(str_replace(",","/",$data));
-}
-
-function mod_b64_encode($data){
-       return str_replace("/",",",str_replace("=","",base64_encode($data)));
-}
-
-
-function utf8_to_html($str){
-       $len = strlen($str);
-       $out = "";
-       for($i=0;$i<$len;$i+=2){
-               $val = ord($str[$i]);
-               $next_val = ord($str[$i+1]);
-               if ($val<255){
-                       $out.="&#".($val*256+$next_val).";";
-               }else{
-                       $out.=$str[$i].$str[$i+1];
-               }
-       }
-       return $out;
-}
-
-function iil_utf7_decode($str, $raw=false){
-       if (strpos($str, '&')===false) return $str;
-       
-       $len = strlen($str);
-       $in_b64 = false;
-       $b64_data = "";
-       $out = "";
-       for ($i=0;$i<$len;$i++){
-               $char = $str[$i];
-               if ($char=='&') $in_b64 = true;
-               else if ($in_b64 && $char=='-'){
-                       $in_b64 = false;
-                       if ($b64_data=="") $out.="&";
-                       else{
-                               $dec=mod_b64_decode($b64_data);
-                               $out.=($raw?$dec:utf8_to_html($dec));
-                               $b64_data = "";
-                       }
-               }else if ($in_b64) $b64_data.=$char;
-               else $out.=$char;
-       }
-       return $out;
-}
-
-function iil_utf7_encode($str){
-       if (!ereg("[\200-\237]",$str) && !ereg("[\241-\377]",$str))
-        return $str;
-
-       $len = strlen($str);
-
-       for ($i=0;$i<$len;$i++){
-               $val = ord($str[$i]);
-               if ($val>=224 && $val<=239){
-                       $unicode = ($val-224) * 4096 + (ord($str[$i+1])-128) * 64 + (ord($str[$i+2])-128);
-                       $i+=2;
-                       $utf_code.=chr((int)($unicode/256)).chr($unicode%256);
-               }else if ($val>=192 && $val<=223){
-                       $unicode = ($val-192) * 64 + (ord($str[$i+1])-128);
-                       $i++;
-                       $utf_code.=chr((int)($unicode/256)).chr($unicode%256);
-               }else{
-                       if ($utf_code){
-                               $out.='&'.mod_b64_encode($utf_code).'-';
-                               $utf_code="";
-                       }
-                       if ($str[$i]=="-") $out.="&";
-                       $out.=$str[$i];
-               }
-       }
-       if ($utf_code)
-               $out.='&'.mod_b64_encode($utf_code).'-';
-       return $out;
-}
-
-
-?>
\ No newline at end of file
index 995d82fb61240d8359cee1ef5255425b3de6f9bb..e6b3ce1710fdb50d101344886fbccd9fda78070c 100644 (file)
                - include BODYSTRUCTURE in iil_C_FetchHeaders()
                - added iil_C_FetchMIMEHeaders() function
                - added \* flag support 
+               - use PREG instead of EREG
+               - removed caching functions
+               - handling connection startup response
+               - added UID EXPUNGE support
+               - fixed problem with double quotes and spaces in folder names in LIST and LSUB 
+               - rewritten iil_C_FetchHeaderIndex()
 
 ********************************************************/
 
  * @todo Replace echo-debugging (make it adhere to config setting and log)
  */
 
-// changed path to work within roundcube webmail
-include_once 'lib/icl_commons.inc';
-
 
 if (!isset($IMAP_USE_HEADER_DATE) || !$IMAP_USE_HEADER_DATE) {
     $IMAP_USE_INTERNAL_DATE = true;
 }
 
-/**
- * @todo Maybe use date() to generate this.
- */
-$GLOBALS['IMAP_MONTHS'] = array("Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4,
-    "May" => 5, "Jun" => 6, "Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10,
-    "Nov" => 11, "Dec" => 12);
-
-$GLOBALS['IMAP_SERVER_TZ'] = date('Z');
-
 $GLOBALS['IMAP_FLAGS'] = array(
     'SEEN'     => '\\Seen',
     'DELETED'  => '\\Deleted',
@@ -134,9 +128,6 @@ class iilConnection
        var $selected;
        var $message;
        var $host;
-       var $cache;
-       var $uid_cache;
-       var $do_cache;
        var $exists;
        var $recent;
        var $rootdir;
@@ -182,6 +173,7 @@ class iilBasicHeader
        var $forwarded = false;
        var $junk = false;
        var $flagged = false;
+       var $others = array();
 }
 
 /**
@@ -205,7 +197,11 @@ function iil_xor($string, $string2) {
 }
 
 function iil_PutLine($fp, $string, $endln=true) {
-//      console('C: '. rtrim($string));
+       global $my_prefs;
+       
+       if (!empty($my_prefs['debug_mode']))
+               write_log('imap', 'C: '. rtrim($string));
+       
         return fputs($fp, $string . ($endln ? "\r\n" : ''));
 }
 
@@ -232,7 +228,9 @@ function iil_PutLineC($fp, $string, $endln=true) {
        return $res;
 }
 
-function iil_ReadLine($fp, $size) {
+function iil_ReadLine($fp, $size=1024) {
+       global $my_prefs;
+       
        $line = '';
 
        if (!$fp) {
@@ -245,19 +243,21 @@ function iil_ReadLine($fp, $size) {
     
        do {
                $buffer = fgets($fp, $size);
+
                if ($buffer === false) {
                        break;
                }
-//             console('S: '. chop($buffer));
+               if (!empty($my_prefs['debug_mode']))
+                       write_log('imap', 'S: '. chop($buffer));
                $line .= $buffer;
        } while ($buffer[strlen($buffer)-1] != "\n");
-       
+
        return $line;
 }
 
-function iil_MultLine($fp, $line) {
+function iil_MultLine($fp, $line, $escape=false) {
        $line = chop($line);
-       if (ereg('\{[0-9]+\}$', $line)) {
+       if (preg_match('/\{[0-9]+\}$/', $line)) {
                $out = '';
         
                preg_match_all('/(.*)\{([0-9]+)\}$/', $line, $a);
@@ -266,37 +266,43 @@ function iil_MultLine($fp, $line) {
                        $line = iil_ReadBytes($fp, $bytes); 
                        $out .= $line;
                }
-               $line = $a[1][0] . "\"$out\"";
-//             console('[...] '. $out);
+
+               $line = $a[1][0] . '"' . ($escape ? iil_Escape($out) : $out) . '"';
        }
        return $line;
 }
 
 function iil_ReadBytes($fp, $bytes) {
+       global $my_prefs;
        $data = '';
        $len  = 0;
        do {
-               $data .= fread($fp, $bytes-$len);
-               if ($len == strlen($data)) {
+               $d = fread($fp, $bytes-$len);
+               if (!empty($my_prefs['debug_mode']))
+                       write_log('imap', 'S: '. $d);
+                $data .= $d;
+               $data_len = strlen($data);
+               if ($len == $data_len) {
                        break; //nothing was read -> exit to avoid apache lockups
                }
-               $len = strlen($data);
+               $len = $data_len;
        } while ($len < $bytes);
        
        return $data;
 }
 
+// don't use it in loops, until you exactly know what you're doing
 function iil_ReadReply($fp) {
        do {
                $line = trim(iil_ReadLine($fp, 1024));
        } while ($line[0] == '*');
-       
+
        return $line;
 }
 
 function iil_ParseResult($string) {
-       $a = explode(' ', $string);
-       if (count($a) > 2) {
+       $a = explode(' ', trim($string));
+       if (count($a) >= 2) {
                if (strcasecmp($a[1], 'OK') == 0) {
                        return 0;
                } else if (strcasecmp($a[1], 'NO') == 0) {
@@ -305,7 +311,7 @@ function iil_ParseResult($string) {
                        return -2;
                } else if (strcasecmp($a[1], 'BYE') == 0) {
                        return -3;
-               }
+               }
        }
        return -4;
 }
@@ -319,13 +325,13 @@ function iil_StartsWith($string, $match, $error=false) {
        if (strncmp($string, $match, $len) == 0) {
                return true;
        }
-       if ($error && preg_match('/^\* (BYE|BAD) /', $string)) {
+       if ($error && preg_match('/^\* (BYE|BAD) /i', $string)) {
                return true;
        }
        return false;
 }
 
-function iil_StartsWithI($string, $match, $bye=false) {
+function iil_StartsWithI($string, $match, $error=false) {
        $len = strlen($match);
        if ($len == 0) {
                return false;
@@ -333,7 +339,7 @@ function iil_StartsWithI($string, $match, $bye=false) {
        if (strncasecmp($string, $match, $len) == 0) {
                return true;
        }
-       if ($bye && strncmp($string, '* BYE ', 6) == 0) {
+       if ($error && preg_match('/^\* (BYE|BAD) /i', $string)) {
                return true;
 
        }
@@ -438,13 +444,8 @@ function iil_C_Login(&$conn, $user, $password) {
 
     iil_PutLine($conn->fp, 'a001 LOGIN "'.iil_Escape($user).'" "'.iil_Escape($password).'"');
 
-    do {
-        $line = iil_ReadReply($conn->fp);
-        if ($line === false) {
-            break;
-        }
-    } while (!iil_StartsWith($line, 'a001 ', true));
-    
+    $line = iil_ReadReply($conn->fp);
+
     // process result
     $result = iil_ParseResult($line);
 
@@ -545,7 +546,6 @@ function iil_C_NameSpace(&$conn) {
 function iil_Connect($host, $user, $password, $options=null) { 
        global $iil_error, $iil_errornum;
        global $ICL_SSL, $ICL_PORT;
-       global $IMAP_NO_CACHE;
        global $my_prefs, $IMAP_USE_INTERNAL_DATE;
        
        $iil_error = '';
@@ -560,6 +560,8 @@ function iil_Connect($host, $user, $password, $options=null) {
                                $my_prefs['rootdir'] = $optval;
                        } else if ($optkey == 'delimiter') {
                                $my_prefs['delimiter'] = $optval;
+                       } else if ($optkey == 'debug_mode') {
+                               $my_prefs['debug_mode'] = $optval;
                        }
                }
        }
@@ -578,16 +580,12 @@ function iil_Connect($host, $user, $password, $options=null) {
        $conn->selected    = '';
        $conn->user        = $user;
        $conn->host        = $host;
-       $conn->cache       = array();
-       $conn->do_cache    = (function_exists("cache_write")&&!$IMAP_NO_CACHE);
-       $conn->cache_dirty = array();
        
        if ($my_prefs['sort_field'] == 'INTERNALDATE') {
                $IMAP_USE_INTERNAL_DATE = true;
        } else if ($my_prefs['sort_field'] == 'DATE') {
                $IMAP_USE_INTERNAL_DATE = false;
        }
-       //echo '<!-- conn sort_field: '.$my_prefs['sort_field'].' //-->';
        
        //check input
        if (empty($host)) {
@@ -621,8 +619,21 @@ function iil_Connect($host, $user, $password, $options=null) {
                return false;
        }
 
-       $iil_error .= "Socket connection established\r\n";
-       $line       = iil_ReadLine($conn->fp, 4096);
+       stream_set_timeout($conn->fp, 10);
+       $line = stream_get_line($conn->fp, 8192, "\r\n");
+
+       if ($my_prefs['debug_mode'] && $line)
+               write_log('imap', 'S: '. $line);
+
+       // Connected to wrong port or connection error?
+       if (!preg_match('/^\* (OK|PREAUTH)/i', $line)) {
+               if ($line)
+                       $iil_error = "Wrong startup greeting ($host:$ICL_PORT): $line";
+               else
+                       $iil_error = "Empty startup greeting ($host:$ICL_PORT)";
+               $iil_errornum = -2;
+               return false;
+       }
 
        // RFC3501 [7.1] optional CAPABILITY response
        if (preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)) {
@@ -712,7 +723,6 @@ function iil_Connect($host, $user, $password, $options=null) {
 }
 
 function iil_Close(&$conn) {
-       iil_C_WriteCache($conn);
        if (iil_PutLine($conn->fp, "I LOGOUT")) {
                fgets($conn->fp, 1024);
                fclose($conn->fp);
@@ -720,100 +730,21 @@ function iil_Close(&$conn) {
        }
 }
 
-function iil_ClearCache($user, $host) {
-}
-
-function iil_C_WriteCache(&$conn) {
-       //echo "<!-- doing iil_C_WriteCache //-->\n";
-       if (!$conn->do_cache) return false;
-       
-       if (is_array($conn->cache)) {
-               while (list($folder,$data)=each($conn->cache)) {
-                       if ($folder && is_array($data) && $conn->cache_dirty[$folder]) {
-                               $key = $folder.".imap";
-                               $result = cache_write($conn->user, $conn->host, $key, $data, true);
-                               //echo "<!-- writing $key $data: $result //-->\n";
-                       }
-               }
-       }
-}
-
-function iil_C_EnableCache(&$conn) {
-       $conn->do_cache = true;
-}
-
-function iil_C_DisableCache(&$conn) {
-       $conn->do_cache = false;
-}
-
-function iil_C_LoadCache(&$conn, $folder) {
-       if (!$conn->do_cache) {
-           return false;
-       }
-    
-       $key = $folder.'.imap';
-       if (!is_array($conn->cache[$folder])) {
-               $conn->cache[$folder]       = cache_read($conn->user, $conn->host, $key);
-               $conn->cache_dirty[$folder] = false;
-       }
-}
-
-function iil_C_ExpireCachedItems(&$conn, $folder, $message_set) {
-       
-       if (!$conn->do_cache) {
-               return; //caching disabled
-       }
-       if (!is_array($conn->cache[$folder])) {
-               return; //cache not initialized|empty
-       }
-       if (count($conn->cache[$folder]) == 0) {
-               return; //cache not initialized|empty
-       }
-    
-       $uids = iil_C_FetchHeaderIndex($conn, $folder, $message_set, 'UID');
-       $num_removed = 0;
-       if (is_array($uids)) {
-               //echo "<!-- unsetting: ".implode(",",$uids)." //-->\n";
-               while (list($n,$uid)=each($uids)) {
-                       unset($conn->cache[$folder][$uid]);
-                       //$conn->cache[$folder][$uid] = false;
-                       //$num_removed++;
+function iil_ExplodeQuotedString($delimiter, $string) {
+       $result = array();
+       $strlen = strlen($string);
+         
+       for ($q=$p=$i=0; $i < $strlen; $i++) {
+               if ($string[$i] == "\"" && $string[$i-1] != "\\") {
+                       $q = $q ? false : true;
                }
-               $conn->cache_dirty[$folder] = true;
-
-               //echo '<!--'."\n";
-               //print_r($conn->cache);
-               //echo "\n".'//-->'."\n";
-       } else {
-               echo "<!-- failed to get uids: $message_set //-->\n";
-       }
-       
-       /*
-       if ($num_removed>0) {
-               $new_cache;
-               reset($conn->cache[$folder]);
-               while (list($uid,$item)=each($conn->cache[$folder])) {
-                       if ($item) $new_cache[$uid] = $conn->cache[$folder][$uid];
+               else if (!$q && preg_match("/$delimiter/", $string[$i])) {
+                       $result[] = substr($string, $p, $i - $p);
+                       $p = $i + 1;
                }
-               $conn->cache[$folder] = $new_cache;
        }
-       */
-}
 
-function iil_ExplodeQuotedString($delimiter, $string) {
-       $quotes = explode('"', $string);
-       while ( list($key, $val) = each($quotes)) {
-               if (($key % 2) == 1) {
-                       $quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]);
-               }
-       }
-       $string = implode('"', $quotes);
-       
-       $result = explode($delimiter, $string);
-       while ( list($key, $val) = each($result) ) {
-               $result[$key] = str_replace('_!@!_', $delimiter, $result[$key]);
-       }
-    
+       $result[] = substr($string, $p);
        return $result;
 }
 
@@ -852,8 +783,6 @@ function iil_C_Select(&$conn, $mailbox) {
                return true;
        }
     
-       iil_C_LoadCache($conn, $mailbox);
-       
        if (iil_PutLine($conn->fp, "sel1 SELECT \"".iil_Escape($mailbox).'"')) {
                do {
                        $line = chop(iil_ReadLine($conn->fp, 300));
@@ -862,7 +791,7 @@ function iil_C_Select(&$conn, $mailbox) {
                                if (strcasecmp($a[2], 'EXISTS') == 0) {
                                        $conn->exists = (int) $a[1];
                                }
-                               if (strcasecmp($a[2], 'RECENT') == 0) {
+                               else if (strcasecmp($a[2], 'RECENT') == 0) {
                                        $conn->recent = (int) $a[1];
                                }
                        }
@@ -915,46 +844,23 @@ function iil_SplitHeaderLine($string) {
        return $string;
 }
 
-function iil_StrToTime($str) {
-       $IMAP_MONTHS    = $GLOBALS['IMAP_MONTHS'];
-       $IMAP_SERVER_TZ = $GLOBALS['IMAP_SERVER_TZ'];
-               
-       if ($str) {
-           $time1 = strtotime($str);
-       }
-       if ($time1 && $time1 != -1) {
-           return $time1-$IMAP_SERVER_TZ;
-       }
-       //echo '<!--'.$str.'//-->';
-       
-       //replace double spaces with single space
-       $str = trim($str);
-       $str = str_replace('  ', ' ', $str);
-       
-       //strip off day of week
-       $pos = strpos($str, ' ');
-       if (!is_numeric(substr($str, 0, $pos))) {
-           $str = substr($str, $pos+1);
+function iil_StrToTime($date) {
+
+       // 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))
+       {
+               $d = explode(' ', $date);
+               array_pop($d);
+               if (!$d) break;
+               $date = implode(' ', $d);
        }
-       //explode, take good parts
-       $a = explode(' ', $str);
 
-       $month_str = $a[1];
-       $month     = $IMAP_MONTHS[$month_str];
-       $day       = (int)$a[0];
-       $year      = (int)$a[2];
-       $time      = $a[3];
-       $tz_str    = $a[4];
-       $tz        = substr($tz_str, 0, 3);
-       $ta        = explode(':', $time);
-       $hour      = (int)$ta[0]-(int)$tz;
-       $minute    = (int)$ta[1];
-       $second    = (int)$ta[2];
-       
-       //make UNIX timestamp
-       $time2 = mktime($hour, $minute, $second, $month, $day, $year);
-       //echo '<!--'.$time1.' '.$time2.' //-->'."\n";
-       return $time2;
+       $ts = (int) $ts;
+
+       return $ts < 0 ? 0 : $ts;       
 }
 
 function iil_C_Sort(&$conn, $mailbox, $field, $add='', $is_uid=FALSE,
@@ -986,14 +892,14 @@ function iil_C_Sort(&$conn, $mailbox, $field, $add='', $is_uid=FALSE,
        $command  = 's ' . $is_uid . 'SORT (' . $field . ') ';
        $command .= $encoding . ' ALL' . $add;
        $line     = $data = '';
-       
+
        if (!iil_PutLineC($conn->fp, $command)) {
            return false;
        }
        do {
-               $line = chop(iil_ReadLine($conn->fp, 1024));
+               $line = chop(iil_ReadLine($conn->fp));
                if (iil_StartsWith($line, '* SORT')) {
-                       $data .= ($data ? ' ' : '') . substr($line, 7);
+                       $data .= substr($line, 7);
                } else if (preg_match('/^[0-9 ]+$/', $line)) {
                        $data .= $line;
                }
@@ -1006,32 +912,21 @@ function iil_C_Sort(&$conn, $mailbox, $field, $add='', $is_uid=FALSE,
                 return false;
        }
        
-       $out = explode(' ',$data);
-       return $out;
+       return preg_split('/\s+/', $data, -1, PREG_SPLIT_NO_EMPTY);
 }
 
-function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field,
-    $normalize=true) {
-       global $IMAP_USE_INTERNAL_DATE;
-       
-       $c=0;
-       $result=array();
-       $fp = $conn->fp;
-               
-       if (empty($index_field)) {
-           $index_field = 'DATE';
-       }
-       $index_field = strtoupper($index_field);
-       
+function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field='', $skip_deleted=true) {
+
        list($from_idx, $to_idx) = explode(':', $message_set);
-       if (empty($message_set) || (isset($to_idx)
-           && (int)$from_idx > (int)$to_idx)) {
+       if (empty($message_set) ||
+               (isset($to_idx) && $to_idx != '*' && (int)$from_idx > (int)$to_idx)) {
                return false;
        }
+
+       $index_field = empty($index_field) ? 'DATE' : strtoupper($index_field);
        
-       //$fields_a['DATE'] = ($IMAP_USE_INTERNAL_DATE?6:1);
        $fields_a['DATE']         = 1;
-       $fields_a['INTERNALDATE'] = 6;
+       $fields_a['INTERNALDATE'] = 4;
        $fields_a['FROM']         = 1;
        $fields_a['REPLY-TO']     = 1;
        $fields_a['SENDER']       = 1;
@@ -1040,178 +935,107 @@ function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field,
        $fields_a['UID']          = 2;
        $fields_a['SIZE']         = 2;
        $fields_a['SEEN']         = 3;
-       $fields_a['RECENT']       = 4;
-       $fields_a['DELETED']      = 5;
-       
-       $mode=$fields_a[$index_field];
-       if (!($mode > 0)) {
-           return false;
+       $fields_a['RECENT']       = 3;
+       $fields_a['DELETED']      = 3;
+
+       if (!($mode = $fields_a[$index_field])) {
+               return false;
        }
-    
+
        /*  Do "SELECT" command */
        if (!iil_C_Select($conn, $mailbox)) {
-           return false;
+               return false;
        }
-    
-       /* FETCH date,from,subject headers */
-       if ($mode == 1) {
-               $key     = 'fhi' . ($c++);
-               $request = $key . " FETCH $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)])";
-               if (!iil_PutLine($fp, $request)) {
-                   return false;
-               }
-               do {
-                       
-                       $line=chop(iil_ReadLine($fp, 200));
-                       $a=explode(' ', $line);
-                       if (($line[0] == '*') && ($a[2] == 'FETCH')
-                           && ($line[strlen($line)-1] != ')')) {
-                               $id=$a[1];
+       
+       // build FETCH command string
+       $key     = 'fhi0';
+       $deleted = $skip_deleted ? ' FLAGS' : '';
 
-                               $str=$line=chop(iil_ReadLine($fp, 300));
+       if ($mode == 1)
+               $request = " FETCH $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)]$deleted)";
+       else if ($mode == 2) {
+               if ($index_field == 'SIZE')
+                       $request = " FETCH $message_set (RFC822.SIZE$deleted)";
+               else
+                       $request = " FETCH $message_set ($index_field$deleted)";
+       } else if ($mode == 3)
+               $request = " FETCH $message_set (FLAGS)";
+       else // 4
+               $request = " FETCH $message_set (INTERNALDATE$deleted)";
 
-                               while ($line[0] != ')') {                                       //caution, this line works only in this particular case
-                                       $line=chop(iil_ReadLine($fp, 300));
-                                       if ($line[0] != ')') {
-                                               if (ord($line[0]) <= 32) {                      //continuation from previous header line
-                                                       $str.= ' ' . trim($line);
-                                               }
-                                               if ((ord($line[0]) > 32) || (strlen($line[0]) == 0)) {
-                                                       list($field, $string) = iil_SplitHeaderLine($str);
-                                                       if (strcasecmp($field, 'date') == 0) {
-                                                               $result[$id] = iil_StrToTime($string);
-                                                       } else {
-                                                               $result[$id] = str_replace('"', '', $string);
-                                                               if ($normalize) {
-                                                                   $result[$id] = strtoupper($result[$id]);
-                                                               }
-                                                       }
-                                                       $str=$line;
-                                               }
-                                       }
-                               }
-                       }
-                       /*
-                       $end_pos = strlen($line)-1;
-                       if (($line[0]=="*") && ($a[2]=="FETCH") && ($line[$end_pos]=="}")) {
-                               $id = $a[1];
-                               $pos = strrpos($line, "{")+1;
-                               $bytes = (int)substr($line, $pos, $end_pos-$pos);
-                               $received = 0;
-                               do {
-                                       $line      = iil_ReadLine($fp, 0);
-                                       $received += strlen($line);
-                                       $line      = chop($line);
-                                       
-                                       if ($received>$bytes) {
-                                               break;
-                                       } else if (!$line) {
-                                               continue;
-                                       }
+       $request = $key . $request;
 
-                                       list($field, $string) = explode(': ', $line);
-                                       
-                                       if (strcasecmp($field, 'date') == 0) {
-                                               $result[$id] = iil_StrToTime($string);
-                                       } else if ($index_field != 'DATE') {
-                                               $result[$id]=strtoupper(str_replace('"', '', $string));
-                                       }
-                               } while ($line[0] != ')');
-                       } else {
-                               //one line response, not expected so ignore                             
-                       }
-                       */
-               } while (!iil_StartsWith($line, $key, true));
+       if (!iil_PutLine($conn->fp, $request))
+               return false;
 
-       }else if ($mode == 6) {
+       $result = array();
 
-               $key     = 'fhi' . ($c++);
-               $request = $key . " FETCH $message_set (INTERNALDATE)";
-               if (!iil_PutLine($fp, $request)) {
-                   return false;
-               }
-               do {
-                       $line=chop(iil_ReadLine($fp, 200));
-                       if ($line[0] == '*') {
-                               /*
-                                * original:
-                                * "* 10 FETCH (INTERNALDATE "31-Jul-2002 09:18:02 -0500")"
-                                */
-                               $paren_pos = strpos($line, '(');
-                               $foo       = substr($line, 0, $paren_pos);
-                               $a         = explode(' ', $foo);
-                               $id        = $a[1];
-                               
-                               $open_pos  = strpos($line, '"') + 1;
-                               $close_pos = strrpos($line, '"');
-                               if ($open_pos && $close_pos) {
-                                       $len         = $close_pos - $open_pos;
-                                       $time_str    = substr($line, $open_pos, $len);
-                                       $result[$id] = strtotime($time_str);
+       do {
+               $line = chop(iil_ReadLine($conn->fp, 200));
+               $line = iil_MultLine($conn->fp, $line);
+
+               if (preg_match('/^\* ([0-9]+) FETCH/', $line, $m)) {
+
+                       $id = $m[1];
+                       $flags = NULL;
+                                       
+                       if ($skip_deleted && preg_match('/FLAGS \(([^)]+)\)/', $line, $matches)) {
+                               $flags = explode(' ', strtoupper($matches[1]));
+                               if (in_array('\\DELETED', $flags)) {
+                                       $deleted[$id] = $id;
+                                       continue;
                                }
-                       } else {
-                               $a = explode(' ', $line);
                        }
-               } while (!iil_StartsWith($a[0], $key, true));
-       } else {
-               if ($mode >= 3) {
-                   $field_name = 'FLAGS';
-               } else if ($index_field == 'SIZE') {
-                   $field_name = 'RFC822.SIZE';
-               } else {
-                   $field_name = $index_field;
-               }
-        
-               /*                      FETCH uid, size, flags          */
-               $key     = 'fhi' .($c++);
-               $request = $key . " FETCH $message_set ($field_name)";
-
-               if (!iil_PutLine($fp, $request)) {
-                   return false;
-               }
-               do {
-                       $line=chop(iil_ReadLine($fp, 200));
-                       $a = explode(' ', $line);
-                       if (($line[0] == '*') && ($a[2] == 'FETCH')) {
-                               $line = str_replace('(', '', $line);
-                               $line = str_replace(')', '', $line);
-                               $a    = explode(' ', $line);
-                               
-                               $id = $a[1];
 
-                               if (isset($result[$id])) {
-                                   continue; //if we already got the data, skip forward
+                       if ($mode == 1) {
+                               if (preg_match('/BODY\[HEADER\.FIELDS \("?(DATE|FROM|REPLY-TO|SENDER|TO|SUBJECT)"?\)\] (.*)/', $line, $matches)) {
+                                       $value = preg_replace(array('/^"*[a-z]+:/i', '/\s+$/sm'), array('', ''), $matches[2]);
+                                       $value = trim($value);
+                                       if ($index_field == 'DATE') {
+                                               $result[$id] = iil_StrToTime($value);
+                                       } else {
+                                               $result[$id] = $value;
+                                       }
+                               } else {
+                                       $result[$id] = '';
                                }
-                               if ($a[3]!=$field_name) {
-                                       continue;  //make sure it's returning what we requested
+                       } else if ($mode == 2) {
+                               if (preg_match('/\((UID|RFC822\.SIZE) ([0-9]+)/', $line, $matches)) {
+                                       $result[$id] = trim($matches[2]);
+                               } else {
+                                       $result[$id] = 0;
                                }
-                
-                               /*  Caution, bad assumptions, next several lines */
-                               if ($mode == 2) {
-                                   $result[$id] = $a[4];
+                       } else if ($mode == 3) {
+                               if (!$flags && preg_match('/FLAGS \(([^)]+)\)/', $line, $matches)) {
+                                       $flags = explode(' ', $matches[1]);
+                               }
+                               $result[$id] = in_array('\\'.$index_field, $flags) ? 1 : 0;
+                       } else if ($mode == 4) {
+                               if (preg_match('/INTERNALDATE "([^"]+)"/', $line, $matches)) {
+                                       $result[$id] = iil_StrToTime($matches[1]);
                                } else {
-                                       $haystack    = strtoupper($line);
-                                       $result[$id] = (strpos($haystack, $index_field) > 0 ? "F" : "N");
+                                       $result[$id] = 0;
                                }
                        }
-               } while (!iil_StartsWith($line, $key, true));
-       }
+               }
+       } while (!iil_StartsWith($line, $key, true));
 
+/*
        //check number of elements...
-       list($start_mid, $end_mid) = explode(':', $message_set);
-       if (is_numeric($start_mid) && is_numeric($end_mid)) {
+       if (is_numeric($from_idx) && is_numeric($to_idx)) {
                //count how many we should have
-               $should_have = $end_mid - $start_mid +1;
+               $should_have = $to_idx - $from_idx + 1;
                
                //if we have less, try and fill in the "gaps"
                if (count($result) < $should_have) {
-                       for ($i=$start_mid; $i<=$end_mid; $i++) {
+                       for ($i=$from_idx; $i<=$to_idx; $i++) {
                                if (!isset($result[$i])) {
                                        $result[$i] = '';
                                }
                        }
                }
        }
+*/
        return $result; 
 }
 
@@ -1284,50 +1108,7 @@ function iil_C_FetchUIDs(&$conn,$mailbox) {
        }
        $message_set = '1' . ($num>1?':' . $num:'');
        
-       //if cache not enabled, just call iil_C_FetchHeaderIndex on 'UID' field
-       if (!$conn->do_cache)
-               return iil_C_FetchHeaderIndex($conn, $mailbox, $message_set, 'UID');
-
-       //otherwise, let's check cache first
-       $key        = $mailbox.'.uids';
-       $cache_good = true;
-       if ($conn->uid_cache) {
-           $data = $conn->uid_cache;
-       } else {
-           $data = cache_read($conn->user, $conn->host, $key);
-       }
-    
-       //was anything cached at all?
-       if ($data === false) {
-           $cache_good = -1;
-       }
-    
-       //make sure number of messages were the same
-       if ($cache_good > 0 && $data['n'] != $num) {
-           $cache_good = -2;
-       }
-    
-       //if everything's okay so far...
-       if ($cache_good > 0) {
-               //check UIDs of highest mid with current and cached
-               $temp = iil_C_Search($conn, $mailbox, 'UID ' . $data['d'][$num]);
-               if (!$temp || !is_array($temp) || $temp[0] != $num) {
-                   $cache_good = -3;
-               }
-       }
-
-       //if cached data's good, return it
-       if ($cache_good > 0) {
-               return $data['d'];
-       }
-
-       //otherwise, we need to fetch it
-       $data      = array('n' => $num, 'd' => array());
-       $data['d'] = iil_C_FetchHeaderIndex($conn, $mailbox, $message_set, 'UID');
-    
-       cache_write($conn->user, $conn->host, $key, $data);
-       $conn->uid_cache = $data;
-       return $data['d'];
+       return iil_C_FetchHeaderIndex($conn, $mailbox, $message_set, 'UID');
 }
 
 function iil_SortThreadHeaders($headers, $index_a, $uids) {
@@ -1354,30 +1135,7 @@ function iil_C_FetchThreadHeaders(&$conn, $mailbox, $message_set) {
        $uids   = iil_C_FetchUIDs($conn, $mailbox);
        $debug  = false;
        
-       /* Get cached records where possible */
-       if ($conn->do_cache) {
-               $cached = cache_read($conn->user, $conn->host, $mailbox.'.thhd');
-               if ($cached && is_array($uids) && count($uids)>0) {
-                       $needed_set = '';
-                       foreach ($uids as $id=>$uid) {
-                               if ($cached[$uid]) {
-                                       $result[$uid]     = $cached[$uid];
-                                       $result[$uid]->id = $id;
-                               } else {
-                                   $needed_set .= ($needed_set ? ',' : '') . $id;
-                               }
-                       }
-                       if ($needed_set) {
-                           $message_set = $needed_set;
-                       } else {
-                           $message_set = '';
-                       }
-               }
-       }
        $message_set = iil_CompressMessageSet($message_set);
-       if ($debug) {
-           echo "Still need: ".$message_set;
-       }
     
        /* if we're missing any, get them */
        if ($message_set) {
@@ -1395,7 +1153,7 @@ function iil_C_FetchThreadHeaders(&$conn, $mailbox, $message_set) {
                        if ($debug) {
                            echo $line . "\n";
                        }
-                       if (ereg('\{[0-9]+\}$', $line)) {
+                       if (preg_match('/\{[0-9]+\}$/', $line)) {
                                $a       = explode(' ', $line);
                                $new = array();
 
@@ -1413,7 +1171,7 @@ function iil_C_FetchThreadHeaders(&$conn, $mailbox, $message_set) {
 
                                                $new[strtoupper($field_name)] = trim($field_val);
 
-                                       } else if (ereg('^[[:space:]]', $line)) {
+                                       } else if (preg_match('/^\s+/', $line)) {
                                                $new[strtoupper($field_name)] .= trim($line);
                                        }
                                } while ($line[0] != ')');
@@ -1432,13 +1190,6 @@ function iil_C_FetchThreadHeaders(&$conn, $mailbox, $message_set) {
                $result = iil_SortThreadHeaders($result, $index_a, $uids);      
        }
        
-       /* write new set to cache */
-       if ($conn->do_cache) {
-               if (count($result)!=count($cached)) {
-                       cache_write($conn->user, $conn->host, $mailbox . '.thhd', $result);
-               }
-       }
-       
        //echo 'iil_FetchThreadHeaders:'."\n";
        //print_r($result);
        
@@ -1463,7 +1214,7 @@ function iil_C_BuildThreads2(&$conn, $mailbox, $message_set, &$clock) {
        $fp        = $conn->fp;
        $debug     = false;
        
-       $sbj_filter_pat = '[a-zA-Z]{2,3}(\[[0-9]*\])?:([[:space:]]*)';
+       $sbj_filter_pat = '/[a-z]{2,3}(\[[0-9]*\])?:(\s*)/i';
        
        /*  Do "SELECT" command */
        if (!iil_C_Select($conn, $mailbox)) {
@@ -1500,18 +1251,18 @@ function iil_C_BuildThreads2(&$conn, $mailbox, $message_set, &$clock) {
                }
         
                /* if subject contains 'RE:' or has in-reply-to header, it's a reply */
-               $sbj_pre ='';
+               $sbj_pre = '';
                $has_re = false;
-               if (eregi($sbj_filter_pat, $new['SUBJECT'])) {
+               if (preg_match($sbj_filter_pat, $new['SUBJECT'])) {
                    $has_re = true;
                }
-               if ($has_re||$new['IN-REPLY-TO']) {
+               if ($has_re || $new['IN-REPLY-TO']) {
                    $sbj_pre = 'RE:';
                }
         
                /* strip out 're:', 'fw:' etc */
                if ($has_re) {
-                   $sbj = ereg_replace($sbj_filter_pat, '', $new['SUBJECT']);
+                   $sbj = preg_replace($sbj_filter_pat, '', $new['SUBJECT']);
                } else {
                    $sbj = $new['SUBJECT'];
                }
@@ -1661,46 +1412,23 @@ function iil_IndexThreads(&$tree) {
        return $t_index;
 }
 
-function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bodystr=false)
+function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bodystr=false, $add='')
 {
        global $IMAP_USE_INTERNAL_DATE;
        
        $result = array();
        $fp     = $conn->fp;
        
-       list($from_idx, $to_idx) = explode(':', $message_set);
-       if (empty($message_set) || (isset($to_idx)
-               && (int)$from_idx > (int)$to_idx)) {
-               return false;
-       }
-               
        /*  Do "SELECT" command */
        if (!iil_C_Select($conn, $mailbox)) {
                $conn->error = "Couldn't select $mailbox";
                return false;
        }
-               
-       /* Get cached records where possible */
-       if ($conn->do_cache) {
-               $uids = iil_C_FetchHeaderIndex($conn, $mailbox, $message_set, "UID");
-               if (is_array($uids) && count($conn->cache[$mailbox]>0)) {
-                       $needed_set = '';
-                       while (list($id,$uid)=each($uids)) {
-                               if ($conn->cache[$mailbox][$uid]) {
-                                       $result[$id]     = $conn->cache[$mailbox][$uid];
-                                       $result[$id]->id = $id;
-                               } else {
-                                   $needed_set.=($needed_set ? ',': '') . $id;
-                               }
-                       }
-                       //echo "<!-- iil_C_FetchHeader\nMessage Set: $message_set\nNeeded Set:$needed_set\n//-->\n";
-                       if ($needed_set) {
-                               $message_set = iil_CompressMessageSet($needed_set);
-                       } else {
-                               return $result;
-                       }
-               }
-       }
+
+       $message_set = iil_CompressMessageSet($message_set);
+
+       if ($add)
+               $add = ' '.strtoupper(trim($add));
 
        /* FETCH uid, size, flags and headers */
        $key      = 'FH12';
@@ -1711,7 +1439,7 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
        $request .= "BODY.PEEK[HEADER.FIELDS ";
        $request .= "(DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC ";
        $request .= "CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID ";
-       $request .= "REFERENCES DISPOSITION-NOTIFICATION-TO X-PRIORITY)])";
+       $request .= "REFERENCES DISPOSITION-NOTIFICATION-TO X-PRIORITY".$add.")])";
 
        if (!iil_PutLine($fp, $request)) {
                return false;
@@ -1742,7 +1470,7 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                $str = $matches[1];
 
                                // swap parents with quotes, then explode
-                               $str = eregi_replace("[()]", "\"", $str);
+                               $str = preg_replace('/[()]/', '"', $str);
                                $a = iil_ExplodeQuotedString(' ', $str);
 
                                // did we get the right number of replies?
@@ -1764,25 +1492,8 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                        // if time is gmt...
                                        $time_str = str_replace('GMT','+0000',$time_str);
                                        
-                                       //get timezone
-                                       $time_str      = substr($time_str, 0, -1);
-                                       $time_zone_str = substr($time_str, -5); // extract timezone
-                                       $time_str      = substr($time_str, 0, -5); // remove timezone
-                                       $time_zone     = (float)substr($time_zone_str, 1, 2); // get first two digits
-                       
-                                       if ($time_zone_str[3] != '0') {
-                                                $time_zone += 0.5;  //handle half hour offset
-                                       }
-                                       if ($time_zone_str[0] == '-') {
-                                               $time_zone = $time_zone * -1.0; //minus?
-                                       }
-                                       
-                                       //calculate timestamp
-                                        $timestamp     = strtotime($time_str); //return's server's time
-                                       $timestamp    -= $time_zone * 3600; //compensate for tz, get GMT
-
                                        $result[$id]->internaldate = $time_str;
-                                       $result[$id]->timestamp = $timestamp;
+                                       $result[$id]->timestamp = iil_StrToTime($time_str);
                                        $result[$id]->date = $time_str;
                                }
 
@@ -1790,13 +1501,13 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                if($bodystr) {
                                        while (!preg_match('/ BODYSTRUCTURE (.*) BODY\[HEADER.FIELDS/s', $line, $m)) {
                                                $line2 = iil_ReadLine($fp, 1024);
-                                               $line .= iil_MultLine($fp, $line2);
+                                               $line .= iil_MultLine($fp, $line2, true);
                                        }
                                        $result[$id]->body_structure = $m[1];
                                }
 
                                // the rest of the result
-                               preg_match('/ BODY\[HEADER.FIELDS \(.*\)\]\s*(.*)/s', $line, $m);
+                               preg_match('/ BODY\[HEADER.FIELDS \(.*?\)\]\s*(.*)$/s', $line, $m);
                                $reslines = explode("\n", trim($m[1], '"'));
                                // re-parse (see below)
                                foreach ($reslines as $line) {
@@ -1853,13 +1564,13 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                                $headers[$k] = '';
                                        }
                                }
-       
+
                                // create array with header field:data
                                while ( list($lines_key, $str) = each($lines) ) {
                                        list($field, $string) = iil_SplitHeaderLine($str);
                                        
                                        $field  = strtolower($field);
-                                        $string = ereg_replace("\n[[:space:]]*"," ",$string); 
+                                       $string = preg_replace('/\n\s*/', ' ', $string);
                                        
                                        switch ($field) {
                                        case 'date';
@@ -1900,7 +1611,7 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                                }
                                                break;
                                        case 'in-reply-to':
-                                               $result[$id]->in_reply_to = ereg_replace("[\n<>]", '', $string);
+                                               $result[$id]->in_reply_to = preg_replace('/[\n<>]/', '', $string);
                                                break;
                                        case 'references':
                                                $result[$id]->references = $string;
@@ -1917,21 +1628,19 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
                                                if (preg_match('/^(\d+)/', $string, $matches))
                                                        $result[$id]->priority = intval($matches[1]);
                                                break;
+                                       default:
+                                               if (strlen($field) > 2)
+                                                       $result[$id]->others[$field] = $string;
+                                               break;
                                        } // end switch ()
                                } // end while ()
-               
-                               if ($conn->do_cache) {
-                                       $uid = $result[$id]->uid;
-                                       $conn->cache[$mailbox][$uid] = $result[$id];
-                                       $conn->cache_dirty[$mailbox] = true;
-                               }
                        } else {
                                $a = explode(' ', $line);
                        }
 
                        // process flags
                        if (!empty($flags_str)) {
-                               $flags_str = eregi_replace('[\\\"]', '', $flags_str);
+                               $flags_str = preg_replace('/[\\\"]/', '', $flags_str);
                                $flags_a   = explode(' ', $flags_str);
                                        
                                if (is_array($flags_a)) {
@@ -1964,9 +1673,9 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bo
        return $result;
 }
 
-function iil_C_FetchHeader(&$conn, $mailbox, $id, $uidfetch=false, $bodystr=false) {
+function iil_C_FetchHeader(&$conn, $mailbox, $id, $uidfetch=false, $bodystr=false, $add='') {
 
-       $a  = iil_C_FetchHeaders($conn, $mailbox, $id, $uidfetch, $bodystr);
+       $a  = iil_C_FetchHeaders($conn, $mailbox, $id, $uidfetch, $bodystr, $add);
        if (is_array($a)) {
                return array_shift($a);
        }
@@ -2003,8 +1712,8 @@ function iil_SortHeaders($a, $field, $flag) {
                while (list($key, $val)=each($a)) {
 
                        if ($field == 'timestamp') {
-                               $data = @strtotime($val->date);
-                               if ($data == false) {
+                               $data = iil_StrToTime($val->date);
+                               if (!$data) {
                                        $data = $val->timestamp;
                                }
                        } else {
@@ -2036,11 +1745,13 @@ function iil_SortHeaders($a, $field, $flag) {
        return $result;
 }
 
-function iil_C_Expunge(&$conn, $mailbox) {
+function iil_C_Expunge(&$conn, $mailbox, $messages=NULL) {
 
        if (iil_C_Select($conn, $mailbox)) {
                $c = 0;
-               iil_PutLine($conn->fp, "exp1 EXPUNGE");
+               $command = $messages ? "UID EXPUNGE $messages" : "EXPUNGE";
+
+               iil_PutLine($conn->fp, "exp1 $command");
                do {
                        $line=chop(iil_ReadLine($conn->fp, 100));
                        if ($line[0] == '*') {
@@ -2072,7 +1783,7 @@ function iil_C_ModFlag(&$conn, $mailbox, $messages, $flag, $mod) {
     
        if (iil_C_Select($conn, $mailbox)) {
                $c = 0;
-               iil_PutLine($fp, "flg STORE $messages " . $mod . "FLAGS (" . $flag . ")");
+               iil_PutLine($fp, "flg UID STORE $messages " . $mod . "FLAGS (" . $flag . ")");
                do {
                        $line=chop(iil_ReadLine($fp, 100));
                        if ($line[0] == '*') {
@@ -2081,7 +1792,6 @@ function iil_C_ModFlag(&$conn, $mailbox, $messages, $flag, $mod) {
                } while (!iil_StartsWith($line, 'flg', true));
 
                if (iil_ParseResult($line) == 0) {
-                       iil_C_ExpireCachedItems($conn, $mailbox, $messages);
                        return $c;
                }
                $conn->error = $line;
@@ -2103,14 +1813,6 @@ function iil_C_Delete(&$conn, $mailbox, $messages) {
        return iil_C_ModFlag($conn, $mailbox, $messages, 'DELETED', '+');
 }
 
-function iil_C_Undelete(&$conn, $mailbox, $messages) {
-       return iil_C_ModFlag($conn, $mailbox, $messages, 'DELETED', '-');
-}
-
-function iil_C_Unseen(&$conn, $mailbox, $messages) {
-       return iil_C_ModFlag($conn, $mailbox, $messages, 'SEEN', '-');
-}
-
 function iil_C_Copy(&$conn, $messages, $from, $to) {
        $fp = $conn->fp;
 
@@ -2121,28 +1823,19 @@ function iil_C_Copy(&$conn, $messages, $from, $to) {
        if (iil_C_Select($conn, $from)) {
                $c=0;
                
-               iil_PutLine($fp, "cpy1 COPY $messages \"".iil_Escape($to)."\"");
-               $line=iil_ReadReply($fp);
+               iil_PutLine($fp, "cpy1 UID COPY $messages \"".iil_Escape($to)."\"");
+               $line = iil_ReadReply($fp);
                return iil_ParseResult($line);
        } else {
                return -1;
        }
 }
 
-function iil_FormatSearchDate($month, $day, $year) {
-       $month  = (int) $month;
-       $months = $GLOBALS['IMAP_MONTHS'];
-       return $day . '-' . $months[$month] . '-' . $year;
-}
-
 function iil_C_CountUnseen(&$conn, $folder) {
-       $index = iil_C_Search($conn, $folder, 'ALL UNSEEN');
-       if (is_array($index)) {
-               if (($cnt = count($index)) && $index[0] != '') {
-                       return $cnt;
-               }
-       }
-       return false;
+        $index = iil_C_Search($conn, $folder, 'ALL UNSEEN');
+        if (is_array($index))
+                return count($index);
+        return false;
 }
 
 function iil_C_UID2ID(&$conn, $folder, $uid) {
@@ -2156,45 +1849,46 @@ function iil_C_UID2ID(&$conn, $folder, $uid) {
 }
 
 function iil_C_ID2UID(&$conn, $folder, $id) {
-       $fp = $conn->fp;
+
        if ($id == 0) {
            return      -1;
        }
        $result = -1;
        if (iil_C_Select($conn, $folder)) {
-               $key = 'FUID';
-               if (iil_PutLine($fp, "$key FETCH $id (UID)")) {
+               $key = 'fuid';
+               if (iil_PutLine($conn->fp, "$key FETCH $id (UID)")) {
                        do {
-                               $line=chop(iil_ReadLine($fp, 1024));
-                               if (eregi("^\* $id FETCH \(UID (.*)\)", $line, $r)) {
+                               $line = chop(iil_ReadLine($conn->fp, 1024));
+                               if (preg_match("/^\* $id FETCH \(UID (.*)\)/i", $line, $r)) {
                                        $result = $r[1];
                                }
-                       } while (!preg_match("/^$key/", $line));
+                       } while (!iil_StartsWith($line, $key, true));
                }
        }
        return $result;
 }
 
 function iil_C_Search(&$conn, $folder, $criteria) {
-       $fp = $conn->fp;
+
        if (iil_C_Select($conn, $folder)) {
-               $c = 0;
+               $data = '';
                
                $query = 'srch1 SEARCH ' . chop($criteria);
-               if (!iil_PutLineC($fp, $query)) {
+               if (!iil_PutLineC($conn->fp, $query)) {
                        return false;
                }
                do {
-                       $line=trim(iil_ReadLine($fp, 10000));
-                       if (eregi("^\* SEARCH", $line)) {
-                               $str = trim(substr($line, 8));
-                               $messages = explode(' ', $str);
+                       $line = trim(iil_ReadLine($conn->fp));
+                       if (iil_StartsWith($line, '* SEARCH')) {
+                               $data .= substr($line, 8);
+                       } else if (preg_match('/^[0-9 ]+$/', $line)) {
+                               $data .= $line;
                        }
                } while (!iil_StartsWith($line, 'srch1', true));
 
                $result_code = iil_ParseResult($line);
                if ($result_code == 0) {
-                   return $messages;
+                   return preg_split('/\s+/', $data, -1, PREG_SPLIT_NO_EMPTY);
                }
                $conn->error = 'iil_C_Search: ' . $line . "\n";
                return false;   
@@ -2204,12 +1898,13 @@ function iil_C_Search(&$conn, $folder, $criteria) {
 }
 
 function iil_C_Move(&$conn, $messages, $from, $to) {
-    $fp = $conn->fp;
 
     if (!$from || !$to) {
         return -1;
     }
-    $r = iil_C_Copy($conn, $messages, $from,$to);
+    
+    $r = iil_C_Copy($conn, $messages, $from, $to);
+
     if ($r==0) {
         return iil_C_Delete($conn, $from, $messages);
     }
@@ -2318,7 +2013,7 @@ function iil_C_ListMailboxes(&$conn, $ref, $mailbox) {
        // get folder list
        do {
                $line = iil_ReadLine($fp, 500);
-               $line = iil_MultLine($fp, $line);
+               $line = iil_MultLine($fp, $line, true);
 
                $a = explode(' ', $line);
                if (($line[0] == '*') && ($a[1] == 'LIST')) {
@@ -2326,10 +2021,10 @@ function iil_C_ListMailboxes(&$conn, $ref, $mailbox) {
                        // split one line
                        $a = iil_ExplodeQuotedString(' ', $line);
                        // last string is folder name
-                       $folder = trim($a[count($a)-1], '"');
+                       $folder = preg_replace(array('/^"/', '/"$/'), '', iil_UnEscape($a[count($a)-1]));
             
                        if (empty($ignore) || (!empty($ignore)
-                               && !eregi($ignore, $folder))) {
+                               && !preg_match('/'.preg_quote(ignore, '/').'/i', $folder))) {
                                $folders[$i] = $folder;
                        }
             
@@ -2383,7 +2078,7 @@ function iil_C_ListSubscribed(&$conn, $ref, $mailbox) {
        // get folder list
        do {
                $line = iil_ReadLine($fp, 500);
-               $line = iil_MultLine($fp, $line);
+               $line = iil_MultLine($fp, $line, true);
                $a    = explode(' ', $line);
         
                if (($line[0] == '*') && ($a[1] == 'LSUB' || $a[1] == 'LIST')) {
@@ -2391,13 +2086,11 @@ function iil_C_ListSubscribed(&$conn, $ref, $mailbox) {
             
                        // split one line
                        $a = iil_ExplodeQuotedString(' ', $line);
-            
                        // last string is folder name
-                       //$folder = UTF7DecodeString(str_replace('"', '', $a[count($a)-1]));
-                       $folder = trim($a[count($a)-1], '"');
-            
+                       $folder = preg_replace(array('/^"/', '/"$/'), '', iil_UnEscape($a[count($a)-1]));
+        
                        if ((!in_array($folder, $folders)) && (empty($ignore)
-                               || (!empty($ignore) && !eregi($ignore, $folder)))) {
+                               || (!empty($ignore) && !preg_match('/'.preg_quote(ignore, '/').'/i', $folder)))) {
                            $folders[$i] = $folder;
                        }
             
@@ -2432,8 +2125,8 @@ function iil_C_Subscribe(&$conn, $folder) {
        $query = 'sub1 SUBSCRIBE "' . iil_Escape($folder). '"';
        iil_PutLine($fp, $query);
 
-       $line = trim(iil_ReadLine($fp, 10000));
-       return iil_ParseResult($line);
+       $line = trim(iil_ReadLine($fp, 512));
+       return (iil_ParseResult($line) == 0);
 }
 
 function iil_C_UnSubscribe(&$conn, $folder) {
@@ -2442,8 +2135,8 @@ function iil_C_UnSubscribe(&$conn, $folder) {
        $query = 'usub1 UNSUBSCRIBE "' . iil_Escape($folder) . '"';
        iil_PutLine($fp, $query);
     
-       $line = trim(iil_ReadLine($fp, 10000));
-       return iil_ParseResult($line);
+       $line = trim(iil_ReadLine($fp, 512));
+       return (iil_ParseResult($line) == 0);
 }
 
 function iil_C_FetchMIMEHeaders(&$conn, $mailbox, $id, $parts) {
@@ -2486,39 +2179,51 @@ function iil_C_FetchMIMEHeaders(&$conn, $mailbox, $id, $parts) {
        return $result;
 }
 
-function iil_C_FetchPartHeader(&$conn, $mailbox, $id, $part) {
+function iil_C_FetchPartHeader(&$conn, $mailbox, $id, $is_uid=false, $part=NULL) {
 
        $part = empty($part) ? 'HEADER' : $part.'.MIME';
 
-        return iil_C_HandlePartBody($conn, $mailbox, $id, $part, 1);
+        return iil_C_HandlePartBody($conn, $mailbox, $id, $is_uid, $part);
 }
 
-function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part='', $mode=1, $file=NULL) {
-       /* modes:
-        1: return string (or write to $file pointer)
-        2: print
-        3: base64 and print (or write to $file pointer)
-       */
+function iil_C_HandlePartBody(&$conn, $mailbox, $id, $is_uid=false, $part='', $encoding=NULL, $print=NULL, $file=NULL) {
        
        $fp     = $conn->fp;
        $result = false;
        
+       switch ($encoding) {
+               case 'base64':
+                       $mode = 1;
+               break;
+               case 'quoted-printable':
+                       $mode = 2;
+               break;
+               case 'x-uuencode':
+               case 'x-uue':
+               case 'uue':
+               case 'uuencode':
+                       $mode = 3;
+               break;
+               default:
+                       $mode = 0;
+       }
+       
        if (iil_C_Select($conn, $mailbox)) {
                $reply_key = '* ' . $id;
-        
+
                // format request
-               $key     = 'ftch' . ($c++) . ' ';
-               $request = $key . "FETCH $id (BODY.PEEK[$part])";
+               $key     = 'ftch0';
+               $request = $key . ($is_uid ? ' UID' : '') . " FETCH $id (BODY.PEEK[$part])";
                // send request
                if (!iil_PutLine($fp, $request)) {
                    return false;
                }
-        
+
                // receive reply line
                do {
                        $line = chop(iil_ReadLine($fp, 1000));
                        $a    = explode(' ', $line);
-               } while ($a[2] != 'FETCH');
+               } while (!($end = iil_StartsWith($line, $key, true)) && $a[2] != 'FETCH');
                $len = strlen($line);
 
                // handle empty "* X FETCH ()" response
@@ -2533,15 +2238,14 @@ function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part='', $mode=1, $file=NU
                                $len  = $to - $from;
                                $result = substr($line, $from, $len);
                        }
-           
-                       if ($mode == 2) {
-                               echo $result;
-                       } else if ($mode == 3) {
-                               if ($file)
-                                       fwrite($file, base64_decode($result));
-                               else
-                                       echo base64_decode($result);
-                       }                            
+
+                       if ($mode == 1)
+                               $result = base64_decode($result);
+                       else if ($mode == 2)
+                               $result = quoted_printable_decode($result);
+                       else if ($mode == 3)
+                               $result = convert_uudecode($result);
+
                } else if ($line[$len-1] == '}') {
                        //multi-line request, find sizes of content and receive that many bytes
                        $from     = strpos($line, '{') + 1;
@@ -2557,19 +2261,12 @@ function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part='', $mode=1, $file=NU
                 
                                if ($len > $bytes) {
                                        $line = substr($line, 0, $bytes);
+                                       $len = strlen($line);
                                }
-                               $bytes -= strlen($line);
-
-                               $line = rtrim($line, "\t\r\n\0\x0B");
+                               $bytes -= $len;
 
                                if ($mode == 1) {
-                                       if ($file)
-                                               fwrite($file, $line . "\n");
-                                       else
-                                               $result .= $line . "\n";
-                               } else if ($mode == 2) {
-                                       echo $line . "\n";
-                               } else if ($mode == 3) {
+                                       $line = rtrim($line, "\t\r\n\0\x0B");
                                        // create chunks with proper length for base64 decoding
                                        $line = $prev.$line;
                                        $length = strlen($line);
@@ -2583,64 +2280,68 @@ function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part='', $mode=1, $file=NU
 
                                        if ($file)
                                                fwrite($file, base64_decode($line));
-                                       else
+                                       else if ($print)
                                                echo base64_decode($line);
+                                       else
+                                               $result .= base64_decode($line);
+                               } else if ($mode == 2) {
+                                       $line = rtrim($line, "\t\r\0\x0B");
+                                       if ($file)
+                                               fwrite($file, quoted_printable_decode($line));
+                                       else if ($print)
+                                               echo quoted_printable_decode($line);
+                                       else
+                                               $result .= quoted_printable_decode($line);
+                               } else if ($mode == 3) {
+                                       $line = rtrim($line, "\t\r\n\0\x0B");
+                                       if ($line == 'end' || preg_match('/^begin\s+[0-7]+\s+.+$/', $line))
+                                               continue;
+                                       if ($file)
+                                               fwrite($file, convert_uudecode($line));
+                                       else if ($print)
+                                               echo convert_uudecode($line);
+                                       else
+                                               $result .= convert_uudecode($line);
+                               } else {
+                                       $line = rtrim($line, "\t\r\n\0\x0B");
+                                       if ($file)
+                                               fwrite($file, $line . "\n");
+                                       else if ($print)
+                                               echo $line . "\n";
+                                       else
+                                               $result .= $line . "\n";
                                }
                        }
                }
+
                // read in anything up until last line
-               do {
-                       $line = iil_ReadLine($fp, 1024);
-               } while (!iil_StartsWith($line, $key, true));
-        
-               if ($mode == 3 && $file) {
-                       return true;
-               }
-       
+               if (!$end)
+                       do {
+                               $line = iil_ReadLine($fp, 1024);
+                       } while (!iil_StartsWith($line, $key, true));
+
                if ($result) {
                        $result = rtrim($result, "\t\r\n\0\x0B");
                        if ($file) {
                                fwrite($file, $result);
-                               return true;
-                       }       
-                       return $result; // substr($result, 0, strlen($result)-1);
+                       } else if ($print) {
+                               echo $result;
+                       } else
+                               return $result; // substr($result, 0, strlen($result)-1);
+
+                       return true;
                }
-               
-               return false;
-       } else {
-               echo 'Select failed.';
        }
     
-       if ($mode==1) {
-               if ($file) {
-                       fwrite($file, $result);
-                       return true;
-               }
-               return $result;
-       }
-       
        return false;
 }
 
-function iil_C_FetchPartBody(&$conn, $mailbox, $id, $part, $file=NULL) {
-       return iil_C_HandlePartBody($conn, $mailbox, $id, $part, 1, $file);
-}
-
-function iil_C_PrintPartBody(&$conn, $mailbox, $id, $part) {
-       iil_C_HandlePartBody($conn, $mailbox, $id, $part, 2);
-}
-
-function iil_C_PrintBase64Body(&$conn, $mailbox, $id, $part) {
-       iil_C_HandlePartBody($conn, $mailbox, $id, $part, 3);
-}
-
 function iil_C_CreateFolder(&$conn, $folder) {
        $fp = $conn->fp;
        if (iil_PutLine($fp, 'c CREATE "' . iil_Escape($folder) . '"')) {
                do {
                        $line=iil_ReadLine($fp, 300);
-               } while ($line[0] != 'c');
-        $conn->error = $line;
+               } while (!iil_StartsWith($line, 'c ', true));
                return (iil_ParseResult($line) == 0);
        }
        return false;
@@ -2651,7 +2352,7 @@ function iil_C_RenameFolder(&$conn, $from, $to) {
        if (iil_PutLine($fp, 'r RENAME "' . iil_Escape($from) . '" "' . iil_Escape($to) . '"')) {
                do {
                        $line = iil_ReadLine($fp, 300);
-               } while ($line[0] != 'r');
+               } while (!iil_StartsWith($line, 'r ', true));
                return (iil_ParseResult($line) == 0);
        }
        return false;
@@ -2662,40 +2363,47 @@ function iil_C_DeleteFolder(&$conn, $folder) {
        if (iil_PutLine($fp, 'd DELETE "' . iil_Escape($folder). '"')) {
                do {
                        $line=iil_ReadLine($fp, 300);
-               } while ($line[0] != 'd');
+               } while (!iil_StartsWith($line, 'd ', true));
                return (iil_ParseResult($line) == 0);
        }
-       $conn->error = "Couldn't send command\n";
        return false;
 }
 
 function iil_C_Append(&$conn, $folder, &$message) {
        if (!$folder) {
-               return false;
+               return false;
        }
        $fp = $conn->fp;
 
        $message = str_replace("\r", '', $message);
-       $message = str_replace("\n", "\r\n", $message);         
+       $message = str_replace("\n", "\r\n", $message);
 
        $len = strlen($message);
        if (!$len) {
-               return false;
+               return false;
        }
 
-       $request = 'A APPEND "' . iil_Escape($folder) .'" (\\Seen) {' . $len . '}';
-    
+       $request = 'a APPEND "' . iil_Escape($folder) .'" (\\Seen) {' . $len . '}';
+
        if (iil_PutLine($fp, $request)) {
-               $line=iil_ReadLine($fp, 100);           
-               $sent = fwrite($fp, $message."\r\n");
+               $line = iil_ReadLine($fp, 512);
+
+               if ($line[0] != '+') {
+                       // $errornum = iil_ParseResult($line);
+                       $conn->error .= "Cannot write to folder: $line\n";
+                       return false;
+               }
+
+               iil_PutLine($fp, $message);
+
                do {
-                       $line=iil_ReadLine($fp, 1000);
-               } while ($line[0] != 'A');
+                       $line = iil_ReadLine($fp);
+               } while (!iil_StartsWith($line, 'a ', true));
        
                $result = (iil_ParseResult($line) == 0);
                if (!$result) {
                    $conn->error .= $line . "\n";
-               }
+               }
                return $result;
        }
 
@@ -2709,7 +2417,7 @@ function iil_C_AppendFromFile(&$conn, $folder, $path) {
        }
     
        //open message file
-       $in_fp = false;                         
+       $in_fp = false;
        if (file_exists(realpath($path))) {
                $in_fp = fopen($path, 'r');
        }
@@ -2725,31 +2433,35 @@ function iil_C_AppendFromFile(&$conn, $folder, $path) {
        }
     
        //send APPEND command
-       $request    = 'A APPEND "' . iil_Escape($folder) . '" (\\Seen) {' . $len . '}';
-       $bytes_sent = 0;
+       $request    = 'a APPEND "' . iil_Escape($folder) . '" (\\Seen) {' . $len . '}';
        if (iil_PutLine($fp, $request)) {
-               $line = iil_ReadLine($fp, 100);
-                               
+               $line = iil_ReadLine($fp, 512);
+
+               if ($line[0] != '+') {
+                       //$errornum = iil_ParseResult($line);
+                       $conn->error .= "Cannot write to folder: $line\n";
+                       return false;
+               }
+
                //send file
                while (!feof($in_fp)) {
                        $buffer      = fgets($in_fp, 4096);
-                       $bytes_sent += strlen($buffer);
                        iil_PutLine($fp, $buffer, false);
                }
                fclose($in_fp);
 
-               iil_PutLine($fp, '');
+               iil_PutLine($fp, ''); // \r\n
 
                //read response
                do {
-                       $line = iil_ReadLine($fp, 1000);
-               } while ($line[0] != 'A');
-                       
+                       $line = iil_ReadLine($fp);
+               } while (!iil_StartsWith($line, 'a ', true));
+
                $result = (iil_ParseResult($line) == 0);
                if (!$result) {
                    $conn->error .= $line . "\n";
                }
-        
+
                return $result;
        }
        
@@ -2757,35 +2469,27 @@ function iil_C_AppendFromFile(&$conn, $folder, $path) {
        return false;
 }
 
-function iil_C_FetchStructureString(&$conn, $folder, $id) {
+function iil_C_FetchStructureString(&$conn, $folder, $id, $is_uid=false) {
        $fp     = $conn->fp;
        $result = false;
        
        if (iil_C_Select($conn, $folder)) {
                $key = 'F1247';
 
-               if (iil_PutLine($fp, "$key FETCH $id (BODYSTRUCTURE)")) {
+               if (iil_PutLine($fp, $key . ($is_uid ? ' UID' : '') ." FETCH $id (BODYSTRUCTURE)")) {
                        do {
                                $line = iil_ReadLine($fp, 5000);
-                               $line = iil_MultLine($fp, $line);
-                               list(, $index, $cmd, $rest) = explode(' ', $line);
-                               if ($cmd != 'FETCH' || $index == $id || preg_match("/^$key/", $line))
+                               $line = iil_MultLine($fp, $line, true);
+                               if (!preg_match("/^$key/", $line))
                                        $result .= $line;
-                       } while (!preg_match("/^$key/", $line));
+                       } while (!iil_StartsWith($line, $key, true));
 
-                       $result = trim(substr($result, strpos($result, 'BODYSTRUCTURE')+13, -(strlen($result)-strrpos($result, $key)+1)));
+                       $result = trim(substr($result, strpos($result, 'BODYSTRUCTURE')+13, -1));
                }
        }
        return $result;
 }
 
-function iil_C_PrintSource(&$conn, $folder, $id, $part) {
-       $header = iil_C_FetchPartHeader($conn, $folder, $id, $part);
-       //echo str_replace("\r", '', $header);
-       echo $header;
-       echo iil_C_PrintPartBody($conn, $folder, $id, $part);
-}
-
 function iil_C_GetQuota(&$conn) {
 /*
  * GETQUOTAROOT "INBOX"
@@ -2810,7 +2514,7 @@ function iil_C_GetQuota(&$conn) {
        // return false if not found, parse if found
        $min_free = PHP_INT_MAX;
        foreach ($quota_lines as $key => $quota_line) {
-               $quota_line   = eregi_replace('[()]', '', $quota_line);
+               $quota_line   = preg_replace('/[()]/', '', $quota_line);
                $parts        = explode(' ', $quota_line);
                $storage_part = array_search('STORAGE', $parts);
                
@@ -2835,7 +2539,7 @@ function iil_C_GetQuota(&$conn) {
 function iil_C_ClearFolder(&$conn, $folder) {
        $num_in_trash = iil_C_CountMessages($conn, $folder);
        if ($num_in_trash > 0) {
-               iil_C_Delete($conn, $folder, '1:' . $num_in_trash);
+               iil_C_Delete($conn, $folder, '1:*');
        }
        return (iil_C_Expunge($conn, $folder) >= 0);
 }
index 16fc52dafa81ee5ce61be2eb5726377072ffa9e0..860edbff240382e8ea4e8be69f7ab2f8721b64a4 100644 (file)
@@ -91,7 +91,8 @@ function iml_GetRawStructureArray($str){
     $line = str_replace(")(", ") (", $line);
 
        $struct = iml_ParseBSString($line);
-       if ((strcasecmp($struct[0], "message")==0) && (strcasecmp($struct[1], "rfc822")==0)){
+       if (!is_array($struct[0]) && (strcasecmp($struct[0], "message")==0)
+               && (strcasecmp($struct[1], "rfc822")==0)) {
                $struct = array($struct);
        }
     return $struct;
index 8e3682a9bbdc30d6bddeab2979a4b761f2709acd..750faf65748ab0fd389d01fb9ef0c3d138f4a321 100644 (file)
@@ -185,12 +185,12 @@ function extract_mapi_attrs($buf, &$attachment_data)
       switch($attr_name)
       {
          case TNEF_MAPI_ATTACH_LONG_FILENAME: // used in preference to AFILENAME value
-            $attachment_data[0]['name'] = ereg_replace('.*[\/](.*)$', '\1', $value); // strip path
+            $attachment_data[0]['name'] = preg_replace('/.*[\/](.*)$/', '\1', $value); // strip path
             break;
 
          case TNEF_MAPI_ATTACH_MIME_TAG: // Is this ever set, and what is format?
-            $attachment_data[0]['type0'] = ereg_replace('^(.*)/.*', '\1', $value);
-            $attachment_data[0]['type1'] = ereg_replace('.*/(.*)$', '\1', $value);
+            $attachment_data[0]['type0'] = preg_replace('/^(.*)\/.*/', '\1', $value);
+            $attachment_data[0]['type1'] = preg_replace('/.*\/(.*)$/', '\1', $value);
             break;
 
          case TNEF_MAPI_ATTACH_DATA:
@@ -247,7 +247,7 @@ function tnef_decode_attachment(&$buf, &$attachment_data)
 
       case TNEF_AFILENAME: // filename
          $length = tnef_geti32($buf);
-         $attachment_data[0]['name'] = ereg_replace('.*[\/](.*)$',
+         $attachment_data[0]['name'] = preg_replace('/.*[\/](.*)$/',
                                                     '\1',
                                                     tnef_getx($length, $buf)); // strip path
          tnef_geti16($buf); //checksum
index 338baeca6f76a64b7389f4ed11c8ecbf510ba1bb..01b0488fc8bde9e92bca73b1bd8b74fc8d088183 100644 (file)
  * Dont be a fool:
  *  - Dont alter data on a GET: '<img src="http://yourhost/mail?action=delete&uid=3267" />'
  *  - ...
+ *
+ * Roundcube Changes:
+ * - added $block_elements
+ * - changed $ignore_elements behaviour
  */
 
 class washtml
 {
   /* Allowed HTML elements (default) */
-  static $html_elements = array('a', 'abbr', 'acronym', 'address', 'area', 'b', 'basefont', 'bdo', 'big', 'blockquote', 'br', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'label', 'legend', 'li', 'map', 'menu', 'nobr', 'ol', 'p', 'pre', 'q', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'img');
+  static $html_elements = array('a', 'abbr', 'acronym', 'address', 'area', 'b', 'basefont', 'bdo', 'big', 'blockquote', 'br', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'ins', 'label', 'legend', 'li', 'map', 'menu', 'nobr', 'ol', 'p', 'pre', 'q', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'wbr', 'img');
   
-  /* Ignore these HTML tags but process their content */
-  static $ignore_elements = array('html', 'head', 'body');
+  /* Ignore these HTML tags and their content */
+  static $ignore_elements = array('script', 'applet', 'embed', 'object', 'style');
   
   /* Allowed HTML attributes */
   static $html_attribs = array('name', 'class', 'title', 'alt', 'width', 'height', 'align', 'nowrap', 'col', 'row', 'id', 'rowspan', 'colspan', 'cellspacing', 'cellpadding', 'valign', 'bgcolor', 'color', 'border', 'bordercolorlight', 'bordercolordark', 'face', 'marginwidth', 'marginheight', 'axis', 'border', 'abbr', 'char', 'charoff', 'clear', 'compact', 'coords', 'vspace', 'hspace', 'cellborder', 'size', 'lang', 'dir');  
+
+  /* Block elements which could be empty but cannot be returned in short form (<tag />) */
+  static $block_elements = array('div', 'p', 'pre', 'blockquote');
   
   /* State for linked objects in HTML */
   public $extlinks = false;
@@ -97,6 +104,9 @@ class washtml
   /* Ignore these HTML tags but process their content */
   private $_ignore_elements = array();
 
+  /* Block elements which could be empty but cannot be returned in short form (<tag />) */
+  private $_block_elements = array();
+
   /* Allowed HTML attributes */
   private $_html_attribs = array();
   
@@ -106,7 +116,8 @@ class washtml
     $this->_html_elements = array_flip((array)$p['html_elements']) + array_flip(self::$html_elements) ;
     $this->_html_attribs = array_flip((array)$p['html_attribs']) + array_flip(self::$html_attribs);
     $this->_ignore_elements = array_flip((array)$p['ignore_elements']) + array_flip(self::$ignore_elements);
-    unset($p['html_elements'], $p['html_attribs'], $p['ignore_elements']);
+    $this->_block_elements = array_flip((array)$p['block_elements']) + array_flip(self::$block_elements);
+    unset($p['html_elements'], $p['html_attribs'], $p['ignore_elements'], $p['block_elements']);
     $this->config = $p + array('show_washed'=>true, 'allow_remote'=>false, 'cid_map'=>array());
   }
   
@@ -160,7 +171,7 @@ class washtml
       $key = strtolower($key);
       $value = $node->getAttribute($key);
       if(isset($this->_html_attribs[$key]) ||
-         ($key == 'href' && preg_match('/^(http|https|ftp|mailto):.+/i', $value)))
+         ($key == 'href' && preg_match('/^(http:|https:|ftp:|mailto:|#).+/i', $value)))
         $t .= ' ' . $key . '="' . htmlspecialchars($value, ENT_QUOTES) . '"';
       else if($key == 'style' && ($style = $this->wash_style($value)))
         $t .= ' style="' . $style . '"';
@@ -202,12 +213,13 @@ class washtml
         } else if(isset($this->_html_elements[$tagName])) {
           $content = $this->dumpHtml($node);
           $dump .= '<' . $tagName . $this->wash_attribs($node) .
-            ($content?">$content</$tagName>":' />');
+            ($content || isset($this->_block_elements[$tagName]) ? ">$content</$tagName>" : ' />');
         } else if(isset($this->_ignore_elements[$tagName])) {
-          $dump .= '<!-- ' . htmlspecialchars($tagName, ENT_QUOTES) . ' ignored -->';
-          $dump .= $this->dumpHtml($node); //Just ignored
-        } else
           $dump .= '<!-- ' . htmlspecialchars($tagName, ENT_QUOTES) . ' not allowed -->';
+        } else {
+          $dump .= '<!-- ' . htmlspecialchars($tagName, ENT_QUOTES) . ' ignored -->';
+          $dump .= $this->dumpHtml($node); // ignore tags not its content
+       }
         break;
       case XML_CDATA_SECTION_NODE:
         $dump .= $node->nodeValue;
@@ -240,4 +252,4 @@ class washtml
 
 }
 
-?>
\ No newline at end of file
+?>
index 3e1cf096749c9eafc649829d5bf1d4e274fa54b0..a9b8902ac0450617d79bd7093bdce3c45afc3c02 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Ossama Khayat <okhayat@yahoo.com>                             |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -226,7 +226,6 @@ $labels['skipdeleted'] = 'لا تظهر الرسائل المحذوفة';
 $labels['showinlineimages'] = 'أظهر الصّور المرفقة أسفل الرسالة';
 $labels['autosavedraft'] = 'حفظ المسودة تلقائياً';
 $labels['everynminutes'] = 'كل $n دقيقة';
-$labels['keepaliveevery'] = 'كل $n دقيقة';
 $labels['keepalive'] = 'تحقق من وجود رسائل جديدة عند';
 $labels['never'] = 'أبداً';
 $labels['messagesdisplaying'] = 'إظهار الرسائل';
index 01afbd9c76cf8fb81f7755dc6a34ee8ba5a22c2e..2a2df2b3cb68a09410998559680bf0db353f339d 100644 (file)
@@ -288,8 +288,7 @@ $labels['fromknownsenders'] = 'de contautos conocíos';
 $labels['always'] = 'siempre';
 $labels['showinlineimages'] = 'Amosar imáxenes axuntes embaxu\'l mensaxe';
 $labels['autosavedraft'] = 'Guardar borrador de secute';
-$labels['everynminutes'] = 'cada $n minutos';
-$labels['keepaliveevery']  = 'cada $n minutu/os';
+$labels['everynminutes']  = 'cada $n minutu/os';
 $labels['keepalive']  = 'Guetar mensaxes nuevos cada';
 $labels['never'] = 'nunca';
 $labels['messagesdisplaying'] = 'Vista de mensaxes';
@@ -325,6 +324,4 @@ $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
 $labels['GB'] = 'GB';
 
-//personalizau
-$labels['anu'] = date(Y);
 ?>
index 8efabf6828c0774d9936411ecd5dca66c3cd1b6e..73f7d97dee9bb0de474637a325a862a2ea106538 100644 (file)
@@ -229,8 +229,7 @@ $labels['fromknownsenders'] = 'bilinən göndərilənlərdən';
 $labels['always'] = 'hər zaman';
 $labels['showinlineimages'] = 'Əlavə olunmuş qrafikləri məktubun aşağısında göstər';
 $labels['autosavedraft'] = 'Qaralamanı avtomatik olaraq yaddaşda saxla';
-$labels['everynminutes'] = 'hər $n dəqiqədə bir';
-$labels['keepaliveevery'] = 'hər $n dəqiqə(lər)';
+$labels['everynminutes'] = 'hər $n dəqiqə(lər)';
 $labels['keepalive'] = 'Yeni məktubları burada yoxlayın:';
 $labels['never'] = 'heç bir zaman';
 $labels['messagesdisplaying'] = 'Məktubların göstərilməsi';
index 71e3a603149355c799bf73bfafa6086d2a3dc483..415b31c47900a7eda59a56ec36e554b298e4778b 100644 (file)
@@ -117,10 +117,16 @@ $labels['markread'] = 'Като прочетени';
 $labels['markunread'] = 'Като нови';
 $labels['markflagged'] = 'Като отбелязани';
 $labels['markunflagged'] = 'Като неотбелязани';
+$labels['messageactions'] = 'Още действия';
 $labels['select'] = 'Избери';
 $labels['all'] = 'Всички';
 $labels['none'] = 'Нищо';
 $labels['unread'] = 'Нови';
+$labels['flagged'] = 'Отбелязано';
+$labels['unanswered'] = 'Неотговорено';
+$labels['deleted'] = 'Изтрито';
+$labels['invert'] = 'Invert';
+$labels['filter'] = 'Филтър';
 $labels['compact'] = 'Свий';
 $labels['empty'] = 'Изпразни';
 $labels['purge'] = 'Изчисти';
@@ -129,8 +135,11 @@ $labels['unknown'] = 'няма информация';
 $labels['unlimited'] = 'няма ограничение';
 $labels['quicksearch'] = 'Бързо търсене';
 $labels['resetsearch'] = 'Изчисти търсенето и покажи всички писма';
+$labels['msgtext'] = 'Цялото съобщение';
 $labels['openinextwin'] = 'Отвори в нов прозорец';
+$labels['emlsave'] = 'Изтегли (.eml)';
 $labels['compose'] = 'Ново писмо';
+$labels['editasnew'] = 'Редактирай като ново';
 $labels['savemessage'] = 'Запиши в Чернови';
 $labels['sendmessage'] = 'Изпрати писмото';
 $labels['addattachment'] = 'Прикачи файл';
@@ -144,10 +153,10 @@ $labels['attachments'] = 'Прикачени файлове';
 $labels['upload'] = 'Качи';
 $labels['close'] = 'Затвори';
 $labels['low'] = 'Нисък';
-$labels['lowest'] = '*';
+$labels['lowest'] = 'Най-нисък';
 $labels['normal'] = 'Нормален';
 $labels['high'] = 'Висок';
-$labels['highest'] = '*****';
+$labels['highest'] = 'Най-висок';
 $labels['nosubject'] = '(няма заглавие)';
 $labels['showimages'] = 'Показвай изображения';
 $labels['alwaysshow'] = 'Винаги показвай изображения от $ ';
@@ -224,10 +233,11 @@ $labels['ignore'] = 'Отхвърли';
 $labels['readwhendeleted'] = 'Отбележи като прочетено при изтриване';
 $labels['flagfordeletion'] = 'Отбележи съобщението за изтриване';
 $labels['skipdeleted'] = 'Не показвай изтритите съобщения';
+$labels['fromknownsenders'] = 'Oт познати изпращачи';
+$labels['always'] = 'Винаги';
 $labels['showinlineimages'] = 'Покажи прикачените изображения след съобщението';
 $labels['autosavedraft'] = 'Автоматично записвай чернова';
 $labels['everynminutes'] = 'всеки $n минути';
-$labels['keepaliveevery'] = 'всеки $n минути';
 $labels['keepalive'] = 'Проверявай за нови съобщения при';
 $labels['never'] = 'никога';
 $labels['messagesdisplaying'] = 'Показване на събщенията';
@@ -237,6 +247,13 @@ $labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
 $labels['2047folding'] = 'Full RFC 2047 (други)';
 $labels['advancedoptions'] = 'Настройки за напреднали';
+$labels['checkallfolders'] = 'Провери всички папки за нови писма';
+$labels['displaynext'] = 'След изтриване / премини към следващото писмо';
+$labels['mainoptions'] = 'Основни настройки';
+$labels['section'] = 'Раздел';
+$labels['maintenance'] = 'Поддръжка';
+$labels['newmessage'] = 'Ново съобщение';
+$labels['listoptions'] = 'Покажи списък с настройки';
 $labels['folder'] = 'Папка';
 $labels['folders'] = 'Папки';
 $labels['foldername'] = 'Име на папката';
index 4c647fcf7b1a44d15ca6583fe5f41ac31cab1fcd..e03a1a8b0a67bc5c3304d85dc3c567486dada876 100644 (file)
@@ -229,7 +229,6 @@ $labels['always'] = 'সবসময়';
 $labels['showinlineimages'] = 'মেইলের সাথে জোড়া লাগানো ছবি, মেইলের নিচে দেখা যাবে';
 $labels['autosavedraft'] = 'নিজেনিজি খসড়া জমা হয়ে যাবে';
 $labels['everynminutes'] = 'প্রতি $n মিনিটে';
-$labels['keepaliveevery'] = 'প্রতি $n মিনিটে';
 $labels['keepalive'] = 'নতুন মেইল/চিঠি এসেছে কিনা তা দেখা হবে,';
 $labels['never'] = 'কখোনোই না';
 $labels['messagesdisplaying'] = 'মেইল/চিঠি দেখা যাচ্ছে';
diff --git a/program/localization/br/labels.inc b/program/localization/br/labels.inc
new file mode 100644 (file)
index 0000000..726662b
--- /dev/null
@@ -0,0 +1,182 @@
+<?php
+
+/*
+
+ +-----------------------------------------------------------------------+
+ | language/bzg/labels.inc                                                |
+ |                                                                       |
+ | Language file of the RoundCube Webmail client                         |
+ | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: aldweb <info@aldweb.com>                                      |
+ |         Pierre HAEGELI <pierre@haegeli.net>                           |
+ |         Mickaël Wolff <rcw@lupusmic.org>                              |
+ +-----------------------------------------------------------------------+
+
+ @version $Id$
+
+*/
+
+$labels = array();
+$labels['welcome'] = 'Degemer mat war $product';
+$labels['username'] = 'Implijer';
+$labels['password'] = 'Ger-Tremen';
+$labels['server'] = 'Servijer';
+$labels['login'] = 'Dilesadur';
+$labels['logout'] = 'Kuitaat';
+$labels['mail'] = 'Postel elektronek';
+$labels['settings'] = 'Dibarzhioù';
+$labels['addressbook'] = 'Karned chomlec\'hioù';
+$labels['inbox'] = 'Kemennadoù resevet';
+$labels['drafts'] = 'Brouilhedoù';
+$labels['sent'] = 'Kemennadoù kaset';
+$labels['trash'] = 'Pod-lastez';
+$labels['junk'] = 'Stroboù';
+$labels['subject'] = 'Sujed';
+$labels['from'] = 'Eus';
+$labels['to'] = 'Ouzh';
+$labels['cc'] = 'Cc';
+$labels['bcc'] = 'Cci';
+$labels['replyto'] = 'Respont ouzh';
+$labels['date'] = 'Deiz';
+$labels['size'] = 'Ment';
+$labels['priority'] = 'Kentwir';
+$labels['organization'] = 'Aozadur';
+$labels['reply-to'] = 'Respont ouzh';
+$labels['mailboxlist'] = 'Renkelloù';
+$labels['messagesfromto'] = 'Kemennadoù eus $from ouzh $to war $count';
+$labels['messagenrof'] = 'Kemennad $nr war $count';
+$labels['moveto'] = 'Dilec\'hiañ ouzh...';
+$labels['download'] = 'Pellgargañ';
+$labels['filename'] = 'Anv ar restr';
+$labels['filesize'] = 'Ment ar restr';
+$labels['preferhtml'] = 'Diskouez en HTML';
+$labels['htmlmessage'] = 'Kemennad en HTML';
+$labels['prettydate'] = 'Diskouez berr deizioù';
+$labels['addtoaddressbook'] = 'Ouzhpennañ er c\'harned chomlec\'hioù';
+$labels['sun'] = 'Sul';
+$labels['mon'] = 'Lun';
+$labels['tue'] = 'Meu';
+$labels['wed'] = 'Mer';
+$labels['thu'] = 'Yao';
+$labels['fri'] = 'Gwe';
+$labels['sat'] = 'Sad';
+$labels['sunday'] = 'Sul';
+$labels['monday'] = 'Lun';
+$labels['tuesday'] = 'Meurzh';
+$labels['wednesday'] = 'Merc\'her';
+$labels['thursday'] = 'Yaou';
+$labels['friday'] = 'Gwener';
+$labels['saturday'] = 'Sadorn';
+$labels['today'] = 'Hiziv';
+$labels['checkmail'] = 'Gwiriañ kemennadoù nevez';
+$labels['writenewmessage'] = 'Skrivañ ur c\'hemennad nevez';
+$labels['replytomessage'] = 'Respont kemennad';
+$labels['replytoallmessage'] = 'Respont d\'an holl';
+$labels['forwardmessage'] = 'Treuzkas ar c\'hemennad';
+$labels['deletemessage'] = 'Dilec\'hiañ ar c\'hemennad er pod-lastez';
+$labels['printmessage'] = 'Moulañ ar c\'hemennad-se';
+$labels['previousmessage'] = 'Gwelout ar c\"hemennad a-raok';
+$labels['previousmessages'] = 'Gwelout ar c\'hemennadoù a-raok';
+$labels['firstmessage'] = 'Gwelout ar c\'hemennad kentañ';
+$labels['firstmessages'] = 'Gwelout ar bajenn gentañ kemennadoù';
+$labels['nextmessage'] = 'Gwelout ar c\'hemennad da heul';
+$labels['nextmessages'] = 'Gwelout ar c\'hemennadoù da heul';
+$labels['lastmessage'] = 'Gwelout ar c\'hemennad diwezhañ';
+$labels['lastmessages'] = 'Gwelout ar bajenn diwezhañ kemennadoù';
+$labels['backtolist'] = 'Distreiñ el listenn kemennadoù';
+$labels['viewsource'] = 'Gwelout an tarzh';
+$labels['select'] = 'Diuzañ';
+$labels['all'] = 'An holl';
+$labels['none'] = 'Ebet';
+$labels['unread'] = 'Na lennet';
+$labels['compact'] = 'Stummaat';
+$labels['empty'] = 'Skarzhañ';
+$labels['purge'] = 'Spurjañ';
+$labels['quota'] = 'Implijadur pladenn';
+$labels['unknown'] = 'Dianav';
+$labels['unlimited'] = 'didermen';
+$labels['quicksearch'] = 'Klask prim';
+$labels['resetsearch'] = 'Aderaouekaat ar glask';
+$labels['compose'] = 'Skrivañ ur c\'hemennad nevez';
+$labels['sendmessage'] = 'Kas ar c\'hemennad diouzhtu';
+$labels['savemessage'] = 'Gwarediñ ar brouilhed-se';
+$labels['addattachment'] = 'Stagañ ur restr';
+$labels['charset'] = 'Engodadur';
+$labels['editortype'] = 'Furmad aozer';
+$labels['returnreceipt'] = 'Testeni degemer';
+$labels['checkspelling'] = 'Gwiriañ ar reizhskrivadur';
+$labels['resumeediting'] = 'Distreiñ en aozer';
+$labels['revertto'] = 'Distreiñ en/r';
+$labels['attachments'] = 'Restroù staget';
+$labels['upload'] = 'Stagañ';
+$labels['close'] = 'Serriñ';
+$labels['low'] = 'Izel';
+$labels['lowest'] = 'An izelañ';
+$labels['normal'] = 'Reizh';
+$labels['high'] = 'Uhel';
+$labels['highest'] = 'An uhelañ';
+$labels['nosubject'] = '(n\'eus ket sujed)';
+$labels['showimages'] = 'Diskouez ar skeudennoù';
+$labels['htmltoggle'] = 'HTML';
+$labels['plaintoggle'] = 'testenn kriz';
+$labels['name'] = 'Anv da ziskouez';
+$labels['firstname'] = 'Raganv';
+$labels['surname'] = 'Anv';
+$labels['email'] = 'Postel elektronek';
+$labels['addcontact'] = 'Ouzhpennañ an darempred diuzet en hor c\'harned chomlec\'hioù';
+$labels['editcontact'] = 'Cheñch an darempred';
+$labels['edit'] = 'Cheñch';
+$labels['cancel'] = 'Nullañ';
+$labels['save'] = 'Gwarediñ';
+$labels['delete'] = 'Dilemel';
+$labels['newcontact'] = 'Krouiñ un darempred nevez';
+$labels['deletecontact'] = 'Dilemel an darempredoù diuzet';
+$labels['composeto'] = 'Skrivañ ur c\'hemennad ouzh';
+$labels['contactsfromto'] = 'Darempredoù eus $from ouzh $to war $count';
+$labels['print'] = 'Moulañ';
+$labels['export'] = 'Ezporzhiañ';
+$labels['previouspage'] = 'Diskouez pajenn a-raok';
+$labels['firstpage'] = 'Gwelout ar bajenn gentañ';
+$labels['nextpage'] = 'Diskouez pajenn da heul';
+$labels['lastpage'] = 'Gwelout ar bajenn diwezhañ';
+$labels['groups'] = 'Strolladoù';
+$labels['personaladrbook'] = 'Chomlec\'h personel';
+$labels['settingsfor'] = 'Arventennoù evit';
+$labels['preferences'] = 'Dibarzhioù';
+$labels['userpreferences'] = 'Dibarzhioù implijer';
+$labels['editpreferences'] = 'Cheñch dibarzhioù implijer';
+$labels['identities'] = 'Identelezhioù';
+$labels['manageidentities'] = 'Merañ an identelezhioù evit ar c\'hont-se';
+$labels['newidentity'] = 'Identelezh nevez';
+$labels['newitem'] = 'Elfenn nevez';
+$labels['edititem'] = 'Cheñch an elfenn';
+$labels['setdefault'] = 'Arventennoù dre ziouer';
+$labels['language'] = 'Yezh';
+$labels['timezone'] = 'Gwerzhid-eur';
+$labels['pagesize'] = 'Niver a linenn dre bajenn';
+$labels['signature'] = 'Sinadur';
+$labels['dstactive'] = 'Eur an hañv';
+$labels['htmleditor'] = 'Sevel ur c\'hemennad er furmad HTML';
+$labels['htmlsignature'] = 'Sinadur HTML';
+$labels['previewpane'] = 'Diskouez panel alberz';
+$labels['autosavedraft'] = 'Gwarediñ emgefre brouilhedoù';
+$labels['everynminutes'] = 'Bep $n munutoù';
+$labels['never'] = 'ebet';
+$labels['folder'] = 'Renkell';
+$labels['folders'] = 'Renkelloù';
+$labels['foldername'] = 'Anv ar renkell';
+$labels['subscribed'] = 'Koumananer';
+$labels['create'] = 'Krouiñ';
+$labels['createfolder'] = 'Krouiñ ur renkell nevez';
+$labels['rename'] = 'Adanviñ';
+$labels['renamefolder'] = 'Adanviñ ar renkell';
+$labels['deletefolder'] = 'Dilemel ar renkell';
+$labels['managefolders'] = 'Aozañ ar renkelloù';
+$labels['sortby'] = 'Rummañ dre';
+$labels['sortasc'] = 'Rumm diagentad';
+$labels['sortdesc'] = 'Rumm diskennad';
+
+?>
diff --git a/program/localization/br/messages.inc b/program/localization/br/messages.inc
new file mode 100644 (file)
index 0000000..1d71c18
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+/*
+
+ +-----------------------------------------------------------------------+
+ | language/bzg/messages.inc                                              |
+ |                                                                       |
+ | Language file of the RoundCube Webmail client                         |
+ | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: aldweb <info@aldweb.com>                                      |
+ |         Pierre HAEGELI <pierre@haegeli.net>                           |
+ |         Mickaël Wolff <rcw@lupusmic.org>                              |
+ +-----------------------------------------------------------------------+
+
+ @version $Id$
+
+*/
+
+$messages = array();
+$messages['loginfailed'] = 'Fazi dilesadur';
+$messages['cookiesdisabled'] = 'N\'eus ket c\'hoant toupinoù Hor merder';
+$messages['sessionerror'] = 'Direizh eo hoc\'h dalc\'h pe echu eo';
+$messages['imaperror'] = 'Fazi kevreadur ouzh ar servijer IMAP';
+$messages['nomessagesfound'] = 'Kemennadoù ebet er voest lizhiri';
+$messages['loggedout'] = 'Digevreet hoc\'h eus mat. Kenavo !';
+$messages['mailboxempty'] = 'Boest lizhiri dileun';
+$messages['loading'] = 'O kargañ...';
+$messages['loadingdata'] = 'O kargañ roadennoù...';
+$messages['checkingmail'] = 'O Gwiriañ kemennadoù nevez...';
+$messages['sendingmessage'] = 'O kas ar c\'hemennad...';
+$messages['messagesent'] = 'Kaset eo mat hoc\'h c\'hemennad';
+$messages['savingmessage'] = 'O gwarediñ ar c\'hemennad...';
+$messages['messagesaved'] = 'Kemennad gwaredet dindan Brouilhedoù';
+$messages['successfullysaved'] = 'Gwarediñ graet';
+$messages['addedsuccessfully'] = 'Darempred ouzhpennet er c\'harned chomlec\'hioù';
+$messages['contactexists'] = 'Bout a ra un darempred gant memes postel elektronek';
+$messages['blockedimages'] = 'Evit gwarantiñ hoc\'h buhez prevez, stanket eo bet skeudennoù pell er c\'hemennad-se.';
+$messages['encryptedmessage'] = 'Rineget eo ar c\'hemennad, ha ne c\'hall ket bezañ diskouez. Ma Digarezit !';
+$messages['nocontactsfound'] = 'N\'eo ket bet kavet darempred ebet';
+$messages['contactnotfound'] = 'N\'eo ket bet kavet an darempred goulennet';
+$messages['sendingfailed'] = 'N\'eo ket bet kaset ar c\'hemennad';
+$messages['errorsaving'] = 'Fazi en deus graet reuz en hoc\'h gwarediñ';
+$messages['errormoving'] = 'N\'eus ket tu da zilec\'hiañ ar c\'hemennad';
+$messages['errordeleting'] = 'N\'eus ket tu da zilemel ar c\'hemennad';
+$messages['deletecontactconfirm'] = 'C\'hoant hoc\'h eus da zilemel an darempred(où) diuzet ?';
+$messages['deletemessagesconfirm'] = 'C\'hoant hoc\'h eus da zilemel ar c\'hemennad(où) diuzet ?';
+$messages['deletefolderconfirm'] = 'C\'hoant hoc\'h eus da skarzhañ ar renkell-se ?';
+$messages['purgefolderconfirm'] = 'C\'hoant hoc\'h eus da skarzhañ an holl kemennad eus ar renkell-se ?';
+$messages['formincomplete'] = 'N\'eo ket leuniet ar furmskrid penn-da-benn';
+$messages['noemailwarning'] = 'Termenit ur postel elektronek mat mar plij ganeoc\'h';
+$messages['nonamewarning'] = 'Termenit un anv mar plij ganeoc\'h';
+$messages['nopagesizewarning'] = 'Termenit ur ment pajenn mar plij ganeoc\'h';
+$messages['norecipientwarning'] = 'Ouzhpennit ur resever da nebeutañ mar plij ganeoc\'h';
+$messages['nosubjectwarning'] = 'Dileun eo ar maezienn « Sujed » . C\'hoant hoc\'h eus da leuniañ anezhiñ diouzhtu ?';
+$messages['nobodywarning'] = 'Kas ar c\'hemennad hep testenn ?';
+$messages['notsentwarning'] = 'N\'eo ket bet kaset ar c\'hemennad. C\'hoant hoc\'h eus dilezel ar c\'hemennad-se ?';
+$messages['noldapserver'] = 'Dizuit ur servijer LDAP evit ar glask';
+$messages['nocontactsreturned'] = 'Darempred ebet kavet';
+$messages['nosearchname'] = 'Skrivit un anv darempred pe ur postel elektronek';
+$messages['searchsuccessful'] = '$nr kemennad kavet';
+$messages['searchnomatch'] = 'Disoc\'h ebet gant ar glask';
+$messages['searching'] = 'O klask...';
+$messages['checking'] = 'O gwiriañ...';
+$messages['nospellerrors'] = 'Fazi ebet kavet';
+$messages['folderdeleted'] = 'Renkell skarzhet';
+$messages['deletedsuccessfully'] = 'Dilemet mat';
+$messages['converting'] = 'O tilemel furmaozañ...';
+$messages['messageopenerror'] = 'N\'us ket tu da gargañ ar c\'hemennad adalek ar servijer';
+$messages['fileuploaderror'] = 'Fazi o treuzkas ar restr';
+$messages['filesizeerror'] = 'Re vras eo ar restr treuzkaset $size';
+$messages['copysuccess'] = 'Kopiañ mat $nr chomlec\'h';
+$messages['copyerror'] = 'Ne c\'hall ket kopiañ chomlec\'hioù';
+$messages['sourceisreadonly'] = 'Lenn hepken eo an tarzh chomlec\'h se';
+$messages['errorsavingcontact'] = 'Ne c\'haller ket gwarediñ chomlec\'h darempred';
+
+?>
index 1fe14afe566f5a2862c734b1c6b51441712a082e..f01248f21cb72b4bc0cdf2c3d90fa1e821b6be53 100644 (file)
@@ -13,7 +13,7 @@
  | Author: Begzudin Omerovic <Begzudin.Omerovic@gmail.com>               |
  +-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+ @version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -213,7 +213,6 @@ $labels['htmleditor']= 'Pisi HTML poruke';
 $labels['htmlsignature'] ='HTML potpis';
 $labels['previewpane'] ='Pokaži prethodu poruku';
 $labels['autosavedraft'] ='Automatski spasi predlozak';
-$labels['everynminutes'] ='svakih $n minuta';
 $labels['never'] ='nikada';
 
 $labels['folder']  = 'Fascikla';
index ae42f205f003026734e953801cced62c912f8427..479ae171bb092443a002ad976f5a6d01b7e08ac6 100644 (file)
@@ -14,7 +14,7 @@
 |         Simo <sim6@graciasensefils.net>                               |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
@@ -117,12 +117,15 @@ $labels['markread'] = 'Com a llegits';
 $labels['markunread'] = 'Com a no llegits';
 $labels['markflagged'] = 'Com marcat';
 $labels['markunflagged'] = 'Com no marcat';
+$labels['messageactions'] = 'Més accions...';
 $labels['select'] = 'Seleccionar';
 $labels['all'] = 'Tots';
 $labels['none'] = 'Cap';
 $labels['unread'] = 'No llegits';
 $labels['flagged'] = 'Marcat';
 $labels['unanswered'] = 'No respost';
+$labels['deleted'] = 'Esborrat';
+$labels['invert'] = 'Invertir';
 $labels['filter'] = 'Filtre';
 $labels['compact'] = 'Compacta';
 $labels['empty'] = 'Buida';
@@ -132,8 +135,12 @@ $labels['unknown'] = 'desconegut';
 $labels['unlimited'] = 'il·limitat';
 $labels['quicksearch'] = 'Cerca ràpida';
 $labels['resetsearch'] = 'Neteja cerca';
+$labels['searchmod'] = 'Cercar modificadors';
+$labels['msgtext'] = 'Missatge sencer';
 $labels['openinextwin'] = 'Obrir a una nova finestra';
+$labels['emlsave'] = 'Descarregar (.eml)';
 $labels['compose'] = 'Escriure un missatge';
+$labels['editasnew'] = 'Editar com a nou';
 $labels['savemessage'] = 'Desa aquest esborrany';
 $labels['sendmessage'] = 'Enviar ara el missatge';
 $labels['addattachment'] = 'Afegir un fitxer';
@@ -232,8 +239,7 @@ $labels['fromknownsenders'] = 'de remitent conegut';
 $labels['always'] = 'sempre';
 $labels['showinlineimages'] = 'Mostra les imatges adjuntes sota el missatge';
 $labels['autosavedraft'] = 'Desar esborrany automàticament';
-$labels['everynminutes'] = 'cada $n minuts';
-$labels['keepaliveevery'] = 'cada $n minut(s)';
+$labels['everynminutes'] = 'cada $n minut(s)';
 $labels['keepalive'] = 'Comprovar nous missatges a';
 $labels['never'] = 'mai';
 $labels['messagesdisplaying'] = 'Vista de missatges';
@@ -245,6 +251,12 @@ $labels['2047folding'] = 'Complet RFC 2047 (un altre)';
 $labels['advancedoptions'] = 'Opcions avançades';
 $labels['focusonnewmessage'] = 'Enviar el focus al navegador quan hi hagi un nou missatge';
 $labels['checkallfolders'] = 'Comprovar totes les carpetes per missatges nous';
+$labels['displaynext'] = 'Mostrar el següent missatge després de esborrar-ne o moure\'n un';
+$labels['mainoptions'] = 'Opcions principals';
+$labels['section'] = 'Secció';
+$labels['maintenance'] = 'Manteniment';
+$labels['newmessage'] = 'Missatge nou';
+$labels['listoptions'] = 'Opcions de llista';
 $labels['folder'] = 'Carpeta';
 $labels['folders'] = 'Carpetes';
 $labels['foldername'] = 'Nom de carpeta';
@@ -265,4 +277,4 @@ $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
 $labels['GB'] = 'GB';
 
-?>
\ No newline at end of file
+?>
index 45f68ac529b4d387cd08e789a67ac7d0cb651b6f..01d23d974828a068429c54ecb62c3cf8a578d300 100644 (file)
@@ -14,7 +14,7 @@
 |         Simo <sim6@graciasensefils.net>                               |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
@@ -23,6 +23,8 @@ $messages['loginfailed'] = 'Contrasenya incorrecta';
 $messages['cookiesdisabled'] = 'El seu navegador no accepta cookies';
 $messages['sessionerror'] = 'La seva sessió no existeix o ha expirat';
 $messages['imaperror'] = 'Error de conexió amb el servidor IMAP';
+$messages['servererror'] = 'Error del Servidor!';
+$messages['invalidrequest'] = 'Petició invàlida! No s\'ha desat les dades.';
 $messages['nomessagesfound'] = 'No s\'han trobat missatges en aquesta bústia';
 $messages['loggedout'] = 'Ha tancat la sessió. Fins aviat!';
 $messages['mailboxempty'] = 'La bústia està buida';
@@ -46,6 +48,7 @@ $messages['errorsavingsent'] = 'Va ocòrrer un error mentre es desava el missatg
 $messages['errorsaving'] = 'Va ocòrrer un error mentre es desava';
 $messages['errormoving'] = 'No s\'ha pogut moure el missatge';
 $messages['errordeleting'] = 'No s\'ha pogut eliminar el missatge';
+$messages['errormarking'] = 'No s\'ha pogut marcar el missatge.';
 $messages['deletecontactconfirm'] = 'Realment vol suprimir el(s) contacte(s) selecionat(s)?';
 $messages['deletemessagesconfirm'] = 'Realment vol suprimir el(s) missatge(s) selecionat(s)?';
 $messages['deletefolderconfirm'] = 'Realment vol suprimir aquesta carpeta?';
@@ -95,5 +98,12 @@ $messages['importconfirm'] = '<b>S\'han importat $inserted contactes satisfactò
 $messages['opnotpermitted'] = 'Operació no permesa!';
 $messages['nofromaddress'] = 'Falta l\'adreça d\'e-mail a la identitat seleccionada';
 $messages['editorwarning'] = 'Si canvieu a l\'editor de text pla perdreu tot el format del text. Voleu continuar?';
+$messages['httpreceivedencrypterror'] = 'Ha ocorregut un error fatal de configuració. Contacta amb el teu administrador inmediatament. <b>El teu missatge no pot ser enviat.</b>';
+$messages['smtpconnerror'] = 'Error SMTP ($code): La connexió al servidor ha fallat.';
+$messages['smtpautherror'] = 'Error SMTP ($code): Identificació fallida.';
+$messages['smtpfromerror'] = 'Error SMTP ($code): No s\'ha pogut posar "$from" com a remitent';
+$messages['smtptoerror'] = 'Error SMTP ($code): No s\'ha pogut posar "$to" com a destinatari';
+$messages['smtprecipientserror'] = 'Error SMTP: No s\'ha pogut analitzar la lista de destinataris';
+$messages['smtperror'] = 'Error SMTP: $msg';
 
-?>
\ No newline at end of file
+?>
index c51c72c2b11c1906d0206eba59fc06fd58f26296..9f880dc2b7bf1525bb7cda1f499264c6e296c4c3 100644 (file)
@@ -15,7 +15,7 @@
 |        Jiri Kaderavek <jiri.kaderavek@webstep.net>                    |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2827 2009-08-02 13:32:47Z yllar $
 
 */
 
@@ -118,12 +118,15 @@ $labels['markread'] = 'Jako přečtené';
 $labels['markunread'] = 'Jako nepřečtené';
 $labels['markflagged'] = 'Jako označené';
 $labels['markunflagged'] = 'Jako neoznačené';
+$labels['messageactions'] = 'Další akce ...';
 $labels['select'] = 'Vybrat';
 $labels['all'] = 'Vše';
 $labels['none'] = 'Nic';
 $labels['unread'] = 'Nepřečtené';
 $labels['flagged'] = 'Označené';
 $labels['unanswered'] = 'Neoznačené';
+$labels['deleted'] = 'Smazané';
+$labels['invert'] = 'Převrátit';
 $labels['filter'] = 'Filtr';
 $labels['compact'] = 'Zmenšit';
 $labels['empty'] = 'Vymazat';
@@ -133,8 +136,12 @@ $labels['unknown'] = 'neznámý';
 $labels['unlimited'] = 'neomezený';
 $labels['quicksearch'] = 'Rychlé vyhledávání';
 $labels['resetsearch'] = 'Zrušit vyhledávání';
+$labels['searchmod'] = 'Parametry hledání';
+$labels['msgtext'] = 'Celá zpráva';
 $labels['openinextwin'] = 'Otevřít v novém okně';
+$labels['emlsave'] = 'Stáhnout (.eml)';
 $labels['compose'] = 'Napsat zprávu';
+$labels['editasnew'] = 'Upravit jako novou';
 $labels['savemessage'] = 'Uložit do rozepsaných';
 $labels['sendmessage'] = 'Odeslat zprávu nyní';
 $labels['addattachment'] = 'Přidat přílohu';
@@ -234,7 +241,6 @@ $labels['always'] = 'vždy';
 $labels['showinlineimages'] = 'Zobrazovat připojené obrázky pod textem';
 $labels['autosavedraft'] = 'Automaticky uložit rozepsané zprávy';
 $labels['everynminutes'] = 'každých $n minut';
-$labels['keepaliveevery'] = 'každých $n minut';
 $labels['keepalive'] = 'Zkontrolovat nové zprávy';
 $labels['never'] = 'nikdy';
 $labels['messagesdisplaying'] = 'Zobrazování zpráv';
@@ -246,6 +252,7 @@ $labels['2047folding'] = 'Podle RFC 2047 (ostatní)';
 $labels['advancedoptions'] = 'Pokročilá nastavení';
 $labels['focusonnewmessage'] = 'Aktivovat okno prohlížeče při príchozí zprávě';
 $labels['checkallfolders'] = 'Kontrolovat nové zprávy ve všech složkách';
+$labels['displaynext'] = 'Zobrazit další zprávu po smazání/přesunu zprávy';
 $labels['folder'] = 'Složka';
 $labels['folders'] = 'Složky';
 $labels['foldername'] = 'Jméno složky';
@@ -266,4 +273,4 @@ $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
 $labels['GB'] = 'GB';
 
-?>
+?>
\ No newline at end of file
index 49ad44e37ced85d069b3264615106cf99c1249d9..96dc00e47c51346e2a549e5669b00523a2636c23 100644 (file)
@@ -15,7 +15,7 @@
 |        Jiri Kaderavek <jiri.kaderavek@webstep.net>                    |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2827 2009-08-02 13:32:47Z yllar $
 
 */
 
@@ -24,6 +24,8 @@ $messages['loginfailed'] = 'Přihlášení selhalo';
 $messages['cookiesdisabled'] = 'Váš prohlížeč nepodporuje cookies, které jsou pro přihlášení nezbytné';
 $messages['sessionerror'] = 'Vaše přihlášení je neplatné nebo vypršelo';
 $messages['imaperror'] = 'Připojení na IMAP server selhalo';
+$messages['servererror'] = 'Chyba serveru!';
+$messages['invalidrequest'] = 'Nesprávný požadavek. Data nebyla uložena.';
 $messages['nomessagesfound'] = 'Ve schránce nebyla nalezena žádná zpráva';
 $messages['loggedout'] = 'Byli jste úspěšně odhlášeni. Nashledanou!';
 $messages['mailboxempty'] = 'Schránka je prázdná';
@@ -47,6 +49,7 @@ $messages['errorsavingsent'] = 'Nastala chyba při ukládání odeslané zprávy
 $messages['errorsaving'] = 'Vyskytla se chyba při ukládání';
 $messages['errormoving'] = 'Nemohu přesunout zprávu';
 $messages['errordeleting'] = 'Nemohu smazat zprávu';
+$messages['errormarking'] = 'Zpráva nelze označit';
 $messages['deletecontactconfirm'] = 'Opravdu chcete smazat označené kontakty?';
 $messages['deletemessagesconfirm'] = 'Opravdu chcete smazat označené zprávy?';
 $messages['deletefolderconfirm'] = 'Chcete opravdu smazat tento adresář?';
@@ -96,5 +99,12 @@ $messages['importconfirm'] = '<b>Úspěšně naimportováno $inserted kontaktů,
 $messages['opnotpermitted'] = 'Operace není povolena!';
 $messages['nofromaddress'] = 'Chybějící e-mailová adresa v označeném profilu';
 $messages['editorwarning'] = 'Přepnutím do režimu prostého textu ztratíte veškeré formátování. Chcete pokračovat?';
+$messages['httpreceivedencrypterror'] = 'Vyskytla se vážná chyba v konfiguraci. Kontaktujte neprodleně administátora. <b>Vaše zpráva nemohla být odeslána.</b>        ';
+$messages['smtpconnerror'] = 'Chyba SMTP ($code): Připojení k serveru selhalo';
+$messages['smtpautherror'] = 'Chyba SMTP ($code): Chyba přihlášení';
+$messages['smtpfromerror'] = 'Chyba SMTP ($code): Nelze nastavit odesílatele "$from"';
+$messages['smtptoerror'] = 'Chyba SMTP ($code): Nelze přidat příjemce "$to"';
+$messages['smtprecipientserror'] = 'Chyba SMTP: Nelze zpracovat seznam příjemců';
+$messages['smtperror'] = 'Chyba SMTP: $msg';
 
-?>
+?>
\ No newline at end of file
index 332d2f9b29a240fac044149d60f0c1e8c78c190d..5125c7e813c3a18084f7a2ca151b2ca6b4188da4 100644 (file)
@@ -113,12 +113,15 @@ $labels['markread'] = 'Wedi eu darllen';
 $labels['markunread'] = 'Heb eu darllen';
 $labels['markflagged'] = 'Wedi eu fflagio';
 $labels['markunflagged'] = 'Heb eu fflagio';
+$labels['messageactions'] = 'Mwy o weithredoedd...';
 $labels['select'] = 'Dewis';
 $labels['all'] = 'Popeth';
 $labels['none'] = 'Dim byd';
 $labels['unread'] = 'Heb eu darllen';
 $labels['flagged'] = 'Nodwyd';
 $labels['unanswered'] = 'Heb ei ateb';
+$labels['deleted'] = 'Dilewyd';
+$labels['invert'] = 'Gwrth-droi';
 $labels['filter'] = 'Hidlo';
 $labels['compact'] = 'Crynhoi';
 $labels['empty'] = 'Gwagio';
@@ -128,8 +131,12 @@ $labels['unknown'] = 'anhysbys';
 $labels['unlimited'] = 'diderfyn';
 $labels['quicksearch'] = 'Chwiliad cyflym';
 $labels['resetsearch'] = 'Ail-osod chwiliad';
+$labels['searchmod'] = 'Addasyddion chwilio';
+$labels['msgtext'] = 'Y neges yn llawn';
 $labels['openinextwin'] = 'Agor mewn ffenest newydd';
+$labels['emlsave'] = 'Llwytho lawr (.eml)';
 $labels['compose'] = 'Ysgrifennu neges';
+$labels['editasnew'] = 'Golygu fel neges newydd';
 $labels['savemessage'] = 'Cadw\'r drafft hwn';
 $labels['sendmessage'] = 'Danfon nawr';
 $labels['addattachment'] = 'Atodi ffeil';
@@ -229,7 +236,6 @@ $labels['always'] = 'bob amser';
 $labels['showinlineimages'] = 'Dangos lluniau atodol islaw\'r neges';
 $labels['autosavedraft'] = 'Cadw drafft yn awtomatig';
 $labels['everynminutes'] = 'bob $n munud';
-$labels['keepaliveevery'] = 'bob $n munud';
 $labels['keepalive'] = 'Gofyn am negeseuon newydd ymlaen';
 $labels['never'] = 'byth';
 $labels['messagesdisplaying'] = 'Dangos Negeseuon';
@@ -241,6 +247,12 @@ $labels['2047folding'] = 'RFC 2047 llawn (arall)';
 $labels['advancedoptions'] = 'Dewisiadau uwch';
 $labels['focusonnewmessage'] = 'Ffocysu\'r porwr ar y neges newydd';
 $labels['checkallfolders'] = 'Chwilio pob ffolder am negeseuon newydd';
+$labels['displaynext'] = 'Ar ôl dileu/symud neges dangos y neges nesaf';
+$labels['mainoptions'] = 'Prif Ddewisiadau';
+$labels['section'] = 'Adran';
+$labels['maintenance'] = 'Gwaith cynnal a chadw';
+$labels['newmessage'] = 'Neges Newydd';
+$labels['listoptions'] = 'Rhestru Dewisiadau';
 $labels['folder'] = 'Ffolder';
 $labels['folders'] = 'Ffolderi';
 $labels['foldername'] = 'Enw ffolder';
index 5c92f94b52d01f03fa4310ea56aee275efb0cb3e..5ddc8a3d4ed48fc96c7ff354291eda1a8665b8f1 100644 (file)
@@ -19,6 +19,8 @@ $messages['loginfailed'] = 'Methwyd a\'ch mewngofnodi';
 $messages['cookiesdisabled'] = 'Nid yw eich porwr yn derbyn cwcis';
 $messages['sessionerror'] = 'Mae\'r sesiwn yn anghywir neu wedi dod i ben';
 $messages['imaperror'] = 'Methwyd cysylltu a\'r gweinydd IMAP';
+$messages['servererror'] = 'Gwall Gweinydd!';
+$messages['invalidrequest'] = 'Cais annilys! Ni chadwyd unrhyw wybodaeth.';
 $messages['nomessagesfound'] = 'Dim negeseuon wedi eu canfod yn y blwch hwn';
 $messages['loggedout'] = 'Rydych wedi gorffen y sesiwn yn llwyddianus. Hwyl fawr!';
 $messages['mailboxempty'] = 'Blwch yn wag';
@@ -42,6 +44,7 @@ $messages['errorsavingsent'] = 'Fe gafwyd gwall wrth cadw\'r neges ddanfonwyd';
 $messages['errorsaving'] = 'Fe gafwyd gwall wrth gadw';
 $messages['errormoving'] = 'Methwyd symud y neges';
 $messages['errordeleting'] = 'Methwyd dileu y neges';
+$messages['errormarking'] = 'Methwyd nodi y neges';
 $messages['deletecontactconfirm'] = 'Ydych chi wir am ddileu y cysylltiadau ddewiswyd?';
 $messages['deletemessagesconfirm'] = 'Ydych chi wir am ddileu y neges(euon) ddewiswyd?';
 $messages['deletefolderconfirm'] = 'Ydych chi wir am ddileu y ffolder yma?';
@@ -91,5 +94,12 @@ $messages['importconfirm'] = '<b>Fe mewnforiwyd $inserted cyswllt yn llwyddiannu
 $messages['opnotpermitted'] = 'Ni chaniateir y weithred!';
 $messages['nofromaddress'] = 'Cyfeiriad e-bost ar goll yn y personoliaeth a ddewiswyd';
 $messages['editorwarning'] = 'Mi fydd newid i\'r golygydd testun plaen yn golygu byddwch chi\'n colli unrhyw arddulliau yn eich testun. Hoffech chi barhau?';
+$messages['httpreceivedencrypterror'] = 'Fe gafwyd gwall angheuol yn y ffurfweddiad. Cysylltwch â\'ch gweinyddwr ar unwaith. <b>Nid oedd yn bosib dangos eich neges.</b>';
+$messages['smtpconnerror'] = 'Gwall SMTP ($code): Methwyd cysylltu a\'r gweinydd';
+$messages['smtpautherror'] = 'Gwall SMTP ($code): Methwyd dilysu\'r cyfrif';
+$messages['smtpfromerror'] = 'Gwall SMTP ($code): Methwyd gosod y danfonwr "$from"';
+$messages['smtptoerror'] = 'Gwall SMTP ($code): Methwyd ychwanegu derbynwr "$to"';
+$messages['smtprecipientserror'] = 'Gwall SMTP: Nid oedd yn bosib darllen y rhestr o dderbynnwyr';
+$messages['smtperror'] = 'Gwall SMTP: $msg';
 
 ?>
index c6db21f82935f41b0c4fba974ab5587e66c2fe26..9f8bee63d5c6c3577749edbdbba0bcb10aa4db8e 100644 (file)
@@ -14,7 +14,7 @@
 |         Søren Aggeboe <soren@aggeboe.dk>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -232,7 +232,6 @@ $labels['always'] = 'altid';
 $labels['showinlineimages'] = 'Vis vedhæftede billeder under beskeden';
 $labels['autosavedraft'] = 'Gem kladde automatisk';
 $labels['everynminutes'] = 'hver $n. minut';
-$labels['keepaliveevery'] = 'hver $n. minut';
 $labels['never'] = 'aldrig';
 $labels['messagesdisplaying'] = 'Viser beskeder';
 $labels['messagescomposition'] = 'Skriver nye beskeder';
@@ -264,4 +263,3 @@ $labels['MB'] = 'MB';
 $labels['GB'] = 'GB';
 
 ?>
-
index 59c4ae6f9877dfa18490db7d581b5bfb3323b056..56f4ef446adf25d7e9d84af53c8fe713030e5d7b 100644 (file)
@@ -14,7 +14,7 @@
 |         Søren Aggeboe <soren@aggeboe.dk>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: messages.inc 2494 2009-05-17 11:56:53Z yllar $
 
 */
 
@@ -97,4 +97,3 @@ $messages['nofromaddress'] = 'Der mangler en email-adresse i den valgte identite
 $messages['editorwarning'] = 'Al formatering af teksten forsvinder, hvis der skiftes til ren tekst. Vil du fortsætte?';
 
 ?>
-
index f69b031e53a1096e470f1570af847bd89168af4d..ebe538af92e9682b7b68bdd9e739408ceabd43a1 100644 (file)
@@ -14,7 +14,7 @@
 | Corrections: Alexander Stiebing <ja.stiebing[NOSPAM]@web.de>          |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2316 2009-02-27 10:54:17Z thomasb $
+@version $Id: labels.inc 2854 2009-08-12 11:00:13Z thomasb $
 
 */
 
@@ -101,7 +101,7 @@ $labels['replytoallmessage'] = 'Antwort an Absender und alle Empfänger verfasse
 $labels['forwardmessage'] = 'Nachricht weiterleiten';
 $labels['deletemessage'] = 'Nachricht löschen';
 $labels['movemessagetotrash'] = 'Nachricht in den Papierkorb verschieben';
-$labels['printmessage'] = 'Diese Nachricht drucken';
+$labels['printmessage'] = 'Nachricht drucken';
 $labels['previousmessage'] = 'Vorherige Nachricht anzeigen';
 $labels['previousmessages'] = 'Vorherige Nachrichten anzeigen';
 $labels['firstmessage'] = 'Die erste Nachricht anzeigen';
@@ -117,12 +117,15 @@ $labels['markread'] = 'Als gelesen';
 $labels['markunread'] = 'Als ungelesen';
 $labels['markflagged'] = 'Stern hinzufügen';
 $labels['markunflagged'] = 'Stern entfernen';
+$labels['messageactions']   = 'Weitere Aktionen...';
 $labels['select'] = 'Auswählen';
 $labels['all'] = 'Alle';
 $labels['none'] = 'Keine';
 $labels['unread'] = 'Ungelesene';
 $labels['flagged'] = 'Markierte';
 $labels['unanswered'] = 'Unbeantwortete';
+$labels['deleted'] = 'Gelöschte';
+$labels['invert'] = 'Umkehren';
 $labels['filter'] = 'Filter';
 $labels['compact'] = 'Packen';
 $labels['empty'] = 'Leeren';
@@ -132,8 +135,12 @@ $labels['unknown'] = 'unbekannt';
 $labels['unlimited'] = 'unlimitiert';
 $labels['quicksearch'] = 'Schnellsuche';
 $labels['resetsearch'] = 'Löschen';
+$labels['searchmod']  = 'Suchkriterien ändern';
+$labels['msgtext']  = 'Ganze Nachricht';
 $labels['openinextwin'] = 'In neuem Fenster öffnen';
+$labels['emlsave'] = 'Herunterladen (.eml)';
 $labels['compose'] = 'Neue Nachricht verfassen';
+$labels['editasnew'] = 'Als neue Nachricht öffnen';
 $labels['savemessage'] = 'Nachricht speichern';
 $labels['sendmessage'] = 'Nachricht jetzt senden';
 $labels['addattachment'] = 'Datei anfügen';
@@ -232,8 +239,7 @@ $labels['fromknownsenders'] = 'bei bekannten Absendern';
 $labels['always'] = 'immer';
 $labels['showinlineimages'] = 'Angehängte Bilder unter der Nachricht anzeigen';
 $labels['autosavedraft'] = 'Entwurf autom. speichern';
-$labels['everynminutes'] = 'alle $n Minuten';
-$labels['keepaliveevery'] = '$n Minute(n)';
+$labels['everynminutes'] = '$n Minute(n)';
 $labels['keepalive'] = 'Auf neue Nachrichten prüfen nach';
 $labels['never'] = 'nie';
 $labels['messagesdisplaying'] = 'Nachrichtendarstellung';
@@ -245,6 +251,12 @@ $labels['2047folding'] = 'Vollständig RFC 2047 kompatibel (andere)';
 $labels['advancedoptions'] = 'Erweiterte Einstellungen';
 $labels['focusonnewmessage'] = 'Fokussiere Browserfenster bei neuen Nachrichten';
 $labels['checkallfolders'] = 'Alle Ordner auf neue Nachrichten prüfen';
+$labels['displaynext'] = 'Zeige nächste Nachricht nach verschieben/löschen';
+$labels['mainoptions'] = 'Allgemein';
+$labels['section'] = 'Bereich';
+$labels['maintenance'] = 'Wartung';
+$labels['newmessage'] = 'Neue Nachrichten';
+$labels['listoptions'] = 'Listendarstellung';
 $labels['folder'] = 'Ordner';
 $labels['folders'] = 'Ordner';
 $labels['foldername'] = 'Ordnername';
index 16ea8845988305c4ce8919449926f4b667165c97..522b267b492499fd1eed4c97f6f483fe2e8f9ed2 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2755 2009-07-15 09:49:35Z thomasb $
 
 */
 
@@ -22,6 +22,8 @@ $messages['loginfailed'] = 'Login fehlgeschlagen';
 $messages['cookiesdisabled'] = 'Ihr Browser akzeptiert keine Cookies';
 $messages['sessionerror'] = 'Ihre Session ist ungültig oder abgelaufen';
 $messages['imaperror'] = 'Keine Verbindung zum IMAP Server';
+$messages['servererror'] = 'Serverfehler!';
+$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!';
 $messages['mailboxempty'] = 'Ordner ist leer';
@@ -45,6 +47,7 @@ $messages['errorsavingsent'] = 'Ein Fehler ist beim Speichern der gesendeten Nac
 $messages['errorsaving'] = 'Beim Speichern ist ein Fehler aufgetreten';
 $messages['errormoving'] = 'Nachricht konnte nicht verschoben werden';
 $messages['errordeleting'] = 'Nachricht konnte nicht gelöscht werden';
+$messages['errormarking'] = 'Nachricht konnte nicht markiert werden';
 $messages['deletecontactconfirm'] = 'Wollen Sie die ausgewählten Kontakte wirklich löschen';
 $messages['deletemessagesconfirm'] = 'Wollen Sie die ausgewählten Nachrichten wirklich löschen?';
 $messages['deletefolderconfirm'] = 'Wollen Sie diesen Ordner wirklich löschen?';
@@ -94,5 +97,11 @@ $messages['importconfirm'] = '<b>Es wurden $inserted Adressen erfolgreich import
 $messages['opnotpermitted'] = 'Operation nicht erlaubt!';
 $messages['nofromaddress'] = 'Fehlende E-Mail-Adresse in ausgewählter Identität';
 $messages['editorwarning'] = 'Beim Wechseln in den Texteditor gehen alle Textformatierungen verloren. Möchten Sie fortfahren?';
+$messages['smtpconnerror'] = 'SMTP Fehler ($code): Die Verbindung ist fehlgeschlagen';
+$messages['smtpautherror'] = 'SMTP Fehler ($code): Die Authentisierung ist fehlgeschlagen';
+$messages['smtpfromerror'] = 'SMTP Fehler ($code): Der Absender ("$from") konnte nicht gesetzt werden';
+$messages['smtptoerror'] = 'SMTP Fehler ($code): Der Empfänger ("$to") konnte nicht gesetzt werden';
+$messages['smtprecipientserror'] = 'SMTP Fehler: Die Empfängerliste konnte nicht verarbeitet werden';
+$messages['smtperror'] = 'SMTP Fehler: $msg';
 
 ?>
index ffeee629282469459c6aaaed758cc8147e65c86a..af3f19f5e540624f6080b4da65f2ca58764ebd77 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Marcel Schlesinger <info@marcel-schlesinger.de>               |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2316 2009-02-27 10:54:17Z thomasb $
+@version $Id: labels.inc 2854 2009-08-12 11:00:13Z thomasb $
 
 */
 
@@ -100,7 +100,7 @@ $labels['replytoallmessage'] = 'Antwort an Absender und alle Empfänger verfasse
 $labels['forwardmessage'] = 'Nachricht weiterleiten';
 $labels['deletemessage'] = 'Nachricht löschen';
 $labels['movemessagetotrash'] = 'Nachricht in den Papierkorb verschieben';
-$labels['printmessage'] = 'Diese Nachricht drucken';
+$labels['printmessage'] = 'Nachricht drucken';
 $labels['previousmessage'] = 'Vorherige Nachricht anzeigen';
 $labels['previousmessages'] = 'Vorherige Nachrichten anzeigen';
 $labels['firstmessage'] = 'Die erste Nachricht anzeigen';
@@ -116,12 +116,15 @@ $labels['markread'] = 'Als gelesen';
 $labels['markunread'] = 'Als ungelesen';
 $labels['markflagged'] = 'Stern hinzufügen';
 $labels['markunflagged'] = 'Stern entfernen';
+$labels['messageactions'] = 'Weitere Aktionen...';
 $labels['select'] = 'Auswählen';
 $labels['all'] = 'Alle';
 $labels['none'] = 'Keine';
 $labels['unread'] = 'Ungelesene';
 $labels['flagged'] = 'Markierte';
 $labels['unanswered'] = 'Unbeantwortete';
+$labels['deleted'] = 'Gelöschte';
+$labels['invert'] = 'Invertieren';
 $labels['filter'] = 'Filter';
 $labels['compact'] = 'Packen';
 $labels['empty'] = 'Leeren';
@@ -131,8 +134,12 @@ $labels['unknown'] = 'unbekannt';
 $labels['unlimited'] = 'unbegrenzt';
 $labels['quicksearch'] = 'Schnellsuche';
 $labels['resetsearch'] = 'Suche zurücksetzen';
+$labels['searchmod'] = 'Suchkriterien ändern';
+$labels['msgtext'] = 'Nachricht';
 $labels['openinextwin'] = 'In neuem Fenster öffnen';
+$labels['emlsave'] = 'Lokal speichern (.eml)';
 $labels['compose'] = 'Neue Nachricht verfassen';
+$labels['editasnew'] = 'Als neue Nachricht öffnen';
 $labels['savemessage'] = 'Nachricht speichern';
 $labels['sendmessage'] = 'Nachricht jetzt senden';
 $labels['addattachment'] = 'Datei anfügen';
@@ -231,8 +238,7 @@ $labels['fromknownsenders'] = 'bei bekannten Absendern';
 $labels['always'] = 'immer';
 $labels['showinlineimages'] = 'Angehängte Bilder unter der Nachricht anzeigen';
 $labels['autosavedraft'] = 'Entwurf automatisch speichern';
-$labels['everynminutes'] = 'alle $n Minuten';
-$labels['keepaliveevery'] = '$n Minute(n)';
+$labels['everynminutes'] = '$n Minute(n)';
 $labels['keepalive'] = 'Auf neue Nachrichten prüfen nach';
 $labels['never'] = 'nie';
 $labels['messagesdisplaying'] = 'Nachrichtendarstellung';
@@ -244,6 +250,12 @@ $labels['2047folding'] = 'Vollständig RFC 2047 kompatibel (andere)';
 $labels['advancedoptions'] = 'Erweiterte Einstellungen';
 $labels['focusonnewmessage'] = 'Fokussiere Browserfenster bei neuen Nachrichten';
 $labels['checkallfolders'] = 'Alle Ordner auf neue Nachrichten prüfen';
+$labels['displaynext'] = 'Zeige nächste Nachricht nach verschieben/löschen';
+$labels['mainoptions'] = 'Allgemein';
+$labels['section'] = 'Bereich';
+$labels['maintenance'] = 'Wartung';
+$labels['newmessage'] = 'Neue Nachrichten';
+$labels['listoptions'] = 'Listendarstellung';
 $labels['folder'] = 'Ordner';
 $labels['folders'] = 'Ordner';
 $labels['foldername'] = 'Ordnername';
index 23c7738724ae5ea7b70660b9215251ccd9293ff6..0437bb08a7b6bc7467bd9deb24ba7db65bb6e4a6 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Marcel Schlesinger <info@marcel-schlesinger.de>               |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2755 2009-07-15 09:49:35Z thomasb $
 
 */
 
@@ -22,6 +22,8 @@ $messages['loginfailed'] = 'Anmeldung fehlgeschlagen';
 $messages['cookiesdisabled'] = 'Ihr Browser akzeptiert keine Cookies';
 $messages['sessionerror'] = 'Ihre Session ist ungültig oder abgelaufen';
 $messages['imaperror'] = 'Keine Verbindung zum IMAP-Server';
+$messages['servererror'] = 'Serverfehler!';
+$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!';
 $messages['mailboxempty'] = 'Ordner ist leer';
@@ -45,6 +47,7 @@ $messages['errorsavingsent'] = 'Ein Fehler ist beim Speichern der gesendeten Nac
 $messages['errorsaving'] = 'Beim Speichern ist ein Fehler aufgetreten';
 $messages['errormoving'] = 'Nachricht konnte nicht verschoben werden';
 $messages['errordeleting'] = 'Nachricht konnte nicht gelöscht werden';
+$messages['errormarking'] = 'Nachricht konnte nicht markiert werden';
 $messages['deletecontactconfirm'] = 'Wollen Sie die ausgewählten Kontakte wirklich löschen?';
 $messages['deletemessagesconfirm'] = 'Wollen Sie die ausgewählten Nachrichten wirklich löschen?';
 $messages['deletefolderconfirm'] = 'Wollen Sie diesen Ordner wirklich löschen?';
@@ -94,5 +97,12 @@ $messages['importconfirm'] = '<b>Es wurden $inserted Adressen erfolgreich import
 $messages['opnotpermitted'] = 'Operation nicht erlaubt!';
 $messages['nofromaddress'] = 'Fehlende E-Mail-Adresse in ausgewählter Identität';
 $messages['editorwarning'] = 'Beim Wechseln in den Texteditor gehen alle Textformatierungen verloren. Möchten Sie fortfahren?';
+$messages['httpreceivedencrypterror'] = 'Ein fataler Konfigurationsfehler ist aufgetreten. Kontaktieren Sie bitte sofort Ihren Administrator. <b>Ihre Nachricht konnte nicht versendet werden.</b>';
+$messages['smtpconnerror'] = 'SMTP Fehler ($code): Die Verbindung ist fehlgeschlagen';
+$messages['smtpautherror'] = 'SMTP Fehler ($code): Die Authentisierung ist fehlgeschlagen';
+$messages['smtpfromerror'] = 'SMTP Fehler ($code): Der Absender ("$from") konnte nicht gesetzt werden';
+$messages['smtptoerror'] = 'SMTP Fehler ($code): Der Empfänger ("$to") konnte nicht gesetzt werden';
+$messages['smtprecipientserror'] = 'SMTP Fehler: Die Empfängerliste konnte nicht verarbeitet werden';
+$messages['smtperror'] = 'SMTP Fehler: $msg';
 
 ?>
index bffaa90b06a9035caf1c7703b413309cc823937c..c3e7c1be0c54cad58b9ed5d3cd9dd8934a2c104b 100644 (file)
@@ -14,7 +14,7 @@
  |         John Economou <hsoc@irc.gr>                                   |
  +-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+ @version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -173,7 +173,6 @@ $labels['htmleditor'] = 'Σύνθεση HTML μηνύματος';
 $labels['htmlsignature'] = 'Υπογραφή HTML';
 $labels['previewpane'] = 'Εμφάνιση προηγούμενου παραθύρου';
 $labels['autosavedraft'] = 'Αυτόματη προχείρου';
-$labels['everynminutes'] = 'κάθε $n λεπτά';
 $labels['never'] = 'ποτέ';
 $labels['folder'] = 'Φάκελος';
 $labels['folders'] = 'Φάκελοι';
index 6056fa170ea72997a3560fb8908bb08951f50b5e..ff96e5e96c6ea2e219d2cded8e2f7cd7b68d4fb6 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Weiran Zhang (weiran@weiran.co.uk)                            |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2616 2009-06-05 16:24:10Z alec $
 
 */
 
@@ -122,6 +122,8 @@ $labels['none'] = 'None';
 $labels['unread'] = 'Unread';
 $labels['flagged'] = 'Flagged';
 $labels['unanswered'] = 'Unanswered';
+$labels['deleted'] = 'Deleted';
+$labels['invert'] = 'Invert';
 $labels['filter'] = 'Filter';
 $labels['compact'] = 'Compact';
 $labels['empty'] = 'Empty';
@@ -134,6 +136,7 @@ $labels['resetsearch'] = 'Reset search';
 $labels['searchmod']  = 'Search modifiers';
 $labels['msgtext']  = 'Entire message';
 $labels['openinextwin'] = 'Open in new window';
+$labels['emlsave'] = 'Save (.eml)';
 $labels['compose'] = 'Compose a message';
 $labels['savemessage'] = 'Save this draft';
 $labels['sendmessage'] = 'Send now';
@@ -233,8 +236,7 @@ $labels['fromknownsenders'] = 'from known senders';
 $labels['always'] = 'always';
 $labels['showinlineimages'] = 'Display attached images below the message';
 $labels['autosavedraft'] = 'Automatically save draft';
-$labels['everynminutes'] = 'every $n minutes';
-$labels['keepaliveevery'] = 'every $n minute(s)';
+$labels['everynminutes'] = 'every $n minute(s)';
 $labels['keepalive'] = 'Check for new messages on';
 $labels['never'] = 'never';
 $labels['messagesdisplaying'] = 'Displaying Messages';
index 62b87c7072b6b4701525ba0d927dd6e59f09be97..08de1aaac1b495c93da3808756e81a6ae6202a10 100644 (file)
@@ -13,7 +13,7 @@
  | Author: Weiran Zhang (weiran@weiran.co.uk)                            |
  +-----------------------------------------------------------------------+
 
- @version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+ @version $Id: messages.inc 2713 2009-07-06 09:13:10Z alec $
 
 */
 
@@ -22,6 +22,7 @@ $messages['loginfailed'] = 'Login failed';
 $messages['cookiesdisabled'] = 'Your browser does not accept cookies';
 $messages['sessionerror'] = 'Your session is invalid or has expired';
 $messages['imaperror'] = 'Connection to IMAP server failed';
+$messages['servererror'] = 'Server Error!';
 $messages['nomessagesfound'] = 'No messages found in this mailbox';
 $messages['loggedout'] = 'You have successfully terminated the session. Good bye!';
 $messages['mailboxempty'] = 'Mailbox is empty';
@@ -45,6 +46,7 @@ $messages['errorsavingsent'] = 'An error occurred while saving sent message';
 $messages['errorsaving'] = 'An error occurred while saving';
 $messages['errormoving'] = 'Could not move the message';
 $messages['errordeleting'] = 'Could not delete the message';
+$messages['errormarking'] = 'Could not mark the message';
 $messages['deletecontactconfirm'] = 'Do you really want to delete the selected contact(s)?';
 $messages['deletemessagesconfirm'] = 'Do you really want to delete the selected message(s)?';
 $messages['deletefolderconfirm'] = 'Do you really want to delete this folder?';
@@ -94,5 +96,12 @@ $messages['importconfirm'] = '<b>Successfully imported $inserted contacts, $skip
 $messages['opnotpermitted'] = 'Operation not permitted!';
 $messages['nofromaddress'] = 'Missing e-mail address in selected identity';
 $messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
+$messages['httpreceivedencrypterror'] = 'A fatal configuration error occurred. Contact your administrator immediately. <b>Your message can not be sent.</b>';
+$messages['smtpconnerror'] = 'SMTP Error ($code): Connection to server failed';
+$messages['smtpautherror'] = 'SMTP Error ($code): Authentication failed';
+$messages['smtpfromerror'] = 'SMTP Error ($code): Failed to set sender "$from"';
+$messages['smtptoerror'] = 'SMTP Error ($code): Failed to add recipient "$to"';
+$messages['smtprecipientserror'] = 'SMTP Error: Unable to parse recipients list';
+$messages['smtperror'] = 'SMTP Error: $msg';
 
 ?>
index d8d05a18e02bdffd9f1bbf5c3a87d9a2a1f011a6..b6b8bb4230c70102a38c9972cc4f768412d07e52 100644 (file)
@@ -13,7 +13,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- @version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+ @version $Id: labels.inc 2831 2009-08-03 18:42:57Z alec $
 
 */
 
@@ -29,7 +29,7 @@ $labels['login']     = 'Login';
 // taskbar
 $labels['logout']   = 'Logout';
 $labels['mail']     = 'E-Mail';
-$labels['settings'] = 'Personal Settings';
+$labels['settings'] = 'Settings';
 $labels['addressbook'] = 'Address Book';
 
 // mailbox names
@@ -140,8 +140,9 @@ $labels['viewsource']       = 'Show source';
 $labels['markmessages']     = 'Mark messages';
 $labels['markread']         = 'As read';
 $labels['markunread']       = 'As unread';
-$labels['markflagged']         = 'As flagged';
-$labels['markunflagged']       = 'As unflagged';
+$labels['markflagged']      = 'As flagged';
+$labels['markunflagged']    = 'As unflagged';
+$labels['messageactions']   = 'More actions...';
 
 $labels['select'] = 'Select';
 $labels['all'] = 'All';
@@ -149,6 +150,8 @@ $labels['none'] = 'None';
 $labels['unread'] = 'Unread';
 $labels['flagged'] = 'Flagged';
 $labels['unanswered'] = 'Unanswered';
+$labels['deleted'] = 'Deleted';
+$labels['invert'] = 'Invert';
 $labels['filter'] = 'Filter';
 
 $labels['compact'] = 'Compact';
@@ -165,9 +168,11 @@ $labels['searchmod']  = 'Search modifiers';
 $labels['msgtext']  = 'Entire message';
 
 $labels['openinextwin'] = 'Open in new window';
+$labels['emlsave'] = 'Download (.eml)';
 
 // message compose
 $labels['compose']        = 'Compose a message';
+$labels['editasnew']      = 'Edit as new';
 $labels['savemessage']    = 'Save this draft';
 $labels['sendmessage']    = 'Send now';
 $labels['addattachment']  = 'Attach a file';
@@ -288,8 +293,7 @@ $labels['fromknownsenders'] = 'from known senders';
 $labels['always'] = 'always';
 $labels['showinlineimages'] = 'Display attached images below the message';
 $labels['autosavedraft']  = 'Automatically save draft';
-$labels['everynminutes']  = 'every $n minutes';
-$labels['keepaliveevery']  = 'every $n minute(s)';
+$labels['everynminutes']  = 'every $n minute(s)';
 $labels['keepalive']  = 'Check for new messages on';
 $labels['never']  = 'never';
 $labels['messagesdisplaying'] = 'Displaying Messages';
@@ -301,6 +305,12 @@ $labels['2047folding'] = 'Full RFC 2047 (other)';
 $labels['advancedoptions'] = 'Advanced options';
 $labels['focusonnewmessage'] = 'Focus browser window on new message';
 $labels['checkallfolders'] = 'Check all folders for new messages';
+$labels['displaynext'] = 'After message delete/move display the next message';
+$labels['mainoptions'] = 'Main Options';
+$labels['section'] = 'Section';
+$labels['maintenance'] = 'Maintenance';
+$labels['newmessage'] = 'New Message';
+$labels['listoptions'] = 'List Options';
 
 $labels['folder']  = 'Folder';
 $labels['folders']  = 'Folders';
index 75473cd3bb6b9a2e1677da364188a006548ddafd..79c9f162ec9151f08c7ab822196a0abb213882fe 100644 (file)
@@ -13,7 +13,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- @version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+ @version $Id: messages.inc 2755 2009-07-15 09:49:35Z thomasb $
 
 */
 
@@ -22,6 +22,8 @@ $messages['loginfailed']  = 'Login failed';
 $messages['cookiesdisabled'] = 'Your browser does not accept cookies';
 $messages['sessionerror'] = 'Your session is invalid or expired';
 $messages['imaperror'] = 'Connection to IMAP server failed';
+$messages['servererror'] = 'Server Error!';
+$messages['invalidrequest'] = 'Invalid request! No data was saved.';
 $messages['nomessagesfound'] = 'No messages found in this mailbox';
 $messages['loggedout'] = 'You have successfully terminated the session. Good bye!';
 $messages['mailboxempty'] = 'Mailbox is empty';
@@ -45,6 +47,7 @@ $messages['errorsavingsent'] = 'An error occured while saving sent message';
 $messages['errorsaving'] = 'An error occured while saving';
 $messages['errormoving'] = 'Could not move the message';
 $messages['errordeleting'] = 'Could not delete the message';
+$messages['errormarking'] = 'Could not mark the message';
 $messages['deletecontactconfirm']  = 'Do you really want to delete the selected contact(s)?';
 $messages['deletemessagesconfirm'] = 'Do you really want to delete the selected message(s)?';
 $messages['deletefolderconfirm']  = 'Do you really want to delete this folder?';
@@ -94,5 +97,12 @@ $messages['importconfirm'] = '<b>Successfully imported $inserted contacts, $skip
 $messages['opnotpermitted'] = 'Operation not permitted!';
 $messages['nofromaddress'] = 'Missing e-mail address in selected identity';
 $messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
+$messages['httpreceivedencrypterror'] = 'A fatal configuration error occurred. Contact your administrator immediately. <b>Your message can not be sent.</b>';
+$messages['smtpconnerror'] = 'SMTP Error ($code): Connection to server failed';
+$messages['smtpautherror'] = 'SMTP Error ($code): Authentication failed';
+$messages['smtpfromerror'] = 'SMTP Error ($code): Failed to set sender "$from"';
+$messages['smtptoerror'] = 'SMTP Error ($code): Failed to add recipient "$to"';
+$messages['smtprecipientserror'] = 'SMTP Error: Unable to parse recipients list';
+$messages['smtperror'] = 'SMTP Error: $msg';
 
 ?>
index 77a6fbbdeb703889b74f144efa308643fa6fa15b..468418822db6139e95cad3d89a8cd72dc6b10ee3 100644 (file)
@@ -210,7 +210,6 @@ $labels['readwhendeleted'] = 'Marku mesaĝon kiel legita kiam forigata';
 $labels['flagfordeletion'] = 'Marku mesaĝon kiel forigita anstataŭ forigi';
 $labels['showinlineimages'] = 'Montru alfiksitajn bildojn sub la mesaĝo';
 $labels['autosavedraft'] = 'Aŭtomate savu malneton';
-$labels['everynminutes'] = 'ĉiujn $n minutojn';
 $labels['never'] = 'neniam';
 $labels['messagesdisplaying'] = 'Mesaĝoj vidigante';
 $labels['messagescomposition'] = 'Mesaĝo-verkado';
index 916acff006470179132e98db12c95eeeeff7fbb1..4191351fa682f54c78a15207eb767a7766ab98a2 100644 (file)
@@ -23,7 +23,7 @@
 
 $labels = array();
 $labels['welcome'] = 'Bienvenido a $product';
-$labels['username'] = 'Email';
+$labels['username'] = 'Nombre de usuario';
 $labels['password'] = 'Contraseña';
 $labels['server'] = 'Servidor';
 $labels['login'] = 'Entrar';
@@ -120,12 +120,14 @@ $labels['markread'] = 'Como leído';
 $labels['markunread'] = 'Como no leído';
 $labels['markflagged'] = 'Como marcado';
 $labels['markunflagged'] = 'Como no marcado';
+$labels['messageactions'] = 'Más acciones...';
 $labels['select'] = 'Elija';
 $labels['all'] = 'Todos';
 $labels['none'] = 'Ninguno';
 $labels['unread'] = 'Sin leer';
 $labels['flagged'] = 'Marcado';
 $labels['unanswered'] = 'Sin respuesta';
+$labels['invert'] = 'Invertir';
 $labels['filter'] = 'Filtrar';
 $labels['compact'] = 'Compactar';
 $labels['empty'] = 'Vaciar';
@@ -135,7 +137,10 @@ $labels['unknown'] = 'desconocido';
 $labels['unlimited'] = 'sin límite';
 $labels['quicksearch'] = 'Búsqueda rápida';
 $labels['resetsearch'] = 'Reajustar la búsqueda';
+$labels['searchmod'] = 'Opciones de búsqueda';
+$labels['msgtext'] = 'Mensaje completo';
 $labels['openinextwin'] = 'Abrir en ventana nueva';
+$labels['emlsave'] = 'Guardar (.eml)';
 $labels['compose'] = 'Escribir un mensaje';
 $labels['savemessage'] = 'Guardar como borrador';
 $labels['sendmessage'] = 'Enviar ahora el mensaje';
@@ -156,7 +161,7 @@ $labels['high'] = 'Alto';
 $labels['highest'] = 'Altísimo';
 $labels['nosubject'] = '(sin asunto)';
 $labels['showimages'] = 'Mostrar imágenes';
-$labels['alwaysshow'] = 'Siempre mostratr imágenes de $sender';
+$labels['alwaysshow'] = 'Siempre mostrar imágenes de $sender';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Texto';
 $labels['savesentmessagein'] = 'Guardar mensaje enviado en';
@@ -179,7 +184,7 @@ $labels['edit'] = 'Editar';
 $labels['cancel'] = 'Cancelar';
 $labels['save'] = 'Guardar';
 $labels['delete'] = 'Eliminar';
-$labels['newcontact'] = 'Añador nuevo contacto';
+$labels['newcontact'] = 'Añadir nuevo contacto';
 $labels['deletecontact'] = 'Eliminar contactos seleccionados';
 $labels['composeto'] = 'Enviar mensaje a';
 $labels['contactsfromto'] = 'Contactos $from a $to de $count';
@@ -196,7 +201,7 @@ $labels['import'] = 'Importar';
 $labels['importcontacts'] = 'Importar contactos';
 $labels['importfromfile'] = 'Importar desde el archivo:';
 $labels['importreplace'] = 'Reemplazar completamente la lista de contactos';
-$labels['importtext'] = 'Puede importar contactos desde una lista existente.<br/>Actualmente soportamos la importación de contactos en formato <a href="http://es.wikipedia.org/wiki/VCard">vCard</a>.';
+$labels['importtext'] = 'Puede importar contactos desde una lista existente.<br/>Actualmente sólo soportamos el formato <a href="http://es.wikipedia.org/wiki/VCard">vCard</a>.';
 $labels['done'] = 'Hecho';
 $labels['settingsfor'] = 'Configuración para';
 $labels['preferences'] = 'Preferencias';
@@ -227,7 +232,7 @@ $labels['mdnrequests'] = 'Notificaciones de envío';
 $labels['askuser'] = 'preguntar al usuario';
 $labels['autosend'] = 'enviar automáticamente';
 $labels['ignore'] = 'ignorar';
-$labels['readwhendeleted'] = 'Marcar el mensage como leido al borrarlo';
+$labels['readwhendeleted'] = 'Marcar el mensage como leído al borrarlo';
 $labels['flagfordeletion'] = 'Marcar el mensage para borrarse en vez de borrarlo';
 $labels['skipdeleted'] = 'No mostrar mensajes eliminados';
 $labels['showremoteimages'] = 'Mostrar imágenes remotas';
@@ -235,16 +240,15 @@ $labels['fromknownsenders'] = 'de remitentes conocidos';
 $labels['always'] = 'siempre';
 $labels['showinlineimages'] = 'Mostrar imágenes adjuntas debajo del mensaje';
 $labels['autosavedraft'] = 'Guardar borrador automáticamente';
-$labels['everynminutes'] = 'cada $n minutos';
-$labels['keepaliveevery'] = 'cada $n minutos(s)';
+$labels['everynminutes'] = 'cada $n minuto(s)';
 $labels['keepalive'] = 'Verificar si hay nuevos mensajes en';
 $labels['never'] = 'nunca';
 $labels['messagesdisplaying'] = 'Vista de mensajes';
 $labels['messagescomposition'] = 'Composición de mensajes';
 $labels['mimeparamfolding'] = 'Nombre de adjuntos';
-$labels['2231folding'] = 'RFC 2231 Completo (Thunderbird)';
+$labels['2231folding'] = 'RFC 2231 (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
-$labels['2047folding'] = 'RFC 2047 Completo (Otro)';
+$labels['2047folding'] = 'RFC 2047 (Otro)';
 $labels['advancedoptions'] = 'Opciones Avanzadas';
 $labels['focusonnewmessage'] = 'Traer al frente la ventana del navegador cuando haya nuevos mensajes';
 $labels['checkallfolders'] = 'Verificar todas las carpetas por nuevos mensajes';
index 206c9a0670dc47c681876fc24b06ee6d5277a212..027485bdfcf68aac0d5d1a2d72b112285f37fcc9 100644 (file)
 */
 
 $messages = array();
+$messages['loginfailed'] = 'Contraseña o nombre de usuario incorrecto';
+$messages['cookiesdisabled'] = 'Su navegador no acepta cookies';
+$messages['sessionerror'] = 'Su sesión no existe o ha expirado';
+$messages['imaperror'] = 'Error de conexión con el servidor IMAP';
+$messages['servererror'] = '¡Error en el servidor!';
+$messages['nomessagesfound'] = 'No se han encontrado mensajes en esta casilla';
+$messages['loggedout'] = 'Ha cerrado la sesión. ¡Hasta pronto!';
+$messages['mailboxempty'] = 'La casilla está vacía';
+$messages['loading'] = 'Cargando...';
+$messages['loadingdata'] = 'Cargando datos...';
+$messages['checkingmail'] = 'Verificando si hay nuevos mensajes...';
+$messages['sendingmessage'] = 'Enviando mensaje...';
+$messages['messagesent'] = 'Mensaje enviado correctamente';
+$messages['savingmessage'] = 'Guardar mensaje...';
+$messages['messagesaved'] = 'Mensaje guardado en borradores';
+$messages['successfullysaved'] = 'Guardado correctamente';
+$messages['addedsuccessfully'] = 'Contacto añadido correctamente a la libreta de direcciones';
+$messages['contactexists'] = 'Ya existe un contacto con esta dirección de correo';
+$messages['blockedimages'] = 'Para proteger su privacidad, las imágenes externas han sido bloqueadas en este mensaje';
+$messages['encryptedmessage'] = 'Este es un mensaje cifrado y no puede ser mostrado. ¡Lo siento!';
+$messages['nocontactsfound'] = 'No hay contactos';
+$messages['contactnotfound'] = 'El contacto solicitado no existe';
+$messages['sendingfailed'] = 'Error al enviar mensaje';
+$messages['senttooquickly'] = 'Por favor, espere $sec segundo(s) antes de enviar este mensaje';
+$messages['errorsavingsent'] = 'Ocurrió un error al guardar el mensaje enviado';
+$messages['errorsaving'] = 'Ocurrió un error al guardar';
+$messages['errormoving'] = 'No se ha podido mover el mensaje';
+$messages['errordeleting'] = 'No se ha podido eliminar el mensaje';
+$messages['deletecontactconfirm'] = '¿Realmente quiere eliminar los contactos seleccionados?';
+$messages['deletemessagesconfirm'] = '¿Realmente quiere eliminar los mensajes seleccionados?';
+$messages['deletefolderconfirm'] = '¿Realmente quiere eliminar esta carpeta?';
+$messages['purgefolderconfirm'] = '¿Realmente quiere eliminar todos los mensajes de esta carpeta?';
+$messages['foldercreating'] = 'Creando carpeta...';
+$messages['folderdeleting'] = 'Eliminando carpeta...';
+$messages['folderrenaming'] = 'Renombrando carpeta...';
+$messages['foldermoving'] = 'Moviendo carpeta...';
+$messages['formincomplete'] = 'No se han llenado todos los campos del formulario';
+$messages['noemailwarning'] = 'Por favor, introduzca un e-mail válido';
+$messages['nonamewarning'] = 'Por favor, introduzca su nombre';
+$messages['nopagesizewarning'] = 'Por favor, introduzca un tamaño de página';
+$messages['nosenderwarning'] = 'Por favor, introduzca el e-mail del emisor';
+$messages['norecipientwarning'] = 'Por favor, introduzca al menos un destinatario';
+$messages['nosubjectwarning'] = 'El campo "Asunto" esta vacío. ¿Desea completarlo en este momento?';
+$messages['nobodywarning'] = '¿Quiere enviar este mensaje sin texto?';
+$messages['notsentwarning'] = 'El mensaje no ha sido enviado. ¿Desea descartar su mensaje?';
+$messages['noldapserver'] = 'Por favor, seleccione un servidor LDAP para buscar';
+$messages['nocontactsreturned'] = 'No se han encontrado contactos';
+$messages['nosearchname'] = 'Por favor, introduzca un nombre o la dirección de e-mail';
+$messages['searchsuccessful'] = 'Se encontraron $nr mensajes';
+$messages['searchnomatch'] = 'La búsqueda no obtuvo resultados';
+$messages['searching'] = 'Buscando...';
+$messages['checking'] = 'Revisando...';
+$messages['nospellerrors'] = 'No se encontraron errores ortográficos';
+$messages['folderdeleted'] = 'Carpeta eliminada exitosamente';
+$messages['deletedsuccessfully'] = 'Eliminado exitosamente';
+$messages['converting'] = 'Removiendo el formato del mensaje...';
+$messages['messageopenerror'] = 'No puedo descargar el mensaje del servidor';
+$messages['fileuploaderror'] = 'Error al subir archivos';
+$messages['filesizeerror'] = 'El archivo excede el tamaño maximo ($size)';
+$messages['copysuccess'] = '$nr direcciones copiadas con éxito';
+$messages['copyerror'] = 'No se pudo copiar ninguna dirección';
+$messages['sourceisreadonly'] = 'Esta dirección es de sólo-lectura';
+$messages['errorsavingcontact'] = 'No se pudo guardar la dirección de contacto';
+$messages['movingmessage'] = 'Moviendo mensaje...';
+$messages['receiptsent'] = 'La notificación de lectura se ha enviado con éxito.';
+$messages['errorsendingreceipt'] = 'No se ha podido enviar la notificación de lectura.';
+$messages['nodeletelastidentity'] = 'No se puede borrar esta identidad puesto que es la última.';
+$messages['addsubfolderhint'] = 'Esta carpeta se creará como una subcarpeta dentro de la carpeta seleccionada';
+$messages['forbiddencharacter'] = 'El nombre de la carpeta contiene un carácter prohibido';
+$messages['selectimportfile'] = 'Por favor, seleccione el archivo a subir';
+$messages['addresswriterror'] = 'La libreta de direcciones seleccionada es de solo-lectura';
+$messages['importwait'] = 'Importando, aguarde por favor...';
+$messages['importerror'] = 'Falló la importación! El archivo seleccionado parece no ser un archivo del tipo vCard válido.';
+$messages['importconfirm'] = '<b>Se importaron $inserted contactos correctamente. $skipped ya existentes fueron ignorados</b>:<p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'Operación no permitida!';
+$messages['nofromaddress'] = 'El contacto seleccionado no tiene dirección de e-mail';
+$messages['editorwarning'] = 'Si cambia a texto plano se perderán todas las opciones de formato. ¿Desea continuar?';
+$messages['httpreceivedencrypterror'] = 'Ha ocurrido un error fatal de configuración. Contacte inmediatamente a su administrador. <b>Su mensaje no ha sido enviado.</b>';
 
-$messages['loginfailed']                                               = 'Contraseña incorrecta';
-$messages['cookiesdisabled']                           = 'Su navegador no acepta cookies';
-$messages['sessionerror']                                      = 'Su sesión no existe o ha expirado';
-$messages['imaperror']                                                         = 'Error de conexión con el servidor IMAP';
-$messages['nomessagesfound']                           = 'No se han encontrado mensajes en esta casilla';
-$messages['loggedout']                                                         = 'Ha cerrado la sesión. ¡Hasta pronto!';
-$messages['mailboxempty']                                      = 'La casilla está vacía';
-$messages['loading']                                                           = 'Cargando...';
-$messages['loadingdata']                                               = 'Cargando datos...';
-$messages['checkingmail']                                      = 'Verificando si hay nuevos mensajes...';
-$messages['sendingmessage']                            = 'Enviando mensaje...';
-$messages['messagesent']                                               = 'Mensaje enviado correctamente';
-$messages['savingmessage']                                     = 'Guardar mensaje...';
-$messages['messagesaved']                                      = 'Mensaje guardado en borradores';
-$messages['successfullysaved']                         = 'Guardado correctamente';
-$messages['addedsuccessfully']                         = 'Contacto añadido correctamente a la libreta de direcciones';
-$messages['contactexists']                                     = 'Ya existe un contacto con esta dirección de correo';
-$messages['blockedimages']                                     = 'Para proteger su privacidad, las imágenes externas han sido bloqueadas en este mensaje';
-$messages['encryptedmessage']                  = 'Este es un mensaje cifrado y no puede ser mostrado. ¡Lo siento!';
-$messages['nocontactsfound']                           = 'No hay contactos';
-$messages['contactnotfound']                           = 'El contacto solicitado no existe';
-$messages['sendingfailed']                                     = 'Error al enviar mensaje';
-$messages['senttooquickly']                            = 'Por favor, aguarde $sec segundo(s) antes de enviar este mensaje';
-$messages['errorsavingsent']                           = 'Ocurrió un error al guardar el mensaje enviado';
-$messages['errorsaving']                                               = 'Ocurrió un error al guardar';
-$messages['errormoving']                                               = 'No se ha podido mover el mensaje';
-$messages['errordeleting']                                     = 'No se ha podido eliminar el mensaje';
-$messages['deletecontactconfirm']              = '¿Realmente quiere eliminar los contactos seleccionados?';
-$messages['deletemessagesconfirm']     = '¿Realmente quiere eliminar los mensajes seleccionados?';
-$messages['deletefolderconfirm']               = '¿Está seguro de que quiere eliminar esta carpeta?';
-$messages['purgefolderconfirm']                = '¿Está seguro de que quiere eliminar todos los mensajes de esta carpeta?';
-$messages['foldercreating']                            = 'Creando carpeta...';
-$messages['folderdeleting']                            = 'Eliminando carpeta...';
-$messages['folderrenaming']                            = 'Renombrando carpeta...';
-$messages['foldermoving']                                      = 'Moviendo carpeta...';
-$messages['formincomplete']                            = 'No se han llenado todos los campos del formulario';
-$messages['noemailwarning']                            = 'Por favor, introduzca un e-mail válido';
-$messages['nonamewarning']                                     = 'Por favor, introduzca su nombre';
-$messages['nopagesizewarning']                         = 'Por favor, introduzca un tamaño de página';
-$messages['nosenderwarning']                           = 'Please enter sender e-mail address'; //TODO
-$messages['norecipientwarning']                = 'Por favor, introduzca al menos un destinatario';
-$messages['nosubjectwarning']                  = 'El campo "Asunto" esta vacío. ¿Desea completarlo en este momento?';
-$messages['nobodywarning']                                     = '¿Quiere enviar este mensaje sin texto?';
-$messages['notsentwarning']                            = 'El mensaje no ha sido enviado. ¿Desea descartar su mensaje?';
-$messages['noldapserver']                                      = 'Por favor, seleccione un servidor LDAP para buscar';
-$messages['nocontactsreturned']                = 'No se han encontrado contactos';
-$messages['nosearchname']                                      = 'Por favor, introduzca un nombre o la dirección de e-mail';
-$messages['searchsuccessful']                  = 'Se encontraron $nr mensajes';
-$messages['searchnomatch']                                     = 'La búsqueda no obtuvo resultados';
-$messages['searching']                                                         = 'Buscando...';
-$messages['checking']                                                  = 'Revisando...';
-$messages['nospellerrors']                                     = 'No se encontraron errores ortográficos';
-$messages['folderdeleted']                                     = 'Carpeta eliminada exitosamente';
-$messages['deletedsuccessfully']               = 'Eliminado exitosamente';
-$messages['converting']                                                = 'Removiendo el formato del mensaje...';
-$messages['messageopenerror']                  = 'No puedo descargar el mensaje del servidor';
-$messages['fileuploaderror']                           = 'Fallo en la subida de archivos';
-$messages['filesizeerror']                                     = 'El archivo excede el tamaño maximo ($size)';
-$messages['copysuccess']                                               = '$nr direcciones copiadas con éxito';
-$messages['copyerror']                                                         = 'No se pudo copiar ninguna dirección';
-$messages['sourceisreadonly']                  = 'Esta dirección es de sólo-lectura';
-$messages['errorsavingcontact']                = 'No se pudo guardar la dirección de contacto';
-$messages['movingmessage']                                     = 'Moviendo mensaje...';
-$messages['receiptsent']                                               = 'La notificación de lectura se ha enviado con éxito.';
-$messages['errorsendingreceipt']               = 'No se ha podido enviar la notificación de lectura.';
-$messages['nodeletelastidentity']      = 'No se puede borrar esta identidad puesto que es la última.';
-$messages['addsubfolderhint']                  = 'Esta carpeta se creará como una subcarpeta dentro de la carpeta seleccionada';
-$messages['forbiddencharacter']                = 'El nombre de la carpeta contiene un caracter prohibido';
-$messages['selectimportfile']                  = 'Por favor, seleccione el archivo a subir';
-$messages['addresswriterror']                  = 'La libreta de direcciones seleccionada es de solo lectura';
-$messages['importwait']                                                = 'Importando, aguarde por favor...';
-$messages['importerror']                                               = 'Falló la importación! El archivo seleccionado parece no ser un archivo del tipo vCard válido.';
-$messages['importconfirm']                                     = '<b>Se importaron $inserted contactos correctamente. $skipped ya existentes fueron ignorados</b>:<p><em>$names</em></p>'; //TODO: ¿names?
-$messages['opnotpermitted']                            = 'Operación no permitida!';
-$messages['nofromaddress']                                     = 'Missing e-mail address in selected identity'; //TODO
-$messages['editorwarning']                                     = 'Si cambia a texto plano se perderán todas las opciones de formato. ¿Desea continuar?';
-
-?>
\ No newline at end of file
+?>
index 3eab5b27bf4de8e69d1054da48327576562db2ea..bd33497a72a279972d51620f53d891b3d1612947 100644 (file)
 |         http://www.mediaiberia.com                                    |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2319 2009-03-01 06:43:24Z alec $
+@version $Id: labels.inc 2756 2009-07-15 19:31:05Z yllar $
 
 */
 
 $labels = array();
-// login page
 $labels['welcome'] = 'Bienvenido a $product';
 $labels['username'] = 'Nombre de usuario';
 $labels['password'] = 'Contraseña';
 $labels['server'] = 'Servidor';
 $labels['login'] = 'Entrar';
-
-// taskbar
 $labels['logout'] = 'Cerrar sesión';
 $labels['mail'] = 'Correo';
 $labels['settings'] = 'Configuración';
 $labels['addressbook'] = 'Contactos';
-
-// mailbox names
 $labels['inbox'] = 'Entrada';
 $labels['drafts'] = 'Borradores';
 $labels['sent'] = 'Enviados';
 $labels['trash'] = 'Papelera';
 $labels['junk'] = 'Basura';
-
-// message listing
 $labels['subject'] = 'Asunto';
 $labels['from'] = 'Remitente';
 $labels['to'] = 'Destinatario';
 $labels['cc'] = 'Copia';
-$labels['bcc'] = 'Bcc';
+$labels['bcc'] = 'Cco';
 $labels['replyto'] = 'Respuesta a';
 $labels['date'] = 'Fecha';
 $labels['size'] = 'Tamaño';
 $labels['priority'] = 'Prioridad';
 $labels['organization'] = 'Organización';
-
-// aliases
-$labels['reply-to'] = $labels['replyto'];
-
+$labels['reply-to'] = 'Respuesta a';
 $labels['mailboxlist'] = 'Bandejas';
 $labels['messagesfromto'] = 'Mensajes $from a $to de $count';
 $labels['messagenrof'] = 'Mensaje $nr de $count';
-
 $labels['moveto'] = 'Mover a...';
 $labels['download'] = 'Descargar';
-
 $labels['filename'] = 'Nombre del archivo';
 $labels['filesize'] = 'Tamaño del archivo';
-
 $labels['preferhtml'] = 'Prefiero HTML';
 $labels['htmlmessage'] = 'Mensaje HTML';
 $labels['prettydate'] = 'Fecha detallada';
-
 $labels['addtoaddressbook'] = 'Añadir a contactos';
-
-// weekdays short
 $labels['sun'] = 'Dom';
 $labels['mon'] = 'Lun';
 $labels['tue'] = 'Mar';
@@ -82,8 +66,6 @@ $labels['wed'] = 'Mié';
 $labels['thu'] = 'Jue';
 $labels['fri'] = 'Vie';
 $labels['sat'] = 'Sáb';
-
-// weekdays long
 $labels['sunday'] = 'Domingo';
 $labels['monday'] = 'Lunes';
 $labels['tuesday'] = 'Martes';
@@ -91,8 +73,6 @@ $labels['wednesday'] = 'Miércoles';
 $labels['thursday'] = 'Jueves';
 $labels['friday'] = 'Viernes';
 $labels['saturday'] = 'Sábado';
-
-// months short
 $labels['jan'] = 'Ene';
 $labels['feb'] = 'Feb';
 $labels['mar'] = 'Mar';
@@ -105,8 +85,6 @@ $labels['sep'] = 'Sep';
 $labels['oct'] = 'Oct';
 $labels['nov'] = 'Nov';
 $labels['dec'] = 'Dic';
-
-// months long
 $labels['longjan'] = 'Enero';
 $labels['longfeb'] = 'Febrero';
 $labels['longmar'] = 'Marzo';
@@ -119,151 +97,126 @@ $labels['longsep'] = 'Septiembre';
 $labels['longoct'] = 'Octubre';
 $labels['longnov'] = 'Noviembre';
 $labels['longdec'] = 'Diciembre';
-
 $labels['today'] = 'Hoy';
-
-// toolbar buttons
-$labels['checkmail']         = 'Revisar si hay nuevos mensajes';
-$labels['writenewmessage']   = 'Crear nuevo mensaje';
-$labels['replytomessage']    = 'Responder mensaje';
+$labels['checkmail'] = 'Revisar si hay nuevos mensajes';
+$labels['writenewmessage'] = 'Crear nuevo mensaje';
+$labels['replytomessage'] = 'Responder mensaje';
 $labels['replytoallmessage'] = 'Responder al emisor y a todos los destinatarios';
-$labels['forwardmessage']    = 'Reenviar mensaje';
-$labels['deletemessage']     = 'Eliminar mensaje';
+$labels['forwardmessage'] = 'Reenviar mensaje';
+$labels['deletemessage'] = 'Eliminar mensaje';
 $labels['movemessagetotrash'] = 'Mover mensaje a la papelera';
-$labels['printmessage']      = 'Imprimir este mensaje';
-$labels['previousmessage']   = 'Mostrar mensaje anterior';
-$labels['previousmessages']  = 'Mostrar grupo anterior de mensajes';
-$labels['firstmessage']      = 'Mostrar primer mensaje';
-$labels['firstmessages']     = 'Mostrar primer grupo de mensajes';
-$labels['nextmessage']       = 'Mostrar siguente mensaje';
-$labels['nextmessages']      = 'Mostrar siguente grupo de mensajes';
-$labels['lastmessage']       = 'Mostrar último mensaje';
-$labels['lastmessages']      = 'Mostrar último grupo de mensajes';
-$labels['backtolist']        = 'Volver a la lista de mensajes';
-$labels['viewsource']        = 'Mostrar código';
-$labels['markmessages']      = 'Marcar mensajes';
-$labels['markread']          = 'Como leído';
-$labels['markunread']        = 'Como no leído';
-$labels['markflagged']       = 'Como marcado';
-$labels['markunflagged']     = 'Como no marcado';
-
+$labels['printmessage'] = 'Imprimir este mensaje';
+$labels['previousmessage'] = 'Mostrar mensaje anterior';
+$labels['previousmessages'] = 'Mostrar grupo anterior de mensajes';
+$labels['firstmessage'] = 'Mostrar primer mensaje';
+$labels['firstmessages'] = 'Mostrar primer grupo de mensajes';
+$labels['nextmessage'] = 'Mostrar siguente mensaje';
+$labels['nextmessages'] = 'Mostrar siguente grupo de mensajes';
+$labels['lastmessage'] = 'Mostrar último mensaje';
+$labels['lastmessages'] = 'Mostrar último grupo de mensajes';
+$labels['backtolist'] = 'Volver a la lista de mensajes';
+$labels['viewsource'] = 'Mostrar código';
+$labels['markmessages'] = 'Marcar mensajes';
+$labels['markread'] = 'Como leído';
+$labels['markunread'] = 'Como no leído';
+$labels['markflagged'] = 'Como marcado';
+$labels['markunflagged'] = 'Como no marcado';
+$labels['messageactions'] = 'Más acciones...';
 $labels['select'] = 'Elija';
 $labels['all'] = 'Todos';
 $labels['none'] = 'Ninguno';
 $labels['unread'] = 'Sin leer';
-$labels['flagged']    = 'Señalado';
+$labels['flagged'] = 'Señalado';
 $labels['unanswered'] = 'Sin respuesta';
+$labels['deleted'] = 'Eliminado';
+$labels['invert'] = 'Invertir';
 $labels['filter'] = 'Filtrar';
-
-$labels['compact'] = 'Compacta';
-$labels['empty'] = 'Vacía';
+$labels['compact'] = 'Compactar';
+$labels['empty'] = 'Vaciar';
 $labels['purge'] = 'Eliminar';
-
 $labels['quota'] = 'Uso de cuenta';
 $labels['unknown'] = 'desconocido';
 $labels['unlimited'] = 'sin límite';
-
 $labels['quicksearch'] = 'Búsqueda rápida';
 $labels['resetsearch'] = 'Afinar la búsqueda';
-
+$labels['searchmod'] = 'Opciones de búsqueda';
+$labels['msgtext'] = 'Mensaje completo';
 $labels['openinextwin'] = 'Abrir en nueva ventana';
-
-// message compose
+$labels['emlsave'] = 'Guardar (.eml)';
 $labels['compose'] = 'Escribir un mensaje';
+$labels['editasnew'] = 'Editar como nuevo';
 $labels['savemessage'] = 'Guardar como borrador';
 $labels['sendmessage'] = 'Enviar ahora el mensaje';
 $labels['addattachment'] = 'Añadir un archivo';
 $labels['charset'] = 'Codificación';
 $labels['editortype'] = 'Tipo de editor';
 $labels['returnreceipt'] = 'Acuse de recibo';
-
 $labels['checkspelling'] = 'Revisar ortografía';
 $labels['resumeediting'] = 'Continuar edición';
 $labels['revertto'] = 'Revertir a';
-
 $labels['attachments'] = 'Adjuntos';
 $labels['upload'] = 'Subir';
 $labels['close'] = 'Cerrar';
-
 $labels['low'] = 'Bajo';
 $labels['lowest'] = 'Bajísimo';
 $labels['normal'] = 'Normal';
 $labels['high'] = 'Alto';
 $labels['highest'] = 'Altísimo';
-
 $labels['nosubject'] = '(sin asunto)';
 $labels['showimages'] = 'Mostrar imágenes';
-$labels['alwaysshow'] = 'Muestra siempre imágenes de $sender';
-
+$labels['alwaysshow'] = 'Mostrar siempre imágenes de $sender';
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Texto';
 $labels['savesentmessagein'] = 'Guardar mensaje enviado en';
 $labels['dontsave'] = 'No guardar';
 $labels['maxuploadsize'] = 'Tamaño máximo permitido: $size';
-
 $labels['addcc'] = 'Añadir Cc';
-$labels['addbcc'] = 'Añadir Bcc';
+$labels['addbcc'] = 'Añadir Cco';
 $labels['addreplyto'] = 'Añadir Respuesta a';
-
-// mdn
 $labels['mdnrequest'] = 'El emisor de este mensaje desea ser notificado cuando usted lo lea. ¿Quiere enviar esta notificación?';
 $labels['receiptread'] = 'Notificación de lectura';
 $labels['yourmessage'] = 'Esta es una notificación de lectura de su mensaje';
 $labels['receiptnote'] = 'Nota: Esta notificación sólo significa que su mensaje fue mostrado en la computadora del receptor. No hay garantía de que el receptor haya leído o entendido el contenido del mensaje.';
-
-// address boook
 $labels['name'] = 'Nombre completo';
 $labels['firstname'] = 'Nombre';
 $labels['surname'] = 'Apellido';
 $labels['email'] = 'Correo';
-
 $labels['addcontact'] = 'Añadir nuevo contacto';
 $labels['editcontact'] = 'Editar contacto';
-
 $labels['edit'] = 'Editar';
 $labels['cancel'] = 'Cancelar';
 $labels['save'] = 'Guardar';
 $labels['delete'] = 'Eliminar';
-
 $labels['newcontact'] = 'Crear nuevo contacto';
 $labels['deletecontact'] = 'Eliminar contactos seleccionados';
 $labels['composeto'] = 'Enviar mensaje a';
 $labels['contactsfromto'] = 'Contactos $from a $to de $count';
 $labels['print'] = 'Imprimir';
 $labels['export'] = 'Exportar';
-$labels['exportvcards']   = 'Exportar contactos en formato vCard';
-
+$labels['exportvcards'] = 'Exportar contactos en formato vCard';
 $labels['previouspage'] = 'Mostrar grupo anterior';
 $labels['firstpage'] = 'Mostrar primer grupo';
 $labels['nextpage'] = 'Mostrar grupo siguiente';
 $labels['lastpage'] = 'Mostrar último grupo';
-
 $labels['groups'] = 'Grupos';
 $labels['personaladrbook'] = 'Direcciones personales';
-
 $labels['import'] = 'Importar';
 $labels['importcontacts'] = 'Importar contactos';
 $labels['importfromfile'] = 'Importar desde archivo:';
 $labels['importreplace'] = 'Reemplazar toda la lista de contactos';
-$labels['importtext'] = 'Puedes importar contactos de una lista existente.<br/>Puedes ver el formato soportado de datos en: <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>.';
+$labels['importtext'] = 'Puede importar contactos desde una lista existente.<br/>Actualmente sólo soportamos el formato <a href="http://es.wikipedia.org/wiki/VCard">vCard</a>.';
 $labels['done'] = 'Realizado';
-
-// settings
 $labels['settingsfor'] = 'Configuración para';
-
 $labels['preferences'] = 'Preferencias';
 $labels['userpreferences'] = 'Preferencias de usuario';
 $labels['editpreferences'] = 'Editar preferencias de usuario';
-
 $labels['identities'] = 'Identidades';
 $labels['manageidentities'] = 'Gestionar identidades para esta cuenta';
 $labels['newidentity'] = 'Nueva identidad';
-
 $labels['newitem'] = 'Nuevo';
 $labels['edititem'] = 'Editar';
-
 $labels['setdefault'] = 'Seleccionar opción por defecto';
-$labels['autodetect']  = 'Auto';
+$labels['autodetect'] = 'Automático';
 $labels['language'] = 'Idioma';
 $labels['timezone'] = 'Zona horaria';
 $labels['pagesize'] = 'Filas por página';
@@ -290,20 +243,18 @@ $labels['fromknownsenders'] = 'de remitentes conocidos';
 $labels['always'] = 'siempre';
 $labels['showinlineimages'] = 'Mostrar imágenes adjuntas debajo del mensaje';
 $labels['autosavedraft'] = 'Guardar borrador automáticamente';
-$labels['everynminutes'] = 'cada $n minutos';
-$labels['keepaliveevery']  = 'cada $n minuto(s)';
-$labels['keepalive']  = 'Comprobar mensajes en línea';
+$labels['everynminutes'] = 'cada $n minuto(s)';
+$labels['keepalive'] = 'Comprobar mensajes en línea';
 $labels['never'] = 'nunca';
 $labels['messagesdisplaying'] = 'Vista de mensajes';
 $labels['messagescomposition'] = 'Composición de mensajes';
 $labels['mimeparamfolding'] = 'Nombres de archivos adjuntos';
-$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
+$labels['2231folding'] = 'RFC 2231 (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
-$labels['2047folding'] = 'Full RFC 2047 (otro)';
+$labels['2047folding'] = 'RFC 2047 (otro)';
 $labels['advancedoptions'] = 'Opciones Avanzadas';
 $labels['focusonnewmessage'] = 'Activar la ventana del navegador en un mensaje nuevo';
 $labels['checkallfolders'] = 'Comprobar todas las carpetas para mensajes nuevos';
-
 $labels['folder'] = 'Bandeja';
 $labels['folders'] = 'Bandejas';
 $labels['foldername'] = 'Nombre de bandeja';
@@ -316,15 +267,12 @@ $labels['renamefolder'] = 'Renombrar bandeja';
 $labels['deletefolder'] = 'Eliminar bandeja';
 $labels['managefolders'] = 'Administrar bandejas';
 $labels['specialfolders'] = 'Bandejas Especiales';
-
 $labels['sortby'] = 'Ordenar por';
 $labels['sortasc'] = 'Orden ascendente';
 $labels['sortdesc'] = 'Orden descendente';
-
-// units
 $labels['B'] = 'B';
-$labels['KB'] = 'Kb';
-$labels['MB'] = 'Mb';
-$labels['GB'] = 'Gb';
+$labels['KB'] = 'KB';
+$labels['MB'] = 'MB';
+$labels['GB'] = 'GB';
 
 ?>
index 280e337f5a4dcc9f92a116b5238a2ecda92d1ec0..bf27835b50a22f5e0a3426813cdcd599ff854567 100644 (file)
 |                                                                       |
 +-----------------------------------------------------------------------+
 | Author: Javier Smaldone <javier@smaldone.com.ar>                      |
+|         http://www.smaldone.com.ar                                    |
 |         David Grajal Blanco <dgrabla@gmail.com>                       |
+|         http://david.grajal.net                                       |
 |         Lito Jornero <jornero@gmail.com>                              |
-|         Angel Bueno  <info@mediaiberia.com>                           |
-|          htt://www.mediaiberia.com                                    |
+|         Angel Bueno Prieto <info@mediaiberia.com>                     |
+|         http://www.mediaiberia.com                                    |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2319 2009-03-01 06:43:24Z alec $
+@version $Id: messages.inc 2756 2009-07-15 19:31:05Z yllar $
 */
 
 $messages = array();
@@ -25,6 +27,7 @@ $messages['loginfailed'] = 'Contraseña o nombre de usuario incorrecto';
 $messages['cookiesdisabled'] = 'Su navegador no acepta cookies';
 $messages['sessionerror'] = 'Su sesión no existe o ha expirado';
 $messages['imaperror'] = 'Error de conexión con el servidor IMAP';
+$messages['servererror'] = '¡Error en el servidor!';
 $messages['nomessagesfound'] = 'No se han encontrado mensajes en esta casilla';
 $messages['loggedout'] = 'Ha cerrado la sesión. ¡Hasta pronto!';
 $messages['mailboxempty'] = 'La casilla está vacía';
@@ -43,15 +46,16 @@ $messages['encryptedmessage'] = 'Este es un mensaje cifrado y no puede ser mostr
 $messages['nocontactsfound'] = 'No hay contactos';
 $messages['contactnotfound'] = 'El contacto solicitado no existe';
 $messages['sendingfailed'] = 'Error al enviar mensaje';
-$messages['senttooquickly'] = 'Por favor espere $sec seg(s). antes de mandar este mensaje';
-$messages['errorsavingsent'] = 'Un error ha ocurrido al guardar el mensaje enviado';
+$messages['senttooquickly'] = 'Por favor, espere $sec segundo(s) antes de mandar este mensaje';
+$messages['errorsavingsent'] = 'Ha ocurrido un error al guardar el mensaje enviado';
 $messages['errorsaving'] = 'Ocurrió un error mientras se guardaba';
 $messages['errormoving'] = 'No se ha podido mover el mensaje';
 $messages['errordeleting'] = 'No se ha podido eliminar el mensaje';
+$messages['errormarking'] = 'No se ha podido marcar el mensaje';
 $messages['deletecontactconfirm'] = '¿Realmente quiere eliminar los contactos seleccionados?';
 $messages['deletemessagesconfirm'] = '¿Realmente quiere eliminar los mensajes seleccionados?';
-$messages['deletefolderconfirm'] = '¿Está seguro de que quiere eliminar esta carpeta?';
-$messages['purgefolderconfirm'] = '¿Está seguro de que quiere eliminar todos los mensajes de esta carpeta?';
+$messages['deletefolderconfirm'] = '¿Realmente quiere eliminar esta carpeta?';
+$messages['purgefolderconfirm'] = '¿Realmente quiere eliminar todos los mensajes de esta carpeta?';
 $messages['foldercreating'] = 'Creando carpeta...';
 $messages['folderdeleting'] = 'Borrando carpeta...';
 $messages['folderrenaming'] = 'Renombrando carpeta...';
@@ -60,7 +64,7 @@ $messages['formincomplete'] = 'No ha rellenado todos los campos del formulario';
 $messages['noemailwarning'] = 'Por favor, introduzca un e-mail válido';
 $messages['nonamewarning'] = 'Por favor, introduzca su nombre';
 $messages['nopagesizewarning'] = 'Por favor, introduzca un tamaño de página';
-$messages['nosenderwarning'] = 'Por favor, introduzca el e-mail de quien envía';
+$messages['nosenderwarning'] = 'Por favor, introduzca el e-mail del emisor';
 $messages['norecipientwarning'] = 'Por favor, introduzca al menos un destinatario';
 $messages['nosubjectwarning'] = 'El campo "Asunto" está vacío. ¿Desea completarlo en este momento?';
 $messages['nobodywarning'] = '¿Quiere enviar este mensaje sin texto?';
@@ -77,7 +81,7 @@ $messages['folderdeleted'] = 'Carpeta eliminada exitosamente';
 $messages['deletedsuccessfully'] = 'Eliminado exitosamente';
 $messages['converting'] = 'Removiendo el formato del mensaje...';
 $messages['messageopenerror'] = 'No puedo descargar el mensaje del servidor';
-$messages['fileuploaderror'] = 'Fallo en la subida de archivos';
+$messages['fileuploaderror'] = 'Error al subir archivos';
 $messages['filesizeerror'] = 'El archivo excede el tamaño máximo ($size)';
 $messages['copysuccess'] = '$nr direcciones copiadas con éxito';
 $messages['copyerror'] = 'No se pudo copiar ninguna dirección';
@@ -92,10 +96,17 @@ $messages['forbiddencharacter'] = 'El nombre de la carpeta contiene un carácter
 $messages['selectimportfile'] = 'Por favor, seleccione un archivo para subir';
 $messages['addresswriterror'] = 'No se puede escribir la dirección de contacto seleccionada';
 $messages['importwait'] = 'Importando, espere...';
-$messages['importerror'] = '¡Fallo al Importar! Este archivo no es un formato válido vCard.';
+$messages['importerror'] = '¡Error al importar! Este archivo no es un formato válido vCard.';
 $messages['importconfirm'] = '<b>Se han insertado: $inserted contactos, y se han omitido: $skipped porque ya existían</b>:<p><em>$names</em></p>';
 $messages['opnotpermitted'] = '¡Operación no permitida!';
-$messages['nofromaddress'] = 'No se encuentra la dirección e-mail en el contacto seleccionado';
+$messages['nofromaddress'] = 'El contacto seleccionado no tiene dirección de e-mail';
 $messages['editorwarning'] = 'Cambiando a texto plano perderá el formato del mensaje. ¿Desea continuar?';
+$messages['httpreceivedencrypterror'] = 'Ha ocurrido un error fatal de configuración. Contacte inmediatamente a su administrador. <b>Su mensaje no ha sido enviado.</b>';
+$messages['smtpconnerror'] = 'Error SMTP ($code): Ha fallado la conexión al servidor';
+$messages['smtpautherror'] = 'Error SMTP ($code): Error de autenticación';
+$messages['smtpfromerror'] = 'Error SMTP ($code): No se ha podido asignar el emisor "$from"';
+$messages['smtptoerror'] = 'Error SMTP ($code): No se ha podido establecer remitente "$to"';
+$messages['smtprecipientserror'] = 'Error SMTP: No es posible analizar la lista de destinatarios';
+$messages['smtperror'] = 'Error SMTP: $msg';
 
 ?>
index e9ac149873f2e684afd09d20a041063fd148b9a2..8ee16b89601721f8edcb72c5be799461ef6fb6ab 100644 (file)
@@ -116,12 +116,15 @@ $labels['markread'] = 'Loetuks';
 $labels['markunread'] = 'Mitte loetuks';
 $labels['markflagged'] = 'Lisa lipik';
 $labels['markunflagged'] = 'Eemalda lipik';
+$labels['messageactions'] = 'Veel tegevusi...';
 $labels['select'] = 'Vali';
 $labels['all'] = 'kõik';
 $labels['none'] = 'mitte midagi';
 $labels['unread'] = 'mitte loetud';
 $labels['flagged'] = 'Märgistatud';
 $labels['unanswered'] = 'Vastamata';
+$labels['deleted'] = 'Kustutatud';
+$labels['invert'] = 'Vaheta';
 $labels['filter'] = 'Filtreeri';
 $labels['compact'] = 'Tihenda';
 $labels['empty'] = 'Tühjenda';
@@ -134,7 +137,9 @@ $labels['resetsearch'] = 'Lähtesta otsing';
 $labels['searchmod'] = 'Otsingu laiendid';
 $labels['msgtext'] = 'Kogu kirjast';
 $labels['openinextwin'] = 'Ava uues aknas';
+$labels['emlsave'] = 'Salvesta (.eml)';
 $labels['compose'] = 'Koosta kiri';
+$labels['editasnew'] = 'Muuda uuena';
 $labels['savemessage'] = 'Salvesta see mustand';
 $labels['sendmessage'] = 'Saada kiri kohe';
 $labels['addattachment'] = 'Lisa fail';
@@ -234,7 +239,6 @@ $labels['always'] = 'alati';
 $labels['showinlineimages'] = 'Näita manustatud pilte kirja all';
 $labels['autosavedraft'] = 'Salvesta mustandid automaatselt';
 $labels['everynminutes'] = 'iga $n minuti tagant';
-$labels['keepaliveevery'] = 'iga $n minuti tagant';
 $labels['keepalive'] = 'Kontrolli uusi kirju';
 $labels['never'] = 'mitte kunagi';
 $labels['messagesdisplaying'] = 'Kirjade näitamine';
@@ -246,6 +250,12 @@ $labels['2047folding'] = 'Täielik RFC 2047 (muu)';
 $labels['advancedoptions'] = 'Lisaseadistused';
 $labels['focusonnewmessage'] = 'Fokusseeri brauseri aken uue kirja korral';
 $labels['checkallfolders'] = 'Kontrolli uusi kirju kõigist kaustadest';
+$labels['displaynext'] = 'Peale kirja kustutamist/liigutamist näita järgmist kirja';
+$labels['mainoptions'] = 'Peamised valikud';
+$labels['section'] = 'Osa';
+$labels['maintenance'] = 'Hooldus';
+$labels['newmessage'] = 'Uus kiri';
+$labels['listoptions'] = 'Nimekirja valikud';
 $labels['folder'] = 'Kaust';
 $labels['folders'] = 'Kaustad';
 $labels['foldername'] = 'Kausta nimi';
index 12f4d2c857e9bccfed27b6d15ac366c1516dd434..30d85c7cddbb1bcbdec7d8204e36284ba5b343f6 100644 (file)
@@ -22,6 +22,8 @@ $messages['loginfailed'] = 'Sisselogimine ebaõnnestus';
 $messages['cookiesdisabled'] = 'Sinu veebilehitseja ei võta präänikuid vastu';
 $messages['sessionerror'] = 'Sinu sessioon on aegunud või vigane';
 $messages['imaperror'] = 'Ei õnnestunud IMAP serveriga ühendust luua';
+$messages['servererror'] = 'Serveri tõrge!';
+$messages['invalidrequest'] = 'Lubamatu päring! Andmeid ei salvestatud.';
 $messages['nomessagesfound'] = 'Postkast paistab tühi olevat';
 $messages['loggedout'] = 'Sinu sessioon on edukalt lõpetatud. Nägemiseni!';
 $messages['mailboxempty'] = 'Postkast on tühi';
@@ -45,6 +47,7 @@ $messages['errorsavingsent'] = 'Saadetud kirja salvestamisel ilmnes tõrge';
 $messages['errorsaving'] = 'Salvestamise ajal ilmnes viga';
 $messages['errormoving'] = 'Ei suutnud seda kirja liigutada';
 $messages['errordeleting'] = 'Ei suutnud seda kirja kustutada';
+$messages['errormarking'] = 'Kirja märkimine nurjus';
 $messages['deletecontactconfirm'] = 'Soovid valitud kontaktid kustutada ?';
 $messages['deletemessagesconfirm'] = 'Soovid valitud kirja(d) kustutada ?';
 $messages['deletefolderconfirm'] = 'Soovid selle kataloogi kindlasti kustutada ?';
@@ -94,5 +97,12 @@ $messages['importconfirm'] = '<b>Edukalt imporditud $inserted kontakti, $skipped
 $messages['opnotpermitted'] = 'Tegevus pole lubatud!';
 $messages['nofromaddress'] = 'Valitud identiteedil puudub e-posti aadress';
 $messages['editorwarning'] = 'Klaarteksti redaktorile lülitamine kaotab kogu teksti vorminduse. Soovid jätkata?';
+$messages['httpreceivedencrypterror'] = 'Ilmnes saatuslik konfiguratsiooniviga. Võta koheselt oma süsteemiadministraatoriga ühendust. <b> Sinu kirja polnud võimalik ära saata. </b>';
+$messages['smtpconnerror'] = 'SMTP Tõrge ($code): Serveriga ühendumine nurjus';
+$messages['smtpautherror'] = 'SMTP Tõrge ($code): Autentimine nurjus';
+$messages['smtpfromerror'] = 'SMTP Tõrge ($code): "$from" saatjaks määramine nurjus';
+$messages['smtptoerror'] = 'SMTP Tõrge ($code): "$to" saajaks määramine nurjus';
+$messages['smtprecipientserror'] = 'SMTP Tõrge: Saajate nimekirja parsimine nurjus';
+$messages['smtperror'] = 'SMTP Tõrge: $msg';
 
 ?>
index 886cd64a3c1566a5ada2ddd989ef16b2bfe1a6e9..bd2dfd3818b78d34f450e45a7c8bcbbbeab7ffc7 100644 (file)
@@ -13,7 +13,7 @@
 |         Bihar <gaurdabihar@gmail.com>                                 |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -214,7 +214,6 @@ $labels['readwhendeleted'] = 'Markatu mezua irakurrita bezala ezabatzerakoan';
 $labels['flagfordeletion'] = 'Markatu mezua ezabatzeko ezabatu beharrean';
 $labels['showinlineimages'] = 'Erakutsi erantzitako irudiak mezuaren azpian';
 $labels['autosavedraft'] = 'Zirriborroa automatikoki gorde';
-$labels['everynminutes'] = '$n minuturo';
 $labels['never'] = 'inoiz ez';
 $labels['messagesdisplaying'] = 'Mezuak ikusi';
 $labels['messagescomposition'] = 'Mezuak sortu';
index 485e220dc6b3bd48592df3b0d4071140374a44bd..aefff490127006b3f4a39738d92e6a12183a7b98 100644 (file)
@@ -232,8 +232,7 @@ $labels['fromknownsenders'] = 'از سوی فرستنده شناس';
 $labels['always'] = 'همواره';
 $labels['showinlineimages'] = 'نمایش عکس های الصاق شده در پایین پیغام';
 $labels['autosavedraft'] = 'ذخیره‌ی خودکار پیش‌نویس';
-$labels['everynminutes'] = 'دقیقه $n هر';
-$labels['keepaliveevery'] = 'دقیقه/ها $n هر';
+$labels['everynminutes'] = 'دقیقه/ها $n هر';
 $labels['keepalive'] = 'بررسی پیغام جدید روی';
 $labels['never'] = 'هرگز';
 $labels['messagesdisplaying'] = 'نمایش داده شدن پیغام ها';
diff --git a/program/localization/fa_AF/labels.inc b/program/localization/fa_AF/labels.inc
new file mode 100644 (file)
index 0000000..1fc3a01
--- /dev/null
@@ -0,0 +1,306 @@
+<?php
+
+
+
+// login page
+$labels['welcome']   = 'به اين پروژه خوش امديد';
+$labels['username']  = 'نام کاربر  ';
+$labels['password']  = 'شفر';
+$labels['server']    = 'سرور';
+$labels['login']     = 'داخل شدن ';
+
+// taskbar
+$labels['logout']   = 'خروج';
+$labels['mail']     = 'ايميل ';
+$labels['settings'] = 'تنظیمات شخصی';
+$labels['addressbook'] = 'کتاب ادرس ';
+
+// mailbox names
+$labels['inbox']  = 'نامه های ارسالي  ';
+$labels['drafts'] = 'نامه های ناتکمیل';
+$labels['sent']   = 'ارسال شده ';
+$labels['trash']  = 'اشغال دانی';
+$labels['junk']   = 'بیکاره';
+
+// message listing
+$labels['subject'] = 'مضمون ';
+$labels['from']    = 'ارسال کننده ';
+$labels['to']      = 'ګيرينده ';
+$labels['cc']      = 'تکثیر';
+$labels['bcc']     = 'تکثیر پنهان';
+$labels['replyto'] = 'جواب نامه';
+$labels['date']    = 'تاريخ ';
+$labels['size']    = 'اندازه  ';
+$labels['priority'] = 'اولویت';
+$labels['organization'] = 'تنظیمات';
+
+$labels['mailboxlist'] = 'پوشه ها';
+$labels['messagesfromto'] = 'از  مقدار پيغام به مقدار حساب شده ';
+$labels['messagenrof'] = 'از شمار پيغام های حساب شده ';
+
+$labels['moveto']   = 'انتقال بدهید به ...';
+$labels['download'] = 'داونلود کردن ';
+
+$labels['filename'] = ' نام فايل ';
+$labels['filesize'] = 'اندازه فايل';
+
+$labels['preferhtml'] = 'نشان دادن ايچ ټي ام ايل ';
+$labels['htmlmessage'] = 'پيغام ايچ ټي‌ام ايل ';
+$labels['prettydate'] = 'تاريخ های مهم ';
+
+$labels['addtoaddressbook'] = 'در کتاب ادرس علاوه نماييد ';
+
+// weekdays short
+$labels['sun'] = 'يکشنپبه ';
+$labels['mon'] = 'دوشنبه  ';
+$labels['tue'] = 'سه شنبه  ';
+$labels['wed'] = 'چهارشنبه ';
+$labels['thu'] = 'پنج شنبه  ';
+$labels['fri'] = 'جمعه ';
+$labels['sat'] = 'شنبه  ';
+
+// weekdays long
+$labels['sunday']    = 'يکشنبه ';
+$labels['monday']    = 'دوشنبه ';
+$labels['tuesday']   = 'سه شنبه ';
+$labels['wednesday'] = 'چهارشنبه  ';
+$labels['thursday']  = 'پنج شنبه  ';
+$labels['friday']    = 'جمعه  ';
+$labels['saturday']  = 'شنبه  ';
+
+// months short
+$labels['jan'] = 'جنوری';
+$labels['feb'] = 'فبروری';
+$labels['mar'] = 'مارچ';
+$labels['apr'] = 'اپریل';
+$labels['may'] = 'می';
+$labels['jun'] = 'جون';
+$labels['jul']         = 'جولایی';
+$labels['aug'] = 'آگست';
+$labels['sep'] = 'سپتمبر';
+$labels['oct'] = 'اکتوبر';
+$labels['nov'] = 'نومبر';
+$labels['dec'] = 'دسمبر';
+
+// months long
+$labels['longjan']     = 'جنوری';
+$labels['longfeb']     = 'فبروری';
+$labels['longmar']     = 'مارچ';
+$labels['longapr']     = 'اپریل';
+$labels['longmay']     = 'می';
+$labels['longjun']     = 'جون';
+$labels['longjul']     = 'جولایی';
+$labels['longaug']     = 'آگست';
+$labels['longsep']     = 'سپتمبر';
+$labels['longoct']     = 'اکتوبر';
+$labels['longnov']     = 'نومبر';
+$labels['longdec']     = 'دسمبر';
+
+$labels['today'] = 'امروز ';
+
+// toolbar buttons
+$labels['checkmail']        = 'بررسي کردن پيغام های جديد ';
+$labels['writenewmessage']  = 'ساختن پيغام جديد ';
+$labels['replytomessage']   = 'جواب دادن به پيغام ';
+$labels['replytoallmessage'] = 'به فرستنده و تمام گيرينده ها جواب بدهيد ';
+$labels['forwardmessage']   = 'فرستادن این پیام به دیگران / فارورد';
+$labels['deletemessage']    = 'حذف کردن پيغام ';
+$labels['movemessagetotrash'] = 'پيغام را به اشيآيي حذف شده منتقل نماييد ';
+$labels['printmessage']     = 'اين پيغام را چاپ کنيد ';
+$labels['previousmessage']  = 'پيغام قبلي را نشان دهيد ';
+$labels['previousmessages'] = 'دسته قبلي پيغام ها را نشان دهيد ';
+$labels['firstmessage']     = 'پيغام اولي را نشان دهيد ';
+$labels['firstmessages']    = 'دسته اولي‌پيغام ها را نشان دهيد ';
+$labels['nextmessage']      = 'پيغام بعدي رانشان دهيد ';
+$labels['nextmessages']     = 'بسته بعدی پيغام ها را نشان دهيد ';
+$labels['lastmessage']      = 'پيغام اخير را نشان دهيد ';
+$labels['lastmessages']     = 'بسته آخری پيغام ها را نشان دهيد ';
+$labels['backtolist']       = 'بازگشتن به لست پيغام ';
+$labels['viewsource']       = 'منبع / کود را نشان دهيد  ';
+$labels['markmessages']     = 'پيغام ها را نشاني کنيد ';
+$labels['markread']         = 'مانند خوانده شده ';
+$labels['markunread']       = 'مانند خوانده نشده  ';
+$labels['markflagged']         = 'مانند نشانی شده ';
+$labels['markunflagged']       = 'مانند نشانی ناشده';
+
+$labels['select'] = 'انتخاب کردن ';
+$labels['all'] = 'تمام ';
+$labels['none'] = 'هيچ کدام';
+$labels['unread'] = 'ناخوانده ';
+$labels['flagged'] = ' نشانی شده ';
+$labels['unanswered'] = 'پیامهای جواب نداده شده';
+$labels['filter'] = 'تصفیه کردن';
+
+$labels['compact'] = 'خلاصه ';
+$labels['empty'] = 'خالي ';
+$labels['purge'] = ' پاکسازي ';
+
+$labels['quota'] = '‌طريقه استعمال ديسک ';
+$labels['unknown']  = 'نامعلوم ';
+$labels['unlimited']  = 'نامعين/ نامحدود ';
+
+$labels['quicksearch']  = 'جستجوی سریع';
+$labels['resetsearch']  = 'بازنشاندن جستجو ';
+
+$labels['openinextwin'] = 'در پینجره ای جدید باز کنید';
+
+// message compose
+$labels['compose']        = 'نوشتن پیام حدید';
+$labels['savemessage']    = 'این پیش نویس را حفظ نمایید';
+$labels['sendmessage']    = 'پيغام را همين حالا ارسال کنيد ';
+$labels['addattachment']  = 'ضميمه نمودن يک فايل ';
+$labels['charset']        = 'ست کرکتر ها';
+$labels['editortype']     = 'روش تصحیح کننده / نوشتاری';
+$labels['returnreceipt']  = 'رسید برای مراجعت نامه  ';
+
+$labels['checkspelling'] = 'املا را بررسي کنيد ';
+$labels['resumeediting'] = 'ادامه / بازگشت به تصحیی کردن / نوشتن';
+$labels['revertto']      = 'رجوع کردن به ';
+
+$labels['attachments'] = 'ضميمه ها ';
+$labels['upload'] = 'اپلود کردن ';
+$labels['close']  = 'بستن ';
+
+$labels['low']     = 'کم ';
+$labels['lowest']  = 'کمترین';
+$labels['normal']  = 'عادی';
+$labels['high']    = 'عالي ';
+$labels['highest'] = 'عاليترين ';
+
+$labels['nosubject']  = 'مضمون ندارد ';
+$labels['showimages'] = 'نمايش دادن تصاوير ';
+$labels['alwaysshow'] = 'همیشه نشان بده تصاویر را از این فرسیتنده﷼';
+
+$labels['htmltoggle'] = 'ایچ تی ام ایل';
+$labels['plaintoggle'] = 'متن ساده ';
+$labels['savesentmessagein'] = 'پیام ارسال شده را ذخیره کن در';
+$labels['dontsave'] = 'ذخیره نکنید';
+$labels['maxuploadsize'] = '$sizeزیاد ترین اندازه اجازه داده شده فایل عبارت است از ';
+
+$labels['addcc'] = 'نسخیه دوم  را علاوه کنید';
+$labels['addbcc'] = 'نسخه پنهان را علاوه کنید';
+$labels['addreplyto'] = 'علاوه کردن ';
+
+// mdn
+$labels['mdnrequest'] = 'فرستانده این پیام خواهش نموده زمانیکه شما نامه را خواندید براش آگاهی داده شود آيا شما ميخواهيد که فرستنده را آګاه سازيد ';
+$labels['receiptread'] = 'بازگشت رسید (خوانده شده)';
+$labels['yourmessage'] = 'برای پيغام شما اين يک رسید بازگشت است ';
+$labels['receiptnote'] = 'يادداشت : اين رسيد شما را فقط اګاه ميسازد که پيغام به کامپیوتر گیرنده نمایش داده شده است  هیچ گارنتی وجود ندارد که گیرنده پیام این پیام را خوانده و یا مطالب آن را درک کرده باشد.';
+
+// address boook
+$labels['name']      = 'نشان دادن نام  ';
+$labels['firstname'] = 'اسم/ نام ';
+$labels['surname']   = 'اسم فاميلي / تخلص';
+$labels['email']     = 'ايميل ';
+
+$labels['addcontact'] = 'آدرس جديد را علاوه کنيد ';
+$labels['editcontact'] = 'آدرس جدید را تصحیح کنید';
+
+$labels['edit']   = 'تصحيح کردن ';
+$labels['cancel'] = 'لغو کردن/ حذف کردن ';
+$labels['save']   = 'حفظ کردن ';
+$labels['delete'] = 'حذف کردن ';
+
+$labels['newcontact']     = 'کارت تماس جديد را بسازيد ';
+$labels['deletecontact']  = 'آدرس های انتخاب شده را حذف کنيد ';
+$labels['composeto']      = 'ايمیل را نوشته کنيد به ';
+$labels['contactsfromto'] = 'از$count$to به $from آدرس ها از ';
+$labels['print']          = 'چاپ کردن  ';
+$labels['export']         = 'صادر کردن ';
+$labels['exportvcards']   = ' صادر نماییدVcardآدرس ها را به فرمت ';
+
+$labels['previouspage']   = ' بسته قبلي را نشان دهيد ';
+$labels['firstpage']      = 'بسته اولي را نشان دهيد ';
+$labels['nextpage']       = 'بسته بعدي را نشان دهيد ';
+$labels['lastpage']       = 'بسته اخير را نشان دهيد ';
+
+$labels['groups'] = ' گروه ها ';
+$labels['personaladrbook'] = 'ادرس های شخصي ';
+
+$labels['import'] = 'وارد کردن';
+$labels['importcontacts'] = 'آدرس ها را وارد نمایید';
+$labels['importfromfile'] = 'از یک فایل وارد نمایید';
+$labels['importreplace'] = 'تمام کتاب آدرس ها را عوض نمایید';
+$labels['importtext'] = 'شما میتوانید که آدرس ها را از یاک کتاب آدرس های موجوده وارد نمایید<br/>شما میتوانید که آدرس ها را به فرمت <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>وارد نمایید ';
+$labels['done'] = 'اجرا شد';
+
+// settings
+$labels['settingsfor']  = 'تنظیمات برای';
+
+$labels['preferences']  = 'ترجيحات ';
+$labels['userpreferences']  = 'ترجيحات کاربر ';
+$labels['editpreferences']  = 'تصحيح کردن ترجيحات  کاربر ';
+
+$labels['identities']  = ' شناخت ها ';
+$labels['manageidentities']  = 'اداره کردن شناسای ها برای اين آدرس ';
+$labels['newidentity']  = 'شناخت جديد ';
+
+$labels['newitem']  = 'فقره جديد  ';
+$labels['edititem']  = 'تصحيح کردن فقره';
+
+$labels['setdefault']  = 'بطور همیشگی انتخاب نمایید';
+$labels['autodetect']  = 'اتومات';
+$labels['language']  = 'لسان';
+$labels['timezone']  = ' ناحيه زمانی ';
+$labels['pagesize']  = 'تعداد سطر ها در صفحه';
+$labels['signature'] = 'امضا ';
+$labels['dstactive']  = 'Daylight saving time';
+$labels['htmleditor'] = 'پيغام ايچ ټي ام ايل رانوشته کنيد ';
+$labels['htmlsignature'] = 'امضای حساب ایمیل بشکل ایچ تی ام ال';
+$labels['previewpane'] = 'چوکات پیشنما را نشان دهید';
+$labels['skin'] = 'تمپلیت محیط کاربری';
+$labels['logoutclear'] = 'Clear Trash on logout';
+$labels['logoutcompact'] = 'Compact Inbox on logout';
+$labels['uisettings'] = 'محیط کاربر';
+$labels['serversettings'] = 'تنظیمات سرور';
+$labels['mailboxview'] = 'طرز نمایش صندوق پستی';
+$labels['mdnrequests'] = 'آگاهی های ارسال کننده';
+$labels['askuser'] = 'از کاربر بپرسید';
+$labels['autosend'] = 'پیام را بطور خودکار روان کنید';
+$labels['ignore'] = 'رد کردن';
+$labels['readwhendeleted'] = 'در هنگام حفظ پیام را خوانده شده نشانی کنید';
+$labels['flagfordeletion'] = 'Flag the message for deletion instead of delete';
+$labels['skipdeleted'] = 'پیام های حذف شده را نمایش ندهید';
+$labels['showremoteimages'] = 'Display remote inline images';
+$labels['fromknownsenders'] = 'نامه های از آدرس های شناخته شده';
+$labels['always'] = 'همیشه';
+$labels['showinlineimages'] = 'تصاویر ضمیمه شده را در پایین پیام نشان دهید.';
+$labels['autosavedraft']  = 'بصورت خودکار پیش نويس را حفظ کنيد ';
+$labels['everynminutes']  = ' دقیفه$n هر ';
+$labels['keepaliveevery']  = ' دقیفه$n هر ';
+$labels['keepalive']  = 'بررسي کردن پيغام های جديد ';
+$labels['never']  = 'هیچگاه';
+$labels['messagesdisplaying'] = 'نمایش دادن پیام ها';
+$labels['messagescomposition'] = 'ایجاد کردن پیام جدید';
+$labels['mimeparamfolding'] = 'نام های ضمیمه ها';
+$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Full RFC 2047 (دیگر ها)';
+$labels['advancedoptions'] = 'انتخاب های پیشرفته';
+$labels['focusonnewmessage'] = 'فوکس دادن پینجره مرورگر به پیام جدید';
+$labels['checkallfolders'] = 'تمام پوشه ها را بخاطر پیام های جدید بررسی کنید';
+
+$labels['folder']  = 'پوشه ';
+$labels['folders']  = 'پوشه ها';
+$labels['foldername']  = 'نام پوشه ';
+$labels['subscribed']  = 'مشترک ';
+$labels['messagecount'] = 'پيغام ها ';
+$labels['create']  = 'ایجاد کردن';
+$labels['createfolder']  = 'ایجاد پوشه جدید';
+$labels['rename'] = 'تغيير نام ';
+$labels['renamefolder'] = 'تغييرنام پوشه ';
+$labels['deletefolder']  = 'حذف کردن پوشه ';
+$labels['managefolders']  = 'اداره کردن پوشه ها ';
+$labels['specialfolders'] = 'پوشه های مخصوص';
+
+$labels['sortby'] = 'فهرست کردن توسط ';
+$labels['sortasc']  = 'فهرست کردن از طرف بالا به پايين ';
+$labels['sortdesc'] = 'فهرست کردن از طرف پايين به بالا ';
+
+// units
+$labels['B'] = 'بایت';
+$labels['KB'] = 'کیلو بایت';
+$labels['MB'] = 'میگا بایت';
+$labels['GB'] = 'گیگا بایت';
+
+?>
diff --git a/program/localization/fa_AF/messages.inc b/program/localization/fa_AF/messages.inc
new file mode 100644 (file)
index 0000000..17394ac
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+$messages['loginfailed']  = 'داخل شدن به سيستم موفق نه شد ';
+$messages['cookiesdisabled'] = 'جستجوگر شما  cookies را قبول نميکند ';
+$messages['sessionerror'] = 'جلسه شما وجود ندارد و يا هم از زمان معين آن گذشته است ';
+$messages['imaperror'] = 'وصل شدن به آیمیپ سرور موفق نشد ';
+$messages['nomessagesfound'] = 'هيچ پيغامی در اين صندوق پستي دريافت نه شد ';
+$messages['loggedout'] = 'جلسه شما بصورت مکمل فسخ شده است  خدا حافظ ';
+$messages['mailboxempty'] = 'صندوق پستي خالي است ';
+$messages['loading'] = 'در حال باز شدن  ...';
+$messages['loadingdata'] = 'در حال بار کردن دیتا';
+$messages['checkingmail'] = 'پيغام های جديد را بررسي ميکند ';
+$messages['sendingmessage'] = 'پيغام ها را ارسال ميکند ';
+$messages['messagesent'] = 'پیام موفقانه ارسال گردید';
+$messages['savingmessage'] = 'در حال حفظ کردن پیام';
+$messages['messagesaved'] = 'پيغام را به پیش نويس حفظ کرد ';
+$messages['successfullysaved'] = 'حفظ پیام موفقانه صورت گرفت';
+$messages['addedsuccessfully'] = 'آدرس بصورت مکمل در کتاب ادرس علاوه شد ';
+$messages['contactexists'] = 'يک آدرس همرا اين ايميل ادرس قبلاً وجود دارد  ';
+$messages['blockedimages'] = 'برای حفظ استقلال پيغام شما، تصاویر اجنبی این پیام بلاک شده اند ';
+$messages['encryptedmessage'] = 'اين يک پيغام مخفي است و اشکار شده نميتواند   معذرت ميخواهيم ';
+$messages['nocontactsfound'] = 'هيچ آدرسی دريافت نه شد ';
+$messages['contactnotfound'] = 'آدرس خواسته شده دريافت نه شد ';
+$messages['sendingfailed'] = 'فرستادن پيغام موفق نه شد ';
+$messages['senttooquickly'] = ' ثانیه منتظر باشید$secلطفا مدت  قبل از ارسال این پیام';
+$messages['errorsavingsent'] = 'در جريان حفظ کردن پیام ارسال شده يکاشتباه به وجود امد ';
+$messages['errorsaving'] = 'در جريان حفظ کردن يکاشتباه به وجود امد ';
+$messages['errormoving'] = 'پيغام نقل مکان شده نتوانست ';
+$messages['errordeleting'] = 'پيغام حذف شده نتوانست ';
+$messages['deletecontactconfirm']  = 'آيا واقعاً شما ميخواهيد که آدرس های انتخاب شده را حذف کنيد؟ ';
+$messages['deletemessagesconfirm'] = 'آيا واقعاً شما ميخواهيد که پيغام هاي انتخاب شده را حذف کنيد؟ ';
+$messages['deletefolderconfirm']  = 'آيا واقعاً شما ميخواهيد که اين پوشه را حذف کنيد؟ ';
+$messages['purgefolderconfirm']  = 'آيا واقعاً شما ميخواهيد  تمام پيغام های که  در اين پوشه وجود دارد حذف کنيد؟ ';
+$messages['foldercreating'] = 'در حال ایجاد پوشه';
+$messages['folderdeleting'] = 'در حال حذف پوشه';
+$messages['folderrenaming'] = 'در حال تغییر نام پوشه';
+$messages['foldermoving'] = 'در حال انتقال پوشه';
+$messages['formincomplete'] = 'فورمه بصورت مکمل خانه پري نه شده است ';
+$messages['noemailwarning'] = 'لطفاً يک ايميل ادرس موجود را داخل کنيد ';
+$messages['nonamewarning']  = 'لطفاً يک نام را داخل کنيد ';
+$messages['nopagesizewarning'] = 'لطفاً اندازه يک صفحه را داخل کنيد ';
+$messages['nosenderwarning'] = 'لطفاً ایمیل آدرس ارسال کننده را داخل کنید';
+$messages['norecipientwarning'] = 'لطفاً کم از کم يک آدرس گيرينده را نوشته / داخل کنيد ';
+$messages['nosubjectwarning']  = 'بخش مضمون خالي است  آیا میخواهید که حالا یکی آنها را درج نمایید؟.';
+$messages['nobodywarning'] = 'اين پيغام را بدون متن بفرستیم؟ ';
+$messages['notsentwarning'] = 'پيغام ارسال نه شده است   آیا میخواهید که از این نامه صرف نظر نمایید';
+$messages['noldapserver'] = 'لطفاً يک ايل دپ سرور را بخاطر جستجو انتخاب کنيد ';
+$messages['nocontactsreturned'] = 'موفق به دریافت هیچ آدرس نشدیم';
+$messages['nosearchname'] = 'لطفاً يک نام تماس و يا هم يک ايميل ادرس را داخل کنيد ';
+$messages['searchsuccessful'] = '$nr پیام دریافت شد';
+$messages['searchnomatch'] = 'جستجو گر موفق به دریافت هیچ گونه اثری نشد';
+$messages['searching'] = 'در حال جستجو';
+$messages['checking'] = 'در حال بررسی';
+$messages['nospellerrors'] = 'هيچ اشتباه املايي را دريافت نه کرد ';
+$messages['folderdeleted'] = 'پوشه موفقانه از بين رفت/ حذف گرديد ';
+$messages['deletedsuccessfully'] = "موفقانه حذف شد";
+$messages['converting'] = 'در حال از بین بردن شکل دهی و ساختار (فرمت)';
+$messages['messageopenerror'] = 'پيغام از سرور جريان کرده نتوانست ';
+$messages['fileuploaderror'] = 'اپلود کردن فايل موفق نه شد. ';
+$messages['filesizeerror'] = 'تثبیت شده میباشد$size حجم فایل آپلود شده بیشتر از حجم کلی ';
+$messages['copysuccess'] = 'آدرس ها کاپی شد. $nrموفقانه بع تعداد ';
+$messages['copyerror'] = 'هيچ يک از تماس ها را کاپي کرده نتوانست ';
+$messages['sourceisreadonly'] = 'اجازه نمامه کود / منبع این آدرس قفط خواندنی است';
+$messages['errorsavingcontact'] = 'ادرس این پیام را حفظکرده نتوانست ';
+$messages['movingmessage'] = 'ذر حال انتقال پیام...';
+$messages['receiptsent'] = 'یک رسید برای ارسال کننده این پیام فرستاده شد.';
+$messages['errorsendingreceipt'] = 'رسيد ارسال شده نتوانست  ';
+$messages['nodeletelastidentity'] = 'شما این شناخت نامه را حذف کرده نمیتوانید. این آخرین شناخت نامه شما است.';
+$messages['addsubfolderhint'] = 'این پوشه به حیث پوشه فرعی پوشه انتخاب شده فعلی ساخته خواهد شد.';
+$messages['forbiddencharacter'] = 'نام پوشه دارای یک کرکتر ممنوعه است.';
+$messages['selectimportfile'] = 'لطفاً یک فایل را برای آپلود کردن انتخاب نمایید.';
+$messages['addresswriterror'] = 'کتابچه آدرس انتخاب شده دارای اجازه نامه نوشتاری نیست.';
+$messages['importwait'] = 'در حال وارد کردن لطفا صبر کنید.';
+$messages['importerror'] = 'وارد نمودن (آدرس ها / فایل ها) موفق نشد. نیستvCard فایل آپلود شده فایل صحیح ';
+$messages['importconfirm'] = '<b>Successfully imported $inserted contacts, $skipped existing entries skipped</b>:<p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'اجازه این عملکرد را ندارید';
+$messages['nofromaddress'] = 'بخش ایمیل آدرس در شناخت نامه انتخاب شده مفقود است.';
+$messages['editorwarning'] = 'استفاده از تصحیح کننده متن ساده تمام فرمت و ساختار داده شده را از بین خواهد برد. آیا میخواهید که ادامه بدهید.';
+
+?>
index 56758fb6e1bcdbc58d0ddc5e6855292d4e71d95b..2a1643616adeef9c592f3cce9c41384fb1288ace 100644 (file)
 +-----------------------------------------------------------------------+
 | Author: Ville Alatalo <ville@alatalo.org>                             |
 |         Veljo Velling <veve@utu.fi>                                   |
+|         Jorma Tuomainen <jt@wiza.fi>                                  |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2581 2009-05-31 11:12:04Z alec $
 
 */
 
@@ -121,6 +122,9 @@ $labels['select'] = 'Valitse';
 $labels['all'] = 'Kaikki';
 $labels['none'] = 'Ei mitään';
 $labels['unread'] = 'Lukemattomat';
+$labels['flagged'] = 'Korostettu';
+$labels['unanswered'] = 'Vastaamaton';
+$labels['filter'] = 'Suodin';
 $labels['compact'] = 'Tiivistä';
 $labels['empty'] = 'Tyhjennä';
 $labels['purge'] = 'Puhdista';
@@ -129,7 +133,10 @@ $labels['unknown'] = 'tuntematon';
 $labels['unlimited'] = 'rajoittamaton';
 $labels['quicksearch'] = 'Pikahaku';
 $labels['resetsearch'] = 'Nollaa haku';
+$labels['searchmod'] = 'Haku kriteerit';
+$labels['msgtext'] = 'Koko viesti';
 $labels['openinextwin'] = 'Avaa uudessa ikkunassa';
+$labels['emlsave'] = 'Tallenna (.eml)';
 $labels['compose'] = 'Viestin kirjoitus';
 $labels['savemessage'] = 'Tallenna tämä luonnos';
 $labels['sendmessage'] = 'Lähetä viesti';
@@ -224,9 +231,13 @@ $labels['ignore'] = 'jätä huomiotta';
 $labels['readwhendeleted'] = 'Merkitse poistettavat viestit luetuiksi';
 $labels['flagfordeletion'] = 'Poistamisen sijaan, merkitse viestit poistettavaksi';
 $labels['skipdeleted'] = 'Älä näytä poistettuja viestejä';
+$labels['showremoteimages'] = 'Näytä ulkopuoliset kuvat viestissä';
+$labels['fromknownsenders'] = 'tunnetuilta lähettäjiltä';
+$labels['always'] = 'aina';
 $labels['showinlineimages'] = 'Näytä liitekuvat viestin jälkeen';
 $labels['autosavedraft'] = 'Tallenna luonnos automaattisesti';
-$labels['everynminutes'] = '$n minuutin välein';
+$labels['everynminutes'] = 'joka $n minuutti';
+$labels['keepalive'] = 'Tarkasta uudet viestit';
 $labels['never'] = 'ei koskaan';
 $labels['messagesdisplaying'] = 'Viestien näyttäminen';
 $labels['messagescomposition'] = 'Viestien kirjoittaminen';
@@ -235,6 +246,8 @@ $labels['2231folding'] = 'Täysin RFC 2231 mukainen (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 mukainen (MS Outlook)';
 $labels['2047folding'] = 'Täysin RFC 2047 mukainen (muut)';
 $labels['advancedoptions'] = 'Lisäasetukset';
+$labels['focusonnewmessage'] = 'Tarkenna selainikkuna uuteen viestiin';
+$labels['checkallfolders'] = 'Tarkista kaikki kansiot uusien viestien varalta';
 $labels['folder'] = 'Kansio';
 $labels['folders'] = 'Kansiot';
 $labels['foldername'] = 'Kansion nimi';
index 4aa80243fd6703e1dcdbc869fe37950428b9a75b..a31abbe1a1fb43487a3b9ef13cb8237aad2296c8 100644 (file)
 +-----------------------------------------------------------------------+
 | Author: Ville Alatalo <ville@alatalo.org>                             |
 |         Veljo Velling <veve@utu.fi>                                   |
+|         Jorma Tuomainen <jt@wiza.fi>                                  |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2572 2009-05-29 17:39:35Z alec $
 
 */
 
@@ -23,6 +24,7 @@ $messages['loginfailed'] = 'Sisäänkirjautuminen epäonnistui';
 $messages['cookiesdisabled'] = 'Selaimesi ei hyväksy evästeitä';
 $messages['sessionerror'] = 'Sessio ei kelpaa tai ei ole enää voimassa';
 $messages['imaperror'] = 'Yhteys IMAP-palvelimeen epäonnistui';
+$messages['servererror'] = 'Palvelin virhe!';
 $messages['nomessagesfound'] = 'Kansiossa ei ole sähköpostiviestejä';
 $messages['loggedout'] = 'Sinut on kirjattu ulos järjestelmästä.';
 $messages['mailboxempty'] = 'Kansio on tyhjä';
@@ -94,5 +96,7 @@ $messages['importerror'] = 'Tuonti epäonnistui! Lähetetty tiedosto ei ole vCar
 $messages['importconfirm'] = '<b>$inserted kontaktia tuotu onnistuneesti $inserted kontaktioa, $skipped olemassaolevaa kontaktia hypättiin yli</b>:<p><em>$names</em></p>';
 $messages['opnotpermitted'] = 'Toiminto ei ole sallittu!';
 $messages['nofromaddress'] = 'Valittu identiteetti ei sisällä sähköpostiosoitetta';
+$messages['editorwarning'] = 'Vaihtaminen tekstieditoriin aiheuttaa viestin muotoilun katoamisen. Haluatko jatkaa?';
+$messages['httpreceivedencrypterror'] = 'Vakava virhe asetuksissa. Ota välittömästi yhteys ylläpitoon. <b>Viestiäsi ei voida lähettää.</b>';
 
 ?>
index 4081dc2243d95f2ed455b98a96b7bcb4b14d44c7..9e8a24cb89a9129ad7f9651f649ef69602d03f54 100644 (file)
@@ -118,12 +118,15 @@ $labels['markread'] = 'Comme lus';
 $labels['markunread'] = 'Comme non lus';
 $labels['markflagged'] = 'Comme suivi';
 $labels['markunflagged'] = 'Comme non-suivi';
+$labels['messageactions'] = 'Actions supplémentaires...';
 $labels['select'] = 'Sélectionner';
 $labels['all'] = 'Tous';
 $labels['none'] = 'Aucun';
 $labels['unread'] = 'Non lus';
 $labels['flagged'] = 'Marqué';
 $labels['unanswered'] = 'Non répondu';
+$labels['deleted'] = 'Supprimé';
+$labels['invert'] = 'Inverser';
 $labels['filter'] = 'Filtre';
 $labels['compact'] = 'Compacter';
 $labels['empty'] = 'Vider';
@@ -133,8 +136,12 @@ $labels['unknown'] = 'inconnue';
 $labels['unlimited'] = 'illimitée';
 $labels['quicksearch'] = 'Recherche rapide';
 $labels['resetsearch'] = 'Réinitialiser la recherche';
+$labels['searchmod'] = 'Portée de la recherche';
+$labels['msgtext'] = 'Message entier';
 $labels['openinextwin'] = 'Ouvrir dans une nouvelle fenêtre';
+$labels['emlsave'] = 'Télécharger (.eml)';
 $labels['compose'] = 'Composer un nouveau message';
+$labels['editasnew'] = 'Editer en tant que nouveau message';
 $labels['savemessage'] = 'Sauvegarder ce brouillon';
 $labels['sendmessage'] = 'Envoyer le message maintenant';
 $labels['addattachment'] = 'Joindre un fichier';
@@ -233,8 +240,7 @@ $labels['fromknownsenders'] = 'venant d\'expéditeurs connus';
 $labels['always'] = 'toujours';
 $labels['showinlineimages'] = 'Afficher les images attachées après le message';
 $labels['autosavedraft'] = 'Sauvegarde automatique des brouillons';
-$labels['everynminutes'] = 'toutes les $n minutes';
-$labels['keepaliveevery'] = 'toutes les $n minute(s)';
+$labels['everynminutes'] = 'toutes les $n minute(s)';
 $labels['keepalive'] = 'Chercher les nouveaux messages';
 $labels['never'] = 'jamais';
 $labels['messagesdisplaying'] = 'Affichage des messages';
@@ -266,4 +272,4 @@ $labels['KB'] = 'Ko';
 $labels['MB'] = 'Mo';
 $labels['GB'] = 'Go';
 
-?>
+?>
\ No newline at end of file
index 9d9306f17edfcc63c17694e74e65b7e3489663c5..fd4451bd53eeaad5ef94de3f3f04fe84ce2a20e5 100644 (file)
@@ -24,6 +24,8 @@ $messages['loginfailed'] = 'Erreur d\'authentification';
 $messages['cookiesdisabled'] = 'Votre navigateur n\'accepte pas les cookies';
 $messages['sessionerror'] = 'Votre session est invalide ou a expiré';
 $messages['imaperror'] = 'Erreur de connexion au serveur IMAP';
+$messages['servererror'] = 'Erreur Serveur !';
+$messages['invalidrequest'] = 'Requête invalide ! Aucune donnée n\'a été sauvegardée.';
 $messages['nomessagesfound'] = 'Aucun message trouvé dans cette boîte aux lettres';
 $messages['loggedout'] = 'Vous venez de vous déconnecter avec succès. Au revoir !';
 $messages['mailboxempty'] = 'Boîte aux lettres vide';
@@ -41,12 +43,13 @@ $messages['blockedimages'] = 'Afin de préserver votre vie privée, les images d
 $messages['encryptedmessage'] = 'Ceci est un message crypté et il ne peut pas être affiché. Désolé !';
 $messages['nocontactsfound'] = 'Aucun contact n\'a pu être trouvé';
 $messages['contactnotfound'] = 'Le contact demandé n\'a pas été trouvé';
-$messages['sendingfailed'] = 'L\'envoie du message a échoué';
+$messages['sendingfailed'] = 'L\'envoi du message a échoué';
 $messages['senttooquickly'] = 'Vous devez attendre $sec sec. pour envoyer le message';
 $messages['errorsavingsent'] = 'Une erreur est survenue pendant la sauvegarde du message envoyé';
 $messages['errorsaving'] = 'Une erreur a empêché la sauvegarde';
 $messages['errormoving'] = 'Impossible de déplacer le message';
 $messages['errordeleting'] = 'Impossible d\'effacer le message';
+$messages['errormarking'] = 'Impossible de marquer le message';
 $messages['deletecontactconfirm'] = 'Voulez-vous vraiment effacer le(s) contact(s) sélectionné(s) ?';
 $messages['deletemessagesconfirm'] = 'Voulez-vous vraiment supprimer le(s) message(s) séléctionné(s) ?';
 $messages['deletefolderconfirm'] = 'Voulez-vous vraiment effacer ce dossier ?';
@@ -96,5 +99,12 @@ $messages['importconfirm'] = '<b>$inserted contacts importés avec succès, $ski
 $messages['opnotpermitted'] = 'Cette opération n\'est pas permise !';
 $messages['nofromaddress'] = 'Il manque une adresse e-mail dans l\'identitée sélectionnée';
 $messages['editorwarning'] = 'Passer à l\'éditeur texte seul causera la perte du formatage du texte. Voulez-vous continuer ?';
+$messages['httpreceivedencrypterror'] = 'Une erreur fatale de configuration est survenue. Veuillez contacter votre administrateur immédiatement. <b>Votre message n\'a pas pû être envoyé.</b>';
+$messages['smtpconnerror'] = 'Erreur SMTP ($code): Echec de la connexion au serveur';
+$messages['smtpautherror'] = 'Erreur SMTP ($code): Echec de l\'authentification';
+$messages['smtpfromerror'] = 'Erreur SMTP ($code): Impossible de définir l\'expéditeur "$from"';
+$messages['smtptoerror'] = 'Erreur SMTP ($code): Impossible d\'ajouter le destinataire "$to"';
+$messages['smtprecipientserror'] = 'Erreur SMTP: Impossible de lire la liste des destinataires';
+$messages['smtperror'] = 'Erreur SMTP: $msg';
 
 ?>
index e09a004a425b30c3023be71422e7c7ac0ed3f8a6..55c0524d5843f1790e106078ef1f7541e21ab617 100755 (executable)
@@ -160,7 +160,6 @@ $labels['htmleditor'] = 'Scríobh teachtaireachta HTML';
 $labels['htmlsignature'] = 'Mana clabhsúir HTML';
 $labels['previewpane'] = 'Taispeáin an pána réamhamharc';
 $labels['autosavedraft'] = 'Sábháil dréachta go huathoibríoch';
-$labels['everynminutes'] = ' i gceann gach $n nóiméad';
 $labels['never'] = 'riamh';
 $labels['folder'] = 'Fillteán';
 $labels['folders'] = 'Fillteán';
index faefcabde5a6898312870eb43e327352a85bf050..27827877b2a932964e473a392aafa3838717f9b8 100644 (file)
@@ -113,12 +113,15 @@ $labels['markread'] = 'Coma lidas';
 $labels['markunread'] = 'Coma non lidas';
 $labels['markflagged'] = 'Coma marcadas';
 $labels['markunflagged'] = 'Coma non marcadas';
+$labels['messageactions'] = 'Máis accións...';
 $labels['select'] = 'Seleccionar';
 $labels['all'] = 'Todas';
 $labels['none'] = 'Ningunha';
 $labels['unread'] = 'Non lidas';
 $labels['flagged'] = 'Marcadas';
 $labels['unanswered'] = 'Non respostadas';
+$labels['deleted'] = 'Eliminada';
+$labels['invert'] = 'Inverter';
 $labels['filter'] = 'Filtro';
 $labels['compact'] = 'Compactar';
 $labels['empty'] = 'Baleiro';
@@ -128,8 +131,12 @@ $labels['unknown'] = 'desconocido';
 $labels['unlimited'] = 'ilimitado';
 $labels['quicksearch'] = 'Busca rápida';
 $labels['resetsearch'] = 'Restablecer a busca';
+$labels['searchmod'] = 'Modificadores de busca';
+$labels['msgtext'] = 'Mensaxe enteira';
 $labels['openinextwin'] = 'Abrir nunha nova fiestra';
+$labels['emlsave'] = 'Gardar (.eml)';
 $labels['compose'] = 'Redactar unha mensaxe';
+$labels['editasnew'] = 'Editar coma nova';
 $labels['savemessage'] = 'Gardar a mensaxe coma borrador';
 $labels['sendmessage'] = 'Enviar a mensaxe agora';
 $labels['addattachment'] = 'Anexar un ficheiro';
@@ -228,8 +235,7 @@ $labels['fromknownsenders'] = 'de remitentes coñecidos';
 $labels['always'] = 'sempre';
 $labels['showinlineimages'] = 'Amosar as imaxes anexas baixo a mensaxe';
 $labels['autosavedraft'] = 'Gardar borrador automáticamente';
-$labels['everynminutes'] = 'cada $n minutos';
-$labels['keepaliveevery'] = 'cada $n minuto(s)';
+$labels['everynminutes'] = 'cada $n minuto(s)';
 $labels['keepalive'] = 'Procurar novas mensaxes en';
 $labels['never'] = 'nunca';
 $labels['messagesdisplaying'] = 'Visualización das mensaxes';
@@ -241,6 +247,12 @@ $labels['2047folding'] = 'Conforme ao RFC 2047 (other)';
 $labels['advancedoptions'] = 'Opcións avanzadas';
 $labels['focusonnewmessage'] = 'Enfocar o navegador se hai mensaxes novas';
 $labels['checkallfolders'] = 'Procurar novas mensaxes en tódolos cartafoles';
+$labels['displaynext'] = 'Amosar a seguinte mensaxe despois de borrar ou mover unha mensaxe';
+$labels['mainoptions'] = 'Opcións principais';
+$labels['section'] = 'Sección';
+$labels['maintenance'] = 'Mantemento';
+$labels['newmessage'] = 'Nova mensaxe';
+$labels['listoptions'] = 'Opcións de lista';
 $labels['folder'] = 'Cartafol';
 $labels['folders'] = 'Cartafoles';
 $labels['foldername'] = 'Nome do cartafol';
index daafd0845504fc76a0dd7273ae79ec56918bbf2d..f1a0d702c333e47aca192eb78abec274431f710a 100644 (file)
@@ -19,6 +19,8 @@ $messages['loginfailed'] = 'Fallou o acceso';
 $messages['cookiesdisabled'] = 'O seu navegador non acepta galletas';
 $messages['sessionerror'] = 'A súa sesión non é válida ou expirou';
 $messages['imaperror'] = 'Fallou a conexión co servidor IMAP';
+$messages['servererror'] = 'Erro no servidor!';
+$messages['invalidrequest'] = 'Petición inválida!. Non se gardou ningún dato.';
 $messages['nomessagesfound'] = 'Non se atoparon mensaxes nesta caixa de correo';
 $messages['loggedout'] = 'Rematou correctamente a súa sesión. Ata logo!';
 $messages['mailboxempty'] = 'A caixa de correo está vacía';
@@ -42,6 +44,7 @@ $messages['errorsavingsent'] = 'Ocurriu un erro mentres se gardaba a mensaxe env
 $messages['errorsaving'] = 'Ocurriu un erro mentres se gardaba';
 $messages['errormoving'] = 'Non se puido mover a mensaxe';
 $messages['errordeleting'] = 'Non se puido eliminar a mensaxe';
+$messages['errormarking'] = 'Non se puido marcar a mensaxe';
 $messages['deletecontactconfirm'] = 'Quere eliminar o(s) contacto(s) seleccionado(s)?';
 $messages['deletemessagesconfirm'] = 'Quere eliminar a(s) mensaxe(s) seleccionadas?';
 $messages['deletefolderconfirm'] = 'Quere eliminar este cartafol?';
@@ -91,5 +94,12 @@ $messages['importconfirm'] = '<b>Importáronse correctamente $inserted contactos
 $messages['opnotpermitted'] = 'Operación non permitida';
 $messages['nofromaddress'] = 'Falta o enderezo de correo electrónico na identidade que escolleu';
 $messages['editorwarning'] = 'Se troca neste intre ao editor de texto plano, vai perder todo o formato do texto. Quere continuar?';
+$messages['httpreceivedencrypterror'] = 'Produciuse un erro fatal de configuración. Contacte ao administrador inmediatamente. <b>Non se puido enviar a súa mensaxe.</b>';
+$messages['smtpconnerror'] = 'Erro SMTP ($code): Fallou a conexión co servidor';
+$messages['smtpautherror'] = 'Erro SMTP ($code): Fallou a autenticación';
+$messages['smtpfromerror'] = 'Erro SMTP ($code): Non se puido establecer o remitente "$from"';
+$messages['smtptoerror'] = 'Erro SMTP ($code): Non se puido engadir o destinatario "$to"';
+$messages['smtprecipientserror'] = 'Erro SMTP: Non se pode analizar a lista de destinatarios';
+$messages['smtperror'] = 'Erro SMTP: $msg';
 
 ?>
index 93f033d7321b469316551789f86469bb89ad5261..e82e7c78ab0114691a556d6fe85feb6be697b66e 100644 (file)
@@ -11,7 +11,7 @@
 +-----------------------------------------------------------------------+
 | Author: Moshe Leibovitch  <moish@mln.co.il>                           |
 | Updates: Noor Dawod <noor@comrax.com>                                 |
-| Updates: Moshe Leibovitch  <moish@mln.co.il>  06122008                |
+| Updates: Moshe Leibovitch  <moish@mln.co.il>  19082009                |
 +-----------------------------------------------------------------------+
 */
 
@@ -114,12 +114,15 @@ $labels['markread'] = 'כנקראו';
 $labels['markunread'] = 'כלא נקראו';
 $labels['markflagged'] = 'כמסומן';
 $labels['markunflagged'] = 'כלא מסומן';
+$labels['messageactions'] = 'פעולות נוספות';
 $labels['select'] = 'בחירה';
 $labels['all'] = 'הכל';
 $labels['none'] = 'כלום';
 $labels['unread'] = 'לא נקראו';
 $labels['flagged'] = 'מסומן';
 $labels['unanswered'] = 'לא נענה';
+$labels['deleted'] = 'נמחק';
+$labels['invert'] = 'היפוך הסימון';
 $labels['filter'] = 'סינון';
 $labels['compact'] = 'פינוי שטח לא מנוצל';
 $labels['empty'] = 'ריקון';
@@ -129,8 +132,12 @@ $labels['unknown'] = 'לא ידוע';
 $labels['unlimited'] = 'ללא הגבלה';
 $labels['quicksearch'] = 'חיפוש מהיר';
 $labels['resetsearch'] = 'ניקוי תיבת החיפוש';
+$labels['searchmod'] = 'מאפייני חיפוש';
+$labels['msgtext'] = 'כל ההודעה';
 $labels['openinextwin'] = 'פתיחה בחלון חדש';
+$labels['emlsave'] = 'הורדת הודעה בפורמט  EML';
 $labels['compose'] = 'כתיבת הודעה';
+$labels['editasnew'] = 'עריכת ההודעה כחדשה';
 $labels['savemessage'] = 'שמירת טיוטה';
 $labels['sendmessage'] = 'משלוח מיידי';
 $labels['addattachment'] = 'צירוף קובץ';
@@ -230,7 +237,6 @@ $labels['always'] = 'תמיד';
 $labels['showinlineimages'] = 'הצגת תמונות מצורפות בתחתית ההודעה';
 $labels['autosavedraft'] = 'שמירה אוטומטית של טיוטה';
 $labels['everynminutes'] = 'כל $n דקות';
-$labels['keepaliveevery'] = 'כל $n דקות';
 $labels['keepalive'] = 'בדיקת הגעה של הודעות חדשות';
 $labels['never'] = 'אף פעם';
 $labels['messagesdisplaying'] = 'הצגת הודעות';
@@ -242,6 +248,12 @@ $labels['2047folding'] = 'תאימות מלאה 2047 אחרים';
 $labels['advancedoptions'] = 'הגדרות נוספות';
 $labels['focusonnewmessage'] = 'מיקוד הסמן על החלון עם ההודעה החדשה';
 $labels['checkallfolders'] = 'בדיקת הודעות חדשות בכל התיקים';
+$labels['displaynext'] = 'מעבר להודעה הבאה לאחר מחיקה או תיוק';
+$labels['mainoptions'] = 'אפשרויות עיקריות';
+$labels['section'] = 'קטע';
+$labels['maintenance'] = 'תחזוקה';
+$labels['newmessage'] = 'הודעה חדשה';
+$labels['listoptions'] = 'אפשרויות רשימה';
 $labels['folder'] = 'תיק';
 $labels['folders'] = 'תיקים';
 $labels['foldername'] = 'שם תיק';
index 977af63743ea7b57a230b28f619b5ca38185e91b..ccd3959d13ce521743e3225d87bb8b15031a6aa8 100644 (file)
@@ -11,7 +11,7 @@
 +-----------------------------------------------------------------------+
 | Author: Moshe Leibovitch    <moish@mln.co.il>                         |
 | Updates: Noor Dawod <noor@comrax.com>                                 |
-| Updates: Moshe Leibovitch  <moish@mln.co.il>  06122008                |
+| Updates: Moshe Leibovitch  <moish@mln.co.il>  30072009                |
 +-----------------------------------------------------------------------+
 
 */
@@ -21,6 +21,8 @@ $messages['loginfailed'] = 'הכניסה נכשלה';
 $messages['cookiesdisabled'] = 'הדפדפן אינו מקבל עוגיות';
 $messages['sessionerror'] = 'כניסתך למערכת אינה חוקית או שפג תוקפה';
 $messages['imaperror'] = 'הקשר לשרת הדואר נכשל';
+$messages['servererror'] = '! שגיאת שרת';
+$messages['invalidrequest'] = 'בקשה לא חוקית. המידע לא נשמר';
 $messages['nomessagesfound'] = 'לא נמצאו הודעות בתיבה זו';
 $messages['loggedout'] = 'הקשר הסתיים. להתראות!';
 $messages['mailboxempty'] = 'רשימת ההודעות ריקה';
@@ -44,6 +46,7 @@ $messages['errorsavingsent'] = 'נגרמה שגיאה במהלך שמירת הה
 $messages['errorsaving'] = 'נגרמה שגיאה במהלך השמירה';
 $messages['errormoving'] = 'לא ניתן לתייק את ההודעה';
 $messages['errordeleting'] = 'לא ניתן למחוק את ההודעה';
+$messages['errormarking'] = 'לא ניתן לסמן ההודעה';
 $messages['deletecontactconfirm'] = 'האם למחוק את איש הקשר?';
 $messages['deletemessagesconfirm'] = 'האם למחוק את ההודעות המסומנות?';
 $messages['deletefolderconfirm'] = 'האם למחוק תיק זה?';
@@ -93,5 +96,12 @@ $messages['importconfirm'] = '<b>יובאו $inserted אנשי קשר, $skipped
 $messages['opnotpermitted'] = 'פעולה אסורה!';
 $messages['nofromaddress'] = 'לזהות שנבחרה חסרה כתובת דואר';
 $messages['editorwarning'] = 'המעבר לעורך רגיל יגרום לאיבוד את העריכה הקיימת. האם להמשיך?';
+$messages['httpreceivedencrypterror'] = 'ארעה שגיאת תצורה חמורה. נא להודיע מייד למנהל/ת המערכת. <B> הודעתך לא תשלח <B> ';
+$messages['smtpconnerror'] = 'SMTP ($code): אבד הקשר לשרת';
+$messages['smtpautherror'] = 'SMTP ($code): ההזדהות נכשלה';
+$messages['smtpfromerror'] = 'SMTP ($code): "$from" לא נרשמה כתובת השולח';
+$messages['smtptoerror'] = 'SMTP ($code): "$to" לא נרשמה כתובת המקבל';
+$messages['smtprecipientserror'] = 'SMTP : לא ניתן לפענח רשימת נמענים';
+$messages['smtperror'] = 'SMTP: $msg';
 
 ?>
index 987e39f2f0e5ebdc50b280c7789735a1832a6200..9216b563176ea876e29513b71931be1716ac3d3a 100644 (file)
@@ -218,7 +218,6 @@ $labels['htmlsignature']    = 'ऐच-टी-ऐम-एल (HTML) दस्तख
 $labels['previewpane']         = 'झलक पट्टी दिखाऐं';
 
 $labels['autosavedraft']       = 'ड्राफ़ट अपने आप सहेजते जाऐं';
-$labels['everynminutes']       = 'हर $n मिनट';
 $labels['never']               = 'कभी नहाीं';
 
 $labels['folder']              = 'फ़ोल्डर';
index 0d8c7ba95c6fcbef3e2e694dfbd9ccc7da2c817c..b9bd945e81ae953549ff30525dc5630132da8e41 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Edi Budimilic <edi@gemstudio.hr>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -228,7 +228,6 @@ $labels['skipdeleted'] = 'Ne prikazivaj pobrisane poruke';
 $labels['showinlineimages'] = 'Prikaži slike ispod poruke';
 $labels['autosavedraft'] = 'Automatski spremi draft';
 $labels['everynminutes'] = 'svakih $n minuta';
-$labels['keepaliveevery'] = 'svakih $n minuta';
 $labels['keepalive'] = 'Provjeri nove poruke';
 $labels['never'] = 'Nikada';
 $labels['messagesdisplaying'] = 'Prikazujem poruke';
index 2874e1583f800e047454aa73eff7b1e687876ab4..9a465d1b3b3863ff5747b0cabb6277cf7600f17b 100644 (file)
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Levente Farkas <lfarkas at lfarkas dot org>                   |
-|         Ervin Hegedüs <airween@damson.hu>                             |
+| Author: Zark Bonfire (ikkhares@gmail.com)                             |
+|         Levente Farkas <lfarkas at lfarkas dot org>                   |
+|         Ervin Hegedűs <airween@damson.hu>                             |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2254 2009-01-22 19:52:46Z yllar $
+@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
 $labels = array();
+
+// login page 
 $labels['welcome'] = 'Üdvözli a $product';
 $labels['username'] = 'Felhasználónév';
 $labels['password'] = 'Jelszó';
 $labels['server'] = 'Szerver';
 $labels['login'] = 'Belépés';
+
+// taskbar 
 $labels['logout'] = 'Kijelentkezés';
 $labels['mail'] = 'E-mail';
 $labels['settings'] = 'Egyéni beállítások';
 $labels['addressbook'] = 'Címjegyzék';
+
+// mailbox names 
 $labels['inbox'] = 'Érkezett levelek';
 $labels['drafts'] = 'Piszkozatok';
 $labels['sent'] = 'Küldött levelek';
 $labels['trash'] = 'Törölt elemek';
-$labels['junk'] = 'Szemetes';
+$labels['junk'] = 'Kéretlen levelek';
+
+// message listing 
 $labels['subject'] = 'Tárgy';
 $labels['from'] = 'Feladó';
 $labels['to'] = 'Címzett';
@@ -43,18 +52,27 @@ $labels['date'] = 'Dátum';
 $labels['size'] = 'Méret';
 $labels['priority'] = 'Sürgősség';
 $labels['organization'] = 'Szervezet';
+
+// aliases
 $labels['reply-to'] = 'Válaszcím';
+
 $labels['mailboxlist'] = 'Mappák';
 $labels['messagesfromto'] = 'Üzenetek: $from - $to / $count';
 $labels['messagenrof'] = '$nr / $count üzenet';
+
 $labels['moveto'] = 'áthelyezés...';
 $labels['download'] = 'letöltés';
-$labels['filename'] = 'File neve';
-$labels['filesize'] = 'File mérete';
+
+$labels['filename'] = 'Fájl neve';
+$labels['filesize'] = 'Fájl mérete';
+
 $labels['preferhtml'] = 'HTML megjelenítés';
 $labels['htmlmessage'] = 'HTML üzenet';
 $labels['prettydate'] = 'Rövid dátumok';
+
 $labels['addtoaddressbook'] = 'Hozzáadás a címjegyzékhez';
+
+// weekdays short 
 $labels['sun'] = 'Vas';
 $labels['mon'] = 'Hét';
 $labels['tue'] = 'Kedd';
@@ -62,6 +80,8 @@ $labels['wed'] = 'Szer';
 $labels['thu'] = 'Csüt';
 $labels['fri'] = 'Pén';
 $labels['sat'] = 'Szom';
+
+// weekdays long 
 $labels['sunday'] = 'Vasárnap';
 $labels['monday'] = 'Hétfő';
 $labels['tuesday'] = 'Kedd';
@@ -69,6 +89,8 @@ $labels['wednesday'] = 'Szerda';
 $labels['thursday'] = 'Csütörtök';
 $labels['friday'] = 'Péntek';
 $labels['saturday'] = 'Szombat';
+
+// months short 
 $labels['jan'] = 'Jan';
 $labels['feb'] = 'Febr';
 $labels['mar'] = 'Márc';
@@ -81,6 +103,8 @@ $labels['sep'] = 'Szept';
 $labels['oct'] = 'Okt';
 $labels['nov'] = 'Nov';
 $labels['dec'] = 'Dec';
+
+// months long 
 $labels['longjan'] = 'Január';
 $labels['longfeb'] = 'Február';
 $labels['longmar'] = 'Március';
@@ -93,7 +117,10 @@ $labels['longsep'] = 'Szeptember';
 $labels['longoct'] = 'Október';
 $labels['longnov'] = 'November';
 $labels['longdec'] = 'December';
+
 $labels['today'] = 'Ma';
+
+// toolbar buttons 
 $labels['checkmail'] = 'Új üzenetek ellenőrzése';
 $labels['writenewmessage'] = 'Új üzenet';
 $labels['replytomessage'] = 'Válasz';
@@ -117,65 +144,92 @@ $labels['markread'] = 'Olvasottként';
 $labels['markunread'] = 'Olvasatlanként';
 $labels['markflagged'] = 'Jelöltként';
 $labels['markunflagged'] = 'Jelöletlenként';
+$labels['messageactions'] = 'További lehetőségek...';
+
 $labels['select'] = 'Kijelölés';
 $labels['all'] = 'Összes';
 $labels['none'] = 'Nincs';
 $labels['unread'] = 'Olvasatlan';
 $labels['flagged'] = 'Megjelölt';
 $labels['unanswered'] = 'Megválaszolatlan';
+$labels['deleted'] = 'Törölt';
+$labels['invert'] = 'Invertálás';
 $labels['filter'] = 'Szűrés';
+
 $labels['compact'] = 'Tömörítés';
-$labels['empty'] = 'Ürítés';
+$labels['empty'] = 'Kiürítés';
 $labels['purge'] = 'Tisztítás';
+
 $labels['quota'] = 'Diszk használat';
 $labels['unknown'] = 'ismeretlen';
 $labels['unlimited'] = 'korlátlan';
+
 $labels['quicksearch'] = 'Gyorskeresés';
 $labels['resetsearch'] = 'Alapállapot';
+$labels['searchmod'] = 'Keresési opciók';
+$labels['msgtext'] = 'Teljes üzenet';
+
 $labels['openinextwin'] = 'Megnyitás új ablakban';
+$labels['emlsave'] = 'Letöltés (.eml)';
+
+// message compose 
 $labels['compose'] = 'Üzenet létrehozása';
+$labels['editasnew'] = 'Szerkesztés újként';
 $labels['savemessage'] = 'Vázlat mentése';
-$labels['sendmessage'] = 'Üzenet azonnali küldése';
-$labels['addattachment'] = 'File csatolása';
+$labels['sendmessage'] = 'Üzenet küldése';
+$labels['addattachment'] = 'Fájl csatolása';
 $labels['charset'] = 'Karakterkészlet';
 $labels['editortype'] = 'Szerkesztő típusa';
 $labels['returnreceipt'] = 'Értesítés';
+
 $labels['checkspelling'] = 'Helyesírás-ellenőrzés';
 $labels['resumeediting'] = 'Helyesírás kész';
 $labels['revertto'] = 'Vissza erre:';
-$labels['attachments'] = 'Csatolások';
+
+$labels['attachments'] = 'Csatolmányok';
 $labels['upload'] = 'Feltöltés';
 $labels['close'] = 'Bezárás';
+
 $labels['low'] = 'Alacsony';
 $labels['lowest'] = 'Legkisebb';
 $labels['normal'] = 'Normál';
 $labels['high'] = 'Magas';
 $labels['highest'] = 'Legmagasabb';
+
 $labels['nosubject'] = '(nincs tárgy)';
 $labels['showimages'] = 'Képek megjelenítése';
 $labels['alwaysshow'] = 'Képek megjelenítése mindíg ha a feladó $sender';
+
 $labels['htmltoggle'] = 'HTML';
 $labels['plaintoggle'] = 'Egyszerű szöveg';
 $labels['savesentmessagein'] = 'Elküldött üzenet mentése ide:';
-$labels['dontsave'] = 'ne mentsük';
+$labels['dontsave'] = 'nincs mentés';
 $labels['maxuploadsize'] = 'A maximális feltölthető fájl mérete $size';
+
 $labels['addcc'] = 'Cc (Másolati cím) hozzáadása';
 $labels['addbcc'] = 'Bcc (Titkos másolati cím) hozzáadása';
 $labels['addreplyto'] = 'Válaszcím hozzáadása';
-$labels['mdnrequest'] = 'Az üzenet küldője értesítést kér arról hogy elolvastad a levelet. Elküdjük az Olvasási Értesítést?';
+
+// mdn 
+$labels['mdnrequest'] = 'Az üzenet küldője értesítést kér arról, hogy elolvasta a levelet. El legyen küldve az Olvasási Értesítés?';
 $labels['receiptread'] = 'Olvasási Értesítés (olvasott)';
-$labels['yourmessage'] = 'Ez az üzeneted Olvasási Értesítése';
+$labels['yourmessage'] = 'Ez az üzenete Olvasási Értesítése';
 $labels['receiptnote'] = 'Megjegyzés: Ez az Olvasási Értesítés csak azt igazolja, hogy az üzenet megjelenítésre került a címzett számítógépén. Nincs rá garancia, hogy a címzett elolvasta volna az üzenetet illetve megértette volna annak tartalmát.';
+
+// address boook 
 $labels['name'] = 'Megjelenített név';
 $labels['firstname'] = 'Keresztnév';
 $labels['surname'] = 'Vezetéknév';
 $labels['email'] = 'E-mail cím';
+
 $labels['addcontact'] = 'Új kapcsolat hozzáadása';
 $labels['editcontact'] = 'Kapcsolat szerkesztése';
+
 $labels['edit'] = 'Szerkesztés';
 $labels['cancel'] = 'Mégsem';
 $labels['save'] = 'Mentés';
 $labels['delete'] = 'Törlés';
+
 $labels['newcontact'] = 'Új névjegykártya létrehozása';
 $labels['deletecontact'] = 'Kijelölt kapcsolatok törlése';
 $labels['composeto'] = 'E-mail küldése erre a címre';
@@ -183,27 +237,36 @@ $labels['contactsfromto'] = 'Kapcsolatok: $from - $to / $count';
 $labels['print'] = 'Nyomtatás';
 $labels['export'] = 'Exportálás';
 $labels['exportvcards'] = 'Kapcsolatok exportálása vCard formátumban';
+
 $labels['previouspage'] = 'Előző lap';
 $labels['firstpage'] = 'Első lap';
 $labels['nextpage'] = 'Következő lap';
 $labels['lastpage'] = 'Utolsó lap';
+
 $labels['groups'] = 'Csoportok';
 $labels['personaladrbook'] = 'Személyes címjegyzék';
+
 $labels['import'] = 'Importálás';
 $labels['importcontacts'] = 'Kapcsolatok importálása';
 $labels['importfromfile'] = 'Importálás fájlból:';
 $labels['importreplace'] = 'A teljes címjegyzék cseréje';
 $labels['importtext'] = 'Feltölthet kapcsolatokat egy már létező címjegyzékből. <br/> Jelenleg a <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>  formátumú adatok importálása támogatott.';
 $labels['done'] = 'Kész';
+
+// settings
 $labels['settingsfor'] = 'Beállítás';
+
 $labels['preferences'] = 'Beállítások';
 $labels['userpreferences'] = 'Felhasználói beállítások';
 $labels['editpreferences'] = 'Felhasználói beállítások szerkesztése';
+
 $labels['identities'] = 'Azonosítók';
 $labels['manageidentities'] = 'Hozzáférés azonosítóinak kezelése';
 $labels['newidentity'] = 'Új azonosító';
+
 $labels['newitem'] = 'Új elem';
 $labels['edititem'] = 'Elem szerkesztése';
+
 $labels['setdefault'] = 'Beállítás alapértelmezettnek';
 $labels['autodetect'] = 'Automatikus';
 $labels['language'] = 'Nyelv';
@@ -214,7 +277,7 @@ $labels['dstactive'] = 'Nyári időszámítás';
 $labels['htmleditor'] = 'HTML üzenet írása';
 $labels['htmlsignature'] = 'HTML aláírás';
 $labels['previewpane'] = 'Előnézeti kép';
-$labels['skin'] = 'Smink';
+$labels['skin'] = 'Kinézet';
 $labels['logoutclear'] = 'Törölt elemek mappa ürítése kilépéskor';
 $labels['logoutcompact'] = 'Beérkezett üzenetek mappa tömörítése kilépéskor';
 $labels['uisettings'] = 'Felhasználói felület';
@@ -226,14 +289,13 @@ $labels['autosend'] = 'automatikus küldés';
 $labels['ignore'] = 'hagyja figyelmen kívül';
 $labels['readwhendeleted'] = 'Üzenet olvasottként jelölése törléskor';
 $labels['flagfordeletion'] = 'Üzenet törlendőnek jelölése törlés helyett ';
-$labels['skipdeleted'] = 'Ne mutassuk a törölt üzeneteket';
+$labels['skipdeleted'] = 'Törölt üzenetek ne legyenek megjelenítve';
 $labels['showremoteimages'] = 'Távoli beágyazott képek mutatása';
 $labels['fromknownsenders'] = 'csak ismert feladóktól';
 $labels['always'] = 'mindig';
 $labels['showinlineimages'] = 'Csatolt képek megjelenítése az üzenet alatt';
 $labels['autosavedraft'] = 'Automatikus piszkozat mentés';
 $labels['everynminutes'] = 'minden $n percben';
-$labels['keepaliveevery'] = 'minden $n percben';
 $labels['keepalive'] = 'Új üzenetek keresése itt: ';
 $labels['never'] = 'soha';
 $labels['messagesdisplaying'] = 'Üzenetek megjelenítése';
@@ -245,6 +307,13 @@ $labels['2047folding'] = 'Full RFC 2047 (egyéb)';
 $labels['advancedoptions'] = 'Haladó beállítások';
 $labels['focusonnewmessage'] = 'Beérkező új üzenet ablakának fókuszba hozása';
 $labels['checkallfolders'] = 'Új üzenetek ellenőrzése minden (al)mappában';
+$labels['displaynext'] = 'Levél törlése/mozgatása után jelenjen meg a következő üzenet';
+$labels['mainoptions'] = 'Általános beállítások';
+$labels['section'] = 'Szakasz';
+$labels['maintenance'] = 'Karbantartás';
+$labels['newmessage'] = 'Új üzenet';
+$labels['listoptions'] = 'Lista beállítások';
+
 $labels['folder'] = 'Mappa';
 $labels['folders'] = 'Mappák';
 $labels['foldername'] = 'Mappa neve';
@@ -257,9 +326,12 @@ $labels['renamefolder'] = 'Mappa átnevezése';
 $labels['deletefolder'] = 'Mappa törlése';
 $labels['managefolders'] = 'Mappák kezelése';
 $labels['specialfolders'] = 'Különleges mappák';
+
 $labels['sortby'] = 'Rendezés';
 $labels['sortasc'] = 'növekvő';
 $labels['sortdesc'] = 'csökkenő';
+
+// units 
 $labels['B'] = 'B';
 $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
index a67acdfc7e9cea2de274af3cdd06c38e66945eb0..c826ecc6b506a46ba84695045f3e78fc40448e2d 100644 (file)
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Levente Farkas <lfarkas at lfarkas dot org>                   |
-|         Ervin Hegedüs <airween@damson.hu>                             |
+| Author: Zark Bonfire (ikkhares@gmail.com)                             |
+|         Levente Farkas <lfarkas at lfarkas dot org>                   |
+|         Ervin Hegedűs <airween@damson.hu>                             |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2254 2009-01-22 19:52:46Z yllar $
+@version $Id: messages.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
@@ -23,8 +24,10 @@ $messages['loginfailed'] = 'Sikertelen belépés';
 $messages['cookiesdisabled'] = 'A böngésző nem támogatja a sütik használatát';
 $messages['sessionerror'] = 'Érvénytelen vagy lejárt munkamenet';
 $messages['imaperror'] = 'Nem sikerült a kapcsolódás az IMAP szerverhez';
+$messages['servererror'] = 'Szerverhiba!';
+$messages['invalidrequest'] = 'Érvénytelen kérés! Az adatok nem lettek elmentve.';
 $messages['nomessagesfound'] = 'A fiók nem tartalmaz leveleket';
-$messages['loggedout'] = 'Sikeres kijelentkezés. Viszont látásra!';
+$messages['loggedout'] = 'Sikeres kijelentkezés. Viszontlátásra!';
 $messages['mailboxempty'] = 'A fiók üres';
 $messages['loading'] = 'Betöltés...';
 $messages['loadingdata'] = 'Az adatok betöltése...';
@@ -37,7 +40,7 @@ $messages['successfullysaved'] = 'A mentés sikerült';
 $messages['addedsuccessfully'] = 'A cím hozzáadása a címjegyzékhez megtörtént';
 $messages['contactexists'] = 'A kapcsolat már létezik ezzel az e-mail címmel';
 $messages['blockedimages'] = 'Biztonsági okokból a távoli képek letöltése tiltott.';
-$messages['encryptedmessage'] = 'Az üzenet titkosított, emiatt nem tudom megjeleníteni.';
+$messages['encryptedmessage'] = 'Az üzenet titkosított, ezért nem megjeleníteníthető.';
 $messages['nocontactsfound'] = 'Nincs kapcsolat';
 $messages['contactnotfound'] = 'A kiválasztott kapcsolat nem található';
 $messages['sendingfailed'] = 'Az üzenet elküldése nem sikerült';
@@ -46,46 +49,47 @@ $messages['errorsavingsent'] = 'Hiba történt az elküldött üzenet mentése k
 $messages['errorsaving'] = 'A mentés során hiba lépett fel';
 $messages['errormoving'] = 'Az üzenetet nem sikerült áthelyezni';
 $messages['errordeleting'] = 'Az üzenetet nem sikerült törölni';
-$messages['deletecontactconfirm'] = 'Biztos, hogy törölni szeretnéd a kijelölt címe(ke)t?';
-$messages['deletemessagesconfirm'] = 'Biztos, hogy törölni szeretnéd a kijelölt üzenete(ke)t?';
-$messages['deletefolderconfirm'] = 'Biztos, hogy törölni szeretnéd ezt a mappát?';
-$messages['purgefolderconfirm'] = 'Biztos vagy benne, hogy az összes üzenet törölhető?';
+$messages['errormarking'] = 'Az üzenetet nem sikerült megjelölni';
+$messages['deletecontactconfirm'] = 'Biztos, hogy törölni szeretné a kijelölt címe(ke)t?';
+$messages['deletemessagesconfirm'] = 'Biztos, hogy törölni szeretné a kijelölt üzenete(ke)t?';
+$messages['deletefolderconfirm'] = 'Biztos, hogy törölni szeretné ezt a mappát?';
+$messages['purgefolderconfirm'] = 'Biztos benne, hogy az összes üzenet törölhető?';
 $messages['foldercreating'] = 'Mappa létrehozása...';
 $messages['folderdeleting'] = 'Mappa törlése...';
 $messages['folderrenaming'] = 'Mappa átnevezése...';
 $messages['foldermoving'] = 'Mappa mozgatása...';
 $messages['formincomplete'] = 'Az űrlap hiányosan lett kitöltve';
-$messages['noemailwarning'] = 'Adj meg egy valós e-mail címet';
-$messages['nonamewarning'] = 'Adj meg egy nevet';
-$messages['nopagesizewarning'] = 'Add meg a papír méretét';
-$messages['nosenderwarning'] = 'Kérem adja meg a feladó email címét';
-$messages['norecipientwarning'] = 'Legalább egy címzettet adj meg';
-$messages['nosubjectwarning'] = 'A \"Tárgy\" mező üres. Szeretnéd most kitölteni?';
-$messages['nobodywarning'] = 'Elküldöd az üzenetet tárgy nélkül?';
-$messages['notsentwarning'] = 'Az üzenet még nem küldtem el. Eldobod az üzenetet?';
-$messages['noldapserver'] = 'Adj meg egy LDAP szervert a kereséshez';
-$messages['nocontactsreturned'] = 'Nem találtam kapcsolatot';
-$messages['nosearchname'] = 'Add meg a kapcsolat nevét vagy e-mail címét';
-$messages['searchsuccessful'] = '$nr üzenetet találtam';
+$messages['noemailwarning'] = 'Adjon meg egy valós e-mail címet';
+$messages['nonamewarning'] = 'Adjon meg egy nevet';
+$messages['nopagesizewarning'] = 'Adja meg a papír méretét';
+$messages['nosenderwarning'] = 'Kérem adja meg a feladó e-mail címét';
+$messages['norecipientwarning'] = 'Legalább egy címzettet adjon meg';
+$messages['nosubjectwarning'] = 'A Tárgy mező üres. Szeretné most kitölteni?';
+$messages['nobodywarning'] = 'Elküldi az üzenetet üresen?';
+$messages['notsentwarning'] = 'Az üzenet még nem lett elküldve. Eldobja az üzenetet?';
+$messages['noldapserver'] = 'Adjon meg egy LDAP szervert a kereséshez';
+$messages['nocontactsreturned'] = 'Nem található kapcsolat';
+$messages['nosearchname'] = 'Adja meg a kapcsolat nevét vagy e-mail címét';
+$messages['searchsuccessful'] = '$nr üzenet található';
 $messages['searchnomatch'] = 'Nincs találat';
 $messages['searching'] = 'Keresés...';
 $messages['checking'] = 'Ellenőrzés...';
-$messages['nospellerrors'] = 'Nem találtam helyesírási hibát';
+$messages['nospellerrors'] = 'Nem található helyesírási hiba';
 $messages['folderdeleted'] = 'A mappa sikeresen törölve';
 $messages['deletedsuccessfully'] = 'Törölve';
 $messages['converting'] = 'Formázás eltávolítása az üzenetből...';
-$messages['messageopenerror'] = 'Nem tudom letölteni a leveleket a szerverről';
+$messages['messageopenerror'] = 'A levelek a szerverről nem tölthetők le';
 $messages['fileuploaderror'] = 'Feltöltés sikertelen';
-$messages['filesizeerror'] = 'A feltöltött file mérete meghaladja a maximális méretet $size';
-$messages['copysuccess'] = 'Sikeresen másoltunk $nr címet';
-$messages['copyerror'] = 'Nem tudtunk másolni egyetlen címet sem';
+$messages['filesizeerror'] = 'A feltöltött fájl mérete meghaladja a maximális méretet $size';
+$messages['copysuccess'] = '$nr cím sikeresen másolva';
+$messages['copyerror'] = 'Egyetlen cím sem másolható';
 $messages['sourceisreadonly'] = 'Ez a címforrás csak olvasható';
-$messages['errorsavingcontact'] = 'Nem tudtuk menteni a kapcsolat címét';
+$messages['errorsavingcontact'] = 'A kapcsolat címe nem menthető';
 $messages['movingmessage'] = 'Üzenet mozgatása...';
-$messages['receiptsent'] = 'Az Olvasási Értesítést elküldtük';
+$messages['receiptsent'] = 'Az Olvasási Értesítés el lett küldve';
 $messages['errorsendingreceipt'] = 'Az Olvasási Értesítést nem sikerült elküldeni';
 $messages['nodeletelastidentity'] = 'Nem törölheti ezt a profilt, ez az egyetlen';
-$messages['addsubfolderhint'] = 'Az új könyvtárat az aktuálisan kiválasztott alkönyvtáraként fogjuk létrehozni';
+$messages['addsubfolderhint'] = 'Az új könyvtár az aktuálisan kiválasztott alkönyvtáraként lesz létrehozva';
 $messages['forbiddencharacter'] = 'A mappa neve tiltott karaktert tartalmaz';
 $messages['selectimportfile'] = 'Kérjük válassza ki a feltölteni kívánt fájlt';
 $messages['addresswriterror'] = 'A kiválasztott címjegyzék nem írható';
@@ -93,7 +97,14 @@ $messages['importwait'] = 'Importálás folyamatban, kérem várjon...';
 $messages['importerror'] = 'Az importálás sikertelen! A feltöltött állomány nem egy érvényes vCard fájl.';
 $messages['importconfirm'] = '<b>Sikeresen importálásra került $inserted kapcsolat, kihagyva $skipped már létező bejegyzés</b>:<p><em>$names</em></p>';
 $messages['opnotpermitted'] = 'A művelet nem megengedett!';
-$messages['nofromaddress'] = 'Hiányzó email cím a kiválasztott feladónál';
+$messages['nofromaddress'] = 'Hiányzó e-mail cím a kiválasztott feladónál';
 $messages['editorwarning'] = 'Az egyszerű szöveges formátumra való váltás az összes formázás elvesztésével jár. Biztosan folytatja?';
+$messages['httpreceivedencrypterror'] = 'Végzetes konfigurációs hiba történt, azonnal lépjen kapcsolatba az üzemeltetővel. <b>Az üzenet nem küldhető el.</b>';
+$messages['smtpconnerror'] = 'SMTP hiba ($code): Sikertelen kapcsolódás a szerverhez';
+$messages['smtpautherror'] = 'SMTP hiba ($code): Sikertelen bejelentkezés';
+$messages['smtpfromerror'] = 'SMTP hiba ($code): Nem sikerült a feladó beállítása: "$from"';
+$messages['smtptoerror'] = 'SMTP hiba ($code): Nem sikerült a következő címzett hozzáadása: "$to"';
+$messages['smtprecipientserror'] = 'SMTP hiba ($code): A címzett lista feldolgozása sikertelen';
+$messages['smtperror'] = 'SMTP hiba ($code): $msg';
 
 ?>
index 6e4012bdf3321aab8cdfaf05e7131a198ed4b6ed..aef3d777585bf3ea29f7a18446be87d36da86d00 100644 (file)
@@ -12,7 +12,7 @@
 | Author: Vahan Yerkanian <vahan@arminco.com>                           |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -231,7 +231,6 @@ $labels['always'] = 'միշտ';
 $labels['showinlineimages'] = 'Ցուցադրել կցված պատկերները հաղորդագրության տակ';
 $labels['autosavedraft'] = 'Սևագրի ավտոմատ գրանցում';
 $labels['everynminutes'] = 'ամեն $n րոպեն';
-$labels['keepaliveevery'] = 'ամեն $n րոպեն';
 $labels['keepalive'] = 'Ստուգել նոր նամակները';
 $labels['never'] = 'երբեք';
 $labels['messagesdisplaying'] = 'նամակները ցուցադրելիս';
index beb5e4ff62ebb408a0e7da82c9daf4664d995d29..7a5754b7e84911261cd4056e5d6bcfa9681870f5 100644 (file)
@@ -12,7 +12,7 @@
 | Author: Vahan Yerkanian <vahan@arminco.com>                           |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: messages.inc 2359 2009-03-19 07:53:16Z thomasb $
 
 */
 
index 60d330b757c562e6e22e0c37a0c4364c56a7722e..285ad5ef6b6a9a3e862118eaf7d4a2a811581773 100644 (file)
@@ -116,12 +116,15 @@ $labels['markread'] = 'Terbaca';
 $labels['markunread'] = 'Belum Terbaca';
 $labels['markflagged'] = 'Sudah ditandai';
 $labels['markunflagged'] = 'Belum ditandai';
+$labels['messageactions'] = 'Tindakan lain...';
 $labels['select'] = 'Pilih';
 $labels['all'] = 'Semua';
 $labels['none'] = 'Tidak satupun';
 $labels['unread'] = 'Belum terbaca';
 $labels['flagged'] = 'Ditandai';
 $labels['unanswered'] = 'Belum terjawab';
+$labels['deleted'] = 'Terhapus';
+$labels['invert'] = 'Sebaliknya';
 $labels['filter'] = 'Penyaringan';
 $labels['compact'] = 'Ramping';
 $labels['empty'] = 'Kosong';
@@ -131,8 +134,12 @@ $labels['unknown'] = 'Tidak dikenal';
 $labels['unlimited'] = 'Tidak terbatas';
 $labels['quicksearch'] = 'Pencarian cepat';
 $labels['resetsearch'] = 'Atur ulang pencarian';
+$labels['searchmod'] = 'Peubah pencarian';
+$labels['msgtext'] = 'Seluruh pesan';
 $labels['openinextwin'] = 'Buka dalam jendela baru';
+$labels['emlsave'] = 'Unduh (.eml)';
 $labels['compose'] = 'Tulis sebuah pesan';
+$labels['editasnew'] = 'Sunting sebagai pesan baru';
 $labels['savemessage'] = 'Simpan konsep surat  ini';
 $labels['sendmessage'] = 'Kirim pesan sekarang';
 $labels['addattachment'] = 'Sisipkan sebuah berkas';
@@ -232,7 +239,6 @@ $labels['always'] = 'selalu';
 $labels['showinlineimages'] = 'Tampilkan gambar terlampir dibawah pesan';
 $labels['autosavedraft'] = 'Otomatis menyimpan pesan tertunda';
 $labels['everynminutes'] = 'setiap $n menit';
-$labels['keepaliveevery'] = 'setiap $n menit';
 $labels['keepalive'] = 'Periksa pesan baru saat';
 $labels['never'] = 'tidak pernah';
 $labels['messagesdisplaying'] = 'Penampilan Pesan';
@@ -244,6 +250,12 @@ $labels['2047folding'] = 'Full RFC 2047 (other)';
 $labels['advancedoptions'] = 'Pilihan canggih';
 $labels['focusonnewmessage'] = 'Pusatkan jendela broswer saat ada pesan baru';
 $labels['checkallfolders'] = 'Periksa semua map untuk pesan baru';
+$labels['displaynext'] = 'Setelah menghapus/memindahkan, tampilkan pesan berikutnya';
+$labels['mainoptions'] = 'Pilihan Utama';
+$labels['section'] = 'Bagian';
+$labels['maintenance'] = 'Perbaikan';
+$labels['newmessage'] = 'Pesan baru';
+$labels['listoptions'] = 'Daftar Pilihan';
 $labels['folder'] = 'Map';
 $labels['folders'] = 'Map-map';
 $labels['foldername'] = 'Nama map';
index fad4e281a2871382f9588c5cf10082ab8124828d..c159b4582d8c836485bc0c7aeeab9b2f05afb1b8 100644 (file)
@@ -22,6 +22,8 @@ $messages['loginfailed'] = 'Gagal masuk';
 $messages['cookiesdisabled'] = 'Browser Anda tidak menerima cookies';
 $messages['sessionerror'] = 'Session Anda invalid atau kadaluwarsa';
 $messages['imaperror'] = 'Koneksi ke IMAP server gagal';
+$messages['servererror'] = 'Server Error!';
+$messages['invalidrequest'] = 'Permintaan tidak valid! Tidak ada data yang tersimpan.';
 $messages['nomessagesfound'] = 'Surat tidak ditemukan di kotak masuk ini';
 $messages['loggedout'] = 'Anda berhasil mengakhiri session. Selamat Tinggal!';
 $messages['mailboxempty'] = 'Kotak masuk kosong';
@@ -45,6 +47,7 @@ $messages['errorsavingsent'] = 'Error ketika menyimpan pesan terkirim';
 $messages['errorsaving'] = 'Error ketika menyimpan';
 $messages['errormoving'] = 'Pesan tidak bisa dipindahkan';
 $messages['errordeleting'] = 'Pesan tidak bisa dihapus';
+$messages['errormarking'] = 'Tidak dapat menandai pesan';
 $messages['deletecontactconfirm'] = 'Apakah anda yakin untuk menghapus kontak terpilih?';
 $messages['deletemessagesconfirm'] = 'Yakin menghapus pesan terpilih?';
 $messages['deletefolderconfirm'] = 'Apakah anda benar-benar ingin menghapus map ini?';
@@ -94,5 +97,12 @@ $messages['importconfirm'] = '<b>Berhasil mengimpor $inserted kontak, $skipped e
 $messages['opnotpermitted'] = 'Operasi tidak diperbolehkan!';
 $messages['nofromaddress'] = 'kekurangan alamat e-mail pada identitas terpilih';
 $messages['editorwarning'] = 'Beralih pada editor teks murni akan mengakibatkan semua pemformatan teks hilang. Lanjutkan?';
+$messages['httpreceivedencrypterror'] = 'Terjadi sebuah kesalahan pengaturan. Segera hubungi administrator Anda. <b> Pesan Anda tidak bisa terkirim.</b>';
+$messages['smtpconnerror'] = 'SMTP Error ($code): Koneksi ke server gagal';
+$messages['smtpautherror'] = 'SMTP Error ($code): Otentifikasi gagal';
+$messages['smtpfromerror'] = 'SMTP Error ($code): Gagal mengatur pengirim "$from"';
+$messages['smtptoerror'] = 'SMTP Error ($code): Gagal menambah penerima "$to"';
+$messages['smtprecipientserror'] = 'SMTP Error ($code): Tidak dapat menguraikan daftar penerima';
+$messages['smtperror'] = 'SMTP Error : $msg';
 
 ?>
index bb9adc63b55e103543acb0d87946ecd6efe57424..964d41d84862932d497694fb88b41e87e6a1e38b 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: index.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: index.inc 2653 2009-06-18 20:42:48Z yllar $
 
 */
 
@@ -32,6 +32,7 @@ $rcube_languages = array(
   'bs_BA' => 'Bosnian (Serbian Latin)',
   'bg_BG' => 'Bulgarian',
   'bn_BD' => 'Bengali',
+  'br'   => 'Brezhoneg',
   'ca_ES' => 'Català',
   'cy_GB' => 'Cymraeg',
   'zh_CN' => 'Chinese (Simplified)',
@@ -39,6 +40,7 @@ $rcube_languages = array(
   'hr_HR' => 'Croatian (Hrvatski)',
   'cs_CZ' => 'Czech',
   'da_DK' => 'Dansk',
+  'fa_AF' => 'Dari',
   'de_DE' => 'Deutsch (Deutsch)',
   'de_CH' => 'Deutsch (Schweiz)',
   'en_GB' => 'English (GB)',
@@ -73,6 +75,7 @@ $rcube_languages = array(
   'ne_NP' => 'Nepali',
   'nb_NO' => 'Norsk (Bokmål)',
   'nn_NO' => 'Norsk (Nynorsk)',
+  'ps'           => 'Pashto',
   'fa'    => 'Persian (Farsi)',
   'pl_PL' => 'Polski',
   'pt_BR' => 'Portuguese (Brazilian)',
index 52fe7998627e47f1b25a6be2c6fbc607917427fa..48f8d9854499c064ed3bb7caf4104eb4e895d628 100644 (file)
@@ -231,8 +231,7 @@ $labels['fromknownsenders'] = 'frá þekktum sendendum';
 $labels['always'] = 'alltaf';
 $labels['showinlineimages'] = 'Sýna viðhangandi myndir fyrir neðan skeytið';
 $labels['autosavedraft'] = 'Vista sjálfkrafa sem drög';
-$labels['everynminutes'] = 'á $n mínútna fresti';
-$labels['keepaliveevery'] = '$n mínútu fresti';
+$labels['everynminutes'] = '$n mínútu fresti';
 $labels['keepalive'] = 'Athuga ný skeyti á';
 $labels['never'] = 'aldrei';
 $labels['messagesdisplaying'] = 'Sýni skeyti';
index bb936e95bbeefa8267fa6d4ddad8504127944787..ab69f38a50b9f71b8f13b9021a2ced43ac6b459f 100644 (file)
@@ -14,7 +14,7 @@
 |         Yusef Maali <contact@yusefmaali.net>                          |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2900 2009-09-01 11:47:46Z yllar $
 
 */
 
@@ -117,12 +117,14 @@ $labels['markread'] = 'Letti';
 $labels['markunread'] = 'Non letti';
 $labels['markflagged'] = 'Contrassegnati';
 $labels['markunflagged'] = 'Non contrassegnati';
+$labels['messageactions'] = 'Altre azioni...';
 $labels['select'] = 'Seleziona';
 $labels['all'] = 'Tutti';
 $labels['none'] = 'Nessuno';
 $labels['unread'] = 'Non letti';
 $labels['flagged'] = 'Contrassegnati';
 $labels['unanswered'] = 'Senza risposta';
+$labels['deleted'] = 'Cancellato';
 $labels['filter'] = 'Filtra';
 $labels['compact'] = 'Compatta';
 $labels['empty'] = 'Svuota';
@@ -133,7 +135,9 @@ $labels['unlimited'] = 'illimitato';
 $labels['quicksearch'] = 'Ricerca veloce';
 $labels['resetsearch'] = 'Annulla ricerca';
 $labels['openinextwin'] = 'Apri in una nuova finestra';
+$labels['emlsave'] = 'Scarica (.eml)';
 $labels['compose'] = 'Scrivi un messaggio';
+$labels['editasnew'] = 'Modifica come nuovo';
 $labels['savemessage'] = 'Salva come bozza';
 $labels['sendmessage'] = 'Invia il messaggio adesso';
 $labels['addattachment'] = 'Allega un file';
@@ -232,8 +236,7 @@ $labels['fromknownsenders'] = 'da mittenti conosciuti';
 $labels['always'] = 'sempre';
 $labels['showinlineimages'] = 'Mostra immagini allegate sotto il messaggio';
 $labels['autosavedraft'] = 'Salva le bozze automaticamente';
-$labels['everynminutes'] = 'ogni $n minuti';
-$labels['keepaliveevery'] = 'ogni $n minuto(i)';
+$labels['everynminutes'] = 'ogni $n minuto(i)';
 $labels['keepalive'] = 'Controlla la presenza di nuovi messaggi';
 $labels['never'] = 'mai';
 $labels['messagesdisplaying'] = 'Visualizzazione Messaggi';
@@ -245,6 +248,12 @@ $labels['2047folding'] = 'RFC 2047 completo (altri)';
 $labels['advancedoptions'] = 'Opzioni avanzate';
 $labels['focusonnewmessage'] = 'Attiva la finestra del browser all\'arrivo di un nuovo messaggio';
 $labels['checkallfolders'] = 'Controlla tutte le cartelle per la presenza di nuovi messaggi';
+$labels['displaynext'] = 'Dopo aver cancellato/spostato il messaggio mostra quello successivo';
+$labels['mainoptions'] = 'Opzioni principali';
+$labels['section'] = 'Selezione';
+$labels['maintenance'] = 'Manutenzione';
+$labels['newmessage'] = 'Nuovo Messaggio';
+$labels['listoptions'] = 'Mostra Opzioni';
 $labels['folder'] = 'Cartella';
 $labels['folders'] = 'Cartelle';
 $labels['foldername'] = 'Nome cartella';
index fe2d988325fc709e003b63b01857c829ee54a6a4..e7fb4008415590688eb33391a8cef88a181d6836 100644 (file)
@@ -14,7 +14,7 @@
 |         Yusef Maali <contact@yusefmaali.net>                          |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2900 2009-09-01 11:47:46Z yllar $
 
 */
 
@@ -23,6 +23,8 @@ $messages['loginfailed'] = 'Impossibile accedere. Utente o password non corretti
 $messages['cookiesdisabled'] = 'Il tuo browser non accetta i cookies';
 $messages['sessionerror'] = 'Sessione non valida o scaduta';
 $messages['imaperror'] = 'Impossibile connettersi al server IMAP';
+$messages['servererror'] = 'Errore del Server!';
+$messages['invalidrequest'] = 'Richiesta non valida! Nessun dato salvato.';
 $messages['nomessagesfound'] = 'Nessun messaggio trovato in questa cartella';
 $messages['loggedout'] = 'Sessione chiusa correttamente. Arrivederci!';
 $messages['mailboxempty'] = 'La cartella è vuota';
@@ -46,6 +48,7 @@ $messages['errorsavingsent'] = 'C\'è stato un errore nel salvare il messaggio i
 $messages['errorsaving'] = 'Impossibile salvare';
 $messages['errormoving'] = 'Impossibile spostare il messaggio';
 $messages['errordeleting'] = 'Impossibile eliminare il messaggio';
+$messages['errormarking'] = 'Impossibile segnare il messaggio';
 $messages['deletecontactconfirm'] = 'Sei sicuro di voler eliminare i contatti selezionati?';
 $messages['deletemessagesconfirm'] = 'Sei sicuro di voler eliminare i messaggi selezionati?';
 $messages['deletefolderconfirm'] = 'Sei sicuro di voler eliminare la cartella selezionata?';
@@ -95,5 +98,12 @@ $messages['importconfirm'] = '<b>Importati con successo $inserted contatti, salt
 $messages['opnotpermitted'] = 'Operazione non consentita!';
 $messages['nofromaddress'] = 'Indirizzo e-mail mancante nell\'identità selezionata';
 $messages['editorwarning'] = 'Passare all\'editor testuale farà perdere tutte le informazioni di formattazione. Sicuro di voler continuare?';
+$messages['httpreceivedencrypterror'] = 'Fatale errore di configurazione. Per favore contatta l\'amministratore immediatamente. Il tuo messaggio non può essere inviato.';
+$messages['smtpconnerror'] = 'Errore SMTP ($code): Connessione al server fallita';
+$messages['smtpautherror'] = 'Errore SMTP ($code): Autenticazione fallita';
+$messages['smtpfromerror'] = 'Errore SMTP ($code): Fallita l\'impostazione del mittente "$from"';
+$messages['smtptoerror'] = 'Errore SMTP ($code): Fallito l\'inserimento del destinatario "$to"';
+$messages['smtprecipientserror'] = 'Errore SMTP: Impossibile processare la lista dei destinatari';
+$messages['smtperror'] = 'Errore SMTP: $msg';
 
 ?>
index 4e0dbf771fcf51ca828986470365e0abb5cde80e..d4ef97f77c649e8af1059f945b3bfb91f5b2e089 100644 (file)
@@ -14,7 +14,7 @@
 |         Takashi Takamatsu <taka717@gmail.com>                         |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2653 2009-06-18 20:42:48Z yllar $
 
 */
 
@@ -117,23 +117,30 @@ $labels['markread'] = '既読にする';
 $labels['markunread'] = '未読にする';
 $labels['markflagged'] = 'フラグを付ける';
 $labels['markunflagged'] = 'フラグを外す';
+$labels['messageactions'] = 'その他の処理';
 $labels['select'] = '選択';
 $labels['all'] = 'すべて';
 $labels['none'] = 'なし';
 $labels['unread'] = '未読';
 $labels['flagged'] = 'フラグあり';
 $labels['unanswered'] = '未返信';
-$labels['filter'] = 'フィルタ';
+$labels['deleted'] = '削除済';
+$labels['invert'] = '反転';
+$labels['filter'] = 'フィルター';
 $labels['compact'] = 'コンパクト';
 $labels['empty'] = '空';
-$labels['purge'] = '破棄';
+$labels['purge'] = 'ごみ箱を空にする';
 $labels['quota'] = 'ディスク使用量';
 $labels['unknown'] = '不明';
-$labels['unlimited'] = '制限なし';
+$labels['unlimited'] = '無制限';
 $labels['quicksearch'] = '検索';
-$labels['resetsearch'] = '検索の解除';
+$labels['resetsearch'] = '検索解除';
+$labels['searchmod'] = '検索条件';
+$labels['msgtext'] = 'すべてのメール';
 $labels['openinextwin'] = '新しいウィンドウで開く';
+$labels['emlsave'] = 'eml ファイルとして保存';
 $labels['compose'] = 'メールの作成';
+$labels['editasnew'] = '新規として編集';
 $labels['savemessage'] = '下書きに保存';
 $labels['sendmessage'] = '今すぐ送信';
 $labels['addattachment'] = 'ファイルの添付';
@@ -214,6 +221,7 @@ $labels['dstactive'] = '夏時間の適用';
 $labels['htmleditor'] = 'メール作成はHTMLが標準';
 $labels['htmlsignature'] = 'HTML の署名';
 $labels['previewpane'] = 'プレビューペインの表示';
+$labels['skin'] = 'スキン';
 $labels['logoutclear'] = 'ログアウト時にごみ箱を空にする';
 $labels['logoutcompact'] = 'ログアウト時にフォルダのコンパクト化を実行';
 $labels['uisettings'] = 'ユーザーインターフェース';
@@ -226,13 +234,12 @@ $labels['ignore'] = '無視する';
 $labels['readwhendeleted'] = '削除したメールを既読にする';
 $labels['flagfordeletion'] = '実際に削除せずに削除済みフラグを付ける';
 $labels['skipdeleted'] = '削除済みメールを表示しない';
-$labels['showremoteimages'] = 'リモート画像の表示';
-$labels['fromknownsenders'] = '既知の送信者';
+$labels['showremoteimages'] = '外部URLの画像をインライン表示する';
+$labels['fromknownsenders'] = '知り合いから';
 $labels['always'] = '常に';
 $labels['showinlineimages'] = 'メールに添付された画像を表示する';
 $labels['autosavedraft'] = '自動的に下書きを保存';
 $labels['everynminutes'] = '$n 分毎';
-$labels['keepaliveevery'] = '$n 分毎';
 $labels['keepalive'] = '新着メールの確認間隔';
 $labels['never'] = 'しない';
 $labels['messagesdisplaying'] = 'メールの表示';
@@ -242,8 +249,8 @@ $labels['2231folding'] = 'RFC 2231 準拠 (Thunderbird)';
 $labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
 $labels['2047folding'] = 'RFC 2047 準拠 (other)';
 $labels['advancedoptions'] = '高度な設定';
-$labels['focusonnewmessage'] = '新しいメールが届いたらブラウザにフォーカスを移す';
-$labels['checkallfolders'] = 'ã\81\99ã\81¹ã\81¦ã\81®ã\83\95ã\82©ã\83«ã\83\80ã\81®新着メールを確認する';
+$labels['focusonnewmessage'] = '新メールが届いたらブラウザにフォーカスを移す';
+$labels['checkallfolders'] = 'ã\81\99ã\81¹ã\81¦ã\81®ã\83\95ã\82©ã\83«ã\83\80ã\81§新着メールを確認する';
 $labels['folder'] = 'フォルダ';
 $labels['folders'] = 'フォルダ一覧';
 $labels['foldername'] = 'フォルダ名';
@@ -259,7 +266,7 @@ $labels['specialfolders'] = '特殊なフォルダ';
 $labels['sortby'] = '整列の基準にする';
 $labels['sortasc'] = '昇順で整列';
 $labels['sortdesc'] = '降順で整列';
-$labels['B'] = 'B';
+$labels['B'] = 'バイト';
 $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
 $labels['GB'] = 'GB';
index d953b7689d1ba332771b9d0106df3ff3185d958e..39344b53574cf9ccd66e154d061fcb95a320fbd2 100644 (file)
@@ -14,7 +14,7 @@
 |         Takashi Takamatsu <taka717@gmail.com>                         |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2653 2009-06-18 20:42:48Z yllar $
 
 */
 
@@ -23,13 +23,14 @@ $messages['loginfailed'] = 'ログインに失敗しました。';
 $messages['cookiesdisabled'] = 'ブラウザで Cookie が無効に設定されています。';
 $messages['sessionerror'] = 'セッションが正しくないか期限切れです。';
 $messages['imaperror'] = 'IMAP サーバへの接続に失敗しました。';
+$messages['servererror'] = 'サーバエラーが発生しました。';
 $messages['nomessagesfound'] = 'メールはありません。';
 $messages['loggedout'] = 'ログアウトしました。';
 $messages['mailboxempty'] = 'メールボックスは空です。';
-$messages['loading'] = '読み込み中...';
-$messages['loadingdata'] = 'データを読み込み中です...';
-$messages['checkingmail'] = 'ã\83¡ã\83¼ã\83«ã\81®ç¢ºèª\8d中ã\81§す...';
-$messages['sendingmessage'] = 'メールを送信中です...';
+$messages['loading'] = '読中...';
+$messages['loadingdata'] = 'データを読込中...';
+$messages['checkingmail'] = 'ã\83¡ã\83¼ã\83«ã\82\92確èª\8dã\81\97ã\81¦ã\81\84ã\81¾す...';
+$messages['sendingmessage'] = 'メールを送信しています...';
 $messages['messagesent'] = 'メールを送信しました。';
 $messages['savingmessage'] = 'メールを保存しています...';
 $messages['messagesaved'] = 'メールを下書きに保存しました。';
@@ -40,20 +41,21 @@ $messages['blockedimages'] = 'プライバシー保護のため、このメー
 $messages['encryptedmessage'] = 'このメールは暗号化されているため表示できません。';
 $messages['nocontactsfound'] = '連絡先がありません。';
 $messages['contactnotfound'] = '要求された連絡先が見つかりません。';
-$messages['sendingfailed'] = 'メール送信に失敗しました。';
-$messages['senttooquickly'] = 'このメールを送信する前に、$sec お待ちください。';
+$messages['sendingfailed'] = 'メール送信に失敗しました。';
+$messages['senttooquickly'] = 'このメールを送信するまで $sec 秒お待ちください。';
 $messages['errorsavingsent'] = '送信メールの保存中にエラーが発生しました。';
 $messages['errorsaving'] = '保存中にエラーが発生しました。';
 $messages['errormoving'] = 'メールを移動できません。';
 $messages['errordeleting'] = 'メールを削除できません。';
+$messages['errormarking'] = 'メールをマークできません。';
 $messages['deletecontactconfirm'] = '選択した連絡先を本当に削除しますか?';
 $messages['deletemessagesconfirm'] = '選択したメールを本当に削除しますか?';
 $messages['deletefolderconfirm'] = 'このフォルダを本当に削除しますか?';
 $messages['purgefolderconfirm'] = 'このフォルダの全てのメールを本当に削除しますか?';
-$messages['foldercreating'] = 'ã\83\95ã\82©ã\83«ã\83\80ã\81®ä½\9cæ\88\90中ã\81§す...';
-$messages['folderdeleting'] = 'ã\83\95ã\82©ã\83«ã\83\80ã\81®å\89\8aé\99¤ä¸­ã\81§す...';
-$messages['folderrenaming'] = 'ã\83\95ã\82©ã\83«ã\83\80å\90\8dã\81®å¤\89æ\9b´ä¸­ã\81§す...';
-$messages['foldermoving'] = 'ã\83\95ã\82©ã\83«ã\83\80ã\81®ç§»å\8b\95中ã\81§す...';
+$messages['foldercreating'] = 'ã\83\95ã\82©ã\83«ã\83\80ã\82\92ä½\9cæ\88\90ã\81\97ã\81¦ã\81\84ã\81¾す...';
+$messages['folderdeleting'] = 'ã\83\95ã\82©ã\83«ã\83\80ã\82\92å\89\8aé\99¤ã\81\97ã\81¦ã\81\84ã\81¾す...';
+$messages['folderrenaming'] = 'ã\83\95ã\82©ã\83«ã\83\80å\90\8dã\82\92å¤\89æ\9b´ã\81\97ã\81¦ã\81\84ã\81¾す...';
+$messages['foldermoving'] = 'ã\83\95ã\82©ã\83«ã\83\80ã\82\92移å\8b\95ã\81\97ã\81¦ã\81\84ã\81¾す...';
 $messages['formincomplete'] = 'フォームの項目が完全に入力されていません。';
 $messages['noemailwarning'] = '有効なメールアドレスを入力して下さい。';
 $messages['nonamewarning'] = '名前を入力して下さい。';
@@ -68,20 +70,20 @@ $messages['nocontactsreturned'] = '連絡先がありません。';
 $messages['nosearchname'] = '連絡先の名前かメールアドレスを入力して下さい。';
 $messages['searchsuccessful'] = ' $nr 件のメールが見つかりました。';
 $messages['searchnomatch'] = '一致するメールはありません。';
-$messages['searching'] = '検索中です...';
-$messages['checking'] = '確認中です...';
+$messages['searching'] = '検索中...';
+$messages['checking'] = '確認中...';
 $messages['nospellerrors'] = 'スペルミスは見つかりませんでした。';
 $messages['folderdeleted'] = 'フォルダを削除しました。';
 $messages['deletedsuccessfully'] = '削除しました。';
-$messages['converting'] = 'メールから書式を削除中です...';
+$messages['converting'] = 'メールから書式を削除しています...';
 $messages['messageopenerror'] = 'サーバからメールを取得できません。';
 $messages['fileuploaderror'] = 'ファイルのアップロードに失敗しました。';
-$messages['filesizeerror'] = 'ã\82¢ã\83\83ã\83\97ã\83­ã\83¼ã\83\89ã\81\97ã\81\9fã\83\95ã\82¡ã\82¤ã\83«ã\81®ã\82µã\82¤ã\82ºã\81\8cä¸\8aé\99\90 $size ã\82\92è¶\85ã\81\88ã\81¾ã\81\97ã\81\9fã\80\82';
+$messages['filesizeerror'] = 'アップロードファイルのサイズが上限 $size を超えました。';
 $messages['copysuccess'] = 'アドレス $nr 個のコピーに成功しました。';
 $messages['copyerror'] = 'アドレスをコピーできません。';
-$messages['sourceisreadonly'] = 'このアドレス情報は読み取り専用です。';
+$messages['sourceisreadonly'] = 'このアドレス情報は読専用です。';
 $messages['errorsavingcontact'] = '連絡先のアドレスを保存できません。';
-$messages['movingmessage'] = '移動中です...';
+$messages['movingmessage'] = 'メールを移動しています...';
 $messages['receiptsent'] = '開封確認を送信しました。';
 $messages['errorsendingreceipt'] = '開封確認を送信できません。';
 $messages['nodeletelastidentity'] = '削除できません。少なくとも1つの個人情報が必要です。';
@@ -90,10 +92,11 @@ $messages['forbiddencharacter'] = 'フォルダ名に利用できない文字が
 $messages['selectimportfile'] = 'アップロードするファイルを選択してください。';
 $messages['addresswriterror'] = '選択したアドレス帳に書き込めません。';
 $messages['importwait'] = 'インポート中です。しばらくお待ちください...';
-$messages['importerror'] = 'インポートに失敗しました。アップロードしたファイルは正しくない vCard ファイルです。';
-$messages['importconfirm'] = '<b>$inserted ä»¶ã\81®é\80£çµ¡å\85\88ã\81®ã\82¤ã\83³ã\83\9dã\83¼ã\83\88ã\81«æ\88\90å\8a\9fã\81¾ã\81\97ã\81\9fã\80\82<br />$skipped ä»¶ã\81®ç\99»é\8c²æ¸\88ã\81¿é\80£çµ¡å\85\88ã\82\92ã\82¹ã\82­ã\83\83ã\83\97ã\81\97ã\81¾ã\81\97ã\81\9fã\80\82</b><p><em>$names</em></p>';
+$messages['importerror'] = 'インポートに失敗しました。アップロードしたファイルは不正な vCard ファイルです。';
+$messages['importconfirm'] = '<b>$inserted ä»¶ã\81®é\80£çµ¡å\85\88ã\82\92ã\82¤ã\83³ã\83\9dã\83¼ã\83\88ã\81\97ã\81¾ã\81\97ã\81\9fã\80\82<br />æ\97¢ç\99»é\8c²ã\81®é\80£çµ¡å\85\88 $skipped ä»¶ã\82\92ã\82¹ã\82­ã\83\83ã\83\97ã\81\97ã\81¾ã\81\97ã\81\9f</b>ï¼\9a<p><em>$names</em></p>';
 $messages['opnotpermitted'] = 'その操作は許可されていません。';
-$messages['nofromaddress'] = '選択中の個人情報のメールアドレスが失われました';
-$messages['editorwarning'] = 'テキストエディタに切替えるとすべての装飾が失われます。切替えてもよろしいですか?';
+$messages['nofromaddress'] = '選択中の個人情報にメールアドレスが含まれていません。';
+$messages['editorwarning'] = 'テキストエディタに切り替えるとすべての書式が失われます。よろしいですか?';
+$messages['httpreceivedencrypterror'] = '致命的な設定エラーが発生しました。<b>メッセージは送信されませんでした。</b>システム管理者に至急連絡してください。';
 
 ?>
index 1ff4b55df8d7471f574f45a1f974f2e62cc23ed0..5a000f674fbbbd601e15b85b416f446b2d6653df 100755 (executable)
@@ -231,7 +231,6 @@ $labels['always'] = 'ყოველთვის';
 $labels['showinlineimages'] = 'ატვირთული სურათები გამოაჩინე გზავნილის ქვემოთ';
 $labels['autosavedraft'] = 'ავტომატური შენახვა';
 $labels['everynminutes'] = 'ყოველ $n წუთში';
-$labels['keepaliveevery'] = 'ყოველ $n წუთში';
 $labels['keepalive'] = 'შეამოწმე ახალ შეტყობინებაზე';
 $labels['never'] = 'არასდროს';
 $labels['messagesdisplaying'] = 'გამოაჩინე შეტყობინებები';
index 0e108f1af9d94ffdcb22d194a02a2ede6d501ef4..370cebe1c5720aee3ae10e3b3b5c347cd9dc4890 100644 (file)
@@ -232,7 +232,6 @@ $labels['always'] = '항상';
 $labels['showinlineimages'] = '메시지 아래에 첨부 이미지 보이기';
 $labels['autosavedraft'] = '드래프트 자동 저장';
 $labels['everynminutes'] = '$n 분마다';
-$labels['keepaliveevery'] = '$n 분마다';
 $labels['keepalive'] = '다음 간격마다 새 메시지 자동 체크';
 $labels['never'] = '하지 않음';
 $labels['messagesdisplaying'] = '메시지 표시 중';
index 3edd3e559522dd66ba2b1676f1c949d1b3e9a84f..bc9e8216aefaa6a05f16014b16cc4830b5609f02 100644 (file)
@@ -169,7 +169,6 @@ $labels['htmleditor'] = 'Peyameke HTML biafirîne';
 $labels['htmlsignature'] = 'Şanenava HTML';
 $labels['previewpane'] = 'Panela berê nîşan bide';
 $labels['autosavedraft'] = 'Xweber hilîne';
-$labels['everynminutes'] = 'her $n çirke';
 $labels['never'] = 'qet';
 $labels['folder'] = 'Peldank';
 $labels['folders'] = 'Peldank';
index b3e04402b489381aba42634f5f3bf5faf1ee4a77..55a3acbbcbaf2447e9b1857397c2662822fa2b41 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Martynas Bendorius <martynas@evanet.lt>                       |
 +-----------------------------------------------------------------------+'
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2891 2009-08-29 18:56:48Z yllar $
 
 */
 
@@ -47,7 +47,7 @@ $labels['mailboxlist'] = 'Aplankai';
 $labels['messagesfromto'] = 'Laiškai nuo $from iki $to iš $count';
 $labels['messagenrof'] = 'Laiškas $nr iš $count';
 $labels['moveto'] = 'perkelti į ...';
-$labels['download'] = 'parsisiųsti';
+$labels['download'] = 'Parsisiųsti';
 $labels['filename'] = 'Bylos vardas';
 $labels['filesize'] = 'Bylos dydis';
 $labels['preferhtml'] = 'Rodyti HTML';
@@ -116,12 +116,15 @@ $labels['markread'] = 'Kaip perskaitytus';
 $labels['markunread'] = 'Kaip neperskaitytus';
 $labels['markflagged'] = 'Kaip pažymėtą';
 $labels['markunflagged'] = 'Kaip nepažymėtą';
+$labels['messageactions'] = 'Daugiau veiksmų';
 $labels['select'] = 'Pažymėti';
 $labels['all'] = 'Visus';
 $labels['none'] = 'Nieko';
 $labels['unread'] = 'Neskaitytas';
 $labels['flagged'] = 'Pažymėtas';
 $labels['unanswered'] = 'Neatsakytas';
+$labels['deleted'] = 'Pašalintas';
+$labels['invert'] = 'Invertuoti';
 $labels['filter'] = 'Filtruoti';
 $labels['compact'] = 'Suspausti';
 $labels['empty'] = 'Ištuštinti';
@@ -131,8 +134,12 @@ $labels['unknown'] = 'nežinomas';
 $labels['unlimited'] = 'neribotas';
 $labels['quicksearch'] = 'Greita paieška';
 $labels['resetsearch'] = 'Atšaukti paiešką';
+$labels['searchmod'] = 'Paieškos modifikatoriai';
+$labels['msgtext'] = 'Visas laiškas';
 $labels['openinextwin'] = 'Atidaryti naujame lange';
+$labels['emlsave'] = 'Parsiųsti (.eml)';
 $labels['compose'] = 'Rašyti nauja laiška';
+$labels['editasnew'] = 'Redaguoti kaip naują';
 $labels['savemessage'] = 'Išsaugoti šį juodraštį';
 $labels['sendmessage'] = 'Išsiųsti laiską';
 $labels['addattachment'] = 'Prisegti bylą';
@@ -231,8 +238,7 @@ $labels['fromknownsenders'] = 'iš žinomų siuntėjų';
 $labels['always'] = 'visada';
 $labels['showinlineimages'] = 'Rodyti prisegtus paveikslėlius žemiau laiško';
 $labels['autosavedraft'] = 'Automatiškai išsaugoti juodraščius';
-$labels['everynminutes'] = 'kas $n minutes(-čių)';
-$labels['keepaliveevery'] = 'kas $n minutę(-čių)';
+$labels['everynminutes'] = 'kas $n minutę(-čių)';
 $labels['keepalive'] = 'Tikrinti ar nėra naujų pranešimus';
 $labels['never'] = 'niekada';
 $labels['messagesdisplaying'] = 'Laiškų rodymas';
@@ -244,6 +250,12 @@ $labels['2047folding'] = 'Pilnas RFC 2047 (kita)';
 $labels['advancedoptions'] = 'Papildomi nustatymai';
 $labels['focusonnewmessage'] = 'Fokusuoti naršyklės langą gavus naują laišką';
 $labels['checkallfolders'] = 'Tikrinti ar nėra naujų laiškų visuose aplankuose';
+$labels['displaynext'] = 'Po laiško pašalinimo/perkėlimo rodyti pranešimą';
+$labels['mainoptions'] = 'Pagrindiniai nustatymai';
+$labels['section'] = 'Sekcija';
+$labels['maintenance'] = 'Priežiūra';
+$labels['newmessage'] = 'Naujas laiškas';
+$labels['listoptions'] = 'Rodyti nustatymus';
 $labels['folder'] = 'Aplankas';
 $labels['folders'] = 'Aplankai';
 $labels['foldername'] = 'Aplanko vardas';
index dd1d30927eb544000a04f73ae3302cedde30ba56..103f399cd02c5ac2d7ad9fe4de11149e4074b120 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Martynas Bendorius <martynas@evanet.lt>                       |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2891 2009-08-29 18:56:48Z yllar $
 
 */
 
@@ -22,6 +22,8 @@ $messages['loginfailed'] = 'Prisijungti nepavyko';
 $messages['cookiesdisabled'] = 'Jūsų naršyklė nepriima slapukų';
 $messages['sessionerror'] = 'Jūsų sesija negaliojanti';
 $messages['imaperror'] = 'Nepavyko prisijungti prie IMAP serverio';
+$messages['servererror'] = 'Serverio klaida!';
+$messages['invalidrequest'] = 'Neteisinga užklausa! Duomenys neišsaugoti.';
 $messages['nomessagesfound'] = 'Šioje pašto dėžutėje laiškų nėra ';
 $messages['loggedout'] = 'Jus sėkmingai atsijungėte. Viso gero!';
 $messages['mailboxempty'] = 'Pašto dėžutė tuščia';
@@ -45,6 +47,7 @@ $messages['errorsavingsent'] = 'Išsaugant išsiųstą laišką įvyko klaida';
 $messages['errorsaving'] = 'Išsaugant įvyko klaida';
 $messages['errormoving'] = 'Laiško perkelti nepavyko';
 $messages['errordeleting'] = 'Laiško ištrinti nepavyko';
+$messages['errormarking'] = 'Nepavyko pažymėti laiško';
 $messages['deletecontactconfirm'] = 'Ar jūs tikrai norite ištrinti pasirinktą(-us) kontaktą(-us)?';
 $messages['deletemessagesconfirm'] = 'Ar jūs tikrai norite ištrinti pasirinktą(-us) žinutę(-es)?';
 $messages['deletefolderconfirm'] = 'Ar jūs tikrai norite ištrinti šį aplanką?';
@@ -94,5 +97,12 @@ $messages['importconfirm'] = '<b>Sėkmingai importuoti $inserted kontaktai, $ski
 $messages['opnotpermitted'] = 'Operacija neleistina!';
 $messages['nofromaddress'] = 'Nerastas el. pašto adresas pasirinktoje tapatybėje';
 $messages['editorwarning'] = 'Pereinant tik į teksto redagavimą visas formatavimas bus prarastas. Ar tikrai norite vykdyti užklausą?';
+$messages['httpreceivedencrypterror'] = 'Įvyko lemtinga konfigūracijos klaida. Nedelsiant susisiekite su administratoriumi. <b>Jūsų laiškas negali būti išsiųstas.</b>';
+$messages['smtpconnerror'] = 'SMTP klaida ($code): Nepavyko prisijungti prie serverio';
+$messages['smtpautherror'] = 'SMTP klaida ($code): Autentifikacija neįvyko';
+$messages['smtpfromerror'] = 'SMTP klaida ($code): Nepavyko nustatyti siuntėjo "$from"';
+$messages['smtptoerror'] = 'SMTP klaida ($code): Nepavyko pridėti gavėjo "$to"';
+$messages['smtprecipientserror'] = 'SMTP klaida: Nepavyko apdoroti gavėjų sąrašo';
+$messages['smtperror'] = 'SMTP klaida: $msg';
 
 ?>
index b34df37c23d88e6207dec70ee5bfa9bbe6c8b498..ac2c7aaff4c105e509d5206ad7dcba5364ca0ef7 100644 (file)
@@ -15,7 +15,7 @@
 |         Lauris Bukšis-Haberkorns <lauris@nix.lv>                      |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -231,8 +231,7 @@ $labels['fromknownsenders'] = 'no zināmiem sūtītājiem';
 $labels['always'] = 'vienmēr';
 $labels['showinlineimages'] = 'Attēlot pielikuma attēlus zem vēstules';
 $labels['autosavedraft'] = 'Automātiski saglabāt uzmetumu';
-$labels['everynminutes'] = 'katras $n minūtes';
-$labels['keepaliveevery'] = 'katru $n minūti(-es)';
+$labels['everynminutes'] = 'katru $n minūti(-es)';
 $labels['keepalive'] = 'Pārbaudīt jaunas vēstules mapēs';
 $labels['never'] = 'nekad';
 $labels['messagesdisplaying'] = 'Vēstuļu attēlošana';
index 3331df477a8c7e67cf704c929eecd2f4c9e177f9..4d2e16cf93e3c14fd8485c6bf8229cbeffb47183 100644 (file)
@@ -15,7 +15,7 @@
 |         Lauris Bukšis-Haberkorns <lauris@nix.lv>                      |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: messages.inc 2400 2009-04-19 11:32:56Z yllar $
 
 */
 
index 0e8f49771d1bf0bff7f9556fbcea2297a5bc5817..250010e56108aee20159700670683ff6f48432c0 100755 (executable)
@@ -231,7 +231,6 @@ $labels['always'] = 'секогаш';
 $labels['showinlineimages'] = 'Прикажи ги прикачените слики под пораката';
 $labels['autosavedraft'] = 'Авоматски снимај во Непратени';
 $labels['everynminutes'] = 'секои $n минути';
-$labels['keepaliveevery'] = 'секои $n минути';
 $labels['keepalive'] = 'Провери за нови пораки на';
 $labels['never'] = 'никогаш';
 $labels['messagesdisplaying'] = 'Прикажување на порака';
diff --git a/program/localization/mr_IN/labels.inc b/program/localization/mr_IN/labels.inc
new file mode 100755 (executable)
index 0000000..2f862bd
--- /dev/null
@@ -0,0 +1,263 @@
+<?php
+
+/*
++-----------------------------------------------------------------------+
+| language/mr_IN/labels.inc                                             |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2009, RoundQube Dev. - Switzerland                      |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author:Nitin Nimkar <nvncom at yahoo.com>                             |
++-----------------------------------------------------------------------+
+
+*/
+
+$labels = array();
+$labels['welcome'] = '$product वरती स्वागत आहे';
+$labels['username'] = 'वापरकर्त्याचे नाव(तुमचे इमेल) ';
+$labels['password'] = 'परवलीचा शब्द';
+$labels['server'] = 'सर्व्हर';
+$labels['login'] = 'प्रवेश';
+$labels['logout'] = 'बाहेर जा';
+$labels['mail'] = 'इ-मेल';
+$labels['settings'] = 'तुमची पसंती';
+$labels['addressbook'] = 'पत्ता नोंदवही';
+$labels['inbox'] = 'आलेले संदेश';
+$labels['drafts'] = 'मसुदा';
+$labels['sent'] = 'पाठवलेले';
+$labels['trash'] = 'कचरा पेटी';
+$labels['junk'] = 'नको असलेले कचरा संदेश्';
+$labels['subject'] = 'विषय';
+$labels['from'] = 'पाठवणार';
+$labels['to'] = 'प्रती';
+$labels['cc'] = 'प्रत';
+$labels['bcc'] = 'गुप्त प्रत';
+$labels['replyto'] = 'उत्तर द्या ';
+$labels['date'] = 'दिनांक';
+$labels['size'] = 'आकार';
+$labels['priority'] = 'प्राधान्य';
+$labels['organization'] = 'संस्था';
+$labels['reply-to'] = 'उत्तर द्या ';
+$labels['mailboxlist'] = 'फोल्डर्स';
+$labels['messagesfromto'] = '$from कडून $to साठी $count वा';
+$labels['messagenrof'] = 'Message $nr of $count';
+$labels['moveto'] = 'या फोल्डरमधे ठेवा';
+$labels['download'] = 'उतरवून घ्या';
+$labels['filename'] = 'फाईलचे नाव';
+$labels['filesize'] = 'फाईलचा आकार';
+$labels['preferhtml'] = 'एच टी एम एल दाखवा';
+$labels['htmlmessage'] = 'एच टी एम एल संदेश';
+$labels['prettydate'] = 'विशेष दिवस';
+$labels['addtoaddressbook'] = 'पत्ता नोंदवहीत नोंदवा ';
+$labels['sun'] = 'रवी';
+$labels['mon'] = 'सोम';
+$labels['tue'] = 'मंगळ';
+$labels['wed'] = 'बुध';
+$labels['thu'] = 'गुरु';
+$labels['fri'] = 'शुक्र';
+$labels['sat'] = 'शनी';
+$labels['sunday'] = 'रविवार';
+$labels['monday'] = 'सोमवार';
+$labels['tuesday'] = 'मंगळवार';
+$labels['wednesday'] = 'बुधवार';
+$labels['thursday'] = 'गुरुवार';
+$labels['friday'] = 'शुक्रवार';
+$labels['saturday'] = 'शनीवार';
+$labels['jan'] = 'जान';
+$labels['feb'] = 'फेब्';
+$labels['mar'] = 'मार्च';
+$labels['apr'] = 'एप्रिल';
+$labels['may'] = 'मे';
+$labels['jun'] = 'जून';
+$labels['jul'] = 'जुलै';
+$labels['aug'] = 'ऑगस्ट';
+$labels['sep'] = 'सप्टें';
+$labels['oct'] = 'ऑक्टो';
+$labels['nov'] = 'नोव्हें';
+$labels['dec'] = 'डिसें';
+$labels['longjan'] = 'जानेवारी';
+$labels['longfeb'] = 'फेब्रूवारी';
+$labels['longmar'] = 'मार्च';
+$labels['longapr'] = 'एप्रिल';
+$labels['longmay'] = 'मे';
+$labels['longjun'] = 'जून';
+$labels['longjul'] = 'जुलै';
+$labels['longaug'] = 'ऑगस्ट';
+$labels['longsep'] = 'सप्टेंबर';
+$labels['longoct'] = 'ऑक्टोबर';
+$labels['longnov'] = 'नोव्हेंबर';
+$labels['longdec'] = 'डिसेंबर';
+$labels['today'] = 'आज';
+$labels['checkmail'] = 'नवीन संदेश आले आहेत का पहा';
+$labels['writenewmessage'] = 'नवीन संदेश तयार करा';
+$labels['replytomessage'] = 'उत्तर द्या';
+$labels['replytoallmessage'] = 'पाठवणार्‍याला आणि प्रत केलेल्या सर्वांना संदेश पाठवा';
+$labels['forwardmessage'] = 'हा संदेश पाठवा';
+$labels['deletemessage'] = 'संदेश काढून टाका';
+$labels['movemessagetotrash'] = 'संदेश कचरापेटीत टाका';
+$labels['printmessage'] = 'हा संदेश छापा';
+$labels['previousmessage'] = 'आधिचा संदेश दाखवा';
+$labels['previousmessages'] = 'आधिच्या संदेशांचा गट दाखवा';
+$labels['firstmessage'] = 'पहिला संदेश दाखवा';
+$labels['firstmessages'] = 'पहिला संदेशांचा गट दाखवा';
+$labels['nextmessage'] = 'नंतरचा संदेश दाखवा';
+$labels['nextmessages'] = 'नंतरचा संदेशांचा गट दाखवा';
+$labels['lastmessage'] = 'शेवटचा संदेश दाखवा';
+$labels['lastmessages'] = 'शेवटचा संदेशांचा गट दाखवा';
+$labels['backtolist'] = 'संदेशांच्या यादीकडे परत चला';
+$labels['viewsource'] = 'मूळ संदेशाचा प्रोग्राम कोड दाखवा';
+$labels['markmessages'] = 'संदेशाला खूण करा';
+$labels['markread'] = 'वाचलेला म्हणून खूण करा';
+$labels['markunread'] = 'न वाचलेला म्हणून खूण करा';
+$labels['markflagged'] = 'खूण लावलेला म्हणून खूण करा';
+$labels['markunflagged'] = 'खूण काढलेला म्हणून खूण करा';
+$labels['select'] = 'निवडा';
+$labels['all'] = 'सर्व';
+$labels['none'] = 'कोणताही नाही';
+$labels['unread'] = 'न वाचलेले';
+$labels['flagged'] = 'खूण लावलेले';
+$labels['unanswered'] = 'उत्तर न दिलेले';
+$labels['filter'] = 'गाळणी';
+$labels['compact'] = 'कमितकमी करा';
+$labels['empty'] = 'रिकामा';
+$labels['purge'] = 'काढून टाका';
+$labels['quota'] = 'डिस्कचा वापर';
+$labels['unknown'] = 'माहित नसलेला';
+$labels['unlimited'] = 'अमर्याद';
+$labels['quicksearch'] = 'चटकन शोध';
+$labels['resetsearch'] = 'परत शोध ';
+$labels['openinextwin'] = 'नवीन खिडकी उघडा';
+$labels['compose'] = 'नवीन संदेश तयार करा';
+$labels['savemessage'] = 'हा मसूदा ठेऊन द्या';
+$labels['sendmessage'] = 'आत्ता पाठवा';
+$labels['addattachment'] = 'फाईल सोबत जोडा';
+$labels['charset'] = 'कॅरेक्टर सेट';
+$labels['editortype'] = 'संपादकाचा प्रकार';
+$labels['returnreceipt'] = 'पोच पावती';
+$labels['checkspelling'] = 'शुध्द लेखन';
+$labels['resumeediting'] = 'परत संदेश तयार करणे चालू करा';
+$labels['revertto'] = 'परत जा';
+$labels['attachments'] = 'जोडलेल्या';
+$labels['upload'] = 'चढवा';
+$labels['close'] = 'बंद';
+$labels['low'] = 'कमी';
+$labels['lowest'] = 'कमित कमी';
+$labels['normal'] = 'नेहमी प्रमाणे';
+$labels['high'] = 'तातडीचे';
+$labels['highest'] = 'अतिशय तातडीचे';
+$labels['nosubject'] = '(विषय नाही)';
+$labels['showimages'] = 'चित्र दाखवा';
+$labels['alwaysshow'] = '$sender कडून आलेल्या संदेशातील चित्र दाखवा';
+$labels['htmltoggle'] = 'एच टी एम एल';
+$labels['plaintoggle'] = 'साधे टेक्स्ट';
+$labels['savesentmessagein'] = 'पाठवलेला संदेश या फोल्डरमधे ठेवा';
+$labels['dontsave'] = 'संदेश ठेवू नका';
+$labels['maxuploadsize'] = '$size हा जास्तित जास्त फाईलचा आकार';
+$labels['addcc'] = 'प्रत करा';
+$labels['addbcc'] = 'गुप्त प्रत करा';
+$labels['addreplyto'] = 'आणखी लोकांना संदेश पाठवा';
+$labels['mdnrequest'] = 'हा संदेश पाठवणार्‍याने हा संदेश तुम्ही वाचल्यावर कळवावयाला सांगितले आहे. तुम्हाला असे कळवणे चालेल ना?';
+$labels['receiptread'] = 'पोच पावती (संदेश वाचला)';
+$labels['yourmessage'] = 'ही तुमच्या संदेशाची पोच पावती आहे. ';
+$labels['receiptnote'] = 'सूचना: ही पोच पावती तुम्ही ज्यांना  संदेश पाठवला त्यांच्या संगणकावर दिसला एवढेच सांगते. तुम्ही ज्यांना हा संदेश पाठवला, त्यांनी तो वाचला, आणि त्यांना तो नक्की समजला हे मात्र सांगत नाही. ';
+$labels['name'] = 'टोपणनाव';
+$labels['firstname'] = 'नाव';
+$labels['surname'] = 'आडनाव';
+$labels['email'] = 'इ-मेल्';
+$labels['addcontact'] = 'नवीन पत्ता नोंदवहीत ठेवा';
+$labels['editcontact'] = 'नोंदवहीतील पत्ता सुधारा';
+$labels['edit'] = 'संदेश तयार करा';
+$labels['cancel'] = 'रद्द करा';
+$labels['save'] = 'ठेवून द्या';
+$labels['delete'] = 'काढून टाका';
+$labels['newcontact'] = 'नोंदवहीत नवीन संपर्क लिहिण्यासाठी';
+$labels['deletecontact'] = 'खूण केलेले सर्व संपर्काचे पत्ते काढून टाका';
+$labels['composeto'] = 'साठी नवीन संदेश तयार करा';
+$labels['contactsfromto'] = '$from पासून ते $to पर्यंत $count पैकी';
+$labels['print'] = 'छापा';
+$labels['export'] = 'निर्यात करा';
+$labels['exportvcards'] = 'व्ही कार्ड स्वरुपात पत्ते निर्यात करा';
+$labels['previouspage'] = 'आधिचा गट दाखवा';
+$labels['firstpage'] = 'पहिला गट दाखवा';
+$labels['nextpage'] = 'नंतरचा गट दाखवा';
+$labels['lastpage'] = 'शेवटचा गट दाखवा';
+$labels['groups'] = 'गट';
+$labels['personaladrbook'] = 'वैयक्तिक पत्ते';
+$labels['import'] = 'आयात करा';
+$labels['importcontacts'] = 'पत्ते आयात करा';
+$labels['importfromfile'] = 'या फाईल मधून आयात करा';
+$labels['importreplace'] = 'संपूर्ण पत्ता नोंदवही बदला';
+$labels['importtext'] = 'तुम्ही तुमच्याकडील पत्ता नोंदवहीतील पत्ते तुम्ही येथे घेऊ शकता.<br/>सध्या आम्ही या <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> प्रकारच्या वेगवेगळ्या नोंदवहीतील पत्ते घेऊ शकतो. ';
+$labels['done'] = 'झाले';
+$labels['settingsfor'] = 'साठी सेटिंग्ज';
+$labels['preferences'] = 'तुमची पसंती';
+$labels['userpreferences'] = 'वापरकर्त्याची पसंती';
+$labels['editpreferences'] = 'वापरकर्त्याची पसंती सुधारा';
+$labels['identities'] = 'ओळख';
+$labels['manageidentities'] = 'या खात्यासाठी ओळखींचे नियोजन करा';
+$labels['newidentity'] = 'नवीन ओळख';
+$labels['newitem'] = 'नवीन प्रकार';
+$labels['edititem'] = 'प्रकार सुधारा';
+$labels['setdefault'] = 'हा नेहमीसाठी वापरा';
+$labels['autodetect'] = 'स्वयंचलित';
+$labels['language'] = 'भाषा';
+$labels['timezone'] = 'आंतराष्ट्रीय वेळ';
+$labels['pagesize'] = 'प्रत्येक पानावरील ओळी';
+$labels['signature'] = 'सही';
+$labels['dstactive'] = 'दिवसाची वेळ';
+$labels['htmleditor'] = 'एच टी एम एल संदेश तयारा करा';
+$labels['htmlsignature'] = 'एच टी एम एल सही';
+$labels['previewpane'] = 'प्रक्रियापूर्व तावदान दाखवा';
+$labels['skin'] = 'दृष्य गोष्टी';
+$labels['logoutclear'] = 'खात्यातून बाहेर पडतांना कचरा पेटी साफ करा';
+$labels['logoutcompact'] = 'खात्यातून बाहेर पडतांना आलेल्या संदेशांना छोटे आणि व्यवस्थित करा';
+$labels['uisettings'] = 'वापरकर्त्यासाठीचा इंटरफेस';
+$labels['serversettings'] = 'सर्व्हरची सेटिंग्ज';
+$labels['mailboxview'] = 'टपाल पेटी पहाणे';
+$labels['mdnrequests'] = 'पाठवणार्‍याच्या सूचना';
+$labels['askuser'] = 'वापरकर्त्याला विचारा';
+$labels['autosend'] = 'स्वयंचलित (आपोआप पाठेवणे)';
+$labels['ignore'] = 'दुर्लक्ष करा';
+$labels['readwhendeleted'] = 'काढून टाकल्यावर संदेश वाचला असे दाखवा';
+$labels['flagfordeletion'] = 'संदेश काढून टाकण्या ऎवजी संदेश काढून टाकण्यासाठी आहे अशी खूण करा';
+$labels['skipdeleted'] = 'काढून टाकलेले संदेश दाखवू नका';
+$labels['showremoteimages'] = 'संदेशातील चित्रे दाखवा';
+$labels['fromknownsenders'] = 'माहितीतील पाठवणार्‍याकडून संदेश';
+$labels['always'] = 'नेहमी';
+$labels['showinlineimages'] = 'सोबत जोडलेली चित्रे संदेशाच्या खाली दाखवा';
+$labels['autosavedraft'] = 'मसूदा आपोआप जतन करा';
+$labels['everynminutes'] = 'प्रत्येक $n मिनिटांनी';
+$labels['keepalive'] = 'वर नवे संदेश आले आहेत का ते पहा';
+$labels['never'] = 'केंव्हाच नाही';
+$labels['messagesdisplaying'] = 'संदेश दाखवा';
+$labels['messagescomposition'] = 'संदेश तयार करा';
+$labels['mimeparamfolding'] = 'सोबत दिलेल्या फाईल्सची नावे ';
+$labels['2231folding'] = 'संपूर्ण        आर एफ सी 2231(थंडरबर्ड)';
+$labels['miscfolding'] = 'आर एफ सी  2047/2231 (मायक्रोसॉफ़्ट आऊटलूक)';
+$labels['2047folding'] = 'संपूर्ण        आर एफ सी 2047(ईतर)';
+$labels['advancedoptions'] = 'अधिक पर्याय';
+$labels['focusonnewmessage'] = 'ब्राऊझर खिडकी नवीन संदेशावर केंद्रित करा';
+$labels['checkallfolders'] = 'सर्व फोल्डरमधे नवीन संदेश शोधा';
+$labels['folder'] = 'फोल्डर';
+$labels['folders'] = 'फोल्डर्स';
+$labels['foldername'] = 'फोल्डरचे नाव';
+$labels['subscribed'] = 'वर्गणिदार होणे';
+$labels['messagecount'] = 'संदेश';
+$labels['create'] = 'तयार करा';
+$labels['createfolder'] = 'नवीन फोल्डर तयार करा';
+$labels['rename'] = 'नवीन नाव द्या';
+$labels['renamefolder'] = 'फोल्डरला नवीन नाव द्या';
+$labels['deletefolder'] = 'फोल्डर काढून टाका';
+$labels['managefolders'] = 'फोल्डर्सचे नियोजन करा';
+$labels['specialfolders'] = 'विषेश फोल्डर';
+$labels['sortby'] = 'ने वर्गवारी करा';
+$labels['sortasc'] = 'चढत्या क्रमाने';
+$labels['sortdesc'] = 'उतरत्या क्रमाने';
+$labels['B'] = 'बी';
+$labels['KB'] = 'केबी';
+$labels['MB'] = 'एमबी';
+$labels['GB'] = 'जीबी';
+
+?>
\ No newline at end of file
diff --git a/program/localization/mr_IN/messages.inc b/program/localization/mr_IN/messages.inc
new file mode 100755 (executable)
index 0000000..ef25025
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+
+/*
++-----------------------------------------------------------------------+
+| language/mr_IN/messages.inc                                           |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2009, RoundQube Dev. - Switzerland                      |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author:Nitin Nimkar <nvncom at yahoo.com>                             |
++-----------------------------------------------------------------------+
+
+*/
+
+$messages = array();
+$messages['loginfailed'] = 'प्रवेश करता आला नाही';
+$messages['cookiesdisabled'] = 'तुमचा ब्राऊझर कुकीज घेऊ शकत नाही';
+$messages['sessionerror'] = 'तुम्ही प्रवेश केल्यानंतर बराच वेळ काही न करता गेला म्हणून तुमचा कालावधी संपला किंवा तुमच्या कालावधीच्या नोंदेत काही चूक झाली आहे.';
+$messages['imaperror'] = 'आयमॅप सर्व्हरशी संपर्क होवू शकला नाही.';
+$messages['nomessagesfound'] = 'या खात्यामधे कोणताही संदेश आलेला नाही';
+$messages['loggedout'] = 'तुम्ही यशस्वीरित्या खाते बंद केले आहे . राम राम !';
+$messages['mailboxempty'] = 'खात्यात कोणताही संदेश नाही';
+$messages['loading'] = 'संदेश आणत आहे';
+$messages['loadingdata'] = 'माहिती आणत आहे ';
+$messages['checkingmail'] = 'नवीन संदेश आले आहेत का हे पहात आहे';
+$messages['sendingmessage'] = 'संदेश पाठवत आहे';
+$messages['messagesent'] = 'संदेश यशस्वीरित्या पाठवण्यात आला आहे';
+$messages['savingmessage'] = 'संदेश जतन करुन ठेवत आहे';
+$messages['messagesaved'] = 'संदेश मसुदा फोल्डरमधे ठेवत आहे';
+$messages['successfullysaved'] = 'यशस्वीरित्या ठेवला';
+$messages['addedsuccessfully'] = 'नवीन नाव पत्तां नोंदवहीत व्यवस्थित ठेवला';
+$messages['contactexists'] = 'हा इमेल पत्ता नोंदवहीत आधिच आहे. ';
+$messages['blockedimages'] = 'तुमची गोपनीयता पाळण्यासाठी या संदेशातील दुसर्‍या सर्व्हरवरील चित्रे दिसणे थांबवले आहे.';
+$messages['encryptedmessage'] = 'हा गुप्त व सांकेतिक संदेश आहे. तो तुम्हाला असा दाखवता येणार नाही. ';
+$messages['nocontactsfound'] = 'कोणताच पत्ता नोंदवहीत नाही.';
+$messages['contactnotfound'] = 'या नावाचा कोणताच पत्ता नोंदवहीत नाही.';
+$messages['sendingfailed'] = 'संदेश पाठवता आला नाही.';
+$messages['senttooquickly'] = 'कृपया हा संदेश पाठवण्यापूर्वी $sec थांबा ';
+$messages['errorsavingsent'] = 'पाठवलेला संदेश ठेवून देतांना काहीतरी चूक झाली. ';
+$messages['errorsaving'] = 'संदेश ठेवून देतांना काहीतरी चूक झाली. ';
+$messages['errormoving'] = 'संदेश तेथे ठेवता आला नाही.';
+$messages['errordeleting'] = 'संदेश काढून टाकता आला नाही. ';
+$messages['deletecontactconfirm'] = 'खूण केलेले सर्व पत्ते खरोखरच तुम्हाला काढून टाकायचे आहेत का?';
+$messages['deletemessagesconfirm'] = 'खूण केलेले सर्व संदेश खरोखरच तुम्हाला काढून टाकायचे आहेत का?';
+$messages['deletefolderconfirm'] = 'हा फोल्डर खरोखरच तुम्हाला काढून टाकायचा आहेत का?';
+$messages['purgefolderconfirm'] = 'या फोल्डरमधिल सर्व संदेश खरोखरच तुम्हाला काढून टाकायचे आहेत का?';
+$messages['foldercreating'] = 'फोल्डर तयार करत आहे';
+$messages['folderdeleting'] = 'फोल्डर काढून टाकत आहे';
+$messages['folderrenaming'] = 'फोल्डरला नवीन नाव देत आहे.';
+$messages['foldermoving'] = 'फोल्डर हलवत आहे.';
+$messages['formincomplete'] = 'फॉर्म पूर्णपणे भरलेला  नाही. ';
+$messages['noemailwarning'] = 'योग्य, बरोबर, आणि वैध इमेल पत्ता द्या. ';
+$messages['nonamewarning'] = 'नाव द्या';
+$messages['nopagesizewarning'] = 'पानाचा आकार द्या';
+$messages['nosenderwarning'] = 'पाठवणार्‍याचा इमेल पत्ता द्या';
+$messages['norecipientwarning'] = 'किमान एकतरी पत्ता द्या ज्यांना तुम्हाला संदेश पाठवावयाचा आहे. ';
+$messages['nosubjectwarning'] = 'विषय दिलेला नाही. तुम्हाला विषय द्यायचा आहे का?';
+$messages['nobodywarning'] = 'संदेशामधे कोणताही मजकूर नाही. तुम्हाला तसाच संदेश पाठवावयाचा आहे का?';
+$messages['notsentwarning'] = 'संदेश पाठवला गेला नाही. तुम्हाला हा संदेश रद्द करायचा आहे का?';
+$messages['noldapserver'] = 'शोधण्यासाठी ldap सर्व्हर निवडा';
+$messages['nocontactsreturned'] = 'कोणताही पत्ता नोंदवहीत नाही. ';
+$messages['nosearchname'] = 'कृपया ज्यांना तुम्हाला संदेश पाठवावयाचा आहे त्यांचे नाव किंवा इमेल पत्ता द्या. ';
+$messages['searchsuccessful'] = '$nr संदेष मिळाले.';
+$messages['searchnomatch'] = 'शोध घेतल्यानंतर एकही संदेश मिळाला नाही ';
+$messages['searching'] = 'शोधत आहे......';
+$messages['checking'] = 'तपासत आहे.....';
+$messages['nospellerrors'] = 'शुध्दलेखनाची चूक सापडली नाही';
+$messages['folderdeleted'] = 'फोल्डर यशस्वी रित्या काढून टाकण्यात आला आहे. ';
+$messages['deletedsuccessfully'] = 'यशस्वी रित्या काढून टाकण्यात आला आहे. ';
+$messages['converting'] = 'दृष्य स्वरुप काढून टाकण्यात येत आहे. ';
+$messages['messageopenerror'] = 'सर्व्हरवरुन संदेश आणता आला नाही. ';
+$messages['fileuploaderror'] = 'फाईल चढवता आली नाही ';
+$messages['filesizeerror'] = 'तुम्ही चढवलेली फाईल क्षमतेपेक्षा जास्त मोठी आहे. ';
+$messages['copysuccess'] = '$nr पत्त्यांची यशस्वीरित्या प्रत केली.';
+$messages['copyerror'] = 'कोणत्याही पत्त्याची प्रत बनवता आली नाही.';
+$messages['sourceisreadonly'] = 'पत्ता फक्त वाचण्यासाठी आहे.';
+$messages['errorsavingcontact'] = 'पत्ता नोंदवहीत ठेवता आला नाही. ';
+$messages['movingmessage'] = 'संदेश हलवत आहे..';
+$messages['receiptsent'] = 'पोचपावती यशस्वीरित्या पाठवण्यात आली आहे. ';
+$messages['errorsendingreceipt'] = 'पोचपावती पाठवता आली नाही.';
+$messages['nodeletelastidentity'] = 'तुम्ही हे खाते काढून टाकू शकत नाही कारण हे तुमचे शेवटचे खाते आहे.';
+$messages['addsubfolderhint'] = 'हा फोल्डर निवडलेल्या फोल्डरचा उप-फोल्डर असेल';
+$messages['forbiddencharacter'] = 'फोल्डरच्या नावात न चालणारी अक्षरे किंवा खूणा आहेत.';
+$messages['selectimportfile'] = 'चढवण्यासाठी फाईल निवडा';
+$messages['addresswriterror'] = 'निवडलेल्या पत्ता नोंदवहीत नोंद करता येत नाही.';
+$messages['importwait'] = 'आयात करत आहे, कृपया वाट पहा.....';
+$messages['importerror'] = 'आयात झाली नाही. आयात करत असलेली फाईल व्हीकार्ड प्रकाराची नाही';
+$messages['importconfirm'] = '<b>$inserted पत्ते यशस्वीरित्या आयात केल, $skipped आधिच असलेल्या नोंदी केल्या नाहीत</b>:<p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'ही क्रिया करण्यास परवानगी नाही. ';
+$messages['nofromaddress'] = 'निवडलेल्या खात्यात इमेल पत्ता दिलेला नाही.';
+$messages['editorwarning'] = 'टेक्स्ट संपादन निवडल्यास संदेशाचे दृष्य स्वरुप बदलून जाईल. तुम्हाला असेच करायचे आहे ना?';
+
+?>
\ No newline at end of file
index b27c457d9eb95f1e5a672c7349e2ca3acc4c4e09..4e5d948b00e5e48464285903419130f3a001b52f 100644 (file)
@@ -207,7 +207,6 @@ $labels['ignore'] = 'Biarkan';
 $labels['readwhendeleted'] = 'Tanda mesej sebagai dibaca ketika hapus';
 $labels['flagfordeletion'] = 'Tanda mesej untuk pembuangan (tidak delete terus)';
 $labels['autosavedraft'] = 'Simpan draf dengan automatik';
-$labels['everynminutes'] = 'setiap $n minit';
 $labels['never'] = 'tidak pernah';
 $labels['folder'] = 'Kabinet Fail';
 $labels['folders'] = 'Kabinet Fail';
index bd469ab72c60aff4bca62a0e50d5aad7a8a46adc..d19a7527bd42d7cbdf83eeb3fd7870fa52dd8214 100644 (file)
 | Author: Odd Henriksen <odd@digicon.no>                                |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2784 2009-07-22 12:23:12Z yllar $
 
 */
 
 $labels = array();
 $labels['welcome'] = 'Velkommen til $product';
-$labels['username'] = 'Brukernavn:';
-$labels['password'] = 'Passord:';
+$labels['username'] = 'Brukernavn';
+$labels['password'] = 'Passord';
 $labels['server'] = 'Server';
 $labels['login'] = 'Logg på';
 $labels['logout'] = 'Logg ut';
@@ -118,12 +118,15 @@ $labels['markread'] = 'som lest';
 $labels['markunread'] = 'som ulest';
 $labels['markflagged'] = 'som flagget';
 $labels['markunflagged'] = 'som uflagget';
+$labels['messageactions'] = 'Flere valg...';
 $labels['select'] = 'Velg';
 $labels['all'] = 'Alle';
 $labels['none'] = 'Ingen';
 $labels['unread'] = 'Uleste';
 $labels['flagged'] = 'Flagget';
 $labels['unanswered'] = 'Ubesvarte';
+$labels['deleted'] = 'Slettet';
+$labels['invert'] = 'Inverter';
 $labels['filter'] = 'Filter';
 $labels['compact'] = 'Rydd opp';
 $labels['empty'] = 'Tøm';
@@ -133,8 +136,12 @@ $labels['unknown'] = 'ukjent';
 $labels['unlimited'] = 'ubegrenset';
 $labels['quicksearch'] = 'Hurtigsøk';
 $labels['resetsearch'] = 'Nullstill søk';
+$labels['searchmod'] = 'Søke felt';
+$labels['msgtext'] = 'Hele meldingen';
 $labels['openinextwin'] = 'Åpne i nytt vindu';
+$labels['emlsave'] = 'Last ned (.eml)';
 $labels['compose'] = 'Skriv ny e-post';
+$labels['editasnew'] = 'Rediger som ny';
 $labels['savemessage'] = 'Lagre kladd';
 $labels['sendmessage'] = 'Send e-posten';
 $labels['addattachment'] = 'Vedlegg';
@@ -233,8 +240,7 @@ $labels['fromknownsenders'] = 'fra kjente avsendere';
 $labels['always'] = 'alltid';
 $labels['showinlineimages'] = 'Vis vedlagte bilder under meldingen';
 $labels['autosavedraft'] = 'Autolagring av utkast';
-$labels['everynminutes'] = 'Hvert $n. minutt';
-$labels['keepaliveevery'] = 'hvert $n minutt';
+$labels['everynminutes'] = 'hvert $n minutt';
 $labels['keepalive'] = 'Se etter ny e-post';
 $labels['never'] = 'Aldri';
 $labels['messagesdisplaying'] = 'Visning av meldinger';
index f74a32ccca28106cb9ac1581d82540c418bb3cdb..c96d781a6e67e152e493223591d1955df4169436 100644 (file)
@@ -15,7 +15,7 @@
 | Author: Odd Henriksen <odd@digicon.no>                                |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: messages.inc 2784 2009-07-22 12:23:12Z yllar $
 
 */
 
@@ -24,6 +24,8 @@ $messages['loginfailed'] = 'Pålogging mislyktes';
 $messages['cookiesdisabled'] = 'Din nettleser aksepterer ikke cookies';
 $messages['sessionerror'] = 'Din session er ugyldig eller utløpt';
 $messages['imaperror'] = 'Forbindelsen til IMAP serveren sviktet';
+$messages['servererror'] = 'Server feil!';
+$messages['invalidrequest'] = 'Ugyldig forespørsel! Ingen data ble lagret.';
 $messages['nomessagesfound'] = 'Det ble ikke funnet noen meldinger i denne innboksen';
 $messages['loggedout'] = 'Du er logget av webmail. Ha det bra!';
 $messages['mailboxempty'] = 'Postkassen er tom!';
@@ -47,6 +49,7 @@ $messages['errorsavingsent'] = 'En feil oppsto under lagring av sendt melding';
 $messages['errorsaving'] = 'Det oppstod en feil ved lagring av data';
 $messages['errormoving'] = 'Kunne ikke flytte meldingen';
 $messages['errordeleting'] = 'Kunne ikke slette meldingen';
+$messages['errormarking'] = 'Kunne ikke markere meldingen';
 $messages['deletecontactconfirm'] = 'Vil du virkelig slette valgte kontakt(er)?';
 $messages['deletemessagesconfirm'] = 'Vil du virkelig slette de(n) valgte meldingen(e)?';
 $messages['deletefolderconfirm'] = 'Vil du virkelig slette denne mappen?';
@@ -96,5 +99,12 @@ $messages['importconfirm'] = '<b>Importerte $inserted kontakter vellykket, hoppe
 $messages['opnotpermitted'] = 'Handling ikke tillatt!';
 $messages['nofromaddress'] = 'E-postadresse mangler i valgt identitet';
 $messages['editorwarning'] = 'Å bytte format til ren tekst vil føre til at all tekstformatering går tapt. Ønsker du å fortsette?';
+$messages['httpreceivedencrypterror'] = 'En uopprettelig feil oppsto. Vennligst kontakt din administrator umiddelbart. <b>Din melding kunne ikke sendes.</b>';
+$messages['smtpconnerror'] = 'SMTP Feil ($code): Tilkobling til server feilet';
+$messages['smtpautherror'] = 'SMTP Feil ($code): Pålogging feilet';
+$messages['smtpfromerror'] = 'SMTP Feil ($code): Kunne ikke sette avsender "$from"';
+$messages['smtptoerror'] = 'SMTP Feil ($code): Kunne ikke legge til mottaker "$to"';
+$messages['smtprecipientserror'] = 'SMTP Feil ($code): Kunne ikke lese mottaker listen';
+$messages['smtperror'] = 'SMTP Feil ($code): $msg';
 
 ?>
index 1b1e899a0a7e437e6bfc87cf95b287644a3433a8..2a9bbcd989f4cf1d8e40c20a6096920b207d5263 100644 (file)
-<?php\r
-\r
-/*\r
- +-----------------------------------------------------------------------+\r
- | localization/ne/labels.inc                                            |\r
- |                                                                       |\r
- | Language file of the RoundCube Webmail client                         |\r
- | Copyright (C) 2007, RoundQube Dev. - Switzerland                      |\r
- | Licensed under the GNU GPL                                            |\r
- |                                                                       |\r
- +-----------------------------------------------------------------------+\r
- | Nepali Translation by:                                                |\r
- | Prasanna Singh <prasanna@bhunet.com>, <prasanna@bhunet.com>           |\r
- | RoundCubeAuthor: Thomas Bruederli <roundcube@gmail.com>               |\r
- +-----------------------------------------------------------------------+\r
-*/\r
-\r
-$labels = array();\r
-$labels['welcome'] = '$product मा स्वागत छ';\r
-$labels['username'] = 'युसरनेम';\r
-$labels['password'] = 'पासवर्ड';\r
-$labels['server'] = 'सर्भर';\r
-$labels['login'] = 'लगईन';\r
-$labels['logout'] = 'लगआउट';\r
-$labels['mail'] = 'ई-मेल';\r
-$labels['settings'] = 'व्यक्तिगत रोजाईहरु';\r
-$labels['addressbook'] = 'ठेगाना किताब';\r
-$labels['inbox'] = 'इनबक्स';\r
-$labels['drafts'] = 'ड्राफ्ट';\r
-$labels['sent'] = 'पठईएका मेलहरु';\r
-$labels['trash'] = 'रद्दी टोकरी';\r
-$labels['junk'] = 'स्पाम';\r
-$labels['subject'] = 'विषय';\r
-$labels['from'] = 'प्रेषक';\r
-$labels['to'] = 'प्रापक';\r
-$labels['cc'] = 'कार्बन कपि';\r
-$labels['bcc'] = 'अंधो कार्बन कपि';\r
-$labels['replyto'] = 'पुन: जवाब';\r
-$labels['date'] = 'तारिख';\r
-$labels['size'] = 'नाप';\r
-$labels['priority'] = 'मेलको प्राथमिकता';\r
-$labels['organization'] = 'संस्था';\r
-$labels['reply-to'] = 'पुन: जवाब';\r
-$labels['mailboxlist'] = 'फोलडर';\r
-$labels['messagesfromto'] = 'मेलहरु $from बाट $to सम्म, $count मध्यबाट';\r
-$labels['messagenrof'] = '$nr नम्बर मेल, $count मध्यबाट';\r
-$labels['moveto'] = 'सार्नुहोस...';\r
-$labels['download'] = 'डाऊनलोड';\r
-$labels['filename'] = 'फाईलको नाम';\r
-$labels['filesize'] = 'फाईलको नाप';\r
-$labels['preferhtml'] = 'ऐच-टी-ऐम-ऐल(HTML) देखाउनुहोस';\r
-$labels['htmlmessage'] = 'ऐच-टी-ऐम-ऐल (HTML) रूपका मेल';\r
-$labels['prettydate'] = 'सुन्दर तारिख';\r
-$labels['addtoaddressbook'] = 'ठेगाना पुस्तिकामा जोड्नुहोस';\r
-$labels['sun'] = 'आइत';\r
-$labels['mon'] = 'सोम';\r
-$labels['tue'] = 'मंगल';\r
-$labels['wed'] = 'बुध';\r
-$labels['thu'] = 'विहि';\r
-$labels['fri'] = 'शुक';\r
-$labels['sat'] = 'शनि';\r
-$labels['sunday'] = 'आइतवार';\r
-$labels['monday'] = 'सोमवार';\r
-$labels['tuesday'] = 'मंगलवार';\r
-$labels['wednesday'] = 'बुधवार';\r
-$labels['thursday'] = 'विहिवार';\r
-$labels['friday'] = 'शुक्रवार';\r
-$labels['saturday'] = 'शनिवार';\r
-$labels['today'] = 'आज';\r
-$labels['checkmail'] = 'नया मेल खोज्नुहोस';\r
-$labels['writenewmessage'] = 'नया मेल लेखनुहोस';\r
-$labels['replytomessage'] = 'मेलको जवाफ दिनुहोस';\r
-$labels['replytoallmessage'] = 'प्रेषक लगायत सबैलाई जवाफ दिनुहोस';\r
-$labels['forwardmessage'] = 'मेल अगाडि पठाउनुहोस';\r
-$labels['deletemessage'] = 'रद्दी टोकरीमा सार्नुहोस';\r
-$labels['printmessage'] = 'मेल छाप्नुहोस';\r
-$labels['previousmessage'] = 'पछाडिको मेल देखाउनुहोस';\r
-$labels['previousmessages'] = 'पछाडिको मेलका सेटहरु देखाउनुहोस';\r
-$labels['firstmessage'] = 'पहलो मेल देखाउनुहोस';\r
-$labels['firstmessages'] = 'पहलो मेलका सेटहरु देखाउनुहोस';\r
-$labels['nextmessage'] = 'अगाडिको मेल देखाउनुहोस';\r
-$labels['nextmessages'] = 'अगाडिको मेलका सेटहरु देखाउनुहोस';\r
-$labels['lastmessage'] = 'अन्तिम मेल देखाउनुहोस';\r
-$labels['lastmessages'] = 'अन्तिम मेलका सेटहरु देखाउनुहोस';\r
-$labels['backtolist'] = 'मेल सूची देखाउनुहोस';\r
-$labels['viewsource'] = 'श्रोत देखाउनुहोस';\r
-$labels['select'] = 'चुन्नुहोस';\r
-$labels['all'] = 'सबै |';\r
-$labels['none'] = 'हैन';\r
-$labels['unread'] = 'नपढिएका |';\r
-$labels['compact'] = 'छोटो गर्नुहोस';\r
-$labels['empty'] = 'खाली गर्ने';\r
-$labels['purge'] = 'नाम निशाना मेटाउनुहोस';\r
-$labels['quota'] = 'डिस्कको उपभोग';\r
-$labels['unknown'] = 'अज्ञात';\r
-$labels['unlimited'] = 'अनगिन्ति';\r
-$labels['quicksearch'] = 'स्फुर्ति खोज';\r
-$labels['resetsearch'] = 'पन: खोज';\r
-$labels['compose'] = 'मेल लखन गर्नुहोस';\r
-$labels['sendmessage'] = 'तुरुन्तै मेल पठाउनुहोस';\r
-$labels['savemessage'] = 'ड्राफ्ट जोगाउनुहोस';\r
-$labels['addattachment'] = 'फाइल टाँस्नुहोस';\r
-$labels['charset'] = 'क्यारेक्टर सेट';\r
-$labels['editortype'] = 'सम्पादकको प्रकार';\r
-$labels['returnreceipt'] = 'फिर्ति रसीद';\r
-$labels['checkspelling'] = 'हिज्जे जाँच';\r
-$labels['resumeediting'] = 'पुन: सम्पादन गर्नुहोस';\r
-$labels['revertto'] = 'पहिलेको स्थितीमा जानुहोस';\r
-$labels['attachments'] = 'टाँसिएका फाईलहरु';\r
-$labels['upload'] = 'अपलोड';\r
-$labels['close'] = 'बन्द';\r
-$labels['low'] = 'कम';\r
-$labels['lowest'] = 'सबै भन्दा कम';\r
-$labels['normal'] = 'साधारण';\r
-$labels['high'] = 'उच्च';\r
-$labels['highest'] = 'उच्चतम';\r
-$labels['nosubject'] = '(बिना विषयको)';\r
-$labels['showimages'] = 'चित्र देखाउनुहोस';\r
-$labels['htmltoggle'] = 'ऐच-टी-ऐम-एल (HTML)';\r
-$labels['plaintoggle'] = 'सादा अक्षर';\r
-$labels['name'] = 'देखाउने नाम';\r
-$labels['firstname'] = 'पहिलो नाम';\r
-$labels['surname'] = 'थर';\r
-$labels['email'] = 'ई-मेल';\r
-$labels['addcontact'] = 'नया सम्पर्क जोड्नुहोस';\r
-$labels['editcontact'] = 'सम्पर्क सच्याउनुहोस';\r
-$labels['edit'] = 'सच्याउनुहोस';\r
-$labels['cancel'] = 'खारेज गर्नुहोस';\r
-$labels['save'] = 'जोगाउनुहोस';\r
-$labels['delete'] = 'मेटाउनुहोस';\r
-$labels['newcontact'] = 'नया सम्पर्क कार्ड बनाउनुहोस';\r
-$labels['deletecontact'] = 'छानिएका सम्पर्कहरु मेटाउनुहोस';\r
-$labels['composeto'] = 'मेल लेखी पठाउनुहोस';\r
-$labels['contactsfromto'] = 'सम्पर्कहरु $from बाट $to सम्म, $count मध्यबाट';\r
-$labels['print'] = 'छाप्नुहोस';\r
-$labels['export'] = 'ऐक्स्पोर्ट गर्नुहोस';\r
-$labels['previouspage'] = 'पहिलेको सेट देखाउनुहोस';\r
-$labels['firstpage'] = 'पहिलो सेट देखाउनुहोस';\r
-$labels['nextpage'] = 'अर्को सेट देखाउनुहोस';\r
-$labels['lastpage'] = 'अन्तिम सेट देखाउनुहोस';\r
-$labels['groups'] = 'समूहहरु';\r
-$labels['personaladrbook'] = 'व्यक्तिगत ठेगानाहरु';\r
-$labels['settingsfor'] = 'तय';\r
-$labels['preferences'] = 'रोजाइहरु';\r
-$labels['userpreferences'] = 'यूसरका रोजाइहरु';\r
-$labels['editpreferences'] = 'यूसरका रोजाइहर सम्पादन गर्नुहोस';\r
-$labels['identities'] = 'पहिचानहरु';\r
-$labels['manageidentities'] = 'यो खाताको पहिचानहरको व्यवस्था गर्नुहोस';\r
-$labels['newidentity'] = 'नया पहिचान';\r
-$labels['newitem'] = 'नया प्रकार';\r
-$labels['edititem'] = 'प्रकार सम्पादन गर्नुहोस';\r
-$labels['setdefault'] = 'तय गर्नुहोस';\r
-$labels['language'] = 'भाषा';\r
-$labels['timezone'] = 'समय क्षेत्र';\r
-$labels['pagesize'] = 'हरेक पन्नामा यति';\r
-$labels['signature'] = 'हस्ताक्षर';\r
-$labels['dstactive'] = 'प्रकाश बचाव';\r
-$labels['htmleditor'] = 'ऐच-टी-ऐम-एल (HTML) मेल लखन गर्नुहोस';\r
-$labels['htmlsignature'] = 'ऐच-टी-ऐम-एल (HTML) हस्ताक्षर';\r
-$labels['previewpane'] = 'पूर्व दृष्य देखाउनुहोस';\r
-$labels['autosavedraft'] = 'स्वत ड्राफ्ट जोगाउनुहोस';\r
-$labels['everynminutes'] = 'प्रत्येक $n मिनटमा';\r
-$labels['never'] = 'काहिलै नहुने';\r
-$labels['folder'] = 'फोल्डर';\r
-$labels['folders'] = 'फोल्डरहरु';\r
-$labels['foldername'] = 'फोल्डरको नाम';\r
-$labels['subscribed'] = 'सबस्क्राईब गरियो';\r
-$labels['create'] = 'बनाउनुहोस';\r
-$labels['createfolder'] = 'नया फोलडर बनाउनुहोस';\r
-$labels['rename'] = 'नाम बदल्नुहोस';\r
-$labels['renamefolder'] = 'फोलडरको नाम बदल्नुहोस';\r
-$labels['deletefolder'] = 'फोलडर मेट्नुहोस';\r
-$labels['managefolders'] = 'फोलडर व्यवस्थित गर्नुहोस';\r
-$labels['sortby'] = 'यसरी तय गर्नुहोस';\r
-$labels['sortasc'] = 'पहिलो देखि अन्तिम सम्म तय गर्नुहोस';\r
-$labels['sortdesc'] = 'अन्तिम देखि पहिलो सम्म तय गर्नुहोस';\r
-\r
-?>\r
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | localization/ne/labels.inc                                            |
+ |                                                                       |
+ | Language file of the RoundCube Webmail client                         |
+ | Copyright (C) 2007, RoundQube Dev. - Switzerland                      |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Nepali Translation by:                                                |
+ | Prasanna Singh <prasanna@bhunet.com>, <prasanna@bhunet.com>           |
+ | RoundCubeAuthor: Thomas Bruederli <roundcube@gmail.com>               |
+ +-----------------------------------------------------------------------+
+*/
+
+$labels = array();
+$labels['welcome'] = '$product मा स्वागत छ';
+$labels['username'] = 'युसरनेम';
+$labels['password'] = 'पासवर्ड';
+$labels['server'] = 'सर्भर';
+$labels['login'] = 'लगईन';
+$labels['logout'] = 'लगआउट';
+$labels['mail'] = 'ई-मेल';
+$labels['settings'] = 'व्यक्तिगत रोजाईहरु';
+$labels['addressbook'] = 'ठेगाना किताब';
+$labels['inbox'] = 'इनबक्स';
+$labels['drafts'] = 'ड्राफ्ट';
+$labels['sent'] = 'पठईएका मेलहरु';
+$labels['trash'] = 'रद्दी टोकरी';
+$labels['junk'] = 'स्पाम';
+$labels['subject'] = 'विषय';
+$labels['from'] = 'प्रेषक';
+$labels['to'] = 'प्रापक';
+$labels['cc'] = 'कार्बन कपि';
+$labels['bcc'] = 'अंधो कार्बन कपि';
+$labels['replyto'] = 'पुन: जवाब';
+$labels['date'] = 'तारिख';
+$labels['size'] = 'नाप';
+$labels['priority'] = 'मेलको प्राथमिकता';
+$labels['organization'] = 'संस्था';
+$labels['reply-to'] = 'पुन: जवाब';
+$labels['mailboxlist'] = 'फोलडर';
+$labels['messagesfromto'] = 'मेलहरु $from बाट $to सम्म, $count मध्यबाट';
+$labels['messagenrof'] = '$nr नम्बर मेल, $count मध्यबाट';
+$labels['moveto'] = 'सार्नुहोस...';
+$labels['download'] = 'डाऊनलोड';
+$labels['filename'] = 'फाईलको नाम';
+$labels['filesize'] = 'फाईलको नाप';
+$labels['preferhtml'] = 'ऐच-टी-ऐम-ऐल(HTML) देखाउनुहोस';
+$labels['htmlmessage'] = 'ऐच-टी-ऐम-ऐल (HTML) रूपका मेल';
+$labels['prettydate'] = 'सुन्दर तारिख';
+$labels['addtoaddressbook'] = 'ठेगाना पुस्तिकामा जोड्नुहोस';
+$labels['sun'] = 'आइत';
+$labels['mon'] = 'सोम';
+$labels['tue'] = 'मंगल';
+$labels['wed'] = 'बुध';
+$labels['thu'] = 'विहि';
+$labels['fri'] = 'शुक';
+$labels['sat'] = 'शनि';
+$labels['sunday'] = 'आइतवार';
+$labels['monday'] = 'सोमवार';
+$labels['tuesday'] = 'मंगलवार';
+$labels['wednesday'] = 'बुधवार';
+$labels['thursday'] = 'विहिवार';
+$labels['friday'] = 'शुक्रवार';
+$labels['saturday'] = 'शनिवार';
+$labels['today'] = 'आज';
+$labels['checkmail'] = 'नया मेल खोज्नुहोस';
+$labels['writenewmessage'] = 'नया मेल लेखनुहोस';
+$labels['replytomessage'] = 'मेलको जवाफ दिनुहोस';
+$labels['replytoallmessage'] = 'प्रेषक लगायत सबैलाई जवाफ दिनुहोस';
+$labels['forwardmessage'] = 'मेल अगाडि पठाउनुहोस';
+$labels['deletemessage'] = 'रद्दी टोकरीमा सार्नुहोस';
+$labels['printmessage'] = 'मेल छाप्नुहोस';
+$labels['previousmessage'] = 'पछाडिको मेल देखाउनुहोस';
+$labels['previousmessages'] = 'पछाडिको मेलका सेटहरु देखाउनुहोस';
+$labels['firstmessage'] = 'पहलो मेल देखाउनुहोस';
+$labels['firstmessages'] = 'पहलो मेलका सेटहरु देखाउनुहोस';
+$labels['nextmessage'] = 'अगाडिको मेल देखाउनुहोस';
+$labels['nextmessages'] = 'अगाडिको मेलका सेटहरु देखाउनुहोस';
+$labels['lastmessage'] = 'अन्तिम मेल देखाउनुहोस';
+$labels['lastmessages'] = 'अन्तिम मेलका सेटहरु देखाउनुहोस';
+$labels['backtolist'] = 'मेल सूची देखाउनुहोस';
+$labels['viewsource'] = 'श्रोत देखाउनुहोस';
+$labels['select'] = 'चुन्नुहोस';
+$labels['all'] = 'सबै |';
+$labels['none'] = 'हैन';
+$labels['unread'] = 'नपढिएका |';
+$labels['compact'] = 'छोटो गर्नुहोस';
+$labels['empty'] = 'खाली गर्ने';
+$labels['purge'] = 'नाम निशाना मेटाउनुहोस';
+$labels['quota'] = 'डिस्कको उपभोग';
+$labels['unknown'] = 'अज्ञात';
+$labels['unlimited'] = 'अनगिन्ति';
+$labels['quicksearch'] = 'स्फुर्ति खोज';
+$labels['resetsearch'] = 'पन: खोज';
+$labels['compose'] = 'मेल लखन गर्नुहोस';
+$labels['sendmessage'] = 'तुरुन्तै मेल पठाउनुहोस';
+$labels['savemessage'] = 'ड्राफ्ट जोगाउनुहोस';
+$labels['addattachment'] = 'फाइल टाँस्नुहोस';
+$labels['charset'] = 'क्यारेक्टर सेट';
+$labels['editortype'] = 'सम्पादकको प्रकार';
+$labels['returnreceipt'] = 'फिर्ति रसीद';
+$labels['checkspelling'] = 'हिज्जे जाँच';
+$labels['resumeediting'] = 'पुन: सम्पादन गर्नुहोस';
+$labels['revertto'] = 'पहिलेको स्थितीमा जानुहोस';
+$labels['attachments'] = 'टाँसिएका फाईलहरु';
+$labels['upload'] = 'अपलोड';
+$labels['close'] = 'बन्द';
+$labels['low'] = 'कम';
+$labels['lowest'] = 'सबै भन्दा कम';
+$labels['normal'] = 'साधारण';
+$labels['high'] = 'उच्च';
+$labels['highest'] = 'उच्चतम';
+$labels['nosubject'] = '(बिना विषयको)';
+$labels['showimages'] = 'चित्र देखाउनुहोस';
+$labels['htmltoggle'] = 'ऐच-टी-ऐम-एल (HTML)';
+$labels['plaintoggle'] = 'सादा अक्षर';
+$labels['name'] = 'देखाउने नाम';
+$labels['firstname'] = 'पहिलो नाम';
+$labels['surname'] = 'थर';
+$labels['email'] = 'ई-मेल';
+$labels['addcontact'] = 'नया सम्पर्क जोड्नुहोस';
+$labels['editcontact'] = 'सम्पर्क सच्याउनुहोस';
+$labels['edit'] = 'सच्याउनुहोस';
+$labels['cancel'] = 'खारेज गर्नुहोस';
+$labels['save'] = 'जोगाउनुहोस';
+$labels['delete'] = 'मेटाउनुहोस';
+$labels['newcontact'] = 'नया सम्पर्क कार्ड बनाउनुहोस';
+$labels['deletecontact'] = 'छानिएका सम्पर्कहरु मेटाउनुहोस';
+$labels['composeto'] = 'मेल लेखी पठाउनुहोस';
+$labels['contactsfromto'] = 'सम्पर्कहरु $from बाट $to सम्म, $count मध्यबाट';
+$labels['print'] = 'छाप्नुहोस';
+$labels['export'] = 'ऐक्स्पोर्ट गर्नुहोस';
+$labels['previouspage'] = 'पहिलेको सेट देखाउनुहोस';
+$labels['firstpage'] = 'पहिलो सेट देखाउनुहोस';
+$labels['nextpage'] = 'अर्को सेट देखाउनुहोस';
+$labels['lastpage'] = 'अन्तिम सेट देखाउनुहोस';
+$labels['groups'] = 'समूहहरु';
+$labels['personaladrbook'] = 'व्यक्तिगत ठेगानाहरु';
+$labels['settingsfor'] = 'तय';
+$labels['preferences'] = 'रोजाइहरु';
+$labels['userpreferences'] = 'यूसरका रोजाइहरु';
+$labels['editpreferences'] = 'यूसरका रोजाइहर सम्पादन गर्नुहोस';
+$labels['identities'] = 'पहिचानहरु';
+$labels['manageidentities'] = 'यो खाताको पहिचानहरको व्यवस्था गर्नुहोस';
+$labels['newidentity'] = 'नया पहिचान';
+$labels['newitem'] = 'नया प्रकार';
+$labels['edititem'] = 'प्रकार सम्पादन गर्नुहोस';
+$labels['setdefault'] = 'तय गर्नुहोस';
+$labels['language'] = 'भाषा';
+$labels['timezone'] = 'समय क्षेत्र';
+$labels['pagesize'] = 'हरेक पन्नामा यति';
+$labels['signature'] = 'हस्ताक्षर';
+$labels['dstactive'] = 'प्रकाश बचाव';
+$labels['htmleditor'] = 'ऐच-टी-ऐम-एल (HTML) मेल लखन गर्नुहोस';
+$labels['htmlsignature'] = 'ऐच-टी-ऐम-एल (HTML) हस्ताक्षर';
+$labels['previewpane'] = 'पूर्व दृष्य देखाउनुहोस';
+$labels['autosavedraft'] = 'स्वत ड्राफ्ट जोगाउनुहोस';
+$labels['never'] = 'काहिलै नहुने';
+$labels['folder'] = 'फोल्डर';
+$labels['folders'] = 'फोल्डरहरु';
+$labels['foldername'] = 'फोल्डरको नाम';
+$labels['subscribed'] = 'सबस्क्राईब गरियो';
+$labels['create'] = 'बनाउनुहोस';
+$labels['createfolder'] = 'नया फोलडर बनाउनुहोस';
+$labels['rename'] = 'नाम बदल्नुहोस';
+$labels['renamefolder'] = 'फोलडरको नाम बदल्नुहोस';
+$labels['deletefolder'] = 'फोलडर मेट्नुहोस';
+$labels['managefolders'] = 'फोलडर व्यवस्थित गर्नुहोस';
+$labels['sortby'] = 'यसरी तय गर्नुहोस';
+$labels['sortasc'] = 'पहिलो देखि अन्तिम सम्म तय गर्नुहोस';
+$labels['sortdesc'] = 'अन्तिम देखि पहिलो सम्म तय गर्नुहोस';
+
+?>
index bd281999991d4ed379cf904cdf4e0380b0f8f916..3481d6b85b734524424583b4d27ab0b88bf6deb9 100644 (file)
@@ -1,75 +1,75 @@
-<?php\r
-\r
-/*\r
- +-----------------------------------------------------------------------+\r
- | localization/ne/messages.inc                                          |\r
- |                                                                       |\r
- | Language file of the RoundCube Webmail client                         |\r
- | Copyright (C) 2007, RoundCube Dev. - Switzerland                      |\r
- | Licensed under the GNU GPL                                            |\r
- |                                                                       |\r
- +-----------------------------------------------------------------------+\r
- | Nepali Translation by:                                                |\r
- | Prasanna Singh <prasanna@bhunet.com>, <prasanna@bhunet.com>           |\r
- | RoundCubeAuthor: Thomas Bruederli <roundcube@gmail.com>               |\r
- +-----------------------------------------------------------------------+\r
-*/\r
-\r
-$messages = array();\r
-$messages['loginfailed'] = 'लागईन हुन पाएन';\r
-$messages['cookiesdisabled'] = 'तपाईको ब्राऊसरले कुकी स्वीकार गारिरहेको छैन';\r
-$messages['sessionerror'] = 'सत्र समाप्त वा अवैद्य';\r
-$messages['imaperror'] = 'सर्वर संग सम्पर्क हुन पाएन';\r
-$messages['nomessagesfound'] = 'यो मेलबक्स मा कुनै मेल छैन';\r
-$messages['loggedout'] = 'सत्र समाप्त । नमास्कार!';\r
-$messages['mailboxempty'] = 'मेल बक्स खाली छ';\r
-$messages['loading'] = 'लोड भईरहेको छ...';\r
-$messages['loadingdata'] = 'डाटा लोड भईरहेको छै...';\r
-$messages['checkingmail'] = 'नया मेलको खोजी भईरहेको छ...';\r
-$messages['sendingmessage'] = 'मेल पठाईदै रहेको छ...';\r
-$messages['messagesent'] = 'मेल सफल्तापूर्वक पठाईयो';\r
-$messages['savingmessage'] = 'मेल जोगाईदै छ...';\r
-$messages['messagesaved'] = 'मेल ड्राफ्ट फोल्डरमा जोगाईयो';\r
-$messages['successfullysaved'] = 'सफल्तापूर्वक जोगाईयो';\r
-$messages['addedsuccessfully'] = 'सम्पर्क पुस्तिकामा सफल्तापूर्वक सम्पर्क प्रविष्ट गारियो';\r
-$messages['contactexists'] = 'यो ई-मेल पहिलै लिईसकिएको छ';\r
-$messages['blockedimages'] = 'तपाईको प्राईवेसी को लागि तथा अन्य स्पामबाट बच्नकोलागि यो मेलमा चित्रहुरु देखाईएका छैनन्।';\r
-$messages['encryptedmessage'] = 'माफ गर्नुहोसे, यो मेल ईन्क्रिफ्ट गरिएको रूपमा छ, त्यसैले देखाउन सकिदैन!';\r
-$messages['nocontactsfound'] = 'कुनै सम्पर्क भेटिएन';\r
-$messages['contactnotfound'] = 'अनुरोध गारिएको सम्पर्क भेटिएन';\r
-$messages['sendingfailed'] = 'मेल पठाउन सकिएन';\r
-$messages['errorsaving'] = 'जोगाउदा-जोगाउदै गडबड भायो';\r
-$messages['errormoving'] = 'मेल सार्न सकिएन';\r
-$messages['errordeleting'] = 'मेल मेटाउन सकिएन';\r
-$messages['deletecontactconfirm'] = 'तापाईले छान्नुभएको सम्पर्कहरु, साँचै मेट्न चहानुहुन्छ?';\r
-$messages['deletemessagesconfirm'] = 'तापाईले छान्नु भएको मेलहरु, साँचै मेट्न चहानुहुन्छ?';\r
-$messages['deletefolderconfirm'] = 'तापाईले साँचै यो फोल्डर मेट्न चहानु हुन्छ?';\r
-$messages['purgefolderconfirm'] = 'तापाईले साँचै यो फोल्डरमा भएका सबै मेलहरु मेट्न चहानुहुन्छ?';\r
-$messages['formincomplete'] = 'फर्म पूर्ण रुपमा भरिएको छैन';\r
-$messages['noemailwarning'] = 'कृपया वैद्य ई-मेल भर्नुहोस';\r
-$messages['nonamewarning'] = 'कृपया नाम भर्नुहोस';\r
-$messages['nopagesizewarning'] = 'कृपया पन्नाको नाप भर्नुहोस';\r
-$messages['norecipientwarning'] = 'कृपया कम-से-कम एउटा प्रापकको विवरण भर्नुहोस';\r
-$messages['nosubjectwarning'] = 'मेलको कुनै विषय तोकिएको छैनै। केहि तोक्न चहानुहुन्छ ?';\r
-$messages['nobodywarning'] = 'बिना केहि लेखि पठाउने?';\r
-$messages['notsentwarning'] = 'मेल पठएको छैन.. मेल रद्द गर्न चहानुहुन्छ?';\r
-$messages['noldapserver'] = 'कृपया खोजको निम्ति एउटा ऐलडाप सर्वर छान्नहोस';\r
-$messages['nocontactsreturned'] = 'कुनै सम्पर्क फेला परेनन्';\r
-$messages['nosearchname'] = 'कृपया सम्पर्कको नाम या ई-मेल भर्नुहोस';\r
-$messages['searchsuccessful'] = '$nr मेलहरु पाइयो';\r
-$messages['searchnomatch'] = 'खोज असफल रहयो';\r
-$messages['searching'] = 'खोजि भईरहेको छ...';\r
-$messages['checking'] = 'जाँच भईरहेको छ...';\r
-$messages['nospellerrors'] = 'कुनै गलत हिज्जे फेला परेनन्';\r
-$messages['folderdeleted'] = 'फोल्डर सफल्तापूर्वक मेटियो';\r
-$messages['deletedsuccessfully'] = 'सफल्तापूर्वक मेटियो';\r
-$messages['converting'] = 'मेलबाट फोर्माटिङ हटाईदै छ...';\r
-$messages['messageopenerror'] = 'सर्वरबाट मेल लोड हुन सकेन';\r
-$messages['fileuploaderror'] = 'फाईल अपलोड हुन असफल';\r
-$messages['filesizeerror'] = 'अपलोड गरिएको फाईल हद $size भन्दा ठूलो छ';\r
-$messages['copysuccess'] = 'सफल्तापूर्वक $nr ठेगानाहरु उतारियो';\r
-$messages['copyerror'] = 'कुनै पनि ठेगानाहरु उतार्न सकिएन';\r
-$messages['sourceisreadonly'] = 'यो ठेगाना को श्रोत पढ्नको लागि मात्र उपलब्ध छ';\r
-$messages['errorsavingcontact'] = 'स्मपर्कको ठेगाना जोगाउन सकिएन';\r
-\r
-?>\r
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | localization/ne/messages.inc                                          |
+ |                                                                       |
+ | Language file of the RoundCube Webmail client                         |
+ | Copyright (C) 2007, RoundCube Dev. - Switzerland                      |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Nepali Translation by:                                                |
+ | Prasanna Singh <prasanna@bhunet.com>, <prasanna@bhunet.com>           |
+ | RoundCubeAuthor: Thomas Bruederli <roundcube@gmail.com>               |
+ +-----------------------------------------------------------------------+
+*/
+
+$messages = array();
+$messages['loginfailed'] = 'लागईन हुन पाएन';
+$messages['cookiesdisabled'] = 'तपाईको ब्राऊसरले कुकी स्वीकार गारिरहेको छैन';
+$messages['sessionerror'] = 'सत्र समाप्त वा अवैद्य';
+$messages['imaperror'] = 'सर्वर संग सम्पर्क हुन पाएन';
+$messages['nomessagesfound'] = 'यो मेलबक्स मा कुनै मेल छैन';
+$messages['loggedout'] = 'सत्र समाप्त । नमास्कार!';
+$messages['mailboxempty'] = 'मेल बक्स खाली छ';
+$messages['loading'] = 'लोड भईरहेको छ...';
+$messages['loadingdata'] = 'डाटा लोड भईरहेको छै...';
+$messages['checkingmail'] = 'नया मेलको खोजी भईरहेको छ...';
+$messages['sendingmessage'] = 'मेल पठाईदै रहेको छ...';
+$messages['messagesent'] = 'मेल सफल्तापूर्वक पठाईयो';
+$messages['savingmessage'] = 'मेल जोगाईदै छ...';
+$messages['messagesaved'] = 'मेल ड्राफ्ट फोल्डरमा जोगाईयो';
+$messages['successfullysaved'] = 'सफल्तापूर्वक जोगाईयो';
+$messages['addedsuccessfully'] = 'सम्पर्क पुस्तिकामा सफल्तापूर्वक सम्पर्क प्रविष्ट गारियो';
+$messages['contactexists'] = 'यो ई-मेल पहिलै लिईसकिएको छ';
+$messages['blockedimages'] = 'तपाईको प्राईवेसी को लागि तथा अन्य स्पामबाट बच्नकोलागि यो मेलमा चित्रहुरु देखाईएका छैनन्।';
+$messages['encryptedmessage'] = 'माफ गर्नुहोसे, यो मेल ईन्क्रिफ्ट गरिएको रूपमा छ, त्यसैले देखाउन सकिदैन!';
+$messages['nocontactsfound'] = 'कुनै सम्पर्क भेटिएन';
+$messages['contactnotfound'] = 'अनुरोध गारिएको सम्पर्क भेटिएन';
+$messages['sendingfailed'] = 'मेल पठाउन सकिएन';
+$messages['errorsaving'] = 'जोगाउदा-जोगाउदै गडबड भायो';
+$messages['errormoving'] = 'मेल सार्न सकिएन';
+$messages['errordeleting'] = 'मेल मेटाउन सकिएन';
+$messages['deletecontactconfirm'] = 'तापाईले छान्नुभएको सम्पर्कहरु, साँचै मेट्न चहानुहुन्छ?';
+$messages['deletemessagesconfirm'] = 'तापाईले छान्नु भएको मेलहरु, साँचै मेट्न चहानुहुन्छ?';
+$messages['deletefolderconfirm'] = 'तापाईले साँचै यो फोल्डर मेट्न चहानु हुन्छ?';
+$messages['purgefolderconfirm'] = 'तापाईले साँचै यो फोल्डरमा भएका सबै मेलहरु मेट्न चहानुहुन्छ?';
+$messages['formincomplete'] = 'फर्म पूर्ण रुपमा भरिएको छैन';
+$messages['noemailwarning'] = 'कृपया वैद्य ई-मेल भर्नुहोस';
+$messages['nonamewarning'] = 'कृपया नाम भर्नुहोस';
+$messages['nopagesizewarning'] = 'कृपया पन्नाको नाप भर्नुहोस';
+$messages['norecipientwarning'] = 'कृपया कम-से-कम एउटा प्रापकको विवरण भर्नुहोस';
+$messages['nosubjectwarning'] = 'मेलको कुनै विषय तोकिएको छैनै। केहि तोक्न चहानुहुन्छ ?';
+$messages['nobodywarning'] = 'बिना केहि लेखि पठाउने?';
+$messages['notsentwarning'] = 'मेल पठएको छैन.. मेल रद्द गर्न चहानुहुन्छ?';
+$messages['noldapserver'] = 'कृपया खोजको निम्ति एउटा ऐलडाप सर्वर छान्नहोस';
+$messages['nocontactsreturned'] = 'कुनै सम्पर्क फेला परेनन्';
+$messages['nosearchname'] = 'कृपया सम्पर्कको नाम या ई-मेल भर्नुहोस';
+$messages['searchsuccessful'] = '$nr मेलहरु पाइयो';
+$messages['searchnomatch'] = 'खोज असफल रहयो';
+$messages['searching'] = 'खोजि भईरहेको छ...';
+$messages['checking'] = 'जाँच भईरहेको छ...';
+$messages['nospellerrors'] = 'कुनै गलत हिज्जे फेला परेनन्';
+$messages['folderdeleted'] = 'फोल्डर सफल्तापूर्वक मेटियो';
+$messages['deletedsuccessfully'] = 'सफल्तापूर्वक मेटियो';
+$messages['converting'] = 'मेलबाट फोर्माटिङ हटाईदै छ...';
+$messages['messageopenerror'] = 'सर्वरबाट मेल लोड हुन सकेन';
+$messages['fileuploaderror'] = 'फाईल अपलोड हुन असफल';
+$messages['filesizeerror'] = 'अपलोड गरिएको फाईल हद $size भन्दा ठूलो छ';
+$messages['copysuccess'] = 'सफल्तापूर्वक $nr ठेगानाहरु उतारियो';
+$messages['copyerror'] = 'कुनै पनि ठेगानाहरु उतार्न सकिएन';
+$messages['sourceisreadonly'] = 'यो ठेगाना को श्रोत पढ्नको लागि मात्र उपलब्ध छ';
+$messages['errorsavingcontact'] = 'स्मपर्कको ठेगाना जोगाउन सकिएन';
+
+?>
index 2041e47753f381974ba1f13b783272ab6afea471..3a21f8732b095365704455376d60169200c99c7d 100644 (file)
@@ -14,7 +14,7 @@
 |         Laurens Vets <laurens@daemon.be>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -233,7 +233,6 @@ $labels['always'] = 'altijd';
 $labels['showinlineimages'] = 'Toon bijgevoegde afbeeldingen onder het bericht';
 $labels['autosavedraft'] = 'Automatisch als concept opslaan';
 $labels['everynminutes'] = 'elke $n minuten';
-$labels['keepaliveevery'] = 'elke $n minuten';
 $labels['keepalive'] = 'Controleer op nieuwe berichten';
 $labels['never'] = 'nooit';
 $labels['messagesdisplaying'] = 'Berichten weergave';
index 25ec8d92c22ca70c223b644ef5b26d395f12cc56..48cce87eb90899fd6922feb29536dc1c28384db4 100644 (file)
 | Author: Mark Moses <mark@katmoda.com>                                 |
 |         Lazlo Westerhof <roundcube@lazlo.me>                          |
 |         Laurens Vets <laurens@daemon.be>                              |
+|         Frits Letteboer <f.letteboer@radiotwenterand.nl>              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2914 2009-09-04 10:51:09Z robin $
 
 */
 
@@ -118,12 +119,15 @@ $labels['markread'] = 'Gelezen';
 $labels['markunread'] = 'Ongelezen';
 $labels['markflagged'] = 'Selecteren';
 $labels['markunflagged'] = 'Niet selecteren';
+$labels['messageactions'] = 'Meer acties...';
 $labels['select'] = 'Selecteer';
 $labels['all'] = 'Allemaal';
 $labels['none'] = 'Geen';
 $labels['unread'] = 'Ongelezen';
 $labels['flagged'] = 'Geselecteerd';
 $labels['unanswered'] = 'Onbeantwoord';
+$labels['deleted'] = 'Verwijderd';
+$labels['invert'] = 'Selectie omdraaien';
 $labels['filter'] = 'Filter';
 $labels['compact'] = 'Opschonen';
 $labels['empty'] = 'Legen';
@@ -136,7 +140,9 @@ $labels['resetsearch'] = 'Reset zoekopdracht';
 $labels['searchmod'] = 'Zoekopties';
 $labels['msgtext'] = 'Gehele bericht';
 $labels['openinextwin'] = 'Openen in een nieuw venster';
+$labels['emlsave'] = 'Opslaan (.eml)';
 $labels['compose'] = 'Nieuw bericht aanmaken';
+$labels['editasnew'] = 'Als nieuw bewerken';
 $labels['savemessage'] = 'Bewaar als concept';
 $labels['sendmessage'] = 'Verstuur het bericht nu';
 $labels['addattachment'] = 'Voeg een bijlage toe';
@@ -168,7 +174,7 @@ $labels['addreplyto'] = 'Antwoord-aan toevoegen';
 $labels['mdnrequest'] = 'De afzender van dit bericht heeft gevraagd een melding te ontvangen wanneer u dit bericht heeft gelezen. Wilt u deze melding verzenden?';
 $labels['receiptread'] = 'Ontvangstbevestiging (gelezen)';
 $labels['yourmessage'] = 'Dit is een ontvangstbevestiging voor uw bericht';
-$labels['receiptnote'] = 'Let op: Dit bevestigd alleen dat uw bericht bij de geaddresseerde is weergegeven. Er is geen garantie dat de geaddresseerde het bericht daadwerkelijk heeft gelezen of de inhoud heeft begrepen.';
+$labels['receiptnote'] = 'Let op: Dit bevestigt alleen dat uw bericht bij de geadresseerde is weergegeven. Er is geen garantie dat de geadresseerde het bericht daadwerkelijk heeft gelezen of de inhoud ervan heeft begrepen.';
 $labels['name'] = 'Naam';
 $labels['firstname'] = 'Voornaam';
 $labels['surname'] = 'Achternaam';
@@ -236,7 +242,6 @@ $labels['always'] = 'altijd';
 $labels['showinlineimages'] = 'Toon bijgevoegde afbeeldingen onder het bericht';
 $labels['autosavedraft'] = 'Concept automatisch opslaan';
 $labels['everynminutes'] = 'iedere $n minuten';
-$labels['keepaliveevery'] = 'iedere $n minuten';
 $labels['keepalive'] = 'Controleer op nieuwe berichten';
 $labels['never'] = 'nooit';
 $labels['messagesdisplaying'] = 'Berichten weergave';
@@ -248,6 +253,12 @@ $labels['2047folding'] = 'Volledig RFC 2047 (andere)';
 $labels['advancedoptions'] = 'Geavanceerde opties';
 $labels['focusonnewmessage'] = 'Focus browserscherm bij nieuw bericht';
 $labels['checkallfolders'] = 'Controleer alle mappen op nieuwe berichten';
+$labels['displaynext'] = 'Na verplaatsen/verwijderen het volgende bericht tonen';
+$labels['mainoptions'] = 'Hoofdopties';
+$labels['section'] = 'Sectie';
+$labels['maintenance'] = 'Onderhoud';
+$labels['newmessage'] = 'Nieuw bericht';
+$labels['listoptions'] = 'Lijstopties';
 $labels['folder'] = 'Map';
 $labels['folders'] = 'Mappen';
 $labels['foldername'] = 'Mapnaam';
index 4df22d3abd2890b5e75c0f2a16099725936f29bf..2ad18952e31749f802f91058848e121104c92ea2 100644 (file)
 |                                                                       |
 +-----------------------------------------------------------------------+
 | Author: Mark Moses <mark@katmoda.com>                                 |
-|         Lazlo Westerhof <roundcube@lazlo.me>                          |
+|         Lazlo Westerhof <roundcube@lazlo.me>                         |
+|         Frits Letteboer <f.letteboer@radiotwenterand.nl>              |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2798 2009-07-24 13:30:39Z robin $
 
 */
 
@@ -23,6 +24,8 @@ $messages['loginfailed'] = 'Inloggen mislukt';
 $messages['cookiesdisabled'] = 'Uw browser accepteert geen cookies';
 $messages['sessionerror'] = 'Uw sessie is verlopen of ongeldig';
 $messages['imaperror'] = 'Connectie met IMAP server mislukt';
+$messages['servererror'] = 'Server Fout!';
+$messages['invalidrequest'] = 'Ongeldige aanvraag! Er zijn geen gegevens opgeslagen.';
 $messages['nomessagesfound'] = 'Geen berichten gevonden in deze mailbox';
 $messages['loggedout'] = 'Succesvol uitgelogd. Tot ziens!';
 $messages['mailboxempty'] = 'Mailbox is leeg';
@@ -46,6 +49,7 @@ $messages['errorsavingsent'] = 'Er is een fout opgetreden tijdens het opslaan va
 $messages['errorsaving'] = 'Er is een fout opgetreden tijdens het opslaan';
 $messages['errormoving'] = 'Kan het bericht niet verplaatsen';
 $messages['errordeleting'] = 'Kan het bericht niet verwijderen';
+$messages['errormarking'] = 'Kon bericht niet markeren';
 $messages['deletecontactconfirm'] = 'Weet u zeker dat u de geselecteerde contactperso(o)n/en wilt verwijderen?';
 $messages['deletemessagesconfirm'] = 'Weet u zeker dat u de geselecteerde bericht(en) wilt verwijderen?';
 $messages['deletefolderconfirm'] = 'Weet u zeker dat u deze map wilt verwijderen?';
@@ -95,5 +99,12 @@ $messages['importconfirm'] = '<b>Er zijn $inserted contactpersonen succesvol ge
 $messages['opnotpermitted'] = 'Deze verrichting is niet toegestaan!';
 $messages['nofromaddress'] = 'Het e-mailadres mist in de geselecteerde identiteit';
 $messages['editorwarning'] = 'Door het overschakelen naar de platte tekst editor gaat alle opmaak verloren. Weet je zeker dat je verder wil gaan?';
+$messages['httpreceivedencrypterror'] = 'Er is een fatale fout opgetreden. Neem direct contact op met uw systeembeheerder. <b>Uw bericht kon niet worden verzonden.</b>';
+$messages['smtpconnerror'] = 'SMTP Fout ($code): Verbinding met server mislukt';
+$messages['smtpautherror'] = 'SMTP Fout ($code): Autenticatie mislukt';
+$messages['smtpfromerror'] = 'SMTP Fout ($code): Kon afzender "$from" niet instellen';
+$messages['smtptoerror'] = 'SMTP Fout ($code): Kon ontvanger "$to" niet toevoegen';
+$messages['smtprecipientserror'] = 'SMTP Fout: Kon lijst van ontvangers niet verwerken';
+$messages['smtperror'] = 'SMTP Fout: $msg';
 
 ?>
index 4e434b45b14bfd74c4259f8922b6461294846e68..482ce2dec164b88ce8f1eedf435f6d4f16eea125 100644 (file)
@@ -14,7 +14,7 @@
 | Update: Odin Omdal Hørthe <odin.omdal@gmail.com>                      |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -225,7 +225,6 @@ $labels['readwhendeleted'] = 'Marker melding som lese ved sletting';
 $labels['flagfordeletion'] = 'Flagg meldinga for sletting i staden for å sletta';
 $labels['showinlineimages'] = 'Vis vedlagte bilete under meldinga';
 $labels['autosavedraft'] = 'Lagra kladd automatisk';
-$labels['everynminutes'] = 'kvart $n minutt';
 $labels['never'] = 'aldri';
 $labels['messagesdisplaying'] = 'Meldingar som viser';
 $labels['messagescomposition'] = 'Meldingar sin komposisjon';
index 7b8a39d64a16263dd0b61327cbf1bec76d5aeaef..9f98d206a8d079eab2f903b3760b8337c7d043b4 100644 (file)
@@ -122,17 +122,20 @@ $labels['lastmessage'] = 'Pokaż ostatnią';
 $labels['lastmessages'] = 'Pokaż ostatnie';
 $labels['backtolist'] = 'Pokaż listę wiadomości';
 $labels['viewsource'] = 'Pokaż źródło';
-$labels['markmessages'] = 'Oznacz wiadomość';
-$labels['markread'] = 'Jako przeczytaną';
-$labels['markunread'] = 'Jako nieprzeczytaną';
-$labels['markflagged'] = 'Jako oflagowaną';
-$labels['markunflagged'] = 'Jako nieoflagowaną';
+$labels['markmessages'] = 'Oznacz wiadomości';
+$labels['markread'] = 'Jako przeczytane';
+$labels['markunread'] = 'Jako nieprzeczytane';
+$labels['markflagged'] = 'Jako oflagowane';
+$labels['markunflagged'] = 'Jako nieoflagowane';
+$labels['messageactions'] = 'Więcej akcji...';
 $labels['select'] = 'Zaznacz';
 $labels['all'] = 'Wszystkie';
 $labels['none'] = 'Anuluj';
 $labels['unread'] = 'Nieprzeczytane';
 $labels['flagged'] = 'Oznaczone';
 $labels['unanswered'] = 'Bez odpowiedzi';
+$labels['deleted'] = 'Usunięte';
+$labels['invert'] = 'Odwróć';
 $labels['filter'] = 'Filtr';
 $labels['compact'] = 'Porządkuj';
 $labels['empty'] = 'Opróżnij';
@@ -145,7 +148,9 @@ $labels['resetsearch'] = 'Wyczyść filtr';
 $labels['searchmod']  = 'Parametry wyszukiwania';
 $labels['msgtext']  = 'Cała wiadomość';
 $labels['openinextwin'] = 'Otwórz w nowym oknie';
+$labels['emlsave'] = 'Pobierz (.eml)';
 $labels['compose'] = 'Utwórz wiadomość';
+$labels['editasnew'] = 'Edytuj jako nową';
 $labels['savemessage'] = 'Zapisz kopię roboczą';
 $labels['sendmessage'] = 'Wyślij teraz';
 $labels['addattachment'] = 'Dołącz plik';
@@ -211,7 +216,7 @@ $labels['edititem'] = 'Edytuj';
 $labels['setdefault'] = 'Domyślna';
 $labels['language'] = 'Język';
 $labels['timezone'] = 'Strefa czasowa';
-$labels['pagesize'] = 'Wierszy na stronie';
+$labels['pagesize'] = 'Liczba wierszy na stronie';
 $labels['signature'] = 'Podpis';
 $labels['dstactive'] = 'Czas letni';
 $labels['htmleditor'] = 'Twórz wiadomości HTML';
@@ -224,7 +229,7 @@ $labels['uisettings'] = 'Interfejs użytkownika';
 $labels['serversettings'] = 'Ustawienia serwera';
 $labels['mailboxview'] = 'Widok skrzynki pocztowej';
 $labels['mdnrequests'] = 'Potwierdzenia odbioru';
-$labels['askuser'] = 'spytaj użytkownika';
+$labels['askuser'] = 'pytaj';
 $labels['autosend'] = 'wyślij automatycznie';
 $labels['ignore'] = 'ignoruj';
 $labels['mimeparamfolding'] = 'Nazwy załączników';
@@ -236,11 +241,11 @@ $labels['readwhendeleted'] = 'Podczas usuwania oznacz wiadomość jako przeczyta
 $labels['flagfordeletion'] = 'Oznacz wiadomość do usunięcia zamiast ją usuwać';
 $labels['skipdeleted'] = 'Ukryj wiadomości oznaczone do usunięcia';
 $labels['autosavedraft'] = 'Automatyczny zapis tworzonej wiadomości';
-$labels['everynminutes'] = 'co $n minut(y)';
 $labels['keepalive']  = 'Sprawdzaj czy nadeszły nowe wiadomości';
-$labels['keepaliveevery']  = 'co $n minut(y)';
+$labels['everynminutes']  = 'co $n minut(y)';
 $labels['never'] = 'nigdy';
 $labels['focusonnewmessage'] = 'Informuj przeglądarkę o nowej wiadomości';
+$labels['displaynext'] = 'Po usunięciu/przeniesieniu wiadomości wyświetl następną';
 $labels['folder'] = 'Folder';
 $labels['folders'] = 'Foldery';
 $labels['foldername'] = 'Nazwa folderu';
@@ -270,5 +275,10 @@ $labels['KB'] = 'KB';
 $labels['MB'] = 'MB';
 $labels['GB'] = 'GB';
 $labels['checkallfolders'] = 'Sprawdzaj czy nadeszły nowe wiadomości we wszystkich folderach';
+$labels['mainoptions'] = 'Opcje główne';
+$labels['section'] = 'Sekcja';
+$labels['maintenance'] = 'Konserwacja';
+$labels['newmessage'] = 'Nowa wiadomość';
+$labels['listoptions'] = 'Opcje list';
 
 ?>
index 897c16b0176694cfbf933fa52bc34bdc066b4a12..0c0168f6d9c9e4448d5c2fb9e027c9dfdc6a1848 100644 (file)
@@ -27,6 +27,7 @@ $messages['loginfailed'] = 'Błąd logowania!';
 $messages['cookiesdisabled'] = 'Twoja przeglądarka nie obsługuje ciasteczek!';
 $messages['sessionerror'] = 'Błąd sesji bądź sesja wygasła!';
 $messages['imaperror'] = 'Błąd połączenia z serwerem!';
+$messages['servererror'] = 'Błąd serwera!';
 $messages['nomessagesfound'] = 'Brak wiadomości w skrzynce.';
 $messages['loggedout'] = 'Użytkownik wylogował się poprawnie.';
 $messages['mailboxempty'] = 'Skrzynka jest pusta!';
@@ -50,6 +51,7 @@ $messages['errorsavingsent'] = 'Wystąpił błąd podczas zapisu wysłanej wiado
 $messages['errorsaving'] = 'Wystąpił błąd podczas zapisu!';
 $messages['errormoving'] = 'Nie można przenieść wybranej wiadomości!';
 $messages['errordeleting'] = 'Nie można usunąć wiadomości!';
+$messages['errormarking'] = 'Nie można oznaczyć wiadomości!';
 $messages['deletecontactconfirm'] = 'Czy na pewno chcesz usunąć wybrane kontakty?';
 $messages['deletemessagesconfirm'] = 'Czy na pewno chcesz usunąć wybrane wiadomości?';
 $messages['deletefolderconfirm'] = 'Czy na pewno chcesz usunąć wybrany folder?';
@@ -99,5 +101,13 @@ $messages['importconfirm'] = '<b>Pomyślnie dodano $inserted kontaktów, pomini
 $messages['opnotpermitted'] = 'Niedozwolona operacja!';
 $messages['nofromaddress'] = 'Brak adresu e-mail w wybranej tożsamości';
 $messages['editorwarning'] = 'Zmiana edytora spowoduje utratę formatowania tekstu. Czy jesteś pewien, że chcesz to zrobić?';
+$messages['httpreceivedencrypterror'] = 'Wystąpił błąd krytyczny. Skontaktuj się z administratorem. <b>Nie można wysłać wiadomości.</b>';
+$messages['smtpconnerror'] = 'Błąd SMTP ($code): Nie można nawiązać połączenia z serwerem';
+$messages['smtpautherror'] = 'Błąd SMTP ($code): Uwierzytelnianie nie powiodło się';
+$messages['smtpfromerror'] = 'Błąd SMTP ($code): Nie można ustawić nadawcy "$from"';
+$messages['smtptoerror'] = 'Błąd SMTP ($code): Nie można dodać odbiorcy "$to"';
+$messages['smtprecipientserror'] = 'Błąd SMTP: Parsowanie listy odbiorców nie powiodło się';
+$messages['smtperror'] = 'Błąd SMTP: $msg';
+$messages['invalidrequest'] = 'Błędne żądanie! Nie zapisano danych.';
 
 ?>
diff --git a/program/localization/ps/labels.inc b/program/localization/ps/labels.inc
new file mode 100755 (executable)
index 0000000..7dd6430
--- /dev/null
@@ -0,0 +1,306 @@
+<?php
+
+
+
+// login page
+$labels['welcome']   = '$product ته ښه راغلاست ';
+$labels['username']  = 'کارن نوم';
+$labels['password']  = 'پټنوم';
+$labels['server']    = 'برابرونکی';
+$labels['login']     = 'ننوتون';
+
+// taskbar
+$labels['logout']   = 'وتون';
+$labels['mail']     = 'برېښناليک';
+$labels['settings'] = 'ځاني برابرونې';
+$labels['addressbook'] = 'پتې کتاب';
+
+// mailbox names
+$labels['inbox']  = 'راغلي ليکونه';
+$labels['drafts'] = 'بارليک';
+$labels['sent']   = 'لېږل شوي ليکونه';
+$labels['trash']  = 'کثافت دانۍ';
+$labels['junk']   = 'جنک';
+
+// message listing
+$labels['subject'] = ' مضمون';
+$labels['from']    = 'استوونکی';
+$labels['to']      = 'ترلاسه کوونکی';
+$labels['cc']      = 'لمېسل';
+$labels['bcc']     = 'پټليکی';
+$labels['replyto'] = 'ځوابول';
+$labels['date']    = 'نېټه';
+$labels['size']    = 'کچه ';
+$labels['priority'] = 'لومړيتوب';
+$labels['organization'] = 'ټولنه';
+
+$labels['mailboxlist'] = 'پوښۍ';
+$labels['messagesfromto'] = 'له ټاکلي استوزو څخه ټاکلي شمېرل شوو استوزو ته ';
+$labels['messagenrof'] = 'له $nr ځخه استوزو $count استوزو ته';
+
+$labels['moveto']   = 'ته خوځوي';
+$labels['download'] = 'ښکته کول';
+
+$labels['filename'] = ' فايل نوم';
+$labels['filesize'] = 'فايل کچه';
+
+$labels['preferhtml'] = 'ايچ ټي ام ايل ښوون';
+$labels['htmlmessage'] = 'ايچ ټي ام ايل استوزه';
+$labels['prettydate'] = ' په زړه پورې نېټې';
+
+$labels['addtoaddressbook'] = 'د پتو کتاب ته يې ورزيات کړئ';
+
+// weekdays short
+$labels['sun'] = 'يوه نۍ ';
+$labels['mon'] = 'دوه نۍ';
+$labels['tue'] = 'درې نۍ';
+$labels['wed'] = 'څلورنۍ';
+$labels['thu'] = 'پنځنۍ';
+$labels['fri'] = 'جمعه';
+$labels['sat'] = 'نۍ';
+
+// weekdays long
+$labels['sunday']    = 'يوه نۍ';
+$labels['monday']    = 'دوه نۍ';
+$labels['tuesday']   = 'درې نۍ';
+$labels['wednesday'] = 'منځنۍ';
+$labels['thursday']  = 'پنځنۍ';
+$labels['friday']    = 'جمعه';
+$labels['saturday']  = 'نۍ';
+
+// months short
+$labels['jan'] = 'حنوري';
+$labels['feb'] = 'فبروري';
+$labels['mar'] = 'مارچ';
+$labels['apr'] = 'اپريل';
+$labels['may'] = 'مئ';
+$labels['jun'] = 'جون';
+$labels['jul']         = 'جولاي';
+$labels['aug'] = 'اګست';
+$labels['sep'] = 'سپتمپر';
+$labels['oct'] = 'اکتوبر';
+$labels['nov'] = 'نومبر';
+$labels['dec'] = 'ډسمبر';
+
+// months long
+$labels['longjan']     = 'جنوري';
+$labels['longfeb']     = 'فبروري';
+$labels['longmar']     = 'مارچ';
+$labels['longapr']     = 'اپريل';
+$labels['longmay']     = 'مئ';
+$labels['longjun']     = 'جون';
+$labels['longjul']     = 'جولای';
+$labels['longaug']     = 'اګست';
+$labels['longsep']     = 'سپتمبر';
+$labels['longoct']     = 'اکتوبر';
+$labels['longnov']     = 'نومبر';
+$labels['longdec']     = 'ډسمبر';
+
+$labels['today'] = 'نن ';
+
+// toolbar buttons
+$labels['checkmail']        = 'نوي استوزي وګوره';
+$labels['writenewmessage']  = 'نوي استوزي جوړول ';
+$labels['replytomessage']   = 'استوونکي ته ځواب ورکړئ';
+$labels['replytoallmessage'] = 'استوونکي او ټولو ترلاسه کوونکو ته ځواب لېږل ';
+$labels['forwardmessage']   = 'استوزه بل ته استول ';
+$labels['deletemessage']    = 'استوزه ړنګول ';
+$labels['movemessagetotrash'] = 'استوزه کثافت داني ته واستوه';
+$labels['printmessage']     = 'دا استوزه چاپ کړه ';
+$labels['previousmessage']  = 'پخوانۍ استوزه وښيه ';
+$labels['previousmessages'] = 'د استوزو پخوانی غونډ وښيه ';
+$labels['firstmessage']     = 'لومړی استوزه وښيه ';
+$labels['firstmessages']    = 'د استوزو لومړی غونډ وښيه ';
+$labels['nextmessage']      = 'ورپسې استوزه وښيه  ';
+$labels['nextmessages']     = 'د استوزو ورپسې غونډ وښيه ';
+$labels['lastmessage']      = 'پای /آخري استوزه وښيه ';
+$labels['lastmessages']     = 'داستوزو پای غونډ وښيه ';
+$labels['backtolist']       = 'بيرته د استوزو لست ته ';
+$labels['viewsource']       = 'سرچينه وښيه ';
+$labels['markmessages']     = 'استوزي په نښه کړئ ';
+$labels['markread']         = 'لوستل شوي په توګه ';
+$labels['markunread']       = 'د نالوستل شوي په توګه ';
+$labels['markflagged']         = 'د بي کاره په توګه';
+$labels['markunflagged']       = 'د کارونې په توګه';
+
+$labels['select'] = 'ټاکل ';
+$labels['all'] = 'ټول ';
+$labels['none'] = 'هېڅ ';
+$labels['unread'] = 'نالوستي ';
+$labels['flagged'] = 'بې کاره';
+$labels['unanswered'] = 'ناځواب شوي';
+$labels['filter'] = 'چڼول';
+
+$labels['compact'] = 'کېښکلی ';
+$labels['empty'] = 'تش ';
+$labels['purge'] = 'لرول ';
+
+$labels['quota'] = 'ټيکلي لارښود ';
+$labels['unknown']  = 'نامعلوم ';
+$labels['unlimited']  = 'بي کچه ';
+
+$labels['quicksearch']  = 'ژر پلټنه ';
+$labels['resetsearch']  = 'د پلټنې بياسمون ';
+
+$labels['openinextwin'] = 'په نوي کړکۍ کې پرانيزه';
+
+// message compose
+$labels['compose']        = 'استوزه وليکه ';
+$labels['savemessage']    = 'دا ګارليک خوندي کړه ';
+$labels['sendmessage']    = 'اوس يې واستوه';
+$labels['addattachment']  = 'يو فايل ونښلوه ';
+$labels['charset']        = 'چيرست';
+$labels['editortype']     = 'د ټايب سمونګر ';
+$labels['returnreceipt']  = 'د رسليک راګرځېدل ';
+
+$labels['checkspelling'] = 'ليکدود کتنه ';
+$labels['resumeediting'] = 'کارمخينې سمونه ';
+$labels['revertto']      = 'ته بېرته اړول ';
+
+$labels['attachments'] = 'نښلني ';
+$labels['upload'] = 'پورته کول ';
+$labels['close']  = 'بندول ';
+
+$labels['low']     = 'ټيټ ';
+$labels['lowest']  = 'خورا ټيټ ';
+$labels['normal']  = 'نورمال ';
+$labels['high']    = 'لوړ ';
+$labels['highest'] = 'خورا لوړ ';
+
+$labels['nosubject']  = 'هېڅ موضوع';
+$labels['showimages'] = 'انځورونه وښيه ';
+$labels['alwaysshow'] = 'تل له $استوونکي څخه انځورونه وښيه';
+
+$labels['htmltoggle'] = 'ايچ ټی ايمل ال';
+$labels['plaintoggle'] = 'ساده متن ';
+$labels['savesentmessagein'] = 'استول شوي استوزه په خوندي کړه';
+$labels['dontsave'] = 'مه ساته';
+$labels['maxuploadsize'] = 'لږترلږه د اجازه شوي فايل کچه $وي';
+
+$labels['addcc'] = 'څرګندليک ';
+$labels['addbcc'] = 'پټليک ';
+$labels['addreplyto'] = 'ته ورزيات کړه ';
+
+// mdn
+$labels['mdnrequest'] = 'ددې استوزي استوونکی پوښتي چېد استوزي لوستلو سره سم تاسې خبر کړي،.    غواړئ چې استوونکی خبرشي؟ ';
+$labels['receiptread'] = 'رسليک راګرځېدل (لوستل ';
+$labels['yourmessage'] = ' دا رسليک راګرځېدل ستاسې استوزي لپاره دی ';
+$labels['receiptnote'] = 'يادونه: دا رسليک تاسې ته يوازې ددې خبرتيا درکوي چې کله استوزی د ترلاسه کوونکي په کمپيوټر کې څرګند شي،  ددې هيڅ ډاډګيرنه نشته چې ترلاسه کوونکي د  استوزي متن لوستی او يا پرې پوه شوی دی';
+
+// address boook
+$labels['name']      = 'نوم ښوونه';
+$labels['firstname'] = 'نوم  ';
+$labels['surname']   = 'کورنی نوم ';
+$labels['email']     = 'برېښناليک';
+
+$labels['addcontact'] = 'نوی اړيکلوری ورزيات کړه ';
+$labels['editcontact'] = 'اړيکلوري سمون ';
+
+$labels['edit']   = ' سمون ';
+$labels['cancel'] = 'لري کول ';
+$labels['save']   = 'ساتل ';
+$labels['delete'] = 'ړنګول ';
+
+$labels['newcontact']     = ' نوي اړيکلوري کارټ جوړ کړه   ';
+$labels['deletecontact']  = 'ټاکل شوي اړيکلوري ړنګ کړه ';
+$labels['composeto']      = '  ته ليک وليکه ';
+$labels['contactsfromto'] = 'له دومره اړيکلورو څخه دومره شمېرل شوي Contacts $from to $to of $count';
+$labels['print']          = 'چاپ ';
+$labels['export']         = 'بهرول ';
+$labels['exportvcards']   = 'اړيکلوري د ويکارډ په بڼه واستوئ';
+
+$labels['previouspage']   = 'پخوانی غونډ وښيه  ';
+$labels['firstpage']      = 'لومړی غونډ وښيه  ';
+$labels['nextpage']       = 'ورپسې غونډ وښيه ';
+$labels['lastpage']       = ' پای غونډ وښيه ';
+
+$labels['groups'] = 'ډلې ';
+$labels['personaladrbook'] = 'ځاني پتې ';
+
+$labels['import'] = 'رانقلول';
+$labels['importcontacts'] = 'اړيکلوري نقل کړئ';
+$labels['importfromfile'] = 'له فايل څخه رانقل کړئ';
+$labels['importreplace'] = 'ټول ادرس کتاب بدل کړئ';
+$labels['importtext'] = 'تاسې کولی شئ‌چې يو اړيکلوری له شته پتې کتاب څخه پورته کړئ<br/>موږ همدا اوس له  <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>پتې رانقلوو . د فايلونو بڼې';
+$labels['done'] = 'ترسره شو';
+
+// settings
+$labels['settingsfor']  = 'لپاره برابرونې ';
+
+$labels['preferences']  = 'غورونې ';
+$labels['userpreferences']  = 'کارن غورونې ';
+$labels['editpreferences']  = 'د کارن غورونو سمون ';
+
+$labels['identities']  = 'پېژندنې ';
+$labels['manageidentities']  = 'ددې حساب پېژندنو برابرول ';
+$labels['newidentity']  = 'نوي پېژندنه ';
+
+$labels['newitem']  = 'نوی توک ';
+$labels['edititem']  = 'توک سمون ';
+
+$labels['setdefault']  = 'تلوالي برابرول ';
+$labels['autodetect']  = 'په خپلواکه توګه';
+$labels['language']  = 'ژبه ';
+$labels['timezone']  = 'سيميز وخت ';
+$labels['pagesize']  = 'په هر مخ پرتې کښې ';
+$labels['signature'] = 'لاسليک ';
+$labels['dstactive']  = 'ورځنيو کارونو لنډيز ساتل';
+$labels['htmleditor'] = 'ايچ ټي‌ام ايل استوزي وليکه ';
+$labels['htmlsignature'] = 'ايچ ټي ام ايل لاسليک ';
+$labels['previewpane'] = ' پخوانی چوکاټ وښييه ';
+$labels['skin'] = 'انټرفيس بڼه';
+$labels['logoutclear'] = 'کثافت داني د وتنې په وخت کې پاکه کړه';
+$labels['logoutcompact'] = 'د وتنې په وخت کې ليکبکس ونښلوه';
+$labels['uisettings'] = 'د کاروونکي برسېر';
+$labels['serversettings'] = 'سرور برابرونې';
+$labels['mailboxview'] = 'ليکبکس ښکار کړه';
+$labels['mdnrequests'] = 'د استوونکي خبرتياوې';
+$labels['askuser'] = 'له کاروونکي څخه وپوښته';
+$labels['autosend'] = 'په خپلواکه توګه واستوه';
+$labels['ignore'] = 'لرې کړه';
+$labels['readwhendeleted'] = 'په ړنګ شوو کې استوزي د لوستل شوي  په توګه په نښه کړه';
+$labels['flagfordeletion'] = 'استوزه د ړنګ شوي پرځای بېکاره کړه';
+$labels['skipdeleted'] = 'ړنګ شوي استوزي مه ښکاره کوه';
+$labels['showremoteimages'] = 'انځورونه له لري په ليکه کې ښکاره کړه';
+$labels['fromknownsenders'] = 'له اشنا استوونکو څخه';
+$labels['always'] = 'تل';
+$labels['showinlineimages'] = 'نښلول شوي انځورونه تر استوزې لاندې ښکاره کړه';
+$labels['autosavedraft']  = 'بارليک په خپل سري توګه  خوندي‌کړه ';
+$labels['everynminutes']  = 'هر ه ګڼه په دقيقو کې  ';
+$labels['keepaliveevery']  = 'هر دقيقې $n';
+$labels['keepalive']  = 'نوي استوزي وګوره په';
+$labels['never']  = 'هېڅ ';
+$labels['messagesdisplaying'] = 'استوزي ښيي';
+$labels['messagescomposition'] = 'استوزي ليکي';
+$labels['mimeparamfolding'] = 'د نښلول شوو نومونه';
+$labels['2231folding'] = 'بشپړ RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Full RFC 2047 (نور)';
+$labels['advancedoptions'] = 'پرمختللي لارې';
+$labels['focusonnewmessage'] = 'فوکاس براوسر کړکۍ په نوي استوزي کې';
+$labels['checkallfolders'] = 'په ټولو پوښيو کې نوي استوزي وګورئ';
+
+$labels['folder']  = 'پوښۍ ';
+$labels['folders']  = 'پوښۍ';
+$labels['foldername']  = 'پوښۍ نوم ';
+$labels['subscribed']  = 'ګډ شو ';
+$labels['messagecount'] = 'استوزي ';
+$labels['create']  = 'جوړول، رامنځ ته کول ';
+$labels['createfolder']  = 'نوې پوښۍ جوړ کړه ';
+$labels['rename'] = 'بيانومول ';
+$labels['renamefolder'] = 'پوښۍ بيانومول ';
+$labels['deletefolder']  = 'پوښۍ ړنګول ';
+$labels['managefolders']  = 'پوښيو څارل ';
+$labels['specialfolders'] = 'ځانګړي پوښۍۍ';
+
+$labels['sortby'] = ' اڼل  ';
+$labels['sortasc']  = 'له پورته نه ښکته خوا ته برابرول ';
+$labels['sortdesc'] = 'له ښکته نه پورته خوا ته برابرول';
+
+// units
+$labels['B'] = 'بي';
+$labels['KB'] = 'کي بي';
+$labels['MB'] = 'ام بي';
+$labels['GB'] = 'جي بي';
+
+?>
diff --git a/program/localization/ps/messages.inc b/program/localization/ps/messages.inc
new file mode 100755 (executable)
index 0000000..c5aae6a
--- /dev/null
@@ -0,0 +1,80 @@
+<?php
+
+$messages['loginfailed']  = 'ننوتنه په بري سره ترسره نه شوه ';
+$messages['cookiesdisabled'] = 'ستاسو لټوني ککوړي ونه منل ';
+$messages['sessionerror'] = ' ستاسې ناسته ناباوري يا له مينځه تللې ده';
+$messages['imaperror'] = 'له ای ميپ سرور سره پيوستون په بري سره ترسره نه شو ';
+$messages['nomessagesfound'] = 'ليکبکس کې هېڅ استوزي ونه مونده';
+$messages['loggedout'] = 'تاسې له ناستې څخه په بشپړه توګه وويستل شوئ الله په امان';
+$messages['mailboxempty'] = 'ليکبکس تش دی';
+$messages['loading'] = 'د کار په حال کې';
+$messages['loadingdata'] = 'اومتوک د کار په حال کې';
+$messages['checkingmail'] = 'نوي استوزي ګوري';
+$messages['sendingmessage'] = 'استوزه استوي.';
+$messages['messagesent'] = 'استوزه په بري سره واستول شوه';
+$messages['savingmessage'] = 'استوزه خوندي کوي';
+$messages['messagesaved'] = 'استوزه په بارليک کې خوندي شوه';
+$messages['successfullysaved'] = 'په بري‌سره خوندي شوه';
+$messages['addedsuccessfully'] = 'اړيکلوری په بري سره پتې کتاب ته ور زيات شو';
+$messages['contactexists'] = 'يو اړيکلوری له دې برېښناليک پتې سره شتون لري';
+$messages['blockedimages'] = 'ستاسو د پټتيآ خوندي کېدو لپاره ، له لري انځورنه په دې استوزي‌کې بند کړئ ';
+$messages['encryptedmessage'] = 'دا يوه پټه استوزه ده او نه څرګندېږي. بښنه غواړو';
+$messages['nocontactsfound'] = 'هېڅ اړيکلوری يې ونه موند';
+$messages['contactnotfound'] = 'وړاندی شوی اړيکلوری ونه مونده';
+$messages['sendingfailed'] = 'استوزي استونه په بري سره پای ته ونه رسېده';
+$messages['senttooquickly'] = 'مهرباني وکړئ $صبر وکړئ د دې استوزې له لېږلو مخکې';
+$messages['errorsavingsent'] = 'دخوندي کولو او لېږلو پر  مهال يوه تيروتنه رامنځ ته شوه';
+$messages['errorsaving'] = 'دخوندي کولو پر  مهال يوه تيروتنه رامنځ ته شوه';
+$messages['errormoving'] = 'استوزه ونه خوځول شوه';
+$messages['errordeleting'] = 'استوزه ړنګه نه شوه';
+$messages['deletecontactconfirm']  = ' په رښتيا سره غواړئ چې ټاکل شوی اړيکلوری ړنګ کړئ؟ ';
+$messages['deletemessagesconfirm'] = 'په رښتيا سره غواړئ چې ټاکل شوي استوزي‌ړنګ کړئ؟';
+$messages['deletefolderconfirm']  = 'په رښتيآ سره غواړئ چې دا پوښۍ ړنګه کړئ؟';
+$messages['purgefolderconfirm']  = 'په رښتيا سره غواړئ چې ددې پوښۍ ټول استوزي‌ړنګ کړئ؟';
+$messages['foldercreating'] = 'پوښۍ جوړوي';
+$messages['folderdeleting'] = 'پوښۍ ړنګوي';
+$messages['folderrenaming'] = 'پوښۍ بيانوموي';
+$messages['foldermoving'] = 'پوښۍ خوځوي';
+$messages['formincomplete'] = 'دا پورمه بشپړه ډکه شوې نه ده';
+$messages['noemailwarning'] = 'مهرباني وکړئ د يوه شته برېښناليک پته ورځای کړئ';
+$messages['nonamewarning']  = 'مهرباني‌وکړئ يو نوم وليکئ';
+$messages['nopagesizewarning'] = 'مهرباني‌وکړئ د پاڼې کچه ورکړئ';
+$messages['nosenderwarning'] = 'مهرباني وکړئ د استول شوي برېښناليک پته وليکئ';
+$messages['norecipientwarning'] = 'مهرباني‌وکړئ لږ تر لږه يو ترلاسه کوونکی وليکئ';
+$messages['nosubjectwarning']  = 'د مضمون ډګر تش دی يا تاسو غواړئ چې همدا اوس يو له هغو څخه وليکئ';
+$messages['nobodywarning'] = 'دا استوزه پرته له متن څخه استوئ؟';
+$messages['notsentwarning'] = 'استوزه نه ده لېږل شوې. غواړئ چې استوزه مو لرې وغورځوئ';
+$messages['noldapserver'] = 'مهرباني وکړئ يو ال ډپ سرور د پلټلو لپاره وټاکئ';
+$messages['nocontactsreturned'] = 'هېڅ يو اړيکلوری يې ونه موند';
+$messages['nosearchname'] = 'مهرباني وکړئ  د يو اړيکلوري‌نوم يا برېښناليک پته وليکئ';
+$messages['searchsuccessful'] = 'استوزي ومونده$';
+$messages['searchnomatch'] = 'د پلټلو بيا راګرځېدل هېڅ سمون ونه خوړه';
+$messages['searching'] = 'پلټي';
+$messages['checking'] = 'ګوري';
+$messages['nospellerrors'] = 'هېڅ ليکدودي‌تيروتنه ونه مونده';
+$messages['folderdeleted'] = 'پوښۍ په بشپړه توګه ړنګه شوه';
+$messages['deletedsuccessfully'] = "په بشپړه توګه ړنګ شول";
+$messages['converting'] = 'له استوزي څخه بڼې ړنګېږي';
+$messages['messageopenerror'] = 'له سرور څخه استوزي پرمخ نه شي تلی';
+$messages['fileuploaderror'] = 'دفايل پورته کول په بري سره سرته ونه رسيده';
+$messages['filesizeerror'] = 'د پورته شوي فايل کچه بايد لږترلږه له $څخه تيری ونه کړي';
+$messages['copysuccess'] = 'په بشپړه توګه $پتې کاپي شوې';
+$messages['copyerror'] = 'هېڅ يوه پته يې کاپي‌نه شوای کړای';
+$messages['sourceisreadonly'] = 'ددې پتې يوازې سرچينه لوستل کېږي';
+$messages['errorsavingcontact'] = ' د پتې اړيکلوری يې خوندي‌نه شو کړای ';
+$messages['movingmessage'] = 'استوزه خوځوي';
+$messages['receiptsent'] = 'يو لوستل شوی رسليک په بشپړه توګه واستول شو';
+$messages['errorsendingreceipt'] = 'رسليک يې ونه شوای ليږلی';
+$messages['nodeletelastidentity'] = 'تاسې نه شئ کولی چې دا پېژندنه ړنګه کړئ، داستاسو اخرنی پيژندنه ده';
+$messages['addsubfolderhint'] = 'دا پوښۍ د دويمۍ پوښۍ په توګه د ټاکل شوي اوسني ځای کې جوړشي';
+$messages['forbiddencharacter'] = 'د پوښۍ نوم له فوربايډن تورو څخه جوړ دی';
+$messages['selectimportfile'] = 'مهرباني وکړئ‌يو فايل د پورته کولو لپاره وټاکئ';
+$messages['addresswriterror'] = 'ټاکل شوی پتې کتاب د بياليکلو نه دی';
+$messages['importwait'] = 'نقلوي...صبر وکړئ';
+$messages['importerror'] = 'نقلول په بري سره ترسره نه شول پورته شوی فايل شته ویکارډ فايل نه دی';
+$messages['importconfirm'] = '<b>په بشپړه توګه نقل شو $اړيکلوري داخل شول, $شته تيرشوي انټاير څخه تيرشول</b>:<p><em>$نومونه</em></p>';
+$messages['opnotpermitted'] = 'چار اجازه نه لري';
+$messages['nofromaddress'] = 'په ټاکل شوي پيژندنه کې برېښناليک پتې له لاسه ورکړي';
+$messages['editorwarning'] = 'که د متن بڼو له منځه تللو ګواښ وي نو د متن سمون پرانيزئ. غواړئ چې دوام ورکړئ';
+
+?>
index d53811d23a00ecd5631fc20315cac6044373785b..9d6873d71bbf5bde79ad6f08de2023baa025769d 100644 (file)
@@ -17,7 +17,7 @@
 |         Victor Benincasa <vbenincasa@gmail.com>                       |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
@@ -120,13 +120,16 @@ $labels['markread'] = 'como lidas';
 $labels['markunread'] = 'como não lidas';
 $labels['markflagged'] = 'como sinalizadas';
 $labels['markunflagged'] = 'como não sinalizadas';
+$labels['messageactions'] = 'Mais ações...';
 $labels['select'] = 'Selecionar';
 $labels['all'] = 'Todas';
 $labels['none'] = 'Nenhuma';
 $labels['unread'] = 'Não lidas';
 $labels['flagged'] = 'Sinalizada';
 $labels['unanswered'] = 'Não respondida';
-$labels['filter'] = 'Filtro';
+$labels['deleted'] = 'Excluída';
+$labels['invert'] = 'Inverter';
+$labels['filter'] = 'Exibir';
 $labels['compact'] = 'Compactar';
 $labels['empty'] = 'Esvaziar';
 $labels['purge'] = 'Apagar';
@@ -138,7 +141,9 @@ $labels['resetsearch'] = 'Limpar';
 $labels['searchmod'] = 'Opções da pesquisa';
 $labels['msgtext'] = 'Mensagem inteira';
 $labels['openinextwin'] = 'Abrir em nova janela';
+$labels['emlsave'] = 'Download (.eml)';
 $labels['compose'] = 'Escrever mensagem';
+$labels['editasnew'] = 'Editar como novo';
 $labels['savemessage'] = 'Salvar Rascunho';
 $labels['sendmessage'] = 'Enviar';
 $labels['addattachment'] = 'Anexar um arquivo';
@@ -237,8 +242,7 @@ $labels['fromknownsenders'] = 'de remetentes conhecidos';
 $labels['always'] = 'sempre';
 $labels['showinlineimages'] = 'Exibir imagens anexadas abaixo da mensagem';
 $labels['autosavedraft'] = 'Salvar rascunho automaticamente';
-$labels['everynminutes'] = 'a cada $n minutos';
-$labels['keepaliveevery'] = 'a cada $n minuto(s)';
+$labels['everynminutes'] = 'a cada $n minuto(s)';
 $labels['keepalive'] = 'Verificar se há novas mensagens';
 $labels['never'] = 'nunca';
 $labels['messagesdisplaying'] = 'Exibição de mensagens';
@@ -250,6 +254,12 @@ $labels['2047folding'] = 'RFC 2047 Integral (outro)';
 $labels['advancedoptions'] = 'Opções avançadas';
 $labels['focusonnewmessage'] = 'Focar janela do navegador na nova mensagem';
 $labels['checkallfolders'] = 'Verificar se há novas mensagens em todas as pastas';
+$labels['displaynext'] = 'Exibir a mensagem seguinte após apagar/mover uma mensagem';
+$labels['mainoptions'] = 'Opções Principais';
+$labels['section'] = 'Seção';
+$labels['maintenance'] = 'Manutenção';
+$labels['newmessage'] = 'Novas Mensagens';
+$labels['listoptions'] = 'Opções de Exibição';
 $labels['folder'] = 'Pasta';
 $labels['folders'] = 'Pastas';
 $labels['foldername'] = 'Nome da pasta';
index a1c98ce901c989977f59da93eda42bbfd9c25135..b17e6ccff73a6fb1a2d49c17d02a4d28bf979c90 100644 (file)
@@ -17,7 +17,7 @@
 |         Victor Benincasa <vbenincasa@gmail.com>                       |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2799 2009-07-26 11:42:46Z yllar $
 
 */
 
@@ -26,6 +26,8 @@ $messages['loginfailed'] = 'Falha no login';
 $messages['cookiesdisabled'] = 'Seu navegador não suporta cookies';
 $messages['sessionerror'] = 'A sessão do seu navegador é inválida ou expirou';
 $messages['imaperror'] = 'Falha na conexão com o servidor IMAP';
+$messages['servererror'] = 'Erro no Servidor!';
+$messages['invalidrequest'] = 'Requisição inválida! Nenhum dado foi salvo.';
 $messages['nomessagesfound'] = 'Nenhuma mensagem foi encontrada';
 $messages['loggedout'] = 'Sua sessão foi finalizada com sucesso. Até breve!';
 $messages['mailboxempty'] = 'A caixa de mensagens está vazia';
@@ -49,6 +51,7 @@ $messages['errorsavingsent'] = 'Ocorreu um erro ao salvar a mensagem enviada';
 $messages['errorsaving'] = 'Ocorreu um erro ao salvar';
 $messages['errormoving'] = 'Não foi possível mover a mensagem';
 $messages['errordeleting'] = 'Não foi possível apagar a mensagem';
+$messages['errormarking'] = 'Não foi possível marcar a mensagem';
 $messages['deletecontactconfirm'] = 'Deseja realmente excluir o(s) contato(s) selecionado(s)?';
 $messages['deletemessagesconfirm'] = 'Deseja realmente excluir a(s) mensagem(s) selecionada(s)?';
 $messages['deletefolderconfirm'] = 'Deseja realmente excluir esta pasta?';
@@ -98,5 +101,12 @@ $messages['importconfirm'] = '<b>Foram importados com sucesso $inserted contatos
 $messages['opnotpermitted'] = 'Operação não permitida!';
 $messages['nofromaddress'] = 'Falta o endereço de email na identidade selecionada';
 $messages['editorwarning'] = 'Mudar para o editor de texto simples elimina toda a formatação de texto. Deseja continuar?';
+$messages['httpreceivedencrypterror'] = 'Ocorreu um erro de configuração. Informe ao administrador do sistema imediatamente. <b>Sua mensagem não pode ser enviada.</b>';
+$messages['smtpconnerror'] = 'Erro SMTP ($code): Conexão ao servidor falhou';
+$messages['smtpautherror'] = 'Erro SMTP ($code): Falha na autenticação';
+$messages['smtpfromerror'] = 'Erro SMTP ($code): Falha ao definir o remetente "$from"';
+$messages['smtptoerror'] = 'Erro SMTP ($code): Falha ao adicionar o destinatário "$to"';
+$messages['smtprecipientserror'] = 'Erro SMTP: Não é possível analisar a lista destinatários';
+$messages['smtperror'] = 'Erro SMTP: $msg';
 
 ?>
index 2054e2cdff69f0e0b2378da40ab6ed6a89910ae3..66d2baa59eb51b9f48d48f4f330520c062a6683e 100644 (file)
@@ -16,7 +16,7 @@
 |          Nuno Costa <nuno@criacaoweb.net>                             |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -234,8 +234,7 @@ $labels['fromknownsenders'] = 'de remetentes conhecidos';
 $labels['always'] = 'sempre';
 $labels['showinlineimages'] = 'Mostrar imagens anexadas abaixo da mensagem';
 $labels['autosavedraft'] = 'Salvar rascunho automaticamente';
-$labels['everynminutes'] = 'a cada $n minutos';
-$labels['keepaliveevery'] = 'cada $n minuto(s)';
+$labels['everynminutes'] = 'cada $n minuto(s)';
 $labels['keepalive'] = 'Verificar novas mensagens em';
 $labels['never'] = 'nunca';
 $labels['messagesdisplaying'] = 'A exibir mensagens';
index 057ddf1adcb6d79e47f8b3311b4a1f8e3641519e..40d0fe2ff2b0e43458d5969944459eace44c4ef4 100644 (file)
@@ -13,7 +13,7 @@
 |         Zeno Popovici <zeno.popovici at ulbsibiu.ro>                  |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -231,8 +231,7 @@ $labels['fromknownsenders'] = 'de la expeditori cunoscuti';
 $labels['always'] = 'intotdeauna';
 $labels['showinlineimages'] = 'Arata imaginile atasate sub mesaj';
 $labels['autosavedraft'] = 'Salveaza ciorna automat';
-$labels['everynminutes'] = 'fiecare $n minute';
-$labels['keepaliveevery'] = 'fiecare $n minut(e)';
+$labels['everynminutes'] = 'fiecare $n minut(e)';
 $labels['keepalive'] = 'Verifica mesaje noi la';
 $labels['never'] = 'niciodata';
 $labels['messagesdisplaying'] = 'Afisarea Mesajelor';
@@ -265,4 +264,3 @@ $labels['MB'] = 'MO';
 $labels['GB'] = 'GO';
 
 ?>
-
index e4ca2c1141ff08b9633fa3e5c650b0a7931e6629..edfe48365eb127915246f47d8dbdee578fa5b8b3 100644 (file)
@@ -13,7 +13,7 @@
 |         Zeno Popovici <zeno.popovici at ulbsibiu.ro>                  |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: messages.inc 2494 2009-05-17 11:56:53Z yllar $
 
 */
 
@@ -96,4 +96,3 @@ $messages['nofromaddress'] = 'Nu exista o adresa de e-mail in identitatea select
 $messages['editorwarning'] = 'Trecerea in mod text a editorului va cauza pierderea formatarii textului. Doriti sa continuati?';
 
 ?>
-
index 5479d2c9e71fc4315e4e3f4392eb05235bf40983..6fce7f5eea47f976d7707d77004269d497aa370c 100644 (file)
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Maxim Zenin <maxx@webmechanics.ru>                            |
-|         Vladimir Kulev <me@lightoze.net>                              |
-|         Artur Smolkin <artsmolkin@ya.ru>                              |
+| Author: Artur Smolkin <artsmolkin@ya.ru>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
@@ -118,12 +116,15 @@ $labels['markread'] = 'Как прочитанное';
 $labels['markunread'] = 'Как непрочитанное';
 $labels['markflagged'] = 'Установить флаг';
 $labels['markunflagged'] = 'Снять флаг';
+$labels['messageactions'] = 'Еще действия...';
 $labels['select'] = 'Выбрать';
 $labels['all'] = 'Все';
 $labels['none'] = 'Ничего';
 $labels['unread'] = 'Непрочитанные';
 $labels['flagged'] = 'Помеченные';
 $labels['unanswered'] = 'Неотвеченные';
+$labels['deleted'] = 'Удаленное';
+$labels['invert'] = 'Инвертное';
 $labels['filter'] = 'Фильтр';
 $labels['compact'] = 'Сжать';
 $labels['empty'] = 'Опустошить';
@@ -136,7 +137,9 @@ $labels['resetsearch'] = 'Сброс';
 $labels['searchmod'] = 'Варианты поиска';
 $labels['msgtext'] = 'Всё сообщение';
 $labels['openinextwin'] = 'Открыть в новом окне';
+$labels['emlsave'] = 'Сохранить (.eml)';
 $labels['compose'] = 'Написать сообщение';
+$labels['editasnew'] = 'Редактировать как новое';
 $labels['savemessage'] = 'Сохранить черновик';
 $labels['sendmessage'] = 'Отправить сейчас';
 $labels['addattachment'] = 'Добавить вложение';
@@ -236,7 +239,6 @@ $labels['always'] = 'всегда';
 $labels['showinlineimages'] = 'Показывать вложенные изображения внизу сообщения';
 $labels['autosavedraft'] = 'Автосохранение черновика';
 $labels['everynminutes'] = 'каждые $n минут';
-$labels['keepaliveevery'] = 'каждые $n минут';
 $labels['keepalive'] = 'Проверять новые сообщения';
 $labels['never'] = 'никогда';
 $labels['messagesdisplaying'] = 'Отображение сообщений';
@@ -248,6 +250,12 @@ $labels['2047folding'] = 'RFC 2047  (для старых программ)';
 $labels['advancedoptions'] = 'Дополнительные настройки';
 $labels['focusonnewmessage'] = 'Фокусировать окно браузера при новом сообщении';
 $labels['checkallfolders'] = 'Проверять новые сообщения во всех папках';
+$labels['displaynext'] = 'Показать следующее сообщение, после удаления или перемещения данного';
+$labels['mainoptions'] = 'Основные настройки';
+$labels['section'] = 'Раздел';
+$labels['maintenance'] = 'Обслуживание';
+$labels['newmessage'] = 'Новое сообщение';
+$labels['listoptions'] = 'Список настроек';
 $labels['folder'] = 'Папка';
 $labels['folders'] = 'Папки';
 $labels['foldername'] = 'Имя папки';
index 5001e3627635ce6f6eb295eca61bff236e810dde..42e623ddfb8bad3364c1ddb08533a28d1dd42a2c 100644 (file)
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Maxim Zenin <maxx@webmechanics.ru>                            |
-|         Vladimir Kulev <me@lightoze.net>                              |
-|         Artur Smolkin <admin@roundcube.ru>                            |
+| Author: Artur Smolkin <artsmolkin@ya.ru>                              |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2784 2009-07-22 12:23:12Z yllar $
 
 */
 
@@ -24,6 +22,8 @@ $messages['loginfailed'] = 'Неудачная попытка входа';
 $messages['cookiesdisabled'] = 'Ваш броузер не принимает cookie';
 $messages['sessionerror'] = 'Ваша сессия устарела';
 $messages['imaperror'] = 'Неудачное соединение с IMAP сервером';
+$messages['servererror'] = 'Ошибка сервера!';
+$messages['invalidrequest'] = 'Неверный запрос! Информация не сохранена.';
 $messages['nomessagesfound'] = 'Сообщений не найдено';
 $messages['loggedout'] = 'Ваша сессия завершена. Всего доброго!';
 $messages['mailboxempty'] = 'Почтовый ящик пуст';
@@ -47,6 +47,7 @@ $messages['errorsavingsent'] = 'Произошла ошибка при сохр
 $messages['errorsaving'] = 'В процессе сохранения произошла ошибка';
 $messages['errormoving'] = 'Не удалось переместить сообщение';
 $messages['errordeleting'] = 'Не удалось удалить сообщение';
+$messages['errormarking'] = 'Невозможно пометить сообщение';
 $messages['deletecontactconfirm'] = 'Вы действительно хотите удалить выделенные контакты?';
 $messages['deletemessagesconfirm'] = 'Вы действительно хотите удалить выбранные сообщения?';
 $messages['deletefolderconfirm'] = 'Вы действительно хотите удалить эту папку?';
@@ -96,5 +97,12 @@ $messages['importconfirm'] = '<b>Успешно импортировано $inse
 $messages['opnotpermitted'] = 'Действие запрещено!';
 $messages['nofromaddress'] = 'В выбранном профиле не хватает адреса электронной почты';
 $messages['editorwarning'] = 'При переключении в редактор простого текста все форматирование будет потеряно. Продолжить?';
+$messages['httpreceivedencrypterror'] = 'На сервере возникла неизбежная ошибка. Срочно свяжитесь с Вашим администратором. <b>Ваше сообщение может быть не отправлено.</b>';
+$messages['smtpconnerror'] = 'SMTP Error ($code): Соединение с сервером сброшено';
+$messages['smtpautherror'] = 'SMTP Error ($code): Ошибка авторизации';
+$messages['smtpfromerror'] = 'SMTP Error ($code): Невозможно установить отправителя "$from"';
+$messages['smtptoerror'] = 'SMTP Error ($code): Невозможно добавить получателя "$to"';
+$messages['smtprecipientserror'] = 'SMTP Error ($code): Невозможно обработать список получателей';
+$messages['smtperror'] = 'SMTP Error ($code): $msg';
 
 ?>
index 6dec90c24b203069ecb9a59ae588834c19fa1ed9..4234a72056ac1e7d7a72f28170c290ab4d99e39f 100644 (file)
-<?php\r
-\r
-/*\r
- +-----------------------------------------------------------------------+\r
- | language/si/labels.inc                                                |\r
- |                                                                       |\r
- | Language file of the RoundCube Webmail client                         |\r
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |\r
- | Licensed under the GNU GPL                                            |\r
- |                                                                       |\r
- +-----------------------------------------------------------------------+\r
- | Author: Melanga Dissanayake <Melanga.Dissanayake@pabcbank.com>        |\r
- +-----------------------------------------------------------------------+\r
-\r
- @version $Id$\r
-\r
-*/\r
-\r
-$labels = array();\r
-$labels['welcome'] = '$product ආයුබොවන්';\r
-$labels['username'] = 'නම';\r
-$labels['password'] = 'මුරපදය';\r
-$labels['server'] = 'පද්ධතිය';\r
-$labels['login'] = 'අතුල්වීම';\r
-$labels['logout'] = 'පිටවීම';\r
-$labels['mail'] = 'විද්යුත් තැපෑල';\r
-$labels['settings'] = 'පොද්ගලික කට්ටල අංග';\r
-$labels['addressbook'] = 'ලිපින පොත';\r
-$labels['inbox'] = 'ඇතුල්වීම්';\r
-$labels['drafts'] = 'කටු සටහන්';\r
-$labels['sent'] = 'පිටවුම්';\r
-$labels['trash'] = 'ලටපට';\r
-$labels['junk'] = 'සුන්බුන්';\r
-$labels['subject'] = 'මාතෘකාව';\r
-$labels['from'] = 'යවන්නා';\r
-$labels['to'] = 'ලබන්නා';\r
-$labels['cc'] = 'පිටපත් කිරීම්';\r
-$labels['bcc'] = 'අඳ පිටපත් කිරීම්';\r
-$labels['replyto'] = 'පිළිතුරු සඳහා';\r
-$labels['date'] = 'දිනය';\r
-$labels['size'] = 'ප්රමාණය';\r
-$labels['priority'] = 'ප්රමුඛතාව';\r
-$labels['organization'] = 'සංවිධානය';\r
-$labels['reply-to'] = 'පිළිතුරු සඳහා';\r
-$labels['mailboxlist'] = 'ෆෝල්ඩරය';\r
-$labels['messagesfromto'] = '$from ගෙන් $to පනිවුඩ $count';\r
-$labels['messagenrof'] = 'පනිවුඩය $count න් $nr ';\r
-$labels['moveto'] = 'ගෙනයෑම...';\r
-$labels['download'] = 'බාගතකිරීම';\r
-$labels['filename'] = 'ගොනුවේ නම';\r
-$labels['filesize'] = 'ගොනුවේ ප්රමාණය';\r
-$labels['preferhtml'] = 'HTML විදහා පෙන්වීම';\r
-$labels['htmlmessage'] = 'HTML පනිවුඩය';\r
-$labels['prettydate'] = 'සුරුබුහුටි දින';\r
-$labels['addtoaddressbook'] = 'ලිපින පොතට එකතු කරන්න';\r
-$labels['sun'] = 'ඉරිදා';\r
-$labels['mon'] = 'සඳුදා';\r
-$labels['tue'] = 'අගහ';\r
-$labels['wed'] = 'බදාදා';\r
-$labels['thu'] = 'බ්රහස්';\r
-$labels['fri'] = 'සිකුරා';\r
-$labels['sat'] = 'සෙනසු';\r
-$labels['sunday'] = 'ඉරිදා';\r
-$labels['monday'] = 'සඳුදා';\r
-$labels['tuesday'] = 'අගහරුවාදා';\r
-$labels['wednesday'] = 'බදාදා';\r
-$labels['thursday'] = 'බ්රහස්පතිනිදා';\r
-$labels['friday'] = 'සිකුරාදා';\r
-$labels['saturday'] = 'සෙනසුරාදා';\r
-$labels['today'] = 'අද';\r
-$labels['checkmail'] = 'අඵත් පනිවුඩ සඳහා පිරික්සීම';\r
-$labels['writenewmessage'] = 'අඵත් පනිවුඩක්';\r
-$labels['replytomessage'] = 'පනිවුඩයට පිළිතුරු';\r
-$labels['replytoallmessage'] = 'එවන්නාට සහ සැමට පිළිතුරු';\r
-$labels['forwardmessage'] = 'පනිවුඩය ඉදිරියට';\r
-$labels['deletemessage'] = 'පනිවුඩය ලටපට තුලට ගෙනයන්න';\r
-$labels['movemessagetotrash'] = 'පණිවුඩය ලටපට වෙත ගෙන යන්න';\r
-$labels['printmessage'] = 'පනිවුඩය මුද්රනය කරන්න';\r
-$labels['previousmessage'] = 'කලින් පනිවුඩය පෙන්නන්න';\r
-$labels['previousmessages'] = 'කලින් පනිවුඩ කට්ටලය පෙන්නන්න';\r
-$labels['firstmessage'] = 'පළමුවන පනිවුඩය පෙන්නන්න';\r
-$labels['firstmessages'] = 'පළමුවන පනිවුඩ කට්ටලය පෙන්නන්න';\r
-$labels['nextmessage'] = 'මීළඟ පනිවුඩය පෙන්නන්න';\r
-$labels['nextmessages'] = 'මීළඟ පනිවුඩ කට්ටලය පෙන්නන්න';\r
-$labels['lastmessage'] = 'අවසාන පනිවුඩය පෙන්නන්න';\r
-$labels['lastmessages'] = 'අවසාන පනිවුඩ කට්ටලය පෙන්නන්න';\r
-$labels['backtolist'] = 'නැවතත් පනිවුඩ ලැයිස්තුවට';\r
-$labels['viewsource'] = 'මූලාශ්රය පෙන්නන්න';\r
-$labels['markmessages'] = 'පණිවුඩ';\r
-$labels['markread'] = 'කියවු ලෙස සළකුණු කරන්න';\r
-$labels['markunread'] = 'නොකියවු ලෙස සළකුණු කරන්න';\r
-$labels['select'] = 'තෝරාගන්න';\r
-$labels['all'] = 'සියලු';\r
-$labels['none'] = 'තෝරානොගත්';\r
-$labels['unread'] = 'නොකියවූ';\r
-$labels['compact'] = 'සංයුක්ත';\r
-$labels['empty'] = 'රික්ත';\r
-$labels['purge'] = 'විරේචන';\r
-$labels['quota'] = 'භාවිතය';\r
-$labels['unknown'] = 'නාඳුනන';\r
-$labels['unlimited'] = 'අසීමිත';\r
-$labels['quicksearch'] = 'ඉක්මන් සෙවුම';\r
-$labels['resetsearch'] = 'සෙවුම යලි පිහිටවීම';\r
-$labels['compose'] = 'පනිවුඩයක් සෑදීම';\r
-$labels['savemessage'] = 'කටු සටහනේ තැන්පත කරන්න';\r
-$labels['sendmessage'] = 'පනිවුඩය දැන් යවන්න';\r
-$labels['addattachment'] = 'ගොනුවක් ඇතුලත් කිරීම';\r
-$labels['charset'] = 'අකුරැ කට්ටලය';\r
-$labels['editortype'] = 'සම්පාදන ආකාරය';\r
-$labels['returnreceipt'] = 'නැවත ලබන්නා';\r
-$labels['checkspelling'] = 'වචන පරීක්ෂාව';\r
-$labels['resumeediting'] = 'සම්පාදන නැවත ඇරඹීම';\r
-$labels['revertto'] = 'ආපසු ඒම';\r
-$labels['attachments'] = 'ගොනු';\r
-$labels['upload'] = 'ඇතුල් කරීම';\r
-$labels['close'] = 'වැසීම';\r
-$labels['low'] = 'අඩු';\r
-$labels['lowest'] = 'අඩුම';\r
-$labels['normal'] = 'සමක';\r
-$labels['high'] = 'ඉහළ';\r
-$labels['highest'] = 'ඉහළම';\r
-$labels['nosubject'] = '(මාතෘකාව නොමැති)';\r
-$labels['showimages'] = 'රූප පෙන්නන්න';\r
-$labels['htmltoggle'] = 'HTML';\r
-$labels['plaintoggle'] = 'පැහැදිලි අකුරු';\r
-$labels['addcc'] = 'Cc එක් කරන්න';\r
-$labels['addbcc'] = 'Bcc එක් කරන්න';\r
-$labels['addreplyto'] = '\'පිළිතුරු සඳහා\' එක් කරන්න';\r
-$labels['mdnrequest'] = 'මෙම පණිවුඩය එවන්නා ඔබ එය කියවු බව අසයි. එය දැන්වීමට ඔබ කැමතිද?';\r
-$labels['receiptread'] = 'ලැබීම් ලදුපත (කියවීම)';\r
-$labels['yourmessage'] = 'මෙය ඔබගේ පණිවුඩයේ ලැබීම් ලදුපතයි';\r
-$labels['receiptnote'] = 'සටහන: ලැබීම් ලදුපත මගින් මෙම පණිවුඩය කියවූ බව හෝ තේරුම් ගත් බව ගම්‍ය නොවේ. පණිවුඩය ලබන්නාට පෙන්නුම් කල බවටට සාක්ෂියක් පමණි';\r
-$labels['name'] = 'නම පෙන්නන්න';\r
-$labels['firstname'] = 'පළමු නම';\r
-$labels['surname'] = 'අවසාන නම';\r
-$labels['email'] = 'ද්යුත් තැපෑල';\r
-$labels['addcontact'] = 'ලිපින පොතට එකතු කරන්න';\r
-$labels['editcontact'] = 'ලිපිනය වෙනස් කිරීම';\r
-$labels['edit'] = 'වෙනස් කිරීම';\r
-$labels['cancel'] = 'අවලංගු කරීම';\r
-$labels['save'] = 'තැන්පත් කිරීම';\r
-$labels['delete'] = 'මකා දැමීම';\r
-$labels['newcontact'] = 'අඵත් ලිපින පතක් සෑදීම';\r
-$labels['deletecontact'] = 'තෝරාගත් ලිපින මකා දැමන්න';\r
-$labels['composeto'] = 'පනිවුඩයක් සෑදීම';\r
-$labels['contactsfromto'] = '$from ගෙන් $to ලිපින $count';\r
-$labels['print'] = 'මුද්රණය';\r
-$labels['export'] = 'නිර්යාත';\r
-$labels['previouspage'] = 'කලින් කට්ටලය පෙන්නන්න';\r
-$labels['firstpage'] = 'පළමුවන කට්ටලය පෙන්නන්න';\r
-$labels['nextpage'] = 'මීළඟ කට්ටලය පෙන්නන්න';\r
-$labels['lastpage'] = 'අවසාන කට්ටලය පෙන්නන්න';\r
-$labels['groups'] = 'කණ්ඩායම්';\r
-$labels['personaladrbook'] = 'පොද්ගලික ලිපිනය';\r
-$labels['settingsfor'] = 'සඳහා කට්ටල අංග';\r
-$labels['preferences'] = 'අභිමතය';\r
-$labels['userpreferences'] = 'පරිශීලක අභිමතය';\r
-$labels['editpreferences'] = 'පරිශීලක අභිමතය වෙනස් කිරීම්';\r
-$labels['identities'] = 'අනන්නයතාව';\r
-$labels['manageidentities'] = 'මෙම ගිණුමෙ අනන්නයතාව හැසිරවීම';\r
-$labels['newidentity'] = 'අඵත් අනන්නයතාව';\r
-$labels['newitem'] = 'අඵත් අයිතම';\r
-$labels['edititem'] = 'අයිතම වෙනස් කිරීම්';\r
-$labels['setdefault'] = 'පළමු තත්වයට';\r
-$labels['language'] = 'භාෂාව';\r
-$labels['timezone'] = 'කාල කලාපය';\r
-$labels['pagesize'] = 'පිටුවකටඅ පේළි';\r
-$labels['signature'] = 'අත්සන';\r
-$labels['dstactive'] = 'දිවා එළිය ඉතිරි කිරීම';\r
-$labels['htmleditor'] = 'HTML පනිවුඩයක් සෑදීම';\r
-$labels['htmlsignature'] = 'HTML අත්සන';\r
-$labels['previewpane'] = 'පූර්වදර්ශන කොටස පෙන්නන්න';\r
-$labels['autosavedraft'] = 'ස්වයංක්රීයව කටු සටහනේ තැන්පත් කරන්න';\r
-$labels['everynminutes'] = 'සෑම මිනිත්තු $n';\r
-$labels['never'] = 'කිසි විටෙකත් නැති';\r
-$labels['folder'] = 'ෆෝල්ඩරය';\r
-$labels['folders'] = 'ෆෝල්ඩර';\r
-$labels['foldername'] = 'ෆෝල්ඩරයේ නම';\r
-$labels['subscribed'] = 'සාමාජික';\r
-$labels['messagecount'] = 'පනිවුඩ';\r
-$labels['create'] = 'සෑදීම';\r
-$labels['createfolder'] = 'අඵත් ෆෝල්ඩරයක් සෑදීම';\r
-$labels['rename'] = 'නැවත නම් කිරීම';\r
-$labels['renamefolder'] = 'ෆෝල්ඩරය නැවත නම් කිරීම';\r
-$labels['deletefolder'] = 'ෆෝල්ඩරය මකා දැමීම';\r
-$labels['managefolders'] = 'හැසිරවීම හැසිරවීම';\r
-$labels['sortby'] = 'චිසින් වර්ග කිරීම';\r
-$labels['sortasc'] = 'ආරෝහණ වර්ග කිරීම';\r
-$labels['sortdesc'] = 'අවරෝහණ වර්ග කිරීම';\r
-\r
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | language/si/labels.inc                                                |
+ |                                                                       |
+ | Language file of the RoundCube Webmail client                         |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Melanga Dissanayake <Melanga.Dissanayake@pabcbank.com>        |
+ +-----------------------------------------------------------------------+
+
+ @version $Id$
+
+*/
+
+$labels = array();
+$labels['welcome'] = '$product ආයුබොවන්';
+$labels['username'] = 'නම';
+$labels['password'] = 'මුරපදය';
+$labels['server'] = 'පද්ධතිය';
+$labels['login'] = 'අතුල්වීම';
+$labels['logout'] = 'පිටවීම';
+$labels['mail'] = 'විද්යුත් තැපෑල';
+$labels['settings'] = 'පොද්ගලික කට්ටල අංග';
+$labels['addressbook'] = 'ලිපින පොත';
+$labels['inbox'] = 'ඇතුල්වීම්';
+$labels['drafts'] = 'කටු සටහන්';
+$labels['sent'] = 'පිටවුම්';
+$labels['trash'] = 'ලටපට';
+$labels['junk'] = 'සුන්බුන්';
+$labels['subject'] = 'මාතෘකාව';
+$labels['from'] = 'යවන්නා';
+$labels['to'] = 'ලබන්නා';
+$labels['cc'] = 'පිටපත් කිරීම්';
+$labels['bcc'] = 'අඳ පිටපත් කිරීම්';
+$labels['replyto'] = 'පිළිතුරු සඳහා';
+$labels['date'] = 'දිනය';
+$labels['size'] = 'ප්රමාණය';
+$labels['priority'] = 'ප්රමුඛතාව';
+$labels['organization'] = 'සංවිධානය';
+$labels['reply-to'] = 'පිළිතුරු සඳහා';
+$labels['mailboxlist'] = 'ෆෝල්ඩරය';
+$labels['messagesfromto'] = '$from ගෙන් $to පනිවුඩ $count';
+$labels['messagenrof'] = 'පනිවුඩය $count න් $nr ';
+$labels['moveto'] = 'ගෙනයෑම...';
+$labels['download'] = 'බාගතකිරීම';
+$labels['filename'] = 'ගොනුවේ නම';
+$labels['filesize'] = 'ගොනුවේ ප්රමාණය';
+$labels['preferhtml'] = 'HTML විදහා පෙන්වීම';
+$labels['htmlmessage'] = 'HTML පනිවුඩය';
+$labels['prettydate'] = 'සුරුබුහුටි දින';
+$labels['addtoaddressbook'] = 'ලිපින පොතට එකතු කරන්න';
+$labels['sun'] = 'ඉරිදා';
+$labels['mon'] = 'සඳුදා';
+$labels['tue'] = 'අගහ';
+$labels['wed'] = 'බදාදා';
+$labels['thu'] = 'බ්රහස්';
+$labels['fri'] = 'සිකුරා';
+$labels['sat'] = 'සෙනසු';
+$labels['sunday'] = 'ඉරිදා';
+$labels['monday'] = 'සඳුදා';
+$labels['tuesday'] = 'අගහරුවාදා';
+$labels['wednesday'] = 'බදාදා';
+$labels['thursday'] = 'බ්රහස්පතිනිදා';
+$labels['friday'] = 'සිකුරාදා';
+$labels['saturday'] = 'සෙනසුරාදා';
+$labels['today'] = 'අද';
+$labels['checkmail'] = 'අඵත් පනිවුඩ සඳහා පිරික්සීම';
+$labels['writenewmessage'] = 'අඵත් පනිවුඩක්';
+$labels['replytomessage'] = 'පනිවුඩයට පිළිතුරු';
+$labels['replytoallmessage'] = 'එවන්නාට සහ සැමට පිළිතුරු';
+$labels['forwardmessage'] = 'පනිවුඩය ඉදිරියට';
+$labels['deletemessage'] = 'පනිවුඩය ලටපට තුලට ගෙනයන්න';
+$labels['movemessagetotrash'] = 'පණිවුඩය ලටපට වෙත ගෙන යන්න';
+$labels['printmessage'] = 'පනිවුඩය මුද්රනය කරන්න';
+$labels['previousmessage'] = 'කලින් පනිවුඩය පෙන්නන්න';
+$labels['previousmessages'] = 'කලින් පනිවුඩ කට්ටලය පෙන්නන්න';
+$labels['firstmessage'] = 'පළමුවන පනිවුඩය පෙන්නන්න';
+$labels['firstmessages'] = 'පළමුවන පනිවුඩ කට්ටලය පෙන්නන්න';
+$labels['nextmessage'] = 'මීළඟ පනිවුඩය පෙන්නන්න';
+$labels['nextmessages'] = 'මීළඟ පනිවුඩ කට්ටලය පෙන්නන්න';
+$labels['lastmessage'] = 'අවසාන පනිවුඩය පෙන්නන්න';
+$labels['lastmessages'] = 'අවසාන පනිවුඩ කට්ටලය පෙන්නන්න';
+$labels['backtolist'] = 'නැවතත් පනිවුඩ ලැයිස්තුවට';
+$labels['viewsource'] = 'මූලාශ්රය පෙන්නන්න';
+$labels['markmessages'] = 'පණිවුඩ';
+$labels['markread'] = 'කියවු ලෙස සළකුණු කරන්න';
+$labels['markunread'] = 'නොකියවු ලෙස සළකුණු කරන්න';
+$labels['select'] = 'තෝරාගන්න';
+$labels['all'] = 'සියලු';
+$labels['none'] = 'තෝරානොගත්';
+$labels['unread'] = 'නොකියවූ';
+$labels['compact'] = 'සංයුක්ත';
+$labels['empty'] = 'රික්ත';
+$labels['purge'] = 'විරේචන';
+$labels['quota'] = 'භාවිතය';
+$labels['unknown'] = 'නාඳුනන';
+$labels['unlimited'] = 'අසීමිත';
+$labels['quicksearch'] = 'ඉක්මන් සෙවුම';
+$labels['resetsearch'] = 'සෙවුම යලි පිහිටවීම';
+$labels['compose'] = 'පනිවුඩයක් සෑදීම';
+$labels['savemessage'] = 'කටු සටහනේ තැන්පත කරන්න';
+$labels['sendmessage'] = 'පනිවුඩය දැන් යවන්න';
+$labels['addattachment'] = 'ගොනුවක් ඇතුලත් කිරීම';
+$labels['charset'] = 'අකුරැ කට්ටලය';
+$labels['editortype'] = 'සම්පාදන ආකාරය';
+$labels['returnreceipt'] = 'නැවත ලබන්නා';
+$labels['checkspelling'] = 'වචන පරීක්ෂාව';
+$labels['resumeediting'] = 'සම්පාදන නැවත ඇරඹීම';
+$labels['revertto'] = 'ආපසු ඒම';
+$labels['attachments'] = 'ගොනු';
+$labels['upload'] = 'ඇතුල් කරීම';
+$labels['close'] = 'වැසීම';
+$labels['low'] = 'අඩු';
+$labels['lowest'] = 'අඩුම';
+$labels['normal'] = 'සමක';
+$labels['high'] = 'ඉහළ';
+$labels['highest'] = 'ඉහළම';
+$labels['nosubject'] = '(මාතෘකාව නොමැති)';
+$labels['showimages'] = 'රූප පෙන්නන්න';
+$labels['htmltoggle'] = 'HTML';
+$labels['plaintoggle'] = 'පැහැදිලි අකුරු';
+$labels['addcc'] = 'Cc එක් කරන්න';
+$labels['addbcc'] = 'Bcc එක් කරන්න';
+$labels['addreplyto'] = '\'පිළිතුරු සඳහා\' එක් කරන්න';
+$labels['mdnrequest'] = 'මෙම පණිවුඩය එවන්නා ඔබ එය කියවු බව අසයි. එය දැන්වීමට ඔබ කැමතිද?';
+$labels['receiptread'] = 'ලැබීම් ලදුපත (කියවීම)';
+$labels['yourmessage'] = 'මෙය ඔබගේ පණිවුඩයේ ලැබීම් ලදුපතයි';
+$labels['receiptnote'] = 'සටහන: ලැබීම් ලදුපත මගින් මෙම පණිවුඩය කියවූ බව හෝ තේරුම් ගත් බව ගම්‍ය නොවේ. පණිවුඩය ලබන්නාට පෙන්නුම් කල බවටට සාක්ෂියක් පමණි';
+$labels['name'] = 'නම පෙන්නන්න';
+$labels['firstname'] = 'පළමු නම';
+$labels['surname'] = 'අවසාන නම';
+$labels['email'] = 'ද්යුත් තැපෑල';
+$labels['addcontact'] = 'ලිපින පොතට එකතු කරන්න';
+$labels['editcontact'] = 'ලිපිනය වෙනස් කිරීම';
+$labels['edit'] = 'වෙනස් කිරීම';
+$labels['cancel'] = 'අවලංගු කරීම';
+$labels['save'] = 'තැන්පත් කිරීම';
+$labels['delete'] = 'මකා දැමීම';
+$labels['newcontact'] = 'අඵත් ලිපින පතක් සෑදීම';
+$labels['deletecontact'] = 'තෝරාගත් ලිපින මකා දැමන්න';
+$labels['composeto'] = 'පනිවුඩයක් සෑදීම';
+$labels['contactsfromto'] = '$from ගෙන් $to ලිපින $count';
+$labels['print'] = 'මුද්රණය';
+$labels['export'] = 'නිර්යාත';
+$labels['previouspage'] = 'කලින් කට්ටලය පෙන්නන්න';
+$labels['firstpage'] = 'පළමුවන කට්ටලය පෙන්නන්න';
+$labels['nextpage'] = 'මීළඟ කට්ටලය පෙන්නන්න';
+$labels['lastpage'] = 'අවසාන කට්ටලය පෙන්නන්න';
+$labels['groups'] = 'කණ්ඩායම්';
+$labels['personaladrbook'] = 'පොද්ගලික ලිපිනය';
+$labels['settingsfor'] = 'සඳහා කට්ටල අංග';
+$labels['preferences'] = 'අභිමතය';
+$labels['userpreferences'] = 'පරිශීලක අභිමතය';
+$labels['editpreferences'] = 'පරිශීලක අභිමතය වෙනස් කිරීම්';
+$labels['identities'] = 'අනන්නයතාව';
+$labels['manageidentities'] = 'මෙම ගිණුමෙ අනන්නයතාව හැසිරවීම';
+$labels['newidentity'] = 'අඵත් අනන්නයතාව';
+$labels['newitem'] = 'අඵත් අයිතම';
+$labels['edititem'] = 'අයිතම වෙනස් කිරීම්';
+$labels['setdefault'] = 'පළමු තත්වයට';
+$labels['language'] = 'භාෂාව';
+$labels['timezone'] = 'කාල කලාපය';
+$labels['pagesize'] = 'පිටුවකටඅ පේළි';
+$labels['signature'] = 'අත්සන';
+$labels['dstactive'] = 'දිවා එළිය ඉතිරි කිරීම';
+$labels['htmleditor'] = 'HTML පනිවුඩයක් සෑදීම';
+$labels['htmlsignature'] = 'HTML අත්සන';
+$labels['previewpane'] = 'පූර්වදර්ශන කොටස පෙන්නන්න';
+$labels['autosavedraft'] = 'ස්වයංක්රීයව කටු සටහනේ තැන්පත් කරන්න';
+$labels['never'] = 'කිසි විටෙකත් නැති';
+$labels['folder'] = 'ෆෝල්ඩරය';
+$labels['folders'] = 'ෆෝල්ඩර';
+$labels['foldername'] = 'ෆෝල්ඩරයේ නම';
+$labels['subscribed'] = 'සාමාජික';
+$labels['messagecount'] = 'පනිවුඩ';
+$labels['create'] = 'සෑදීම';
+$labels['createfolder'] = 'අඵත් ෆෝල්ඩරයක් සෑදීම';
+$labels['rename'] = 'නැවත නම් කිරීම';
+$labels['renamefolder'] = 'ෆෝල්ඩරය නැවත නම් කිරීම';
+$labels['deletefolder'] = 'ෆෝල්ඩරය මකා දැමීම';
+$labels['managefolders'] = 'හැසිරවීම හැසිරවීම';
+$labels['sortby'] = 'චිසින් වර්ග කිරීම';
+$labels['sortasc'] = 'ආරෝහණ වර්ග කිරීම';
+$labels['sortdesc'] = 'අවරෝහණ වර්ග කිරීම';
+
 ?>
\ No newline at end of file
index a489bcd8e9d797d53bd5b34519d40fec93768299..cfb8955a73b18eb0ab1a0f3fe2b3001c2d78b58c 100644 (file)
@@ -1,81 +1,81 @@
-<?\r
-/*\r
-\r
- +-----------------------------------------------------------------------+\r
- | language/si/messages.inc                                              |\r
- |                                                                       |\r
- | Language file of the RoundCube Webmail client                         |\r
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |\r
- | Licensed under the GNU GPL                                            |\r
- |                                                                       |\r
- +-----------------------------------------------------------------------+\r
- | Author: Melanga Dissanayake <Melanga.Dissanayake@pabcbank.com>        |\r
- +-----------------------------------------------------------------------+\r
-\r
- @version $Id$\r
-\r
-*/\r
-\r
-$messages = array();\r
-$messages['loginfailed'] = 'ඇතුල්වීම අසාර්ථකයි';\r
-$messages['cookiesdisabled'] = 'ඔබේ බෞසරය කුකී බාර ගන්නේ නැත';\r
-$messages['sessionerror'] = 'ඔබේ වාරය අවලංගු හෝ කාලය ඉකුත් වී ඇත';\r
-$messages['imaperror'] = 'IMAP සම්බන්ධතාවය අසාර්ථකයි';\r
-$messages['nomessagesfound'] = 'ලියුම් පෙට්ටියේ පනිවුඩ නැත';\r
-$messages['loggedout'] = 'ඔබගේ වාරය සාර්ථකව අවසන් විය. අයුබොවන්!';\r
-$messages['mailboxempty'] = 'ලියුම් පෙට්ටිය හිස්';\r
-$messages['loading'] = 'පූරනය...';\r
-$messages['loadingdata'] = 'දත්ත පූරනය...';\r
-$messages['checkingmail'] = 'අලුත් පනිවුඩ පරීක්ෂා කිරීම...';\r
-$messages['sendingmessage'] = 'පනිවුඩය යැවීම...';\r
-$messages['messagesent'] = 'පනිවුඩය සාර්ථකව යවන ලදී';\r
-$messages['savingmessage'] = 'පනිවුඩය තැන්පත් කීරීම...';\r
-$messages['messagesaved'] = 'පනිවුඩය කටු සටහනේ තැන්පත් විය';\r
-$messages['successfullysaved'] = 'සාර්ථකව තැන්පත විය';\r
-$messages['addedsuccessfully'] = 'ලිපිනය සාර්ථකව ලිපින පොතට එකතු කරන ලදී';\r
-$messages['contactexists'] = 'ඉහත ලිපිනය සහිත විද්යුත් තැපැල් ලිපිනයක් ලිපින පොතේ ඇත';\r
-$messages['blockedimages'] = 'ඔබගෙ පොද්ගලිකත්වය හේතුවෙන්, දුරස්ථ රූප අවහිර කර ඇත.';\r
-$messages['encryptedmessage'] = 'මෙම පනිවුඩය රහස් කේතනය කර ඇති බැවින් පෙන්විය නොහැක. සමාවන්න!';\r
-$messages['nocontactsfound'] = 'ලිපින සොයා ගත නොහැක';\r
-$messages['contactnotfound'] = 'ඉල්ලූ ලිපිනය සොයාගත නොහැක';\r
-$messages['sendingfailed'] = 'පනිවුඩය යැවීම අසාර්ථකයි';\r
-$messages['errorsaving'] = 'පනිවුඩය තැන්පත් කීරීමේදී දොෂයක් සිදු විය';\r
-$messages['errormoving'] = 'පනිවුඩය ගෙන යාමට නොහැක';\r
-$messages['errordeleting'] = 'පනිවුඩය මකා දැමීමට නොහැක';\r
-$messages['deletecontactconfirm'] = 'තෝරා ඇති ලිපින ඔබට මකා දැමීමට සැබවින්ම වුවමනාද?';\r
-$messages['deletemessagesconfirm'] = 'තෝරා ඇත පනිවුඩ ඔබට මකා දැමීමට සැබවින්ම වුවමනාද?';\r
-$messages['deletefolderconfirm'] = 'ෆෝල්ඩරය මකා දැමීමට සැබවින්ම වුවමනාද?';\r
-$messages['purgefolderconfirm'] = 'මෙම ෆෝල්ඩරයේ ඇති සියලුම පනිවුඩ ඔබට මකා දැමීමට සැබවින්ම වුවමනාද?';\r
-$messages['formincomplete'] = 'පෝරමය සම්පූර්ණයෙන් පුරවා නොමැත';\r
-$messages['noemailwarning'] = 'කරුණාකර වලංගු විද්යුත් තැපැල් ලිපිනයක් ඇතුලත් කරන්න';\r
-$messages['nonamewarning'] = 'කරුණාකර නම ඇතුලත් කරන්න';\r
-$messages['nopagesizewarning'] = 'කරුණාකර පිටුවේ ප්රමානය ඇතුලත් කරන්න';\r
-$messages['norecipientwarning'] = 'කරුණාකර යටත් පිරිසෙයින් එක් ලබන්නෙකු හෝ ඇතුලත් කරන්න';\r
-$messages['nosubjectwarning'] = '"මාතෘකාව" හිස්. මාතෘකාවක් අතුලත් කිරීමට ඔබ කැමතිද?';\r
-$messages['nobodywarning'] = 'මෙම හිස් පනිවුඩය යවන්නද?';\r
-$messages['notsentwarning'] = 'පනිවුඩය යැවීමට නොහැකි විය. ඔබට එය බැහැර කිරීමට වුවමනාද?';\r
-$messages['noldapserver'] = 'සෙවුම සඳහා කරුණාකර ldap සම්බන්ධතාවයක් තෝරා ගන්න';\r
-$messages['nocontactsreturned'] = 'ලිපින/ය සොයා ගත නොහැක';\r
-$messages['nosearchname'] = 'කරුණාකර ලිපිනයෙහි නම හෝ විද්යුත් තැපැල් ලිපිනය ඇතුලත් කරන්න';\r
-$messages['searchsuccessful'] = '$nr පනිවුඩය හමු විය';\r
-$messages['searchnomatch'] = 'සෙවුමට අදාල ගැලපීමක් නොමැත';\r
-$messages['searching'] = 'සොයමින් පවතී...';\r
-$messages['checking'] = 'පිරික්සමින් පවතී...';\r
-$messages['nospellerrors'] = 'වියාකරන දොෂ නොමැත';\r
-$messages['folderdeleted'] = 'ෆෝල්ඩරය සාර්ථකව මකා දමන ලදී';\r
-$messages['deletedsuccessfully'] = 'සාර්ථකව මකා දමන ලදී';\r
-$messages['converting'] = 'පනිවුඩයෙන් ආකෘතීකරණය ඉවත් කිරීම';\r
-$messages['messageopenerror'] = 'පනිවුඩය පූරනය කිරීමට නොහැක';\r
-$messages['fileuploaderror'] = 'ගොනුව ඇතුලත් කිරීමට නොහැක';\r
-$messages['filesizeerror'] = 'ඇතුලත් කල ගොනුවෙ ප්රමාණය උපරිම අගය $size ඉක්මවා ඇත';\r
-$messages['copysuccess'] = '$nr ලිපිනය සාර්ථකව පිටපත් කරන ලදී';\r
-$messages['copyerror'] = 'කවර ලිපිනයක්වත් හෝ පිටපත් කල නොහැක';\r
-$messages['sourceisreadonly'] = 'මෙම ලිපින මූලාශ්රය කියවීම සඳහා පමනි';\r
-$messages['errorsavingcontact'] = 'ලිපිනය තැන්පත් කීරීමට නොහැක';\r
-$messages['movingmessage'] = 'පනිවුඩය ගෙනයමින් පවතී...';\r
-$messages['receiptsent'] = 'කියවීම් භාර ගැනීම සාර්ථකව යවන ලදී';\r
-$messages['errorsendingreceipt'] = 'කියවීම් භාර ගැනීම යැවීමට නොහැක';\r
-$messages['nodeletelastidentity'] = 'අවසාන අනන්‍යතාවය මකා දැමිය නොහැක';\r
-$messages['addsubfolderhint'] = 'ෆෝල්ඩරය දැනට තෝරාගෙන ඇති ෆෝල්ඩරයෙහි අනු ෆෝල්ඩරයක් ලෙස සෑදේ';\r
-\r
-?>
\ No newline at end of file
+<?php
+/*
+
+ +-----------------------------------------------------------------------+
+ | language/si/messages.inc                                              |
+ |                                                                       |
+ | Language file of the RoundCube Webmail client                         |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Melanga Dissanayake <Melanga.Dissanayake@pabcbank.com>        |
+ +-----------------------------------------------------------------------+
+
+ @version $Id$
+
+*/
+
+$messages = array();
+$messages['loginfailed'] = 'ඇතුල්වීම අසාර්ථකයි';
+$messages['cookiesdisabled'] = 'ඔබේ බෞසරය කුකී බාර ගන්නේ නැත';
+$messages['sessionerror'] = 'ඔබේ වාරය අවලංගු හෝ කාලය ඉකුත් වී ඇත';
+$messages['imaperror'] = 'IMAP සම්බන්ධතාවය අසාර්ථකයි';
+$messages['nomessagesfound'] = 'ලියුම් පෙට්ටියේ පනිවුඩ නැත';
+$messages['loggedout'] = 'ඔබගේ වාරය සාර්ථකව අවසන් විය. අයුබොවන්!';
+$messages['mailboxempty'] = 'ලියුම් පෙට්ටිය හිස්';
+$messages['loading'] = 'පූරනය...';
+$messages['loadingdata'] = 'දත්ත පූරනය...';
+$messages['checkingmail'] = 'අලුත් පනිවුඩ පරීක්ෂා කිරීම...';
+$messages['sendingmessage'] = 'පනිවුඩය යැවීම...';
+$messages['messagesent'] = 'පනිවුඩය සාර්ථකව යවන ලදී';
+$messages['savingmessage'] = 'පනිවුඩය තැන්පත් කීරීම...';
+$messages['messagesaved'] = 'පනිවුඩය කටු සටහනේ තැන්පත් විය';
+$messages['successfullysaved'] = 'සාර්ථකව තැන්පත විය';
+$messages['addedsuccessfully'] = 'ලිපිනය සාර්ථකව ලිපින පොතට එකතු කරන ලදී';
+$messages['contactexists'] = 'ඉහත ලිපිනය සහිත විද්යුත් තැපැල් ලිපිනයක් ලිපින පොතේ ඇත';
+$messages['blockedimages'] = 'ඔබගෙ පොද්ගලිකත්වය හේතුවෙන්, දුරස්ථ රූප අවහිර කර ඇත.';
+$messages['encryptedmessage'] = 'මෙම පනිවුඩය රහස් කේතනය කර ඇති බැවින් පෙන්විය නොහැක. සමාවන්න!';
+$messages['nocontactsfound'] = 'ලිපින සොයා ගත නොහැක';
+$messages['contactnotfound'] = 'ඉල්ලූ ලිපිනය සොයාගත නොහැක';
+$messages['sendingfailed'] = 'පනිවුඩය යැවීම අසාර්ථකයි';
+$messages['errorsaving'] = 'පනිවුඩය තැන්පත් කීරීමේදී දොෂයක් සිදු විය';
+$messages['errormoving'] = 'පනිවුඩය ගෙන යාමට නොහැක';
+$messages['errordeleting'] = 'පනිවුඩය මකා දැමීමට නොහැක';
+$messages['deletecontactconfirm'] = 'තෝරා ඇති ලිපින ඔබට මකා දැමීමට සැබවින්ම වුවමනාද?';
+$messages['deletemessagesconfirm'] = 'තෝරා ඇත පනිවුඩ ඔබට මකා දැමීමට සැබවින්ම වුවමනාද?';
+$messages['deletefolderconfirm'] = 'ෆෝල්ඩරය මකා දැමීමට සැබවින්ම වුවමනාද?';
+$messages['purgefolderconfirm'] = 'මෙම ෆෝල්ඩරයේ ඇති සියලුම පනිවුඩ ඔබට මකා දැමීමට සැබවින්ම වුවමනාද?';
+$messages['formincomplete'] = 'පෝරමය සම්පූර්ණයෙන් පුරවා නොමැත';
+$messages['noemailwarning'] = 'කරුණාකර වලංගු විද්යුත් තැපැල් ලිපිනයක් ඇතුලත් කරන්න';
+$messages['nonamewarning'] = 'කරුණාකර නම ඇතුලත් කරන්න';
+$messages['nopagesizewarning'] = 'කරුණාකර පිටුවේ ප්රමානය ඇතුලත් කරන්න';
+$messages['norecipientwarning'] = 'කරුණාකර යටත් පිරිසෙයින් එක් ලබන්නෙකු හෝ ඇතුලත් කරන්න';
+$messages['nosubjectwarning'] = '"මාතෘකාව" හිස්. මාතෘකාවක් අතුලත් කිරීමට ඔබ කැමතිද?';
+$messages['nobodywarning'] = 'මෙම හිස් පනිවුඩය යවන්නද?';
+$messages['notsentwarning'] = 'පනිවුඩය යැවීමට නොහැකි විය. ඔබට එය බැහැර කිරීමට වුවමනාද?';
+$messages['noldapserver'] = 'සෙවුම සඳහා කරුණාකර ldap සම්බන්ධතාවයක් තෝරා ගන්න';
+$messages['nocontactsreturned'] = 'ලිපින/ය සොයා ගත නොහැක';
+$messages['nosearchname'] = 'කරුණාකර ලිපිනයෙහි නම හෝ විද්යුත් තැපැල් ලිපිනය ඇතුලත් කරන්න';
+$messages['searchsuccessful'] = '$nr පනිවුඩය හමු විය';
+$messages['searchnomatch'] = 'සෙවුමට අදාල ගැලපීමක් නොමැත';
+$messages['searching'] = 'සොයමින් පවතී...';
+$messages['checking'] = 'පිරික්සමින් පවතී...';
+$messages['nospellerrors'] = 'වියාකරන දොෂ නොමැත';
+$messages['folderdeleted'] = 'ෆෝල්ඩරය සාර්ථකව මකා දමන ලදී';
+$messages['deletedsuccessfully'] = 'සාර්ථකව මකා දමන ලදී';
+$messages['converting'] = 'පනිවුඩයෙන් ආකෘතීකරණය ඉවත් කිරීම';
+$messages['messageopenerror'] = 'පනිවුඩය පූරනය කිරීමට නොහැක';
+$messages['fileuploaderror'] = 'ගොනුව ඇතුලත් කිරීමට නොහැක';
+$messages['filesizeerror'] = 'ඇතුලත් කල ගොනුවෙ ප්රමාණය උපරිම අගය $size ඉක්මවා ඇත';
+$messages['copysuccess'] = '$nr ලිපිනය සාර්ථකව පිටපත් කරන ලදී';
+$messages['copyerror'] = 'කවර ලිපිනයක්වත් හෝ පිටපත් කල නොහැක';
+$messages['sourceisreadonly'] = 'මෙම ලිපින මූලාශ්රය කියවීම සඳහා පමනි';
+$messages['errorsavingcontact'] = 'ලිපිනය තැන්පත් කීරීමට නොහැක';
+$messages['movingmessage'] = 'පනිවුඩය ගෙනයමින් පවතී...';
+$messages['receiptsent'] = 'කියවීම් භාර ගැනීම සාර්ථකව යවන ලදී';
+$messages['errorsendingreceipt'] = 'කියවීම් භාර ගැනීම යැවීමට නොහැක';
+$messages['nodeletelastidentity'] = 'අවසාන අනන්‍යතාවය මකා දැමිය නොහැක';
+$messages['addsubfolderhint'] = 'ෆෝල්ඩරය දැනට තෝරාගෙන ඇති ෆෝල්ඩරයෙහි අනු ෆෝල්ඩරයක් ලෙස සෑදේ';
+
+?>
index 34bcbaacc27793fa09aa50c365305a0d1a7fa58e..03f8b762123265b22da096786a7edc0099d4d69f 100644 (file)
@@ -15,7 +15,7 @@
 |         Peter Mann   <peter.mann@tuke.sk>                             |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -227,7 +227,6 @@ $labels['flagfordeletion'] = 'Pri odstránení správy iba označiť správu ako
 $labels['skipdeleted'] = 'Nezobrazovať zmazané správy';
 $labels['showinlineimages'] = 'Zobraziť pripojené obrázky pod správou';
 $labels['autosavedraft'] = 'Automaticky uložiť koncept';
-$labels['everynminutes'] = 'každých $n minút';
 $labels['keepalive'] = 'Kontrolovať nové správy';
 $labels['never'] = 'nikdy';
 $labels['messagesdisplaying'] = 'Zobrazovanie správ';
index 9ec706ee145090b4f9c359fdf739e1cb3d8e353b..750e284705ca460e853a09a176dad18cfa3200ac 100644 (file)
 +-----------------------------------------------------------------------+
 | Author: Andrej Sossi <asossi@dotcom.ts.it>                            |
 |         Andrej Mocilnik <amocilnik@dotcom.ts.it>                      |
+|         Barbara Krasovec <barbarak@arnes.si>                          |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
@@ -69,41 +70,78 @@ $labels['wednesday'] = 'Sreda';
 $labels['thursday'] = 'Četrtek';
 $labels['friday'] = 'Petek';
 $labels['saturday'] = 'Sobota';
+$labels['jan'] = 'Jan';
+$labels['feb'] = 'Feb';
+$labels['mar'] = 'Mar';
+$labels['apr'] = 'Apr';
+$labels['may'] = 'Maj';
+$labels['jun'] = 'Jun';
+$labels['jul'] = 'Jul';
+$labels['aug'] = 'Avg';
+$labels['sep'] = 'Sep';
+$labels['oct'] = 'Okt';
+$labels['nov'] = 'Nov';
+$labels['dec'] = 'Dec';
+$labels['longjan'] = 'Januar';
+$labels['longfeb'] = 'Februar';
+$labels['longmar'] = 'Marec';
+$labels['longapr'] = 'April';
+$labels['longmay'] = 'Maj';
+$labels['longjun'] = 'Junij';
+$labels['longjul'] = 'Julij';
+$labels['longaug'] = 'Avgust';
+$labels['longsep'] = 'September';
+$labels['longoct'] = 'Oktober';
+$labels['longnov'] = 'November';
+$labels['longdec'] = 'December';
 $labels['today'] = 'Danes';
 $labels['checkmail'] = 'Preglej nova sporočila';
 $labels['writenewmessage'] = 'Novo sporočilo';
-$labels['replytomessage'] = 'Odgovori na sporočilo';
-$labels['replytoallmessage'] = 'Odgovori pošiljatelju in vsem prejemnikom';
-$labels['forwardmessage'] = 'Posreduj sporočilo';
-$labels['deletemessage'] = 'Premakni sporočilo v smeti';
-$labels['movemessagetotrash'] = 'Premakni v smetnjak';
-$labels['printmessage'] = 'Natisni to sporočilo';
+$labels['replytomessage'] = 'Odgovori';
+$labels['replytoallmessage'] = 'Odgovori vsem';
+$labels['forwardmessage'] = 'Posreduj';
+$labels['deletemessage'] = 'Izbriši';
+$labels['movemessagetotrash'] = 'Premakni v smeti';
+$labels['printmessage'] = 'Natisni';
 $labels['previousmessage'] = 'Prikaži prejšnje sporočilo';
 $labels['previousmessages'] = 'Prikaži prejšnja sporočila';
 $labels['firstmessage'] = 'Prikaži prvo sporočilo';
 $labels['firstmessages'] = 'Prikaži prva sporočila';
-$labels['nextmessage'] = 'Prikaži naslednjo sporočilo';
+$labels['nextmessage'] = 'Prikaži naslednje sporočilo';
 $labels['nextmessages'] = 'Prikaži naslednja sporočila';
-$labels['lastmessage'] = 'Prikaži zadnjo sporočilo';
+$labels['lastmessage'] = 'Prikaži zadnje sporočilo';
 $labels['lastmessages'] = 'Prikaži zadnja sporočila';
 $labels['backtolist'] = 'Nazaj na seznam sporočil';
 $labels['viewsource'] = 'Prikaži izvirno kodo';
 $labels['markmessages'] = 'Označi sporočilo';
 $labels['markread'] = 'Kot prebrano';
 $labels['markunread'] = 'Kot neprebrano';
+$labels['markflagged'] = 'Kot označeno';
+$labels['markunflagged'] = 'Kot neoznačeno';
+$labels['messageactions'] = 'Več možnosti';
 $labels['select'] = 'Izberi';
 $labels['all'] = 'Vse';
-$labels['none'] = 'Nobenih';
+$labels['none'] = 'Ničesar';
 $labels['unread'] = 'Neprebrano';
+$labels['flagged'] = 'Označeno';
+$labels['unanswered'] = 'Neoznačeno';
+$labels['deleted'] = 'Izbrisano';
+$labels['invert'] = 'Zamenjaj';
+$labels['filter'] = 'Prikaži';
 $labels['compact'] = 'Stisni';
 $labels['empty'] = 'Izprazni';
 $labels['purge'] = 'Počisti';
-$labels['quota'] = 'Poraba diska';
+$labels['quota'] = 'Poraba prostora';
 $labels['unknown'] = 'neznana';
 $labels['unlimited'] = 'neomejena';
 $labels['quicksearch'] = 'Hitri iskalnik';
 $labels['resetsearch'] = 'Prekliči iskanje';
+$labels['searchmod'] = 'Spremembe iskanja';
+$labels['msgtext'] = 'Celotno sporočilo';
+$labels['openinextwin'] = 'Odpri v novem oknu';
+$labels['emlsave'] = 'Prenos datoteke(.eml)';
 $labels['compose'] = 'Sestavi sporočilo';
+$labels['editasnew'] = 'Uredi kot novo';
 $labels['savemessage'] = 'Shrani kot osnutek';
 $labels['sendmessage'] = 'Pošlji sporočilo zdaj';
 $labels['addattachment'] = 'Pripni datoteko';
@@ -123,15 +161,19 @@ $labels['high'] = 'Visoka';
 $labels['highest'] = 'Najvišja';
 $labels['nosubject'] = '(brez naslova)';
 $labels['showimages'] = 'Prikaži slike';
+$labels['alwaysshow'] = 'Vedno prikaži slike od $sender';
 $labels['htmltoggle'] = 'Obogateno besedilo (HTML)';
 $labels['plaintoggle'] = 'Samo besedilo';
+$labels['savesentmessagein'] = 'Shrani poslana sporočila v';
+$labels['dontsave'] = 'Ne shrani';
+$labels['maxuploadsize'] = 'Največja dovoljena velikost datoteke je $size';
 $labels['addcc'] = 'Dodaj Kp';
 $labels['addbcc'] = 'Dodaj Skp';
 $labels['addreplyto'] = 'Dodaj naslov za odgovor';
-$labels['mdnrequest'] = 'Pošiljatelj tega sporočila je zaprosil za portdilo, ko vi preberete to sporočilo. Hočete poslati obvestilo?';
-$labels['receiptread'] = 'Potrdilo o prebranem sporočilu';
-$labels['yourmessage'] = 'To je potrdilo, da je bilo vaše sporočilo prebrano';
-$labels['receiptnote'] = 'Pozor: to je samo potrdilo, da vaše sporočilo je bilo prikazano na prejemnikovem računalniku. To še ne pomeni, da je prejemnik prebral ali razumel vsebino vašega sporočila.';
+$labels['mdnrequest'] = 'Pošiljatelj tega sporočila je zaprosil za potrdilo o branju. Želite o tem obvestiti pošiljatelja?';
+$labels['receiptread'] = 'Potrdilo o branju';
+$labels['yourmessage'] = 'To je potrdilo o branju.';
+$labels['receiptnote'] = 'Pozor: to je samo potrdilo, da je bilo vaše sporočilo prikazano na prejemnikovem računalniku. To še ne pomeni, da je prejemnik prebral ali razumel vsebino vašega sporočila.';
 $labels['name'] = 'Ime za prikaz';
 $labels['firstname'] = 'Ime';
 $labels['surname'] = 'Priimek';
@@ -148,12 +190,19 @@ $labels['composeto'] = 'Sestavi sporočilo za';
 $labels['contactsfromto'] = 'Vizitke $from od $to do $count';
 $labels['print'] = 'Natisni';
 $labels['export'] = 'Izvozi';
+$labels['exportvcards'] = 'Izvozi stike v  formatu vCard';
 $labels['previouspage'] = 'Prejšnja stran';
 $labels['firstpage'] = 'Prva stran';
 $labels['nextpage'] = 'Naslednja stran';
 $labels['lastpage'] = 'Zadnja stran';
 $labels['groups'] = 'Skupine';
 $labels['personaladrbook'] = 'Osebni Stiki';
+$labels['import'] = 'Uvozi';
+$labels['importcontacts'] = 'Uvozi stike';
+$labels['importfromfile'] = 'Uvozi iz datoteke:';
+$labels['importreplace'] = 'Zamenjaj celoten imenik';
+$labels['importtext'] = 'Stike lahko prenesete iz obstoječega imenika<br/> Trenutno je podprto uvažanje naslovov v  formatu <a href="http://en.wikipedia.org/wiki/VCard">vCard</a>';
+$labels['done'] = 'Dokončano';
 $labels['settingsfor'] = 'Nastavitve za';
 $labels['preferences'] = 'Nastavitve';
 $labels['userpreferences'] = 'Uporabniške nastavitve';
@@ -164,17 +213,51 @@ $labels['newidentity'] = 'Nova identiteta';
 $labels['newitem'] = 'Nov predmet';
 $labels['edititem'] = 'Uredi predmet';
 $labels['setdefault'] = 'Nastavi privzeto';
+$labels['autodetect'] = 'Samodejno';
 $labels['language'] = 'Jezik';
 $labels['timezone'] = 'Časovni pas';
 $labels['pagesize'] = 'Vrstic na stran';
 $labels['signature'] = 'Podpis';
-$labels['dstactive'] = 'Avtomatična nastavitev sončne/legalne ure';
+$labels['dstactive'] = 'Samodejna nastavitev sončne/legalne ure';
 $labels['htmleditor'] = 'Sestavi sporočila z obogatenim besedilom';
 $labels['htmlsignature'] = 'Podpis z obogatenim besedilom';
 $labels['previewpane'] = 'Prikaži predogled';
-$labels['autosavedraft'] = 'Avtomatično shrani osnutke';
-$labels['everynminutes'] = 'vsakih $n minut';
+$labels['skin'] = 'Tema uporabniškega vmesnika';
+$labels['logoutclear'] = 'Izprazni mapo Smeti ob odjavi';
+$labels['logoutcompact'] = 'Stisni sporočila v mapi Inbox ob odjavi';
+$labels['uisettings'] = 'Uporabniški vmesnik';
+$labels['serversettings'] = 'Nastavitve strežnika';
+$labels['mailboxview'] = 'Pogled poštnega predala';
+$labels['mdnrequests'] = 'Obvestila pošiljatelja';
+$labels['askuser'] = 'vprašaj uporabnika';
+$labels['autosend'] = 'pošlji samodejno';
+$labels['ignore'] = 'ne upoštevaj';
+$labels['readwhendeleted'] = 'Označi izbrisano sporočilo kot prebrano';
+$labels['flagfordeletion'] = 'Ne izbriši sporočila, le označi kot izbrisano';
+$labels['skipdeleted'] = 'Ne prikaži izbrisanih sporočil';
+$labels['showremoteimages'] = 'Prikaži medvrstične slike';
+$labels['fromknownsenders'] = 'od znanih pošiljateljev';
+$labels['always'] = 'vedno';
+$labels['showinlineimages'] = 'Prikaži priponke na dnu sporočila';
+$labels['autosavedraft'] = 'Samodejno shrani osnutke';
+$labels['everynminutes'] = '$n minut';
+$labels['keepalive'] = 'Preglej nova sporočila na';
 $labels['never'] = 'nikoli';
+$labels['messagesdisplaying'] = 'Prikazovanje sporočil';
+$labels['messagescomposition'] = 'Sestavljanje sporočil';
+$labels['mimeparamfolding'] = 'Imena priponk';
+$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Full RFC 2047 (ostali)';
+$labels['advancedoptions'] = 'Dodatne možnosti';
+$labels['focusonnewmessage'] = 'Usmeri okno brskalnika na novo sporočilo';
+$labels['checkallfolders'] = 'Preglej nova sporočila za vse mape';
+$labels['displaynext'] = 'Po izbrisu/premikanju sporočila prikaži naslednje sporočilo';
+$labels['mainoptions'] = 'Osnovne nastavitve';
+$labels['section'] = 'Razdelek';
+$labels['maintenance'] = 'Vzdrževanje';
+$labels['newmessage'] = 'Novo sporočilo';
+$labels['listoptions'] = 'Prikaži seznam možnosti';
 $labels['folder'] = 'Mapa';
 $labels['folders'] = 'Mape';
 $labels['foldername'] = 'Ime mape';
@@ -185,9 +268,14 @@ $labels['createfolder'] = 'Ustvari novo mapo';
 $labels['rename'] = 'Preimenuj';
 $labels['renamefolder'] = 'Preimenuj mapo';
 $labels['deletefolder'] = 'Izbriši mapo';
-$labels['managefolders'] = 'Urejaj mape';
+$labels['managefolders'] = 'Uredi mape';
+$labels['specialfolders'] = 'Posebne mape';
 $labels['sortby'] = 'Uredi po';
 $labels['sortasc'] = 'Uredi naraščajoče';
 $labels['sortdesc'] = 'Uredi padajoče';
+$labels['B'] = 'B';
+$labels['KB'] = 'KB';
+$labels['MB'] = 'MB';
+$labels['GB'] = 'GB';
 
 ?>
index 448a5104aff41325aaf082d55ea8108309d93f07..ff1991d9535be6994e914bad23c7d1aeadc3eecb 100644 (file)
 <?php
 
 /*
-
 +-----------------------------------------------------------------------+
-| language/sl/messages.inc                                              |
+| language/_NEW_/messages.inc                                           |
 |                                                                       |
 | Language file of the RoundCube Webmail client                         |
-| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Copyright (C) 2008, RoundQube Dev. - Switzerland                      |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Andrej Sossi <asossi@dotcom.ts.it>                            |
-|         Andrej Mocilnik <amocilnik@dotcom.ts.it>                      |
+| Author:   Barbara Krasovec -  barbarak@arnes.si                                                            |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
-
 */
 
 $messages = array();
-$messages['loginfailed'] = 'Prijava neuspešna';
-$messages['cookiesdisabled'] = 'Vaš brskalnik nima omogočenih piškotov';
-$messages['sessionerror'] = 'Vaša seja je napačna oz. potekla';
-$messages['imaperror'] = 'Povezava na IMAP strežnik neuspešna';
-$messages['nomessagesfound'] = 'Ni sporočil';
-$messages['loggedout'] = 'Uspešno ste zaključili sejo. Nasvidenje!';
-$messages['mailboxempty'] = 'Nabiralnik je prazen';
-$messages['loading'] = 'Nalagam...';
-$messages['loadingdata'] = 'Nalagam podatke...';
-$messages['checkingmail'] = 'Iščem nova sporočila...';
-$messages['sendingmessage'] = 'Pošiljam sporočilo...';
-$messages['messagesent'] = 'Sporočilo uspešno poslano';
-$messages['savingmessage'] = 'Shranjujem sporočilo';
-$messages['messagesaved'] = 'Sporočilo shranjeno v osnutke';
-$messages['successfullysaved'] = 'Uspešno shranjeno';
-$messages['addedsuccessfully'] = 'Vizitka uspešno dodana';
-$messages['contactexists'] = 'Vizitka s tem e-naslovom že obstaja!';
-$messages['blockedimages'] = 'Zaradi vaše varnosti slike v tem sporočilu niso prikazane.';
-$messages['encryptedmessage'] = 'To je zaščiteno sporočilo, na žalost ne more biti prikazano. Oprostite!';
-$messages['nocontactsfound'] = 'Ne najdem nobene vizitke';
-$messages['contactnotfound'] = 'Ne najdem iskane vizitke';
-$messages['sendingfailed'] = 'Pošiljanje sporočila neuspešno';
-$messages['errorsaving'] = 'Pri shranjevanju je prišlo do napake';
-$messages['errormoving'] = 'Ne morem premakniti sporočila';
-$messages['errordeleting'] = 'Ne morem izbrisati sporočila';
-$messages['deletecontactconfirm'] = 'Želite zbrisati izbrane vizitke?';
-$messages['deletemessagesconfirm'] = 'Želite zbrisati izbrana sporočila?';
-$messages['deletefolderconfirm'] = 'Želite zbrisati to mapo?';
-$messages['purgefolderconfirm'] = 'Želite zbrisati vsa sporočila v tej mapi?';
-$messages['formincomplete'] = 'Obrazec ni bil izpolnjen v celoti';
-$messages['noemailwarning'] = 'Prosim vpišite veljaven e-naslov';
-$messages['nonamewarning'] = 'Prosim vpišite ime';
-$messages['nopagesizewarning'] = 'Prosim vpišite velikost strani';
-$messages['norecipientwarning'] = 'Prosim vpišite vsaj enega naslovnika';
-$messages['nosubjectwarning'] = 'Polje "Naslov" je prazno. Ali ga želite vpisati zdaj?';
-$messages['nobodywarning'] = 'Pošlji to sporočilo brez besedila?';
-$messages['notsentwarning'] = 'Sporočilo ni bilo poslano. Želite opustiti vaše sporočilo?';
-$messages['noldapserver'] = 'Prosim izberite ldap strežnik za iskanje';
-$messages['nocontactsreturned'] = 'Ne najdem vizitk';
-$messages['nosearchname'] = 'Prosim vpišite ime ali e-naslov stika';
-$messages['searchsuccessful'] = 'Število dobljenih sporočil: $nr';
-$messages['searchnomatch'] = 'Iskanje ni doprineslo nobenega rezultata';
-$messages['searching'] = 'Iščem...';
-$messages['checking'] = 'Previrjam...';
-$messages['nospellerrors'] = 'Ni pravopisnih napak';
-$messages['folderdeleted'] = 'Mapa uspešno zbrisana';
-$messages['deletedsuccessfully'] = 'Uspešno zbrisano';
-$messages['converting'] = 'Brišem obogatitev besedila...';
-$messages['messageopenerror'] = 'Neuspešno nalaganje sporočila s stežnika';
-$messages['fileuploaderror'] = 'Neuspešno nalaganje datoteke';
-$messages['filesizeerror'] = 'Naložena datoteka presega maksimalno velikost $size';
-$messages['copysuccess'] = 'Število prepisanih naslovov: $nr';
-$messages['copyerror'] = 'Ne morem prepisati nobenega naslova';
-$messages['sourceisreadonly'] = 'Izvirnik naslova je samo berljiv';
-$messages['errorsavingcontact'] = 'Ne morem shraniti vizitke';
-$messages['movingmessage'] = 'Premakni besedilo...';
-$messages['receiptsent'] = 'Potrdilo o prebranem sporočilu je bilo uspešno poslano';
-$messages['errorsendingreceipt'] = 'Nemogoče poslati potrdilo o prebranem sporočilu';
-$messages['nodeletelastidentity'] = 'Nemogoče zbrisati identitete. Ta je edina, ki imate.';
-$messages['addsubfolderhint'] = 'Mapa bo narejena kot podmapa trenutno izbrane mape';
+$messages['loginfailed'] = 'Prijava ni uspela';
+$messages['cookiesdisabled'] = 'Vaš spletni brskalnik ne sprejema piškotkov.';
+$messages['sessionerror'] = 'Seja je neveljavna ali je potekla.';
+$messages['imaperror'] = 'Povzava z IMAP strežnikom je spodletela.';
+$messages['servererror'] = 'Napaka strežnika!';
+$messages['invalidrequest'] = 'Neveljavna zahteva. Podatki niso bili shranjeni.';
+$messages['nomessagesfound'] = 'V poštnem predalu ni sporočil.';
+$messages['loggedout'] = 'Odjava je bila uspešna.';
+$messages['mailboxempty'] = 'Poštni predal je prazen.';
+$messages['loading'] = 'Nalaganje...';
+$messages['loadingdata'] = 'Nalaganje podatkov...';
+$messages['checkingmail'] = 'Preverjanje novih sporočil...';
+$messages['sendingmessage'] = 'Pošiljanje sporočil...';
+$messages['messagesent'] = 'Sporočilo je bilo uspešno poslano.';
+$messages['savingmessage'] = 'Shranjevanje sporočila...';
+$messages['messagesaved'] = 'Sporočilo je bilo shranjeno v Osnutke';
+$messages['successfullysaved'] = 'Uspešno shranjeno.';
+$messages['addedsuccessfully'] = 'Stik je bil uspešno dodan v imenik.';
+$messages['contactexists'] = 'Stik s tem elektronskim naslovom že obstaja.';
+$messages['blockedimages'] = 'Zaradi zaščite zasebnosti je prikaz slik v sporočilu onemogočen.';
+$messages['encryptedmessage'] = 'Sporočilo je šifrirano in ne more biti prikazano.';
+$messages['nocontactsfound'] = 'Nobenega stika ni bilo mogoče najti.';
+$messages['contactnotfound'] = 'Iskanega stika ni bilo mogoče najti.';
+$messages['sendingfailed'] = 'Sporočila ni bilo mogoče poslati.';
+$messages['senttooquickly'] = 'Počakajte $sek sekund in nato znova poskusite s pošiljanjem sporočila.';
+$messages['errorsavingsent'] = 'Pri shranjevanju poslanega sporočila je prišlo do napake.';
+$messages['errorsaving'] = 'Pri shranjevanju je prišlo do napake.';
+$messages['errormoving'] = 'Sporočila ni bilo mogoče premakniti.';
+$messages['errordeleting'] = 'Sporočila ni bilo mogoče izbrisati.';
+$messages['errormarking'] = 'Sporočila ni bilo mogoče označiti.';
+$messages['deletecontactconfirm'] = 'Ste prepričani, da želite izbrisati označen(e) stik(e)?';
+$messages['deletemessagesconfirm'] = 'Ste prepričani, da želite izbrisati označeno(a) sporočilo(a)?';
+$messages['deletefolderconfirm'] = 'Ste prepričani, da želite to mapo izbrisati?';
+$messages['purgefolderconfirm'] = 'Ste prepričani, da želite izbrisati vsa sporočila v mapi?';
+$messages['foldercreating'] = 'Ustvarjanje mape...';
+$messages['folderdeleting'] = 'Brisanje mape...';
+$messages['folderrenaming'] = 'Preimenovanje mape...';
+$messages['foldermoving'] = 'Premiranje mape...';
+$messages['formincomplete'] = 'Obrazec ni v celoti izpolnjen';
+$messages['noemailwarning'] = 'Vnesite veljaven elektronski naslov';
+$messages['nonamewarning'] = 'Vnesite ime';
+$messages['nopagesizewarning'] = 'Vnesite velikost strani';
+$messages['nosenderwarning'] = 'Vnesite elektronski naslov pošiljatelja';
+$messages['norecipientwarning'] = 'Vnesite vsaj enega prejemnika sporočila';
+$messages['nosubjectwarning'] = 'Polje "Zadeva" je prazno. Želite dodati tekst v to polje?';
+$messages['nobodywarning'] = 'Želite poslati sporočilo brez vsebine?';
+$messages['notsentwarning'] = 'Sporočilo ni bilo poslano. Želite zavreči to sporočilo?';
+$messages['noldapserver'] = 'Izberite LDAP strežnik, v katerem želite iskati?';
+$messages['nocontactsreturned'] = 'Nobenega stika ni bilo mogoče najti';
+$messages['nosearchname'] = 'Vnesite ime ali elektronski naslov stika';
+$messages['searchsuccessful'] = '$nr najdenih sporočil';
+$messages['searchnomatch'] = 'Ni zadetkov';
+$messages['searching'] = 'Iskanje...';
+$messages['checking'] = 'Preverjanje...';
+$messages['nospellerrors'] = 'V tekstu ni bilo nobenih pravopisnih napak';
+$messages['folderdeleted'] = 'Mapa je bila uspešno izbrisana.';
+$messages['deletedsuccessfully'] = 'Uspešno izbrisano';
+$messages['converting'] = 'Odstranjevanje nastavitev oblikovanja...';
+$messages['messageopenerror'] = 'Sporočila ni bilo mogoče prenesti iz strežnika';
+$messages['fileuploaderror'] = 'Prenos datoteke je spodletel';
+$messages['filesizeerror'] = 'Naložena datoteka presega največjo dovoljeno velikost $size';
+$messages['copysuccess'] = '$nr naslovov je bilo uspešno prenešenih';
+$messages['copyerror'] = 'Nobenih naslovov ni bilo mogoče kopirati';
+$messages['sourceisreadonly'] = 'Ta naslov je na voljo samo za branje';
+$messages['errorsavingcontact'] = 'Stika ni bilo mogoče shraniti';
+$messages['movingmessage'] = 'Premikanje sporočila...';
+$messages['receiptsent'] = 'Sporočilo o branju je bilo uspešno poslano';
+$messages['errorsendingreceipt'] = 'Sporočila o branju ni bilo mogoče poslati';
+$messages['nodeletelastidentity'] = 'Te identitete ni mogoče izbrisati, saj je edina.';
+$messages['addsubfolderhint'] = 'Ta mapa bo ustvarjena kot podmapa od izbrane mape.';
+$messages['forbiddencharacter'] = 'Ime mape vsebuje nedovoljen znak';
+$messages['selectimportfile'] = 'Izberite datoteko, ki jo želite prenesti';
+$messages['addresswriterror'] = 'Izbran imenik ni zapisljiv';
+$messages['importwait'] = 'Uvažanje poteka...';
+$messages['importerror'] = 'Uvažanje je spodletelo. Naložena datoteka ni veljavena vCard datoteka.';
+$messages['importconfirm'] = '<b>Uspešno uvoženi $inserted stiki, $skipped stikov že obstaja v imeniku</b>:<p><em>$names</em></p>';
+$messages['opnotpermitted'] = 'Operacija ni dovoljena.';
+$messages['nofromaddress'] = 'V izbrani identiteti manjka elektronski naslov.';
+$messages['editorwarning'] = 'Preklop v splošen urejevalnik onemogoča uporabo izbranih nastavitev oblikovanja. Želite nadaljevati?';
+$messages['httpreceivedencrypterror'] = 'Prišlo je do večje napake v konfiguraciji.Obrnite se na skrbnika sistema.  <b>Sporočila ni bilo mogoče poslati.</b>';
+$messages['smtpconnerror'] = 'Napaka pri pošiljanju ($code): Povezava s strežnikom je spodletela';
+$messages['smtpautherror'] = 'Napaka pri pošiljanju($code): Avtentikacija je spodletela';
+$messages['smtpfromerror'] = 'Napaka pri pošiljanju ($code): Neveljaven elektronski naslov pošiljatelja "$from"';
+$messages['smtptoerror'] = 'Napaka pri pošiljanju ($code): Neveljaven elektronski naslov prejemnika "$to"';
+$messages['smtprecipientserror'] = 'Napaka pri pošiljanju: Seznama prejemnikov ni bilo mogoče razčleniti';
+$messages['smtperror'] = 'Napaka pri pošiljanju:$msg';
 
 ?>
index 2b710b134921dcf59c326bcd5327e04152e3b971..699ecf733a8c0d518da459546502c8bb060c0be1 100644 (file)
@@ -172,7 +172,6 @@ $labels['htmleditor'] = 'Shkruaj mesazhe HTML';
 $labels['htmlsignature'] = 'Nënshkrimi HTML';
 $labels['previewpane'] = 'Shiko si duket';
 $labels['autosavedraft'] = 'Ruaje automatikisht si draft';
-$labels['everynminutes'] = 'çdo $n minuta';
 $labels['never'] = 'kurrë';
 $labels['folder'] = 'Kutia';
 $labels['folders'] = 'Kutitë';
index dba0ba6ff1eb37a220c3913c8209bd544af24c41..bdd77b0ed1eb1b17b3e8d870199d1a8768d16399 100644 (file)
-<?php\r
-\r
-/*\r
-\r
- +-----------------------------------------------------------------------+\r
- | language/sr_cyrillic/labels.inc                                       |\r
- |                                                                       |\r
- | Language file of the RoundCube Webmail client                         |\r
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |\r
- | Licensed under the GNU GPL                                            |\r
- |                                                                       |\r
- +-----------------------------------------------------------------------+\r
- | Author: Branko Kokanovic <branko.kokanovic@gmail.com                  |\r
- +-----------------------------------------------------------------------+\r
-\r
- @version $Id$\r
-\r
-*/\r
-\r
-$labels = array();\r
-$labels['welcome'] = 'Добродошли на $product';\r
-$labels['username'] = 'Корисничко име';\r
-$labels['password'] = 'Лозинка';\r
-$labels['server'] = 'Сервер';\r
-$labels['login'] = 'Пријава';\r
-$labels['logout'] = 'Одјава';\r
-$labels['mail'] = 'Сандуче';\r
-$labels['settings'] = 'Подешавања';\r
-$labels['addressbook'] = 'Именик';\r
-$labels['inbox'] = 'Примљене';\r
-$labels['drafts'] = 'Снимљене';\r
-$labels['sent'] = 'Послате';\r
-$labels['trash'] = 'Канта';\r
-$labels['junk'] = 'Смеће';\r
-$labels['subject'] = 'Наслов';\r
-$labels['from'] = 'Од';\r
-$labels['to'] = 'За';\r
-$labels['cc'] = 'Cc';\r
-$labels['bcc'] = 'Bcc';\r
-$labels['replyto'] = 'Reply-To';\r
-$labels['date'] = 'Датум';\r
-$labels['size'] = 'Величина';\r
-$labels['priority'] = 'Приоритет';\r
-$labels['organization'] = 'Организација';\r
-$labels['reply-to'] = 'Reply-To';\r
-$labels['mailboxlist'] = 'Фасцикле';\r
-$labels['messagesfromto'] = 'Поруке од $from за $to од укупно $count';\r
-$labels['messagenrof'] = 'Порука број $nr од $count';\r
-$labels['moveto'] = 'пребаци у...';\r
-$labels['download'] = 'преузми (скидање)';\r
-$labels['filename'] = 'Име датотекеe';\r
-$labels['filesize'] = 'Величина датотеке';\r
-$labels['preferhtml'] = 'Предност дај ХТМЛ формату';\r
-$labels['htmlmessage'] = 'ХТМЛ формат поруке';\r
-$labels['prettydate'] = 'Форматирани датум';\r
-$labels['addtoaddressbook'] = 'Додај у именик';\r
-$labels['sun'] = 'Нед';\r
-$labels['mon'] = 'Пон';\r
-$labels['tue'] = 'Уто';\r
-$labels['wed'] = 'Сре';\r
-$labels['thu'] = 'Чет';\r
-$labels['fri'] = 'Пет';\r
-$labels['sat'] = 'Суб';\r
-$labels['sunday'] = 'Недеља';\r
-$labels['monday'] = 'Понедељак';\r
-$labels['tuesday'] = 'Уторак';\r
-$labels['wednesday'] = 'Среда';\r
-$labels['thursday'] = 'Четвртак';\r
-$labels['friday'] = 'Петак';\r
-$labels['saturday'] = 'Субота';\r
-$labels['today'] = 'данас';\r
-$labels['checkmail'] = 'Провера нових порука';\r
-$labels['writenewmessage'] = 'Нова порука';\r
-$labels['replytomessage'] = 'Одговори на поруку';\r
-$labels['replytoallmessage'] = 'Одговори пошиљаоцу и свим примаоцима';\r
-$labels['forwardmessage'] = 'Проследи поруку';\r
-$labels['deletemessage'] = 'Извриши поруку';\r
-$labels['movemessagetotrash'] = 'Пребаци поруку у канту';\r
-$labels['printmessage'] = 'Одштампај поруку';\r
-$labels['previousmessage'] = 'Прикажи претходну поруку';\r
-$labels['previousmessages'] = 'Прикажи претходни скуп порука';\r
-$labels['firstmessage'] = 'Прикажи прву поруку';\r
-$labels['firstmessages'] = 'Прикажи први скуп порука';\r
-$labels['nextmessage'] = 'Прикажи следећу поруку';\r
-$labels['nextmessages'] = 'Прикажи следећи скуп порука';\r
-$labels['lastmessage'] = 'Прикажи последњу поруку';\r
-$labels['lastmessages'] = 'Прикажи последњи скуп порука';\r
-$labels['backtolist'] = 'Повратак на листу порука';\r
-$labels['viewsource'] = 'Прикажи поруку у изворном облику';\r
-$labels['markmessages'] = 'Обележи поруке';\r
-$labels['markread'] = 'Као прочитане';\r
-$labels['markunread'] = 'Као непрочитане';\r
-$labels['select'] = 'Означи';\r
-$labels['all'] = 'Све';\r
-$labels['none'] = 'Ниједну';\r
-$labels['unread'] = 'Непрочитане';\r
-$labels['compact'] = 'Компакција';\r
-$labels['empty'] = 'Испразни';\r
-$labels['purge'] = 'Oчисти';\r
-$labels['quota'] = 'Квота';\r
-$labels['unknown'] = 'непозната';\r
-$labels['unlimited'] = 'бесконачна';\r
-$labels['quicksearch'] = 'Брза претрага';\r
-$labels['resetsearch'] = 'Прикажи све поруке';\r
-$labels['compose'] = 'Нова порука';\r
-$labels['savemessage'] = 'Сачувај у Снимљене';\r
-$labels['sendmessage'] = 'Пошаљи поруку';\r
-$labels['addattachment'] = 'Приложи датотеку';\r
-$labels['charset'] = 'Скуп карактера';\r
-$labels['editortype'] = 'Врста едитора';\r
-$labels['returnreceipt'] = 'Потврда о приспећу';\r
-$labels['checkspelling'] = 'Провера правописа';\r
-$labels['resumeediting'] = 'Повратак у режим писања';\r
-$labels['revertto'] = 'Врати се на';\r
-$labels['attachments'] = 'Прилози ';\r
-$labels['upload'] = 'Додај';\r
-$labels['close'] = 'Затвори';\r
-$labels['low'] = 'Низак';\r
-$labels['lowest'] = 'Најнижи';\r
-$labels['normal'] = 'Средњи';\r
-$labels['high'] = 'Висок';\r
-$labels['highest'] = 'Највиши';\r
-$labels['nosubject'] = '(без наслова)';\r
-$labels['showimages'] = 'Прикажи слике';\r
-$labels['htmltoggle'] = 'HTML';\r
-$labels['plaintoggle'] = 'Обичан текст';\r
-$labels['addcc'] = 'Додај Cc';\r
-$labels['addbcc'] = 'Додај Bcc';\r
-$labels['addreplyto'] = 'Додај Reply-To';\r
-$labels['mdnrequest'] = 'Пошиљалац ове поруке је замолио да буде обавештен када прочитате ову поруку. Да ли желите да обавестите пошиљаоца?';\r
-$labels['receiptread'] = 'Обавештење о приспећу (прочитана порука)';\r
-$labels['yourmessage'] = 'Ово је обавештење о приспећу за вашу поруку';\r
-$labels['receiptnote'] = 'Пажња: Ово обавештење само потврђује да је порука приказана на рачунару примаоца. Не постоји гаранција да је прималац прочитао или разумео садржај поруке.';\r
-$labels['name'] = 'Пуно име';\r
-$labels['firstname'] = 'Име';\r
-$labels['surname'] = 'Презиме';\r
-$labels['email'] = 'Е-мејл';\r
-$labels['addcontact'] = 'Додај нови контакт';\r
-$labels['editcontact'] = 'Измени контакт';\r
-$labels['edit'] = 'Измени';\r
-$labels['cancel'] = 'Поништи';\r
-$labels['save'] = 'Сачувај';\r
-$labels['delete'] = 'Обриши';\r
-$labels['newcontact'] = 'Додај нови контакт';\r
-$labels['deletecontact'] = 'Обриши одабране контакте';\r
-$labels['composeto'] = 'Напиши поруку...';\r
-$labels['contactsfromto'] = 'Контакти од $from до $to од укупно $count';\r
-$labels['print'] = 'Штампај';\r
-$labels['export'] = 'Извези';\r
-$labels['previouspage'] = 'Прикажи претходну страну';\r
-$labels['firstpage'] = 'Прикажи први скуп';\r
-$labels['nextpage'] = 'Прикажи следећу страну';\r
-$labels['lastpage'] = 'Прикажи последњи скуп';\r
-$labels['groups'] = 'Групе';\r
-$labels['personaladrbook'] = 'Личне адресе';\r
-$labels['settingsfor'] = 'Подешавања за';\r
-$labels['preferences'] = 'Подешавања';\r
-$labels['userpreferences'] = 'Општа подешавања';\r
-$labels['editpreferences'] = 'Измена општих подешавања';\r
-$labels['identities'] = 'Идентитети';\r
-$labels['manageidentities'] = 'Подеси идентитете за овај налог';\r
-$labels['newidentity'] = 'Додај идентитет';\r
-$labels['newitem'] = 'Нова ставка';\r
-$labels['edititem'] = 'Измена ставке';\r
-$labels['setdefault'] = 'Подеси подразумевано';\r
-$labels['language'] = 'Језик';\r
-$labels['timezone'] = 'Временска зона';\r
-$labels['pagesize'] = 'Редова по страни';\r
-$labels['signature'] = 'Потпис';\r
-$labels['dstactive'] = 'Летње померање времена';\r
-$labels['htmleditor'] = 'Састави HTML поруке';\r
-$labels['htmlsignature'] = 'HTML потпис';\r
-$labels['previewpane'] = 'Прикажи панел за преглед';\r
-$labels['autosavedraft'] = 'Аутоматски чувај у Снимљене';\r
-$labels['everynminutes'] = 'сваких $n минута';\r
-$labels['never'] = 'никад';\r
-$labels['folder'] = 'Фасцикла';\r
-$labels['folders'] = 'Фасцикле';\r
-$labels['foldername'] = 'Име фасцикле';\r
-$labels['subscribed'] = 'Потписана';\r
-$labels['messagecount'] = 'Поруке';\r
-$labels['create'] = 'Креирај';\r
-$labels['createfolder'] = 'Креирај нову фасциклу';\r
-$labels['rename'] = 'Преименуј';\r
-$labels['renamefolder'] = 'Преименуј фасциклу';\r
-$labels['deletefolder'] = 'Обриши фасциклу';\r
-$labels['managefolders'] = 'Подеси фасциклу';\r
-$labels['sortby'] = 'Сортирај по';\r
-$labels['sortasc'] = 'Сортирај растуће';\r
-$labels['sortdesc'] = 'Сортирај опадајуће';\r
-\r
-?>\r
+<?php
+
+/*
+
+ +-----------------------------------------------------------------------+
+ | language/sr_cyrillic/labels.inc                                       |
+ |                                                                       |
+ | Language file of the RoundCube Webmail client                         |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Branko Kokanovic <branko.kokanovic@gmail.com                  |
+ +-----------------------------------------------------------------------+
+
+ @version $Id$
+
+*/
+
+$labels = array();
+$labels['welcome'] = 'Добродошли на $product';
+$labels['username'] = 'Корисничко име';
+$labels['password'] = 'Лозинка';
+$labels['server'] = 'Сервер';
+$labels['login'] = 'Пријава';
+$labels['logout'] = 'Одјава';
+$labels['mail'] = 'Сандуче';
+$labels['settings'] = 'Подешавања';
+$labels['addressbook'] = 'Именик';
+$labels['inbox'] = 'Примљене';
+$labels['drafts'] = 'Снимљене';
+$labels['sent'] = 'Послате';
+$labels['trash'] = 'Канта';
+$labels['junk'] = 'Смеће';
+$labels['subject'] = 'Наслов';
+$labels['from'] = 'Од';
+$labels['to'] = 'За';
+$labels['cc'] = 'Cc';
+$labels['bcc'] = 'Bcc';
+$labels['replyto'] = 'Reply-To';
+$labels['date'] = 'Датум';
+$labels['size'] = 'Величина';
+$labels['priority'] = 'Приоритет';
+$labels['organization'] = 'Организација';
+$labels['reply-to'] = 'Reply-To';
+$labels['mailboxlist'] = 'Фасцикле';
+$labels['messagesfromto'] = 'Поруке од $from за $to од укупно $count';
+$labels['messagenrof'] = 'Порука број $nr од $count';
+$labels['moveto'] = 'пребаци у...';
+$labels['download'] = 'преузми (скидање)';
+$labels['filename'] = 'Име датотекеe';
+$labels['filesize'] = 'Величина датотеке';
+$labels['preferhtml'] = 'Предност дај ХТМЛ формату';
+$labels['htmlmessage'] = 'ХТМЛ формат поруке';
+$labels['prettydate'] = 'Форматирани датум';
+$labels['addtoaddressbook'] = 'Додај у именик';
+$labels['sun'] = 'Нед';
+$labels['mon'] = 'Пон';
+$labels['tue'] = 'Уто';
+$labels['wed'] = 'Сре';
+$labels['thu'] = 'Чет';
+$labels['fri'] = 'Пет';
+$labels['sat'] = 'Суб';
+$labels['sunday'] = 'Недеља';
+$labels['monday'] = 'Понедељак';
+$labels['tuesday'] = 'Уторак';
+$labels['wednesday'] = 'Среда';
+$labels['thursday'] = 'Четвртак';
+$labels['friday'] = 'Петак';
+$labels['saturday'] = 'Субота';
+$labels['today'] = 'данас';
+$labels['checkmail'] = 'Провера нових порука';
+$labels['writenewmessage'] = 'Нова порука';
+$labels['replytomessage'] = 'Одговори на поруку';
+$labels['replytoallmessage'] = 'Одговори пошиљаоцу и свим примаоцима';
+$labels['forwardmessage'] = 'Проследи поруку';
+$labels['deletemessage'] = 'Извриши поруку';
+$labels['movemessagetotrash'] = 'Пребаци поруку у канту';
+$labels['printmessage'] = 'Одштампај поруку';
+$labels['previousmessage'] = 'Прикажи претходну поруку';
+$labels['previousmessages'] = 'Прикажи претходни скуп порука';
+$labels['firstmessage'] = 'Прикажи прву поруку';
+$labels['firstmessages'] = 'Прикажи први скуп порука';
+$labels['nextmessage'] = 'Прикажи следећу поруку';
+$labels['nextmessages'] = 'Прикажи следећи скуп порука';
+$labels['lastmessage'] = 'Прикажи последњу поруку';
+$labels['lastmessages'] = 'Прикажи последњи скуп порука';
+$labels['backtolist'] = 'Повратак на листу порука';
+$labels['viewsource'] = 'Прикажи поруку у изворном облику';
+$labels['markmessages'] = 'Обележи поруке';
+$labels['markread'] = 'Као прочитане';
+$labels['markunread'] = 'Као непрочитане';
+$labels['select'] = 'Означи';
+$labels['all'] = 'Све';
+$labels['none'] = 'Ниједну';
+$labels['unread'] = 'Непрочитане';
+$labels['compact'] = 'Компакција';
+$labels['empty'] = 'Испразни';
+$labels['purge'] = 'Oчисти';
+$labels['quota'] = 'Квота';
+$labels['unknown'] = 'непозната';
+$labels['unlimited'] = 'бесконачна';
+$labels['quicksearch'] = 'Брза претрага';
+$labels['resetsearch'] = 'Прикажи све поруке';
+$labels['compose'] = 'Нова порука';
+$labels['savemessage'] = 'Сачувај у Снимљене';
+$labels['sendmessage'] = 'Пошаљи поруку';
+$labels['addattachment'] = 'Приложи датотеку';
+$labels['charset'] = 'Скуп карактера';
+$labels['editortype'] = 'Врста едитора';
+$labels['returnreceipt'] = 'Потврда о приспећу';
+$labels['checkspelling'] = 'Провера правописа';
+$labels['resumeediting'] = 'Повратак у режим писања';
+$labels['revertto'] = 'Врати се на';
+$labels['attachments'] = 'Прилози ';
+$labels['upload'] = 'Додај';
+$labels['close'] = 'Затвори';
+$labels['low'] = 'Низак';
+$labels['lowest'] = 'Најнижи';
+$labels['normal'] = 'Средњи';
+$labels['high'] = 'Висок';
+$labels['highest'] = 'Највиши';
+$labels['nosubject'] = '(без наслова)';
+$labels['showimages'] = 'Прикажи слике';
+$labels['htmltoggle'] = 'HTML';
+$labels['plaintoggle'] = 'Обичан текст';
+$labels['addcc'] = 'Додај Cc';
+$labels['addbcc'] = 'Додај Bcc';
+$labels['addreplyto'] = 'Додај Reply-To';
+$labels['mdnrequest'] = 'Пошиљалац ове поруке је замолио да буде обавештен када прочитате ову поруку. Да ли желите да обавестите пошиљаоца?';
+$labels['receiptread'] = 'Обавештење о приспећу (прочитана порука)';
+$labels['yourmessage'] = 'Ово је обавештење о приспећу за вашу поруку';
+$labels['receiptnote'] = 'Пажња: Ово обавештење само потврђује да је порука приказана на рачунару примаоца. Не постоји гаранција да је прималац прочитао или разумео садржај поруке.';
+$labels['name'] = 'Пуно име';
+$labels['firstname'] = 'Име';
+$labels['surname'] = 'Презиме';
+$labels['email'] = 'Е-мејл';
+$labels['addcontact'] = 'Додај нови контакт';
+$labels['editcontact'] = 'Измени контакт';
+$labels['edit'] = 'Измени';
+$labels['cancel'] = 'Поништи';
+$labels['save'] = 'Сачувај';
+$labels['delete'] = 'Обриши';
+$labels['newcontact'] = 'Додај нови контакт';
+$labels['deletecontact'] = 'Обриши одабране контакте';
+$labels['composeto'] = 'Напиши поруку...';
+$labels['contactsfromto'] = 'Контакти од $from до $to од укупно $count';
+$labels['print'] = 'Штампај';
+$labels['export'] = 'Извези';
+$labels['previouspage'] = 'Прикажи претходну страну';
+$labels['firstpage'] = 'Прикажи први скуп';
+$labels['nextpage'] = 'Прикажи следећу страну';
+$labels['lastpage'] = 'Прикажи последњи скуп';
+$labels['groups'] = 'Групе';
+$labels['personaladrbook'] = 'Личне адресе';
+$labels['settingsfor'] = 'Подешавања за';
+$labels['preferences'] = 'Подешавања';
+$labels['userpreferences'] = 'Општа подешавања';
+$labels['editpreferences'] = 'Измена општих подешавања';
+$labels['identities'] = 'Идентитети';
+$labels['manageidentities'] = 'Подеси идентитете за овај налог';
+$labels['newidentity'] = 'Додај идентитет';
+$labels['newitem'] = 'Нова ставка';
+$labels['edititem'] = 'Измена ставке';
+$labels['setdefault'] = 'Подеси подразумевано';
+$labels['language'] = 'Језик';
+$labels['timezone'] = 'Временска зона';
+$labels['pagesize'] = 'Редова по страни';
+$labels['signature'] = 'Потпис';
+$labels['dstactive'] = 'Летње померање времена';
+$labels['htmleditor'] = 'Састави HTML поруке';
+$labels['htmlsignature'] = 'HTML потпис';
+$labels['previewpane'] = 'Прикажи панел за преглед';
+$labels['autosavedraft'] = 'Аутоматски чувај у Снимљене';
+$labels['never'] = 'никад';
+$labels['folder'] = 'Фасцикла';
+$labels['folders'] = 'Фасцикле';
+$labels['foldername'] = 'Име фасцикле';
+$labels['subscribed'] = 'Потписана';
+$labels['messagecount'] = 'Поруке';
+$labels['create'] = 'Креирај';
+$labels['createfolder'] = 'Креирај нову фасциклу';
+$labels['rename'] = 'Преименуј';
+$labels['renamefolder'] = 'Преименуј фасциклу';
+$labels['deletefolder'] = 'Обриши фасциклу';
+$labels['managefolders'] = 'Подеси фасциклу';
+$labels['sortby'] = 'Сортирај по';
+$labels['sortasc'] = 'Сортирај растуће';
+$labels['sortdesc'] = 'Сортирај опадајуће';
+
+?>
index 43f3fcff8712b86af2e5bf7827da265bc8190a66..de8b0a2a91aa1b463e17c402cc08a2e9a98b48f6 100644 (file)
@@ -1,82 +1,82 @@
-<?php\r
-\r
-/*\r
-\r
- +-----------------------------------------------------------------------+\r
- | language/sr_cyrillic/messages.inc                                     |\r
- |                                                                       |\r
- | Language file of the RoundCube Webmail client                         |\r
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |\r
- | Licensed under the GNU GPL                                            |\r
- |                                                                       |\r
- +-----------------------------------------------------------------------+\r
- | Author: Branko Kokanovic <branko.kokanovic@gmail.com>                 |\r
- +-----------------------------------------------------------------------+\r
-\r
- @version $Id$\r
-\r
-*/\r
-\r
-$messages = array();\r
-$messages['loginfailed'] = 'Неуспешно пријављивање';\r
-$messages['cookiesdisabled'] = 'Ваш интернет прегледач не подржава колачиће';\r
-$messages['sessionerror'] = 'Сесија није валидна или је истекла';\r
-$messages['imaperror'] = 'Неуспешна конекција на IMAP сервер';\r
-$messages['nomessagesfound'] = 'Немате порука у сандучету';\r
-$messages['loggedout'] = 'Успешно сте се одјавили.';\r
-$messages['mailboxempty'] = 'Сандуче је празно';\r
-$messages['loading'] = 'Учитавање...';\r
-$messages['loadingdata'] = 'Учитавање података...';\r
-$messages['checkingmail'] = 'Провера нових порука у току...';\r
-$messages['sendingmessage'] = 'Порука се шаље...';\r
-$messages['messagesent'] = 'Порука је успешно послата';\r
-$messages['savingmessage'] = 'Порука се снима...';\r
-$messages['messagesaved'] = 'Порука успешно сачувана у Снимљене';\r
-$messages['successfullysaved'] = 'Снимање успешно обављено';\r
-$messages['addedsuccessfully'] = 'Контакт успешно додат у именик';\r
-$messages['contactexists'] = 'Контакт са овом е-мејл адресом већ постоји у именику';\r
-$messages['blockedimages'] = 'Због заштите приватности, слике са удаљених сервера су блокиране';\r
-$messages['encryptedmessage'] = 'Ова порука је шифрована, па се не може приказати';\r
-$messages['nocontactsfound'] = 'Није пронађен ниједан контакт';\r
-$messages['contactnotfound'] = 'Жељени контакт није нађен';\r
-$messages['sendingfailed'] = 'Грешка при слању поруке';\r
-$messages['errorsaving'] = 'Грешка при снимању поруке';\r
-$messages['errormoving'] = 'Грешка при премештању поруке';\r
-$messages['errordeleting'] = 'Грешка при брисању поруке';\r
-$messages['deletecontactconfirm'] = 'Да ли стварно желите да обришете изабране контакте?';\r
-$messages['deletemessagesconfirm'] = 'Да ли стварно желите да обришете изабране поруке?';\r
-$messages['deletefolderconfirm'] = 'Да ли заиста желите да обришете изабрану фасциклу?';\r
-$messages['purgefolderconfirm'] = 'Да ли заиста желите да обришете све поруке у фасцикли?';\r
-$messages['formincomplete'] = 'Формулар није у целости попуњен';\r
-$messages['noemailwarning'] = 'Унесите валидну е-мејл адресу';\r
-$messages['nonamewarning'] = 'Унесите име';\r
-$messages['nopagesizewarning'] = 'Унесите величину странице';\r
-$messages['norecipientwarning'] = 'Унесите примаоца/примаоце (За)';\r
-$messages['nosubjectwarning'] = 'Поље \'Наслов\' је празно. Желите ли да унесете наслов?';\r
-$messages['nobodywarning'] = 'Да ли желите да пошаљете поруку без текста?';\r
-$messages['notsentwarning'] = 'Порука није послата. Да ли желите да одбаците ову поруку?';\r
-$messages['noldapserver'] = 'Унесите LDAP сервер за претрагу';\r
-$messages['nocontactsreturned'] = 'Није пронађен ниједан контакт';\r
-$messages['nosearchname'] = 'Унесите име или е-мејл адресу';\r
-$messages['searchsuccessful'] = 'Број пронађених порука: $nr';\r
-$messages['searchnomatch'] = 'Тражена фраза није пронађена ни у једној поруци';\r
-$messages['searching'] = 'Претрага у току...';\r
-$messages['checking'] = 'Провера у току...';\r
-$messages['nospellerrors'] = 'Није пронађена ниједна правописна грешка';\r
-$messages['folderdeleted'] = 'Фасцикла успешно обрисана';\r
-$messages['deletedsuccessfully'] = 'Брисање успешно';\r
-$messages['converting'] = 'Уклањање форматирања из поруке...';\r
-$messages['messageopenerror'] = 'Порука се не може учитати са сервера';\r
-$messages['fileuploaderror'] = 'Слање датотеке неуспешно';\r
-$messages['filesizeerror'] = 'Послата датотека не може да прекорачи величину од $size';\r
-$messages['copysuccess'] = 'Успешно копирано $nr адреса';\r
-$messages['copyerror'] = 'Немогуће је ископирати иједну адресу';\r
-$messages['sourceisreadonly'] = 'Овај извор адресе је само за читање';\r
-$messages['errorsavingcontact'] = 'Неуспело снимање адресе контакта';\r
-$messages['movingmessage'] = 'Премештам поруку...';\r
-$messages['receiptsent'] = 'Успешно послато обавештење о приспећу';\r
-$messages['errorsendingreceipt'] = 'Неуспело слање обавештења о приспећу';\r
-$messages['nodeletelastidentity'] = 'Не можете обрисати овај идентитет, он Вам је последњи.';\r
-$messages['addsubfolderhint'] = 'Ова фасцикла ће бити креирана као подфасцикла тренутне';\r
-\r
-?>\r
+<?php
+
+/*
+
+ +-----------------------------------------------------------------------+
+ | language/sr_cyrillic/messages.inc                                     |
+ |                                                                       |
+ | Language file of the RoundCube Webmail client                         |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Branko Kokanovic <branko.kokanovic@gmail.com>                 |
+ +-----------------------------------------------------------------------+
+
+ @version $Id$
+
+*/
+
+$messages = array();
+$messages['loginfailed'] = 'Неуспешно пријављивање';
+$messages['cookiesdisabled'] = 'Ваш интернет прегледач не подржава колачиће';
+$messages['sessionerror'] = 'Сесија није валидна или је истекла';
+$messages['imaperror'] = 'Неуспешна конекција на IMAP сервер';
+$messages['nomessagesfound'] = 'Немате порука у сандучету';
+$messages['loggedout'] = 'Успешно сте се одјавили.';
+$messages['mailboxempty'] = 'Сандуче је празно';
+$messages['loading'] = 'Учитавање...';
+$messages['loadingdata'] = 'Учитавање података...';
+$messages['checkingmail'] = 'Провера нових порука у току...';
+$messages['sendingmessage'] = 'Порука се шаље...';
+$messages['messagesent'] = 'Порука је успешно послата';
+$messages['savingmessage'] = 'Порука се снима...';
+$messages['messagesaved'] = 'Порука успешно сачувана у Снимљене';
+$messages['successfullysaved'] = 'Снимање успешно обављено';
+$messages['addedsuccessfully'] = 'Контакт успешно додат у именик';
+$messages['contactexists'] = 'Контакт са овом е-мејл адресом већ постоји у именику';
+$messages['blockedimages'] = 'Због заштите приватности, слике са удаљених сервера су блокиране';
+$messages['encryptedmessage'] = 'Ова порука је шифрована, па се не може приказати';
+$messages['nocontactsfound'] = 'Није пронађен ниједан контакт';
+$messages['contactnotfound'] = 'Жељени контакт није нађен';
+$messages['sendingfailed'] = 'Грешка при слању поруке';
+$messages['errorsaving'] = 'Грешка при снимању поруке';
+$messages['errormoving'] = 'Грешка при премештању поруке';
+$messages['errordeleting'] = 'Грешка при брисању поруке';
+$messages['deletecontactconfirm'] = 'Да ли стварно желите да обришете изабране контакте?';
+$messages['deletemessagesconfirm'] = 'Да ли стварно желите да обришете изабране поруке?';
+$messages['deletefolderconfirm'] = 'Да ли заиста желите да обришете изабрану фасциклу?';
+$messages['purgefolderconfirm'] = 'Да ли заиста желите да обришете све поруке у фасцикли?';
+$messages['formincomplete'] = 'Формулар није у целости попуњен';
+$messages['noemailwarning'] = 'Унесите валидну е-мејл адресу';
+$messages['nonamewarning'] = 'Унесите име';
+$messages['nopagesizewarning'] = 'Унесите величину странице';
+$messages['norecipientwarning'] = 'Унесите примаоца/примаоце (За)';
+$messages['nosubjectwarning'] = 'Поље \'Наслов\' је празно. Желите ли да унесете наслов?';
+$messages['nobodywarning'] = 'Да ли желите да пошаљете поруку без текста?';
+$messages['notsentwarning'] = 'Порука није послата. Да ли желите да одбаците ову поруку?';
+$messages['noldapserver'] = 'Унесите LDAP сервер за претрагу';
+$messages['nocontactsreturned'] = 'Није пронађен ниједан контакт';
+$messages['nosearchname'] = 'Унесите име или е-мејл адресу';
+$messages['searchsuccessful'] = 'Број пронађених порука: $nr';
+$messages['searchnomatch'] = 'Тражена фраза није пронађена ни у једној поруци';
+$messages['searching'] = 'Претрага у току...';
+$messages['checking'] = 'Провера у току...';
+$messages['nospellerrors'] = 'Није пронађена ниједна правописна грешка';
+$messages['folderdeleted'] = 'Фасцикла успешно обрисана';
+$messages['deletedsuccessfully'] = 'Брисање успешно';
+$messages['converting'] = 'Уклањање форматирања из поруке...';
+$messages['messageopenerror'] = 'Порука се не може учитати са сервера';
+$messages['fileuploaderror'] = 'Слање датотеке неуспешно';
+$messages['filesizeerror'] = 'Послата датотека не може да прекорачи величину од $size';
+$messages['copysuccess'] = 'Успешно копирано $nr адреса';
+$messages['copyerror'] = 'Немогуће је ископирати иједну адресу';
+$messages['sourceisreadonly'] = 'Овај извор адресе је само за читање';
+$messages['errorsavingcontact'] = 'Неуспело снимање адресе контакта';
+$messages['movingmessage'] = 'Премештам поруку...';
+$messages['receiptsent'] = 'Успешно послато обавештење о приспећу';
+$messages['errorsendingreceipt'] = 'Неуспело слање обавештења о приспећу';
+$messages['nodeletelastidentity'] = 'Не можете обрисати овај идентитет, он Вам је последњи.';
+$messages['addsubfolderhint'] = 'Ова фасцикла ће бити креирана као подфасцикла тренутне';
+
+?>
index 7f40c43dacf4c7e7e8984d8385baa32971d4e917..9ecfbfe073766ef07f60c2ea647b0f321583aae3 100644 (file)
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
-| Author: Jonas Nasholm <info@bitfuse.net>                              |
+| Author: Jonas Nasholm <rcm@bitfuse.net>                               |
 |         Fredrik Nygren <f.nygren@gmail.com>                           |
 |         Andreas Henriksson <andreas@fatal.se>                         |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
@@ -112,18 +112,21 @@ $labels['nextmessages'] = 'Visa nästa grupp av meddelanden';
 $labels['lastmessage'] = 'Visa sista meddelandet';
 $labels['lastmessages'] = 'Visa sista gruppen av meddelanden';
 $labels['backtolist'] = 'Tillbaka till meddelandelistan';
-$labels['viewsource'] = 'Visa källa';
+$labels['viewsource'] = 'Visa källkod';
 $labels['markmessages'] = 'Markera meddelande';
 $labels['markread'] = 'Läst';
 $labels['markunread'] = 'Oläst';
 $labels['markflagged'] = 'Flaggat';
 $labels['markunflagged'] = 'Oflaggat';
+$labels['messageactions'] = 'Fler hanteringsalternativ...';
 $labels['select'] = 'Välj';
 $labels['all'] = 'Alla';
 $labels['none'] = 'Ingen';
 $labels['unread'] = 'Olästa';
 $labels['flagged'] = 'Flaggade';
 $labels['unanswered'] = 'Obesvarade';
+$labels['deleted'] = 'Raderade';
+$labels['invert'] = 'Invertera';
 $labels['filter'] = 'Filter';
 $labels['compact'] = 'Packa';
 $labels['empty'] = 'Töm';
@@ -136,12 +139,14 @@ $labels['resetsearch'] = 'Återställ sökning';
 $labels['searchmod'] = 'Sökalternativ';
 $labels['msgtext'] = 'Hela meddelandet';
 $labels['openinextwin'] = 'Öppna i nytt fönster';
+$labels['emlsave'] = 'Spara (.eml)';
 $labels['compose'] = 'Skapa nytt meddelande';
+$labels['editasnew'] = 'Redigera som nytt';
 $labels['savemessage'] = 'Spara utkast';
 $labels['sendmessage'] = 'Skicka meddelande';
 $labels['addattachment'] = 'Bifoga fil';
 $labels['charset'] = 'Teckenkodning';
-$labels['editortype'] = 'Typ av redigerare';
+$labels['editortype'] = 'Textredigerare';
 $labels['returnreceipt'] = 'Mottagarkvitto';
 $labels['checkspelling'] = 'Kontrollera stavning';
 $labels['resumeediting'] = 'Återuppta redigering';
@@ -236,7 +241,6 @@ $labels['always'] = 'Alltid';
 $labels['showinlineimages'] = 'Visa bifogade bilder efter meddelande';
 $labels['autosavedraft'] = 'Spara utkast med automatiskt intervall';
 $labels['everynminutes'] = '$n min';
-$labels['keepaliveevery'] = '$n min';
 $labels['keepalive'] = 'Hämta nya meddelanden med automatiskt intervall';
 $labels['never'] = 'Aldrig';
 $labels['messagesdisplaying'] = 'Visning av meddelanden';
@@ -248,6 +252,12 @@ $labels['2047folding'] = 'Full RFC 2047 (övriga)';
 $labels['advancedoptions'] = 'Avancerade inställningar';
 $labels['focusonnewmessage'] = 'Fokusera webbläsarens fönster vid nytt meddelande';
 $labels['checkallfolders'] = 'Genomsök samtliga kataloger efter nya meddelanden';
+$labels['displaynext'] = 'Visa nästa meddelande efter radering/flyttning av meddelande';
+$labels['mainoptions'] = 'Huvudalternativ';
+$labels['section'] = 'Avdelning';
+$labels['maintenance'] = 'Underhåll';
+$labels['newmessage'] = 'Nytt meddelande';
+$labels['listoptions'] = 'Listalternativ';
 $labels['folder'] = 'Katalog';
 $labels['folders'] = 'Kataloger';
 $labels['foldername'] = 'Katalognamn';
index 4b13de3d4a9193a37638ba50714a2bcafacebf42..a944c581a5cec755da34eeea6b980a1a594440e0 100644 (file)
@@ -2,20 +2,20 @@
 
 /*
 
- +-----------------------------------------------------------------------+
- | language/sv_SE/messages.inc                                           |
- |                                                                       |
- | Language file of the RoundCube Webmail client                         |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
- | Licensed under the GNU GPL                                            |
- |                                                                       |
- +-----------------------------------------------------------------------+
- | Author: Fredrik Nygren <f.nygren@gmail.com>                           |
- |         Andreas Henriksson <andreas@fatal.se>                         |
- |         Jonas Nasholm <info@bitfuse.net>                              |
- +-----------------------------------------------------------------------+
++-----------------------------------------------------------------------+
+| language/sv_SE/messages.inc                                           |
+|                                                                       |
+| Language file of the RoundCube Webmail client                         |
+| Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+| Licensed under the GNU GPL                                            |
+|                                                                       |
++-----------------------------------------------------------------------+
+| Author: Jonas Nasholm <rcm@bitfuse.net>                               |
+|         Fredrik Nygren <f.nygren@gmail.com>                           |
+|         Andreas Henriksson <andreas@fatal.se>                         |
++-----------------------------------------------------------------------+
 
- @version $Id: messages.inc 2215 2009-01-05 11:23:03Z alec $
+@version $Id: messages.inc 2850 2009-08-07 21:17:12Z yllar $
 
 */
 
@@ -24,6 +24,8 @@ $messages['loginfailed'] = 'Inloggningen misslyckades';
 $messages['cookiesdisabled'] = 'Din webbläsare accepterar inte cookies';
 $messages['sessionerror'] = 'Din inloggning är felaktig eller har gått ut';
 $messages['imaperror'] = 'Kontakt med IMAP-servern misslyckades';
+$messages['servererror'] = 'Fel i servern!';
+$messages['invalidrequest'] = 'Ogiltig begäran! Informationen sparades inte.';
 $messages['nomessagesfound'] = 'Inga meddelanden';
 $messages['loggedout'] = 'Du är utloggad. Välkommen åter!';
 $messages['mailboxempty'] = 'Katalogen är tom';
@@ -47,6 +49,7 @@ $messages['errorsavingsent'] = 'Ett fel inträffade när det skickade meddelande
 $messages['errorsaving'] = 'Meddelandet kunde inte sparads';
 $messages['errormoving'] = 'Meddelandet kunde inte flyttas';
 $messages['errordeleting'] = 'Meddelandet kunde inte raderas';
+$messages['errormarking'] = 'Meddelandet kunde inte markeras';
 $messages['deletecontactconfirm'] = 'Vill du verkligen radera valda kontakter?';
 $messages['deletemessagesconfirm'] = 'Vill du verkligen ta bort valda meddelanden?';
 $messages['deletefolderconfirm'] = 'Vill du verkligen radera den här katalogen?';
@@ -63,12 +66,12 @@ $messages['nosenderwarning'] = 'Vänligen ange en avsändaradress';
 $messages['norecipientwarning'] = 'Vänligen ange minst en mottagare';
 $messages['nosubjectwarning'] = 'Ämnesfältet är tomt. Vill du lägga till något nu?';
 $messages['nobodywarning'] = 'Skicka det här meddelandet utan text?';
-$messages['notsentwarning'] = 'Meddelande har inte skickats. Vill du avbryta meddelandet?';
+$messages['notsentwarning'] = 'Meddelandet har inte skickats. Vill du avbryta meddelandet?';
 $messages['noldapserver'] = 'Vänligen ange en LDAP-server att söka';
 $messages['nocontactsreturned'] = 'Inga kontakter hittades';
 $messages['nosearchname'] = 'Vänligen ange ett kontaktnamn eller en adress';
 $messages['searchsuccessful'] = '$nr meddelanden hittades';
-$messages['searchnomatch'] = 'Sökningen returnerade inga träffar';
+$messages['searchnomatch'] = 'Sökningen gav inget resultat';
 $messages['searching'] = 'Söker...';
 $messages['checking'] = 'Kontrollerar...';
 $messages['nospellerrors'] = 'Inget stavfel hittades';
@@ -96,5 +99,12 @@ $messages['importconfirm'] = '<b>Lyckad import av $inserted kontakter, $skipped
 $messages['opnotpermitted'] = 'Otillåten operation!';
 $messages['nofromaddress'] = 'Adressen saknas i den valda identiteten';
 $messages['editorwarning'] = 'Genom att växla till text-läge går formateringen förlorad. Vill du fortsätta?';
+$messages['httpreceivedencrypterror'] = 'Ett irreparabelt fel har uppstått. Kontakta administratören omgående. <b>Meddelandet kan inte skickas.</b>';
+$messages['smtpconnerror'] = 'SMTP-fel ($code): Anslutning till servern misslyckades';
+$messages['smtpautherror'] = 'SMTP-fel ($code): Inloggningen misslyckades';
+$messages['smtpfromerror'] = 'SMTP-fel ($code): Kan inte sätta avsändaradress till "$from"';
+$messages['smtptoerror'] = 'SMTP-fel ($code): Kan inte lägga till mottagaradress "$to"';
+$messages['smtprecipientserror'] = 'SMTP-fel: Felaktigt formaterad lista med mottagaradresser';
+$messages['smtperror'] = 'SMTP-fel: $msg';
 
-?>
\ No newline at end of file
+?>
index 0d1a73f66421726ce248a581833a2491e5aca95e..cb6419ed9671ac5d57f908827f98253396c189f0 100644 (file)
@@ -155,7 +155,6 @@ $labels['htmleditor'] = 'เขียนจดหมายแบบ HTML';
 $labels['htmlsignature'] = 'ลายมือชื่อแบบ HTML';
 $labels['previewpane'] = 'แสดงหน้าต่างตัวอย่างแสดงผล';
 $labels['autosavedraft'] = 'บันทึกเป็นจดหมายร่างอัตโนมัติ';
-$labels['everynminutes'] = 'ทุกๆ $n นาที';
 $labels['never'] = 'ไม่ใช้';
 $labels['folder'] = 'กล่องจดหมาย';
 $labels['folders'] = 'กล่องจดหมาย';
index 6212d4b197ae04af8e737d4c1309f78a1382b65b..d66a29a3d09dc66c2afac6e9aa756eb10c59f309 100644 (file)
@@ -14,7 +14,7 @@
 | Author: Gökdeniz Karadağ <gokdenizk@gmail.com>                        |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2827 2009-08-02 13:32:47Z yllar $
 
 */
 
@@ -117,10 +117,16 @@ $labels['markread'] = 'okunmuş olarak';
 $labels['markunread'] = 'okunmamış olarak';
 $labels['markflagged'] = 'işaretli olarak';
 $labels['markunflagged'] = 'işaretsiz olarak';
+$labels['messageactions'] = 'Diğer eylemler...';
 $labels['select'] = 'Seç';
 $labels['all'] = 'Hepsini';
 $labels['none'] = 'Hiçbirini';
 $labels['unread'] = 'Okunmamışları';
+$labels['flagged'] = 'İşaretlenmişleri';
+$labels['unanswered'] = 'Yanıtlanmamışları';
+$labels['deleted'] = 'Silinmişleri';
+$labels['invert'] = 'Seçimi Tersine Çevir';
+$labels['filter'] = 'Göster';
 $labels['compact'] = 'Sıklaştır';
 $labels['empty'] = 'Boşalt';
 $labels['purge'] = 'Sil';
@@ -129,8 +135,12 @@ $labels['unknown'] = 'bilinmeyen';
 $labels['unlimited'] = 'sınırsız';
 $labels['quicksearch'] = 'Hızlı arama';
 $labels['resetsearch'] = 'Aramayı bitir';
+$labels['searchmod'] = 'Arama detayları';
+$labels['msgtext'] = 'Tüm posta gövdesi';
 $labels['openinextwin'] = 'Yeni pencerede aç';
+$labels['emlsave'] = 'İndir (.eml)';
 $labels['compose'] = 'Yeni posta oluştur';
+$labels['editasnew'] = 'Postayı yeni olarak düzenle';
 $labels['savemessage'] = 'Taslak olarak kaydet';
 $labels['sendmessage'] = 'Postayı gönder';
 $labels['addattachment'] = 'Dosya ekle';
@@ -160,7 +170,6 @@ $labels['addcc'] = 'İlgili kopyası ekle';
 $labels['addbcc'] = 'Gizli kopya ekle';
 $labels['addreplyto'] = 'Yanıtlama adresi ekle';
 $labels['mdnrequest'] = 'Bu postayı gönderen kişi, postayı okuduğunuza dair alındı onayı istedi. Alındı onayını göndermek ister misiniz ?';
-$labels['mdnrequests'] = 'Alındı onayları';
 $labels['receiptread'] = 'Alındı Onayı (okundu)';
 $labels['yourmessage'] = 'Bu, postanız için alındı onayıdır';
 $labels['receiptnote'] = 'Not: Bu alındı onayı sadece postanızın alıcının bilgisayarında gösterildiğini belirtir. Alıcının posta içeriğini okuduğunu veya anladığını garantilemez.';
@@ -218,17 +227,31 @@ $labels['logoutcompact'] = 'Oturumu kapatınca Gelen Kutusunu sıklaştır';
 $labels['uisettings'] = 'Kullanıcı Arayüzü';
 $labels['serversettings'] = 'Sunucu Ayarları';
 $labels['mailboxview'] = 'Posta Kutusu Görünümü';
+$labels['mdnrequests'] = 'Alındı onayları';
 $labels['askuser'] = 'kullanıcıya sor';
 $labels['autosend'] = 'otomatik olarak gönder';
 $labels['ignore'] = 'gözardı et';
 $labels['readwhendeleted'] = 'Silinen postaları okunmuş olarak işaretle';
 $labels['flagfordeletion'] = 'Postaları silmek yerine silinecek olarak işaretle';
+$labels['skipdeleted'] = 'Silinmiş postaları gösterme';
+$labels['showremoteimages'] = 'Uzaktan yüklenen resimleri göster';
+$labels['fromknownsenders'] = 'bilinen göndericilerden';
+$labels['always'] = 'her zaman';
 $labels['showinlineimages'] = 'Postanın ekindeki resimleri postanın altında göster';
 $labels['autosavedraft'] = 'Taslağı otomatik kaydet:';
 $labels['everynminutes'] = 'her $n dakikada bir';
+$labels['keepalive'] = 'Yeni postaları denetle:';
 $labels['never'] = 'asla';
 $labels['messagesdisplaying'] = 'Posta Görüntüleme';
 $labels['messagescomposition'] = 'Yeni Posta Oluşturma';
+$labels['mimeparamfolding'] = 'Eklenti isimleri';
+$labels['2231folding'] = 'Tam RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Tam RFC 2047 (diğer)';
+$labels['advancedoptions'] = 'Gelişmiş seçenekler';
+$labels['focusonnewmessage'] = 'Yeni posta geldiğinde web tarayıcı penceresine odaklan.';
+$labels['checkallfolders'] = 'Tüm klasörlerdeki yeni postaları denetle';
+$labels['displaynext'] = 'Posta silindikten/taşındıktan sonra sıradaki postayı göster';
 $labels['folder'] = 'Klasör';
 $labels['folders'] = 'Klasörler';
 $labels['foldername'] = 'Klasör ismi';
@@ -244,27 +267,9 @@ $labels['specialfolders'] = 'Özel klasörler';
 $labels['sortby'] = 'Sırala';
 $labels['sortasc'] = 'Artarak';
 $labels['sortdesc'] = 'Azalarak';
-$labels['filter'] = 'Süzgeç';
-$labels['always'] = 'her zaman'; 
-$labels['fromknownsenders'] = 'bilinen göndericilerden';
-$labels['showremoteimages'] = 'Uzaktan yüklenen resimleri göster';
-$labels['checkallfolders'] = 'Tüm klasörlerdeki yeni postaları denetle';
-$labels['flagged'] = 'İşaretlenmiş'; 
-$labels['unanswered'] = 'Yanıtlanmamış';
-$labels['keepaliveevery']  = 'her $n dakikada bir'; 
-$labels['keepalive']  = 'Yeni postaları denetle:';
-$labels['focusonnewmessage'] = 'Yeni posta geldiğinde web tarayıcı penceresine odaklan.';
-$labels['skipdeleted'] = 'Silinmiş postaları gösterme';
-
-$labels['B'] = 'B'; 
-$labels['KB'] = 'KB'; 
-$labels['MB'] = 'MB'; 
-$labels['GB'] = 'GB'; 
-
-$labels['mimeparamfolding'] = 'Eklenti isimleri';
-$labels['2231folding'] = 'Tam RFC 2231 (Thunderbird)';
-$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
-$labels['2047folding'] = 'Tam RFC 2047 (diğer)';
-$labels['advancedoptions'] = 'Gelişmiş seçenekler';
+$labels['B'] = 'B';
+$labels['KB'] = 'KB';
+$labels['MB'] = 'MB';
+$labels['GB'] = 'GB';
 
 ?>
index bed3351bd1b5835b9b433da2a8f4be68c66d3946..a497d787f53153486e70be903db8c40ff3896eb6 100644 (file)
@@ -14,7 +14,7 @@
 | Author: Gökdeniz Karadağ <gokdenizk@gmail.com>                        |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: messages.inc 2827 2009-08-02 13:32:47Z yllar $
 
 */
 
@@ -23,6 +23,8 @@ $messages['loginfailed'] = 'Giriş Başarısız';
 $messages['cookiesdisabled'] = 'Tarayıcınız çerezleri kabul etmiyor';
 $messages['sessionerror'] = 'Oturumunuz sona ermiş veya hatalı';
 $messages['imaperror'] = 'IMAP sunucusuna bağlanılamadı';
+$messages['servererror'] = 'Sunucu Hatası!';
+$messages['invalidrequest'] = 'Geçersiz İstek! Veri kaydedilmedi';
 $messages['nomessagesfound'] = 'Posta kutusunda ileti bulunamadı';
 $messages['loggedout'] = 'Oturumu başarılı bir şekilde kapattınız. Güle güle!';
 $messages['mailboxempty'] = 'Posta kutusu boş';
@@ -46,6 +48,7 @@ $messages['errorsavingsent'] = 'Gönderilen postayı kaydederken hata oluştu';
 $messages['errorsaving'] = 'Kaydederken bir hata oluştu';
 $messages['errormoving'] = 'Posta taşınamadı';
 $messages['errordeleting'] = 'Posta silinemedi';
+$messages['errormarking'] = 'Posta işaretlenemedi';
 $messages['deletecontactconfirm'] = 'Seçili kişileri silmek istediğinizden emin misiniz?';
 $messages['deletemessagesconfirm'] = 'Seçili postaları silmek istediğinizden emin misiniz?';
 $messages['deletefolderconfirm'] = 'Bu klasörü silmek istediğinizden emin misiniz?';
@@ -53,11 +56,12 @@ $messages['purgefolderconfirm'] = 'Bu klasördeki tüm postaları silmek istedi
 $messages['foldercreating'] = 'Klasör oluştuluyor...';
 $messages['folderdeleting'] = 'Klasör siliniyor...';
 $messages['folderrenaming'] = 'Klasör yeniden adlandırılıyor...';
-$messages['foldermoving'] = 'Klasör taşınıyor...'; 
+$messages['foldermoving'] = 'Klasör taşınıyor...';
 $messages['formincomplete'] = 'Form tam olarak doldurulmadı';
 $messages['noemailwarning'] = 'Lütfen geçerli bir e-posta adresi girin';
 $messages['nonamewarning'] = 'Lütfen bir isim girin';
 $messages['nopagesizewarning'] = 'Lütfen bir sayfa boyutu girin';
+$messages['nosenderwarning'] = 'Lütfen gönderici e-posta adresini girin';
 $messages['norecipientwarning'] = 'Lütfen en az bir alıcı belirtin';
 $messages['nosubjectwarning'] = '"Konu" kutusu boş bırakılmış. Şimdi bir konu belirtmek ister misiniz?';
 $messages['nobodywarning'] = 'Postayı boş olarak gönder?';
@@ -92,8 +96,14 @@ $messages['importwait'] = 'Aktarılıyor, lütfen bekleyin...';
 $messages['importerror'] = 'İçe aktarma başarısız! Yüklenen dosya geçerli bir vCard dosyası değil';
 $messages['importconfirm'] = '<b>$inserted kişi başarıyla aktarıldı, halihazırda var olan $skipped kişi atlandı</b>:<p><em>$names</em></p>';
 $messages['opnotpermitted'] = 'Bu işleme izin verilmedi!';
-$messages['editorwarning'] = 'Düz metin düzenleyiciye geçmek, metin üzerindeki bütün biçimlendirmeleri kaldıracak. Devam etmek istiyor musunuz?';
 $messages['nofromaddress'] = 'Seçili kimlikte e-posta adresi yok';
-$messages['nosenderwarning'] = 'Lütfen gönderici e-posta adresini girin';
+$messages['editorwarning'] = 'Düz metin düzenleyiciye geçmek, metin üzerindeki bütün biçimlendirmeleri kaldıracak. Devam etmek istiyor musunuz?';
+$messages['httpreceivedencrypterror'] = 'Ayarlarda bir hata oluştu. Sistem yöneticinize haber verin. <b>Postanız gönderilemedi</b>';
+$messages['smtpconnerror'] = 'SMTP Hatası ($code): Sunucuya bağlanılamadı';
+$messages['smtpautherror'] = 'SMTP Hatası ($code): Kimlik doğrulama başarısız oldu';
+$messages['smtpfromerror'] = 'SMTP Hatası ($code): Gönderen adresi "$from" olarak ayarlanamadı';
+$messages['smtptoerror'] = 'SMTP Hatası ($code): "$to" alıcısı eklenemedi';
+$messages['smtprecipientserror'] = 'SMTP Hatası: Posta alıcılarının listesi ayrıştırılamadı';
+$messages['smtperror'] = 'SMTP Hatası: $msg';
 
 ?>
index 3484dcc43b5345d8faf5d13b65457cee712cf45b..06f65e4538782c727d77950071e8622adb5b1588 100644 (file)
@@ -232,7 +232,6 @@ $labels['always'] = 'завжди';
 $labels['showinlineimages'] = 'Показувати вкладені зображення внизу повідомлення';
 $labels['autosavedraft'] = 'Автозбереження чернетки';
 $labels['everynminutes'] = 'кожні $n хвилин';
-$labels['keepaliveevery'] = 'кожні $n хвилин';
 $labels['keepalive'] = 'Перевірка нових повідомлень';
 $labels['never'] = 'ніколи';
 $labels['messagesdisplaying'] = 'Відображення повідомлень';
index ca4b573c468073dcf2a51a1721a2d489b3990c4f..b4eca9f5ac15ddffe6a52f32127dc534279850fc 100644 (file)
-<?php\r
-\r
-/*\r
-\r
- +-----------------------------------------------------------------------+\r
- | language/vn/labels.inc                                                |\r
- |                                                                       |\r
+<?php
+
+/*
+
+ +-----------------------------------------------------------------------+
+ | language/vn/labels.inc                                                |
+ |                                                                       |
  | Language file of the RoundCube Webmail client                         |
  | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
- |                                                                       |\r
- +-----------------------------------------------------------------------+\r
- | Author: Vinh Bui <bqvinh@buivinh.info>                                |\r
- +-----------------------------------------------------------------------+\r
-\r
- @version $Id$\r
-\r
-*/\r
-\r
-$labels = array();\r
-\r
-// login page\r
-$labels['welcome']   = 'Xin mời sử dụng $product';\r
-$labels['username']  = 'Tên người dùng';\r
-$labels['password']  = 'Mật khẩu';\r
-$labels['server']    = 'Máy chủ?';\r
-$labels['login']     = 'Đăng nhập';\r
-\r
-// taskbar\r
-$labels['logout']   = 'Đăng xuất';\r
-$labels['mail']     = 'E-Mail';\r
-$labels['settings'] = 'Thiết lập';\r
-$labels['addressbook'] = 'Sổ địa chỉ';\r
-\r
-// mailbox names\r
-$labels['inbox']  = 'Inbox';\r
-$labels['drafts'] = 'Drafts';\r
-$labels['sent']   = 'Sent';\r
-$labels['trash']  = 'Trash';\r
-$labels['junk']   = 'Junk';\r
-\r
-// message listing\r
-$labels['subject'] = 'Tiêu đề';\r
-$labels['from']    = 'Người gửi';\r
-$labels['to']      = 'Người nhận';\r
-$labels['cc']      = 'Đồng nhận';\r
-$labels['bcc']     = 'Đồng nhận (2)';\r
-$labels['replyto'] = 'Trả lời vào';\r
-$labels['date']    = 'Ngày';\r
-$labels['size']    = 'D.Lượng';\r
-$labels['priority'] = 'Ưu tiên';\r
-$labels['organization'] = 'Cơ quan';\r
-\r
-// aliases\r
-$labels['reply-to'] = $labels['replyto'];\r
-\r
-$labels['mailboxlist'] = 'Thư mục';\r
-$labels['messagesfromto'] = 'Thư $from - $to / $count';\r
-$labels['messagenrof'] = 'Thư $nr / $count';\r
-\r
-$labels['moveto']   = 'chuyển đến...';\r
-$labels['download'] = 'tải xuống';\r
-\r
-$labels['filename'] = 'Tên file';\r
-$labels['filesize'] = 'Dung lượng';\r
-\r
-$labels['preferhtml'] = 'Dùng HTML';\r
-$labels['htmlmessage'] = 'Thư kiểu HTML';\r
-$labels['prettydate'] = 'Hiển thị ngày đầy đủ';\r
-\r
-$labels['addtoaddressbook'] = 'Thêm và sổ địa chỉ';\r
-\r
-// weekdays short\r
-$labels['sun'] = 'CN';\r
-$labels['mon'] = 'T2';\r
-$labels['tue'] = 'T3';\r
-$labels['wed'] = 'T4';\r
-$labels['thu'] = 'T5';\r
-$labels['fri'] = 'T6';\r
-$labels['sat'] = 'T7';\r
-\r
-// weekdays long\r
-$labels['sunday']    = 'Chủ nhật';\r
-$labels['monday']    = 'Thứ hai';\r
-$labels['tuesday']   = 'Thứ ba';\r
-$labels['wednesday'] = 'Thứ tư';\r
-$labels['thursday']  = 'Thứ năm';\r
-$labels['friday']    = 'Thứ sáu';\r
-$labels['saturday']  = 'Thứ bẩy';\r
-\r
-$labels['today'] = 'Hôm nay';\r
-\r
-// toolbar buttons\r
-$labels['checkmail']        = 'Kiểm tra thư mới';\r
-$labels['writenewmessage']  = 'Soạn thư mới';\r
-$labels['replytomessage']   = 'Trả lời thư';\r
-$labels['replytoallmessage'] = 'Trả lời tất cả';\r
-$labels['forwardmessage']   = 'Chuyển thư';\r
-$labels['deletemessage']    = 'Xóa thư';\r
-$labels['printmessage']     = 'In thư';\r
-$labels['previousmessages'] = 'Hiển thị các thư trước';\r
-$labels['nextmessages']     = 'Hiển thị các thư sau';\r
-$labels['backtolist']       = 'Trở về danh sách thư';\r
-$labels['viewsource']       = 'Hiển thị mã nguồn';\r
-\r
-$labels['select'] = 'Chọn';\r
-$labels['all'] = 'Toàn bộ';\r
-$labels['none'] = 'Bỏ chọn';\r
-$labels['unread'] = 'Chưa đọc';\r
-\r
-$labels['compact'] = 'Rút gọn';\r
-$labels['empty'] = 'Xóa rỗng';\r
-$labels['purge'] = 'Tối giản';\r
-\r
-$labels['quota'] = 'Hạn mức';\r
-$labels['unknown']  = 'không rõ';\r
-$labels['unlimited']  = 'không hạn chế';\r
-\r
-$labels['quicksearch']  = 'Tìm nhanh';\r
-$labels['resetsearch']  = 'Xóa bỏ tìm kiếm';\r
-\r
-// message compose\r
-$labels['compose']  = 'Soạn thư';\r
-$labels['savemessage']  = 'Lưu thư đang soạn';\r
-$labels['sendmessage']  = 'Gửi thư';\r
-$labels['addattachment']  = 'Gửi kèm';\r
-$labels['charset']  = 'Bộ ký tự';\r
-$labels['returnreceipt'] = 'Báo nhận';\r
-\r
-$labels['checkspelling'] = 'Kiểm tra chính tả';\r
-$labels['resumeediting'] = 'Soạn thảo';\r
-$labels['revertto'] = 'Chuyển về';\r
-\r
-$labels['attachments'] = 'Gửi kèm';\r
-$labels['upload'] = 'Tải lên';\r
-$labels['close']  = 'Đóng';\r
-\r
-$labels['low']     = 'Thấp';\r
-$labels['lowest']  = 'Thấp nhất';\r
-$labels['normal']  = 'Bình thường';\r
-$labels['high']    = 'Khẩn';\r
-$labels['highest'] = 'Thượng khẩn';\r
-\r
-$labels['nosubject']  = '(no subject)';\r
-$labels['showimages'] = 'Hiển thị ảnh';\r
-\r
-// address boook\r
-$labels['name']      = 'Tên hiển thị';\r
-$labels['firstname'] = 'Tên';\r
-$labels['surname']   = 'Họ';\r
-$labels['email']     = 'E-Mail';\r
-\r
-$labels['addcontact'] = 'Thêm mới địa chỉ';\r
-$labels['editcontact'] = 'Sửa địa chỉ cũ';\r
-\r
-$labels['edit']   = 'Sửa đổi';\r
-$labels['cancel'] = 'Ngưng';\r
-$labels['save']   = 'Lưu';\r
-$labels['delete'] = 'Xóa';\r
-\r
-$labels['newcontact']     = 'Thêm mới địa chỉ liên hệ';\r
-$labels['deletecontact']  = 'Xóa địa chỉ được chọn';\r
-$labels['composeto']      = 'Soạn thư cho';\r
-$labels['contactsfromto'] = 'Địa chỉ từ $from - $to / $count';\r
-$labels['print']          = 'In thư';\r
-$labels['export']         = 'Export';\r
-\r
-$labels['previouspage']   = 'Trang trước';\r
-$labels['nextpage']       = 'Trang tiếp';\r
-\r
-// LDAP search\r
-$labels['ldapsearch'] = 'LDAP directory search';\r
-\r
-$labels['ldappublicsearchname']    = 'Tên địa chỉ';\r
-$labels['ldappublicsearchtype'] = 'Khớp toàn bộ?';\r
-$labels['ldappublicserverselect'] = 'Chọn máy chủ';\r
-$labels['ldappublicsearchfield'] = 'Tìm trên';\r
-$labels['ldappublicsearchform'] = 'Tìm địa chỉ liên hệ';\r
-$labels['ldappublicsearch'] = 'Tìm kiếm';\r
-\r
-// settings\r
-$labels['settingsfor']  = 'Thiết lập cho';\r
-\r
-$labels['preferences']  = 'Tham số';\r
-$labels['userpreferences']  = 'Tham số người dùng';\r
-$labels['editpreferences']  = 'Sửa đổi';\r
-\r
-$labels['identities']  = 'Người dùng';\r
-$labels['manageidentities']  = 'Quản trị người dùng';\r
-$labels['newidentity']  = 'Người dùng mới';\r
-\r
-$labels['newitem']  = 'Thêm mới';\r
-$labels['edititem']  = 'Sửa đổi';\r
-\r
-$labels['setdefault']  = 'Thiết lập mặc định';\r
-$labels['language']  = 'Ngôn ngữ';\r
-$labels['timezone']  = 'Múi giờ';\r
-$labels['pagesize']  = 'Số dòng trên trang';\r
-$labels['signature'] = 'Chữ ký';\r
-$labels['dstactive']  = 'Giờ mùa hè';\r
-\r
-$labels['folder']  = 'Thư mục';\r
-$labels['folders']  = 'Thư mục';\r
-$labels['foldername']  = 'Tên thư mục';\r
-$labels['subscribed']  = 'Cho sử dụng';\r
-$labels['create']  = 'Tạo';\r
-$labels['createfolder']  = 'Tạo thư mục mới';\r
-$labels['rename'] = 'Đổi tên';\r
-$labels['renamefolder'] = 'Đổi tên thư mục';\r
-$labels['deletefolder']  = 'Xóa thư mục';\r
-$labels['managefolders']  = 'Quản trị thư mục';\r
-\r
-$labels['sortby'] = 'Sắp xếp';\r
-$labels['sortasc']  = 'Xếp tăng dần';\r
-$labels['sortdesc'] = 'Xếp giảm dần';\r
-\r
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Vinh Bui <bqvinh@buivinh.info>                                |
+ +-----------------------------------------------------------------------+
+
+ @version $Id$
+
+*/
+
+$labels = array();
+
+// login page
+$labels['welcome']   = 'Xin mời sử dụng $product';
+$labels['username']  = 'Tên người dùng';
+$labels['password']  = 'Mật khẩu';
+$labels['server']    = 'Máy chủ?';
+$labels['login']     = 'Đăng nhập';
+
+// taskbar
+$labels['logout']   = 'Đăng xuất';
+$labels['mail']     = 'E-Mail';
+$labels['settings'] = 'Thiết lập';
+$labels['addressbook'] = 'Sổ địa chỉ';
+
+// mailbox names
+$labels['inbox']  = 'Inbox';
+$labels['drafts'] = 'Drafts';
+$labels['sent']   = 'Sent';
+$labels['trash']  = 'Trash';
+$labels['junk']   = 'Junk';
+
+// message listing
+$labels['subject'] = 'Tiêu đề';
+$labels['from']    = 'Người gửi';
+$labels['to']      = 'Người nhận';
+$labels['cc']      = 'Đồng nhận';
+$labels['bcc']     = 'Đồng nhận (2)';
+$labels['replyto'] = 'Trả lời vào';
+$labels['date']    = 'Ngày';
+$labels['size']    = 'D.Lượng';
+$labels['priority'] = 'Ưu tiên';
+$labels['organization'] = 'Cơ quan';
+
+// aliases
+$labels['reply-to'] = $labels['replyto'];
+
+$labels['mailboxlist'] = 'Thư mục';
+$labels['messagesfromto'] = 'Thư $from - $to / $count';
+$labels['messagenrof'] = 'Thư $nr / $count';
+
+$labels['moveto']   = 'chuyển đến...';
+$labels['download'] = 'tải xuống';
+
+$labels['filename'] = 'Tên file';
+$labels['filesize'] = 'Dung lượng';
+
+$labels['preferhtml'] = 'Dùng HTML';
+$labels['htmlmessage'] = 'Thư kiểu HTML';
+$labels['prettydate'] = 'Hiển thị ngày đầy đủ';
+
+$labels['addtoaddressbook'] = 'Thêm và sổ địa chỉ';
+
+// weekdays short
+$labels['sun'] = 'CN';
+$labels['mon'] = 'T2';
+$labels['tue'] = 'T3';
+$labels['wed'] = 'T4';
+$labels['thu'] = 'T5';
+$labels['fri'] = 'T6';
+$labels['sat'] = 'T7';
+
+// weekdays long
+$labels['sunday']    = 'Chủ nhật';
+$labels['monday']    = 'Thứ hai';
+$labels['tuesday']   = 'Thứ ba';
+$labels['wednesday'] = 'Thứ tư';
+$labels['thursday']  = 'Thứ năm';
+$labels['friday']    = 'Thứ sáu';
+$labels['saturday']  = 'Thứ bẩy';
+
+$labels['today'] = 'Hôm nay';
+
+// toolbar buttons
+$labels['checkmail']        = 'Kiểm tra thư mới';
+$labels['writenewmessage']  = 'Soạn thư mới';
+$labels['replytomessage']   = 'Trả lời thư';
+$labels['replytoallmessage'] = 'Trả lời tất cả';
+$labels['forwardmessage']   = 'Chuyển thư';
+$labels['deletemessage']    = 'Xóa thư';
+$labels['printmessage']     = 'In thư';
+$labels['previousmessages'] = 'Hiển thị các thư trước';
+$labels['nextmessages']     = 'Hiển thị các thư sau';
+$labels['backtolist']       = 'Trở về danh sách thư';
+$labels['viewsource']       = 'Hiển thị mã nguồn';
+
+$labels['select'] = 'Chọn';
+$labels['all'] = 'Toàn bộ';
+$labels['none'] = 'Bỏ chọn';
+$labels['unread'] = 'Chưa đọc';
+
+$labels['compact'] = 'Rút gọn';
+$labels['empty'] = 'Xóa rỗng';
+$labels['purge'] = 'Tối giản';
+
+$labels['quota'] = 'Hạn mức';
+$labels['unknown']  = 'không rõ';
+$labels['unlimited']  = 'không hạn chế';
+
+$labels['quicksearch']  = 'Tìm nhanh';
+$labels['resetsearch']  = 'Xóa bỏ tìm kiếm';
+
+// message compose
+$labels['compose']  = 'Soạn thư';
+$labels['savemessage']  = 'Lưu thư đang soạn';
+$labels['sendmessage']  = 'Gửi thư';
+$labels['addattachment']  = 'Gửi kèm';
+$labels['charset']  = 'Bộ ký tự';
+$labels['returnreceipt'] = 'Báo nhận';
+
+$labels['checkspelling'] = 'Kiểm tra chính tả';
+$labels['resumeediting'] = 'Soạn thảo';
+$labels['revertto'] = 'Chuyển về';
+
+$labels['attachments'] = 'Gửi kèm';
+$labels['upload'] = 'Tải lên';
+$labels['close']  = 'Đóng';
+
+$labels['low']     = 'Thấp';
+$labels['lowest']  = 'Thấp nhất';
+$labels['normal']  = 'Bình thường';
+$labels['high']    = 'Khẩn';
+$labels['highest'] = 'Thượng khẩn';
+
+$labels['nosubject']  = '(no subject)';
+$labels['showimages'] = 'Hiển thị ảnh';
+
+// address boook
+$labels['name']      = 'Tên hiển thị';
+$labels['firstname'] = 'Tên';
+$labels['surname']   = 'Họ';
+$labels['email']     = 'E-Mail';
+
+$labels['addcontact'] = 'Thêm mới địa chỉ';
+$labels['editcontact'] = 'Sửa địa chỉ cũ';
+
+$labels['edit']   = 'Sửa đổi';
+$labels['cancel'] = 'Ngưng';
+$labels['save']   = 'Lưu';
+$labels['delete'] = 'Xóa';
+
+$labels['newcontact']     = 'Thêm mới địa chỉ liên hệ';
+$labels['deletecontact']  = 'Xóa địa chỉ được chọn';
+$labels['composeto']      = 'Soạn thư cho';
+$labels['contactsfromto'] = 'Địa chỉ từ $from - $to / $count';
+$labels['print']          = 'In thư';
+$labels['export']         = 'Export';
+
+$labels['previouspage']   = 'Trang trước';
+$labels['nextpage']       = 'Trang tiếp';
+
+// LDAP search
+$labels['ldapsearch'] = 'LDAP directory search';
+
+$labels['ldappublicsearchname']    = 'Tên địa chỉ';
+$labels['ldappublicsearchtype'] = 'Khớp toàn bộ?';
+$labels['ldappublicserverselect'] = 'Chọn máy chủ';
+$labels['ldappublicsearchfield'] = 'Tìm trên';
+$labels['ldappublicsearchform'] = 'Tìm địa chỉ liên hệ';
+$labels['ldappublicsearch'] = 'Tìm kiếm';
+
+// settings
+$labels['settingsfor']  = 'Thiết lập cho';
+
+$labels['preferences']  = 'Tham số';
+$labels['userpreferences']  = 'Tham số người dùng';
+$labels['editpreferences']  = 'Sửa đổi';
+
+$labels['identities']  = 'Người dùng';
+$labels['manageidentities']  = 'Quản trị người dùng';
+$labels['newidentity']  = 'Người dùng mới';
+
+$labels['newitem']  = 'Thêm mới';
+$labels['edititem']  = 'Sửa đổi';
+
+$labels['setdefault']  = 'Thiết lập mặc định';
+$labels['language']  = 'Ngôn ngữ';
+$labels['timezone']  = 'Múi giờ';
+$labels['pagesize']  = 'Số dòng trên trang';
+$labels['signature'] = 'Chữ ký';
+$labels['dstactive']  = 'Giờ mùa hè';
+
+$labels['folder']  = 'Thư mục';
+$labels['folders']  = 'Thư mục';
+$labels['foldername']  = 'Tên thư mục';
+$labels['subscribed']  = 'Cho sử dụng';
+$labels['create']  = 'Tạo';
+$labels['createfolder']  = 'Tạo thư mục mới';
+$labels['rename'] = 'Đổi tên';
+$labels['renamefolder'] = 'Đổi tên thư mục';
+$labels['deletefolder']  = 'Xóa thư mục';
+$labels['managefolders']  = 'Quản trị thư mục';
+
+$labels['sortby'] = 'Sắp xếp';
+$labels['sortasc']  = 'Xếp tăng dần';
+$labels['sortdesc'] = 'Xếp giảm dần';
+
 ?>
\ No newline at end of file
index 69b4dfd7f3ffef142bef537e340208e5797db2a8..465b04ea83f43a0987d5f0c291a111643454a816 100644 (file)
@@ -1,66 +1,66 @@
-<?php\r
-\r
-/*\r
-\r
- +-----------------------------------------------------------------------+\r
- | language/vn/messages.inc                                              |\r
- |                                                                       |\r
+<?php
+
+/*
+
+ +-----------------------------------------------------------------------+
+ | language/vn/messages.inc                                              |
+ |                                                                       |
  | Language file of the RoundCube Webmail client                         |
  | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
- |                                                                       |\r
- +-----------------------------------------------------------------------+\r
- | Author: Vinh Bui <bqvinh@buivinh.info>                                |\r
- +-----------------------------------------------------------------------+\r
-\r
- @version $Id$\r
-\r
-*/\r
-\r
-$messages = array();\r
-$messages['loginfailed']  = 'Không đăng nhập được';\r
-$messages['cookiesdisabled'] = 'Trình duyệt không hỗ trợ cookies';\r
-$messages['sessionerror'] = 'Phiên làm việc không hợp lệ hoặc đã hết hạn';\r
-$messages['imaperror'] = 'Không kết nối được với máy chủ IMAP';\r
-$messages['nomessagesfound'] = 'Không có thư trong hòm thư này';\r
-$messages['loggedout'] = 'Phiên làm việc đã kết thúc. Hẹn gặp lại!';\r
-$messages['mailboxempty'] = 'Hộp thư rỗng';\r
-$messages['loading'] = 'Vui lòng chờ trong giây lát...';\r
-$messages['loadingdata'] = 'Đang nạp dữ liệu...';\r
-$messages['checkingmail'] = 'Kiểm tra thư mới...';\r
-$messages['sendingmessage'] = 'Đang gửi thư...';\r
-$messages['messagesent'] = 'Thư đã được gửi';\r
-$messages['savingmessage'] = 'Đang lưu thư...';\r
-$messages['messagesaved'] = 'Thư đã được gửi vào ngăn Drafts';\r
-$messages['successfullysaved'] = 'Đã lưu thành công';\r
-$messages['addedsuccessfully'] = 'Địa chỉ liên hệ đã được lưu';\r
-$messages['contactexists'] = 'Địa chỉ liên hệ với e-mail này đã được lưu trước đây';\r
-$messages['blockedimages'] = 'Để bảo vệ tính riêng tư, chức năng hiện ảnh từ xa bị cấm trong thư này.';\r
-$messages['encryptedmessage'] = 'Thư này được mã hóa, không thể xem. Rất tiếc!';\r
-$messages['nocontactsfound'] = 'Không tìm thấy địa chỉ liên hệ';\r
-$messages['sendingfailed'] = 'Không gửi được thư';\r
-$messages['errorsaving'] = 'Lỗi khi lưu';\r
-$messages['errormoving'] = 'Không thể chuyển được thư';\r
-$messages['errordeleting'] = 'Không thể xóa được thư';\r
-$messages['deletecontactconfirm']  = 'Xóa bỏ các địa chỉ được chọn?';\r
-$messages['deletefolderconfirm']  = 'Xóa bỏ thư mục này?';\r
-$messages['purgefolderconfirm']  = 'Xóa toàn bộ thư trong thư mục nào?';\r
-$messages['formincomplete'] = 'Mẫu chưa được điền xong';\r
-$messages['noemailwarning'] = 'Nhập địa chỉ email';\r
-$messages['nonamewarning']  = 'Nhập tên';\r
-$messages['nopagesizewarning'] = 'Nhập kích cỡ của trang';\r
-$messages['norecipientwarning'] = 'Thư cần có it nhất 1 người nhận';\r
-$messages['nosubjectwarning']  = 'Mục "Tiêu đề" chưa có. Điền tiêu đề ?';\r
-$messages['nobodywarning'] = 'Thư không nội dung, vẫn tiếp tục gửi?';\r
-$messages['notsentwarning'] = 'Thư chưa được gửi. Bỏ qua thư đang soạn?';\r
-$messages['noldapserver'] = 'Chọn máy chủ ldap server để tìm';\r
-$messages['nocontactsreturned'] = 'Không tìm thấy địa chỉ';\r
-$messages['nosearchname'] = 'Nhập địa chỉ hoặc email';\r
-$messages['searchsuccessful'] = '$nr messages found';\r
-$messages['searchnomatch'] = 'Không tìm thấy';\r
-$messages['searching'] = 'Tìm kiếm...';\r
-$messages['checking'] = 'Kiểm tra...';\r
-$messages['nospellerrors'] = 'Không có lỗi chính tả';\r
-$messages['folderdeleted'] = 'Thư mục đã được xóa';\r
-\r
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Vinh Bui <bqvinh@buivinh.info>                                |
+ +-----------------------------------------------------------------------+
+
+ @version $Id$
+
+*/
+
+$messages = array();
+$messages['loginfailed']  = 'Không đăng nhập được';
+$messages['cookiesdisabled'] = 'Trình duyệt không hỗ trợ cookies';
+$messages['sessionerror'] = 'Phiên làm việc không hợp lệ hoặc đã hết hạn';
+$messages['imaperror'] = 'Không kết nối được với máy chủ IMAP';
+$messages['nomessagesfound'] = 'Không có thư trong hòm thư này';
+$messages['loggedout'] = 'Phiên làm việc đã kết thúc. Hẹn gặp lại!';
+$messages['mailboxempty'] = 'Hộp thư rỗng';
+$messages['loading'] = 'Vui lòng chờ trong giây lát...';
+$messages['loadingdata'] = 'Đang nạp dữ liệu...';
+$messages['checkingmail'] = 'Kiểm tra thư mới...';
+$messages['sendingmessage'] = 'Đang gửi thư...';
+$messages['messagesent'] = 'Thư đã được gửi';
+$messages['savingmessage'] = 'Đang lưu thư...';
+$messages['messagesaved'] = 'Thư đã được gửi vào ngăn Drafts';
+$messages['successfullysaved'] = 'Đã lưu thành công';
+$messages['addedsuccessfully'] = 'Địa chỉ liên hệ đã được lưu';
+$messages['contactexists'] = 'Địa chỉ liên hệ với e-mail này đã được lưu trước đây';
+$messages['blockedimages'] = 'Để bảo vệ tính riêng tư, chức năng hiện ảnh từ xa bị cấm trong thư này.';
+$messages['encryptedmessage'] = 'Thư này được mã hóa, không thể xem. Rất tiếc!';
+$messages['nocontactsfound'] = 'Không tìm thấy địa chỉ liên hệ';
+$messages['sendingfailed'] = 'Không gửi được thư';
+$messages['errorsaving'] = 'Lỗi khi lưu';
+$messages['errormoving'] = 'Không thể chuyển được thư';
+$messages['errordeleting'] = 'Không thể xóa được thư';
+$messages['deletecontactconfirm']  = 'Xóa bỏ các địa chỉ được chọn?';
+$messages['deletefolderconfirm']  = 'Xóa bỏ thư mục này?';
+$messages['purgefolderconfirm']  = 'Xóa toàn bộ thư trong thư mục nào?';
+$messages['formincomplete'] = 'Mẫu chưa được điền xong';
+$messages['noemailwarning'] = 'Nhập địa chỉ email';
+$messages['nonamewarning']  = 'Nhập tên';
+$messages['nopagesizewarning'] = 'Nhập kích cỡ của trang';
+$messages['norecipientwarning'] = 'Thư cần có it nhất 1 người nhận';
+$messages['nosubjectwarning']  = 'Mục "Tiêu đề" chưa có. Điền tiêu đề ?';
+$messages['nobodywarning'] = 'Thư không nội dung, vẫn tiếp tục gửi?';
+$messages['notsentwarning'] = 'Thư chưa được gửi. Bỏ qua thư đang soạn?';
+$messages['noldapserver'] = 'Chọn máy chủ ldap server để tìm';
+$messages['nocontactsreturned'] = 'Không tìm thấy địa chỉ';
+$messages['nosearchname'] = 'Nhập địa chỉ hoặc email';
+$messages['searchsuccessful'] = '$nr messages found';
+$messages['searchnomatch'] = 'Không tìm thấy';
+$messages['searching'] = 'Tìm kiếm...';
+$messages['checking'] = 'Kiểm tra...';
+$messages['nospellerrors'] = 'Không có lỗi chính tả';
+$messages['folderdeleted'] = 'Thư mục đã được xóa';
+
 ?>
\ No newline at end of file
index 630b25cb6c65bc3cee04e1e58ae36be117e94635..e108adf66a421ce6a194ada098faed2bb025ff17 100644 (file)
@@ -14,7 +14,7 @@
 |         Zhang Huang bin <michaelbibby@gmail.com>                      |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2237 2009-01-17 01:55:39Z till $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -232,8 +232,7 @@ $labels['fromknownsenders'] = '来自未知的发件人';
 $labels['always'] = '总是';
 $labels['showinlineimages'] = '在邮件下方显示附件中的图片';
 $labels['autosavedraft'] = '自动保存到草稿箱';
-$labels['everynminutes'] = '第 $n 分钟';
-$labels['keepaliveevery'] = '每隔 $n 分钟';
+$labels['everynminutes'] = '每隔 $n 分钟';
 $labels['keepalive'] = '检查新邮件';
 $labels['never'] = '从不';
 $labels['messagesdisplaying'] = '邮件显示设置';
index 355c635d403b442ef11f1980e5df3e3ada67bb20..48b458b1be3cd58ed7e530e826119ed1ed5b1b4f 100644 (file)
@@ -15,7 +15,7 @@
 |         Ting-Hung Chiu <earrl@mmlab.cse.yzu.edu.tw>                   |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: labels.inc 2513 2009-05-21 12:59:19Z alec $
 
 */
 
@@ -236,7 +236,6 @@ $labels['always'] = '總是接受';
 $labels['showinlineimages'] = '將附加檔案的圖片顯示於郵件最後';
 $labels['autosavedraft'] = '自動儲存草稿';
 $labels['everynminutes'] = '每 $n 分鐘';
-$labels['keepaliveevery'] = '每 $n 分鐘';
 $labels['keepalive'] = '檢查新郵件的間隔時間';
 $labels['never'] = '絕對不要';
 $labels['messagesdisplaying'] = '郵件顯示設定';
index 47f0234b4ab0a215696add8fc96a409ea2e641a0..257bbc31bc84cd87f819a12359b9f191b99f5f98 100644 (file)
@@ -15,7 +15,7 @@
 |         Ting-Hung Chiu <earrl@mmlab.cse.yzu.edu.tw>                   |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 2483 2009-05-15 10:22:29Z thomasb $
+@version $Id: messages.inc 2470 2009-05-12 20:04:11Z yllar $
 
 */
 
index 268903bf53398c593630716745ae954805d60675..a27b67b09211b0cd95a28e6ef82bcfc6ebadeb24 100644 (file)
 
 */
 
+// only process ajax requests
+if (!$OUTPUT->ajax_call)
+  return;
+
 $cid = get_input_value('_cid', RCUBE_INPUT_POST);
 $target = get_input_value('_to', RCUBE_INPUT_POST);
 if ($cid && preg_match('/^[a-z0-9\-_=]+(,[a-z0-9\-_=]+)*$/i', $cid) && strlen($target) && $target != $source)
@@ -26,8 +30,13 @@ if ($cid && preg_match('/^[a-z0-9\-_=]+(,[a-z0-9\-_=]+)*$/i', $cid) && strlen($t
   $success = false;
   $TARGET = $RCMAIL->get_address_book($target);
 
-  if ($TARGET && $TARGET->ready && !$TARGET->readonly)
-    $success = $TARGET->insert($CONTACTS->search($CONTACTS->primary_key, $cid), true);
+  if ($TARGET && $TARGET->ready && !$TARGET->readonly) {
+    $plugin = $RCMAIL->plugins->exec_hook('create_contact', array('record' => $CONTACTS->search($CONTACTS->primary_key, $cid), 'source' => $target));
+    $a_record = $plugin['record'];
+
+    if (!$plugin['abort'])
+      $success = $TARGET->insert($CONTACTS->search($a_record, true));
+  }
 
   if (empty($success))
     $OUTPUT->show_message('copyerror', 'error');
@@ -41,4 +50,4 @@ if ($cid && preg_match('/^[a-z0-9\-_=]+(,[a-z0-9\-_=]+)*$/i', $cid) && strlen($t
 // send response
 $OUTPUT->send();
 
-?>
\ No newline at end of file
+?>
index d429dbad6a59089a4595826daee46115441a89b1..9919a2d12c75c6c21464b824578f16aa36fbdf37 100644 (file)
@@ -5,7 +5,7 @@
  | program/steps/addressbook/delete.inc                                  |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: delete.inc 1361 2008-05-07 22:16:00Z richs $
+ $Id: delete.inc 2758 2009-07-16 15:01:05Z thomasb $
 
 */
 
-if (($cid = get_input_value('_cid', RCUBE_INPUT_POST)) &&
+if ($OUTPUT->ajax_call &&
+    ($cid = get_input_value('_cid', RCUBE_INPUT_POST)) &&
     (preg_match('/^[0-9]+(,[0-9]+)*$/', $cid) ||
      preg_match('/^[a-zA-Z0-9=]+(,[a-zA-Z0-9=]+)*$/', $cid))
    )
   {
-  $deleted = $CONTACTS->delete($cid);
+  $plugin = $RCMAIL->plugins->exec_hook('delete_contact', array('id' => $cid, 'source' => get_input_value('_source', RCUBE_INPUT_GPC)));
+  
+  $deleted = !$plugin['abort'] ? $CONTACTS->delete($cid) : false;
   if (!$deleted)
     {
     // send error message
index d18cf883598421be0d853d1b7d77e949e1c1e7ee..0657969db26d66bc5a11e6fffe45ebd7a192f4f1 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: edit.inc 1939 2008-10-05 07:18:15Z alec $
+ $Id: edit.inc 2755 2009-07-15 09:49:35Z thomasb $
 
 */
 
@@ -81,36 +81,27 @@ $OUTPUT->add_handler('contacteditform', 'rcmail_contact_editform');
 
 // similar function as in /steps/settings/edit_identity.inc
 function get_form_tags($attrib)
-  {
+{
   global $CONTACTS, $EDIT_FORM, $RCMAIL;
 
-  $result = $CONTACTS->get_result();
-  $form_start = '';
-  if (!strlen($EDIT_FORM))
-    {
-    $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task));
-    $hiddenfields->add(array('name' => '_action', 'value' => 'save'));
-    $hiddenfields->add(array('name' => '_source', 'value' => get_input_value('_source', RCUBE_INPUT_GPC)));
-    $hiddenfields->add(array('name' => '_framed', 'value' => (empty($_REQUEST['_framed']) ? 0 : 1)));
+  $form_start = $form_end = '';
+  
+  if (empty($EDIT_FORM)) {
+    $hiddenfields = new html_hiddenfield(array('name' => '_source', 'value' => get_input_value('_source', RCUBE_INPUT_GPC)));
     
     if (($result = $CONTACTS->get_result()) && ($record = $result->first()))
       $hiddenfields->add(array('name' => '_cid', 'value' => $record['ID']));
     
-    $form_start = !strlen($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : '';
-    $form_start .= $hiddenfields->show();
-    }
-    
-  $form_end = (strlen($EDIT_FORM) && !strlen($attrib['form'])) ? '</form>' : '';
-  $form_name = strlen($attrib['form']) ? $attrib['form'] : 'form';
-  
-  if (!strlen($EDIT_FORM))
-    $RCMAIL->output->add_gui_object('editform', $form_name);
-  
-  $EDIT_FORM = $form_name;
+    $form_start = $RCMAIL->output->request_form(array('name' => "form", 'method' => "post", 'task' => $RCMAIL->task, 'action' => 'save', 'request' => 'save.'.intval($record['ID']), 'noclose' => true) + $attrib, $hiddenfields->show());
+    $form_end = !strlen($attrib['form']) ? '</form>' : '';
 
-  return array($form_start, $form_end); 
+    $EDIT_FORM = !empty($attrib['form']) ? $attrib['form'] : 'form';
+    $RCMAIL->output->add_gui_object('editform', $EDIT_FORM);
   }
 
+  return array($form_start, $form_end); 
+}
+
 
 
 if (!$CONTACTS->get_result() && $OUTPUT->template_exists('addcontact'))
index d49fbe997eccdb9d09e94d879f288a37c1731fcd..101006f87f32cb97a45f391e3a25bcbfb0f4a9a8 100644 (file)
@@ -26,7 +26,7 @@ $result = $CONTACTS->list_records();
 
 // send downlaod headers
 send_nocacheing_headers();
-header('Content-Type: text/x-vcard; charset=UTF-8');
+header('Content-Type: text/x-vcard; charset='.RCMAIL_CHARSET);
 header('Content-Disposition: attachment; filename="rcube_contacts.vcf"');
 
 while ($result && ($row = $result->next())) {
index d87c2f892ebf02bd15ff269bbf0c7e986b342e55..e14d8a8f7776e2a89218e3f633af9913bf633590 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 1939 2008-10-05 07:18:15Z alec $
+ $Id: func.inc 2894 2009-08-29 20:56:00Z alec $
 
 */
 
+// add list of address sources to client env
+$js_list = array();
+if (strtolower($CONFIG['address_book_type']) != 'ldap') {
+  // We are using the DB address book, add it.
+  $js_list['0'] = array('id' => 0, 'name' => rcube_label('personaladrbook'), 'readonly' => false);
+}
+if (is_array($CONFIG['ldap_public'])) {
+  foreach ($CONFIG['ldap_public'] as $id => $prop)
+    $js_list[$id] = array('id' => $id, 'name' => $prop['name'], 'readonly' => !$prop['writable']);
+}
+
+$plugin = $RCMAIL->plugins->exec_hook('address_sources', array('sources' => $js_list));
+$js_list = $plugin['sources'];
+
+// select source
+$source = get_input_value('_source', RCUBE_INPUT_GPC);
+
+// if source is not set use first directory
+if (empty($source))
+  $source = $js_list[key($js_list)]['id'];
+
+
 // instantiate a contacts object according to the given source
-$CONTACTS = $RCMAIL->get_address_book(($source = get_input_value('_source', RCUBE_INPUT_GPC)));
+$CONTACTS = $RCMAIL->get_address_book($source);
 
 $CONTACTS->set_pagesize($CONFIG['pagesize']);
 
@@ -37,23 +59,12 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
 // set data source env
 $OUTPUT->set_env('source', $source ? $source : '0');
 $OUTPUT->set_env('readonly', $CONTACTS->readonly, false);
-
-// add list of address sources to client env
-$js_list = array();
-if (strtolower($CONFIG['address_book_type']) != 'ldap') {
-  // We are using the DB address book, add it.
-  $js_list = array("0" => array('id' => 0, 'readonly' => false));
-}
-if (is_array($CONFIG['ldap_public'])) {
-  foreach ($CONFIG['ldap_public'] as $id => $prop)
-    $js_list[$id] = array('id' => $id, 'readonly' => !$prop['writable']);
-}
 $OUTPUT->set_env('address_sources', $js_list);
 
 
 function rcmail_directory_list($attrib)
 {
-  global $CONFIG, $OUTPUT;
+  global $RCMAIL, $OUTPUT;
   
   if (!$attrib['id'])
     $attrib['id'] = 'rcmdirectorylist';
@@ -63,26 +74,24 @@ function rcmail_directory_list($attrib)
   $current = get_input_value('_source', RCUBE_INPUT_GPC);
   $line_templ = html::tag('li', array('id' => 'rcmli%s', 'class' => '%s'),
     html::a(array('href' => '%s', 'onclick' => "return ".JS_OBJECT_NAME.".command('list','%s',this)"), '%s'));
-    
-  if (strtolower($CONFIG['address_book_type']) != 'ldap') {
-    $out .= sprintf($line_templ, $local_id, (!$current ? 'selected' : ''),
-      Q(rcmail_url(null, array('_source' => $local_id))), $local_id, rcube_label('personaladrbook'));
-  } // end if
-  else {
+
+  if (!$current && strtolower($RCMAIL->config->get('address_book_type', 'sql')) != 'ldap') {
+    $current = '0';
+  }
+  else if (!$current) {
     // DB address book not used, see if a source is set, if not use the
     // first LDAP directory.
-    if (!$current) {
-      $current = key((array)$CONFIG['ldap_public']);
-    } // end if
-  } // end else
-  
-  foreach ((array)$CONFIG['ldap_public'] as $id => $prop) {
+    $current = key((array)$RCMAIL->config->get('ldap_public', array()));
+  }
+
+  foreach ((array)$OUTPUT->env['address_sources'] as $j => $source) {
+    $id = $source['id'] ? $source['id'] : $j;
     $js_id = JQ($id);
     $dom_id = preg_replace('/[^a-z0-9\-_]/i', '', $id);
     $out .= sprintf($line_templ, $dom_id, ($current == $id ? 'selected' : ''),
-      Q(rcmail_url(null, array('_source' => $id))), $js_id, (!empty($prop['name']) ? Q($prop['name']) : Q($id)));
+      Q(rcmail_url(null, array('_source' => $id))), $js_id, (!empty($source['name']) ? Q($source['name']) : Q($id)));
   }
-  
+
   $OUTPUT->add_gui_object('folderlist', $attrib['id']);
   
   return html::tag('ul', $attrib, $out, html::$common_attrib);
index 8140a85266e9a749c9c6717380d1b84f8194c730..1d5b00e1a0e68a1ff9866448f5b7ea5267523dea 100644 (file)
@@ -75,18 +75,18 @@ function rcmail_import_buttons($attrib)
 {
   global $IMPORT_STATS, $OUTPUT;
   
-  $attrib += array('type' => "input");
+  $attrib += array('type' => 'input');
   unset($attrib['name']);
   
   if (is_object($IMPORT_STATS)) {
     $attrib['class'] = trim($attrib['class'] . ' mainaction');
-    $out = $OUTPUT->button(array('command' => "list", 'label' => "done") + $attrib);
+    $out = $OUTPUT->button(array('command' => 'list', 'label' => 'done') + $attrib);
   }
   else {
-    $out = $OUTPUT->button(array('command' => "list", 'label' => "cancel") + $attrib);
+    $out = $OUTPUT->button(array('command' => 'list', 'label' => 'cancel') + $attrib);
     $out .= '&nbsp;';
     $attrib['class'] = trim($attrib['class'] . ' mainaction');
-    $out .= $OUTPUT->button(array('command' => "import", 'label' => "import") + $attrib);
+    $out .= $OUTPUT->button(array('command' => 'import', 'label' => 'import') + $attrib);
   }
   
   return $out;
@@ -142,19 +142,22 @@ if ($_FILES['_file']['tmp_name'] && is_uploaded_file($_FILES['_file']['tmp_name'
         }
       }
       
-      $success = $CONTACTS->insert(array(
+      $a_record = array(
         'name' => $vcard->displayname,
         'firstname' => $vcard->firstname,
         'surname' => $vcard->surname,
         'email' => $email,
         'vcard' => $vcard->export(),
-      ));
+      );
       
-      if ($success) {
+      $plugin = $RCMAIL->plugins->exec_hook('create_contact', array('record' => $a_record, 'source' => null));
+      $a_record = $plugin['record'];
+
+      // insert record and send response
+      if (!$plugin['abort'] && ($success = $CONTACTS->insert($a_record))) {
         $IMPORT_STATS->inserted++;
         $IMPORT_STATS->names[] = $vcard->displayname;
-      }
-      else {
+      } else {
         $IMPORT_STATS->errors++;
       }
     }
@@ -165,8 +168,7 @@ if ($_FILES['_file']['tmp_name'] && is_uploaded_file($_FILES['_file']['tmp_name'
 else if ($err = $_FILES['_file']['error']) {
   if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
     $OUTPUT->show_message('filesizeerror', 'error', array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize')))));
-  }
-  else {
+  } else {
     $OUTPUT->show_message('fileuploaderror', 'error');
   }
 }
index 234a3c9909e8be5f85fae15b72b1ee6f5c317295..4b9a018d234570eeb08504f4f871790d6b75958c 100644 (file)
@@ -5,7 +5,7 @@
  | program/steps/addressbook/save.inc                                    |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: save.inc 1407 2008-05-19 17:47:45Z thomasb $
+ $Id: save.inc 2889 2009-08-29 18:41:17Z alec $
 
 */
 
+$cid = get_input_value('_cid', RCUBE_INPUT_POST);
+$return_action = empty($cid) ? 'add' : 'show';
+
 // cannot edit record
 if ($CONTACTS->readonly)
 {
   $OUTPUT->show_message('contactreadonly', 'error');
-  rcmail_overwrite_action(empty($_POST['_cid']) ? 'add' : 'show');
+  rcmail_overwrite_action($return_action);
   return;
 }
 
@@ -31,7 +34,7 @@ if ($CONTACTS->readonly)
 if ((!get_input_value('_name', RCUBE_INPUT_POST) || !get_input_value('_email', RCUBE_INPUT_POST)))
 {
   $OUTPUT->show_message('formincomplete', 'warning');
-  rcmail_overwrite_action(empty($_POST['_cid']) ? 'add' : 'show');
+  rcmail_overwrite_action($return_action);
   return;
 }
 
@@ -39,7 +42,6 @@ if ((!get_input_value('_name', RCUBE_INPUT_POST) || !get_input_value('_email', R
 // setup some vars we need
 $a_save_cols = array('name', 'firstname', 'surname', 'email');
 $a_record = array();
-$cid = get_input_value('_cid', RCUBE_INPUT_POST);
 
 // read POST values into hash array
 foreach ($a_save_cols as $col)
@@ -52,26 +54,36 @@ foreach ($a_save_cols as $col)
 // update an existing contact
 if (!empty($cid))
 {
-  if ($CONTACTS->update($cid, $a_record))
+  $plugin = $RCMAIL->plugins->exec_hook('save_contact', array('id' => $cid, 'record' => $a_record, 'source' => get_input_value('_source', RCUBE_INPUT_GPC)));
+  $a_record = $plugin['record'];
+  
+  if (!$plugin['abort'] && ($result = $CONTACTS->update($cid, $a_record)))
   {
+    // LDAP DN change
+    if (is_string($result) && strlen($result)>1) {
+      $newcid = $result;
+      // change cid in POST for 'show' action
+      $_POST['_cid'] = $newcid;
+    }
+    
     // define list of cols to be displayed
     $a_js_cols = array();
-    $record = $CONTACTS->get_record($cid, true);
+    $record = $CONTACTS->get_record($newcid ? $newcid : $cid, true);
 
     foreach (array('name', 'email') as $col)
       $a_js_cols[] = (string)$record[$col];
 
     // update the changed col in list
-    $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols);
+    $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid);
       
     // show confirmation
-    $OUTPUT->show_message('successfullysaved', 'confirmation');    
+    $OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
     rcmail_overwrite_action('show');
   }
   else
   {
     // show error message
-    $OUTPUT->show_message('errorsaving', 'error');
+    $OUTPUT->show_message('errorsaving', 'error', null, false);
     rcmail_overwrite_action('show');
   }
 }
@@ -85,13 +97,16 @@ else
   // show warning message
   if ($existing->count)
   {
-    $OUTPUT->show_message('contactexists', 'warning');
+    $OUTPUT->show_message('contactexists', 'warning', null, false);
     rcmail_overwrite_action('add');
     return;
   }
 
+  $plugin = $RCMAIL->plugins->exec_hook('create_contact', array('record' => $a_record, 'source' => get_input_value('_source', RCUBE_INPUT_GPC)));
+  $a_record = $plugin['record'];
+
   // insert record and send response
-  if ($insert_id = $CONTACTS->insert($a_record))
+  if (!$plugin['abort'] && ($insert_id = $CONTACTS->insert($a_record)))
   {
     // add contact row or jump to the page where it should appear
     $CONTACTS->reset();
@@ -105,14 +120,14 @@ else
     $OUTPUT->command('parent.set_rowcount', rcmail_get_rowcount_text());
 
     // show confirmation
-    $OUTPUT->show_message('successfullysaved', 'confirmation');
+    $OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
     rcmail_overwrite_action('show');
     $_GET['_cid'] = $insert_id;
   }
   else
   {
     // show error message
-    $OUTPUT->show_message('errorsaving', 'error');
+    $OUTPUT->show_message('errorsaving', 'error', null, false);
     rcmail_overwrite_action('add');
   }
 }
index 01233a0bdf8530ef47f673699836274c1087fff5..790db060dfb15b508336a7bde6a3de11bfbe42a9 100644 (file)
@@ -32,7 +32,7 @@ if ($result->count > 0)
 {
   // save search settings in session
   $_SESSION['search'][$search_request] = $CONTACTS->get_search_set();
-  
+
   // create javascript list
   rcmail_js_contacts_list($result);
 }
index 401e1d2e06d0a3b708f50928f5cae8466e768552..5cc04bf436ea7426c745783559f76c7ec1d15c0f 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: error.inc 2237 2009-01-17 01:55:39Z till $
+ $Id: error.inc 2547 2009-05-26 16:54:55Z alec $
 
 */
 
@@ -81,12 +81,17 @@ else {
   if (($CONFIG['debug_level'] & 4) && $ERROR_MESSAGE)
     $__error_text = $ERROR_MESSAGE;
   else
-    $__error_text = sprintf('Error No. [0x%04X]', $ERROR_CODE);
+    $__error_text = sprintf('Error No. [%s]', $ERROR_CODE);
 }
 
 
-// compose page content
+// Ajax request
+if ($OUTPUT && ($OUTPUT instanceof rcube_json_output)) {
+  header("HTTP/1.0 $ERROR_CODE $__error_title");
+  die;
+}
 
+// compose page content
 $__page_content = <<<EOF
 <div>
 <h3 class="error-title">$__error_title</h3>
@@ -94,8 +99,6 @@ $__page_content = <<<EOF
 </div>
 EOF;
 
-
-
 if ($OUTPUT && $OUTPUT->template_exists('error')) {
   $OUTPUT->reset();
   $OUTPUT->send('error');
index c089e71b370a6047c7db457ad46a4736ce656e11..d2bb293876f31272256157298b009991f3cabca1 100644 (file)
@@ -5,7 +5,7 @@
  | program/steps/mail/addcontact.inc                                     |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: addcontact.inc 1712 2008-09-02 07:42:46Z thomasb $
+ $Id: addcontact.inc 2758 2009-07-16 15:01:05Z thomasb $
 
 */
 
+// only process ajax requests
+if (!$OUTPUT->ajax_call)
+  return;
+
 $done = false;
 $CONTACTS = $RCMAIL->get_address_book(null, true);
 
@@ -41,8 +45,14 @@ if (!empty($_POST['_address']) && is_object($CONTACTS))
     $existing = $CONTACTS->search('email', $contact['email'], true, false);
     if ($done = $existing->count)
       $OUTPUT->show_message('contactexists', 'warning');
-    else if ($done = $CONTACTS->insert($contact))
-      $OUTPUT->show_message('addedsuccessfully', 'confirmation');
+    else
+    {
+      $plugin = $RCMAIL->plugins->exec_hook('create_contact', array('record' => $contact, 'source' => null));
+      $contact = $plugin['record'];
+
+      if (!$plugin['abort'] && ($done = $CONTACTS->insert($contact)))
+        $OUTPUT->show_message('addedsuccessfully', 'confirmation');
+    }
   }
 }
 
index f6e29f9d76e1a1abc1271e78e005703c2fadb400..60157034559520b109bce97d965a4fcff7252a5f 100644 (file)
@@ -28,46 +28,45 @@ if (!$_SESSION['compose']) {
 // remove an attachment
 if ($RCMAIL->action=='remove-attachment')
 {
-  if (preg_match('/^rcmfile([0-9]+)$/', $_POST['_file'], $regs))
-  {
+  $id = 'undefined';
+  if (preg_match('/^rcmfile(\w+)$/', $_POST['_file'], $regs))
     $id = $regs[1];
-    if (is_array($_SESSION['compose']['attachments'][$id]))
-    {
-      @unlink($_SESSION['compose']['attachments'][$id]['path']);
+  if ($attachment = $_SESSION['compose']['attachments'][$id])
+    $attachment = $RCMAIL->plugins->exec_hook('remove_attachment', $attachment);
+  if ($attachment['status']) {
+    if (is_array($_SESSION['compose']['attachments'][$id])) {
       unset($_SESSION['compose']['attachments'][$id]);
       $OUTPUT->command('remove_from_attachment_list', "rcmfile$id");
-      $OUTPUT->send();
     }
   }
+  
+  $OUTPUT->send();
   exit;
 }
 
 if ($RCMAIL->action=='display-attachment')
 {
-  if (preg_match('/^rcmfile([0-9]+)$/', $_GET['_file'], $regs))
-  {
+  $id = 'undefined';
+  if (preg_match('/^rcmfile(\w+)$/', $_GET['_file'], $regs))
     $id = $regs[1];
-    if (is_array($_SESSION['compose']['attachments'][$id]))
-    {
-      $apath = $_SESSION['compose']['attachments'][$id]['path'];
-      header('Content-Type: ' . $_SESSION['compose']['attachments'][$id]['mimetype']);
-      header('Content-Length: ' . filesize($apath));
-      readfile($apath);
-    }
+  if ($attachment = $_SESSION['compose']['attachments'][$id])
+    $attachment = $RCMAIL->plugins->exec_hook('display_attachment', $attachment);
+    
+  if ($attachment['status']) {
+    $size = $attachment['data'] ? strlen($attachment['data']) : @filesize($attachment['path']);
+    header('Content-Type: ' . $attachment['mimetype']);
+    header('Content-Length: ' . $size);
+    
+    if ($attachment['data'])
+      echo $attachment['data'];
+    else if ($attachment['path'])
+      readfile($attachment['path']);
   }
   exit;
 }
 
 // attachment upload action
 
-// use common temp dir for file uploads
-$temp_dir = unslashify($CONFIG['temp_dir']);
-
-// #1484529: we need absolute path on Windows for move_uploaded_file()
-if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
-  $temp_dir = realpath($temp_dir);
-}
-
 if (!is_array($_SESSION['compose']['attachments'])) {
   $_SESSION['compose']['attachments'] = array();
 }
@@ -77,20 +76,25 @@ $OUTPUT->reset();
 
 if (is_array($_FILES['_attachments']['tmp_name'])) {
   foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
-    $tmpfname = tempnam($temp_dir, 'rcmAttmnt');
-    if (move_uploaded_file($filepath, $tmpfname) && file_exists($tmpfname)) {
-      $id = count($_SESSION['compose']['attachments']);
-      $_SESSION['compose']['attachments'][] = array(
-        'name' => $_FILES['_attachments']['name'][$i],
-        'mimetype' => rc_mime_content_type($tmpfname, $_FILES['_attachments']['name'][$i], $_FILES['_attachments']['type'][$i]),
-        'path' => $tmpfname,
-      );
-
-      if (is_file($icon = $CONFIG['skin_path'] . '/images/icons/remove-attachment.png')) {
+    $attachment = array(
+      'path' => $filepath,
+      'name' => $_FILES['_attachments']['name'][$i],
+      'mimetype' => rc_mime_content_type($filepath, $_FILES['_attachments']['name'][$i], $_FILES['_attachments']['type'][$i])
+    );
+
+    $attachment = $RCMAIL->plugins->exec_hook('upload_attachment', $attachment);
+
+    if ($attachment['status'] && !$attachment['abort']) {
+      $id = $attachment['id'];
+      
+      // store new attachment in session
+      unset($attachment['status'], $attachment['abort']);
+      $_SESSION['compose']['attachments'][$id] = $attachment;
+      
+      if (($icon = $_SESSION['compose']['deleteicon']) && is_file($icon)) {
         $button = html::img(array(
           'src' => $icon,
-          'alt' => rcube_label('delete'),
-          'style' => "padding-right:2px;vertical-align:middle",
+          'alt' => rcube_label('delete')
         ));
       }
       else {
@@ -99,11 +103,11 @@ if (is_array($_FILES['_attachments']['tmp_name'])) {
 
       $content = html::a(array(
         'href' => "#delete",
-        'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%d', this)", JS_OBJECT_NAME, $id),
+        'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id),
         'title' => rcube_label('delete'),
       ), $button);
-      
-      $content .= Q($_FILES['_attachments']['name'][$i]);
+
+      $content .= Q($attachment['name']);
       
       $OUTPUT->command('add2attachment_list', "rcmfile$id", $content);
     }
@@ -112,6 +116,9 @@ if (is_array($_FILES['_attachments']['tmp_name'])) {
       if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
         $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize'))))));
       }
+      else if ($attachment['error']) {
+        $msg = $attachment['error'];
+      }
       else {
         $msg = rcube_label('fileuploaderror');
       }
index b1aba7d62e8db91b2e6e7da6f8913a2cbcc9b968..46915672d47019678eb400f948f13e8ed1d7802f 100644 (file)
@@ -23,7 +23,7 @@ $MAXNUM = 15;
 $contacts = array();
 $book_types = (array) $RCMAIL->config->get('autocomplete_addressbooks', 'sql');
 
-if ($book_types && $search = get_input_value('_search', RCUBE_INPUT_POST)) {
+if ($book_types && $search = get_input_value('_search', RCUBE_INPUT_POST, true)) {
 
   foreach ($book_types as $id) {
     $abook = $RCMAIL->get_address_book($id);
@@ -31,11 +31,9 @@ if ($book_types && $search = get_input_value('_search', RCUBE_INPUT_POST)) {
 
     if ($result = $abook->search(array('email','name'), $search)) {
       while ($sql_arr = $result->iterate()) {
-        if (stripos((string)$sql_arr['email'], $search) !== false || stripos((string)$sql_arr['name'], $search) !== false) {
           $contacts[] = format_email_recipient($sql_arr['email'], $sql_arr['name']);
          if (count($contacts) >= $MAXNUM)
             break 2;
-        }
       }
     }
   }
@@ -46,4 +44,4 @@ if ($book_types && $search = get_input_value('_search', RCUBE_INPUT_POST)) {
 $OUTPUT->command('ksearch_query_results', $contacts, $search);
 $OUTPUT->send();
 
-?>
\ No newline at end of file
+?>
index 54e1702de192e85915fb4114e836317d499a6342..78b7fbbdf1e93de97bd545c1f989a1b8f217a102 100644 (file)
@@ -28,7 +28,7 @@ foreach ($a_mailboxes as $mbox_name) {
       // refresh saved search set
       if (($search_request = get_input_value('_search', RCUBE_INPUT_GPC)) && isset($_SESSION['search'][$search_request])) {
         $_SESSION['search'][$search_request] = $IMAP->refresh_search();
-       $all_count = $IMAP->messagecount();
+        $all_count = $IMAP->messagecount();
       } else {
         $all_count = $IMAP->messagecount(NULL, 'ALL', TRUE);
       }
@@ -47,6 +47,9 @@ foreach ($a_mailboxes as $mbox_name) {
       if (!empty($_GET['_quota']))
         $OUTPUT->command('set_quota', rcmail_quota_content($IMAP->get_quota()));
 
+      // trigger plugin hook
+      $RCMAIL->plugins->exec_hook('new_messages', array('mailbox' => $mbox_name, 'count' => $unread_count));
+
       // "No-list" mode, don't get messages
       if (empty($_GET['_list']))
         continue;
@@ -62,7 +65,7 @@ foreach ($a_mailboxes as $mbox_name) {
         // get the headers
         $result_h = $IMAP->list_headers($mbox_name, 1, 'date', 'DESC');
         // add to the list
-       rcmail_js_message_list($result_h, TRUE);
+        rcmail_js_message_list($result_h, true, false);
       }
     }
   }
index 525298b757a13215fcda9e9596ec28dd7d76b2cc..19e0b030e63b96ce74d98c4dfebaa6f72e5ff0f4 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: compose.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: compose.inc 2909 2009-09-03 06:49:00Z alec $
 
 */
 
@@ -23,6 +23,7 @@
 define('RCUBE_COMPOSE_REPLY', 0x0106);
 define('RCUBE_COMPOSE_FORWARD', 0x0107);
 define('RCUBE_COMPOSE_DRAFT', 0x0108);
+define('RCUBE_COMPOSE_EDIT', 0x0109);
 
 $MESSAGE_FORM = NULL;
 $MESSAGE = NULL;
@@ -35,16 +36,53 @@ $MESSAGE = NULL;
 if (!is_array($_SESSION['compose']) || $_SESSION['compose']['id'] != get_input_value('_id', RCUBE_INPUT_GET))
 {
   rcmail_compose_cleanup();
-  $_SESSION['compose'] = array('id' => uniqid(rand()), 'param' => array_map('strip_tags', $_GET));
+  $_SESSION['compose'] = array(
+    'id' => uniqid(rand()),
+    'param' => request2param(RCUBE_INPUT_GET),
+    'mailbox' => $IMAP->get_mailbox_name(),
+  );
   
   // process values like "mailto:foo@bar.com?subject=new+message&cc=another"
-  if ($_SESSION['compose']['param']['_to']) {
-    $mailto = explode('?', $_SESSION['compose']['param']['_to']);
+  if ($_SESSION['compose']['param']['to']) {
+    $mailto = explode('?', $_SESSION['compose']['param']['to']);
     if (count($mailto) > 1) {
-      $_SESSION['compose']['param']['_to'] = $mailto[0];
+      $_SESSION['compose']['param']['to'] = $mailto[0];
       parse_str($mailto[1], $query);
       foreach ($query as $f => $val)
-        $_SESSION['compose']['param']["_$f"] = $val;
+        $_SESSION['compose']['param'][$f] = $val;
+    }
+  }
+  
+  // pipe compose parameters thru plugins
+  $plugin = $RCMAIL->plugins->exec_hook('message_compose', $_SESSION['compose']);
+  $_SESSION['compose']['param'] = $plugin['param'];
+  
+  // add attachments listed by message_compose hook
+  if (is_array($plugin['attachments'])) {
+    foreach ($plugin['attachments'] as $attach) {
+      // we have structured data
+      if (is_array($attach)) {
+        $attachment = $attach;
+      }
+      // only a file path is given
+      else {
+        $filename = basename($attach);
+        $attachment = array(
+          'name' => $filename,
+          'mimetype' => rc_mime_content_type($attach, $filename),
+          'path' => $attach
+        );
+      }
+      
+      // save attachment if valid
+      if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) {
+        $attachment = rcmail::get_instance()->plugins->exec_hook('save_attachment', $attachment);
+      }
+      
+      if ($attachment['status'] && !$attachment['abort']) {
+        unset($attachment['data'], $attachment['status'], $attachment['abort']);
+        $_SESSION['compose']['attachments'][$attachment['id']] = $attachment;
+      }
     }
   }
 
@@ -52,6 +90,7 @@ if (!is_array($_SESSION['compose']) || $_SESSION['compose']['id'] != get_input_v
   $OUTPUT->redirect(array('_action' => 'compose', '_id' => $_SESSION['compose']['id']));
 }
 
+
 // add some labels to client
 $OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning',
     'nobodywarning', 'notsentwarning', 'savingmessage', 'sendingmessage', 'messagesaved',
@@ -66,11 +105,13 @@ if (!empty($CONFIG['drafts_mbox'])) {
 $OUTPUT->set_env('mailbox', $IMAP->get_mailbox_name());
 
 // get reference message and set compose mode
-if ($msg_uid = $_SESSION['compose']['param']['_reply_uid'])
+if ($msg_uid = $_SESSION['compose']['param']['reply_uid'])
   $compose_mode = RCUBE_COMPOSE_REPLY;
-else if ($msg_uid = $_SESSION['compose']['param']['_forward_uid'])
+else if ($msg_uid = $_SESSION['compose']['param']['forward_uid'])
   $compose_mode = RCUBE_COMPOSE_FORWARD;
-else if ($msg_uid = $_SESSION['compose']['param']['_draft_uid']) {
+else if ($msg_uid = $_SESSION['compose']['param']['uid'])
+  $compose_mode = RCUBE_COMPOSE_EDIT;
+else if ($msg_uid = $_SESSION['compose']['param']['draft_uid']) {
   $RCMAIL->imap->set_mailbox($CONFIG['drafts_mbox']);
   $compose_mode = RCUBE_COMPOSE_DRAFT;
 }
@@ -78,6 +119,8 @@ else if ($msg_uid = $_SESSION['compose']['param']['_draft_uid']) {
 if (!empty($msg_uid))
 {
   // similar as in program/steps/mail/show.inc
+  // re-set 'prefer_html' to have possibility to use html part for compose
+  $CONFIG['prefer_html'] = $CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT;
   $MESSAGE = new rcube_message($msg_uid);
   
   if (!empty($MESSAGE->headers->charset))
@@ -89,7 +132,7 @@ if (!empty($msg_uid))
     $_SESSION['compose']['reply_msgid'] = $MESSAGE->headers->messageID;
     $_SESSION['compose']['references']  = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID);
 
-    if (!empty($_SESSION['compose']['param']['_all']))
+    if (!empty($_SESSION['compose']['param']['all']))
       $MESSAGE->reply_all = 1;
   }
   else if ($compose_mode == RCUBE_COMPOSE_DRAFT)
@@ -129,23 +172,23 @@ function rcmail_compose_headers($attrib)
 
     case 'to':
       $fname = '_to';
-      $header = 'to';
+      $header = $param = 'to';
       
       // we have a set of recipients stored is session
-      if (($mailto_id = $_SESSION['compose']['param']['_mailto']) && $_SESSION['mailto'][$mailto_id])
+      if (($mailto_id = $_SESSION['compose']['param']['mailto']) && $_SESSION['mailto'][$mailto_id])
         $fvalue = urldecode($_SESSION['mailto'][$mailto_id]);
       
     case 'cc':
       if (!$fname)
       {
         $fname = '_cc';
-        $header = 'cc';
+        $header = $param = 'cc';
       }
     case 'bcc':
       if (!$fname)
       {
         $fname = '_bcc';
-        $header = 'bcc';
+        $header = $param = 'bcc';
       }
         
       $allow_attrib = array('id', 'class', 'style', 'cols', 'rows', 'tabindex');
@@ -155,18 +198,19 @@ function rcmail_compose_headers($attrib)
     case 'replyto':
     case 'reply-to':
       $fname = '_replyto';
+      $param = 'replyto';
       $allow_attrib = array('id', 'class', 'style', 'size', 'tabindex');
       $field_type = 'html_inputfield';
       break;
   }
  
-  if ($fname && !empty($_POST[$fname]))
+  if ($fname && !empty($_POST[$fname])) {
     $fvalue = get_input_value($fname, RCUBE_INPUT_POST, TRUE);
-  else if ($fname && !$fvalue && !empty($_SESSION['compose']['param'][$fname]))
-    $fvalue = $_SESSION['compose']['param'][$fname];
-
-  else if ($header && $compose_mode == RCUBE_COMPOSE_REPLY)
-  {
+  }
+  else if ($fname && !$fvalue && !empty($_SESSION['compose']['param'][$param])) {
+    $fvalue = $_SESSION['compose']['param'][$param];
+  }
+  else if ($header && $compose_mode == RCUBE_COMPOSE_REPLY) {
     // get recipent address(es) out of the message headers
     if ($header=='to' && !empty($MESSAGE->headers->replyto))
       $fvalue = $MESSAGE->headers->replyto;
@@ -204,7 +248,7 @@ function rcmail_compose_headers($attrib)
       }
     }
   }
-  else if ($header && $compose_mode == RCUBE_COMPOSE_DRAFT)
+  else if ($header && in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT)))
   {
     // get drafted headers
     if ($header=='to' && !empty($MESSAGE->headers->to))
@@ -259,7 +303,7 @@ function rcmail_compose_header_from($attrib)
     foreach ($a_to as $addr)
     {
       if (!empty($addr['mailto']))
-        $a_recipients[] = rc_strtolower($addr['mailto']);
+        $a_recipients[] = mb_strtolower($addr['mailto']);
     }
 
     if (!empty($MESSAGE->headers->cc))
@@ -268,15 +312,15 @@ function rcmail_compose_header_from($attrib)
       foreach ($a_cc as $addr)
       {
         if (!empty($addr['mailto']))
-          $a_recipients[] = rc_strtolower($addr['mailto']);
+          $a_recipients[] = mb_strtolower($addr['mailto']);
       }
     }
   }
 
   // get this user's identities
-  $sql_result = $USER->list_identities();
+  $user_identities = $USER->list_identities();
 
-  if ($DB->num_rows($sql_result))
+  if (count($user_identities))
   {
     $from_id = 0;
     $a_signatures = array();
@@ -284,13 +328,13 @@ function rcmail_compose_header_from($attrib)
     $field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)";
     $select_from = new html_select($field_attrib);
 
-    while ($sql_arr = $DB->fetch_assoc($sql_result))
+    foreach ($user_identities as $sql_arr)
     {
       $identity_id = $sql_arr['identity_id'];
       $select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $identity_id);
 
       // add signature to array
-      if (!empty($sql_arr['signature']))
+      if (!empty($sql_arr['signature']) && empty($_SESSION['compose']['param']['nosig']))
       {
         $a_signatures[$identity_id]['text'] = $sql_arr['signature'];
         $a_signatures[$identity_id]['is_html'] = ($sql_arr['html_signature'] == 1) ? true : false;
@@ -310,7 +354,7 @@ function rcmail_compose_header_from($attrib)
         if ($compose_mode == RCUBE_COMPOSE_DRAFT && strstr($MESSAGE->headers->from, $sql_arr['email']))
           $from_id = $sql_arr['identity_id'];
         // set identity if it's one of the reply-message recipients (with prio for default identity)
-        else if (in_array(rc_strtolower($sql_arr['email']), $a_recipients) && (empty($from_id) || $sql_arr['standard']))
+        else if (in_array(mb_strtolower($sql_arr['email']), $a_recipients) && (empty($from_id) || $sql_arr['standard']))
           $from_id = $sql_arr['identity_id'];
       }
     }
@@ -345,11 +389,11 @@ function rcmail_compose_body($attrib)
   unset($attrib['form']);
   
   if (empty($attrib['id']))
-    $attrib['id'] = 'rcmComposeMessage';
+    $attrib['id'] = 'rcmComposeBody';
 
   $attrib['name'] = '_message';
 
-  if ($CONFIG['htmleditor'])
+  if ($CONFIG['htmleditor'] || (($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) && $MESSAGE->has_html_part()))
     $isHtml = true;
   else
     $isHtml = false;
@@ -361,9 +405,14 @@ function rcmail_compose_body($attrib)
   {
     $body = get_input_value('_message', RCUBE_INPUT_POST, true);
   }
+  else if ($_SESSION['compose']['param']['body'])
+  {
+    $body = $_SESSION['compose']['param']['body'];
+    $isHtml = false;
+  }
   else if ($compose_mode)
   {
-    if ($isHtml && $MESSAGE->has_html_part())
+    if (($isHtml || $compose_mode == RCUBE_COMPOSE_DRAFT) && $MESSAGE->has_html_part())
     {
       $body = $MESSAGE->first_html_part();
       $isHtml = true;
@@ -373,7 +422,7 @@ function rcmail_compose_body($attrib)
       $body = $MESSAGE->first_text_part();
       $isHtml = false;
     }
-    
+
     // compose reply-body
     if ($compose_mode == RCUBE_COMPOSE_REPLY)
       $body = rcmail_create_reply_body($body, $isHtml);
@@ -381,12 +430,12 @@ function rcmail_compose_body($attrib)
     else if ($compose_mode == RCUBE_COMPOSE_FORWARD)
       $body = rcmail_create_forward_body($body, $isHtml);
     // load draft message body
-    else if ($compose_mode == RCUBE_COMPOSE_DRAFT)
+    else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT)
       $body = rcmail_create_draft_body($body, $isHtml);
   }
-  else if (!empty($_SESSION['compose']['param']['_body']))
+  else if (!empty($_SESSION['compose']['param']['body']))
   {
-    $body = $_SESSION['compose']['param']['_body'];
+    $body = $_SESSION['compose']['param']['body'];
   }
 
   $out = $form_start ? "$form_start\n" : '';
@@ -406,6 +455,8 @@ function rcmail_compose_body($attrib)
   $out .= $textarea->show($body);
   $out .= $form_end ? "\n$form_end" : '';
 
+  $OUTPUT->set_env('composebody', $attrib['id']);
+
   // include HTML editor
   rcube_html_editor();
   
@@ -433,6 +484,7 @@ function rcmail_compose_body($attrib)
       "googie.lang_no_error_found = \"%s\";\n".
       "googie.setLanguages(%s);\n".
       "googie.setCurrentLanguage('%s');\n".
+      "googie.setSpellContainer('spellcheck-control');\n".
       "googie.decorateTextarea('%s');\n".
       "%s.set_env('spellcheck', googie);",
       $RCMAIL->comm_path,
@@ -552,12 +604,12 @@ function rcmail_create_forward_body($body, $bodyIsHtml)
         "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">To: </th><td>%s</td></tr>",
       Q($MESSAGE->subject),
       Q($MESSAGE->headers->date),
-      htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset(), true),
-       htmlspecialchars(Q($MESSAGE->get_header('to'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset(), true));
+      htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset()),
+      htmlspecialchars(Q($MESSAGE->get_header('to'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset()));
 
     if ($MESSAGE->headers->replyto && $MESSAGE->headers->replyto != $MESSAGE->headers->from)
       $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Reply-To: </th><td>%s</td></tr>",
-       htmlspecialchars(Q($MESSAGE->get_header('replyto'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset(), true));
+        htmlspecialchars(Q($MESSAGE->get_header('replyto'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset()));
 
     $prefix .= "</tbody></table><br>";
   }
@@ -574,7 +626,7 @@ function rcmail_create_draft_body($body, $bodyIsHtml)
    * add attachments
    * sizeof($MESSAGE->mime_parts can be 1 - e.g. attachment, but no text!
    */
-  if (!isset($_SESSION['compose']['forward_attachments'])
+  if (empty($_SESSION['compose']['forward_attachments'])
       && is_array($MESSAGE->mime_parts)
       && count($MESSAGE->mime_parts) > 0)
   {
@@ -592,27 +644,22 @@ function rcmail_create_draft_body($body, $bodyIsHtml)
 function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
 {
   global $OUTPUT;
-  
+
   $cid_map = array();
-  $id = 0;
-  
   foreach ((array)$message->mime_parts as $pid => $part)
   {
-    if (($part->ctype_primary != 'message' || !$bodyIsHtml) &&
-        ($part->disposition=='attachment' || $part->disposition=='inline' || $part->headers['content-id']
-         || (empty($part->disposition) && $part->filename)))
+    if (($part->ctype_primary != 'message' || !$bodyIsHtml) && $part->ctype_primary != 'multipart' && 
+        ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename))
     {
       if ($attachment = rcmail_save_attachment($message, $pid)) {
-        $_SESSION['compose']['attachments'][$id] = $attachment;
-       if ($bodyIsHtml && $part->filename && $part->content_id) {
-         $cid_map['cid:'.$part->content_id] = 
-           $OUTPUT->app->comm_path.'&_action=display-attachment&_file=rcmfile'.$id;
+        $_SESSION['compose']['attachments'][$attachment['id']] = $attachment;
+        if ($bodyIsHtml && $part->content_id) {
+          $cid_map['cid:'.$part->content_id] = $OUTPUT->app->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'];
         }
-       $id++;
       }
     }
   }
-       
+
   $_SESSION['compose']['forward_attachments'] = true;
 
   return $cid_map;
@@ -624,15 +671,11 @@ function rcmail_write_inline_attachments(&$message)
   global $OUTPUT;
 
   $cid_map = array();
-  $id = 0;
-  
   foreach ((array)$message->mime_parts as $pid => $part) {
     if ($part->content_id && $part->filename) {
       if ($attachment = rcmail_save_attachment($message, $pid)) {
-        $_SESSION['compose']['attachments'][$id] = $attachment;
-        $cid_map['cid:'.$part->content_id] = 
-         $OUTPUT->app->comm_path.'&_action=display-attachment&_file=rcmfile'.$id;
-        $id++;
+        $_SESSION['compose']['attachments'][$attachment['id']] = $attachment;
+        $cid_map['cid:'.$part->content_id] = $OUTPUT->app->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'];
       }
     }
   }
@@ -642,24 +685,43 @@ function rcmail_write_inline_attachments(&$message)
 
 function rcmail_save_attachment(&$message, $pid)
 {
-  global $RCMAIL;
-
-  $temp_dir = unslashify($RCMAIL->config->get('temp_dir'));
-  $tmp_path = tempnam($temp_dir, 'rcmAttmnt');
   $part = $message->mime_parts[$pid];
+  $mem_limit = parse_bytes(ini_get('memory_limit'));
+  $curr_mem = function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024; // safe value: 16MB
+  $data = $path = null;
+
+  // don't load too big attachments into memory
+  if ($mem_limit > 0 && $part->size > $mem_limit - $curr_mem) {
+    $rcmail = rcmail::get_instance();
+    $temp_dir = unslashify($rcmail->config->get('temp_dir'));
+    $path = tempnam($temp_dir, 'rcmAttmnt');
+    if ($fp = fopen($path, 'w')) {
+      $message->get_part_content($pid, $fp);
+      fclose($fp);
+    } else
+      return false;
+  } else {
+    $data = $message->get_part_content($pid);
+  }
+
+  $attachment = array(
+    'name' => $part->filename ? $part->filename : 'Part_'.$pid.'.'.$part->ctype_secondary,
+    'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary,
+    'content_id' => $part->content_id,
+    'data' => $data,
+    'path' => $path
+  );
   
-  if ($fp = fopen($tmp_path, 'w'))
-  {
-    $message->get_part_content($pid, $fp);
-    fclose($fp);
+  $attachment = rcmail::get_instance()->plugins->exec_hook('save_attachment', $attachment);
 
-    return array(
-        'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary,
-        'name' => $part->filename,
-        'path' => $tmp_path,
-       'content_id' => $part->content_id
-    );
+  if ($attachment['status']) {
+    unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']);
+    return $attachment;
+  } else if ($path) {
+    @unlink($path);
   }
+  
+  return false;
 }
 
 
@@ -682,24 +744,24 @@ function rcmail_compose_subject($attrib)
   }
   // create a reply-subject
   else if ($compose_mode == RCUBE_COMPOSE_REPLY) {
-    if (eregi('^re:', $MESSAGE->subject))
+    if (preg_match('/^re:/i', $MESSAGE->subject))
       $subject = $MESSAGE->subject;
     else
       $subject = 'Re: '.$MESSAGE->subject;
   }
   // create a forward-subject
   else if ($compose_mode == RCUBE_COMPOSE_FORWARD) {
-    if (eregi('^fwd:', $MESSAGE->subject))
+    if (preg_match('/^fwd:/i', $MESSAGE->subject))
       $subject = $MESSAGE->subject;
     else
       $subject = 'Fwd: '.$MESSAGE->subject;
   }
   // creeate a draft-subject
-  else if ($compose_mode == RCUBE_COMPOSE_DRAFT) {
+  else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) {
     $subject = $MESSAGE->subject;
   }
-  else if (!empty($_SESSION['compose']['param']['_subject'])) {
-    $subject = $_SESSION['compose']['param']['_subject'];
+  else if (!empty($_SESSION['compose']['param']['subject'])) {
+    $subject = $_SESSION['compose']['param']['subject'];
   }
   
   $out = $form_start ? "$form_start\n" : '';
@@ -722,11 +784,12 @@ function rcmail_compose_attachment_list($attrib)
   
   if (is_array($_SESSION['compose']['attachments']))
   {
-    if ($attrib['deleteicon'])
+    if ($attrib['deleteicon']) {
       $button = html::img(array(
         'src' => $CONFIG['skin_path'] . $attrib['deleteicon'],
-        'alt' => rcube_label('delete'),
-        'style' => "padding-right:2px;vertical-align:middle"));
+        'alt' => rcube_label('delete')
+      ));
+    }
     else
       $button = Q(rcube_label('delete'));
 
@@ -739,11 +802,14 @@ function rcmail_compose_attachment_list($attrib)
         html::a(array(
             'href' => "#delete",
             'title' => rcube_label('delete'),
-            'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%d', this)", JS_OBJECT_NAME, $id)),
+            'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id)),
           $button) . Q($a_prop['name']));
     }
   }
 
+  if ($attrib['deleteicon'])
+    $_SESSION['compose']['deleteicon'] = $CONFIG['skin_path'] . $attrib['deleteicon'];
+
   $OUTPUT->add_gui_object('attachmentlist', $attrib['id']);
     
   return html::tag('ul', $attrib, $out, html::$common_attrib);
@@ -802,7 +868,12 @@ function rcmail_priority_selector($attrib)
                        rcube_label('highest')),
                  array(5, 4, 0, 2, 1));
                  
-  $sel = isset($_POST['_priority']) ? $_POST['_priority'] : intval($MESSAGE->headers->priority);
+  if (isset($_POST['_priority']))
+    $sel = $_POST['_priority'];
+  else if (intval($MESSAGE->headers->priority) != 3)
+    $sel = intval($MESSAGE->headers->priority);
+  else
+    $sel = 0;
 
   $out = $form_start ? "$form_start\n" : '';
   $out .= $selector->show($sel);
@@ -827,8 +898,8 @@ function rcmail_receipt_checkbox($attrib)
   $checkbox = new html_checkbox($attrib);
 
   $out = $form_start ? "$form_start\n" : '';
-  $out .= $checkbox->show(
-    $compose_mode == RCUBE_COMPOSE_DRAFT && $MESSAGE->headers->mdn_to ? 1 : 0);
+  $out .= $checkbox->show(in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))
+       && $MESSAGE->headers->mdn_to ? 1 : 0);
   $out .= $form_end ? "\n$form_end" : '';
 
   return $out;
@@ -839,23 +910,27 @@ function rcmail_editor_selector($attrib)
 {
   global $CONFIG, $MESSAGE, $compose_mode;
 
-  $choices = array(
-    'html'  => 'htmltoggle',
-    'plain' => 'plaintoggle'
-  );
-
   // determine whether HTML or plain text should be checked
-  $useHtml = $CONFIG['htmleditor'] ? true : false;
-
   if ($compose_mode)
-    $useHtml = ($useHtml && $MESSAGE->has_html_part());
+    $useHtml = (($CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT)
+       && $MESSAGE->has_html_part());
+  else
+    $useHtml = $CONFIG['htmleditor'] ? true : false;
+
+  if (empty($attrib['editorid']))
+    $attrib['editorid'] = 'rcmComposeBody';
+
+  if (empty($attrib['name']))
+    $attrib['name'] = 'editorSelect';
+    
+  $attrib['onchange'] = "return rcmail_toggle_editor(this.value=='html', '".$attrib['editorid']."', '_is_html')";
+
+  $select = new html_select($attrib);
 
-  $editorid = empty($attrib['editorid']) ? 'rcmComposeMessage' : $attrib['editorid'];
+  $select->add(Q(rcube_label('htmltoggle')), 'html');
+  $select->add(Q(rcube_label('plaintoggle')), 'plain');
 
-  $selector = '';
-  $chosenvalue = $useHtml ? 'html' : 'plain';
-  $radio = new html_radiobutton(array('name' => '_editorSelect',
-    'onclick' => "return rcmail_toggle_editor(this.value=='html', '$editorid', '_is_html')"));
+  return $select->show($useHtml ? 'html' : 'plain');
 
   foreach ($choices as $value => $text)
   {
index 88e48b2116f6376fb2d93b658934cdb0920bf034..bd6a92664384d1baa82c96e51f7c08efdde3a994 100644 (file)
@@ -5,7 +5,7 @@
  | program/steps/mail/folders.inc                                        |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: folders.inc 1570 2008-06-24 13:04:57Z alec $
+ $Id: folders.inc 2758 2009-07-16 15:01:05Z thomasb $
 */
 
+// only process ajax requests
+if (!$OUTPUT->ajax_call)
+  return;
+
 $mbox_name = $IMAP->get_mailbox_name();
 
 // send EXPUNGE command
index e694b8aaaf0aab237b5d5d010c27b5073bdc6ca5..d2c54a76b0dc51a0b266bce3b8025e427b5b1b9f 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: func.inc 2880 2009-08-27 09:52:52Z alec $
 
 */
 
-require_once('include/rcube_smtp.inc');
-
-$EMAIL_ADDRESS_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})';
+$EMAIL_ADDRESS_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9][a-z0-9\-\.]*\\.[a-z]{2,5})';
 
 // actions that do not require imap connection
 $NOIMAP_ACTIONS = array('spell', 'addcontact', 'autocomplete', 'upload', 'display-attachment', 'remove-attachment');
@@ -79,6 +77,7 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list')
       $OUTPUT->set_env('search_request', $search_request);
       }
     
+      $OUTPUT->set_env('search_mods', $_SESSION['search_mods'] ? $_SESSION['search_mods'] : array('subject'=>'subject'));
       // make sure the message count is refreshed (for default view)
       $IMAP->messagecount($mbox_name, 'ALL', true);
     }
@@ -88,6 +87,15 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list')
   $OUTPUT->set_env('quota', $IMAP->get_capability('quota'));
   $OUTPUT->set_env('delimiter', $IMAP->get_hierarchy_delimiter());
 
+  if ($CONFIG['flag_for_deletion'])
+    $OUTPUT->set_env('flag_for_deletion', true);
+  if ($CONFIG['read_when_deleted'])
+    $OUTPUT->set_env('read_when_deleted', true);
+  if ($CONFIG['skip_deleted'])
+    $OUTPUT->set_env('skip_deleted', true);
+  if ($CONFIG['display_next'])
+    $OUTPUT->set_env('display_next', true);
+         
   if ($CONFIG['trash_mbox'])
     $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
   if ($CONFIG['drafts_mbox'])
@@ -236,7 +244,6 @@ function rcmail_message_list($attrib)
   if (!sizeof($a_headers))
     $OUTPUT->show_message('nomessagesfound', 'notice');
 
-
   $a_js_message_arr = array();
 
   // create row for each message
@@ -293,7 +300,6 @@ function rcmail_message_list($attrib)
     
     $out .= sprintf("<td class=\"icon\">%s</td>\n", $message_icon ? sprintf($image_tag, $skin_path, $message_icon, '') : '');
 
-
     $IMAP->set_charset(!empty($header->charset) ? $header->charset : $CONFIG['default_charset']);
   
     // format each col
@@ -307,7 +313,7 @@ function rcmail_message_list($attrib)
         $uid_param = $mbox==$CONFIG['drafts_mbox'] ? '_draft_uid' : '_uid';
         $cont = abbreviate_string(trim($IMAP->decode_header($header->$col)), 160);
         if (empty($cont)) $cont = rcube_label('nosubject');
-        $cont = sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), Q($cont));
+        $cont = $OUTPUT->browser->ie ? Q($cont) : sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), Q($cont));
         }
       else if ($col=='flag')
         $cont = $flagged_icon ? sprintf($image_tag, $skin_path, $flagged_icon, '') : '';
@@ -374,8 +380,9 @@ function rcmail_message_list($attrib)
 
 /**
  * return javascript commands to add rows to the message list
+ * or to replace the whole list (IE only)
  */
-function rcmail_js_message_list($a_headers, $insert_top=FALSE)
+function rcmail_js_message_list($a_headers, $insert_top=FALSE, $replace=TRUE)
   {
   global $CONFIG, $IMAP, $OUTPUT;
 
@@ -391,7 +398,11 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE)
       && (($f = array_search('from', $a_show_cols)) !== false) && array_search('to', $a_show_cols) === false)
     $a_show_cols[$f] = 'to';
 
+  $browser = new rcube_browser;
+
   $OUTPUT->command('set_message_coltypes', $a_show_cols);
+  if ($browser->ie && $replace)
+    $OUTPUT->command('offline_message_list', true);
 
   // loop through message headers
   foreach ($a_headers as $n => $header)
@@ -419,9 +430,9 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE)
         {
         $action = $mbox==$CONFIG['drafts_mbox'] ? 'compose' : 'show';
         $uid_param = $mbox==$CONFIG['drafts_mbox'] ? '_draft_uid' : '_uid';
-        $cont = abbreviate_string(trim($IMAP->decode_header($header->$col)), 160);
+       $cont = abbreviate_string(trim($IMAP->decode_header($header->$col)), 160);
         if (!$cont) $cont = rcube_label('nosubject');
-        $cont = sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), Q($cont));
+        $cont = $browser->ie ? Q($cont) : sprintf('<a href="%s" onclick="return rcube_event.cancel(event)">%s</a>', Q(rcmail_url($action, array($uid_param=>$header->uid, '_mbox'=>$mbox))), Q($cont));
         }
       else if ($col=='size')
         $cont = show_bytes($header->$col);
@@ -433,12 +444,17 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE)
       $a_msg_cols[$col] = $cont;
       }
 
-    $a_msg_flags['deleted'] = $header->deleted ? 1 : 0;
-    $a_msg_flags['unread'] = $header->seen ? 0 : 1;
-    $a_msg_flags['replied'] = $header->answered ? 1 : 0;
-    $a_msg_flags['forwarded'] = $header->forwarded ? 1 : 0;
-    $a_msg_flags['flagged'] = $header->flagged ? 1 : 0;
-    
+    if ($header->deleted)
+      $a_msg_flags['deleted'] = 1;
+    if (!$header->seen)
+      $a_msg_flags['unread'] = 1;
+    if ($header->answered)
+      $a_msg_flags['replied'] = 1;
+    if ($header->forwarded)
+      $a_msg_flags['forwarded'] = 1;
+    if ($header->flagged)
+      $a_msg_flags['flagged'] = 1;
+
     $OUTPUT->command('add_message_row',
       $header->uid,
       $a_msg_cols,
@@ -446,6 +462,9 @@ function rcmail_js_message_list($a_headers, $insert_top=FALSE)
       preg_match("/multipart\/m/i", $header->ctype),
       $insert_top);
     }
+
+    if ($browser->ie && $replace)
+      $OUTPUT->command('offline_message_list', false);
   }
 
 
@@ -651,40 +670,38 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
   global $REMOTE_OBJECTS;
   
   $p += array('safe' => false, 'inline_html' => true);
-  
+
   // special replacements (not properly handled by washtml class)
   $html_search = array(
     '/(<\/nobr>)(\s+)(<nobr>)/i',      // space(s) between <NOBR>
-    '/(<[\/]*st1:[^>]+>)/i',           // Microsoft's Smart Tags <ST1>
-    '/<\/?rte_text>/i',                        // Rich Text Editor tags (#1485647)
     '/<title>.*<\/title>/i',           // PHP bug #32547 workaround: remove title tag
-    '/<html[^>]*>/im',                 // malformed html: remove html tags (#1485139)
-    '/<\/html>/i',                     // malformed html: remove html tags (#1485139)
     '/^(\0\0\xFE\xFF|\xFF\xFE\0\0|\xFE\xFF|\xFF\xFE|\xEF\xBB\xBF)/',   // byte-order mark (only outlook?)
+    '/<html\s[^>]+>/i',                        // washtml/DOMDocument cannot handle xml namespaces
   );
   $html_replace = array(
     '\\1'.' &nbsp; '.'\\3',
     '',
     '',
-    '',
-    '',
-    '',
-    '',
+    '<html>',
   );
   $html = preg_replace($html_search, $html_replace, $html);
 
-  // charset was converted to UTF-8 in rcube_imap::get_message_part() -> change charset specification in HTML accordingly
-  $charset_pattern = '/(\s+content=[\'"]?\w+\/\w+;\s*charset)=([a-z0-9-_]+)/i';
-  if (preg_match($charset_pattern, $html)) {
-    $html = preg_replace($charset_pattern, '\\1='.RCMAIL_CHARSET, $html);
+  // fix (unknown/malformed) HTML tags before "wash"
+  $html = preg_replace_callback('/(<[\/!]*)([^ >]+)/', 'rcmail_html_tag_callback', $html);
+
+  // charset was converted to UTF-8 in rcube_imap::get_message_part(),
+  // -> change charset specification in HTML accordingly
+  $charset_pattern = '(<meta\s+[^>]*)(content=[\'"]?\w+\/\w+;\s*charset)=([a-z0-9-_]+)';
+  if (preg_match("/$charset_pattern/Ui", $html)) {
+    $html = preg_replace("/$charset_pattern/i", '\\1\\2='.RCMAIL_CHARSET, $html);
   }
   else {
-    // add head for malformed messages, washtml cannot work without that
+    // add meta content-type to malformed messages, washtml cannot work without that
     if (!preg_match('/<head[^>]*>(.*)<\/head>/Uims', $html))
       $html = '<head></head>'. $html;
-    $html = substr_replace($html, '<meta http-equiv="content-type" content="text/html; charset='.RCMAIL_CHARSET.'" />', intval(stripos($html, '<head>')+6), 0);
+    $html = substr_replace($html, '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />', intval(stripos($html, '<head>')+6), 0);
   }
-    
+
   // turn relative into absolute urls
   $html = rcmail_resolve_base($html);
 
@@ -709,9 +726,8 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
   $washer = new washtml($wash_opts);
   $washer->add_callback('form', 'rcmail_washtml_callback');
 
-  if ($p['safe']) {  // allow CSS styles, will be sanitized by rcmail_washtml_callback()
-    $washer->add_callback('style', 'rcmail_washtml_callback');
-  }
+  // allow CSS styles, will be sanitized by rcmail_washtml_callback()
+  $washer->add_callback('style', 'rcmail_washtml_callback');
     
   $html = $washer->wash($html);
   $REMOTE_OBJECTS = $washer->extlinks;
@@ -730,71 +746,97 @@ function rcmail_wash_html($html, $p = array(), $cid_replaces)
  */
 function rcmail_print_body($part, $p = array())
 {
-  $p += array('safe' => false, 'plain' => false, 'inline_html' => true);
+  global $RCMAIL;
+  
+  // trigger plugin hook
+  $data = $RCMAIL->plugins->exec_hook('message_part_before',
+    array('type' => $part->ctype_secondary, 'body' => $part->body) + $p + array('safe' => false, 'plain' => false, 'inline_html' => true));
 
   // convert html to text/plain
-  if ($part->ctype_secondary == 'html' && $p['plain']) {
-    $txt = new html2text($part->body, false, true);
+  if ($data['type'] == 'html' && $data['plain']) {
+    $txt = new html2text($data['body'], false, true);
     $body = $txt->get_text();
     $part->ctype_secondary = 'plain';
   }
   // text/html
-  else if ($part->ctype_secondary == 'html') {
-    return rcmail_wash_html($part->body, $p, $part->replaces);
+  else if ($data['type'] == 'html') {
+    $body = rcmail_wash_html($data['body'], $data, $part->replaces);
+    $part->ctype_secondary = $data['type'];
   }
   // text/enriched
-  else if ($part->ctype_secondary=='enriched') {
+  else if ($data['type'] == 'enriched') {
     $part->ctype_secondary = 'html';
     require_once('lib/enriched.inc');
-    return Q(enriched_to_html($part->body), 'show');
+    $body = Q(enriched_to_html($data['body']), 'show');
   }
-  else
+  else {
+    // assert plaintext
     $body = $part->body;
-
-
-  /**** assert plaintext ****/
-
-  // make links and email-addresses clickable
-  $replacements = new rcube_string_replacer;
-  
-  $url_chars = 'a-z0-9_\-\+\*\$\/&%=@#:;';
-  $url_chars_within = '\?\.~,!';
+    $part->ctype_secondary = $data['type'] = 'plain';
+  }
   
-  // search for patterns like links and e-mail addresses
-  $body = preg_replace_callback("/([\w]+):\/\/([a-z0-9\-\.]+[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/i", array($replacements, 'link_callback'), $body);
-  $body = preg_replace_callback("/([^\/:]|\s)(www\.)([a-z0-9\-]{2,}[a-z]{2,4}([$url_chars$url_chars_within]*[$url_chars])?)/i", array($replacements, 'link_callback'), $body);
-  $body = preg_replace_callback('/([a-z0-9][a-z0-9\-\.\+\_]*@[a-z0-9]([a-z0-9\-][.]?)*[a-z0-9]\\.[a-z]{2,5})/i', array($replacements, 'mailto_callback'), $body);
-
-  // split body into single lines
-  $a_lines = preg_split('/\r?\n/', $body);
-  $quote_level = 0;
-
-  // colorize quoted parts
-  for ($n=0; $n < sizeof($a_lines); $n++) {
-    $line = $a_lines[$n];
-    $quotation = '';
-    $q = 0;
+  // free some memory (hopefully)
+  unset($data['body']);
+
+  // plaintext postprocessing
+  if ($part->ctype_secondary == 'plain') {
+    // make links and email-addresses clickable
+    $replacements = new rcube_string_replacer;
     
-    if (preg_match('/^(>+\s*)+/', $line, $regs)) {
-      $q    = strlen(preg_replace('/\s/', '', $regs[0]));
-      $line = substr($line, strlen($regs[0]));
-
-      if ($q > $quote_level)
-        $quotation = str_repeat('<blockquote>', $q - $quote_level);
-      else if ($q < $quote_level)
-        $quotation = str_repeat("</blockquote>", $quote_level - $q);
+    // search for patterns like links and e-mail addresses
+    $body = preg_replace_callback($replacements->link_pattern, array($replacements, 'link_callback'), $body);
+    $body = preg_replace_callback($replacements->mailto_pattern, array($replacements, 'mailto_callback'), $body);
+
+    // split body into single lines
+    $a_lines = preg_split('/\r?\n/', $body);
+    $q_lines = array();
+    $quote_level = 0;
+
+    // find/mark quoted lines...
+    for ($n=0, $cnt=count($a_lines); $n < $cnt; $n++) {
+      $q = 0;
+    
+      if ($a_lines[$n][0] == '>' && preg_match('/^(>+\s*)+/', $a_lines[$n], $regs)) {
+        $q = strlen(preg_replace('/\s/', '', $regs[0]));
+       $a_lines[$n] = substr($a_lines[$n], strlen($regs[0]));
+
+        if ($q > $quote_level)
+          $q_lines[$n]['quote'] = $q - $quote_level;
+        else if ($q < $quote_level)
+          $q_lines[$n]['endquote'] = $quote_level - $q;
+      }
+      else if ($quote_level > 0)
+        $q_lines[$n]['endquote'] = $quote_level;
+
+      $quote_level = $q;
     }
-    else if ($quote_level > 0)
-      $quotation = str_repeat("</blockquote>", $quote_level);
 
-    $quote_level = $q;
-    $a_lines[$n] = $quotation . Q($line, 'replace', false);  // htmlquote plaintext
+    // quote plain text
+    $body = Q(join("\n", $a_lines), 'replace', false);
+
+    // colorize signature
+    if (($sp = strrpos($body, '-- ')) !== false)
+      if (($sp == 0 || $body[$sp-1] == "\n") && $body[$sp+3] == "\n") {
+       $body = substr($body, 0, max(0, $sp))
+           .'<span class="sig">'.substr($body, $sp).'</span>';
+      }
+
+    // colorize quoted lines
+    $a_lines = preg_split('/\n/', $body);
+    foreach ($q_lines as $i => $q)
+      if ($q['quote'])
+        $a_lines[$i] = str_repeat('<blockquote>', $q['quote']) . $a_lines[$i];
+      else if ($q['endquote'])
+        $a_lines[$i] = str_repeat('</blockquote>', $q['endquote']) . $a_lines[$i];
+
+    // insert the links for urls and mailtos
+    $body = $replacements->resolve(join("\n", $a_lines));
   }
 
-  // insert the links for urls and mailtos
-  $body = $replacements->resolve(join("\n", $a_lines));
+  // allow post-processing of the message body
+  $data = $RCMAIL->plugins->exec_hook('message_part_after', array('type' => $part->ctype_secondary, 'body' => $body) + $data);
 
-  return html::tag('pre', array(), $body);
+  return $data['type'] == 'html' ? $data['body'] : html::tag('pre', array(), $data['body']);
 }
 
 
@@ -821,7 +863,7 @@ function rcmail_washtml_callback($tagname, $attrib, $content)
       
     case 'style':
       // decode all escaped entities and reduce to ascii strings
-      $stripped = preg_replace('/[^a-zA-Z\(:]/', '', rcmail_xss_entitiy_decode($content));
+      $stripped = preg_replace('/[^a-zA-Z\(:]/', '', rcmail_xss_entity_decode($content));
       
       // now check for evil strings like expression, behavior or url()
       if (!preg_match('/expression|behavior|url\(|import/', $stripped)) {
@@ -837,12 +879,28 @@ function rcmail_washtml_callback($tagname, $attrib, $content)
 }
 
 
+/**
+ * Callback function for HTML tags fixing
+ */
+function rcmail_html_tag_callback($matches)
+{
+  $tagname = $matches[2];
+
+  $tagname = preg_replace(array(
+    '/:.*$/',          // Microsoft's Smart Tags <st1:xxxx>
+    '/[^a-z0-9_-]/i',  // forbidden characters
+    ), '', $tagname);
+
+  return $matches[1].$tagname;
+}
+
+
 /**
  * return table with message headers
  */
 function rcmail_message_headers($attrib, $headers=NULL)
   {
-  global $IMAP, $OUTPUT, $MESSAGE, $PRINT_MODE, $CONFIG;
+  global $IMAP, $OUTPUT, $MESSAGE, $PRINT_MODE, $RCMAIL;
   static $sa_attrib;
   
   // keep header table attrib
@@ -851,66 +909,62 @@ function rcmail_message_headers($attrib, $headers=NULL)
   else if (!is_array($attrib) && is_array($sa_attrib))
     $attrib = $sa_attrib;
   
-  
   if (!isset($MESSAGE))
     return FALSE;
 
   // get associative array of headers object
   if (!$headers)
     $headers = is_object($MESSAGE->headers) ? get_object_vars($MESSAGE->headers) : $MESSAGE->headers;
-    
-  $header_count = 0;
-  
-  // allow the following attributes to be added to the <table> tag
-  $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));
-  $out = '<table' . $attrib_str . ">\n";
 
   // show these headers
   $standard_headers = array('subject', 'from', 'to', 'cc', 'bcc', 'replyto', 'date');
+  $output_headers = array();
 
-  foreach ($standard_headers as $hkey)
-    {
+  foreach ($standard_headers as $hkey) {
     if (!$headers[$hkey])
       continue;
 
-    if ($hkey == 'date')
-      {
+    if ($hkey == 'date') {
       if ($PRINT_MODE)
-        $header_value = format_date($headers[$hkey], $CONFIG['date_long'] ? $CONFIG['date_long'] : 'x');
+        $header_value = format_date($headers[$hkey], $RCMAIL->config->get('date_long', 'x'));
       else
         $header_value = format_date($headers[$hkey]);
-      }
-    else if ($hkey == 'replyto')
-      {
+    }
+    else if ($hkey == 'replyto') {
       if ($headers['replyto'] != $headers['from'])
-        $header_value = Q(rcmail_address_string($headers['replyto'], null, true, $attrib['addicon']), 'show');
+        $header_value = rcmail_address_string($headers['replyto'], null, true, $attrib['addicon']);
       else
         continue;
-      }
+    }
     else if (in_array($hkey, array('from', 'to', 'cc', 'bcc')))
-      $header_value = Q(rcmail_address_string($headers[$hkey], null, true, $attrib['addicon']), 'show');
+      $header_value = rcmail_address_string($headers[$hkey], null, true, $attrib['addicon']);
     else if ($hkey == 'subject' && empty($headers[$hkey]))
-      $header_value = Q(rcube_label('nosubject'));
+      $header_value = rcube_label('nosubject');
     else
-      $header_value = Q(trim($IMAP->decode_header($headers[$hkey])));
-
-    $out .= "\n<tr>\n";
-    $out .= '<td class="header-title">'.Q(rcube_label($hkey)).":&nbsp;</td>\n";
-    $out .= '<td class="'.$hkey.'" width="90%">'.$header_value."</td>\n</tr>";
-    $header_count++;
-    }
+      $header_value = trim($IMAP->decode_header($headers[$hkey]));
+      
+    $output_headers[$hkey] = array('title' => rcube_label($hkey), 'value' => $header_value, 'raw' => $headers[$hkey]);
+  }
+    
+  $plugin = $RCMAIL->plugins->exec_hook('message_headers_output', array('output' => $output_headers, 'headers' => $MESSAGE->headers));
+  
+  // compose html table
+  $table = new html_table(array('cols' => 2));
+  
+  foreach ($plugin['output'] as $hkey => $row) {
+    $table->add(array('class' => 'header-title'), Q($row['title']));
+    $table->add(array('class' => $hkey, 'width' => "90%"), Q($row['value'], ($hkey == 'subject' ? 'strict' : 'show')));
+  }
 
   // all headers division
-  $out .= "\n".'<tr><td colspan="2" class="more-headers show-headers"
-       onclick="return '.JS_OBJECT_NAME.'.command(\'load-headers\', \'\', this)"></td></tr>';
-  $out .= "\n".'<tr id="all-headers"><td colspan="2" class="all"><div id="headers-source"></div></td></tr>';
-
+  $table->add(array('colspan' => 2, 'class' => "more-headers show-headers", 'onclick' => "return ".JS_OBJECT_NAME.".command('load-headers','',this)"), '');
+  $table->add_row(array('id' => "all-headers"));
+  $table->add(array('colspan' => 2, 'class' => "all"), html::div(array('id' => 'headers-source'), ''));
+  
   $OUTPUT->add_gui_object('all_headers_row', 'all-headers');
   $OUTPUT->add_gui_object('all_headers_box', 'headers-source');
 
-  $out .= "\n</table>\n\n";
-
-  return $header_count ? $out : '';  
+  return $table->show($attrib);
   }
 
 
@@ -944,7 +998,7 @@ function rcmail_message_body($attrib)
       {
       if ($part->type == 'headers')
         $out .= rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : NULL, $part->headers);
-      else if ($part->type == 'content')
+      else if ($part->type == 'content' && $part->size)
         {
         if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset']))
           $part->ctype_parameters['charset'] = $MESSAGE->headers->charset;
@@ -965,7 +1019,6 @@ function rcmail_message_body($attrib)
   else
     $out .= html::div('message-part', html::tag('pre', array(), Q($MESSAGE->body)));
 
-
   $ctype_primary = strtolower($MESSAGE->structure->ctype_primary);
   $ctype_secondary = strtolower($MESSAGE->structure->ctype_secondary);
 
@@ -1251,19 +1304,16 @@ function rcmail_compose_cleanup()
   if (!isset($_SESSION['compose']))
     return;
 
-  // remove attachment files from temp dir
-  if (is_array($_SESSION['compose']['attachments']))
-    foreach ($_SESSION['compose']['attachments'] as $attachment)
-      @unlink($attachment['path']);
+  rcmail::get_instance()->plugins->exec_hook('cleanup_attachments',array());
   
-  unset($_SESSION['compose']);
+  rcube_sess_unset('compose');
   }
   
 
 /**
  * Send the given message compose object using the configured method
  */
-function rcmail_deliver_message(&$message, $from, $mailto)
+function rcmail_deliver_message(&$message, $from, $mailto, &$smtp_error)
 {
   global $CONFIG, $RCMAIL;
 
@@ -1271,8 +1321,7 @@ function rcmail_deliver_message(&$message, $from, $mailto)
   $headers = $message->headers();
 
   // send thru SMTP server using custom SMTP library
-  if ($CONFIG['smtp_server'])
-    {
+  if ($CONFIG['smtp_server']) {
     // generate list of recipients
     $a_recipients = array($mailto);
   
@@ -1288,18 +1337,20 @@ function rcmail_deliver_message(&$message, $from, $mailto)
     unset($message->_headers['Bcc']);
 
     // send message
-    $smtp_response = array();
-    $sent = smtp_mail($from, $a_recipients, ($foo = $message->txtHeaders($send_headers, true)), $msg_body, $smtp_response);
+    if (!is_object($RCMAIL->smtp))
+      $RCMAIL->smtp_init(true);
+     
+    $sent = $RCMAIL->smtp->send_mail($from, $a_recipients, ($foo = $message->txtHeaders($send_headers, true)), $msg_body);
+    $smtp_response = $RCMAIL->smtp->get_response();
+    $smtp_error = $RCMAIL->smtp->get_error();
 
     // log error
     if (!$sent)
       raise_error(array('code' => 800, 'type' => 'smtp', 'line' => __LINE__, 'file' => __FILE__,
                         'message' => "SMTP error: ".join("\n", $smtp_response)), TRUE, FALSE);
-    }
-  
+  }
   // send mail using PHP's mail() function
-  else
-    {
+  else {
     // unset some headers because they will be added by the mail() function
     $headers_enc = $message->headers($headers);
     $headers_php = $message->_headers;
@@ -1320,19 +1371,21 @@ function rcmail_deliver_message(&$message, $from, $mailto)
       $sent = mail($headers_enc['To'], $headers_enc['Subject'], $msg_body, $header_str);
     else
       $sent = mail($headers_enc['To'], $headers_enc['Subject'], $msg_body, $header_str, "-f$from");
-    }
+  }
   
-  if ($sent)
-  {
+  if ($sent) {
+    $RCMAIL->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body));
+    
     // remove MDN headers after sending
     unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']);
     
-    if ($CONFIG['smtp_log'])
+    if ($CONFIG['smtp_log']) {
       write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s",
-               $RCMAIL->user->get_username(),
-               $_SERVER['REMOTE_ADDR'],
-               $mailto,
-               !empty($smtp_response) ? join('; ', $smtp_response) : ''));
+        $RCMAIL->user->get_username(),
+        $_SERVER['REMOTE_ADDR'],
+        $mailto,
+        !empty($smtp_response) ? join('; ', $smtp_response) : ''));
+    }
   }
   
   $message->_headers = array();
@@ -1342,7 +1395,7 @@ function rcmail_deliver_message(&$message, $from, $mailto)
 }
 
 
-function rcmail_send_mdn($uid)
+function rcmail_send_mdn($uid, &$smtp_error)
 {
   global $RCMAIL, $IMAP;
 
@@ -1400,7 +1453,7 @@ function rcmail_send_mdn($uid)
     $compose->setTXTBody(rc_wordwrap($body, 75, "\r\n"));
     $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline');
 
-    $sent = rcmail_deliver_message($compose, $identity['email'], $mailto);
+    $sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error);
 
     if ($sent)
     {
@@ -1415,7 +1468,7 @@ function rcmail_send_mdn($uid)
 
 function rcmail_search_filter($attrib)
 {
-  global $OUTPUT;
+  global $OUTPUT, $CONFIG;
 
   if (!strlen($attrib['id']))
     $attrib['id'] = 'rcmlistfilter';
@@ -1435,6 +1488,8 @@ function rcmail_search_filter($attrib)
   $select_filter->add(rcube_label('unread'), 'UNSEEN');
   $select_filter->add(rcube_label('flagged'), 'FLAGGED');
   $select_filter->add(rcube_label('unanswered'), 'UNANSWERED');
+  if (!$CONFIG['skip_deleted'])
+    $select_filter->add(rcube_label('deleted'), 'DELETED');
 
   $out = $select_filter->show($_SESSION['search_filter']);
 
index 23d412d613afe0eafaf0eba90f6e526a03241f76..acec6c80a36349a2c03e9c3164f80d29e9d0e916 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: get.inc 2282 2009-02-08 20:38:54Z thomasb $
+ $Id: get.inc 2912 2009-09-04 10:38:18Z thomasb $
 
 */
 
@@ -25,14 +25,15 @@ if (!empty($_GET['_preload'])) {
   $url = str_replace('&_preload=1', '', $_SERVER['REQUEST_URI']);
   $message = rcube_label('loadingdata');
 
-  print "<html>\n<head>\n" .
-        '<meta http-equiv="refresh" content="0; url='.Q($url).'">' .
-        "\n</head>\n<body>" .
-        $message .
-        "\n</body>\n</html>";
+  header('Content-Type: text/html; charset=' . RCMAIL_CHARSET);
+  print "<html>\n<head>\n"
+        . '<meta http-equiv="refresh" content="0; url='.Q($url).'">' . "\n"
+        . '<meta http-equiv="content-type" content="text/html; charset='.RCMAIL_CHARSET.'">' . "\n"
+        . "</head>\n<body>\n$message\n</body>\n</html>";
   exit;
 }
 
+ob_end_clean();
 
 // similar code as in program/steps/mail/show.inc
 if (!empty($_GET['_uid'])) {
@@ -112,7 +113,7 @@ else if ($pid = get_input_value('_part', RCUBE_INPUT_GET)) {
       // turn off output buffering and print part content
       if ($part->body)
         echo $part->body;
-      else
+      else if ($part->size)
         $IMAP->get_message_part($MESSAGE->uid, $part->mime_id, $part, true);
     }
 
index 1ae84c3eae1ebf7b66d5ca1a8945e0b104642bc1..4df43722b5d1a2db01c4cc83162608a59d68e237 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: list.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: list.inc 2634 2009-06-11 07:53:32Z alec $
 
 */
 
@@ -57,11 +57,10 @@ if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL')
                              
 
 // fetch message headers
-if ($IMAP->messagecount($mbox_name, 'ALL', !empty($_REQUEST['_refresh'])))
+if ($count = $IMAP->messagecount($mbox_name, 'ALL', !empty($_REQUEST['_refresh'])))
   $a_headers = $IMAP->list_headers($mbox_name, NULL, $sort_col, $sort_order);
 
-$count = $IMAP->messagecount($mbox_name);
-$unseen = $IMAP->messagecount($mbox_name, 'UNSEEN', !empty($_REQUEST['_refresh']));
+$unseen = $count ? $IMAP->messagecount($mbox_name, 'UNSEEN', !empty($_REQUEST['_refresh'])) : 0;
 
 // update message count display
 $pages = ceil($count/$IMAP->page_size);
index b7edeb4a83611f5ae72ba35beb5a8ef3956de0ab..718ac0dad9933baa052cff6bcd78f6889c64fa17 100644 (file)
@@ -4,7 +4,7 @@
  | program/steps/mail/mark.inc                                           |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: mark.inc 1962 2008-10-09 06:25:43Z alec $
+ $Id: mark.inc 2758 2009-07-16 15:01:05Z thomasb $
 
 */
 
+// only process ajax requests
+if (!$OUTPUT->ajax_call)
+  return;
+
 $a_flags_map = array(
   'undelete' => 'UNDELETED',
   'delete' => 'DELETED',
@@ -29,25 +33,86 @@ $a_flags_map = array(
 if (($uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_value('_flag', RCUBE_INPUT_POST)))
 {
   $flag = $a_flags_map[$flag] ? $a_flags_map[$flag] : strtoupper($flag);
+
+  if ($flag == 'DELETED' && $CONFIG['skip_deleted'] && $_POST['_from'] != 'show') {
+    // count messages before changing anything
+    $old_count = $IMAP->messagecount();
+    $old_pages = ceil($old_count / $IMAP->page_size);
+    $count = sizeof(explode(',', $uids));
+  }
+
   $marked = $IMAP->set_flag($uids, $flag);
+  
+  if ($marked == -1) {
+    // send error message
+    if ($_POST['_from'] != 'show')
+      $OUTPUT->command('list_mailbox');
+    $OUTPUT->show_message('errormarking', 'error');
+    $OUTPUT->send();
+    exit;
+  }
 
-  if($flag == 'DELETED' && $CONFIG['read_when_deleted'] && !empty($_POST['_ruid']))
-    {
+  if($flag == 'DELETED' && $CONFIG['read_when_deleted'] && !empty($_POST['_ruid'])) {
     $uids = get_input_value('_ruid', RCUBE_INPUT_POST);
     $read = $IMAP->set_flag($uids, 'SEEN');
     
-    if ($read != -1)
+    if ($read != -1 && !$CONFIG['skip_deleted'])
       $OUTPUT->command('flag_deleted_as_read', $uids);
-    }
-
-  if ($marked != -1 && ($flag == 'SEEN' || $flag == 'UNSEEN'))
-  {
+  }
+    
+  if ($flag == 'SEEN' || $flag == 'UNSEEN' || ($flag == 'DELETED' && !$CONFIG['skip_deleted'])) {
     $mbox_name = $IMAP->get_mailbox_name();
     $OUTPUT->command('set_unread_count', $mbox_name, $IMAP->messagecount($mbox_name, 'UNSEEN'), ($mbox_name == 'INBOX'));
   }
+  else if ($flag == 'DELETED' && $CONFIG['skip_deleted']) {
+    if ($_POST['_from'] == 'show') {
+      if ($next = get_input_value('_next_uid', RCUBE_INPUT_GPC))
+        $OUTPUT->command('show_message', $next);
+      else
+        $OUTPUT->command('command', 'list');
+    } else {
+      // refresh saved search set after moving some messages
+      if (($search_request = get_input_value('_search', RCUBE_INPUT_GPC)) && $IMAP->search_set) {
+        $_SESSION['search'][$search_request] = $IMAP->refresh_search();
+      }
+
+      $msg_count      = $IMAP->messagecount();
+      $pages          = ceil($msg_count / $IMAP->page_size);
+      $nextpage_count = $old_count - $IMAP->page_size * $IMAP->list_page;
+      $remaining      = $msg_count - $IMAP->page_size * ($IMAP->list_page - 1);
+
+      // jump back one page (user removed the whole last page)
+      if ($IMAP->list_page > 1 && $nextpage_count <= 0 && $remaining == 0) {
+        $IMAP->set_page($IMAP->list_page-1);
+        $_SESSION['page'] = $IMAP->list_page;
+        $jump_back = true;
+      }
+
+      // update message count display
+      $OUTPUT->set_env('messagecount', $msg_count);
+      $OUTPUT->set_env('current_page', $IMAP->list_page);
+      $OUTPUT->set_env('pagecount', $pages);
+
+      // update mailboxlist
+      $mbox = $IMAP->get_mailbox_name();
+      $unseen_count = $msg_count ? $IMAP->messagecount($mbox, 'UNSEEN') : 0;
+      $OUTPUT->command('set_unread_count', $mbox, $unseen_count, ($mbox == 'INBOX'));
+      $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count));
 
+      // add new rows from next page (if any)
+      if (($jump_back || $nextpage_count > 0)) {
+        $sort_col   = isset($_SESSION['sort_col'])   ? $_SESSION['sort_col']   : $CONFIG['message_sort_col'];
+        $sort_order = isset($_SESSION['sort_order']) ? $_SESSION['sort_order'] : $CONFIG['message_sort_order'];
+  
+        $a_headers = $IMAP->list_headers($mbox, NULL, $sort_col, $sort_order, $count);
+      
+        rcmail_js_message_list($a_headers, false, false);
+      }
+    }
+  }
+  
   $OUTPUT->send();
 }
   
 exit;
-?>
\ No newline at end of file
+?>
index 013acbd0e0619c3f6730751851a1406cd0b6f8c0..2262b48c4bc1f2ab17cc22bbea68f3d65ecc59a2 100644 (file)
@@ -5,7 +5,7 @@
  | program/steps/mail/move_del.inc                                       |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: move_del.inc 2018 2008-10-27 10:53:56Z alec $
+ $Id: move_del.inc 2758 2009-07-16 15:01:05Z thomasb $
 
 */
 
+// only process ajax requests
+if (!$OUTPUT->ajax_call)
+  return;
+
 // count messages before changing anything
 $old_count = $IMAP->messagecount();
 $old_pages = ceil($old_count / $IMAP->page_size);
@@ -37,14 +41,14 @@ if ($RCMAIL->action=='moveto' && !empty($_POST['_uid']) && !empty($_POST['_targe
   
     if (!$moved) {
         // send error message
-        $OUTPUT->command('list_mailbox');
+       if ($_POST['_from'] != 'show')
+          $OUTPUT->command('list_mailbox');
         $OUTPUT->show_message('errormoving', 'error');
         $OUTPUT->send();
         exit;
     }
 
-    if (!$CONFIG['flag_for_deletion'])
-        $addrows = true;
+    $addrows = true;
 }
 // delete messages 
 else if ($RCMAIL->action=='delete' && !empty($_POST['_uid'])) {
@@ -54,7 +58,8 @@ else if ($RCMAIL->action=='delete' && !empty($_POST['_uid'])) {
   
     if (!$del) {
         // send error message
-        $OUTPUT->command('list_mailbox');
+       if ($_POST['_from'] != 'show')
+          $OUTPUT->command('list_mailbox');
         $OUTPUT->show_message('errordeleting', 'error');
         $OUTPUT->send();
         exit;
@@ -66,50 +71,62 @@ else if ($RCMAIL->action=='delete' && !empty($_POST['_uid'])) {
 else {
     exit;
 }
+
 // refresh saved search set after moving some messages
 if (($search_request = get_input_value('_search', RCUBE_INPUT_GPC)) && $IMAP->search_set) {
     $_SESSION['search'][$search_request] = $IMAP->refresh_search();
 }
 
-$msg_count      = $IMAP->messagecount();
-$pages          = ceil($msg_count / $IMAP->page_size);
-$nextpage_count = $old_count - $IMAP->page_size * $IMAP->list_page;
-$remaining      = $msg_count - $IMAP->page_size * ($IMAP->list_page - 1);
-
-// jump back one page (user removed the whole last page)
-if ($IMAP->list_page > 1 && $nextpage_count <= 0 && $remaining == 0) {
+if ($_POST['_from'] == 'show')
+{
+  if ($next = get_input_value('_next_uid', RCUBE_INPUT_GPC))
+    $OUTPUT->command('show_message', $next);
+  else
+    $OUTPUT->command('command', 'list');
+}
+else
+{
+  $msg_count      = $IMAP->messagecount();
+  $pages          = ceil($msg_count / $IMAP->page_size);
+  $nextpage_count = $old_count - $IMAP->page_size * $IMAP->list_page;
+  $remaining      = $msg_count - $IMAP->page_size * ($IMAP->list_page - 1);
+
+  // jump back one page (user removed the whole last page)
+  if ($IMAP->list_page > 1 && $nextpage_count <= 0 && $remaining == 0) {
     $IMAP->set_page($IMAP->list_page-1);
     $_SESSION['page'] = $IMAP->list_page;
     $jump_back = true;
-}
+  }
 
-// update message count display
-$OUTPUT->set_env('pagecount', $pages);
-$OUTPUT->set_env('messagecount', $msg_count);
-$OUTPUT->set_env('current_page', $IMAP->list_page);
-$OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count));
+  // update message count display
+  $OUTPUT->set_env('messagecount', $msg_count);
+  $OUTPUT->set_env('current_page', $IMAP->list_page);
+  $OUTPUT->set_env('pagecount', $pages);
 
-// update mailboxlist
-$mbox = $IMAP->get_mailbox_name();
-$OUTPUT->command('set_unread_count', $mbox, $IMAP->messagecount($mbox, 'UNSEEN'), ($mbox == 'INBOX'));
+  // update mailboxlist
+  $mbox = $IMAP->get_mailbox_name();
+  $unseen_count = $msg_count ? $IMAP->messagecount($mbox, 'UNSEEN') : 0;
+  $OUTPUT->command('set_unread_count', $mbox, $unseen_count, ($mbox == 'INBOX'));
 
-if ($RCMAIL->action=='moveto' && $target) {
+  if ($RCMAIL->action=='moveto' && $target) {
     $OUTPUT->command('set_unread_count', $target, $IMAP->messagecount($target, 'UNSEEN'));
-}
+  }
 
-$OUTPUT->command('set_quota', rcmail_quota_content($IMAP->get_quota()));
+  $OUTPUT->command('set_quota', rcmail_quota_content($IMAP->get_quota()));
+  $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count));
 
-// add new rows from next page (if any)
-if ($addrows && $_POST['_from']!='show' && ($jump_back || $nextpage_count > 0)) {
+  // add new rows from next page (if any)
+  if ($addrows && ($jump_back || $nextpage_count > 0)) {
     $sort_col   = isset($_SESSION['sort_col'])   ? $_SESSION['sort_col']   : $CONFIG['message_sort_col'];
     $sort_order = isset($_SESSION['sort_order']) ? $_SESSION['sort_order'] : $CONFIG['message_sort_order'];
-  
-    $a_headers = $IMAP->list_headers($mbox, NULL, $sort_col, $sort_order);
-    if (!$jump_back) {
-        $a_headers = array_slice($a_headers, -$count, $count);
-    }
-    rcmail_js_message_list($a_headers);
+
+    $a_headers = $IMAP->list_headers($mbox, NULL, $sort_col, $sort_order, $count);
+
+    rcmail_js_message_list($a_headers, false, false);
+  }
 }
 
 // send response
 $OUTPUT->send();
+
+?>
index ed6c2b7054f89e243c853a24f6d1fbc06ce346ac..b8fe716df81dfd58053060e0d5adafe917f288ca 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Sjon Hortensius <sjon@hortensius.net>                         |
  +-----------------------------------------------------------------------+
 
- $Id: rss.inc 2223 2009-01-08 14:12:00Z alec $
+ $Id: rss.inc 2672 2009-06-22 16:20:34Z alec $
 
 */
 
@@ -49,7 +49,7 @@ $sort_order = 'DESC';
 
 // Send global XML output
 header('Content-type: text/xml');
-echo '<?xml version="1.0" encoding="UTF-8"?>
+echo '<?xml version="1.0" encoding="'.RCMAIL_CHARSET.'"?>
        <rss version="2.0"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
index 95ca67a12502423be93c03e831b63c1be3f4e448..d62b128d3ed14e9aa30083524e54041b7258d69b 100644 (file)
@@ -21,13 +21,14 @@ $IMAP->set_search_set(NULL);
 $_SESSION['page'] = 1;
 
 // using encodeURI with javascript "should" give us
-// a correctly UTF-8 encoded query string
-$imap_charset = 'UTF-8';
+// a correctly encoded query string
+$imap_charset = RCMAIL_CHARSET;
 
 // get search string
 $str = get_input_value('_q', RCUBE_INPUT_GET);
 $filter = get_input_value('_filter', RCUBE_INPUT_GET);
 $mbox = get_input_value('_mbox', RCUBE_INPUT_GET);
+$headers = get_input_value('_headers', RCUBE_INPUT_GET);
 $search_request = md5($mbox.$filter.$str);
 
 // add list filter string
@@ -39,47 +40,55 @@ $_SESSION['search_filter'] = $filter;
 if (preg_match("/^from:.*/i", $str))
 {
   list(,$srch) = explode(":", $str);
-  $subject = "HEADER FROM";
-  $search = trim($srch);
+  $subject['from'] = "HEADER FROM";
 }
 else if (preg_match("/^to:.*/i", $str))
 {
   list(,$srch) = explode(":", $str);
-  $subject = "HEADER TO";
-  $search = trim($srch);
+  $subject['to'] = "HEADER TO";
 }
 else if (preg_match("/^cc:.*/i", $str))
 {
   list(,$srch) = explode(":", $str);
-  $subject = "HEADER CC";
-  $search = trim($srch);
+  $subject['cc'] = "HEADER CC";
+}
+else if (preg_match("/^bcc:.*/i", $str))
+{
+  list(,$srch) = explode(":", $str);
+  $subject['bcc'] = "HEADER BCC";
 }
 else if (preg_match("/^subject:.*/i", $str))
 {
   list(,$srch) = explode(":", $str);
-  $subject = "HEADER SUBJECT";
-  $search = trim($srch);
+  $subject['subject'] = "HEADER SUBJECT";
 }
 else if (preg_match("/^body:.*/i", $str))
 {
   list(,$srch) = explode(":", $str);
-  $subject = "TEXT";
-  $search = trim($srch);
+  $subject['text'] = "TEXT";
 }
 // search in subject and sender by default
 else if(trim($str))
 {
-  $from = ($mbox == $CONFIG['sent_mbox'] || $mbox == $CONFIG['drafts_mbox']) ? "TO" : "FROM";
-  $subject = array("HEADER SUBJECT", "HEADER $from");
-  $search = trim($str);
+  if ($headers) {
+    $headers = explode(',', $headers);
+    foreach($headers as $header)
+      switch ($header) {
+        case 'text': $subject['text'] = 'TEXT'; break;
+        default: $subject[$header] = 'HEADER '.$header;
+      }
+  } else {
+    $subject['subject'] = 'HEADER SUBJECT';
+  }
 }
 
-if ($subject && !is_array($subject))
-  $search_str .= sprintf(" %s {%d}\r\n%s", $subject, strlen($search), $search);
-else if ($subject) {
-  $search_str .= ' OR';
-  foreach($subject as $sub)
+$search = $srch ? trim($srch) : trim($str);
+
+if ($subject) {
+  $search_str .= str_repeat(' OR', count($subject)-1);
+  foreach ($subject as $sub)
     $search_str .= sprintf(" %s {%d}\r\n%s", $sub, strlen($search), $search);
+  $_SESSION['search_mods'] = $subject;
 }
 
 $search_str = trim($search_str);
index 418e1728327213e2bc08180479a43b419a78147d..85ea8739fc3e74de371b4379f0819ab328a5b284 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: sendmail.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: sendmail.inc 2713 2009-07-06 09:13:10Z alec $
 
 */
 
@@ -55,6 +55,17 @@ if (!$savedraft) {
 
 /****** message sending functions ********/
 
+// encrypt parts of the header
+function rcmail_encrypt_header($what)
+{
+  global $CONFIG, $RCMAIL;
+  if (!$CONFIG['http_received_header_encrypt'])
+  {
+    return $what;
+  }
+  return $RCMAIL->encrypt($what);
+}
+
 // get identity record
 function rcmail_get_identity($id)
   {
@@ -138,7 +149,7 @@ function rcmail_attach_emoticons(&$mime_message)
 }
 
 // parse email address input
-function rcmail_mailto_format($mailto)
+function rcmail_email_input_format($mailto)
 {
   $regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/', '/(\S{1})(<\S+@\S+>)/U');
   $replace = array(', ', ', ', '', ',', '\\1 \\2');
@@ -189,9 +200,9 @@ $message_id = sprintf('<%s@%s>', md5(uniqid('rcmail'.rand(),true)), $RCMAIL->con
 $input_charset = $OUTPUT->get_charset();
 $message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $input_charset;
 
-$mailto = rcmail_mailto_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset));
-$mailcc = rcmail_mailto_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset));
-$mailbcc = rcmail_mailto_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset));
+$mailto = rcmail_email_input_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset));
+$mailcc = rcmail_email_input_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset));
+$mailbcc = rcmail_email_input_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset));
 
 if (empty($mailto) && !empty($mailcc)) {
   $mailto = $mailcc;
@@ -201,19 +212,42 @@ else if (empty($mailto))
   $mailto = 'undisclosed-recipients:;';
 
 // get sender name and address
-$from = get_input_value('_from', RCUBE_INPUT_POST);
+$from = get_input_value('_from', RCUBE_INPUT_POST, true, $message_charset);
 $identity_arr = rcmail_get_identity($from);
 
-if ($identity_arr)
+if (!$identity_arr && ($from = rcmail_email_input_format($from))) {
+  if (preg_match('/(\S+@\S+)/', $from, $m))
+    $identity_arr['mailto'] = $m[1];
+} else
   $from = $identity_arr['mailto'];
 
 if (empty($identity_arr['string']))
   $identity_arr['string'] = $from;
 
 // compose headers array
-$headers = array('Date' => date('r'),
-                 'From' => rcube_charset_convert($identity_arr['string'], RCMAIL_CHARSET, $message_charset),
-                 'To'   => $mailto);
+$headers = array();
+
+// if configured, the Received headers goes to top, for good measure
+if ($CONFIG['http_received_header'])
+{
+  $nldlm = $RCMAIL->config->header_delimiter() . "\t";
+  $http_header = 'from ';
+  if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+    $http_header .= rcmail_encrypt_header(gethostbyaddr($_SERVER['HTTP_X_FORWARDED_FOR'])) .
+      ' [' . rcmail_encrypt_header($_SERVER['HTTP_X_FORWARDED_FOR']) . ']';
+    $http_header .= $nldlm . ' via ';
+  }
+  $http_header .= rcmail_encrypt_header(gethostbyaddr($_SERVER['REMOTE_ADDR'])) .
+      ' [' . rcmail_encrypt_header($_SERVER['REMOTE_ADDR']) .']';
+  $http_header .= $nldlm . 'with ' . $_SERVER['SERVER_PROTOCOL'] .
+      ' ('.$_SERVER['REQUEST_METHOD'] . '); ' . date('r');
+  $http_header = wordwrap($http_header, 69, $nldlm);
+  $headers['Received'] = $http_header;
+}
+
+$headers['Date'] = date('r');
+$headers['From'] = rcube_charset_convert($identity_arr['string'], RCMAIL_CHARSET, $message_charset);
+$headers['To'] = $mailto;
 
 // additional recipients
 if (!empty($mailcc))
@@ -226,13 +260,13 @@ if (!empty($identity_arr['bcc']))
   $headers['Bcc'] = ($headers['Bcc'] ? $headers['Bcc'].', ' : '') . $identity_arr['bcc'];
 
 // add subject
-$headers['Subject'] = trim(get_input_value('_subject', RCUBE_INPUT_POST, FALSE, $message_charset));
+$headers['Subject'] = trim(get_input_value('_subject', RCUBE_INPUT_POST, TRUE, $message_charset));
 
 if (!empty($identity_arr['organization']))
   $headers['Organization'] = $identity_arr['organization'];
 
 if (!empty($_POST['_replyto']))
-  $headers['Reply-To'] = rcmail_mailto_format(get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset));
+  $headers['Reply-To'] = rcmail_email_input_format(get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset));
 else if (!empty($identity_arr['reply-to']))
   $headers['Reply-To'] = $identity_arr['reply-to'];
 
@@ -257,16 +291,6 @@ if (!empty($_POST['_receipt']))
   }
 
 // additional headers
-if ($CONFIG['http_received_header'])
-{
-  $nldlm = $RCMAIL->config->header_delimiter() . "\t";
-  $headers['Received'] =  wordwrap('from ' . (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ?
-      gethostbyaddr($_SERVER['HTTP_X_FORWARDED_FOR']).' ['.$_SERVER['HTTP_X_FORWARDED_FOR'].']'.$nldlm.' via ' : '') .
-    gethostbyaddr($_SERVER['REMOTE_ADDR']).' ['.$_SERVER['REMOTE_ADDR'].']'.$nldlm.'with ' .
-    $_SERVER['SERVER_PROTOCOL'].' ('.$_SERVER['REQUEST_METHOD'].'); ' . date('r'),
-    69, $nldlm);
-}
-
 $headers['Message-ID'] = $message_id;
 $headers['X-Sender'] = $from;
 
@@ -287,7 +311,7 @@ if (!$savedraft) {
   // generic footer for all messages
   if (!empty($CONFIG['generic_message_footer'])) {
     $footer = file_get_contents(realpath($CONFIG['generic_message_footer']));
-    $footer = rcube_charset_convert($footer, 'UTF-8', $message_charset);
+    $footer = rcube_charset_convert($footer, RCMAIL_CHARSET, $message_charset);
   }
 }
 
@@ -297,86 +321,92 @@ $MAIL_MIME = new rcube_mail_mime($RCMAIL->config->header_delimiter());
 // For HTML-formatted messages, construct the MIME message with both
 // the HTML part and the plain-text part
 
-if ($isHtml)
-  {
-  $MAIL_MIME->setHTMLBody($message_body . ($footer ? "\r\n<pre>".$footer.'</pre>' : ''));
+if ($isHtml) {
+  $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $message_body, 'type' => 'html', 'message' => $MAIL_MIME));
+  $MAIL_MIME->setHTMLBody($plugin['body'] . ($footer ? "\r\n<pre>".$footer.'</pre>' : ''));
 
   // add a plain text version of the e-mail as an alternative part.
-  $h2t = new html2text($message_body, false, true, 0);
-  $plainTextPart = rc_wordwrap($h2t->get_text(), 75, "\r\n"). ($footer ? "\r\n".$footer : '');
+  $h2t = new html2text($plugin['body'], false, true, 0);
+  $plainTextPart = rc_wordwrap($h2t->get_text(), 75, "\r\n") . ($footer ? "\r\n".$footer : '');
   $plainTextPart = wordwrap($plainTextPart, 998, "\r\n", true);
-  if (!strlen($plainTextPart))
-    { 
+  if (!strlen($plainTextPart)) {
     // empty message body breaks attachment handling in drafts 
     $plainTextPart = "\r\n"; 
-    }
-  $MAIL_MIME->setTXTBody($plainTextPart);
+  }
+  $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $plainTextPart, 'type' => 'alternative', 'message' => $MAIL_MIME));
+  $MAIL_MIME->setTXTBody($plugin['body']);
 
   // look for "emoticon" images from TinyMCE and copy into message as attachments
   $message_body = rcmail_attach_emoticons($MAIL_MIME);
-  }
+}
 else
   {
   $message_body = rc_wordwrap($message_body, 75, "\r\n");
   if ($footer)
     $message_body .= "\r\n" . $footer;
   $message_body = wordwrap($message_body, 998, "\r\n", true);
-  if (!strlen($message_body))  
-    { 
+  if (!strlen($message_body)) { 
     // empty message body breaks attachment handling in drafts 
     $message_body = "\r\n"; 
-    } 
-  $MAIL_MIME->setTXTBody($message_body, FALSE, TRUE);
   }
+  $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $message_body, 'type' => 'plain', 'message' => $MAIL_MIME));
+  $MAIL_MIME->setTXTBody($plugin['body'], false, true);
+}
 
 // chose transfer encoding
 $charset_7bit = array('ASCII', 'ISO-2022-JP', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-15');
 $transfer_encoding = in_array(strtoupper($message_charset), $charset_7bit) ? '7bit' : '8bit';
 
 // add stored attachments, if any
-if (is_array($_SESSION['compose']['attachments']))
-  foreach ($_SESSION['compose']['attachments'] as $id => $attachment)
-  {
-    $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' . $id . '[\s\'"]\s*/';
-    $match = preg_match($dispurl, $message_body, $matches);
-    if ($isHtml && ($match > 0))
-    {
+if (is_array($_SESSION['compose']['attachments'])) {
+  foreach ($_SESSION['compose']['attachments'] as $id => $attachment) {
+    // This hook retrieves the attachment contents from the file storage backend
+    $attachment = $RCMAIL->plugins->exec_hook('get_attachment', $attachment);
+
+    $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' . preg_quote($attachment['id']) . '[\s\'"]\s*/';
+    $message_body = $MAIL_MIME->getHTMLBody();
+    if ($isHtml && (preg_match($dispurl, $message_body) > 0)) {
       $message_body = preg_replace($dispurl, ' src="'.$attachment['name'].'" ', $message_body);
       $MAIL_MIME->setHTMLBody($message_body);
-      $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name']);
+      
+      if ($attachment['data'])
+        $MAIL_MIME->addHTMLImage($attachment['data'], $attachment['mimetype'], $attachment['name'], false);
+      else
+        $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name'], true);
     }
-    else
-    {
+    else {
       $ctype = str_replace('image/pjpeg', 'image/jpeg', $attachment['mimetype']); // #1484914
+      $file = $attachment['data'] ? $attachment['data'] : $attachment['path'];
 
       // .eml attachments send inline
-      $MAIL_MIME->addAttachment($attachment['path'],
+      $MAIL_MIME->addAttachment($file,
         $ctype, 
-        $attachment['name'], true, 
+        $attachment['name'],
+        ($attachment['data'] ? false : true),
         ($ctype == 'message/rfc822' ? $transfer_encoding : 'base64'),
         ($ctype == 'message/rfc822' ? 'inline' : 'attachment'),
         $message_charset, '', '', 
-       $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,
-       $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL
-       );
+        $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,
+        $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL
+      );
     }
   }
+}
 
 // add submitted attachments
-if (is_array($_FILES['_attachments']['tmp_name']))
-  foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath)
-    {
+if (is_array($_FILES['_attachments']['tmp_name'])) {
+  foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) {
     $ctype = $files['type'][$i];
     $ctype = str_replace('image/pjpeg', 'image/jpeg', $ctype); // #1484914
     
     $MAIL_MIME->addAttachment($filepath, $ctype, $files['name'][$i], true,
-       $ctype == 'message/rfc822' ? $transfer_encoding : 'base64',
-       'attachment', $message_charset, '', '', 
-       $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,
-       $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL
-       );
-    }
-
+      $ctype == 'message/rfc822' ? $transfer_encoding : 'base64',
+      'attachment', $message_charset, '', '', 
+      $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,
+      $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL
+    );
+  }
+}
 
 // encoding settings for mail composing
 $MAIL_MIME->setParam(array(
@@ -388,6 +418,9 @@ $MAIL_MIME->setParam(array(
   'text_charset'  => $message_charset,
 ));
 
+$data = $RCMAIL->plugins->exec_hook('outgoing_message_headers', array('headers' => $headers));
+$headers = $data['headers'];
+
 // encoding subject header with mb_encode provides better results with asian characters
 if (function_exists("mb_encode_mimeheader"))
 {
@@ -408,12 +441,15 @@ if (!$savedraft)
     $OUTPUT->send('iframe'); 
   }
 
-  $sent = rcmail_deliver_message($MAIL_MIME, $from, $mailto);
+  $sent = rcmail_deliver_message($MAIL_MIME, $from, $mailto, $smtp_error);
   
   // return to compose page if sending failed
   if (!$sent)
     {
-    $OUTPUT->show_message("sendingfailed", 'error'); 
+    if ($smtp_error)
+      $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']); 
+    else
+      $OUTPUT->show_message('sendingfailed', 'error'); 
     $OUTPUT->send('iframe');
     }
 
@@ -423,9 +459,9 @@ if (!$savedraft)
   
   // set replied/forwarded flag
   if ($_SESSION['compose']['reply_uid'])
-    $IMAP->set_flag($_SESSION['compose']['reply_uid'], 'ANSWERED');
+    $IMAP->set_flag($_SESSION['compose']['reply_uid'], 'ANSWERED', $_SESSION['compose']['mailbox']);
   else if ($_SESSION['compose']['forward_uid'])
-    $IMAP->set_flag($_SESSION['compose']['forward_uid'], 'FORWARDED');
+    $IMAP->set_flag($_SESSION['compose']['forward_uid'], 'FORWARDED', $_SESSION['compose']['mailbox']);
 
 } // End of SMTP Delivery Block
 
index 3d7755cf32b68e4bf9d8c19a9599b08654b806c9..f1fb7929668484b525f6f0d1a0a9957044bc3fd5 100644 (file)
 
 */
 
+// only process ajax requests
+if (!$OUTPUT->ajax_call)
+  return;
 
 if (!empty($_POST['_uid'])) {
-  $sent = rcmail_send_mdn(get_input_value('_uid', RCUBE_INPUT_POST));
+  $sent = rcmail_send_mdn(get_input_value('_uid', RCUBE_INPUT_POST), $smtp_error);
 }
 
 // show either confirm or error message
@@ -29,6 +32,9 @@ if ($sent) {
   $OUTPUT->set_env('mdn_request', false);
   $OUTPUT->show_message('receiptsent', 'confirmation');
 }
+else if ($smtp_error) {
+  $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']);
+}
 else {
   $OUTPUT->show_message('errorsendingreceipt', 'error');
 }
index 26ebf3dac88cfe43bb5ec9bae4031519da5a5869..de30bead282127a21026b161b4252fbdf931ebe8 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: show.inc 2301 2009-02-18 19:15:36Z alec $
+ $Id: show.inc 2822 2009-07-31 09:07:54Z alec $
 
 */
 
@@ -25,21 +25,21 @@ $PRINT_MODE = $RCMAIL->action=='print' ? TRUE : FALSE;
 if ($_GET['_uid']) {
   $MESSAGE = new rcube_message(get_input_value('_uid', RCUBE_INPUT_GET));
 
-  // set message charset as default
-  if (!empty($MESSAGE->headers->charset))
-    $IMAP->set_charset($MESSAGE->headers->charset);
-
-  // go back to list if message not found (wrong UID)
+  // if message not found (wrong UID)...
   if (empty($MESSAGE->headers)) {
     $OUTPUT->show_message('messageopenerror', 'error');
-    if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messagepreview'))
-        $OUTPUT->send('messagepreview');
+    // ... display error or preview page
+    if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messageerror'))
+      $OUTPUT->send('messageerror');
+    else if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messagepreview'))
+      $OUTPUT->send('messagepreview');
+    // ... go back to the list
     else {
       rcmail_overwrite_action('');
       return;
     }
   }
-    
+
   $mbox_name = $IMAP->get_mailbox_name();
   
   // show images?
@@ -50,7 +50,10 @@ if ($_GET['_uid']) {
     .intval($MESSAGE->headers->mdn_sent)
     .intval($MESSAGE->is_safe)
     .(!empty($MESSAGE->attachments) ? intval($CONFIG['inline_images']) : '')
-    .intval($PRINT_MODE));
+    .intval($PRINT_MODE)
+    .$_SESSION['sort_col'].$_SESSION['sort_order']
+    .$IMAP->messagecount($mbox_name, 'ALL', true)
+    );
 
   // allow caching, unless remote images are present
   if ((bool)$MESSAGE->is_safe)
@@ -58,6 +61,10 @@ if ($_GET['_uid']) {
   else if (empty($CONFIG['devel_mode']))
     send_modified_header($_SESSION['login_time'], $etag, !$MESSAGE->headers->seen);
 
+  // set message charset as default
+  if (!empty($MESSAGE->headers->charset))
+    $IMAP->set_charset($MESSAGE->headers->charset);
+
   $OUTPUT->set_pagetitle($MESSAGE->subject);
   
   // give message uid to the client
@@ -71,7 +78,7 @@ if ($_GET['_uid']) {
     $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
   if (!$OUTPUT->ajax_call)
     $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', 'movingmessage');
-    
+        
   // check for unset disposition notification
   if ($MESSAGE->headers->mdn_to &&
       !$MESSAGE->headers->mdn_sent && !$MESSAGE->headers->seen &&
@@ -81,9 +88,11 @@ if ($_GET['_uid']) {
   {
     if (intval($CONFIG['mdn_requests']) === 1)
     {
-      if (rcmail_send_mdn($MESSAGE->uid))
+      if (rcmail_send_mdn($MESSAGE->uid, $smtp_error))
         $OUTPUT->show_message('receiptsent', 'confirmation');
-      else
+      else if ($smtp_error)
+        $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']);
+      else     
         $OUTPUT->show_message('errorsendingreceipt', 'error');
     }
     else if (empty($CONFIG['mdn_requests']))
@@ -98,20 +107,8 @@ if ($_GET['_uid']) {
     {
     $next = $prev = $first = $last = -1;
 
-    if ((!($_SESSION['sort_col'] == 'date' && $_SESSION['sort_order'] == 'DESC') &&
-      $IMAP->get_capability('sort')) || !empty($_REQUEST['_search']))
-      {
-      // Only if we use custom sorting
-      $a_msg_index = $IMAP->message_index(NULL, $_SESSION['sort_col'], $_SESSION['sort_order']);
-
-      $MESSAGE->index = array_search($IMAP->get_id($MESSAGE->uid), $a_msg_index);
-
-      $prev = isset($a_msg_index[$MESSAGE->index-1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index-1]) : -1 ;
-      $first = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[0]) : -1;
-      $next = isset($a_msg_index[$MESSAGE->index+1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index+1]) : -1 ;
-      $last = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[count($a_msg_index)-1]) : -1;
-      }
-    else
+    if ($_SESSION['sort_col'] == 'date' && $_SESSION['sort_order'] != 'DESC'
+        && empty($_REQUEST['_search']) && !$IMAP->skip_deleted)
       {
       // this assumes that we are sorted by date_DESC
       $cnt = $IMAP->messagecount();
@@ -123,6 +120,18 @@ if ($_GET['_uid']) {
       $next = $IMAP->get_uid($seq - 1);
       $last = $IMAP->get_uid(1);
       }
+    else 
+      {
+      // Only if we use custom sorting
+      $a_msg_index = $IMAP->message_index(NULL, $_SESSION['sort_col'], $_SESSION['sort_order']);
+
+      $MESSAGE->index = array_search($IMAP->get_id($MESSAGE->uid), $a_msg_index);
+
+      $prev = isset($a_msg_index[$MESSAGE->index-1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index-1]) : -1 ;
+      $first = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[0]) : -1;
+      $next = isset($a_msg_index[$MESSAGE->index+1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index+1]) : -1 ;
+      $last = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[count($a_msg_index)-1]) : -1;
+      }
 
     if ($prev > 0)
       $OUTPUT->set_env('prev_uid', $prev);
@@ -134,10 +143,13 @@ if ($_GET['_uid']) {
       $OUTPUT->set_env('last_uid', $last);
     }
 
-  // mark message as read
+  if ($CONFIG['display_next'])
+    $OUTPUT->set_env('display_next', true);
+
   if (!$MESSAGE->headers->seen)
-    $IMAP->set_flag($MESSAGE->uid, 'SEEN');
-  }
+    $RCMAIL->plugins->exec_hook('message_read', array('uid' => $MESSAGE->uid,
+      'mailbox' => $IMAP->mailbox, 'message' => $MESSAGE));
+}
 
 
 
@@ -153,7 +165,7 @@ function rcmail_message_attachments($attrib)
         $ol .= html::tag('li', null, sprintf("%s (%s)", Q($attach_prop->filename), Q(show_bytes($attach_prop->size))));
       }
       else {
-        if (rc_strlen($attach_prop->filename) > 50) {
+        if (mb_strlen($attach_prop->filename) > 50) {
           $filename = abbreviate_string($attach_prop->filename, 50);
           $title = $attach_prop->filename;
       }
@@ -212,9 +224,17 @@ $OUTPUT->add_handlers(array(
 
 
 if ($RCMAIL->action=='print' && $OUTPUT->template_exists('printmessage'))
-  $OUTPUT->send('printmessage');
+  $OUTPUT->send('printmessage', false);
 else if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messagepreview'))
-  $OUTPUT->send('messagepreview');
+  $OUTPUT->send('messagepreview', false);
 else
-  $OUTPUT->send('message');
+  $OUTPUT->send('message', false);
+
+
+// mark message as read
+if ($MESSAGE && $MESSAGE->headers && !$MESSAGE->headers->seen)
+  $IMAP->set_flag($MESSAGE->uid, 'SEEN');
+
+exit;
+
 ?>
index 102ef5a14993a4d83d33ae1710745a96efa653c5..717b92ee580dededdd172a0cb5b0660588d60263 100644 (file)
@@ -30,6 +30,9 @@ if (!extension_loaded('pspell')) {
     exit;
 }
 
+// max. number of suggestions for one word
+define('MAX_SUGGESTIONS', 10);
+
 // read input
 $data = file_get_contents('php://input');
 
@@ -46,15 +49,18 @@ $words = preg_split('/[ !"#$%&()*+\\,-.\/\n:;<=>?@\[\]^_{|}]+/', $text, NULL,  P
 $plink = pspell_new(get_input_value('lang', RCUBE_INPUT_GET), null, null, RCMAIL_CHARSET, PSPELL_FAST);
 
 // send output
-$out = '<?xml version="1.0" encoding="UTF-8"?><spellresult charschecked="'.rc_strlen($text).'">';
+$out = '<?xml version="1.0" encoding="'.RCMAIL_CHARSET.'"?><spellresult charschecked="'.mb_strlen($text).'">';
 
 $diff = 0;
 foreach ($words as $w) {
     $word = trim($w[0]);
     $pos  = $w[1] - $diff;
-    $len  = rc_strlen($word);
+    $len  = mb_strlen($word);
     if ($word && $plink && !pspell_check($plink, $word)) {
         $suggestions = pspell_suggest($plink, $word);
+       if (sizeof($suggestions)>10)
+         $suggestions = array_slice($suggestions, 0, MAX_SUGGESTIONS);
+
         $out .= '<c o="'.$pos.'" l="'.$len.'">';
         $out .= implode("\t", $suggestions);
         $out .= '</c>';
index c22f80ace77cca52eefa6db8fd2144fac1644ba3..38c3f6516b5b8a7d6e09fbdd8e1a5b87446b4060 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: viewsource.inc 2237 2009-01-17 01:55:39Z till $
+ $Id: viewsource.inc 2613 2009-06-05 13:34:07Z alec $
 
 */
 
+ob_end_clean();
 
 // similar code as in program/steps/mail/get.inc
 if ($uid = get_input_value('_uid', RCUBE_INPUT_GET))
@@ -26,6 +27,22 @@ if ($uid = get_input_value('_uid', RCUBE_INPUT_GET))
   $headers = $IMAP->get_headers($uid);
   $charset = $headers->charset ? $headers->charset : $IMAP->default_charset;
   header("Content-Type: text/plain; charset={$charset}");
+
+  if (!empty($_GET['_save'])) {
+    $filename = ($headers->subject ? $IMAP->decode_header($headers->subject) : 'roundcube') . '.eml';
+    $browser = new rcube_browser;
+    
+    if ($browser->ie && $browser->ver < 7)
+      $filename = rawurlencode(abbreviate_string($filename, 55));
+    else if ($browser->ie)
+      $filename = rawurlencode($filename);
+    else
+      $filename = addcslashes($filename, '"');
+
+    header("Content-Length: {$headers->size}");
+    header("Content-Disposition: attachment; filename=\"$filename\"");
+  }
+  
   $IMAP->print_raw_body($uid);
 }
 else
index 84f5c33d93b8dcb3c835ba7eb311952dd34a0ce5..c3410603c33b496a9fda5fbc1ebacda621390612 100644 (file)
@@ -5,7 +5,7 @@
  | program/steps/settings/delete_identity.inc                            |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: delete_identity.inc 2008 2008-10-24 08:30:52Z alec $
+ $Id: delete_identity.inc 2779 2009-07-21 16:13:42Z thomasb $
 
 */
 
-if (($ids = get_input_value('_iid', RCUBE_INPUT_GET)) && preg_match('/^[0-9]+(,[0-9]+)*$/', $ids))
+$iid = get_input_value('_iid', RCUBE_INPUT_GPC);
+
+// check request token
+if (!$OUTPUT->ajax_call && !$RCMAIL->check_request(RCUBE_INPUT_GPC)) {
+  $OUTPUT->show_message('invalidrequest', 'error');
+  rcmail_overwrite_action('identities');
+  return;
+}
+
+if ($iid && preg_match('/^[0-9]+(,[0-9]+)*$/', $iid))
 {
-  if ($USER->delete_identity($ids)) {
-    $OUTPUT->show_message('deletedsuccessfully', 'confirmation');
+  $plugin = $RCMAIL->plugins->exec_hook('delete_identity', array('id' => $iid));
+  
+  if (!$plugin['abort'] && $USER->delete_identity($iid)) {
+    $OUTPUT->show_message('deletedsuccessfully', 'confirmation', null, false);
   }
   else {
-    $OUTPUT->show_message('nodeletelastidentity', 'error');
+    $OUTPUT->show_message('nodeletelastidentity', 'error', null, false);
   }
   // send response
   if ($OUTPUT->ajax_call)
index 02802c742a9a7bed3c009a93d5eaeaa3ec00f753..0e5d58d22a2a8e6d5635aa1a47a2153e606ecdad 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: edit_identity.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: edit_identity.inc 2755 2009-07-15 09:49:35Z thomasb $
 
 */
 
@@ -60,7 +60,7 @@ function rcube_identity_form($attrib)
   $t_rows = !empty($attrib['textarearows']) ? $attrib['textarearows'] : 6;
   $t_cols = !empty($attrib['textareacols']) ? $attrib['textareacols'] : 40;
 
-  list($form_start, $form_end) = get_form_tags($attrib, 'save-identity', array('name' => '_iid', 'value' => $IDENTITY_RECORD['identity_id']));
+  list($form_start, $form_end) = get_form_tags($attrib, 'save-identity', intval($IDENTITY_RECORD['identity_id']), array('name' => '_iid', 'value' => $IDENTITY_RECORD['identity_id']));
   unset($attrib['form']);
 
   // list of available cols
diff --git a/program/steps/settings/edit_prefs.inc b/program/steps/settings/edit_prefs.inc
new file mode 100644 (file)
index 0000000..9fcbc42
--- /dev/null
@@ -0,0 +1,521 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/settings/edit_prefs.inc                                 |
+ |                                                                       |
+ | This file is part of the RoundCube Webmail client                     |
+ | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Provide functionality for user's settings & preferences             |
+ |                                                                       |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+
+ $Id: func.inc 2822 2009-07-31 09:07:54Z alec $
+
+*/
+
+if (!$OUTPUT->ajax_call)
+  $OUTPUT->set_pagetitle(rcube_label('preferences'));
+
+
+$CURR_SECTION = get_input_value('_section', RCUBE_INPUT_GPC);
+
+function rcmail_user_prefs_form($attrib)
+{
+  global $RCMAIL, $CURR_SECTION;
+
+  // add some labels to client
+  $RCMAIL->output->add_label('nopagesizewarning');
+
+  unset($attrib['form']);
+  
+  list($form_start, $form_end) = get_form_tags($attrib, 'save-prefs', null,
+    array('name' => '_section', 'value' => $CURR_SECTION));
+
+  $out = $form_start;
+  
+  $out .= rcmail_user_prefs_block($CURR_SECTION, $attrib);
+  
+  return $out . $form_end;
+}
+
+function rcmail_user_prefs_block($part, $attrib)
+{
+  global $RCMAIL;
+
+  $config = $RCMAIL->config->all();
+  $no_override = array_flip($RCMAIL->config->get('dont_override', array()));
+  
+  $blocks = array();
+  
+  switch ($part)
+  {
+  // General UI settings
+  case 'general':
+  
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+      'list' => array('name' => Q(rcube_label('listoptions'))),
+    );
+    
+    // language selection
+    if (!isset($no_override['language'])) {
+      $a_lang = $RCMAIL->list_languages();
+      asort($a_lang);
+
+      $field_id = 'rcmfd_lang';
+      $select_lang = new html_select(array('name' => '_language', 'id' => $field_id));
+      $select_lang->add(array_values($a_lang), array_keys($a_lang));
+
+      $blocks['main']['options']['language'] = array(
+        'title' => html::label($field_id, Q(rcube_label('language'))),
+        'content' => $select_lang->show($RCMAIL->user->language),
+      );
+    }
+
+    // show page size selection
+    if (!isset($no_override['timezone'])) {
+      $field_id = 'rcmfd_timezone';
+      $select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id, 'onchange' => "document.getElementById('rcmfd_dst').disabled=this.selectedIndex==0"));
+      $select_timezone->add(rcube_label('autodetect'), 'auto');
+      $select_timezone->add('(GMT -11:00) Midway Island, Samoa', '-11');
+      $select_timezone->add('(GMT -10:00) Hawaii', '-10');
+      $select_timezone->add('(GMT -9:30) Marquesas Islands', '-9.5');
+      $select_timezone->add('(GMT -9:00) Alaska', '-9');
+      $select_timezone->add('(GMT -8:00) Pacific Time (US/Canada)', '-8');
+      $select_timezone->add('(GMT -7:00) Mountain Time (US/Canada)', '-7');
+      $select_timezone->add('(GMT -6:00) Central Time (US/Canada), Mexico City', '-6');
+      $select_timezone->add('(GMT -5:00) Eastern Time (US/Canada), Bogota, Lima', '-5');
+      $select_timezone->add('(GMT -4:30) Caracas', '-4.5');
+      $select_timezone->add('(GMT -4:00) Atlantic Time (Canada), La Paz', '-4');
+      $select_timezone->add('(GMT -3:30) Nfld Time (Canada), Nfld, S. Labador', '-3.5');
+      $select_timezone->add('(GMT -3:00) Brazil, Buenos Aires, Georgetown', '-3');
+      $select_timezone->add('(GMT -2:00) Mid-Atlantic', '-2');
+      $select_timezone->add('(GMT -1:00) Azores, Cape Verde Islands', '-1');
+      $select_timezone->add('(GMT) Western Europe, London, Lisbon, Casablanca', '0');
+      $select_timezone->add('(GMT +1:00) Central European Time', '1');
+      $select_timezone->add('(GMT +2:00) EET: Tallinn, Helsinki, Kaliningrad, South Africa', '2');
+      $select_timezone->add('(GMT +3:00) Baghdad, Kuwait, Riyadh, Moscow, Nairobi', '3');
+      $select_timezone->add('(GMT +3:30) Tehran', '3.5');
+      $select_timezone->add('(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi', '4');
+      $select_timezone->add('(GMT +4:30) Kabul', '4.5');
+      $select_timezone->add('(GMT +5:00) Ekaterinburg, Islamabad, Karachi', '5');
+      $select_timezone->add('(GMT +5:30) Chennai, Kolkata, Mumbai, New Delhi', '5.5');
+      $select_timezone->add('(GMT +5:45) Kathmandu', '5.75');
+      $select_timezone->add('(GMT +6:00) Almaty, Dhaka, Colombo', '6');
+      $select_timezone->add('(GMT +6:30) Cocos Islands, Myanmar', '6.5');
+      $select_timezone->add('(GMT +7:00) Bangkok, Hanoi, Jakarta', '7');
+      $select_timezone->add('(GMT +8:00) Beijing, Perth, Singapore, Taipei', '8');
+      $select_timezone->add('(GMT +8:45) Caiguna, Eucla, Border Village', '8.75');
+      $select_timezone->add('(GMT +9:00) Tokyo, Seoul, Yakutsk', '9');
+      $select_timezone->add('(GMT +9:30) Adelaide, Darwin', '9.5');
+      $select_timezone->add('(GMT +10:00) EAST/AEST: Sydney, Guam, Vladivostok', '10');
+      $select_timezone->add('(GMT +10:30) New South Wales', '10.5');
+      $select_timezone->add('(GMT +11:00) Magadan, Solomon Islands', '11');
+      $select_timezone->add('(GMT +11:30) Norfolk Island', '11.5');
+      $select_timezone->add('(GMT +12:00) Auckland, Wellington, Kamchatka', '12');
+      $select_timezone->add('(GMT +12:45) Chatham Islands', '12.75');
+      $select_timezone->add('(GMT +13:00) Tonga, Pheonix Islands', '13');
+      $select_timezone->add('(GMT +14:00) Kiribati', '14');
+
+      $blocks['main']['options']['timezone'] = array(
+        'title' => html::label($field_id, Q(rcube_label('timezone'))),
+        'content' => $select_timezone->show((string)$config['timezone']),
+      );
+    }
+
+    // daylight savings
+    if (!isset($no_override['dst_active'])) {
+      $field_id = 'rcmfd_dst';
+      $input_dst = new html_checkbox(array('name' => '_dst_active', 'id' => $field_id, 'value' => 1, 'disabled' => ($config['timezone'] === 'auto')));
+
+      $blocks['main']['options']['dstactive'] = array(
+        'title' => html::label($field_id, Q(rcube_label('dstactive'))),
+        'content' => $input_dst->show($config['dst_active']),
+      );
+    }
+
+    // MM: Show checkbox for toggling 'pretty dates' 
+    if (!isset($no_override['prettydate'])) {
+      $field_id = 'rcmfd_prettydate';
+      $input_prettydate = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['prettydate'] = array(
+        'title' => html::label($field_id, Q(rcube_label('prettydate'))),
+        'content' => $input_prettydate->show($config['prettydate']?1:0),
+      );
+    }
+
+    // show page size selection
+    if (!isset($no_override['pagesize'])) {
+      $field_id = 'rcmfd_pgsize';
+      $input_pagesize = new html_inputfield(array('name' => '_pagesize', 'id' => $field_id, 'size' => 5));
+
+      $blocks['list']['options']['pagesize'] = array(
+        'title' => html::label($field_id, Q(rcube_label('pagesize'))),
+        'content' => $input_pagesize->show($config['pagesize']),
+      );
+    }
+
+    // show drop-down for available skins
+    if (!isset($no_override['skin'])) {
+      $skins = rcmail_get_skins();
+
+      if (count($skins) > 1) {
+        $field_id = 'rcmfd_skin';
+        $input_skin = new html_select(array('name'=>'_skin', 'id'=>$field_id));
+
+        foreach($skins as $skin)
+          $input_skin->add($skin, $skin);
+
+        $blocks['main']['options']['skin'] = array(
+          'title' => html::label($field_id, Q(rcube_label('skin'))),
+          'content' => $input_skin->show($config['skin']),
+        );
+      }
+    }
+    
+    break;
+
+  // Mailbox view (mail screen)
+  case 'mailbox':
+
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+      'new_message' => array('name' => Q(rcube_label('newmessage'))),
+    );
+
+    // show config parameter for preview pane
+    if (!isset($no_override['preview_pane'])) {
+      $field_id = 'rcmfd_preview';
+      $input_preview = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['preview_pane'] = array(
+        'title' => html::label($field_id, Q(rcube_label('previewpane'))),
+        'content' => $input_preview->show($config['preview_pane']?1:0),
+      );
+    }
+
+    if (!isset($no_override['mdn_requests'])) {
+      $field_id = 'rcmfd_mdn_requests';
+      $select_mdn_requests = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
+      $select_mdn_requests->add(rcube_label('askuser'), 0);
+      $select_mdn_requests->add(rcube_label('autosend'), 1);
+      $select_mdn_requests->add(rcube_label('ignore'), 2);
+
+      $blocks['main']['options']['mdn_requests'] = array(
+        'title' => html::label($field_id, Q(rcube_label('mdnrequests'))),
+        'content' => $select_mdn_requests->show($config['mdn_requests']),
+      );
+    }
+
+    if (!isset($no_override['focus_on_new_message'])) {
+      $field_id = 'rcmfd_focus_on_new_message';
+      $input_focus_on_new_message = new html_checkbox(array('name' => '_focus_on_new_message', 'id' => $field_id, 'value' => 1));
+
+      $blocks['new_message']['options']['focus_on_new_message'] = array(
+        'title' => html::label($field_id, Q(rcube_label('focusonnewmessage'))),
+        'content' => $input_focus_on_new_message->show($config['focus_on_new_message']?1:0),
+      );
+    }
+
+    if (!isset($no_override['keep_alive'])) {
+      $field_id = 'rcmfd_keep_alive';
+      $select_keep_alive = new html_select(array('name' => '_keep_alive', 'id' => $field_id));
+
+      foreach(array(1, 3, 5, 10, 15, 30, 60) as $min)
+        if((!$config['min_keep_alive'] || $config['min_keep_alive'] <= $min * 60)
+            && (!$config['session_lifetime'] || $config['session_lifetime'] > $min)) {
+          $select_keep_alive->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min);
+        }
+
+      $blocks['new_message']['options']['keep_alive'] = array(
+        'title' => html::label($field_id, Q(rcube_label('keepalive'))),
+        'content' => $select_keep_alive->show($config['keep_alive']/60),
+      );
+    }
+
+    if (!isset($no_override['check_all_folders'])) {
+      $field_id = 'rcmfd_check_all_folders';
+      $input_check_all = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));
+
+      $blocks['new_message']['options']['check_all_folders'] = array(
+        'title' => html::label($field_id, Q(rcube_label('checkallfolders'))),
+        'content' => $input_check_all->show($config['check_all_folders']?1:0),
+      );
+    }
+
+    break;
+
+  // Message viewing
+  case 'mailview':
+
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+    );
+
+    // show checkbox for HTML/plaintext messages
+    if (!isset($no_override['prefer_html'])) {
+      $field_id = 'rcmfd_htmlmsg';
+      $input_preferhtml = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
+        'onchange' => JS_OBJECT_NAME.'.toggle_prefer_html(this)'));
+
+      $blocks['main']['options']['prefer_html'] = array(
+        'title' => html::label($field_id, Q(rcube_label('preferhtml'))),
+        'content' => $input_preferhtml->show($config['prefer_html']?1:0),
+      );
+    }
+
+    if (!isset($no_override['show_images'])) {
+      $field_id = 'rcmfd_show_images';
+      $input_show_images = new html_select(array('name' => '_show_images', 'id' => $field_id));
+      $input_show_images->add(rcube_label('never'), 0);
+      $input_show_images->add(rcube_label('fromknownsenders'), 1);
+      $input_show_images->add(rcube_label('always'), 2);
+
+      $blocks['main']['options']['show_images'] = array(
+        'title' => html::label($field_id, Q(rcube_label('showremoteimages'))),
+        'content' => $input_show_images->show($config['show_images']),
+      );
+    }
+
+    if (!isset($no_override['inline_images'])) {
+      $field_id = 'rcmfd_inline_images';
+      $input_inline_images = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['inline_images'] = array(
+        'title' => html::label($field_id, Q(rcube_label('showinlineimages'))),
+        'content' => $input_inline_images->show($config['inline_images']?1:0),
+      );
+    }
+
+    // "display after delete" checkbox
+    if (!isset($no_override['display_next'])) {
+      $field_id = 'rcmfd_displaynext';
+      $input_displaynext = new html_checkbox(array('name' => '_display_next', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['display_next'] = array(
+        'title' => html::label($field_id, Q(rcube_label('displaynext'))),
+        'content' => $input_displaynext->show($config['display_next']?1:0),
+      );
+    }
+
+    break;
+
+  // Mail composition
+  case 'compose':
+
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+    );
+
+    // Show checkbox for HTML Editor
+    if (!isset($no_override['htmleditor'])) {
+      $field_id = 'rcmfd_htmleditor';
+      $input_htmleditor = new html_checkbox(array('name' => '_htmleditor', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['htmleditor'] = array(
+        'title' => html::label($field_id, Q(rcube_label('htmleditor'))),
+        'content' => $input_htmleditor->show($config['htmleditor']?1:0),
+      );
+    }
+
+    if (!isset($no_override['draft_autosave'])) {
+      $field_id = 'rcmfd_autosave';
+      $select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
+      $select_autosave->add(rcube_label('never'), 0);
+      foreach (array(1, 3, 5, 10) as $i => $min)
+        $select_autosave->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min*60);
+
+      $blocks['main']['options']['draft_autosave'] = array(
+        'title' => html::label($field_id, Q(rcube_label('autosavedraft'))),
+        'content' => $select_autosave->show($config['draft_autosave']),
+      );
+    }
+
+    if (!isset($no_override['mime_param_folding'])) {
+      $field_id = 'rcmfd_param_folding';
+      $select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
+      $select_param_folding->add(rcube_label('2231folding'), 0);
+      $select_param_folding->add(rcube_label('miscfolding'), 1);
+      $select_param_folding->add(rcube_label('2047folding'), 2);
+
+      $blocks['main']['options']['mime_param_folding'] = array(
+       'advanced' => true,
+        'title' => html::label($field_id, Q(rcube_label('mimeparamfolding'))),
+        'content' => $select_param_folding->show($config['mime_param_folding']),
+      );
+    }
+
+    break;
+
+  // Special IMAP folders
+  case 'folders':
+
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+    );
+
+    // Configure special folders
+    if (!isset($no_override['default_imap_folders'])) {
+      $RCMAIL->imap_init(true);
+      $select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true, 'maxlength' => 30));
+
+      if (!isset($no_override['drafts_mbox']))
+        $blocks['main']['options']['drafts_mbox'] = array(
+          'title' => Q(rcube_label('drafts')),
+          'content' => $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox")),
+        );
+
+      if (!isset($no_override['sent_mbox']))
+        $blocks['main']['options']['sent_mbox'] = array(
+          'title' => Q(rcube_label('sent')),
+          'content' => $select->show($config['sent_mbox'], array('name' => "_sent_mbox")),
+       );
+
+      if (!isset($no_override['junk_mbox']))
+        $blocks['main']['options']['junk_mbox'] = array(
+          'title' => Q(rcube_label('junk')),
+          'content' => $select->show($config['junk_mbox'], array('name' => "_junk_mbox")),
+       );
+
+      if (!isset($no_override['trash_mbox']))
+        $blocks['main']['options']['trash_mbox'] = array(
+          'title' => Q(rcube_label('trash')),
+          'content' => $select->show($config['trash_mbox'], array('name' => "_trash_mbox")),
+        );
+    }
+    break;
+
+  // Server settings
+  case 'server':
+
+    $blocks = array(
+      'main' => array('name' => Q(rcube_label('mainoptions'))),
+      'maintenance' => array('name' => Q(rcube_label('maintenance'))),
+    );
+
+    if (!isset($no_override['read_when_deleted'])) {
+      $field_id = 'rcmfd_read_deleted';
+      $input_readdeleted = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['read_when_deleted'] = array(
+        'title' => html::label($field_id, Q(rcube_label('readwhendeleted'))),
+        'content' => $input_readdeleted->show($config['read_when_deleted']?1:0),
+      );
+    }
+
+    if (!isset($no_override['flag_for_deletion'])) {
+      $field_id = 'rcmfd_flag_for_deletion';
+      $input_flagfordeletion = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['flag_for_deletion'] = array(
+        'title' => html::label($field_id, Q(rcube_label('flagfordeletion'))),
+        'content' => $input_flagfordeletion->show($config['flag_for_deletion']?1:0),
+      );
+    }
+
+    // don't show deleted messages
+    if (!isset($no_override['skip_deleted'])) {
+      $field_id = 'rcmfd_skip_deleted';
+      $input_purge = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1));
+
+      $blocks['main']['options']['skip_deleted'] = array(
+        'title' => html::label($field_id, Q(rcube_label('skipdeleted'))),
+        'content' => $input_purge->show($config['skip_deleted']?1:0),
+      );
+    }
+
+    // Trash purging on logout
+    if (!isset($no_override['logout_purge'])) {
+      $field_id = 'rcmfd_logout_purge';
+      $input_purge = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
+
+      $blocks['maintenance']['options']['logout_purge'] = array(
+        'title' => html::label($field_id, Q(rcube_label('logoutclear'))),
+        'content' => $input_purge->show($config['logout_purge']?1:0),
+      );
+    }
+
+    // INBOX compacting on logout
+    if (!isset($no_override['logout_expunge'])) {
+      $field_id = 'rcmfd_logout_expunge';
+      $input_expunge = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
+
+      $blocks['maintenance']['options']['logout_expunge'] = array(
+        'title' => html::label($field_id, Q(rcube_label('logoutcompact'))),
+        'content' => $input_expunge->show($config['logout_expunge']?1:0),
+      );
+    }
+
+    break;
+  }
+
+  $data = $RCMAIL->plugins->exec_hook('user_preferences', array('section' => $part, 'blocks' => $blocks));
+
+  // create output
+  foreach ($data['blocks'] as $idx => $block) {
+    if ($block['options']) {
+      $table = new html_table(array('cols' => 2));
+
+      foreach ($block['options'] as $option) {
+       if ($option['advanced'])
+          $table->set_row_attribs('advanced');
+       
+        $table->add('title', $option['title']);
+       $table->add(null, $option['content']);
+      }
+
+      $out .= html::tag('fieldset', null, html::tag('legend', null, $block['name']) . $table->show($attrib));
+    }
+  }
+
+  return $out;
+}
+
+
+function rcmail_get_skins()
+{
+  $path = 'skins';
+  $skins = array();
+
+  $dir = opendir($path);
+  
+  if (!$dir)
+       return false;
+  
+  while (($file = readdir($dir)) !== false)
+  {
+    $filename = $path.'/'.$file;
+    if (is_dir($filename) && is_readable($filename) 
+       && !in_array($file, array('.', '..', '.svn')))
+      $skins[] = $file;
+  }
+
+  closedir($dir);
+
+  return $skins;
+}
+
+function rcmail_prefs_section_name()
+{
+  global $SECTIONS, $CURR_SECTION;
+  
+  return $SECTIONS[$CURR_SECTION]['section'];
+}
+
+
+// register UI objects
+$OUTPUT->add_handlers(array(
+  'userprefs' => 'rcmail_user_prefs_form',
+  'sectionname' => 'rcmail_prefs_section_name',
+));
+
+$OUTPUT->send('settingsedit');
+
+?>
index cef7cee47c11048d21030f1a1c16776866483d80..7a7c128acbe283b2cbd370602007cb29724505fc 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: func.inc 2830 2009-08-03 18:27:53Z alec $
 
 */
 
 if (!$OUTPUT->ajax_call)
   $OUTPUT->set_pagetitle(rcube_label('preferences'));
 
-function rcmail_user_prefs_form($attrib)
-{
-  global $RCMAIL;
+// define sections list
+$SECTIONS['general'] = array('id' => 'general', 'section' => rcube_label('uisettings'));
+$SECTIONS['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview'));
+$SECTIONS['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition'));
+$SECTIONS['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying'));
+$SECTIONS['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders'));
+$SECTIONS['server'] = array('id' => 'server',  'section' => rcube_label('serversettings'));
 
-  $no_override = array_flip($RCMAIL->config->get('dont_override', array()));
-  $blocks = $attrib['parts'] ? preg_split('/[\s,;]+/', strip_quotes($attrib['parts'])) : array('general','mailbox','compose','mailview','folders','server');
 
-  // add some labels to client
-  $RCMAIL->output->add_label('nopagesizewarning');
-  
-  list($form_start, $form_end) = get_form_tags($attrib, 'save-prefs');
-  unset($attrib['form']);
-
-  $out = $form_start;
-  
-  foreach ($blocks as $part)
-    $out .= rcmail_user_prefs_block($part, $no_override, $attrib);
-  
-  return $out . $form_end;
-}
-
-function rcmail_user_prefs_block($part, $no_override, $attrib)
-{
-  global $RCMAIL;
-  $config = $RCMAIL->config->all();
-  
-  switch ($part)
+// similar function as /steps/settings/identities.inc::rcmail_identity_frame()
+function rcmail_preferences_frame($attrib)
   {
-  // General UI settings
-  case 'general':
-    $table = new html_table(array('cols' => 2));
-
-    // show language selection
-    if (!isset($no_override['language'])) {
-      $a_lang = $RCMAIL->list_languages();
-      asort($a_lang);
-
-      $field_id = 'rcmfd_lang';
-      $select_lang = new html_select(array('name' => '_language', 'id' => $field_id));
-      $select_lang->add(array_values($a_lang), array_keys($a_lang));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('language'))));
-      $table->add(null, $select_lang->show($RCMAIL->user->language));
-    }
-
-    // show page size selection
-    if (!isset($no_override['timezone'])) {
-      $field_id = 'rcmfd_timezone';
-      $select_timezone = new html_select(array('name' => '_timezone', 'id' => $field_id, 'onchange' => "document.getElementById('rcmfd_dst').disabled=this.selectedIndex==0"));
-      $select_timezone->add(rcube_label('autodetect'), 'auto');
-      $select_timezone->add('(GMT -11:00) Midway Island, Samoa', '-11');
-      $select_timezone->add('(GMT -10:00) Hawaii', '-10');
-      $select_timezone->add('(GMT -9:30) Marquesas Islands', '-9.5');
-      $select_timezone->add('(GMT -9:00) Alaska', '-9');
-      $select_timezone->add('(GMT -8:00) Pacific Time (US/Canada)', '-8');
-      $select_timezone->add('(GMT -7:00) Mountain Time (US/Canada)', '-7');
-      $select_timezone->add('(GMT -6:00) Central Time (US/Canada), Mexico City', '-6');
-      $select_timezone->add('(GMT -5:00) Eastern Time (US/Canada), Bogota, Lima', '-5');
-      $select_timezone->add('(GMT -4:30) Caracas', '-4.5');
-      $select_timezone->add('(GMT -4:00) Atlantic Time (Canada), La Paz', '-4');
-      $select_timezone->add('(GMT -3:30) Nfld Time (Canada), Nfld, S. Labador', '-3.5');
-      $select_timezone->add('(GMT -3:00) Brazil, Buenos Aires, Georgetown', '-3');
-      $select_timezone->add('(GMT -2:00) Mid-Atlantic', '-2');
-      $select_timezone->add('(GMT -1:00) Azores, Cape Verde Islands', '-1');
-      $select_timezone->add('(GMT) Western Europe, London, Lisbon, Casablanca', '0');
-      $select_timezone->add('(GMT +1:00) Central European Time', '1');
-      $select_timezone->add('(GMT +2:00) EET: Tallinn, Helsinki, Kaliningrad, South Africa', '2');
-      $select_timezone->add('(GMT +3:00) Baghdad, Kuwait, Riyadh, Moscow, Nairobi', '3');
-      $select_timezone->add('(GMT +3:30) Tehran', '3.5');
-      $select_timezone->add('(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi', '4');
-      $select_timezone->add('(GMT +4:30) Kabul', '4.5');
-      $select_timezone->add('(GMT +5:00) Ekaterinburg, Islamabad, Karachi', '5');
-      $select_timezone->add('(GMT +5:30) Chennai, Kolkata, Mumbai, New Delhi', '5.5');
-      $select_timezone->add('(GMT +5:45) Kathmandu', '5.75');
-      $select_timezone->add('(GMT +6:00) Almaty, Dhaka, Colombo', '6');
-      $select_timezone->add('(GMT +6:30) Cocos Islands, Myanmar', '6.5');
-      $select_timezone->add('(GMT +7:00) Bangkok, Hanoi, Jakarta', '7');
-      $select_timezone->add('(GMT +8:00) Beijing, Perth, Singapore, Taipei', '8');
-      $select_timezone->add('(GMT +8:45) Caiguna, Eucla, Border Village', '8.75');
-      $select_timezone->add('(GMT +9:00) Tokyo, Seoul, Yakutsk', '9');
-      $select_timezone->add('(GMT +9:30) Adelaide, Darwin', '9.5');
-      $select_timezone->add('(GMT +10:00) EAST/AEST: Sydney, Guam, Vladivostok', '10');
-      $select_timezone->add('(GMT +10:30) New South Wales', '10.5');
-      $select_timezone->add('(GMT +11:00) Magadan, Solomon Islands', '11');
-      $select_timezone->add('(GMT +11:30) Norfolk Island', '11.5');
-      $select_timezone->add('(GMT +12:00) Auckland, Wellington, Kamchatka', '12');
-      $select_timezone->add('(GMT +12:45) Chatham Islands', '12.75');
-      $select_timezone->add('(GMT +13:00) Tonga, Pheonix Islands', '13');
-      $select_timezone->add('(GMT +14:00) Kiribati', '14');
-
-      $table->add('title', html::label($field_id, Q(rcube_label('timezone'))));
-      $table->add(null, $select_timezone->show((string)$config['timezone']));
-    }
-
-    // daylight savings
-    if (!isset($no_override['dst_active'])) {
-      $field_id = 'rcmfd_dst';
-      $input_dst = new html_checkbox(array('name' => '_dst_active', 'id' => $field_id, 'value' => 1, 'disabled' => ($config['timezone'] === 'auto')));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('dstactive'))));
-      $table->add(null, $input_dst->show($config['dst_active']));
-    }
-
-    // MM: Show checkbox for toggling 'pretty dates' 
-    if (!isset($no_override['prettydate'])) {
-      $field_id = 'rcmfd_prettydate';
-      $input_prettydate = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('prettydate'))));
-      $table->add(null, $input_prettydate->show($config['prettydate']?1:0));
-    }
-
-    // show page size selection
-    if (!isset($no_override['pagesize'])) {
-      $field_id = 'rcmfd_pgsize';
-      $input_pagesize = new html_inputfield(array('name' => '_pagesize', 'id' => $field_id, 'size' => 5));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('pagesize'))));
-      $table->add(null, $input_pagesize->show($config['pagesize']));
-    }
-
-    // show drop-down for available skins
-    if (!isset($no_override['skin'])) {
-      $skins = rcmail_get_skins();
-
-      if (count($skins) > 1) {
-        $field_id = 'rcmfd_skin';
-        $input_skin = new html_select(array('name'=>'_skin', 'id'=>$field_id));
-
-        foreach($skins as $skin)
-          $input_skin->add($skin, $skin);
-
-        $table->add('title', html::label($field_id, Q(rcube_label('skin'))));
-        $table->add(null, $input_skin->show($config['skin']));
-      }
-    }
-    
-    if ($table->size())
-      $out = html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('uisettings'))) . $table->show($attrib));
-    break;
-
-
-  // Mailbox view (mail screen)
-  case 'mailbox':
-    $table = new html_table(array('cols' => 2));
-
-    if (!isset($no_override['focus_on_new_message'])) {
-      $field_id = 'rcmfd_focus_on_new_message';
-      $input_focus_on_new_message = new html_checkbox(array('name' => '_focus_on_new_message', 'id' => $field_id, 'value' => 1));
-      $table->add('title', html::label($field_id, Q(rcube_label('focusonnewmessage'))));
-      $table->add(null, $input_focus_on_new_message->show($config['focus_on_new_message']?1:0));
-    }
-
-    // show config parameter for preview pane
-    if (!isset($no_override['preview_pane'])) {
-      $field_id = 'rcmfd_preview';
-      $input_preview = new html_checkbox(array('name' => '_preview_pane', 'id' => $field_id, 'value' => 1));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('previewpane'))));
-      $table->add(null, $input_preview->show($config['preview_pane']?1:0));
-    }
-
-    if (!isset($no_override['mdn_requests'])) {
-      $field_id = 'rcmfd_mdn_requests';
-      $select_mdn_requests = new html_select(array('name' => '_mdn_requests', 'id' => $field_id));
-      $select_mdn_requests->add(rcube_label('askuser'), 0);
-      $select_mdn_requests->add(rcube_label('autosend'), 1);
-      $select_mdn_requests->add(rcube_label('ignore'), 2);
-
-      $table->add('title', html::label($field_id, Q(rcube_label('mdnrequests'))));
-      $table->add(null, $select_mdn_requests->show($config['mdn_requests']));
-    }
-
-    if (!isset($no_override['keep_alive'])) {
-      $field_id = 'rcmfd_keep_alive';
-      $select_keep_alive = new html_select(array('name' => '_keep_alive', 'id' => $field_id));
-
-      foreach(array(1, 3, 5, 10, 15, 30, 60) as $min)
-        if((!$config['min_keep_alive'] || $config['min_keep_alive'] <= $min * 60)
-            && (!$config['session_lifetime'] || $config['session_lifetime'] > $min)) {
-          $select_keep_alive->add(rcube_label(array('name' => 'keepaliveevery', 'vars' => array('n' => $min))), $min);
-        }
-
-      $table->add('title', html::label($field_id, Q(rcube_label('keepalive'))));
-      $table->add(null, $select_keep_alive->show($config['keep_alive']/60));
-    }
-
-    if (!isset($no_override['check_all_folders'])) {
-      $field_id = 'rcmfd_check_all_folders';
-      $input_check_all = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));
-      $table->add('title', html::label($field_id, Q(rcube_label('checkallfolders'))));
-      $table->add(null, $input_check_all->show($config['check_all_folders']?1:0));
-    }
-
-    if ($table->size())
-      $out = html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('mailboxview'))) . $table->show($attrib));
-    break;
-
-
-  // Message viewing
-  case 'mailview':
-    $table = new html_table(array('cols' => 2));
-
-    // show checkbox for HTML/plaintext messages
-    if (!isset($no_override['prefer_html'])) {
-      $field_id = 'rcmfd_htmlmsg';
-      $input_preferhtml = new html_checkbox(array('name' => '_prefer_html', 'id' => $field_id, 'value' => 1,
-        'onchange' => JS_OBJECT_NAME.'.toggle_prefer_html(this)'));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('preferhtml'))));
-      $table->add(null, $input_preferhtml->show($config['prefer_html']?1:0));
-    }
-
-    if (!isset($no_override['show_images'])) {
-      $field_id = 'rcmfd_show_images';
-      $input_show_images = new html_select(array('name' => '_show_images', 'id' => $field_id));
-      $input_show_images->add(rcube_label('never'), 0);
-      $input_show_images->add(rcube_label('fromknownsenders'), 1);
-      $input_show_images->add(rcube_label('always'), 2);
-
-      $table->add('title', html::label($field_id, Q(rcube_label('showremoteimages'))));
-      $table->add(null, $input_show_images->show($config['show_images']));
-    }
-
-    if (!isset($no_override['inline_images'])) {
-      $field_id = 'rcmfd_inline_images';
-      $input_inline_images = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('showinlineimages'))));
-      $table->add(null, $input_inline_images->show($config['inline_images']?1:0));
-    }
-
-    if ($table->size())
-      $out = html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('messagesdisplaying'))) . $table->show($attrib));
-    break;
+  global $OUTPUT;
 
+  if (!$attrib['id'])
+    $attrib['id'] = 'rcmprefsframe';
 
-  // Mail composition
-  case 'compose':
-    $table = new html_table(array('cols' => 2));
+  $attrib['name'] = $attrib['id'];
 
-    // Show checkbox for HTML Editor
-    if (!isset($no_override['htmleditor'])) {
-      $field_id = 'rcmfd_htmleditor';
-      $input_htmleditor = new html_checkbox(array('name' => '_htmleditor', 'id' => $field_id, 'value' => 1));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('htmleditor'))));
-      $table->add(null, $input_htmleditor->show($config['htmleditor']?1:0));
-    }
-
-    if (!isset($no_override['draft_autosave'])) {
-      $field_id = 'rcmfd_autosave';
-      $select_autosave = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox'])));
-      $select_autosave->add(rcube_label('never'), 0);
-      foreach (array(3, 5, 10) as $i => $min)
-        $select_autosave->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min*60);
-
-      $table->add('title', html::label($field_id, Q(rcube_label('autosavedraft'))));
-      $table->add(null, $select_autosave->show($config['draft_autosave']));
-    }
-
-    if (!isset($no_override['mime_param_folding'])) {
-      $field_id = 'rcmfd_param_folding';
-      $select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id));
-      $select_param_folding->add(rcube_label('2231folding'), 0);
-      $select_param_folding->add(rcube_label('miscfolding'), 1);
-      $select_param_folding->add(rcube_label('2047folding'), 2);
-
-      $table->set_row_attribs('advanced');
-      $table->add('title', html::label($field_id, Q(rcube_label('mimeparamfolding'))));
-      $table->add(null, $select_param_folding->show($config['mime_param_folding']));
-    }
-
-    if ($table->size())
-      $out = html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('messagescomposition'))) . $table->show($attrib));
-    break;
-
-
-  // Special IMAP folders
-  case 'folders':
-    // Configure special folders
-    if (!isset($no_override['default_imap_folders'])) {
-      $RCMAIL->imap_init(true);
-      $select = rcmail_mailbox_select(array('noselection' => '---', 'realnames' => true, 'maxlength' => 30));
-
-      $table = new html_table(array('cols' => 2));
-
-      if (!isset($no_override['drafts_mbox'])) {
-        $table->add('title', Q(rcube_label('drafts')));
-        $table->add(null, $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox", 'onchange' => "document.getElementById('rcmfd_autosave').disabled=this.selectedIndex==0")));
-      }
-
-      if (!isset($no_override['sent_mbox'])) {
-        $table->add('title', Q(rcube_label('sent')));
-        $table->add(null, $select->show($config['sent_mbox'], array('name' => "_sent_mbox")));
-      }
-
-      if (!isset($no_override['junk_mbox'])) {
-        $table->add('title', Q(rcube_label('junk')));
-        $table->add(null, $select->show($config['junk_mbox'], array('name' => "_junk_mbox")));
-      }
-
-      if (!isset($no_override['trash_mbox'])) {
-        $table->add('title', Q(rcube_label('trash')));
-        $table->add(null, $select->show($config['trash_mbox'], array('name' => "_trash_mbox")));
-      }
-
-      $out = html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('specialfolders'))) . $table->show($attrib));
-    }
-    break;
-
-
-  // Server settings
-  case 'server':
-    $table = new html_table(array('cols' => 2));
-
-    if (!isset($no_override['read_when_deleted'])) {
-      $field_id = 'rcmfd_read_deleted';
-      $input_readdeleted = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('readwhendeleted'))));
-      $table->add(null, $input_readdeleted->show($config['read_when_deleted']?1:0));
-    }
-
-    if (!isset($no_override['flag_for_deletion'])) {
-      $field_id = 'rcmfd_flag_for_deletion';
-      $input_flagfordeletion = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('flagfordeletion'))));
-      $table->add(null, $input_flagfordeletion->show($config['flag_for_deletion']?1:0));
-    }
-
-    // don't show deleted messages
-    if (!isset($no_override['skip_deleted'])) {
-      $field_id = 'rcmfd_skip_deleted';
-      $input_purge = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('skipdeleted'))));
-      $table->add(null, $input_purge->show($config['skip_deleted']?1:0));
-    }
-
-    // Trash purging on logout
-    if (!isset($no_override['logout_purge'])) {
-      $field_id = 'rcmfd_logout_purge';
-      $input_purge = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1));
-
-      $table->add('title', html::label($field_id, Q(rcube_label('logoutclear'))));
-      $table->add(null, $input_purge->show($config['logout_purge']?1:0));
-    }
+  $OUTPUT->set_env('contentframe', $attrib['name']);
+  $OUTPUT->set_env('blankpage', $attrib['src'] ? $OUTPUT->abs_url($attrib['src']) : 'program/blank.gif');
+  
+  return html::iframe($attrib);
+  }
 
-    // INBOX compacting on logout
-    if (!isset($no_override['logout_expunge'])) {
-      $field_id = 'rcmfd_logout_expunge';
-      $input_expunge = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1));
 
-      $table->add('title', html::label($field_id, Q(rcube_label('logoutcompact'))));
-      $table->add(null, $input_expunge->show($config['logout_expunge']?1:0));
-    }
+function rcmail_sections_list($attrib)
+  {
+  global $RCMAIL, $SECTIONS;
+  
+  // add id to message list table if not specified
+  if (!strlen($attrib['id']))
+    $attrib['id'] = 'rcmsectionslist';
 
-    if ($table->size())
-      $out = html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('serversettings'))) . $table->show($attrib));
-    break;
+  // hook + define list cols
+  $plugin = $RCMAIL->plugins->exec_hook('list_prefs_sections',
+    array('list' => $SECTIONS, 'cols' => array('section')));
+           
+  // create XHTML table
+  $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'id');
 
+  // set client env
+  $RCMAIL->output->add_gui_object('sectionslist', $attrib['id']);
+  $RCMAIL->output->include_script('list.js');
 
-    default:
-      $out = '';
-  }
-  
   return $out;
-}
+  }
 
 
 function rcmail_identities_list($attrib)
   {
-  global $OUTPUT, $USER;
+  global $OUTPUT, $USER, $RCMAIL;
 
   // add id to message list table if not specified
   if (!strlen($attrib['id']))
     $attrib['id'] = 'rcmIdentitiesList';
 
-  // define list of cols to be displayed
-  $a_show_cols = array('name', 'email');
+  // get all identites from DB and define list of cols to be displayed
+  $plugin = $RCMAIL->plugins->exec_hook('list_identities', array(
+    'list' => $USER->list_identities(),
+    'cols' => array('name', 'email')));
 
   // create XHTML table  
-  $out = rcube_table_output($attrib, $USER->list_identities(), $a_show_cols, 'identity_id');
+  $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'identity_id');
   
   // set client env
   $OUTPUT->add_gui_object('identitieslist', $attrib['id']);
@@ -415,65 +94,40 @@ function rcmail_identities_list($attrib)
   }
 
 
-
 // similar function as in /steps/addressbook/edit.inc
-function get_form_tags($attrib, $action, $add_hidden=array())
+function get_form_tags($attrib, $action, $id = null, $hidden = null)
   {
   global $EDIT_FORM, $RCMAIL;
 
-  $form_start = '';
-  if (!strlen($EDIT_FORM))
-    {
-    $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task));
-    $hiddenfields->add(array('name' => '_action', 'value' => $action));
-    
-    if ($add_hidden)
-      $hiddenfields->add($add_hidden);
+  $form_start = $form_end = '';
+  
+  if (empty($EDIT_FORM)) {
+    $request_key = $action . (isset($id) ? '.'.$id : '');
+    $form_start = $RCMAIL->output->request_form(array(
+       'name' => 'form', 'method' => 'post',
+       'task' => $RCMAIL->task, 'action' => $action,
+       'request' => $request_key, 'noclose' => true) + $attrib);
     
-    $form_start = !strlen($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : '';
-    $form_start .= $hiddenfields->show();
+    if (is_array($hidden)) {
+      $hiddenfields = new html_hiddenfield($hidden);
+      $form_start .= $hiddenfields->show();
     }
     
-  $form_end = (!strlen($EDIT_FORM) && !strlen($attrib['form'])) ? '</form>' : '';
-  $form_name = strlen($attrib['form']) ? $attrib['form'] : 'form';
+    $form_end = !strlen($attrib['form']) ? '</form>' : '';
 
-  if (!strlen($EDIT_FORM))
-    $RCMAIL->output->add_gui_object('editform', $form_name);
-  
-  $EDIT_FORM = $form_name;
-
-  return array($form_start, $form_end);
+    $EDIT_FORM = !empty($attrib['form']) ? $attrib['form'] : 'form';
+    $RCMAIL->output->add_gui_object('editform', $EDIT_FORM);
   }
 
-function rcmail_get_skins()
-  {
-  $path = 'skins';
-  $skins = array();
-
-  $dir = opendir($path);
-  
-  if (!$dir)
-       return false;
-  
-  while (($file = readdir($dir)) !== false)
-    {
-    $filename = $path.'/'.$file;
-    if (is_dir($filename) && is_readable($filename) 
-       && !in_array($file, array('.', '..', '.svn')))
-      $skins[] = $file;
-    }
-
-  closedir($dir);
-
-  return $skins;
+  return array($form_start, $form_end);
   }
 
 
 // register UI objects
 $OUTPUT->add_handlers(array(
-  'userprefs' => 'rcmail_user_prefs_form',
+  'prefsframe' => 'rcmail_preferences_frame',
+  'sectionslist' => 'rcmail_sections_list',
   'identitieslist' => 'rcmail_identities_list',
-  'itentitieslist' => 'rcmail_identities_list'  // keep this for backward compatibility
 ));
 
 ?>
index c785d31b4cf69255d2b1f99b99da4fb8616a0644..66b7edf2b7aa7bb2115efe15d35e14c2b5bdccec 100644 (file)
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: manage_folders.inc 2256 2009-01-23 10:29:51Z alec $
+ $Id: manage_folders.inc 2505 2009-05-20 09:55:15Z alec $
 
 */
 
-// WARNING: folder names in UI are encoded with UTF-8
+// WARNING: folder names in UI are encoded with RCMAIL_CHARSET
 
 // init IMAP connection
 $RCMAIL->imap_init(true);
@@ -27,14 +27,14 @@ $RCMAIL->imap_init(true);
 // subscribe to one or more mailboxes
 if ($RCMAIL->action=='subscribe')
   {
-  if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF-7'))
+  if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF7-IMAP'))
     $IMAP->subscribe(array($mbox));
   }
 
 // unsubscribe one or more mailboxes
 else if ($RCMAIL->action=='unsubscribe')
   {
-  if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF-7'))
+  if ($mbox = get_input_value('_mbox', RCUBE_INPUT_POST, false, 'UTF7-IMAP'))
     $IMAP->unsubscribe(array($mbox));
   }
 
@@ -43,7 +43,7 @@ else if ($RCMAIL->action=='create-folder')
   {
   if (!empty($_POST['_name']))
     {
-    $name = trim(get_input_value('_name', RCUBE_INPUT_POST, FALSE, 'UTF-7'));
+    $name = trim(get_input_value('_name', RCUBE_INPUT_POST, FALSE, 'UTF7-IMAP'));
     $create = $IMAP->create_mailbox($name, TRUE);
     }
   
@@ -52,9 +52,9 @@ else if ($RCMAIL->action=='create-folder')
     $delimiter = $IMAP->get_hierarchy_delimiter();
     $folderlist = $IMAP->list_unsubscribed();
     $index = array_search($create, $folderlist);
-    $before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF-7') : false;
+    $before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF7-IMAP') : false;
     
-    $create = rcube_charset_convert($create, 'UTF-7');
+    $create = rcube_charset_convert($create, 'UTF7-IMAP');
     $foldersplit = explode($delimiter, $create);
     $display_create = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', substr_count($create, $delimiter)) . $foldersplit[count($foldersplit)-1];
 
@@ -73,8 +73,8 @@ else if ($RCMAIL->action=='rename-folder')
     {
     $name_utf8 = trim(get_input_value('_folder_newname', RCUBE_INPUT_POST));
     $oldname_utf8 = get_input_value('_folder_oldname', RCUBE_INPUT_POST);
-    $name = rcube_charset_convert($name_utf8, 'UTF-8', 'UTF-7');
-    $oldname = rcube_charset_convert($oldname_utf8, 'UTF-8', 'UTF-7');
+    $name = rcube_charset_convert($name_utf8, RCMAIL_CHARSET, 'UTF7-IMAP');
+    $oldname = rcube_charset_convert($oldname_utf8, RCMAIL_CHARSET, 'UTF7-IMAP');
 
     $rename = $IMAP->rename_mailbox($oldname, $name);
     }
@@ -95,23 +95,22 @@ else if ($RCMAIL->action=='rename-folder')
         $foldersplit = explode($delimiter, $folderlist[$x]);
         $level = count($foldersplit) - 1;
         $display_rename = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $level) 
-          . rcube_charset_convert($foldersplit[$level], 'UTF-7');
+          . rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP');
 
-        $before = isset($folderlist[$x+1]) ? rcube_charset_convert($folderlist[$x+1], 'UTF-7') : false;
+        $before = isset($folderlist[$x+1]) ? rcube_charset_convert($folderlist[$x+1], 'UTF7-IMAP') : false;
         
-        $OUTPUT->command('replace_folder_row', rcube_charset_convert($oldfolder, 'UTF-7'),
-          rcube_charset_convert($folderlist[$x], 'UTF-7'), $display_rename, $before);
+        $OUTPUT->command('replace_folder_row', rcube_charset_convert($oldfolder, 'UTF7-IMAP'),
+          rcube_charset_convert($folderlist[$x], 'UTF7-IMAP'), $display_rename, $before);
         }
       }
 
     $foldersplit = explode($delimiter, $rename);
     $level = count($foldersplit) - 1;
-    $display_rename = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $level) . rcube_charset_convert($foldersplit[$level], 'UTF-7');
+    $display_rename = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $level) . rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP');
     $index = array_search($rename, $folderlist);
-    $before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF-7') : false;
-
-    $OUTPUT->command('replace_folder_row', $oldname_utf8, rcube_charset_convert($rename, 'UTF-7'), $display_rename, $before);
+    $before = $index !== false && isset($folderlist[$index+1]) ? rcube_charset_convert($folderlist[$index+1], 'UTF7-IMAP') : false;
 
+    $OUTPUT->command('replace_folder_row', $oldname_utf8, rcube_charset_convert($rename, 'UTF7-IMAP'), $display_rename, $before);
     $OUTPUT->command('reset_folder_rename');
     }
   else if (!$rename && $OUTPUT->ajax_call)
@@ -130,7 +129,7 @@ else if ($RCMAIL->action=='delete-folder')
   $delimiter = $IMAP->get_hierarchy_delimiter();
   
   $mboxes_utf8 = get_input_value('_mboxes', RCUBE_INPUT_POST);
-  $mboxes = rcube_charset_convert($mboxes_utf8, 'UTF-8', 'UTF-7');
+  $mboxes = rcube_charset_convert($mboxes_utf8, RCMAIL_CHARSET, 'UTF7-IMAP');
 
   if ($mboxes)
     $deleted = $IMAP->delete_mailbox(array($mboxes));
@@ -142,7 +141,7 @@ else if ($RCMAIL->action=='delete-folder')
       {
       if (preg_match('/^'. preg_quote($mboxes.$delimiter, '/') .'/', $mbox))
         {
-        $OUTPUT->command('remove_folder_row', rcube_charset_convert($mbox, 'UTF-7'));
+        $OUTPUT->command('remove_folder_row', rcube_charset_convert($mbox, 'UTF7-IMAP'));
         }
       }
     $OUTPUT->show_message('folderdeleted', 'confirmation');
@@ -189,7 +188,7 @@ function rcube_subscription_form($attrib)
   // pre-process folders list
   foreach ($a_unsubscribed as $i => $folder) {
     $foldersplit = explode($delimiter, $folder);
-    $name = rcube_charset_convert(array_pop($foldersplit), 'UTF-7');
+    $name = rcube_charset_convert(array_pop($foldersplit), 'UTF7-IMAP');
     $parent_folder = join($delimiter, $foldersplit);
     $level = count($foldersplit);
 
@@ -198,7 +197,7 @@ function rcube_subscription_form($attrib)
       for ($i=1; $i<=$level; $i++) {
        $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i));
        if ($ancestor_folder && !$seen[$ancestor_folder]++) {
-         $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF-7');
+         $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP');
          $list_folders[] = array('id' => $ancestor_folder, 'name' => $ancestor_name, 'level' => $i-1, 'virtual' => true);
        }
       }
@@ -231,7 +230,7 @@ function rcube_subscription_form($attrib)
     $classes = array($i%2 ? 'even' : 'odd');
     $folder_js = JQ($folder['id']);
     $display_folder = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $folder['level']) . ($protected ? rcmail_localize_foldername($folder['id']) : $folder['name']);
-    $folder_utf8 = rcube_charset_convert($folder['id'], 'UTF-7');
+    $folder_utf8 = rcube_charset_convert($folder['id'], 'UTF7-IMAP');
     
     if ($folder['virtual'])
       $classes[] = 'virtual';
@@ -256,6 +255,7 @@ function rcube_subscription_form($attrib)
     $a_js_folders['rcmrow'.$idx] = array($folder_utf8, $display_folder, $protected || $folder['virtual']);
   }
 
+  rcmail::get_instance()->plugins->exec_hook('manage_folders', array('table'=>$table));
 
   $OUTPUT->add_gui_object('subscriptionlist', $attrib['id']);
   $OUTPUT->set_env('subscriptionrows', $a_js_folders);
index 30beae4e25597a713cb2212975fc8a2bb716d5b7..977d7033adc35000ba488637ea5a8e5c760012fa 100644 (file)
@@ -5,7 +5,7 @@
  | program/steps/settings/save_identity.inc                              |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: save_identity.inc 2483 2009-05-15 10:22:29Z thomasb $
+ $Id: save_identity.inc 2778 2009-07-21 16:02:33Z thomasb $
 
 */
 
@@ -60,7 +60,11 @@ if (IDENTITIES_LEVEL == 1 || IDENTITIES_LEVEL == 3)
 // update an existing contact
 if ($_POST['_iid'])
 {
-  if ($updated = $USER->update_identity(get_input_value('_iid', RCUBE_INPUT_POST), $save_data))
+  $iid = get_input_value('_iid', RCUBE_INPUT_POST);
+  $plugin = $RCMAIL->plugins->exec_hook('save_identity', array('id' => $iid, 'record' => $save_data));
+  $save_data = $plugin['record'];
+
+  if (!$plugin['abort'] && ($updated = $USER->update_identity($iid, $save_data)))
   {
     $OUTPUT->show_message('successfullysaved', 'confirmation');
     
@@ -73,10 +77,10 @@ if ($_POST['_iid'])
       // ...      
     }
   }
-  else if ($DB->is_error())
+  else if ($plugin['abort'] || $DB->is_error())
   {
     // show error message
-    $OUTPUT->show_message('errorsaving', 'error');
+    $OUTPUT->show_message('errorsaving', 'error', null, false);
     rcmail_overwrite_action('edit-identity');
     return;
   }
@@ -88,9 +92,12 @@ else if (IDENTITIES_LEVEL < 2)
   if (IDENTITIES_LEVEL == 1)
     $save_data['email'] = $RCMAIL->user->get_username();
 
-  if ($save_data['email'] && ($insert_id = $USER->insert_identity($save_data)))
+  $plugin = $RCMAIL->plugins->exec_hook('create_identity', array('record' => $save_data));
+  $save_data = $plugin['record'];
+
+  if (!$plugin['abort'] && $save_data['email'] && ($insert_id = $USER->insert_identity($save_data)))
   {
-    $OUTPUT->show_message('successfullysaved', 'confirmation');
+    $OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
     
     $_GET['_iid'] = $insert_id;
 
@@ -100,7 +107,7 @@ else if (IDENTITIES_LEVEL < 2)
   else
   {
     // show error message
-    $OUTPUT->show_message('errorsaving', 'error');
+    $OUTPUT->show_message('errorsaving', 'error', null, false);
     rcmail_overwrite_action('edit-identity');
     return;
   }
index de9e1eb5993ff8e1fbb01af478607385fc0e35ec..0653d8f9ef997c3e11802b63bda2800372f12c96 100644 (file)
@@ -5,7 +5,7 @@
  | program/steps/settings/save_prefs.inc                                 |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: save_prefs.inc 2115 2008-12-04 10:21:34Z alec $
+ $Id: save_prefs.inc 2873 2009-08-27 06:18:54Z thomasb $
 
 */
 
-$a_user_prefs = array(
-  'language'     => isset($_POST['_language']) ? get_input_value('_language', RCUBE_INPUT_POST) : $CONFIG['language'],
-  'timezone'     => isset($_POST['_timezone']) ? (is_numeric($_POST['_timezone']) ? floatval($_POST['_timezone']) : get_input_value('_timezone', RCUBE_INPUT_POST)) : $CONFIG['timezone'],
-  'dst_active'   => isset($_POST['_dst_active']) ? TRUE : FALSE,
-  'pagesize'     => is_numeric($_POST['_pagesize']) ? max(2, intval($_POST['_pagesize'])) : $CONFIG['pagesize'],
-  'prettydate'   => isset($_POST['_pretty_date']) ? TRUE : FALSE,
-  'prefer_html'  => isset($_POST['_prefer_html']) ? TRUE : FALSE,
-  'htmleditor'   => isset($_POST['_htmleditor']) ? TRUE : FALSE,
-  'inline_images'   => isset($_POST['_inline_images']) ? TRUE : FALSE,
-  'preview_pane' => isset($_POST['_preview_pane']) ? TRUE : FALSE,
-  'focus_on_new_message' => isset($_POST['_focus_on_new_message']) ? TRUE : FALSE,
-  'read_when_deleted' => isset($_POST['_read_when_deleted']) ? TRUE : FALSE,
-  'skip_deleted' => isset($_POST['_skip_deleted']) ? TRUE : FALSE,
-  'flag_for_deletion' => isset($_POST['_flag_for_deletion']) ? TRUE : FALSE,
-  'logout_purge' => isset($_POST['_logout_purge']) ? TRUE : FALSE,
-  'logout_expunge' => isset($_POST['_logout_expunge']) ? TRUE : FALSE,
-  'draft_autosave' => isset($_POST['_draft_autosave']) ? intval($_POST['_draft_autosave']) : 0,
-  'show_images' => isset($_POST['_show_images']) ? intval($_POST['_show_images']) : 0,
-  'keep_alive' => isset($_POST['_keep_alive']) ? intval($_POST['_keep_alive'])*60 : $CONFIG['keep_alive'],
-  'check_all_folders' => isset($_POST['_check_all_folders']) ? TRUE : FALSE,
-  'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0,
-  'mdn_requests' => isset($_POST['_mdn_requests']) ? intval($_POST['_mdn_requests']) : 0,
-  'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
-  'drafts_mbox' => get_input_value('_drafts_mbox', RCUBE_INPUT_POST),
-  'sent_mbox' => get_input_value('_sent_mbox', RCUBE_INPUT_POST),
-  'junk_mbox' => get_input_value('_junk_mbox', RCUBE_INPUT_POST),
-  'trash_mbox' => get_input_value('_trash_mbox', RCUBE_INPUT_POST),
-  );
+$CURR_SECTION = get_input_value('_section', RCUBE_INPUT_POST);
+
+$a_user_prefs = array();
+
+// set options for specified section
+switch ($CURR_SECTION)
+{
+  case 'general':
+    $a_user_prefs = array(
+      'language'     => isset($_POST['_language']) ? get_input_value('_language', RCUBE_INPUT_POST) : $CONFIG['language'],
+      'timezone'     => isset($_POST['_timezone']) ? (is_numeric($_POST['_timezone']) ? floatval($_POST['_timezone']) : get_input_value('_timezone', RCUBE_INPUT_POST)) : $CONFIG['timezone'],
+      'dst_active'   => isset($_POST['_dst_active']) ? TRUE : FALSE,
+      'pagesize'     => is_numeric($_POST['_pagesize']) ? max(2, intval($_POST['_pagesize'])) : $CONFIG['pagesize'],
+      'prettydate'   => isset($_POST['_pretty_date']) ? TRUE : FALSE,
+      'skin'        => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
+    );
+
+  break;
+  case 'mailbox':
+    $a_user_prefs = array(
+      'focus_on_new_message' => isset($_POST['_focus_on_new_message']) ? TRUE : FALSE,
+      'preview_pane'        => isset($_POST['_preview_pane']) ? TRUE : FALSE,
+      'mdn_requests'         => isset($_POST['_mdn_requests']) ? intval($_POST['_mdn_requests']) : 0,
+      'keep_alive'           => isset($_POST['_keep_alive']) ? intval($_POST['_keep_alive'])*60 : $CONFIG['keep_alive'],
+      'check_all_folders'    => isset($_POST['_check_all_folders']) ? TRUE : FALSE,
+    );
+
+  break;
+  case 'mailview':
+    $a_user_prefs = array(
+      'prefer_html'     => isset($_POST['_prefer_html']) ? TRUE : FALSE,
+      'inline_images'   => isset($_POST['_inline_images']) ? TRUE : FALSE,
+      'show_images'     => isset($_POST['_show_images']) ? intval($_POST['_show_images']) : 0,
+      'display_next'    => isset($_POST['_display_next']) ? TRUE : FALSE,
+    );
+
+  break;
+  case 'compose':
+    $a_user_prefs = array(
+      'htmleditor'         => isset($_POST['_htmleditor']) ? TRUE : FALSE,
+      'draft_autosave'     => isset($_POST['_draft_autosave']) ? intval($_POST['_draft_autosave']) : 0,
+      'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0,
+    );
+
+  break;
+  case 'server':
+    $a_user_prefs = array(
+      'read_when_deleted' => isset($_POST['_read_when_deleted']) ? TRUE : FALSE,
+      'skip_deleted'      => isset($_POST['_skip_deleted']) ? TRUE : FALSE,
+      'flag_for_deletion' => isset($_POST['_flag_for_deletion']) ? TRUE : FALSE,
+      'logout_purge'      => isset($_POST['_logout_purge']) ? TRUE : FALSE,
+      'logout_expunge'    => isset($_POST['_logout_expunge']) ? TRUE : FALSE,
+    );
+
+  break;
+  case 'folders':
+    $a_user_prefs = array(
+      'drafts_mbox' => get_input_value('_drafts_mbox', RCUBE_INPUT_POST),
+      'sent_mbox'   => get_input_value('_sent_mbox', RCUBE_INPUT_POST),
+      'junk_mbox'   => get_input_value('_junk_mbox', RCUBE_INPUT_POST),
+      'trash_mbox'  => get_input_value('_trash_mbox', RCUBE_INPUT_POST),
+    );
+
+  break;
+}
+
+
+$data = rcmail::get_instance()->plugins->exec_hook('save_preferences',
+  array('prefs' => $a_user_prefs, 'section' => $CURR_SECTION));
+
+$a_user_prefs = $data['prefs'];
 
 // don't override these parameters
 foreach ((array)$CONFIG['dont_override'] as $p)
   $a_user_prefs[$p] = $CONFIG[$p];
 
-// special handling for 'default_imap_folders'
-if (in_array('default_imap_folders', (array)$CONFIG['dont_override'])) {
-  foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p)
-    $a_user_prefs[$p] = $CONFIG[$p];
-}
-else {
-  $a_user_prefs['default_imap_folders'] = array('INBOX');
-  foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) {
-    if ($a_user_prefs[$p])
-      $a_user_prefs['default_imap_folders'][] = $a_user_prefs[$p];
-  }
-}
 
-// switch UI language
-if (isset($_POST['_language'])) {
-  $RCMAIL->load_language($a_user_prefs['language']);
-}
+// verify some options
+switch ($CURR_SECTION)
+{
+  case 'general':
 
-// switch skin
-$OUTPUT->set_skin($a_user_prefs['skin']);
+    // switch UI language
+    if (isset($_POST['_language']) && $a_user_prefs['language'] != $_SESSION['language']) {
+      $RCMAIL->load_language($a_user_prefs['language']);
+      $OUTPUT->command('reload', 500);
+    }
 
-// force min size
-if ($a_user_prefs['pagesize'] < 1)
-  $a_user_prefs['pagesize'] = 10;
+    // switch skin
+    $OUTPUT->set_skin($a_user_prefs['skin']);
 
-if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['pagesize'] > $CONFIG['max_pagesize']))
-  $a_user_prefs['pagesize'] = (int) $CONFIG['max_pagesize'];
+    // force min size
+    if ($a_user_prefs['pagesize'] < 1)
+      $a_user_prefs['pagesize'] = 10;
 
-// force keep_alive
-if (isset($a_user_prefs['keep_alive'])) {
-    $a_user_prefs['keep_alive'] = max(60, $CONFIG['min_keep_alive'], $a_user_prefs['keep_alive']);
-    if (!empty($CONFIG['session_lifetime']))
-      $a_user_prefs['keep_alive'] = min($CONFIG['session_lifetime']*60, $a_user_prefs['keep_alive']);
-}
+    if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['pagesize'] > $CONFIG['max_pagesize']))
+      $a_user_prefs['pagesize'] = (int) $CONFIG['max_pagesize'];
+
+  break;
+  case 'mailbox':
+
+    // force keep_alive
+    if (isset($a_user_prefs['keep_alive'])) {
+      $a_user_prefs['keep_alive'] = max(60, $CONFIG['min_keep_alive'], $a_user_prefs['keep_alive']);
+      if (!empty($CONFIG['session_lifetime']))
+        $a_user_prefs['keep_alive'] = min($CONFIG['session_lifetime']*60, $a_user_prefs['keep_alive']);
+    }
 
+  break;
+  case 'folders':
+
+    // special handling for 'default_imap_folders'
+    if (in_array('default_imap_folders', (array)$CONFIG['dont_override'])) {
+      foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p)
+        $a_user_prefs[$p] = $CONFIG[$p];
+    } else {
+      $a_user_prefs['default_imap_folders'] = array('INBOX');
+      foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) {
+        if ($a_user_prefs[$p])
+          $a_user_prefs['default_imap_folders'][] = $a_user_prefs[$p];
+      }
+    }
+  
+  break;
+}
 
 if ($USER->save_prefs($a_user_prefs))
   $OUTPUT->show_message('successfullysaved', 'confirmation');
 
-// go to next step
-rcmail_overwrite_action('preferences');
+// display the form again
+rcmail_overwrite_action('edit-prefs');
 
 ?>
index 6f984e01d82558624bfe308f8dd00cb111e5bcdf..45dcf9bc4c2b2b0e099240dd006a9eb66e6614b6 100644 (file)
@@ -4,7 +4,7 @@
 {
   position: absolute;
   top: 45px;
-  left: 200px;
+  left: 205px;
   height: 35px;
 }
 
   padding-right: 10px;
 }
 
+#abooktoolbar a.button,
+#abooktoolbar a.buttonPas,
+#abooktoolbar span.separator {
+  display: block;
+  float: left;
+  width: 32px;
+  height: 32px;
+  padding: 0;
+  margin-right: 10px;
+  overflow: hidden;
+  background: url('images/abook_toolbar.png') 0 0 no-repeat transparent;
+  opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
+}
+
+#abooktoolbar a.buttonPas {
+  opacity: 0.35;
+}
+
+#abooktoolbar a.addcontactSel {
+  background-position: 0 -32px;
+}
+
+#abooktoolbar a.compose {
+  background-position: -32px 0;
+}
+
+#abooktoolbar a.composeSel {
+  background-position: -32px -32px;
+}
+
+#abooktoolbar a.delete {
+  background-position: -64px 0;
+}
+
+#abooktoolbar a.deleteSel {
+  background-position: -64px -32px;
+}
+
+#abooktoolbar a.import {
+  background-position: -96px 0;
+}
+
+#abooktoolbar a.importSel {
+  background-position: -96px -32px;
+}
+
+#abooktoolbar a.export {
+  background-position: -128px 0;
+}
+
+#abooktoolbar a.exportSel {
+  background-position: -128px -32px;
+}
+
+#abooktoolbar span.separator {
+  width: 5px;
+  background-image: url('images/abook_toolbar.png');
+  background-position: -162px 0;
+}
+
 #abookcountbar
 {
   position: absolute;
   color: #333333;
 }
 
-#mainscreen
+#addressscreen
 {
   position: absolute;
   top: 85px;
   right: 20px;
   bottom: 40px;
-  left: 200px;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-220)+'px');
-  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');
+  left: 205px;
 }
 
 #directorylist
   top: 85px;
   bottom: 40px;
   left: 20px;
-  width: 170px;
+  width: 175px;
   border: 1px solid #999999;
   background-color: #F9F9F9;
   overflow: hidden;
-  /* css hack for IE */
-  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');  
 }
 
 #addresslist
   border: 1px solid #999999;
   background-color: #F9F9F9;
   overflow: auto;
-  /* css hack for IE */
-  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
 }
 
 #importbox
   background-color: #F9F9F9;
   padding-bottom: 4ex;
   overflow: auto;
-  /* css hack for IE */
-  height: expression((parseInt(document.documentElement.clientHeight)-135)+'px');  
 }
 
 #addresslist
 {
   width: 100%;
   table-layout: fixed;
-  /* css hack for IE */
-  width: expression(document.getElementById('addresslist').clientWidth);
 }
 
 
   bottom: 0px;
   border: 1px solid #999999;
   overflow: hidden;
-  /* css hack for IE */
-  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
-  width: expression((parseInt(this.parentNode.offsetWidth)-555)+'px');
 }
 
 body.iframe,
@@ -185,8 +231,7 @@ body.iframe,
   color: #333;
   font-size: 11px;
   font-weight: bold;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif);
+  background: url('images/listheader.gif') top left repeat-x #CCC;
   white-space: nowrap;
 }
 
index 34ea1d2b8310be33be23ef17aa2484f7e351dad5..43b3a92abd9675f4cd8d8daa5aa903a8ef77fda8 100644 (file)
@@ -82,14 +82,9 @@ input, textarea
 {
   font-size: 9pt;
   font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
-  color: #333333;
+  color: black;
   padding-left: 3px;
   padding-right: 3px;
-  /* IE hacks for input elements */
-  border-style: expression(this.type=='checkbox' || this.type=='radio' || this.id=='quicksearchbox' ? 'none' : 'solid');
-  border-width: expression(this.type=='checkbox' || this.type=='radio' ? '0' : '1px');
-  border-color: expression(this.type=='checkbox' || this.type=='radio' ? '' : '#666666');
-  background-color: expression(this.type=='checkbox' || this.type=='radio' ? 'transparent' : '#ffffff');
 }
 
 input.button
@@ -116,7 +111,6 @@ input.mainaction
 
 img
 {
-  behavior: url('skins/default/pngbehavior.htc');
   border: 0;
 }
 
@@ -136,8 +130,8 @@ img
 #header
 {
   position: absolute;
-  top: 10px;
-  left: 20px;
+  top: 8px;
+  left: 19px;
   width: 170px;
   height: 40px;
   z-index: 100;
@@ -157,15 +151,13 @@ img
   z-index: 2;
 }
 
-#taskbar a,
-#taskbar a:active,
-#taskbar a:visited
+#taskbar a
 {
   font-size: 11px;
   color: #666666;
   text-decoration: none;
-  padding: 6px 16px 6px 25px;
-  background-repeat: no-repeat;
+  padding: 6px 14px 6px 27px;
+  background: url('images/taskicons.gif') no-repeat;
 }
 
 #taskbar a:hover
@@ -173,27 +165,26 @@ img
   color: #333333;
 }
 
-a.button-mail
+#taskbar a.button-mail
 {
-  background-image: url(images/buttons/mail.gif);
+  background-position: 0 0;
 }
 
-a.button-addressbook
+#taskbar a.button-addressbook
 {
-  background-image: url(images/buttons/addressbook.gif);
+  background-position: 0 -25px;
 }
 
-a.button-settings
+#taskbar a.button-settings
 {
-  background-image: url(images/buttons/settings.gif);
+  background-position: 0 -50px;
 }
 
-a.button-logout
+#taskbar a.button-logout
 {
-  background-image: url(images/buttons/logout.gif);
+  background-position: 0 -75px;
 }
 
-
 #message
 {
   position: absolute;
@@ -203,23 +194,20 @@ a.button-logout
   right: 200px;
   z-index: 5000;
   opacity: 0.85;
-  /* IE */
-  filter: alpha(opacity=85);
 }
 
 #message div
 {
   width: 400px;
   margin: 0px auto;
-  height: 24px;
-  min-height: 24px;
+  min-height: 22px;
   padding: 8px 10px 8px 46px;
 }
 
 #message div.notice,
 #remote-objects-message
 {
-  background: url(images/display/info.png) 6px 3px no-repeat;
+  background: url('images/display/icons.png') 6px 3px no-repeat;
   background-color: #F7FDCB;
   border: 1px solid #C2D071;
 }
@@ -227,25 +215,78 @@ a.button-logout
 #message div.error,
 #message div.warning
 {
-  background: url(images/display/warning.png) 6px 3px no-repeat;
+  background: url('images/display/icons.png') 6px -97px no-repeat;
   background-color: #EF9398;
   border: 1px solid #DC5757;
 }
 
 #message div.confirmation
 {
-  background: url(images/display/confirm.png) 6px 3px no-repeat;
+  background: url('images/display/icons.png') 6px -47px no-repeat;
   background-color: #A6EF7B;
   border: 1px solid #76C83F;
 }
 
 #message div.loading
 {
-  background: url(images/display/loading.gif) 6px 3px no-repeat;
+  background: url('images/display/loading.gif') 6px 3px no-repeat;
   background-color: #EBEBEB;
   border: 1px solid #CCCCCC;
 }
 
+#pagecontent
+{
+  position: absolute;
+  top: 95px;
+  left: 20px;
+}
+
+.pagenav a.button,
+.pagenav a.buttonPas
+{
+  display: block;
+  float: left;
+  width: 11px;
+  height: 11px;
+  padding: 0;
+  margin: 1px;
+  overflow: hidden;
+  background: url('images/pagenav.gif') 0 0 no-repeat transparent;
+  opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
+}
+
+.pagenav a.buttonPas {
+  opacity: 0.35;
+}
+
+.pagenav a.firstpageSel {
+  background-position: 0 -11px;
+}
+
+.pagenav a.prevpage {
+  background-position: -11px 0;
+}
+
+.pagenav a.prevpageSel {
+  background-position: -11px -11px;
+}
+
+.pagenav a.nextpage {
+  background-position: -22px 0;
+}
+
+.pagenav a.nextpageSel {
+  background-position: -22px -11px;
+}
+
+.pagenav a.lastpage {
+  background-position: -33px 0;
+}
+
+.pagenav a.lastpageSel {
+  background-position: -33px -11px;
+}
+
 .splitter
 {
   user-select: none;
@@ -270,18 +311,12 @@ a.button-logout
 .boxtitle
 {
   height: 12px !important;
-  padding: 4px 20px 3px 20px;
+  padding: 2px 10px 5px 10px;
   border-bottom: 1px solid #999;
   color: #333;
   font-size: 11px;
   font-weight: bold;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif);
-}
-
-.radios-left label
-{
-  padding-left: 0.3em;
+  background: url('images/listheader.gif') top left repeat-x #CCC;
 }
 
 /***** common table settings ******/
@@ -293,8 +328,7 @@ table.records-table thead tr td
   vertical-align: middle;
   border-bottom: 1px solid #999999;
   color: #333333;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif); 
+  background: url('images/listheader.gif') top left repeat-x #CCC;
   font-size: 11px;
   font-weight: bold;
 }
@@ -345,7 +379,7 @@ table.records-table tr.unfocused td
   background: url('images/searchfield.gif') top left no-repeat;
 }
 
-#quicksearchbar a
+#searchreset
 {
   position: absolute;
   top: 3px;
@@ -353,6 +387,13 @@ table.records-table tr.unfocused td
   text-decoration: none;
 }
 
+#searchmod
+{
+ position: absolute;
+ top: 3px;
+ right: 160px;
+}
+
 #quicksearchbar img
 {
   vertical-align: middle;
@@ -362,7 +403,7 @@ table.records-table tr.unfocused td
 {
   position: absolute;
   top: 2px;
-  left: 20px;
+  left: 24px;
   width: 140px;
   height: 15px;
   font-size: 11px;
@@ -404,8 +445,6 @@ table.records-table tr.unfocused td
   font-size: 11px;
   white-space: nowrap;
   opacity: 0.7;
-  -moz-opacity: 0.7;
-  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=70);
 }
 
 a.rcmContactAddress
@@ -450,3 +489,35 @@ a.rcmContactAddress:hover
   background-color: #CC3333;
 }
 
+#login-form
+{
+  margin-left: auto;
+  margin-right: auto;
+  margin-top: 50px;
+  width: 400px;
+  border: 1px solid #999;
+}
+
+#login-form table td.title
+{
+  color: #666;
+  text-align: right;
+  padding-right: 10px;
+  white-space: nowrap;
+}
+
+#login-form table
+{
+  width: 1%;
+  margin: auto;
+}
+
+#login-form .boxcontent
+{
+  padding: 20px 10px 10px 10px;
+}
+
+#console
+{
+  opacity: 0.8;
+}
index 31a0a592e903ec23608a5e23f9ac26d52699e7b5..cb3717ced1f546815805b440e8efc30ecc0952be 100644 (file)
@@ -13,3 +13,12 @@ body {
        margin-top: 2px;
 }
 
+pre
+{
+       margin: 0;
+       padding: 0;
+       white-space: -moz-pre-wrap !important;
+       white-space: pre-wrap !important;
+       white-space: pre;
+       word-wrap: break-word; /* IE (and Safari) */
+}
index 9e71f6f9a0e9b677c0d80564d758505d091c747a..df8af15af84abb0cb3635e7f537dbddf717bc531 100644 (file)
@@ -8,24 +8,16 @@
 
 function rcube_init_settings_tabs()
 {
+  var tab = '#settingstabdefault';
   if (window.rcmail && rcmail.env.action)
-    {
-    var action = rcmail.env.action=='preferences' ? 'default' : (rcmail.env.action.indexOf('identity')>0 ? 'identities' : rcmail.env.action);
-    var tab = document.getElementById('settingstab'+action);
-    }
-  else 
-    var tab = document.getElementById('settingstabdefault');
-  
-  if (tab)
-    tab.className = 'tablink-selected';
+    tab = '#settingstab' + (rcmail.env.action=='preferences' ? 'default' : (rcmail.env.action.indexOf('identity')>0 ? 'identities' : rcmail.env.action.replace(/\./g, '')));
+
+  $(tab).addClass('tablink-selected');
 }
 
 function rcube_show_advanced(visible)
 {
-  var rows = document.getElementsByTagName('TR');
-  for(var i=0; i<rows.length; i++)
-    if(rows[i].className && rows[i].className.match(/advanced/))
-      rows[i].style.display = visible ? (bw.ie ? 'block' : 'table-row') : 'none';
+  $('tr.advanced').css('display', (visible ? (bw.ie ? 'block' : 'table-row') : 'none'));
 }
 
 /**
@@ -65,7 +57,7 @@ function rcmail_hide_header_form(id)
   link.style.display = '';
   
   parent = link.parentNode;
-  links = parent.getElementsByTagName('A');
+  links = parent.getElementsByTagName('a');
 
   for (var i=0; i<links.length; i++)
     if (links[i].style.display != 'none')
@@ -128,7 +120,9 @@ function rcmail_init_compose_form()
 
 function rcube_mail_ui()
 {
-  this.markmenu = new rcube_layer('markmessagemenu');
+  this.markmenu = $('#markmessagemenu');
+  this.searchmenu = $('#searchmenu');
+  this.messagemenu = $('#messagemenu');
 }
 
 rcube_mail_ui.prototype = {
@@ -136,25 +130,86 @@ rcube_mail_ui.prototype = {
 show_markmenu: function(show)
 {
   if (typeof show == 'undefined')
-    show = this.markmenu.visible ? false : true;
+    show = this.markmenu.is(':visible') ? false : true;
   
   var ref = rcube_find_object('markreadbutton');
   if (show && ref)
-    this.markmenu.move(ref.offsetLeft, ref.offsetTop + ref.offsetHeight);
+    this.markmenu.css({ left:ref.offsetLeft, top:(ref.offsetTop + ref.offsetHeight) });
+  
+  this.markmenu[show?'show':'hide']();
+},
+
+show_messagemenu: function(show)
+{
+  if (typeof show == 'undefined')
+    show = this.messagemenu.is(':visible') ? false : true;
+
+  var ref = rcube_find_object('messagemenulink');
+  if (show && ref)
+    this.messagemenu.css({ left:ref.offsetLeft, top:(ref.offsetTop + ref.offsetHeight) });
+
+  this.messagemenu[show?'show':'hide']();
+},
+
+show_searchmenu: function(show)
+{
+  if (typeof show == 'undefined')
+    show = this.searchmenu.is(':visible') ? false : true;
+
+  var ref = rcube_find_object('searchmod');
+  if (show && ref) {
+    var pos = $(ref).offset();
+    this.searchmenu.css({ left:pos.left, top:(pos.top + ref.offsetHeight + 2)});
+
+    if (rcmail.env.search_mods) {
+      for (var n in rcmail.env.search_mods) {
+        box = rcube_find_object('s_mod_' + n);
+        box.checked = 'checked';
+      }
+    }
+  }
+  this.searchmenu[show?'show':'hide']();
+},
+set_searchmod: function(elem)
+{
+  if (!rcmail.env.search_mods)
+    rcmail.env.search_mods = new Object();
   
-  this.markmenu.show(show);
+  if (!elem.checked)
+    delete(rcmail.env.search_mods[elem.value]);
+  else
+    rcmail.env.search_mods[elem.value] = elem.value;
 },
 
 body_mouseup: function(evt, p)
 {
-  if (this.markmenu && this.markmenu.visible && rcube_event.get_target(evt) != rcube_find_object('markreadbutton'))
+  if (this.markmenu && this.markmenu.is(':visible') && rcube_event.get_target(evt) != rcube_find_object('markreadbutton'))
     this.show_markmenu(false);
+  else if (this.messagemenu && this.messagemenu.is(':visible') && rcube_event.get_target(evt) != rcube_find_object('messagemenulink'))
+    this.show_messagemenu(false);
+  else if (this.searchmenu && this.searchmenu.is(':visible') && rcube_event.get_target(evt) != rcube_find_object('searchmod')) {
+    var menu = rcube_find_object('searchmenu');
+    var target = rcube_event.get_target(evt);
+    while (target.parentNode) {
+      if (target.parentNode == menu)
+        return;
+      target = target.parentNode;
+    }
+    this.show_searchmenu(false);
+  }
 },
 
 body_keypress: function(evt, p)
 {
-  if (rcube_event.get_keycode(evt) == 27 && this.markmenu && this.markmenu.visible)
-    this.show_markmenu(false);
+  if (rcube_event.get_keycode(evt) == 27) {
+    if (this.markmenu && this.markmenu.is(':visible'))
+      this.show_markmenu(false);
+    if (this.searchmenu && this.searchmenu.is(':visible'))
+      this.show_searchmenu(false);
+    if (this.messagemenu && this.messagemenu.is(':visible'))
+      this.show_messagemenu(false);
+  }
 }
 
 };
index 5738338be7be7e760cad100eab75a1022af42db8..6e8d41c920eb2c4a8b2a4bff66043ed1ff06ad33 100644 (file)
   visibility: hidden;
 }
 
+.googie_edit_layer {
+  border: 1px solid #666666;
+  background-color: #ffffff;
+  padding: 1px 4px;
+  margin: 1px 0px;
+  font-size: 9pt;
+  font-family: "Courier New", Courier, monospace;
+}
+
+.googie_edit_layer span {
+  font-size: 9pt;
+  font-family: "Courier New", Courier, monospace;
+}
+
 .googie_list {
   width: 100%;
   margin: 0;
@@ -34,7 +48,7 @@
 }
 
 .googie_list_onout {
-  background-color: #F6F6F6;
+  background-color: #fff;
 }
 
 .googie_list_selected {
 
 .googie_list_revert {
   font-size: 11px;
-  color: #b91479;
+  color: #b91414;
 }
 
+.googie_list_revert:hover {
+  color: #fff;
+}
 .googie_link {
   color: #b91414;
   text-decoration: underline;
   text-decoration: none;
 }
 
-.googie_check_spelling_ok {
+.googie_check_spelling_ok, 
+.googie_resume_editing {
   color: green;
   font-size: 11px;
-  text-decoration: underline;
   cursor: pointer;
 }
 
+.googie_check_spelling_ok:hover,
+.googie_resume_editing:hover {
+  text-decoration: underline;
+}
+
 .googie_lang_3d_click img {
   vertical-align: middle;
   border-top: 1px solid #555;
diff --git a/skins/default/ie6hacks.css b/skins/default/ie6hacks.css
new file mode 100644 (file)
index 0000000..448bbf9
--- /dev/null
@@ -0,0 +1,55 @@
+/* CSS hacks for IE versions 5,6 */
+
+img
+{
+  behavior: url('skins/default/pngbehavior.htc');
+}
+
+#message div.notice,
+#message div.error,
+#message div.warning,
+#message div.confirmation,
+#remote-objects-message
+{
+  background-image: url('images/display/icons.gif');
+}
+
+#messagemenu li a
+{
+  background-image: url('images/messageactions.gif');
+}
+
+#mailboxlist li
+{
+  background-image: url('images/icons/folders.gif');
+}
+
+#messagetoolbar a
+{
+  display: block;
+  float: left;
+  padding-right: 10px;
+}
+
+#messagetoolbar a.button,
+#messagetoolbar a.buttonPas {
+  background-image: url('images/mail_toolbar.gif');
+}
+
+#abooktoolbar a.button,
+#abooktoolbar a.buttonPas,
+#abooktoolbar span.separator {
+  background-image: url('images/abook_toolbar.gif');
+}
+
+ul.toolbarmenu li
+{
+  width: auto;
+  border: 1px solid #f6f6f6;
+}
+
+ul.toolbarmenu li a
+{
+  float: none;
+  padding: ;
+}
\ No newline at end of file
diff --git a/skins/default/iehacks.css b/skins/default/iehacks.css
new file mode 100644 (file)
index 0000000..f074d8b
--- /dev/null
@@ -0,0 +1,253 @@
+/* CSS hacks for IE versions <= 8 */
+
+input, textarea
+{
+  border-style: expression(this.type=='checkbox' || this.type=='radio' || this.id=='quicksearchbox' ? 'none' : 'solid');
+  border-width: expression(this.type=='checkbox' || this.type=='radio' ? '0' : '1px');
+  border-color: expression(this.type=='checkbox' || this.type=='radio' ? '' : '#666666');
+  background-color: expression(this.type=='checkbox' || this.type=='radio' ? 'transparent' : '#ffffff');
+}
+
+.pagenav a.buttonPas
+{
+  filter: alpha(opacity=35);
+}
+
+#message
+{
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)";
+  filter: alpha(opacity=85);
+}
+
+#markmessagemenu,
+#searchmenu,
+#messagemenu
+{
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
+  filter: alpha(opacity=90);
+
+}
+
+#tabsbar
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-240)+'px');
+}
+
+#folder-manager
+{
+  height: expression((parseInt(document.documentElement.clientHeight)-235)+'px');
+}
+
+#identities-list
+{
+  height: expression((parseInt(document.documentElement.clientHeight)-155)+'px');
+}
+
+#messagetoolbar
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-215)+'px');
+  z-index: 240;
+}
+
+#messagetoolbar select.mboxlist
+{
+  top: -8px;
+}
+
+#abooktoolbar a.buttonPas
+{
+  filter: alpha(opacity=35);
+  background-image: url('images/abook_toolbar.gif');
+}
+
+#messagetoolbar a.buttonPas
+{
+  filter: alpha(opacity=35);
+  background-image: url('images/mail_toolbar.gif');
+}
+
+#messagetoolbar select.mboxlist
+{
+  margin: 0 8px;
+  top: 8px;
+}
+
+#mainscreen
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
+  height: expression((parseInt(document.documentElement.clientHeight)-101)+'px');
+}
+
+#directorylist
+{
+  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');  
+}
+
+#addresslist,
+#sectionslist
+{
+  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+}
+
+#mailleftcontainer
+{
+  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+}
+
+#mailrightcontainer
+{
+  width: expression((parseInt(this.parentNode.offsetWidth)-170)+'px');
+  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+}
+
+#mailrightcontent
+{
+  width: 100%;
+}
+
+#messagepartcontainer
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
+  height: expression((parseInt(document.documentElement.clientHeight)-100)+'px');
+}
+
+#mailcontframe
+{
+  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+}
+
+#mailrightcontent
+{
+  height: expression((parseInt(this.parentNode.offsetHeight)-20)+'px');
+}
+
+#partheader
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-240)+'px');
+}
+
+#mailboxlist-container
+{
+  height: expression((parseInt(this.parentNode.offsetHeight)-20)+'px');
+}
+
+#subscription-table
+{
+  width: auto;
+}
+
+#messagelist
+{
+  width: inherit;
+  *width: auto; /* IE6/7 conditional hack */
+  border-collapse: collapse;
+}
+
+#messageframe
+{
+  width: expression((parseInt(this.parentNode.offsetWidth)-180)+'px');
+  height: expression((parseInt(this.parentNode.offsetHeight)-20)+'px');
+}
+
+#messagecanvas 
+{
+  width: expression((parseInt(this.parentNode.offsetWidth)-20)+'px');
+}
+
+#printmessageframe
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-220)+'px');
+  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');
+}
+
+#attachment-list
+{
+  height: expression(Math.min(16, parseInt(document.documentElement.clientHeight))+'px');
+}
+
+#countcontrols
+{
+  width: 24em;
+}
+
+body.iframe 
+{
+  width: expression((parseInt(document.documentElement.clientWidth))+'px');
+}
+
+#compose-container
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-230)+'px');
+  height: expression((parseInt(document.documentElement.clientHeight)-120)+'px');
+}
+
+#compose-body,
+#compose-headers td textarea,
+#compose-headers td input
+{
+  width: 99%;
+}
+
+div.message-part pre,
+div.message-htmlpart pre,
+div.message-part div.pre
+{
+  word-wrap: break-word;
+}
+
+#addressscreen
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-220)+'px');
+  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');
+}
+
+#prefsscreen
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
+  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');
+}
+
+#importbox
+{
+  height: expression((parseInt(document.documentElement.clientHeight)-135)+'px');
+}
+
+#contacts-table
+{
+  width: expression(document.getElementById('addresslist').clientWidth);
+}
+
+#contacts-box,
+#prefs-box
+{
+  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+  width: expression((parseInt(this.parentNode.offsetWidth)-555)+'px');
+}
+
+#identity-details
+{
+  width: expression((parseInt(document.documentElement.clientWidth)-470)+'px');
+  height: expression((parseInt(document.documentElement.clientHeight)-155)+'px');
+}
+
+#rcmdraglayer
+{
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
+  filter: alpha(opacity=70);
+}
+
+ul.toolbarmenu li
+{
+  min-width: auto;
+}
+
+ul.toolbarmenu li a
+{
+  min-height: auto;
+}
+
+#console
+{
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
+  filter: alpha(opacity=80);
+}
diff --git a/skins/default/images/abook_toolbar.gif b/skins/default/images/abook_toolbar.gif
new file mode 100644 (file)
index 0000000..1de95da
Binary files /dev/null and b/skins/default/images/abook_toolbar.gif differ
diff --git a/skins/default/images/abook_toolbar.png b/skins/default/images/abook_toolbar.png
new file mode 100644 (file)
index 0000000..cb7ae05
Binary files /dev/null and b/skins/default/images/abook_toolbar.png differ
index 0454ff8561c788659a1ca26a067ed659f14fb478..e94fcd6a0bb91b482debef61f456fd20ebdeb16e 100644 (file)
Binary files a/skins/default/images/buttons/add_act.png and b/skins/default/images/buttons/add_act.png differ
diff --git a/skins/default/images/buttons/add_contact_act.png b/skins/default/images/buttons/add_contact_act.png
deleted file mode 100644 (file)
index 994242c..0000000
Binary files a/skins/default/images/buttons/add_contact_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/add_contact_pas.png b/skins/default/images/buttons/add_contact_pas.png
deleted file mode 100644 (file)
index 91ca0d0..0000000
Binary files a/skins/default/images/buttons/add_contact_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/add_contact_sel.png b/skins/default/images/buttons/add_contact_sel.png
deleted file mode 100644 (file)
index effa91a..0000000
Binary files a/skins/default/images/buttons/add_contact_sel.png and /dev/null differ
index cf4de2e0b5dafe96ab985257aec75e1823711013..9f67c520206ded9c68d6c218658e3458d0c8e512 100644 (file)
Binary files a/skins/default/images/buttons/add_pas.png and b/skins/default/images/buttons/add_pas.png differ
index a6d8197d86964d43547de04307bb87bceff9d5cf..2a3719fba91425b76c83f567dd6c3e10d17d93ee 100644 (file)
Binary files a/skins/default/images/buttons/add_sel.png and b/skins/default/images/buttons/add_sel.png differ
diff --git a/skins/default/images/buttons/addressbook.gif b/skins/default/images/buttons/addressbook.gif
deleted file mode 100644 (file)
index d8c0c17..0000000
Binary files a/skins/default/images/buttons/addressbook.gif and /dev/null differ
diff --git a/skins/default/images/buttons/addressbook.png b/skins/default/images/buttons/addressbook.png
deleted file mode 100644 (file)
index 359f33e..0000000
Binary files a/skins/default/images/buttons/addressbook.png and /dev/null differ
diff --git a/skins/default/images/buttons/adr_import_act.png b/skins/default/images/buttons/adr_import_act.png
deleted file mode 100644 (file)
index c600c71..0000000
Binary files a/skins/default/images/buttons/adr_import_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/adr_import_pas.png b/skins/default/images/buttons/adr_import_pas.png
deleted file mode 100644 (file)
index 265d1b4..0000000
Binary files a/skins/default/images/buttons/adr_import_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/adr_import_sel.png b/skins/default/images/buttons/adr_import_sel.png
deleted file mode 100644 (file)
index d78bbfd..0000000
Binary files a/skins/default/images/buttons/adr_import_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/attach_act.png b/skins/default/images/buttons/attach_act.png
deleted file mode 100644 (file)
index 612d36d..0000000
Binary files a/skins/default/images/buttons/attach_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/attach_pas.png b/skins/default/images/buttons/attach_pas.png
deleted file mode 100644 (file)
index 37c67c9..0000000
Binary files a/skins/default/images/buttons/attach_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/attach_sel.png b/skins/default/images/buttons/attach_sel.png
deleted file mode 100644 (file)
index 81a4700..0000000
Binary files a/skins/default/images/buttons/attach_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/back_act.png b/skins/default/images/buttons/back_act.png
deleted file mode 100644 (file)
index d5352b5..0000000
Binary files a/skins/default/images/buttons/back_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/back_pas.png b/skins/default/images/buttons/back_pas.png
deleted file mode 100644 (file)
index ac15bad..0000000
Binary files a/skins/default/images/buttons/back_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/back_sel.png b/skins/default/images/buttons/back_sel.png
deleted file mode 100644 (file)
index b25acbf..0000000
Binary files a/skins/default/images/buttons/back_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/compose_act.png b/skins/default/images/buttons/compose_act.png
deleted file mode 100644 (file)
index c7e2d61..0000000
Binary files a/skins/default/images/buttons/compose_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/compose_pas.png b/skins/default/images/buttons/compose_pas.png
deleted file mode 100644 (file)
index 5fd9d7a..0000000
Binary files a/skins/default/images/buttons/compose_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/compose_sel.png b/skins/default/images/buttons/compose_sel.png
deleted file mode 100644 (file)
index 2efd8cb..0000000
Binary files a/skins/default/images/buttons/compose_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/contacts_act.png b/skins/default/images/buttons/contacts_act.png
deleted file mode 100644 (file)
index 9876128..0000000
Binary files a/skins/default/images/buttons/contacts_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/contacts_pas.png b/skins/default/images/buttons/contacts_pas.png
deleted file mode 100644 (file)
index 25dfd8c..0000000
Binary files a/skins/default/images/buttons/contacts_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/contacts_sel.png b/skins/default/images/buttons/contacts_sel.png
deleted file mode 100644 (file)
index 20df77c..0000000
Binary files a/skins/default/images/buttons/contacts_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/delete_act.png b/skins/default/images/buttons/delete_act.png
deleted file mode 100644 (file)
index b141cd3..0000000
Binary files a/skins/default/images/buttons/delete_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/delete_pas.png b/skins/default/images/buttons/delete_pas.png
deleted file mode 100644 (file)
index fc1e892..0000000
Binary files a/skins/default/images/buttons/delete_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/delete_sel.png b/skins/default/images/buttons/delete_sel.png
deleted file mode 100644 (file)
index b4c32c1..0000000
Binary files a/skins/default/images/buttons/delete_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/down_arrow.png b/skins/default/images/buttons/down_arrow.png
deleted file mode 100644 (file)
index d4f9e2d..0000000
Binary files a/skins/default/images/buttons/down_arrow.png and /dev/null differ
diff --git a/skins/default/images/buttons/download_act.png b/skins/default/images/buttons/download_act.png
deleted file mode 100644 (file)
index 694527d..0000000
Binary files a/skins/default/images/buttons/download_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/download_pas.png b/skins/default/images/buttons/download_pas.png
deleted file mode 100644 (file)
index fb39db5..0000000
Binary files a/skins/default/images/buttons/download_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/download_sel.png b/skins/default/images/buttons/download_sel.png
deleted file mode 100644 (file)
index cfc44b3..0000000
Binary files a/skins/default/images/buttons/download_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/drafts_act.png b/skins/default/images/buttons/drafts_act.png
deleted file mode 100644 (file)
index 3fc718a..0000000
Binary files a/skins/default/images/buttons/drafts_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/drafts_pas.png b/skins/default/images/buttons/drafts_pas.png
deleted file mode 100644 (file)
index 424709e..0000000
Binary files a/skins/default/images/buttons/drafts_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/drafts_sel.png b/skins/default/images/buttons/drafts_sel.png
deleted file mode 100644 (file)
index 34419b8..0000000
Binary files a/skins/default/images/buttons/drafts_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/edit_contact_act.png b/skins/default/images/buttons/edit_contact_act.png
deleted file mode 100644 (file)
index 57b2782..0000000
Binary files a/skins/default/images/buttons/edit_contact_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/edit_contact_pas.png b/skins/default/images/buttons/edit_contact_pas.png
deleted file mode 100644 (file)
index b999294..0000000
Binary files a/skins/default/images/buttons/edit_contact_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/edit_contact_sel.png b/skins/default/images/buttons/edit_contact_sel.png
deleted file mode 100644 (file)
index 616d583..0000000
Binary files a/skins/default/images/buttons/edit_contact_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/first_act.png b/skins/default/images/buttons/first_act.png
deleted file mode 100644 (file)
index 8322fd1..0000000
Binary files a/skins/default/images/buttons/first_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/first_pas.png b/skins/default/images/buttons/first_pas.png
deleted file mode 100644 (file)
index 0934cd1..0000000
Binary files a/skins/default/images/buttons/first_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/first_sel.png b/skins/default/images/buttons/first_sel.png
deleted file mode 100644 (file)
index 6bc1d9f..0000000
Binary files a/skins/default/images/buttons/first_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/forward_act.png b/skins/default/images/buttons/forward_act.png
deleted file mode 100644 (file)
index 2fdbdba..0000000
Binary files a/skins/default/images/buttons/forward_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/forward_pas.png b/skins/default/images/buttons/forward_pas.png
deleted file mode 100644 (file)
index e671398..0000000
Binary files a/skins/default/images/buttons/forward_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/forward_sel.png b/skins/default/images/buttons/forward_sel.png
deleted file mode 100644 (file)
index 90f67bb..0000000
Binary files a/skins/default/images/buttons/forward_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/inbox_act.png b/skins/default/images/buttons/inbox_act.png
deleted file mode 100644 (file)
index 30c1e76..0000000
Binary files a/skins/default/images/buttons/inbox_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/inbox_pas.png b/skins/default/images/buttons/inbox_pas.png
deleted file mode 100644 (file)
index 67f4da0..0000000
Binary files a/skins/default/images/buttons/inbox_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/inbox_sel.png b/skins/default/images/buttons/inbox_sel.png
deleted file mode 100644 (file)
index 89d661e..0000000
Binary files a/skins/default/images/buttons/inbox_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/last_act.png b/skins/default/images/buttons/last_act.png
deleted file mode 100644 (file)
index 3967fa4..0000000
Binary files a/skins/default/images/buttons/last_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/last_pas.png b/skins/default/images/buttons/last_pas.png
deleted file mode 100644 (file)
index e18d37a..0000000
Binary files a/skins/default/images/buttons/last_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/last_sel.png b/skins/default/images/buttons/last_sel.png
deleted file mode 100644 (file)
index 0d608ea..0000000
Binary files a/skins/default/images/buttons/last_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/logout.gif b/skins/default/images/buttons/logout.gif
deleted file mode 100644 (file)
index 93eb1aa..0000000
Binary files a/skins/default/images/buttons/logout.gif and /dev/null differ
diff --git a/skins/default/images/buttons/logout.png b/skins/default/images/buttons/logout.png
deleted file mode 100644 (file)
index 2fe632a..0000000
Binary files a/skins/default/images/buttons/logout.png and /dev/null differ
diff --git a/skins/default/images/buttons/mail.gif b/skins/default/images/buttons/mail.gif
deleted file mode 100644 (file)
index 8bb93f7..0000000
Binary files a/skins/default/images/buttons/mail.gif and /dev/null differ
diff --git a/skins/default/images/buttons/mail.png b/skins/default/images/buttons/mail.png
deleted file mode 100644 (file)
index 30c1e76..0000000
Binary files a/skins/default/images/buttons/mail.png and /dev/null differ
diff --git a/skins/default/images/buttons/markread_act.png b/skins/default/images/buttons/markread_act.png
deleted file mode 100644 (file)
index 32c0511..0000000
Binary files a/skins/default/images/buttons/markread_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/next_act.png b/skins/default/images/buttons/next_act.png
deleted file mode 100644 (file)
index fed8294..0000000
Binary files a/skins/default/images/buttons/next_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/next_pas.png b/skins/default/images/buttons/next_pas.png
deleted file mode 100644 (file)
index df80ad3..0000000
Binary files a/skins/default/images/buttons/next_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/next_sel.png b/skins/default/images/buttons/next_sel.png
deleted file mode 100644 (file)
index 77cb1b1..0000000
Binary files a/skins/default/images/buttons/next_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/previous_act.png b/skins/default/images/buttons/previous_act.png
deleted file mode 100644 (file)
index 457d873..0000000
Binary files a/skins/default/images/buttons/previous_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/previous_pas.png b/skins/default/images/buttons/previous_pas.png
deleted file mode 100644 (file)
index db7186d..0000000
Binary files a/skins/default/images/buttons/previous_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/previous_sel.png b/skins/default/images/buttons/previous_sel.png
deleted file mode 100644 (file)
index d102a53..0000000
Binary files a/skins/default/images/buttons/previous_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/print_act.png b/skins/default/images/buttons/print_act.png
deleted file mode 100644 (file)
index 19e1f33..0000000
Binary files a/skins/default/images/buttons/print_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/print_pas.png b/skins/default/images/buttons/print_pas.png
deleted file mode 100644 (file)
index b6c0e78..0000000
Binary files a/skins/default/images/buttons/print_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/print_sel.png b/skins/default/images/buttons/print_sel.png
deleted file mode 100644 (file)
index 0ddaa31..0000000
Binary files a/skins/default/images/buttons/print_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/reply_act.png b/skins/default/images/buttons/reply_act.png
deleted file mode 100644 (file)
index 89ad7cc..0000000
Binary files a/skins/default/images/buttons/reply_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/reply_pas.png b/skins/default/images/buttons/reply_pas.png
deleted file mode 100644 (file)
index 0b38933..0000000
Binary files a/skins/default/images/buttons/reply_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/reply_sel.png b/skins/default/images/buttons/reply_sel.png
deleted file mode 100644 (file)
index 76f5eac..0000000
Binary files a/skins/default/images/buttons/reply_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/replyall_act.png b/skins/default/images/buttons/replyall_act.png
deleted file mode 100644 (file)
index b6ad3fb..0000000
Binary files a/skins/default/images/buttons/replyall_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/replyall_pas.png b/skins/default/images/buttons/replyall_pas.png
deleted file mode 100644 (file)
index 948072d..0000000
Binary files a/skins/default/images/buttons/replyall_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/replyall_sel.png b/skins/default/images/buttons/replyall_sel.png
deleted file mode 100644 (file)
index 483436c..0000000
Binary files a/skins/default/images/buttons/replyall_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/send_act.png b/skins/default/images/buttons/send_act.png
deleted file mode 100644 (file)
index 999d21d..0000000
Binary files a/skins/default/images/buttons/send_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/send_pas.png b/skins/default/images/buttons/send_pas.png
deleted file mode 100644 (file)
index db227c9..0000000
Binary files a/skins/default/images/buttons/send_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/send_sel.png b/skins/default/images/buttons/send_sel.png
deleted file mode 100644 (file)
index fc3d133..0000000
Binary files a/skins/default/images/buttons/send_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/settings.gif b/skins/default/images/buttons/settings.gif
deleted file mode 100644 (file)
index a390cd9..0000000
Binary files a/skins/default/images/buttons/settings.gif and /dev/null differ
diff --git a/skins/default/images/buttons/settings.png b/skins/default/images/buttons/settings.png
deleted file mode 100644 (file)
index 41395bf..0000000
Binary files a/skins/default/images/buttons/settings.png and /dev/null differ
diff --git a/skins/default/images/buttons/source_act.png b/skins/default/images/buttons/source_act.png
deleted file mode 100644 (file)
index 3971b5c..0000000
Binary files a/skins/default/images/buttons/source_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/source_pas.png b/skins/default/images/buttons/source_pas.png
deleted file mode 100644 (file)
index aec440a..0000000
Binary files a/skins/default/images/buttons/source_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/source_sel.png b/skins/default/images/buttons/source_sel.png
deleted file mode 100644 (file)
index 4749317..0000000
Binary files a/skins/default/images/buttons/source_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/spacer.gif b/skins/default/images/buttons/spacer.gif
deleted file mode 100644 (file)
index 5bfd67a..0000000
Binary files a/skins/default/images/buttons/spacer.gif and /dev/null differ
diff --git a/skins/default/images/buttons/spellcheck_act.png b/skins/default/images/buttons/spellcheck_act.png
deleted file mode 100644 (file)
index dd3056e..0000000
Binary files a/skins/default/images/buttons/spellcheck_act.png and /dev/null differ
diff --git a/skins/default/images/buttons/spellcheck_pas.png b/skins/default/images/buttons/spellcheck_pas.png
deleted file mode 100644 (file)
index 3d41201..0000000
Binary files a/skins/default/images/buttons/spellcheck_pas.png and /dev/null differ
diff --git a/skins/default/images/buttons/spellcheck_sel.png b/skins/default/images/buttons/spellcheck_sel.png
deleted file mode 100644 (file)
index 8c24d6f..0000000
Binary files a/skins/default/images/buttons/spellcheck_sel.png and /dev/null differ
diff --git a/skins/default/images/buttons/up_arrow.png b/skins/default/images/buttons/up_arrow.png
deleted file mode 100644 (file)
index aca1b54..0000000
Binary files a/skins/default/images/buttons/up_arrow.png and /dev/null differ
diff --git a/skins/default/images/display/confirm.png b/skins/default/images/display/confirm.png
deleted file mode 100644 (file)
index 27265f8..0000000
Binary files a/skins/default/images/display/confirm.png and /dev/null differ
diff --git a/skins/default/images/display/icons.gif b/skins/default/images/display/icons.gif
new file mode 100644 (file)
index 0000000..e6dfb1b
Binary files /dev/null and b/skins/default/images/display/icons.gif differ
diff --git a/skins/default/images/display/icons.png b/skins/default/images/display/icons.png
new file mode 100644 (file)
index 0000000..2ab7d43
Binary files /dev/null and b/skins/default/images/display/icons.png differ
diff --git a/skins/default/images/display/info.png b/skins/default/images/display/info.png
deleted file mode 100644 (file)
index 85462e4..0000000
Binary files a/skins/default/images/display/info.png and /dev/null differ
diff --git a/skins/default/images/display/warning.png b/skins/default/images/display/warning.png
deleted file mode 100644 (file)
index 9909617..0000000
Binary files a/skins/default/images/display/warning.png and /dev/null differ
index 5a011f29e2276c9b5650e8a219a3eccbc26ce25a..b3bd18c129e04149b0913efb6dc092d4967d3abc 100644 (file)
Binary files a/skins/default/images/favicon.ico and b/skins/default/images/favicon.ico differ
diff --git a/skins/default/images/icons/delete.png b/skins/default/images/icons/delete.png
new file mode 100644 (file)
index 0000000..f1cf0ae
Binary files /dev/null and b/skins/default/images/icons/delete.png differ
diff --git a/skins/default/images/icons/folder-closed.png b/skins/default/images/icons/folder-closed.png
deleted file mode 100644 (file)
index 5cbf72a..0000000
Binary files a/skins/default/images/icons/folder-closed.png and /dev/null differ
diff --git a/skins/default/images/icons/folder-drafts.png b/skins/default/images/icons/folder-drafts.png
deleted file mode 100644 (file)
index d828b56..0000000
Binary files a/skins/default/images/icons/folder-drafts.png and /dev/null differ
diff --git a/skins/default/images/icons/folder-inbox.png b/skins/default/images/icons/folder-inbox.png
deleted file mode 100644 (file)
index 995ca81..0000000
Binary files a/skins/default/images/icons/folder-inbox.png and /dev/null differ
diff --git a/skins/default/images/icons/folder-junk.png b/skins/default/images/icons/folder-junk.png
deleted file mode 100644 (file)
index 06fbd49..0000000
Binary files a/skins/default/images/icons/folder-junk.png and /dev/null differ
diff --git a/skins/default/images/icons/folder-open.png b/skins/default/images/icons/folder-open.png
deleted file mode 100644 (file)
index 09ba4b3..0000000
Binary files a/skins/default/images/icons/folder-open.png and /dev/null differ
diff --git a/skins/default/images/icons/folder-sent.png b/skins/default/images/icons/folder-sent.png
deleted file mode 100644 (file)
index 2968ab5..0000000
Binary files a/skins/default/images/icons/folder-sent.png and /dev/null differ
diff --git a/skins/default/images/icons/folder-trash.png b/skins/default/images/icons/folder-trash.png
deleted file mode 100644 (file)
index 0712aaa..0000000
Binary files a/skins/default/images/icons/folder-trash.png and /dev/null differ
diff --git a/skins/default/images/icons/folders.gif b/skins/default/images/icons/folders.gif
new file mode 100644 (file)
index 0000000..9598085
Binary files /dev/null and b/skins/default/images/icons/folders.gif differ
diff --git a/skins/default/images/icons/folders.png b/skins/default/images/icons/folders.png
new file mode 100644 (file)
index 0000000..a6c042c
Binary files /dev/null and b/skins/default/images/icons/folders.png differ
diff --git a/skins/default/images/icons/glass.gif b/skins/default/images/icons/glass.gif
new file mode 100644 (file)
index 0000000..9a705b4
Binary files /dev/null and b/skins/default/images/icons/glass.gif differ
diff --git a/skins/default/images/icons/glass.png b/skins/default/images/icons/glass.png
new file mode 100644 (file)
index 0000000..41dbb3a
Binary files /dev/null and b/skins/default/images/icons/glass.png differ
diff --git a/skins/default/images/icons/glass_roll.png b/skins/default/images/icons/glass_roll.png
new file mode 100644 (file)
index 0000000..a6d975a
Binary files /dev/null and b/skins/default/images/icons/glass_roll.png differ
diff --git a/skins/default/images/icons/remove-attachment.png b/skins/default/images/icons/remove-attachment.png
deleted file mode 100644 (file)
index 8d496fe..0000000
Binary files a/skins/default/images/icons/remove-attachment.png and /dev/null differ
index c7d97489bca942fdf34cee3e4f3b0ac09a2e9b00..ac0773514693c8de8ad9c4a133361e03204ae652 100644 (file)
Binary files a/skins/default/images/icons/silhouette.png and b/skins/default/images/icons/silhouette.png differ
diff --git a/skins/default/images/icons/sort.gif b/skins/default/images/icons/sort.gif
new file mode 100644 (file)
index 0000000..f8f2756
Binary files /dev/null and b/skins/default/images/icons/sort.gif differ
diff --git a/skins/default/images/listheader.gif b/skins/default/images/listheader.gif
new file mode 100644 (file)
index 0000000..e7f5015
Binary files /dev/null and b/skins/default/images/listheader.gif differ
diff --git a/skins/default/images/listheader_aqua.gif b/skins/default/images/listheader_aqua.gif
deleted file mode 100644 (file)
index 59f44ea..0000000
Binary files a/skins/default/images/listheader_aqua.gif and /dev/null differ
diff --git a/skins/default/images/listheader_dark.gif b/skins/default/images/listheader_dark.gif
deleted file mode 100644 (file)
index cd35555..0000000
Binary files a/skins/default/images/listheader_dark.gif and /dev/null differ
diff --git a/skins/default/images/listheader_light.gif b/skins/default/images/listheader_light.gif
deleted file mode 100644 (file)
index 8d9e6ca..0000000
Binary files a/skins/default/images/listheader_light.gif and /dev/null differ
diff --git a/skins/default/images/mail_toolbar.gif b/skins/default/images/mail_toolbar.gif
new file mode 100644 (file)
index 0000000..9a8fdc3
Binary files /dev/null and b/skins/default/images/mail_toolbar.gif differ
diff --git a/skins/default/images/mail_toolbar.png b/skins/default/images/mail_toolbar.png
new file mode 100644 (file)
index 0000000..ece87ad
Binary files /dev/null and b/skins/default/images/mail_toolbar.png differ
diff --git a/skins/default/images/messageactions.gif b/skins/default/images/messageactions.gif
new file mode 100644 (file)
index 0000000..5f0a533
Binary files /dev/null and b/skins/default/images/messageactions.gif differ
diff --git a/skins/default/images/messageactions.png b/skins/default/images/messageactions.png
new file mode 100644 (file)
index 0000000..8dfb389
Binary files /dev/null and b/skins/default/images/messageactions.png differ
diff --git a/skins/default/images/pagenav.gif b/skins/default/images/pagenav.gif
new file mode 100644 (file)
index 0000000..92a73a4
Binary files /dev/null and b/skins/default/images/pagenav.gif differ
diff --git a/skins/default/images/roundcube_logo.gif b/skins/default/images/roundcube_logo.gif
deleted file mode 100644 (file)
index b77fd3d..0000000
Binary files a/skins/default/images/roundcube_logo.gif and /dev/null differ
index 847d011227c32ac3ff5be767c58615b9ec164cf7..1a4783e6eba527e140cffc0d650c9437f11e7e1b 100644 (file)
Binary files a/skins/default/images/roundcube_logo.png and b/skins/default/images/roundcube_logo.png differ
diff --git a/skins/default/images/roundcube_logo_print.gif b/skins/default/images/roundcube_logo_print.gif
deleted file mode 100644 (file)
index 8fbf6a8..0000000
Binary files a/skins/default/images/roundcube_logo_print.gif and /dev/null differ
index b1dc9389ee863978757c6bbdbb0f2ea11557abd0..756a17e47b89e3021ba12b76414d0ead368ff3f7 100644 (file)
Binary files a/skins/default/images/searchfield.gif and b/skins/default/images/searchfield.gif differ
diff --git a/skins/default/images/sort_asc.gif b/skins/default/images/sort_asc.gif
deleted file mode 100644 (file)
index 244db10..0000000
Binary files a/skins/default/images/sort_asc.gif and /dev/null differ
diff --git a/skins/default/images/sort_desc.gif b/skins/default/images/sort_desc.gif
deleted file mode 100644 (file)
index 2427311..0000000
Binary files a/skins/default/images/sort_desc.gif and /dev/null differ
diff --git a/skins/default/images/tab_act.gif b/skins/default/images/tab_act.gif
deleted file mode 100644 (file)
index 9329db1..0000000
Binary files a/skins/default/images/tab_act.gif and /dev/null differ
diff --git a/skins/default/images/tab_pas.gif b/skins/default/images/tab_pas.gif
deleted file mode 100644 (file)
index 26adabf..0000000
Binary files a/skins/default/images/tab_pas.gif and /dev/null differ
diff --git a/skins/default/images/tabs.gif b/skins/default/images/tabs.gif
new file mode 100644 (file)
index 0000000..1448227
Binary files /dev/null and b/skins/default/images/tabs.gif differ
diff --git a/skins/default/images/taskicons.gif b/skins/default/images/taskicons.gif
new file mode 100644 (file)
index 0000000..53376c3
Binary files /dev/null and b/skins/default/images/taskicons.gif differ
diff --git a/skins/default/images/taskicons.png b/skins/default/images/taskicons.png
new file mode 100644 (file)
index 0000000..a6ee706
Binary files /dev/null and b/skins/default/images/taskicons.png differ
index 30aeb4c19d4ccda6d2d020d061a66edd5e84a58c..e2d176e2223801125e1f740e1f4f47a60e70feb1 100644 (file)
@@ -1,3 +1,11 @@
 <link rel="index" href="$__comm_path" />
 <link rel="shortcut icon" href="/images/favicon.ico"/>
-<link rel="stylesheet" type="text/css" href="/common.css" />
\ No newline at end of file
+<link rel="stylesheet" type="text/css" href="/common.css" />
+<roundcube:if condition="env:task != 'login'" /><link rel="stylesheet" type="text/css" href="/<roundcube:exp expression="env:task=='addressbook'?'addresses':env:task" />.css" /><roundcube:endif />
+<roundcube:if condition="browser:ie" />
+<!--[if lte IE 8]><link rel="stylesheet" type="text/css" href="/iehacks.css" /><![endif]-->
+<!--[if lte IE 6]><link rel="stylesheet" type="text/css" href="/ie6hacks.css" /><![endif]-->
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/safari.css" />
+<roundcube:endif />
\ No newline at end of file
diff --git a/skins/default/includes/messagemenu.html b/skins/default/includes/messagemenu.html
new file mode 100644 (file)
index 0000000..ad2a6c6
--- /dev/null
@@ -0,0 +1,10 @@
+<div id="messagemenu">
+  <ul class="toolbarmenu">
+    <li><roundcube:button class="printlink" command="print" label="printmessage" classAct="printlink active" /></li>
+    <li><roundcube:button class="downloadlink" command="download" label="emlsave" classAct="downloadlink active" /></li>
+    <li><roundcube:button class="editlink" command="edit" label="editasnew" classAct="editlink active" /></li>
+    <li class="separator_below"><roundcube:button class="sourcelink" command="viewsource" label="viewsource" classAct="sourcelink active" /></li>
+    <li><roundcube:button class="openlink" command="open" label="openinextwin" target="_blank" classAct="openlink active" /></li>
+    <roundcube:container name="messagemenu" id="messagemenu" />
+  </ul>
+</div>
index 5121ba19b3c356a74708ccdcd9357b5e9fd78817..ce6d234075989300c8b6df910ece40b72c2490a6 100644 (file)
@@ -2,4 +2,6 @@
 <span id="settingstabdefault" class="tablink"><roundcube:button command="preferences" type="link" label="preferences" title="editpreferences" /></span>
 <span id="settingstabfolders" class="tablink"><roundcube:button command="folders" type="link" label="folders" title="managefolders" class="tablink" /></span>
 <span id="settingstabidentities" class="tablink"><roundcube:button command="identities" type="link" label="identities" title="manageidentities" class="tablink" /></span>
+<roundcube:container name="tabs" id="tabsbar" />
+<script type="text/javascript"> if (window.rcmail) rcmail.add_onload(rcube_init_settings_tabs); </script>
 </div>
index ef1aa826801a90f40075d327b6f16a8cf747db48..3510d206baf3ca7c1d71d8fcd8aacf7548a9498f 100644 (file)
@@ -2,5 +2,6 @@
 <roundcube:button command="mail" label="mail" class="button-mail" />
 <roundcube:button command="addressbook" label="addressbook" class="button-addressbook" />
 <roundcube:button command="settings" label="settings" class="button-settings" />
+<roundcube:container name="taskbar" id="taskbar" />
 <roundcube:button command="logout" label="logout" class="button-logout" />
 </div>
\ No newline at end of file
index 5a4e57bfee5d1f2a29ab509b6081228b1c60567d..48e48efd86156a5d493a07e7fdc0f5c2f31adaf8 100644 (file)
 {
   position: absolute;
   top: 47px;
-  left: 200px;
-  right: 200px;
+  left: 205px;
+  right: 10px;
   height: 35px;
+  min-width: 650px;
   white-space: nowrap;
 /*  border: 1px solid #cccccc; */
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-400)+'px');
 }
 
-#messagetoolbar a
+#messagetoolbar a
 {
+  display: block;
+  float: left;
   padding-right: 10px;
 }
 
-#messagetoolbar select
+#messagetoolbar a.button,
+#messagetoolbar a.buttonPas {
+  display: block;
+  float: left;
+  width: 32px;
+  height: 32px;
+  padding: 0;
+  margin-right: 10px;
+  overflow: hidden;
+  background: url('images/mail_toolbar.png') 0 0 no-repeat transparent;
+  opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
+}
+
+#messagetoolbar a.buttonPas {
+  opacity: 0.35;
+}
+
+#messagetoolbar a.checkmailSel {
+  background-position: 0 -32px;
+}
+
+#messagetoolbar a.back {
+  background-position: -32px 0;
+}
+
+#messagetoolbar a.backSel {
+  background-position: -32px -32px;
+}
+
+#messagetoolbar a.compose {
+  background-position: -64px 0;
+}
+
+#messagetoolbar a.composeSel {
+  background-position: -64px -32px;
+}
+
+#messagetoolbar a.reply {
+  background-position: -96px 0;
+}
+
+#messagetoolbar a.replySel {
+  background-position: -96px -32px;
+}
+
+#messagetoolbar a.replyAll {
+  background-position: -128px 0;
+}
+
+#messagetoolbar a.replyAllSel {
+  background-position: -128px -32px;
+}
+
+#messagetoolbar a.forward {
+  background-position: -160px 0;
+}
+
+#messagetoolbar a.forwardSel {
+  background-position: -160px -32px;
+}
+
+#messagetoolbar a.delete {
+  background-position: -192px 0;
+}
+
+#messagetoolbar a.deleteSel {
+  background-position: -192px -32px;
+}
+
+#messagetoolbar a.markmessage {
+  background-position: -256px 0;
+}
+
+#messagetoolbar a.messagemenu {
+  width: 36px;
+  background-position: -288px 0;
+}
+
+#messagetoolbar a.spellcheck {
+  background-position: -386px 0;
+}
+
+#messagetoolbar a.spellcheckSel {
+  background-position: -386px -32px;
+}
+
+#messagetoolbar a.attach {
+  background-position: -354px 0;
+}
+
+#messagetoolbar a.attachSel {
+  background-position: -354px -32px;
+}
+
+#messagetoolbar a.savedraft {
+  background-position: -322px 0;
+}
+
+#messagetoolbar a.savedraftSel {
+  background-position: -322px -32px;
+}
+
+#messagetoolbar a.send {
+  background-position: -418px 0;
+}
+
+#messagetoolbar a.sendSel {
+  background-position: -418px -32px;
+}
+
+
+#messagetoolbar select,
+#compose-container select
 {
   font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
   font-size: 11px;
   color: #333333;
+  height: 21px;
 }
 
 #messagetoolbar select.mboxlist
 {
-  position: absolute;
-  left: 375px;
-  top: 8px;
+  position: relative;
+  margin: 0 8px;
+  top: 6px;
 }
 
 #messagetoolbar select.mboxlist option
   padding-left: 2px;
 }
 
-#markmessagemenu
+#markmessagemenu,
+#searchmenu,
+#messagemenu
 {
   position: absolute;
   top: 32px;
   left: 90px;
   width: auto;
-  visibility: hidden;
+  display: none;
   background-color: #F9F9F9;
   border: 1px solid #CCC;
   padding: 1px;
   opacity: 0.9;
-  filter:alpha(opacity=90);
   z-index: 240;
 }
 
+#searchmenu
+{
+  width: 172px;
+}
+
 ul.toolbarmenu
 {
   margin: 0;
@@ -70,29 +190,121 @@ ul.toolbarmenu li
   font-size: 11px;
   white-space: nowrap;
   min-width: 130px;
-  width: auto !important;
-  width: 130px;
 }
 
 ul.toolbarmenu li a
 {
   display: block;
   color: #a0a0a0;
-  padding: 2px 8px 3px 12px;
+  padding: 2px 8px 3px 22px;
   text-decoration: none;
+  min-height: 14px;
+}
+
+ul.toolbarmenu li a.active,
+ul.toolbarmenu li a.active:active,
+ul.toolbarmenu li a.active:visited
+{
+  color: #333;
+}
+
+ul.toolbarmenu li input
+{
+  vertical-align: middle;
+}
+
+ul.toolbarmenu li hr
+{
+  color: #ccc;
+  width: 130px;
+  height: 1px;
+  margin: 2px 1px 2px 1px;
+}
+
+ul.toolbarmenu li img
+{
+  float: left;
+  margin: 0 2px;
+}
+
+ul.toolbarmenu li.separator_below
+{
+  border-bottom: 1px solid #ccc;
+  margin-bottom: 2px;
+  padding-bottom: 2px;
+}
+
+ul.toolbarmenu li.separator_above
+{
+  border-top: 1px solid #ccc;
+  margin-top: 2px;
+  padding-top: 2px;
+}
+
+#messagemenu li a.active:hover,
+#markmessagemenu li a.active:hover
+{
+  color: #fff;
+  background-color: #c00;
+}
+
+#messagemenu li a
+{
+  background: url('images/messageactions.png') no-repeat 1px 0;
+  background-position: 0px 20px;
+}
+
+#messagemenu li a.printlink
+{
+  background-position: 1px 1px;
+}
+
+#messagemenu li a.downloadlink
+{
+  background-position: 1px -17px;
+}
+
+#messagemenu li a.sourcelink
+{
+  background-position: 1px -35px;
+}
+
+#messagemenu li a.openlink
+{
+  background-position: 1px -53px;
+}
+
+#messagemenu li a.editlink
+{
+  background-position: 1px -71px;
+}
+
+#markmessagemenu a.readlink
+{
+  background: url('images/icons/dot.png') no-repeat 2px;
+}
+
+#markmessagemenu a.unreadlink
+{
+  background: url('images/icons/unread.png') no-repeat 2px;
+}
+
+#markmessagemenu a.flaggedlink
+{
+  background: url('images/icons/flagged.png') no-repeat 2px;
 }
 
-ul.toolbarmenu li a.active:hover
+#markmessagemenu a.unflaggedlink
 {
-  background-color: #ddd;
+  background: url('images/icons/unflagged.png') no-repeat 2px;
 }
 
 #searchfilter
 {
+  white-space: nowrap;
   position: absolute;
-  right: 18px;
-  top: 8px;
-  text-align: right;
+  right: 190px;
+  vertical-align: middle;
 }
 
 #searchfilter label
@@ -120,9 +332,6 @@ td.formlinks a:visited
 #mailboxcontrols a.active,
 #mailboxcontrols a.active:active,
 #mailboxcontrols a.active:visited,
-ul.toolbarmenu li a.active,
-ul.toolbarmenu li a.active:active,
-ul.toolbarmenu li a.active:visited,
 td.formlinks a,
 td.formlinks a:visited
 {
@@ -135,8 +344,7 @@ td.formlinks a:visited
   text-decoration: underline;
 }
 
-#listcontrols,
-#mailboxcontrols
+#listcontrols
 {
   padding-right: 2em;
 }
@@ -144,10 +352,10 @@ td.formlinks a:visited
 #messagecountbar
 {
   position: absolute;
-  bottom: 16px;
-  right: 20px;
+  bottom: 0px;
+  right: 0px;
   width: 300px;
-  height: 20px;
+  height: 16px;
   text-align: right;
   white-space: nowrap;
 }
@@ -158,16 +366,22 @@ td.formlinks a:visited
   color: #333333;
 }
 
-#mainscreen 
+#mainscreen
 {
   position: absolute;
   top: 85px;
   right: 20px;
-  bottom: 40px;
+  bottom: 16px;
   left: 20px;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
-  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');
+}
+
+#mailleftcontainer
+{
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  bottom: 0px;
+  width: 195px;
 }
 
 #mailrightcontainer
@@ -177,11 +391,17 @@ td.formlinks a:visited
   left: 170px;
   bottom: 0px;
   right: 0px;
-  /* css hack for IE */
-  width: expression((parseInt(this.parentNode.offsetWidth)-170)+'px');
-  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
 }
-         
+
+#mailrightcontent
+{
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  bottom: 20px;
+}
+
 #messagepartcontainer
 {
   position: absolute;
@@ -189,9 +409,6 @@ td.formlinks a:visited
   left: 20px;
   right: 20px;
   bottom: 20px;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
-  height: expression((parseInt(document.documentElement.clientHeight)-100)+'px');
 }
 
 #mailcontframe
@@ -203,8 +420,8 @@ td.formlinks a:visited
   border: 1px solid #999999;
   background-color: #F9F9F9;
   overflow: auto;
-  /* css hack for IE */
-  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+  overflow-y: auto;
+  overflow-x: hidden;
 }
 
 #mailpreviewframe
@@ -215,8 +432,6 @@ td.formlinks a:visited
   bottom: 0px;
   border: 1px solid #999999;
   background-color: #F9F9F9;
-  /* css hack for IE */
-  height: expression((parseInt(this.parentNode.offsetHeight)-205)+'px');
 }
 
 #messagecontframe
@@ -246,8 +461,6 @@ td.formlinks a:visited
   left: 220px;
   right: 20px;
   height: 40px;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-240)+'px');
 }
 
 #partheader table td
@@ -273,8 +486,7 @@ td.formlinks a:visited
   height: 12px;
   margin: 0;
   padding: 3px 10px 4px 10px;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif); 
+  background: url('images/listheader.gif') top left repeat-x #CCC;
   border-bottom: 1px solid #999;
   color: #333333;
   font-size: 11px;
@@ -286,13 +498,11 @@ td.formlinks a:visited
   position: absolute;
   top: 0px;
   left: 0px;
-  width: 160px;
-  bottom: 0px;
+  width: 100%;
+  bottom: 20px;
   border: 1px solid #999;
   background-color: #F9F9F9;
   overflow: auto;
-  /* css hack for IE */
-  height: expression(parseInt(this.parentNode.offsetHeight)+'px');
 }
 
 #mailboxlist
@@ -312,8 +522,7 @@ td.formlinks a:visited
   display: block;
   position: relative;
   font-size: 11px;
-  background: url(images/icons/folder-closed.png) no-repeat;
-  background-position: 5px 1px;
+  background: url('images/icons/folders.png') 5px 1px no-repeat;
   border-bottom: 1px solid #EBEBEB;
 }
 
@@ -335,37 +544,37 @@ td.formlinks a:visited
 
 #mailboxlist li div.collapsed
 {
-  background: url(images/icons/collapsed.png) bottom right no-repeat;
+  background: url('images/icons/collapsed.png') bottom right no-repeat;
 }
 
 #mailboxlist li div.expanded
 {
-  background: url(images/icons/expanded.png) bottom right no-repeat;
+  background: url('images/icons/expanded.png') bottom right no-repeat;
 }
 
 #mailboxlist li.inbox
 {
-  background-image: url(images/icons/folder-inbox.png);
+  background-position: 5px -19px;
 }
 
 #mailboxlist li.drafts
 {
-  background-image: url(images/icons/folder-drafts.png);
+  background-position: 5px -40px;
 }
 
 #mailboxlist li.sent
 {
-  background-image: url(images/icons/folder-sent.png);
+  background-position: 5px -60px;
 }
 
 #mailboxlist li.junk
 {
-  background-image: url(images/icons/folder-junk.png);
+  background-position: 5px -80px;
 }
 
 #mailboxlist li.trash
 {
-  background-image: url(images/icons/folder-trash.png);
+  background-position: 5px -100px;
 }
 
 #mailboxlist li a
@@ -420,16 +629,13 @@ td.formlinks a:visited
   font-weight: normal;
 }
 
-
 #mailfooter
 {
   position: absolute;
-  left: 20px;
-  right: 20px;
-  bottom: 18px;
-  height: 20px;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
+  left: 0px;
+  bottom: 0px;
+  height: 16px;
+  width: 100%;
 }
 
 #mailfooter table tr td
@@ -438,7 +644,16 @@ td.formlinks a:visited
   vertical-align: bottom;
 }
 
-#mailboxcontrols,
+#mailboxcontrols
+{
+  position: absolute;
+  left: 0px;
+  bottom: 0px;
+  height: 16px;
+  width: auto;
+  font-size: 11px;
+}
+
 #listcontrols,
 #countcontrols,
 #quotabox
@@ -447,6 +662,19 @@ td.formlinks a:visited
   font-size: 11px;
 }
 
+#countcontrols
+{
+  min-width: 25em;
+}
+
+#countcontrols a.button,
+#countcontrols a.buttonPas,
+#messagecountbar a.button,
+#messagecountbar a.buttonPas
+{
+  float: right;
+}
+
 
 /** message list styles */
 
@@ -461,13 +689,11 @@ body.messagelist
   width: 100%;
   display: table;
   table-layout: fixed;
-  /* css hack for IE */
-  width: expression('auto');
 }
 
 #messagelist thead tr td
 {
-  height: 20px;
+  height: 19px;
   padding-top: 0px;
   padding-bottom: 0px;
   padding-left: 2px;
@@ -475,8 +701,7 @@ body.messagelist
   vertical-align: middle;
   border-bottom: 1px solid #999999;
   color: #333333;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif); 
+  background: url('images/listheader.gif') top left repeat-x #CCC;
   font-size: 11px;
   font-weight: bold;
 }
@@ -484,17 +709,17 @@ body.messagelist
 #messagelist thead tr td.sortedASC,
 #messagelist thead tr td.sortedDESC
 {
-  background-image: url(images/listheader_dark.gif); 
+  background-position: 0 -20px;
 }
 
 #messagelist thead tr td.sortedASC a
 {
-  background: url(images/sort_asc.gif) top right no-repeat;
+  background: url('images/icons/sort.gif') right 0 no-repeat;
 }
 
 #messagelist thead tr td.sortedDESC a
 {
-  background: url(images/sort_desc.gif) top right no-repeat;
+  background: url('images/icons/sort.gif') right -14px no-repeat;
 }
 
 #messagelist thead tr td a
@@ -515,6 +740,7 @@ body.messagelist
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
   border-bottom: 1px solid #EBEBEB;
   cursor: default;
 }
@@ -539,10 +765,18 @@ body.messagelist
   vertical-align: middle;
 }
 
-#messagelist tr td.icon,
-#messagelist tr td.flag
+#messagelist thead tr td.icon,
+#messagelist thead tr td.flag
+{
+  width: 22px;
+  padding: 0;
+  text-align: center;
+}
+
+#messagelist tbody tr td.icon,
+#messagelist tbody tr td.flag
 {
-  width: 16px;
+  padding: 2px 3px 2px 3px;
   vertical-align: middle;
   cursor: pointer;
 }
@@ -557,6 +791,7 @@ body.messagelist
 {
   overflow: hidden;
   vertical-align: middle;
+  width: 99%;
 }
 
 #messagelist tr td.size
@@ -636,13 +871,6 @@ body.messagelist
   color: #CCCCCC;
 }
 
-/* safari hacks \*/
-html>body*#messagelist[id$="messagelist"]:not([class="none"]) { width: 99.8%; }
-html>body*#messagelist[id$="messagelist"]:not([class="none"]) tr td.flag,
-html>body*#messagelist[id$="messagelist"]:not([class="none"]) tr td.icon { width: 20px; }
-html>body*input[type$="file"]:not([class="none"]) { background-color: transparent; border: 0; }
-/**/
-
 #quotadisplay
 {
   color: #666666;
@@ -663,21 +891,13 @@ html>body*input[type$="file"]:not([class="none"]) { background-color: transparen
 {
   position: absolute;
   top: 0px;
-  left: 170px;
+  left: 180px;
   right: 0px;
-  bottom: 0px;
+  bottom: 20px;
   border: 1px solid #999;
   background-color: #FFF;
   overflow: auto;
-  /* css hack for IE */
-  width: expression((parseInt(this.parentNode.offsetWidth)-170)+'px');
-  height: expression((parseInt(this.parentNode.offsetHeight))+'px');
-}
-
-#messagecanvas 
-{
-  /* css hack for IE */
-  width: expression((parseInt(this.parentNode.offsetWidth)-20)+'px');
+  z-index: 1;
 }
 
 #printmessageframe
@@ -690,9 +910,6 @@ html>body*input[type$="file"]:not([class="none"]) { background-color: transparen
   border: 1px solid #999;
   background-color: #FFF;
   overflow: auto;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-220)+'px');
-  height: expression((parseInt(document.documentElement.clientHeight)-125)+'px');
 }
 
 div.messageheaderbox
@@ -749,8 +966,17 @@ table.headers-table tr td.all
   color: #666666;
   text-align: left;
   padding-right: 10px;
-  vertical-align: center;
   text-align: center;
+  padding: 2px 6px 4px 6px;
+  border-bottom: 0;
+}
+
+table.headers-table tr td.more-headers
+{
+  cursor: pointer;
+  width: 100%;
+  height: 8px;
+  border-bottom: 0;
 }
 
 #attachment-list
@@ -761,8 +987,6 @@ table.headers-table tr td.all
   list-style-image: none;
   list-style-type: none;
   background: url(images/icons/attachment.png) 60px 2px no-repeat #DFDFDF;
-  /* IE6 hack */    
-  _height: expression(Math.min(16, parseInt(document.documentElement.clientHeight))+'px');
 }
 
 #attachment-list:after
@@ -827,10 +1051,13 @@ div.message-part div.pre
   padding: 0px;
   font-family: monospace;
   white-space: -moz-pre-wrap !important;
-  white-space: -o-pre-wrap !important;
   white-space: pre-wrap !important;
   white-space: pre;
-  word-wrap: break-word; /* IE (and Safari) */
+}
+
+div.message-part span.sig
+{
+  color: #666666;
 }
 
 div.message-part blockquote
@@ -857,12 +1084,6 @@ div.message-part blockquote blockquote blockquote
   border-right: 2px solid #bb0000;
 }
 
-body.iframe 
-{
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth))+'px');
-}
-
 body.iframe div.message-htmlpart
 {
   margin: 8px;
@@ -913,28 +1134,38 @@ div.message-htmlpart div.rcmBody
 #receipt-selector
 {
   padding-left: 30px;
+  white-space: nowrap;
 }
 
 #compose-container
 {
   position: absolute;
   top: 90px;
-  left: 190px;
+  left: 205px;
   right: 25px;
   bottom: 30px;
   margin: 0px;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-210)+'px');
-  height: expression((parseInt(document.documentElement.clientHeight)-120)+'px');
+}
+
+#spellcheck-control
+{
+  text-align: right;
+  padding-top: 3px;
+}
+
+#editor-select
+{
+  float: left;
 }
 
 #compose-div
 {
   position: absolute;
-  top: 110px;
-  bottom: 40px;
+  top: 130px;
+  bottom: 30px;
   width: 100%;
   vertical-align: top;
+  padding-top: 2px;
 }
 
 #compose-headers
@@ -963,7 +1194,6 @@ div.message-htmlpart div.rcmBody
 #compose-headers td input
 {
   width: 100%;
-  width: expression('99%');
 }
 
 #compose-headers td textarea
@@ -991,7 +1221,7 @@ div.message-htmlpart div.rcmBody
   position: absolute;
   top: 100px;
   left: 20px;
-  width: 160px;
+  width: 170px;
 }
 
 #compose-attachments ul
@@ -1016,6 +1246,12 @@ div.message-htmlpart div.rcmBody
   overflow: hidden;
 }
 
+#compose-attachments ul li img
+{
+  padding-right: 2px;
+  vertical-align: middle;
+}
+
 #attachment-title
 {
   background: url(images/icons/attachment.png) top left no-repeat;
@@ -1044,20 +1280,6 @@ div.message-htmlpart div.rcmBody
   margin-top: 4px;
 }
 
-table.headers-table tr td.more-headers
-{
-  cursor: pointer;
-  width: 100%;
-  height: 8px;
-  border-bottom: 0;
-}
-
-table.headers-table tr td.all
-{
-  padding: 2px 6px 4px 6px;
-  border-bottom: 0;
-}
-
 td.show-headers
 {
   background: url(images/icons/down_small.gif) no-repeat center;
index 441a5de91574eafa7f50d48df960cbaa7812b812..5522a05c9de32d379b8f1c00f9f60e0a3aafdb13 100644 (file)
@@ -27,8 +27,8 @@ a, a:active, a:visited
 
 #header
 {
-  margin-left: 5mm;
-  margin-bottom: 3mm;
+  float: right;
+  margin: 0 5mm 3mm 5mm;
 }
 
 #messageframe
@@ -39,6 +39,7 @@ a, a:active, a:visited
 table.headers-table
 {
   table-layout: fixed;
+  margin-top: 14px;
 }
 
 table.headers-table tr td
@@ -110,7 +111,6 @@ div.message-part div.pre
   margin: 0;
   padding: 0;
   font-family: monospace;
-  white-space: -o-pre-wrap !important;
   white-space: -moz-pre-wrap !important;
   white-space: pre-wrap !important;
   white-space: pre;
diff --git a/skins/default/safari.css b/skins/default/safari.css
new file mode 100644 (file)
index 0000000..942cf25
--- /dev/null
@@ -0,0 +1,16 @@
+body
+{
+  height: 100%;
+}
+
+html>body*#messagelist[id$="messagelist"]:not([class="none"]) { width: 99.8%; }
+html>body*#messagelist[id$="messagelist"]:not([class="none"]) tr td.flag,
+html>body*#messagelist[id$="messagelist"]:not([class="none"]) tr td.icon { width: 20px; }
+html>body*input[type$="file"]:not([class="none"]) { background-color: transparent; border: 0; }
+
+div.message-part pre,
+div.message-htmlpart pre,
+div.message-part div.pre
+{
+  word-wrap: break-word;
+}
index 6c984ab672fe2df3ccbc016eaa40b5e5c347947a..74388a4b6504048a7222d421b79054182cb13071 100644 (file)
@@ -10,8 +10,6 @@
   height: 22px;
   border-bottom: 1px solid #999999;
   white-space: nowrap;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-240)+'px');
 }
 
 span.tablink,
@@ -21,12 +19,14 @@ span.tablink-selected
   width: 100px;
   height: 24px !important;
   height: 22px;
-  background: url('images/tab_pas.gif') top left no-repeat;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  background: url('images/tabs.gif') top left no-repeat;
 }
 
 span.tablink-selected
 {
-  background: url('images/tab_act.gif') top left no-repeat;
+  background-position: -102px 0;
 }
 
 span.tablink a,
@@ -44,41 +44,6 @@ span.tablink-selected a
   color: #000000;
 }
 
-#userprefs-box
-{
-  position: absolute;
-  top: 95px;
-  left: 20px;
-  bottom: 60px;
-  right: 20px;
-  overflow: auto;
-  border: 1px solid #999999;
-  /* css hack for IE */
-  height: expression((parseInt(document.documentElement.clientHeight)-155)+'px');
-  width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
-}
-
-#userprefs-box table td.title
-{
-  color: #666666;
-  padding-right: 10px;
-  white-space: nowrap;
-}
-
-#userprefs-box table tr.advanced
-{
-  display: none;
-}
-
-.userprefs-block
-{
-  float: left;
-  margin-right: 14px;
-  min-width: 520px;
-  /* css hack for IE */
-  width: expression(Math.min(520, parseInt(document.documentElement.clientWidth))+'px');
-}
-
 #rcmfd_timezone
 {
   width: 300px;
@@ -99,8 +64,6 @@ span.tablink-selected a
   bottom: 140px;
   overflow: auto;
   border: 1px solid #999999;
-  /* css hack for IE */
-  height: expression((parseInt(document.documentElement.clientHeight)-235)+'px');
 }
 
 #folder-manager.droptarget
@@ -114,8 +77,6 @@ span.tablink-selected a
   bottom: 60px;
   width: 420px;
   border: 1px solid #999999;
-  /* css hack for IE */
-  height: expression((parseInt(document.documentElement.clientHeight)-155)+'px');
 }
 
 #listbuttons
@@ -135,8 +96,11 @@ span.tablink-selected a
 #subscription-table
 {
   width: 100%;
-  /* css hack for IE */
-  width: expression('auto');
+}
+
+#subscription-table input
+{
+  font: inherit;
 }
 
 #subscription-table tbody td,
@@ -157,6 +121,12 @@ span.tablink-selected a
   width: 45%;
 }
 
+#subscription-table tbody td
+{
+  height: 22px !important;
+  height: 18px;
+}
+
 #subscription-table tr.virtual td
 {
   color: #666;
@@ -190,12 +160,25 @@ span.tablink-selected a
   width: 90px;
 }
 
+#subscription-table tbody td.subscribed,
+#subscription-table tbody td.rename,
+#subscription-table tbody td.delete
+{
+  padding: 1px 4px;
+}
+
 #subscription-table thead td.rename,
 #subscription-table thead td.delete
 {
   width: 30px;
 }
 
+#subscription-table td.name input
+{
+  font: inherit;
+  width: 240px;
+}
+
 #identity-frame
 {
   position: relative;
@@ -212,9 +195,6 @@ span.tablink-selected a
   bottom: 60px;
   border: 1px solid #999999;
   overflow: auto;
-  /* css hack for IE */
-  width: expression((parseInt(document.documentElement.clientWidth)-470)+'px');
-  height: expression((parseInt(document.documentElement.clientHeight)-155)+'px');
 }
 
 #identity-details table td.title
@@ -239,18 +219,17 @@ input.disabled
   bottom: 20px;
 }
 
-#userprefs-title,
 #identity-title,
+#prefs-title,
 div.boxtitle
 {
   height: 12px !important;
-  padding: 4px 20px 3px 6px;
+  padding: 2px 10px 5px 10px;
   border-bottom: 1px solid #999999;
   color: #333333;
   font-size: 11px;
   font-weight: bold;
-  background-color: #EBEBEB;
-  background-image: url(images/listheader_aqua.gif); 
+  background: url('images/listheader.gif') top left repeat-x #CCC;
 }
 
 div.settingsbox
@@ -278,12 +257,81 @@ legend
   color: #999999;
 }
 
-div.advswitch
+#prefsscreen
 {
-  white-space: nowrap;
-  text-align: right;
   position: absolute;
-  bottom: 35px;
+  top: 95px;
   right: 20px;
-  width: 460px;
+  bottom: 30px;
+  left: 20px;
+}
+
+#sectionslist
+{
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  bottom: 0px;
+  border: 1px solid #999999;
+  background-color: #F9F9F9;
+  overflow: auto;
+}
+
+#sections-table
+{
+  width: 100%;
+  table-layout: fixed;
+}
+
+#sections-table tbody td
+{
+  cursor: default;
+}
+
+#prefs-box
+{
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  bottom: 0px;
+  border: 1px solid #999999;
+  overflow: hidden;
+}
+
+body.iframe,
+#prefs-frame
+{
+  background-color: #F9F9F9;
+  border: none;
+}
+
+#prefs-details
+{
+  margin: 15px;
+}
+
+#prefs-details table td.title
+{
+  color: #666;
+  padding-right: 10px;
+}
+
+#formfooter
+{
+  width: 100%;
+}
+
+#formfooter .footerleft
+{
+  padding-left: 20px;
+  white-space: nowrap;
+  float: left;
+}
+
+#formfooter .footerright
+{
+  padding-right: 20px;
+  white-space: nowrap;
+  text-align: right;
+  float: right;
 }
index 3ed0eb62a4edc4331f1f139d18ab6fb5469636c5..83506eecb1290789be1fa283e3dfba9b359ce5b1 100644 (file)
@@ -22,18 +22,18 @@ function rcube_splitter(attrib)
     this.p2 = document.getElementById(this.p2id);
 
     // create and position the handle for this splitter
-    this.p1pos = rcube_get_object_pos(this.p1, this.relative);
-    this.p2pos = rcube_get_object_pos(this.p2, this.relative);
+    this.p1pos = this.relative ? $(this.p1).position() : $(this.p1).offset();
+    this.p2pos = this.relative ? $(this.p2).position() : $(this.p2).offset();
     
     if (this.horizontal)
       {
-      var top = this.p1pos.y + this.p1.offsetHeight;
+      var top = this.p1pos.top + this.p1.offsetHeight;
       this.layer = new rcube_layer(this.id, {x: 0, y: top, height: 10, 
            width: '100%', vis: 1, parent: this.p1.parentNode});
       }
     else
       {
-      var left = this.p1pos.x + this.p1.offsetWidth;
+      var left = this.p1pos.left + this.p1.offsetWidth;
       this.layer = new rcube_layer(this.id, {x: left, y: 0, width: 10, 
            height: '100%', vis: 1,  parent: this.p1.parentNode});
       }
@@ -70,18 +70,18 @@ function rcube_splitter(attrib)
     if (this.horizontal)
       {
       var lh = this.layer.height - this.offset * 2;
-      this.p1.style.height = Math.floor(this.pos - this.p1pos.y - lh / 2) + 'px';
+      this.p1.style.height = Math.floor(this.pos - this.p1pos.top - lh / 2) + 'px';
       this.p2.style.top = Math.ceil(this.pos + lh / 2) + 'px';
-      this.layer.move(this.layer.x, Math.round(this.pos - lh / 2 + 1));             
+      this.layer.move(this.layer.x, Math.round(this.pos - lh / 2 + 1));
       if (bw.ie)
-       {
+        {
         var new_height = (parseInt(this.p2.parentNode.offsetHeight) - parseInt(this.p2.style.top));
         this.p2.style.height = (new_height > 0 ? new_height : 0) +'px';
         }
       }
     else
       {
-      this.p1.style.width = Math.floor(this.pos - this.p1pos.x - this.layer.width / 2) + 'px';
+      this.p1.style.width = Math.floor(this.pos - this.p1pos.left - this.layer.width / 2) + 'px';
       this.p2.style.left = Math.ceil(this.pos + this.layer.width / 2) + 'px';
       this.layer.move(Math.round(this.pos - this.layer.width / 2 + 1), this.layer.y);
       if (bw.ie)
@@ -94,16 +94,20 @@ function rcube_splitter(attrib)
    */
   this.onDragStart = function(e)
     {
-    this.p1pos = rcube_get_object_pos(this.p1, this.relative);
-    this.p2pos = rcube_get_object_pos(this.p2, this.relative);
+    // disable text selection while dragging the splitter
+    if (window.webkit || bw.safari)
+      document.body.style.webkitUserSelect = 'none';
+
+    this.p1pos = this.relative ? $(this.p1).position() : $(this.p1).offset();
+    this.p2pos = this.relative ? $(this.p2).position() : $(this.p2).offset();
     this.drag_active = true;
-    
+
     // start listening to mousemove events
     rcube_event.add_listener({element:document, event:'mousemove', object:this, method:'onDrag'});
     rcube_event.add_listener({element:document, event:'mouseup', object:this, method:'onDragStop'});
 
     // need to listen in any iframe documents too, b/c otherwise the splitter stops moving when we move over an iframe
-    var iframes = document.getElementsByTagName('IFRAME');
+    var iframes = document.getElementsByTagName('iframe');
     this.iframe_events = Object();
     for (var n in iframes)
       {
@@ -119,8 +123,8 @@ function rcube_splitter(attrib)
         // I don't use the add_listener function for this one because I need to create closures to fetch
         // the position of each iframe when the event is received
         var s = this;
-        var id = iframes[n].id;
-        this.iframe_events[n] = function(e){ e._offset = rcube_get_object_pos(document.getElementById(id)); return s.onDrag(e); }
+        var id = '#'+iframes[n].id;
+        this.iframe_events[n] = function(e){ e._offset = $(id).offset(); return s.onDrag(e); }
 
         if (iframedoc.addEventListener)
           iframedoc.addEventListener('mousemove', this.iframe_events[n], false);
@@ -145,14 +149,14 @@ function rcube_splitter(attrib)
 
     if (this.relative)
       {
-      var parent = rcube_get_object_pos(this.p1.parentNode);
-      pos.x -= parent.x;
-      pos.y -= parent.y;
+      var parent = $(this.p1.parentNode).offset();
+      pos.x -= parent.left;
+      pos.y -= parent.top;
       }
 
     if (this.horizontal)
       {
-      if (((pos.y - this.layer.height * 1.5) > this.p1pos.y) && ((pos.y + this.layer.height * 1.5) < (this.p2pos.y + this.p2.offsetHeight)))
+      if (((pos.y - this.layer.height * 1.5) > this.p1pos.top) && ((pos.y + this.layer.height * 1.5) < (this.p2pos.top + this.p2.offsetHeight)))
         {
         this.pos = pos.y;
         this.resize();
@@ -160,15 +164,15 @@ function rcube_splitter(attrib)
       }
     else
       {
-      if (((pos.x - this.layer.width * 1.5) > this.p1pos.x) && ((pos.x + this.layer.width * 1.5) < (this.p2pos.x + this.p2.offsetWidth)))
+      if (((pos.x - this.layer.width * 1.5) > this.p1pos.left) && ((pos.x + this.layer.width * 1.5) < (this.p2pos.left + this.p2.offsetWidth)))
         {
         this.pos = pos.x;
         this.resize();
         }
       }
 
-    this.p1pos = rcube_get_object_pos(this.p1, this.relative);
-    this.p2pos = rcube_get_object_pos(this.p2, this.relative);
+    this.p1pos = this.relative ? $(this.p1).position() : $(this.p1).offset();
+    this.p2pos = this.relative ? $(this.p2).position() : $(this.p2).offset();
     return false;
     };
 
@@ -177,12 +181,16 @@ function rcube_splitter(attrib)
    */
   this.onDragStop = function(e)
     {
+    // resume the ability to highlight text
+    if(window.webkit || bw.safari)
+      document.body.style.webkitUserSelect = 'auto';
+
     // cancel the listening for drag events
     rcube_event.remove_listener({element:document, event:'mousemove', object:this, method:'onDrag'});
     rcube_event.remove_listener({element:document, event:'mouseup', object:this, method:'onDragStop'});
     this.drag_active = false;
 
-    var iframes = document.getElementsByTagName('IFRAME');
+    var iframes = document.getElementsByTagName('iframe');
 
     for (var n in iframes)
       {
@@ -198,7 +206,7 @@ function rcube_splitter(attrib)
         if (this.iframe_events[n]) {
           if (iframedoc.removeEventListener)
             iframedoc.removeEventListener('mousemove', this.iframe_events[n], false);
-         else if (iframedoc.detachEvent)
+          else if (iframedoc.detachEvent)
             iframedoc.detachEvent('onmousemove', this.iframe_events[n]);
           else
             iframedoc['onmousemove'] = null;
index 38151c9e40d66c8b4fd0460480d56c9490aadd79..3b18ec5e742b600648efe1f36643dc1b8c27ed4d 100644 (file)
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/addresses.css" />
 </head>
 <body class="iframe">
 
index ce295567bdd23b71e5bb1a1c4e846a2948b6516b..b0325b5afec758e70119893d154e848451aec29f 100644 (file)
@@ -3,25 +3,22 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/addresses.css" />
 <script type="text/javascript" src="/splitter.js"></script>
 
 <style type="text/css">
-<roundcube:if condition="config:ldap_public == false" />
-#abookcountbar { left: 20px;}
-#mainscreen { left:20px; /* IE hack */ width:expression((parseInt(document.documentElement.clientWidth)-40)+'px') }
+<roundcube:if condition="count(env:address_sources) &lt;= 1" />
+#abookcountbar { left: 20px; }
+#addressscreen { left: 20px; 
+<roundcube:exp expression="browser:ie ? 'width:expression((parseInt(document.documentElement.clientWidth)-40)+\\'px\\');' : ''" />
+}
 #addresslist { width: <roundcube:exp expression="!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter-5 : 245" />px; }
-#contacts-box {
-    left: <roundcube:exp expression="!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter+5 : 255" />px;
-    /* IE hack */
-    width:expression((parseInt(mainscreen.offsetWidth)-<roundcube:exp expression="!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter+5 : 255" />)+'px')
+#contacts-box { left: <roundcube:exp expression="!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter+5 : 255" />px;
+<roundcube:exp expression="browser:ie ? ('width:expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter+5 : 255).')+\\'px\\');') : ''" />
 }
 <roundcube:else />
 #addresslist { width: <roundcube:exp expression="!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter-5 : 245" />px; }
-#contacts-box {
-    left: <roundcube:exp expression="!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter+5 : 255" />px;
-    /* IE hack */
-    width:expression((parseInt(mainscreen.offsetWidth)-<roundcube:exp expression="!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter+5 : 255" />)+'px')
+#contacts-box { left: <roundcube:exp expression="!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter+5 : 255" />px;
+<roundcube:exp expression="browser:ie ? ('width:expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:addressviewsplitter) ? cookie:addressviewsplitter+5 : 255).')+\\'px\\');') : ''" />
 }
 <roundcube:endif />
 </style>
 <roundcube:include file="/includes/header.html" />
 
 <div id="abooktoolbar">
-<roundcube:button command="add" imageSel="/images/buttons/add_contact_sel.png" imageAct="/images/buttons/add_contact_act.png" imagePas="/images/buttons/add_contact_pas.png" width="32" height="32" title="newcontact" />
-<roundcube:button command="delete" imageSel="/images/buttons/delete_sel.png" imageAct="/images/buttons/delete_act.png" imagePas="/images/buttons/delete_pas.png" width="32" height="32" title="deletecontact" />
-<roundcube:button command="compose" imageSel="/images/buttons/compose_sel.png" imageAct="/images/buttons/compose_act.png" imagePas="/images/buttons/compose_pas.png" width="32" height="32" title="composeto" />
-<roundcube:button command="import" imageSel="/images/buttons/adr_import_sel.png" imageAct="/images/buttons/adr_import_act.png" imagePas="/images/buttons/adr_import_pas.png" width="32" height="32" title="importcontacts" />
-<roundcube:button command="export" imageSel="/images/buttons/download_sel.png" imageAct="/images/buttons/download_act.png" imagePas="/images/buttons/download_pas.png" width="32" height="32" title="exportvcards" />
+<roundcube:button command="add" type="link" class="button addcontact" classAct="button addcontact" classSel="button addcontactSel" title="newcontact" content=" " />
+<roundcube:button command="compose" type="link" class="buttonPas compose" classAct="button compose" classSel="button composeSel" title="composeto" content=" " />
+<roundcube:button command="delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="deletecontact" content=" " />
+<span class="separator">&nbsp;</span>
+<roundcube:button command="import" type="link" class="buttonPas import" classAct="button import" classSel="button importSel" title="importcontacts" content=" " />
+<roundcube:button command="export" type="link" class="buttonPas export" classAct="button export" classSel="button exportSel" title="exportvcards" content=" " />
+<roundcube:container name="toolbar" id="abooktoolbar" />
 </div>
 
 <div id="quicksearchbar">
-<roundcube:object name="searchform" id="quicksearchbox" /><roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
+<roundcube:button name="searchmod" id="searchmod" image="/images/icons/glass.png" />
+<roundcube:object name="searchform" id="quicksearchbox" />
+<roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
 </div>
 
-<roundcube:if condition="config:ldap_public" />
+<roundcube:if condition="count(env:address_sources) &gt; 1" />
 <div id="directorylist">
 <div id="groups-title"><roundcube:label name="groups" /></div>
 <roundcube:object name="directorylist" id="directories-list" />
 </div>
 <roundcube:endif />
 
-<div id="mainscreen">
+<div id="addressscreen">
 
 <div id="addresslist">
 <roundcube:object name="addresslist" id="contacts-table" class="records-table" cellspacing="0" summary="Contacts list" />
 
 </div>
 
-<div id="abookcountbar">
-<roundcube:button command="firstpage" imageSel="/images/buttons/first_sel.png" imageAct="/images/buttons/first_act.png" imagePas="/images/buttons/first_pas.png" width="11" height="11" title="firstpage" />
-<roundcube:button command="previouspage" imageSel="/images/buttons/previous_sel.png" imageAct="/images/buttons/previous_act.png" imagePas="/images/buttons/previous_pas.png" width="11" height="11" title="previouspage" />
-&nbsp;<roundcube:object name="recordsCountDisplay" />&nbsp;
-<roundcube:button command="nextpage" imageSel="/images/buttons/next_sel.png" imageAct="/images/buttons/next_act.png" imagePas="/images/buttons/next_pas.png" width="11" height="11" title="nextpage" />
-<roundcube:button command="lastpage" imageSel="/images/buttons/last_sel.png" imageAct="/images/buttons/last_act.png" imagePas="/images/buttons/last_pas.png" width="11" height="11" title="lastpage" />
+<div id="abookcountbar" class="pagenav">
+  <roundcube:button command="firstpage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstpage" content=" " />
+  <roundcube:button command="previouspage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previouspage" content=" " />
+  <roundcube:object name="recordsCountDisplay" style="padding:0 1em; float:left" />
+  <roundcube:button command="nextpage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextpage" content=" " />
+  <roundcube:button command="lastpage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastpage" content=" " />
 </div>
 
 </body>
index 73e6575945da8438ba41d9d296bbd74ce2930fcb..7a5aa8dc6f248766f720519ae0812e37b90ce5fc 100644 (file)
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="productname" /> :: <roundcube:label name="compose" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/mail.css" />
 <link rel="stylesheet" type="text/css" href="/googiespell.css" />
 <script type="text/javascript" src="/functions.js"></script>
 </head>
 <div id="messagetoolbar">
 <table border="0" cellspacing="0" cellpadding="0"><tr>
     <td id="compose-toolbar">
-       <roundcube:button command="list" image="/images/buttons/back_act.png" imageSel="/images/buttons/back_sel.png" imageAct="/images/buttons/back_act.png" width="32" height="32" title="backtolist" />
-       <roundcube:button command="send" imageSel="/images/buttons/send_sel.png" imageAct="/images/buttons/send_act.png" imagePas="/images/buttons/send_pas.png" width="32" height="32" title="sendmessage" />
-       <roundcube:button command="spellcheck" imageSel="/images/buttons/spellcheck_sel.png" imageAct="/images/buttons/spellcheck_act.png" imagePas="/images/buttons/spellcheck_pas.png" width="32" height="32" title="checkspelling" />
-       <roundcube:button command="add-attachment" imageSel="/images/buttons/attach_sel.png" imageAct="/images/buttons/attach_act.png" imagePas="/images/buttons/attach_pas.png" width="32" height="32" title="addattachment" />
-       <roundcube:button command="savedraft" imageSel="/images/buttons/drafts_sel.png" imageAct="/images/buttons/drafts_act.png" imagePas="/images/buttons/drafts_pas.png" width="32" height="32" title="savemessage" />
+      <roundcube:button command="list" type="link" class="button back" classAct="button back" classSel="button backSel" title="backtolist" content=" " />
+      <roundcube:button command="send" type="link" class="buttonPas send" classAct="button send" classSel="button sendSel" title="sendmessage" content=" " />
+      <roundcube:button command="spellcheck" type="link" class="buttonPas spellcheck" classAct="button spellcheck" classSel="button spellcheckSel" title="checkspelling" content=" " />
+      <roundcube:button command="add-attachment" type="link" class="buttonPas attach" classAct="button attach" classSel="button attachSel" title="addattachment" content=" " />
+      <roundcube:button command="savedraft" type="link" class="buttonPas savedraft" classAct="button savedraft" classSel="button savedraftSel" title="savemessage" content=" " />
     </td>
     <td id="priority-selector">
-       <label for="rcmcomposepriority"><roundcube:label name="priority" />:</label>&nbsp;<roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" />
+      <label for="rcmcomposepriority"><roundcube:label name="priority" />:</label>&nbsp;<roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" />
     </td>
     <td id="receipt-selector">
-       <roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" />&nbsp;<label for="rcmcomposereceipt"><roundcube:label name="returnreceipt" /></label>
+      <roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" />&nbsp;<label for="rcmcomposereceipt"><roundcube:label name="returnreceipt" /></label>
     </td>
 </tr></table>
 </div>
            </tr><tr>
                <td class="title"><label for="compose-subject"><roundcube:label name="subject" /></label></td>
                <td><roundcube:object name="composeSubject" id="compose-subject" form="form" tabindex="6" /></td>
+           </tr><tr>
+               <td class="title"><roundcube:label name="editortype" /></td>
+               <td>
+                   <div id="editor-select"><roundcube:object name="editorSelector" editorid="compose-body" /></div>
+                   <div id="spellcheck-control"></div>
+               </td>
            </tr>
        </tbody>
        </table>
                    <roundcube:button type="input" command="send" class="button mainaction" label="sendmessage" tabindex="8" />
                    <roundcube:button type="input" command="list" class="button" label="cancel" tabindex="9" />
                </td>
-               <td style="text-align:center; white-space: nowrap">
-                   <label><roundcube:label name="savesentmessagein" />: <roundcube:object name="storetarget" maxlength="30" /></label>
-               </td>
-               <td style="text-align:right; white-space:nowrap">
-                   <roundcube:label name="editortype" />:&nbsp;
-                   <span class="radios-left"><roundcube:object name="editorSelector" editorid="compose-body" tabindex="10" /></span>
+               <td style="text-align:right; white-space: nowrap">
+                   <label><roundcube:label name="savesentmessagein" />: <roundcube:object name="storetarget" maxlength="30" tabindex="10" /></label>
                </td>
            </tr>
        </tbody></table>
@@ -92,7 +93,7 @@
 
 <div id="compose-attachments">
 <div id="attachment-title"><roundcube:label name="attachments" /></div>
-<roundcube:object name="composeAttachmentList" deleteIcon="/images/icons/remove-attachment.png"/ >
+<roundcube:object name="composeAttachmentList" deleteIcon="/images/icons/delete.png" />
 <p><roundcube:button command="add-attachment" imagePas="/images/buttons/add_pas.png" imageSel="/images/buttons/add_sel.png" imageAct="/images/buttons/add_act.png" width="23" height="18" title="addattachment" /></p>
 </div>
 
index 6cef903e55be9401f71f4a473fc4393285572990..1fc1237f805865999a7520631940223818a9c216 100644 (file)
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/addresses.css" />
 </head>
 <body class="iframe">
 
index 0d1f6a4ab868f5f8c8f6c1d114e30592defbbf33..deff97990989ffe268cde2a7ec22f8c8ab8fe319 100644 (file)
@@ -3,10 +3,9 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/settings.css" />
 <script type="text/javascript" src="/functions.js"></script>
 </head>
-<body onload="rcube_init_settings_tabs()">
+<body>
 
 <roundcube:include file="/includes/taskbar.html" />
 <roundcube:include file="/includes/header.html" />
index 6b2ff7747c69cb19d8862552f750aa7022fca16f..9f4f9936c29f526ebac4c716351c09a83ccdd510 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
-<title>RoundCube|Mail :: ERROR</title>
+<title><roundcube:object name="productname" /> :: ERROR</title>
 <roundcube:include file="/includes/links.html" />
 </head>
 <body>
index 9799bc576cb2c39554907df333a0f86fe35d326f..395da1cfcd1ff17d27bf8857f68ea69be24a8a8c 100644 (file)
@@ -3,10 +3,9 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/settings.css" />
 <script type="text/javascript" src="/functions.js"></script>
 </head>
-<body onload="rcube_init_settings_tabs()">
+<body>
 
 <roundcube:include file="/includes/taskbar.html" />
 <roundcube:include file="/includes/header.html" />
@@ -22,7 +21,7 @@
 
 <div id="identity-details">
   <div style="margin:10px auto; text-align:center">
-  <img src="/images/watermark.gif" width="260" height="228" alt="RoundCube" />
+  <img src="/images/watermark.gif" width="260" height="228" alt="" />
   </div>
 </div>
 
index 35a8e41f8137b3ef9fd3e004c28e678602c080c5..9eff968745083e27d789e543de7ee105886dcca1 100644 (file)
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/addresses.css" />
 </head>
 <body>
 
@@ -13,7 +12,7 @@
 <div id="importbox">
 <div class="boxtitle"><roundcube:label name="importcontacts" /></div>
 
-<div style="padding-left:20px; width:48em">
+<div style="padding-left:12px; width:48em">
 <roundcube:object name="importstep" />
 
 <p><br />
index d16a08fdd9a4e5db8c6932ada9192ab71b09e0c2..a61e70c0b55fd90f0d50dc4749f7c7343ec9d64a 100644 (file)
@@ -4,32 +4,10 @@
 <title><roundcube:object name="pagetitle" /></title>
 <meta name="Robots" content="noindex,nofollow" />
 <roundcube:include file="/includes/links.html" />
-<style type="text/css">
-
-#login-form {
-  margin-left: auto;
-  margin-right: auto;
-  margin-top: 50px;
-  width: 380px;
-  border: 1px solid #999;
-}
-
-#login-form table td.title
-{
-  color: #666;
-  text-align: right;
-  padding-right: 10px;
-}
-
-.boxcontent {
-  padding: 20px 20px 10px 20px;
-}
-
-</style>
 </head>
 <body>
 
-<img src="/images/roundcube_logo.png" border="0" alt="<roundcube:object name='productname' />" style="margin:2px 12px" />
+<img src="/images/roundcube_logo.png" border="0" alt="<roundcube:object name='productname' />" style="margin:0 11px" />
 
 <roundcube:object name="message" id="message" />
 
index 96be0f65ee68ed227cd9fa236af7e8d60ae84a29..2d16f62bf339f2e31d40b7b3eb3d5b6a941a3ead 100644 (file)
@@ -3,23 +3,18 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/mail.css" />
 <script type="text/javascript" src="/splitter.js"></script>
 <script type="text/javascript" src="/functions.js"></script>
 <style type="text/css">
 <roundcube:if condition="config:preview_pane == true" />
 #mailcontframe { height: <roundcube:exp expression="!empty(cookie:mailviewsplitter) ? cookie:mailviewsplitter-5 : 195" />px; }
-#mailpreviewframe {
-    top: <roundcube:exp expression="!empty(cookie:mailviewsplitter) ? cookie:mailviewsplitter+5 : 205" />px;
-    /* css hack for IE */
-    height: expression((parseInt(this.parentNode.offsetHeight)-<roundcube:exp expression="!empty(cookie:mailviewsplitter) ? cookie:mailviewsplitter+5 : 205" />)+'px');
+#mailpreviewframe { top: <roundcube:exp expression="!empty(cookie:mailviewsplitter) ? cookie:mailviewsplitter+5 : 205" />px;
+<roundcube:exp expression="browser:ie ? ('height: expression((parseInt(this.parentNode.offsetHeight)-'.(!empty(cookie:mailviewsplitter) ? cookie:mailviewsplitter+25 : 245).')+\\'px\\');') : ''" />
 }
 <roundcube:endif />
-#mailboxlist-container { width: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv-5 : 160" />px; }
-#mailrightcontainer {
-    left: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 170" />px;
-    /* css hack for IE */
-    width: expression((parseInt(this.parentNode.offsetWidth)-<roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 170" />)+'px');
+#mailleftcontainer { width: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv-5 : 175" />px; }
+#mailrightcontainer { left: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 185" />px;
+<roundcube:exp expression="browser:ie ? ('width: expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 180).')+\\'px\\');') : ''" />
 }
 </style>
 </head>
 <roundcube:include file="/includes/header.html" />
 
 <div id="mainscreen">
-
+<div id="mailleftcontainer">
 <div id="mailboxlist-container">
 <h3 id="mailboxlist-header"><roundcube:label name="mailboxlist" /></h3>
 <roundcube:object name="mailboxlist" id="mailboxlist" maxlength="16" />
 </div>
 
 <script type="text/javascript">
-  var mailviewsplitv = new rcube_splitter({id:'mailviewsplitterv', p1: 'mailboxlist-container', p2: 'mailrightcontainer', orientation: 'v', relative: true, start: 165});
+  var mailviewsplitv = new rcube_splitter({id:'mailviewsplitterv', p1: 'mailleftcontainer', p2: 'mailrightcontainer', orientation: 'v', relative: true, start: 165});
   rcmail.add_onload('mailviewsplitv.init()');
 </script>
 
-<div id="mailrightcontainer">
+<div id="mailboxcontrols">
+  <roundcube:label name="folder" />:&nbsp;
+  <roundcube:button command="expunge" label="compact" classAct="active" />&nbsp;
+  <roundcube:button command="purge" label="empty" classAct="active" />&nbsp;
+</div>
+</div>
 
+<div id="mailrightcontainer">
+<div id="mailrightcontent">
 <div id="mailcontframe">
 <roundcube:object name="messages"
   id="messagelist"
@@ -62,7 +64,7 @@
 <roundcube:if condition="config:preview_pane == true" />
 
 <script type="text/javascript">
-  var mailviewsplit = new rcube_splitter({id:'mailviewsplitter', p1: 'mailcontframe', p2: 'mailpreviewframe', orientation: 'h', relative: true, start: 200});
+  var mailviewsplit = new rcube_splitter({id:'mailviewsplitter', p1: 'mailcontframe', p2: 'mailpreviewframe', orientation: 'h', relative: true, start: 205});
   rcmail.add_onload('mailviewsplit.init()');
 </script>
 
 </div>
 
 <roundcube:endif />
-
 </div>
 
+<div id="mailfooter">
+<table cellpadding="1" cellspacing="0" width="100%"><tr>
+  <td>
+    <span id="listcontrols">
+      <roundcube:label name="select" />:&nbsp;
+      <roundcube:button command="select-all" label="all" classAct="active" />&nbsp;
+      <roundcube:button command="select-all" prop="unread" label="unread" classAct="active" />&nbsp;
+      <roundcube:button command="select-all" prop="invert" label="invert" classAct="active" />&nbsp;
+      <roundcube:button command="select-none" label="none" classAct="active" /> &nbsp;
+      <roundcube:container name="listcontrols" id="listcontrols" />
+    </span>
+  </td>
+  <roundcube:if condition="env:quota" />
+  <td style="text-align:center">
+    <span id="quotabox"><roundcube:label name="quota" />: <roundcube:object name="quotaDisplay" display="image" width="100" id="quotadisplay" /></span>
+  </td>
+  <roundcube:endif />
+  <td id="countcontrols" class="pagenav">
+    <roundcube:button command="lastpage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastmessages" content=" " />
+    <roundcube:button command="nextpage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextmessages" content=" " />
+    <roundcube:object name="messageCountDisplay" style="padding:0 1em; float:right" />
+    <roundcube:button command="previouspage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previousmessages" content=" " />
+    <roundcube:button command="firstpage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstmessages" content=" " />
+  </td>
+</tr></table>
 </div>
 
-<div id="mailfooter">
-<table cellpadding="1" cellspacing="0">
-<tr>
-<td width="99%">
-<span id="mailboxcontrols">
-<roundcube:label name="folder" />:&nbsp;
-<roundcube:button command="expunge" label="compact" classAct="active" />&nbsp;
-<roundcube:button command="purge" label="empty" classAct="active" />&nbsp;
-</span>
-<span id="listcontrols">
-<roundcube:label name="select" />:&nbsp;
-<roundcube:button command="select-all" label="all" classAct="active" />&nbsp;
-<roundcube:button command="select-all" prop="unread" label="unread" classAct="active" />&nbsp;
-<roundcube:button command="select-none" label="none" classAct="active" /> &nbsp;
-</span>
-<roundcube:if condition="env:quota" />
-<span id="quotabox">
-<roundcube:label name="quota" />: <roundcube:object name="quotaDisplay" display="image" width="100" id="quotadisplay" />
-</span>
-<roundcube:endif />
-</td>
-<td width="1%">
-<span id="countcontrols">
-<roundcube:button command="firstpage" imageSel="/images/buttons/first_sel.png" imageAct="/images/buttons/first_act.png" imagePas="/images/buttons/first_pas.png" width="11" height="11" title="firstmessages" />
-<roundcube:button command="previouspage" imageSel="/images/buttons/previous_sel.png" imageAct="/images/buttons/previous_act.png" imagePas="/images/buttons/previous_pas.png" width="11" height="11" title="previousmessages" />
-&nbsp;<roundcube:object name="messageCountDisplay" />&nbsp;
-<roundcube:button command="nextpage" imageSel="/images/buttons/next_sel.png" imageAct="/images/buttons/next_act.png" imagePas="/images/buttons/next_pas.png" width="11" height="11" title="nextmessages" />
-<roundcube:button command="lastpage" imageSel="/images/buttons/last_sel.png" imageAct="/images/buttons/last_act.png" imagePas="/images/buttons/last_pas.png" width="11" height="11" title="lastmessages" />
-</span>
-</td>
-</tr>
-</table>
 </div>
+</div>
+
 
 <div id="messagetoolbar">
-<roundcube:button command="checkmail" imageSel="/images/buttons/inbox_sel.png" imageAct="/images/buttons/inbox_act.png" imagePas="/images/buttons/inbox_pas.png" width="32" height="32" title="checkmail" />
-<roundcube:button command="compose" imageSel="/images/buttons/compose_sel.png" imageAct="/images/buttons/compose_act.png" imagePas="/images/buttons/compose_pas.png" width="32" height="32" title="writenewmessage" />
-<roundcube:button name="markreadbutton" id="markreadbutton" image="/images/buttons/markread_act.png" width="32" height="32" title="markmessages" onclick="rcmail_ui.show_markmenu();return false" />
-<roundcube:button command="reply" imageSel="/images/buttons/reply_sel.png" imageAct="/images/buttons/reply_act.png" imagePas="/images/buttons/reply_pas.png" width="32" height="32" title="replytomessage" />
-<roundcube:button command="reply-all" imageSel="/images/buttons/replyall_sel.png" imageAct="/images/buttons/replyall_act.png" imagePas="/images/buttons/replyall_pas.png" width="32" height="32" title="replytoallmessage" />
-<roundcube:button command="forward" imageSel="/images/buttons/forward_sel.png" imageAct="/images/buttons/forward_act.png" imagePas="/images/buttons/forward_pas.png" width="32" height="32" title="forwardmessage" />
-<roundcube:button command="delete" imageSel="/images/buttons/delete_sel.png" imageAct="/images/buttons/delete_act.png" imagePas="/images/buttons/delete_pas.png" width="32" height="32" title="deletemessage" />
-<roundcube:button command="print" imageSel="/images/buttons/print_sel.png" imageAct="/images/buttons/print_act.png" imagePas="/images/buttons/print_pas.png" width="32" height="32" title="printmessage" />
+<roundcube:button command="checkmail" type="link" class="button checkmail" classAct="button checkmail" classSel="button checkmailSel" title="checkmail" content=" " />
+<roundcube:button command="compose" type="link" class="button compose" classAct="button compose" classSel="button composeSel" title="writenewmessage" content=" " />
+<roundcube:button command="reply" type="link" class="buttonPas reply" classAct="button reply" classSel="button replySel" title="replytomessage" content=" " />
+<roundcube:button command="reply-all" type="link" class="buttonPas replyAll" classAct="button replyAll" classSel="button replyAllSel" title="replytoallmessage" content=" " />
+<roundcube:button command="forward" type="link" class="buttonPas forward" classAct="button forward" classSel="button forwardSel" title="forwardmessage" content=" " />
+<roundcube:button command="delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="deletemessage" content=" " />
+<roundcube:container name="toolbar" id="messagetoolbar" />
+<roundcube:button name="markreadbutton" id="markreadbutton" type="link" class="button markmessage" title="markmessages" onclick="rcmail_ui.show_markmenu();return false" content=" " />
+<roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button messagemenu" title="messageactions" onclick="rcmail_ui.show_messagemenu();return false" content=" " />
 
 <div id="markmessagemenu">
   <ul class="toolbarmenu">
-    <li><roundcube:button command="mark" prop="read" label="markread" classAct="active" /></li>
-    <li><roundcube:button command="mark" prop="unread" label="markunread" classAct="active" /></li>
-    <li><roundcube:button command="mark" prop="flagged" label="markflagged" classAct="active" /></li>
-    <li><roundcube:button command="mark" prop="unflagged" label="markunflagged" classAct="active" /></li>
+    <li><roundcube:button command="mark" prop="read" label="markread" classAct="readlink active" class="readlink" /></li>
+    <li><roundcube:button command="mark" prop="unread" label="markunread" classAct="unreadlink active" class="unreadlink" /></li>
+    <li><roundcube:button command="mark" prop="flagged" label="markflagged" classAct="flaggedlink active" class="flaggedlink" /></li>
+    <li><roundcube:button command="mark" prop="unflagged" label="markunflagged" classAct="unflaggedlink active" class="unflaggedlink" /></li>
+    <roundcube:container name="markmenu" id="markmessagemenu" />
   </ul>
 </div>
 
-<div id="searchfilter">
-  <label for="rcmlistfilter"><roundcube:label name="filter" /></label>:
-  <roundcube:object name="searchfilter" class="searchfilter" />
+<roundcube:include file="/includes/messagemenu.html" />
+
 </div>
+
+<div id="searchmenu">
+  <ul class="toolbarmenu">
+    <li><input type="checkbox" name="s_mods[]" value="subject" id="s_mod_subject" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_subject"><roundcube:label name="subject" /></label></li>
+    <li><input type="checkbox" name="s_mods[]" value="from" id="s_mod_from" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_from"><roundcube:label name="from" /></label></li>
+    <li><input type="checkbox" name="s_mods[]" value="to" id="s_mod_to" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_to"><roundcube:label name="to" /></label></li>
+    <li><input type="checkbox" name="s_mods[]" value="cc" id="s_mod_cc" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_cc"><roundcube:label name="cc" /></label></li>
+    <li><input type="checkbox" name="s_mods[]" value="bcc" id="s_mod_bcc" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_bcc"><roundcube:label name="bcc" /></label></li>
+    <li><input type="checkbox" name="s_mods[]" value="text" id="s_mod_text" onclick="rcmail_ui.set_searchmod(this)" /><label for="s_mod_text"><roundcube:label name="msgtext" /></label></li>
+  </ul>
 </div>
 
 <div id="quicksearchbar">
-<roundcube:object name="searchform" id="quicksearchbox" /><roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
+<div id="searchfilter">
+  <label for="rcmlistfilter"><roundcube:label name="filter" /></label>:
+  <roundcube:object name="searchfilter" class="searchfilter" />
+</div>
+<roundcube:button name="searchmod" id="searchmod" image="/images/icons/glass_roll.png" onclick="rcmail_ui.show_searchmenu();return false" title="searchmod" />
+<roundcube:object name="searchform" id="quicksearchbox" />
+<roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
 </div>
 
 </body>
index 5da5c22f1801477bd719666a95a099bd9a25bb5a..80f5df279419869b8f8acbc3b8514f9a48480bdd 100644 (file)
@@ -3,10 +3,9 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/settings.css" />
 <script type="text/javascript" src="/functions.js"></script>
 </head>
-<body onload="rcube_init_settings_tabs()">
+<body>
 
 <roundcube:include file="/includes/taskbar.html" />
 <roundcube:include file="/includes/header.html" />
@@ -17,7 +16,7 @@
 <div id="folder-manager">
 <roundcube:object name="foldersubscription" form="subscriptionform" id="subscription-table"
   cellpadding="1" cellspacing="0" summary="Folder subscription table" class="records-table"
-  deleteIcon="/images/icons/folder-trash.png"
+  deleteIcon="/images/icons/delete.png"
   renameIcon="/images/icons/rename.png" />
 </div>
 
index b8d66c1beb950cbfbf6339fd7282f987c833693f..852f4b44c9b462fcc7bb572b9bade2b80766f987 100644 (file)
@@ -3,51 +3,45 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/mail.css" />
 <script type="text/javascript" src="/splitter.js"></script>
+<script type="text/javascript" src="/functions.js"></script>
 <style type="text/css">
-#mailboxlist-container { width: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv-5 : 160" />px; }
-#messageframe {
-    left: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 170" />px;
-    width: expression((parseInt(this.parentNode.offsetWidth)-<roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 170" />)+'px');
+#mailboxlist-container { width: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv-5 : 170" />px; }
+#messageframe { left: <roundcube:exp expression="!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 180" />px;
+<roundcube:exp expression="browser:ie ? ('width: expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:mailviewsplitterv) ? cookie:mailviewsplitterv+5 : 180).')+\\'px\\');') : ''" />
 }
 </style>
 </head>
-<body>
+<body onload="rcube_init_mail_ui()">
 
 <roundcube:include file="/includes/taskbar.html" />
 <roundcube:include file="/includes/header.html" />
 
-<div id="messagecountbar">
-<roundcube:button command="firstmessage" imageSel="/images/buttons/first_sel.png" imageAct="/images/buttons/first_act.png" imagePas="/images/buttons/first_pas.png" width="11" height="11" title="firstmessage" />
-<roundcube:button command="previousmessage" imageSel="/images/buttons/previous_sel.png" imageAct="/images/buttons/previous_act.png" imagePas="/images/buttons/previous_pas.png" width="11" height="11" title="previousmessage" />
-&nbsp;<roundcube:object name="messageCountDisplay" />&nbsp;
-<roundcube:button command="nextmessage" imageSel="/images/buttons/next_sel.png" imageAct="/images/buttons/next_act.png" imagePas="/images/buttons/next_pas.png" width="11" height="11" title="nextmessage" />
-<roundcube:button command="lastmessage" imageSel="/images/buttons/last_sel.png" imageAct="/images/buttons/last_act.png" imagePas="/images/buttons/last_pas.png" width="11" height="11" title="lastmessage" />
-</div>
-
 <div id="messagetoolbar">
-<roundcube:button command="list" image="/images/buttons/back_act.png" imageSel="/images/buttons/back_sel.png" imageAct="/images/buttons/back_act.png" width="32" height="32" title="backtolist" />
-<roundcube:button command="compose" imageSel="/images/buttons/compose_sel.png" imageAct="/images/buttons/compose_act.png" imagePas="/images/buttons/compose_pas.png" width="32" height="32" title="writenewmessage" />
-<roundcube:button command="reply" imageSel="/images/buttons/reply_sel.png" imageAct="/images/buttons/reply_act.png" imagePas="/images/buttons/reply_pas.png" width="32" height="32" title="replytomessage" />
-<roundcube:button command="reply-all" imageSel="/images/buttons/replyall_sel.png" imageAct="/images/buttons/replyall_act.png" imagePas="/images/buttons/replyall_pas.png" width="32" height="32" title="replytoallmessage" />
-<roundcube:button command="forward" imageSel="/images/buttons/forward_sel.png" imageAct="/images/buttons/forward_act.png" imagePas="/images/buttons/forward_pas.png" width="32" height="32" title="forwardmessage" />
-<roundcube:button command="delete" imageSel="/images/buttons/delete_sel.png" imageAct="/images/buttons/delete_act.png" imagePas="/images/buttons/delete_pas.png" width="32" height="32" title="deletemessage" />
-<roundcube:button command="print" imageSel="/images/buttons/print_sel.png" imageAct="/images/buttons/print_act.png" imagePas="/images/buttons/print_pas.png" width="32" height="32" title="printmessage" />
-<roundcube:button command="viewsource" imageSel="/images/buttons/source_sel.png" imageAct="/images/buttons/source_act.png" imagePas="/images/buttons/source_pas.png" width="32" height="32" title="viewsource" />
+<roundcube:button command="list" type="link" class="button back" classAct="button back" classSel="button backSel" title="backtolist" content=" " />
+<roundcube:button command="compose" type="link" class="button compose" classAct="button compose" classSel="button composeSel" title="writenewmessage" content=" " />
+<roundcube:button command="reply" type="link" class="buttonPas reply" classAct="button reply" classSel="button replySel" title="replytomessage" content=" " />
+<roundcube:button command="reply-all" type="link" class="buttonPas replyAll" classAct="button replyAll" classSel="button replyAllSel" title="replytoallmessage" content=" " />
+<roundcube:button command="forward" type="link" class="buttonPas forward" classAct="button forward" classSel="button forwardSel" title="forwardmessage" content=" " />
+<roundcube:button command="delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="deletemessage" content=" " />
+<roundcube:container name="toolbar" id="messagetoolbar" />
+<roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button messagemenu" title="messageactions" onclick="rcmail_ui.show_messagemenu();return false" content=" " />
 <roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mboxlist" />
+
+<roundcube:include file="/includes/messagemenu.html" />
 </div>
 
 <div id="mainscreen">
-
+<div id="mailleftcontainer">
 <div id="mailboxlist-container">
 <div id="mailboxlist-header"><roundcube:label name="mailboxlist" /></div>
 <roundcube:object name="mailboxlist" id="mailboxlist" maxlength="25" />
 </div>
+</div>
 
 <div id="messageframe">
 <div id="messagecanvas">
-<roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" addicon="/images/icons/plus.gif" summary="Message headers" />
+<roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" addicon="/images/icons/silhouette.png" summary="Message headers" />
 <roundcube:object name="messageAttachments" id="attachment-list" />
 
 <roundcube:object name="blockedObjects" id="remote-objects-message" />
 </div>
 </div>
 
+<div id="messagecountbar" class="pagenav">
+  <roundcube:button command="lastmessage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastmessage" content=" " />
+  <roundcube:button command="nextmessage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextmessage" content=" " />
+  <roundcube:object name="messageCountDisplay" style="padding:0 1em 0 1em; float:right" />
+  <roundcube:button command="previousmessage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previousmessage" content=" " />
+  <roundcube:button command="firstmessage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstmessage" content=" " />
+</div>
 </div>
 
 <script type="text/javascript">
diff --git a/skins/default/templates/messageerror.html b/skins/default/templates/messageerror.html
new file mode 100644 (file)
index 0000000..d180e74
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title></title>
+<roundcube:include file="/includes/links.html" />
+</head>
+<body class="iframe" style="background-color:#F2F2F2;">
+
+<div style="margin:20px auto; text-align:center">
+<img src="/images/watermark.gif" width="260" height="228" alt="" />
+</div>
+
+</body>
+</html>
index c524b7f23996f7b5da14633b39197bffd8ec789f..ce7dbe2e16f6663048f4285e548722ba89c1b2f5 100644 (file)
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/mail.css" />
 </head>
 <body class="extwin">
 
index 24848bbe73ee7d8284978a5ae0ba3468f6503bf0..fbece6bc310a50efb3b4dc524dab270ba8fffe79 100644 (file)
@@ -2,14 +2,13 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title><roundcube:object name="pagetitle" /></title>
-<link rel="stylesheet" type="text/css" href="/common.css" />
-<link rel="stylesheet" type="text/css" href="/mail.css" />
+<roundcube:include file="/includes/links.html" />
 </head>
 <body class="iframe">
 
 <div class="messageheaderbox">
 <roundcube:button command="permaurl" image="/images/icons/extwin.png" width="15" height="15" title="openinextwin" id="messageviewlink" target="_blank" />
-<roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" addicon="/images/icons/plus.gif" summary="Message headers" />
+<roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" addicon="/images/icons/silhouette.png" summary="Message headers" />
 <roundcube:object name="messageAttachments" id="attachment-list" />
 </div>
 
diff --git a/skins/default/templates/plugin.html b/skins/default/templates/plugin.html
new file mode 100644 (file)
index 0000000..03f0203
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<script type="text/javascript" src="/functions.js"></script>
+</head>
+<body>
+
+<roundcube:include file="/includes/taskbar.html" />
+<roundcube:include file="/includes/header.html" />
+<roundcube:if condition="env:task == 'settings'" />
+  <roundcube:include file="/includes/settingstabs.html" />
+<roundcube:endif />
+
+<div id="pagecontent">
+<roundcube:object name="plugin.body" />
+</div>
+  
+<roundcube:object name="plugin.footer" />
+
+</body>
+</html>
index 17ea7bf5a8fe7cff02a66a0afc11c03333174f91..f2775cd61dcd56cd3883fb39126dcc64d9694862 100644 (file)
@@ -6,7 +6,7 @@
 </head>
 <body>
 
-<div id="header"><img src="/images/roundcube_logo_print.gif" alt="<roundcube:object name="productname" />" /></div>
+<div id="header"><img src="/images/roundcube_logo.png" alt="<roundcube:object name="productname" />" /></div>
 
 <div id="printmessageframe">
 <roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" />
index a3f5298cd6e5dd25183852394515f102e23b946f..0ff86ad2cf2d9b6e04d92c6fc04a69b6b7d27b98 100644 (file)
@@ -3,40 +3,38 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/settings.css" />
 <script type="text/javascript" src="/functions.js"></script>
+<script type="text/javascript" src="/splitter.js"></script>
+
+<style type="text/css">
+#sectionslist { width: <roundcube:exp expression="!empty(cookie:prefsviewsplitter) ? cookie:prefsviewsplitter-5 : 190" />px; }
+#prefs-box { left: <roundcube:exp expression="!empty(cookie:prefsviewsplitter) ? cookie:prefsviewsplitter+5 : 200" />px;
+<roundcube:exp expression="browser:ie ? ('width:expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:prefsviewsplitter) ? cookie:prefsviewsplitter+5 : 200).')+\\'px\\');') : ''" />
+}
+</style>
+
 </head>
-<body onload="rcube_init_settings_tabs()">
+<body>
 
 <roundcube:include file="/includes/taskbar.html" />
 <roundcube:include file="/includes/header.html" />
 <roundcube:include file="/includes/settingstabs.html" />
 
-<form name="form" action="./" method="post">
+<div id="prefsscreen">
 
-<div id="userprefs-box">
-<div id="userprefs-title"><roundcube:label name="userpreferences" /></div>
-
-<div style="padding:15px 0 15px 15px">
-<div class="userprefs-block">
-  <roundcube:object name="userprefs" form="form" parts="general,mailbox,mailview" />
-</div>
-<div class="userprefs-block">
-  <roundcube:object name="userprefs" form="form" parts="compose,folders,server" />
-</div>
-<div style="clear:left"></div>
-</div>
+<div id="sectionslist">
+<roundcube:object name="sectionslist" id="sections-table" class="records-table" cellspacing="0" />
 </div>
 
-<p id="listbuttons">
-<roundcube:button command="save" type="input" class="button mainaction" label="save" />
-</p>
+<script type="text/javascript">
+  var prefviewsplit = new rcube_splitter({id:'prefsviewsplitter', p1: 'sectionslist', p2: 'prefs-box', orientation: 'v', relative: true, start: 195});
+  rcmail.add_onload('prefviewsplit.init()');
+</script>
 
-</form>
+<div id="prefs-box">
+<roundcube:object name="prefsframe" id="prefs-frame" width="100%" height="100%" frameborder="0" src="/watermark.html" />
+</div>
 
-<div class="advswitch">
-<label for="advswitch"><roundcube:label name="advancedoptions"></label>
-<input type="checkbox" id="advswitch" name="_advanced" value="0" onclick="rcube_show_advanced(this.checked)" />
 </div>
 
 </body>
diff --git a/skins/default/templates/settingsedit.html b/skins/default/templates/settingsedit.html
new file mode 100644 (file)
index 0000000..dcd5c5c
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<script type="text/javascript" src="/functions.js"></script>
+</head>
+<body class="iframe">
+
+<div id="prefs-title" class="boxtitle"><roundcube:object name="sectionname" /></div>
+
+<form name="form" action="./" method="post">
+
+<div id="prefs-details">
+<roundcube:object name="userprefs" form="form" />
+</div>
+
+<div id="formfooter">
+<div class="footerleft">
+<roundcube:button command="save" type="input" class="button mainaction" label="save" />
+</div>
+
+</div>
+<p>&nbsp;</p>
+
+</form>
+
+</body>
+</html>
index 79304578c6b2529db7a0abd9698237ea1f10acd5..e50c6031c4b67f547d399b43355e4e94e44c804d 100644 (file)
@@ -3,7 +3,6 @@
 <head>
 <title><roundcube:object name="pagetitle" /></title>
 <roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/addresses.css" />
 </head>
 <body class="iframe">
 
index ebad64361bcd0c96174d4644016cd61a96eb1e47..c16a50357ed98768aea2ae68aa6f0b9ae3ad3719 100644 (file)
@@ -2,8 +2,14 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <title></title>
+  <!--[if IE]>
+  <style type="text/css">
+    body { width: expression((parseInt(document.documentElement.clientWidth)-20)+'px'); }
+  </style>
+  <![endif]-->
 </head>
-<body style="background-color:#F2F2F2; width: expression((parseInt(document.documentElement.clientWidth)-20)+'px');">
+
+<body style="background-color:#F2F2F2;">
 
 <div style="margin:20px auto; text-align:center">
 <img src="images/watermark.gif" width="260" height="228" alt="" />