# HG changeset patch # User Dan # Date 1203702713 18000 # Node ID c433348f3628f81e2f16d5956e0aa5323ddb5cfa # Parent d9dd2b2134c419b3bb70e94f3fcf4c92b7ed230f# Parent d823e49e2e4eae7bfea6ebff1e9ac6aa12a73eb4 Merging fixes and updates from stable branch diff -r d823e49e2e4e -r c433348f3628 .hgtags --- a/.hgtags Fri Feb 22 12:46:51 2008 -0500 +++ b/.hgtags Fri Feb 22 12:51:53 2008 -0500 @@ -11,3 +11,6 @@ 95dc632bf0846b5a7d7d841a4fe9518964a1cc9a release f8356d9c3481b7ebb88dbf70637d8f5d2cca4528 rebrand d409d7fcf6f8bc638e0282101fb823ccf3e29e59 release +3395ecddd831ee2f0229ab3b4a1c9d69f0ab73d7 release +d1a95497b68f765f6ca4ed816d07b20b13cee692 rebrand +ceff43bbc3d3bc18d7679f88ef6fec2e070bc704 release diff -r d823e49e2e4e -r c433348f3628 README --- a/README Fri Feb 22 12:46:51 2008 -0500 +++ b/README Fri Feb 22 12:51:53 2008 -0500 @@ -1,5 +1,5 @@ Enano CMS -Version 1.0.3 +Version 1.1.2 ----------------------------- Thanks for downloading Enano! If you're looking for an installation guide, @@ -9,7 +9,7 @@ ----------------------------- Enano CMS -Copyright (C) 2006-2007 Dan Fuhry. All rights except those explicitly granted +Copyright (C) 2006-2008 Dan Fuhry. All rights except those explicitly granted by the included license agreement reserved. PHILOSOPHY @@ -74,16 +74,30 @@ CHANGES IN THIS RELEASE ----------------------------- -Please see for a list of changes in +Please see for a list of changes in this release. UPGRADING FROM PREVIOUS RELEASES ----------------------------- -This tarball includes an upgrade script that can migrate any previous version -of Enano to this one. Before you upload the contents of this tarball to your -server, you might want to delete the files config.new.php and .htaccess.new, -neither of which are needed if you are performing an upgrade. +This tarball includes a very basic migration script that you can use to change +a 1.0.x installation into a 1.1.x one. Make sure you're using the latest 1.0.x +release (1.0.3 at the time of this writing) BEFORE you run the migration +script. DO NOT UPGRADE A PRODUCTION SITE. + +As of 1.1.2, basic upgrade functionality is included and is considered highly +experimental. Back up your entire database and Enano root before upgrading. + +TRANSLATING ENANO +----------------------------- + +This is the only the second formal release of Enano that is localized. Right +now since this is an alpha, you probably don't want to do any translation +because you'll be doing a TON more strings at every release. HOWEVER, we're +looking for people to sign up and volunteer for translation efforts later on. +If you have a native or very good knowledge of a language, drop us an e-mail +and we'll get you onto the translator list and eventually onto a mailing list +specifically for l10n. EXPANDING YOUR SITE'S CAPABILITIES ----------------------------- @@ -91,7 +105,10 @@ There is a gallery of plugins for Enano at . It's not very full right now because not every plugin has a page on the website yet, and some plugins still have -yet to be ported to work with some of the newer API changes. +yet to be ported to work with some of the newer API changes. Being an alpha +release you'll probably need to look in the Mercurial repositories at + for the latest versions of plugins that are designed +to work under both 1.0.x and 1.1.x. GIVING YOUR SITE A NEW LOOK ----------------------------- @@ -100,20 +117,19 @@ Again, we're still working on packaging up themes and creating pages for them, so try to be patient. We have quite a few themes in the works. You can create your own themes too; for more information, see Chapter V of the Enano -Administrator's handbook, at . +Administrator's handbook, at . Unless +specifically marked, themes on the Enano website are compatible with 1.0.x. +While you can use 1.0.x themes under 1.1.x, some features (namely viewing IPs +on comments and the default "Inherit" option in the ACL editor) will be missing +unless you copy over comment.tpl and acledit.tpl respectively from Oxygen or +one of the other themes included with this 1.1.x package. GETTING SUPPORT ----------------------------- -Before contacting support, have a look at the Enano Documentation at -. Most of Enano's features are documented with -step-by-step guides at this site; if you encounter a problem, then please -contact the Enano team as instructed below. - -Support for Enano is available via the Enano forums at -. You can also use our IRC channel -(irc.freenode.net #enano) or purchase paid one-on-one support via instant -messaging for US$20 an hour. +This is an alpha release. No support of any kind will be provided, but proper +bug reports are appreciated. See the Enano forums at + for more information. Have fun with Enano! diff -r d823e49e2e4e -r c433348f3628 ajax.php --- a/ajax.php Fri Feb 22 12:46:51 2008 -0500 +++ b/ajax.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.1 * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -35,7 +35,7 @@ define('ENANO_ROOT', dirname($filename)); require(ENANO_ROOT.'/includes/functions.php'); require(ENANO_ROOT.'/includes/dbal.php'); - require(ENANO_ROOT.'/includes/json.php'); + require(ENANO_ROOT.'/includes/json2.php'); require(ENANO_ROOT . '/config.php'); unset($dbuser, $dbpasswd); @@ -47,7 +47,6 @@ $db->connect(); // result is sent using JSON - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); $return = Array( 'mode' => 'success', 'users_real' => Array() @@ -61,7 +60,7 @@ 'mode' => 'error', 'error' => 'Invalid URI' ); - die( $json->encode($return) ); + die( enano_json_encode($return) ); } $allowanon = ( isset($_GET['allowanon']) && $_GET['allowanon'] == '1' ) ? '' : ' AND user_id > 1'; $q = $db->sql_query('SELECT username FROM '.table_prefix.'users WHERE ' . ENANO_SQLFUNC_LOWERCASE . '(username) LIKE ' . ENANO_SQLFUNC_LOWERCASE . '(\'%'.$name.'%\')' . $allowanon . ' ORDER BY username ASC;'); @@ -80,7 +79,7 @@ // all done! :-) $db->close(); - echo $json->encode( $return ); + echo enano_json_encode( $return ); exit; } @@ -97,21 +96,116 @@ echo PageUtils::checkusername($_GET['name']); break; case "getsource": + header('Content-type: text/plain'); $password = ( isset($_GET['pagepass']) ) ? $_GET['pagepass'] : false; - $page = new PageProcessor($paths->page_id, $paths->namespace); + $revid = ( isset($_GET['revid']) ) ? intval($_GET['revid']) : 0; + $page = new PageProcessor($paths->page_id, $paths->namespace, $revid); $page->password = $password; + $have_draft = false; if ( $src = $page->fetch_source() ) { - echo $src; + $allowed = true; + $q = $db->sql_query('SELECT author, time_id, page_text, edit_summary FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' + AND page_id = \'' . $db->escape($paths->page_id) . '\' + AND namespace = \'' . $db->escape($paths->namespace) . '\' + AND is_draft = 1;'); + if ( !$q ) + $db->die_json(); + + if ( $db->numrows() > 0 ) + { + $have_draft = true; + $draft_row = $db->fetchrow($q); + } } else if ( $src !== false ) { - echo ''; + $allowed = true; + $src = ''; } else { - echo 'err_access_denied'; + $allowed = false; + $src = ''; + } + + $auth_edit = ( $session->get_permissions('edit_page') && ( $session->get_permissions('even_when_protected') || !$paths->page_protected ) ); + $auth_wysiwyg = ( $session->get_permissions('edit_wysiwyg') ); + + $return = array( + 'mode' => 'editor', + 'src' => $src, + 'auth_view_source' => $allowed, + 'auth_edit' => $auth_edit, + 'time' => time(), + 'require_captcha' => false, + 'allow_wysiwyg' => $auth_wysiwyg, + 'revid' => $revid, + 'have_draft' => false + ); + + if ( $have_draft ) + { + $row =& $draft_row; + $return['have_draft'] = true; + $return['draft_author'] = $row['author']; + $return['draft_time'] = enano_date('d M Y h:i a', intval($row['time_id'])); + if ( isset($_GET['get_draft']) && @$_GET['get_draft'] === '1' ) + { + $return['src'] = $row['page_text']; + $return['edit_summary'] = $row['edit_summary']; + } } + + if ( $revid > 0 ) + { + // Retrieve information about this revision and the current one + $q = $db->sql_query('SELECT l1.author AS currentrev_author, l2.author AS oldrev_author FROM ' . table_prefix . 'logs AS l1 + LEFT JOIN ' . table_prefix . 'logs AS l2 + ON ( l2.time_id = ' . $revid . ' + AND l2.log_type = \'page\' + AND l2.action = \'edit\' + AND l2.page_id = \'' . $db->escape($paths->page_id) . '\' + AND l2.namespace = \'' . $db->escape($paths->namespace) . '\' + ) + WHERE l1.log_type = \'page\' + AND l1.action = \'edit\' + AND l1.page_id = \'' . $db->escape($paths->page_id) . '\' + AND l1.namespace = \'' . $db->escape($paths->namespace) . '\' + AND l1.time_id >= ' . $revid . ' + ORDER BY l1.time_id DESC;'); + if ( !$q ) + $db->die_json(); + + $rev_count = $db->numrows() - 1; + if ( $rev_count == -1 ) + { + $return = array( + 'mode' => 'error', + 'error' => '[Internal] No rows returned by revision info query. SQL:
' . $db->latest_query . '
' + ); + } + else + { + $row = $db->fetchrow(); + $return['undo_info'] = array( + 'old_author' => $row['oldrev_author'], + 'current_author' => $row['currentrev_author'], + 'undo_count' => $rev_count + ); + } + } + + if ( $auth_edit && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) + { + $return['require_captcha'] = true; + $return['captcha_id'] = $session->make_captcha(); + } + + $template->load_theme(); + $return['toolbar_templates'] = $template->extract_vars('toolbar.tpl'); + + echo enano_json_encode($return); break; case "getpage": // echo PageUtils::getpage($paths->page, false, ( (isset($_GET['oldid'])) ? $_GET['oldid'] : false )); @@ -127,7 +221,7 @@ $summ = ( isset($_POST['summary']) ) ? $_POST['summary'] : ''; $minor = isset($_POST['minor']); $e = PageUtils::savepage($paths->page_id, $paths->namespace, $_POST['text'], $summ, $minor); - if($e=='good') + if ( $e == 'good' ) { $page = new PageProcessor($paths->page_id, $paths->namespace); $page->send(); @@ -137,6 +231,159 @@ echo '

Error saving the page: '.$e.'

'; } break; + case "savepage_json": + header('Content-type: application/json'); + if ( !isset($_POST['r']) ) + die('Invalid request [1]'); + + $request = enano_json_decode($_POST['r']); + if ( !isset($request['src']) || !isset($request['summary']) || !isset($request['minor_edit']) || !isset($request['time']) || !isset($request['draft']) ) + die('Invalid request [2]
' . htmlspecialchars(print_r($request, true)) . '
'); + + $time = intval($request['time']); + + if ( $request['draft'] ) + { + // + // The user wants to save a draft version of the page. + // + + // Delete any draft copies if they exist + $q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' + AND page_id = \'' . $db->escape($paths->page_id) . '\' + AND namespace = \'' . $db->escape($paths->namespace) . '\' + AND is_draft = 1;'); + if ( !$q ) + $db->die_json(); + + $src = RenderMan::preprocess_text($request['src'], false, false); + + // Save the draft + $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs ( log_type, action, page_id, namespace, author, edit_summary, page_text, is_draft, time_id ) + VALUES ( + \'page\', + \'edit\', + \'' . $db->escape($paths->page_id) . '\', + \'' . $db->escape($paths->namespace) . '\', + \'' . $db->escape($session->username) . '\', + \'' . $db->escape($request['summary']) . '\', + \'' . $db->escape($src) . '\', + 1, + ' . time() . ' + );'); + + // Done! + $return = array( + 'mode' => 'success', + 'is_draft' => true + ); + } + else + { + // Verify that no edits have been made since the editor was requested + $q = $db->sql_query('SELECT time_id, author FROM ' . table_prefix . "logs WHERE log_type = 'page' AND action = 'edit' AND page_id = '{$paths->page_id}' AND namespace = '{$paths->namespace}' AND is_draft != 1 ORDER BY time_id DESC LIMIT 1;"); + if ( !$q ) + $db->die_json(); + + $row = $db->fetchrow(); + $db->free_result(); + + if ( $row['time_id'] > $time ) + { + $return = array( + 'mode' => 'obsolete', + 'author' => $row['author'], + 'date_string' => enano_date('d M Y h:i a', $row['time_id']), + 'time' => $row['time_id'] // time() ??? + ); + echo enano_json_encode($return); + break; + } + + // Verify captcha, if needed + if ( !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) + { + if ( !isset($request['captcha_id']) || !isset($request['captcha_code']) ) + { + die('Invalid request, need captcha metadata'); + } + $code_correct = strtolower($session->get_captcha($request['captcha_id'])); + $code_input = strtolower($request['captcha_code']); + if ( $code_correct !== $code_input ) + { + $return = array( + 'mode' => 'errors', + 'errors' => array($lang->get('editor_err_captcha_wrong')), + 'new_captcha' => $session->make_captcha() + ); + echo enano_json_encode($return); + break; + } + } + + // Verification complete. Start the PageProcessor and let it do the dirty work for us. + $page = new PageProcessor($paths->page_id, $paths->namespace); + if ( $page->update_page($request['src'], $request['summary'], ( $request['minor_edit'] == 1 )) ) + { + $return = array( + 'mode' => 'success', + 'is_draft' => false + ); + } + else + { + $errors = array(); + while ( $err = $page->pop_error() ) + { + $errors[] = $err; + } + $return = array( + 'mode' => 'errors', + 'errors' => array_values($errors) + ); + if ( !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) + { + $return['new_captcha'] = $session->make_captcha(); + } + } + + // If this is based on a draft version, delete the draft - we no longer need it. + if ( @$request['used_draft'] ) + { + $q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\' + AND page_id = \'' . $db->escape($paths->page_id) . '\' + AND namespace = \'' . $db->escape($paths->namespace) . '\' + AND is_draft = 1;'); + } + } + + echo enano_json_encode($return); + + break; + case "diff_cur": + + // Lie about our content type to fool ad scripts + header('Content-type: application/xhtml+xml'); + + if ( !isset($_POST['text']) ) + die('Invalid request'); + + $page = new PageProcessor($paths->page_id, $paths->namespace); + if ( !($src = $page->fetch_source()) ) + { + die('Access denied'); + } + + $diff = RenderMan::diff($src, $_POST['text']); + if ( $diff == '
' ) + { + $diff = '

' . $lang->get('editor_msg_diff_empty') . '

'; + } + + echo '
' . $lang->get('editor_msg_diff') . '
'; + echo $diff; + + break; case "protect": echo PageUtils::protect($paths->page_id, $paths->namespace, (int)$_POST['level'], $_POST['reason']); break; @@ -166,7 +413,7 @@ case "deletepage": $reason = ( isset($_POST['reason']) ) ? $_POST['reason'] : false; if ( empty($reason) ) - die('Please enter a reason for deleting this page.'); + die($lang->get('page_err_need_reason')); echo PageUtils::deletepage($paths->page_id, $paths->namespace, $reason); break; case "delvote": @@ -285,7 +532,6 @@ die('GOOD'); break; case 'get_tags': - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); $ret = array('tags' => array(), 'user_level' => $session->user_level, 'can_add' => $session->get_permissions('tag_create')); $q = $db->sql_query('SELECT t.tag_id, t.tag_name, pg.pg_target IS NOT NULL AS used_in_acl, t.user_id FROM '.table_prefix.'tags AS t @@ -321,11 +567,10 @@ ); } - echo $json->encode($ret); + echo enano_json_encode($ret); break; case 'addtag': - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); $resp = array( 'success' => false, 'error' => 'No error', @@ -337,7 +582,7 @@ if ( !$session->get_permissions('tag_create') ) { $resp['error'] = 'You are not permitted to tag pages.'; - die($json->encode($resp)); + die(enano_json_encode($resp)); } // sanitize the tag name @@ -347,7 +592,7 @@ if ( strlen($tag) < 2 ) { $resp['error'] = 'Tags must consist of at least 2 alphanumeric characters.'; - die($json->encode($resp)); + die(enano_json_encode($resp)); } // check if tag is already on page @@ -357,7 +602,7 @@ if ( $db->numrows() > 0 ) { $resp['error'] = 'This page already has this tag.'; - die($json->encode($resp)); + die(enano_json_encode($resp)); } $db->free_result(); @@ -369,7 +614,7 @@ if ( $db->numrows() > 0 && !$can_edit_acl ) { $resp['error'] = 'This tag is used in an ACL page group, and thus can\'t be added to a page by people without administrator privileges.'; - die($json->encode($resp)); + die(enano_json_encode($resp)); } $resp['in_acl'] = ( $db->numrows() > 0 ); $db->free_result(); @@ -383,7 +628,7 @@ $resp['tag'] = $tag; $resp['tag_id'] = $db->insert_id(); - echo $json->encode($resp); + echo enano_json_encode($resp); break; case 'deltag': diff -r d823e49e2e4e -r c433348f3628 cron.php --- a/cron.php Fri Feb 22 12:46:51 2008 -0500 +++ b/cron.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License diff -r d823e49e2e4e -r c433348f3628 files/avatars/.htaccess --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files/avatars/.htaccess Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,1 @@ +Allow from all diff -r d823e49e2e4e -r c433348f3628 images/about-powered-pgsql.png Binary file images/about-powered-pgsql.png has changed diff -r d823e49e2e4e -r c433348f3628 images/check.png Binary file images/check.png has changed diff -r d823e49e2e4e -r c433348f3628 images/checkbad.png Binary file images/checkbad.png has changed diff -r d823e49e2e4e -r c433348f3628 images/checkunk.png Binary file images/checkunk.png has changed diff -r d823e49e2e4e -r c433348f3628 images/editor/diff.gif Binary file images/editor/diff.gif has changed diff -r d823e49e2e4e -r c433348f3628 images/editor/discard.gif Binary file images/editor/discard.gif has changed diff -r d823e49e2e4e -r c433348f3628 images/editor/preview.gif Binary file images/editor/preview.gif has changed diff -r d823e49e2e4e -r c433348f3628 images/editor/revert.gif Binary file images/editor/revert.gif has changed diff -r d823e49e2e4e -r c433348f3628 images/editor/save.gif Binary file images/editor/save.gif has changed diff -r d823e49e2e4e -r c433348f3628 images/editor/savedraft.gif Binary file images/editor/savedraft.gif has changed diff -r d823e49e2e4e -r c433348f3628 images/enano-artwork/README --- a/images/enano-artwork/README Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -The images in this directory are copyright (C) 2007 Dan Fuhry. Except -as permitted by applicable law, they may not be used in any way other -than to promote the unmodified Enano CMS. You also may not modify and -then distribute the images in this directory, or distribute them sep- -arately from the Enano packages. The goal here is to establish a uni- -que identity for Enano through the use of a logo, and that identity -would be confused if this logo is used for unofficial Enano distros. - diff -r d823e49e2e4e -r c433348f3628 images/enano-artwork/installer-greeting-blue.png Binary file images/enano-artwork/installer-greeting-blue.png has changed diff -r d823e49e2e4e -r c433348f3628 images/enano-artwork/installer-greeting-green.png Binary file images/enano-artwork/installer-greeting-green.png has changed diff -r d823e49e2e4e -r c433348f3628 images/pm_ajax.gif Binary file images/pm_ajax.gif has changed diff -r d823e49e2e4e -r c433348f3628 images/pm_star_off.png Binary file images/pm_star_off.png has changed diff -r d823e49e2e4e -r c433348f3628 images/pm_star_on.png Binary file images/pm_star_on.png has changed diff -r d823e49e2e4e -r c433348f3628 includes/captcha.php --- a/includes/captcha.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/captcha.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * captcha.php - visual confirmation system used during registration * @@ -11,738 +11,178 @@ * * 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 details. - * - * This file contains code written by Paul Sohier (www.paulscripts.nl). The CAPTCHA code was ported from the phpBB Better - * Captcha mod, and has been released under the GPLv2 by the original author. - * - * This file contains code written by the phpBB team (www.phpbb.com). phpBB is licensed under the GPLv2. + */ + +/** + * The base class for CAPTCHA engines. + * @package Enano + * @subpackage User management + * @copyright 2008 Dan Fuhry */ -class captcha +class captcha_base { - var $chars, $confirm_id, $compat, $code, $captcha_config; - function __construct($code) + + /** + * Our session ID + * @var string + */ + + private $session_id; + + /** + * Our saved session data + * @var array + */ + + private $session_data; + + /** + * The confirmation code we're generating. + * @var string + */ + + private $code = ''; + + /** + * Numerical ID (primary key) for our session + * @var int + */ + + private $id = 0; + + /** + * Constructor. + * @param string Session ID for captcha + */ + + function __construct($session_id, $row = false) { global $db, $session, $paths, $template, $plugins; // Common objects - - // Check if GD exists, otherwise we will use the fallback phpBB confirm image - $this->compat = false; - if(!extension_loaded("gd")){ - $this->compat = true; + if ( !preg_match('/^[a-f0-9]{32}([a-z0-9]{8})?$/', $session_id) ) + { + throw new Exception('Invalid session ID'); } - if(!function_exists("gd_info") || !function_exists('imagettftext')){ - $this->compat = true; + $this->session_id = $session_id; + // If we weren't supplied with session info, retreive it + if ( !is_array($row) ) + { + $q = $db->sql_query('SELECT code_id, code, session_data FROM ' . table_prefix . "captcha WHERE session_id = '$session_id';"); + if ( !$q ) + $db->_die(); + $row = $db->fetchrow(); + $row['code_id'] = intval($row['code_id']); + $db->free_result(); } - $this->code = $code; - - $hex = Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); - $latticecolor = '#'; - for($i=0;$i<6;$i++) $latticecolor .= $hex[mt_rand(0, 15)]; + if ( !isset($row['code']) || !isset($row['session_data']) || !is_int(@$row['code_id']) ) + { + throw new Exception('Row doesn\'t contain what we need (code and session_data)'); + } + $this->session_data = ( is_array($x = @unserialize($row['session_data'])) ) ? $x : array(); + $this->code = $row['code']; + $this->id = $row['code_id']; - $this->captcha_config = array ( - 'width' => '350', - 'height' => '90', - 'background_color' => '#E5ECF9', - 'jpeg' => '0', - 'jpeg_quality' => '95', - 'pre_letters' => '1', - 'pre_letters_great' => '0', - 'font' => '1', - 'chess' => '2', - 'ellipses' => '2', - 'arcs' => '2', - 'lines' => '2', - 'image' => '0', - 'gammacorrect' => '0.8', - 'foreground_lattice_x' => (string)mt_rand(25, 30), - 'foreground_lattice_y' => (string)mt_rand(25, 30), - 'lattice_color' => $latticecolor, - ); + // run any custom init functions + if ( function_exists(array($this, 'construct_hook')) ) + $this->construct_hook(); } - function captcha($code) - { - $this->__construct($code); - } - function dss_rand() + + /** + * Retrieves a key from the session data set + * @param int|string Key to fetch + * @param mixed Default value for key + * @return mixed + */ + + function session_fetch($key, $default = false) { - global $db; - - $val = microtime() . mt_rand(); - $val = md5($val . 'a'); - return substr($val, 4, 16); + return ( isset($this->session_data[$key]) ) ? $this->session_data[$key] : $default; } - function make_image() + /** + * Stores a value in the session's data set. Change must be committed using $captcha->session_commit() + * @param int|string Name of key + * @param mixed Value - can be an array, string, int, or double, but probably not objects :-) + */ + + function session_store($key, $value) { - $code=$this->code; - if($this->compat) - { - // We can we will generate a single filtered png - // Thanks to DavidMJ for emulating zlib within the code :) - $_png = $this->define_filtered_pngs(); - - $total_width = 320; - $total_height = 50; - $img_height = 40; - $img_width = 0; - $l = 0; - - list($usec, $sec) = explode(' ', microtime()); - mt_srand($sec * $usec); - - $char_widths = array(); - for ($i = 0; $i < strlen($code); $i++) - { - $char = $code{$i}; - - $width = mt_rand(0, 4); - $char_widths[] = $width; - $img_width += $_png[$char]['width'] - $width; - } - - $offset_x = mt_rand(0, $total_width - $img_width); - $offset_y = mt_rand(0, $total_height - $img_height); - - $image = ''; - $hold_chars = array(); - for ($i = 0; $i < $total_height; $i++) - { - $image .= chr(0); - - if ($i > $offset_y && $i < $offset_y + $img_height) - { - $j = 0; - - for ($k = 0; $k < $offset_x; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - - for ($k = 0; $k < strlen($code); $k++) - { - $char = $code{$k}; - - if (empty($hold_chars[$char])) - { - $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); - } - $image .= $this->randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j]); - $j++; - } - - for ($k = $offset_x + $img_width; $k < $total_width; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - - $l++; - } - else - { - for ($k = 0; $k < $total_width; $k++) - { - $image .= chr(mt_rand(140, 255)); - } - } - - } - unset($hold); - - $image = $this->create_png($image, $total_width, $total_height); + $this->session_data[$key] = $value; + } + + /** + * Commits changes to the session data set to the database. + */ + + function session_commit() + { + global $db, $session, $paths, $template, $plugins; // Common objects + $session_data = serialize($this->session_data); + $session_data = $db->escape($session_data); + $code = $db->escape($this->code); + + $q = $db->sql_query('UPDATE ' . table_prefix . "captcha SET code = '$code', session_data = '$session_data' WHERE code_id = {$this->id};"); + if ( !$q ) + $db->_die(); + } + + /** + * Changes the confirmation code + * @param string New string + */ - // Output image - header('Content-Type: image/png'); - header('Cache-control: no-cache, no-store'); - echo $image; - - unset($image); - unset($_png); - } elseif(defined('ENANO_CAPTCHA_BIGNFAT')) { - // Prefs - $total_width = $this->captcha_config['width']; - $total_height = $this->captcha_config['height']; - - $hex_bg_color = $this->get_rgb($this->captcha_config['background_color']); - $bg_color = array(); - $bg_color = explode(",", $hex_bg_color); - - $jpeg = $this->captcha_config['jpeg']; - $img_quality = $this->captcha_config['jpeg_quality']; - // Max quality is 95 - - $pre_letters = $this->captcha_config['pre_letters']; - $pre_letter_great = $this->captcha_config['pre_letters_great']; - $rnd_font = $this->captcha_config['font']; - $chess = $this->captcha_config['chess']; - $ellipses = $this->captcha_config['ellipses']; - $arcs = $this->captcha_config['arcs']; - $lines = $this->captcha_config['lines']; - $image = $this->captcha_config['image']; - - $gammacorrect = $this->captcha_config['gammacorrect']; - - $foreground_lattice_y = $this->captcha_config['foreground_lattice_y']; - $foreground_lattice_x = $this->captcha_config['foreground_lattice_x']; - $hex_lattice_color = $this->get_rgb($this->captcha_config['lattice_color']); - $rgb_lattice_color = array(); - $rgb_lattice_color = explode(",", $hex_lattice_color); - - $font_debug = false; - - // Fonts and images init - if ($image) - { - $bg_imgs = array(); - if ($img_dir = opendir(ENANO_ROOT.'/includes/captcha/pics/')) - { - while (true == ($file = @readdir($img_dir))) - { - if ((substr(strtolower($file), -3) == 'jpg') || (substr(strtolower($file), -3) == 'gif')) - { - $bg_imgs[] = $file; - } - } - closedir($img_dir); - } - // Grab a random Background Image or set FALSE if none was found - $bg_img = ( count($bg_imgs) ) ? rand(0, (count($bg_imgs)-1)) : false; - } - - $fonts = array(); - if ($fonts_dir = opendir(ENANO_ROOT.'/includes/captcha/fonts/')) - { - while (true == ($file = @readdir($fonts_dir))) - { - if ((substr(strtolower($file), strlen($file)-3, strlen($file)) == 'ttf')) - { - $fonts[] = $file; - } - } - closedir($fonts_dir); - } else { - die('Error reading directory: '.ENANO_ROOT.'/includes/captcha/fonts/'); - } - $font = rand(0, (count($fonts)-1)); - - // Generate - $image = ($this->gdVersion() >= 2) ? imagecreatetruecolor($total_width, $total_height) : imagecreate($total_width, $total_height); - $background_color = imagecolorallocate($image, $bg_color[0], $bg_color[1], $bg_color[2]); - imagefill($image, 0, 0, $background_color); - - // Generate backgrund - if ($chess == '1' || $chess == '2' && rand(0,1)) - { - // Draw rectangles - for($i = 0; $i <= 8; $i++) - { - $rectanglecolor = imagecolorallocate($image, rand(100,200),rand(100,200),rand(100,200)); - imagefilledrectangle($image, 0, 0, round($total_width-($total_width/8*$i)), round($total_height), $rectanglecolor); - $rectanglecolor = imagecolorallocate($image, rand(100,200),rand(100,200),rand(100,200)); - imagefilledrectangle($image, 0, 0, round($total_width-($total_width/8*$i)), round($total_height/2), $rectanglecolor); - } - } - if ($ellipses == '1' || $ellipses == '2' && rand(0,1)) - { - // Draw random ellipses - for ($i = 1; $i <= 60; $i++) - { - $ellipsecolor = imagecolorallocate($image, rand(100,250),rand(100,250),rand(100,250)); - imagefilledellipse($image, round(rand(0, $total_width)), round(rand(0, $total_height)), round(rand(0, $total_width/8)), round(rand(0, $total_height/4)), $ellipsecolor); - } - } - if ($arcs == '1' || $arcs == '2' && rand(0,1)) - { - // Draw random partial ellipses - for ($i = 0; $i <= 30; $i++) - { - $linecolor = imagecolorallocate($image, rand(120,255),rand(120,255),rand(120,255)); - $cx = round(rand(1, $total_width)); - $cy = round(rand(1, $total_height)); - $int_w = round(rand(1, $total_width/2)); - $int_h = round(rand(1, $total_height)); - imagearc($image, $cx, $cy, $int_w, $int_h, round(rand(0, 190)), round(rand(191, 360)), $linecolor); - imagearc($image, $cx-1, $cy-1, $int_w, $int_h, round(rand(0, 190)), round(rand(191, 360)), $linecolor); - } - } - if ($lines == '1' || $lines == '2' && rand(0,1)) - { - // Draw random lines - for ($i = 0; $i <= 50; $i++) - { - $linecolor = imagecolorallocate($image, rand(120,255),rand(120,255),rand(120,255)); - imageline($image, round(rand(1, $total_width*3)), round(rand(1, $total_height*5)), round(rand(1, $total_width/2)), round(rand(1, $total_height*2)), $linecolor); - } - } - - $text_color_array = array('255,51,0', '51,77,255', '204,51,102', '0,153,0', '255,166,2', '255,0,255', '255,0,0', '0,255,0', '0,0,255', '0,255,255'); - shuffle($text_color_array); - $pre_text_color_array = array('255,71,20', '71,20,224', '224,71,122', '20,173,20', '255,186,22', '25,25,25'); - shuffle($pre_text_color_array); - $white = imagecolorallocate($image, 255, 255, 255); - $gray = imagecolorallocate($image, 100, 100, 100); - $black = imagecolorallocate($image, 0, 0, 0); - $lattice_color = imagecolorallocate($image, $rgb_lattice_color[0], $rgb_lattice_color[1], $rgb_lattice_color[2]); - - $x_char_position = (round(($total_width - 12) / strlen($code)) + mt_rand(-3, 5)); - - for ($i = 0; $i < strlen($code); $i++) - { - mt_srand((double)microtime()*1000000); - - $char = $code{$i}; - $size = mt_rand(floor($total_height / 3.5), ceil($total_height / 2.8)); - $font = ($rnd_font) ? rand(0, (count($fonts)-1)) : $font; - $angle = mt_rand(-30, 30); - - $char_pos = array(); - $char_pos = imagettfbbox($size, $angle, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - $letter_width = abs($char_pos[0]) + abs($char_pos[4]); - $letter_height = abs($char_pos[1]) + abs($char_pos[5]); - - $x_pos = ($x_char_position / 4) + ($i * $x_char_position); - ($i == strlen($code)-1 && $x_pos >= ($total_width - ($letter_width + 5))) ? $x_pos = ($total_width - ($letter_width + 5)) : ''; - $y_pos = mt_rand(($size * 1.4 ), $total_height - ($size * 0.4)); - - // Pre letters - $size = ($pre_letter_great) ? $size + (2 * $pre_letters) : $size - (2 * $pre_letters); - for ($count = 1; $count <= $pre_letters; $count++) - { - $pre_angle = $angle + mt_rand(-20, 20); - - $text_color = $pre_text_color_array[mt_rand(0,count($pre_text_color_array)-1)]; - $text_color = explode(",", $text_color); - $textcolor = imagecolorallocate($image, $text_color[0], $text_color[1], $text_color[2]); - - imagettftext($image, $size, $pre_angle, $x_pos, $y_pos-2, $white, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - imagettftext($image, $size, $pre_angle, $x_pos+2, $y_pos, $black, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - imagettftext($image, $size, $pre_angle, $x_pos+1, $y_pos-1, $textcolor, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - - $size = ($pre_letter_great) ? $size - 2 : $size + 2; - } - - // Final letters - $text_color = $text_color_array[mt_rand(0,count($text_color_array)-1)]; - $text_color = explode(",", $text_color); - $textcolor = imagecolorallocate($image, $text_color[0], $text_color[1], $text_color[2]); - - imagettftext($image, $size, $angle, $x_pos, $y_pos-2, $white, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - imagettftext($image, $size, $angle, $x_pos+2, $y_pos, $black, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - imagettftext($image, $size, $angle, $x_pos+1, $y_pos-1, $textcolor, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); - } - - - ($gammacorrect) ? imagegammacorrect($image, 1.0, $gammacorrect) : ''; - - // Generate a white lattice in foreground - if ($foreground_lattice_y) - { - // x lines - $ih = round($total_height / $foreground_lattice_y); - for ($i = 0; $i <= $ih; $i++) - { - imageline($image, 0, $i*$foreground_lattice_y, $total_width, $i*$foreground_lattice_y, $lattice_color); - } - } - if ($foreground_lattice_x) - { - // y lines - $iw = round($total_width / $foreground_lattice_x); - for ($i = 0; $i <= $iw; $i++) - { - imageline($image, $i*$foreground_lattice_x, 0, $i*$foreground_lattice_x, $total_height, $lattice_color); - } - } - - // Font debug - if ($font_debug && !$rnd_font) - { - imagestring($image, 5, 2, 0, $fonts[$font], $white); - imagestring($image, 5, 5, 0, $fonts[$font], $white); - imagestring($image, 5, 4, 2, $fonts[$font], $gray); - imagestring($image, 5, 3, 1, $fonts[$font], $black); - } - - // Display - header("Last-Modified: " . gmdate("D, d M Y H:i:s") ." GMT"); - header("Pragma: no-cache"); - header("Cache-Control: no-store, no-cache, max-age=0, must-revalidate"); - (!$jpeg) ? header("Content-Type: image/png") : header("Content-Type: image/jpeg"); - - (!$jpeg) ? imagepng($image) : imagejpeg($image, '', $img_quality); - imagedestroy($image); - } else { - /** - * The next part is orginnaly written by ted from mastercode.nl and modified for use in Enano. - **/ - header("content-type:image/png"); - header('Cache-control: no-cache, no-store'); - $breedte = 320; - $hoogte = 60; - $img = imagecreatetruecolor($breedte,$hoogte); - $achtergrond = imagecolorallocate($img, $this->color("bg"), $this->color("bg"), $this->color("bg")); - - imagefilledrectangle($img, 0, 0, $breedte-1, $hoogte-1, $achtergrond); - for($g = 0;$g < 30; $g++) - { - $t = $this->dss_rand(); - $t = $t[0]; - - $ypos = rand(0,$hoogte); - $xpos = rand(0,$breedte); - - $kleur = imagecolorallocate($img, $this->color("bgtekst"), $this->color("bgtekst"), $this->color("bgtekst")); - - imagettftext($img, $this->size(), $this->move(), $xpos, $ypos, $kleur, $this->font(), $t); - } - $stukje = $breedte / (strlen($code) + 3); - - for($j = 0;$j < strlen($code); $j++) - { - - - $tek = $code[$j]; - $ypos = rand(33,43); - $xpos = $stukje * ($j+1); - - $kleur2 = imagecolorallocate($img, $this->color("tekst"), $this->color("tekst"), $this->color("tekst")); - - imagettftext($img, $this->size(), $this->move(), $xpos, $ypos, $kleur2, $this->font() , $tek); - } - - imagepng($img); + function set_code($code) + { + if ( !is_string($code) ) + return false; + + $this->code = $code; + } + + /** + * Returns the confirmation code + * @return string + */ + + function get_code() + { + return $this->code; + } + +} + +/** + * Returns a new captcha object + * @param string Session ID + * @param string Optional - engine to load + * @param array Optional row to send to the captcha engine + */ + +function captcha_object($session_id, $engine = false, $row = false) +{ + static $singletons = array(); + if ( !$engine ) + { + $engine = getConfig('captcha_engine'); + if ( !$engine ) + { + $engine = 'bc'; } } - /** - * Some functions :) - * Also orginally written by mastercode.nl - **/ - /** - * Function to create a random color - * @param $type string Mode for the color - * @return int - **/ - function color($type) - { - switch($type) - { - case "bg": - $kleur = rand(224,255); - break; - case "tekst": - $kleur = rand(0,127); - break; - case "bgtekst": - $kleur = rand(200,224); - break; - default: - $kleur = rand(0,255); - break; - } - return $kleur; - } - /** - * Function to ranom the size - * @return int - **/ - function size() - { - $grootte = rand(14,30); - return $grootte; - } - /** - * Function to random the posistion - * @return int - **/ - function move() - { - $draai = rand(-25,25); - return $draai; - } - /** - * Function to return a ttf file from fonts map - * @return string - **/ - function font() + if( !extension_loaded("gd") || !function_exists("gd_info") || !function_exists('imagettftext') ) { - $f = @opendir(ENANO_ROOT . '/includes/captcha/fonts/'); - if(!$f) die('Can\'t open '.ENANO_ROOT.'/includes/captcha/fonts/ for reading'); - $ar = array(); - while(($file = @readdir($f)) !== false) - { - if(!in_array($file, array('.','..')) && strstr($file, '.ttf')) - { - $ar[] = $file; - } - } - if(count($ar)) - { - shuffle($ar); - $i = rand(0,(count($ar) - 1)); - return ENANO_ROOT . '/includes/captcha/fonts/' . $ar[$i]; - } + $engine = 'failsafe'; } - - // This is designed to randomise the pixels of the image data within - // certain limits so as to keep it readable. It also varies the image - // width a little - function randomise($scanline, $width) - { - $new_line = ''; - $start = floor($width/2); - $end = strlen($scanline) - ceil($width/2); - - for ($i = $start; $i < $end; $i++) - { - $pixel = ord($scanline{$i}); - - if ($pixel < 190) - { - $new_line .= chr(mt_rand(0, 205)); - } - else if ($pixel > 190) - { - $new_line .= chr(mt_rand(145, 255)); - } - else - { - $new_line .= $scanline{$i}; - } - } - - return $new_line; - } - - // This creates a chunk of the given type, with the given data - // of the given length adding the relevant crc - function png_chunk($length, $type, $data) - { - $raw = $type; - $raw .= $data; - $crc = crc32($raw); - $raw .= pack('C4', $crc >> 24, $crc >> 16, $crc >> 8, $crc); - - return pack('C4', $length >> 24, $length >> 16, $length >> 8, $length) . $raw; - } - - // Creates greyscale 8bit png - The PNG spec can be found at - // http://www.libpng.org/pub/png/spec/PNG-Contents.html we use - // png because it's a fully recognised open standard and supported - // by practically all modern browsers and OSs - function create_png($raw_image, $width, $height) - + if ( !class_exists("captcha_engine_$engine") ) { - // SIG - $image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10); - // IHDR - $raw = pack('C4', $width >> 24, $width >> 16, $width >> 8, $width); - $raw .= pack('C4', $height >> 24, $height >> 16, $height >> 8, $height); - $raw .= pack('C5', 8, 0, 0, 0, 0); - $image .= $this->png_chunk(13, 'IHDR', $raw); - - if (@extension_loaded('zlib')) - { - $raw_image = gzcompress($raw_image); - $length = strlen($raw_image); - } - else - { - // The total length of this image, uncompressed, is just a calculation of pixels - $length = ($width + 1) * $height; - - // Adler-32 hash generation - // Optimized Adler-32 loop ported from the GNU Classpath project - $temp_length = $length; - $s1 = 1; - $s2 = $index = 0; - - while ($temp_length > 0) - { - // We can defer the modulo operation: - // s1 maximally grows from 65521 to 65521 + 255 * 3800 - // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 - $substract_value = ($temp_length < 3800) ? $temp_length : 3800; - $temp_length -= $substract_value; - - while (--$substract_value >= 0) - { - $s1 += ord($raw_image[$index]); - $s2 += $s1; - - $index++; - } - - $s1 %= 65521; - $s2 %= 65521; - } - $adler_hash = pack('N', ($s2 << 16) | $s1); - - // This is the same thing as gzcompress($raw_image, 0) but does not need zlib - $raw_image = pack('C3v2', 0x78, 0x01, 0x01, $length, ~$length) . $raw_image . $adler_hash; - - // The Zlib header + Adler hash make us add on 11 - $length += 11; - } - - // IDAT - $image .= $this->png_chunk($length, 'IDAT', $raw_image); - - // IEND - $image .= $this->png_chunk(0, 'IEND', ''); - - return $image; + require_once ENANO_ROOT . "/includes/captcha/engine_{$engine}.php"; } - - // Each 'data' element is base64_encoded uncompressed IDAT - // png image data - function define_filtered_pngs() + if ( !class_exists("captcha_engine_$engine") ) { - $_png = array( - '0' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////olFAkBAAAGDyA4P///M31/////////////wD////////////////0dAgAAAAAAAAAAAAEcPipFGHn////////////AP//////////////6DAAAAAAAAAAAAAAAAAALSEAN+T///////////8A//////////////xAAAAAAAAAAAAAAAAAAAAAACPA/////////////wD/////////////oAAAAAAAAAAAAAAAAAAAAAAAev//////////////AP////////////8oAAAAAAAAPNj/zDAAAAAAAABD//////////////8A////////////1AAAAAAAABjw////5BAAAAAAAADo/////////////wD///////////+QAAAAAAAAbP//////QgAAAAAAAKj/////////////AP///////////1wAAAAAAACs/////8AXAAAAAAAAcP////////////8A////////////OAAAAAAAAND////dNwAAAAAAAABI/////////////wD///////////8gAAAAAAAA4P//7koACwAAAAAAACT/////////////AP///////////wgAAAAAAAD///VqAwaPAAAAAAAAEP////////////8A////////////AAAAAAAAAP/8kQYDavUAAAAAAAAA/////////////wD///////////8AAAAAAAAA/6kNAEru/wAAAAAAAAD/////////////AP///////////wAAAAAAAADAIwA33f//AAAAAAAAAP////////////8A////////////FAAAAAAAADYAI8D///8AAAAAAAAQ/////////////wD///////////8kAAAAAAAAAA2p////5AAAAAAAACD/////////////AP///////////0gAAAAAAAAFkfz////UAAAAAAAAQP////////////8A////////////cAAAAAAAAET1/////7AAAAAAAABo/////////////wD///////////+oAAAAAAAAXfX/////sAAAAAAAAGj/////////////AAAAALgAAAAAAAAwAAAAAAAAAAAAAAD////////////oAAAAAAAACOT////oEAAAAAAAAOD/////////////AP////////////8+AAAAAAAAKMz/zDQAAAAAAAA0//////////////8A////////////7jgAAAAAAAAAAAAAAAAAAAAAAKT//////////////wD///////////VqAwIAAAAAAAAAAAAAAAAAAAA8////////////////AP//////////rQcDaVEAAAAAAAAAAAAAAAAAKOj///////////////8A///////////nblnu/IAIAAAAAAAAAAAAAFzw/////////////////wD////////////79////+iITCAAAAAgSITg////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////w==','width' => 40), - '1' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////8BAAAAAAAP//////////////////AP////////////////////////9sAAAAAAAA//////////////////8A////////////////////////pAAAAAAAAAD//////////////////wD//////////////////////6wEAAAAAAAAAP//////////////////AP////////////////////h4AAAAAAAAAAAA//////////////////8A//////////////////ygJAAAAAAAAAAAAAD//////////////////wD//////////////9x8HAAAAAAAAAAAAAAAAP//////////////////AP//////////////AAAAAAAAAAAAAAAAAAAA//////////////////8A//////////////8AAAAAAAAAAAAAAAAAAAD//////////////////wD//////////////wAAAAAAAAR4AAAAAAAAAP//////////////////AP//////////////AAAAAAA4zP8AAAAAAAAA//////////////////8A//////////////8AAAA4sP///wAAAAAAAAD//////////////////wD//////////////yR80P//////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '2' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////okFAkCAAABCBIfNT///////////////////8A///////////////8hAgAAAAAAAAAAAAAAFTo/////////////////wD//////////////1QAAAAAAAAAAAAAAAAAACjo////////////////AP////////////+MAAAAAAAAAAAAAAAAAAAAADj///////////////8A////////////9BAAAAAAAAAAAAAAAAAAAAAAALD//////////////wD///////////+gAAAAAAAAAHjs+KwMAAAAAAAAVP//////////////AP///////////1gAAAAAAABM/////6QAAAAAAAAU//////////////8A////////////KAAAAAAAALj/////+AAAAAAAAAD//////////////wD///////////+MfGBMOCAI8P/////wAAAAAAAACP//////////////AP///////////////////////////5wAAAAAAAAw//////////////8A///////////////////////////oFAAAAAAAAHz//////////////wD/////////////////////////6CgAAAAAAAAE3P//////////////AP///////////////////////9ggAAAAAAAAAHT///////////////8A//////////////////////+0DAAAAAAAAAA8+P///////////////wD/////////////////////gAAAAAAAAAAAKOj/////////////////AP//////////////////9FAAAAAAAAAAADzw//////////////////8A/////////////////+g4AAAAAAAAAABk/P///////////////////wD////////////////oKAAAAAAAAAAMqP//////////////////////AP//////////////6CgAAAAAAAAAMNz///////////////////////8A//////////////g4AAAAAAAAAFT0/////////////////////////wD/////////////bAAAAAAAAABU/P//////////////////////////AP///////////8wAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A////////////SAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////9AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////xAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP////////////////////////////////////////////////////8=','width' => 40), - '3' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////8sGg0FAAAACA4cLz8////////////////////AP//////////////rBgAAAAAAAAAAAAAACTA//////////////////8A/////////////3QAAAAAAAAAAAAAAAAAAASs/////////////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAjc////////////////AP//////////6AwAAAAAAAAAAAAAAAAAAAAAAGT///////////////8A//////////94AAAAAAAABJDw/8g4AAAAAAAAHP///////////////wD//////////yAAAAAAAACE/////9gAAAAAAAAA////////////////AP///////////NSwiGQ4FOT//////AAAAAAAABD///////////////8A//////////////////////////+YAAAAAAAAVP///////////////wD//////////////////////P/ggAQAAAAAAATM////////////////AP////////////////////9gAAAAAAAAAAAElP////////////////8A/////////////////////0AAAAAAAAAAHLj//////////////////wD/////////////////////OAAAAAAAAAAwkPj/////////////////AP////////////////////8gAAAAAAAAAAAAINj///////////////8A/////////////////////xAAAAAAAAAAAAAAIPD//////////////wD/////////////////////uOz/4HgEAAAAAAAAhP//////////////AP///////////////////////////3wAAAAAAAAw//////////////8A////////////////////////////6AAAAAAAAAj//////////////wD/////////////////////////////AAAAAAAAAP//////////////AP//////////tJh8YEQoDNz//////+AAAAAAAAAY//////////////8A//////////88AAAAAAAAaP//////dAAAAAAAAEz//////////////wD//////////6QAAAAAAAAAdOD/5HQAAAAAAAAApP//////////////AP///////////CgAAAAAAAAAAAAAAAAAAAAAACD4//////////////8A////////////yAQAAAAAAAAAAAAAAAAAAAAEuP///////////////wD/////////////rAQAAAAAAAAAAAAAAAAABJD/////////////////AP//////////////zDQAAAAAAAAAAAAAACTA//////////////////8A/////////////////8BwOCAAAAAUNGi0/P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '4' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////////////nAAAAAAAAAD///////////////8A/////////////////////////8AEAAAAAAAAAP///////////////wD////////////////////////gGAAAAAAAAAAA////////////////AP//////////////////////9DAAAAAAAAAAAAD///////////////8A//////////////////////9UAAAAAAAAAAAAAP///////////////wD/////////////////////hAAAAAAAAAAAAAAA////////////////AP///////////////////7QAAAAAAAAAAAAAAAD///////////////8A///////////////////UDAAAAAAUAAAAAAAAAP///////////////wD/////////////////7CQAAAAABMAAAAAAAAAA////////////////AP////////////////xEAAAAAACU/wAAAAAAAAD///////////////8A////////////////cAAAAAAAZP//AAAAAAAAAP///////////////wD//////////////6AAAAAAADz8//8AAAAAAAAA////////////////AP/////////////IBAAAAAAc6P///wAAAAAAAAD///////////////8A////////////5BgAAAAADMz/////AAAAAAAAAP///////////////wD///////////g0AAAAAACk//////8AAAAAAAAA////////////////AP//////////XAAAAAAAfP///////wAAAAAAAAD///////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP///////////////////////////wAAAAAAAAD///////////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '5' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////8AAAAAAAAAAAAAAAAAAAAAAA//////////////8A///////////////MAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////6wAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////iAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////////9kAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////0QAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////IAAAAAAAYP////////////////////////////8A//////////////wAAAAAAAB8/////////////////////////////wD/////////////3AAAAAAAAIj/////////////////////////////AP////////////+4AAAAAAAAoLRYHAAEKGTE//////////////////8A/////////////5QAAAAAAAAQAAAAAAAAAABY9P///////////////wD/////////////dAAAAAAAAAAAAAAAAAAAAAA89P//////////////AP////////////9QAAAAAAAAAAAAAAAAAAAAAABg//////////////8A/////////////zAAAAAAAAAAAAAAAAAAAAAAAADQ/////////////wD/////////////IAAAAAAAAGjY/+h4BAAAAAAAAGz/////////////AP//////////////9NS0lHSc//////90AAAAAAAALP////////////8A/////////////////////////////9QAAAAAAAAE/////////////wD//////////////////////////////wAAAAAAAAD/////////////AP/////////////////////////////8AAAAAAAAEP////////////8A////////////pIRwWEAgDOD//////8wAAAAAAAA8/////////////wD///////////9EAAAAAAAAaP//////ZAAAAAAAAHz/////////////AP///////////6QAAAAAAAAAaOD/4GQAAAAAAAAE4P////////////8A/////////////CQAAAAAAAAAAAAAAAAAAAAAAGD//////////////wD/////////////yAQAAAAAAAAAAAAAAAAAAAAc7P//////////////AP//////////////rAwAAAAAAAAAAAAAAAAAGNj///////////////8A////////////////0EAAAAAAAAAAAAAAAFTo/////////////////wD//////////////////8h4QCAAAAAcQHzU////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '6' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////+0ZCwMAAAUNGjI////////////////////AP/////////////////EMAAAAAAAAAAAAABM6P////////////////8A////////////////lAQAAAAAAAAAAAAAAAAo6P///////////////wD//////////////6wAAAAAAAAAAAAAAAAAAABI////////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAACw//////////////8A/////////////3AAAAAAAAAoxP/YPAAAAAAAAEj//////////////wD////////////4EAAAAAAACOD////YDCBAVGiAoP//////////////AP///////////7gAAAAAAABY//////////////////////////////8A////////////eAAAAAAAAJT//////////////////////////////wD///////////9MAAAAAAAAvP/IXBgABCx03P//////////////////AP///////////ygAAAAAAADcdAAAAAAAAAAEiP////////////////8A////////////FAAAAAAAAFAAAAAAAAAAAAAAcP///////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAlP//////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAQ8P////////////8A////////////AAAAAAAAAABAyP/kZAAAAAAAAACQ/////////////wD///////////8MAAAAAAAALPj/////WAAAAAAAAET/////////////AP///////////yQAAAAAAACY///////MAAAAAAAAFP////////////8A////////////SAAAAAAAAMD///////wAAAAAAAAA/////////////wD///////////9wAAAAAAAAvP///////wAAAAAAAAD/////////////AP///////////7QAAAAAAACI///////UAAAAAAAAJP////////////8A////////////+AwAAAAAACDw/////2wAAAAAAABY/////////////wD/////////////cAAAAAAAADC8/Ox4AAAAAAAAAKj/////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAAAk/P////////////8A//////////////+oAAAAAAAAAAAAAAAAAAAABLj//////////////wD///////////////+QAAAAAAAAAAAAAAAAAACQ////////////////AP////////////////+0JAAAAAAAAAAAAAAkuP////////////////8A///////////////////8sGg0FAAADCxgqPz//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '7' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAABP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAy4/////////////wD//////////////////////////+QUAAAAAAAEuP//////////////AP/////////////////////////8QAAAAAAAAKT///////////////8A/////////////////////////4wAAAAAAAB0/////////////////wD////////////////////////cCAAAAAAANPz/////////////////AP///////////////////////0QAAAAAAATY//////////////////8A//////////////////////+0AAAAAAAAeP///////////////////wD//////////////////////CQAAAAAABTw////////////////////AP////////////////////+gAAAAAAAAkP////////////////////8A/////////////////////ywAAAAAABDw/////////////////////wD///////////////////+4AAAAAAAAbP//////////////////////AP///////////////////1wAAAAAAADQ//////////////////////8A///////////////////4DAAAAAAAMP///////////////////////wD//////////////////7QAAAAAAAB8////////////////////////AP//////////////////aAAAAAAAAMj///////////////////////8A//////////////////8oAAAAAAAM/P///////////////////////wD/////////////////8AAAAAAAAET/////////////////////////AP////////////////+0AAAAAAAAcP////////////////////////8A/////////////////4wAAAAAAACY/////////////////////////wD/////////////////WAAAAAAAAMD/////////////////////////AP////////////////80AAAAAAAA4P////////////////////////8A/////////////////xAAAAAAAAD4/////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '8' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////////IdDQUAAAEIEiA1P//////////////////AP/////////////////gRAAAAAAAAAAAAAAAROD///////////////8A////////////////0BgAAAAAAAAAAAAAAAAAEMj//////////////wD///////////////AcAAAAAAAAAAAAAAAAAAAAHPD/////////////AP//////////////hAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A//////////////8sAAAAAAAAKMz/zCgAAAAAAAAs/////////////wD//////////////wAAAAAAAADM////zAAAAAAAAAD/////////////AP//////////////BAAAAAAAAP//////AAAAAAAABP////////////8A//////////////8sAAAAAAAAzP///9QAAAAAAAAw/////////////wD//////////////3wAAAAAAAAoyP/YNAAAAAAAAIT/////////////AP//////////////7BgAAAAAAAAAAAAAAAAAAAAc8P////////////8A////////////////xBgAAAAAAAAAAAAAAAAAGNj//////////////wD/////////////////tAQAAAAAAAAAAAAAAACo////////////////AP///////////////HAAAAAAAAAAAAAAAAAAAAB8//////////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB8/////////////wD/////////////wAAAAAAAAABk4P/UWAAAAAAAAATQ////////////AP////////////9UAAAAAAAAaP//////XAAAAAAAAGT///////////8A/////////////xgAAAAAAADg///////cAAAAAAAAJP///////////wD/////////////AAAAAAAAAP////////8AAAAAAAAA////////////AP////////////8AAAAAAAAA4P//////3AAAAAAAAAT///////////8A/////////////ygAAAAAAABg//////9cAAAAAAAALP///////////wD/////////////ZAAAAAAAAABY1P/cXAAAAAAAAABw////////////AP/////////////QAAAAAAAAAAAAAAAAAAAAAAAABNz///////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB0/////////////wD///////////////Q8AAAAAAAAAAAAAAAAAAAAUPz/////////////AP////////////////x4CAAAAAAAAAAAAAAAEIT8//////////////8A///////////////////smFQwGAAAABg0ZKT0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - '9' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////ysYCwMAAAUNGiw/P//////////////////AP////////////////+4JAAAAAAAAAAAAAAkuP////////////////8A////////////////lAQAAAAAAAAAAAAAAAAAkP///////////////wD//////////////8AEAAAAAAAAAAAAAAAAAAAAqP//////////////AP/////////////8JAAAAAAAAAAAAAAAAAAAAAAQ7P////////////8A/////////////6wAAAAAAAAAfOz8vCwAAAAAAABw/////////////wD/////////////WAAAAAAAAHD/////7BgAAAAAAAz4////////////AP////////////8kAAAAAAAA1P//////hAAAAAAAALT///////////8A/////////////wAAAAAAAAD///////+4AAAAAAAAcP///////////wD/////////////AAAAAAAAAPz//////8AAAAAAAABI////////////AP////////////8UAAAAAAAAzP//////lAAAAAAAACT///////////8A/////////////0QAAAAAAABY//////gsAAAAAAAADP///////////wD/////////////kAAAAAAAAABw5P/IPAAAAAAAAAAA////////////AP/////////////wEAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////////+UAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////9wAAAAAAAAAAAAAFAAAAAAAAAU////////////AP////////////////+IBAAAAAAAAABw3AAAAAAAACj///////////8A///////////////////cdCwEABhcxP+8AAAAAAAATP///////////wD//////////////////////////////5AAAAAAAAB4////////////AP//////////////////////////////UAAAAAAAALj///////////8A//////////////+kgGxUQCAM2P///+AIAAAAAAAQ+P///////////wD//////////////0gAAAAAAAA42P/EKAAAAAAAAHD/////////////AP//////////////sAAAAAAAAAAAAAAAAAAAAAAQ6P////////////8A////////////////TAAAAAAAAAAAAAAAAAAAAKz//////////////wD////////////////oKAAAAAAAAAAAAAAAAASU////////////////AP/////////////////sUAAAAAAAAAAAAAAwxP////////////////8A////////////////////yHA0FAAADCxktP///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'A' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////+QAAAAAAAAAAAAAAOT/////////////////AP//////////////////kAAAAAAAAAAAAAAAkP////////////////8A//////////////////88AAAAAAAAAAAAAAA8/////////////////wD/////////////////5AAAAAAAAAAAAAAAAADk////////////////AP////////////////+QAAAAAAAAAAAAAAAAAJD///////////////8A/////////////////zwAAAAAAAAAAAAAAAAAPP///////////////wD////////////////kAAAAAAAAAAgAAAAAAAAA5P//////////////AP///////////////5AAAAAAAAAAgAAAAAAAAACQ//////////////8A////////////////PAAAAAAAAAz8HAAAAAAAADz//////////////wD//////////////+QAAAAAAAAAWP9kAAAAAAAAANz/////////////AP//////////////kAAAAAAAAACk/7wAAAAAAAAAhP////////////8A//////////////88AAAAAAAABOz//BQAAAAAAAAw/////////////wD/////////////4AAAAAAAAAA8////ZAAAAAAAAADc////////////AP////////////+EAAAAAAAAAIj///+8AAAAAAAAAIT///////////8A/////////////zAAAAAAAAAA2P////wQAAAAAAAAMP///////////wD////////////cAAAAAAAAACT//////1wAAAAAAAAA3P//////////AP///////////4QAAAAAAAAAAAAAAAAAAAAAAAAAAACE//////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAAAAAADD//////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANz/////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhP////////8A//////////8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/////////wD/////////3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc////////AP////////+EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIT///////8A/////////zAAAAAAAAAAhP///////////2QAAAAAAAAAMP///////wD////////cAAAAAAAAAADM////////////vAAAAAAAAAAA3P//////AP///////4QAAAAAAAAAHP/////////////4DAAAAAAAAACE//////8A////////MAAAAAAAAABk//////////////9cAAAAAAAAADD//////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'B' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAEDh83P///////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAEhP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAeP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAABY////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAABT///////////8A//////////8AAAAAAAAAAP/////4zEwAAAAAAAAAAP///////////wD//////////wAAAAAAAAAA////////7AAAAAAAAAAQ////////////AP//////////AAAAAAAAAAD////////sAAAAAAAAAEj///////////8A//////////8AAAAAAAAAAP/////4zEQAAAAAAAAAtP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAFz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAiA/P////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAIjPj//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAGKz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJT///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAABNz//////////wD//////////wAAAAAAAAAA///////sqCAAAAAAAAAAbP//////////AP//////////AAAAAAAAAAD/////////yAAAAAAAAAAs//////////8A//////////8AAAAAAAAAAP//////////AAAAAAAAAAT//////////wD//////////wAAAAAAAAAA/////////7wAAAAAAAAAAP//////////AP//////////AAAAAAAAAAD//////+ikGAAAAAAAAAAY//////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFT//////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsP//////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADj///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAc6P///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAATOj/////////////AP//////////AAAAAAAAAAAAAAAAAAAEIEBkkNj///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'C' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////5JRULBAAAAgkTIDQ//////////////////8A////////////////1FAAAAAAAAAAAAAAAABAyP///////////////wD//////////////4gEAAAAAAAAAAAAAAAAAAAElP//////////////AP////////////9wAAAAAAAAAAAAAAAAAAAAAAAAlP////////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAEyP///////////wD//////////9wIAAAAAAAAAAAAAAAAAAAAAAAAAAAw////////////AP//////////WAAAAAAAAAAAWMz/8JwQAAAAAAAAAACw//////////8A/////////+wEAAAAAAAAAID//////9QMAAAAAAAAAET//////////wD/////////nAAAAAAAAAAo/P///////3wAAAAABDBspP//////////AP////////9gAAAAAAAAAIz/////////3BxQjMT0//////////////8A/////////zQAAAAAAAAAzP///////////////////////////////wD/////////GAAAAAAAAADo////////////////////////////////AP////////8AAAAAAAAAAP////////////////////////////////8A/////////wAAAAAAAAAA/////////////////////////////////wD/////////AAAAAAAAAAD/////////////////////////////////AP////////8cAAAAAAAAAOj///////////////////////////////8A/////////zgAAAAAAAAA0P/////////kIGio7P///////////////wD/////////bAAAAAAAAACg/////////5wAAAAAMHS49P//////////AP////////+oAAAAAAAAAEz/////////PAAAAAAAAAAc//////////8A//////////QIAAAAAAAAALz//////6QAAAAAAAAAAGT//////////wD//////////3AAAAAAAAAADIzo/+SEBAAAAAAAAAAAyP//////////AP//////////7BAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////rAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD/////////////fAAAAAAAAAAAAAAAAAAAAAAAAJz/////////////AP//////////////iAQAAAAAAAAAAAAAAAAAAASY//////////////8A////////////////yEAAAAAAAAAAAAAAAAA8yP///////////////wD//////////////////9yIUCwQAAAAIEB4yP//////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'D' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAADChQkOT/////////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAABGjw//////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAACDY/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAABjk////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKj//////////wD///////////8AAAAAAAAAAP///+isSAAAAAAAAAAANP//////////AP///////////wAAAAAAAAAA////////hAAAAAAAAAAA2P////////8A////////////AAAAAAAAAAD/////////MAAAAAAAAACQ/////////wD///////////8AAAAAAAAAAP////////+MAAAAAAAAAFj/////////AP///////////wAAAAAAAAAA/////////8gAAAAAAAAAMP////////8A////////////AAAAAAAAAAD/////////5AAAAAAAAAAY/////////wD///////////8AAAAAAAAAAP//////////AAAAAAAAAAD/////////AP///////////wAAAAAAAAAA//////////8AAAAAAAAAAP////////8A////////////AAAAAAAAAAD//////////wAAAAAAAAAA/////////wD///////////8AAAAAAAAAAP/////////wAAAAAAAAABD/////////AP///////////wAAAAAAAAAA/////////9QAAAAAAAAAJP////////8A////////////AAAAAAAAAAD/////////qAAAAAAAAABI/////////wD///////////8AAAAAAAAAAP////////9QAAAAAAAAAHj/////////AP///////////wAAAAAAAAAA////////uAAAAAAAAAAAvP////////8A////////////AAAAAAAAAAD////w0HwEAAAAAAAAACT8/////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAADz8//////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAY6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAKNz/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAACHT0//////////////8A////////////AAAAAAAAAAAAAAAAABg4bKj0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'E' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'F' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'G' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////MB8TCgQAAAACCA4YJzs////////////////AP///////////////JQcAAAAAAAAAAAAAAAAAAhw8P////////////8A/////////////9gwAAAAAAAAAAAAAAAAAAAAAAAk2P///////////wD////////////EDAAAAAAAAAAAAAAAAAAAAAAAAAAc7P//////////AP//////////2AwAAAAAAAAAAAAAAAAAAAAAAAAAAABY//////////8A//////////wwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ/////////wD/////////kAAAAAAAAAAAEHzQ/P/gmCAAAAAAAAAAAFz/////////AP////////wcAAAAAAAAACjg////////8CwAAAAAAAAgWP////////8A////////vAAAAAAAAAAI2P//////////yBRAcJjI8P///////////wD///////94AAAAAAAAAGD/////////////////////////////////AP///////0AAAAAAAAAAsP////////////////////////////////8A////////IAAAAAAAAADc/////////////////////////////////wD///////8AAAAAAAAAAP///////wAAAAAAAAAAAAAAAAD/////////AP///////wAAAAAAAAAA////////AAAAAAAAAAAAAAAAAP////////8A////////AAAAAAAAAAD///////8AAAAAAAAAAAAAAAAA/////////wD///////8gAAAAAAAAAOD//////wAAAAAAAAAAAAAAAAD/////////AP///////0AAAAAAAAAAtP//////AAAAAAAAAAAAAAAAAP////////8A////////cAAAAAAAAABw//////8AAAAAAAAAAAAAAAAA/////////wD///////+8AAAAAAAAABDs////////////AAAAAAAAAAD/////////AP////////wYAAAAAAAAADz0//////////AAAAAAAAAAAP////////8A/////////5AAAAAAAAAAACCY4P//3KhcCAAAAAAAAAAA/////////wD/////////+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AP//////////xAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP////////8A////////////rAQAAAAAAAAAAAAAAAAAAAAAAAAAAGTw/////////wD/////////////vBQAAAAAAAAAAAAAAAAAAAAAADjI////////////AP//////////////8HAQAAAAAAAAAAAAAAAAAEiw//////////////8A//////////////////iwcEAgBAAABCA4aKDk/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'H' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'I' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'J' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAj//////////////wD//////////+zMrIxwUDAQ//////wAAAAAAAAAIP//////////////AP//////////DAAAAAAAAADo////2AAAAAAAAAA0//////////////8A//////////8wAAAAAAAAAKj///+YAAAAAAAAAFj//////////////wD//////////2gAAAAAAAAAIND/yBgAAAAAAAAAkP//////////////AP//////////vAAAAAAAAAAAAAAAAAAAAAAAAADc//////////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAUP///////////////wD////////////EBAAAAAAAAAAAAAAAAAAAABjk////////////////AP////////////+sBAAAAAAAAAAAAAAAAAAY2P////////////////8A///////////////EMAAAAAAAAAAAAAAAVOj//////////////////wD/////////////////vHBAIAAAABg8fNT/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'K' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////8AAAAAAAAAAP//////////wAQAAAAAAAAAAABw////////AP///////wAAAAAAAAAA/////////9AMAAAAAAAAAAAAcP////////8A////////AAAAAAAAAAD////////cGAAAAAAAAAAAAHD//////////wD///////8AAAAAAAAAAP//////6CgAAAAAAAAAAABs////////////AP///////wAAAAAAAAAA//////Q0AAAAAAAAAAAAVPz///////////8A////////AAAAAAAAAAD////8RAAAAAAAAAAAAFT8/////////////wD///////8AAAAAAAAAAP///1gAAAAAAAAAAABU/P//////////////AP///////wAAAAAAAAAA//9wAAAAAAAAAAAASPz///////////////8A////////AAAAAAAAAAD/jAAAAAAAAAAAADz0/////////////////wD///////8AAAAAAAAAAKQAAAAAAAAAAAA89P//////////////////AP///////wAAAAAAAAAABAAAAAAAAAAAFPT///////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAApP///////////////////wD///////8AAAAAAAAAAAAAAAAAAAAAAAAU8P//////////////////AP///////wAAAAAAAAAAAAAAAAAAAAAAAABk//////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAAAADE/////////////////wD///////8AAAAAAAAAAAAAAAAoEAAAAAAAACz8////////////////AP///////wAAAAAAAAAAAAAAGNiAAAAAAAAAAIj///////////////8A////////AAAAAAAAAAAAABjY//gYAAAAAAAACOD//////////////wD///////8AAAAAAAAAAAAY2P///5wAAAAAAAAASP//////////////AP///////wAAAAAAAAAAGNj//////CgAAAAAAAAAqP////////////8A////////AAAAAAAAAADI////////sAAAAAAAAAAc8P///////////wD///////8AAAAAAAAAAP//////////QAAAAAAAAABs////////////AP///////wAAAAAAAAAA///////////IAAAAAAAAAATI//////////8A////////AAAAAAAAAAD///////////9YAAAAAAAAADD8/////////wD///////8AAAAAAAAAAP///////////9wEAAAAAAAAAJD/////////AP///////wAAAAAAAAAA/////////////3AAAAAAAAAADOT///////8A////////AAAAAAAAAAD/////////////7BAAAAAAAAAAUP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'L' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'M' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////8AAAAAAAAAAAAAAHz//////3wAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAATP//////UAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAc//////8cAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAADw////8AAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAAALz////AAAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAAkP///5AAAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAABc////ZAAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAoAAAAADD///8wAAAAACQAAAAAAAAA////////AP//////AAAAAAAAAFwAAAAABPz//AgAAAAAXAAAAAAAAAD///////8A//////8AAAAAAAAAkAAAAAAA0P/UAAAAAACQAAAAAAAAAP///////wD//////wAAAAAAAADMAAAAAACg/6gAAAAAAMQAAAAAAAAA////////AP//////AAAAAAAAAPgEAAAAAHD/dAAAAAAE+AAAAAAAAAD///////8A//////8AAAAAAAAA/zQAAAAAQP9IAAAAADD/AAAAAAAAAP///////wD//////wAAAAAAAAD/bAAAAAAQ/xQAAAAAaP8AAAAAAAAA////////AP//////AAAAAAAAAP+gAAAAAADQAAAAAACc/wAAAAAAAAD///////8A//////8AAAAAAAAA/9QAAAAAAGgAAAAAAND/AAAAAAAAAP///////wD//////wAAAAAAAAD//wwAAAAAFAAAAAAM/P8AAAAAAAAA////////AP//////AAAAAAAAAP//RAAAAAAAAAAAADz//wAAAAAAAAD///////8A//////8AAAAAAAAA//94AAAAAAAAAAAAcP//AAAAAAAAAP///////wD//////wAAAAAAAAD//7AAAAAAAAAAAACo//8AAAAAAAAA////////AP//////AAAAAAAAAP//5AAAAAAAAAAAANz//wAAAAAAAAD///////8A//////8AAAAAAAAA////HAAAAAAAAAAQ////AAAAAAAAAP///////wD//////wAAAAAAAAD///9QAAAAAAAAAEz///8AAAAAAAAA////////AP//////AAAAAAAAAP///4gAAAAAAAAAfP///wAAAAAAAAD///////8A//////8AAAAAAAAA////vAAAAAAAAACw////AAAAAAAAAP///////wD//////wAAAAAAAAD////wAAAAAAAAAOz///8AAAAAAAAA////////AP//////AAAAAAAAAP////8sAAAAAAAc/////wAAAAAAAAD///////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'N' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAALD/////////////AAAAAAAAAP//////////AP////////8AAAAAAAAAFOj///////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAASP///////////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAkP//////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAI1P////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAw+P///////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAABw////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAC8//////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAABzs/////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAFD/////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAJz///8AAAAAAAAA//////////8A/////////wAAAAAAAAAUAAAAAAAADNz//wAAAAAAAAD//////////wD/////////AAAAAAAAALQAAAAAAAAANPz/AAAAAAAAAP//////////AP////////8AAAAAAAAA/2wAAAAAAAAAfP8AAAAAAAAA//////////8A/////////wAAAAAAAAD/+CwAAAAAAAAExAAAAAAAAAD//////////wD/////////AAAAAAAAAP//0AQAAAAAAAAgAAAAAAAAAP//////////AP////////8AAAAAAAAA////jAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////RAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP/////kFAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA//////+sAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD///////9kAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP////////QkAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA/////////8wEAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD//////////4QAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP///////////DwAAAAAAAAAAP//////////AP////////8AAAAAAAAA////////////4BAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////////////qAAAAAAAAAD//////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'O' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////0qGw4HAAAABw4aKT0/////////////////wD////////////////wcAwAAAAAAAAAAAAAAAho6P//////////////AP//////////////uBQAAAAAAAAAAAAAAAAAAAAMoP////////////8A/////////////6AEAAAAAAAAAAAAAAAAAAAAAAAAkP///////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP//////////8BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAM5P////////8A//////////9wAAAAAAAAAAAsrPD/7KQsAAAAAAAAAABg/////////wD/////////+BAAAAAAAAAAUPj///////hQAAAAAAAAAAjs////////AP////////+sAAAAAAAAABDw//////////AYAAAAAAAAAKD///////8A/////////2wAAAAAAAAAdP///////////3wAAAAAAAAAYP///////wD/////////OAAAAAAAAAC4////////////xAAAAAAAAAAw////////AP////////8cAAAAAAAAAOD////////////oAAAAAAAAABT///////8A/////////wAAAAAAAAAA//////////////8AAAAAAAAAAP///////wD/////////AAAAAAAAAAD//////////////wAAAAAAAAAA////////AP////////8AAAAAAAAAAP/////////////8AAAAAAAAAAD///////8A/////////xwAAAAAAAAA5P///////////+AAAAAAAAAAHP///////wD/////////NAAAAAAAAAC8////////////uAAAAAAAAAA4////////AP////////9oAAAAAAAAAHj///////////98AAAAAAAAAGT///////8A/////////6gAAAAAAAAAGPD/////////+BgAAAAAAAAApP///////wD/////////9AwAAAAAAAAAUPz///////xcAAAAAAAAAAjs////////AP//////////cAAAAAAAAAAALKjs//CwOAAAAAAAAAAAYP////////8A///////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzk/////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP////////////+QAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A//////////////+sEAAAAAAAAAAAAAAAAAAAAAyg/////////////wD////////////////oZAgAAAAAAAAAAAAAAARg4P//////////////AP//////////////////9KhsOCAAAAAUMFyc7P////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'P' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////wAAAAAAAAAAAAAAAAAACCxguP////////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAOOD//////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAGOD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAARP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAABo////////////AP///////////wAAAAAAAAAA////6JwMAAAAAAAAADD///////////8A////////////AAAAAAAAAAD//////6AAAAAAAAAADP///////////wD///////////8AAAAAAAAAAP//////9AAAAAAAAAAA////////////AP///////////wAAAAAAAAAA///////0AAAAAAAAAAD///////////8A////////////AAAAAAAAAAD//////5gAAAAAAAAAHP///////////wD///////////8AAAAAAAAAAP///9iICAAAAAAAAABI////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAIT/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAABU/P////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAIhPz//////////////wD///////////8AAAAAAAAAAAAAAAAABCRMkOz/////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'Q' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////SoaDQcAAAAHDhoqPT///////////////////8A//////////////BwDAAAAAAAAAAAAAAACHDo/////////////////wD///////////+4FAAAAAAAAAAAAAAAAAAAABCo////////////////AP//////////nAQAAAAAAAAAAAAAAAAAAAAAAACQ//////////////8A/////////7gEAAAAAAAAAAAAAAAAAAAAAAAAAACg/////////////wD////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzo////////////AP///////3AAAAAAAAAAACyo8P/sqCwAAAAAAAAAAGT///////////8A///////4EAAAAAAAAABM+P///////FQAAAAAAAAACPT//////////wD//////7AAAAAAAAAAFPD/////////9BgAAAAAAAAApP//////////AP//////bAAAAAAAAAB4////////////fAAAAAAAAABk//////////8A//////84AAAAAAAAALz///////////+8AAAAAAAAADT//////////wD//////xwAAAAAAAAA6P///////////+QAAAAAAAAAHP//////////AP//////AAAAAAAAAAD//////////////wAAAAAAAAAA//////////8A//////8AAAAAAAAAAP//////////////AAAAAAAAAAD//////////wD//////wAAAAAAAAAA/P////////////8AAAAAAAAAAP//////////AP//////GAAAAAAAAADg////////////4AAAAAAAAAAc//////////8A//////84AAAAAAAAALT////MJHTo//+8AAAAAAAAADT//////////wD//////2wAAAAAAAAAdP///2AAABCg/3wAAAAAAAAAZP//////////AP//////rAAAAAAAAAAY9P/sCAAAAABMGAAAAAAAAACk//////////8A///////4EAAAAAAAAABU/P+0OAAAAAAAAAAAAAAACPT//////////wD///////94AAAAAAAAAAA4sPD/gAAAAAAAAAAAAABk////////////AP////////AcAAAAAAAAAAAAAAAAAAAAAAAAAAAADOT///////////8A/////////7wEAAAAAAAAAAAAAAAAAAAAAAAAAACQ/////////////wD//////////6wEAAAAAAAAAAAAAAAAAAAAAAAAABSs////////////AP///////////7gUAAAAAAAAAAAAAAAAAAAAAAAAAABAwP////////8A//////////////BwDAAAAAAAAAAAAAAABAgAAAAAAAA8/////////wD////////////////0qGg0GAAAABgwXJjkxBgAAAAAALD/////////AP//////////////////////////////////5DQAAAAk/P////////8A////////////////////////////////////+GwAAJD//////////wD//////////////////////////////////////8A49P//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'R' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////wAAAAAAAAAAAAAAAAAAAAQgOGSk+P///////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAcuP//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEsP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ6P///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD///////////8A/////////wAAAAAAAAAA///////svDgAAAAAAAAACP///////////wD/////////AAAAAAAAAAD/////////7AAAAAAAAAAA////////////AP////////8AAAAAAAAAAP/////////cAAAAAAAAABD///////////8A/////////wAAAAAAAAAA//////DQoCQAAAAAAAAAQP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACU////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPj///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAzU/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAA02P//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAxctPz///////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAEDY/////////////////wD/////////AAAAAAAAAAD/9LAsAAAAAAAAAAzc////////////////AP////////8AAAAAAAAAAP///+wkAAAAAAAAADD8//////////////8A/////////wAAAAAAAAAA/////8QAAAAAAAAAAJD//////////////wD/////////AAAAAAAAAAD//////1QAAAAAAAAAFPD/////////////AP////////8AAAAAAAAAAP//////3AQAAAAAAAAAgP////////////8A/////////wAAAAAAAAAA////////aAAAAAAAAAAM6P///////////wD/////////AAAAAAAAAAD////////oCAAAAAAAAABs////////////AP////////8AAAAAAAAAAP////////+AAAAAAAAAAATc//////////8A/////////wAAAAAAAAAA//////////AUAAAAAAAAAFj//////////wD/////////AAAAAAAAAAD//////////5AAAAAAAAAAAND/////////AP////////8AAAAAAAAAAP//////////+CQAAAAAAAAAQP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'S' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////8vHBEIAgAAAQgQHC8/P////////////////8A////////////////pCQAAAAAAAAAAAAAAAAcoP///////////////wD//////////////FwAAAAAAAAAAAAAAAAAAAAAXP//////////////AP////////////9oAAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A////////////zAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////9cAAAAAAAAAAAAAAAAAAAAAAAAAACA////////////AP///////////xgAAAAAAAAAUOD/8KwkAAAAAAAAADj///////////8A////////////AAAAAAAAAAD0/////8wABCAgICxASP///////////wD///////////8MAAAAAAAAAMz/////////////////////////////AP///////////0AAAAAAAAAACFiQxPT///////////////////////8A////////////oAAAAAAAAAAAAAAAADBwtPT//////////////////wD////////////8QAAAAAAAAAAAAAAAAAAACFTA////////////////AP/////////////oOAAAAAAAAAAAAAAAAAAAAABM6P////////////8A///////////////4fAgAAAAAAAAAAAAAAAAAAAAY2P///////////wD/////////////////7IwwAAAAAAAAAAAAAAAAAAAo+P//////////AP/////////////////////koGw0BAAAAAAAAAAAAACU//////////8A///////////////////////////4uFgAAAAAAAAAADz//////////wD//////////2BgSEA0IBwA6P///////5QAAAAAAAAADP//////////AP//////////JAAAAAAAAACc/////////AAAAAAAAAAA//////////8A//////////9YAAAAAAAAACDo///////AAAAAAAAAABT//////////wD//////////6QAAAAAAAAAACCk7P/snBQAAAAAAAAAUP//////////AP//////////+BAAAAAAAAAAAAAAAAAAAAAAAAAAAACs//////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAAOP///////////wD////////////8RAAAAAAAAAAAAAAAAAAAAAAAABjc////////////AP/////////////0PAAAAAAAAAAAAAAAAAAAAAAg2P////////////8A///////////////8hBQAAAAAAAAAAAAAAAAMdPT//////////////wD/////////////////+LRwSCAMAAAAHDhoqPT/////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'T' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'U' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////JAAAAAAAAADk/////////+gAAAAAAAAAHP//////////AP////////9MAAAAAAAAAJz/////////nAAAAAAAAABE//////////8A/////////4gAAAAAAAAAHOj//////+ggAAAAAAAAAHz//////////wD/////////0AAAAAAAAAAAIJzs/+ykIAAAAAAAAAAA0P//////////AP//////////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A///////////IBAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAAAAJj/////////////AP////////////+UBAAAAAAAAAAAAAAAAAAAAASU//////////////8A///////////////IPAAAAAAAAAAAAAAAAAAwyP///////////////wD/////////////////0IxYOCAIAAAEIEiAyP//////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'V' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////zAAAAAAAAAAYP//////////////ZAAAAAAAAAAw////////AP//////kAAAAAAAAAAU/P////////////8UAAAAAAAAAJD///////8A///////oBAAAAAAAAADE////////////xAAAAAAAAAAE7P///////wD///////9MAAAAAAAAAHD///////////94AAAAAAAAAEz/////////AP///////6gAAAAAAAAAJP///////////yQAAAAAAAAArP////////8A////////+BAAAAAAAAAA1P/////////YAAAAAAAAABT4/////////wD/////////aAAAAAAAAACE/////////4QAAAAAAAAAbP//////////AP/////////EAAAAAAAAADT/////////OAAAAAAAAADM//////////8A//////////8kAAAAAAAAAOT//////+QAAAAAAAAAKP///////////wD//////////4QAAAAAAAAAmP//////nAAAAAAAAACI////////////AP//////////5AAAAAAAAABE//////9EAAAAAAAABOT///////////8A////////////QAAAAAAAAAT0////9AgAAAAAAABI/////////////wD///////////+gAAAAAAAAAKT///+kAAAAAAAAAKj/////////////AP////////////QIAAAAAAAAXP///1wAAAAAAAAM+P////////////8A/////////////1wAAAAAAAAM+P/8DAAAAAAAAGT//////////////wD/////////////vAAAAAAAAAC8/7wAAAAAAAAAxP//////////////AP//////////////HAAAAAAAAGj/aAAAAAAAACT///////////////8A//////////////94AAAAAAAAHP8cAAAAAAAAhP///////////////wD//////////////9gAAAAAAAAAkAAAAAAAAADk////////////////AP///////////////zgAAAAAAAAQAAAAAAAAQP////////////////8A////////////////lAAAAAAAAAAAAAAAAACg/////////////////wD////////////////sCAAAAAAAAAAAAAAADPT/////////////////AP////////////////9QAAAAAAAAAAAAAABg//////////////////8A/////////////////7AAAAAAAAAAAAAAAMD//////////////////wD//////////////////BQAAAAAAAAAAAAc////////////////////AP//////////////////cAAAAAAAAAAAAHz///////////////////8A///////////////////MAAAAAAAAAAAA3P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'W' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//8cAAAAAAAAALz/////4AAAAAAAAAAA6P////+8AAAAAAAAABz//wD//1QAAAAAAAAAjP////+gAAAAAAAAAACo/////4wAAAAAAAAAUP//AP//jAAAAAAAAABU/////2AAAAAAAAAAAGj/////VAAAAAAAAACM//8A///EAAAAAAAAACT/////IAAAAAAAAAAAKP////8kAAAAAAAAAMT//wD///gEAAAAAAAAAPD//+AAAAAAAAAAAAAA6P//8AAAAAAAAAAE9P//AP///zAAAAAAAAAAvP//oAAAAAAAAAAAAACo//+8AAAAAAAAADD///8A////bAAAAAAAAACM//9gAAAAAAAAAAAAAGT//4wAAAAAAAAAaP///wD///+kAAAAAAAAAFT//yAAAAAAAAAAAAAAIP//VAAAAAAAAACc////AP///9gAAAAAAAAAJP/gAAAAAAAAAAAAAAAA4P8kAAAAAAAAANT///8A/////xAAAAAAAAAA8KAAAAAAAAAAAAAAAACg8AAAAAAAAAAQ/////wD/////TAAAAAAAAAC8YAAAAAAAAAAAAAAAAGC8AAAAAAAAAET/////AP////+AAAAAAAAAAIwgAAAAAAAAAAAAAAAAIIwAAAAAAAAAfP////8A/////7gAAAAAAAAANAAAAAAAACwwAAAAAAAANAAAAAAAAACw/////wD/////8AAAAAAAAAAAAAAAAAAAdHgAAAAAAAAAAAAAAAAAAOz/////AP//////KAAAAAAAAAAAAAAAAAC4vAAAAAAAAAAAAAAAAAAg//////8A//////9gAAAAAAAAAAAAAAAACPj4CAAAAAAAAAAAAAAAAFj//////wD//////5QAAAAAAAAAAAAAAABE//9IAAAAAAAAAAAAAAAAkP//////AP//////0AAAAAAAAAAAAAAAAIj//4wAAAAAAAAAAAAAAADI//////8A///////8DAAAAAAAAAAAAAAAzP//1AAAAAAAAAAAAAAABPj//////wD///////88AAAAAAAAAAAAABT/////GAAAAAAAAAAAAAA0////////AP///////3QAAAAAAAAAAAAAWP////9gAAAAAAAAAAAAAHD///////8A////////sAAAAAAAAAAAAACg/////6QAAAAAAAAAAAAApP///////wD////////kAAAAAAAAAAAAAOT/////6AAAAAAAAAAAAADc////////AP////////8cAAAAAAAAAAAo////////MAAAAAAAAAAAEP////////8A/////////1QAAAAAAAAAAHD///////94AAAAAAAAAABM/////////wD/////////jAAAAAAAAAAAtP///////7wAAAAAAAAAAID/////////AP/////////EAAAAAAAAAAT0////////+AgAAAAAAAAAuP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'X' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////9UAAAAAAAAAKz///////////+sAAAAAAAAAFD/////////AP///////+QQAAAAAAAAFOT/////////8BwAAAAAAAAM5P////////8A/////////5gAAAAAAAAATP////////9kAAAAAAAAAJD//////////wD//////////0AAAAAAAAAAoP//////wAAAAAAAAAA0/P//////////AP//////////2AgAAAAAAAAQ4P////gkAAAAAAAABMz///////////8A////////////iAAAAAAAAABA////dAAAAAAAAABw/////////////wD////////////8MAAAAAAAAACU/9AEAAAAAAAAHPD/////////////AP/////////////IBAAAAAAAAAzYMAAAAAAAAACs//////////////8A//////////////90AAAAAAAAABAAAAAAAAAATP///////////////wD///////////////QgAAAAAAAAAAAAAAAAAAzg////////////////AP///////////////7wAAAAAAAAAAAAAAAAAjP////////////////8A/////////////////2AAAAAAAAAAAAAAADD8/////////////////wD/////////////////7BQAAAAAAAAAAAAEyP//////////////////AP/////////////////gDAAAAAAAAAAAAAjY//////////////////8A/////////////////0AAAAAAAAAAAAAAADj8/////////////////wD///////////////+UAAAAAAAAAAAAAAAAAJD/////////////////AP//////////////4AwAAAAAAAAAAAAAAAAADOD///////////////8A//////////////9AAAAAAAAAAAAAAAAAAAAAQP///////////////wD/////////////nAAAAAAAAAAAWAAAAAAAAAAAlP//////////////AP///////////+QQAAAAAAAAAGD/YAAAAAAAAAAM4P////////////8A////////////TAAAAAAAAAAs9P/0LAAAAAAAAABM/////////////wD//////////6AAAAAAAAAADNT////UDAAAAAAAAACg////////////AP/////////kEAAAAAAAAACg//////+gAAAAAAAAABDk//////////8A/////////0wAAAAAAAAAYP////////9gAAAAAAAAAEz//////////wD///////+oAAAAAAAAACz0//////////QsAAAAAAAAAKT/////////AP//////7BQAAAAAAAAM1P///////////9QMAAAAAAAAFOz///////8A//////9UAAAAAAAAAKD//////////////6AAAAAAAAAAVP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'Y' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////1QAAAAAAAAAAGj//////////2gAAAAAAAAAAFT///////8A////////5BAAAAAAAAAAAMT////////EAAAAAAAAAAAQ5P///////wD/////////mAAAAAAAAAAAKPj/////+CgAAAAAAAAAAJj/////////AP//////////PAAAAAAAAAAAgP////+AAAAAAAAAAAA8//////////8A///////////YCAAAAAAAAAAE2P//2AQAAAAAAAAACNj//////////wD///////////+AAAAAAAAAAAA4//84AAAAAAAAAACA////////////AP////////////woAAAAAAAAAACUlAAAAAAAAAAAKPz///////////8A/////////////8gAAAAAAAAAABAQAAAAAAAAAADI/////////////wD//////////////2wAAAAAAAAAAAAAAAAAAAAAbP//////////////AP//////////////8BwAAAAAAAAAAAAAAAAAABzw//////////////8A////////////////tAAAAAAAAAAAAAAAAAAAtP///////////////wD/////////////////VAAAAAAAAAAAAAAAAFT/////////////////AP/////////////////oEAAAAAAAAAAAAAAQ6P////////////////8A//////////////////+cAAAAAAAAAAAAAJz//////////////////wD///////////////////9AAAAAAAAAAABA////////////////////AP///////////////////9gAAAAAAAAAANj///////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - 'Z' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAQ//////////////8A/////////////////////////1AAAAAAAAAABLz//////////////wD///////////////////////98AAAAAAAAAACY////////////////AP//////////////////////pAAAAAAAAAAAaP////////////////8A/////////////////////8QIAAAAAAAAAET8/////////////////wD////////////////////gGAAAAAAAAAAo9P//////////////////AP//////////////////9CwAAAAAAAAAFNz///////////////////8A//////////////////xMAAAAAAAAAATA/////////////////////wD/////////////////eAAAAAAAAAAAnP//////////////////////AP///////////////5wAAAAAAAAAAHT///////////////////////8A///////////////ABAAAAAAAAABM/P///////////////////////wD/////////////3BQAAAAAAAAALPT/////////////////////////AP////////////QoAAAAAAAAABjg//////////////////////////8A///////////8SAAAAAAAAAAExP///////////////////////////wD//////////2wAAAAAAAAAAKD/////////////////////////////AP////////+YAAAAAAAAAAB8//////////////////////////////8A/////////wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), - ); - - return $_png; + throw new Exception("Expected but couldn't find class for captcha engine: captcha_engine_$engine"); } - - // These define base64_encoded raw png image data used - // when we cannot generate our own single png image - function define_raw_pngs() - { - $_png = array( - '0' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QKCNGXKO6AAAAB3RJTUUH0wUOEDQ6EUG1VwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAXNJREFUeNpj/M9AHGAiUt2wVvhyaqAqKyOjpG3jQwaGv+e+IUn9RwJfSjjg4iwFP1aKJD6HyyErfGGAYrquIoP5E2wK/zigu0v5wH9sChdgeKDqP1aFGhBZmxv/z0Dd4IxV4RWIpMQHIPuJAITzAqEQETx7IFQIP5CQNoJwDmALxzMQCuyjg1chnBPYwtECwr8AZN41h0p6YHOjAkTuwf//77wYuCEcFWwKOWA2fM1iZuuHcASwKYQ55c9ENuasrxgRjKlwJS+D17v/hBUeUGYwv/sfn0IRiJQZJIbxuFEFagjvSlDUQNgK2GIGqpC1JRhIfoAqxBYz0DRhn8IMJO+giKEqhMaMJBeI3AHhIKdkRPqG8DlAifqFADyasKRHO6h1Z/6fMYEwTbCmx3cWGCl8CTaFwBhGz+M2/7EpXMvOnBmIok7jBVaFz/Mi3/1pQORrhpgPyOr+M8IL0j9/gKpeLjhy5QEwoDVsYuRR3cE4IktcAJNx8cJaZBeQAAAAAElFTkSuQmCC', - '1' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMi//xxVKAAAAB3RJTUUH0wUOEDYLcqnX7wAAAAlwSFlzAAALEgAACxIB0t1+/AAAAHpJREFUeNpj/M9AHGAiUh1WhR8FGUGAsMKaD9iM/I8BlmCVwVS4hoUohT8qcNiFyv2zQIWBCIV3amRwu54RKcDRAgQ1KigIcJYK7CqR3QsCFmf+Y8qgeQakbANMAz6FKjUXECbj8zWa76nm61GFw1UhI10KqVGFNFQIADdK9Zj7PsV9AAAAAElFTkSuQmCC', - '2' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMwPUBEjoAAAAB3RJTUUH0wUOEDUqFe2UcgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAQxJREFUeNpj/M9AHGAiUt2owkGrkAWF93LFgStPfjCwyGiYRGijqfyPAH9aOJAkQl78RwbICkNQjdB4gUNhD7qzLLAr/CKA4YENSAoRvl7zAUJXvPmxhgfCXILVMxEQvg+IDVUhgtVqDYjkDhD7B2aQIMIx5cOTN29evLAAsaEKObBajQzmQOQMcIQjHLwQgSisIaDwBdS5LHfwK7yhAHVVyX+8CrdAA5HB5gdehQ3Yoxpd4ZcAmDqbD//xKISEIjhU//zHoxDmXQaeFRhOZ8CmzuDOf3wKf8DsDfnyH6/CHJi6P//xKjyDJethVehBpMI7DPgVwrPCCgb8AK5wDwGFcNMF8EkCASOx1QcAGUxu1untnFIAAAAASUVORK5CYII=', - '3' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMxBQugk2AAAAB3RJTUUH0wUOEDU3duv4qwAAAAlwSFlzAAALEgAACxIB0t1+/AAAATdJREFUeNpj/M9AHGAiUt0IVciCzPm7ZceZB28YGBQkLHwcmNFU/keANRJI4ioH/qMAJIUlaHatwaFwBrqrOO5gVfiCB8P9KVgVVkAtnPDh/wkLCFsGq0IFiGQLiH0D06P/GWHJ7O+NOzfuXLlzQRrEhgSawHscwYPurxAcwQMBf/4/aIAYyHIGr8IEeDhO+Y9XoQNUncwOVHGMRPEDSovc+IkzrpGDCQgUbuC1WgBhhsIHfAp3vPn/oIIFKfRxKQSDGohCA4IKX0DTD7YoRAWMUJ9iyQpbn4DBBWUQ5yFEDDnFw622gXAzwBxoYvfB5sYlUI0lD/4/gWWKJdgU/tHAcKjCD6y+PsGCpo4FJbaRgmcNqkqWCThTzxkTJHXo+Ro1HA9uOPHiATDlKJj4eKCVFIzDqWgGAK7GW/haPS+zAAAAAElFTkSuQmCC', - '4' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMyqWttCEAAAAB3RJTUUH0wUOEDUxn4hdngAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKBJREFUeNpj/M9AHGAiUh2FCucyQgCK4H9McIAFixwWhQ8kGIhS+MWAgTiFIQzEKWxhIE7hFgbiFF7hASkQIajwjQpInuUAIYV/XMDyU/4TUlgAlk75T0jhArCszR9CCk+AY07mxX8CCp+AY47nzH8CCn+YgOWW/CekMAYsVfMfl0JGmCBq4kNEDp2zAn0UMmItABjRvDykPTO43DgyFQIANP6pTFLWAdoAAAAASUVORK5CYII=', - '5' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMzPy3XhEAAAAB3RJTUUH0wUOEDUk8lW5dQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAQpJREFUeNpj/M9AHGAiUt2oQuIVfmREBzgU3iHWxAfEKiTaRFpZnfAfAbAr/AsxUYagiVCbeQgqhPpFYmukLCOrZupRNJUIB02BCAjAZCK+/Ed2LoJZgm6bzRfsCgMw3JWAXaEBpg8uIGSRPPMBQmXc+P+iggXCnoOQZUQK1K8PgEAjGcQs7QGL6FzG5mtkcAUiyYIQYcRRUkDTLEIWR1b4ixamQMPhrKUP3rx48eDNFXmwdyFiOthixgXqaTAnBcKpwRaOS6A6Mx78fwBVx/IAm8I/KsTGzAkWNHUyb7Ar/L8GNSlK3MCRev7/v+CApC7kBUoUoAX4yQ0nHjwAWqpiE6GNFgNDoAwHAKC2Q2lMNcCmAAAAAElFTkSuQmCC', - '6' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNAObRd4vAAAAB3RJTUUH0wUOEDUc2lcB6wAAAAlwSFlzAAALEgAACxIB0t1+/AAAATtJREFUeNpj/M9AHGAiUh2Gwq2puryMjKKmmSfRVf5HBkcMEBI+L1CkUBROYUE2QuMFLoVr0CzzwKHwhQC6szZgV1gAtfHI/xs2mEYywsPxp8QHEMVxQ56B4aaJiIKIiIRCPDZf74DwI/5jB4hwPAChbAgG+BWoExlOxkoysuqW3sUV4BoQ/p0SqARLB44AF4HIByDMKMCuEIu7phCrUOADNl/DgMOJ/09SIMwPC7B5hgfC1/kB4kRAOC7YrFaByM0Ac85AOCLYrFaBhSMIQNPlG2wBDg3HP2CSGU/MuEAoiKVXUWxB9cwPiG8UwEGSg5FCMNOjwZ4/byqgpqwgMoWr/MGeZ1agqWPZgSNz/Z+AqnDCf1wK/29B8qbKDhQpRtTE8HfLjjMP3jDwKJh4hKCGJSPNC6lRhTRWCABWpdoxd/bZ4QAAAABJRU5ErkJggg==', - '7' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNA18/fMoAAAAB3RJTUUH0wUOEDUVo4u5TwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAM9JREFUeNpj/M9AHGAiUt2oQnorZIGzGLFJIyJ40HqGhUiFPFuQ/YUFPBGBmLcDSQybwj8OEDOW/CegsAeiruQ/AYV3OMDqTP4QUugCceCN/wQUQn1a8Z+Awj8qYHUiHwgpXAAxcMJ/Qgp1wOoEPhBSuANiYM5/QgpjIAovEFL4gweszgAz0NASxZ4vYMqHYDKDBiIWhWhWa0CS1x9CVn+8AaYsmAlZfQRC6RDMChADGTQIKjxDrMI7EEoBi0JGlMJe8AOY+sFOSCEeQHQBAABCZ7xyT9fJhwAAAABJRU5ErkJggg==', - '8' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNBeBnwpSAAAAB3RJTUUH0wUOEDUOKe5wowAAAAlwSFlzAAALEgAACxIB0t1+/AAAATVJREFUeNpj/M9AHGAiUt1AKmRB459cc+DBGwYWGQ2LEG1Umf/I4IELkozLA2QpFIUXJFDMEDiBQ+EHGTR3yHzArrAFwwct2BXqQGQ1zvw/owFh6mBXCDXmDJB5BsOrjEhxzfoHIgkiGCGB9xtrgEPtOwvEV6FWY4+ZAAgVc5LhZgKEGYI9wN+gBiPu4Pl/BFWlxA1cMfN/C0rUr8AVhX8K0KyuwaEwASNmarAqPACVTXnw/0oENBFewKYQGhYZYE4MVBM2hVAvQ1LhHQhHBVsUMjIgYhCdhy3PPASTd6GOxBYz0KhOQHajDjY3pkC1Rlz5fweqjqEAm8ILGK5gYLlDZICXYI+ZLzZo6gL+4EgUfyo4kJQJtCCpQ8kKQPB2zZ47L14AU5iMgUMAN7IM43AqHwdQIQAhMPz6Gz5V/wAAAABJRU5ErkJggg==', - '9' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNCQ+T2tEAAAAB3RJTUUH0wUOEDUHUDLIBwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAUZJREFUeNpj/M9AHGAiUh26wr9rE3V5GRlFTTM3/kVT+R8Z7FBBSKjsQJFCUTiFBcWMCbgUHmBBs20FdoV/VNDUMQi8wapwDVS65s2fPToQZgFWhRFIkm8kwGyeH9gUQm2+Aua0QDhb4LJI4XgHQmmDSRMIZw+emIEENAeEcwObQhEIdQHiABRbUGPGBSIQAWL/gHqbB5tnJkC1Fjz5f8IGwxwkhR8EsCQarFE4hViF/wsQCgKgHsSu8H8HLFkUQL2rgUPh/zslOiwMEjFH/kND2geXQvQgqMAWhSjgAIRygAswIuXCpXfevHjz4M0ZdQaGhxo/wAnyBTuWmPnvARGxuPH/iAa+9Ph/A7r9Ai+wK/zvg6ZwzX8cCl9oICtjmfIfl8L/bwIQ6gyO/Met8P//EwUmwHTJo5OyBU2CkdaF1KhCWisEAM/sJxmZkdWnAAAAAElFTkSuQmCC', - 'A' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QFwy1U7TfAAAAB3RJTUUH0wUOEC0ZKCZtPQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAO1JREFUeNrt1LERwiAUBuAHZ2GRwsIypQMwQEZwgBQpM4QDZBSLFI7gCA5gQWGRdA5gkTuMSh48eMTUnq96wH98B+QiDCwruTD3D76qF676ueAp0Y9lSBXeSkFWaLAje3T+kkzK4SgpBzZw8pqxJWcdOJuRsyGPbWDk0tS20zw9SXsobdfytJVXdzNsP61i6Zt3K7Ht0UeUgbPdjsrOXMd+2IS2C2qb271HVWi7YANcNXFQsUEVBTXwNdl46jYRxPl52dnwRUZbhkLSDmS8DnxFRWiULxg8UxvobefuRR8ZQYDKtffVVcQWv/RrfgJC4bd0upw4MQAAAABJRU5ErkJggg==', - 'B' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGAusrz2zAAAAB3RJTUUH0wUOEC01Gv4B3gAAAAlwSFlzAAALEgAACxIB0t1+/AAAANJJREFUeNpj/M9AHGAiUh0tFTKiAUHL2rsoKv9DARZDWFr+IwA+hQwMFcQqZDhCrMIIYhWK4FYIYv8444PuV+wK//9/A+UJwBUSCHAL3OEIsdoFyttCpGdiiAtHjoY/RCnk6PlBbBRKrCE6CqcQq5DlDs5whIT3CgUI788EvOEIBCegXB2YPCNMBSNMISqf5TeUjysK90LpP/itfrFEAhZCMHkWdKMYUbk2MAah7BqD02pUYEFkgMu8IE6hD0IdpmegwSejoKLjoY7syaFU7A0HhQA2e4cJytImvAAAAABJRU5ErkJggg==', - 'C' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGBbPqVFqAAAAB3RJTUUH0wUOEC4BEGemqAAAAAlwSFlzAAALEgAACxIB0t1+/AAAASlJREFUeNpj/M9AHGAiUt2owkGrkAWV+3TDgRtPPjBwyGiYBOijSv1HAlcCkGUcTiDLISvsQDOeZQp2hQWYDpuCTeEEbD44ganwDgc2vxpgKoyAyUWc+f9hjgCMtwFd4RuYRxog/ueBcl3QFc6BSmj8gfBrwE40yFmCrjABqrAH5mSZgJ4jX7AEjwlU4Zn/OAAsrp9AaRlccc0IzdeMsBilOPWQrBDmtpfEKnwBpZ8qZq58i6IS6vscKHcBcgQYlOz4gh6OK6AKfaB8G5hN6Aq/wBLPHjB3CczCFIzUA0u2PD0v/j9pgaf1ExgK3wgwYAEOWFL4GizqWC5gyzM1mArnEJkLZ2DPhf//n3BAVmeDkq8ZUZPL3TUn7gBLCgYFBYsAcxQZRmKrDwABNsv9SJSDwwAAAABJRU5ErkJggg==', - 'D' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGC1+orhOAAAAB3RJTUUH0wUOEC4yr7fHvgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAM9JREFUeNpj/M9AHGAiUt1AKmSBsxiRhXlkNBxCpFFU/ocBTDMyPvxHADwKGRgUbhCpkEHiCZEKGRyIVciwArdCIPPFGg8YzwSvQiBogXFvEFD43wDKnQDl44yZGCh9glAU2sCsJqRQBkq/gMUw3G2wuP6PnU/H9PgRSgsQUvgESosQUngFSqsQUrgCSsNiCFcU7oBx9+CL6w8XamB5SeUPkelxAZEJ1+YPcQolXhCXFTTuEJULOUq+IOVrFgasQELBxMaHG1mEcTiVjwOoEADAIkCnGpmJKgAAAABJRU5ErkJggg==', - 'E' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGDeDwEE0AAAAB3RJTUUH0wUOEC8CkHXGUwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD5JREFUeNpj/M9AHGAiUt2owkGrkAXGYMQqjUgJQ8EzpPsa05+D140oMYTk4KEQ4MMqZqgUhcM1czESW30AABfqB1XDnLzcAAAAAElFTkSuQmCC', - 'F' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGQe8AkDZAAAAB3RJTUUH0wUOEC8JB6cf2wAAAAlwSFlzAAALEgAACxIB0t1+/AAAADlJREFUeNpj/M9AHGAiUt3wUsiCYDJikUYE3lDwDDm+xvTp4HUjIoaQXTsUAnxYxcyoQryAcUSWuAAW/gZTg/yEMAAAAABJRU5ErkJggg==', - 'G' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGRFI1vWIAAAAB3RJTUUH0wUOEC8QY8y3GwAAAAlwSFlzAAALEgAACxIB0t1+/AAAASZJREFUeNpj/M9AHGAiUt0IVciCwvt7ZM+FOy8+MDBwSEho2AQII8v9R4A/U2RQtHEUfEBIIim8YYBhn8oNLAqP8GBxmcwbDIU3sKljYIhAV/jHgAE7uICmcAJMQqDmwp//D2YowPgxqAr/wPyr8QAi8EEHwleIQFW4BxYicG+eEHEomHECET5QhRVQhQn/cQFoFJ6AKgwgFNcPoFwdnAoZIXmGERahKDwkIdqlR1j4PiRW4RVCCmExvQenQrSYEXiDiAoUBfC4loAK23yBSnzArhCRehRmAJPFnRUxHDgU/lDA7zZECj/Cgl2dAkaeWYNVZcoHDIX/94hgKLM4gS27/v9QIICizGMDkiQjSon7c8eBCw+e/GFgkZEwsHCRRpZiHE5FMwCa2YE+WcAOUwAAAABJRU5ErkJggg==', - 'H' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGRw2Z4k1AAAAB3RJTUUH0wUOEC8agxleBQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD1JREFUeNpj/M9AHGAiUt2oQvyABUozQml4+KMLDAXPDAWFLGh8RlwKh4JnaB88GOlxELhxVCFewDgEynAAN2sFVHAvevkAAAAASUVORK5CYII=', - 'I' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGSlg1E0WAAAAB3RJTUUH0wUOEC86uHd+zQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD5JREFUeNpj/M9AHGAiUt1AKmRBMBkxJJE9OhQ8Q32FjGhxDQsjjCQwFDwzqnCwKkRKZqO5EBMwDqcSl2iFAMMeB0s/kLo2AAAAAElFTkSuQmCC', - 'J' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGywiiNsbAAAAB3RJTUUH0wUOEDAFw0tdbgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKdJREFUeNpj/M9AHGAiUh3xClmwijJCaSR3Ud/qUYWjCklTyIHEhifctw8ePHgCxO+B7L9QMQlsChW+QOiX4gwMd6BiItisVoHSB6AYWQwM/kNBBszkC/9PwKyc8B8B4Ar3YPHMHWwK/xtgqAv4j1XhEfScK/EEu8L/a1BVStz4j0Ph/yPItoe8QFH3nxGlkNq75cKDB0DDVBwitNEcwjhwpdmoQrwAAN6ioiFapgUdAAAAAElFTkSuQmCC', - 'K' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHAEoFhGpAAAAB3RJTUUH0wUOEDANzZDVXAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAPZJREFUeNpj/M9AHGAiUt2owgFSyAgFMOGDrDARxkKo0H8wYEDh/b/AAzepACqEVeEdCQx1WBW+0ICry/mPR+EXE7i6kD94FP5xwaYOi8IIrOowFRbA1Xkgq8NQ2ANXZ/PlPx6FS3CpQ1fIAmOIoKn7jxbXf2CMNxvQIxvVRAQQ+YDXaiSQQqxChiOEFGoIQGidP/gVStxogLI68CqUuPH/BzSVcTzAoxCo7v//ObBIxK0QrO7/H1iCXIFT4QkIFxbaMh9wKYQJO0D5OYQUnoDF/QkCCuHJ1+APAYV3YOloAgGF8JTO84SAwjfQiGQIgPAZqV4rAACnKSarzdlc4gAAAABJRU5ErkJggg==', - 'L' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHA64qQw4AAAAB3RJTUUH0wUOEDAXMPIsJgAAAAlwSFlzAAALEgAACxIB0t1+/AAAADlJREFUeNpj/M9AHGAiUt2QUMiCYDJCaezhMBQ8M6pwVCEdFLJgCjEisRH5Zyh4hvoKGUdkQUq0QgARaARRV9jUFQAAAABJRU5ErkJggg==', - 'M' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHBhMfblpAAAAB3RJTUUH0wUOEDAqaJpgNwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAPNJREFUeNrdlK0OgzAUhS8bCQYxMYmcmEAgEAgejQfZQyG2pAIxOYlATkAu691o2tvSYia2iv7lyzn3NG0jhG1tt5H7Aggom7ZuaKPhBFqKV+pFWDGjjcxStEAYXuvBkrKtoVX+gdRiK9i6sxjgeVGUMJzWwZLACaZOTqoAOAronmrlBuvPkQsIgHn8BqnE2AMmhaaYJ57jqTRFMwsDyW249XaJLhAujizm7UFM5XCUXTqiTvBLQYWRc7H3WWt+3NmlyGbOGh9q/45mjQxUb+CA6A2jSqu5MweX0ooQWLJxLYx6fz0GwmBOsww5GP3At/dX4Ayb7qpFI9y5ygAAAABJRU5ErkJggg==', - 'N' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHC6DxyzwAAAAB3RJTUUH0wUOEDAye/b4YQAAAAlwSFlzAAALEgAACxIB0t1+/AAAALRJREFUeNpj/M9AHGAiUt0IV8gIARsRMlAROP8/BEB5Ii/+/0cVgXNRhRk8iFXIMIFYhRxXiFTIYPCDSIUMBcQqZNhDrEKZN0QqZAggViHDHIIKRSAUzx1CCrdAaZM/BBT+z4Eyaggp/KEDYbAcIaDw/wUWCEuBkML/PagBgFvhfxdiFT4RIVLh/zXEKvyfQqzCLypEKvx/hoVIhf9biFX4x4ZIhf8fCBCp8P8KNBHG4VQ0AwDEOyeZhO5p1AAAAABJRU5ErkJggg==', - 'O' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHQExDSDoAAAAB3RJTUUH0wUOEDA4myMRfwAAAAlwSFlzAAALEgAACxIB0t1+/AAAATtJREFUeNpj/M9AHGAiUt3wUsiCyv265ciZJ08YGGRkDGwCuFGk/iOBDwU8SDIcGS+Q5JAV7hBBs45nAVaFC1gwXTYBi8IdWNQxMCzAUPhBBJs6Bp4n6AoLYFI6az78f7NEB8ZNQFP4QwAqEfADwg+A+f0NqsI1UHGBDzCnSKC6EhYzB6B0Cj+UwZ+CKgNTeAZKu8C94QGlL6DGjAyU+wAeXC+gIiIQLiM0KzDC9CFCBlWICsnsL3aFMDc+hcs8QZWBKYSF2g24whvYFZpA6T1whUegNCwyoYGxAmYyLGZ+wOxYghqFX2BpO+APmP8nBspHj2uk1LPizf8PGyxgXPTUQ3x6JDqF//8/AYs6bHkGmCYF0O3FnguBCSaFA0kZS8IDJDlG1IIUVFK8eABMWzI6DgHCyDKMI7LEBQCD5YgI9wbKGgAAAABJRU5ErkJggg==', - 'P' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHQvR2Mn2AAAAB3RJTUUH0wUOEDEDMzPJGgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKVJREFUeNpj/M9AHGAiUh05ChlRAKdu4k5Ulf9hANMQiwf/EQCfQgaJB0QqZHAhViHDEbg0AV8vwRM8QN0v5vBAOSfw+BrMWQDl8MClGeEKGGEKQcRXHmQemTGD1RMy+N14o4MDyvGAS7NgGMaIzPHAYyIy4HhBZMy0EBmFIX+IUsjRgqQOi2fAgEVBwyVGGEUEQw2O3EbLzDWSFDIOhtJsVCEWAAC/Yt2X+2PYcgAAAABJRU5ErkJggg==', - 'Q' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHRxSC0wxAAAAB3RJTUUH0wUOEDEKSu9xvgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAW1JREFUeNpj/M9AHGAiUt2QUMiCzPm65cCZF08YGGRkDBx8uNFU/oeDDwU8SOIcBS/+IwOEwh0iaEYIrMCqcA4LprsmYFG4A4s6BoYFGAo/iGBTx8DzAl1hAUxKZ8WH/29W6MC4KWgKfwhAJXx+gPl/QmB+/4KqcANUXOQDVPiLBFRkCUwhJGb2wGzihzK4U6CMA6hReAbKc4F7wwFKX0CNGRkoB+HJJ1ARGZgAIziFM8J0IUIGXYjMZPaXkEJYYDyBiz+EuRFVoQKUdwWIz6qWvmRguAMVkUBVaIIUalPu9GgshIefAWrwrIHp//L/DQc4KjFiBi2uQ/7832KB5AX0uP5fAZOx2PDhfwNCIXrq+f9BhgEb4HmCkcL3YE3hSHkBnmfWYFMpsoaYXAgGDgcwFKLlaxYOCG2DqRCYrldkmIACUMIgZsaTI5Cg3IBNISp4AoovlT+EFf7/kYPkb3wK//8/YAGPGcYhUIYDAHBC9Yak1w7iAAAAAElFTkSuQmCC', - 'R' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHSkEuIgSAAAAB3RJTUUH0wUOEDEUsOBM3QAAAAlwSFlzAAALEgAACxIB0t1+/AAAAOZJREFUeNpj/M9AHGAiUh0NFLJAaUY0YRkJHYcQdmSh/xCAzRCZHf8RAJ9CBpYNRCpkEHgBV4jfMx+mEOVGIDDAaTWY82aPBZTLgV8hUCkaH6cbP8B8gxHgyODjgwstMDfiVIgWQyFE+lrhB3EBznOFuJgxuUFMXPPEbPmDpA53FH55osKMIoAe4F826MDMvPMfj9WgWFGBBeIf/Ar/H4FxJhBQ+B8WzCIfCCi8A4uvBgIK/2fA/POCgMIXHFBuDqH02ABLM3cIKPwgAuVHEFD4fwJM4AIBhT9goe4AFWAcAsXesFIIAEvJyZHTCSiTAAAAAElFTkSuQmCC', - 'S' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHTRnvuTLAAAAB3RJTUUH0wUOEDEbIF9RTAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAVZJREFUeNpj/M9AHGAiUt2oQvyABYX398CWK3de/GBgkVEw8HFgRpH7jwSWqCDLyCxAlkNS+CcG3boY7AozMB3Wgk3hGSw+4HgBl0b4egIWhT9mYPGMBFQg4MH/D2tgvrKASzPC0yMjlP7CDSTOmrDIMDDwiHBsxzSRBypw5j9WgFDoAPNAxIQjX/ApXIDsC4OCLV9wKfzjwIACOEIO4IiZFxbooePzAqvC/z9qONBUStzAqvD//zc9BqgqNX5gVwgETxbkmCClvSk4FYLdsCMCptAGI2YSGV78+PLmz5MX4mDu1ByIMM9n9JiBxe4caGChy8MZMMsUIEFyAMoVwVC4BGaEwpI3/9/MEYGlJQyFPwQYsIE1mL7GlnCR0iNSXLtgqpO4gy1mvtigq1NAxCBKgP9pEUFWxlOCnNIYUYrmn3v23Ljx5gsw88sYOPhwI0sxDoEyHAABtSc836a1EQAAAABJRU5ErkJggg==', - 'T' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHgUdTbcyAAAAB3RJTUUH0wUOEDEgkVS4aAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADdJREFUeNpj/M9AHGAiUt0IVcgCpRlxyMODeSh4hmiFjGipB+Z7jEQ1FDwzqnBU4WBSyDicimYAb/AFTaJpyH8AAAAASUVORK5CYII=', - 'U' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHhEHl2NPAAAAB3RJTUUH0wUOEDEon48wWgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKlJREFUeNpj/M9AHGAiUh3xClmgNCOUhrsEXYD6Vo8qHFVIuUIVKP0USr+E0jLoCjWg9A4ovQVNHJjUIaADZsILMPeFApRfA5X/D1N4AaZRYc6b/2+WwNQxXEBX+N8Bqxcc/mMoPMGCRR3LBUyF/2dgUTjjPxaF/6egm8ky5T9Whf9P2KCoMziBJPefEaWQurjnzIMXL34wsMhoWHiYo2hjHLjSbFQhXgAAKzejCLAOcVMAAAAASUVORK5CYII=', - 'V' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHh/gL05IAAAAB3RJTUUH0wUOEDEuduyVbwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAVNJREFUeNpj/M9AHGAiUt2owoFRaMgIAYlIMqlQMUMo/z8ITIByRP78hwMRqNgECBei8AULVPQIXN0RqAjLGwgfYrW4B1R4DdzmLVDaQxjZ6v8roDwVuIkqMK3/ka3+/0MAKn4FKn4D5uof/5GtZmCPgEpsQHNDBDsDitVwt5tA+RZQ/pn/qFYj3PQEzHsC5WnA3QyPmQQU3+5AE0VYDTfDBcxzgQbik/8YVv93gMp9AbK/cEAD8T+m1TBb/oD8veEHhs0IE2GmxADZMRAmz4//WKxGkv3DA2Gm/MeqcA/Ujj1w1hHsCv/LQKQz/megRzyawgqIvAxMRwsuhbCEAEvGT3AphEUwNCU5IEv9R8lcUH9/wAxE5HAEgjccSBI8X3CbKOyBxAnhxm3i/w1IEgdQZFA98/+PCFydDKo6VKsZmGPQ0wgOq/+fgYvfQTORkeq1AgCIAvD7+THsDgAAAABJRU5ErkJggg==', - 'W' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QFhZRKnzkAAAAB3RJTUUH0wUOEDIR66frkQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAXNJREFUeNrtlK1ywkAUhZdMZsJMKyIqKhAIBAKBiEBEVCDyCJV9iIo+Do9QGRERgUBEVCAqKhAIREVERURnTvfn3t27xSA6g+kOQ/ZkP/aec5NlBHXZSC7k/sE/AhUwoVkDPQ58/2RUQ2IC6B1XpN7MV8tg62/pUdjSDO7OwR2J0pbekpqZYlMG50bNSGwBDQ4pyV5YtCZ7mqZf1mO2IN2Jynba0XRx49pThjQCbEKWFfVRpIlBzlK4PuLdpxEWlTr4LHvYMEDOaTYS3HCW3DAJt8mmaSXYchZbOfEzkyYGZRbrEbX8qe7GMpLqFeyxV9F4fon1pwcxjxbqJpJTBPBJLoyHYSz1I3xq78aOMssepHZZHFjKhbX9/AZd6e9bsdABeyHTQXiE2PLO6PugCwiP/r1QVLYSlpXwKE1Wno7b7jY+hoWj0aegPyA9+jPrzgqwZJ0j8hhMVtElmDoD19FFPAvamc+sOXBm+KdYEzC63p/9D7Tr72kj/8qjAAAAAElFTkSuQmCC', - 'X' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHi/G9n7kAAAAB3RJTUUH0wUOEDIXAsROpAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAT9JREFUeNpj/M9AHGAiUt3IVhjKCAFr4RJroSKBMIH/YPBEAMITeQLh//8gAxHggQlAFf6fAdXnA+WnQPkT/qMp/O8AlVkA5h2A8kz+YCi8wQGREngA5PxQgXBYzvzHUPi/A2qIA5BdAmUX/Mei8I8BVHbK/wssEJbMB2wK/5+ASvPcgGlZ8x+rQriFAmghgKHwiwJKXPA8wKXw/x4UhT3/cSr8n4CkzuAPHoVvRODqWE6gyPxHTT1ffiAUCjCgAhRtDkgSFnisnoJixAScCh/wEBk8DmiucsChcA5MQQSMMQWrQlgiZ0iAByey5QiFPlBZnS//v+hgxjZc4QKYKVeAnCswby3AUAi3eAGKNoEn6Ap94A5EjXUfNIUrEA6EALgzl6AohCUGsAMhAOZMkTfICkMw3I5wZgiEyzicimYAFRFkVwgDfJ0AAAAASUVORK5CYII=', - 'Y' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHjkyIsu1AAAAB3RJTUUH0wUOEDIkvRQvsgAAAAlwSFlzAAALEgAACxIB0t1+/AAAANJJREFUeNrt1L0NgzAQBWAcUVB6AAZgBAoKhmAICoZgCAoKxmAECkbwABSUlBRILwF8duwYhFJEihJ37+6T5T9g8K6N20X3FdDDNjKKOeTIqZLtWcKBU73bCx1lPhgQNTWieY1zRLmGCZFQp1xTSSmBDUUgW754BF+GQLxAPUkMxMb0FlzUsqpKLXhxQPRqo+oIerggCvuMC7jhFJounA4gWhO2OIL6Jp/uzglHrh0fTyAaDRucQaTkUpxDQVBYDWZ/hYze6bsv/A8/DNlP/kgvwzuer4kCMGPZDgAAAABJRU5ErkJggg==', - 'Z' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHwfqWOdfAAAAB3RJTUUH0wUOEDIrLasyIwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAL5JREFUeNrl1C0OwkAQBWCWQIJEVPQIFT0GAlHBMRBIBKIHqahAIDlERY9R0UOs3ORh5qVLunmp5GfUZvczbzKzDqtltV7ofgtueHCp16h33xBGwn0KYqoTO/J868Csaj418e0cPujOkLDfmTsECcfcXOGhoC/NZQMUDBUDd5DwxiAtJGzprpCw48xVQcIhM1d6KOgLc/kIBcORgXtIeGGQOyRs6Oq0g7P92YbkRE7bRZhcwhh+6nLF5f7yx30B8Z7FgxzMWtEAAAAASUVORK5CYII=', - ); - - return $_png; - } - - // Function get_rgb by Frank Burian - // http://www.phpfuncs.org/?content=show&id=46 - function get_rgb($hex) { - $hex_array = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, - 'F' => 15); - $hex = str_replace('#', '', strtoupper($hex)); - if (($length = strlen($hex)) == 3) { - $hex = $hex{0}.$hex{0}.$hex{1}.$hex{1}.$hex{2}.$hex{2}; - $length = 6; - } - if ($length != 6 or strlen(str_replace(array_keys($hex_array), '', $hex))) - return NULL; - $rgb['r'] = $hex_array[$hex{0}] * 16 + $hex_array[$hex{1}]; - $rgb['g'] = $hex_array[$hex{2}] * 16 + $hex_array[$hex{3}]; - $rgb['b']= $hex_array[$hex{4}] * 16 + $hex_array[$hex{5}]; - return $rgb['r'].','.$rgb['g'].','.$rgb['b']; - } - - // Function gdVersion by Hagan Fox - // http://de3.php.net/manual/en/function.gd-info.php#52481 - function gdVersion($user_ver = 0) - { - if (! extension_loaded('gd')) { return; } - static $gd_ver = 0; - // Just accept the specified setting if it's 1. - if ($user_ver == 1) { $gd_ver = 1; return 1; } - // Use the static variable if function was called previously. - if ($user_ver !=2 && $gd_ver > 0 ) { return $gd_ver; } - // Use the gd_info() function if possible. - if (function_exists('gd_info')) { - $ver_info = gd_info(); - preg_match('/\d/', $ver_info['GD Version'], $match); - $gd_ver = $match[0]; - return $match[0]; - } - // If phpinfo() is disabled use a specified / fail-safe choice... - if (preg_match('/phpinfo/', ini_get('disable_functions'))) { - if ($user_ver == 2) { - $gd_ver = 2; - return 2; - } else { - $gd_ver = 1; - return 1; - } - } - // ...otherwise use phpinfo(). - ob_start(); - phpinfo(8); - $info = ob_get_contents(); - ob_end_clean(); - $info = stristr($info, 'gd version'); - preg_match('/\d/', $info, $match); - $gd_ver = $match[0]; - return $match[0]; - } - + $class = "captcha_engine_$engine"; + return new $class($session_id, $row); } -// define('ENANO_CAPTCHA_BIGNFAT', ''); - ?> diff -r d823e49e2e4e -r c433348f3628 includes/captcha/dicts/default.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/dicts/default.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,6690 @@ +get_code()); + + /** + * The next part is orginnaly written by ted from mastercode.nl and modified for use in Enano. + **/ + header("content-type:image/png"); + header('Cache-control: no-cache, no-store'); + $breedte = 320; + $hoogte = 60; + $img = imagecreatetruecolor($breedte,$hoogte); + $achtergrond = imagecolorallocate($img, $this->color("bg"), $this->color("bg"), $this->color("bg")); + + imagefilledrectangle($img, 0, 0, $breedte-1, $hoogte-1, $achtergrond); + for($g = 0;$g < 30; $g++) + { + $t = $this->dss_rand(); + $t = $t[0]; + + $ypos = rand(0,$hoogte); + $xpos = rand(0,$breedte); + + $kleur = imagecolorallocate($img, $this->color("bgtekst"), $this->color("bgtekst"), $this->color("bgtekst")); + + imagettftext($img, $this->size(), $this->move(), $xpos, $ypos, $kleur, $this->font(), $t); + } + $stukje = $breedte / (strlen($code) + 3); + + for($j = 0;$j < strlen($code); $j++) + { + + + $tek = $code[$j]; + $ypos = rand(33,43); + $xpos = $stukje * ($j+1); + + $kleur2 = imagecolorallocate($img, $this->color("tekst"), $this->color("tekst"), $this->color("tekst")); + + imagettftext($img, $this->size(), $this->move(), $xpos, $ypos, $kleur2, $this->font() , $tek); + } + + imagepng($img); + } + + /** + * Some functions :) + * Also orginally written by mastercode.nl + **/ + /** + * Function to create a random color + * @param $type string Mode for the color + * @return int + **/ + function color($type) + { + switch($type) + { + case "bg": + $kleur = rand(224,255); + break; + case "tekst": + $kleur = rand(0,127); + break; + case "bgtekst": + $kleur = rand(200,224); + break; + default: + $kleur = rand(0,255); + break; + } + return $kleur; + } + /** + * Function to ranom the size + * @return int + **/ + function size() + { + $grootte = rand(14,30); + return $grootte; + } + /** + * Function to random the posistion + * @return int + **/ + function move() + { + $draai = rand(-25,25); + return $draai; + } + + /** + * Function to return a ttf file from fonts map + * @return string + **/ + function font() + { + $f = @opendir(ENANO_ROOT . '/includes/captcha/fonts/'); + if(!$f) die('Can\'t open includes/captcha/fonts/ for reading'); + $ar = array(); + while(($file = @readdir($f)) !== false) + { + if(!in_array($file, array('.','..')) && strstr($file, '.ttf')) + { + $ar[] = $file; + } + } + if(count($ar)) + { + shuffle($ar); + $i = rand(0,(count($ar) - 1)); + return ENANO_ROOT . '/includes/captcha/fonts/' . $ar[$i]; + } + } + function dss_rand() + { + $val = microtime() . mt_rand(); + $val = md5($val . 'a'); + return substr($val, 4, 16); + } +} diff -r d823e49e2e4e -r c433348f3628 includes/captcha/engine_failsafe.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/engine_failsafe.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,313 @@ +get_code()); + // We can we will generate a single filtered png + // Thanks to DavidMJ for emulating zlib within the code :) + $_png = $this->define_filtered_pngs(); + + $total_width = 320; + $total_height = 50; + $img_height = 40; + $img_width = 0; + $l = 0; + + list($usec, $sec) = explode(' ', microtime()); + mt_srand($sec * $usec); + + $char_widths = array(); + for ($i = 0; $i < strlen($code); $i++) + { + $char = $code{$i}; + + $width = mt_rand(0, 4); + $char_widths[] = $width; + $img_width += $_png[$char]['width'] - $width; + } + + $offset_x = mt_rand(0, $total_width - $img_width); + $offset_y = mt_rand(0, $total_height - $img_height); + + $image = ''; + $hold_chars = array(); + for ($i = 0; $i < $total_height; $i++) + { + $image .= chr(0); + + if ($i > $offset_y && $i < $offset_y + $img_height) + { + $j = 0; + + for ($k = 0; $k < $offset_x; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + + for ($k = 0; $k < strlen($code); $k++) + { + $char = $code{$k}; + + if (empty($hold_chars[$char])) + { + $hold_chars[$char] = explode("\n", chunk_split(base64_decode($_png[$char]['data']), $_png[$char]['width'] + 1, "\n")); + } + $image .= $this->randomise(substr($hold_chars[$char][$l], 1), $char_widths[$j]); + $j++; + } + + for ($k = $offset_x + $img_width; $k < $total_width; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + + $l++; + } + else + { + for ($k = 0; $k < $total_width; $k++) + { + $image .= chr(mt_rand(140, 255)); + } + } + + } + unset($hold); + + $image = $this->create_png($image, $total_width, $total_height); + + // Output image + header('Content-Type: image/png'); + header('Cache-control: no-cache, no-store'); + echo $image; + + unset($image); + unset($_png); + } + // This creates a chunk of the given type, with the given data + // of the given length adding the relevant crc + function png_chunk($length, $type, $data) + { + $raw = $type; + $raw .= $data; + $crc = crc32($raw); + $raw .= pack('C4', $crc >> 24, $crc >> 16, $crc >> 8, $crc); + + return pack('C4', $length >> 24, $length >> 16, $length >> 8, $length) . $raw; + } + + // Creates greyscale 8bit png - The PNG spec can be found at + // http://www.libpng.org/pub/png/spec/PNG-Contents.html we use + // png because it's a fully recognised open standard and supported + // by practically all modern browsers and OSs + function create_png($raw_image, $width, $height) + + { + // SIG + $image = pack('C8', 137, 80, 78, 71, 13, 10, 26, 10); + // IHDR + $raw = pack('C4', $width >> 24, $width >> 16, $width >> 8, $width); + $raw .= pack('C4', $height >> 24, $height >> 16, $height >> 8, $height); + $raw .= pack('C5', 8, 0, 0, 0, 0); + $image .= $this->png_chunk(13, 'IHDR', $raw); + + if (@extension_loaded('zlib')) + { + $raw_image = gzcompress($raw_image); + $length = strlen($raw_image); + } + else + { + // The total length of this image, uncompressed, is just a calculation of pixels + $length = ($width + 1) * $height; + + // Adler-32 hash generation + // Optimized Adler-32 loop ported from the GNU Classpath project + $temp_length = $length; + $s1 = 1; + $s2 = $index = 0; + + while ($temp_length > 0) + { + // We can defer the modulo operation: + // s1 maximally grows from 65521 to 65521 + 255 * 3800 + // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 + $substract_value = ($temp_length < 3800) ? $temp_length : 3800; + $temp_length -= $substract_value; + + while (--$substract_value >= 0) + { + $s1 += ord($raw_image[$index]); + $s2 += $s1; + + $index++; + } + + $s1 %= 65521; + $s2 %= 65521; + } + $adler_hash = pack('N', ($s2 << 16) | $s1); + + // This is the same thing as gzcompress($raw_image, 0) but does not need zlib + $raw_image = pack('C3v2', 0x78, 0x01, 0x01, $length, ~$length) . $raw_image . $adler_hash; + + // The Zlib header + Adler hash make us add on 11 + $length += 11; + } + + // IDAT + $image .= $this->png_chunk($length, 'IDAT', $raw_image); + + // IEND + $image .= $this->png_chunk(0, 'IEND', ''); + + return $image; + } + + // Each 'data' element is base64_encoded uncompressed IDAT + // png image data + function define_filtered_pngs() + { + $_png = array( + '0' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////olFAkBAAAGDyA4P///M31/////////////wD////////////////0dAgAAAAAAAAAAAAEcPipFGHn////////////AP//////////////6DAAAAAAAAAAAAAAAAAALSEAN+T///////////8A//////////////xAAAAAAAAAAAAAAAAAAAAAACPA/////////////wD/////////////oAAAAAAAAAAAAAAAAAAAAAAAev//////////////AP////////////8oAAAAAAAAPNj/zDAAAAAAAABD//////////////8A////////////1AAAAAAAABjw////5BAAAAAAAADo/////////////wD///////////+QAAAAAAAAbP//////QgAAAAAAAKj/////////////AP///////////1wAAAAAAACs/////8AXAAAAAAAAcP////////////8A////////////OAAAAAAAAND////dNwAAAAAAAABI/////////////wD///////////8gAAAAAAAA4P//7koACwAAAAAAACT/////////////AP///////////wgAAAAAAAD///VqAwaPAAAAAAAAEP////////////8A////////////AAAAAAAAAP/8kQYDavUAAAAAAAAA/////////////wD///////////8AAAAAAAAA/6kNAEru/wAAAAAAAAD/////////////AP///////////wAAAAAAAADAIwA33f//AAAAAAAAAP////////////8A////////////FAAAAAAAADYAI8D///8AAAAAAAAQ/////////////wD///////////8kAAAAAAAAAA2p////5AAAAAAAACD/////////////AP///////////0gAAAAAAAAFkfz////UAAAAAAAAQP////////////8A////////////cAAAAAAAAET1/////7AAAAAAAABo/////////////wD///////////+oAAAAAAAAXfX/////sAAAAAAAAGj/////////////AAAAALgAAAAAAAAwAAAAAAAAAAAAAAD////////////oAAAAAAAACOT////oEAAAAAAAAOD/////////////AP////////////8+AAAAAAAAKMz/zDQAAAAAAAA0//////////////8A////////////7jgAAAAAAAAAAAAAAAAAAAAAAKT//////////////wD///////////VqAwIAAAAAAAAAAAAAAAAAAAA8////////////////AP//////////rQcDaVEAAAAAAAAAAAAAAAAAKOj///////////////8A///////////nblnu/IAIAAAAAAAAAAAAAFzw/////////////////wD////////////79////+iITCAAAAAgSITg////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////w==','width' => 40), + '1' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////8BAAAAAAAP//////////////////AP////////////////////////9sAAAAAAAA//////////////////8A////////////////////////pAAAAAAAAAD//////////////////wD//////////////////////6wEAAAAAAAAAP//////////////////AP////////////////////h4AAAAAAAAAAAA//////////////////8A//////////////////ygJAAAAAAAAAAAAAD//////////////////wD//////////////9x8HAAAAAAAAAAAAAAAAP//////////////////AP//////////////AAAAAAAAAAAAAAAAAAAA//////////////////8A//////////////8AAAAAAAAAAAAAAAAAAAD//////////////////wD//////////////wAAAAAAAAR4AAAAAAAAAP//////////////////AP//////////////AAAAAAA4zP8AAAAAAAAA//////////////////8A//////////////8AAAA4sP///wAAAAAAAAD//////////////////wD//////////////yR80P//////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////AAAAAAAAAP//////////////////AP////////////////////////8AAAAAAAAA//////////////////8A/////////////////////////wAAAAAAAAD//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '2' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////okFAkCAAABCBIfNT///////////////////8A///////////////8hAgAAAAAAAAAAAAAAFTo/////////////////wD//////////////1QAAAAAAAAAAAAAAAAAACjo////////////////AP////////////+MAAAAAAAAAAAAAAAAAAAAADj///////////////8A////////////9BAAAAAAAAAAAAAAAAAAAAAAALD//////////////wD///////////+gAAAAAAAAAHjs+KwMAAAAAAAAVP//////////////AP///////////1gAAAAAAABM/////6QAAAAAAAAU//////////////8A////////////KAAAAAAAALj/////+AAAAAAAAAD//////////////wD///////////+MfGBMOCAI8P/////wAAAAAAAACP//////////////AP///////////////////////////5wAAAAAAAAw//////////////8A///////////////////////////oFAAAAAAAAHz//////////////wD/////////////////////////6CgAAAAAAAAE3P//////////////AP///////////////////////9ggAAAAAAAAAHT///////////////8A//////////////////////+0DAAAAAAAAAA8+P///////////////wD/////////////////////gAAAAAAAAAAAKOj/////////////////AP//////////////////9FAAAAAAAAAAADzw//////////////////8A/////////////////+g4AAAAAAAAAABk/P///////////////////wD////////////////oKAAAAAAAAAAMqP//////////////////////AP//////////////6CgAAAAAAAAAMNz///////////////////////8A//////////////g4AAAAAAAAAFT0/////////////////////////wD/////////////bAAAAAAAAABU/P//////////////////////////AP///////////8wAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A////////////SAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////9AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////xAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP////////////////////////////////////////////////////8=','width' => 40), + '3' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////8sGg0FAAAACA4cLz8////////////////////AP//////////////rBgAAAAAAAAAAAAAACTA//////////////////8A/////////////3QAAAAAAAAAAAAAAAAAAASs/////////////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAjc////////////////AP//////////6AwAAAAAAAAAAAAAAAAAAAAAAGT///////////////8A//////////94AAAAAAAABJDw/8g4AAAAAAAAHP///////////////wD//////////yAAAAAAAACE/////9gAAAAAAAAA////////////////AP///////////NSwiGQ4FOT//////AAAAAAAABD///////////////8A//////////////////////////+YAAAAAAAAVP///////////////wD//////////////////////P/ggAQAAAAAAATM////////////////AP////////////////////9gAAAAAAAAAAAElP////////////////8A/////////////////////0AAAAAAAAAAHLj//////////////////wD/////////////////////OAAAAAAAAAAwkPj/////////////////AP////////////////////8gAAAAAAAAAAAAINj///////////////8A/////////////////////xAAAAAAAAAAAAAAIPD//////////////wD/////////////////////uOz/4HgEAAAAAAAAhP//////////////AP///////////////////////////3wAAAAAAAAw//////////////8A////////////////////////////6AAAAAAAAAj//////////////wD/////////////////////////////AAAAAAAAAP//////////////AP//////////tJh8YEQoDNz//////+AAAAAAAAAY//////////////8A//////////88AAAAAAAAaP//////dAAAAAAAAEz//////////////wD//////////6QAAAAAAAAAdOD/5HQAAAAAAAAApP//////////////AP///////////CgAAAAAAAAAAAAAAAAAAAAAACD4//////////////8A////////////yAQAAAAAAAAAAAAAAAAAAAAEuP///////////////wD/////////////rAQAAAAAAAAAAAAAAAAABJD/////////////////AP//////////////zDQAAAAAAAAAAAAAACTA//////////////////8A/////////////////8BwOCAAAAAUNGi0/P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '4' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////////////nAAAAAAAAAD///////////////8A/////////////////////////8AEAAAAAAAAAP///////////////wD////////////////////////gGAAAAAAAAAAA////////////////AP//////////////////////9DAAAAAAAAAAAAD///////////////8A//////////////////////9UAAAAAAAAAAAAAP///////////////wD/////////////////////hAAAAAAAAAAAAAAA////////////////AP///////////////////7QAAAAAAAAAAAAAAAD///////////////8A///////////////////UDAAAAAAUAAAAAAAAAP///////////////wD/////////////////7CQAAAAABMAAAAAAAAAA////////////////AP////////////////xEAAAAAACU/wAAAAAAAAD///////////////8A////////////////cAAAAAAAZP//AAAAAAAAAP///////////////wD//////////////6AAAAAAADz8//8AAAAAAAAA////////////////AP/////////////IBAAAAAAc6P///wAAAAAAAAD///////////////8A////////////5BgAAAAADMz/////AAAAAAAAAP///////////////wD///////////g0AAAAAACk//////8AAAAAAAAA////////////////AP//////////XAAAAAAAfP///////wAAAAAAAAD///////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP///////////////////////////wAAAAAAAAD///////////////8A////////////////////////////AAAAAAAAAP///////////////wD///////////////////////////8AAAAAAAAA////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '5' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////8AAAAAAAAAAAAAAAAAAAAAAA//////////////8A///////////////MAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////6wAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////iAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////////9kAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////////0QAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////////IAAAAAAAYP////////////////////////////8A//////////////wAAAAAAAB8/////////////////////////////wD/////////////3AAAAAAAAIj/////////////////////////////AP////////////+4AAAAAAAAoLRYHAAEKGTE//////////////////8A/////////////5QAAAAAAAAQAAAAAAAAAABY9P///////////////wD/////////////dAAAAAAAAAAAAAAAAAAAAAA89P//////////////AP////////////9QAAAAAAAAAAAAAAAAAAAAAABg//////////////8A/////////////zAAAAAAAAAAAAAAAAAAAAAAAADQ/////////////wD/////////////IAAAAAAAAGjY/+h4BAAAAAAAAGz/////////////AP//////////////9NS0lHSc//////90AAAAAAAALP////////////8A/////////////////////////////9QAAAAAAAAE/////////////wD//////////////////////////////wAAAAAAAAD/////////////AP/////////////////////////////8AAAAAAAAEP////////////8A////////////pIRwWEAgDOD//////8wAAAAAAAA8/////////////wD///////////9EAAAAAAAAaP//////ZAAAAAAAAHz/////////////AP///////////6QAAAAAAAAAaOD/4GQAAAAAAAAE4P////////////8A/////////////CQAAAAAAAAAAAAAAAAAAAAAAGD//////////////wD/////////////yAQAAAAAAAAAAAAAAAAAAAAc7P//////////////AP//////////////rAwAAAAAAAAAAAAAAAAAGNj///////////////8A////////////////0EAAAAAAAAAAAAAAAFTo/////////////////wD//////////////////8h4QCAAAAAcQHzU////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '6' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////+0ZCwMAAAUNGjI////////////////////AP/////////////////EMAAAAAAAAAAAAABM6P////////////////8A////////////////lAQAAAAAAAAAAAAAAAAo6P///////////////wD//////////////6wAAAAAAAAAAAAAAAAAAABI////////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAACw//////////////8A/////////////3AAAAAAAAAoxP/YPAAAAAAAAEj//////////////wD////////////4EAAAAAAACOD////YDCBAVGiAoP//////////////AP///////////7gAAAAAAABY//////////////////////////////8A////////////eAAAAAAAAJT//////////////////////////////wD///////////9MAAAAAAAAvP/IXBgABCx03P//////////////////AP///////////ygAAAAAAADcdAAAAAAAAAAEiP////////////////8A////////////FAAAAAAAAFAAAAAAAAAAAAAAcP///////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAlP//////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAQ8P////////////8A////////////AAAAAAAAAABAyP/kZAAAAAAAAACQ/////////////wD///////////8MAAAAAAAALPj/////WAAAAAAAAET/////////////AP///////////yQAAAAAAACY///////MAAAAAAAAFP////////////8A////////////SAAAAAAAAMD///////wAAAAAAAAA/////////////wD///////////9wAAAAAAAAvP///////wAAAAAAAAD/////////////AP///////////7QAAAAAAACI///////UAAAAAAAAJP////////////8A////////////+AwAAAAAACDw/////2wAAAAAAABY/////////////wD/////////////cAAAAAAAADC8/Ox4AAAAAAAAAKj/////////////AP/////////////oEAAAAAAAAAAAAAAAAAAAAAAk/P////////////8A//////////////+oAAAAAAAAAAAAAAAAAAAABLj//////////////wD///////////////+QAAAAAAAAAAAAAAAAAACQ////////////////AP////////////////+0JAAAAAAAAAAAAAAkuP////////////////8A///////////////////8sGg0FAAADCxgqPz//////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '7' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAABP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAy4/////////////wD//////////////////////////+QUAAAAAAAEuP//////////////AP/////////////////////////8QAAAAAAAAKT///////////////8A/////////////////////////4wAAAAAAAB0/////////////////wD////////////////////////cCAAAAAAANPz/////////////////AP///////////////////////0QAAAAAAATY//////////////////8A//////////////////////+0AAAAAAAAeP///////////////////wD//////////////////////CQAAAAAABTw////////////////////AP////////////////////+gAAAAAAAAkP////////////////////8A/////////////////////ywAAAAAABDw/////////////////////wD///////////////////+4AAAAAAAAbP//////////////////////AP///////////////////1wAAAAAAADQ//////////////////////8A///////////////////4DAAAAAAAMP///////////////////////wD//////////////////7QAAAAAAAB8////////////////////////AP//////////////////aAAAAAAAAMj///////////////////////8A//////////////////8oAAAAAAAM/P///////////////////////wD/////////////////8AAAAAAAAET/////////////////////////AP////////////////+0AAAAAAAAcP////////////////////////8A/////////////////4wAAAAAAACY/////////////////////////wD/////////////////WAAAAAAAAMD/////////////////////////AP////////////////80AAAAAAAA4P////////////////////////8A/////////////////xAAAAAAAAD4/////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '8' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD////////////////////IdDQUAAAEIEiA1P//////////////////AP/////////////////gRAAAAAAAAAAAAAAAROD///////////////8A////////////////0BgAAAAAAAAAAAAAAAAAEMj//////////////wD///////////////AcAAAAAAAAAAAAAAAAAAAAHPD/////////////AP//////////////hAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A//////////////8sAAAAAAAAKMz/zCgAAAAAAAAs/////////////wD//////////////wAAAAAAAADM////zAAAAAAAAAD/////////////AP//////////////BAAAAAAAAP//////AAAAAAAABP////////////8A//////////////8sAAAAAAAAzP///9QAAAAAAAAw/////////////wD//////////////3wAAAAAAAAoyP/YNAAAAAAAAIT/////////////AP//////////////7BgAAAAAAAAAAAAAAAAAAAAc8P////////////8A////////////////xBgAAAAAAAAAAAAAAAAAGNj//////////////wD/////////////////tAQAAAAAAAAAAAAAAACo////////////////AP///////////////HAAAAAAAAAAAAAAAAAAAAB8//////////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB8/////////////wD/////////////wAAAAAAAAABk4P/UWAAAAAAAAATQ////////////AP////////////9UAAAAAAAAaP//////XAAAAAAAAGT///////////8A/////////////xgAAAAAAADg///////cAAAAAAAAJP///////////wD/////////////AAAAAAAAAP////////8AAAAAAAAA////////////AP////////////8AAAAAAAAA4P//////3AAAAAAAAAT///////////8A/////////////ygAAAAAAABg//////9cAAAAAAAALP///////////wD/////////////ZAAAAAAAAABY1P/cXAAAAAAAAABw////////////AP/////////////QAAAAAAAAAAAAAAAAAAAAAAAABNz///////////8A//////////////9gAAAAAAAAAAAAAAAAAAAAAAB0/////////////wD///////////////Q8AAAAAAAAAAAAAAAAAAAAUPz/////////////AP////////////////x4CAAAAAAAAAAAAAAAEIT8//////////////8A///////////////////smFQwGAAAABg0ZKT0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + '9' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////////////ysYCwMAAAUNGiw/P//////////////////AP////////////////+4JAAAAAAAAAAAAAAkuP////////////////8A////////////////lAQAAAAAAAAAAAAAAAAAkP///////////////wD//////////////8AEAAAAAAAAAAAAAAAAAAAAqP//////////////AP/////////////8JAAAAAAAAAAAAAAAAAAAAAAQ7P////////////8A/////////////6wAAAAAAAAAfOz8vCwAAAAAAABw/////////////wD/////////////WAAAAAAAAHD/////7BgAAAAAAAz4////////////AP////////////8kAAAAAAAA1P//////hAAAAAAAALT///////////8A/////////////wAAAAAAAAD///////+4AAAAAAAAcP///////////wD/////////////AAAAAAAAAPz//////8AAAAAAAABI////////////AP////////////8UAAAAAAAAzP//////lAAAAAAAACT///////////8A/////////////0QAAAAAAABY//////gsAAAAAAAADP///////////wD/////////////kAAAAAAAAABw5P/IPAAAAAAAAAAA////////////AP/////////////wEAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A//////////////+UAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////9wAAAAAAAAAAAAAFAAAAAAAAAU////////////AP////////////////+IBAAAAAAAAABw3AAAAAAAACj///////////8A///////////////////cdCwEABhcxP+8AAAAAAAATP///////////wD//////////////////////////////5AAAAAAAAB4////////////AP//////////////////////////////UAAAAAAAALj///////////8A//////////////+kgGxUQCAM2P///+AIAAAAAAAQ+P///////////wD//////////////0gAAAAAAAA42P/EKAAAAAAAAHD/////////////AP//////////////sAAAAAAAAAAAAAAAAAAAAAAQ6P////////////8A////////////////TAAAAAAAAAAAAAAAAAAAAKz//////////////wD////////////////oKAAAAAAAAAAAAAAAAASU////////////////AP/////////////////sUAAAAAAAAAAAAAAwxP////////////////8A////////////////////yHA0FAAADCxktP///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'A' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////+QAAAAAAAAAAAAAAOT/////////////////AP//////////////////kAAAAAAAAAAAAAAAkP////////////////8A//////////////////88AAAAAAAAAAAAAAA8/////////////////wD/////////////////5AAAAAAAAAAAAAAAAADk////////////////AP////////////////+QAAAAAAAAAAAAAAAAAJD///////////////8A/////////////////zwAAAAAAAAAAAAAAAAAPP///////////////wD////////////////kAAAAAAAAAAgAAAAAAAAA5P//////////////AP///////////////5AAAAAAAAAAgAAAAAAAAACQ//////////////8A////////////////PAAAAAAAAAz8HAAAAAAAADz//////////////wD//////////////+QAAAAAAAAAWP9kAAAAAAAAANz/////////////AP//////////////kAAAAAAAAACk/7wAAAAAAAAAhP////////////8A//////////////88AAAAAAAABOz//BQAAAAAAAAw/////////////wD/////////////4AAAAAAAAAA8////ZAAAAAAAAADc////////////AP////////////+EAAAAAAAAAIj///+8AAAAAAAAAIT///////////8A/////////////zAAAAAAAAAA2P////wQAAAAAAAAMP///////////wD////////////cAAAAAAAAACT//////1wAAAAAAAAA3P//////////AP///////////4QAAAAAAAAAAAAAAAAAAAAAAAAAAACE//////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAAAAAADD//////////wD//////////9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANz/////////AP//////////hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhP////////8A//////////8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw/////////wD/////////3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc////////AP////////+EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIT///////8A/////////zAAAAAAAAAAhP///////////2QAAAAAAAAAMP///////wD////////cAAAAAAAAAADM////////////vAAAAAAAAAAA3P//////AP///////4QAAAAAAAAAHP/////////////4DAAAAAAAAACE//////8A////////MAAAAAAAAABk//////////////9cAAAAAAAAADD//////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'B' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAEDh83P///////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAEhP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAeP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAABY////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAABT///////////8A//////////8AAAAAAAAAAP/////4zEwAAAAAAAAAAP///////////wD//////////wAAAAAAAAAA////////7AAAAAAAAAAQ////////////AP//////////AAAAAAAAAAD////////sAAAAAAAAAEj///////////8A//////////8AAAAAAAAAAP/////4zEQAAAAAAAAAtP///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAFz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAiA/P////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAIjPj//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAGKz/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJT///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAABNz//////////wD//////////wAAAAAAAAAA///////sqCAAAAAAAAAAbP//////////AP//////////AAAAAAAAAAD/////////yAAAAAAAAAAs//////////8A//////////8AAAAAAAAAAP//////////AAAAAAAAAAT//////////wD//////////wAAAAAAAAAA/////////7wAAAAAAAAAAP//////////AP//////////AAAAAAAAAAD//////+ikGAAAAAAAAAAY//////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFT//////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsP//////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADj///////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAc6P///////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAATOj/////////////AP//////////AAAAAAAAAAAAAAAAAAAEIEBkkNj///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'C' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////////////5JRULBAAAAgkTIDQ//////////////////8A////////////////1FAAAAAAAAAAAAAAAABAyP///////////////wD//////////////4gEAAAAAAAAAAAAAAAAAAAElP//////////////AP////////////9wAAAAAAAAAAAAAAAAAAAAAAAAlP////////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAEyP///////////wD//////////9wIAAAAAAAAAAAAAAAAAAAAAAAAAAAw////////////AP//////////WAAAAAAAAAAAWMz/8JwQAAAAAAAAAACw//////////8A/////////+wEAAAAAAAAAID//////9QMAAAAAAAAAET//////////wD/////////nAAAAAAAAAAo/P///////3wAAAAABDBspP//////////AP////////9gAAAAAAAAAIz/////////3BxQjMT0//////////////8A/////////zQAAAAAAAAAzP///////////////////////////////wD/////////GAAAAAAAAADo////////////////////////////////AP////////8AAAAAAAAAAP////////////////////////////////8A/////////wAAAAAAAAAA/////////////////////////////////wD/////////AAAAAAAAAAD/////////////////////////////////AP////////8cAAAAAAAAAOj///////////////////////////////8A/////////zgAAAAAAAAA0P/////////kIGio7P///////////////wD/////////bAAAAAAAAACg/////////5wAAAAAMHS49P//////////AP////////+oAAAAAAAAAEz/////////PAAAAAAAAAAc//////////8A//////////QIAAAAAAAAALz//////6QAAAAAAAAAAGT//////////wD//////////3AAAAAAAAAADIzo/+SEBAAAAAAAAAAAyP//////////AP//////////7BAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////rAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD/////////////fAAAAAAAAAAAAAAAAAAAAAAAAJz/////////////AP//////////////iAQAAAAAAAAAAAAAAAAAAASY//////////////8A////////////////yEAAAAAAAAAAAAAAAAA8yP///////////////wD//////////////////9yIUCwQAAAAIEB4yP//////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'D' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////////8AAAAAAAAAAAAAAAAADChQkOT/////////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAABGjw//////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAACDY/////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAABjk////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKj//////////wD///////////8AAAAAAAAAAP///+isSAAAAAAAAAAANP//////////AP///////////wAAAAAAAAAA////////hAAAAAAAAAAA2P////////8A////////////AAAAAAAAAAD/////////MAAAAAAAAACQ/////////wD///////////8AAAAAAAAAAP////////+MAAAAAAAAAFj/////////AP///////////wAAAAAAAAAA/////////8gAAAAAAAAAMP////////8A////////////AAAAAAAAAAD/////////5AAAAAAAAAAY/////////wD///////////8AAAAAAAAAAP//////////AAAAAAAAAAD/////////AP///////////wAAAAAAAAAA//////////8AAAAAAAAAAP////////8A////////////AAAAAAAAAAD//////////wAAAAAAAAAA/////////wD///////////8AAAAAAAAAAP/////////wAAAAAAAAABD/////////AP///////////wAAAAAAAAAA/////////9QAAAAAAAAAJP////////8A////////////AAAAAAAAAAD/////////qAAAAAAAAABI/////////wD///////////8AAAAAAAAAAP////////9QAAAAAAAAAHj/////////AP///////////wAAAAAAAAAA////////uAAAAAAAAAAAvP////////8A////////////AAAAAAAAAAD////w0HwEAAAAAAAAACT8/////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAADz8//////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAY6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAKNz/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAACHT0//////////////8A////////////AAAAAAAAAAAAAAAAABg4bKj0/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'E' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAD///////////////////////////////8A//////////8AAAAAAAAAAP///////////////////////////////wD//////////wAAAAAAAAAA////////////////////////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'F' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'G' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////////////////MB8TCgQAAAACCA4YJzs////////////////AP///////////////JQcAAAAAAAAAAAAAAAAAAhw8P////////////8A/////////////9gwAAAAAAAAAAAAAAAAAAAAAAAk2P///////////wD////////////EDAAAAAAAAAAAAAAAAAAAAAAAAAAc7P//////////AP//////////2AwAAAAAAAAAAAAAAAAAAAAAAAAAAABY//////////8A//////////wwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ/////////wD/////////kAAAAAAAAAAAEHzQ/P/gmCAAAAAAAAAAAFz/////////AP////////wcAAAAAAAAACjg////////8CwAAAAAAAAgWP////////8A////////vAAAAAAAAAAI2P//////////yBRAcJjI8P///////////wD///////94AAAAAAAAAGD/////////////////////////////////AP///////0AAAAAAAAAAsP////////////////////////////////8A////////IAAAAAAAAADc/////////////////////////////////wD///////8AAAAAAAAAAP///////wAAAAAAAAAAAAAAAAD/////////AP///////wAAAAAAAAAA////////AAAAAAAAAAAAAAAAAP////////8A////////AAAAAAAAAAD///////8AAAAAAAAAAAAAAAAA/////////wD///////8gAAAAAAAAAOD//////wAAAAAAAAAAAAAAAAD/////////AP///////0AAAAAAAAAAtP//////AAAAAAAAAAAAAAAAAP////////8A////////cAAAAAAAAABw//////8AAAAAAAAAAAAAAAAA/////////wD///////+8AAAAAAAAABDs////////////AAAAAAAAAAD/////////AP////////wYAAAAAAAAADz0//////////AAAAAAAAAAAP////////8A/////////5AAAAAAAAAAACCY4P//3KhcCAAAAAAAAAAA/////////wD/////////+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////AP//////////xAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIP////////8A////////////rAQAAAAAAAAAAAAAAAAAAAAAAAAAAGTw/////////wD/////////////vBQAAAAAAAAAAAAAAAAAAAAAADjI////////////AP//////////////8HAQAAAAAAAAAAAAAAAAAEiw//////////////8A//////////////////iwcEAgBAAABCA4aKDk/////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'H' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'I' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAP///////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAA////////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAD///////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'J' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAD//////////////wD///////////////////////////8AAAAAAAAAAP//////////////AP///////////////////////////wAAAAAAAAAA//////////////8A////////////////////////////AAAAAAAAAAj//////////////wD//////////+zMrIxwUDAQ//////wAAAAAAAAAIP//////////////AP//////////DAAAAAAAAADo////2AAAAAAAAAA0//////////////8A//////////8wAAAAAAAAAKj///+YAAAAAAAAAFj//////////////wD//////////2gAAAAAAAAAIND/yBgAAAAAAAAAkP//////////////AP//////////vAAAAAAAAAAAAAAAAAAAAAAAAADc//////////////8A////////////MAAAAAAAAAAAAAAAAAAAAAAAUP///////////////wD////////////EBAAAAAAAAAAAAAAAAAAAABjk////////////////AP////////////+sBAAAAAAAAAAAAAAAAAAY2P////////////////8A///////////////EMAAAAAAAAAAAAAAAVOj//////////////////wD/////////////////vHBAIAAAABg8fNT/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'K' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////8AAAAAAAAAAP//////////wAQAAAAAAAAAAABw////////AP///////wAAAAAAAAAA/////////9AMAAAAAAAAAAAAcP////////8A////////AAAAAAAAAAD////////cGAAAAAAAAAAAAHD//////////wD///////8AAAAAAAAAAP//////6CgAAAAAAAAAAABs////////////AP///////wAAAAAAAAAA//////Q0AAAAAAAAAAAAVPz///////////8A////////AAAAAAAAAAD////8RAAAAAAAAAAAAFT8/////////////wD///////8AAAAAAAAAAP///1gAAAAAAAAAAABU/P//////////////AP///////wAAAAAAAAAA//9wAAAAAAAAAAAASPz///////////////8A////////AAAAAAAAAAD/jAAAAAAAAAAAADz0/////////////////wD///////8AAAAAAAAAAKQAAAAAAAAAAAA89P//////////////////AP///////wAAAAAAAAAABAAAAAAAAAAAFPT///////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAApP///////////////////wD///////8AAAAAAAAAAAAAAAAAAAAAAAAU8P//////////////////AP///////wAAAAAAAAAAAAAAAAAAAAAAAABk//////////////////8A////////AAAAAAAAAAAAAAAAAAAAAAAAAADE/////////////////wD///////8AAAAAAAAAAAAAAAAoEAAAAAAAACz8////////////////AP///////wAAAAAAAAAAAAAAGNiAAAAAAAAAAIj///////////////8A////////AAAAAAAAAAAAABjY//gYAAAAAAAACOD//////////////wD///////8AAAAAAAAAAAAY2P///5wAAAAAAAAASP//////////////AP///////wAAAAAAAAAAGNj//////CgAAAAAAAAAqP////////////8A////////AAAAAAAAAADI////////sAAAAAAAAAAc8P///////////wD///////8AAAAAAAAAAP//////////QAAAAAAAAABs////////////AP///////wAAAAAAAAAA///////////IAAAAAAAAAATI//////////8A////////AAAAAAAAAAD///////////9YAAAAAAAAADD8/////////wD///////8AAAAAAAAAAP///////////9wEAAAAAAAAAJD/////////AP///////wAAAAAAAAAA/////////////3AAAAAAAAAADOT///////8A////////AAAAAAAAAAD/////////////7BAAAAAAAAAAUP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'L' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAD/////////////////////////////AP////////////8AAAAAAAAAAP////////////////////////////8A/////////////wAAAAAAAAAA/////////////////////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'M' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////8AAAAAAAAAAAAAAHz//////3wAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAATP//////UAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAc//////8cAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAADw////8AAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAAAAAAALz////AAAAAAAAAAAAAAAAA////////AP//////AAAAAAAAAAAAAAAAkP///5AAAAAAAAAAAAAAAAD///////8A//////8AAAAAAAAAAAAAAABc////ZAAAAAAAAAAAAAAAAP///////wD//////wAAAAAAAAAoAAAAADD///8wAAAAACQAAAAAAAAA////////AP//////AAAAAAAAAFwAAAAABPz//AgAAAAAXAAAAAAAAAD///////8A//////8AAAAAAAAAkAAAAAAA0P/UAAAAAACQAAAAAAAAAP///////wD//////wAAAAAAAADMAAAAAACg/6gAAAAAAMQAAAAAAAAA////////AP//////AAAAAAAAAPgEAAAAAHD/dAAAAAAE+AAAAAAAAAD///////8A//////8AAAAAAAAA/zQAAAAAQP9IAAAAADD/AAAAAAAAAP///////wD//////wAAAAAAAAD/bAAAAAAQ/xQAAAAAaP8AAAAAAAAA////////AP//////AAAAAAAAAP+gAAAAAADQAAAAAACc/wAAAAAAAAD///////8A//////8AAAAAAAAA/9QAAAAAAGgAAAAAAND/AAAAAAAAAP///////wD//////wAAAAAAAAD//wwAAAAAFAAAAAAM/P8AAAAAAAAA////////AP//////AAAAAAAAAP//RAAAAAAAAAAAADz//wAAAAAAAAD///////8A//////8AAAAAAAAA//94AAAAAAAAAAAAcP//AAAAAAAAAP///////wD//////wAAAAAAAAD//7AAAAAAAAAAAACo//8AAAAAAAAA////////AP//////AAAAAAAAAP//5AAAAAAAAAAAANz//wAAAAAAAAD///////8A//////8AAAAAAAAA////HAAAAAAAAAAQ////AAAAAAAAAP///////wD//////wAAAAAAAAD///9QAAAAAAAAAEz///8AAAAAAAAA////////AP//////AAAAAAAAAP///4gAAAAAAAAAfP///wAAAAAAAAD///////8A//////8AAAAAAAAA////vAAAAAAAAACw////AAAAAAAAAP///////wD//////wAAAAAAAAD////wAAAAAAAAAOz///8AAAAAAAAA////////AP//////AAAAAAAAAP////8sAAAAAAAc/////wAAAAAAAAD///////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'N' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAALD/////////////AAAAAAAAAP//////////AP////////8AAAAAAAAAFOj///////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAASP///////////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAkP//////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAI1P////////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAw+P///////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAABw////////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAC8//////8AAAAAAAAA//////////8A/////////wAAAAAAAAAAAAAAABzs/////wAAAAAAAAD//////////wD/////////AAAAAAAAAAAAAAAAAFD/////AAAAAAAAAP//////////AP////////8AAAAAAAAAAAAAAAAAAJz///8AAAAAAAAA//////////8A/////////wAAAAAAAAAUAAAAAAAADNz//wAAAAAAAAD//////////wD/////////AAAAAAAAALQAAAAAAAAANPz/AAAAAAAAAP//////////AP////////8AAAAAAAAA/2wAAAAAAAAAfP8AAAAAAAAA//////////8A/////////wAAAAAAAAD/+CwAAAAAAAAExAAAAAAAAAD//////////wD/////////AAAAAAAAAP//0AQAAAAAAAAgAAAAAAAAAP//////////AP////////8AAAAAAAAA////jAAAAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////RAAAAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP/////kFAAAAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA//////+sAAAAAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD///////9kAAAAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP////////QkAAAAAAAAAAAAAP//////////AP////////8AAAAAAAAA/////////8wEAAAAAAAAAAAA//////////8A/////////wAAAAAAAAD//////////4QAAAAAAAAAAAD//////////wD/////////AAAAAAAAAP///////////DwAAAAAAAAAAP//////////AP////////8AAAAAAAAA////////////4BAAAAAAAAAA//////////8A/////////wAAAAAAAAD/////////////qAAAAAAAAAD//////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'O' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A///////////////////0qGw4HAAAABw4aKT0/////////////////wD////////////////wcAwAAAAAAAAAAAAAAAho6P//////////////AP//////////////uBQAAAAAAAAAAAAAAAAAAAAMoP////////////8A/////////////6AEAAAAAAAAAAAAAAAAAAAAAAAAkP///////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP//////////8BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAM5P////////8A//////////9wAAAAAAAAAAAsrPD/7KQsAAAAAAAAAABg/////////wD/////////+BAAAAAAAAAAUPj///////hQAAAAAAAAAAjs////////AP////////+sAAAAAAAAABDw//////////AYAAAAAAAAAKD///////8A/////////2wAAAAAAAAAdP///////////3wAAAAAAAAAYP///////wD/////////OAAAAAAAAAC4////////////xAAAAAAAAAAw////////AP////////8cAAAAAAAAAOD////////////oAAAAAAAAABT///////8A/////////wAAAAAAAAAA//////////////8AAAAAAAAAAP///////wD/////////AAAAAAAAAAD//////////////wAAAAAAAAAA////////AP////////8AAAAAAAAAAP/////////////8AAAAAAAAAAD///////8A/////////xwAAAAAAAAA5P///////////+AAAAAAAAAAHP///////wD/////////NAAAAAAAAAC8////////////uAAAAAAAAAA4////////AP////////9oAAAAAAAAAHj///////////98AAAAAAAAAGT///////8A/////////6gAAAAAAAAAGPD/////////+BgAAAAAAAAApP///////wD/////////9AwAAAAAAAAAUPz///////xcAAAAAAAAAAjs////////AP//////////cAAAAAAAAAAALKjs//CwOAAAAAAAAAAAYP////////8A///////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzk/////////wD///////////+4BAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//////////AP////////////+QAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A//////////////+sEAAAAAAAAAAAAAAAAAAAAAyg/////////////wD////////////////oZAgAAAAAAAAAAAAAAARg4P//////////////AP//////////////////9KhsOCAAAAAUMFyc7P////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'P' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////////wAAAAAAAAAAAAAAAAAACCxguP////////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAOOD//////////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAGOD/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAARP////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAxP///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAABo////////////AP///////////wAAAAAAAAAA////6JwMAAAAAAAAADD///////////8A////////////AAAAAAAAAAD//////6AAAAAAAAAADP///////////wD///////////8AAAAAAAAAAP//////9AAAAAAAAAAA////////////AP///////////wAAAAAAAAAA///////0AAAAAAAAAAD///////////8A////////////AAAAAAAAAAD//////5gAAAAAAAAAHP///////////wD///////////8AAAAAAAAAAP///9iICAAAAAAAAABI////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAJD///////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////8AAAAAAAAAAAAAAAAAAAAAAAAAAIT/////////////AP///////////wAAAAAAAAAAAAAAAAAAAAAAAABU/P////////////8A////////////AAAAAAAAAAAAAAAAAAAAAAAIhPz//////////////wD///////////8AAAAAAAAAAAAAAAAABCRMkOz/////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP///////////wAAAAAAAAAA//////////////////////////////8A////////////AAAAAAAAAAD//////////////////////////////wD///////////8AAAAAAAAAAP//////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'Q' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////SoaDQcAAAAHDhoqPT///////////////////8A//////////////BwDAAAAAAAAAAAAAAACHDo/////////////////wD///////////+4FAAAAAAAAAAAAAAAAAAAABCo////////////////AP//////////nAQAAAAAAAAAAAAAAAAAAAAAAACQ//////////////8A/////////7gEAAAAAAAAAAAAAAAAAAAAAAAAAACg/////////////wD////////wFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzo////////////AP///////3AAAAAAAAAAACyo8P/sqCwAAAAAAAAAAGT///////////8A///////4EAAAAAAAAABM+P///////FQAAAAAAAAACPT//////////wD//////7AAAAAAAAAAFPD/////////9BgAAAAAAAAApP//////////AP//////bAAAAAAAAAB4////////////fAAAAAAAAABk//////////8A//////84AAAAAAAAALz///////////+8AAAAAAAAADT//////////wD//////xwAAAAAAAAA6P///////////+QAAAAAAAAAHP//////////AP//////AAAAAAAAAAD//////////////wAAAAAAAAAA//////////8A//////8AAAAAAAAAAP//////////////AAAAAAAAAAD//////////wD//////wAAAAAAAAAA/P////////////8AAAAAAAAAAP//////////AP//////GAAAAAAAAADg////////////4AAAAAAAAAAc//////////8A//////84AAAAAAAAALT////MJHTo//+8AAAAAAAAADT//////////wD//////2wAAAAAAAAAdP///2AAABCg/3wAAAAAAAAAZP//////////AP//////rAAAAAAAAAAY9P/sCAAAAABMGAAAAAAAAACk//////////8A///////4EAAAAAAAAABU/P+0OAAAAAAAAAAAAAAACPT//////////wD///////94AAAAAAAAAAA4sPD/gAAAAAAAAAAAAABk////////////AP////////AcAAAAAAAAAAAAAAAAAAAAAAAAAAAADOT///////////8A/////////7wEAAAAAAAAAAAAAAAAAAAAAAAAAACQ/////////////wD//////////6wEAAAAAAAAAAAAAAAAAAAAAAAAABSs////////////AP///////////7gUAAAAAAAAAAAAAAAAAAAAAAAAAABAwP////////8A//////////////BwDAAAAAAAAAAAAAAABAgAAAAAAAA8/////////wD////////////////0qGg0GAAAABgwXJjkxBgAAAAAALD/////////AP//////////////////////////////////5DQAAAAk/P////////8A////////////////////////////////////+GwAAJD//////////wD//////////////////////////////////////8A49P//////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'R' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////wAAAAAAAAAAAAAAAAAAAAQgOGSk+P///////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAcuP//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAEsP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ6P///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD///////////8A/////////wAAAAAAAAAA///////svDgAAAAAAAAACP///////////wD/////////AAAAAAAAAAD/////////7AAAAAAAAAAA////////////AP////////8AAAAAAAAAAP/////////cAAAAAAAAABD///////////8A/////////wAAAAAAAAAA//////DQoCQAAAAAAAAAQP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACU////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIPj///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAzU/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAA02P//////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAxctPz///////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAEDY/////////////////wD/////////AAAAAAAAAAD/9LAsAAAAAAAAAAzc////////////////AP////////8AAAAAAAAAAP///+wkAAAAAAAAADD8//////////////8A/////////wAAAAAAAAAA/////8QAAAAAAAAAAJD//////////////wD/////////AAAAAAAAAAD//////1QAAAAAAAAAFPD/////////////AP////////8AAAAAAAAAAP//////3AQAAAAAAAAAgP////////////8A/////////wAAAAAAAAAA////////aAAAAAAAAAAM6P///////////wD/////////AAAAAAAAAAD////////oCAAAAAAAAABs////////////AP////////8AAAAAAAAAAP////////+AAAAAAAAAAATc//////////8A/////////wAAAAAAAAAA//////////AUAAAAAAAAAFj//////////wD/////////AAAAAAAAAAD//////////5AAAAAAAAAAAND/////////AP////////8AAAAAAAAAAP//////////+CQAAAAAAAAAQP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'S' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP/////////////////8vHBEIAgAAAQgQHC8/P////////////////8A////////////////pCQAAAAAAAAAAAAAAAAcoP///////////////wD//////////////FwAAAAAAAAAAAAAAAAAAAAAXP//////////////AP////////////9oAAAAAAAAAAAAAAAAAAAAAAAAhP////////////8A////////////zAAAAAAAAAAAAAAAAAAAAAAAAAAI6P///////////wD///////////9cAAAAAAAAAAAAAAAAAAAAAAAAAACA////////////AP///////////xgAAAAAAAAAUOD/8KwkAAAAAAAAADj///////////8A////////////AAAAAAAAAAD0/////8wABCAgICxASP///////////wD///////////8MAAAAAAAAAMz/////////////////////////////AP///////////0AAAAAAAAAACFiQxPT///////////////////////8A////////////oAAAAAAAAAAAAAAAADBwtPT//////////////////wD////////////8QAAAAAAAAAAAAAAAAAAACFTA////////////////AP/////////////oOAAAAAAAAAAAAAAAAAAAAABM6P////////////8A///////////////4fAgAAAAAAAAAAAAAAAAAAAAY2P///////////wD/////////////////7IwwAAAAAAAAAAAAAAAAAAAo+P//////////AP/////////////////////koGw0BAAAAAAAAAAAAACU//////////8A///////////////////////////4uFgAAAAAAAAAADz//////////wD//////////2BgSEA0IBwA6P///////5QAAAAAAAAADP//////////AP//////////JAAAAAAAAACc/////////AAAAAAAAAAA//////////8A//////////9YAAAAAAAAACDo///////AAAAAAAAAABT//////////wD//////////6QAAAAAAAAAACCk7P/snBQAAAAAAAAAUP//////////AP//////////+BAAAAAAAAAAAAAAAAAAAAAAAAAAAACs//////////8A////////////kAAAAAAAAAAAAAAAAAAAAAAAAAAAOP///////////wD////////////8RAAAAAAAAAAAAAAAAAAAAAAAABjc////////////AP/////////////0PAAAAAAAAAAAAAAAAAAAAAAg2P////////////8A///////////////8hBQAAAAAAAAAAAAAAAAMdPT//////////////wD/////////////////+LRwSCAMAAAAHDhoqPT/////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'T' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD///////////////////8AAAAAAAAAAP//////////////////////AP///////////////////wAAAAAAAAAA//////////////////////8A////////////////////AAAAAAAAAAD//////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'U' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////AAAAAAAAAAD///////////8AAAAAAAAAAP//////////AP////////8AAAAAAAAAAP///////////wAAAAAAAAAA//////////8A/////////wAAAAAAAAAA////////////AAAAAAAAAAD//////////wD/////////JAAAAAAAAADk/////////+gAAAAAAAAAHP//////////AP////////9MAAAAAAAAAJz/////////nAAAAAAAAABE//////////8A/////////4gAAAAAAAAAHOj//////+ggAAAAAAAAAHz//////////wD/////////0AAAAAAAAAAAIJzs/+ykIAAAAAAAAAAA0P//////////AP//////////QAAAAAAAAAAAAAAAAAAAAAAAAAAAAED///////////8A///////////IBAAAAAAAAAAAAAAAAAAAAAAAAAAE0P///////////wD///////////+YAAAAAAAAAAAAAAAAAAAAAAAAAJj/////////////AP////////////+UBAAAAAAAAAAAAAAAAAAAAASU//////////////8A///////////////IPAAAAAAAAAAAAAAAAAAwyP///////////////wD/////////////////0IxYOCAIAAAEIEiAyP//////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'V' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD//////zAAAAAAAAAAYP//////////////ZAAAAAAAAAAw////////AP//////kAAAAAAAAAAU/P////////////8UAAAAAAAAAJD///////8A///////oBAAAAAAAAADE////////////xAAAAAAAAAAE7P///////wD///////9MAAAAAAAAAHD///////////94AAAAAAAAAEz/////////AP///////6gAAAAAAAAAJP///////////yQAAAAAAAAArP////////8A////////+BAAAAAAAAAA1P/////////YAAAAAAAAABT4/////////wD/////////aAAAAAAAAACE/////////4QAAAAAAAAAbP//////////AP/////////EAAAAAAAAADT/////////OAAAAAAAAADM//////////8A//////////8kAAAAAAAAAOT//////+QAAAAAAAAAKP///////////wD//////////4QAAAAAAAAAmP//////nAAAAAAAAACI////////////AP//////////5AAAAAAAAABE//////9EAAAAAAAABOT///////////8A////////////QAAAAAAAAAT0////9AgAAAAAAABI/////////////wD///////////+gAAAAAAAAAKT///+kAAAAAAAAAKj/////////////AP////////////QIAAAAAAAAXP///1wAAAAAAAAM+P////////////8A/////////////1wAAAAAAAAM+P/8DAAAAAAAAGT//////////////wD/////////////vAAAAAAAAAC8/7wAAAAAAAAAxP//////////////AP//////////////HAAAAAAAAGj/aAAAAAAAACT///////////////8A//////////////94AAAAAAAAHP8cAAAAAAAAhP///////////////wD//////////////9gAAAAAAAAAkAAAAAAAAADk////////////////AP///////////////zgAAAAAAAAQAAAAAAAAQP////////////////8A////////////////lAAAAAAAAAAAAAAAAACg/////////////////wD////////////////sCAAAAAAAAAAAAAAADPT/////////////////AP////////////////9QAAAAAAAAAAAAAABg//////////////////8A/////////////////7AAAAAAAAAAAAAAAMD//////////////////wD//////////////////BQAAAAAAAAAAAAc////////////////////AP//////////////////cAAAAAAAAAAAAHz///////////////////8A///////////////////MAAAAAAAAAAAA3P///////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'W' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//8cAAAAAAAAALz/////4AAAAAAAAAAA6P////+8AAAAAAAAABz//wD//1QAAAAAAAAAjP////+gAAAAAAAAAACo/////4wAAAAAAAAAUP//AP//jAAAAAAAAABU/////2AAAAAAAAAAAGj/////VAAAAAAAAACM//8A///EAAAAAAAAACT/////IAAAAAAAAAAAKP////8kAAAAAAAAAMT//wD///gEAAAAAAAAAPD//+AAAAAAAAAAAAAA6P//8AAAAAAAAAAE9P//AP///zAAAAAAAAAAvP//oAAAAAAAAAAAAACo//+8AAAAAAAAADD///8A////bAAAAAAAAACM//9gAAAAAAAAAAAAAGT//4wAAAAAAAAAaP///wD///+kAAAAAAAAAFT//yAAAAAAAAAAAAAAIP//VAAAAAAAAACc////AP///9gAAAAAAAAAJP/gAAAAAAAAAAAAAAAA4P8kAAAAAAAAANT///8A/////xAAAAAAAAAA8KAAAAAAAAAAAAAAAACg8AAAAAAAAAAQ/////wD/////TAAAAAAAAAC8YAAAAAAAAAAAAAAAAGC8AAAAAAAAAET/////AP////+AAAAAAAAAAIwgAAAAAAAAAAAAAAAAIIwAAAAAAAAAfP////8A/////7gAAAAAAAAANAAAAAAAACwwAAAAAAAANAAAAAAAAACw/////wD/////8AAAAAAAAAAAAAAAAAAAdHgAAAAAAAAAAAAAAAAAAOz/////AP//////KAAAAAAAAAAAAAAAAAC4vAAAAAAAAAAAAAAAAAAg//////8A//////9gAAAAAAAAAAAAAAAACPj4CAAAAAAAAAAAAAAAAFj//////wD//////5QAAAAAAAAAAAAAAABE//9IAAAAAAAAAAAAAAAAkP//////AP//////0AAAAAAAAAAAAAAAAIj//4wAAAAAAAAAAAAAAADI//////8A///////8DAAAAAAAAAAAAAAAzP//1AAAAAAAAAAAAAAABPj//////wD///////88AAAAAAAAAAAAABT/////GAAAAAAAAAAAAAA0////////AP///////3QAAAAAAAAAAAAAWP////9gAAAAAAAAAAAAAHD///////8A////////sAAAAAAAAAAAAACg/////6QAAAAAAAAAAAAApP///////wD////////kAAAAAAAAAAAAAOT/////6AAAAAAAAAAAAADc////////AP////////8cAAAAAAAAAAAo////////MAAAAAAAAAAAEP////////8A/////////1QAAAAAAAAAAHD///////94AAAAAAAAAABM/////////wD/////////jAAAAAAAAAAAtP///////7wAAAAAAAAAAID/////////AP/////////EAAAAAAAAAAT0////////+AgAAAAAAAAAuP////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'X' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD///////9UAAAAAAAAAKz///////////+sAAAAAAAAAFD/////////AP///////+QQAAAAAAAAFOT/////////8BwAAAAAAAAM5P////////8A/////////5gAAAAAAAAATP////////9kAAAAAAAAAJD//////////wD//////////0AAAAAAAAAAoP//////wAAAAAAAAAA0/P//////////AP//////////2AgAAAAAAAAQ4P////gkAAAAAAAABMz///////////8A////////////iAAAAAAAAABA////dAAAAAAAAABw/////////////wD////////////8MAAAAAAAAACU/9AEAAAAAAAAHPD/////////////AP/////////////IBAAAAAAAAAzYMAAAAAAAAACs//////////////8A//////////////90AAAAAAAAABAAAAAAAAAATP///////////////wD///////////////QgAAAAAAAAAAAAAAAAAAzg////////////////AP///////////////7wAAAAAAAAAAAAAAAAAjP////////////////8A/////////////////2AAAAAAAAAAAAAAADD8/////////////////wD/////////////////7BQAAAAAAAAAAAAEyP//////////////////AP/////////////////gDAAAAAAAAAAAAAjY//////////////////8A/////////////////0AAAAAAAAAAAAAAADj8/////////////////wD///////////////+UAAAAAAAAAAAAAAAAAJD/////////////////AP//////////////4AwAAAAAAAAAAAAAAAAADOD///////////////8A//////////////9AAAAAAAAAAAAAAAAAAAAAQP///////////////wD/////////////nAAAAAAAAAAAWAAAAAAAAAAAlP//////////////AP///////////+QQAAAAAAAAAGD/YAAAAAAAAAAM4P////////////8A////////////TAAAAAAAAAAs9P/0LAAAAAAAAABM/////////////wD//////////6AAAAAAAAAADNT////UDAAAAAAAAACg////////////AP/////////kEAAAAAAAAACg//////+gAAAAAAAAABDk//////////8A/////////0wAAAAAAAAAYP////////9gAAAAAAAAAEz//////////wD///////+oAAAAAAAAACz0//////////QsAAAAAAAAAKT/////////AP//////7BQAAAAAAAAM1P///////////9QMAAAAAAAAFOz///////8A//////9UAAAAAAAAAKD//////////////6AAAAAAAAAAVP///////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'Y' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP///////1QAAAAAAAAAAGj//////////2gAAAAAAAAAAFT///////8A////////5BAAAAAAAAAAAMT////////EAAAAAAAAAAAQ5P///////wD/////////mAAAAAAAAAAAKPj/////+CgAAAAAAAAAAJj/////////AP//////////PAAAAAAAAAAAgP////+AAAAAAAAAAAA8//////////8A///////////YCAAAAAAAAAAE2P//2AQAAAAAAAAACNj//////////wD///////////+AAAAAAAAAAAA4//84AAAAAAAAAACA////////////AP////////////woAAAAAAAAAACUlAAAAAAAAAAAKPz///////////8A/////////////8gAAAAAAAAAABAQAAAAAAAAAADI/////////////wD//////////////2wAAAAAAAAAAAAAAAAAAAAAbP//////////////AP//////////////8BwAAAAAAAAAAAAAAAAAABzw//////////////8A////////////////tAAAAAAAAAAAAAAAAAAAtP///////////////wD/////////////////VAAAAAAAAAAAAAAAAFT/////////////////AP/////////////////oEAAAAAAAAAAAAAAQ6P////////////////8A//////////////////+cAAAAAAAAAAAAAJz//////////////////wD///////////////////9AAAAAAAAAAABA////////////////////AP///////////////////9gAAAAAAAAAANj///////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////8AAAAAAAAAAP////////////////////8A/////////////////////wAAAAAAAAAA/////////////////////wD/////////////////////AAAAAAAAAAD/////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + 'Z' => array('data' => 'AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////8A//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////////wD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////////AP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAQ//////////////8A/////////////////////////1AAAAAAAAAABLz//////////////wD///////////////////////98AAAAAAAAAACY////////////////AP//////////////////////pAAAAAAAAAAAaP////////////////8A/////////////////////8QIAAAAAAAAAET8/////////////////wD////////////////////gGAAAAAAAAAAo9P//////////////////AP//////////////////9CwAAAAAAAAAFNz///////////////////8A//////////////////xMAAAAAAAAAATA/////////////////////wD/////////////////eAAAAAAAAAAAnP//////////////////////AP///////////////5wAAAAAAAAAAHT///////////////////////8A///////////////ABAAAAAAAAABM/P///////////////////////wD/////////////3BQAAAAAAAAALPT/////////////////////////AP////////////QoAAAAAAAAABjg//////////////////////////8A///////////8SAAAAAAAAAAExP///////////////////////////wD//////////2wAAAAAAAAAAKD/////////////////////////////AP////////+YAAAAAAAAAAB8//////////////////////////////8A/////////wQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////wD/////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////AP////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8A/////////////////////////////////////////////////////wD/////////////////////////////////////////////////////AP////////////////////////////////////////////////////8=','width' => 40), + ); + + return $_png; + } + + // These define base64_encoded raw png image data used + // when we cannot generate our own single png image + function define_raw_pngs() + { + $_png = array( + '0' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QKCNGXKO6AAAAB3RJTUUH0wUOEDQ6EUG1VwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAXNJREFUeNpj/M9AHGAiUt2wVvhyaqAqKyOjpG3jQwaGv+e+IUn9RwJfSjjg4iwFP1aKJD6HyyErfGGAYrquIoP5E2wK/zigu0v5wH9sChdgeKDqP1aFGhBZmxv/z0Dd4IxV4RWIpMQHIPuJAITzAqEQETx7IFQIP5CQNoJwDmALxzMQCuyjg1chnBPYwtECwr8AZN41h0p6YHOjAkTuwf//77wYuCEcFWwKOWA2fM1iZuuHcASwKYQ55c9ENuasrxgRjKlwJS+D17v/hBUeUGYwv/sfn0IRiJQZJIbxuFEFagjvSlDUQNgK2GIGqpC1JRhIfoAqxBYz0DRhn8IMJO+giKEqhMaMJBeI3AHhIKdkRPqG8DlAifqFADyasKRHO6h1Z/6fMYEwTbCmx3cWGCl8CTaFwBhGz+M2/7EpXMvOnBmIok7jBVaFz/Mi3/1pQORrhpgPyOr+M8IL0j9/gKpeLjhy5QEwoDVsYuRR3cE4IktcAJNx8cJaZBeQAAAAAElFTkSuQmCC', + '1' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMi//xxVKAAAAB3RJTUUH0wUOEDYLcqnX7wAAAAlwSFlzAAALEgAACxIB0t1+/AAAAHpJREFUeNpj/M9AHGAiUh1WhR8FGUGAsMKaD9iM/I8BlmCVwVS4hoUohT8qcNiFyv2zQIWBCIV3amRwu54RKcDRAgQ1KigIcJYK7CqR3QsCFmf+Y8qgeQakbANMAz6FKjUXECbj8zWa76nm61GFw1UhI10KqVGFNFQIADdK9Zj7PsV9AAAAAElFTkSuQmCC', + '2' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMwPUBEjoAAAAB3RJTUUH0wUOEDUqFe2UcgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAQxJREFUeNpj/M9AHGAiUt2owkGrkAWF93LFgStPfjCwyGiYRGijqfyPAH9aOJAkQl78RwbICkNQjdB4gUNhD7qzLLAr/CKA4YENSAoRvl7zAUJXvPmxhgfCXILVMxEQvg+IDVUhgtVqDYjkDhD7B2aQIMIx5cOTN29evLAAsaEKObBajQzmQOQMcIQjHLwQgSisIaDwBdS5LHfwK7yhAHVVyX+8CrdAA5HB5gdehQ3Yoxpd4ZcAmDqbD//xKISEIjhU//zHoxDmXQaeFRhOZ8CmzuDOf3wKf8DsDfnyH6/CHJi6P//xKjyDJethVehBpMI7DPgVwrPCCgb8AK5wDwGFcNMF8EkCASOx1QcAGUxu1untnFIAAAAASUVORK5CYII=', + '3' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMxBQugk2AAAAB3RJTUUH0wUOEDU3duv4qwAAAAlwSFlzAAALEgAACxIB0t1+/AAAATdJREFUeNpj/M9AHGAiUt0IVciCzPm7ZceZB28YGBQkLHwcmNFU/keANRJI4ioH/qMAJIUlaHatwaFwBrqrOO5gVfiCB8P9KVgVVkAtnPDh/wkLCFsGq0IFiGQLiH0D06P/GWHJ7O+NOzfuXLlzQRrEhgSawHscwYPurxAcwQMBf/4/aIAYyHIGr8IEeDhO+Y9XoQNUncwOVHGMRPEDSovc+IkzrpGDCQgUbuC1WgBhhsIHfAp3vPn/oIIFKfRxKQSDGohCA4IKX0DTD7YoRAWMUJ9iyQpbn4DBBWUQ5yFEDDnFw622gXAzwBxoYvfB5sYlUI0lD/4/gWWKJdgU/tHAcKjCD6y+PsGCpo4FJbaRgmcNqkqWCThTzxkTJHXo+Ro1HA9uOPHiATDlKJj4eKCVFIzDqWgGAK7GW/haPS+zAAAAAElFTkSuQmCC', + '4' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMyqWttCEAAAAB3RJTUUH0wUOEDUxn4hdngAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKBJREFUeNpj/M9AHGAiUh2FCucyQgCK4H9McIAFixwWhQ8kGIhS+MWAgTiFIQzEKWxhIE7hFgbiFF7hASkQIajwjQpInuUAIYV/XMDyU/4TUlgAlk75T0jhArCszR9CCk+AY07mxX8CCp+AY47nzH8CCn+YgOWW/CekMAYsVfMfl0JGmCBq4kNEDp2zAn0UMmItABjRvDykPTO43DgyFQIANP6pTFLWAdoAAAAASUVORK5CYII=', + '5' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QMzPy3XhEAAAAB3RJTUUH0wUOEDUk8lW5dQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAQpJREFUeNpj/M9AHGAiUt2oQuIVfmREBzgU3iHWxAfEKiTaRFpZnfAfAbAr/AsxUYagiVCbeQgqhPpFYmukLCOrZupRNJUIB02BCAjAZCK+/Ed2LoJZgm6bzRfsCgMw3JWAXaEBpg8uIGSRPPMBQmXc+P+iggXCnoOQZUQK1K8PgEAjGcQs7QGL6FzG5mtkcAUiyYIQYcRRUkDTLEIWR1b4ixamQMPhrKUP3rx48eDNFXmwdyFiOthixgXqaTAnBcKpwRaOS6A6Mx78fwBVx/IAm8I/KsTGzAkWNHUyb7Ar/L8GNSlK3MCRev7/v+CApC7kBUoUoAX4yQ0nHjwAWqpiE6GNFgNDoAwHAKC2Q2lMNcCmAAAAAElFTkSuQmCC', + '6' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNAObRd4vAAAAB3RJTUUH0wUOEDUc2lcB6wAAAAlwSFlzAAALEgAACxIB0t1+/AAAATtJREFUeNpj/M9AHGAiUh2Gwq2puryMjKKmmSfRVf5HBkcMEBI+L1CkUBROYUE2QuMFLoVr0CzzwKHwhQC6szZgV1gAtfHI/xs2mEYywsPxp8QHEMVxQ56B4aaJiIKIiIRCPDZf74DwI/5jB4hwPAChbAgG+BWoExlOxkoysuqW3sUV4BoQ/p0SqARLB44AF4HIByDMKMCuEIu7phCrUOADNl/DgMOJ/09SIMwPC7B5hgfC1/kB4kRAOC7YrFaByM0Ac85AOCLYrFaBhSMIQNPlG2wBDg3HP2CSGU/MuEAoiKVXUWxB9cwPiG8UwEGSg5FCMNOjwZ4/byqgpqwgMoWr/MGeZ1agqWPZgSNz/Z+AqnDCf1wK/29B8qbKDhQpRtTE8HfLjjMP3jDwKJh4hKCGJSPNC6lRhTRWCABWpdoxd/bZ4QAAAABJRU5ErkJggg==', + '7' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNA18/fMoAAAAB3RJTUUH0wUOEDUVo4u5TwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAM9JREFUeNpj/M9AHGAiUt2oQnorZIGzGLFJIyJ40HqGhUiFPFuQ/YUFPBGBmLcDSQybwj8OEDOW/CegsAeiruQ/AYV3OMDqTP4QUugCceCN/wQUQn1a8Z+Awj8qYHUiHwgpXAAxcMJ/Qgp1wOoEPhBSuANiYM5/QgpjIAovEFL4gweszgAz0NASxZ4vYMqHYDKDBiIWhWhWa0CS1x9CVn+8AaYsmAlZfQRC6RDMChADGTQIKjxDrMI7EEoBi0JGlMJe8AOY+sFOSCEeQHQBAABCZ7xyT9fJhwAAAABJRU5ErkJggg==', + '8' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNBeBnwpSAAAAB3RJTUUH0wUOEDUOKe5wowAAAAlwSFlzAAALEgAACxIB0t1+/AAAATVJREFUeNpj/M9AHGAiUt1AKmRB459cc+DBGwYWGQ2LEG1Umf/I4IELkozLA2QpFIUXJFDMEDiBQ+EHGTR3yHzArrAFwwct2BXqQGQ1zvw/owFh6mBXCDXmDJB5BsOrjEhxzfoHIgkiGCGB9xtrgEPtOwvEV6FWY4+ZAAgVc5LhZgKEGYI9wN+gBiPu4Pl/BFWlxA1cMfN/C0rUr8AVhX8K0KyuwaEwASNmarAqPACVTXnw/0oENBFewKYQGhYZYE4MVBM2hVAvQ1LhHQhHBVsUMjIgYhCdhy3PPASTd6GOxBYz0KhOQHajDjY3pkC1Rlz5fweqjqEAm8ILGK5gYLlDZICXYI+ZLzZo6gL+4EgUfyo4kJQJtCCpQ8kKQPB2zZ47L14AU5iMgUMAN7IM43AqHwdQIQAhMPz6Gz5V/wAAAABJRU5ErkJggg==', + '9' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QNCQ+T2tEAAAAB3RJTUUH0wUOEDUHUDLIBwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAUZJREFUeNpj/M9AHGAiUh26wr9rE3V5GRlFTTM3/kVT+R8Z7FBBSKjsQJFCUTiFBcWMCbgUHmBBs20FdoV/VNDUMQi8wapwDVS65s2fPToQZgFWhRFIkm8kwGyeH9gUQm2+Aua0QDhb4LJI4XgHQmmDSRMIZw+emIEENAeEcwObQhEIdQHiABRbUGPGBSIQAWL/gHqbB5tnJkC1Fjz5f8IGwxwkhR8EsCQarFE4hViF/wsQCgKgHsSu8H8HLFkUQL2rgUPh/zslOiwMEjFH/kND2geXQvQgqMAWhSjgAIRygAswIuXCpXfevHjz4M0ZdQaGhxo/wAnyBTuWmPnvARGxuPH/iAa+9Ph/A7r9Ai+wK/zvg6ZwzX8cCl9oICtjmfIfl8L/bwIQ6gyO/Met8P//EwUmwHTJo5OyBU2CkdaF1KhCWisEAM/sJxmZkdWnAAAAAElFTkSuQmCC', + 'A' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QFwy1U7TfAAAAB3RJTUUH0wUOEC0ZKCZtPQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAO1JREFUeNrt1LERwiAUBuAHZ2GRwsIypQMwQEZwgBQpM4QDZBSLFI7gCA5gQWGRdA5gkTuMSh48eMTUnq96wH98B+QiDCwruTD3D76qF676ueAp0Y9lSBXeSkFWaLAje3T+kkzK4SgpBzZw8pqxJWcdOJuRsyGPbWDk0tS20zw9SXsobdfytJVXdzNsP61i6Zt3K7Ht0UeUgbPdjsrOXMd+2IS2C2qb271HVWi7YANcNXFQsUEVBTXwNdl46jYRxPl52dnwRUZbhkLSDmS8DnxFRWiULxg8UxvobefuRR8ZQYDKtffVVcQWv/RrfgJC4bd0upw4MQAAAABJRU5ErkJggg==', + 'B' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGAusrz2zAAAAB3RJTUUH0wUOEC01Gv4B3gAAAAlwSFlzAAALEgAACxIB0t1+/AAAANJJREFUeNpj/M9AHGAiUh0tFTKiAUHL2rsoKv9DARZDWFr+IwA+hQwMFcQqZDhCrMIIYhWK4FYIYv8444PuV+wK//9/A+UJwBUSCHAL3OEIsdoFyttCpGdiiAtHjoY/RCnk6PlBbBRKrCE6CqcQq5DlDs5whIT3CgUI788EvOEIBCegXB2YPCNMBSNMISqf5TeUjysK90LpP/itfrFEAhZCMHkWdKMYUbk2MAah7BqD02pUYEFkgMu8IE6hD0IdpmegwSejoKLjoY7syaFU7A0HhQA2e4cJytImvAAAAABJRU5ErkJggg==', + 'C' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGBbPqVFqAAAAB3RJTUUH0wUOEC4BEGemqAAAAAlwSFlzAAALEgAACxIB0t1+/AAAASlJREFUeNpj/M9AHGAiUt2owkGrkAWV+3TDgRtPPjBwyGiYBOijSv1HAlcCkGUcTiDLISvsQDOeZQp2hQWYDpuCTeEEbD44ganwDgc2vxpgKoyAyUWc+f9hjgCMtwFd4RuYRxog/ueBcl3QFc6BSmj8gfBrwE40yFmCrjABqrAH5mSZgJ4jX7AEjwlU4Zn/OAAsrp9AaRlccc0IzdeMsBilOPWQrBDmtpfEKnwBpZ8qZq58i6IS6vscKHcBcgQYlOz4gh6OK6AKfaB8G5hN6Aq/wBLPHjB3CczCFIzUA0u2PD0v/j9pgaf1ExgK3wgwYAEOWFL4GizqWC5gyzM1mArnEJkLZ2DPhf//n3BAVmeDkq8ZUZPL3TUn7gBLCgYFBYsAcxQZRmKrDwABNsv9SJSDwwAAAABJRU5ErkJggg==', + 'D' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGC1+orhOAAAAB3RJTUUH0wUOEC4yr7fHvgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAM9JREFUeNpj/M9AHGAiUt1AKmSBsxiRhXlkNBxCpFFU/ocBTDMyPvxHADwKGRgUbhCpkEHiCZEKGRyIVciwArdCIPPFGg8YzwSvQiBogXFvEFD43wDKnQDl44yZGCh9glAU2sCsJqRQBkq/gMUw3G2wuP6PnU/H9PgRSgsQUvgESosQUngFSqsQUrgCSsNiCFcU7oBx9+CL6w8XamB5SeUPkelxAZEJ1+YPcQolXhCXFTTuEJULOUq+IOVrFgasQELBxMaHG1mEcTiVjwOoEADAIkCnGpmJKgAAAABJRU5ErkJggg==', + 'E' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGDeDwEE0AAAAB3RJTUUH0wUOEC8CkHXGUwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD5JREFUeNpj/M9AHGAiUt2owkGrkAXGYMQqjUgJQ8EzpPsa05+D140oMYTk4KEQ4MMqZqgUhcM1czESW30AABfqB1XDnLzcAAAAAElFTkSuQmCC', + 'F' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGQe8AkDZAAAAB3RJTUUH0wUOEC8JB6cf2wAAAAlwSFlzAAALEgAACxIB0t1+/AAAADlJREFUeNpj/M9AHGAiUt3wUsiCYDJikUYE3lDwDDm+xvTp4HUjIoaQXTsUAnxYxcyoQryAcUSWuAAW/gZTg/yEMAAAAABJRU5ErkJggg==', + 'G' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGRFI1vWIAAAAB3RJTUUH0wUOEC8QY8y3GwAAAAlwSFlzAAALEgAACxIB0t1+/AAAASZJREFUeNpj/M9AHGAiUt0IVciCwvt7ZM+FOy8+MDBwSEho2AQII8v9R4A/U2RQtHEUfEBIIim8YYBhn8oNLAqP8GBxmcwbDIU3sKljYIhAV/jHgAE7uICmcAJMQqDmwp//D2YowPgxqAr/wPyr8QAi8EEHwleIQFW4BxYicG+eEHEomHECET5QhRVQhQn/cQFoFJ6AKgwgFNcPoFwdnAoZIXmGERahKDwkIdqlR1j4PiRW4RVCCmExvQenQrSYEXiDiAoUBfC4loAK23yBSnzArhCRehRmAJPFnRUxHDgU/lDA7zZECj/Cgl2dAkaeWYNVZcoHDIX/94hgKLM4gS27/v9QIICizGMDkiQjSon7c8eBCw+e/GFgkZEwsHCRRpZiHE5FMwCa2YE+WcAOUwAAAABJRU5ErkJggg==', + 'H' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGRw2Z4k1AAAAB3RJTUUH0wUOEC8agxleBQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD1JREFUeNpj/M9AHGAiUt2oQvyABUozQml4+KMLDAXPDAWFLGh8RlwKh4JnaB88GOlxELhxVCFewDgEynAAN2sFVHAvevkAAAAASUVORK5CYII=', + 'I' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGSlg1E0WAAAAB3RJTUUH0wUOEC86uHd+zQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAD5JREFUeNpj/M9AHGAiUt1AKmRBMBkxJJE9OhQ8Q32FjGhxDQsjjCQwFDwzqnCwKkRKZqO5EBMwDqcSl2iFAMMeB0s/kLo2AAAAAElFTkSuQmCC', + 'J' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QGywiiNsbAAAAB3RJTUUH0wUOEDAFw0tdbgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKdJREFUeNpj/M9AHGAiUh3xClmwijJCaSR3Ud/qUYWjCklTyIHEhifctw8ePHgCxO+B7L9QMQlsChW+QOiX4gwMd6BiItisVoHSB6AYWQwM/kNBBszkC/9PwKyc8B8B4Ar3YPHMHWwK/xtgqAv4j1XhEfScK/EEu8L/a1BVStz4j0Ph/yPItoe8QFH3nxGlkNq75cKDB0DDVBwitNEcwjhwpdmoQrwAAN6ioiFapgUdAAAAAElFTkSuQmCC', + 'K' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHAEoFhGpAAAAB3RJTUUH0wUOEDANzZDVXAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAPZJREFUeNpj/M9AHGAiUt2owgFSyAgFMOGDrDARxkKo0H8wYEDh/b/AAzepACqEVeEdCQx1WBW+0ICry/mPR+EXE7i6kD94FP5xwaYOi8IIrOowFRbA1Xkgq8NQ2ANXZ/PlPx6FS3CpQ1fIAmOIoKn7jxbXf2CMNxvQIxvVRAQQ+YDXaiSQQqxChiOEFGoIQGidP/gVStxogLI68CqUuPH/BzSVcTzAoxCo7v//ObBIxK0QrO7/H1iCXIFT4QkIFxbaMh9wKYQJO0D5OYQUnoDF/QkCCuHJ1+APAYV3YOloAgGF8JTO84SAwjfQiGQIgPAZqV4rAACnKSarzdlc4gAAAABJRU5ErkJggg==', + 'L' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHA64qQw4AAAAB3RJTUUH0wUOEDAXMPIsJgAAAAlwSFlzAAALEgAACxIB0t1+/AAAADlJREFUeNpj/M9AHGAiUt2QUMiCYDJCaezhMBQ8M6pwVCEdFLJgCjEisRH5Zyh4hvoKGUdkQUq0QgARaARRV9jUFQAAAABJRU5ErkJggg==', + 'M' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHBhMfblpAAAAB3RJTUUH0wUOEDAqaJpgNwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAPNJREFUeNrdlK0OgzAUhS8bCQYxMYmcmEAgEAgejQfZQyG2pAIxOYlATkAu691o2tvSYia2iv7lyzn3NG0jhG1tt5H7Aggom7ZuaKPhBFqKV+pFWDGjjcxStEAYXuvBkrKtoVX+gdRiK9i6sxjgeVGUMJzWwZLACaZOTqoAOAronmrlBuvPkQsIgHn8BqnE2AMmhaaYJ57jqTRFMwsDyW249XaJLhAujizm7UFM5XCUXTqiTvBLQYWRc7H3WWt+3NmlyGbOGh9q/45mjQxUb+CA6A2jSqu5MweX0ooQWLJxLYx6fz0GwmBOsww5GP3At/dX4Ayb7qpFI9y5ygAAAABJRU5ErkJggg==', + 'N' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHC6DxyzwAAAAB3RJTUUH0wUOEDAye/b4YQAAAAlwSFlzAAALEgAACxIB0t1+/AAAALRJREFUeNpj/M9AHGAiUt0IV8gIARsRMlAROP8/BEB5Ii/+/0cVgXNRhRk8iFXIMIFYhRxXiFTIYPCDSIUMBcQqZNhDrEKZN0QqZAggViHDHIIKRSAUzx1CCrdAaZM/BBT+z4Eyaggp/KEDYbAcIaDw/wUWCEuBkML/PagBgFvhfxdiFT4RIVLh/zXEKvyfQqzCLypEKvx/hoVIhf9biFX4x4ZIhf8fCBCp8P8KNBHG4VQ0AwDEOyeZhO5p1AAAAABJRU5ErkJggg==', + 'O' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHQExDSDoAAAAB3RJTUUH0wUOEDA4myMRfwAAAAlwSFlzAAALEgAACxIB0t1+/AAAATtJREFUeNpj/M9AHGAiUt3wUsiCyv265ciZJ08YGGRkDGwCuFGk/iOBDwU8SDIcGS+Q5JAV7hBBs45nAVaFC1gwXTYBi8IdWNQxMCzAUPhBBJs6Bp4n6AoLYFI6az78f7NEB8ZNQFP4QwAqEfADwg+A+f0NqsI1UHGBDzCnSKC6EhYzB6B0Cj+UwZ+CKgNTeAZKu8C94QGlL6DGjAyU+wAeXC+gIiIQLiM0KzDC9CFCBlWICsnsL3aFMDc+hcs8QZWBKYSF2g24whvYFZpA6T1whUegNCwyoYGxAmYyLGZ+wOxYghqFX2BpO+APmP8nBspHj2uk1LPizf8PGyxgXPTUQ3x6JDqF//8/AYs6bHkGmCYF0O3FnguBCSaFA0kZS8IDJDlG1IIUVFK8eABMWzI6DgHCyDKMI7LEBQCD5YgI9wbKGgAAAABJRU5ErkJggg==', + 'P' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHQvR2Mn2AAAAB3RJTUUH0wUOEDEDMzPJGgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKVJREFUeNpj/M9AHGAiUh05ChlRAKdu4k5Ulf9hANMQiwf/EQCfQgaJB0QqZHAhViHDEbg0AV8vwRM8QN0v5vBAOSfw+BrMWQDl8MClGeEKGGEKQcRXHmQemTGD1RMy+N14o4MDyvGAS7NgGMaIzPHAYyIy4HhBZMy0EBmFIX+IUsjRgqQOi2fAgEVBwyVGGEUEQw2O3EbLzDWSFDIOhtJsVCEWAAC/Yt2X+2PYcgAAAABJRU5ErkJggg==', + 'Q' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHRxSC0wxAAAAB3RJTUUH0wUOEDEKSu9xvgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAW1JREFUeNpj/M9AHGAiUt2QUMiCzPm65cCZF08YGGRkDBx8uNFU/oeDDwU8SOIcBS/+IwOEwh0iaEYIrMCqcA4LprsmYFG4A4s6BoYFGAo/iGBTx8DzAl1hAUxKZ8WH/29W6MC4KWgKfwhAJXx+gPl/QmB+/4KqcANUXOQDVPiLBFRkCUwhJGb2wGzihzK4U6CMA6hReAbKc4F7wwFKX0CNGRkoB+HJJ1ARGZgAIziFM8J0IUIGXYjMZPaXkEJYYDyBiz+EuRFVoQKUdwWIz6qWvmRguAMVkUBVaIIUalPu9GgshIefAWrwrIHp//L/DQc4KjFiBi2uQ/7832KB5AX0uP5fAZOx2PDhfwNCIXrq+f9BhgEb4HmCkcL3YE3hSHkBnmfWYFMpsoaYXAgGDgcwFKLlaxYOCG2DqRCYrldkmIACUMIgZsaTI5Cg3IBNISp4AoovlT+EFf7/kYPkb3wK//8/YAGPGcYhUIYDAHBC9Yak1w7iAAAAAElFTkSuQmCC', + 'R' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHSkEuIgSAAAAB3RJTUUH0wUOEDEUsOBM3QAAAAlwSFlzAAALEgAACxIB0t1+/AAAAOZJREFUeNpj/M9AHGAiUh0NFLJAaUY0YRkJHYcQdmSh/xCAzRCZHf8RAJ9CBpYNRCpkEHgBV4jfMx+mEOVGIDDAaTWY82aPBZTLgV8hUCkaH6cbP8B8gxHgyODjgwstMDfiVIgWQyFE+lrhB3EBznOFuJgxuUFMXPPEbPmDpA53FH55osKMIoAe4F826MDMvPMfj9WgWFGBBeIf/Ar/H4FxJhBQ+B8WzCIfCCi8A4uvBgIK/2fA/POCgMIXHFBuDqH02ABLM3cIKPwgAuVHEFD4fwJM4AIBhT9goe4AFWAcAsXesFIIAEvJyZHTCSiTAAAAAElFTkSuQmCC', + 'S' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHTRnvuTLAAAAB3RJTUUH0wUOEDEbIF9RTAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAVZJREFUeNpj/M9AHGAiUt2oQvyABYX398CWK3de/GBgkVEw8HFgRpH7jwSWqCDLyCxAlkNS+CcG3boY7AozMB3Wgk3hGSw+4HgBl0b4egIWhT9mYPGMBFQg4MH/D2tgvrKASzPC0yMjlP7CDSTOmrDIMDDwiHBsxzSRBypw5j9WgFDoAPNAxIQjX/ApXIDsC4OCLV9wKfzjwIACOEIO4IiZFxbooePzAqvC/z9qONBUStzAqvD//zc9BqgqNX5gVwgETxbkmCClvSk4FYLdsCMCptAGI2YSGV78+PLmz5MX4mDu1ByIMM9n9JiBxe4caGChy8MZMMsUIEFyAMoVwVC4BGaEwpI3/9/MEYGlJQyFPwQYsIE1mL7GlnCR0iNSXLtgqpO4gy1mvtigq1NAxCBKgP9pEUFWxlOCnNIYUYrmn3v23Ljx5gsw88sYOPhwI0sxDoEyHAABtSc836a1EQAAAABJRU5ErkJggg==', + 'T' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHgUdTbcyAAAAB3RJTUUH0wUOEDEgkVS4aAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADdJREFUeNpj/M9AHGAiUt0IVcgCpRlxyMODeSh4hmiFjGipB+Z7jEQ1FDwzqnBU4WBSyDicimYAb/AFTaJpyH8AAAAASUVORK5CYII=', + 'U' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHhEHl2NPAAAAB3RJTUUH0wUOEDEon48wWgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAKlJREFUeNpj/M9AHGAiUh3xClmgNCOUhrsEXYD6Vo8qHFVIuUIVKP0USr+E0jLoCjWg9A4ovQVNHJjUIaADZsILMPeFApRfA5X/D1N4AaZRYc6b/2+WwNQxXEBX+N8Bqxcc/mMoPMGCRR3LBUyF/2dgUTjjPxaF/6egm8ky5T9Whf9P2KCoMziBJPefEaWQurjnzIMXL34wsMhoWHiYo2hjHLjSbFQhXgAAKzejCLAOcVMAAAAASUVORK5CYII=', + 'V' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHh/gL05IAAAAB3RJTUUH0wUOEDEuduyVbwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAVNJREFUeNpj/M9AHGAiUt2owoFRaMgIAYlIMqlQMUMo/z8ITIByRP78hwMRqNgECBei8AULVPQIXN0RqAjLGwgfYrW4B1R4DdzmLVDaQxjZ6v8roDwVuIkqMK3/ka3+/0MAKn4FKn4D5uof/5GtZmCPgEpsQHNDBDsDitVwt5tA+RZQ/pn/qFYj3PQEzHsC5WnA3QyPmQQU3+5AE0VYDTfDBcxzgQbik/8YVv93gMp9AbK/cEAD8T+m1TBb/oD8veEHhs0IE2GmxADZMRAmz4//WKxGkv3DA2Gm/MeqcA/Ujj1w1hHsCv/LQKQz/megRzyawgqIvAxMRwsuhbCEAEvGT3AphEUwNCU5IEv9R8lcUH9/wAxE5HAEgjccSBI8X3CbKOyBxAnhxm3i/w1IEgdQZFA98/+PCFydDKo6VKsZmGPQ0wgOq/+fgYvfQTORkeq1AgCIAvD7+THsDgAAAABJRU5ErkJggg==', + 'W' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QFhZRKnzkAAAAB3RJTUUH0wUOEDIR66frkQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAXNJREFUeNrtlK1ywkAUhZdMZsJMKyIqKhAIBAKBiEBEVCDyCJV9iIo+Do9QGRERgUBEVCAqKhAIREVERURnTvfn3t27xSA6g+kOQ/ZkP/aec5NlBHXZSC7k/sE/AhUwoVkDPQ58/2RUQ2IC6B1XpN7MV8tg62/pUdjSDO7OwR2J0pbekpqZYlMG50bNSGwBDQ4pyV5YtCZ7mqZf1mO2IN2Jynba0XRx49pThjQCbEKWFfVRpIlBzlK4PuLdpxEWlTr4LHvYMEDOaTYS3HCW3DAJt8mmaSXYchZbOfEzkyYGZRbrEbX8qe7GMpLqFeyxV9F4fon1pwcxjxbqJpJTBPBJLoyHYSz1I3xq78aOMssepHZZHFjKhbX9/AZd6e9bsdABeyHTQXiE2PLO6PugCwiP/r1QVLYSlpXwKE1Wno7b7jY+hoWj0aegPyA9+jPrzgqwZJ0j8hhMVtElmDoD19FFPAvamc+sOXBm+KdYEzC63p/9D7Tr72kj/8qjAAAAAElFTkSuQmCC', + 'X' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHi/G9n7kAAAAB3RJTUUH0wUOEDIXAsROpAAAAAlwSFlzAAALEgAACxIB0t1+/AAAAT9JREFUeNpj/M9AHGAiUt3IVhjKCAFr4RJroSKBMIH/YPBEAMITeQLh//8gAxHggQlAFf6fAdXnA+WnQPkT/qMp/O8AlVkA5h2A8kz+YCi8wQGREngA5PxQgXBYzvzHUPi/A2qIA5BdAmUX/Mei8I8BVHbK/wssEJbMB2wK/5+ASvPcgGlZ8x+rQriFAmghgKHwiwJKXPA8wKXw/x4UhT3/cSr8n4CkzuAPHoVvRODqWE6gyPxHTT1ffiAUCjCgAhRtDkgSFnisnoJixAScCh/wEBk8DmiucsChcA5MQQSMMQWrQlgiZ0iAByey5QiFPlBZnS//v+hgxjZc4QKYKVeAnCswby3AUAi3eAGKNoEn6Ap94A5EjXUfNIUrEA6EALgzl6AohCUGsAMhAOZMkTfICkMw3I5wZgiEyzicimYAFRFkVwgDfJ0AAAAASUVORK5CYII=', + 'Y' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHjkyIsu1AAAAB3RJTUUH0wUOEDIkvRQvsgAAAAlwSFlzAAALEgAACxIB0t1+/AAAANJJREFUeNrt1L0NgzAQBWAcUVB6AAZgBAoKhmAICoZgCAoKxmAECkbwABSUlBRILwF8duwYhFJEihJ37+6T5T9g8K6N20X3FdDDNjKKOeTIqZLtWcKBU73bCx1lPhgQNTWieY1zRLmGCZFQp1xTSSmBDUUgW754BF+GQLxAPUkMxMb0FlzUsqpKLXhxQPRqo+oIerggCvuMC7jhFJounA4gWhO2OIL6Jp/uzglHrh0fTyAaDRucQaTkUpxDQVBYDWZ/hYze6bsv/A8/DNlP/kgvwzuer4kCMGPZDgAAAABJRU5ErkJggg==', + 'Z' => 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAAAAACpleexAAAAFXRFWHRDcmVhdGlvbiBUaW1lAAfTBQ4QHwfqWOdfAAAAB3RJTUUH0wUOEDIrLasyIwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAL5JREFUeNrl1C0OwkAQBWCWQIJEVPQIFT0GAlHBMRBIBKIHqahAIDlERY9R0UOs3ORh5qVLunmp5GfUZvczbzKzDqtltV7ofgtueHCp16h33xBGwn0KYqoTO/J868Csaj418e0cPujOkLDfmTsECcfcXOGhoC/NZQMUDBUDd5DwxiAtJGzprpCw48xVQcIhM1d6KOgLc/kIBcORgXtIeGGQOyRs6Oq0g7P92YbkRE7bRZhcwhh+6nLF5f7yx30B8Z7FgxzMWtEAAAAASUVORK5CYII=', + ); + + return $_png; + } + + // This is designed to randomise the pixels of the image data within + // certain limits so as to keep it readable. It also varies the image + // width a little + function randomise($scanline, $width) + { + $new_line = ''; + $start = floor($width/2); + $end = strlen($scanline) - ceil($width/2); + + for ($i = $start; $i < $end; $i++) + { + $pixel = ord($scanline{$i}); + + if ($pixel < 190) + { + $new_line .= chr(mt_rand(0, 205)); + } + else if ($pixel > 190) + { + $new_line .= chr(mt_rand(145, 255)); + } + else + { + $new_line .= $scanline{$i}; + } + } + + return $new_line; + } +} diff -r d823e49e2e4e -r c433348f3628 includes/captcha/engine_freecap.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/engine_freecap.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,810 @@ +site_tags[0] = "To avoid spam, please do NOT enter the text if"; + // $this->site_tags[1] = "this site is not puremango.co.uk"; + // or more simply: + // $site_tags[0] = "for use only on puremango.co.uk"; + // reword or add lines as you please + // or if you don't want any text: + $this->site_tags = array(); + + // where to write the above: + // 0=top + // 1=bottom + // 2=both + $this->tag_pos = 1; + + // functions to call for random number generation + // mt_rand produces 'better' random numbers + // but if your server doesn't support it, it's fine to use rand instead + $this->rand_func = "mt_rand"; + $this->seed_func = "mt_srand"; + + // which type of hash to use? + // possible values: "sha1", "md5", "crc32" + // sha1 supported by PHP4.3.0+ + // md5 supported by PHP3+ + // crc32 supported by PHP4.0.1+ + $this->hash_func = $this->session_fetch('hash_func', 'sha1'); + // store in session so can validate in form processor + + // image type: + // possible values: "jpg", "png", "gif" + // jpg doesn't support transparency (transparent bg option ends up white) + // png isn't supported by old browsers (see http://www.libpng.org/pub/png/pngstatus.html) + // gif may not be supported by your GD Lib. + $this->output = "png"; + + // 0=generate pseudo-random string, true=use dictionary + // dictionary is easier to recognise + // - both for humans and computers, so use random string if you're paranoid. + $this->use_dict = false; + // if your server is NOT set up to deny web access to files beginning ".ht" + // then you should ensure the dictionary file is kept outside the web directory + // eg: if www.foo.com/index.html points to c:\website\www\index.html + // then the dictionary should be placed in c:\website\dict.txt + // test your server's config by trying to access the dictionary through a web browser + // you should NOT be able to view the contents. + // can leave this blank if not using dictionary + $this->dict_location = ENANO_ROOT . "/includes/captcha/dicts/default.php"; + + // used to calculate image width, and for non-dictionary word generation + $this->max_word_length = 7; + + // text colour + // 0=one random colour for all letters + // 1=different random colour for each letter + $this->col_type = 1; + + // maximum times a user can refresh the image + // on a 6500 word dictionary, I think 15-50 is enough to not annoy users and make BF unfeasble. + // further notes re: BF attacks in "avoid brute force attacks" section, below + // on the other hand, those attempting OCR will find the ability to request new images + // very useful; if they can't crack one, just grab an easier target... + // for the ultra-paranoid, setting it to <5 will still work for most users + $this->max_attempts = 20; + + // list of fonts to use + // font size should be around 35 pixels wide for each character. + // you can use my GD fontmaker script at www.puremango.co.uk to create your own fonts + // There are other programs to can create GD fonts, but my script allows a greater + // degree of control over exactly how wide each character is, and is therefore + // recommended for 'special' uses. For normal use of GD fonts, + // the GDFontGenerator @ http://www.philiplb.de is excellent for convering ttf to GD + + // the fonts included with freeCap *only* include lowercase alphabetic characters + // so are not suitable for most other uses + // to increase security, you really should add other fonts + $this->font_locations = Array( + //ENANO_ROOT . "/includes/captcha/fonts/assimila.ttf", + //ENANO_ROOT . "/includes/captcha/fonts/elephant.ttf", + //ENANO_ROOT . "/includes/captcha/fonts/swash_normal.ttf", + //ENANO_ROOT . "/includes/captcha/fonts/.ttf", + //ENANO_ROOT . "/includes/captcha/fonts/trekker_regular.ttf" + ENANO_ROOT . "/includes/captcha/fonts/FreeMonoBold.ttf", + ENANO_ROOT . "/includes/captcha/fonts/FreeSerifBold.ttf", + ENANO_ROOT . "/includes/captcha/fonts/LiberationSans-Bold.ttf", + ); + + // background: + // 0=transparent (if jpg, white) + // 1=white bg with grid + // 2=white bg with squiggles + // 3=morphed image blocks + // 'random' background from v1.3 didn't provide any extra security (according to 2 independent experts) + // many thanks to http://ocr-research.org.ua and http://sam.zoy.org/pwntcha/ for testing + // for jpgs, 'transparent' is white + $this->bg_type = 3; + // should we blur the background? (looks nicer, makes text easier to read, takes longer) + $this->blur_bg = false; + + // for bg_type 3, which images should we use? + // if you add your own, make sure they're fairly 'busy' images (ie a lot of shapes in them) + $this->bg_images = Array( + ENANO_ROOT . "/includes/captcha/pics/freecap_im1.jpg", + ENANO_ROOT . "/includes/captcha/pics/freecap_im2.jpg", + ENANO_ROOT . "/includes/captcha/pics/freecap_im3.jpg", + ENANO_ROOT . "/includes/captcha/pics/freecap_im4.jpg", + ENANO_ROOT . "/includes/captcha/pics/allyourbase.jpg" + ); + + // for non-transparent backgrounds only: + // if 0, merges CAPTCHA with bg + // if 1, write CAPTCHA over bg + $this->merge_type = 0; + // should we morph the bg? (recommend yes, but takes a little longer to compute) + $this->morph_bg = true; + + // you shouldn't need to edit anything below this, but it's extensively commented if you do want to play + // have fun, and email me with ideas, or improvements to the code (very interested in speed improvements) + // hope this script saves some spam :-) + } + + ////////////////////////////////////////////////////// + ////// Functions: + ////////////////////////////////////////////////////// + function make_seed() { + // from http://php.net/srand + list($usec, $sec) = explode(' ', microtime()); + return (float) $sec + ((float) $usec * 100000); + } + + function rand_color() { + $rf =& $this->rand_func; + if($this->bg_type==3) + { + // needs darker colour.. + return $rf(10,100); + } else { + return $rf(60,170); + } + } + + function myImageBlur($im) + { + // w00t. my very own blur function + // in GD2, there's a gaussian blur function. bunch of bloody show-offs... :-) + + $width = imagesx($im); + $height = imagesy($im); + + $temp_im = ImageCreateTrueColor($width,$height); + $bg = ImageColorAllocate($temp_im,150,150,150); + + // preserves transparency if in orig image + ImageColorTransparent($temp_im,$bg); + + // fill bg + ImageFill($temp_im,0,0,$bg); + + // anything higher than 3 makes it totally unreadable + // might be useful in a 'real' blur function, though (ie blurring pictures not text) + $distance = 1; + // use $distance=30 to have multiple copies of the word. not sure if this is useful. + + // blur by merging with itself at different x/y offsets: + ImageCopyMerge($temp_im, $im, 0, 0, 0, $distance, $width, $height-$distance, 70); + ImageCopyMerge($im, $temp_im, 0, 0, $distance, 0, $width-$distance, $height, 70); + ImageCopyMerge($temp_im, $im, 0, $distance, 0, 0, $width, $height, 70); + ImageCopyMerge($im, $temp_im, $distance, 0, 0, 0, $width, $height, 70); + // remove temp image + ImageDestroy($temp_im); + + return $im; + } + + function sendImage($pic) + { + // output image with appropriate headers + global $output,$im,$im2,$im3; + // ENANO - obfuscation technique disabled + // (this is for ethical reasons - ask dan at enanocms.org for information on why) + // Basically it outputs an X-Captcha header showing freeCap version, etc. Unnecessary + // header(base64_decode("WC1DYXB0Y2hhOiBmcmVlQ2FwIDEuNCAtIHd3dy5wdXJlbWFuZ28uY28udWs=")); + + if ( $this->debug ) + { + $x = imagesx($pic) - 70; + $y = imagesy($pic) - 20; + + $code = $this->get_code(); + $red = ImageColorAllocateAlpha($pic, 0xAA, 0, 0, 72); + ImageString($pic, 5, $x, $y, $code, $red); + ImageString($pic, 5, 5, $y, "[debug mode]", $red); + } + + switch($this->output) + { + // add other cases as desired + case "jpg": + header("Content-Type: image/jpeg"); + ImageJPEG($pic); + break; + case "gif": + header("Content-Type: image/gif"); + ImageGIF($pic); + break; + case "png": + default: + header("Content-Type: image/png"); + ImagePNG($pic); + break; + } + + // kill GD images (removes from memory) + ImageDestroy($this->im); + ImageDestroy($this->im2); + ImageDestroy($pic); + if(!empty($this->im3)) + { + ImageDestroy($this->im3); + } + exit(); + } + + function make_image() + { + ////////////////////////////////////////////////////// + ////// Create Images + initialise a few things + ////////////////////////////////////////////////////// + + // seed random number generator + // PHP 4.2.0+ doesn't need this, but lower versions will + $this->seed_func($this->make_seed()); + + // how faded should the bg be? (100=totally gone, 0=bright as the day) + // to test how much protection the bg noise gives, take a screenshot of the freeCap image + // and take it into a photo editor. play with contrast and brightness. + // If you can remove most of the bg, then it's not a good enough percentage + switch($this->bg_type) + { + case 0: + break; + case 1: + case 2: + $bg_fade_pct = 65; + break; + case 3: + $bg_fade_pct = 50; + break; + } + // slightly randomise the bg fade + $bg_fade_pct += $this->rand_func(-2,2); + + // read each font and get font character widths + // $font_widths = Array(); + // for($i=0 ; $ifont_locations) ; $i++) + // { + // $handle = fopen($this->font_locations[$i],"r"); + // // read header of GD font, up to char width + // $c_wid = fread($handle,15); + // $font_widths[$i] = ord($c_wid{8})+ord($c_wid{9})+ord($c_wid{10})+ord($c_wid{11}); + // fclose($handle); + // } + + // modify image width depending on maximum possible length of word + // you shouldn't need to use words > 6 chars in length really. + $width = ($this->max_word_length*($this->font_size+10)+75); + $height = 90; + + $this->im = ImageCreateTrueColor($width, $height); + $this->im2 = ImageCreateTrueColor($width, $height); + + //////////////////////////////////////////////////////// + // GENERATE IMAGE // + //////////////////////////////////////////////////////// + + $word = $this->get_code(); + + // save hash of word for comparison + // using hash so that if there's an insecurity elsewhere (eg on the form processor), + // an attacker could only get the hash + // also, shared servers usually give all users access to the session files + // echo `ls /tmp`; and echo `more /tmp/someone_elses_session_file`; usually work + // so even if your site is 100% secure, someone else's site on your server might not be + // hence, even if attackers can read the session file, they can't get the freeCap word + // (though most hashes are easy to brute force for simple strings) + + ////////////////////////////////////////////////////// + ////// Fill BGs and Allocate Colours: + ////////////////////////////////////////////////////// + + // set tag colour + // have to do this before any distortion + // (otherwise colour allocation fails when bg type is 1) + $tag_col = ImageColorAllocate($this->im,10,10,10); + $site_tag_col2 = ImageColorAllocate($this->im2,0,0,0); + + // set debug colours (text colours are set later) + $debug = ImageColorAllocate($this->im, 255, 0, 0); + $debug2 = ImageColorAllocate($this->im2, 255, 0, 0); + + // set background colour (can change to any colour not in possible $text_col range) + // it doesn't matter as it'll be transparent or coloured over. + // if you're using bg_type 3, you might want to try to ensure that the color chosen + // below doesn't appear too much in any of your background images. + $bg = ImageColorAllocate($this->im, 254, 254, 254); + $bg2 = ImageColorAllocate($this->im2, 254, 254, 254); + + // set transparencies + ImageColorTransparent($this->im,$bg); + // im2 transparent to allow characters to overlap slightly while morphing + ImageColorTransparent($this->im2,$bg2); + + // fill backgrounds + ImageFill($this->im,0,0,$bg); + ImageFill($this->im2,0,0,$bg2); + + if($this->bg_type!=0) + { + // generate noisy background, to be merged with CAPTCHA later + // any suggestions on how best to do this much appreciated + // sample code would be even better! + // I'm not an OCR expert (hell, I'm not even an image expert; puremango.co.uk was designed in MsPaint) + // so the noise models are based around my -guesswork- as to what would make it hard for an OCR prog + // ideally, the character obfuscation would be strong enough not to need additional background noise + // in any case, I hope at least one of the options given here provide some extra security! + + $this->im3 = ImageCreateTrueColor($width,$height); + $temp_bg = ImageCreateTrueColor($width*1.5,$height*1.5); + $bg3 = ImageColorAllocate($this->im3,255,255,255); + ImageFill($this->im3,0,0,$bg3); + $temp_bg_col = ImageColorAllocate($temp_bg,255,255,255); + ImageFill($temp_bg,0,0,$temp_bg_col); + + // we draw all noise onto temp_bg + // then if we're morphing, merge from temp_bg to im3 + // or if not, just copy a $widthx$height portion of $temp_bg to $this->im3 + // temp_bg is much larger so that when morphing, the edges retain the noise. + + if($this->bg_type==1) + { + // grid bg: + + // draw grid on x + for($i=$this->rand_func(6,20) ; $i<$width*2 ; $i+=$this->rand_func(10,25)) + { + ImageSetThickness($temp_bg,$this->rand_func(2,6)); + $text_r = $this->rand_func(100,150); + $text_g = $this->rand_func(100,150); + $text_b = $this->rand_func(100,150); + $text_colour3 = ImageColorAllocate($temp_bg, $text_r, $text_g, $text_b); + + ImageLine($temp_bg,$i,0,$i,$height*2,$text_colour3); + } + // draw grid on y + for($i=$this->rand_func(6,20) ; $i<$height*2 ; $i+=$this->rand_func(10,25)) + { + ImageSetThickness($temp_bg,$this->rand_func(2,6)); + $text_r = $this->rand_func(100,150); + $text_g = $this->rand_func(100,150); + $text_b = $this->rand_func(100,150); + $text_colour3 = ImageColorAllocate($temp_bg, $text_r, $text_g, $text_b); + + ImageLine($temp_bg,0,$i,$width*2, $i ,$text_colour3); + } + } else if($this->bg_type==2) { + // draw squiggles! + + $bg3 = ImageColorAllocate($this->im3,255,255,255); + ImageFill($this->im3,0,0,$bg3); + ImageSetThickness($temp_bg,4); + + for($i=0 ; $irand_func(100,150); + $text_g = $this->rand_func(100,150); + $text_b = $this->rand_func(100,150); + $text_colour3 = ImageColorAllocate($temp_bg, $text_r, $text_g, $text_b); + + $points = Array(); + // draw random squiggle for each character + // the longer the loop, the more complex the squiggle + // keep random so OCR can't say "if found shape has 10 points, ignore it" + // each squiggle will, however, be a closed shape, so OCR could try to find + // line terminations and start from there. (I don't think they're that advanced yet..) + for($j=1 ; $j<$this->rand_func(5,10) ; $j++) + { + $points[] = $this->rand_func(1*(20*($i+1)),1*(50*($i+1))); + $points[] = $this->rand_func(30,$height+30); + } + + ImagePolygon($temp_bg,$points,intval(sizeof($points)/2),$text_colour3); + } + + } else if($this->bg_type==3) { + // take random chunks of $this->bg_images and paste them onto the background + + for($i=0 ; $ibg_images) ; $i++) + { + // read each image and its size + $temp_im[$i] = ImageCreateFromJPEG($this->bg_images[$i]); + $temp_width[$i] = imagesx($temp_im[$i]); + $temp_height[$i] = imagesy($temp_im[$i]); + } + + $blocksize = $this->rand_func(20,60); + for($i=0 ; $i<$width*2 ; $i+=$blocksize) + { + // could randomise blocksize here... hardly matters + for($j=0 ; $j<$height*2 ; $j+=$blocksize) + { + $this->image_index = $this->rand_func(0,sizeof($temp_im)-1); + $cut_x = $this->rand_func(0,$temp_width[$this->image_index]-$blocksize); + $cut_y = $this->rand_func(0,$temp_height[$this->image_index]-$blocksize); + ImageCopy($temp_bg, $temp_im[$this->image_index], $i, $j, $cut_x, $cut_y, $blocksize, $blocksize); + } + } + for($i=0 ; $iim3); + + if($this->morph_bg) + { + // morph background + // we do this separately to the main text morph because: + // a) the main text morph is done char-by-char, this is done across whole image + // b) if an attacker could un-morph the bg, it would un-morph the CAPTCHA + // hence bg is morphed differently to text + // why do we morph it at all? it might make it harder for an attacker to remove the background + // morph_chunk 1 looks better but takes longer + + // this is a different and less perfect morph than the one we do on the CAPTCHA + // occasonally you get some dark background showing through around the edges + // it doesn't need to be perfect as it's only the bg. + $morph_chunk = $this->rand_func(1,5); + $morph_y = 0; + for($x=0 ; $x<$width ; $x+=$morph_chunk) + { + $morph_chunk = $this->rand_func(1,5); + $morph_y += $this->rand_func(-1,1); + ImageCopy($this->im3, $temp_bg, $x, 0, $x+30, 30+$morph_y, $morph_chunk, $height*2); + } + + ImageCopy($temp_bg, $this->im3, 0, 0, 0, 0, $width, $height); + + $morph_x = 0; + for($y=0 ; $y<=$height; $y+=$morph_chunk) + { + $morph_chunk = $this->rand_func(1,5); + $morph_x += $this->rand_func(-1,1); + ImageCopy($this->im3, $temp_bg, $morph_x, $y, 0, $y, $width, $morph_chunk); + + } + } else { + // just copy temp_bg onto im3 + ImageCopy($this->im3,$temp_bg,0,0,30,30,$width,$height); + } + + ImageDestroy($temp_bg); + + if($this->blur_bg) + { + $this->myImageBlur($this->im3); + } + } + // for debug: + //sendImage($this->im3); + + ////////////////////////////////////////////////////// + ////// Write Word + ////////////////////////////////////////////////////// + + // write word in random starting X position + $word_start_x = $this->rand_func(5,32); + // y positions jiggled about later + $word_start_y = 50; + + // use last pixelwidth + $font_pixelwidth = $this->font_size + 10; + + if($this->col_type==0) + { + $text_r = $this->rand_color(); + $text_g = $this->rand_color(); + $text_b = $this->rand_color(); + $text_colour2 = ImageColorAllocate($this->im2, $text_r, $text_g, $text_b); + } + + // write each char in different font + for($i=0 ; $icol_type==1) + { + $text_r = $this->rand_color(); + $text_g = $this->rand_color(); + $text_b = $this->rand_color(); + $text_colour2 = ImageColorAllocate($this->im2, $text_r, $text_g, $text_b); + } + + $j = $this->rand_func(0,sizeof($this->font_locations)-1); + // $font = ImageLoadFont($this->font_locations[$j]); + // ImageString($this->im2, $font, $word_start_x+($font_widths[$j]*$i), $word_start_y, $word{$i}, $text_colour2); + ImageTTFText($this->im2, $this->font_size, 0, $word_start_x+(($font_pixelwidth)*$i), $word_start_y, $text_colour2, $this->font_locations[$j], $word{$i}); + } + + // for debug: + // $this->sendImage($this->im2); + + ////////////////////////////////////////////////////// + ////// Morph Image: + ////////////////////////////////////////////////////// + + // calculate how big the text is in pixels + // (so we only morph what we need to) + $word_pix_size = $word_start_x+(strlen($word)*$font_pixelwidth); + + // firstly move each character up or down a bit: + $y_pos = 0; + for($i=$word_start_x ; $i<$word_pix_size ; $i+=$font_pixelwidth) + { + // move on Y axis + // deviates at least 4 pixels between each letter + $prev_y = $y_pos; + do{ + $y_pos = $this->rand_func(-5,5); + } while($y_pos<$prev_y+2 && $y_pos>$prev_y-2); + ImageCopy($this->im, $this->im2, $i, $y_pos, $i, 0, $font_pixelwidth, $height); + + // for debug: + // ImageRectangle($this->im,$i,$y_pos+10,$i+$font_pixelwidth,$y_pos+70,$debug); + } + + // for debug: + // $this->sendImage($this->im); + + ImageFilledRectangle($this->im2,0,0,$width,$height,$bg2); + + // randomly morph each character individually on x-axis + // this is where the main distortion happens + // massively improved since v1.2 + $y_chunk = 1; + $morph_factor = 1; + $morph_x = 0; + for($j=0 ; $jrand_func(-$morph_factor,$morph_factor); + // had to change this to ImageCopyMerge when starting using ImageCreateTrueColor + // according to the manual; "when (pct is) 100 this function behaves identically to imagecopy()" + // but this is NOT true when dealing with transparencies... + ImageCopyMerge($this->im2, $this->im, $orig_x+$morph_x, $i+$y_pos, $orig_x, $i, $font_pixelwidth, $y_chunk, 100); + + // for debug: + //ImageLine($this->im2, $orig_x+$morph_x, $i, $orig_x+$morph_x+1, $i+$y_chunk, $debug2); + //ImageLine($this->im2, $orig_x+$morph_x+$font_pixelwidth, $i, $orig_x+$morph_x+$font_pixelwidth+1, $i+$y_chunk, $debug2); + } + } + + // for debug: + //sendImage($this->im2); + + ImageFilledRectangle($this->im,0,0,$width,$height,$bg); + // now do the same on the y-axis + // (much easier because we can just do it across the whole image, don't have to do it char-by-char) + $y_pos = 0; + $x_chunk = 1; + for($i=0 ; $i<=$width ; $i+=$x_chunk) + { + // can result in image going too far off on Y-axis; + // not much I can do about that, apart from make image bigger + // again, I wish I could do 1.5 pixels + $y_pos += $this->rand_func(-1,1); + ImageCopy($this->im, $this->im2, $i, $y_pos, $i, 0, $x_chunk, $height); + + // for debug: + //ImageLine($this->im,$i+$x_chunk,0,$i+$x_chunk,100,$debug); + //ImageLine($this->im,$i,$y_pos+25,$i+$x_chunk,$y_pos+25,$debug); + } + + // for debug: + //sendImage($this->im); + + // blur edges: + // doesn't really add any security, but looks a lot nicer, and renders text a little easier to read + // for humans (hopefully not for OCRs, but if you know better, feel free to disable this function) + // (and if you do, let me know why) + $this->myImageBlur($this->im); + + // for debug: + //sendImage($this->im); + + if($this->output!="jpg" && $this->bg_type==0) + { + // make background transparent + ImageColorTransparent($this->im,$bg); + } + + + + + + ////////////////////////////////////////////////////// + ////// Try to avoid 'free p*rn' style CAPTCHA re-use + ////////////////////////////////////////////////////// + // ('*'ed to stop my site coming up for certain keyword searches on google) + + // can obscure CAPTCHA word in some cases.. + + // write site tags 'shining through' the morphed image + ImageFilledRectangle($this->im2,0,0,$width,$height,$bg2); + if(is_array($this->site_tags)) + { + for($i=0 ; $isite_tags) ; $i++) + { + // ensure tags are centered + $tag_width = strlen($this->site_tags[$i])*6; + // write tag is chosen position + if($this->tag_pos==0 || $this->tag_pos==2) + { + // write at top + ImageString($this->im2, 2, intval($width/2)-intval($tag_width/2), (10*$i), $this->site_tags[$i], $site_tag_col2); + } + if($this->tag_pos==1 || $this->tag_pos==2) + { + // write at bottom + ImageString($this->im2, 2, intval($width/2)-intval($tag_width/2), ($height-34+($i*10)), $this->site_tags[$i], $site_tag_col2); + } + } + } + ImageCopyMerge($this->im2,$this->im,0,0,0,0,$width,$height,80); + ImageCopy($this->im,$this->im2,0,0,0,0,$width,$height); + // for debug: + //sendImage($this->im); + + + + + ////////////////////////////////////////////////////// + ////// Merge with obfuscated background + ////////////////////////////////////////////////////// + + if($this->bg_type!=0) + { + // merge bg image with CAPTCHA image to create smooth background + + // fade bg: + if($this->bg_type!=3) + { + $temp_im = ImageCreateTrueColor($width,$height); + $white = ImageColorAllocate($temp_im,255,255,255); + ImageFill($temp_im,0,0,$white); + ImageCopyMerge($this->im3,$temp_im,0,0,0,0,$width,$height,$bg_fade_pct); + // for debug: + //sendImage($this->im3); + ImageDestroy($temp_im); + $c_fade_pct = 50; + } else { + $c_fade_pct = $bg_fade_pct; + } + + // captcha over bg: + // might want to not blur if using this method + // otherwise leaves white-ish border around each letter + if($this->merge_type==1) + { + ImageCopyMerge($this->im3,$this->im,0,0,0,0,$width,$height,100); + ImageCopy($this->im,$this->im3,0,0,0,0,$width,$height); + } else { + // bg over captcha: + ImageCopyMerge($this->im,$this->im3,0,0,0,0,$width,$height,$c_fade_pct); + } + } + // for debug: + //sendImage($this->im); + + + ////////////////////////////////////////////////////// + ////// Write tags, remove variables and output! + ////////////////////////////////////////////////////// + + // tag it + // feel free to remove/change + // but if it's not essential I'd appreciate you leaving it + // after all, I've put a lot of work into this and am giving it away for free + // the least you could do is give me credit (or buy me stuff from amazon!) + // but I understand that in professional environments, your boss might not like this tag + // so that's cool. + $tag_str = ""; + // for debug: + //$tag_str = "[".$word."]"; + + // ensure tag is right-aligned + $tag_width = strlen($tag_str)*6; + // write tag + ImageString($this->im, 2, $width-$tag_width, $height-13, $tag_str, $tag_col); + + // unset all sensetive vars + // in case someone include()s this file on a shared server + // you might think this unneccessary, as it exit()s + // but by using register_shutdown_function + // on a -very- insecure shared server, they -might- be able to get the word + unset($word); + // the below aren't really essential, but might aid an OCR attack if discovered. + // so we unset them + + // output final image :-) + $this->sendImage($this->im); + // (sendImage also destroys all used images) + } + + function rand_func($s, $m) + { + global $_starttime; + $tn = microtime_float() - $_starttime; + if ( $tn > 5 ) + { + echo '
';
+      enano_debug_print_backtrace();
+      echo '
'; + exit; + } + $rf =& $this->rand_func; + return $rf($s, $m); + } + + function seed_func($s) + { + $rf =& $this->seed_func; + return $rf($s); + } + + function hash_func($s) + { + $rf =& $this->hash_func; + return $rf($s); + } + +} diff -r d823e49e2e4e -r c433348f3628 includes/captcha/engine_potpourri.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/captcha/engine_potpourri.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,332 @@ +captcha_config = array ( + 'width' => '350', + 'height' => '90', + 'background_color' => '#E5ECF9', + 'jpeg' => '0', + 'jpeg_quality' => '95', + 'pre_letters' => '1', + 'pre_letters_great' => '0', + 'font' => '1', + 'chess' => '2', + 'ellipses' => '2', + 'arcs' => '2', + 'lines' => '2', + 'image' => '0', + 'gammacorrect' => '0.8', + 'foreground_lattice_x' => (string)mt_rand(25, 30), + 'foreground_lattice_y' => (string)mt_rand(25, 30), + 'lattice_color' => $latticecolor, + ); + } + + function make_image() + { + $code = $this->get_code(); + + // Prefs + $total_width = $this->captcha_config['width']; + $total_height = $this->captcha_config['height']; + + $hex_bg_color = $this->get_rgb($this->captcha_config['background_color']); + $bg_color = array(); + $bg_color = explode(",", $hex_bg_color); + + $jpeg = $this->captcha_config['jpeg']; + $img_quality = $this->captcha_config['jpeg_quality']; + // Max quality is 95 + + $pre_letters = $this->captcha_config['pre_letters']; + $pre_letter_great = $this->captcha_config['pre_letters_great']; + $rnd_font = $this->captcha_config['font']; + $chess = $this->captcha_config['chess']; + $ellipses = $this->captcha_config['ellipses']; + $arcs = $this->captcha_config['arcs']; + $lines = $this->captcha_config['lines']; + $image = $this->captcha_config['image']; + + $gammacorrect = $this->captcha_config['gammacorrect']; + + $foreground_lattice_y = $this->captcha_config['foreground_lattice_y']; + $foreground_lattice_x = $this->captcha_config['foreground_lattice_x']; + $hex_lattice_color = $this->get_rgb($this->captcha_config['lattice_color']); + $rgb_lattice_color = array(); + $rgb_lattice_color = explode(",", $hex_lattice_color); + + $font_debug = false; + + // Fonts and images init + if ($image) + { + $bg_imgs = array(); + if ($img_dir = opendir(ENANO_ROOT.'/includes/captcha/pics/')) + { + while (true == ($file = @readdir($img_dir))) + { + if ((substr(strtolower($file), -3) == 'jpg') || (substr(strtolower($file), -3) == 'gif')) + { + $bg_imgs[] = $file; + } + } + closedir($img_dir); + } + // Grab a random Background Image or set FALSE if none was found + $bg_img = ( count($bg_imgs) ) ? rand(0, (count($bg_imgs)-1)) : false; + } + + $fonts = array(); + if ($fonts_dir = opendir(ENANO_ROOT . '/includes/captcha/fonts/')) + { + while (true == ($file = @readdir($fonts_dir))) + { + if ((substr(strtolower($file), strlen($file)-3, strlen($file)) == 'ttf')) + { + $fonts[] = $file; + } + } + closedir($fonts_dir); + } else { + die('Error reading directory: '.ENANO_ROOT.'/includes/captcha/fonts/'); + } + $font = mt_rand(0, (count($fonts)-1)); + + // Generate + $image = ($this->gdVersion() >= 2) ? imagecreatetruecolor($total_width, $total_height) : imagecreate($total_width, $total_height); + $background_color = imagecolorallocate($image, $bg_color[0], $bg_color[1], $bg_color[2]); + imagefill($image, 0, 0, $background_color); + + // Generate backgrund + if ($chess == '1' || $chess == '2' && rand(0,1)) + { + // Draw rectangles + for($i = 0; $i <= 8; $i++) + { + $rectanglecolor = imagecolorallocate($image, rand(100,200),rand(100,200),rand(100,200)); + imagefilledrectangle($image, 0, 0, round($total_width-($total_width/8*$i)), round($total_height), $rectanglecolor); + $rectanglecolor = imagecolorallocate($image, rand(100,200),rand(100,200),rand(100,200)); + imagefilledrectangle($image, 0, 0, round($total_width-($total_width/8*$i)), round($total_height/2), $rectanglecolor); + } + } + if ($ellipses == '1' || $ellipses == '2' && rand(0,1)) + { + // Draw random ellipses + for ($i = 1; $i <= 60; $i++) + { + $ellipsecolor = imagecolorallocate($image, rand(100,250),rand(100,250),rand(100,250)); + imagefilledellipse($image, round(rand(0, $total_width)), round(rand(0, $total_height)), round(rand(0, $total_width/8)), round(rand(0, $total_height/4)), $ellipsecolor); + } + } + if ($arcs == '1' || $arcs == '2' && rand(0,1)) + { + // Draw random partial ellipses + for ($i = 0; $i <= 30; $i++) + { + $linecolor = imagecolorallocate($image, rand(120,255),rand(120,255),rand(120,255)); + $cx = round(rand(1, $total_width)); + $cy = round(rand(1, $total_height)); + $int_w = round(rand(1, $total_width/2)); + $int_h = round(rand(1, $total_height)); + imagearc($image, $cx, $cy, $int_w, $int_h, round(rand(0, 190)), round(rand(191, 360)), $linecolor); + imagearc($image, $cx-1, $cy-1, $int_w, $int_h, round(rand(0, 190)), round(rand(191, 360)), $linecolor); + } + } + if ($lines == '1' || $lines == '2' && rand(0,1)) + { + // Draw random lines + for ($i = 0; $i <= 50; $i++) + { + $linecolor = imagecolorallocate($image, rand(120,255),rand(120,255),rand(120,255)); + imageline($image, round(rand(1, $total_width*3)), round(rand(1, $total_height*5)), round(rand(1, $total_width/2)), round(rand(1, $total_height*2)), $linecolor); + } + } + + $text_color_array = array('255,51,0', '51,77,255', '204,51,102', '0,153,0', '255,166,2', '255,0,255', '255,0,0', '0,255,0', '0,0,255', '0,255,255'); + shuffle($text_color_array); + $pre_text_color_array = array('255,71,20', '71,20,224', '224,71,122', '20,173,20', '255,186,22', '25,25,25'); + shuffle($pre_text_color_array); + $white = imagecolorallocate($image, 255, 255, 255); + $gray = imagecolorallocate($image, 100, 100, 100); + $black = imagecolorallocate($image, 0, 0, 0); + $lattice_color = imagecolorallocate($image, $rgb_lattice_color[0], $rgb_lattice_color[1], $rgb_lattice_color[2]); + + $x_char_position = (round(($total_width - 12) / strlen($code)) + mt_rand(-3, 5)); + + for ($i = 0; $i < strlen($code); $i++) + { + mt_srand((double)microtime()*1000000); + + $char = $code{$i}; + $size = mt_rand(floor($total_height / 3.5), ceil($total_height / 2.8)); + $font = ($rnd_font) ? rand(0, (count($fonts)-1)) : $font; + $angle = mt_rand(-30, 30); + + $char_pos = array(); + $char_pos = imagettfbbox($size, $angle, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + $letter_width = abs($char_pos[0]) + abs($char_pos[4]); + $letter_height = abs($char_pos[1]) + abs($char_pos[5]); + + $x_pos = ($x_char_position / 4) + ($i * $x_char_position); + ($i == strlen($code)-1 && $x_pos >= ($total_width - ($letter_width + 5))) ? $x_pos = ($total_width - ($letter_width + 5)) : ''; + $y_pos = mt_rand(($size * 1.4 ), $total_height - ($size * 0.4)); + + // Pre letters + $size = ($pre_letter_great) ? $size + (2 * $pre_letters) : $size - (2 * $pre_letters); + for ($count = 1; $count <= $pre_letters; $count++) + { + $pre_angle = $angle + mt_rand(-20, 20); + + $text_color = $pre_text_color_array[mt_rand(0,count($pre_text_color_array)-1)]; + $text_color = explode(",", $text_color); + $textcolor = imagecolorallocate($image, $text_color[0], $text_color[1], $text_color[2]); + + imagettftext($image, $size, $pre_angle, $x_pos, $y_pos-2, $white, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + imagettftext($image, $size, $pre_angle, $x_pos+2, $y_pos, $black, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + imagettftext($image, $size, $pre_angle, $x_pos+1, $y_pos-1, $textcolor, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + + $size = ($pre_letter_great) ? $size - 2 : $size + 2; + } + + // Final letters + $text_color = $text_color_array[mt_rand(0,count($text_color_array)-1)]; + $text_color = explode(",", $text_color); + $textcolor = imagecolorallocate($image, $text_color[0], $text_color[1], $text_color[2]); + + imagettftext($image, $size, $angle, $x_pos, $y_pos-2, $white, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + imagettftext($image, $size, $angle, $x_pos+2, $y_pos, $black, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + imagettftext($image, $size, $angle, $x_pos+1, $y_pos-1, $textcolor, ENANO_ROOT.'/includes/captcha/fonts/'.$fonts[$font], $char); + } + + + ($gammacorrect) ? imagegammacorrect($image, 1.0, $gammacorrect) : ''; + + // Generate a white lattice in foreground + if ($foreground_lattice_y) + { + // x lines + $ih = round($total_height / $foreground_lattice_y); + for ($i = 0; $i <= $ih; $i++) + { + imageline($image, 0, $i*$foreground_lattice_y, $total_width, $i*$foreground_lattice_y, $lattice_color); + } + } + if ($foreground_lattice_x) + { + // y lines + $iw = round($total_width / $foreground_lattice_x); + for ($i = 0; $i <= $iw; $i++) + { + imageline($image, $i*$foreground_lattice_x, 0, $i*$foreground_lattice_x, $total_height, $lattice_color); + } + } + + // Font debug + if ($font_debug && !$rnd_font) + { + imagestring($image, 5, 2, 0, $fonts[$font], $white); + imagestring($image, 5, 5, 0, $fonts[$font], $white); + imagestring($image, 5, 4, 2, $fonts[$font], $gray); + imagestring($image, 5, 3, 1, $fonts[$font], $black); + } + + // Display + header("Last-Modified: " . gmdate("D, d M Y H:i:s") ." GMT"); + header("Pragma: no-cache"); + header("Cache-Control: no-store, no-cache, max-age=0, must-revalidate"); + (!$jpeg) ? header("Content-Type: image/png") : header("Content-Type: image/jpeg"); + + (!$jpeg) ? imagepng($image) : imagejpeg($image, '', $img_quality); + imagedestroy($image); + } + + // Function get_rgb by Frank Burian + // http://www.phpfuncs.org/?content=show&id=46 + function get_rgb($hex) { + $hex_array = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, + 'F' => 15); + $hex = str_replace('#', '', strtoupper($hex)); + if (($length = strlen($hex)) == 3) { + $hex = $hex{0}.$hex{0}.$hex{1}.$hex{1}.$hex{2}.$hex{2}; + $length = 6; + } + if ($length != 6 or strlen(str_replace(array_keys($hex_array), '', $hex))) + return NULL; + $rgb['r'] = $hex_array[$hex{0}] * 16 + $hex_array[$hex{1}]; + $rgb['g'] = $hex_array[$hex{2}] * 16 + $hex_array[$hex{3}]; + $rgb['b']= $hex_array[$hex{4}] * 16 + $hex_array[$hex{5}]; + return $rgb['r'].','.$rgb['g'].','.$rgb['b']; + } + + // Function gdVersion by Hagan Fox + // http://de3.php.net/manual/en/function.gd-info.php#52481 + function gdVersion($user_ver = 0) + { + if (! extension_loaded('gd')) { return; } + static $gd_ver = 0; + // Just accept the specified setting if it's 1. + if ($user_ver == 1) { $gd_ver = 1; return 1; } + // Use the static variable if function was called previously. + if ($user_ver !=2 && $gd_ver > 0 ) { return $gd_ver; } + // Use the gd_info() function if possible. + if (function_exists('gd_info')) { + $ver_info = gd_info(); + preg_match('/\d/', $ver_info['GD Version'], $match); + $gd_ver = $match[0]; + return $match[0]; + } + // If phpinfo() is disabled use a specified / fail-safe choice... + if (preg_match('/phpinfo/', ini_get('disable_functions'))) { + if ($user_ver == 2) { + $gd_ver = 2; + return 2; + } else { + $gd_ver = 1; + return 1; + } + } + // ...otherwise use phpinfo(). + ob_start(); + phpinfo(8); + $info = ob_get_contents(); + ob_end_clean(); + $info = stristr($info, 'gd version'); + preg_match('/\d/', $info, $match); + $gd_ver = $match[0]; + return $match[0]; + } +} diff -r d823e49e2e4e -r c433348f3628 includes/captcha/fonts/FreeMonoBold.ttf Binary file includes/captcha/fonts/FreeMonoBold.ttf has changed diff -r d823e49e2e4e -r c433348f3628 includes/captcha/fonts/FreeSerifBold.ttf Binary file includes/captcha/fonts/FreeSerifBold.ttf has changed diff -r d823e49e2e4e -r c433348f3628 includes/captcha/fonts/LiberationSans-Bold.ttf Binary file includes/captcha/fonts/LiberationSans-Bold.ttf has changed diff -r d823e49e2e4e -r c433348f3628 includes/captcha/pics/allyourbase.jpg Binary file includes/captcha/pics/allyourbase.jpg has changed diff -r d823e49e2e4e -r c433348f3628 includes/captcha/pics/freecap_im1.jpg Binary file includes/captcha/pics/freecap_im1.jpg has changed diff -r d823e49e2e4e -r c433348f3628 includes/captcha/pics/freecap_im2.jpg Binary file includes/captcha/pics/freecap_im2.jpg has changed diff -r d823e49e2e4e -r c433348f3628 includes/captcha/pics/freecap_im3.jpg Binary file includes/captcha/pics/freecap_im3.jpg has changed diff -r d823e49e2e4e -r c433348f3628 includes/captcha/pics/freecap_im4.jpg Binary file includes/captcha/pics/freecap_im4.jpg has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/css/enano-shared.css --- a/includes/clientside/css/enano-shared.css Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/css/enano-shared.css Fri Feb 22 12:51:53 2008 -0500 @@ -52,7 +52,7 @@ opacity: 0.6; /*filter: alpha(opacity=60);*/ } -div.toolbar a:hover img { +div.toolbar a:hover img, div.toolbar a:focus img { opacity: 1; /*filter: alpha(opacity=100);*/ } @@ -67,7 +67,7 @@ max-height: 16px; text-decoration: none; } -div.toolbar a:hover { +div.toolbar a:hover, div.toolbar a:focus { border: 1px solid #202090; background-color: #ceceed; color: #000000; @@ -163,6 +163,14 @@ div.tblholder th.subhead { padding: 4px; background-color: #90A0B0; font-weight: bold; text-align: center; color: #FFFFFF; } div.tblholder table { background-color: #FFFFFF; width: 100%; } +/* Colored table cells */ +div.tblholder td.row1_red { padding: 4px; background-color: #F8E0E0; } +div.tblholder td.row2_red { padding: 4px; background-color: #FFF0F0; } +div.tblholder td.row3_red { padding: 4px; background-color: #FFE8E8; } +div.tblholder td.row1_green { padding: 4px; background-color: #E0F8E0; } +div.tblholder td.row2_green { padding: 4px; background-color: #F0FFF0; } +div.tblholder td.row3_green { padding: 4px; background-color: #E8FFE8; } + /* Well, not Midget and not comments (usually), but that's what the class is called ;-). Basically an informational window or used as a wrapper for tables. */ .mdg-comment, .mdg-infobox { margin-left: 1em; padding: 7px; border: 1px solid #AAAAAA; background-color: #E8E8E8; } @@ -185,6 +193,7 @@ div.search-result span.search-result-info { color: #7777CC; } div.search-result span.search-result-url { color: green; } div.search-result span.search-term, div.search-result span.title-search-term { background-color: #FFFFC0; font-weight: bold; } +div.search-result span.url-search-term { font-weight: bold; } div.search-result span.search-result-annotation { font-size: 8pt; } div.search-hibar { border-top: 1px solid #3366CC; margin-top: 10px; color: #000; background-color: #D5DFF3; padding: 3px; vertical-align: middle; } div.search-lobar { background-color: #E5EFFF; margin: 0; padding: 5px; } @@ -416,6 +425,10 @@ .usermessage a:hover { color: #AA5500 !important; } +.usermessage h2 { + border-bottom-color: #ef8500 !important; + color: black; +} div.thumbnail { display: table; border: 1px solid #AAAAAA; @@ -518,3 +531,185 @@ font-size: 0.7em; } +/* Default private message AJAX interface styles (colors and style based on those of Gmail) */ + +div#privmsgs { + /* Neal prefers this border but I personally consider it distasteful because it detracts from the Gmail-ey look. + border: 1px solid #c0c0c0; */ + background-color: white; + color: black; +} + +span.pm_link { + color: #0000ff; + cursor: pointer; + text-decoration: underline; +} + +span.pm_link_folder { + display: block; + text-decoration: none; + padding: 3px; +} + +span.pm_link_selected { + background-color: #c3d9ff; + font-weight: bold; + text-decoration: underline; +} + +span.pm_link_selected_trash { + background-color: #d9d9db; +} + +div.pm_break { + height: 10px; +} + +div.pm_main { + background-color: #c3d9ff; + padding: 5px 5px 3px 5px; + margin-left: 12em; + min-height: 16em; +} + +div.pm_main_trash { + background-color: #d9d9db; +} + +div.pm_status { + display: table; + background-color: #cc0000; + padding: 3px; + margin: 0 auto; + color: white; +} + +div.pm_teaser { + background-color: white; + color: black; + text-align: center; + padding: 8em 1em 8em 1em; +} + +div.pm_mlist_message { + background-color: #e8eef7; + color: black; + border-bottom: 1px solid #d8d8d8; + cursor: pointer; +} + +div.pm_mlist_message span.pm_subject { + font-weight: normal; + display: inline-block; + clip: rect(0px, auto, auto, 0px); + overflow: hidden; + margin: 0 3px 0 0; +} + +div.pm_mlist_message span.pm_sender { + display: inline-block; + width: 30%; + margin: 0 10px 0% 4px; + font-weight: normal; + clip: rect(0px, auto, auto, 0px); + overflow: hidden; +} + +div.pm_mlist_message span.pm_miniclip { + color: #909090; + display: inline-block; + clip: rect(0px, auto, auto, 0px); + overflow: hidden; +} + +div.pm_messagelist_inner { + min-height: 12em; + background-color: white; +} + +div.pm_mlist_message_unread { + background-color: white; +} + +div.pm_mlist_message_unread span.pm_subject { + font-weight: bold; +} + +div.pm_mlist_message_unread span.pm_sender { + font-weight: bold; +} + +div.pm_mlist_message_selected { + background-color: #ffffcc; +} + +span.pm_toolbar_label { + color: black; + font-weight: bold; +} + +div.noborderbottom * { + border-bottom-width: 0px; +} + +div.nobordertop * { + border-top-width: 0px; +} + +/* Theme buttons in admin CP */ + +div.themebutton { + width: 216px; + float: left; + background-position: center center; + background-repeat: no-repeat; + margin-right: 10px; + padding: 5px; + border: 1px solid #F0F0F0; +} + +div.themebutton_theme_disabled { + background-color: #D84308; +} + +div.themebutton_theme_system { + display: none; +} + +div.themebutton a.tb-inner { + opacity: 0; + filter: alpha(opacity=0); + display: block; + height: 110px; + padding-top: 40px; + text-align: center; + font-size: 40px; + text-decoration: none; +} +div.themebutton_theme_system a.tb-inner { + font-size: 28px; + height: 100px; + padding-top: 50px; +} +div.themebutton a.tb-inner:hover { + opacity: 0.75; + filter: alpha(opacity=75); + background-color: #ffffff; +} +div.themebutton a.tb-inner span.themename { + font-size: 8pt; + color: #606060; + display: block; +} + +div.themebutton div.status { + opacity: 0.75; + filter: alpha(opacity=75); + background-image: url(../../../images/loading-big.gif); + background-repeat: no-repeat; + background-position: center center; + background-color: #ffffff; + height: 150px; +} + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/jsres.php --- a/includes/clientside/jsres.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/jsres.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * jsres.php - the Enano client-side runtime, a.k.a. AJAX on steroids * @@ -13,82 +13,173 @@ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. */ -if(!isset($_GET['title'])) $_GET['title'] = 'null'; -require('../common.php'); +// Disable for IE, it causes problems. +if ( strstr(@$_SERVER['HTTP_USER_AGENT'], 'MSIE') ) +{ + header('HTTP/1.1 302 Redirect'); + header('Location: static/enano-lib-basic.js'); + exit(); +} -define('ENABLE_COMPRESSION', ''); +// Setup Enano + +// +// Determine the location of Enano as an absolute path. +// -ob_start(); -header('Content-type: text/javascript'); +// We need to see if this is a specially marked Enano development server. You can create an Enano +// development server by cloning the Mercurial repository into a directory named repo, and then +// using symlinks to reference the original files so as to segregate unique files from non-unique +// and distribution-standard ones. Enano will pivot its root directory accordingly if the file +// .enanodev is found in the Enano root (not /repo/). +if ( strpos(__FILE__, '/repo/') && ( file_exists('../../.enanodev') || file_exists('../../../.enanodev') ) ) +{ + // We have a development directory. Remove /repo/ from the picture. + $filename = str_replace('/repo/', '/', __FILE__); +} +else +{ + // Standard Enano installation + $filename = __FILE__; +} -$file = ( isset($_GET['file']) ) ? $_GET['file'] : 'enano-lib-basic.js'; +// ENANO_ROOT is sometimes defined by plugins like AjIM that need the constant before the Enano API is initialized +if ( !defined('ENANO_ROOT') ) + define('ENANO_ROOT', dirname(dirname(dirname($filename)))); + +chdir(ENANO_ROOT); + +// CONFIG -if(!preg_match('/^([a-z0-9_-]+)\.js$/i', $file)) - die('// ERROR: Hacking attempt'); +// Files safe to run full (aggressive) compression on +$full_compress_safe = array( + // Sorted by file size, descending (du -b *.js | sort -n) + 'libbigint.js', + 'ajax.js', + 'editor.js', + 'acl.js', + 'misc.js', + 'comments.js', + 'rijndael.js', + 'autofill.js', + 'dropdown.js', + 'paginate.js', + 'autocomplete.js', + 'md5.js', + 'pwstrength.js', + 'sha256.js', + 'flyin.js', + 'template-compiler.js', + 'toolbar.js', + 'diffiehellman.js', + 'enanomath.js' +); -$fname = './static/' . $file; -if ( !file_exists($fname) ) - die('// ERROR: File not found: ' . $file); +// Files that should NOT be compressed due to already being compressed, licensing, or invalid produced code +$compress_unsafe = array('SpryEffects.js', 'json.js', 'fat.js', 'admin-menu.js'); + +require('includes/functions.php'); +require('includes/json2.php'); +require('includes/js-compressor.php'); -$everything = file_get_contents($fname); +// Output format will always be JS +header('Content-type: text/javascript'); +$everything = ''; -$mtime = filemtime($fname); -header('Last-Modified: '.date('D, d M Y H:i:s T', $mtime)); -header('Content-disposition: attachment; filename=' . $file); +// Load and parse enano_lib_basic +$file = @file_get_contents('includes/clientside/static/enano-lib-basic.js'); + +$pos_start_includes = strpos($file, '/*!START_INCLUDER*/'); +$pos_end_includes = strpos($file, '/*!END_INCLUDER*/'); -if(defined('ENABLE_COMPRESSION')) +if ( !$pos_start_includes || !$pos_end_includes ) +{ + die('// Error: enano-lib-basic does not have required metacomments'); +} + +$pos_end_includes += strlen('/*!END_INCLUDER*/'); + +preg_match('/var thefiles = (\[([^\]]+?)\]);/', $file, $match); + +if ( empty($match) ) + die('// Error: could not retrieve file list from enano-lib-basic'); + +// Decode file list +try +{ + $file_list = enano_json_decode($match[1]); +} +catch ( Exception $e ) { - echo "/* - * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) - * [Aggressively compressed] Javascript client code - * Copyright (C) 2006-2007 Dan Fuhry - * Enano is Free Software, licensed under the GNU General Public License; see http://enanocms.org/ for details. - */ + die("// Exception caught during file list parsing"); +} + +$apex = filemtime('includes/clientside/static/enano-lib-basic.js'); + +$before_includes = substr($file, 0, $pos_start_includes); +$after_includes = substr($file, $pos_end_includes); + +$everything .= $before_includes; +$everything .= $after_includes; -"; +foreach ( $file_list as $js_file ) +{ + $file_contents = file_get_contents("includes/clientside/static/$js_file"); + $file_md5 = md5($file_contents); + $time = filemtime("includes/clientside/static/$js_file"); + if ( $time > $apex ) + $apex = $time; + // Is this file cached? + $cache_path = ENANO_ROOT . "/cache/jsres_$js_file.json"; + $loaded_cache = false; - $cache_file = ENANO_ROOT . '/cache/jsres-' . $file . '.php'; - - if ( file_exists($cache_file) ) + if ( file_exists($cache_path) ) { - $cached = file_get_contents ( $cache_file ); - $data = unserialize ( $cached ); - if ( $data['md5'] == md5 ( $everything ) ) + // Load the cache file and parse it. + $cache_file = file_get_contents($cache_path); + try + { + $cache_file = enano_json_decode($cache_file); + } + catch ( Exception $e ) + { + // Don't do anything - let our fallbacks come into place + } + if ( is_array($cache_file) && isset($cache_file['md5']) && isset($cache_file['src']) ) { - echo "// The code in this file was fetched from cache\n\n"; - echo $data['code']; - exit; + if ( $cache_file['md5'] === $file_md5 ) + { + $loaded_cache = true; + $file_contents = $cache_file['src']; + } + } + } + if ( !$loaded_cache ) + { + // Try to open the cache file and write to it. If we can't do that, just don't compress the code. + $handle = @fopen($cache_path, 'w'); + if ( $handle ) + { + $aggressive = in_array($js_file, $full_compress_safe); + if ( !in_array($js_file, $compress_unsafe) ) + $file_contents = perform_js_compress($file_contents, $aggressive); + + $payload = enano_json_encode(array( + 'md5' => $file_md5, + 'src' => $file_contents + )); + fwrite($handle, $payload); + fclose($handle); } } - if ( getConfig('cache_thumbs') == '1' ) - { - $js_compressor = new JavascriptCompressor(); - $packed = $js_compressor->getPacked($everything); - $data = Array( - 'md5' => md5 ( $everything ), - 'code' => $packed - ); - echo "// The code in this file was fetched from the static scripts and compressed (packed code cached)\n\n"; - echo $packed; - - $fh = @fopen($cache_file, 'w'); - if (!$fh) - die('// ERROR: Can\'t open cache file for writing'); - fwrite($fh, serialize ( $data ) ); - fclose($fh); - - exit; - } - - echo "// The code in this file was not compressed because packed-script caching is disabled\n\n"; - echo $everything; - + $everything .= "\n // $js_file\n"; + $everything .= "\n" . $file_contents; } -else -{ - echo "// The code in this file was not compressed because all script compression is disabled\n\n"; - echo $everything; -} -?> + +$date = date('r', $apex); +header("Date: $date"); +header("Last-Modified: $date"); + +echo $everything; + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/sbedit.js --- a/includes/clientside/sbedit.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/sbedit.js Fri Feb 22 12:51:53 2008 -0500 @@ -4,7 +4,7 @@ disenable_currentBlock = document.getElementById('disabled_'+id); ajaxGet(makeUrlNS('Special', 'EditSidebar', 'action=disenable&ajax=true&noheaders&id='+id), function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { if(ajax.responseText == 'GOOD') { @@ -31,7 +31,7 @@ delete_currentBlock = { 0 : id, 1 : oElm }; ajaxGet(makeUrlNS('Special', 'EditSidebar', 'action=delete&ajax=true&noheaders&id='+id), function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { if(ajax.responseText == 'GOOD') { @@ -53,7 +53,7 @@ blockEdit_current = { 0 : id, 1 : oElm }; ajaxGet(makeUrlNS('Special', 'EditSidebar', 'action=getsource&noheaders&id='+id), function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { id = blockEdit_current[0]; oElm = blockEdit_current[1]; @@ -71,7 +71,7 @@ thediv.style.margin = '0'; if(ajax.responseText == 'HOUSTON_WE_HAVE_A_PLUGIN') { - thediv.innerHTML = '

This block cannot be edited.

This is a plugin block, and cannot be edited.

close

'; + thediv.innerHTML = '

' + $lang.get('sbedit_msg_cant_edit_plugin_title') + '

' + $lang.get('sbedit_msg_cant_edit_plugin_body', { close_link: 'a href="#" onclick="this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode); return false;"' }) + '

'; } else { @@ -82,7 +82,7 @@ thediv.appendChild(ta); b = document.createElement('br'); thediv.appendChild(b); - thediv.innerHTML += 'save | cancel'; + thediv.innerHTML += '' + $lang.get('sbedit_btn_edit_save') + ' | ' + $lang.get('sbedit_btn_edit_cancel') + ''; } body = document.getElementsByTagName('body'); body = body[0]; @@ -100,7 +100,7 @@ blockSave_current = { 0 : id, 1 : oElm }; ajaxPost(makeUrlNS('Special', 'EditSidebar', 'noheaders&action=save&id='+id), 'content='+taContent, function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { id = blockSave_current[0]; oElm = blockSave_current[1]; @@ -172,7 +172,7 @@ newname = ajaxEscape(newname); ajaxPost(makeUrlNS('Special', 'EditSidebar', 'ajax&noheaders&action=rename&id='+id), 'newname=' +newname, function() { - if ( ajax.readyState == 4 ) + if ( ajax.readyState == 4 && ajax.status == 200 ) { parent.removeChild(img); if ( ajax.responseText != 'GOOD' ) diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/acl.js --- a/includes/clientside/static/acl.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/acl.js Fri Feb 22 12:51:53 2008 -0500 @@ -25,7 +25,7 @@ params = toJSONString(params); params = ajaxEscape(params); ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { var response = String(ajax.responseText + ''); if ( response.substr(0, 1) != '{' ) @@ -49,7 +49,7 @@ aclDataCache = groups; __aclBuildSelector(groups); } - }); + }, true); return false; } @@ -66,11 +66,11 @@ params = toJSONString(params); params = ajaxEscape(params); ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { document.getElementById(aclManagerID+'_main').innerHTML = ''; document.getElementById(aclManagerID + '_back').style.display = 'none'; - document.getElementById(aclManagerID + '_next').value = 'Next >'; + document.getElementById(aclManagerID + '_next').value = $lang.get('etc_wizard_next'); groups = parseJSON(ajax.responseText); if ( groups.mode == 'error' ) { @@ -84,7 +84,7 @@ groups.namespace = thispage[1]; __aclBuildSelector(groups); } - }); + }, true); } function __aclBuildSelector(groups) @@ -115,13 +115,13 @@ grpb.onclick = function() { seed = this.className; document.getElementById('enACL_grpbox_'+seed).style.display = 'block'; document.getElementById('enACL_usrbox_'+seed).style.display = 'none'; }; lbl = document.createElement('label'); lbl.appendChild(grpb); - lbl.appendChild(document.createTextNode('A usergroup')); + lbl.appendChild(document.createTextNode($lang.get('acl_radio_usergroup'))); lbl.style.display = 'block'; span.appendChild(grpsel); anoninfo = document.createElement('div'); anoninfo.className = 'info-box-mini'; - anoninfo.appendChild(document.createTextNode('To edit permissions for guests, select "a specific user", and enter Anonymous as the username.')); + anoninfo.appendChild(document.createTextNode($lang.get('acl_msg_guest_howto'))); span.appendChild(document.createElement('br')); span.appendChild(anoninfo); @@ -133,7 +133,7 @@ usrb.onclick = function() { seed = this.className; document.getElementById('enACL_grpbox_'+seed).style.display = 'none'; document.getElementById('enACL_usrbox_'+seed).style.display = 'block'; }; lbl2 = document.createElement('label'); lbl2.appendChild(usrb); - lbl2.appendChild(document.createTextNode('A specific user')); + lbl2.appendChild(document.createTextNode($lang.get('acl_radio_user'))); lbl2.style.display = 'block'; usrsel = document.createElement('input'); @@ -178,21 +178,21 @@ lblPage = document.createElement('label'); lblPage.style.display = 'block'; lblPage.appendChild(scopeRadioPage); - lblPage.appendChild(document.createTextNode('Only this page')); + lblPage.appendChild(document.createTextNode($lang.get('acl_radio_scope_thispage'))); lblGlobal = document.createElement('label'); lblGlobal.style.display = 'block'; lblGlobal.appendChild(scopeRadioGlobal); - lblGlobal.appendChild(document.createTextNode('The entire website')); + lblGlobal.appendChild(document.createTextNode($lang.get('acl_radio_scope_wholesite'))); lblGroup = document.createElement('label'); lblGroup.style.display = 'block'; lblGroup.appendChild(scopeRadioGroup); - lblGroup.appendChild(document.createTextNode('A group of pages')); + lblGroup.appendChild(document.createTextNode($lang.get('acl_radio_scope_pagegroup'))); scopediv1.appendChild(lblPage); scopediv2.appendChild(lblGroup); scopediv3.appendChild(lblGlobal); scopedesc = document.createElement('p'); - scopedesc.appendChild(document.createTextNode('What should this access rule control?')); + scopedesc.appendChild(document.createTextNode($lang.get('acl_lbl_scope'))); scopePGrp = document.createElement('select'); scopePGrp.style.marginLeft = '13px'; @@ -230,10 +230,10 @@ container.style.paddingTop = '50px'; head = document.createElement('h2'); - head.appendChild(document.createTextNode('Manage page access')); + head.appendChild(document.createTextNode($lang.get('acl_lbl_welcome_title'))); desc = document.createElement('p'); - desc.appendChild(document.createTextNode('Please select who should be affected by this access rule.')); + desc.appendChild(document.createTextNode($lang.get('acl_lbl_welcome_body'))); container.appendChild(head); container.appendChild(desc); @@ -316,7 +316,7 @@ params = toJSONString(params); params = ajaxEscape(params); ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { var response = String(ajax.responseText + ''); if ( response.substr(0, 1) != '{' ) @@ -336,11 +336,14 @@ // Build the ACL edit form // try { - act_desc = ( data.type == 'new' ) ? 'Create access rule' : 'Editing permissions'; - target_type_t = ( data.target_type == 1 ) ? 'group' : 'user'; - target_name_t = data.target_name; - var scope_type = ( data.page_id == false && data.namespace == false ) ? 'this entire site' : ( data.namespace == '__PageGroup' ) ? 'this group of pages' : 'this page'; - html = '

'+act_desc+'

This panel allows you to edit what the '+target_type_t+' "'+target_name_t+'" can do on ' + scope_type + '. Unless you set a permission to "Deny", these permissions may be overridden by other rules.

'; + + var act_desc = ( data.type == 'new' ) ? $lang.get('acl_lbl_editwin_title_create') : $lang.get('acl_lbl_editwin_title_edit'); + var target_type_t = ( data.target_type == 1 ) ? $lang.get('acl_target_type_group') : $lang.get('acl_target_type_user'); + var target_name_t = data.target_name; + var scope_type = ( data.page_id == false && data.namespace == false ) ? $lang.get('acl_scope_type_wholesite') : ( data.namespace == '__PageGroup' ) ? $lang.get('acl_scope_type_pagegroup') : $lang.get('acl_scope_type_thispage'); + + html = '

'+act_desc+'

'; + html += '

' + $lang.get('acl_lbl_editwin_body', { target_type: target_type_t, target: target_name_t, scope_type: scope_type }) + '

'; parser = new templateParser(data.template.acl_field_begin); html += parser.run(); @@ -352,19 +355,34 @@ cls = ( cls == 'row1' ) ? 'row2' : 'row1'; p = new templateParser(data.template.acl_field_item); vars = new Object(); - vars['FIELD_DESC'] = data.acl_descs[i]; + if ( data.acl_descs[i].match(/^([a-z0-9_]+)$/) ) + { + vars['FIELD_DESC'] = $lang.get(data.acl_descs[i]); + } + else + { + vars['FIELD_DESC'] = data.acl_descs[i]; + } + vars['FIELD_INHERIT_CHECKED'] = ''; vars['FIELD_DENY_CHECKED'] = ''; vars['FIELD_DISALLOW_CHECKED'] = ''; vars['FIELD_WIKIMODE_CHECKED'] = ''; vars['FIELD_ALLOW_CHECKED'] = ''; vars['FIELD_NAME'] = i; + if ( !data.current_perms[i] ) + { + data.current_perms[i] = 'i'; + } switch(data.current_perms[i]) { + case 'i': + default: + vars['FIELD_INHERIT_CHECKED'] = 'checked="checked"'; + break; case 1: vars['FIELD_DENY_CHECKED'] = 'checked="checked"'; break; case 2: - default: vars['FIELD_DISALLOW_CHECKED'] = 'checked="checked"'; break; case 3: @@ -384,7 +402,7 @@ html += parser.run(); if(data.type == 'edit') - html += '

Delete this rule

'; + html += '

' + $lang.get('acl_lbl_deleterule') + '

'; var main = document.getElementById(aclManagerID + '_main'); main.innerHTML = html; @@ -400,7 +418,7 @@ aclPermList = array_keys(data.acl_types); document.getElementById(aclManagerID + '_back').style.display = 'inline'; - document.getElementById(aclManagerID + '_next').value = 'Save Changes'; + document.getElementById(aclManagerID + '_next').value = $lang.get('etc_save_changes'); // } catch(e) { alert(e); aclDebug(ajax.responseText); } @@ -410,27 +428,33 @@ note.className = 'info-box'; note.style.marginLeft = '0'; var b = document.createElement('b'); - b.appendChild(document.createTextNode('Permissions updated')); + b.appendChild(document.createTextNode($lang.get('acl_lbl_save_success_title'))); note.appendChild(b); note.appendChild(document.createElement('br')); - note.appendChild(document.createTextNode('The permissions for '+data.target_name+' on this page have been updated successfully. If you changed permissions that affect your user account, you may not see changes until you reload the page.')); + note.appendChild(document.createTextNode($lang.get('acl_lbl_save_success_body', { target_name: data.target_name }))); note.appendChild(document.createElement('br')); var a = document.createElement('a'); - a.href = 'javascript:void(0);'; - a.onclick = function() { this.parentNode.parentNode.removeChild(this.parentNode); return false; }; - a.appendChild(document.createTextNode('[ dismiss :')); + a.href = '#'; + a.id = aclManagerID + '_btn_dismiss'; + a.appendChild(document.createTextNode('[ ' + $lang.get('acl_btn_success_dismiss') + ' :')); note.appendChild(a); var a2 = document.createElement('a'); - a2.href = 'javascript:void(0);'; - a2.onclick = function() { killACLManager(); return false; }; - a2.appendChild(document.createTextNode(': close manager ]')); + a2.href = '#'; + a.id = aclManagerID + '_btn_close'; + a2.appendChild(document.createTextNode(': ' + $lang.get('acl_btn_success_close') + ' ]')); note.appendChild(a2); document.getElementById(aclManagerID + '_main').insertBefore(note, document.getElementById(aclManagerID + '_main').firstChild); if(!document.getElementById(aclManagerID+'_deletelnk')) - document.getElementById(aclManagerID + '_main').innerHTML += '

Delete this rule

'; + document.getElementById(aclManagerID + '_main').innerHTML += '

' + $lang.get('acl_lbl_deleterule') + '

'; //fadeInfoBoxes(); document.getElementById(aclManagerID+'_main').scrollTop = 0; + var a = document.getElementById(aclManagerID + '_btn_dismiss'); + var a2 = document.getElementById(aclManagerID + '_btn_close'); + + a.setAttribute('onclick', function(e) { this.parentNode.parentNode.removeChild(this.parentNode); return false; }); + a2.setAttribute('onclick', function(e) { killACLManager(); return false; }); + aclDataCache.mode = 'save_edit'; break; case 'delete': @@ -441,11 +465,11 @@ params = toJSONString(params); params = ajaxEscape(params); ajaxPost(stdAjaxPrefix+'&_mode=acljson', 'acl_params='+params, function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { document.getElementById(aclManagerID+'_main').innerHTML = ''; document.getElementById(aclManagerID + '_back').style.display = 'none'; - document.getElementById(aclManagerID + '_next').value = 'Next >'; + document.getElementById(aclManagerID + '_next').value = $lang.get('etc_wizard_next'); var thispage = strToPageID(title); groups.page_id = thispage[0]; groups.namespace = thispage[1]; @@ -458,26 +482,26 @@ note.style.width = '558px'; note.id = 'aclSuccessNotice_' + Math.floor(Math.random() * 100000); b = document.createElement('b'); - b.appendChild(document.createTextNode('Entry deleted')); + b.appendChild(document.createTextNode($lang.get('acl_lbl_delete_success_title'))); note.appendChild(b); note.appendChild(document.createElement('br')); - note.appendChild(document.createTextNode('The access rules for '+aclDataCache.target_name+' on this page have been deleted.')); + note.appendChild(document.createTextNode($lang.get('acl_lbl_delete_success_body', { target_name: aclDataCache.target_name }))); note.appendChild(document.createElement('br')); a = document.createElement('a'); a.href = '#'; a.onclick = function() { opacity(this.parentNode.id, 100, 0, 1000); setTimeout('var div = document.getElementById("' + this.parentNode.id + '"); div.parentNode.removeChild(div);', 1100); return false; }; - a.appendChild(document.createTextNode('[ dismiss :')); + a.appendChild(document.createTextNode('[ ' + $lang.get('acl_btn_success_dismiss') + ' :')); note.appendChild(a); a = document.createElement('a'); a.href = '#'; a.onclick = function() { killACLManager(); return false; }; - a.appendChild(document.createTextNode(': close manager ]')); + a.appendChild(document.createTextNode(': ' + $lang.get('acl_btn_success_close') + ' ]')); note.appendChild(a); document.getElementById(aclManagerID + '_main').insertBefore(note, document.getElementById(aclManagerID + '_main').firstChild); //fadeInfoBoxes(); } - }); + }, true); break; case 'error': @@ -491,7 +515,7 @@ break; } } - }); + }, true); } function __aclBuildGroupsHTML(groups) @@ -559,7 +583,7 @@ back = document.createElement('input'); back.type = 'button'; - back.value = '< Back'; + back.value = $lang.get('etc_wizard_back'); back.style.fontWeight = 'normal'; back.onclick = function() { ajaxACLSwitchToSelector(); return false; }; back.style.display = 'none'; @@ -567,14 +591,14 @@ saver = document.createElement('input'); saver.type = 'submit'; - saver.value = 'Next >'; + saver.value = $lang.get('etc_wizard_next'); saver.style.fontWeight = 'bold'; saver.id = aclManagerID + '_next'; closer = document.createElement('input'); closer.type = 'button'; - closer.value = 'Cancel Changes'; - closer.onclick = function() { if(!confirm('Do you really want to close the ACL manager?')) return false; killACLManager(); return false; } + closer.value = $lang.get('etc_cancel_changes'); + closer.onclick = function() { if(!confirm($lang.get('acl_msg_closeacl_confirm'))) return false; killACLManager(); return false; } spacer1 = document.createTextNode(' '); spacer2 = document.createTextNode(' '); @@ -641,7 +665,7 @@ var target_type = parseInt(getRadioState(thefrm, 'target_type', ['1', '2'])); if(isNaN(target_type)) { - alert('Please select a target type.'); + alert($lang.get('acl_err_pleaseselect_targettype')); return false; } target_id = ( target_type == 1 ) ? parseInt(thefrm.group_id.value) : thefrm.username.value; @@ -683,7 +707,7 @@ } if(target_id == '') { - alert('Please enter a username.'); + alert($lang.get('acl_err_pleaseselect_username')); return false; } __aclJSONSubmitAjaxHandler(obj); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/ajax.js --- a/includes/clientside/static/ajax.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/ajax.js Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,22 @@ * AJAX applets */ -function ajaxGet(uri, f) { +function ajaxGet(uri, f, call_editor_safe) { + // Is the editor open? + if ( editor_open && !call_editor_safe ) + { + // Make sure the user is willing to close the editor + var conf = confirm($lang.get('editor_msg_confirm_ajax')); + if ( !conf ) + { + // Kill off any "loading" windows, etc. and cancel the request + unsetAjaxLoading(); + return false; + } + // The user allowed the editor to be closed. Reset flags and knock out the on-close confirmation. + editor_open = false; + enableUnload(); + } if (window.XMLHttpRequest) { ajax = new XMLHttpRequest(); } else { @@ -19,7 +34,22 @@ ajax.send(null); } -function ajaxPost(uri, parms, f) { +function ajaxPost(uri, parms, f, call_editor_safe) { + // Is the editor open? + if ( editor_open && !call_editor_safe ) + { + // Make sure the user is willing to close the editor + var conf = confirm($lang.get('editor_msg_confirm_ajax')); + if ( !conf ) + { + // Kill off any "loading" windows, etc. and cancel the request + unsetAjaxLoading(); + return false; + } + // The user allowed the editor to be closed. Reset flags and knock out the on-close confirmation. + editor_open = false; + enableUnload(); + } if (window.XMLHttpRequest) { ajax = new XMLHttpRequest(); } else { @@ -50,7 +80,7 @@ function handle_invalid_json(response, customerror) { - var mainwin = $('ajaxEditContainer').object; + var mainwin = $dynano('ajaxEditContainer').object; mainwin.innerHTML = ''; // Title @@ -67,7 +97,7 @@ else { customerror = 'We unexpectedly received the following response from the server. The response should have been in the JSON '; - customerror += 'serialization format, but the response wasn\'t composed only of the JSON response. There are three possible triggers'; + customerror += 'serialization format, but the response wasn\'t composed only of the JSON response. There are three possible triggers '; customerror += 'for this problem:'; var el = document.createElement('p'); el.appendChild(document.createTextNode(customerror)); @@ -106,7 +136,7 @@ var mb = new messagebox(MB_YESNO | MB_ICONEXCLAMATION, 'Do you really want to view this response as HTML?', 'If the response was changed during transmission to include malicious code, you may be allowing that malicious code to run by viewing the response as HTML. Only do this if you have reviewed the response text and have found no suspicious code in it.'); mb.onclick['Yes'] = function() { - var html = $('invalidjson_link').object._resp; + var html = $dynano('invalidjson_link').object._resp; var win = window.open('about:blank', 'invalidjson_htmlwin', 'width=550,height=400,status=no,toolbars=no,toolbar=no,address=no,scroll=yes'); win.document.write(html); } @@ -134,142 +164,12 @@ return text; } -// Page editor - -function ajaxEditor() -{ - // IE <6 pseudo-compatibility - if ( KILL_SWITCH ) - return true; - setAjaxLoading(); - ajaxGet(stdAjaxPrefix+'&_mode=getsource', function() { - if(ajax.readyState == 4) { - unsetAjaxLoading(); - if(edit_open) { - c=confirm('Do you really want to revert your changes?'); - if(!c) return; - } - edit_open = true; - selectButtonMajor('article'); - selectButtonMinor('edit'); - if(in_array('ajaxEditArea', grippied_textareas)) - { - // Allow the textarea grippifier to re-create the resizer control on the textarea - grippied_textareas.pop(in_array('ajaxEditArea', grippied_textareas)); - } - disableUnload('If you do, any changes that you have made to this page will be lost.'); - var switcher = ( readCookie('enano_editor_mode') == 'tinymce' ) ? - 'wikitext editor | graphical editor' : - 'wikitext editor | graphical editor' ; - document.getElementById('ajaxEditContainer').innerHTML = '\ -
\ - ' + switcher + '
\ -
\ -
\ - Edit summary:
\ -
\ - save changes | preview changes | revert changes | discard changes\ -
\ - '+editNotice+'\ -
'; - // initTextareas(); - if(readCookie('enano_editor_mode') == 'tinymce') - { - $('ajaxEditArea').switchToMCE(); - } - } - }); -} - -function setEditorMCE() -{ - $('ajaxEditArea').switchToMCE(); - createCookie('enano_editor_mode', 'tinymce', 365); - $('switcher').object.innerHTML = 'wikitext editor | graphical editor'; -} - -function setEditorText() -{ - $('ajaxEditArea').destroyMCE(); - createCookie('enano_editor_mode', 'text', 365); - $('switcher').object.innerHTML = 'wikitext editor | graphical editor'; -} - -function ajaxViewSource() -{ - // IE <6 pseudo-compatibility - if ( KILL_SWITCH ) - return true; - setAjaxLoading(); - ajaxGet(stdAjaxPrefix+'&_mode=getsource', function() { - if(ajax.readyState == 4) { - unsetAjaxLoading(); - if(edit_open) { - c=confirm('Do you really want to revert your changes?'); - if(!c) return; - } - edit_open = true; - selectButtonMajor('article'); - selectButtonMinor('edit'); - if(in_array('ajaxEditArea', grippied_textareas)) - { - // Allow the textarea grippifier to re-create the resizer control on the textarea - grippied_textareas.pop(in_array('ajaxEditArea', grippied_textareas)); - } - document.getElementById('ajaxEditContainer').innerHTML = '\ -
\ -
\ - close viewer\ -
'; - initTextareas(); - } - }); -} - -function ajaxShowPreview() -{ - // IE <6 pseudo-compatibility - if ( KILL_SWITCH ) - return true; - goBusy('Loading preview...'); - var text = ajaxEscape($('ajaxEditArea').getContent()); - if(document.mdgAjaxEditor.minor.checked) minor='&minor'; - else minor=''; - ajaxPost(stdAjaxPrefix+'&_mode=preview', 'summary='+document.getElementById('ajaxEditSummary').value+minor+'&text='+text, function() { - if(ajax.readyState == 4) { - unBusy(); - edit_open = false; - document.getElementById('mdgPreviewContainer').innerHTML = ajax.responseText; - } - }); -} - -function ajaxSavePage() -{ - // IE <6 pseudo-compatibility - if ( KILL_SWITCH ) - return true; - //goBusy('Saving page...'); - var text = ajaxEscape($('ajaxEditArea').getContent()); - if(document.mdgAjaxEditor.minor.checked) minor='&minor'; - else minor=''; - ajaxPost(stdAjaxPrefix+'&_mode=savepage', 'summary='+document.getElementById('ajaxEditSummary').value+minor+'&text='+text, function() { - if(ajax.readyState == 4) { - unBusy(); - edit_open = false; - document.getElementById('ajaxEditContainer').innerHTML = ajax.responseText; - enableUnload(); - unselectAllButtonsMinor(); - } - }); -} - function ajaxDiscard() { // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - c = confirm('Do you really want to discard your changes?'); + c = confirm($lang.get('editor_msg_discard_confirm')); if(!c) return; ajaxReset(); } @@ -279,12 +179,16 @@ // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; + var ns_id = strToPageID(title); + if ( ns_id[1] == 'Special' || ns_id[1] == 'Admin' ) + return false; enableUnload(); setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=getpage&noheaders', function() { - if(ajax.readyState == 4) { + // Allow for 404 here, it's generated by the "page not found" error message + // (even with noheaders specified, probably should be fixed) + if ( ajax.readyState == 4 && ( ajax.status == 200 || ajax.status == 404 ) ) { unsetAjaxLoading(); - edit_open = false; document.getElementById('ajaxEditContainer').innerHTML = ajax.responseText; selectButtonMajor('article'); unselectAllButtonsMinor(); @@ -301,7 +205,7 @@ if(shift) { r = 'NO_REASON'; } else { - r = prompt('Reason for (un)protecting:'); + r = prompt($lang.get('ajax_protect_prompt_reason')); if(!r || r=='') return; } setAjaxLoading(); @@ -310,12 +214,12 @@ document.getElementById('protbtn_2').style.textDecoration = 'none'; document.getElementById('protbtn_'+l).style.textDecoration = 'underline'; ajaxPost(stdAjaxPrefix+'&_mode=protect', 'reason='+ajaxEscape(r)+'&level='+l, function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); if(ajax.responseText != 'good') alert(ajax.responseText); } - }); + }, true); } function ajaxRename() @@ -323,15 +227,15 @@ // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - r = prompt('What title should this page be renamed to?\nNote: This does not and will never change the URL of this page, that must be done from the admin panel.'); + r = prompt($lang.get('ajax_rename_prompt')); if(!r || r=='') return; setAjaxLoading(); ajaxPost(stdAjaxPrefix+'&_mode=rename', 'newtitle='+ajaxEscape(r), function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); alert(ajax.responseText); } - }); + }, true); } function ajaxMakePage() @@ -341,7 +245,7 @@ return true; setAjaxLoading(); ajaxPost(ENANO_SPECIAL_CREATEPAGE, ENANO_CREATEPAGE_PARAMS, function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); window.location.reload(); } @@ -353,19 +257,19 @@ // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - var reason = prompt('Please enter your reason for deleting this page.'); + var reason = prompt($lang.get('ajax_delete_prompt_reason')); if ( !reason || reason == '' ) { return false; } - c = confirm('You are about to REVERSIBLY delete this page. Do you REALLY want to do this?\n\n(Comments and categorization data, as well as any attached files, will be permanently lost)'); + c = confirm($lang.get('ajax_delete_confirm')); if(!c) { return; } setAjaxLoading(); ajaxPost(stdAjaxPrefix+'&_mode=deletepage', 'reason=' + ajaxEscape(reason), function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); alert(ajax.responseText); window.location.reload(); @@ -378,15 +282,15 @@ // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - c = confirm('Are you sure that you want to vote that this page be deleted?'); + c = confirm($lang.get('ajax_delvote_confirm')); if(!c) return; setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=delvote', function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); alert(ajax.responseText); } - }); + }, true); } function ajaxResetDelVotes() @@ -394,11 +298,11 @@ // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - c = confirm('This will reset the number of votes against this page to zero. Do you really want to do this?'); + c = confirm($lang.get('ajax_delvote_reset_confirm')); if(!c) return; setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=resetdelvotes', function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); alert(ajax.responseText); item = document.getElementById('mdgDeleteVoteNoticeBox'); @@ -408,7 +312,7 @@ setTimeout("document.getElementById('mdgDeleteVoteNoticeBox').style.display = 'none';", 1000); } } - }); + }, true); } function ajaxSetWikiMode(val) { @@ -421,7 +325,7 @@ document.getElementById('wikibtn_2').style.textDecoration = 'none'; document.getElementById('wikibtn_'+val).style.textDecoration = 'underline'; ajaxGet(stdAjaxPrefix+'&_mode=setwikimode&mode='+val, function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); if(ajax.responseText!='GOOD') { @@ -442,7 +346,7 @@ return true; setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=catedit', function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); edit_open = false; eval(ajax.responseText); @@ -470,7 +374,7 @@ setAjaxLoading(); query = query.substring(1, query.length); ajaxPost(stdAjaxPrefix+'&_mode=catsave', query, function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); edit_open = false; if(ajax.responseText != 'GOOD') alert(ajax.responseText); @@ -488,7 +392,7 @@ return true; setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=histlist', function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); edit_open = false; selectButtonMajor('article'); @@ -506,7 +410,7 @@ if(!tit) tit=title; setAjaxLoading(); ajaxGet(append_sid(scriptPath+'/ajax.php?title='+tit+'&_mode=getpage&oldid='+oldid), function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); edit_open = false; document.getElementById('ajaxEditContainer').innerHTML = ajax.responseText; @@ -520,7 +424,7 @@ return true; setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=rollback&id='+id, function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); alert(ajax.responseText); } @@ -532,13 +436,13 @@ // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - c = confirm('You are about to DESTROY all log entries for this page. As opposed to (example) deleting this page, this action is completely IRREVERSIBLE and should not be used except in dire circumstances. Do you REALLY want to do this?'); + c = confirm($lang.get('ajax_clearlogs_confirm')); if(!c) return; - c = confirm('You\'re ABSOLUTELY sure???'); + c = confirm($lang.get('ajax_clearlogs_confirm_nag')); if(!c) return; setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=flushlogs', function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); alert(ajax.responseText); window.location.reload(); @@ -622,7 +526,7 @@ setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=pagediff&diff1='+id1+'&diff2='+id2, function() { - if(ajax.readyState==4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); document.getElementById('ajaxEditContainer').innerHTML = ajax.responseText; @@ -638,13 +542,13 @@ if ( KILL_SWITCH ) return true; var inner_html = ''; - inner_html += '

'; - var chtheme_mb = new messagebox(MB_OKCANCEL|MB_ICONQUESTION, 'Change your theme', inner_html); + var chtheme_mb = new messagebox(MB_OKCANCEL|MB_ICONQUESTION, $lang.get('ajax_changestyle_title'), inner_html); chtheme_mb.onbeforeclick['OK'] = ajaxChangeStyleComplete; } @@ -663,7 +567,7 @@ return null; } ajaxGet(stdAjaxPrefix + '&_mode=getstyles&id=' + id, function() { - if ( ajax.readyState == 4 ) + if ( ajax.readyState == 4 && ajax.status == 200 ) { // IE doesn't like substr() on ajax.responseText var response = String(ajax.responseText + ' '); @@ -689,7 +593,7 @@ var p_parent = document.createElement('p'); var label = document.createElement('label'); p_parent.id = 'chtheme_sel_style_parent'; - label.appendChild(document.createTextNode('Style: ')); + label.appendChild(document.createTextNode($lang.get('ajax_changestyle_lbl_style') + ' ')); var select = document.createElement('select'); select.id = 'chtheme_sel_style'; for ( var i in options ) @@ -706,7 +610,7 @@ kid.appendChild(p_parent); } - }); + }, true); } function ajaxChangeStyleComplete() @@ -714,11 +618,11 @@ // IE <6 pseudo-compatibility if ( KILL_SWITCH ) return true; - var theme = $('chtheme_sel_theme'); - var style = $('chtheme_sel_style'); + var theme = $dynano('chtheme_sel_theme'); + var style = $dynano('chtheme_sel_style'); if ( !theme.object || !style.object ) { - alert('Please select a theme from the list.'); + alert($lang.get('ajax_changestyle_pleaseselect_theme')); return true; } var theme_id = theme.object.value; @@ -738,11 +642,11 @@ ajaxPost(stdAjaxPrefix + '&_mode=change_theme', 'theme_id=' + ajaxEscape(theme_id) + '&style_id=' + ajaxEscape(style_id), function() { - if ( ajax.readyState == 4 ) + if ( ajax.readyState == 4 && ajax.status == 200 ) { if ( ajax.responseText == 'GOOD' ) { - var c = confirm('Your theme preference has been changed.\nWould you like to reload the page now to see the changes?'); + var c = confirm($lang.get('ajax_changestyle_success')); if ( c ) window.location.reload(); } @@ -751,7 +655,7 @@ alert('Error occurred during attempt to change theme:\n' + ajax.responseText); } } - }); + }, true); return false; @@ -794,7 +698,7 @@ function ajaxGetStyles(id) { setAjaxLoading(); ajaxGet(stdAjaxPrefix+'&_mode=getstyles&id='+id, function() { - if(ajax.readyState == 4) { + if ( ajax.readyState == 4 && ajax.status == 200 ) { unsetAjaxLoading(); eval(ajax.responseText); html = '

And a style...

'; else html += ''; html += ' '; - html += ' Comment subject:'; - html += ' Comment:'; + html += ' ' + $lang.get('comment_postform_field_subject') + ''; + html += ' ' + $lang.get('comment_postform_field_comment') + ''; if ( !data.logged_in && data.guest_posting == '1' ) { - html += ' Visual confirmation:
Please enter the confirmation code seen in the image on the right into the box. If you cannot read the code, please click on the image to generate a new one. This helps to prevent automated bot posting.'; + html += ' ' + $lang.get('comment_postform_field_captcha_title') + '
' + $lang.get('comment_postform_field_captcha_blurb') + ''; html += ' CAPTCHA image
'; - html += ' Confirmation code: '; + html += ' ' + $lang.get('comment_postform_field_captcha_label') + ' '; html += ' '; html += ' '; } - html += ' '; + html += ' '; html += ' '; html += ''; - } document.getElementById('ajaxEditContainer').innerHTML = html; @@ -171,37 +176,55 @@ tplvars.SIGNATURE = this_comment.signature; if ( this_comment.approved != '1' ) - tplvars.SUBJECT += ' (Unapproved)'; + tplvars.SUBJECT += ' ' + $lang.get('comment_msg_note_unapp') + ''; // Name tplvars.NAME = this_comment.name; if ( this_comment.user_id > 1 ) tplvars.NAME = '' + this_comment.name + ''; + // Avatar + if ( this_comment.user_has_avatar == '1' ) + { + tplvars.AVATAR_URL = scriptPath + '/' + data.avatar_directory + '/' + this_comment.user_id + '.' + this_comment.avatar_type; + tplvars.USERPAGE_LINK = makeUrlNS('User', this_comment.name); + tplvars.AVATAR_ALT = $lang.get('usercp_avatar_image_alt', { username: this_comment.name }); + } + // User level - tplvars.USER_LEVEL = 'Guest'; - if ( this_comment.user_level >= data.user_level.member ) tplvars.USER_LEVEL = 'Member'; - if ( this_comment.user_level >= data.user_level.mod ) tplvars.USER_LEVEL = 'Moderator'; - if ( this_comment.user_level >= data.user_level.admin ) tplvars.USER_LEVEL = 'Administrator'; - + tplvars.USER_LEVEL = $lang.get('user_type_guest'); + if ( this_comment.user_level >= data.user_level.member ) tplvars.USER_LEVEL = $lang.get('user_type_member'); + if ( this_comment.user_level >= data.user_level.mod ) tplvars.USER_LEVEL = $lang.get('user_type_mod'); + if ( this_comment.user_level >= data.user_level.admin ) tplvars.USER_LEVEL = $lang.get('user_type_admin'); + // Send PM link - tplvars.SEND_PM_LINK=(this_comment.user_id>1 && data.logged_in)?'Send private message
':''; + tplvars.SEND_PM_LINK=(this_comment.user_id>1)?'' + $lang.get('comment_btn_send_privmsg') + '
':''; // Add buddy link - tplvars.ADD_BUDDY_LINK=(this_comment.user_id>1 && data.logged_in && this_comment.is_buddy != 1)?'Add to buddy list
':''; + tplvars.ADD_BUDDY_LINK=(this_comment.user_id>1)?'' + $lang.get('comment_btn_add_buddy') + '
':''; // Edit link - tplvars.EDIT_LINK='edit'; + tplvars.EDIT_LINK='' + $lang.get('comment_btn_edit') + ''; // Delete link - tplvars.DELETE_LINK='delete'; + tplvars.DELETE_LINK='' + $lang.get('comment_btn_delete') + ''; // Moderation: (Un)approve link - var appr = ( this_comment.approved == 1 ) ? 'Unapprove' : 'Approve'; + var appr = ( this_comment.approved == 1 ) ? $lang.get('comment_btn_mod_unapprove') : $lang.get('comment_btn_mod_approve'); tplvars.MOD_APPROVE_LINK=''+appr+''; // Moderation: Delete post link - tplvars.MOD_DELETE_LINK='Delete'; + tplvars.MOD_DELETE_LINK='' + $lang.get('comment_btn_mod_delete') + ''; + + // Moderation: IP address link + if ( this_comment.have_ip ) + { + tplvars.MOD_IP_LINK = '' + $lang.get('comment_btn_mod_ip_logged') + ''; + } + else + { + tplvars.MOD_IP_LINK = $lang.get('comment_btn_mod_ip_missing'); + } var tplbool = new Object(); @@ -210,16 +233,22 @@ tplbool.auth_mod = data.auth_mod_comments; tplbool.is_friend = ( this_comment.is_buddy == 1 && this_comment.is_friend == 1 ); tplbool.is_foe = ( this_comment.is_buddy == 1 && this_comment.is_friend == 0 ); + tplbool.user_has_avatar = ( this_comment.user_has_avatar == '1' ); if ( tplbool.is_friend ) - tplvars.USER_LEVEL += '
On your friend list'; + tplvars.USER_LEVEL += '
' + $lang.get('comment_on_friend_list') + ''; else if ( tplbool.is_foe ) - tplvars.USER_LEVEL += '
On your foe list'; + tplvars.USER_LEVEL += '
' + $lang.get('comment_on_foe_list') + ''; parser.assign_vars(tplvars); parser.assign_bool(tplbool); - return '
' + parser.run() + '
'; + var ret = '
'; + ret += ''; + ret += ''; + ret += parser.run(); + ret += '
'; + return ret; } function displayCommentForm() @@ -255,7 +284,7 @@ cmt.appendChild(ta); link.style.fontWeight = 'bold'; - link.innerHTML = 'save'; + link.innerHTML = $lang.get('comment_btn_save'); link.onclick = function() { var id = this.id.substr(this.id.indexOf('_')+1); saveComment(id, this); return false; }; } @@ -273,7 +302,7 @@ 'subj' : subj }; link.style.fontWeight = 'normal'; - link.innerHTML = 'edit'; + link.innerHTML = $lang.get('comment_btn_edit'); link.onclick = function() { var id = this.id.substr(this.id.indexOf('_')+1); editComment(id, this); return false; }; ajaxComments(req); } @@ -282,7 +311,7 @@ { if ( !shift ) { - var c = confirm('Do you really want to delete this comment?'); + var c = confirm($lang.get('comment_msg_delete_confirm')); if(!c) return false; } @@ -340,36 +369,17 @@ } if ( data.approved && data.approved != '1' ) { - document.getElementById('subject_' + data.id).innerHTML += ' (Unapproved)'; + document.getElementById('subject_' + data.id).innerHTML += ' ' + $lang.get('comment_msg_note_unapp') + ''; } if ( data.approved && ( typeof(data.approve_updated) == 'string' && data.approve_updated == 'yes' ) ) { - var appr = ( data.approved == '1' ) ? 'Unapprove' : 'Approve'; + var appr = ( data.approved == '1' ) ? $lang.get('comment_btn_mod_unapprove') : $lang.get('comment_btn_mod_approve'); document.getElementById('comment_approve_'+data.id).innerHTML = appr; - // Update approval status - var p = document.getElementById('comment_status'); - var count = p.firstChild.nodeValue.split(' ')[2]; - - if ( p.firstChild.nextSibling ) - { - var span = p.firstChild.nextSibling; - var is = ( data.approved == '1' ) ? -1 : 1; - var n_unapp = parseInt(span.firstChild.nodeValue.split(' ')[0]) + is; - n_unapp = n_unapp + ''; - } + if ( data.approved == '1' ) + comment_decrement_unapproval(); else - { - var span = document.createElement('span'); - p.innerHTML += ' '; - span.innerHTML = ' '; - span.style.color = '#D84308'; - var n_unapp = '1'; - p.appendChild(span); - } - span.innerHTML = n_unapp + ' of those are unapproved.'; - if ( n_unapp == '0' ) - p.removeChild(span); + comment_increment_unapproval(); } if ( data.text ) { @@ -379,6 +389,13 @@ { document.getElementById('comment_source_' + data.id).value = data.src; } + if ( data.ip_addr ) + { + var span = $dynano('comment_ip_' + data.local_id).object; + if ( !span ) + return false; + span.innerHTML = $lang.get('comment_msg_ip_address') + ' ' + data.ip_addr + ''; + } } function approveComment(id) @@ -396,41 +413,24 @@ // Does the actual DOM object removal function annihiliateComment(id) // Did I spell that right? { - // Approved? - var p = document.getElementById('comment_status'); - + var approved = true; if(document.getElementById('comment_approve_'+id)) { var appr = document.getElementById('comment_approve_'+id).firstChild.nodeValue; - if ( p.firstChild.nextSibling && appr == 'Approve' ) + if ( appr == $lang.get('comment_btn_mod_approve') ) { - var span = p.firstChild.nextSibling; - var t = span.firstChild.nodeValue; - var n_unapp = ( parseInt(t.split(' ')[0]) ) - 1; - if ( n_unapp == 0 ) - p.removeChild(span); - else - span.firstChild.nodeValue = n_unapp + t.substr(t.indexOf(' ')); + approved = false; } } var div = document.getElementById('comment_holder_'+id); div.parentNode.removeChild(div); - var t = p.firstChild.nodeValue.split(' '); - t[2] = ( parseInt(t[2]) - 1 ) + ''; - delete(t.toJSONString); - if ( t[2] == '1' ) + + // update approval status + if ( document.getElementById('comment_count_unapp_inner') && !approved ) { - t[1] = 'is'; - t[3] = 'comment'; + comment_decrement_unapproval(); } - else - { - t[1] = 'are'; - t[3] = 'comments'; - } - t = implode(' ', t); - p.firstChild.nodeValue = t; } function materializeComment(data) @@ -465,38 +465,50 @@ tplvars.NAME = '' + data.name + ''; if ( data.approved != '1' ) - tplvars.SUBJECT += ' (Unapproved)'; + tplvars.SUBJECT += ' ' + $lang.get('comment_msg_note_unapp') + ''; // User level - tplvars.USER_LEVEL = 'Guest'; - if ( data.user_level >= data.user_level_list.member ) tplvars.USER_LEVEL = 'Member'; - if ( data.user_level >= data.user_level_list.mod ) tplvars.USER_LEVEL = 'Moderator'; - if ( data.user_level >= data.user_level_list.admin ) tplvars.USER_LEVEL = 'Administrator'; + tplvars.USER_LEVEL = $lang.get('user_type_guest'); + if ( data.user_level >= data.user_level_list.member ) tplvars.USER_LEVEL = $lang.get('user_type_member'); + if ( data.user_level >= data.user_level_list.mod ) tplvars.USER_LEVEL = $lang.get('user_type_mod'); + if ( data.user_level >= data.user_level_list.admin ) tplvars.USER_LEVEL = $lang.get('user_type_admin'); + + // Avatar + if ( data.user_has_avatar == '1' ) + { + tplvars.AVATAR_URL = scriptPath + '/' + data.avatar_directory + '/' + data.user_id + '.' + data.avatar_type; + tplvars.USERPAGE_LINK = makeUrlNS('User', data.name); + tplvars.AVATAR_ALT = $lang.get('usercp_avatar_image_alt', { username: data.name }); + } // Send PM link - tplvars.SEND_PM_LINK=(data.user_id>1)?'Send private message
':''; + tplvars.SEND_PM_LINK=(data.user_id>1)?'' + $lang.get('comment_btn_send_privmsg') + '
':''; // Add buddy link - tplvars.ADD_BUDDY_LINK=(data.user_id>1)?'Add to buddy list
':''; + tplvars.ADD_BUDDY_LINK=(data.user_id>1)?'' + $lang.get('comment_btn_add_buddy') + '
':''; // Edit link - tplvars.EDIT_LINK='edit'; + tplvars.EDIT_LINK='' + $lang.get('comment_btn_edit') + ''; // Delete link - tplvars.DELETE_LINK='delete'; + tplvars.DELETE_LINK='' + $lang.get('comment_btn_delete') + ''; // Moderation: (Un)approve link - var appr = ( data.approved == 1 ) ? 'Unapprove' : 'Approve'; + var appr = ( data.approved == 1 ) ? $lang.get('comment_btn_mod_unapprove') : $lang.get('comment_btn_mod_approve'); tplvars.MOD_APPROVE_LINK=''+appr+''; // Moderation: Delete post link - tplvars.MOD_DELETE_LINK='Delete'; + tplvars.MOD_DELETE_LINK='' + $lang.get('comment_btn_mod_delete') + ''; + + // Moderation: IP address link + tplvars.MOD_IP_LINK = '' + $lang.get('comment_btn_mod_ip_logged') + ''; var tplbool = new Object(); tplbool.signature = ( data.signature == '' ) ? false : true; tplbool.can_edit = ( data.auth_edit_comments && ( ( data.user_id == data.user_id && data.logged_in ) || data.auth_mod_comments ) ); tplbool.auth_mod = data.auth_mod_comments; + tplbool.user_has_avatar = ( data.user_has_avatar == '1' ); parser.assign_vars(tplvars); parser.assign_bool(tplbool); @@ -519,50 +531,96 @@ document.getElementById('comment_source_'+i).value = data.comment_source; - var p = document.getElementById('comment_status'); - var t = p.firstChild.nodeValue.split(' '); - var n = ( isNaN(parseInt(t[2])) ) ? 0 : parseInt(t[2]); - t[2] = ( n + 1 ) + ''; - delete(t.toJSONString); - if ( t[2] == '1' ) - { - t[1] = 'is'; - t[3] = 'comment'; + var cnt = document.getElementById('comment_count_inner').innerHTML; + cnt = parseInt(cnt); + if ( isNaN(cnt) ) + cnt = 0; + + var subst = { + num_comments: cnt, + page_type: ENANO_PAGE_TYPE } - else - { - t[1] = 'are'; - t[3] = 'comments'; - } - t = implode(' ', t); - p.firstChild.nodeValue = t; + + var count_msg = ( cnt == 0 ) ? $lang.get('comment_msg_count_zero', subst) : ( ( cnt == 1 ) ? $lang.get('comment_msg_count_one', subst) : $lang.get('comment_msg_count_plural', subst) ); + + document.getElementById('comment_status').firstChild.innerHTML = count_msg; if(document.getElementById('comment_approve_'+i)) { - var appr = document.getElementById('comment_approve_'+i).firstChild.nodeValue; - if ( p.firstChild.nextSibling && appr == 'Approve' ) + var is_unappr = document.getElementById('comment_approve_'+i).firstChild.nodeValue; + is_unappr = ( is_unappr == $lang.get('comment_btn_mod_approve') ); + if ( is_unappr ) { - var span = p.firstChild.nextSibling; - var t = span.firstChild.nodeValue; - var n_unapp = ( parseInt(t.split(' ')[0]) ) - 1; - if ( n_unapp == 0 ) - p.removeChild(span); - else - span.firstChild.nodeValue = n_unapp + t.substr(t.indexOf(' ')); - } - else if ( appr == 'Approve' && !p.firstChild.nextSibling ) - { - var span = document.createElement('span'); - p.innerHTML += ' '; - span.innerHTML = '1 of those are unapproved.'; - span.style.color = '#D84308'; - var n_unapp = '1'; - p.appendChild(span); + comment_increment_unapproval(); } } } +function comment_decrement_unapproval() +{ + if ( document.getElementById('comment_count_unapp_inner') ) + { + var num_unapp = parseInt(document.getElementById('comment_count_unapp_inner').innerHTML); + if ( !isNaN(num_unapp) ) + { + num_unapp = num_unapp - 1; + if ( num_unapp == 0 ) + { + var p = document.getElementById('comment_status'); + p.removeChild(p.childNodes[2]); + p.removeChild(p.childNodes[1]); + } + else + { + var count_msg = $lang.get('comment_msg_count_unapp_mod', { num_unapp: num_unapp }); + document.getElementById('comment_count_unapp_inner').parentNode.innerHTML = count_msg; + } + } + } +} + +function comment_increment_unapproval() +{ + if ( document.getElementById('comment_count_unapp_inner') ) + { + var num_unapp = parseInt(document.getElementById('comment_count_unapp_inner').innerHTML); + if ( isNaN(num_unapp) ) + num_unapp = 0; + num_unapp = num_unapp + 1; + var count_msg = $lang.get('comment_msg_count_unapp_mod', { num_unapp: num_unapp }); + document.getElementById('comment_count_unapp_inner').parentNode.innerHTML = count_msg; + } + else + { + var count_msg = $lang.get('comment_msg_count_unapp_mod', { num_unapp: 1 }); + var status = document.getElementById('comment_status'); + if ( !status.childNodes[1] ) + status.appendChild(document.createTextNode(' ')); + var span = document.createElement('span'); + span.id = 'comment_status_unapp'; + span.style.color = '#D84308'; + span.innerHTML = count_msg; + status.appendChild(span); + } +} + +function viewCommentIP(id, local_id) +{ + // set "loading" indicator on IP button + var span = $dynano('comment_ip_' + local_id).object; + if ( !span ) + return false; + span.innerHTML = '...'; + + var parms = { + mode: 'view_ip', + id: id, + local_id: local_id + } + ajaxComments(parms); +} + function htmlspecialchars(text) { text = text.replace(/$1'); + text = text.replace(/'''(.+?)'''/g, '$1'); + text = text.replace(/''(.+?)''/g, '$1'); + text = text.replace(/\[(http|ftp|irc|mailto):([^ \]])+ ([^\]]+?)\]/g, '$4'); + return text; +} + +// Inverse of the previous function +function DN_XHTMLToWikitext(text) +{ + text = text.replace(/

(.+?)<\/h3>/g, '=== $1 ==='); + text = text.replace(/<(b|strong)>(.+?)<\/(b|strong)>/g, "'''$2'''"); + text = text.replace(/<(i|em)>(.+?)<\/(i|em)>/g, "''$2''"); + text = text.replace(/(.+?)<\/a>/g, '[$1 $2]'); + text = text.replace(/<\/?p>/g, ''); + return text; +} + DNobj.prototype.addClass = function(clsname) { addClass(this.object, clsname); return this; }; DNobj.prototype.rmClass = function(clsname) { rmClass( this.object, clsname); return this; }; DNobj.prototype.hasClass = function(clsname) { return hasClass(this.object, clsname); }; diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/editor.js --- a/includes/clientside/static/editor.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/editor.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,23 +1,44 @@ // Javascript routines for the page editor +if ( document.getElementById('mdgCss') ) +{ + var css_url = document.getElementById('mdgCss').href; +} +else +{ + var css_url = scriptPath + '/includes/clientside/css/enano_shared.css'; +} + +var do_popups = ( is_Safari ) ? '' : ',inlinepopups'; +var _skin = ( typeof(tinymce_skin) == 'string' ) ? tinymce_skin : 'default'; +var editor_img_path = scriptPath + '/images/editor'; + +// Idle time required for autosave, in seconds +var AUTOSAVE_TIMEOUT = 15; +var AutosaveTimeoutObj = null; + var enano_tinymce_options = { - mode : "exact", - elements : '', - plugins : 'table', + mode : "none", + plugins : 'table,save,safari,pagebreak,style,layer,advhr,insertdatetime,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras' + do_popups, + theme : 'advanced', + skin : _skin, theme_advanced_resize_horizontal : false, theme_advanced_resizing : true, theme_advanced_toolbar_location : "top", theme_advanced_toolbar_align : "left", - theme_advanced_buttons1_add : "fontselect,fontsizeselect", + theme_advanced_buttons1 : "save,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,forecolor,backcolor,|,formatselect,|,fontselect,fontsizeselect", theme_advanced_buttons3_add_before : "tablecontrols,separator", - theme_advanced_statusbar_location : 'bottom' + theme_advanced_buttons3_add_after : "|,fullscreen", + theme_advanced_statusbar_location : 'bottom', + noneditable_noneditable_class : 'mce_readonly', + content_css : css_url }; var initTinyMCE = function(e) { if ( typeof(tinyMCE) == 'object' ) { - if ( !KILL_SWITCH ) + if ( !KILL_SWITCH && !DISABLE_MCE ) { tinyMCE.init(enano_tinymce_options); } @@ -25,3 +46,891 @@ } addOnloadHook(initTinyMCE); +var editor_open = false; + +function ajaxEditor(revid) +{ + if ( KILL_SWITCH ) + return true; + if ( editor_open ) + return true; + var rev_id_uri = ( revid ) ? '&revid=' + revid : ''; + selectButtonMinor('edit'); + selectButtonMajor('article'); + setAjaxLoading(); + ajaxGet(stdAjaxPrefix + '&_mode=getsource' + rev_id_uri, function() + { + if ( ajax.readyState == 4 && ajax.status == 200 ) + { + unsetAjaxLoading(); + + var response = String(ajax.responseText + ''); + if ( response.substr(0, 1) != '{' ) + { + handle_invalid_json(response); + return false; + } + + response = parseJSON(response); + if ( response.mode == 'error' ) + { + unselectAllButtonsMinor(); + new messagebox(MB_OK | MB_ICONSTOP, $lang.get('editor_err_server'), response.error); + return false; + } + + if ( !response.auth_view_source ) + { + unselectAllButtonsMinor(); + new messagebox(MB_OK | MB_ICONSTOP, $lang.get('editor_err_access_denied_title'), $lang.get('editor_err_access_denied_body')); + return false; + } + + // do we need to enter a captcha before saving the page? + var captcha_hash = ( response.require_captcha ) ? response.captcha_id : false; + + ajaxBuildEditor((!response.auth_edit), response.time, response.allow_wysiwyg, captcha_hash, response.revid, response.undo_info, response); + } + }); +} + +function ajaxBuildEditor(readonly, timestamp, allow_wysiwyg, captcha_hash, revid, undo_info, response) +{ + // Set flags + // We don't want the fancy confirmation framework to trigger if the user is only viewing the page source + if ( !readonly ) + { + editor_open = true; + disableUnload(); + } + + // Destroy existing contents of page container + var edcon = document.getElementById('ajaxEditContainer'); + for ( var i = edcon.childNodes.length - 1; i >= 0; i-- ) + { + edcon.removeChild(edcon.childNodes[i]); + } + + var content = response.src; + + // + // BUILD EDITOR + // + + var heading = document.createElement('h3'); + heading.style.cssFloat = 'left'; + heading.style.styleFloat = 'left'; + heading.style.marginTop = '0px'; + heading.style.marginBottom = '0px'; + heading.appendChild(document.createTextNode($lang.get('editor_msg_editor_heading'))); + + // Plaintext/wikitext toggler + // Only build the editor if using TinyMCE is allowed. THIS IS WEAK + // AND CANNOT BE MADE ANY STRONGER. + + if ( allow_wysiwyg ) + { + var toggler = document.createElement('p'); + toggler.style.marginLeft = '0'; + toggler.style.textAlign = 'right'; + + var span_wiki = document.createElement('span'); + var span_mce = document.createElement('span'); + span_wiki.id = 'enano_edit_btn_pt'; + span_mce.id = 'enano_edit_btn_mce'; + if ( readCookie('enano_editor_mode') == 'tinymce' ) + { + // Current selection is TinyMCE - make span_wiki have the link and span_mce be plaintext + var a = document.createElement('a'); + a.href = '#'; + a.appendChild(document.createTextNode($lang.get('editor_btn_wikitext'))); + span_wiki.appendChild(a); + toggler.appendChild(span_wiki); + toggler.appendChild(document.createTextNode(' | ')); + span_mce.appendChild(document.createTextNode($lang.get('editor_btn_graphical'))); + toggler.appendChild(span_mce); + } + else + { + // Current selection is wikitext - set span_wiki to plaintext and span_mce to link + span_wiki.appendChild(document.createTextNode($lang.get('editor_btn_wikitext'))); + toggler.appendChild(span_wiki); + toggler.appendChild(document.createTextNode(' | ')); + var a = document.createElement('a'); + a.href = '#'; + a.appendChild(document.createTextNode($lang.get('editor_btn_graphical'))); + span_mce.appendChild(a); + toggler.appendChild(span_mce); + } + } + + // Form (to allow submits from MCE to trigger a real save) + var form = document.createElement('form'); + form.action = 'javascript:void(0);'; + form.onsubmit = function() + { + ajaxEditorSave(); + return false; + } + + // Draft notice + if ( response.have_draft ) + { + var dn = document.createElement('div'); + dn.className = 'warning-box'; + dn.id = 'ajax_edit_draft_notice'; + dn.innerHTML = '' + $lang.get('editor_msg_have_draft_title') + '
'; + dn.innerHTML += $lang.get('editor_msg_have_draft_body', { author: response.draft_author, time: response.draft_time }); + } + + // Old-revision notice + if ( revid > 0 ) + { + var oldrev_box = document.createElement('div'); + oldrev_box.className = 'usermessage'; + oldrev_box.appendChild(document.createTextNode($lang.get('editor_msg_editing_old_revision'))); + } + + // Preview holder + var preview_anchor = document.createElement('a'); + preview_anchor.name = 'ajax_preview'; + preview_anchor.id = 'ajax_preview'; + var preview_container = document.createElement('div'); + preview_container.id = 'enano_editor_preview'; + preview_container.style.clear = 'left'; + + // Textarea containing the content + var ta_wrapper = document.createElement('div'); + ta_wrapper.style.margin = '10px 0'; + // ta_wrapper.style.clear = 'both'; + var textarea = document.createElement('textarea'); + ta_wrapper.appendChild(textarea); + + textarea.id = 'ajaxEditArea'; + textarea.rows = '20'; + textarea.cols = '60'; + textarea.style.width = '98.7%'; + + // Revision metadata controls + var tblholder = document.createElement('div'); + tblholder.className = 'tblholder'; + var metatable = document.createElement('table'); + metatable.setAttribute('border', '0'); + metatable.setAttribute('cellspacing', '1'); + metatable.setAttribute('cellpadding', '4'); + + if ( readonly ) + { + // Close Viewer button + var toolbar = ''; + var head = new templateParser(response.toolbar_templates.toolbar_start); + var button = new templateParser(response.toolbar_templates.toolbar_button); + var tail = new templateParser(response.toolbar_templates.toolbar_end); + + button.assign_bool({ + show_title: true + }); + + // Button: close + button.assign_vars({ + TITLE: $lang.get('editor_btn_closeviewer'), + IMAGE: editor_img_path + '/discard.gif', + FLAGS: 'href="#" onclick="ajaxReset(true); return false;"' + }); + toolbar += button.run(); + } + else + { + // First row: edit summary + var tr1 = document.createElement('tr'); + var td1_1 = document.createElement('td'); + var td1_2 = document.createElement('td'); + td1_1.className = 'row2'; + td1_2.className = 'row1'; + td1_2.style.width = '70%'; + td1_1.appendChild(document.createTextNode($lang.get('editor_lbl_edit_summary'))); + td1_1.appendChild(document.createElement('br')); + var small = document.createElement('small'); + small.appendChild(document.createTextNode($lang.get('editor_lbl_edit_summary_explain'))); + td1_1.appendChild(small); + + var field_es = document.createElement('input'); + field_es.id = 'enano_editor_field_summary'; + field_es.type = 'text'; + field_es.size = '40'; + field_es.style.width = '96%'; + + if ( revid > 0 ) + { + undo_info.last_rev_id = revid; + field_es.value = $lang.get('editor_reversion_edit_summary', undo_info); + } + + td1_2.appendChild(field_es); + + tr1.appendChild(td1_1); + tr1.appendChild(td1_2); + + // Second row: minor edit + var tr2 = document.createElement('tr'); + var td2_1 = document.createElement('td'); + var td2_2 = document.createElement('td'); + td2_1.className = 'row2'; + td2_2.className = 'row1'; + td2_1.appendChild(document.createTextNode($lang.get('editor_lbl_minor_edit'))); + td2_1.appendChild(document.createElement('br')); + var small = document.createElement('small'); + small.appendChild(document.createTextNode($lang.get('editor_lbl_minor_edit_explain'))); + td2_1.appendChild(small); + + var label = document.createElement('label'); + var field_mi = document.createElement('input'); + field_mi.id = 'enano_editor_field_minor'; + field_mi.type = 'checkbox'; + label.appendChild(field_mi); + label.appendChild(document.createTextNode(' ')); + label.appendChild(document.createTextNode($lang.get('editor_lbl_minor_edit_field'))); + td2_2.appendChild(label); + + tr2.appendChild(td2_1); + tr2.appendChild(td2_2); + + if ( captcha_hash ) + { + // generate captcha field (effectively third row) + var tr4 = document.createElement('tr'); + var td4_1 = document.createElement('td'); + var td4_2 = document.createElement('td'); + td4_1.className = 'row2'; + td4_2.className = 'row1'; + + td4_1.appendChild(document.createTextNode($lang.get('editor_lbl_field_captcha'))); + td4_1.appendChild(document.createElement('br')); + var small2 = document.createElement('small'); + small2.appendChild(document.createTextNode($lang.get('editor_msg_captcha_pleaseenter'))); + small2.appendChild(document.createElement('br')); + small2.appendChild(document.createElement('br')); + small2.appendChild(document.createTextNode($lang.get('editor_msg_captcha_blind'))); + td4_1.appendChild(small2); + + var img = document.createElement('img'); + img.src = makeUrlNS('Special', 'Captcha/' + captcha_hash); + img._captchaHash = captcha_hash; + img.id = 'enano_editor_captcha_img'; + img.onclick = function() + { + this.src = makeUrlNS('Special', 'Captcha/' + this._captchaHash + '/' + Math.floor(Math.random() * 100000)); + } + img.style.cursor = 'pointer'; + td4_2.appendChild(img); + td4_2.appendChild(document.createElement('br')); + td4_2.appendChild(document.createTextNode($lang.get('editor_lbl_field_captcha_code') + ' ')); + var input = document.createElement('input'); + input.type = 'text'; + input.id = 'enano_editor_field_captcha'; + input._captchaHash = captcha_hash; + input.size = '9'; + td4_2.appendChild(input); + + tr4.appendChild(td4_1); + tr4.appendChild(td4_2); + } + + // Third row: controls + + var toolbar = ''; + var head = new templateParser(response.toolbar_templates.toolbar_start); + var button = new templateParser(response.toolbar_templates.toolbar_button); + var label = new templateParser(response.toolbar_templates.toolbar_label); + var tail = new templateParser(response.toolbar_templates.toolbar_end); + + button.assign_bool({ + show_title: true + }); + + toolbar += head.run(); + + // Button: Save + button.assign_vars({ + TITLE: $lang.get('editor_btn_save'), + IMAGE: editor_img_path + '/save.gif', + FLAGS: 'href="#" onclick="ajaxEditorSave(); return false;"' + }); + toolbar += button.run(); + + // Button: preview + button.assign_vars({ + TITLE: $lang.get('editor_btn_preview'), + IMAGE: editor_img_path + '/preview.gif', + FLAGS: 'href="#" onclick="ajaxEditorGenPreview(); return false;"' + }); + toolbar += button.run(); + + // Button: revert + button.assign_vars({ + TITLE: $lang.get('editor_btn_revert'), + IMAGE: editor_img_path + '/revert.gif', + FLAGS: 'href="#" onclick="ajaxEditorRevertToLatest(); return false;"' + }); + toolbar += button.run(); + + // Button: diff + button.assign_vars({ + TITLE: $lang.get('editor_btn_diff'), + IMAGE: editor_img_path + '/diff.gif', + FLAGS: 'href="#" onclick="ajaxEditorShowDiffs(); return false;"' + }); + toolbar += button.run(); + + // Button: cancel + button.assign_vars({ + TITLE: $lang.get('editor_btn_cancel'), + IMAGE: editor_img_path + '/discard.gif', + FLAGS: 'href="#" onclick="ajaxEditorCancel(); return false;"' + }); + toolbar += button.run(); + + // Separator + label.assign_vars({ + TITLE: ' ' + }); + toolbar += label.run(); + + // Button: Save draft + button.assign_vars({ + TITLE: $lang.get('editor_btn_savedraft'), + IMAGE: editor_img_path + '/savedraft.gif', + FLAGS: 'href="#" onclick="ajaxPerformAutosave(); return false;" id="ajax_edit_savedraft_btn"' + }); + toolbar += button.run(); + + toolbar += tail.run(); + + metatable.appendChild(tr1); + metatable.appendChild(tr2); + if ( captcha_hash ) + { + metatable.appendChild(tr4); + } + // metatable.appendChild(tr3); + } + tblholder.appendChild(metatable); + + // Edit disclaimer/notice + if ( editNotice ) // This is set globally in {JS_DYNAMIC_VARS}. + { + var en_div = document.createElement('div'); + en_div.innerHTML = editNotice; + en_div.className = 'usermessage'; + en_div.style.margin = '10px 0 0 0'; + } + + // Put it all together... + form.appendChild(heading); + if ( allow_wysiwyg ) + form.appendChild(toggler); + + if ( dn ) + form.appendChild(dn); + + if ( oldrev_box ) + form.appendChild(oldrev_box); + + form.appendChild(preview_anchor); + form.appendChild(preview_container); + form.appendChild(ta_wrapper); + form.appendChild(tblholder); + form.innerHTML += '
' + toolbar + '
'; + edcon.appendChild(form); + + if ( editNotice && !readonly ) + { + edcon.appendChild(en_div); + } + + // more textarea attribs/init + var textarea = document.getElementById('ajaxEditArea'); + textarea.as_last_save = 0; + textarea.content_orig = content; + textarea.used_draft = false; + textarea.onkeyup = function() + { + if ( this.needReset ) + { + var img = $dynano('ajax_edit_savedraft_btn').object.getElementsByTagName('img')[0]; + var lbl = $dynano('ajax_edit_savedraft_btn').object.getElementsByTagName('span')[0]; + img.src = editor_img_path + '/savedraft.gif'; + lbl.innerHTML = $lang.get('editor_btn_savedraft'); + } + if ( AutosaveTimeoutObj ) + clearTimeout(AutosaveTimeoutObj); + AutosaveTimeoutObj = setTimeout('ajaxAutosaveDraft();', ( AUTOSAVE_TIMEOUT * 1000 )); + } + + if ( readonly ) + { + textarea.className = 'mce_readonly'; + textarea.setAttribute('readonly', 'readonly'); + } + + // If the editor preference is tinymce, switch the editor to TinyMCE now + if ( readCookie('enano_editor_mode') == 'tinymce' && allow_wysiwyg ) + { + $dynano('ajaxEditArea').switchToMCE(); + } + $dynano('ajaxEditArea').object.focus(); + $dynano('ajaxEditArea').object._edTimestamp = timestamp; + $dynano('ajaxEditArea').setContent(content); + + if ( allow_wysiwyg ) + { + if ( readCookie('enano_editor_mode') == 'tinymce' ) + { + var a = document.getElementById('enano_edit_btn_pt').getElementsByTagName('a')[0]; + a.onclick = function() { + ajaxSetEditorPlain(); + return false; + }; + } + else + { + var a = document.getElementById('enano_edit_btn_mce').getElementsByTagName('a')[0]; + a.onclick = function() { + ajaxSetEditorMCE(); + return false; + }; + } + } + + // Autosave every 5 minutes (m * s * ms) + setInterval('ajaxPerformAutosave();', ( 5 * 60 * 1000 )); +} + +function ajaxEditorSave(is_draft) +{ + if ( !is_draft ) + ajaxSetEditorLoading(); + var ta_content = $dynano('ajaxEditArea').getContent(); + + if ( !is_draft && ( ta_content == '' || ta_content == '

' || ta_content == '

 

' ) ) + { + new messagebox(MB_OK|MB_ICONSTOP, $lang.get('editor_err_no_text_title'), $lang.get('editor_err_no_text_body')); + ajaxUnSetEditorLoading(); + return false; + } + + if ( is_draft ) + { + // ajaxSetEditorLoading(); + var img = $dynano('ajax_edit_savedraft_btn').object.getElementsByTagName('img')[0]; + var lbl = $dynano('ajax_edit_savedraft_btn').object.getElementsByTagName('span')[0]; + img.src = scriptPath + '/images/loading.gif'; + var d = new Date(); + var m = String(d.getMinutes()); + if ( m.length < 2 ) + m = '0' + m; + var time = d.getHours() + ':' + m; + lbl.innerHTML = $lang.get('editor_msg_draft_saving'); + } + + var edit_summ = $dynano('enano_editor_field_summary').object.value; + if ( !edit_summ ) + edit_summ = ''; + var is_minor = ( $dynano('enano_editor_field_minor').object.checked ) ? 1 : 0; + var timestamp = $dynano('ajaxEditArea').object._edTimestamp; + var used_draft = $dynano('ajaxEditArea').object.used_draft; + + var json_packet = { + src: ta_content, + summary: edit_summ, + minor_edit: is_minor, + time: timestamp, + draft: ( is_draft == true ), + used_draft: used_draft + }; + + // Do we need to add captcha info? + if ( document.getElementById('enano_editor_field_captcha') ) + { + var captcha_field = document.getElementById('enano_editor_field_captcha'); + if ( captcha_field.value == '' ) + { + new messagebox(MB_OK|MB_ICONSTOP, $lang.get('editor_err_need_captcha_title'), $lang.get('editor_err_need_captcha_body')); + ajaxUnSetEditorLoading(); + return false; + } + json_packet.captcha_code = captcha_field.value; + json_packet.captcha_id = captcha_field._captchaHash; + } + + json_packet = ajaxEscape(toJSONString(json_packet)); + ajaxPost(stdAjaxPrefix + '&_mode=savepage_json', 'r=' + json_packet, function() + { + if ( ajax.readyState == 4 && ajax.status == 200 ) + { + var response = String(ajax.responseText + ''); + if ( response.substr(0, 1) != '{' ) + { + handle_invalid_json(response); + return false; + } + + response = parseJSON(response); + // This will only be used if there was a lower-level error. + if ( response.mode == 'error' ) + { + new messagebox(MB_OK | MB_ICONSTOP, $lang.get('editor_err_server'), response.error); + return false; + } + // This will be used if the PageProcessor generated errors (usually security/permissions related) + if ( response.mode == 'errors' ) + { + // This will be true if the user entered a captcha code incorrectly, thus + // invalidating the code and requiring a new image to be generated. + if ( response.new_captcha ) + { + // Generate the new captcha field + var img = document.getElementById('enano_editor_captcha_img'); + var input = document.getElementById('enano_editor_field_captcha'); + if ( img && input ) + { + img._captchaHash = response.new_captcha; + input._captchaHash = response.new_captcha; + img.src = makeUrlNS('Special', 'Captcha/' + response.new_captcha); + input.value = ''; + } + } + var errors = '
  • ' + implode('
  • ', response.errors) + '
'; + new messagebox(MB_OK | MB_ICONSTOP, $lang.get('editor_err_save_title'), $lang.get('editor_err_save_body') + errors); + return false; + } + // If someone else got to the page first, warn the user + if ( response.mode == 'obsolete' ) + { + // Update the local timestamp to allow override + $dynano('ajaxEditArea').object._edTimestamp = response.time; + new messagebox(MB_OK | MB_ICONEXCLAMATION, $lang.get('editor_err_obsolete_title'), $lang.get('editor_err_obsolete_body', { author: response.author, timestamp: response.date_string, page_url: makeUrl(title, false, true) })); + return false; + } + if ( response.mode == 'success' ) + { + if ( response.is_draft ) + { + document.getElementById('ajaxEditArea').used_draft = true; + document.getElementById('ajaxEditArea').needReset = true; + var img = $dynano('ajax_edit_savedraft_btn').object.getElementsByTagName('img')[0]; + var lbl = $dynano('ajax_edit_savedraft_btn').object.getElementsByTagName('span')[0]; + img.src = scriptPath + '/images/mini-info.png'; + var d = new Date(); + var m = String(d.getMinutes()); + if ( m.length < 2 ) + m = '0' + m; + var time = d.getHours() + ':' + m; + lbl.innerHTML = $lang.get('editor_msg_draft_saved', { time: time }); + } + else + { + // The save was successful; reset flags and make another request for the new page content + ajaxUnSetEditorLoading(); + setAjaxLoading(); + editor_open = false; + enableUnload(); + changeOpac(0, 'ajaxEditContainer'); + ajaxGet(stdAjaxPrefix + '&_mode=getpage&noheaders', function() + { + if ( ajax.readyState == 4 && ajax.status == 200 ) + { + unsetAjaxLoading(); + selectButtonMajor('article'); + unselectAllButtonsMinor(); + + document.getElementById('ajaxEditContainer').innerHTML = '
' + $lang.get('editor_msg_saved') + '
' + ajax.responseText; + opacity('ajaxEditContainer', 0, 100, 1000); + } + }); + } + } + } + }, true); +} + +function ajaxEditorGenPreview() +{ + ajaxSetEditorLoading(); + var ta_content = $dynano('ajaxEditArea').getContent(); + ta_content = ajaxEscape(ta_content); + if ( $dynano('enano_editor_preview').object.innerHTML != '' ) + { + opacity('enano_editor_preview', 100, 0, 500); + } + ajaxPost(stdAjaxPrefix + '&_mode=preview', 'text=' + ta_content, function() + { + if ( ajax.readyState == 4 && ajax.status == 200 ) + { + ajaxUnSetEditorLoading(); + changeOpac(0, 'enano_editor_preview'); + $dynano('enano_editor_preview').object.innerHTML = ajax.responseText; + window.location.hash = '#ajax_preview'; + opacity('enano_editor_preview', 0, 100, 500); + } + }, true); +} + +function ajaxEditorRevertToLatest() +{ + var mb = new messagebox(MB_YESNO | MB_ICONQUESTION, $lang.get('editor_msg_revert_confirm_title'), $lang.get('editor_msg_revert_confirm_body')); + mb.onclick['Yes'] = function() + { + setTimeout('ajaxEditorRevertToLatestReal();', 750); + } +} + +function ajaxEditorRevertToLatestReal() +{ + ajaxSetEditorLoading(); + ajaxGet(stdAjaxPrefix + '&_mode=getsource', function() + { + if ( ajax.readyState == 4 && ajax.status == 200 ) + { + ajaxUnSetEditorLoading(); + + var response = String(ajax.responseText + ''); + if ( response.substr(0, 1) != '{' ) + { + handle_invalid_json(response); + return false; + } + + response = parseJSON(response); + if ( response.mode == 'error' ) + { + unselectAllButtonsMinor(); + new messagebox(MB_OK | MB_ICONSTOP, $lang.get('editor_err_server'), response.error); + return false; + } + + if ( !response.auth_view_source ) + { + unselectAllButtonsMinor(); + new messagebox(MB_OK | MB_ICONSTOP, $lang.get('editor_err_access_denied_title'), $lang.get('editor_err_access_denied_body')); + return false; + } + + $dynano('ajaxEditArea').setContent(response.src); + } + }, true); +} + +function ajaxEditorShowDiffs() +{ + ajaxSetEditorLoading(); + var ta_content = $dynano('ajaxEditArea').getContent(); + ta_content = ajaxEscape(ta_content); + if ( $dynano('enano_editor_preview').object.innerHTML != '' ) + { + opacity('enano_editor_preview', 100, 0, 500); + } + ajaxPost(stdAjaxPrefix + '&_mode=diff_cur', 'text=' + ta_content, function() + { + if ( ajax.readyState == 4 && ajax.status == 200 ) + { + ajaxUnSetEditorLoading(); + changeOpac(0, 'enano_editor_preview'); + $dynano('enano_editor_preview').object.innerHTML = ajax.responseText; + window.location.hash = '#ajax_preview'; + opacity('enano_editor_preview', 0, 100, 500); + } + }, true); +} + +function ajaxEditorCancel() +{ + var mb = new messagebox(MB_YESNO | MB_ICONQUESTION, $lang.get('editor_msg_cancel_confirm_title'), $lang.get('editor_msg_cancel_confirm_body')); + mb.onclick['Yes'] = function() + { + setAjaxLoading(); + editor_open = false; + enableUnload(); + setTimeout('ajaxReset();', 750); + } +} + +function ajaxSetEditorMCE() +{ + if ( editor_loading ) + return false; + + // Clear out existing buttons + var span_wiki = $dynano('enano_edit_btn_pt').object; + var span_mce = $dynano('enano_edit_btn_mce').object; + span_wiki.removeChild(span_wiki.firstChild); + span_mce.removeChild(span_mce.firstChild); + + // Rebuild control + var a = document.createElement('a'); + a.href = '#'; + a.onclick = function() { + ajaxSetEditorPlain(); + return false; + }; + a.appendChild(document.createTextNode($lang.get('editor_btn_wikitext'))); + span_wiki.appendChild(a); + span_mce.appendChild(document.createTextNode($lang.get('editor_btn_graphical'))); + + // Swap editor + $dynano('ajaxEditArea').switchToMCE(); + + // Remember the setting + createCookie('enano_editor_mode', 'tinymce', 365); +} + +function ajaxSetEditorPlain() +{ + if ( editor_loading ) + return false; + + // Clear out existing buttons + var span_wiki = $dynano('enano_edit_btn_pt').object; + var span_mce = $dynano('enano_edit_btn_mce').object; + span_wiki.removeChild(span_wiki.firstChild); + span_mce.removeChild(span_mce.firstChild); + + // Rebuild control + span_wiki.appendChild(document.createTextNode($lang.get('editor_btn_wikitext'))); + var a = document.createElement('a'); + a.href = '#'; + a.onclick = function() { + ajaxSetEditorMCE(); + return false; + }; + a.appendChild(document.createTextNode($lang.get('editor_btn_graphical'))); + span_mce.appendChild(a); + + // Swap editor + $dynano('ajaxEditArea').destroyMCE(); + + // Remember the setting + createCookie('enano_editor_mode', 'text', 365); +} + +var editor_loading = false; + +function ajaxSetEditorLoading() +{ + var ed = tinyMCE.get('ajaxEditArea'); + editor_loading = true; + if ( ed ) + { + ed.setProgressState(1); + } + else + { + ed = document.getElementById('ajaxEditArea'); + var blackout = document.createElement('div'); + blackout.style.position = 'absolute'; + blackout.style.top = $dynano('ajaxEditArea').Top() + 'px'; + blackout.style.left = $dynano('ajaxEditArea').Left() + 'px'; + blackout.style.width = $dynano('ajaxEditArea').Width() + 'px'; + blackout.style.height = $dynano('ajaxEditArea').Height() + 'px'; + blackout.style.backgroundColor = '#FFFFFF'; + domObjChangeOpac(60, blackout); + blackout.style.backgroundImage = 'url(' + scriptPath + '/includes/clientside/tinymce/themes/advanced/skins/default/img/progress.gif)'; + blackout.style.backgroundPosition = 'center center'; + blackout.style.backgroundRepeat = 'no-repeat'; + blackout.id = 'enano_editor_blackout'; + blackout.style.zIndex = getHighestZ() + 2; + + var body = document.getElementsByTagName('body')[0]; + body.appendChild(blackout); + } +} + +function ajaxUnSetEditorLoading() +{ + editor_loading = false; + var ed = tinyMCE.get('ajaxEditArea'); + if ( ed ) + { + ed.setProgressState(0); + } + else + { + var blackout = document.getElementById('enano_editor_blackout'); + var body = document.getElementsByTagName('body')[0]; + body.removeChild(blackout); + } +} + +function ajaxAutosaveDraft() +{ + var aed = document.getElementById('ajaxEditArea'); + if ( !aed ) + return false; + var last_save = aed.as_last_save; + var now = unix_time(); + if ( ( last_save + 120 ) < now && aed.value != aed.content_orig ) + { + ajaxPerformAutosave(); + } +} + +function ajaxPerformAutosave() +{ + var aed = document.getElementById('ajaxEditArea'); + if ( !aed ) + return false; + var now = unix_time(); + aed.as_last_save = now; + + var ta_content = $dynano('ajaxEditArea').getContent(); + + if ( ta_content == '' || ta_content == '

' || ta_content == '

 

' ) + { + return false; + } + + ajaxEditorSave(true); +} + +function ajaxEditorUseDraft() +{ + var aed = document.getElementById('ajaxEditArea'); + if ( !aed ) + return false; + ajaxSetEditorLoading(); + ajaxGet(stdAjaxPrefix + '&_mode=getsource&get_draft=1', function() + { + if ( ajax.readyState == 4 && ajax.status == 200 ) + { + ajaxUnSetEditorLoading(); + + var response = String(ajax.responseText + ''); + if ( response.substr(0, 1) != '{' ) + { + handle_invalid_json(response); + return false; + } + + response = parseJSON(response); + if ( response.mode == 'error' ) + { + unselectAllButtonsMinor(); + new messagebox(MB_OK | MB_ICONSTOP, $lang.get('editor_err_server'), response.error); + return false; + } + + $dynano('ajaxEditArea').setContent(response.src); + $dynano('ajaxEditArea').object.used_draft = true; + + var es = document.getElementById('enano_editor_field_summary'); + if ( es.value == '' ) + { + es.value = response.edit_summary; + } + + var dn = $dynano('ajax_edit_draft_notice').object; + dn.parentNode.removeChild(dn); + } + }, true); +} + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/enano-lib-basic.js --- a/includes/clientside/static/enano-lib-basic.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/enano-lib-basic.js Fri Feb 22 12:51:53 2008 -0500 @@ -10,8 +10,9 @@ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. * * For more information about Enano, please visit http://enanocms.org/. - * All of the code in these script files may be used freely so long as the above license block is displayed and your - * modified code is distributed under the GPL. See the page Special:About_Enano on this website for more information. + * Unless otherwise noted, all of the code in these script files may be used freely so long as the above license block + * is displayed and your modified code is distributed in compliance with the GPL. See the special page "About Enano" on + * this website for more information. */ if(typeof title != 'string') @@ -63,6 +64,11 @@ // dummy tinyMCE object var tinyMCE = new Object(); +if ( typeof(DISABLE_MCE) == undefined ) +{ + var DISABLE_MCE = false; +} + // Obsolete JSON kill switch function disableJSONExts() { }; @@ -251,17 +257,23 @@ } var head = document.getElementsByTagName('head')[0]; -if ( !KILL_SWITCH ) +if ( !KILL_SWITCH && !DISABLE_MCE ) { var script = document.createElement('script'); script.type="text/javascript"; - script.src=scriptPath+"/includes/clientside/tinymce/tiny_mce_src.js"; + script.src=scriptPath+"/includes/clientside/tinymce/tiny_mce.js"; head.appendChild(script); } +// Do not remove the following comments, they are used by jsres.php. +/*!START_INCLUDER*/ + // Start loading files +// The string from the [ to the ] needs to be valid JSON, it's parsed by jsres.php. var thefiles = [ + 'dynano.js', 'misc.js', + 'login.js', 'admin-menu.js', 'ajax.js', 'autocomplete.js', @@ -273,18 +285,22 @@ 'grippy.js', 'json.js', 'md5.js', + 'libbigint.js', + 'enanomath.js', + 'diffiehellman.js', + 'sha256.js', 'sliders.js', 'toolbar.js', - 'windows.js', 'rijndael.js', + 'l10n.js', 'template-compiler.js', 'acl.js', 'comments.js', 'editor.js', - 'dynano.js', 'flyin.js', 'paginate.js', 'pwstrength.js', + 'theme-manager.js', 'SpryEffects.js', 'loader.js' ]; @@ -309,6 +325,9 @@ head.appendChild(script); } +// Do not remove the following comment, it is used by jsres.php. +/*!END_INCLUDER*/ + addOnloadHook(function() { if ( $_REQUEST['do'] ) { diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/enanomath.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/static/enanomath.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,29 @@ +/* + * EnanoMath, an abstraction layer for big-integer (arbitrary precision) + * mathematics. + */ + +var EnanoMathLayers = {}; + +// EnanoMath layer: Leemon (frontend to BigInt library by Leemon Baird) + +EnanoMathLayers.Leemon = { + Base: 10, + PowMod: function(a, b, c) + { + a = str2bigInt(a, this.Base); + b = str2bigInt(b, this.Base); + c = str2bigInt(c, this.Base); + var result = powMod(a, b, c); + result = bigInt2str(result, this.Base); + return result; + }, + RandomInt: function(bits) + { + var result = randBigInt(bits); + return bigInt2str(result, this.Base); + } +} + +var EnanoMath = EnanoMathLayers.Leemon; + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/faders.js --- a/includes/clientside/static/faders.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/faders.js Fri Feb 22 12:51:53 2008 -0500 @@ -186,7 +186,8 @@ { btn = document.createElement('input'); btn.type = 'button'; - btn.value = 'OK'; + btn.value = $lang.get('etc_ok'); + btn._GenericName = 'OK'; btn.onclick = this.clickHandler; btn.style.margin = '0 3px'; buttondiv.appendChild(btn); @@ -196,14 +197,16 @@ { btn = document.createElement('input'); btn.type = 'button'; - btn.value = 'OK'; + btn.value = $lang.get('etc_ok'); + btn._GenericName = 'OK'; btn.onclick = this.clickHandler; btn.style.margin = '0 3px'; buttondiv.appendChild(btn); btn = document.createElement('input'); btn.type = 'button'; - btn.value = 'Cancel'; + btn.value = $lang.get('etc_cancel'); + btn._GenericName = 'Cancel'; btn.onclick = this.clickHandler; btn.style.margin = '0 3px'; buttondiv.appendChild(btn); @@ -213,14 +216,16 @@ { btn = document.createElement('input'); btn.type = 'button'; - btn.value = 'Yes'; + btn.value = $lang.get('etc_yes'); + btn._GenericName = 'Yes'; btn.onclick = this.clickHandler; btn.style.margin = '0 3px'; buttondiv.appendChild(btn); btn = document.createElement('input'); btn.type = 'button'; - btn.value = 'No'; + btn.value = $lang.get('etc_no'); + btn._GenericName = 'No'; btn.onclick = this.clickHandler; btn.style.margin = '0 3px'; buttondiv.appendChild(btn); @@ -230,21 +235,24 @@ { btn = document.createElement('input'); btn.type = 'button'; - btn.value = 'Yes'; + btn.value = $lang.get('etc_yes'); + btn._GenericName = 'Yes'; btn.onclick = this.clickHandler; btn.style.margin = '0 3px'; buttondiv.appendChild(btn); btn = document.createElement('input'); btn.type = 'button'; - btn.value = 'No'; + btn.value = $lang.get('etc_no'); + btn._GenericName = 'No'; btn.onclick = this.clickHandler; btn.style.margin = '0 3px'; buttondiv.appendChild(btn); btn = document.createElement('input'); btn.type = 'button'; - btn.value = 'Cancel'; + btn.value = $lang.get('etc_cancel'); + btn._GenericName = 'Cancel'; btn.onclick = this.clickHandler; btn.style.margin = '0 3px'; buttondiv.appendChild(btn); @@ -305,7 +313,7 @@ function messagebox_click(obj, mb) { - val = obj.value; + val = ( typeof ( obj._GenericName ) == 'string' ) ? obj._GenericName : obj.value; if(typeof mb.onbeforeclick[val] == 'function') { var o = mb.onbeforeclick[val]; @@ -360,6 +368,8 @@ j = 0; for(var i in d) { + if ( !d[i] ) + continue; if ( !d[i].tagName ) continue; if(d[i].className=='info-box' || d[i].className=='error-box' || d[i].className=='warning-box' || d[i].className=='question-box') @@ -451,7 +461,7 @@ function mb_logout() { - var mb = new messagebox(MB_YESNO|MB_ICONQUESTION, 'Are you sure you want to log out?', 'If you log out, you will no longer be able to access your user preferences, your private messages, or certain areas of this site until you log in again.'); + var mb = new messagebox(MB_YESNO|MB_ICONQUESTION, $lang.get('user_logout_confirm_title'), $lang.get('user_logout_confirm_body')); mb.onclick['Yes'] = function() { window.location = makeUrlNS('Special', 'Logout/' + title); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/flyin.js --- a/includes/clientside/static/flyin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/flyin.js Fri Feb 22 12:51:53 2008 -0500 @@ -83,8 +83,8 @@ // setup element element.style.position = 'absolute'; - dim = [ $(element).Height(), $(element).Width() ]; - off = [ $(element).Top(), $(element).Left() ]; + dim = [ $dynano(element).Height(), $dynano(element).Width() ]; + off = [ $dynano(element).Top(), $dynano(element).Left() ]; if ( height_taken_care_of ) { diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/l10n.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/static/l10n.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,69 @@ +/* + * Enano client-side localization library + */ + +var Language = function(lang_id) +{ + if ( typeof(enano_lang) != 'object' ) + return false; + if ( typeof(enano_lang[lang_id]) != 'object' ) + return false; + this.strings = enano_lang[lang_id]; + this.lang_id = lang_id; + + this.get = function(string_id, subst) + { + if ( window.console ) + { + try { + window.console.log('$lang(' + this.lang_id + '): requested string: ' + string_id); + } + catch(e) + {} + } + var catname = string_id.substr(0, string_id.indexOf('_')); + var string_name = string_id.substr(string_id.indexOf('_') + 1); + if ( typeof(this.strings[catname]) != 'object' ) + return string_id; + if ( typeof(this.strings[catname][string_name]) != 'string' ) + return string_id; + return this.perform_subst(this.strings[catname][string_name], subst); + } + + this.perform_subst = function(str, subst) + { + var this_regex = /%this\.([a-z0-9_]+)%/; + var match; + while ( str.match(this_regex) ) + { + match = str.match(this_regex); + str = str.replace(match[0], this.get(match[1])); + } + // hackish workaround for %config.*% + str = str.replace(/%config\.([a-z0-9_]+)%/g, '%$1%'); + if ( typeof(subst) == 'object' ) + { + for ( var i in subst ) + { + if ( !i.match(/^([a-z0-9_]+)$/) ) + continue; + var regex = new RegExp('%' + i + '%', 'g'); + str = str.replace(regex, subst[i]); + } + } + return str; + } + +} + +var $lang; + +var language_onload = function() +{ + $lang = new Language(ENANO_LANG_ID); + // for debugging :-) + // alert( $lang.get('user_err_invalid_credentials_lockout_captcha', { lockout_fails: '3', lockout_threshold: '5', lockout_duration: '15' }) ); +} + +addOnloadHook(language_onload); + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/libbigint.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/static/libbigint.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,1400 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// Big Integer Library v. 5.1 +// Created 2000, last modified 2007 +// Leemon Baird +// www.leemon.com +// +// Version history: +// +// v 5.1 8 Oct 2007 +// - renamed inverseModInt_ to inverseModInt since it doesn't change its parameters +// - added functions GCD and randBigInt, which call GCD_ and randBigInt_ +// - fixed a bug found by Rob Visser (see comment with his name below) +// - improved comments +// +// This file is public domain. You can use it for any purpose without restriction. +// I do not guarantee that it is correct, so use it at your own risk. If you use +// it for something interesting, I'd appreciate hearing about it. If you find +// any bugs or make any improvements, I'd appreciate hearing about those too. +// It would also be nice if my name and address were left in the comments. +// But none of that is required. +// +// This code defines a bigInt library for arbitrary-precision integers. +// A bigInt is an array of integers storing the value in chunks of bpe bits, +// little endian (buff[0] is the least significant word). +// Negative bigInts are stored two's complement. +// Some functions assume their parameters have at least one leading zero element. +// Functions with an underscore at the end of the name have unpredictable behavior in case of overflow, +// so the caller must make sure the arrays must be big enough to hold the answer. +// For each function where a parameter is modified, that same +// variable must not be used as another argument too. +// So, you cannot square x by doing multMod_(x,x,n). +// You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n). +// +// These functions are designed to avoid frequent dynamic memory allocation in the inner loop. +// For most functions, if it needs a BigInt as a local variable it will actually use +// a global, and will only allocate to it only when it's not the right size. This ensures +// that when a function is called repeatedly with same-sized parameters, it only allocates +// memory on the first call. +// +// Note that for cryptographic purposes, the calls to Math.random() must +// be replaced with calls to a better pseudorandom number generator. +// +// In the following, "bigInt" means a bigInt with at least one leading zero element, +// and "integer" means a nonnegative integer less than radix. In some cases, integer +// can be negative. Negative bigInts are 2s complement. +// +// The following functions do not modify their inputs. +// Those returning a bigInt, string, or Array will dynamically allocate memory for that value. +// Those returning a boolean will return the integer 0 (false) or 1 (true). +// Those returning boolean or int will not allocate memory except possibly on the first time they're called with a given parameter size. +// +// bigInt add(x,y) //return (x+y) for bigInts x and y. +// bigInt addInt(x,n) //return (x+n) where x is a bigInt and n is an integer. +// string bigInt2str(x,base) //return a string form of bigInt x in a given base, with 2 <= base <= 95 +// int bitSize(x) //return how many bits long the bigInt x is, not counting leading zeros +// bigInt dup(x) //return a copy of bigInt x +// boolean equals(x,y) //is the bigInt x equal to the bigint y? +// boolean equalsInt(x,y) //is bigint x equal to integer y? +// bigInt expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed +// Array findPrimes(n) //return array of all primes less than integer n +// bigInt GCD(x,y) //return greatest common divisor of bigInts x and y (each with same number of elements). +// boolean greater(x,y) //is x>y? (x and y are nonnegative bigInts) +// boolean greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y? +// bigInt int2bigInt(t,n,m) //return a bigInt equal to integer t, with at least n bits and m array elements +// bigInt inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null +// int inverseModInt(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse +// boolean isZero(x) //is the bigInt x equal to zero? +// boolean millerRabin(x,b) //does one round of Miller-Rabin base integer b say that bigInt x is possibly prime (as opposed to definitely composite)? +// bigInt mod(x,n) //return a new bigInt equal to (x mod n) for bigInts x and n. +// int modInt(x,n) //return x mod n for bigInt x and integer n. +// bigInt mult(x,y) //return x*y for bigInts x and y. This is faster when y=1). If s=1, then the most significant of those n bits is set to 1. +// bigInt randTruePrime(k) //return a new, random, k-bit, true prime bigInt using Maurer's algorithm. +// bigInt str2bigInt(s,b,n,m) //return a bigInt for number represented in string s in base b with at least n bits and m array elements +// bigInt sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement +// bigInt bigint_trim(x,k) //return a copy of x with exactly k leading zero elements +// +// +// The following functions each have a non-underscored version, which most users should call instead. +// These functions each write to a single parameter, and the caller is responsible for ensuring the array +// passed in is large enough to hold the result. +// +// void addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer +// void add_(x,y) //do x=x+y for bigInts x and y +// void copy_(x,y) //do x=y on bigInts x and y +// void copyInt_(x,n) //do x=n on bigInt x and integer n +// void GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed). (This never overflows its array). +// boolean inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist +// void mod_(x,n) //do x=x mod n for bigInts x and n. (This never overflows its array). +// void mult_(x,y) //do x=x*y for bigInts x and y. +// void multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n. +// void powMod_(x,y,n) //do x=x**y mod n, where x,y,n are bigInts (n is odd) and ** is exponentiation. 0**0=1. +// void randBigInt_(b,n,s) //do b = an n-bit random BigInt. if s=1, then nth bit (most significant bit) is set to 1. n>=1. +// void randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb. +// void sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement. +// +// The following functions do NOT have a non-underscored version. +// They each write a bigInt result to one or more parameters. The caller is responsible for +// ensuring the arrays passed in are large enough to hold the results. +// +// void addShift_(x,y,ys) //do x=x+(y<<(ys*bpe)) +// void carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits. +// void divide_(x,y,q,r) //divide x by y giving quotient q and remainder r +// int divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder. (This never overflows its array). +// int eGCD_(x,y,d,a,b) //sets a,b,d to positive bigInts such that d = GCD_(x,y) = a*x-b*y +// void halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement. (This never overflows its array). +// void leftShift_(x,n) //left shift bigInt x by n bits. n64 multiplier, but not with JavaScript's 32*32->32) +// - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square +// followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that +// method would be slower. This is unfortunate because the code currently spends almost all of its time +// doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring +// would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded +// sentences that seem to imply it's faster to do a non-modular square followed by a single +// Montgomery reduction, but that's obviously wrong. +//////////////////////////////////////////////////////////////////////////////////////// + +//globals +bpe=0; //bits stored per array element +mask=0; //AND this with an array element to chop it down to bpe bits +radix=mask+1; //equals 2^bpe. A single 1 bit to the left of the last bit of mask. + +//the digits for converting to different bases +digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-'; + +//initialize the global variables +for (bpe=0; (1<<(bpe+1)) > (1<>=1; //bpe=number of bits in one element of the array representing the bigInt +mask=(1<0); j--); + for (z=0,w=x[j]; w; (w>>=1),z++); + z+=bpe*j; + return z; +} + +//return a copy of x with at least n elements, adding leading zeros if needed +function expand(x,n) { + var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0); + copy_(ans,x); + return ans; +} + +//return a k-bit true random prime using Maurer's algorithm. +function randTruePrime(k) { + var ans=int2bigInt(0,k,0); + randTruePrime_(ans,k); + return bigint_trim(ans,1); +} + +//return a new bigInt equal to (x mod n) for bigInts x and n. +function mod(x,n) { + var ans=dup(x); + mod_(ans,n); + return bigint_trim(ans,1); +} + +//return (x+n) where x is a bigInt and n is an integer. +function addInt(x,n) { + var ans=expand(x,x.length+1); + addInt_(ans,n); + return bigint_trim(ans,1); +} + +//return x*y for bigInts x and y. This is faster when yy.length ? x.length+1 : y.length+1)); + sub_(ans,y); + return bigint_trim(ans,1); +} + +//return (x+y) for bigInts x and y. +function add(x,y) { + var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); + add_(ans,y); + return bigint_trim(ans,1); +} + +//return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null +function inverseMod(x,n) { + var ans=expand(x,n.length); + var s; + s=inverseMod_(ans,n); + return s ? bigint_trim(ans,1) : null; +} + +//return (x*y mod n) for bigInts x,y,n. For greater speed, let y= 2 + + if (s_i2.length!=ans.length) { + s_i2=dup(ans); + s_R =dup(ans); + s_n1=dup(ans); + s_r2=dup(ans); + s_d =dup(ans); + s_x1=dup(ans); + s_x2=dup(ans); + s_b =dup(ans); + s_n =dup(ans); + s_i =dup(ans); + s_rm=dup(ans); + s_q =dup(ans); + s_a =dup(ans); + s_aa=dup(ans); + } + + if (k <= recLimit) { //generate small random primes by trial division up to its square root + pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k) + copyInt_(ans,0); + for (dd=1;dd;) { + dd=0; + ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits + for (r=1; k-k*r<=m; ) + r=pows[Math.floor(Math.random()*512)]; //r=Math.pow(2,Math.random()-1); + else + r=.5; + + //simulation suggests the more complex algorithm using r=.333 is only slightly faster. + + recSize=Math.floor(r*k)+1; + + randTruePrime_(s_q,recSize); + copyInt_(s_i2,0); + s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2) + divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q)) + + z=bitSize(s_i); + + for (;;) { + for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1] + randBigInt_(s_R,z,0); + if (greater(s_i,s_R)) + break; + } //now s_R is in the range [0,s_i-1] + addInt_(s_R,1); //now s_R is in the range [1,s_i] + add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i] + + copy_(s_n,s_q); + mult_(s_n,s_R); + multInt_(s_n,2); + addInt_(s_n,1); //s_n=2*s_R*s_q+1 + + copy_(s_r2,s_R); + multInt_(s_r2,2); //s_r2=2*s_R + + //check s_n for divisibility by small primes up to B + for (divisible=0,j=0; (j0); j--); //strip leading zeros + for (zz=0,w=s_n[j]; w; (w>>=1),zz++); + zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros + for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1] + randBigInt_(s_a,zz,0); + if (greater(s_n,s_a)) + break; + } //now s_a is in the range [0,s_n-1] + addInt_(s_n,3); //now s_a is in the range [0,s_n-4] + addInt_(s_a,2); //now s_a is in the range [2,s_n-2] + copy_(s_b,s_a); + copy_(s_n1,s_n); + addInt_(s_n1,-1); + powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n + addInt_(s_b,-1); + if (isZero(s_b)) { + copy_(s_b,s_a); + powMod_(s_b,s_r2,s_n); + addInt_(s_b,-1); + copy_(s_aa,s_n); + copy_(s_d,s_b); + GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime + if (equalsInt(s_d,1)) { + copy_(ans,s_aa); + return; //if we've made it this far, then s_n is absolutely guaranteed to be prime + } + } + } + } +} + +//Return an n-bit random BigInt (n>=1). If s=1, then the most significant of those n bits is set to 1. +function randBigInt(n,s) { + var a,b; + a=Math.floor((n-1)/bpe)+2; //# array elements to hold the BigInt with a leading 0 element + b=int2bigInt(0,0,a); + randBigInt_(b,n,s); + return b; +} + +//Set b to an n-bit random BigInt. If s=1, then the most significant of those n bits is set to 1. +//Array b must be big enough to hold the result. Must have n>=1 +function randBigInt_(b,n,s) { + var i,a; + for (i=0;i=0;i--); //find most significant element of x + xp=x[i]; + yp=y[i]; + A=1; B=0; C=0; D=1; + while ((yp+C) && (yp+D)) { + q =Math.floor((xp+A)/(yp+C)); + qp=Math.floor((xp+B)/(yp+D)); + if (q!=qp) + break; + t= A-q*C; A=C; C=t; // do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp) + t= B-q*D; B=D; D=t; + t=xp-q*yp; xp=yp; yp=t; + } + if (B) { + copy_(T,x); + linComb_(x,y,A,B); //x=A*x+B*y + linComb_(y,T,D,C); //y=D*y+C*T + } else { + mod_(x,y); + copy_(T,x); + copy_(x,y); + copy_(y,T); + } + } + if (y[0]==0) + return; + t=modInt(x,y[0]); + copyInt_(x,y[0]); + y[0]=t; + while (y[0]) { + x[0]%=y[0]; + t=x[0]; x[0]=y[0]; y[0]=t; + } +} + +//do x=x**(-1) mod n, for bigInts x and n. +//If no inverse exists, it sets x to zero and returns 0, else it returns 1. +//The x array must be at least as large as the n array. +function inverseMod_(x,n) { + var k=1+2*Math.max(x.length,n.length); + + if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist + copyInt_(x,0); + return 0; + } + + if (eg_u.length!=k) { + eg_u=new Array(k); + eg_v=new Array(k); + eg_A=new Array(k); + eg_B=new Array(k); + eg_C=new Array(k); + eg_D=new Array(k); + } + + copy_(eg_u,x); + copy_(eg_v,n); + copyInt_(eg_A,1); + copyInt_(eg_B,0); + copyInt_(eg_C,0); + copyInt_(eg_D,1); + for (;;) { + while(!(eg_u[0]&1)) { //while eg_u is even + halve_(eg_u); + if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2 + halve_(eg_A); + halve_(eg_B); + } else { + add_(eg_A,n); halve_(eg_A); + sub_(eg_B,x); halve_(eg_B); + } + } + + while (!(eg_v[0]&1)) { //while eg_v is even + halve_(eg_v); + if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2 + halve_(eg_C); + halve_(eg_D); + } else { + add_(eg_C,n); halve_(eg_C); + sub_(eg_D,x); halve_(eg_D); + } + } + + if (!greater(eg_v,eg_u)) { //eg_v <= eg_u + sub_(eg_u,eg_v); + sub_(eg_A,eg_C); + sub_(eg_B,eg_D); + } else { //eg_v > eg_u + sub_(eg_v,eg_u); + sub_(eg_C,eg_A); + sub_(eg_D,eg_B); + } + + if (equalsInt(eg_u,0)) { + if (negative(eg_C)) //make sure answer is nonnegative + add_(eg_C,n); + copy_(x,eg_C); + + if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse + copyInt_(x,0); + return 0; + } + return 1; + } + } +} + +//return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse +function inverseModInt(x,n) { + var a=1,b=0,t; + for (;;) { + if (x==1) return a; + if (x==0) return 0; + b-=a*Math.floor(n/x); + n%=x; + + if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to += + if (n==0) return 0; + a-=b*Math.floor(x/n); + x%=n; + } +} + +//this deprecated function is for backward compatibility only. +function inverseModInt_(x,n) { + return inverseModInt(x,n); +} + + +//Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that: +// v = GCD_(x,y) = a*x-b*y +//The bigInts v, a, b, must have exactly as many elements as the larger of x and y. +function eGCD_(x,y,v,a,b) { + var g=0; + var k=Math.max(x.length,y.length); + if (eg_u.length!=k) { + eg_u=new Array(k); + eg_A=new Array(k); + eg_B=new Array(k); + eg_C=new Array(k); + eg_D=new Array(k); + } + while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even + halve_(x); + halve_(y); + g++; + } + copy_(eg_u,x); + copy_(v,y); + copyInt_(eg_A,1); + copyInt_(eg_B,0); + copyInt_(eg_C,0); + copyInt_(eg_D,1); + for (;;) { + while(!(eg_u[0]&1)) { //while u is even + halve_(eg_u); + if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2 + halve_(eg_A); + halve_(eg_B); + } else { + add_(eg_A,y); halve_(eg_A); + sub_(eg_B,x); halve_(eg_B); + } + } + + while (!(v[0]&1)) { //while v is even + halve_(v); + if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2 + halve_(eg_C); + halve_(eg_D); + } else { + add_(eg_C,y); halve_(eg_C); + sub_(eg_D,x); halve_(eg_D); + } + } + + if (!greater(v,eg_u)) { //v<=u + sub_(eg_u,v); + sub_(eg_A,eg_C); + sub_(eg_B,eg_D); + } else { //v>u + sub_(v,eg_u); + sub_(eg_C,eg_A); + sub_(eg_D,eg_B); + } + if (equalsInt(eg_u,0)) { + if (negative(eg_C)) { //make sure a (C)is nonnegative + add_(eg_C,y); + sub_(eg_D,x); + } + multInt_(eg_D,-1); ///make sure b (D) is nonnegative + copy_(a,eg_C); + copy_(b,eg_D); + leftShift_(v,g); + return; + } + } +} + + +//is bigInt x negative? +function negative(x) { + return ((x[x.length-1]>>(bpe-1))&1); +} + + +//is (x << (shift*bpe)) > y? +//x and y are nonnegative bigInts +//shift is a nonnegative integer +function greaterShift(x,y,shift) { + var kx=x.length, ky=y.length; + k=((kx+shift)=0; i++) + if (x[i]>0) + return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger + for (i=kx-1+shift; i0) + return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger + for (i=k-1; i>=shift; i--) + if (x[i-shift]>y[i]) return 1; + else if (x[i-shift] y? (x and y both nonnegative) +function greater(x,y) { + var i; + var k=(x.length=0;i--) + if (x[i]>y[i]) + return 1; + else if (x[i]= y.length >= 2. +function divide_(x,y,q,r) { + var kx, ky; + var i,j,y1,y2,c,a,b; + copy_(r,x); + for (ky=y.length;y[ky-1]==0;ky--); //ky is number of elements in y, not including leading zeros + + //normalize: ensure the most significant element of y has its highest bit set + b=y[ky-1]; + for (a=0; b; a++) + b>>=1; + a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element + leftShift_(y,a); //multiply both by 1<
ky;kx--); //kx is number of elements in normalized x, not including leading zeros + + copyInt_(q,0); // q=0 + while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) { + subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky) + q[kx-ky]++; // q[kx-ky]++; + } // } + + for (i=kx-1; i>=ky; i--) { + if (r[i]==y[ky-1]) + q[i-ky]=mask; + else + q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]); + + //The following for(;;) loop is equivalent to the commented while loop, + //except that the uncommented version avoids overflow. + //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0 + // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2]) + // q[i-ky]--; + for (;;) { + y2=(ky>1 ? y[ky-2] : 0)*q[i-ky]; + c=y2>>bpe; + y2=y2 & mask; + y1=c+q[i-ky]*y[ky-1]; + c=y1>>bpe; + y1=y1 & mask; + + if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i]) + q[i-ky]--; + else + break; + } + + linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky) + if (negative(r)) { + addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky) + q[i-ky]--; + } + } + + rightShift_(y,a); //undo the normalization step + rightShift_(r,a); //undo the normalization step +} + +//do carries and borrows so each element of the bigInt x fits in bpe bits. +function carry_(x) { + var i,k,c,b; + k=x.length; + c=0; + for (i=0;i>bpe); + c+=b*radix; + } + x[i]=c & mask; + c=(c>>bpe)-b; + } +} + +//return x mod n for bigInt x and integer n. +function modInt(x,n) { + var i,c=0; + for (i=x.length-1; i>=0; i--) + c=(c*radix+x[i])%n; + return c; +} + +//convert the integer t into a bigInt with at least the given number of bits. +//the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word) +//Pad the array with leading zeros so that it has at least minSize elements. +//There will always be at least one leading 0 element. +function int2bigInt(t,bits,minSize) { + var i,k; + k=Math.ceil(bits/bpe)+1; + k=minSize>k ? minSize : k; + buff=new Array(k); + copyInt_(buff,t); + return buff; +} + +//return the bigInt given a string representation in a given base. +//Pad the array with leading zeros so that it has at least minSize elements. +//If base=-1, then it reads in a space-separated list of array elements in decimal. +//The array will always have at least one leading zero, unless base=-1. +function str2bigInt(s,base,minSize) { + var d, i, j, x, y, kk; + var k=s.length; + if (base==-1) { //comma-separated list of array elements in decimal + x=new Array(0); + for (;;) { + y=new Array(x.length+1); + for (i=0;i=36) //convert lowercase to uppercase if base<=36 + d-=26; + if (d=0) { //ignore illegal characters + multInt_(x,base); + addInt_(x,d); + } + } + + for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros + k=minSize>k+1 ? minSize : k+1; + y=new Array(k); + kk=ky.length) { + for (;i0;i--) + s+=x[i]+','; + s+=x[0]; + } + else { //return it in the given base + while (!isZero(s6)) { + t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base); + s=digitsStr.substring(t,t+1)+s; + } + } + if (s.length==0) + s="0"; + return s; +} + +//returns a duplicate of bigInt x +function dup(x) { + var i; + buff=new Array(x.length); + copy_(buff,x); + return buff; +} + +//do x=y on bigInts x and y. x must be an array at least as big as y (not counting the leading zeros in y). +function copy_(x,y) { + var i; + var k=x.length>=bpe; + } +} + +//do x=x+n where x is a bigInt and n is an integer. +//x must be large enough to hold the result. +function addInt_(x,n) { + var i,k,c,b; + x[0]+=n; + k=x.length; + c=0; + for (i=0;i>bpe); + c+=b*radix; + } + x[i]=c & mask; + c=(c>>bpe)-b; + if (!c) return; //stop carrying as soon as the carry_ is zero + } +} + +//right shift bigInt x by n bits. 0 <= n < bpe. +function rightShift_(x,n) { + var i; + var k=Math.floor(n/bpe); + if (k) { + for (i=0;i>n)); + } + x[i]>>=n; +} + +//do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement +function halve_(x) { + var i; + for (i=0;i>1)); + } + x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same +} + +//left shift bigInt x by n bits. +function leftShift_(x,n) { + var i; + var k=Math.floor(n/bpe); + if (k) { + for (i=x.length; i>=k; i--) //left shift x by k elements + x[i]=x[i-k]; + for (;i>=0;i--) + x[i]=0; + n%=bpe; + } + if (!n) + return; + for (i=x.length-1;i>0;i--) { + x[i]=mask & ((x[i]<>(bpe-n))); + } + x[i]=mask & (x[i]<>bpe); + c+=b*radix; + } + x[i]=c & mask; + c=(c>>bpe)-b; + } +} + +//do x=floor(x/n) for bigInt x and integer n, and return the remainder +function divInt_(x,n) { + var i,r=0,s; + for (i=x.length-1;i>=0;i--) { + s=r*radix+x[i]; + x[i]=Math.floor(s/n); + r=s%n; + } + return r; +} + +//do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b. +//x must be large enough to hold the answer. +function linComb_(x,y,a,b) { + var i,c,k,kk; + k=x.length>=bpe; + } + for (i=k;i>=bpe; + } +} + +//do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys. +//x must be large enough to hold the answer. +function linCombShift_(x,y,b,ys) { + var i,c,k,kk; + k=x.length>=bpe; + } + for (i=k;c && i>=bpe; + } +} + +//do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys. +//x must be large enough to hold the answer. +function addShift_(x,y,ys) { + var i,c,k,kk; + k=x.length>=bpe; + } + for (i=k;c && i>=bpe; + } +} + +//do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys. +//x must be large enough to hold the answer. +function subShift_(x,y,ys) { + var i,c,k,kk; + k=x.length>=bpe; + } + for (i=k;c && i>=bpe; + } +} + +//do x=x-y for bigInts x and y. +//x must be large enough to hold the answer. +//negative answers will be 2s complement +function sub_(x,y) { + var i,c,k,kk; + k=x.length>=bpe; + } + for (i=k;c && i>=bpe; + } +} + +//do x=x+y for bigInts x and y. +//x must be large enough to hold the answer. +function add_(x,y) { + var i,c,k,kk; + k=x.length>=bpe; + } + for (i=k;c && i>=bpe; + } +} + +//do x=x*y for bigInts x and y. This is faster when y0 && !x[kx-1]; kx--); //ignore leading zeros in x + k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n + if (s0.length!=k) + s0=new Array(k); + copyInt_(s0,0); + for (i=0;i>=bpe; + for (j=i+1;j>=bpe; + } + s0[i+kx]=c; + } + mod_(s0,n); + copy_(x,s0); +} + +//return x with exactly k leading zero elements +function bigint_trim(x,k) { + var i,y; + for (i=x.length; i>0 && !x[i-1]; i--); + y=new Array(i+k); + copy_(y,x); + return y; +} + +//do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1. +//this is faster when n is odd. x usually needs to have as many elements as n. +function powMod_(x,y,n) { + var k1,k2,kn,np; + if(s7.length!=n.length) + s7=dup(n); + + //for even modulus, use a simple square-and-multiply algorithm, + //rather than using the more complex Montgomery algorithm. + if ((n[0]&1)==0) { + copy_(s7,x); + copyInt_(x,1); + while(!equalsInt(y,0)) { + if (y[0]&1) + multMod_(x,s7,n); + divInt_(y,2); + squareMod_(s7,n); + } + return; + } + + //calculate np from n for the Montgomery multiplications + copyInt_(s7,0); + for (kn=n.length;kn>0 && !n[kn-1];kn--); + np=radix-inverseModInt(modInt(n,radix),radix); + s7[kn]=1; + multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n + + if (s3.length!=x.length) + s3=dup(x); + else + copy_(s3,x); + + for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y + if (y[k1]==0) { //anything to the 0th power is 1 + copyInt_(x,1); + return; + } + for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1] + for (;;) { + if (!(k2>>=1)) { //look at next bit of y + k1--; + if (k1<0) { + mont_(x,one,n,np); + return; + } + k2=1<<(bpe-1); + } + mont_(x,x,n,np); + + if (k2 & y[k1]) //if next bit is a 1 + mont_(x,s3,n,np); + } +} + +//do x=x*y*Ri mod n for bigInts x,y,n, +// where Ri = 2**(-kn*bpe) mod n, and kn is the +// number of elements in the n array, not +// counting leading zeros. +//x must be large enough to hold the answer. +//It's OK if x and y are the same variable. +//must have: +// x,y < n +// n is odd +// np = -(n^(-1)) mod radix +function mont_(x,y,n,np) { + var i,j,c,ui,t; + var kn=n.length; + var ky=y.length; + + if (sa.length!=kn) + sa=new Array(kn); + + for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n + //this function sometimes gives wrong answers when the next line is uncommented + //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y + + copyInt_(sa,0); + + //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys + for (i=0; i> bpe; + t=x[i]; + + //do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe + for (j=1;j>=bpe; + } + for (;j>=bpe; + } + sa[j-1]=c & mask; + } + + if (!greater(n,sa)) + sub_(sa,n); + copy_(x,sa); +} + + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/loader.js --- a/includes/clientside/static/loader.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/loader.js Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,6 @@ function mdgInnerLoader(e) { - jws.startup(); if(window.location.hash == '#comments') ajaxComments(); window.onkeydown=isKeyPressed; window.onkeyup=function(e) { isKeyPressed(e); }; @@ -18,10 +17,14 @@ initSliders(); runOnloadHooks(e); } -if(window.onload) var ld = window.onload; -else var ld = function() {return;}; +var ld; +if(window.onload) ld = window.onload; +else ld = function() {return;}; function enano_init(e) { - ld(e); + if ( typeof(ld) == 'function' ) + { + ld(e); + } mdgInnerLoader(e); } diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/login.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/static/login.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,778 @@ +/* + * AJAX-based intelligent login interface + */ + +/* + * FRONTEND + */ + +/** + * Performs a logon as a regular member. + */ + +function ajaxLogonToMember() +{ + // IE <6 pseudo-compatibility + if ( KILL_SWITCH ) + return true; + if ( auth_level >= USER_LEVEL_MEMBER ) + return true; + ajaxLoginInit(function(k) + { + window.location.reload(); + }, USER_LEVEL_MEMBER); +} + +/** + * Authenticates to the highest level the current user is allowed to go to. + */ + +function ajaxLogonToElev() +{ + if ( auth_level == user_level ) + return true; + + ajaxLoginInit(function(k) + { + ENANO_SID = k; + var url = String(' ' + window.location).substr(1); + url = append_sid(url); + window.location = url; + }, user_level); +} + +/* + * BACKEND + */ + +/** + * Holding object for various AJAX authentication information. + * @var object + */ + +var logindata = {}; + +/** + * Path to the image used to indicate loading progress + * @var string + */ + +if ( !ajax_login_loadimg_path ) + var ajax_login_loadimg_path = false; + +if ( !ajax_login_successimg_path ) + var ajax_login_successimg_path = false; + +/** + * Status variables + * @var int + */ + +var AJAX_STATUS_LOADING_KEY = 1; +var AJAX_STATUS_GENERATING_KEY = 2; +var AJAX_STATUS_LOGGING_IN = 3; +var AJAX_STATUS_SUCCESS = 4; +var AJAX_STATUS_DESTROY = 65535; + +/** + * State constants + * @var int + */ + +var AJAX_STATE_EARLY_INIT = 1; +var AJAX_STATE_LOADING_KEY = 2; + +/** + * Performs the AJAX request to get an encryption key and from there spawns the login form. + * @param function The function that will be called once authentication completes successfully. + * @param int The security level to authenticate at - see http://docs.enanocms.org/Help:Appendix_B + */ + +function ajaxLoginInit(call_on_finish, user_level) +{ + logindata = {}; + + var title = ( user_level > USER_LEVEL_MEMBER ) ? $lang.get('user_login_ajax_prompt_title_elev') : $lang.get('user_login_ajax_prompt_title'); + logindata.mb_object = new messagebox(MB_OKCANCEL | MB_ICONLOCK, title, ''); + + logindata.mb_object.onclick['Cancel'] = function() + { + // Hide the error message and captcha + if ( document.getElementById('ajax_login_error_box') ) + { + document.getElementById('ajax_login_error_box').parentNode.removeChild(document.getElementById('ajax_login_error_box')); + } + if ( document.getElementById('autoCaptcha') ) + { + var to = fly_out_top(document.getElementById('autoCaptcha'), false, true); + setTimeout(function() { + var d = document.getElementById('autoCaptcha'); + d.parentNode.removeChild(d); + }, to); + } + }; + + logindata.mb_object.onbeforeclick['OK'] = function() + { + ajaxLoginSubmitForm(); + return true; + } + + // Fetch the inner content area + logindata.mb_inner = document.getElementById('messageBox').getElementsByTagName('div')[0]; + + // Initialize state + logindata.showing_status = false; + logindata.user_level = user_level; + logindata.successfunc = call_on_finish; + + // Build the "loading" window + ajaxLoginSetStatus(AJAX_STATUS_LOADING_KEY); + + // Request the key + ajaxLoginPerformRequest({ mode: 'getkey' }); +} + +/** + * Sets the contents of the AJAX login window to the appropriate status message. + * @param int One of AJAX_STATUS_* + */ + +function ajaxLoginSetStatus(status) +{ + if ( !logindata.mb_inner ) + return false; + if ( logindata.showing_status ) + { + var div = document.getElementById('ajax_login_status'); + if ( div ) + logindata.mb_inner.removeChild(div); + } + switch(status) + { + case AJAX_STATUS_LOADING_KEY: + + // Create the status div + var div = document.createElement('div'); + div.id = 'ajax_login_status'; + div.style.marginTop = '10px'; + div.style.textAlign = 'center'; + + // The circly ball ajaxy image + status message + var status_msg = $lang.get('user_login_ajax_fetching_key'); + + // Insert the status message + div.appendChild(document.createTextNode(status_msg)); + + // Append a br or two to space things properly + div.appendChild(document.createElement('br')); + div.appendChild(document.createElement('br')); + + var img = document.createElement('img'); + img.src = ( ajax_login_loadimg_path ) ? ajax_login_loadimg_path : scriptPath + '/images/loading-big.gif'; + div.appendChild(img); + + // Another coupla brs + div.appendChild(document.createElement('br')); + div.appendChild(document.createElement('br')); + + // The link to the full login form + var small = document.createElement('small'); + small.innerHTML = $lang.get('user_login_ajax_link_fullform', { link_full_form: makeUrlNS('Special', 'Login/' + title) }); + div.appendChild(small); + + // Insert the entire message into the login window + logindata.mb_inner.innerHTML = ''; + logindata.mb_inner.appendChild(div); + + break; + case AJAX_STATUS_GENERATING_KEY: + + // Create the status div + var div = document.createElement('div'); + div.id = 'ajax_login_status'; + div.style.marginTop = '10px'; + div.style.textAlign = 'center'; + + // The circly ball ajaxy image + status message + var status_msg = $lang.get('user_login_ajax_generating_key'); + + // Insert the status message + div.appendChild(document.createTextNode(status_msg)); + + // Append a br or two to space things properly + div.appendChild(document.createElement('br')); + div.appendChild(document.createElement('br')); + + var img = document.createElement('img'); + img.src = ( ajax_login_loadimg_path ) ? ajax_login_loadimg_path : scriptPath + '/images/loading-big.gif'; + div.appendChild(img); + + // Another coupla brs + div.appendChild(document.createElement('br')); + div.appendChild(document.createElement('br')); + + // The link to the full login form + var small = document.createElement('small'); + small.innerHTML = $lang.get('user_login_ajax_link_fullform_dh', { link_full_form: makeUrlNS('Special', 'Login/' + title) }); + div.appendChild(small); + + // Insert the entire message into the login window + logindata.mb_inner.innerHTML = ''; + logindata.mb_inner.appendChild(div); + + break; + case AJAX_STATUS_LOGGING_IN: + + // Create the status div + var div = document.createElement('div'); + div.id = 'ajax_login_status'; + div.style.marginTop = '10px'; + div.style.textAlign = 'center'; + + // The circly ball ajaxy image + status message + var status_msg = $lang.get('user_login_ajax_loggingin'); + + // Insert the status message + div.appendChild(document.createTextNode(status_msg)); + + // Append a br or two to space things properly + div.appendChild(document.createElement('br')); + div.appendChild(document.createElement('br')); + + var img = document.createElement('img'); + img.src = ( ajax_login_loadimg_path ) ? ajax_login_loadimg_path : scriptPath + '/images/loading-big.gif'; + div.appendChild(img); + + // Insert the entire message into the login window + logindata.mb_inner.innerHTML = ''; + logindata.mb_inner.appendChild(div); + + break; + case AJAX_STATUS_SUCCESS: + + // Create the status div + var div = document.createElement('div'); + div.id = 'ajax_login_status'; + div.style.marginTop = '10px'; + div.style.textAlign = 'center'; + + // The circly ball ajaxy image + status message + var status_msg = $lang.get('user_login_success_short'); + + // Insert the status message + div.appendChild(document.createTextNode(status_msg)); + + // Append a br or two to space things properly + div.appendChild(document.createElement('br')); + div.appendChild(document.createElement('br')); + + var img = document.createElement('img'); + img.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/check.png'; + div.appendChild(img); + + // Insert the entire message into the login window + logindata.mb_inner.innerHTML = ''; + logindata.mb_inner.appendChild(div); + + case AJAX_STATUS_DESTROY: + case null: + case undefined: + logindata.showing_status = false; + return null; + break; + } + logindata.showing_status = true; +} + +/** + * Performs an AJAX logon request to the server and calls ajaxLoginProcessResponse() on the result. + * @param object JSON packet to send + */ + +function ajaxLoginPerformRequest(json) +{ + json = toJSONString(json); + json = ajaxEscape(json); + ajaxPost(makeUrlNS('Special', 'Login/action.json'), 'r=' + json, function() + { + if ( ajax.readyState == 4 && ajax.status == 200 ) + { + // parse response + var response = String(ajax.responseText + ''); + if ( response.substr(0, 1) != '{' ) + { + handle_invalid_json(response); + return false; + } + response = parseJSON(response); + ajaxLoginProcessResponse(response); + } + }, true); +} + +/** + * Processes a response from the login server + * @param object JSON response + */ + +function ajaxLoginProcessResponse(response) +{ + // Did the server send a plaintext error? + if ( response.mode == 'error' ) + { + logindata.mb_object.destroy(); + new messagebox(MB_ICONSTOP | MB_OK, 'FIXME L10N: There was an error in the login process', 'The following error code came from the server:
' + response.error); + return false; + } + // Rid ourselves of any loading windows + ajaxLoginSetStatus(AJAX_STATUS_DESTROY); + // Main mode switch + switch ( response.mode ) + { + case 'build_box': + // The server wants us to build the login form, all the information is there + ajaxLoginBuildForm(response); + break; + case 'login_success': + ajaxLoginSetStatus(AJAX_STATUS_SUCCESS); + logindata.successfunc(response.key); + break; + case 'login_failure': + document.getElementById('messageBox').style.backgroundColor = '#C0C0C0'; + var mb_parent = document.getElementById('messageBox').parentNode; + new Spry.Effect.Shake(mb_parent, {duration: 1500}).start(); + setTimeout(function() + { + document.getElementById('messageBox').style.backgroundColor = '#FFF'; + ajaxLoginBuildForm(response.respawn_info); + ajaxLoginShowFriendlyError(response); + }, 2500); + break; + } +} + +/* + * RESPONSE HANDLERS + */ + +/** + * Builds the login form. + * @param object Metadata to build off of + */ + +function ajaxLoginBuildForm(data) +{ + // let's hope this effectively preloads the image... + var _ = document.createElement('img'); + _.src = ( ajax_login_successimg_path ) ? ajax_login_successimg_path : scriptPath + '/images/check.png'; + + var div = document.createElement('div'); + div.id = 'ajax_login_form'; + + var show_captcha = ( data.locked_out && data.lockout_info.lockout_policy == 'captcha' ) ? data.lockout_info.captcha : false; + + // text displayed on re-auth + if ( logindata.user_level > USER_LEVEL_MEMBER ) + { + div.innerHTML += $lang.get('user_login_ajax_prompt_body_elev') + '

'; + } + + // Create the form + var form = document.createElement('form'); + form.action = 'javascript:void(ajaxLoginSubmitForm());'; + form.onsubmit = function() + { + ajaxLoginSubmitForm(); + return false; + } + + // Using tables to wrap form elements because it results in a + // more visually appealing form. Yes, tables suck. I don't really + // care - they make forms look good. + + var table = document.createElement('table'); + table.style.margin = '0 auto'; + + // Field - username + var tr1 = document.createElement('tr'); + var td1_1 = document.createElement('td'); + td1_1.appendChild(document.createTextNode($lang.get('user_login_field_username') + ':')); + tr1.appendChild(td1_1); + var td1_2 = document.createElement('td'); + var f_username = document.createElement('input'); + f_username.id = 'ajax_login_field_username'; + f_username.name = 'ajax_login_field_username'; + f_username.type = 'text'; + f_username.size = '25'; + if ( data.username ) + f_username.value = data.username; + td1_2.appendChild(f_username); + tr1.appendChild(td1_2); + table.appendChild(tr1); + + // Field - password + var tr2 = document.createElement('tr'); + var td2_1 = document.createElement('td'); + td2_1.appendChild(document.createTextNode($lang.get('user_login_field_password') + ':')); + tr2.appendChild(td2_1); + var td2_2 = document.createElement('td'); + var f_password = document.createElement('input'); + f_password.id = 'ajax_login_field_password'; + f_password.name = 'ajax_login_field_username'; + f_password.type = 'password'; + f_password.size = '25'; + if ( !show_captcha ) + { + f_password.onkeyup = function(e) + { + if ( !e.keyCode ) + e = window.event; + if ( !e.keyCode ) + return true; + if ( e.keyCode == 13 ) + { + ajaxLoginSubmitForm(); + } + } + } + td2_2.appendChild(f_password); + tr2.appendChild(td2_2); + table.appendChild(tr2); + + // Field - captcha + if ( show_captcha ) + { + var tr3 = document.createElement('tr'); + var td3_1 = document.createElement('td'); + td3_1.appendChild(document.createTextNode($lang.get('user_login_field_captcha') + ':')); + tr3.appendChild(td3_1); + var td3_2 = document.createElement('td'); + var f_captcha = document.createElement('input'); + f_captcha.id = 'ajax_login_field_captcha'; + f_captcha.name = 'ajax_login_field_username'; + f_captcha.type = 'text'; + f_captcha.size = '25'; + f_captcha.onkeyup = function(e) + { + if ( !e ) + e = window.event; + if ( !e.keyCode ) + return true; + if ( e.keyCode == 13 ) + { + ajaxLoginSubmitForm(); + } + } + td3_2.appendChild(f_captcha); + tr3.appendChild(td3_2); + table.appendChild(tr3); + } + + // Done building the main part of the form + form.appendChild(table); + + // Field: enable Diffie Hellman + var lbl_dh = document.createElement('label'); + lbl_dh.style.fontSize = 'smaller'; + lbl_dh.style.display = 'block'; + lbl_dh.style.textAlign = 'center'; + var check_dh = document.createElement('input'); + check_dh.type = 'checkbox'; + // this onclick attribute changes the cookie whenever the checkbox or label is clicked + check_dh.setAttribute('onclick', 'var ck = ( this.checked ) ? "enable" : "disable"; createCookie("diffiehellman_login", ck, 3650);'); + if ( readCookie('diffiehellman_login') != 'disable' ) + check_dh.setAttribute('checked', 'checked'); + check_dh.id = 'ajax_login_field_dh'; + lbl_dh.appendChild(check_dh); + lbl_dh.innerHTML += $lang.get('user_login_ajax_check_dh'); + form.appendChild(lbl_dh); + + div.appendChild(form); + + // Diagnostic / help links + // (only displayed in login, not in re-auth) + if ( logindata.user_level == USER_LEVEL_MEMBER ) + { + form.style.marginBottom = '10px'; + var links = document.createElement('small'); + links.style.display = 'block'; + links.style.textAlign = 'center'; + links.innerHTML = ''; + if ( !show_captcha ) + links.innerHTML += $lang.get('user_login_ajax_link_fullform', { link_full_form: makeUrlNS('Special', 'Login/' + title) }) + '
'; + // Always shown + links.innerHTML += $lang.get('user_login_ajax_link_forgotpass', { forgotpass_link: makeUrlNS('Special', 'PasswordReset') }) + '
'; + if ( !show_captcha ) + links.innerHTML += $lang.get('user_login_createaccount_blurb', { reg_link: makeUrlNS('Special', 'Register') }); + div.appendChild(links); + } + + // Insert the entire form into the login window + logindata.mb_inner.innerHTML = ''; + logindata.mb_inner.appendChild(div); + + // Post operations: field focus + if ( data.username ) + f_password.focus(); + else + f_username.focus(); + + // Post operations: show captcha window + if ( show_captcha ) + ajaxShowCaptcha(show_captcha); + + // Post operations: stash encryption keys and All That Jazz(TM) + logindata.key_aes = data.aes_key; + logindata.key_dh = data.dh_public_key; + logindata.captcha_hash = show_captcha; + + // Are we locked out? If so simulate an error and disable the controls + if ( data.lockout_info.lockout_policy == 'lockout' && data.locked_out ) + { + f_username.setAttribute('disabled', 'disabled'); + f_password.setAttribute('disabled', 'disabled'); + var fake_packet = { + error_code: 'locked_out', + respawn_info: data + }; + ajaxLoginShowFriendlyError(fake_packet); + } +} + +function ajaxLoginSubmitForm(real, username, password, captcha) +{ + // Perform AES test to make sure it's all working + if ( !aes_self_test() ) + { + alert('BUG: AES self-test failed'); + login_cache.mb_object.destroy(); + return false; + } + // Hide the error message and captcha + if ( document.getElementById('ajax_login_error_box') ) + { + document.getElementById('ajax_login_error_box').parentNode.removeChild(document.getElementById('ajax_login_error_box')); + } + if ( document.getElementById('autoCaptcha') ) + { + var to = fly_out_top(document.getElementById('autoCaptcha'), false, true); + setTimeout(function() { + var d = document.getElementById('autoCaptcha'); + d.parentNode.removeChild(d); + }, to); + } + // Encryption: preprocessor + if ( real ) + { + var do_dh = true; + } + else if ( document.getElementById('ajax_login_field_dh') ) + { + var do_dh = document.getElementById('ajax_login_field_dh').checked; + } + else + { + // The user probably clicked ok when the form wasn't in there. + return false; + } + if ( !username ) + { + var username = document.getElementById('ajax_login_field_username').value; + } + if ( !password ) + { + var password = document.getElementById('ajax_login_field_password').value; + } + if ( !captcha && document.getElementById('ajax_login_field_captcha') ) + { + var captcha = document.getElementById('ajax_login_field_captcha').value; + } + + if ( do_dh ) + { + ajaxLoginSetStatus(AJAX_STATUS_GENERATING_KEY); + if ( !real ) + { + // Wait while the browser updates the login window + setTimeout(function() + { + ajaxLoginSubmitForm(true, username, password, captcha); + }, 200); + return true; + } + // Perform Diffie Hellman stuff + var dh_priv = dh_gen_private(); + var dh_pub = dh_gen_public(dh_priv); + var secret = dh_gen_shared_secret(dh_priv, logindata.key_dh); + // secret_hash is used to verify that the server guesses the correct secret + var secret_hash = hex_sha1(secret); + // crypt_key is the actual AES key + var crypt_key = (hex_sha256(secret)).substr(0, (keySizeInBits / 4)); + } + else + { + var crypt_key = logindata.key_aes; + } + + ajaxLoginSetStatus(AJAX_STATUS_LOGGING_IN); + + // Encrypt the password and username + var userinfo = toJSONString({ + username: username, + password: password + }); + var crypt_key_ba = hexToByteArray(crypt_key); + userinfo = stringToByteArray(userinfo); + + userinfo = rijndaelEncrypt(userinfo, crypt_key_ba, 'ECB'); + userinfo = byteArrayToHex(userinfo); + // Encrypted username and password (serialized with JSON) are now in the userinfo string + + // Collect other needed information + if ( logindata.captcha_hash ) + { + var captcha_hash = logindata.captcha_hash; + var captcha_code = captcha; + } + else + { + var captcha_hash = false; + var captcha_code = false; + } + + // Ship it across the 'net + if ( do_dh ) + { + var json_packet = { + mode: 'login_dh', + userinfo: userinfo, + captcha_code: captcha_code, + captcha_hash: captcha_hash, + dh_public_key: logindata.key_dh, + dh_client_key: dh_pub, + dh_secret_hash: secret_hash, + level: logindata.user_level + } + } + else + { + var json_packet = { + mode: 'login_aes', + userinfo: userinfo, + captcha_code: captcha_code, + captcha_hash: captcha_hash, + key_aes: hex_md5(crypt_key), + level: logindata.user_level + } + } + ajaxLoginPerformRequest(json_packet); +} + +function ajaxLoginShowFriendlyError(response) +{ + if ( !response.respawn_info ) + return false; + if ( !response.error_code ) + return false; + var text = ajaxLoginGetErrorText(response); + if ( document.getElementById('ajax_login_error_box') ) + { + // console.info('Reusing existing error-box'); + document.getElementById('ajax_login_error_box').innerHTML = text; + return true; + } + + // console.info('Drawing new error-box'); + + // calculate position for the top of the box + var mb_bottom = $('messageBoxButtons').Top() + $('messageBoxButtons').Height(); + // if the box isn't done flying in yet, just estimate + if ( mb_bottom < ( getHeight() / 2 ) ) + { + mb_bottom = ( getHeight() / 2 ) + 120; + } + var win_bottom = getHeight() + getScrollOffset(); + var top = mb_bottom + ( ( win_bottom - mb_bottom ) / 2 ) - 32; + // left position = 0.2 * window_width, seeing as the box is 60% width this works hackishly but nice and quick + var left = getWidth() * 0.2; + + // create the div + var errbox = document.createElement('div'); + errbox.className = 'error-box-mini'; + errbox.style.position = 'absolute'; + errbox.style.width = '60%'; + errbox.style.top = top + 'px'; + errbox.style.left = left + 'px'; + errbox.innerHTML = text; + errbox.id = 'ajax_login_error_box'; + + var body = document.getElementsByTagName('body')[0]; + body.appendChild(errbox); +} + +function ajaxLoginGetErrorText(response) +{ + switch ( response.error_code ) + { + default: + return $lang.get('user_err_' + response.error_code); + break; + case 'locked_out': + if ( response.respawn_info.lockout_info.lockout_policy == 'lockout' ) + { + return $lang.get('user_err_locked_out', { + lockout_threshold: response.respawn_info.lockout_info.lockout_threshold, + lockout_duration: response.respawn_info.lockout_info.lockout_duration, + time_rem: response.respawn_info.lockout_info.time_rem, + plural: ( response.respawn_info.lockout_info.time_rem == 1 ) ? '' : $lang.get('meta_plural'), + captcha_blurb: '' + }); + break; + } + case 'invalid_credentials': + var base = $lang.get('user_err_invalid_credentials'); + if ( response.respawn_info.locked_out ) + { + base += ' '; + var captcha_blurb = ''; + switch(response.respawn_info.lockout_info.lockout_policy) + { + case 'captcha': + captcha_blurb = $lang.get('user_err_locked_out_captcha_blurb'); + break; + case 'lockout': + break; + default: + base += 'WTF? Shouldn\'t be locked out with lockout policy set to disable.'; + break; + } + base += $lang.get('user_err_locked_out', { + captcha_blurb: captcha_blurb, + lockout_threshold: response.respawn_info.lockout_info.lockout_threshold, + lockout_duration: response.respawn_info.lockout_info.lockout_duration, + time_rem: response.respawn_info.lockout_info.time_rem, + plural: ( response.respawn_info.lockout_info.time_rem == 1 ) ? '' : $lang.get('meta_plural') + }); + } + else if ( response.respawn_info.lockout_info.lockout_policy == 'lockout' || response.respawn_info.lockout_info.lockout_policy == 'captcha' ) + { + // if we have a lockout policy of captcha or lockout, then warn the user + switch ( response.respawn_info.lockout_info.lockout_policy ) + { + case 'captcha': + base += $lang.get('user_err_invalid_credentials_lockout', { + fails: response.respawn_info.lockout_info.lockout_fails, + lockout_threshold: response.respawn_info.lockout_info.lockout_threshold, + lockout_duration: response.respawn_info.lockout_info.lockout_duration + }); + break; + case 'lockout': + break; + } + } + return base; + break; + } +} + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/misc.js --- a/includes/clientside/static/misc.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/misc.js Fri Feb 22 12:51:53 2008 -0500 @@ -38,7 +38,7 @@ rDnsObj = o; rDnsBannerObj = bannerOn('Retrieving reverse DNS info...'); ajaxGet(stdAjaxPrefix+'&_mode=rdns&ip='+ipaddr, function() { - if(ajax.readyState == 4) + if ( ajax.readyState == 4 && ajax.status == 200 ) { off = fetch_offset(rDnsObj); dim = fetch_dimensions(rDnsObj); @@ -299,286 +299,13 @@ /* * AJAX login box (experimental) + * Moved / rewritten in login.js */ -var ajax_auth_prompt_cache = false; -var ajax_auth_mb_cache = false; -var ajax_auth_level_cache = false; -var ajax_auth_error_string = false; - +// Included only for API-compatibility function ajaxPromptAdminAuth(call_on_ok, level) { - if ( typeof(call_on_ok) == 'function' ) - { - ajax_auth_prompt_cache = call_on_ok; - } - if ( !level ) - level = USER_LEVEL_MEMBER; - ajax_auth_level_cache = level; - var loading_win = '
'; - var title = ( level > USER_LEVEL_MEMBER ) ? 'You are requesting a sensitive operation.' : 'Please enter your username and password to continue.'; - ajax_auth_mb_cache = new messagebox(MB_OKCANCEL|MB_ICONLOCK, title, loading_win); - ajax_auth_mb_cache.onbeforeclick['OK'] = ajaxValidateLogin; - ajaxAuthLoginInnerSetup(); -} - -function ajaxAuthLoginInnerSetup() -{ - // let's hope this gets the image cached - var _ = new Image(32, 32); - _.src = scriptPath + "/images/good.gif"; - - ajaxGet(makeUrlNS('Special', 'Login', 'act=getkey'), function() { - if ( ajax.readyState == 4 ) - { - var response = String(ajax.responseText); - if ( response.substr(0,1) != '{' ) - { - handle_invalid_json(response); - ajax_auth_mb_cache.destroy(); - return false; - } - response = parseJSON(response); - var level = ajax_auth_level_cache; - var form_html = ''; - var shown_error = false; - if ( ajax_auth_error_string ) - { - shown_error = true; - form_html += '
' + ajax_auth_error_string + '
'; - ajax_auth_error_string = false; - } - else if ( level > USER_LEVEL_MEMBER ) - { - form_html += 'Please re-enter your login details, to verify your identity.

'; - } - form_html += ' \ -
\ - \ - \ - \ - \ - \ - \ - \ - \ -
Username: \ -
Password: \ -
\ -
Trouble logging in? Try the full login form.
'; - if ( level <= USER_LEVEL_MEMBER ) - { - form_html += ' \ - Did you forget your password?
\ - Maybe you need to create an account.
'; - } - form_html += ' \ -
\ - \ - \ -
'; - ajax_auth_mb_cache.updateContent(form_html); - $('messageBox').object.nextSibling.firstChild.tabindex = '3'; - if ( typeof(response.username) == 'string' ) - { - $('ajaxlogin_user').object.value = response.username; - if ( IE ) - { - setTimeout("document.forms['ajax_login_form'].password.focus();", 200); - } - else - { - $('ajaxlogin_pass').object.focus(); - } - } - else - { - if ( IE ) - { - setTimeout("document.forms['ajax_login_form'].username.focus();", 200); - } - else - { - $('ajaxlogin_user').object.focus(); - } - } - $('ajaxlogin_pass').object.onblur = function(e) { if ( !shift ) $('messageBox').object.nextSibling.firstChild.focus(); }; - $('ajaxlogin_pass').object.onkeypress = function(e) - { - // Trigger a form submit when the password field is focused and the user presses enter - - // IE doesn't give us an event object when it should - check window.event. If that - // still fails, give up. - if ( !e ) - { - e = window.event; - } - if ( !e && IE ) - { - return true; - } - if ( e.keyCode == 13 ) - { - ajaxValidateLogin(); - } - }; - /* - ## This causes the background image to disappear under Fx 2 - if ( shown_error ) - { - // fade to #FFF4F4 - var fader = new Spry.Effect.Highlight('ajax_auth_error', {duration: 1000, from: '#FFF4F4', to: '#805600', restoreColor: '#805600', finish: function() - { - var fader = new Spry.Effect.Highlight('ajax_auth_error', {duration: 3000, from: '#805600', to: '#FFF4F4', restoreColor: '#FFF4F4'}); - fader.start(); - }}); - fader.start(); - } - */ - } - }); -} - -function ajaxValidateLogin() -{ - var username,password,auth_enabled,crypt_key,crypt_data,challenge_salt,challenge_data; - username = document.getElementById('ajaxlogin_user'); - if ( !username ) - return false; - username = document.getElementById('ajaxlogin_user').value; - password = document.getElementById('ajaxlogin_pass').value; - auth_enabled = false; - - disableJSONExts(); - - // - // Encryption test - // - - var str = ''; - for(i=0;i

\ - '; - - ajax_auth_mb_cache.updateContent(loading_win); - - ajaxPost(makeUrlNS('Special', 'Login', 'act=ajaxlogin'), 'params=' + json_data, function() { - if ( ajax.readyState == 4 ) - { - var response = ajax.responseText; - if ( response.substr(0,1) != '{' ) - { - alert('Invalid JSON response from server: ' + response); - ajaxAuthLoginInnerSetup(); - return false; - } - response = parseJSON(response); - switch(response.result) - { - case 'success': - var success_win = '
\ -

Success.

\ -

\ -
'; - ajax_auth_mb_cache.updateContent(success_win); - if ( typeof(ajax_auth_prompt_cache) == 'function' ) - { - ajax_auth_prompt_cache(response.key); - } - break; - case 'success_reset': - var conf = confirm('You have logged in using a temporary password. Before you can log in, you must finish resetting your password. Do you want to reset your real password now?'); - if ( conf ) - { - var url = makeUrlNS('Special', 'PasswordReset/stage2/' + response.user_id + '/' + response.temppass); - window.location = url; - } - else - { - ajaxAuthLoginInnerSetup(); - } - break; - case 'error': - if ( response.error == 'The username and/or password is incorrect.' ) - { - ajax_auth_error_string = response.error; - mb_current_obj.updateContent(''); - document.getElementById('messageBox').style.backgroundColor = '#C0C0C0'; - var mb_parent = document.getElementById('messageBox').parentNode; - new Spry.Effect.Shake(mb_parent, {duration: 1500}).start(); - setTimeout("document.getElementById('messageBox').style.backgroundColor = '#FFF'; ajaxAuthLoginInnerSetup();", 2500); - } - else - { - alert(response.error); - ajaxAuthLoginInnerSetup(); - } - break; - default: - alert(ajax.responseText); - break; - } - } - }); - - return true; - + ajaxLogonInit(call_on_ok, level); } // This code is in the public domain. Feel free to link back to http://jan.moesen.nu/ @@ -674,3 +401,181 @@ return ( email.match(/^(?:[\w\d_-]+\.?)+@((?:(?:[\w\d_-]\-?)+\.)+\w{2,4}|localhost)$/) ) ? true : false; } +/** + * Validates a username. + * @param string Username to test + * @return bool + */ + +function validateUsername(username) +{ + var regex = new RegExp('^[^<>&\?\'"%\n\r/]+$', ''); + return ( username.match(regex) ) ? true : false; +} + +/** + * Equivalent of PHP's time() + * @return int + */ + +function unix_time() +{ + return parseInt((new Date()).getTime()/1000); +} + +/* + * Utility functions, moved from windows.js + */ + +// getElementWidth() and getElementHeight() +// Source: http://www.aspandjavascript.co.uk/javascript/javascript_api/get_element_width_height.asp + +function getElementHeight(Elem) { + if (ns4) + { + var elem = getObjNN4(document, Elem); + return elem.clip.height; + } + else + { + if(document.getElementById) + { + var elem = document.getElementById(Elem); + } + else if (document.all) + { + var elem = document.all[Elem]; + } + if (op5) + { + xPos = elem.style.pixelHeight; + } + else + { + xPos = elem.offsetHeight; + } + return xPos; + } +} + +function getElementWidth(Elem) { + if (ns4) { + var elem = getObjNN4(document, Elem); + return elem.clip.width; + } else { + if(document.getElementById) { + var elem = document.getElementById(Elem); + } else if (document.all){ + var elem = document.all[Elem]; + } + if (op5) { + xPos = elem.style.pixelWidth; + } else { + xPos = elem.offsetWidth; + } + return xPos; + } +} + +function getHeight() { + var myHeight = 0; + if( typeof( window.innerWidth ) == 'number' ) { + myHeight = window.innerHeight; + } else if( document.documentElement && + ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { + myHeight = document.documentElement.clientHeight; + } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { + myHeight = document.body.clientHeight; + } + return myHeight; +} + +function getWidth() { + var myWidth = 0; + if( typeof( window.innerWidth ) == 'number' ) { + myWidth = window.innerWidth; + } else if( document.documentElement && + ( document.documentElement.clientWidth || document.documentElement.clientWidth ) ) { + myWidth = document.documentElement.clientWidth; + } else if( document.body && ( document.body.clientWidth || document.body.clientWidth ) ) { + myWidth = document.body.clientWidth; + } + return myWidth; +} + +/** + * Sanitizes a page URL string so that it can safely be stored in the database. + * @param string Page ID to sanitize + * @return string Cleaned text + */ + +function sanitize_page_id(page_id) +{ + // Remove character escapes + page_id = dirtify_page_id(page_id); + + var regex = new RegExp('[A-Za-z0-9\\[\\]\./:;\(\)@_-]', 'g'); + pid_clean = page_id.replace(regex, 'X'); + var pid_dirty = []; + for ( var i = 0; i < pid_clean.length; i++ ) + pid_dirty[i] = pid_clean.substr(i, 1); + + for ( var i = 0; i < pid_dirty.length; i++ ) + { + var char = pid_dirty[i]; + if ( char == 'X' ) + continue; + var cid = char.charCodeAt(0); + cid = cid.toString(16).toUpperCase(); + if ( cid.length < 2 ) + { + cid = '0' + cid; + } + pid_dirty[i] = "." + cid; + } + + var pid_chars = []; + for ( var i = 0; i < page_id.length; i++ ) + pid_chars[i] = page_id.substr(i, 1); + + var page_id_cleaned = ''; + + for ( var id in pid_chars ) + { + var char = pid_chars[id]; + if ( pid_dirty[id] == 'X' ) + page_id_cleaned += char; + else + page_id_cleaned += pid_dirty[id]; + } + + return page_id_cleaned; +} + +/** + * Removes character escapes in a page ID string + * @param string Page ID string to dirty up + * @return string + */ + +function dirtify_page_id(page_id) +{ + // First, replace spaces with underscores + page_id = page_id.replace(/ /g, '_'); + + var matches = page_id.match(/\.[A-Fa-f0-9][A-Fa-f0-9]/g); + + if ( matches != null ) + { + for ( var i = 0; i < matches.length; i++ ) + { + var match = matches[i]; + var byt = (match.substr(1)).toUpperCase(); + var code = eval("0x" + byt); + var regex = new RegExp('\\.' + byt, 'g'); + page_id = page_id.replace(regex, String.fromCharCode(code)); + } + } + + return page_id; +} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/paginate.js --- a/includes/clientside/static/paginate.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/paginate.js Fri Feb 22 12:51:53 2008 -0500 @@ -68,7 +68,7 @@ function _build_paginator(this_page) { var div_styling = ( IE ) ? 'width: 1px; margin: 10px auto 10px 0;' : 'display: table; margin: 10px 0 0 auto;'; - var begin = '
'; + var begin = '
Page:
'; var block = ''; var end = '
' + $lang.get('paginate_lbl_page') + '{LINK}
'; var blk = new templateParser(block); @@ -78,7 +78,7 @@ if ( this_page > 0 ) { var url = '#page_'+(this_page); - var link = "« Prev"; + var link = "« " + $lang.get('paginate_btn_prev') + ""; cls = ( cls == 'row1' ) ? 'row2' : 'row1'; blk.assign_vars({ CLASS: cls, @@ -126,7 +126,7 @@ } } var url = '#page_1'; - var link = ( 0 == this_page ) ? "First" : "« First"; + var link = ( 0 == this_page ) ? "" + $lang.get('paginate_btn_first') + "" : "« " + $lang.get('paginate_btn_first') + ""; blk.assign_vars({ CLASS: cls, LINK: link @@ -164,7 +164,7 @@ cls = ( cls == 'row1' ) ? 'row2' : 'row1'; var url = '#page_' + String( this.num_pages-1 ); - var link = ( ( this.num_pages - 1 ) == this_page ) ? "Last" : "Last »"; + var link = ( ( this.num_pages - 1 ) == this_page ) ? "" + $lang.get('paginate_btn_last') + "" : "" + $lang.get('paginate_btn_last') + " »"; blk.assign_vars({ CLASS: cls, LINK: link @@ -177,7 +177,7 @@ if ( this_page < ( this.num_pages - 1 ) ) { var url = '#page_' + String(this_page + 2); - var link = "Next »"; + var link = "" + $lang.get('paginate_btn_next') + " »"; cls = ( cls == 'row1' ) ? 'row2' : 'row1'; blk.assign_vars({ CLASS: cls, @@ -269,10 +269,10 @@ function paginator_goto(parentobj, this_page, num_pages, perpage, url_string) { - var height = $(parentobj).Height(); - var width = $(parentobj).Width(); - var left = $(parentobj).Left(); - var top = $(parentobj).Top(); + var height = $dynano(parentobj).Height(); + var width = $dynano(parentobj).Width(); + var left = $dynano(parentobj).Left(); + var top = $dynano(parentobj).Top(); var left_pos = left + width ; var top_pos = height + top; var div = document.createElement('div'); @@ -284,14 +284,18 @@ var regex = new RegExp('\"', 'g'); var submit_target = ( typeof(url_string) == 'object' ) ? ( toJSONString(url_string) ).replace(regex, '\'') : 'unescape(\'' + escape(url_string) + '\')'; var onclick = 'paginator_submit(this, '+num_pages+', '+perpage+', '+submit_target+'); return false;'; - div.innerHTML = 'Go to page:
»×'; + div.innerHTML = $lang.get('paginate_lbl_goto_page') + '
»×'; var body = document.getElementsByTagName('body')[0]; domObjChangeOpac(0, div); body.appendChild(div); - document.getElementById(vtmp).onkeypress = function(e){if(e.keyCode==13)this.nextSibling.nextSibling.onclick();}; + document.getElementById(vtmp).onkeypress = function(e) + { + if ( e.keyCode == 13 ) + this.nextSibling.nextSibling.onclick(); + }; document.getElementById(vtmp).focus(); // fade the div @@ -303,7 +307,7 @@ fly_in_bottom(div, false, true); - var divh = $(div).Width(); + var divh = $dynano(div).Width(); left_pos = left_pos - divh; div.style.left = left_pos + 'px'; } @@ -315,7 +319,7 @@ var offset = ( userinput - 1 ) * perpage; if ( userinput > max || isNaN(userinput) || userinput < 1 ) { - new messagebox(MB_OK|MB_ICONSTOP, 'Invalid entry', 'Please enter a page number between 1 and ' + max + '.'); + new messagebox(MB_OK|MB_ICONSTOP, $lang.get('paginate_err_bad_page_title'), $lang.get('paginate_err_bad_page_body', { max: max })); return false; } if ( typeof(formatstring) == 'object' ) diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/pwstrength.js --- a/includes/clientside/static/pwstrength.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/pwstrength.js Fri Feb 22 12:51:53 2008 -0500 @@ -181,9 +181,9 @@ debug_txt += debug[i] + "\n"; } - if ( window.console ) - window.console.info(debug_txt); - else if ( document.getElementById('passdebug') ) + // For users that really want to know why their password sucks. + // Not localized because the feature is really only used for debugging the algorithm. + if ( document.getElementById('passdebug') ) document.getElementById('passdebug').innerHTML = debug_txt; return score; @@ -191,36 +191,53 @@ function password_score_draw(score) { + if ( !$lang ) + { + // $lang isn't initted yet, this happens sometimes on the usercp/emailpassword form. + // Try to init it if we have ENANO_LANG_ID and enano_lang; if not, report an error. + if ( typeof(enano_lang) == 'object' && typeof(ENANO_LANG_ID) == 'number' ) + { + language_onload(); + } + else + { + return { + color: '#000000', + fgcolor: '#666666', + str: 'Language init failed', + }; + } + } // some colors are from the Gmail sign-up form if ( score >= 10 ) { var color = '#000000'; var fgcolor = '#666666'; - var str = 'Very strong (score: '+score+')'; + var str = $lang.get('usercp_pwstrength_score_verystrong', { score: score }); } else if ( score > 3 ) { var color = '#008000'; var fgcolor = '#004000'; - var str = 'Strong (score: '+score+')'; + var str = $lang.get('usercp_pwstrength_score_strong', { score: score }); } else if ( score >= 1 ) { var color = '#6699cc'; var fgcolor = '#4477aa'; - var str = 'Good (score: '+score+')'; + var str = $lang.get('usercp_pwstrength_score_good', { score: score }); } else if ( score >= -3 ) { var color = '#f5ac00'; var fgcolor = '#ffcc33'; - var str = 'Fair (score: '+score+')'; + var str = $lang.get('usercp_pwstrength_score_fair', { score: score }); } else { var color = '#aa0033'; var fgcolor = '#FF6060'; - var str = 'Weak (score: '+score+')'; + var str = $lang.get('usercp_pwstrength_score_weak', { score: score }); } return { color: color, diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/rijndael.js --- a/includes/clientside/static/rijndael.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/rijndael.js Fri Feb 22 12:51:53 2008 -0500 @@ -577,3 +577,34 @@ return result; } +function aes_self_test() +{ + // + // Encryption test + // + + var str = ''; + for(i=0;i nor the names of its contributors may + 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. */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ +function safe_add (x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} +function S (X, n) {return ( X >>> n ) | (X << (32 - n));} +function R (X, n) {return ( X >>> n );} +function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));} +function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));} +function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));} +function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));} +function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));} +function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));} +function core_sha256 (m, l) { + var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2); + var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); + var W = new Array(64); + var a, b, c, d, e, f, g, h, i, j; + var T1, T2; + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + for ( var i = 0; i>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32); + return bin; +} +function binb2hex (binarray) { + var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i++) { + str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); + } + return str; +} +function hex_sha256(s){return binb2hex(core_sha256(str2binb(s),s.length * chrsz));} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/sliders.js --- a/includes/clientside/static/sliders.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/sliders.js Fri Feb 22 12:51:53 2008 -0500 @@ -30,6 +30,9 @@ // use cookies to toggle whether to display it or not var id = ( divs[i].parentNode.firstChild.nextSibling ) ? divs[i].parentNode.firstChild.nextSibling.firstChild : divs[i].parentNode.parentNode.firstChild.nextSibling.firstChild; + if ( !id.nextSibling ) + return; + if(id.innerHTML || id.nextSibling.length < 1) id = id.innerHTML; else id = id.nextSibling.innerHTML; // Gecko fix diff -r d823e49e2e4e -r c433348f3628 includes/clientside/static/template-compiler.js --- a/includes/clientside/static/template-compiler.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/static/template-compiler.js Fri Feb 22 12:51:53 2008 -0500 @@ -54,6 +54,7 @@ code = code.replace(new RegExp(unescape('%0A'), 'g'), '\\n'); code = "'" + code + "'"; code = code.replace(/\{([A-z0-9_-]+)\}/ig, "' + this.tpl_strings['$1'] + '"); + code = code.replace(/\{lang:([a-z0-9_]+)\}/g, "' + $lang.get('$1') + '"); code = code.replace(/\ @@ -144,14 +140,14 @@
- {$lang_advimage_swap_image} + {#advimage_dlg.swap_image} - - + + - + - - - + + + - + - - - + + +
@@ -159,12 +155,12 @@
 
@@ -172,49 +168,49 @@
 
- {$lang_advimage_misc} + {#advimage_dlg.misc} - + - + - + - + - + ' + n + ''; -} - -function renderSettings() { - var se = document.getElementById('settings'), n, sn, inst, h = '', v; - - for (n in tinyMCE.instances) { - inst = tinyMCE.instances[n]; - - if (!tinyMCE.isInstance(inst)) - continue; - - h += '

Instance id: ' + inst.editorId + '

'; - h += '
- + + +
@@ -229,11 +225,11 @@
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advimage/images/sample.gif Binary file includes/clientside/tinymce/plugins/advimage/images/sample.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advimage/img/sample.gif Binary file includes/clientside/tinymce/plugins/advimage/img/sample.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advimage/js/image.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/advimage/js/image.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,434 @@ +var ImageDialog = { + preInit : function() { + var url; + + tinyMCEPopup.requireLangPack(); + + if (url = tinyMCEPopup.getParam("external_image_list_url")) + document.write(''); + }, + + init : function(ed) { + var f = document.forms[0], nl = f.elements, ed = tinyMCEPopup.editor, dom = ed.dom, n = ed.selection.getNode(); + + tinyMCEPopup.resizeToInnerSize(); + this.fillClassList('class_list'); + this.fillFileList('src_list', 'tinyMCEImageList'); + this.fillFileList('over_list', 'tinyMCEImageList'); + this.fillFileList('out_list', 'tinyMCEImageList'); + + if (n.nodeName == 'IMG') { + nl.src.value = dom.getAttrib(n, 'src'); + nl.width.value = dom.getAttrib(n, 'width'); + nl.height.value = dom.getAttrib(n, 'height'); + nl.alt.value = dom.getAttrib(n, 'alt'); + nl.title.value = dom.getAttrib(n, 'title'); + nl.vspace.value = this.getAttrib(n, 'vspace'); + nl.hspace.value = this.getAttrib(n, 'hspace'); + nl.border.value = this.getAttrib(n, 'border'); + selectByValue(f, 'align', this.getAttrib(n, 'align')); + selectByValue(f, 'class_list', dom.getAttrib(n, 'class')); + nl.style.value = dom.getAttrib(n, 'style'); + nl.id.value = dom.getAttrib(n, 'id'); + nl.dir.value = dom.getAttrib(n, 'dir'); + nl.lang.value = dom.getAttrib(n, 'lang'); + nl.usemap.value = dom.getAttrib(n, 'usemap'); + nl.longdesc.value = dom.getAttrib(n, 'longdesc'); + nl.insert.value = ed.getLang('update'); + + if (/^\s*this.src\s*=\s*\'([^\']+)\';?\s*$/.test(dom.getAttrib(n, 'onmouseover'))) + nl.onmouseoversrc.value = dom.getAttrib(n, 'onmouseover').replace(/^\s*this.src\s*=\s*\'([^\']+)\';?\s*$/, '$1'); + + if (/^\s*this.src\s*=\s*\'([^\']+)\';?\s*$/.test(dom.getAttrib(n, 'onmouseout'))) + nl.onmouseoutsrc.value = dom.getAttrib(n, 'onmouseout').replace(/^\s*this.src\s*=\s*\'([^\']+)\';?\s*$/, '$1'); + + if (ed.settings.inline_styles) { + // Move attribs to styles + if (dom.getAttrib(n, 'align')) + this.updateStyle('align'); + + if (dom.getAttrib(n, 'hspace')) + this.updateStyle('hspace'); + + if (dom.getAttrib(n, 'border')) + this.updateStyle('border'); + + if (dom.getAttrib(n, 'vspace')) + this.updateStyle('vspace'); + } + } + + // Setup browse button + document.getElementById('srcbrowsercontainer').innerHTML = getBrowserHTML('srcbrowser','src','image','theme_advanced_image'); + if (isVisible('srcbrowser')) + document.getElementById('src').style.width = '260px'; + + // Setup browse button + document.getElementById('onmouseoversrccontainer').innerHTML = getBrowserHTML('overbrowser','onmouseoversrc','image','theme_advanced_image'); + if (isVisible('overbrowser')) + document.getElementById('onmouseoversrc').style.width = '260px'; + + // Setup browse button + document.getElementById('onmouseoutsrccontainer').innerHTML = getBrowserHTML('outbrowser','onmouseoutsrc','image','theme_advanced_image'); + if (isVisible('outbrowser')) + document.getElementById('onmouseoutsrc').style.width = '260px'; + + // If option enabled default contrain proportions to checked + if (ed.getParam("advimage_constrain_proportions", true)) + f.constrain.checked = true; + + // Check swap image if valid data + if (nl.onmouseoversrc.value || nl.onmouseoutsrc.value) + this.setSwapImage(true); + else + this.setSwapImage(false); + + this.changeAppearance(); + this.showPreviewImage(nl.src.value, 1); + }, + + insert : function(file, title) { + var ed = tinyMCEPopup.editor, t = this, f = document.forms[0]; + + if (f.src.value === '') { + ed.dom.remove(ed.selection.getNode()); + ed.execCommand('mceRepaint'); + tinyMCEPopup.close(); + return; + } + + if (tinyMCEPopup.getParam("accessibility_warnings", 1)) { + if (!f.alt.value) { + tinyMCEPopup.editor.windowManager.confirm(tinyMCEPopup.getLang('advimage_dlg.missing_alt'), function(s) { + if (s) + t.insertAndClose(); + }); + + return; + } + } + + t.insertAndClose(); + }, + + insertAndClose : function() { + var ed = tinyMCEPopup.editor, f = document.forms[0], nl = f.elements, v, args = {}, el; + + // Fixes crash in Safari + if (tinymce.isWebKit) + ed.getWin().focus(); + + if (!ed.settings.inline_styles) { + args = { + vspace : nl.vspace.value, + hspace : nl.hspace.value, + border : nl.border.value, + align : getSelectValue(f, 'align') + }; + } else { + // Remove deprecated values + args = { + vspace : '', + hspace : '', + border : '', + align : '' + }; + } + + tinymce.extend(args, { + src : nl.src.value, + width : nl.width.value, + height : nl.height.value, + alt : nl.alt.value, + title : nl.title.value, + 'class' : getSelectValue(f, 'class_list'), + style : nl.style.value, + id : nl.id.value, + dir : nl.dir.value, + lang : nl.lang.value, + usemap : nl.usemap.value, + longdesc : nl.longdesc.value + }); + + args.onmouseover = args.onmouseout = ''; + + if (f.onmousemovecheck.checked) { + if (nl.onmouseoversrc.value) + args.onmouseover = "this.src='" + nl.onmouseoversrc.value + "';"; + + if (nl.onmouseoutsrc.value) + args.onmouseout = "this.src='" + nl.onmouseoutsrc.value + "';"; + } + + el = ed.selection.getNode(); + + if (el && el.nodeName == 'IMG') { + ed.dom.setAttribs(el, args); + } else { + ed.execCommand('mceInsertContent', false, ''); + ed.dom.setAttribs('__mce_tmp', args); + ed.dom.setAttrib('__mce_tmp', 'id', ''); + } + + tinyMCEPopup.close(); + }, + + getAttrib : function(e, at) { + var ed = tinyMCEPopup.editor, dom = ed.dom, v, v2; + + if (ed.settings.inline_styles) { + switch (at) { + case 'align': + if (v = dom.getStyle(e, 'float')) + return v; + + if (v = dom.getStyle(e, 'vertical-align')) + return v; + + break; + + case 'hspace': + v = dom.getStyle(e, 'margin-left') + v2 = dom.getStyle(e, 'margin-right'); + + if (v && v == v2) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + + case 'vspace': + v = dom.getStyle(e, 'margin-top') + v2 = dom.getStyle(e, 'margin-bottom'); + if (v && v == v2) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + + case 'border': + v = 0; + + tinymce.each(['top', 'right', 'bottom', 'left'], function(sv) { + sv = dom.getStyle(e, 'border-' + sv + '-width'); + + // False or not the same as prev + if (!sv || (sv != v && v !== 0)) { + v = 0; + return false; + } + + if (sv) + v = sv; + }); + + if (v) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + } + } + + if (v = dom.getAttrib(e, at)) + return v; + + return ''; + }, + + setSwapImage : function(st) { + var f = document.forms[0]; + + f.onmousemovecheck.checked = st; + setBrowserDisabled('overbrowser', !st); + setBrowserDisabled('outbrowser', !st); + + if (f.over_list) + f.over_list.disabled = !st; + + if (f.out_list) + f.out_list.disabled = !st; + + f.onmouseoversrc.disabled = !st; + f.onmouseoutsrc.disabled = !st; + }, + + fillClassList : function(id) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + if (v = tinyMCEPopup.getParam('theme_advanced_styles')) { + cl = []; + + tinymce.each(v.split(';'), function(v) { + var p = v.split('='); + + cl.push({'title' : p[0], 'class' : p[1]}); + }); + } else + cl = tinyMCEPopup.editor.dom.getClasses(); + + if (cl.length > 0) { + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); + + tinymce.each(cl, function(o) { + lst.options[lst.options.length] = new Option(o.title || o['class'], o['class']); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + fillFileList : function(id, l) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + l = window[l]; + + if (l && l.length > 0) { + lst.options[lst.options.length] = new Option('', ''); + + tinymce.each(l, function(o) { + lst.options[lst.options.length] = new Option(o[0], o[1]); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + resetImageData : function() { + var f = document.forms[0]; + + f.elements.width.value = f.elements.height.value = ''; + }, + + updateImageData : function(img, st) { + var f = document.forms[0]; + + if (!st) { + f.elements.width.value = img.width; + f.elements.height.value = img.height; + } + + this.preloadImg = img; + }, + + changeAppearance : function() { + var ed = tinyMCEPopup.editor, f = document.forms[0], img = document.getElementById('alignSampleImg'); + + if (img) { + if (ed.getParam('inline_styles')) { + ed.dom.setAttrib(img, 'style', f.style.value); + } else { + img.align = f.align.value; + img.border = f.border.value; + img.hspace = f.hspace.value; + img.vspace = f.vspace.value; + } + } + }, + + changeHeight : function() { + var f = document.forms[0], tp, t = this; + + if (!f.constrain.checked || !t.preloadImg) { + return; + } + + if (f.width.value == "" || f.height.value == "") + return; + + tp = (parseInt(f.width.value) / parseInt(t.preloadImg.width)) * t.preloadImg.height; + f.height.value = tp.toFixed(0); + }, + + changeWidth : function() { + var f = document.forms[0], tp, t = this; + + if (!f.constrain.checked || !t.preloadImg) { + return; + } + + if (f.width.value == "" || f.height.value == "") + return; + + tp = (parseInt(f.height.value) / parseInt(t.preloadImg.height)) * t.preloadImg.width; + f.width.value = tp.toFixed(0); + }, + + updateStyle : function(ty) { + var dom = tinyMCEPopup.dom, st, v, f = document.forms[0], img = dom.create('img', {style : dom.get('style').value}); + + if (tinyMCEPopup.editor.settings.inline_styles) { + // Handle align + if (ty == 'align') { + dom.setStyle(img, 'float', ''); + dom.setStyle(img, 'vertical-align', ''); + + v = getSelectValue(f, 'align'); + if (v) { + if (v == 'left' || v == 'right') + dom.setStyle(img, 'float', v); + else + img.style.verticalAlign = v; + } + } + + // Handle border + if (ty == 'border') { + dom.setStyle(img, 'border', ''); + + v = f.border.value; + if (v || v == '0') { + if (v == '0') + img.style.border = ''; + else + img.style.border = v + 'px solid black'; + } + } + + // Handle hspace + if (ty == 'hspace') { + dom.setStyle(img, 'marginLeft', ''); + dom.setStyle(img, 'marginRight', ''); + + v = f.hspace.value; + if (v) { + img.style.marginLeft = v + 'px'; + img.style.marginRight = v + 'px'; + } + } + + // Handle vspace + if (ty == 'vspace') { + dom.setStyle(img, 'marginTop', ''); + dom.setStyle(img, 'marginBottom', ''); + + v = f.vspace.value; + if (v) { + img.style.marginTop = v + 'px'; + img.style.marginBottom = v + 'px'; + } + } + + // Merge + dom.get('style').value = dom.serializeStyle(dom.parseStyle(img.style.cssText)); + } + }, + + changeMouseMove : function() { + }, + + showPreviewImage : function(u, st) { + if (!u) { + tinyMCEPopup.dom.setHTML('prev', ''); + return; + } + + if (!st && tinyMCEPopup.getParam("advimage_update_dimensions_onchange", true)) + this.resetImageData(); + + u = tinyMCEPopup.editor.documentBaseURI.toAbsolute(u); + + if (!st) + tinyMCEPopup.dom.setHTML('prev', ''); + else + tinyMCEPopup.dom.setHTML('prev', ''); + } +}; + +ImageDialog.preInit(); +tinyMCEPopup.onInit.add(ImageDialog.init, ImageDialog); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advimage/jscripts/functions.js --- a/includes/clientside/tinymce/plugins/advimage/jscripts/functions.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,534 +0,0 @@ -/* Functions for the advimage plugin popup */ - -var preloadImg = null; -var orgImageWidth, orgImageHeight; - -function preinit() { - // Initialize - tinyMCE.setWindowArg('mce_windowresize', false); - - // Import external list url javascript - var url = tinyMCE.getParam("external_image_list_url"); - if (url != null) { - // Fix relative - if (url.charAt(0) != '/' && url.indexOf('://') == -1) - url = tinyMCE.documentBasePath + "/" + url; - - document.write(''); - } -} - -function convertURL(url, node, on_save) { - return eval("tinyMCEPopup.windowOpener." + tinyMCE.settings['urlconverter_callback'] + "(url, node, on_save);"); -} - -function getImageSrc(str) { - var pos = -1; - - if (!str) - return ""; - - if ((pos = str.indexOf('this.src=')) != -1) { - var src = str.substring(pos + 10); - - src = src.substring(0, src.indexOf('\'')); - - if (tinyMCE.getParam('convert_urls')) - src = convertURL(src, null, true); - - return src; - } - - return ""; -} - -function init() { - tinyMCEPopup.resizeToInnerSize(); - - var formObj = document.forms[0]; - var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')); - var elm = inst.getFocusElement(); - var action = "insert"; - var html = ""; - - // Image list src - html = getImageListHTML('imagelistsrc','src','onSelectMainImage'); - if (html == "") - document.getElementById("imagelistsrcrow").style.display = 'none'; - else - document.getElementById("imagelistsrccontainer").innerHTML = html; - - // Image list oversrc - html = getImageListHTML('imagelistover','onmouseoversrc'); - if (html == "") - document.getElementById("imagelistoverrow").style.display = 'none'; - else - document.getElementById("imagelistovercontainer").innerHTML = html; - - // Image list outsrc - html = getImageListHTML('imagelistout','onmouseoutsrc'); - if (html == "") - document.getElementById("imagelistoutrow").style.display = 'none'; - else - document.getElementById("imagelistoutcontainer").innerHTML = html; - - // Src browser - html = getBrowserHTML('srcbrowser','src','image','advimage'); - document.getElementById("srcbrowsercontainer").innerHTML = html; - - // Over browser - html = getBrowserHTML('oversrcbrowser','onmouseoversrc','image','advimage'); - document.getElementById("onmouseoversrccontainer").innerHTML = html; - - // Out browser - html = getBrowserHTML('outsrcbrowser','onmouseoutsrc','image','advimage'); - document.getElementById("onmouseoutsrccontainer").innerHTML = html; - - // Longdesc browser - html = getBrowserHTML('longdescbrowser','longdesc','file','advimage'); - document.getElementById("longdesccontainer").innerHTML = html; - - // Resize some elements - if (isVisible('srcbrowser')) - document.getElementById('src').style.width = '260px'; - - if (isVisible('oversrcbrowser')) - document.getElementById('onmouseoversrc').style.width = '260px'; - - if (isVisible('outsrcbrowser')) - document.getElementById('onmouseoutsrc').style.width = '260px'; - - if (isVisible('longdescbrowser')) - document.getElementById('longdesc').style.width = '180px'; - - // Check action - if (elm != null && elm.nodeName == "IMG") - action = "update"; - - formObj.insert.value = tinyMCE.getLang('lang_' + action, 'Insert', true); - - if (action == "update") { - var src = tinyMCE.getAttrib(elm, 'src'); - var onmouseoversrc = getImageSrc(tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onmouseover'))); - var onmouseoutsrc = getImageSrc(tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onmouseout'))); - - src = convertURL(src, elm, true); - - // Use mce_src if found - var mceRealSrc = tinyMCE.getAttrib(elm, 'mce_src'); - if (mceRealSrc != "") { - src = mceRealSrc; - - if (tinyMCE.getParam('convert_urls')) - src = convertURL(src, elm, true); - } - - if (onmouseoversrc != "" && tinyMCE.getParam('convert_urls')) - onmouseoversrc = convertURL(onmouseoversrc, elm, true); - - if (onmouseoutsrc != "" && tinyMCE.getParam('convert_urls')) - onmouseoutsrc = convertURL(onmouseoutsrc, elm, true); - - // Setup form data - var style = tinyMCE.parseStyle(tinyMCE.getAttrib(elm, "style")); - - // Store away old size - orgImageWidth = trimSize(getStyle(elm, 'width')) - orgImageHeight = trimSize(getStyle(elm, 'height')); - - formObj.src.value = src; - formObj.alt.value = tinyMCE.getAttrib(elm, 'alt'); - formObj.title.value = tinyMCE.getAttrib(elm, 'title'); - formObj.border.value = trimSize(getStyle(elm, 'border', 'borderWidth')); - formObj.vspace.value = tinyMCE.getAttrib(elm, 'vspace'); - formObj.hspace.value = tinyMCE.getAttrib(elm, 'hspace'); - formObj.width.value = orgImageWidth; - formObj.height.value = orgImageHeight; - formObj.onmouseoversrc.value = onmouseoversrc; - formObj.onmouseoutsrc.value = onmouseoutsrc; - formObj.id.value = tinyMCE.getAttrib(elm, 'id'); - formObj.dir.value = tinyMCE.getAttrib(elm, 'dir'); - formObj.lang.value = tinyMCE.getAttrib(elm, 'lang'); - formObj.longdesc.value = tinyMCE.getAttrib(elm, 'longdesc'); - formObj.usemap.value = tinyMCE.getAttrib(elm, 'usemap'); - formObj.style.value = tinyMCE.serializeStyle(style); - - // Select by the values - if (tinyMCE.isMSIE) - selectByValue(formObj, 'align', getStyle(elm, 'align', 'styleFloat')); - else - selectByValue(formObj, 'align', getStyle(elm, 'align', 'cssFloat')); - - addClassesToList('classlist', 'advimage_styles'); - - selectByValue(formObj, 'classlist', tinyMCE.getAttrib(elm, 'class')); - selectByValue(formObj, 'imagelistsrc', src); - selectByValue(formObj, 'imagelistover', onmouseoversrc); - selectByValue(formObj, 'imagelistout', onmouseoutsrc); - - updateStyle(); - showPreviewImage(src, true); - changeAppearance(); - - window.focus(); - } else - addClassesToList('classlist', 'advimage_styles'); - - // If option enabled default contrain proportions to checked - if (tinyMCE.getParam("advimage_constrain_proportions", true)) - formObj.constrain.checked = true; - - // Check swap image if valid data - if (formObj.onmouseoversrc.value != "" || formObj.onmouseoutsrc.value != "") - setSwapImageDisabled(false); - else - setSwapImageDisabled(true); -} - -function setSwapImageDisabled(state) { - var formObj = document.forms[0]; - - formObj.onmousemovecheck.checked = !state; - - setBrowserDisabled('overbrowser', state); - setBrowserDisabled('outbrowser', state); - - if (formObj.imagelistover) - formObj.imagelistover.disabled = state; - - if (formObj.imagelistout) - formObj.imagelistout.disabled = state; - - formObj.onmouseoversrc.disabled = state; - formObj.onmouseoutsrc.disabled = state; -} - -function setAttrib(elm, attrib, value) { - var formObj = document.forms[0]; - var valueElm = formObj.elements[attrib]; - - if (typeof(value) == "undefined" || value == null) { - value = ""; - - if (valueElm) - value = valueElm.value; - } - - if (value != "") { - elm.setAttribute(attrib, value); - - if (attrib == "style") - attrib = "style.cssText"; - - if (attrib == "longdesc") - attrib = "longDesc"; - - if (attrib == "width") { - attrib = "style.width"; - value = value + "px"; - value = value.replace(/%px/g, 'px'); - } - - if (attrib == "height") { - attrib = "style.height"; - value = value + "px"; - value = value.replace(/%px/g, 'px'); - } - - if (attrib == "class") - attrib = "className"; - - eval('elm.' + attrib + "=value;"); - } else - elm.removeAttribute(attrib); -} - -function makeAttrib(attrib, value) { - var formObj = document.forms[0]; - var valueElm = formObj.elements[attrib]; - - if (typeof(value) == "undefined" || value == null) { - value = ""; - - if (valueElm) - value = valueElm.value; - } - - if (value == "") - return ""; - - // XML encode it - value = value.replace(/&/g, '&'); - value = value.replace(/\"/g, '"'); - value = value.replace(//g, '>'); - - return ' ' + attrib + '="' + value + '"'; -} - -function insertAction() { - var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')); - var elm = inst.getFocusElement(); - var formObj = document.forms[0]; - var src = formObj.src.value; - var onmouseoversrc = formObj.onmouseoversrc.value; - var onmouseoutsrc = formObj.onmouseoutsrc.value; - - if (!AutoValidator.validate(formObj)) { - alert(tinyMCE.getLang('lang_invalid_data')); - return false; - } - - if (tinyMCE.getParam("accessibility_warnings")) { - if (formObj.alt.value == "" && !confirm(tinyMCE.getLang('lang_advimage_missing_alt', '', true))) - return; - } - - if (onmouseoversrc && onmouseoversrc != "") - onmouseoversrc = "this.src='" + convertURL(onmouseoversrc, tinyMCE.imgElement) + "';"; - - if (onmouseoutsrc && onmouseoutsrc != "") - onmouseoutsrc = "this.src='" + convertURL(onmouseoutsrc, tinyMCE.imgElement) + "';"; - - if (elm != null && elm.nodeName == "IMG") { - setAttrib(elm, 'src', convertURL(src, tinyMCE.imgElement)); - setAttrib(elm, 'mce_src', src); - setAttrib(elm, 'alt'); - setAttrib(elm, 'title'); - setAttrib(elm, 'border'); - setAttrib(elm, 'vspace'); - setAttrib(elm, 'hspace'); - setAttrib(elm, 'width'); - setAttrib(elm, 'height'); - setAttrib(elm, 'onmouseover', onmouseoversrc); - setAttrib(elm, 'onmouseout', onmouseoutsrc); - setAttrib(elm, 'id'); - setAttrib(elm, 'dir'); - setAttrib(elm, 'lang'); - setAttrib(elm, 'longdesc'); - setAttrib(elm, 'usemap'); - setAttrib(elm, 'style'); - setAttrib(elm, 'class', getSelectValue(formObj, 'classlist')); - setAttrib(elm, 'align', getSelectValue(formObj, 'align')); - - //tinyMCEPopup.execCommand("mceRepaint"); - - // Repaint if dimensions changed - if (formObj.width.value != orgImageWidth || formObj.height.value != orgImageHeight) - inst.repaint(); - - // Refresh in old MSIE - if (tinyMCE.isMSIE5) - elm.outerHTML = elm.outerHTML; - } else { - var html = "' -} - -function updateImageData() { - var formObj = document.forms[0]; - - preloadImg = document.getElementById('previewImg'); - - if (formObj.width.value == "") - formObj.width.value = preloadImg.width; - - if (formObj.height.value == "") - formObj.height.value = preloadImg.height; - - updateStyle(); -} - -function resetImageData() { - var formObj = document.forms[0]; - formObj.width.value = formObj.height.value = ""; -} - -function getSelectValue(form_obj, field_name) { - var elm = form_obj.elements[field_name]; - - if (elm == null || elm.options == null) - return ""; - - return elm.options[elm.selectedIndex].value; -} - -function getImageListHTML(elm_id, target_form_element, onchange_func) { - if (typeof(tinyMCEImageList) == "undefined" || tinyMCEImageList.length == 0) - return ""; - - var html = ""; - - html += ''; - - return html; - - // tinyMCE.debug('-- image list start --', html, '-- image list end --'); -} - -// While loading -preinit(); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advimage/langs/en.js --- a/includes/clientside/tinymce/plugins/advimage/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('advimage',{ -tab_general : 'General', -tab_appearance : 'Appearance', -tab_advanced : 'Advanced', -general : 'General', -title : 'Title', -preview : 'Preview', -constrain_proportions : 'Constrain proportions', -langdir : 'Language direction', -langcode : 'Language code', -long_desc : 'Long description link', -style : 'Style', -classes : 'Classes', -ltr : 'Left to right', -rtl : 'Right to left', -id : 'Id', -image_map : 'Image map', -swap_image : 'Swap image', -alt_image : 'Alternative image', -mouseover : 'for mouse over', -mouseout : 'for mouse out', -misc : 'Miscellaneous', -example_img : 'Appearance preview image', -missing_alt : 'Are you sure you want to continue without including an Image Description? Without it the image may not be accessible to some users with disabilities, or to those using a text browser, or browsing the Web with images turned off.' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advimage/langs/en_dlg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/advimage/langs/en_dlg.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,43 @@ +tinyMCE.addI18n('en.advimage_dlg',{ +tab_general:"General", +tab_appearance:"Appearance", +tab_advanced:"Advanced", +general:"General", +title:"Title", +preview:"Preview", +constrain_proportions:"Constrain proportions", +langdir:"Language direction", +langcode:"Language code", +long_desc:"Long description link", +style:"Style", +classes:"Classes", +ltr:"Left to right", +rtl:"Right to left", +id:"Id", +map:"Image map", +swap_image:"Swap image", +alt_image:"Alternative image", +mouseover:"for mouse over", +mouseout:"for mouse out", +misc:"Miscellaneous", +example_img:"Appearance preview image", +missing_alt:"Are you sure you want to continue without including an Image Description? Without it the image may not be accessible to some users with disabilities, or to those using a text browser, or browsing the Web with images turned off.", +dialog_title:"Insert/edit image", +src:"Image URL", +alt:"Image description", +list:"Image list", +border:"Border", +dimensions:"Dimensions", +vspace:"Vertical space", +hspace:"Horizontal space", +align:"Alignment", +align_baseline:"Baseline", +align_top:"Top", +align_middle:"Middle", +align_bottom:"Bottom", +align_texttop:"Text top", +align_textbottom:"Text bottom", +align_left:"Left", +align_right:"Right", +image_list:"Image list" +}); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advimage/readme.txt --- a/includes/clientside/tinymce/plugins/advimage/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/css/advlink.css --- a/includes/clientside/tinymce/plugins/advlink/css/advlink.css Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/advlink/css/advlink.css Fri Feb 22 12:51:53 2008 -0500 @@ -1,35 +1,8 @@ -/* CSS file for advimage plugin popup */ - -.mceLinkList, .mceAnchorList, #targetlist { - width: 280px; -} - -.mceActionPanel { - margin-top: 7px; -} - -.panel_wrapper div.current { - height: 320px; -} - -#classlist, #title, #href { - width: 280px; -} - -#popupurl, #popupname { - width: 200px; -} - -#popupwidth, #popupheight, #popupleft, #popuptop { - width: 30px; - vertical-align: middle; - text-align: center; -} - -#id, #style, #classes, #target, #dir, #hreflang, #lang, #charset, #type, #rel, #rev, #tabindex, #accesskey { - width: 200px; -} - -#events_panel input { - width: 200px; -} +.mceLinkList, .mceAnchorList, #targetlist {width:280px;} +.mceActionPanel {margin-top:7px;} +.panel_wrapper div.current {height:320px;} +#classlist, #title, #href {width:280px;} +#popupurl, #popupname {width:200px;} +#popupwidth, #popupheight, #popupleft, #popuptop {width:30px;vertical-align:middle;text-align:center;} +#id, #style, #classes, #target, #dir, #hreflang, #lang, #charset, #type, #rel, #rev, #tabindex, #accesskey {width:200px;} +#events_panel input {width:200px;} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/editor_plugin.js --- a/includes/clientside/tinymce/plugins/advlink/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/advlink/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('advlink');var TinyMCE_AdvancedLinkPlugin={getInfo:function(){return{longname:'Advanced link',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlink',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},initInstance:function(inst){inst.addShortcut('ctrl','k','lang_advlink_desc','mceAdvLink')},getControlHTML:function(cn){switch(cn){case"link":return tinyMCE.getButtonHTML(cn,'lang_link_desc','{$themeurl}/images/link.gif','mceAdvLink')}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mceAdvLink":var anySelection=false;var inst=tinyMCE.getInstanceById(editor_id);var focusElm=inst.getFocusElement();var selectedText=inst.selection.getSelectedText();if(tinyMCE.selectedElement)anySelection=(tinyMCE.selectedElement.nodeName.toLowerCase()=="img")||(selectedText&&selectedText.length>0);if(anySelection||(focusElm!=null&&focusElm.nodeName=="A")){var template=new Array();template['file']='../../plugins/advlink/link.htm';template['width']=480;template['height']=400;template['width']+=tinyMCE.getLang('lang_advlink_delta_width',0);template['height']+=tinyMCE.getLang('lang_advlink_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes"})}return true}return false},handleNodeChange:function(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){if(node==null)return;do{if(node.nodeName=="A"&&tinyMCE.getAttrib(node,'href')!=""){tinyMCE.switchClass(editor_id+'_advlink','mceButtonSelected');return true}}while((node=node.parentNode));if(any_selection){tinyMCE.switchClass(editor_id+'_advlink','mceButtonNormal');return true}tinyMCE.switchClass(editor_id+'_advlink','mceButtonDisabled');return true}};tinyMCE.addPlugin("advlink",TinyMCE_AdvancedLinkPlugin); \ No newline at end of file +(function(){tinymce.create('tinymce.plugins.AdvancedLinkPlugin',{init:function(ed,url){this.editor=ed;ed.addCommand('mceAdvLink',function(){var se=ed.selection;if(se.isCollapsed()&&!ed.dom.getParent(se.getNode(),'A'))return;ed.windowManager.open({file:url+'/link.htm',width:480+parseInt(ed.getLang('advlink.delta_width',0)),height:400+parseInt(ed.getLang('advlink.delta_height',0)),inline:1},{plugin_url:url});});ed.addButton('link',{title:'advlink.link_desc',cmd:'mceAdvLink'});ed.addShortcut('ctrl+k','advlink.advlink_desc','mceAdvLink');ed.onNodeChange.add(function(ed,cm,n,co){cm.setDisabled('link',co&&n.nodeName!='A');cm.setActive('link',n.nodeName=='A'&&!n.name);});},getInfo:function(){return{longname:'Advanced link',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlink',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('advlink',tinymce.plugins.AdvancedLinkPlugin);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/advlink/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/advlink/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,88 +1,58 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 539 2008-01-14 19:08:58Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('advlink'); +(function() { + tinymce.create('tinymce.plugins.AdvancedLinkPlugin', { + init : function(ed, url) { + this.editor = ed; -var TinyMCE_AdvancedLinkPlugin = { - getInfo : function() { - return { - longname : 'Advanced link', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlink', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, - - initInstance : function(inst) { - inst.addShortcut('ctrl', 'k', 'lang_advlink_desc', 'mceAdvLink'); - }, + // Register commands + ed.addCommand('mceAdvLink', function() { + var se = ed.selection; - getControlHTML : function(cn) { - switch (cn) { - case "link": - return tinyMCE.getButtonHTML(cn, 'lang_link_desc', '{$themeurl}/images/link.gif', 'mceAdvLink'); - } - - return ""; - }, + // No selection and not in link + if (se.isCollapsed() && !ed.dom.getParent(se.getNode(), 'A')) + return; - execCommand : function(editor_id, element, command, user_interface, value) { - switch (command) { - case "mceAdvLink": - var anySelection = false; - var inst = tinyMCE.getInstanceById(editor_id); - var focusElm = inst.getFocusElement(); - var selectedText = inst.selection.getSelectedText(); - - if (tinyMCE.selectedElement) - anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (selectedText && selectedText.length > 0); - - if (anySelection || (focusElm != null && focusElm.nodeName == "A")) { - var template = new Array(); + ed.windowManager.open({ + file : url + '/link.htm', + width : 480 + parseInt(ed.getLang('advlink.delta_width', 0)), + height : 400 + parseInt(ed.getLang('advlink.delta_height', 0)), + inline : 1 + }, { + plugin_url : url + }); + }); - template['file'] = '../../plugins/advlink/link.htm'; - template['width'] = 480; - template['height'] = 400; - - // Language specific width and height addons - template['width'] += tinyMCE.getLang('lang_advlink_delta_width', 0); - template['height'] += tinyMCE.getLang('lang_advlink_delta_height', 0); + // Register buttons + ed.addButton('link', { + title : 'advlink.link_desc', + cmd : 'mceAdvLink' + }); - tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"}); - } + ed.addShortcut('ctrl+k', 'advlink.advlink_desc', 'mceAdvLink'); - return true; - } - - return false; - }, + ed.onNodeChange.add(function(ed, cm, n, co) { + cm.setDisabled('link', co && n.nodeName != 'A'); + cm.setActive('link', n.nodeName == 'A' && !n.name); + }); + }, - handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { - if (node == null) - return; - - do { - if (node.nodeName == "A" && tinyMCE.getAttrib(node, 'href') != "") { - tinyMCE.switchClass(editor_id + '_advlink', 'mceButtonSelected'); - return true; - } - } while ((node = node.parentNode)); + getInfo : function() { + return { + longname : 'Advanced link', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlink', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); - if (any_selection) { - tinyMCE.switchClass(editor_id + '_advlink', 'mceButtonNormal'); - return true; - } - - tinyMCE.switchClass(editor_id + '_advlink', 'mceButtonDisabled'); - - return true; - } -}; - -tinyMCE.addPlugin("advlink", TinyMCE_AdvancedLinkPlugin); + // Register plugin + tinymce.PluginManager.add('advlink', tinymce.plugins.AdvancedLinkPlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/js/advlink.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/advlink/js/advlink.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,563 @@ +/* Functions for the advlink plugin popup */ + +tinyMCEPopup.requireLangPack(); + +var templates = { + "window.open" : "window.open('${url}','${target}','${options}')" +}; + +function preinit() { + var url; + + if (url = tinyMCEPopup.getParam("external_link_list_url")) + document.write(''); +} + +function changeClass() { + var formObj = document.forms[0]; + formObj.classes.value = getSelectValue(formObj, 'classlist'); +} + +function init() { + tinyMCEPopup.resizeToInnerSize(); + + var formObj = document.forms[0]; + var inst = tinyMCEPopup.editor; + var elm = inst.selection.getNode(); + var action = "insert"; + var html; + + document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser','href','file','advlink'); + document.getElementById('popupurlbrowsercontainer').innerHTML = getBrowserHTML('popupurlbrowser','popupurl','file','advlink'); + document.getElementById('linklisthrefcontainer').innerHTML = getLinkListHTML('linklisthref','href'); + document.getElementById('anchorlistcontainer').innerHTML = getAnchorListHTML('anchorlist','href'); + document.getElementById('targetlistcontainer').innerHTML = getTargetListHTML('targetlist','target'); + + // Link list + html = getLinkListHTML('linklisthref','href'); + if (html == "") + document.getElementById("linklisthrefrow").style.display = 'none'; + else + document.getElementById("linklisthrefcontainer").innerHTML = html; + + // Resize some elements + if (isVisible('hrefbrowser')) + document.getElementById('href').style.width = '260px'; + + if (isVisible('popupurlbrowser')) + document.getElementById('popupurl').style.width = '180px'; + + elm = inst.dom.getParent(elm, "A"); + if (elm != null && elm.nodeName == "A") + action = "update"; + + formObj.insert.value = tinyMCEPopup.getLang(action, 'Insert', true); + + setPopupControlsDisabled(true); + + if (action == "update") { + var href = inst.dom.getAttrib(elm, 'href'); + var onclick = inst.dom.getAttrib(elm, 'onclick'); + + // Setup form data + setFormValue('href', href); + setFormValue('title', inst.dom.getAttrib(elm, 'title')); + setFormValue('id', inst.dom.getAttrib(elm, 'id')); + setFormValue('style', inst.dom.getAttrib(elm, "style")); + setFormValue('rel', inst.dom.getAttrib(elm, 'rel')); + setFormValue('rev', inst.dom.getAttrib(elm, 'rev')); + setFormValue('charset', inst.dom.getAttrib(elm, 'charset')); + setFormValue('hreflang', inst.dom.getAttrib(elm, 'hreflang')); + setFormValue('dir', inst.dom.getAttrib(elm, 'dir')); + setFormValue('lang', inst.dom.getAttrib(elm, 'lang')); + setFormValue('tabindex', inst.dom.getAttrib(elm, 'tabindex', typeof(elm.tabindex) != "undefined" ? elm.tabindex : "")); + setFormValue('accesskey', inst.dom.getAttrib(elm, 'accesskey', typeof(elm.accesskey) != "undefined" ? elm.accesskey : "")); + setFormValue('type', inst.dom.getAttrib(elm, 'type')); + setFormValue('onfocus', inst.dom.getAttrib(elm, 'onfocus')); + setFormValue('onblur', inst.dom.getAttrib(elm, 'onblur')); + setFormValue('onclick', onclick); + setFormValue('ondblclick', inst.dom.getAttrib(elm, 'ondblclick')); + setFormValue('onmousedown', inst.dom.getAttrib(elm, 'onmousedown')); + setFormValue('onmouseup', inst.dom.getAttrib(elm, 'onmouseup')); + setFormValue('onmouseover', inst.dom.getAttrib(elm, 'onmouseover')); + setFormValue('onmousemove', inst.dom.getAttrib(elm, 'onmousemove')); + setFormValue('onmouseout', inst.dom.getAttrib(elm, 'onmouseout')); + setFormValue('onkeypress', inst.dom.getAttrib(elm, 'onkeypress')); + setFormValue('onkeydown', inst.dom.getAttrib(elm, 'onkeydown')); + setFormValue('onkeyup', inst.dom.getAttrib(elm, 'onkeyup')); + setFormValue('target', inst.dom.getAttrib(elm, 'target')); + setFormValue('classes', inst.dom.getAttrib(elm, 'class')); + + // Parse onclick data + if (onclick != null && onclick.indexOf('window.open') != -1) + parseWindowOpen(onclick); + else + parseFunction(onclick); + + // Select by the values + selectByValue(formObj, 'dir', inst.dom.getAttrib(elm, 'dir')); + selectByValue(formObj, 'rel', inst.dom.getAttrib(elm, 'rel')); + selectByValue(formObj, 'rev', inst.dom.getAttrib(elm, 'rev')); + selectByValue(formObj, 'linklisthref', href); + + if (href.charAt(0) == '#') + selectByValue(formObj, 'anchorlist', href); + + addClassesToList('classlist', 'advlink_styles'); + + selectByValue(formObj, 'classlist', inst.dom.getAttrib(elm, 'class'), true); + selectByValue(formObj, 'targetlist', inst.dom.getAttrib(elm, 'target'), true); + } else + addClassesToList('classlist', 'advlink_styles'); + + window.focus(); +} + +function checkPrefix(n) { + if (n.value && Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advlink_dlg.is_email'))) + n.value = 'mailto:' + n.value; + + if (/^\s*www./i.test(n.value) && confirm(tinyMCEPopup.getLang('advlink_dlg.is_external'))) + n.value = 'http://' + n.value; +} + +function setFormValue(name, value) { + document.forms[0].elements[name].value = value; +} + +function parseWindowOpen(onclick) { + var formObj = document.forms[0]; + + // Preprocess center code + if (onclick.indexOf('return false;') != -1) { + formObj.popupreturn.checked = true; + onclick = onclick.replace('return false;', ''); + } else + formObj.popupreturn.checked = false; + + var onClickData = parseLink(onclick); + + if (onClickData != null) { + formObj.ispopup.checked = true; + setPopupControlsDisabled(false); + + var onClickWindowOptions = parseOptions(onClickData['options']); + var url = onClickData['url']; + + formObj.popupname.value = onClickData['target']; + formObj.popupurl.value = url; + formObj.popupwidth.value = getOption(onClickWindowOptions, 'width'); + formObj.popupheight.value = getOption(onClickWindowOptions, 'height'); + + formObj.popupleft.value = getOption(onClickWindowOptions, 'left'); + formObj.popuptop.value = getOption(onClickWindowOptions, 'top'); + + if (formObj.popupleft.value.indexOf('screen') != -1) + formObj.popupleft.value = "c"; + + if (formObj.popuptop.value.indexOf('screen') != -1) + formObj.popuptop.value = "c"; + + formObj.popuplocation.checked = getOption(onClickWindowOptions, 'location') == "yes"; + formObj.popupscrollbars.checked = getOption(onClickWindowOptions, 'scrollbars') == "yes"; + formObj.popupmenubar.checked = getOption(onClickWindowOptions, 'menubar') == "yes"; + formObj.popupresizable.checked = getOption(onClickWindowOptions, 'resizable') == "yes"; + formObj.popuptoolbar.checked = getOption(onClickWindowOptions, 'toolbar') == "yes"; + formObj.popupstatus.checked = getOption(onClickWindowOptions, 'status') == "yes"; + formObj.popupdependent.checked = getOption(onClickWindowOptions, 'dependent') == "yes"; + + buildOnClick(); + } +} + +function parseFunction(onclick) { + var formObj = document.forms[0]; + var onClickData = parseLink(onclick); + + // TODO: Add stuff here +} + +function getOption(opts, name) { + return typeof(opts[name]) == "undefined" ? "" : opts[name]; +} + +function setPopupControlsDisabled(state) { + var formObj = document.forms[0]; + + formObj.popupname.disabled = state; + formObj.popupurl.disabled = state; + formObj.popupwidth.disabled = state; + formObj.popupheight.disabled = state; + formObj.popupleft.disabled = state; + formObj.popuptop.disabled = state; + formObj.popuplocation.disabled = state; + formObj.popupscrollbars.disabled = state; + formObj.popupmenubar.disabled = state; + formObj.popupresizable.disabled = state; + formObj.popuptoolbar.disabled = state; + formObj.popupstatus.disabled = state; + formObj.popupreturn.disabled = state; + formObj.popupdependent.disabled = state; + + setBrowserDisabled('popupurlbrowser', state); +} + +function parseLink(link) { + link = link.replace(new RegExp(''', 'g'), "'"); + + var fnName = link.replace(new RegExp("\\s*([A-Za-z0-9\.]*)\\s*\\(.*", "gi"), "$1"); + + // Is function name a template function + var template = templates[fnName]; + if (template) { + // Build regexp + var variableNames = template.match(new RegExp("'?\\$\\{[A-Za-z0-9\.]*\\}'?", "gi")); + var regExp = "\\s*[A-Za-z0-9\.]*\\s*\\("; + var replaceStr = ""; + for (var i=0; i'); + for (var i=0; i'; + html += ''; + + for (i=0; i' + name + ''; + } + + html += ''; + + return html; +} + +function insertAction() { + var inst = tinyMCEPopup.editor; + var elm, elementArray, i; + + elm = inst.selection.getNode(); + checkPrefix(document.forms[0].href); + + elm = inst.dom.getParent(elm, "A"); + + // Remove element if there is no href + if (!document.forms[0].href.value) { + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + i = inst.selection.getBookmark(); + inst.dom.remove(elm, 1); + inst.selection.moveToBookmark(i); + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); + return; + } + + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + + // Create new anchor elements + if (elm == null) { + tinyMCEPopup.execCommand("CreateLink", false, "#mce_temp_url#"); + + elementArray = tinymce.grep(inst.dom.select("a"), function(n) {return inst.dom.getAttrib(n, 'href') == '#mce_temp_url#';}); + for (i=0; i' + tinyMCELinkList[i][0] + ''; + + html += ''; + + return html; + + // tinyMCE.debug('-- image list start --', html, '-- image list end --'); +} + +function getTargetListHTML(elm_id, target_form_element) { + var targets = tinyMCEPopup.getParam('theme_advanced_link_targets', '').split(';'); + var html = ''; + + html += ''; + + return html; +} + +// While loading +preinit(); +tinyMCEPopup.onInit.add(init); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/jscripts/functions.js --- a/includes/clientside/tinymce/plugins/advlink/jscripts/functions.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,568 +0,0 @@ -/* Functions for the advlink plugin popup */ - -var templates = { - "window.open" : "window.open('${url}','${target}','${options}')" -}; - -function preinit() { - // Initialize - tinyMCE.setWindowArg('mce_windowresize', false); - - // Import external list url javascript - var url = tinyMCE.getParam("external_link_list_url"); - if (url != null) { - // Fix relative - if (url.charAt(0) != '/' && url.indexOf('://') == -1) - url = tinyMCE.documentBasePath + "/" + url; - - document.write(''); - } -} - -function changeClass() { - var formObj = document.forms[0]; - formObj.classes.value = getSelectValue(formObj, 'classlist'); -} - -function init() { - tinyMCEPopup.resizeToInnerSize(); - - var formObj = document.forms[0]; - var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')); - var elm = inst.getFocusElement(); - var action = "insert"; - var html; - - document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser','href','file','advlink'); - document.getElementById('popupurlbrowsercontainer').innerHTML = getBrowserHTML('popupurlbrowser','popupurl','file','advlink'); - document.getElementById('linklisthrefcontainer').innerHTML = getLinkListHTML('linklisthref','href'); - document.getElementById('anchorlistcontainer').innerHTML = getAnchorListHTML('anchorlist','href'); - document.getElementById('targetlistcontainer').innerHTML = getTargetListHTML('targetlist','target'); - - // Link list - html = getLinkListHTML('linklisthref','href'); - if (html == "") - document.getElementById("linklisthrefrow").style.display = 'none'; - else - document.getElementById("linklisthrefcontainer").innerHTML = html; - - // Resize some elements - if (isVisible('hrefbrowser')) - document.getElementById('href').style.width = '260px'; - - if (isVisible('popupurlbrowser')) - document.getElementById('popupurl').style.width = '180px'; - - elm = tinyMCE.getParentElement(elm, "a"); - if (elm != null && elm.nodeName == "A") - action = "update"; - - formObj.insert.value = tinyMCE.getLang('lang_' + action, 'Insert', true); - - setPopupControlsDisabled(true); - - if (action == "update") { - var href = tinyMCE.getAttrib(elm, 'href'); - - href = convertURL(href, elm, true); - - // Use mce_href if found - var mceRealHref = tinyMCE.getAttrib(elm, 'mce_href'); - if (mceRealHref != "") { - href = mceRealHref; - - if (tinyMCE.getParam('convert_urls')) - href = convertURL(href, elm, true); - } - - var onclick = tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onclick')); - - // Setup form data - setFormValue('href', href); - setFormValue('title', tinyMCE.getAttrib(elm, 'title')); - setFormValue('id', tinyMCE.getAttrib(elm, 'id')); - setFormValue('style', tinyMCE.serializeStyle(tinyMCE.parseStyle(tinyMCE.getAttrib(elm, "style")))); - setFormValue('rel', tinyMCE.getAttrib(elm, 'rel')); - setFormValue('rev', tinyMCE.getAttrib(elm, 'rev')); - setFormValue('charset', tinyMCE.getAttrib(elm, 'charset')); - setFormValue('hreflang', tinyMCE.getAttrib(elm, 'hreflang')); - setFormValue('dir', tinyMCE.getAttrib(elm, 'dir')); - setFormValue('lang', tinyMCE.getAttrib(elm, 'lang')); - setFormValue('tabindex', tinyMCE.getAttrib(elm, 'tabindex', typeof(elm.tabindex) != "undefined" ? elm.tabindex : "")); - setFormValue('accesskey', tinyMCE.getAttrib(elm, 'accesskey', typeof(elm.accesskey) != "undefined" ? elm.accesskey : "")); - setFormValue('type', tinyMCE.getAttrib(elm, 'type')); - setFormValue('onfocus', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onfocus'))); - setFormValue('onblur', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onblur'))); - setFormValue('onclick', onclick); - setFormValue('ondblclick', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'ondblclick'))); - setFormValue('onmousedown', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onmousedown'))); - setFormValue('onmouseup', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onmouseup'))); - setFormValue('onmouseover', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onmouseover'))); - setFormValue('onmousemove', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onmousemove'))); - setFormValue('onmouseout', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onmouseout'))); - setFormValue('onkeypress', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onkeypress'))); - setFormValue('onkeydown', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onkeydown'))); - setFormValue('onkeyup', tinyMCE.cleanupEventStr(tinyMCE.getAttrib(elm, 'onkeyup'))); - setFormValue('target', tinyMCE.getAttrib(elm, 'target')); - setFormValue('classes', tinyMCE.getAttrib(elm, 'class')); - - // Parse onclick data - if (onclick != null && onclick.indexOf('window.open') != -1) - parseWindowOpen(onclick); - else - parseFunction(onclick); - - // Select by the values - selectByValue(formObj, 'dir', tinyMCE.getAttrib(elm, 'dir')); - selectByValue(formObj, 'rel', tinyMCE.getAttrib(elm, 'rel')); - selectByValue(formObj, 'rev', tinyMCE.getAttrib(elm, 'rev')); - selectByValue(formObj, 'linklisthref', href); - - if (href.charAt(0) == '#') - selectByValue(formObj, 'anchorlist', href); - - addClassesToList('classlist', 'advlink_styles'); - - selectByValue(formObj, 'classlist', tinyMCE.getAttrib(elm, 'class'), true); - selectByValue(formObj, 'targetlist', tinyMCE.getAttrib(elm, 'target'), true); - } else - addClassesToList('classlist', 'advlink_styles'); - - window.focus(); -} - -function setFormValue(name, value) { - document.forms[0].elements[name].value = value; -} - -function convertURL(url, node, on_save) { - return eval("tinyMCEPopup.windowOpener." + tinyMCE.settings['urlconverter_callback'] + "(url, node, on_save);"); -} - -function parseWindowOpen(onclick) { - var formObj = document.forms[0]; - - // Preprocess center code - if (onclick.indexOf('return false;') != -1) { - formObj.popupreturn.checked = true; - onclick = onclick.replace('return false;', ''); - } else - formObj.popupreturn.checked = false; - - var onClickData = parseLink(onclick); - - if (onClickData != null) { - formObj.ispopup.checked = true; - setPopupControlsDisabled(false); - - var onClickWindowOptions = parseOptions(onClickData['options']); - var url = onClickData['url']; - - if (tinyMCE.getParam('convert_urls')) - url = convertURL(url, null, true); - - formObj.popupname.value = onClickData['target']; - formObj.popupurl.value = url; - formObj.popupwidth.value = getOption(onClickWindowOptions, 'width'); - formObj.popupheight.value = getOption(onClickWindowOptions, 'height'); - - formObj.popupleft.value = getOption(onClickWindowOptions, 'left'); - formObj.popuptop.value = getOption(onClickWindowOptions, 'top'); - - if (formObj.popupleft.value.indexOf('screen') != -1) - formObj.popupleft.value = "c"; - - if (formObj.popuptop.value.indexOf('screen') != -1) - formObj.popuptop.value = "c"; - - formObj.popuplocation.checked = getOption(onClickWindowOptions, 'location') == "yes"; - formObj.popupscrollbars.checked = getOption(onClickWindowOptions, 'scrollbars') == "yes"; - formObj.popupmenubar.checked = getOption(onClickWindowOptions, 'menubar') == "yes"; - formObj.popupresizable.checked = getOption(onClickWindowOptions, 'resizable') == "yes"; - formObj.popuptoolbar.checked = getOption(onClickWindowOptions, 'toolbar') == "yes"; - formObj.popupstatus.checked = getOption(onClickWindowOptions, 'status') == "yes"; - formObj.popupdependent.checked = getOption(onClickWindowOptions, 'dependent') == "yes"; - - buildOnClick(); - } -} - -function parseFunction(onclick) { - var formObj = document.forms[0]; - var onClickData = parseLink(onclick); - - // TODO: Add stuff here -} - -function getOption(opts, name) { - return typeof(opts[name]) == "undefined" ? "" : opts[name]; -} - -function setPopupControlsDisabled(state) { - var formObj = document.forms[0]; - - formObj.popupname.disabled = state; - formObj.popupurl.disabled = state; - formObj.popupwidth.disabled = state; - formObj.popupheight.disabled = state; - formObj.popupleft.disabled = state; - formObj.popuptop.disabled = state; - formObj.popuplocation.disabled = state; - formObj.popupscrollbars.disabled = state; - formObj.popupmenubar.disabled = state; - formObj.popupresizable.disabled = state; - formObj.popuptoolbar.disabled = state; - formObj.popupstatus.disabled = state; - formObj.popupreturn.disabled = state; - formObj.popupdependent.disabled = state; - - setBrowserDisabled('popupurlbrowser', state); -} - -function parseLink(link) { - link = link.replace(new RegExp(''', 'g'), "'"); - - var fnName = link.replace(new RegExp("\\s*([A-Za-z0-9\.]*)\\s*\\(.*", "gi"), "$1"); - - // Is function name a template function - var template = templates[fnName]; - if (template) { - // Build regexp - var variableNames = template.match(new RegExp("'?\\$\\{[A-Za-z0-9\.]*\\}'?", "gi")); - var regExp = "\\s*[A-Za-z0-9\.]*\\s*\\("; - var replaceStr = ""; - for (var i=0; i'); - for (var i=0; i'; - html += ''; - - for (var i=0; i' + name + ''; - } - - html += ''; - - return html; -} - -function insertAction() { - var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')); - var elm = inst.getFocusElement(); - - elm = tinyMCE.getParentElement(elm, "a"); - - tinyMCEPopup.execCommand("mceBeginUndoLevel"); - - // Create new anchor elements - if (elm == null) { - if (tinyMCE.isSafari) - tinyMCEPopup.execCommand("mceInsertContent", false, '' + inst.selection.getSelectedHTML() + ''); - else - tinyMCEPopup.execCommand("createlink", false, "#mce_temp_url#"); - - var elementArray = tinyMCE.getElementsByAttributeValue(inst.getBody(), "a", "href", "#mce_temp_url#"); - for (var i=0; i' + tinyMCELinkList[i][0] + ''; - - html += ''; - - return html; - - // tinyMCE.debug('-- image list start --', html, '-- image list end --'); -} - -function getTargetListHTML(elm_id, target_form_element) { - var targets = tinyMCE.getParam('theme_advanced_link_targets', '').split(';'); - var html = ''; - - html += ''; - - return html; -} - -// While loading -preinit(); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/langs/en.js --- a/includes/clientside/tinymce/plugins/advlink/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('advlink',{ -general_tab : 'General', -popup_tab : 'Popup', -events_tab : 'Events', -advanced_tab : 'Advanced', -general_props : 'General properties', -popup_props : 'Popup properties', -event_props : 'Events', -advanced_props : 'Advanced properties', -popup_opts : 'Options', -anchor_names : 'Anchors', -target_same : 'Open in this window / frame', -target_parent : 'Open in parent window / frame', -target_top : 'Open in top frame (replaces all frames)', -target_blank : 'Open in new window', -popup : 'Javascript popup', -popup_url : 'Popup URL', -popup_name : 'Window name', -popup_return : 'Insert \'return false\'', -popup_scrollbars : 'Show scrollbars', -popup_statusbar : 'Show status bar', -popup_toolbar : 'Show toolbars', -popup_menubar : 'Show menu bar', -popup_location : 'Show location bar', -popup_resizable : 'Make window resizable', -popup_dependent : 'Dependent (Mozilla/Firefox only)', -popup_size : 'Size', -popup_position : 'Position (X/Y)', -id : 'Id', -style: 'Style', -classes : 'Classes', -target_name : 'Target name', -langdir : 'Language direction', -target_langcode : 'Target language', -langcode : 'Language code', -encoding : 'Target character encoding', -mime : 'Target MIME type', -rel : 'Relationship page to target', -rev : 'Relationship target to page', -tabindex : 'Tabindex', -accesskey : 'Accesskey', -ltr : 'Left to right', -rtl : 'Right to left' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/langs/en_dlg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/advlink/langs/en_dlg.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,52 @@ +tinyMCE.addI18n('en.advlink_dlg',{ +title:"Insert/edit link", +url:"Link URL", +target:"Target", +titlefield:"Title", +is_email:"The URL you entered seems to be an email address, do you want to add the required mailto: prefix?", +is_external:"The URL you entered seems to external link, do you want to add the required http:// prefix?", +list:"Link list", +general_tab:"General", +popup_tab:"Popup", +events_tab:"Events", +advanced_tab:"Advanced", +general_props:"General properties", +popup_props:"Popup properties", +event_props:"Events", +advanced_props:"Advanced properties", +popup_opts:"Options", +anchor_names:"Anchors", +target_same:"Open in this window / frame", +target_parent:"Open in parent window / frame", +target_top:"Open in top frame (replaces all frames)", +target_blank:"Open in new window", +popup:"Javascript popup", +popup_url:"Popup URL", +popup_name:"Window name", +popup_return:"Insert 'return false'", +popup_scrollbars:"Show scrollbars", +popup_statusbar:"Show status bar", +popup_toolbar:"Show toolbars", +popup_menubar:"Show menu bar", +popup_location:"Show location bar", +popup_resizable:"Make window resizable", +popup_dependent:"Dependent (Mozilla/Firefox only)", +popup_size:"Size", +popup_position:"Position (X/Y)", +id:"Id", +style:"Style", +classes:"Classes", +target_name:"Target name", +langdir:"Language direction", +target_langcode:"Target language", +langcode:"Language code", +encoding:"Target character encoding", +mime:"Target MIME type", +rel:"Relationship page to target", +rev:"Relationship target to page", +tabindex:"Tabindex", +accesskey:"Accesskey", +ltr:"Left to right", +rtl:"Right to left", +link_list:"Link list" +}); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/link.htm --- a/includes/clientside/tinymce/plugins/advlink/link.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/advlink/link.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,32 +1,34 @@ + - {$lang_insert_link_title} - - - - + {#advlink_dlg.title} + + + + + - +
- {$lang_advlink_general_props} + {#advlink_dlg.general_props}
- + - + - + - + - + - + @@ -64,14 +66,14 @@
@@ -35,26 +37,26 @@
 
 
 
- + '; - }, + 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'}); - addItem : function(icon, title, command, value, disabled) { - if (title.charAt(0) == '$') - title = tinyMCE.getLang(title.substring(1)); - - var onMouseDown = ''; - var html = ''; - - if (tinyMCE.isMSIE && !tinyMCE.isMSIE5_0) - onMouseDown = 'contextMenu.execCommand(\'' + command + '\', \'' + value + '\');return false;'; - else - onMouseDown = this.settings['commandhandler'] + '(\'' + command + '\', \'' + value + '\');return false;'; - - if (icon == "") - icon = this.settings['spacer_image']; - - if (!disabled) - html += ''; - else - html += ''; + 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'}); + } - html += ''; - html += ''; - html += ''; - - // Add to main - this.html += html; - }, - - show : function(x, y) { - var vp, width, height, yo; - - if (this.html == "") - return; - - var html = ''; + m.addSeparator(); + m.add({title : 'advanced.image_desc', icon : 'image', cmd : ed.plugins.advimage ? 'mceAdvImage' : 'mceImage', ui : true}); - html += '
   @@ -82,18 +84,18 @@ - + - + - +
  
   x px
   / (c /c = center) @@ -102,32 +104,32 @@
- {$lang_advlink_popup_opts} + {#advlink_dlg.popup_opts} - + - + - + - + - + - + - + - +
@@ -136,66 +138,66 @@
- {$lang_advlink_advanced_props} + {#advlink_dlg.advanced_props} - + - + - + - + - + - + - + - + - + - + - + - + - +
@@ -256,7 +258,7 @@
- {$lang_advlink_event_props} + {#advlink_dlg.event_props} @@ -325,11 +327,11 @@
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/advlink/readme.txt --- a/includes/clientside/tinymce/plugins/advlink/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/autosave/editor_plugin.js --- a/includes/clientside/tinymce/plugins/autosave/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/autosave/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('autosave');var TinyMCE_AutoSavePlugin={getInfo:function(){return{longname:'Auto save',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},_beforeUnloadHandler:function(){var n,inst,anyDirty=false,msg=tinyMCE.getLang("lang_autosave_unload_msg");if(tinyMCE.getParam("fullscreen_is_enabled"))return;for(n in tinyMCE.instances){inst=tinyMCE.instances[n];if(!tinyMCE.isInstance(inst))continue;if(inst.isDirty())return msg}return}};window.onbeforeunload=TinyMCE_AutoSavePlugin._beforeUnloadHandler;tinyMCE.addPlugin("autosave",TinyMCE_AutoSavePlugin); \ No newline at end of file +(function(){tinymce.create('tinymce.plugins.AutoSavePlugin',{init:function(ed,url){var t=this;t.editor=ed;window.onbeforeunload=tinymce.plugins.AutoSavePlugin._beforeUnloadHandler;},getInfo:function(){return{longname:'Auto save',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave',version:tinymce.majorVersion+"."+tinymce.minorVersion};},'static':{_beforeUnloadHandler:function(){var msg;tinymce.each(tinyMCE.editors,function(ed){if(ed.getParam("fullscreen_is_enabled"))return;if(ed.isDirty()){msg=ed.getLang("autosave.unload_msg");return false;}});return msg;}}});tinymce.PluginManager.add('autosave',tinymce.plugins.AutoSavePlugin);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/autosave/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/autosave/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/autosave/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,46 +1,51 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('autosave'); +(function() { + tinymce.create('tinymce.plugins.AutoSavePlugin', { + init : function(ed, url) { + var t = this; + + t.editor = ed; + + window.onbeforeunload = tinymce.plugins.AutoSavePlugin._beforeUnloadHandler; + }, -var TinyMCE_AutoSavePlugin = { - getInfo : function() { - return { - longname : 'Auto save', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, + getInfo : function() { + return { + longname : 'Auto save', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + }, - // Private plugin internal methods - - _beforeUnloadHandler : function() { - var n, inst, anyDirty = false, msg = tinyMCE.getLang("lang_autosave_unload_msg"); + // Private plugin internal methods - if (tinyMCE.getParam("fullscreen_is_enabled")) - return; + 'static' : { + _beforeUnloadHandler : function() { + var msg; - for (n in tinyMCE.instances) { - inst = tinyMCE.instances[n]; - - if (!tinyMCE.isInstance(inst)) - continue; + tinymce.each(tinyMCE.editors, function(ed) { + if (ed.getParam("fullscreen_is_enabled")) + return; - if (inst.isDirty()) - return msg; - } + if (ed.isDirty()) { + msg = ed.getLang("autosave.unload_msg"); + return false; + } + }); - return; - } -}; + return msg; + } + } + }); -window.onbeforeunload = TinyMCE_AutoSavePlugin._beforeUnloadHandler; - -tinyMCE.addPlugin("autosave", TinyMCE_AutoSavePlugin); + // Register plugin + tinymce.PluginManager.add('autosave', tinymce.plugins.AutoSavePlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/autosave/langs/en.js --- a/includes/clientside/tinymce/plugins/autosave/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -// EN lang variables - -tinyMCE.addToLang('',{ -autosave_unload_msg : 'The changes you made will be lost if you navigate away from this page.' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/autosave/readme.txt --- a/includes/clientside/tinymce/plugins/autosave/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/bbcode/editor_plugin.js --- a/includes/clientside/tinymce/plugins/bbcode/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/bbcode/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -var TinyMCE_BBCodePlugin={getInfo:function(){return{longname:'BBCode Plugin',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},cleanup:function(type,content){var dialect=tinyMCE.getParam('bbcode_dialect','punbb').toLowerCase();switch(type){case"insert_to_editor":content=this['_'+dialect+'_bbcode2html'](content);break;case"get_from_editor":content=this['_'+dialect+'_html2bbcode'](content);break}return content},_punbb_html2bbcode:function(s){s=tinyMCE.trim(s);function rep(re,str){s=s.replace(re,str)};rep(/(.*?)<\/a>/gi,"[url]$1[/url]");rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");rep(/(.*?)<\/font>/gi,"[color=$1]$2[/color]");rep(/(.*?)<\/font>/gi,"$1");rep(//gi,"[img]$1[/img]");rep(/(.*?)<\/span>/gi,"[code]$1[/code]");rep(/(.*?)<\/span>/gi,"[quote]$1[/quote]");rep(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]");rep(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]");rep(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]");rep(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]");rep(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]");rep(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]");rep(/<\/(strong|b)>/gi,"[/b]");rep(/<(strong|b)>/gi,"[b]");rep(/<\/(em|i)>/gi,"[/i]");rep(/<(em|i)>/gi,"[i]");rep(/<\/u>/gi,"[/u]");rep(//gi,"[u]");rep(/
/gi,"\n");rep(//gi,"\n");rep(/
/gi,"\n");rep(/

/gi,"");rep(/<\/p>/gi,"\n");rep(/ /gi," ");rep(/"/gi,"\"");rep(/</gi,"<");rep(/>/gi,">");rep(/&/gi,"&");rep(/&undefined;/gi,"'");return s},_punbb_bbcode2html:function(s){s=tinyMCE.trim(s);function rep(re,str){s=s.replace(re,str)};rep(/\n/gi,"
");rep(/\[b\]/gi,"");rep(/\[\/b\]/gi,"");rep(/\[i\]/gi,"");rep(/\[\/i\]/gi,"");rep(/\[u\]/gi,"");rep(/\[\/u\]/gi,"");rep(/\[url\](.*?)\[\/url\]/gi,"
$1");rep(/\[img\](.*?)\[\/img\]/gi,"");rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"$2");rep(/\[code\](.*?)\[\/code\]/gi,"$1 ");rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"$1 ");return s}};tinyMCE.addPlugin("bbcode",TinyMCE_BBCodePlugin); \ No newline at end of file +(function(){tinymce.create('tinymce.plugins.BBCodePlugin',{init:function(ed,url){var t=this,dialect=ed.getParam('bbcode_dialect','punbb').toLowerCase();ed.onBeforeSetContent.add(function(ed,o){o.content=t['_'+dialect+'_bbcode2html'](o.content);});ed.onPostProcess.add(function(ed,o){if(o.set)o.content=t['_'+dialect+'_bbcode2html'](o.content);if(o.get)o.content=t['_'+dialect+'_html2bbcode'](o.content);});},getInfo:function(){return{longname:'BBCode Plugin',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_punbb_html2bbcode:function(s){s=tinymce.trim(s);function rep(re,str){s=s.replace(re,str);};rep(/(.*?)<\/a>/gi,"[url=$1]$2[/url]");rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]");rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]");rep(/(.*?)<\/span>/gi,"[color=$1]$2[/color]");rep(/(.*?)<\/font>/gi,"[color=$1]$2[/color]");rep(/(.*?)<\/span>/gi,"[size=$1]$2[/size]");rep(/(.*?)<\/font>/gi,"$1");rep(//gi,"[img]$1[/img]");rep(/(.*?)<\/span>/gi,"[code]$1[/code]");rep(/(.*?)<\/span>/gi,"[quote]$1[/quote]");rep(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]");rep(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]");rep(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]");rep(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]");rep(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]");rep(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]");rep(/<\/(strong|b)>/gi,"[/b]");rep(/<(strong|b)>/gi,"[b]");rep(/<\/(em|i)>/gi,"[/i]");rep(/<(em|i)>/gi,"[i]");rep(/<\/u>/gi,"[/u]");rep(/(.*?)<\/span>/gi,"[u]$1[/u]");rep(//gi,"[u]");rep(/
/gi,"\n");rep(//gi,"\n");rep(/
/gi,"\n");rep(/

/gi,"");rep(/<\/p>/gi,"\n");rep(/ /gi," ");rep(/"/gi,"\"");rep(/</gi,"<");rep(/>/gi,">");rep(/&/gi,"&");return s;},_punbb_bbcode2html:function(s){s=tinymce.trim(s);function rep(re,str){s=s.replace(re,str);};rep(/\n/gi,"
");rep(/\[b\]/gi,"");rep(/\[\/b\]/gi,"");rep(/\[i\]/gi,"");rep(/\[\/i\]/gi,"");rep(/\[u\]/gi,"");rep(/\[\/u\]/gi,"");rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,"$2");rep(/\[url\](.*?)\[\/url\]/gi,"$1");rep(/\[img\](.*?)\[\/img\]/gi,"");rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"$2");rep(/\[code\](.*?)\[\/code\]/gi,"$1 ");rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"$1 ");return s;}});tinymce.PluginManager.add('bbcode',tinymce.plugins.BBCodePlugin);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/bbcode/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/bbcode/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/bbcode/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,102 +1,115 @@ -var TinyMCE_BBCodePlugin = { - getInfo : function() { - return { - longname : 'BBCode Plugin', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, +/** + * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * + * @author Moxiecode + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ - cleanup : function(type, content) { - var dialect = tinyMCE.getParam('bbcode_dialect', 'punbb').toLowerCase(); +(function() { + tinymce.create('tinymce.plugins.BBCodePlugin', { + init : function(ed, url) { + var t = this, dialect = ed.getParam('bbcode_dialect', 'punbb').toLowerCase(); + + ed.onBeforeSetContent.add(function(ed, o) { + o.content = t['_' + dialect + '_bbcode2html'](o.content); + }); + + ed.onPostProcess.add(function(ed, o) { + if (o.set) + o.content = t['_' + dialect + '_bbcode2html'](o.content); - switch (type) { - case "insert_to_editor": - content = this['_' + dialect + '_bbcode2html'](content); - break; - - case "get_from_editor": - content = this['_' + dialect + '_html2bbcode'](content); - break; - } + if (o.get) + o.content = t['_' + dialect + '_html2bbcode'](o.content); + }); + }, - return content; - }, - - // Private methods + getInfo : function() { + return { + longname : 'BBCode Plugin', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + }, - // HTML -> BBCode in PunBB dialect - _punbb_html2bbcode : function(s) { - s = tinyMCE.trim(s); + // Private methods - function rep(re, str) { - s = s.replace(re, str); - }; + // HTML -> BBCode in PunBB dialect + _punbb_html2bbcode : function(s) { + s = tinymce.trim(s); + + function rep(re, str) { + s = s.replace(re, str); + }; - // example: to [b] - rep(/(.*?)<\/a>/gi,"[url]$1[/url]"); - rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"); - rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"); - rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"); - rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"); - rep(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"); - rep(/(.*?)<\/font>/gi,"$1"); - rep(//gi,"[img]$1[/img]"); - rep(/(.*?)<\/span>/gi,"[code]$1[/code]"); - rep(/(.*?)<\/span>/gi,"[quote]$1[/quote]"); - rep(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"); - rep(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"); - rep(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"); - rep(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"); - rep(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"); - rep(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"); - rep(/<\/(strong|b)>/gi,"[/b]"); - rep(/<(strong|b)>/gi,"[b]"); - rep(/<\/(em|i)>/gi,"[/i]"); - rep(/<(em|i)>/gi,"[i]"); - rep(/<\/u>/gi,"[/u]"); - rep(//gi,"[u]"); - rep(/
/gi,"\n"); - rep(//gi,"\n"); - rep(/
/gi,"\n"); - rep(/

/gi,""); - rep(/<\/p>/gi,"\n"); - rep(/ /gi," "); - rep(/"/gi,"\""); - rep(/</gi,"<"); - rep(/>/gi,">"); - rep(/&/gi,"&"); - rep(/&undefined;/gi,"'"); // quickfix + // example: to [b] + rep(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"); + rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"); + rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"); + rep(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"); + rep(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"); + rep(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"); + rep(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"); + rep(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"); + rep(/(.*?)<\/font>/gi,"$1"); + rep(//gi,"[img]$1[/img]"); + rep(/(.*?)<\/span>/gi,"[code]$1[/code]"); + rep(/(.*?)<\/span>/gi,"[quote]$1[/quote]"); + rep(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"); + rep(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"); + rep(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"); + rep(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"); + rep(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"); + rep(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"); + rep(/<\/(strong|b)>/gi,"[/b]"); + rep(/<(strong|b)>/gi,"[b]"); + rep(/<\/(em|i)>/gi,"[/i]"); + rep(/<(em|i)>/gi,"[i]"); + rep(/<\/u>/gi,"[/u]"); + rep(/(.*?)<\/span>/gi,"[u]$1[/u]"); + rep(//gi,"[u]"); + rep(/
/gi,"\n"); + rep(//gi,"\n"); + rep(/
/gi,"\n"); + rep(/

/gi,""); + rep(/<\/p>/gi,"\n"); + rep(/ /gi," "); + rep(/"/gi,"\""); + rep(/</gi,"<"); + rep(/>/gi,">"); + rep(/&/gi,"&"); - return s; - }, + return s; + }, - // BBCode -> HTML from PunBB dialect - _punbb_bbcode2html : function(s) { - s = tinyMCE.trim(s); + // BBCode -> HTML from PunBB dialect + _punbb_bbcode2html : function(s) { + s = tinymce.trim(s); - function rep(re, str) { - s = s.replace(re, str); - }; + function rep(re, str) { + s = s.replace(re, str); + }; - // example: [b] to - rep(/\n/gi,"
"); - rep(/\[b\]/gi,""); - rep(/\[\/b\]/gi,""); - rep(/\[i\]/gi,""); - rep(/\[\/i\]/gi,""); - rep(/\[u\]/gi,""); - rep(/\[\/u\]/gi,""); - rep(/\[url\](.*?)\[\/url\]/gi,"
$1"); - rep(/\[img\](.*?)\[\/img\]/gi,""); - rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"$2"); - rep(/\[code\](.*?)\[\/code\]/gi,"$1 "); - rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"$1 "); + // example: [b] to + rep(/\n/gi,"
"); + rep(/\[b\]/gi,""); + rep(/\[\/b\]/gi,""); + rep(/\[i\]/gi,""); + rep(/\[\/i\]/gi,""); + rep(/\[u\]/gi,""); + rep(/\[\/u\]/gi,""); + rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,"$2"); + rep(/\[url\](.*?)\[\/url\]/gi,"$1"); + rep(/\[img\](.*?)\[\/img\]/gi,""); + rep(/\[color=(.*?)\](.*?)\[\/color\]/gi,"$2"); + rep(/\[code\](.*?)\[\/code\]/gi,"$1 "); + rep(/\[quote.*?\](.*?)\[\/quote\]/gi,"$1 "); - return s; - } -}; + return s; + } + }); -tinyMCE.addPlugin("bbcode", TinyMCE_BBCodePlugin); + // Register plugin + tinymce.PluginManager.add('bbcode', tinymce.plugins.BBCodePlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/cleanup/editor_plugin.js diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/cleanup/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/cleanup/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -/** - * $Id: editor_plugin_src.js 162 2007-01-03 16:16:52Z spocke $ - * - * Experimental plugin for new Cleanup routine, this logic will be moved into the core ones it's stable enougth. - * - * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. - */ - -/* Dummy file since cleanup is now moved to core */ diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/cleanup/readme.txt --- a/includes/clientside/tinymce/plugins/cleanup/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Dummy plugin since cleanup is now moved into core. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/compat2x/editor_plugin.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/compat2x/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +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');doc.close()}};TinyMCE_ContextMenu.prototype={clearAll:function(){this.html="";this.contextMenuDiv.innerHTML=""},addSeparator:function(){this.html+='

'},addItem:function(icon,title,command,value,disabled){if(title.charAt(0)=='$')title=tinyMCE.getLang(title.substring(1));var onMouseDown='';var html='';if(tinyMCE.isMSIE&&!tinyMCE.isMSIE5_0)onMouseDown='contextMenu.execCommand(\''+command+'\', \''+value+'\');return false;';else onMouseDown=this.settings['commandhandler']+'(\''+command+'\', \''+value+'\');return false;';if(icon=="")icon=this.settings['spacer_image'];if(!disabled)html+='';else html+='';html+='';html+='';html+='';this.html+=html},show:function(x,y){var vp,width,height,yo;if(this.html=="")return;var html='';html+='
';html+=' ';html+=title;html+=' ';html+='
';html+=this.html;html+='
';this.contextMenuDiv.innerHTML=html;this.contextMenuDiv.style.display="block";width=this.contextMenuDiv.offsetWidth;height=this.contextMenuDiv.offsetHeight;this.contextMenuDiv.style.display="none";if(tinyMCE.isMSIE&&!tinyMCE.isMSIE5_0&&!tinyMCE.isOpera){this.pop.document.body.innerHTML='
'+html+"
";this.pop.document.tinyMCE=tinyMCE;this.pop.document.contextMenu=this;this.pop.show(x,y,width,height)}else{vp=this.getViewPort();yo=tinyMCE.isMSIE5_0?document.body.scrollTop:self.pageYOffset;this.contextMenuDiv.style.left=(x>vp.left+vp.width-width?vp.left+vp.width-width:x)+'px';this.contextMenuDiv.style.top=(y>vp.top+vp.height-height?vp.top+vp.height-height:y)+'px';this.contextMenuDiv.style.display="block"}},getViewPort:function(){return{left:self.pageXOffset||self.document.documentElement.scrollLeft||self.document.body.scrollLeft,top:self.pageYOffset||self.document.documentElement.scrollTop||self.document.body.scrollTop,width:document.documentElement.offsetWidth||document.body.offsetWidth,height:self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}},hide:function(){if(tinyMCE.isMSIE&&!tinyMCE.isMSIE5_0&&!tinyMCE.isOpera)this.pop.hide();else this.contextMenuDiv.style.display="none"},execCommand:function(command,value){eval(this.settings['commandhandler']+"(command, value);")}}; \ No newline at end of file +(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){t._getMenu(ed).showMenu(e.clientX,e.clientY);Event.cancel(e);});function hide(){if(t._menu){t._menu.removeAll();t._menu.destroy();}};ed.onMouseDown.add(hide);ed.onKeyDown.add(hide);Event.add(document,'click',hide);},_getMenu:function(ed){var t=this,m=t._menu,se=ed.selection,col=se.isCollapsed(),el=se.getNode()||ed.getBody(),am;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,offset_y:p1.y,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 diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/contextmenu/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/contextmenu/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/contextmenu/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,357 +1,84 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -if (!tinyMCE.settings['contextmenu_skip_plugin_css']) { - tinyMCE.loadCSS(tinyMCE.baseURL + "/plugins/contextmenu/css/contextmenu.css"); -} - -var TinyMCE_ContextMenuPlugin = { - // Private fields - _contextMenu : null, +(function() { + var Event = tinymce.dom.Event, each = tinymce.each, DOM = tinymce.DOM; - getInfo : function() { - return { - longname : 'Context menus', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, - - initInstance : function(inst) { - // Is not working on MSIE 5.0 or Opera no contextmenu event - if (tinyMCE.isMSIE5_0 && tinyMCE.isOpera) - return; - - TinyMCE_ContextMenuPlugin._contextMenu = new TinyMCE_ContextMenu({ - commandhandler : "TinyMCE_ContextMenuPlugin._commandHandler", - spacer_image : tinyMCE.baseURL + "/plugins/contextmenu/images/spacer.gif" - }); - - // Add hide event handles - tinyMCE.addEvent(inst.getDoc(), "click", TinyMCE_ContextMenuPlugin._hideContextMenu); - tinyMCE.addEvent(inst.getDoc(), "keypress", TinyMCE_ContextMenuPlugin._hideContextMenu); - tinyMCE.addEvent(inst.getDoc(), "keydown", TinyMCE_ContextMenuPlugin._hideContextMenu); - tinyMCE.addEvent(document, "click", TinyMCE_ContextMenuPlugin._hideContextMenu); - tinyMCE.addEvent(document, "keypress", TinyMCE_ContextMenuPlugin._hideContextMenu); - tinyMCE.addEvent(document, "keydown", TinyMCE_ContextMenuPlugin._hideContextMenu); + tinymce.create('tinymce.plugins.ContextMenu', { + init : function(ed) { + var t = this; - // Attach contextmenu event - if (tinyMCE.isGecko) { - tinyMCE.addEvent(inst.getDoc(), "contextmenu", function(e) {TinyMCE_ContextMenuPlugin._showContextMenu(tinyMCE.isMSIE ? inst.contentWindow.event : e, inst);}); - } else - tinyMCE.addEvent(inst.getDoc(), "contextmenu", TinyMCE_ContextMenuPlugin._onContextMenu); - }, - - // Private plugin internal methods - - _onContextMenu : function(e) { - var elm = tinyMCE.isMSIE ? e.srcElement : e.target; - var targetInst, body; - - // Find instance - if ((body = tinyMCE.getParentElement(elm, "body")) != null) { - for (var n in tinyMCE.instances) { - var inst = tinyMCE.instances[n]; - if (!tinyMCE.isInstance(inst)) - continue; + t.editor = ed; + t.onContextMenu = new tinymce.util.Dispatcher(this); - if (body == inst.getBody()) { - targetInst = inst; - break; - } - } - - return TinyMCE_ContextMenuPlugin._showContextMenu(tinyMCE.isMSIE ? targetInst.contentWindow.event : e, targetInst); - } - }, - - _showContextMenu : function(e, inst) { - function getAttrib(elm, name) { - return elm.getAttribute(name) ? elm.getAttribute(name) : ""; - } - - var x, y, elm, contextMenu; - var pos = tinyMCE.getAbsPosition(inst.iframeElement); - - x = tinyMCE.isMSIE ? e.screenX : pos.absLeft + (e.pageX - inst.getBody().scrollLeft); - y = tinyMCE.isMSIE ? e.screenY : pos.absTop + (e.pageY - inst.getBody().scrollTop); - elm = tinyMCE.isMSIE ? e.srcElement : e.target; - - contextMenu = this._contextMenu; - contextMenu.inst = inst; + ed.onContextMenu.add(function(ed, e) { + t._getMenu(ed).showMenu(e.clientX, e.clientY); + Event.cancel(e); + }); - // Mozilla needs some time - window.setTimeout(function () { - var theme = tinyMCE.getParam("theme"); - - contextMenu.clearAll(); - var sel = inst.selection.getSelectedText().length != 0 || elm.nodeName == "IMG"; - - // Default items - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/cut.gif", "$lang_cut_desc", "Cut", "", !sel); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/copy.gif", "$lang_copy_desc", "Copy", "", !sel); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/paste.gif", "$lang_paste_desc", "Paste", "", false); - - if (sel || (elm ? (elm.nodeName == 'A' && tinyMCE.getAttrib(elm, 'name') == '') || (elm.nodeName == 'IMG') : false)) { - contextMenu.addSeparator(); - contextMenu.addItem(tinyMCE.baseURL + "/themes/advanced/images/link.gif", "$lang_link_desc", inst.hasPlugin("advlink") ? "mceAdvLink" : "mceLink"); - contextMenu.addItem(tinyMCE.baseURL + "/themes/advanced/images/unlink.gif", "$lang_unlink_desc", "unlink", "", (elm ? (elm.nodeName != 'A') && (elm.nodeName != 'IMG') : true)); - } - - // Get element - elm = tinyMCE.getParentElement(elm, "img,table,td" + (inst.hasPlugin("advhr") ? ',hr' : '')); - if (elm) { - switch (elm.nodeName) { - case "IMG": - contextMenu.addSeparator(); - - // If flash - if (tinyMCE.hasPlugin('flash') && tinyMCE.getAttrib(elm, 'class').indexOf('mceItemFlash') != -1) - contextMenu.addItem(tinyMCE.baseURL + "/plugins/flash/images/flash.gif", "$lang_flash_props", "mceFlash"); - else if (tinyMCE.hasPlugin('media') && /mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(tinyMCE.getAttrib(elm, 'class'))) - contextMenu.addItem(tinyMCE.baseURL + "/plugins/flash/images/flash.gif", "$lang_media_title", "mceMedia"); - else - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/image.gif", "$lang_image_props_desc", inst.hasPlugin("advimage") ? "mceAdvImage" : "mceImage"); - break; - - case "HR": - contextMenu.addSeparator(); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/advhr/images/advhr.gif", "$lang_insert_advhr_desc", "mceAdvancedHr"); - break; + function hide() { + if (t._menu) { + t._menu.removeAll(); + t._menu.destroy(); + } + }; - case "TABLE": - case "TD": - // Is table plugin loaded - if (inst.hasPlugin("table")) { - var colspan = (elm.nodeName == "TABLE") ? "" : getAttrib(elm, "colspan"); - var rowspan = (elm.nodeName == "TABLE") ? "" : getAttrib(elm, "rowspan"); - - colspan = colspan == "" ? "1" : colspan; - rowspan = rowspan == "" ? "1" : rowspan; - - contextMenu.addSeparator(); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/cut.gif", "$lang_table_cut_row_desc", "mceTableCutRow"); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/copy.gif", "$lang_table_copy_row_desc", "mceTableCopyRow"); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/paste.gif", "$lang_table_paste_row_before_desc", "mceTablePasteRowBefore", "", inst.tableRowClipboard == null); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/paste.gif", "$lang_table_paste_row_after_desc", "mceTablePasteRowAfter", "", inst.tableRowClipboard == null); + ed.onMouseDown.add(hide); + ed.onKeyDown.add(hide); + Event.add(document, 'click', hide); + }, - /* contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/justifyleft.gif", "$lang_justifyleft_desc", "JustifyLeft", "", false); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/justifycenter.gif", "$lang_justifycenter_desc", "JustifyCenter", "", false); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/justifyright.gif", "$lang_justifyright_desc", "JustifyRight", "", false); - contextMenu.addItem(tinyMCE.baseURL + "/themes/" + theme + "/images/justifyfull.gif", "$lang_justifyfull_desc", "JustifyFull", "", false);*/ - contextMenu.addSeparator(); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table.gif", "$lang_table_desc", "mceInsertTable", "insert"); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table.gif", "$lang_table_props_desc", "mceInsertTable"); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_cell_props.gif", "$lang_table_cell_desc", "mceTableCellProps"); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_delete.gif", "$lang_table_del", "mceTableDelete"); - contextMenu.addSeparator(); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_row_props.gif", "$lang_table_row_desc", "mceTableRowProps"); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_insert_row_before.gif", "$lang_table_row_before_desc", "mceTableInsertRowBefore"); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_insert_row_after.gif", "$lang_table_row_after_desc", "mceTableInsertRowAfter"); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_delete_row.gif", "$lang_table_delete_row_desc", "mceTableDeleteRow"); - contextMenu.addSeparator(); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_insert_col_before.gif", "$lang_table_col_before_desc", "mceTableInsertColBefore"); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_insert_col_after.gif", "$lang_table_col_after_desc", "mceTableInsertColAfter"); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_delete_col.gif", "$lang_table_delete_col_desc", "mceTableDeleteCol"); - contextMenu.addSeparator(); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_split_cells.gif", "$lang_table_split_cells_desc", "mceTableSplitCells", "", (colspan == "1" && rowspan == "1")); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table_merge_cells.gif", "$lang_table_merge_cells_desc", "mceTableMergeCells", "", false); - } - break; - } - } else { - // Add table specific - if (inst.hasPlugin("table")) { - contextMenu.addSeparator(); - contextMenu.addItem(tinyMCE.baseURL + "/plugins/table/images/table.gif", "$lang_table_desc", "mceInsertTable", "insert"); - } + _getMenu : function(ed) { + var t = this, m = t._menu, se = ed.selection, col = se.isCollapsed(), el = se.getNode() || ed.getBody(), am; + + if (m) { + m.removeAll(); + m.destroy(); } - contextMenu.show(x, y); - }, 10); - - // Cancel default handeling - tinyMCE.cancelEvent(e); - return false; - }, - - _hideContextMenu : function() { - if (TinyMCE_ContextMenuPlugin._contextMenu) - TinyMCE_ContextMenuPlugin._contextMenu.hide(); - }, - - _commandHandler : function(command, value) { - var cm = TinyMCE_ContextMenuPlugin._contextMenu; - - cm.hide(); - - // UI must be true on these - var ui = false; - if (command == "mceInsertTable" || command == "mceTableCellProps" || command == "mceTableRowProps" || command == "mceTableMergeCells") - ui = true; - - if (command == "Paste") - value = null; - - if (tinyMCE.getParam("dialog_type") == "modal" && tinyMCE.isMSIE) { - // Cell properties will generate access denied error is this isn't done?! - window.setTimeout(function() { - cm.inst.execCommand(command, ui, value); - }, 100); - } else - cm.inst.execCommand(command, ui, value); - } -}; - -tinyMCE.addPlugin("contextmenu", TinyMCE_ContextMenuPlugin); - -// Context menu class - -function TinyMCE_ContextMenu(settings) { - var doc, self = this; + p1 = DOM.getPos(ed.getContentAreaContainer()); + p2 = DOM.getPos(ed.getContainer()); - // Default value function - function defParam(key, def_val) { - settings[key] = typeof(settings[key]) != "undefined" ? settings[key] : def_val; - } - - this.isMSIE = (navigator.appName == "Microsoft Internet Explorer"); - - // Setup contextmenu div - this.contextMenuDiv = document.createElement("div"); - this.contextMenuDiv.className = "contextMenu"; - this.contextMenuDiv.setAttribute("class", "contextMenu"); - this.contextMenuDiv.style.display = "none"; - this.contextMenuDiv.style.position = 'absolute'; - this.contextMenuDiv.style.zindex = 1000; - this.contextMenuDiv.style.left = '0'; - this.contextMenuDiv.style.top = '0'; - this.contextMenuDiv.unselectable = "on"; - - document.body.appendChild(this.contextMenuDiv); - - // Setup default values - defParam("commandhandler", ""); - defParam("spacer_image", "images/spacer.gif"); + m = ed.controlManager.createDropMenu('contextmenu', { + offset_x : p1.x, + offset_y : p1.y, +/* vp_offset_x : p2.x, + vp_offset_y : p2.y,*/ + constrain : 1 + }); - this.items = new Array(); - this.settings = settings; - this.html = ""; + t._menu = m; - // IE Popup - if (tinyMCE.isMSIE && !tinyMCE.isMSIE5_0 && !tinyMCE.isOpera) { - this.pop = window.createPopup(); - doc = this.pop.document; - doc.open(); - doc.write(''); - doc.close(); - } -}; - -TinyMCE_ContextMenu.prototype = { - clearAll : function() { - this.html = ""; - this.contextMenuDiv.innerHTML = ""; - }, - - addSeparator : function() { - this.html += '
'; - html += this.html; - html += '
'; - - this.contextMenuDiv.innerHTML = html; - - // Get dimensions - this.contextMenuDiv.style.display = "block"; - width = this.contextMenuDiv.offsetWidth; - height = this.contextMenuDiv.offsetHeight; - this.contextMenuDiv.style.display = "none"; + 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'}); - if (tinyMCE.isMSIE && !tinyMCE.isMSIE5_0 && !tinyMCE.isOpera) { - // Setup popup and show - this.pop.document.body.innerHTML = '
' + html + "
"; - this.pop.document.tinyMCE = tinyMCE; - this.pop.document.contextMenu = this; - this.pop.show(x, y, width, height); - } else { - vp = this.getViewPort(); - yo = tinyMCE.isMSIE5_0 ? document.body.scrollTop : self.pageYOffset; - this.contextMenuDiv.style.left = (x > vp.left + vp.width - width ? vp.left + vp.width - width : x) + 'px'; - this.contextMenuDiv.style.top = (y > vp.top + vp.height - height ? vp.top + vp.height - height : y) + 'px'; - this.contextMenuDiv.style.display = "block"; - } - }, + t.onContextMenu.dispatch(t, m, el, col); - getViewPort : function() { - return { - left : self.pageXOffset || self.document.documentElement.scrollLeft || self.document.body.scrollLeft, - top: self.pageYOffset || self.document.documentElement.scrollTop || self.document.body.scrollTop, - width : document.documentElement.offsetWidth || document.body.offsetWidth, - height : self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight - }; - }, + return m; + } + }); - hide : function() { - if (tinyMCE.isMSIE && !tinyMCE.isMSIE5_0 && !tinyMCE.isOpera) - this.pop.hide(); - else - this.contextMenuDiv.style.display = "none"; - }, - - execCommand : function(command, value) { - eval(this.settings['commandhandler'] + "(command, value);"); - } -}; + // Register plugin + tinymce.PluginManager.add('contextmenu', tinymce.plugins.ContextMenu); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/contextmenu/images/spacer.gif Binary file includes/clientside/tinymce/plugins/contextmenu/images/spacer.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/contextmenu/readme.txt --- a/includes/clientside/tinymce/plugins/contextmenu/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/devkit/css/devkit.css --- a/includes/clientside/tinymce/plugins/devkit/css/devkit.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -body { - overflow: hidden; -} - -h1 { - font-size: 14px; - margin: 0 0 10px 0; -} - -h2 { - font-size: 12px; - margin: 3px 0 3px 0; -} - -h3 { - font-size: 11px; - margin: 3px 0 3px 0; -} - -#log { - font-family: Verdana; - border: 1px solid gray; - width: 100%; height: 240px; - overflow: scroll; - white-space: nowrap; -} - -#log span { - display: block; -} - -#log span.msg { - float: left; -} - -#log span.time { - float: left; -} - -#log br { - clear: both; -} - -#logfilter { - width: 350px; -} - -#logenabled { - border: 0; -} - -#settings_panel span, #info_panel span, #content_panel span, #command_states_panel span, #undo_redo_panel span { - display: block; - margin: 5px 0 5px 0; -} - -div.data { - width: 100%; height: 240px; - overflow: scroll; - border: 1px solid gray; -} - -#misc_panel div.data { - height: 270px; -} - -.data input { - width: 265px; - border: 0; -} - -.data h2 { - margin-left: 5px; -} - -.data h3 { - margin-left: 7px; -} - -.data div { - margin-left: 7px; -} - -.data table { - margin: 0 0 15px 15px; -} - -.data p { - margin: 0; padding: 0; - margin-top: 5px; - margin-left: 5px; -} - -table, td { - border: 1px solid gray; - border-collapse: collapse; -} - -#flip { - position: absolute; - left: 295; top: 384px; -} - -.bspec { - color: gray; -} - -.dep { - color: #880000; -} - -.col1 { - width: 265px; -} - -div.undodata { -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/devkit/css/devkit_ui.css --- a/includes/clientside/tinymce/plugins/devkit/css/devkit_ui.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -#devkit { - position: absolute; - top: -385px; right: 0; - width: 640px; height: 390px; - border: 1px solid black; - z-index: 10000; -} - -.devkitup { - top: -385px !important; -} - -.devkitdown { - top: 0 !important; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/devkit/devkit.htm --- a/includes/clientside/tinymce/plugins/devkit/devkit.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ - - - {$lang_devkit_title} - - - - - - - - - -
-

{$lang_devkit_title}

- - - -
-
-
- {$lang_devkit_log_tab} - -
- -
- -
- -
- - - -
- -
-
- - -
-
- -
-
- {$lang_devkit_info_tab} - - [{$lang_devkit_refresh}] - -
-

{$lang_devkit_info_help}

-
-
-
- -
-
- {$lang_devkit_settings_tab} - - [{$lang_devkit_refresh}] - -
-

{$lang_devkit_settings_help}

-
-
-
- -
-
- {$lang_devkit_content_tab} - - [{$lang_devkit_refresh}] - -
-

{$lang_devkit_content_help}

-
-
-
- -
-
- {$lang_devkit_command_states_tab} - - [{$lang_devkit_refresh}] - -
-

{$lang_devkit_command_states_help}

-
-
-
- -
-
- {$lang_devkit_undo_redo_tab} - - [{$lang_devkit_refresh}] - -
-

{$lang_devkit_undo_redo_help}

-
- - -
-
- -
-
- {$lang_devkit_misc_tab} - -
-

{$lang_devkit_misc_help}

-
-

Selection: [Store selection] [Restore selection]

-
-
Insert custom HTML content
-
- -
-
Eval JS:
-
- -
-
-
-
-
- -
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/devkit/editor_plugin.js --- a/includes/clientside/tinymce/plugins/devkit/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -tinyMCE.importPluginLanguagePack('devkit');var TinyMCE_DevKitPlugin={_logFilter:'\\[(importCSS|execCommand|execInstanceCommand|debug)\\]',_logPadding:'',_startTime:null,_benchMark:false,_winLoaded:false,_isDebugEvents:false,getInfo:function(){return{longname:'Development Kit',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/devkit',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},initInstance:function(inst){this._setup()},_setup:function(){if(this._loaded)return;this._loaded=true;document.___TinyMCE=tinyMCE;this._logFilter=tinyMCE.getParam('devkit_log_filter',this._logFilter);this._benchMark=tinyMCE.getParam('devkit_bench_mark',false);var ifr=document.createElement('iframe');ifr.setAttribute("id","devkit");ifr.setAttribute("frameBorder","0");ifr.setAttribute("src",tinyMCE.baseURL+'/plugins/devkit/devkit.htm');document.body.appendChild(ifr);tinyMCE.importCSS(document,tinyMCE.baseURL+'/plugins/devkit/css/devkit_ui.css')},_start:function(){this._logPadding+='\u00a0';return new Date().getTime()},_end:function(st){if(this._logPadding.length>0)this._logPadding=this._logPadding.substring(0,this._logPadding.length-1);if(this._benchMark)this._log("benchmark","Execution time: "+(new Date().getTime()-st))},_log:function(t){var m,a,i,e=document.getElementById('devkit'),now=new Date().getTime();if(!this._startTime)this._startTime=now;m=(this._logPadding.length>1?this._logPadding:'')+'['+(now-this._startTime)+'] ['+t+'] ';a=this._log.arguments;for(i=1;i1)m+=', ';m+=a[i]}if(!new RegExp(this._logFilter,'gi').test(m)){if(this._logPadding.length>0)this._logPadding=this._logPadding.substring(0,this._logPadding.length-1);return}if(!this._winLoaded)tinyMCE.log[tinyMCE.log.length]=m;else e.contentWindow.debug(m)},_debugEvents:function(s){var i,ld,inst,n,ev=['CheckboxStateChange','DOMAttrModified','DOMMenuItemActive','DOMMenuItemInactive','DOMMouseScroll','DOMNodeInserted','DOMNodeRemoved','RadioStateChange','blur','broadcast','change','click','close','command','commandupdate','contextmenu','dblclick','dragdrop','dragenter','dragexit','draggesture','dragover','focus','input','keydown','keypress','keyup','load','mousedown','mouseout','mouseover','mouseup','overflow','overflowchanged','popuphidden','popuphiding','popupshowing','popupshown','select','syncfrompreference','synctopreference','underflow','unload','abort','activate','afterprint','afterupdate','beforeactivate','beforecopy','beforecut','beforedeactivate','beforeeditfocus','beforepaste','beforeprint','beforeunload','beforeupdate','bounce','cellchange','controlselect','copy','cut','dataavailable','datasetchanged','datasetcomplete','deactivate','dragend','dragleave','dragstart','drop','error','errorupdate','filterchange','finish','focusin','focusout','help','layoutcomplete','losecapture','mouseenter','mouseleave','mousewheel','move','moveend','movestart','paste','propertychange','readystatechange','reset','resize','resizeend','resizestart','rowenter','rowexit','rowsdelete','rowsinserted','scroll','selectionchange','selectstart','start','stop','submit'];if(TinyMCE_DevKitPlugin._isDebugEvents==s)return;TinyMCE_DevKitPlugin._isDebugEvents=s;for(n in tinyMCE.instances){inst=tinyMCE.instances[n];if(!tinyMCE.isInstance(inst)||inst.getDoc()==ld)continue;ld=inst.getDoc();for(i=0;i0?',':'')+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}};tinyMCE.__debug=tinyMCE.debug;tinyMCE.debug=function(){var a,i,m='',now=new Date().getTime(),start=TinyMCE_DevKitPlugin._startTime;if(!start)TinyMCE_DevKitPlugin._startTime=start=now;a=this.debug.arguments;for(i=0;i0)m+=', ';m+=a[i]}TinyMCE_DevKitPlugin._log('debug',m)};tinyMCE.dump=function(o){tinyMCE.debug(TinyMCE_DevKitPlugin._serialize(o))};tinyMCE.sleep=function(t){var s=new Date().getTime(),b;while(new Date().getTime()-s 0) - this._logPadding = this._logPadding.substring(0, this._logPadding.length - 1); - - if (this._benchMark) - this._log("benchmark", "Execution time: " + (new Date().getTime() - st)); - }, - - _log : function(t) { - var m, a, i, e = document.getElementById('devkit'), now = new Date().getTime(); - - if (!this._startTime) - this._startTime = now; - - m = (this._logPadding.length > 1 ? this._logPadding : '') + '[' + (now - this._startTime) + '] [' + t + '] '; - - a = this._log.arguments; - for (i=1; i 1) - m += ', '; - - m += a[i]; - } - - if (!new RegExp(this._logFilter, 'gi').test(m)) { - if (this._logPadding.length > 0) - this._logPadding = this._logPadding.substring(0, this._logPadding.length - 1); - - return; - } - - if (!this._winLoaded) - tinyMCE.log[tinyMCE.log.length] = m; - else - e.contentWindow.debug(m); - }, - - _debugEvents : function(s) { - var i, ld, inst, n, ev = ['CheckboxStateChange','DOMAttrModified','DOMMenuItemActive', - 'DOMMenuItemInactive','DOMMouseScroll','DOMNodeInserted','DOMNodeRemoved', - 'RadioStateChange','blur','broadcast','change','click','close','command', - 'commandupdate','contextmenu','dblclick','dragdrop','dragenter','dragexit', - 'draggesture','dragover','focus','input','keydown','keypress','keyup','load', - 'mousedown','mouseout','mouseover','mouseup','overflow','overflowchanged','popuphidden', - 'popuphiding','popupshowing','popupshown','select','syncfrompreference','synctopreference', - 'underflow','unload','abort','activate','afterprint','afterupdate','beforeactivate', - 'beforecopy','beforecut','beforedeactivate','beforeeditfocus','beforepaste','beforeprint', - 'beforeunload','beforeupdate','bounce','cellchange','controlselect','copy','cut', - 'dataavailable','datasetchanged','datasetcomplete','deactivate','dragend','dragleave', - 'dragstart','drop','error','errorupdate','filterchange','finish','focusin','focusout', - 'help','layoutcomplete','losecapture','mouseenter','mouseleave','mousewheel', - 'move','moveend','movestart','paste','propertychange','readystatechange','reset','resize', - 'resizeend','resizestart','rowenter','rowexit','rowsdelete','rowsinserted','scroll', - 'selectionchange','selectstart','start','stop','submit']; - // mousemove - - if (TinyMCE_DevKitPlugin._isDebugEvents == s) - return; - - TinyMCE_DevKitPlugin._isDebugEvents = s; - - for (n in tinyMCE.instances) { - inst = tinyMCE.instances[n]; - - if (!tinyMCE.isInstance(inst) || inst.getDoc() == ld) - continue; - - ld = inst.getDoc(); - - for (i=0; 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; - } -}; - -// Patch and piggy back functions -tinyMCE.__debug = tinyMCE.debug; -tinyMCE.debug = function() { - var a, i, m = '', now = new Date().getTime(), start = TinyMCE_DevKitPlugin._startTime; - - if (!start) - TinyMCE_DevKitPlugin._startTime = start = now; - - a = this.debug.arguments; - for (i=0; i 0) - m += ', '; - - m += a[i]; - } - - TinyMCE_DevKitPlugin._log('debug', m); -}; - -tinyMCE.dump = function(o) { - tinyMCE.debug(TinyMCE_DevKitPlugin._serialize(o)); -}; - -tinyMCE.sleep = function(t) { - var s = new Date().getTime(), b; - - while (new Date().getTime() - s < t) b=1; -}; - -tinyMCE.__execCommand = tinyMCE.execCommand; -tinyMCE.execCommand = function(command, user_interface, value) { - var r, st, dk = TinyMCE_DevKitPlugin; - - st = dk._start(); - dk._log('execCommand', command, user_interface, value); - r = tinyMCE.__execCommand(command, user_interface, value); - dk._end(st); - - return r; -}; - -tinyMCE.__execInstanceCommand = tinyMCE.execInstanceCommand; -tinyMCE.execInstanceCommand = function(editor_id, command, user_interface, value, focus) { - var r, st, dk = TinyMCE_DevKitPlugin; - - st = dk._start(); - dk._log('execInstanceCommand', editor_id, command, user_interface, value); - r = tinyMCE.__execInstanceCommand(editor_id, command, user_interface, value); - dk._end(st); - - return r; -}; - -TinyMCE_Engine.prototype.__handleEvent = TinyMCE_Engine.prototype.handleEvent; -TinyMCE_Engine.prototype.handleEvent = function(e) { - var r, st, dk = TinyMCE_DevKitPlugin; - - st = dk._start(); - dk._log('handleEvent', e.type); - r = tinyMCE.__handleEvent(e); - dk._end(st); - - return r; -}; - -tinyMCE.__importCSS = tinyMCE.importCSS; -tinyMCE.importCSS = function(doc, css) { - var r, st, dk = TinyMCE_DevKitPlugin; - - st = dk._start(); - dk._log('importCSS', doc, css); - r = tinyMCE.__importCSS(doc, css); - dk._end(st); - - return r; -}; - -tinyMCE.__triggerNodeChange = tinyMCE.triggerNodeChange; -tinyMCE.triggerNodeChange = function(focus, setup_content) { - var r, st, dk = TinyMCE_DevKitPlugin; - - st = dk._start(); - dk._log('triggerNodeChange', focus, setup_content); - r = tinyMCE.__triggerNodeChange(focus, setup_content); - dk._end(st); - - return r; -}; - -tinyMCE.__dispatchCallback = tinyMCE.dispatchCallback; -tinyMCE.dispatchCallback = function(i, p, n) { - var r, st, dk = TinyMCE_DevKitPlugin; - - st = dk._start(); - dk._log('dispatchCallback', i, p, n); - r = tinyMCE.__dispatchCallback(i, p, n); - dk._end(st); - - return r; -}; - -tinyMCE.__executeCallback = tinyMCE.executeCallback; -tinyMCE.executeCallback = function(i, p, n) { - var r, st, dk = TinyMCE_DevKitPlugin; - - st = dk._start(); - dk._log('executeCallback', i, p, n); - r = tinyMCE.__executeCallback(i, p, n); - dk._end(st); - - return r; -}; - -tinyMCE.__execCommandCallback = tinyMCE.execCommandCallback; -tinyMCE.execCommandCallback = function(i, p, n) { - var r, st, dk = TinyMCE_DevKitPlugin; - - st = dk._start(); - dk._log('execCommandCallback', i, p, n); - r = tinyMCE.__execCommandCallback(i, p, n); - dk._end(st); - - return r; -}; - -tinyMCE.addPlugin("devkit", TinyMCE_DevKitPlugin); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/devkit/images/flip_down.gif Binary file includes/clientside/tinymce/plugins/devkit/images/flip_down.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/devkit/images/flip_up.gif Binary file includes/clientside/tinymce/plugins/devkit/images/flip_up.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/devkit/jscripts/devkit.js --- a/includes/clientside/tinymce/plugins/devkit/jscripts/devkit.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,331 +0,0 @@ -var devkit = parent.tinyMCE.plugins['devkit'], logEnabled = true, flip = false, book = null; - -function init() { - var log, i, f = document.forms[0]; - - devkit._winLoaded = true; - - log = tinyMCE.log; - - for (i=0; i'; - h += ''; - - h += addRenderInfo('editorId', inst.editorId); - h += addRenderInfo('visualAid', inst.visualAid); - h += addRenderInfo('foreColor', inst.foreColor); - h += addRenderInfo('backColor', inst.backColor); - h += addRenderInfo('formTargetElementId', inst.formTargetElementId); - h += addRenderInfo('formElement', inst.formElement ? inst.formElement.nodeName : null); - h += addRenderInfo('oldTargetElement', inst.oldTargetElement ? inst.oldTargetElement.nodeName : null); - h += addRenderInfo('linkElement', inst.linkElement ? inst.linkElement.nodeName : null, 'dep'); - h += addRenderInfo('imgElement', inst.imgElement ? inst.imgElement.nodeName : null, 'dep'); - h += addRenderInfo('selectedNode', inst.selectedNode ? inst.selectedNode.nodeName : null, 'dep'); - h += addRenderInfo('targetElement', inst.targetElement ? inst.targetElement.nodeName : null); - h += addRenderInfo('getBody().nodeName', inst.getBody() ? inst.getBody().nodeName : null); - h += addRenderInfo('getBody().getAttribute("id")', inst.getBody() ? inst.getBody().getAttribute("id") : null); - h += addRenderInfo('getDoc().location', inst.getDoc() ? inst.getDoc().location : null); - h += addRenderInfo('startContent', inst.startContent); - h += addRenderInfo('isHidden()', inst.isHidden()); - h += addRenderInfo('isDirty()', inst.isDirty()); - h += addRenderInfo('undoRedo.undoLevels.length', inst.undoRedo.undoLevels.length); - h += addRenderInfo('undoRedo.undoIndex', inst.undoRedo.undoIndex); - h += addRenderInfo('selection.getSelectedHTML()', inst.selection.getSelectedHTML()); - h += addRenderInfo('selection.isCollapsed()', inst.selection.isCollapsed() || 'false'); - h += addRenderInfo('selection.getSelectedText()', inst.selection.getSelectedText()); - h += addRenderInfo('selection.getFocusElement().nodeName', inst.selection.getFocusElement().nodeName); - h += addRenderInfo('selection.getFocusElement().outerHTML', tinyMCE.getOuterHTML(inst.selection.getFocusElement())); - - if ((tinyMCE.isGecko || tinyMCE.isOpera) && sel && rng) { - h += addRenderInfo('selection.getSel().anchorNode.nodeName', sel.anchorNode ? sel.anchorNode.nodeName : null, 'bspec'); - h += addRenderInfo('selection.getSel().anchorOffset', sel.anchorOffset, 'bspec'); - h += addRenderInfo('selection.getSel().focusNode.nodeName', sel.focusNode ? sel.focusNode.nodeName : null, 'bspec'); - h += addRenderInfo('selection.getSel().focusOffset', sel.focusOffset, 'bspec'); - h += addRenderInfo('selection.getRng().startContainer.nodeName', rng.startContainer ? rng.startContainer.nodeName : null, 'bspec'); - h += addRenderInfo('selection.getRng().startOffset', rng.startOffset, 'bspec'); - h += addRenderInfo('selection.getRng().endContainer.nodeName', rng.endContainer ? rng.endContainer.nodeName : null, 'bspec'); - h += addRenderInfo('selection.getRng().endOffset', rng.endOffset, 'bspec'); - } - - if (typeof(rng.item) != 'undefined' || typeof(rng.htmlText) != 'undefined') { - if (!rng.item) { - h += addRenderInfo('selection.getSel().type', sel.type, 'bspec'); - h += addRenderInfo('selection.getRng().htmlText', rng.htmlText, 'bspec'); - h += addRenderInfo('selection.getRng().text', rng.text, 'bspec'); - } else - h += addRenderInfo('selection.getRng().item(0).nodeName', rng.item(0).nodeName, 'bspec'); - } - - h += '
'; - } - - h += '

Fields marked in gray is not cross browser and should be used with care.

'; - h += '

Fields marked red are marked deprecated and will be removed in the future.


'; - - se.innerHTML = h; -} - -function addRenderInfo(n, v, c) { - return '
'; - - for (sn in inst.settings) { - v = inst.settings[sn]; - - h += ''; - } - - h += '
' + tinyMCE.xmlEncode(sn) + '
'; - } - - se.innerHTML = h; -} - -function renderContent() { - var se = document.getElementById('content'), n, inst, h = ''; - - for (n in tinyMCE.instances) { - inst = tinyMCE.instances[n]; - - if (!tinyMCE.isInstance(inst)) - continue; - - h += '

Instance id: ' + inst.editorId + '

'; - - h += '

Start content - inst.startContent:

'; - h += '
' + tinyMCE.xmlEncode(inst.startContent) + '
'; - - h += '

Raw content - inst.getBody().innerHTML or inst.getHTML(true):

'; - h += '
' + tinyMCE.xmlEncode(inst.getHTML(true)) + '
'; - - h += '

Cleaned content - inst.getHTML():

'; - h += '
' + tinyMCE.xmlEncode(inst.getHTML()) + '
'; - - if (inst.serializedHTML) { - h += '

Serialized HTML content - inst.serializedHTML:

'; - h += '
' + tinyMCE.xmlEncode(inst.serializedHTML) + '
'; - } - } - - se.innerHTML = h; -} - -function renderCommandStates() { - var se = document.getElementById('command_states'), n, inst, h = '', v, ex; - var cmds = new Array('2D-Position','AbsolutePosition','BackColor','BlockDirLTR','BlockDirRTL','Bold','BrowseMode','Copy','CreateBookmark','CreateLink','Cut','Delete','DirLTR','DirRTL','EditMode','enableInlineTableEditing','enableObjectResizing','FontName','FontSize','ForeColor','FormatBlock','Indent','InsertButton','InsertFieldset','InsertHorizontalRule','InsertIFrame','InsertImage','InsertInputButton','InsertInputCheckbox','InsertInputFileUpload','InsertInputHidden','InsertInputImage','InsertInputPassword','InsertInputRadio','InsertInputReset','InsertInputSubmit','InsertInputText','InsertMarquee','InsertOrderedList','InsertParagraph','InsertSelectDropdown','InsertSelectListbox','InsertTextArea','InsertUnorderedList','Italic','JustifyCenter','JustifyFull','JustifyLeft','JustifyNone','JustifyRight','LiveResize','MultipleSelection','Open','Outdent','OverWrite','Paste','PlayImage','Redo','Refresh','RemoveFormat','SaveAs','SelectAll','SizeToControl','SizeToControlHeight','SizeToControlWidth','Stop','StopImage','StrikeThrough','styleWithCSS','Subscript','Superscript','UnBookmark','Underline','Undo','Unlink','Unselect'), i; - - for (n in tinyMCE.instances) { - inst = tinyMCE.instances[n]; - - if (!tinyMCE.isInstance(inst)) - continue; - - h += '

Instance id: ' + inst.editorId + '

'; - h += ''; - - for (i=0; i'; - } - - h += '
'; - } - - se.innerHTML = h; -} - -function renderUndoRedo() { - var se = document.getElementById('undo_redo'), inst, n, h = '', i, le, id, d, ur; - var f = document.forms[0]; - - if (tinyMCE.undoLevels) { - le = tinyMCE.undoLevels; - - h += '

Global undo/redo

'; - h += ''; - h += ''; - h += ''; - h += '
undoLevels.length' + le.length + '
undoIndex' + tinyMCE.undoIndex + '
'; - - for (i=0; i'; - } - - for (n in tinyMCE.instances) { - inst = tinyMCE.instances[n]; - - if (!tinyMCE.isInstance(inst)) - continue; - - ur = inst.undoRedo; - le = ur.undoLevels; - - h += '

Instance id: ' + inst.editorId + '

'; - h += ''; - h += ''; - h += ''; - h += ''; - h += ''; - h += '
undoLevels.length' + le.length + '
undoIndex' + ur.undoIndex + '
typingUndoIndex' + ur.typingUndoIndex + '
undoRedo' + ur.undoRedo + '
'; - - for (i=0; i'; - h += '
' + tinyMCE.xmlEncode(le[i].content) + '
'; - - if (i > 0 && f.undo_diff.checked) { - d = diff_main(i > 0 ? le[i-1].content.replace(/[\r\n]+/g, '') : null, le[i].content.replace(/[\r\n]+/g, ''), false); - diff_cleanup_semantic(d); - h += '

Diff ' + (i-1) + ',' + i + '

' + diff_prettyhtml(d) + '
'; - } - } - } - - se.innerHTML = h; -} - -function clearLog() { - document.getElementById('log').innerHTML = ''; - devkit._startTime = null; -} - -function cancelAction() { - parent.document.getElementById('devkit').style.display = 'none'; -} - -function toggleDebugEvents(s) { - devkit._debugEvents(s); -} - -function storeSelection() { - book = tinyMCE.selectedInstance.selection.getBookmark(); - - return false; -} - -function restoreSelection() { - tinyMCE.selectedInstance.selection.moveToBookmark(book); - - return false; -} \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/devkit/jscripts/diff.js --- a/includes/clientside/tinymce/plugins/devkit/jscripts/diff.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1192 +0,0 @@ -// Diff_Match_Patch v1.3 -// Computes the difference between two texts to create a patch. -// Applies the patch onto another text, allowing for errors. -// Copyright (C) 2006 Neil Fraser -// http://neil.fraser.name/software/diff_match_patch/ - -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// 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 (www.gnu.org) for more details. - - -// Constants. -// Redefine these in your program to override the defaults. - -// Number of seconds to map a diff before giving up. (0 for infinity) -var DIFF_TIMEOUT = 1.0; -// Cost of an empty edit operation in terms of edit characters. -var DIFF_EDIT_COST = 4; -// Tweak the relative importance (0.0 = accuracy, 1.0 = proximity) -var MATCH_BALANCE = 0.5; -// At what point is no match declared (0.0 = perfection, 1.0 = very loose) -var MATCH_THRESHOLD = 0.5; -// The min and max cutoffs used when computing text lengths. -var MATCH_MINLENGTH = 100; -var MATCH_MAXLENGTH = 1000; -// Chunk size for context length. -var PATCH_MARGIN = 4; - - - ////////////////////////////////////////////////////////////////////// - // Diff // -////////////////////////////////////////////////////////////////////// - -// The data structure representing a diff is an array of tuples: -// [[-1, "Hello"], [1, "Goodbye"], [0, " world."]] -// which means: delete "Hello", add "Goodbye" and keep " world." - - -function diff_main(text1, text2, checklines) { - // Find the differences between two texts. Return an array of changes. - // If checklines is present and false, then don't run a line-level diff first to identify the changed areas. - // Check for equality (speedup) - if (text1 == text2) - return [[0, text1]]; - - if (typeof checklines == 'undefined') - checklines = true; - - var a; - // Trim off common prefix (speedup) - a = diff_prefix(text1, text2); - text1 = a[0]; - text2 = a[1]; - var commonprefix = a[2]; - - // Trim off common suffix (speedup) - a = diff_suffix(text1, text2); - text1 = a[0]; - text2 = a[1]; - var commonsuffix = a[2]; - - var diff, i; - var longtext = text1.length > text2.length ? text1 : text2; - var shorttext = text1.length > text2.length ? text2 : text1; - - if (!text1) { // Just add some text (speedup) - diff = [[1, text2]]; - } else if (!text2) { // Just delete some text (speedup) - diff = [[-1, text1]]; - } else if ((i = longtext.indexOf(shorttext)) != -1) { - // Shorter text is inside the longer text (speedup) - diff = [[1, longtext.substring(0, i)], [0, shorttext], [1, longtext.substring(i+shorttext.length)]]; - // Swap insertions for deletions if diff is reversed. - if (text1.length > text2.length) - diff[0][0] = diff[2][0] = -1; - } else { - longtext = shorttext = null; // Garbage collect - // Check to see if the problem can be split in two. - var hm = diff_halfmatch(text1, text2); - if (hm) { - // A half-match was found, sort out the return data. - var text1_a = hm[0]; - var text1_b = hm[1]; - var text2_a = hm[2]; - var text2_b = hm[3]; - var mid_common = hm[4]; - // Send both pairs off for separate processing. - var diff_a = diff_main(text1_a, text2_a, checklines); - var diff_b = diff_main(text1_b, text2_b, checklines); - // Merge the results. - diff = diff_a.concat([[0, mid_common]], diff_b); - } else { - // Perform a real diff. - if (checklines && text1.length + text2.length < 250) - checklines = false; // Too trivial for the overhead. - if (checklines) { - // Scan the text on a line-by-line basis first. - a = diff_lines2chars(text1, text2); - text1 = a[0]; - text2 = a[1]; - var linearray = a[2]; - } - diff = diff_map(text1, text2); - if (!diff) // No acceptable result. - diff = [[-1, text1], [1, text2]]; - if (checklines) { - diff_chars2lines(diff, linearray); // Convert the diff back to original text. - diff_cleanup_semantic(diff); // Eliminate freak matches (e.g. blank lines) - - // Rediff any replacement blocks, this time on character-by-character basis. - diff.push([0, '']); // Add a dummy entry at the end. - var pointer = 0; - var count_delete = 0; - var count_insert = 0; - var text_delete = ''; - var text_insert = ''; - while(pointer < diff.length) { - if (diff[pointer][0] == 1) { - count_insert++; - text_insert += diff[pointer][1]; - } else if (diff[pointer][0] == -1) { - count_delete++; - text_delete += diff[pointer][1]; - } else { // Upon reaching an equality, check for prior redundancies. - if (count_delete >= 1 && count_insert >= 1) { - // Delete the offending records and add the merged ones. - a = diff_main(text_delete, text_insert, false); - diff.splice(pointer - count_delete - count_insert, count_delete + count_insert); - pointer = pointer - count_delete - count_insert; - for (i=a.length-1; i>=0; i--) - diff.splice(pointer, 0, a[i]); - pointer = pointer + a.length; - } - count_insert = 0; - count_delete = 0; - text_delete = ''; - text_insert = ''; - } - pointer++; - } - diff.pop(); // Remove the dummy entry at the end. - - } - } - } - - if (commonprefix) - diff.unshift([0, commonprefix]); - if (commonsuffix) - diff.push([0, commonsuffix]); - diff_cleanup_merge(diff); - return diff; -} - - -function diff_lines2chars(text1, text2) { - // Split text into an array of strings. - // Reduce the texts to a string of hashes where each character represents one line. - var linearray = new Array(); // linearray[4] == "Hello\n" - var linehash = new Object(); // linehash["Hello\n"] == 4 - - // "\x00" is a valid JavaScript character, but the Venkman debugger doesn't like it (bug 335098) - // So we'll insert a junk entry to avoid generating a null character. - linearray.push(''); - - function diff_lines2chars_munge(text) { - // My first ever closure! - var i, line; - var chars = ''; - while (text) { - i = text.indexOf('\n'); - if (i == -1) - i = text.length; - line = text.substring(0, i+1); - text = text.substring(i+1); - if (linehash.hasOwnProperty ? linehash.hasOwnProperty(line) : (linehash[line] !== undefined)) { - chars += String.fromCharCode(linehash[line]); - } else { - linearray.push(line); - linehash[line] = linearray.length - 1; - chars += String.fromCharCode(linearray.length - 1); - } - } - return chars; - } - - var chars1 = diff_lines2chars_munge(text1); - var chars2 = diff_lines2chars_munge(text2); - return [chars1, chars2, linearray]; -} - - -function diff_chars2lines(diff, linearray) { - // Rehydrate the text in a diff from a string of line hashes to real lines of text. - var chars, text; - for (var x=0; x 0 && now.getTime() > ms_end) // Timeout reached - return null; - - // Walk the front path one step. - v_map1[d] = new Object(); - for (var k=-d; k<=d; k+=2) { - if (k == -d || k != d && v1[k-1] < v1[k+1]) - x = v1[k+1]; - else - x = v1[k-1]+1; - y = x - k; - footstep = x+","+y; - if (front && (hasOwnProperty ? footsteps.hasOwnProperty(footstep) : (footsteps[footstep] !== undefined))) - done = true; - if (!front) - footsteps[footstep] = d; - while (!done && x < text1.length && y < text2.length && text1.charAt(x) == text2.charAt(y)) { - x++; y++; - footstep = x+","+y; - if (front && (hasOwnProperty ? footsteps.hasOwnProperty(footstep) : (footsteps[footstep] !== undefined))) - done = true; - if (!front) - footsteps[footstep] = d; - } - v1[k] = x; - v_map1[d][x+","+y] = true; - if (done) { - // Front path ran over reverse path. - v_map2 = v_map2.slice(0, footsteps[footstep]+1); - var a = diff_path1(v_map1, text1.substring(0, x), text2.substring(0, y)); - return a.concat(diff_path2(v_map2, text1.substring(x), text2.substring(y))); - } - } - - // Walk the reverse path one step. - v_map2[d] = new Object(); - for (var k=-d; k<=d; k+=2) { - if (k == -d || k != d && v2[k-1] < v2[k+1]) - x = v2[k+1]; - else - x = v2[k-1]+1; - y = x - k; - footstep = (text1.length-x)+","+(text2.length-y); - if (!front && (hasOwnProperty ? footsteps.hasOwnProperty(footstep) : (footsteps[footstep] !== undefined))) - done = true; - if (front) - footsteps[footstep] = d; - while (!done && x < text1.length && y < text2.length && text1.charAt(text1.length-x-1) == text2.charAt(text2.length-y-1)) { - x++; y++; - footstep = (text1.length-x)+","+(text2.length-y); - if (!front && (hasOwnProperty ? footsteps.hasOwnProperty(footstep) : (footsteps[footstep] !== undefined))) - done = true; - if (front) - footsteps[footstep] = d; - } - v2[k] = x; - v_map2[d][x+","+y] = true; - if (done) { - // Reverse path ran over front path. - v_map1 = v_map1.slice(0, footsteps[footstep]+1); - var a = diff_path1(v_map1, text1.substring(0, text1.length-x), text2.substring(0, text2.length-y)); - return a.concat(diff_path2(v_map2, text1.substring(text1.length-x), text2.substring(text2.length-y))); - } - } - } - // Number of diffs equals number of characters, no commonality at all. - return null; -} - - -function diff_path1(v_map, text1, text2) { - // Work from the middle back to the start to determine the path. - var path = []; - var x = text1.length; - var y = text2.length; - var last_op = null; - for (var d=v_map.length-2; d>=0; d--) { - while(1) { - if (v_map[d].hasOwnProperty ? v_map[d].hasOwnProperty((x-1)+","+y) : (v_map[d][(x-1)+","+y] !== undefined)) { - x--; - if (last_op === -1) - path[0][1] = text1.charAt(x) + path[0][1]; - else - path.unshift([-1, text1.charAt(x)]); - last_op = -1; - break; - } else if (v_map[d].hasOwnProperty ? v_map[d].hasOwnProperty(x+","+(y-1)) : (v_map[d][x+","+(y-1)] !== undefined)) { - y--; - if (last_op === 1) - path[0][1] = text2.charAt(y) + path[0][1]; - else - path.unshift([1, text2.charAt(y)]); - last_op = 1; - break; - } else { - x--; - y--; - //if (text1.charAt(x) != text2.charAt(y)) - // return alert("No diagonal. Can't happen. (diff_path1)"); - if (last_op === 0) - path[0][1] = text1.charAt(x) + path[0][1]; - else - path.unshift([0, text1.charAt(x)]); - last_op = 0; - } - } - } - return path; -} - - -function diff_path2(v_map, text1, text2) { - // Work from the middle back to the end to determine the path. - var path = []; - var x = text1.length; - var y = text2.length; - var last_op = null; - for (var d=v_map.length-2; d>=0; d--) { - while(1) { - if (v_map[d].hasOwnProperty ? v_map[d].hasOwnProperty((x-1)+","+y) : (v_map[d][(x-1)+","+y] !== undefined)) { - x--; - if (last_op === -1) - path[path.length-1][1] += text1.charAt(text1.length-x-1); - else - path.push([-1, text1.charAt(text1.length-x-1)]); - last_op = -1; - break; - } else if (v_map[d].hasOwnProperty ? v_map[d].hasOwnProperty(x+","+(y-1)) : (v_map[d][x+","+(y-1)] !== undefined)) { - y--; - if (last_op === 1) - path[path.length-1][1] += text2.charAt(text2.length-y-1); - else - path.push([1, text2.charAt(text2.length-y-1)]); - last_op = 1; - break; - } else { - x--; - y--; - //if (text1.charAt(text1.length-x-1) != text2.charAt(text2.length-y-1)) - // return alert("No diagonal. Can't happen. (diff_path2)"); - if (last_op === 0) - path[path.length-1][1] += text1.charAt(text1.length-x-1); - else - path.push([0, text1.charAt(text1.length-x-1)]); - last_op = 0; - } - } - } - return path; -} - - -function diff_prefix(text1, text2) { - // Trim off common prefix - var pointermin = 0; - var pointermax = Math.min(text1.length, text2.length); - var pointermid = pointermax; - while(pointermin < pointermid) { - if (text1.substring(0, pointermid) == text2.substring(0, pointermid)) - pointermin = pointermid; - else - pointermax = pointermid; - pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); - } - var commonprefix = text1.substring(0, pointermid); - text1 = text1.substring(pointermid); - text2 = text2.substring(pointermid); - return [text1, text2, commonprefix]; -} - - -function diff_suffix(text1, text2) { - // Trim off common suffix - var pointermin = 0; - var pointermax = Math.min(text1.length, text2.length); - var pointermid = pointermax; - while(pointermin < pointermid) { - if (text1.substring(text1.length-pointermid) == text2.substring(text2.length-pointermid)) - pointermin = pointermid; - else - pointermax = pointermid; - pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin); - } - var commonsuffix = text1.substring(text1.length-pointermid); - text1 = text1.substring(0, text1.length-pointermid); - text2 = text2.substring(0, text2.length-pointermid); - return [text1, text2, commonsuffix]; -} - - -function diff_halfmatch(text1, text2) { - // Do the two texts share a substring which is at least half the length of the longer text? - var longtext = text1.length > text2.length ? text1 : text2; - var shorttext = text1.length > text2.length ? text2 : text1; - if (longtext.length < 10 || shorttext.length < 1) - return null; // Pointless. - - function diff_halfmatch_i(longtext, shorttext, i) { - // Start with a 1/4 length substring at position i as a seed. - var seed = longtext.substring(i, i+Math.floor(longtext.length/4)); - var j = -1; - var best_common = ''; - var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b; - while ((j = shorttext.indexOf(seed, j+1)) != -1) { - var my_prefix = diff_prefix(longtext.substring(i), shorttext.substring(j)); - var my_suffix = diff_suffix(longtext.substring(0, i), shorttext.substring(0, j)); - if (best_common.length < (my_suffix[2] + my_prefix[2]).length) { - best_common = my_suffix[2] + my_prefix[2]; - best_longtext_a = my_suffix[0]; - best_longtext_b = my_prefix[0]; - best_shorttext_a = my_suffix[1]; - best_shorttext_b = my_prefix[1]; - } - } - if (best_common.length >= longtext.length/2) - return [best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b, best_common]; - else - return null; - } - - // First check if the second quarter is the seed for a half-match. - var hm1 = diff_halfmatch_i(longtext, shorttext, Math.ceil(longtext.length/4)); - // Check again based on the third quarter. - var hm2 = diff_halfmatch_i(longtext, shorttext, Math.ceil(longtext.length/2)); - var hm; - if (!hm1 && !hm2) - return null; - else if (!hm2) - hm = hm1; - else if (!hm1) - hm = hm2; - else // Both matched. Select the longest. - hm = hm1[4].length > hm2[4].length ? hm1 : hm2; - - // A half-match was found, sort out the return data. - if (text1.length > text2.length) { - var text1_a = hm[0]; - var text1_b = hm[1]; - var text2_a = hm[2]; - var text2_b = hm[3]; - } else { - var text2_a = hm[0]; - var text2_b = hm[1]; - var text1_a = hm[2]; - var text1_b = hm[3]; - } - var mid_common = hm[4]; - return [text1_a, text1_b, text2_a, text2_b, mid_common]; -} - - -function diff_cleanup_semantic(diff) { - // Reduce the number of edits by eliminating semantically trivial equalities. - var changes = false; - var equalities = []; // Stack of indices where equalities are found. - var lastequality = null; // Always equal to equalities[equalities.length-1][1] - var pointer = 0; // Index of current position. - var length_changes1 = 0; // Number of characters that changed prior to the equality. - var length_changes2 = 0; // Number of characters that changed after the equality. - while (pointer < diff.length) { - if (diff[pointer][0] == 0) { // equality found - equalities.push(pointer); - length_changes1 = length_changes2; - length_changes2 = 0; - lastequality = diff[pointer][1]; - } else { // an insertion or deletion - length_changes2 += diff[pointer][1].length; - if (lastequality != null && (lastequality.length <= length_changes1) && (lastequality.length <= length_changes2)) { - //alert("Splitting: '"+lastequality+"'"); - diff.splice(equalities[equalities.length-1], 0, [-1, lastequality]); // Duplicate record - diff[equalities[equalities.length-1]+1][0] = 1; // Change second copy to insert. - equalities.pop(); // Throw away the equality we just deleted; - equalities.pop(); // Throw away the previous equality; - pointer = equalities.length ? equalities[equalities.length-1] : -1; - length_changes1 = 0; // Reset the counters. - length_changes2 = 0; - lastequality = null; - changes = true; - } - } - pointer++; - } - - if (changes) - diff_cleanup_merge(diff); -} - - -function diff_cleanup_efficiency(diff) { - // Reduce the number of edits by eliminating operationally trivial equalities. - var changes = false; - var equalities = []; // Stack of indices where equalities are found. - var lastequality = ''; // Always equal to equalities[equalities.length-1][1] - var pointer = 0; // Index of current position. - var pre_ins = false; // Is there an insertion operation before the last equality. - var pre_del = false; // Is there an deletion operation before the last equality. - var post_ins = false; // Is there an insertion operation after the last equality. - var post_del = false; // Is there an deletion operation after the last equality. - while (pointer < diff.length) { - if (diff[pointer][0] == 0) { // equality found - if (diff[pointer][1].length < DIFF_EDIT_COST && (post_ins || post_del)) { - // Candidate found. - equalities.push(pointer); - pre_ins = post_ins; - pre_del = post_del; - lastequality = diff[pointer][1]; - } else { - // Not a candidate, and can never become one. - equalities = []; - lastequality = ''; - } - post_ins = post_del = false; - } else { // an insertion or deletion - if (diff[pointer][0] == -1) - post_del = true; - else - post_ins = true; - // Five types to be split: - // ABXYCD - // AXCD - // ABXC - // AXCD - // ABXC - if (lastequality && ((pre_ins && pre_del && post_ins && post_del) || ((lastequality.length < DIFF_EDIT_COST/2) && (pre_ins + pre_del + post_ins + post_del) == 3))) { - //alert("Splitting: '"+lastequality+"'"); - diff.splice(equalities[equalities.length-1], 0, [-1, lastequality]); // Duplicate record - diff[equalities[equalities.length-1]+1][0] = 1; // Change second copy to insert. - equalities.pop(); // Throw away the equality we just deleted; - lastequality = ''; - if (pre_ins && pre_del) { - // No changes made which could affect previous entry, keep going. - post_ins = post_del = true; - equalities = []; - } else { - equalities.pop(); // Throw away the previous equality; - pointer = equalities.length ? equalities[equalities.length-1] : -1; - post_ins = post_del = false; - } - changes = true; - } - } - pointer++; - } - - if (changes) - diff_cleanup_merge(diff); -} - - -function diff_cleanup_merge(diff) { - // Reorder and merge like edit sections. Merge equalities. - // Any edit section can move as long as it doesn't cross an equality. - diff.push([0, '']); // Add a dummy entry at the end. - var pointer = 0; - var count_delete = 0; - var count_insert = 0; - var text_delete = ''; - var text_insert = ''; - var record_insert, record_delete; - var my_xfix; - while(pointer < diff.length) { - if (diff[pointer][0] == 1) { - count_insert++; - text_insert += diff[pointer][1]; - pointer++; - } else if (diff[pointer][0] == -1) { - count_delete++; - text_delete += diff[pointer][1]; - pointer++; - } else { // Upon reaching an equality, check for prior redundancies. - if (count_delete > 1 || count_insert > 1) { - if (count_delete > 1 && count_insert > 1) { - // Factor out any common prefixies. - my_xfix = diff_prefix(text_insert, text_delete); - if (my_xfix[2] != '') { - if ((pointer - count_delete - count_insert) > 0 && diff[pointer - count_delete - count_insert - 1][0] == 0) { - text_insert = my_xfix[0]; - text_delete = my_xfix[1]; - diff[pointer - count_delete - count_insert - 1][1] += my_xfix[2]; - } - } - // Factor out any common suffixies. - my_xfix = diff_suffix(text_insert, text_delete); - if (my_xfix[2] != '') { - text_insert = my_xfix[0]; - text_delete = my_xfix[1]; - diff[pointer][1] = my_xfix[2] + diff[pointer][1]; - } - } - // Delete the offending records and add the merged ones. - if (count_delete == 0) - diff.splice(pointer - count_delete - count_insert, count_delete + count_insert, [1, text_insert]); - else if (count_insert == 0) - diff.splice(pointer - count_delete - count_insert, count_delete + count_insert, [-1, text_delete]); - else - diff.splice(pointer - count_delete - count_insert, count_delete + count_insert, [-1, text_delete], [1, text_insert]); - pointer = pointer - count_delete - count_insert + (count_delete ? 1 : 0) + (count_insert ? 1 : 0) + 1; - } else if (pointer != 0 && diff[pointer-1][0] == 0) { - // Merge this equality with the previous one. - diff[pointer-1][1] += diff[pointer][1]; - diff.splice(pointer, 1); - } else { - pointer++; - } - count_insert = 0; - count_delete = 0; - text_delete = ''; - text_insert = ''; - } - } - if (diff[diff.length-1][1] == '') - diff.pop(); // Remove the dummy entry at the end. -} - - -function diff_addindex(diff) { - // Add an index to each tuple, represents where the tuple is located in text2. - // e.g. [[-1, 'h', 0], [1, 'c', 0], [0, 'at', 1]] - var i = 0; - for (var x=0; x1, 5->8 - var chars1 = 0; - var chars2 = 0; - var last_chars1 = 0; - var last_chars2 = 0; - for (var x=0; x loc) // Overshot the location. - break; - last_chars1 = chars1; - last_chars2 = chars2; - } - if (diff.length != x && diff[x][0] == -1) // The location was deleted. - return last_chars2; - // Add the remaining character length. - return last_chars2 + (loc - last_chars1); -} - - -function diff_prettyhtml(diff) { - // Convert a diff array into a pretty HTML report. - diff_addindex(diff); - var html = ''; - for (var x=0; x/g, ">"); - t = t.replace(/\n/g, "¶
"); - if (m == -1) - html += ""+t+""; - else if (m == 1) - html += ""+t+""; - else - html += ""+t+""; - } - return html; -} - - - ////////////////////////////////////////////////////////////////////// - // Match // -////////////////////////////////////////////////////////////////////// - - -function match_getmaxbits() { - // Compute the number of bits in an int. - // The normal answer for JavaScript is 32. - var maxbits = 0; - var oldi = 1; - var newi = 2; - while (oldi != newi) { - maxbits++; - oldi = newi; - newi = newi << 1; - } - return maxbits; -} -var MATCH_MAXBITS = match_getmaxbits(); - - -function match_main(text, pattern, loc) { - // Locate the best instance of 'pattern' in 'text' near 'loc'. - loc = Math.max(0, Math.min(loc, text.length-pattern.length)); - if (text == pattern) { - // Shortcut (potentially not guaranteed by the algorithm) - return 0; - } else if (text.length == 0) { - // Nothing to match. - return null; - } else if (text.substring(loc, loc + pattern.length) == pattern) { - // Perfect match at the perfect spot! (Includes case of null pattern) - return loc; - } else { - // Do a fuzzy compare. - var match = match_bitap(text, pattern, loc); - return match; - } -} - - -function match_bitap(text, pattern, loc) { - // Locate the best instance of 'pattern' in 'text' near 'loc' using the Bitap algorithm. - if (pattern.length > MATCH_MAXBITS) - return alert("Pattern too long for this browser."); - - // Initialise the alphabet. - var s = match_alphabet(pattern); - - var score_text_length = text.length; - // Coerce the text length between reasonable maximums and minimums. - score_text_length = Math.max(score_text_length, MATCH_MINLENGTH); - score_text_length = Math.min(score_text_length, MATCH_MAXLENGTH); - - function match_bitap_score (e, x) { - // Compute and return the score for a match with e errors and x location. - var d = Math.abs(loc-x); - return (e / pattern.length / MATCH_BALANCE) + (d / score_text_length / (1.0 - MATCH_BALANCE)); - } - - // Highest score beyond which we give up. - var score_threshold = MATCH_THRESHOLD; - // Is there a nearby exact match? (speedup) - var best_loc = text.indexOf(pattern, loc); - if (best_loc != -1) - score_threshold = Math.min(match_bitap_score(0, best_loc), score_threshold); - // What about in the other direction? (speedup) - best_loc = text.lastIndexOf(pattern, loc+pattern.length); - if (best_loc != -1) - score_threshold = Math.min(match_bitap_score(0, best_loc), score_threshold); - - // Initialise the bit arrays. - var r = Array(); - var d = -1; - var matchmask = Math.pow(2, pattern.length-1); - best_loc = null; - - var bin_min, bin_mid; - var bin_max = Math.max(loc+loc, text.length); - var last_rd; - for (var d=0; d=start; j--) { - // The alphabet (s) is a sparse hash, so the following lines generate warnings. - if (d == 0) // First pass: exact match. - rd[j] = ((rd[j+1] << 1) | 1) & s[text.charAt(j)]; - else // Subsequent passes: fuzzy match. - rd[j] = ((rd[j+1] << 1) | 1) & s[text.charAt(j)] | ((last_rd[j+1] << 1) | 1) | ((last_rd[j] << 1) | 1) | last_rd[j+1]; - if (rd[j] & matchmask) { - var score = match_bitap_score(d, j); - // This match will almost certainly be better than any existing match. But check anyway. - if (score <= score_threshold) { - // Told you so. - score_threshold = score; - best_loc = j; - if (j > loc) { - // When passing loc, don't exceed our current distance from loc. - start = Math.max(0, loc - (j - loc)); - } else { - // Already passed loc, downhill from here on in. - break; - } - } - } - } - if (match_bitap_score(d+1, loc) > score_threshold) // No hope for a (better) match at greater error levels. - break; - last_rd = rd; - } - return best_loc; -} - - -function match_alphabet(pattern) { - // Initialise the alphabet for the Bitap algorithm. - var s = Object(); - for (var i=0; i 2) { - diff_cleanup_semantic(diff); - diff_cleanup_efficiency(diff); - } - } - if (diff.length == 0) - return []; // Get rid of the null case. - var patches = []; - var patch = new patch_obj(); - var char_count1 = 0; // Number of characters into the text1 string. - var char_count2 = 0; // Number of characters into the text2 string. - var last_type = null; - var prepatch_text = text1; // Recreate the patches to determine context info. - var postpatch_text = text1; - for (var x=0; x= 2*PATCH_MARGIN) { - // Time for a new patch. - if (patch.diffs.length != 0) { - patch_addcontext(patch, prepatch_text); - patches.push(patch); - var patch = new patch_obj(); - last_type = null; - prepatch_text = postpatch_text; - } - } - - // Update the current character count. - if (diff_type != 1) - char_count1 += diff_text.length; - if (diff_type != -1) - char_count2 += diff_text.length; - } - // Pick up the leftover patch if not empty. - if (patch.diffs.length != 0) { - patch_addcontext(patch, prepatch_text); - patches.push(patch); - } - - return patches; -} - - -function patch_apply(patches, text) { - // Merge a set of patches onto the text. - // Return a patched text, as well as a list of true/false values indicating which patches were applied. - patch_splitmax(patches); - var results = []; - var delta = 0; - var expected_loc, start_loc; - var text1, text2; - var diff, mod, index1, index2; - for (var x=0; x MATCH_MAXBITS) { - bigpatch = patches[x]; - // Remove the big old patch. - patches.splice(x, 1); - patch_size = MATCH_MAXBITS; - start1 = bigpatch.start1; - start2 = bigpatch.start2; - precontext = ''; - while (bigpatch.diffs.length != 0) { - // Create one of several smaller patches. - patch = new patch_obj(); - empty = true; - patch.start1 = start1 - precontext.length; - patch.start2 = start2 - precontext.length; - if (precontext != '') { - patch.length1 = patch.length2 = precontext.length; - patch.diffs.push([0, precontext]); - } - while (bigpatch.diffs.length != 0 && patch.length1 < patch_size - PATCH_MARGIN) { - diff_type = bigpatch.diffs[0][0]; - diff_text = bigpatch.diffs[0][1]; - if (diff_type == 1) { - // Insertions are harmless. - patch.length2 += diff_text.length; - start2 += diff_text.length; - patch.diffs.push(bigpatch.diffs.shift()); - empty = false; - } else { - // Deletion or equality. Only take as much as we can stomach. - diff_text = diff_text.substring(0, patch_size - patch.length1 - PATCH_MARGIN); - patch.length1 += diff_text.length; - start1 += diff_text.length; - if (diff_type == 0) { - patch.length2 += diff_text.length; - start2 += diff_text.length; - } else { - empty = false; - } - patch.diffs.push([diff_type, diff_text]); - if (diff_text == bigpatch.diffs[0][1]) - bigpatch.diffs.shift(); - else - bigpatch.diffs[0][1] = bigpatch.diffs[0][1].substring(diff_text.length); - } - } - // Compute the head context for the next patch. - precontext = patch.text2(); - precontext = precontext.substring(precontext.length - PATCH_MARGIN); - // Append the end context for this patch. - postcontext = bigpatch.text1().substring(0, PATCH_MARGIN); - if (postcontext != '') { - patch.length1 += postcontext.length; - patch.length2 += postcontext.length; - if (patch.diffs.length > 0 && patch.diffs[patch.diffs.length-1][0] == 0) - patch.diffs[patch.diffs.length-1][1] += postcontext; - else - patch.diffs.push([0, postcontext]); - } - if (!empty) - patches.splice(x++, 0, patch); - } - } - } -} - - -function patch_totext(patches) { - // Take a list of patches and return a textual representation. - var text = ''; - for (var x=0; x - {$lang_emotions_title} - - + {#emotions_dlg.title} + + - +
-
{$lang_emotions_title}:

+
{#emotions_dlg.title}:

- - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + +
{$lang_emotions_cool}{$lang_emotions_cry}{$lang_emotions_embarassed}{$lang_emotions_foot_in_mouth}{#emotions_dlg.cool}{#emotions_dlg.cry}{#emotions_dlg.embarassed}{#emotions_dlg.foot_in_mouth}
{$lang_emotions_frown}{$lang_emotions_innocent}{$lang_emotions_kiss}{$lang_emotions_laughing}{#emotions_dlg.frown}{#emotions_dlg.innocent}{#emotions_dlg.kiss}{#emotions_dlg.laughing}
{$lang_emotions_money_mouth}{$lang_emotions_sealed}{$lang_emotions_smile}{$lang_emotions_surprised}{#emotions_dlg.money_mouth}{#emotions_dlg.sealed}{#emotions_dlg.smile}{#emotions_dlg.surprised}
{$lang_emotions_tongue-out}{$lang_emotions_undecided}{$lang_emotions_wink}{$lang_emotions_yell}{#emotions_dlg.tongue-out}{#emotions_dlg.undecided}{#emotions_dlg.wink}{#emotions_dlg.yell}
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/emotions.gif Binary file includes/clientside/tinymce/plugins/emotions/images/emotions.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/readme.txt --- a/includes/clientside/tinymce/plugins/emotions/images/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -These emotions where taken from Mozilla Thunderbird. -I hope they don't get angry if I use them here after all this is a open source project aswell. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-cool.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-cool.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-cry.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-cry.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-embarassed.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-embarassed.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-foot-in-mouth.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-foot-in-mouth.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-frown.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-frown.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-innocent.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-innocent.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-kiss.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-kiss.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-laughing.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-laughing.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-money-mouth.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-money-mouth.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-sealed.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-sealed.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-smile.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-smile.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-surprised.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-surprised.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-tongue-out.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-tongue-out.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-undecided.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-undecided.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-wink.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-wink.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/images/smiley-yell.gif Binary file includes/clientside/tinymce/plugins/emotions/images/smiley-yell.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-cool.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-cool.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-cry.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-cry.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-embarassed.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-embarassed.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-foot-in-mouth.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-foot-in-mouth.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-frown.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-frown.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-innocent.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-innocent.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-kiss.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-kiss.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-laughing.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-laughing.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-money-mouth.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-money-mouth.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-sealed.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-sealed.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-smile.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-smile.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-surprised.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-surprised.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-tongue-out.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-tongue-out.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-undecided.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-undecided.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-wink.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-wink.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/img/smiley-yell.gif Binary file includes/clientside/tinymce/plugins/emotions/img/smiley-yell.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/js/emotions.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/emotions/js/emotions.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,22 @@ +tinyMCEPopup.requireLangPack(); + +var EmotionsDialog = { + init : function(ed) { + tinyMCEPopup.resizeToInnerSize(); + }, + + insert : function(file, title) { + var ed = tinyMCEPopup.editor, dom = ed.dom; + + tinyMCEPopup.execCommand('mceInsertContent', false, dom.createHTML('img', { + src : tinyMCEPopup.getWindowArg('plugin_url') + '/img/' + file, + alt : ed.getLang(title), + title : ed.getLang(title), + border : 0 + })); + + tinyMCEPopup.close(); + } +}; + +tinyMCEPopup.onInit.add(EmotionsDialog.init, EmotionsDialog); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/jscripts/functions.js --- a/includes/clientside/tinymce/plugins/emotions/jscripts/functions.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -function init() { - tinyMCEPopup.resizeToInnerSize(); -} - -function insertEmotion(file_name, title) { - title = tinyMCE.getLang(title); - - if (title == null) - title = ""; - - // XML encode - title = title.replace(/&/g, '&'); - title = title.replace(/\"/g, '"'); - title = title.replace(//g, '>'); - - var html = '' + title + ''; - - tinyMCE.execCommand('mceInsertContent', false, html); - tinyMCEPopup.close(); -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/langs/en.js --- a/includes/clientside/tinymce/plugins/emotions/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('emotions',{ -title : 'Insert emotion', -desc : 'Emotions', -cool : 'Cool', -cry : 'Cry', -embarassed : 'Embarassed', -foot_in_mouth : 'Foot in mouth', -frown : 'Frown', -innocent : 'Innocent', -kiss : 'Kiss', -laughing : 'Laughing', -money_mouth : 'Money mouth', -sealed : 'Sealed', -smile : 'Smile', -surprised : 'Surprised', -tongue_out : 'Tongue out', -undecided : 'Undecided', -wink : 'Wink', -yell : 'Yell' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/langs/en_dlg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/emotions/langs/en_dlg.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,20 @@ +tinyMCE.addI18n('en.emotions_dlg',{ +title:"Insert emotion", +desc:"Emotions", +cool:"Cool", +cry:"Cry", +embarassed:"Embarassed", +foot_in_mouth:"Foot in mouth", +frown:"Frown", +innocent:"Innocent", +kiss:"Kiss", +laughing:"Laughing", +money_mouth:"Money mouth", +sealed:"Sealed", +smile:"Smile", +surprised:"Surprised", +tongue_out:"Tongue out", +undecided:"Undecided", +wink:"Wink", +yell:"Yell" +}); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/emotions/readme.txt --- a/includes/clientside/tinymce/plugins/emotions/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/example/dialog.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/example/dialog.htm Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,27 @@ + + + + {#example_dlg.title} + + + + + +
+

Here is a example dialog.

+

Selected text:

+

Custom arg:

+ +
+
+ +
+ +
+ +
+
+
+ + + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/example/editor_plugin.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/example/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,1 @@ +(function(){tinymce.PluginManager.requireLangPack('example');tinymce.create('tinymce.plugins.ExamplePlugin',{init:function(ed,url){ed.addCommand('mceExample',function(){ed.windowManager.open({file:url+'/dialog.htm',width:320+parseInt(ed.getLang('example.delta_width',0)),height:120+parseInt(ed.getLang('example.delta_height',0)),inline:1},{plugin_url:url,some_custom_arg:'custom arg'});});ed.addButton('example',{title:'example.desc',cmd:'mceExample',image:url+'/img/example.gif'});ed.onNodeChange.add(function(ed,cm,n){cm.setActive('example',n.nodeName=='IMG');});},createControl:function(n,cm){return null;},getInfo:function(){return{longname:'Example plugin',author:'Some author',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example',version:"1.0"};}});tinymce.PluginManager.add('example',tinymce.plugins.ExamplePlugin);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/example/editor_plugin_src.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/example/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,81 @@ +/** + * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * + * @author Moxiecode + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ + +(function() { + // Load plugin specific language pack + tinymce.PluginManager.requireLangPack('example'); + + tinymce.create('tinymce.plugins.ExamplePlugin', { + /** + * Initializes the plugin, this will be executed after the plugin has been created. + * This call is done before the editor instance has finished it's initialization so use the onInit event + * of the editor instance to intercept that event. + * + * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in. + * @param {string} url Absolute URL to where the plugin is located. + */ + init : function(ed, url) { + // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample'); + ed.addCommand('mceExample', function() { + ed.windowManager.open({ + file : url + '/dialog.htm', + width : 320 + parseInt(ed.getLang('example.delta_width', 0)), + height : 120 + parseInt(ed.getLang('example.delta_height', 0)), + inline : 1 + }, { + plugin_url : url, // Plugin absolute URL + some_custom_arg : 'custom arg' // Custom argument + }); + }); + + // Register example button + ed.addButton('example', { + title : 'example.desc', + cmd : 'mceExample', + image : url + '/img/example.gif' + }); + + // Add a node change handler, selects the button in the UI when a image is selected + ed.onNodeChange.add(function(ed, cm, n) { + cm.setActive('example', n.nodeName == 'IMG'); + }); + }, + + /** + * Creates control instances based in the incomming name. This method is normally not + * needed since the addButton method of the tinymce.Editor class is a more easy way of adding buttons + * but you sometimes need to create more complex controls like listboxes, split buttons etc then this + * method can be used to create those. + * + * @param {String} n Name of the control to create. + * @param {tinymce.ControlManager} cm Control manager to use inorder to create new control. + * @return {tinymce.ui.Control} New control instance or null if no control was created. + */ + createControl : function(n, cm) { + return null; + }, + + /** + * Returns information about the plugin as a name/value array. + * The current keys are longname, author, authorurl, infourl and version. + * + * @return {Object} Name/value array containing information about the plugin. + */ + getInfo : function() { + return { + longname : 'Example plugin', + author : 'Some author', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example', + version : "1.0" + }; + } + }); + + // Register plugin + tinymce.PluginManager.add('example', tinymce.plugins.ExamplePlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/example/img/example.gif Binary file includes/clientside/tinymce/plugins/example/img/example.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/example/js/dialog.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/example/js/dialog.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,19 @@ +tinyMCEPopup.requireLangPack(); + +var ExampleDialog = { + init : function() { + var f = document.forms[0]; + + // Get the selected contents as text and place it in the input + f.someval.value = tinyMCEPopup.editor.selection.getContent({format : 'text'}); + f.somearg.value = tinyMCEPopup.getWindowArg('some_custom_arg'); + }, + + insert : function() { + // Insert the contents from the input into the document + tinyMCEPopup.editor.execCommand('mceInsertContent', false, document.forms[0].someval.value); + tinyMCEPopup.close(); + } +}; + +tinyMCEPopup.onInit.add(ExampleDialog.init, ExampleDialog); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/example/langs/en.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/example/langs/en.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,3 @@ +tinyMCE.addI18n('en.example',{ + desc : 'This is just a template button' +}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/example/langs/en_dlg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/example/langs/en_dlg.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,3 @@ +tinyMCE.addI18n('en.example_dlg',{ + title : 'This is just a example title' +}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/flash/css/content.css --- a/includes/clientside/tinymce/plugins/flash/css/content.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -.mceItemFlash { - border: 1px dotted #cc0000; - background-image: url('../images/flash.gif'); - background-position: center; - background-repeat: no-repeat; - background-color: #ffffcc; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/flash/css/flash.css --- a/includes/clientside/tinymce/plugins/flash/css/flash.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -.panel_wrapper div.current { - height: 100px; -} - -#width, #height { - width: 50px; -} - -#file { - width: 250px; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/flash/editor_plugin.js --- a/includes/clientside/tinymce/plugins/flash/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -tinyMCE.importPluginLanguagePack('flash');var TinyMCE_FlashPlugin={getInfo:function(){return{longname:'Flash',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/flash',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},initInstance:function(inst){if(!tinyMCE.settings['flash_skip_plugin_css'])tinyMCE.importCSS(inst.getDoc(),tinyMCE.baseURL+"/plugins/flash/css/content.css")},getControlHTML:function(cn){switch(cn){case"flash":return tinyMCE.getButtonHTML(cn,'lang_flash_desc','{$pluginurl}/images/flash.gif','mceFlash')}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mceFlash":var name="",swffile="",swfwidth="",swfheight="",action="insert";var template=new Array();var inst=tinyMCE.getInstanceById(editor_id);var focusElm=inst.getFocusElement();template['file']='../../plugins/flash/flash.htm';template['width']=430;template['height']=175;template['width']+=tinyMCE.getLang('lang_flash_delta_width',0);template['height']+=tinyMCE.getLang('lang_flash_delta_height',0);if(focusElm!=null&&focusElm.nodeName.toLowerCase()=="img"){name=tinyMCE.getAttrib(focusElm,'class');if(name.indexOf('mceItemFlash')==-1)return true;swffile=tinyMCE.getAttrib(focusElm,'alt');if(tinyMCE.getParam('convert_urls'))swffile=eval(tinyMCE.settings['urlconverter_callback']+"(swffile, null, true);");swfwidth=tinyMCE.getAttrib(focusElm,'width');swfheight=tinyMCE.getAttrib(focusElm,'height');action="update"}tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes",swffile:swffile,swfwidth:swfwidth,swfheight:swfheight,action:action});return true}return false},cleanup:function(type,content){switch(type){case"insert_to_editor_dom":if(tinyMCE.getParam('convert_urls')){var imgs=content.getElementsByTagName("img");for(var i=0;i','gi'),'');content=content.replace(new RegExp('<[ ]*object','gi'),'','gi'),'');while((startPos=content.indexOf('',startPos);var attribs=TinyMCE_FlashPlugin._parseAttributes(content.substring(startPos+6,endPos));embedList[embedList.length]=attribs}var index=0;while((startPos=content.indexOf('=embedList.length)break;var attribs=embedList[index];endPos=content.indexOf('',startPos);endPos+=9;var contentAfter=content.substring(endPos);content=content.substring(0,startPos);content+=''+content.substring(endPos);content+=contentAfter;index++;startPos++}var index=0;while((startPos=content.indexOf('=embedList.length)break;var attribs=embedList[index];endPos=content.indexOf('>',startPos);endPos+=9;var contentAfter=content.substring(endPos);content=content.substring(0,startPos);content+=''+content.substring(endPos);content+=contentAfter;index++;startPos++}break;case"get_from_editor":var startPos=-1;while((startPos=content.indexOf('',startPos);var attribs=TinyMCE_FlashPlugin._parseAttributes(content.substring(startPos+4,endPos));if(attribs['class']!="mceItemFlash")continue;endPos+=2;var embedHTML='';var wmode=tinyMCE.getParam("flash_wmode","");var quality=tinyMCE.getParam("flash_quality","high");var menu=tinyMCE.getParam("flash_menu","false");embedHTML+='';embedHTML+='';embedHTML+='';embedHTML+='';embedHTML+='';embedHTML+='';chunkBefore=content.substring(0,startPos);chunkAfter=content.substring(endPos);content=chunkBefore+embedHTML+chunkAfter}break}return content},handleNodeChange:function(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){if(node==null)return;do{if(node.nodeName=="IMG"&&tinyMCE.getAttrib(node,'class').indexOf('mceItemFlash')==0){tinyMCE.switchClass(editor_id+'_flash','mceButtonSelected');return true}}while((node=node.parentNode));tinyMCE.switchClass(editor_id+'_flash','mceButtonNormal');return true},_parseAttributes:function(attribute_string){var attributeName="";var attributeValue="";var withInName;var withInValue;var attributes=new Array();var whiteSpaceRegExp=new RegExp('^[ \n\r\t]+','g');if(attribute_string==null||attribute_string.length<2)return null;withInName=withInValue=false;for(var i=0;i','gi'),''); - content = content.replace(new RegExp('<[ ]*object','gi'),'','gi'),''); - - // Parse all embed tags - while ((startPos = content.indexOf('', startPos); - var attribs = TinyMCE_FlashPlugin._parseAttributes(content.substring(startPos + 6, endPos)); - embedList[embedList.length] = attribs; - } - - // Parse all object tags and replace them with images from the embed data - var index = 0; - while ((startPos = content.indexOf('= embedList.length) - break; - - var attribs = embedList[index]; - - // Find end of object - endPos = content.indexOf('', startPos); - endPos += 9; - - // Insert image - var contentAfter = content.substring(endPos); - content = content.substring(0, startPos); - content += '' + content.substring(endPos); - content += contentAfter; - index++; - - startPos++; - } - - // Parse all embed tags and replace them with images from the embed data - var index = 0; - while ((startPos = content.indexOf('= embedList.length) - break; - - var attribs = embedList[index]; - - // Find end of embed - endPos = content.indexOf('>', startPos); - endPos += 9; - - // Insert image - var contentAfter = content.substring(endPos); - content = content.substring(0, startPos); - content += '' + content.substring(endPos); - content += contentAfter; - index++; - - startPos++; - } - - break; - - case "get_from_editor": - // Parse all img tags and replace them with object+embed - var startPos = -1; - - while ((startPos = content.indexOf('', startPos); - var attribs = TinyMCE_FlashPlugin._parseAttributes(content.substring(startPos + 4, endPos)); - - // Is not flash, skip it - if (attribs['class'] != "mceItemFlash") - continue; - - endPos += 2; - - var embedHTML = ''; - var wmode = tinyMCE.getParam("flash_wmode", ""); - var quality = tinyMCE.getParam("flash_quality", "high"); - var menu = tinyMCE.getParam("flash_menu", "false"); - - // Insert object + embed - embedHTML += ''; - embedHTML += ''; - embedHTML += ''; - embedHTML += ''; - embedHTML += ''; - embedHTML += ''; - - // Insert embed/object chunk - chunkBefore = content.substring(0, startPos); - chunkAfter = content.substring(endPos); - content = chunkBefore + embedHTML + chunkAfter; - } - break; - } - - // Pass through to next handler in chain - return content; - }, - - handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { - if (node == null) - return; - - do { - if (node.nodeName == "IMG" && tinyMCE.getAttrib(node, 'class').indexOf('mceItemFlash') == 0) { - tinyMCE.switchClass(editor_id + '_flash', 'mceButtonSelected'); - return true; - } - } while ((node = node.parentNode)); - - tinyMCE.switchClass(editor_id + '_flash', 'mceButtonNormal'); - - return true; - }, - - // Private plugin internal functions - - _parseAttributes : function(attribute_string) { - var attributeName = ""; - var attributeValue = ""; - var withInName; - var withInValue; - var attributes = new Array(); - var whiteSpaceRegExp = new RegExp('^[ \n\r\t]+', 'g'); - - if (attribute_string == null || attribute_string.length < 2) - return null; - - withInName = withInValue = false; - - for (var i=0; i -
- - -
-
-
- {$lang_flash_general} - - - - - - - - - - - - - - -
- - - - - -
 
-
 
- -  x  - -
-
-
-
- -
-
- -
- -
- -
-
-
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/flash/images/flash.gif Binary file includes/clientside/tinymce/plugins/flash/images/flash.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/flash/jscripts/flash.js --- a/includes/clientside/tinymce/plugins/flash/jscripts/flash.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -var url = tinyMCE.getParam("flash_external_list_url"); -if (url != null) { - // Fix relative - if (url.charAt(0) != '/' && url.indexOf('://') == -1) - url = tinyMCE.documentBasePath + "/" + url; - - document.write(''); -} - -function init() { - tinyMCEPopup.resizeToInnerSize(); - - document.getElementById("filebrowsercontainer").innerHTML = getBrowserHTML('filebrowser','file','flash','flash'); - - // Image list outsrc - var html = getFlashListHTML('filebrowser','file','flash','flash'); - if (html == "") - document.getElementById("linklistrow").style.display = 'none'; - else - document.getElementById("linklistcontainer").innerHTML = html; - - var formObj = document.forms[0]; - var swffile = tinyMCE.getWindowArg('swffile'); - var swfwidth = '' + tinyMCE.getWindowArg('swfwidth'); - var swfheight = '' + tinyMCE.getWindowArg('swfheight'); - - if (swfwidth.indexOf('%')!=-1) { - formObj.width2.value = "%"; - formObj.width.value = swfwidth.substring(0,swfwidth.length-1); - } else { - formObj.width2.value = "px"; - formObj.width.value = swfwidth; - } - - if (swfheight.indexOf('%')!=-1) { - formObj.height2.value = "%"; - formObj.height.value = swfheight.substring(0,swfheight.length-1); - } else { - formObj.height2.value = "px"; - formObj.height.value = swfheight; - } - - formObj.file.value = swffile; - formObj.insert.value = tinyMCE.getLang('lang_' + tinyMCE.getWindowArg('action'), 'Insert', true); - - selectByValue(formObj, 'linklist', swffile); - - // Handle file browser - if (isVisible('filebrowser')) - document.getElementById('file').style.width = '230px'; - - // Auto select flash in list - if (typeof(tinyMCEFlashList) != "undefined" && tinyMCEFlashList.length > 0) { - for (var i=0; i 0) { - var html = ""; - - html += ''; - - return html; - } - - return ""; -} - -function insertFlash() { - var formObj = document.forms[0]; - var html = ''; - var file = formObj.file.value; - var width = formObj.width.value; - var height = formObj.height.value; - if (formObj.width2.value=='%') { - width = width + '%'; - } - if (formObj.height2.value=='%') { - height = height + '%'; - } - - if (width == "") - width = 100; - - if (height == "") - height = 100; - - html += '' - + '' + file + ''; - - tinyMCEPopup.execCommand("mceInsertContent", true, html); - tinyMCE.selectedInstance.repaint(); - - tinyMCEPopup.close(); -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/flash/langs/en.js --- a/includes/clientside/tinymce/plugins/flash/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('flash',{ -title : 'Insert / edit Flash Movie', -desc : 'Insert / edit Flash Movie', -file : 'Flash-File (.swf)', -size : 'Size', -list : 'Flash files', -props : 'Flash properties', -general : 'General' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/flash/readme.txt --- a/includes/clientside/tinymce/plugins/flash/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/fullpage/blank.htm --- a/includes/clientside/tinymce/plugins/fullpage/blank.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ - - - blank_page - - - - - - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/fullpage/css/fullpage.css --- a/includes/clientside/tinymce/plugins/fullpage/css/fullpage.css Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/fullpage/css/fullpage.css Fri Feb 22 12:51:53 2008 -0500 @@ -170,3 +170,9 @@ width: 22px; height: 22px; } + +textarea { + height: 55px; +} + +.panel_wrapper div.current {height:420px;} \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/fullpage/editor_plugin.js --- a/includes/clientside/tinymce/plugins/fullpage/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/fullpage/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('fullpage');var TinyMCE_FullPagePlugin={getInfo:function(){return{longname:'Fullpage',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},getControlHTML:function(cn){switch(cn){case"fullpage":return tinyMCE.getButtonHTML(cn,'lang_fullpage_desc','{$pluginurl}/images/fullpage.gif','mceFullPageProperties')}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mceFullPageProperties":var template=new Array();template['file']='../../plugins/fullpage/fullpage.htm';template['width']=430;template['height']=485+(tinyMCE.isOpera?5:0);template['width']+=tinyMCE.getLang('lang_fullpage_delta_width',0);template['height']+=tinyMCE.getLang('lang_fullpage_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes"});return true;case"mceFullPageUpdate":TinyMCE_FullPagePlugin._addToHead(tinyMCE.getInstanceById(editor_id));return true}return false},cleanup:function(type,content,inst){switch(type){case"insert_to_editor":var tmp=content.toLowerCase();var pos=tmp.indexOf('',pos);pos2=tmp.lastIndexOf('');inst.fullpageTopContent=content.substring(0,pos+1);content=content.substring(pos+1,pos2);}else{if(!inst.fullpageTopContent){var docType=tinyMCE.getParam("fullpage_default_doctype",'');var enc=tinyMCE.getParam("fullpage_default_encoding",'utf-8');var title=tinyMCE.getParam("fullpage_default_title",'Untitled document');var lang=tinyMCE.getParam("fullpage_default_langcode",'en');var pi=tinyMCE.getParam("fullpage_default_xml_pi",true);var ff=tinyMCE.getParam("fullpage_default_font_family","");var fz=tinyMCE.getParam("fullpage_default_font_size","");var ds=tinyMCE.getParam("fullpage_default_style","");var dtc=tinyMCE.getParam("fullpage_default_text_color","");title=title.replace(/&/g,'&');title=title.replace(/\"/g,'"');title=title.replace(//g,'>');tmp='';if(pi)tmp+='\n';tmp+=docType+'\n';tmp+='\n';tmp+='\n';tmp+='\t'+title+'\n';tmp+='\t\n';tmp+='\n';tmp+='\n";break}return content},_addToHead:function(inst){var doc=inst.getDoc();var head=doc.getElementsByTagName("head")[0];var body=doc.body;var h=inst.fullpageTopContent;var e=doc.createElement("body");var nl,i,le,tmp;h=h.replace(/(\r|\n)/gi,'');h=h.replace(/<\?[^\>]*\>/gi,'');h=h.replace(/<\/?(!DOCTYPE|head|html)[^\>]*\>/gi,'');h=h.replace(//gi,'');h=h.replace(//gi,'');h=h.replace(/<(meta|base)[^>]*>/gi,'');h=h.replace(/]*)\/>/gi,'
');h=h.replace(/0){body.style.cssText=tinyMCE.getAttrib(nl[0],'style');if((tmp=tinyMCE.getAttrib(nl[0],'leftmargin'))!=''&&body.style.marginLeft=='')body.style.marginLeft=tmp+"px";if((tmp=tinyMCE.getAttrib(nl[0],'rightmargin'))!=''&&body.style.marginRight=='')body.style.marginRight=tmp+"px";if((tmp=tinyMCE.getAttrib(nl[0],'topmargin'))!=''&&body.style.marginTop=='')body.style.marginTop=tmp+"px";if((tmp=tinyMCE.getAttrib(nl[0],'bottommargin'))!=''&&body.style.marginBottom=='')body.style.marginBottom=tmp+"px";body.dir=tinyMCE.getAttrib(nl[0],'dir');body.vLink=tinyMCE.getAttrib(nl[0],'vlink');body.aLink=tinyMCE.getAttrib(nl[0],'alink');body.link=tinyMCE.getAttrib(nl[0],'link');body.text=tinyMCE.getAttrib(nl[0],'text');if((tmp=tinyMCE.getAttrib(nl[0],'background'))!='')body.style.backgroundImage="url('"+tmp+"')";if((tmp=tinyMCE.getAttrib(nl[0],'bgcolor'))!='')body.style.backgroundColor=tmp}}};tinyMCE.addPlugin("fullpage",TinyMCE_FullPagePlugin);
\ No newline at end of file
+(function(){tinymce.create('tinymce.plugins.FullPagePlugin',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceFullPageProperties',function(){ed.windowManager.open({file:url+'/fullpage.htm',width:430+parseInt(ed.getLang('fullpage.delta_width',0)),height:495+parseInt(ed.getLang('fullpage.delta_height',0)),inline:1},{plugin_url:url,head_html:t.head});});ed.addButton('fullpage',{title:'fullpage.desc',cmd:'mceFullPageProperties'});ed.onBeforeSetContent.add(t._setContent,t);ed.onGetContent.add(t._getContent,t);},getInfo:function(){return{longname:'Fullpage',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_createSerializer:function(){return new tinymce.dom.Serializer({dom:this.editor.dom,apply_source_formatting:true});},_setContent:function(ed,o){var t=this,sp,ep,c=o.content;sp=c.indexOf('',sp);t.head=c.substring(0,sp+1);ep=c.indexOf('';t.head+='\n\n\nUntitled document\n\n\n';t.foot='\n\n';}},_getContent:function(ed,o){var t=this;o.content=tinymce.trim(t.head)+'\n'+tinymce.trim(o.content)+'\n'+tinymce.trim(t.foot);}});tinymce.PluginManager.add('fullpage',tinymce.plugins.FullPagePlugin);})();
\ No newline at end of file
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/fullpage/editor_plugin_src.js
--- a/includes/clientside/tinymce/plugins/fullpage/editor_plugin_src.js	Fri Feb 22 12:46:51 2008 -0500
+++ b/includes/clientside/tinymce/plugins/fullpage/editor_plugin_src.js	Fri Feb 22 12:51:53 2008 -0500
@@ -1,227 +1,88 @@
 /**
- * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $
+ * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $
  *
  * @author Moxiecode
- * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.
+ * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.
  */
 
-/* Import plugin specific language pack */
-tinyMCE.importPluginLanguagePack('fullpage');
-
-var TinyMCE_FullPagePlugin = {
-	getInfo : function() {
-		return {
-			longname : 'Fullpage',
-			author : 'Moxiecode Systems AB',
-			authorurl : 'http://tinymce.moxiecode.com',
-			infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullpage',
-			version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion
-		};
-	},
-
-	getControlHTML : function(cn) {
-		switch (cn) {
-			case "fullpage":
-				return tinyMCE.getButtonHTML(cn, 'lang_fullpage_desc', '{$pluginurl}/images/fullpage.gif', 'mceFullPageProperties');
-		}
-
-		return "";
-	},
+(function() {
+	tinymce.create('tinymce.plugins.FullPagePlugin', {
+		init : function(ed, url) {
+			var t = this;
 
-	execCommand : function(editor_id, element, command, user_interface, value) {
-		// Handle commands
-		switch (command) {
-			case "mceFullPageProperties":
-				var template = new Array();
-
-				template['file']   = '../../plugins/fullpage/fullpage.htm';
-				template['width']  = 430;
-				template['height'] = 485 + (tinyMCE.isOpera ? 5 : 0);
-
-				template['width'] += tinyMCE.getLang('lang_fullpage_delta_width', 0);
-				template['height'] += tinyMCE.getLang('lang_fullpage_delta_height', 0);
-
-				tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"});
-			return true;
-
-			case "mceFullPageUpdate":
-				TinyMCE_FullPagePlugin._addToHead(tinyMCE.getInstanceById(editor_id));
-				return true;
-	   }
-
-	   // Pass to next handler in chain
-	   return false;
-	},
-
-	cleanup : function(type, content, inst) {
-		switch (type) {
-			case "insert_to_editor":
-				var tmp = content.toLowerCase();
-				var pos = tmp.indexOf('', pos);
-					pos2 = tmp.lastIndexOf('');
-					inst.fullpageTopContent = content.substring(0, pos + 1);
-					content = content.substring(pos + 1, pos2);
-					// tinyMCE.debug(inst.fullpageTopContent, content);
-				} else {
-					if (!inst.fullpageTopContent) {
-						var docType = tinyMCE.getParam("fullpage_default_doctype", '');
-						var enc = tinyMCE.getParam("fullpage_default_encoding", 'utf-8');
-						var title = tinyMCE.getParam("fullpage_default_title", 'Untitled document');
-						var lang = tinyMCE.getParam("fullpage_default_langcode", 'en');
-						var pi = tinyMCE.getParam("fullpage_default_xml_pi", true);
-						var ff = tinyMCE.getParam("fullpage_default_font_family", "");
-						var fz = tinyMCE.getParam("fullpage_default_font_size", "");
-						var ds = tinyMCE.getParam("fullpage_default_style", "");
-						var dtc = tinyMCE.getParam("fullpage_default_text_color", "");
+			// Register commands
+			ed.addCommand('mceFullPageProperties', function() {
+				ed.windowManager.open({
+					file : url + '/fullpage.htm',
+					width : 430 + parseInt(ed.getLang('fullpage.delta_width', 0)),
+					height : 495 + parseInt(ed.getLang('fullpage.delta_height', 0)),
+					inline : 1
+				}, {
+					plugin_url : url,
+					head_html : t.head
+				});
+			});
 
-						// Xml encode it
-						title = title.replace(/&/g, '&');
-						title = title.replace(/\"/g, '"');
-						title = title.replace(//g, '>');
-
-						tmp = '';
+			// Register buttons
+			ed.addButton('fullpage', {title : 'fullpage.desc', cmd : 'mceFullPageProperties'});
 
-						// Make default chunk
-						if (pi)
-							tmp += '\n';
-
-						tmp += docType + '\n';
-						tmp += '\n';
-						tmp += '\n';
-						tmp += '\t' + title + '\n';
-						tmp += '\t\n';
-						tmp += '\n';
-						tmp += '\n";
-
-				break;
-		}
-
-		// Pass through to next handler in chain
-		return content;
-	},
-
-	// Private plugin internal methods
+		_createSerializer : function() {
+			return new tinymce.dom.Serializer({
+				dom : this.editor.dom,
+				apply_source_formatting : true
+			});
+		},
 
-	_addToHead : function(inst) {
-		var doc = inst.getDoc();
-		var head = doc.getElementsByTagName("head")[0];
-		var body = doc.body;
-		var h = inst.fullpageTopContent;
-		var e = doc.createElement("body");
-		var nl, i, le, tmp;
+		_setContent : function(ed, o) {
+			var t = this, sp, ep, c = o.content;
 
-		// Remove stuff we don't want
-		h = h.replace(/(\r|\n)/gi, '');
-		h = h.replace(/<\?[^\>]*\>/gi, '');
-		h = h.replace(/<\/?(!DOCTYPE|head|html)[^\>]*\>/gi, '');
-		h = h.replace(//gi, '');
-		h = h.replace(//gi, '');
-		h = h.replace(/<(meta|base)[^>]*>/gi, '');
+			// Parse out head, body and footer
+			sp = c.indexOf(']*)\/>/gi, '
');
-		//h = h.replace(/]*)>(.*?)<\/style>/gi, '
$2
'); - - // Make body a div - h = h.replace(/', sp); + t.head = c.substring(0, sp + 1); - // Reset all body attributes - body.vLink = body.aLink = body.link = body.text = ''; - body.style.cssText = ''; - - // Delete all old links - nl = head.getElementsByTagName('link'); - for (i=0; i 0) { - body.style.cssText = tinyMCE.getAttrib(nl[0], 'style'); - - if ((tmp = tinyMCE.getAttrib(nl[0], 'leftmargin')) != '' && body.style.marginLeft == '') - body.style.marginLeft = tmp + "px"; - - if ((tmp = tinyMCE.getAttrib(nl[0], 'rightmargin')) != '' && body.style.marginRight == '') - body.style.marginRight = tmp + "px"; - - if ((tmp = tinyMCE.getAttrib(nl[0], 'topmargin')) != '' && body.style.marginTop == '') - body.style.marginTop = tmp + "px"; - - if ((tmp = tinyMCE.getAttrib(nl[0], 'bottommargin')) != '' && body.style.marginBottom == '') - body.style.marginBottom = tmp + "px"; + o.content = c.substring(sp + 1, ep); + t.foot = c.substring(ep); + } else { + t.head = ''; + t.head += '\n\n\nUntitled document\n\n\n'; + t.foot = '\n\n'; + } + }, - body.dir = tinyMCE.getAttrib(nl[0], 'dir'); - body.vLink = tinyMCE.getAttrib(nl[0], 'vlink'); - body.aLink = tinyMCE.getAttrib(nl[0], 'alink'); - body.link = tinyMCE.getAttrib(nl[0], 'link'); - body.text = tinyMCE.getAttrib(nl[0], 'text'); + _getContent : function(ed, o) { + var t = this; - if ((tmp = tinyMCE.getAttrib(nl[0], 'background')) != '') - body.style.backgroundImage = "url('" + tmp + "')"; + o.content = tinymce.trim(t.head) + '\n' + tinymce.trim(o.content) + '\n' + tinymce.trim(t.foot); + } + }); - if ((tmp = tinyMCE.getAttrib(nl[0], 'bgcolor')) != '') - body.style.backgroundColor = tmp; - } - } -}; - -tinyMCE.addPlugin("fullpage", TinyMCE_FullPagePlugin); + // Register plugin + tinymce.PluginManager.add('fullpage', tinymce.plugins.FullPagePlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/fullpage/fullpage.htm --- a/includes/clientside/tinymce/plugins/fullpage/fullpage.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/fullpage/fullpage.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,101 +1,101 @@ + - {$lang_fullpage_title} - - - - - + {#fullpage_dlg.title} + + + + - +
- {$lang_fullpage_meta_props} + {#fullpage_dlg.meta_props} - + - - + + - - + + - + - + - +
  
  
  
  
  
   - +
- {$lang_fullpage_langprops} + {#fullpage_dlg.langprops} - + - + - + - + - +
  
  
  
@@ -104,29 +104,29 @@
- {$lang_fullpage_appearance_textprops} + {#fullpage_dlg.appearance_textprops} - + - + - + @@ -274,7 +374,7 @@
@@ -140,11 +140,11 @@
- {$lang_fullpage_appearance_bgprops} + {#fullpage_dlg.appearance_bgprops}
- + @@ -263,7 +363,7 @@
@@ -155,7 +155,7 @@ - + @@ -242,8 +342,8 @@ @@ -254,7 +354,7 @@
@@ -169,30 +169,30 @@
- {$lang_fullpage_appearance_marginprops} + {#fullpage_dlg.appearance_marginprops}
- + - + - + - +
- {$lang_fullpage_appearance_linkprops} + {#fullpage_dlg.appearance_linkprops} - + - + @@ -214,19 +217,116 @@
@@ -202,7 +202,7 @@
@@ -214,7 +214,7 @@ - + @@ -205,7 +208,7 @@
@@ -227,7 +227,7 @@ -/gi, ''); + v = v.replace(/[\n\r]/gi, ''); + v = v.replace(/\s+/gi, ' '); + + r = []; + p = v.split(/{|}/); + + for (i=0; i,' + - 'XHTML 1.0 Frameset=,' + - 'XHTML 1.0 Strict=,' + - 'XHTML 1.1=">,' + - 'HTML 4.01 Transitional=,' + - 'HTML 4.01 Strict=,' + - 'HTML 4.01 Frameset='; - -var defaultEncodings = - 'Western european (iso-8859-1)=iso-8859-1,' + - 'Central European (iso-8859-2)=iso-8859-2,' + - 'Unicode (UTF-8)=utf-8,' + - 'Chinese traditional (Big5)=big5,' + - 'Cyrillic (iso-8859-5)=iso-8859-5,' + - 'Japanese (iso-2022-jp)=iso-2022-jp,' + - 'Greek (iso-8859-7)=iso-8859-7,' + - 'Korean (iso-2022-kr)=iso-2022-kr,' + - 'ASCII (us-ascii)=us-ascii'; - -var defaultMediaTypes = - 'all=all,' + - 'screen=screen,' + - 'print=print,' + - 'tty=tty,' + - 'tv=tv,' + - 'projection=projection,' + - 'handheld=handheld,' + - 'braille=braille,' + - 'aural=aural'; - -var defaultFontNames = 'Arial=arial,helvetica,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,times new roman,times,serif;Tahoma=tahoma,arial,helvetica,sans-serif;Times New Roman=times new roman,times,serif;Verdana=verdana,arial,helvetica,sans-serif;Impact=impact;WingDings=wingdings'; -var defaultFontSizes = '10px,11px,12px,13px,14px,15px,16px'; - -var addMenuLayer = new MCLayer("addmenu"); -var lastElementType = null; -var topDoc; - -function init() { - var f = document.forms['fullpage']; - var i, p, doctypes, encodings, mediaTypes, fonts; - var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')); - - // Setup doctype select box - doctypes = tinyMCE.getParam("fullpage_doctypes", defaultDocTypes).split(','); - for (i=0; i 1) - addSelectValue(f, 'doctypes', p[0], p[1]); - } - - // Setup fonts select box - fonts = tinyMCE.getParam("fullpage_fonts", defaultFontNames).split(';'); - for (i=0; i 1) - addSelectValue(f, 'fontface', p[0], p[1]); - } - - // Setup fontsize select box - fonts = tinyMCE.getParam("fullpage_fontsizes", defaultFontSizes).split(','); - for (i=0; i 1) { - addSelectValue(f, 'element_style_media', p[0], p[1]); - addSelectValue(f, 'element_link_media', p[0], p[1]); - } - } - - // Setup encodings select box - encodings = tinyMCE.getParam("fullpage_encodings", defaultEncodings).split(','); - for (i=0; i 1) { - addSelectValue(f, 'docencoding', p[0], p[1]); - addSelectValue(f, 'element_script_charset', p[0], p[1]); - addSelectValue(f, 'element_link_charset', p[0], p[1]); - } - } - - document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor'); - document.getElementById('link_color_pickcontainer').innerHTML = getColorPickerHTML('link_color_pick','link_color'); - //document.getElementById('hover_color_pickcontainer').innerHTML = getColorPickerHTML('hover_color_pick','hover_color'); - document.getElementById('visited_color_pickcontainer').innerHTML = getColorPickerHTML('visited_color_pick','visited_color'); - document.getElementById('active_color_pickcontainer').innerHTML = getColorPickerHTML('active_color_pick','active_color'); - document.getElementById('textcolor_pickcontainer').innerHTML = getColorPickerHTML('textcolor_pick','textcolor'); - document.getElementById('stylesheet_browsercontainer').innerHTML = getBrowserHTML('stylesheetbrowser','stylesheet','file','fullpage'); - document.getElementById('link_href_pickcontainer').innerHTML = getBrowserHTML('link_href_browser','element_link_href','file','fullpage'); - document.getElementById('script_src_pickcontainer').innerHTML = getBrowserHTML('script_src_browser','element_script_src','file','fullpage'); - document.getElementById('bgimage_pickcontainer').innerHTML = getBrowserHTML('bgimage_browser','bgimage','image','fullpage'); - - // Resize some elements - if (isVisible('stylesheetbrowser')) - document.getElementById('stylesheet').style.width = '220px'; - - if (isVisible('link_href_browser')) - document.getElementById('element_link_href').style.width = '230px'; - - if (isVisible('bgimage_browser')) - document.getElementById('bgimage').style.width = '210px'; - - // Create iframe - var iframe = document.createElement('iframe'); - - iframe.id = 'tempFrame'; - iframe.style.display = 'none'; - iframe.src = tinyMCE.baseURL + "/plugins/fullpage/blank.htm"; - - document.body.appendChild(iframe); - - tinyMCEPopup.resizeToInnerSize(); -} - -function setupIframe(doc) { - var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')); - var hc = inst.fullpageTopContent; - var f = document.forms[0]; - var xmlVer, xmlEnc, docType; - var nodes, i, x, name, value, tmp, l; - - // Keep it from not loading/executing stuff - hc = hc.replace(/ - + - - - + + + + + + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/fullscreen/images/fullscreen.gif Binary file includes/clientside/tinymce/plugins/fullscreen/images/fullscreen.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/fullscreen/langs/en.js --- a/includes/clientside/tinymce/plugins/fullscreen/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('',{ -fullscreen_desc : 'Toggle fullscreen mode' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/fullscreen/readme.txt --- a/includes/clientside/tinymce/plugins/fullscreen/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/iespell/editor_plugin.js --- a/includes/clientside/tinymce/plugins/iespell/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/iespell/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('iespell');var TinyMCE_IESpellPlugin={getInfo:function(){return{longname:'IESpell (MSIE Only)',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/iespell',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},getControlHTML:function(cn){if(cn=="iespell"&&(tinyMCE.isMSIE&&!tinyMCE.isOpera))return tinyMCE.getButtonHTML(cn,'lang_iespell_desc','{$pluginurl}/images/iespell.gif','mceIESpell');return""},execCommand:function(editor_id,element,command,user_interface,value){if(command=="mceIESpell"){try{var ieSpell=new ActiveXObject("ieSpell.ieSpellExtension");ieSpell.CheckDocumentNode(tinyMCE.getInstanceById(editor_id).contentDocument.documentElement)}catch(e){if(e.number==-2146827859){if(confirm(tinyMCE.getLang("lang_iespell_download","",true)))window.open('http://www.iespell.com/download.php','ieSpellDownload','')}else alert("Error Loading ieSpell: Exception "+e.number)}return true}return false}};tinyMCE.addPlugin("iespell",TinyMCE_IESpellPlugin); \ No newline at end of file +(function(){tinymce.create('tinymce.plugins.IESpell',{init:function(ed,url){var t=this,sp;if(!tinymce.isIE)return;t.editor=ed;ed.addCommand('mceIESpell',function(){try{sp=new ActiveXObject("ieSpell.ieSpellExtension");sp.CheckDocumentNode(ed.getDoc().documentElement);}catch(e){if(e.number==-2146827859){ed.windowManager.confirm(ed.getLang("iespell.download"),function(s){if(s)window.open('http://www.iespell.com/download.php','ieSpellDownload','');});}else ed.windowManager.alert("Error Loading ieSpell: Exception "+e.number);}});ed.addButton('iespell',{title:'iespell.iespell_desc',cmd:'mceIESpell'});},getInfo:function(){return{longname:'IESpell (IE Only)',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/iespell',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('iespell',tinymce.plugins.IESpell);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/iespell/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/iespell/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/iespell/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,58 +1,51 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('iespell'); +(function() { + tinymce.create('tinymce.plugins.IESpell', { + init : function(ed, url) { + var t = this, sp; -var TinyMCE_IESpellPlugin = { - getInfo : function() { - return { - longname : 'IESpell (MSIE Only)', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/iespell', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, + if (!tinymce.isIE) + return; - /** - * Returns the HTML contents of the iespell control. - */ - getControlHTML : function(cn) { - // Is it the iespell control and is the brower MSIE. - if (cn == "iespell" && (tinyMCE.isMSIE && !tinyMCE.isOpera)) - return tinyMCE.getButtonHTML(cn, 'lang_iespell_desc', '{$pluginurl}/images/iespell.gif', 'mceIESpell'); - - return ""; - }, + t.editor = ed; - /** - * Executes the mceIESpell command. - */ - execCommand : function(editor_id, element, command, user_interface, value) { - // Handle ieSpellCommand - if (command == "mceIESpell") { - try { - var ieSpell = new ActiveXObject("ieSpell.ieSpellExtension"); - ieSpell.CheckDocumentNode(tinyMCE.getInstanceById(editor_id).contentDocument.documentElement); - } catch (e) { - if (e.number == -2146827859) { - if (confirm(tinyMCE.getLang("lang_iespell_download", "", true))) - window.open('http://www.iespell.com/download.php', 'ieSpellDownload', ''); - } else - alert("Error Loading ieSpell: Exception " + e.number); - } + // Register commands + ed.addCommand('mceIESpell', function() { + try { + sp = new ActiveXObject("ieSpell.ieSpellExtension"); + sp.CheckDocumentNode(ed.getDoc().documentElement); + } catch (e) { + if (e.number == -2146827859) { + ed.windowManager.confirm(ed.getLang("iespell.download"), function(s) { + if (s) + window.open('http://www.iespell.com/download.php', 'ieSpellDownload', ''); + }); + } else + ed.windowManager.alert("Error Loading ieSpell: Exception " + e.number); + } + }); - return true; - } + // Register buttons + ed.addButton('iespell', {title : 'iespell.iespell_desc', cmd : 'mceIESpell'}); + }, - // Pass to next handler in chain - return false; - } -}; + getInfo : function() { + return { + longname : 'IESpell (IE Only)', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/iespell', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); -tinyMCE.addPlugin("iespell", TinyMCE_IESpellPlugin); + // Register plugin + tinymce.PluginManager.add('iespell', tinymce.plugins.IESpell); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/iespell/images/iespell.gif Binary file includes/clientside/tinymce/plugins/iespell/images/iespell.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/iespell/langs/en.js --- a/includes/clientside/tinymce/plugins/iespell/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('',{ -iespell_desc : 'Run spell checking', -iespell_download : "ieSpell not detected. Click OK to go to download page." -}); - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/iespell/readme.txt --- a/includes/clientside/tinymce/plugins/iespell/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/css/inlinepopup.css --- a/includes/clientside/tinymce/plugins/inlinepopups/css/inlinepopup.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* Window classes */ - -.mceWindow { - position: absolute; - left: 0; - top: 0; - border: 1px solid black; - background-color: #D4D0C8; -} - -.mceWindowHead { - background-color: #334F8D; - width: 100%; - height: 18px; - cursor: move; - overflow: hidden; -} - -.mceWindowBody { - clear: both; - background-color: white; -} - -.mceWindowStatusbar { - background-color: #D4D0C8; - height: 12px; - border-top: 1px solid black; -} - -.mceWindowTitle { - float: left; - font-family: "MS Sans Serif"; - font-size: 9pt; - font-weight: bold; - line-height: 18px; - color: white; - margin-left: 2px; - overflow: hidden; -} - -.mceWindowHeadTools { - margin-right: 2px; -} - -.mceWindowClose, .mceWindowMinimize, .mceWindowMaximize { - display: block; - float: right; - overflow: hidden; - margin-top: 2px; -} - -.mceWindowClose { - margin-left: 2px; -} - -.mceWindowMinimize { -} - -.mceWindowMaximize { -} - -.mceWindowResize { - display: block; - float: right; - overflow: hidden; - cursor: se-resize; - width: 12px; - height: 12px; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/editor_plugin.js --- a/includes/clientside/tinymce/plugins/inlinepopups/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/inlinepopups/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -var TinyMCE_InlinePopupsPlugin={getInfo:function(){return{longname:'Inline Popups',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}}};tinyMCE.addPlugin("inlinepopups",TinyMCE_InlinePopupsPlugin);TinyMCE_Engine.prototype.orgOpenWindow=TinyMCE_Engine.prototype.openWindow;TinyMCE_Engine.prototype.orgCloseWindow=TinyMCE_Engine.prototype.closeWindow;TinyMCE_Engine.prototype.openWindow=function(template,args){if(args['inline']!="yes"||tinyMCE.isOpera||tinyMCE.getParam("plugins").indexOf('inlinepopups')==-1){mcWindows.selectedWindow=null;args['mce_inside_iframe']=false;this.orgOpenWindow(template,args);return}var url,resizable,scrollbars;args['mce_inside_iframe']=true;tinyMCE.windowArgs=args;if(template['file'].charAt(0)!='/'&&template['file'].indexOf('://')==-1)url=tinyMCE.baseURL+"/themes/"+tinyMCE.getParam("theme")+"/"+template['file'];else url=template['file'];if(!(width=parseInt(template['width'])))width=320;if(!(height=parseInt(template['height'])))height=200;if(!(minWidth=parseInt(template['minWidth'])))minWidth=100;if(!(minHeight=parseInt(template['minHeight'])))minHeight=100;resizable=(args&&args['resizable'])?args['resizable']:"no";scrollbars=(args&&args['scrollbars'])?args['scrollbars']:"no";height+=18;for(var name in args){if(typeof(args[name])=='function')continue;url=tinyMCE.replaceVar(url,name,escape(args[name]))}var elm=document.getElementById(this.selectedInstance.editorId+'_parent');if(tinyMCE.hasPlugin('fullscreen')&&this.selectedInstance.getData('fullscreen').enabled)pos={absLeft:0,absTop:0};else pos=tinyMCE.getAbsPosition(elm);pos.absLeft+=Math.round((elm.firstChild.clientWidth/ 2) - (width /2));pos.absTop+=Math.round((elm.firstChild.clientHeight/ 2) - (height /2));mcWindows.open(url,mcWindows.idCounter++,"modal=yes,width="+width+",height="+height+",resizable="+resizable+",scrollbars="+scrollbars+",statusbar="+resizable+",left="+pos.absLeft+",top="+pos.absTop+",minWidth="+minWidth+",minHeight="+minHeight)};TinyMCE_Engine.prototype.closeWindow=function(win){var gotit=false,n,w;for(n in mcWindows.windows){w=mcWindows.windows[n];if(typeof(w)=='function')continue;if(win.name==w.id+'_iframe'){w.close();gotit=true}}if(!gotit)this.orgCloseWindow(win);tinyMCE.selectedInstance.getWin().focus()};TinyMCE_Engine.prototype.setWindowTitle=function(win_ref,title){for(var n in mcWindows.windows){var win=mcWindows.windows[n];if(typeof(win)=='function')continue;if(win_ref.name==win.id+"_iframe")window.frames[win.id+"_iframe"].document.getElementById(win.id+'_title').innerHTML=title}};function TinyMCE_Windows(){this.settings=new Array();this.windows=new Array();this.isMSIE=(navigator.appName=="Microsoft Internet Explorer");this.isGecko=navigator.userAgent.indexOf('Gecko')!=-1;this.isSafari=navigator.userAgent.indexOf('Safari')!=-1;this.isMac=navigator.userAgent.indexOf('Mac')!=-1;this.isMSIE5_0=this.isMSIE&&(navigator.userAgent.indexOf('MSIE 5.0')!=-1);this.action="none";this.selectedWindow=null;this.lastSelectedWindow=null;this.zindex=1001;this.mouseDownScreenX=0;this.mouseDownScreenY=0;this.mouseDownLayerX=0;this.mouseDownLayerY=0;this.mouseDownWidth=0;this.mouseDownHeight=0;this.idCounter=0};TinyMCE_Windows.prototype.init=function(settings){this.settings=settings;if(this.isMSIE)this.addEvent(document,"mousemove",mcWindows.eventDispatcher);else this.addEvent(window,"mousemove",mcWindows.eventDispatcher);this.addEvent(document,"mouseup",mcWindows.eventDispatcher);this.addEvent(window,"resize",mcWindows.eventDispatcher);this.addEvent(document,"scroll",mcWindows.eventDispatcher);this.doc=document};TinyMCE_Windows.prototype.getBounds=function(){if(!this.bounds){var vp=tinyMCE.getViewPort(window);var top,left,bottom,right,docEl=this.doc.documentElement;top=vp.top;left=vp.left;bottom=vp.height+top-2;right=vp.width+left-22;this.bounds=[left,top,right,bottom]}return this.bounds};TinyMCE_Windows.prototype.clampBoxPosition=function(x,y,w,h,minW,minH){var bounds=this.getBounds();x=Math.max(bounds[0],Math.min(bounds[2],x+w)-w);y=Math.max(bounds[1],Math.min(bounds[3],y+h)-h);return this.clampBoxSize(x,y,w,h,minW,minH)};TinyMCE_Windows.prototype.clampBoxSize=function(x,y,w,h,minW,minH){var bounds=this.getBounds();return[x,y,Math.max(minW,Math.min(bounds[2],x+w)-x),Math.max(minH,Math.min(bounds[3],y+h)-y)]};TinyMCE_Windows.prototype.getParam=function(name,default_value){var value=null;value=(typeof(this.settings[name])=="undefined")?default_value:this.settings[name];if(value=="true"||value=="false")return(value=="true");return value};TinyMCE_Windows.prototype.eventDispatcher=function(e){e=typeof(e)=="undefined"?window.event:e;if(mcWindows.selectedWindow==null)return;if(mcWindows.isGecko&&e.type=="mousedown"){var elm=e.currentTarget;for(var n in mcWindows.windows){var win=mcWindows.windows[n];if(win.headElement==elm||win.resizeElement==elm){win.focus();break}}}switch(e.type){case"mousemove":mcWindows.selectedWindow.onMouseMove(e);break;case"mouseup":mcWindows.selectedWindow.onMouseUp(e);break;case"mousedown":mcWindows.selectedWindow.onMouseDown(e);break;case"focus":mcWindows.selectedWindow.onFocus(e);break;case"scroll":case"resize":if(mcWindows.clampUpdateTimeout)clearTimeout(mcWindows.clampUpdateTimeout);mcWindows.clampEventType=e.type;mcWindows.clampUpdateTimeout=setTimeout(function(){mcWindows.updateClamping()},100);break}};TinyMCE_Windows.prototype.updateClamping=function(){var clamp,oversize,etype=mcWindows.clampEventType;this.bounds=null;this.clampUpdateTimeout=null;for(var n in this.windows){win=this.windows[n];if(typeof(win)=='function'||!win.winElement)continue;clamp=mcWindows.clampBoxPosition(win.left,win.top,win.winElement.scrollWidth,win.winElement.scrollHeight,win.features.minWidth,win.features.minHeight);oversize=(clamp[2]!=win.winElement.scrollWidth||clamp[3]!=win.winElement.scrollHeight)?true:false;if(!oversize||win.features.resizable=="yes"||etype!="scroll")win.moveTo(clamp[0],clamp[1]);if(oversize&&win.features.resizable=="yes")win.resizeTo(clamp[2],clamp[3])}};TinyMCE_Windows.prototype.addEvent=function(obj,name,handler){if(this.isMSIE)obj.attachEvent("on"+name,handler);else obj.addEventListener(name,handler,false)};TinyMCE_Windows.prototype.cancelEvent=function(e){if(this.isMSIE){e.returnValue=false;e.cancelBubble=true}else e.preventDefault()};TinyMCE_Windows.prototype.parseFeatures=function(opts){opts=opts.toLowerCase();opts=opts.replace(/;/g,",");opts=opts.replace(/[^0-9a-z=,]/g,"");var optionChunks=opts.split(',');var options=new Array();options['left']="10";options['top']="10";options['width']="300";options['height']="300";options['minwidth']="100";options['minheight']="100";options['resizable']="yes";options['minimizable']="yes";options['maximizable']="yes";options['close']="yes";options['movable']="yes";options['statusbar']="yes";options['scrollbars']="auto";options['modal']="no";if(opts=="")return options;for(var i=0;i';html+='';html+='';html+='Wrapper iframe';html+='';html+='';html+='';html+='';html+='
';html+='
';html+='
';if(features['resizable']=="yes"&&features['maximizable']=="yes")html+=' ';html+='
';html+='
';html+='
';if(features['statusbar']=="yes"){html+='
';if(features['resizable']=="yes"){if(this.isGecko)html+='
';else html+='
'}html+='
'}html+='
';html+='';html+='';this.createFloatingIFrame(id,features['left'],features['top'],features['width'],features['height'],html)};TinyMCE_Windows.prototype.setDocumentLock=function(state){var elm=document.getElementById('mcWindowEventBlocker');if(state){if(elm==null){elm=document.createElement("div");elm.id="mcWindowEventBlocker";elm.style.position="absolute";elm.style.left="0";elm.style.top="0";document.body.appendChild(elm)}elm.style.display="none";var imgPath=this.getParam("images_path");var width=document.body.clientWidth;var height=document.body.clientHeight;elm.style.width=width;elm.style.height=height;elm.innerHTML='';elm.style.zIndex=mcWindows.zindex-1;elm.style.display="block"}else if(elm!=null){if(mcWindows.windows.length==0)elm.parentNode.removeChild(elm);else elm.style.zIndex=mcWindows.zindex-1}};TinyMCE_Windows.prototype.onLoad=function(name){var win=mcWindows.windows[name];var id="mcWindow_"+name;var wrapperIframe=window.frames[id+"_iframe"].frames[0];var wrapperDoc=window.frames[id+"_iframe"].document;var doc=window.frames[id+"_iframe"].document;var winDiv=document.getElementById("mcWindow_"+name+"_div");var realIframe=window.frames[id+"_iframe"].frames[0];win.id="mcWindow_"+name;win.winElement=winDiv;win.bodyElement=doc.getElementById(id+'_body');win.iframeElement=doc.getElementById(id+'_iframe');win.headElement=doc.getElementById(id+'_head');win.titleElement=doc.getElementById(id+'_title');win.resizeElement=doc.getElementById(id+'_resize');win.containerElement=doc.getElementById(id+'_container');win.left=win.features['left'];win.top=win.features['top'];win.frame=window.frames[id+'_iframe'].frames[0];win.wrapperFrame=window.frames[id+'_iframe'];win.wrapperIFrameElement=document.getElementById(id+"_iframe");mcWindows.addEvent(win.headElement,"mousedown",mcWindows.eventDispatcher);if(win.resizeElement!=null)mcWindows.addEvent(win.resizeElement,"mousedown",mcWindows.eventDispatcher);if(mcWindows.isMSIE){mcWindows.addEvent(realIframe.document,"mousemove",mcWindows.eventDispatcher);mcWindows.addEvent(realIframe.document,"mouseup",mcWindows.eventDispatcher)}else{mcWindows.addEvent(realIframe,"mousemove",mcWindows.eventDispatcher);mcWindows.addEvent(realIframe,"mouseup",mcWindows.eventDispatcher);mcWindows.addEvent(realIframe,"focus",mcWindows.eventDispatcher)}for(var i=0;i'));}mdf=Event.add(id,'mousedown',function(e){var n=e.target,w,vp;w=t.windows[id];t.focus(id);if(n.nodeName=='A'||n.nodeName=='a'){if(n.className=='max'){w.oldPos=w.element.getXY();w.oldSize=w.element.getSize();vp=DOM.getViewPort();vp.w-=2;vp.h-=2;w.element.moveTo(vp.x,vp.y);w.element.resizeTo(vp.w,vp.h);DOM.setStyles(id+'_ifr',{width:vp.w-w.deltaWidth,height:vp.h-w.deltaHeight});DOM.addClass(id+'_wrapper','maximized');}else if(n.className=='med'){w.element.moveTo(w.oldPos.x,w.oldPos.y);w.element.resizeTo(w.oldSize.w,w.oldSize.h);w.iframeElement.resizeTo(w.oldSize.w-w.deltaWidth,w.oldSize.h-w.deltaHeight);DOM.removeClass(id+'_wrapper','maximized');}else if(n.className=='move')return t._startDrag(id,e,n.className);else if(DOM.hasClass(n,'resize'))return t._startDrag(id,e,n.className.substring(7));}});clf=Event.add(id,'click',function(e){var n=e.target;t.focus(id);if(n.nodeName=='A'||n.nodeName=='a'){switch(n.className){case'close':t.close(null,id);return Event.cancel(e);case'button ok':case'button cancel':f.button_func(n.className=='button ok');return Event.cancel(e);}}});t.windows=t.windows||{};w=t.windows[id]={id:id,mousedown_func:mdf,click_func:clf,element:new Element(id,{blocker:1,container:ed.getContainer()}),iframeElement:new Element(id+'_ifr'),features:f,deltaWidth:dw,deltaHeight:dh};w.iframeElement.on('focus',function(){t.focus(id);});t.focus(id);t._fixIELayout(id,1);return w;},focus:function(id){var t=this,w=t.windows[id];w.zIndex=this.zIndex++;w.element.setStyle('zIndex',w.zIndex);w.element.update();id=id+'_wrapper';DOM.removeClass(t.lastId,'focus');DOM.addClass(id,'focus');t.lastId=id;},_addAll:function(te,ne){var i,n,t=this,dom=tinymce.DOM;if(is(ne,'string'))te.appendChild(dom.doc.createTextNode(ne));else if(ne.length){te=te.appendChild(dom.create(ne[0],ne[1]));for(i=2;iix){fw=w;ix=w.zIndex;}});if(fw)t.focus(fw.id);}},setTitle:function(ti,id){DOM.get(id+'_title').innerHTML=DOM.encode(ti);},alert:function(txt,cb,s){var t=this,w;w=t.open({title:t,type:'alert',button_func:function(s){if(cb)cb.call(s||t,s);t.close(null,w.id);},content:DOM.encode(t.editor.getLang(txt,txt)),inline:1,width:400,height:130});},confirm:function(txt,cb,s){var t=this,w;w=t.open({title:t,type:'confirm',button_func:function(s){if(cb)cb.call(s||t,s);t.close(null,w.id);},content:DOM.encode(t.editor.getLang(txt,txt)),inline:1,width:400,height:130});},_fixIELayout:function(id,s){var w,img;if(!tinymce.isIE6)return;each(['n','s','w','e','nw','ne','sw','se'],function(v){var e=DOM.get(id+'_resize_'+v);DOM.setStyles(e,{width:s?e.clientWidth:'',height:s?e.clientHeight:'',cursor:DOM.getStyle(e,'cursor',1)});DOM.setStyle(id+"_bottom",'bottom','-1px');e=0;});if(w=this.windows[id]){w.element.hide();w.element.show();each(DOM.select('div,a',id),function(e,i){if(e.currentStyle.backgroundImage!='none'){img=new Image();img.src=e.currentStyle.backgroundImage.replace(/url\(\"(.+)\"\)/,'$1');}});DOM.get(id).style.filter='';}}});tinymce.PluginManager.add('inlinepopups',tinymce.plugins.InlinePopups);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/inlinepopups/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/inlinepopups/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,814 +1,559 @@ -/** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ - * - * Moxiecode DHTML Windows script. - * - * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. - */ - -// Patch openWindow, closeWindow TinyMCE functions - -var TinyMCE_InlinePopupsPlugin = { - getInfo : function() { - return { - longname : 'Inline Popups', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - } -}; - -tinyMCE.addPlugin("inlinepopups", TinyMCE_InlinePopupsPlugin); - -// Patch openWindow, closeWindow TinyMCE functions - -TinyMCE_Engine.prototype.orgOpenWindow = TinyMCE_Engine.prototype.openWindow; -TinyMCE_Engine.prototype.orgCloseWindow = TinyMCE_Engine.prototype.closeWindow; - -TinyMCE_Engine.prototype.openWindow = function(template, args) { - // Does the caller support inline - if (args['inline'] != "yes" || tinyMCE.isOpera || tinyMCE.getParam("plugins").indexOf('inlinepopups') == -1) { - mcWindows.selectedWindow = null; - args['mce_inside_iframe'] = false; - this.orgOpenWindow(template, args); - return; - } - - var url, resizable, scrollbars; - - args['mce_inside_iframe'] = true; - tinyMCE.windowArgs = args; - - if (template['file'].charAt(0) != '/' && template['file'].indexOf('://') == -1) - url = tinyMCE.baseURL + "/themes/" + tinyMCE.getParam("theme") + "/" + template['file']; - else - url = template['file']; - - if (!(width = parseInt(template['width']))) - width = 320; - - if (!(height = parseInt(template['height']))) - height = 200; - - if (!(minWidth = parseInt(template['minWidth']))) - minWidth = 100; - - if (!(minHeight = parseInt(template['minHeight']))) - minHeight = 100; - - resizable = (args && args['resizable']) ? args['resizable'] : "no"; - scrollbars = (args && args['scrollbars']) ? args['scrollbars'] : "no"; - - height += 18; - - // Replace all args as variables in URL - for (var name in args) { - if (typeof(args[name]) == 'function') - continue; - - url = tinyMCE.replaceVar(url, name, escape(args[name])); - } - - var elm = document.getElementById(this.selectedInstance.editorId + '_parent'); - - if (tinyMCE.hasPlugin('fullscreen') && this.selectedInstance.getData('fullscreen').enabled) - pos = { absLeft: 0, absTop: 0 }; - else - pos = tinyMCE.getAbsPosition(elm); - - // Center div in editor area - pos.absLeft += Math.round((elm.firstChild.clientWidth / 2) - (width / 2)); - pos.absTop += Math.round((elm.firstChild.clientHeight / 2) - (height / 2)); - - mcWindows.open(url, mcWindows.idCounter++, "modal=yes,width=" + width+ ",height=" + height + ",resizable=" + resizable + ",scrollbars=" + scrollbars + ",statusbar=" + resizable + ",left=" + pos.absLeft + ",top=" + pos.absTop + ",minWidth=" + minWidth + ",minHeight=" + minHeight ); -}; - -TinyMCE_Engine.prototype.closeWindow = function(win) { - var gotit = false, n, w; - for (n in mcWindows.windows) { - w = mcWindows.windows[n]; - if (typeof(w) == 'function') continue; - if (win.name == w.id + '_iframe') { - w.close(); - gotit = true; - } - } - if (!gotit) - this.orgCloseWindow(win); - - tinyMCE.selectedInstance.getWin().focus(); -}; - -TinyMCE_Engine.prototype.setWindowTitle = function(win_ref, title) { - for (var n in mcWindows.windows) { - var win = mcWindows.windows[n]; - if (typeof(win) == 'function') - continue; - - if (win_ref.name == win.id + "_iframe") - window.frames[win.id + "_iframe"].document.getElementById(win.id + '_title').innerHTML = title; - } -}; - -// * * * * * TinyMCE_Windows classes below - -// Windows handler -function TinyMCE_Windows() { - this.settings = new Array(); - this.windows = new Array(); - this.isMSIE = (navigator.appName == "Microsoft Internet Explorer"); - this.isGecko = navigator.userAgent.indexOf('Gecko') != -1; - this.isSafari = navigator.userAgent.indexOf('Safari') != -1; - this.isMac = navigator.userAgent.indexOf('Mac') != -1; - this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1); - this.action = "none"; - this.selectedWindow = null; - this.lastSelectedWindow = null; - this.zindex = 1001; - this.mouseDownScreenX = 0; - this.mouseDownScreenY = 0; - this.mouseDownLayerX = 0; - this.mouseDownLayerY = 0; - this.mouseDownWidth = 0; - this.mouseDownHeight = 0; - this.idCounter = 0; -}; - -TinyMCE_Windows.prototype.init = function(settings) { - this.settings = settings; - - if (this.isMSIE) - this.addEvent(document, "mousemove", mcWindows.eventDispatcher); - else - this.addEvent(window, "mousemove", mcWindows.eventDispatcher); - - this.addEvent(document, "mouseup", mcWindows.eventDispatcher); - - this.addEvent(window, "resize", mcWindows.eventDispatcher); - this.addEvent(document, "scroll", mcWindows.eventDispatcher); - - this.doc = document; -}; - -TinyMCE_Windows.prototype.getBounds = function() { - if (!this.bounds) { - var vp = tinyMCE.getViewPort(window); - var top, left, bottom, right, docEl = this.doc.documentElement; - - top = vp.top; - left = vp.left; - bottom = vp.height + top - 2; - right = vp.width + left - 22; // TODO this number is platform dependant - // x1, y1, x2, y2 - this.bounds = [left, top, right, bottom]; - } - return this.bounds; -}; - -TinyMCE_Windows.prototype.clampBoxPosition = function(x, y, w, h, minW, minH) { - var bounds = this.getBounds(); - - x = Math.max(bounds[0], Math.min(bounds[2], x + w) - w); - y = Math.max(bounds[1], Math.min(bounds[3], y + h) - h); - - return this.clampBoxSize(x, y, w, h, minW, minH); -}; - -TinyMCE_Windows.prototype.clampBoxSize = function(x, y, w, h, minW, minH) { - var bounds = this.getBounds(); - - return [ - x, y, - Math.max(minW, Math.min(bounds[2], x + w) - x), - Math.max(minH, Math.min(bounds[3], y + h) - y) - ]; -}; - -TinyMCE_Windows.prototype.getParam = function(name, default_value) { - var value = null; - - value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name]; - - // Fix bool values - if (value == "true" || value == "false") - return (value == "true"); - - return value; -}; - -TinyMCE_Windows.prototype.eventDispatcher = function(e) { - e = typeof(e) == "undefined" ? window.event : e; - - if (mcWindows.selectedWindow == null) - return; - - // Switch focus - if (mcWindows.isGecko && e.type == "mousedown") { - var elm = e.currentTarget; - - for (var n in mcWindows.windows) { - var win = mcWindows.windows[n]; - - if (win.headElement == elm || win.resizeElement == elm) { - win.focus(); - break; - } - } - } - - switch (e.type) { - case "mousemove": - mcWindows.selectedWindow.onMouseMove(e); - break; - - case "mouseup": - mcWindows.selectedWindow.onMouseUp(e); - break; - - case "mousedown": - mcWindows.selectedWindow.onMouseDown(e); - break; - - case "focus": - mcWindows.selectedWindow.onFocus(e); - break; - case "scroll": - case "resize": - if (mcWindows.clampUpdateTimeout) - clearTimeout(mcWindows.clampUpdateTimeout); - mcWindows.clampEventType = e.type; - mcWindows.clampUpdateTimeout = - setTimeout(function () {mcWindows.updateClamping()}, 100); - break; - } -}; - -TinyMCE_Windows.prototype.updateClamping = function () { - var clamp, oversize, etype = mcWindows.clampEventType; - - this.bounds = null; // Recalc window bounds on resize/scroll - this.clampUpdateTimeout = null; - - for (var n in this.windows) { - win = this.windows[n]; - if (typeof(win) == 'function' || ! win.winElement) continue; - - clamp = mcWindows.clampBoxPosition( - win.left, win.top, - win.winElement.scrollWidth, - win.winElement.scrollHeight, - win.features.minWidth, - win.features.minHeight - ); - oversize = ( - clamp[2] != win.winElement.scrollWidth || - clamp[3] != win.winElement.scrollHeight - ) ? true : false; - - if (!oversize || win.features.resizable == "yes" || etype != "scroll") - win.moveTo(clamp[0], clamp[1]); - if (oversize && win.features.resizable == "yes") - win.resizeTo(clamp[2], clamp[3]); - } -}; - -TinyMCE_Windows.prototype.addEvent = function(obj, name, handler) { - if (this.isMSIE) - obj.attachEvent("on" + name, handler); - else - obj.addEventListener(name, handler, false); -}; - -TinyMCE_Windows.prototype.cancelEvent = function(e) { - if (this.isMSIE) { - e.returnValue = false; - e.cancelBubble = true; - } else - e.preventDefault(); -}; - -TinyMCE_Windows.prototype.parseFeatures = function(opts) { - // Cleanup the options - opts = opts.toLowerCase(); - opts = opts.replace(/;/g, ","); - opts = opts.replace(/[^0-9a-z=,]/g, ""); - - var optionChunks = opts.split(','); - var options = new Array(); - - options['left'] = "10"; - options['top'] = "10"; - options['width'] = "300"; - options['height'] = "300"; - options['minwidth'] = "100"; - options['minheight'] = "100"; - options['resizable'] = "yes"; - options['minimizable'] = "yes"; - options['maximizable'] = "yes"; - options['close'] = "yes"; - options['movable'] = "yes"; - options['statusbar'] = "yes"; - options['scrollbars'] = "auto"; - options['modal'] = "no"; - - if (opts == "") - return options; - - for (var i=0; i'; - html += ''; - html += ''; - - html += '
'; - html += '
'; - html += '
'; - if (features['resizable'] == "yes" && features['maximizable'] == "yes") - html += ' '; - // html += ' '; - html += '
'; - html += '
'; - html += '
'; - - if (features['statusbar'] == "yes") { - html += '
'; - - if (features['resizable'] == "yes") { - if (this.isGecko) - html += '
'; - else - html += '
'; - } - - html += '
'; - } - - html += '
'; - - html += ''; - html += ''; - - // Create iframe - this.createFloatingIFrame(id, features['left'], features['top'], features['width'], features['height'], html); -}; - -// Blocks the document events by placing a image over the whole document -TinyMCE_Windows.prototype.setDocumentLock = function(state) { - var elm = document.getElementById('mcWindowEventBlocker'); - - if (state) { - if (elm == null) { - elm = document.createElement("div"); - - elm.id = "mcWindowEventBlocker"; - elm.style.position = "absolute"; - elm.style.left = "0"; - elm.style.top = "0"; - - document.body.appendChild(elm); - } - - elm.style.display = "none"; - - var imgPath = this.getParam("images_path"); - var width = document.body.clientWidth; - var height = document.body.clientHeight; - - elm.style.width = width; - elm.style.height = height; - elm.innerHTML = ''; - - elm.style.zIndex = mcWindows.zindex-1; - elm.style.display = "block"; - } else if (elm != null) { - if (mcWindows.windows.length == 0) - elm.parentNode.removeChild(elm); - else - elm.style.zIndex = mcWindows.zindex-1; - } -}; - -// Gets called when wrapper iframe is initialized -TinyMCE_Windows.prototype.onLoad = function(name) { - var win = mcWindows.windows[name]; - var id = "mcWindow_" + name; - var wrapperIframe = window.frames[id + "_iframe"].frames[0]; - var wrapperDoc = window.frames[id + "_iframe"].document; - var doc = window.frames[id + "_iframe"].document; - var winDiv = document.getElementById("mcWindow_" + name + "_div"); - var realIframe = window.frames[id + "_iframe"].frames[0]; - - // Set window data - win.id = "mcWindow_" + name; - win.winElement = winDiv; - win.bodyElement = doc.getElementById(id + '_body'); - win.iframeElement = doc.getElementById(id + '_iframe'); - win.headElement = doc.getElementById(id + '_head'); - win.titleElement = doc.getElementById(id + '_title'); - win.resizeElement = doc.getElementById(id + '_resize'); - win.containerElement = doc.getElementById(id + '_container'); - win.left = win.features['left']; - win.top = win.features['top']; - win.frame = window.frames[id + '_iframe'].frames[0]; - win.wrapperFrame = window.frames[id + '_iframe']; - win.wrapperIFrameElement = document.getElementById(id + "_iframe"); - - // Add event handlers - mcWindows.addEvent(win.headElement, "mousedown", mcWindows.eventDispatcher); - - if (win.resizeElement != null) - mcWindows.addEvent(win.resizeElement, "mousedown", mcWindows.eventDispatcher); - - if (mcWindows.isMSIE) { - mcWindows.addEvent(realIframe.document, "mousemove", mcWindows.eventDispatcher); - mcWindows.addEvent(realIframe.document, "mouseup", mcWindows.eventDispatcher); - } else { - mcWindows.addEvent(realIframe, "mousemove", mcWindows.eventDispatcher); - mcWindows.addEvent(realIframe, "mouseup", mcWindows.eventDispatcher); - mcWindows.addEvent(realIframe, "focus", mcWindows.eventDispatcher); - } - - for (var i=0; i')); + } + + // Register events + mdf = Event.add(id, 'mousedown', function(e) { + var n = e.target, w, vp; + + w = t.windows[id]; + t.focus(id); + + if (n.nodeName == 'A' || n.nodeName == 'a') { + if (n.className == 'max') { + w.oldPos = w.element.getXY(); + w.oldSize = w.element.getSize(); + + vp = DOM.getViewPort(); + + // Reduce viewport size to avoid scrollbars + vp.w -= 2; + vp.h -= 2; + + w.element.moveTo(vp.x, vp.y); + w.element.resizeTo(vp.w, vp.h); + DOM.setStyles(id + '_ifr', {width : vp.w - w.deltaWidth, height : vp.h - w.deltaHeight}); + DOM.addClass(id + '_wrapper', 'maximized'); + } else if (n.className == 'med') { + // Reset to old size + w.element.moveTo(w.oldPos.x, w.oldPos.y); + w.element.resizeTo(w.oldSize.w, w.oldSize.h); + w.iframeElement.resizeTo(w.oldSize.w - w.deltaWidth, w.oldSize.h - w.deltaHeight); + + DOM.removeClass(id + '_wrapper', 'maximized'); + } else if (n.className == 'move') + return t._startDrag(id, e, n.className); + else if (DOM.hasClass(n, 'resize')) + return t._startDrag(id, e, n.className.substring(7)); + } + }); + + clf = Event.add(id, 'click', function(e) { + var n = e.target; + + t.focus(id); + + if (n.nodeName == 'A' || n.nodeName == 'a') { + switch (n.className) { + case 'close': + t.close(null, id); + return Event.cancel(e); + + case 'button ok': + case 'button cancel': + f.button_func(n.className == 'button ok'); + return Event.cancel(e); + } + } + }); + + // Add window + t.windows = t.windows || {}; + w = t.windows[id] = { + id : id, + mousedown_func : mdf, + click_func : clf, + element : new Element(id, {blocker : 1, container : ed.getContainer()}), + iframeElement : new Element(id + '_ifr'), + features : f, + deltaWidth : dw, + deltaHeight : dh + }; + + w.iframeElement.on('focus', function() { + t.focus(id); + }); + + t.focus(id); + t._fixIELayout(id, 1); + +// if (DOM.get(id + '_ok')) +// DOM.get(id + '_ok').focus(); + + return w; + }, + + focus : function(id) { + var t = this, w = t.windows[id]; + + w.zIndex = this.zIndex++; + w.element.setStyle('zIndex', w.zIndex); + w.element.update(); + + id = id + '_wrapper'; + DOM.removeClass(t.lastId, 'focus'); + DOM.addClass(id, 'focus'); + t.lastId = id; + }, + + _addAll : function(te, ne) { + var i, n, t = this, dom = tinymce.DOM; + + if (is(ne, 'string')) + te.appendChild(dom.doc.createTextNode(ne)); + else if (ne.length) { + te = te.appendChild(dom.create(ne[0], ne[1])); + + for (i=2; i ix) { + fw = w; + ix = w.zIndex; + } + }); + + if (fw) + t.focus(fw.id); + } + }, + + setTitle : function(ti, id) { + DOM.get(id + '_title').innerHTML = DOM.encode(ti); + }, + + alert : function(txt, cb, s) { + var t = this, w; + + w = t.open({ + title : t, + type : 'alert', + button_func : function(s) { + if (cb) + cb.call(s || t, s); + + t.close(null, w.id); + }, + content : DOM.encode(t.editor.getLang(txt, txt)), + inline : 1, + width : 400, + height : 130 + }); + }, + + confirm : function(txt, cb, s) { + var t = this, w; + + w = t.open({ + title : t, + type : 'confirm', + button_func : function(s) { + if (cb) + cb.call(s || t, s); + + t.close(null, w.id); + }, + content : DOM.encode(t.editor.getLang(txt, txt)), + inline : 1, + width : 400, + height : 130 + }); + }, + + // Internal functions + + _fixIELayout : function(id, s) { + var w, img; + + if (!tinymce.isIE6) + return; + + // Fixes the bug where hover flickers and does odd things in IE6 + each(['n','s','w','e','nw','ne','sw','se'], function(v) { + var e = DOM.get(id + '_resize_' + v); + + DOM.setStyles(e, { + width : s ? e.clientWidth : '', + height : s ? e.clientHeight : '', + cursor : DOM.getStyle(e, 'cursor', 1) + }); + + DOM.setStyle(id + "_bottom", 'bottom', '-1px'); + + e = 0; + }); + + // Fixes graphics glitch + if (w = this.windows[id]) { + // Fixes rendering bug after resize + w.element.hide(); + w.element.show(); + + // Forced a repaint of the window + //DOM.get(id).style.filter = ''; + + // IE has a bug where images used in CSS won't get loaded + // sometimes when the cache in the browser is disabled + // This fix tries to solve it by loading the images using the image object + each(DOM.select('div,a', id), function(e, i) { + if (e.currentStyle.backgroundImage != 'none') { + img = new Image(); + img.src = e.currentStyle.backgroundImage.replace(/url\(\"(.+)\"\)/, '$1'); + } + }); + + DOM.get(id).style.filter = ''; + } + } + }); + + // Register plugin + tinymce.PluginManager.add('inlinepopups', tinymce.plugins.InlinePopups); +})(); + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/images/spacer.gif Binary file includes/clientside/tinymce/plugins/inlinepopups/images/spacer.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/images/window_close.gif Binary file includes/clientside/tinymce/plugins/inlinepopups/images/window_close.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/images/window_maximize.gif Binary file includes/clientside/tinymce/plugins/inlinepopups/images/window_maximize.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/images/window_minimize.gif Binary file includes/clientside/tinymce/plugins/inlinepopups/images/window_minimize.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/images/window_resize.gif Binary file includes/clientside/tinymce/plugins/inlinepopups/images/window_resize.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/inlinepopups/jscripts/mcwindows.js --- a/includes/clientside/tinymce/plugins/inlinepopups/jscripts/mcwindows.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,453 +0,0 @@ -/** - * $Id: mcwindows.js 18 2006-06-29 14:11:23Z spocke $ - * - * Moxiecode DHTML Windows script. - * - * @author Moxiecode - * @copyright Copyright © 2004, Moxiecode Systems AB, All rights reserved. - */ - -// Windows handler -function MCWindows() { - this.settings = new Array(); - this.windows = new Array(); - this.isMSIE = (navigator.appName == "Microsoft Internet Explorer"); - this.isGecko = navigator.userAgent.indexOf('Gecko') != -1; - this.isSafari = navigator.userAgent.indexOf('Safari') != -1; - this.isMac = navigator.userAgent.indexOf('Mac') != -1; - this.isMSIE5_0 = this.isMSIE && (navigator.userAgent.indexOf('MSIE 5.0') != -1); - this.action = "none"; - this.selectedWindow = null; - this.zindex = 100; - this.mouseDownScreenX = 0; - this.mouseDownScreenY = 0; - this.mouseDownLayerX = 0; - this.mouseDownLayerY = 0; - this.mouseDownWidth = 0; - this.mouseDownHeight = 0; -}; - -MCWindows.prototype.init = function(settings) { - this.settings = settings; - - if (this.isMSIE) - this.addEvent(document, "mousemove", mcWindows.eventDispatcher); - else - this.addEvent(window, "mousemove", mcWindows.eventDispatcher); - - this.addEvent(document, "mouseup", mcWindows.eventDispatcher); -}; - -MCWindows.prototype.getParam = function(name, default_value) { - var value = null; - - value = (typeof(this.settings[name]) == "undefined") ? default_value : this.settings[name]; - - // Fix bool values - if (value == "true" || value == "false") - return (value == "true"); - - return value; -}; - -MCWindows.prototype.eventDispatcher = function(e) { - e = typeof(e) == "undefined" ? window.event : e; - - if (mcWindows.selectedWindow == null) - return; - - // Switch focus - if (mcWindows.isGecko && e.type == "mousedown") { - var elm = e.currentTarget; - - for (var n in mcWindows.windows) { - var win = mcWindows.windows[n]; - if (typeof(win) == 'function') - continue; - - if (win.headElement == elm || win.resizeElement == elm) { - win.focus(); - break; - } - } - } - - switch (e.type) { - case "mousemove": - mcWindows.selectedWindow.onMouseMove(e); - break; - - case "mouseup": - mcWindows.selectedWindow.onMouseUp(e); - break; - - case "mousedown": - mcWindows.selectedWindow.onMouseDown(e); - break; - - case "focus": - mcWindows.selectedWindow.onFocus(e); - break; - } -} - -MCWindows.prototype.addEvent = function(obj, name, handler) { - if (this.isMSIE) - obj.attachEvent("on" + name, handler); - else - obj.addEventListener(name, handler, true); -}; - -MCWindows.prototype.cancelEvent = function(e) { - if (this.isMSIE) { - e.returnValue = false; - e.cancelBubble = true; - } else - e.preventDefault(); -}; - -MCWindows.prototype.parseFeatures = function(opts) { - // Cleanup the options - opts = opts.toLowerCase(); - opts = opts.replace(/;/g, ","); - opts = opts.replace(/[^0-9a-z=,]/g, ""); - - var optionChunks = opts.split(','); - var options = new Array(); - - options['left'] = 10; - options['top'] = 10; - options['width'] = 300; - options['height'] = 300; - options['resizable'] = true; - options['minimizable'] = true; - options['maximizable'] = true; - options['close'] = true; - options['movable'] = true; - - if (opts == "") - return options; - - for (var i=0; i'; - - html += '
'; - html += '
'; - html += '
'; -// html += ' '; -// html += ' '; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - - html += ''; - html += ''; - - // Create iframe - this.createFloatingIFrame(id, features['left'], features['top'], features['width'], features['height'], html); -}; - -// Gets called when wrapper iframe is initialized -MCWindows.prototype.onLoad = function(name) { - var win = mcWindows.windows[name]; - var id = "mcWindow_" + name; - var wrapperIframe = window.frames[id + "_iframe"].frames[0]; - var wrapperDoc = window.frames[id + "_iframe"].document; - var doc = window.frames[id + "_iframe"].document; - var winDiv = document.getElementById("mcWindow_" + name + "_div"); - var realIframe = window.frames[id + "_iframe"].frames[0]; - - // Set window data - win.id = "mcWindow_" + name + "_iframe"; - win.winElement = winDiv; - win.bodyElement = doc.getElementById(id + '_body'); - win.iframeElement = doc.getElementById(id + '_iframe'); - win.headElement = doc.getElementById(id + '_head'); - win.titleElement = doc.getElementById(id + '_title'); - win.resizeElement = doc.getElementById(id + '_resize'); - win.containerElement = doc.getElementById(id + '_container'); - win.left = win.features['left']; - win.top = win.features['top']; - win.frame = window.frames[id + '_iframe'].frames[0]; - win.wrapperFrame = window.frames[id + '_iframe']; - win.wrapperIFrameElement = document.getElementById(id + "_iframe"); - - // Add event handlers - mcWindows.addEvent(win.headElement, "mousedown", mcWindows.eventDispatcher); - mcWindows.addEvent(win.resizeElement, "mousedown", mcWindows.eventDispatcher); - - if (mcWindows.isMSIE) { - mcWindows.addEvent(realIframe.document, "mousemove", mcWindows.eventDispatcher); - mcWindows.addEvent(realIframe.document, "mouseup", mcWindows.eventDispatcher); - } else { - mcWindows.addEvent(realIframe, "mousemove", mcWindows.eventDispatcher); - mcWindows.addEvent(realIframe, "mouseup", mcWindows.eventDispatcher); - mcWindows.addEvent(realIframe, "focus", mcWindows.eventDispatcher); - } - - for (var i=0; i --> + + +Template for dialogs + + + + +
+
+
+
+
+
+
+ Blured +
+ +
+
+ Content +
+
+ +
+
+
+
+ Statusbar text. +
+ + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+ Focused +
+ +
+
+ Content +
+
+ +
+
+
+
+ Statusbar text. +
+ + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+ Statusbar +
+ +
+
+ Content +
+
+ +
+
+
+
+ Statusbar text. +
+ + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+ Statusbar, Resizable +
+ +
+
+ Content +
+
+ +
+
+
+
+ Statusbar text. +
+ + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+ Resizable, Maximizable +
+ +
+
+ Content +
+
+ +
+
+
+
+ Statusbar text. +
+ + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+ Blurred, Maximizable, Statusbar, Resizable +
+ +
+
+ Content +
+
+ +
+
+
+
+ Statusbar text. +
+ + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+ Maximized, Maximizable, Minimizable, Focused +
+ +
+
+ Content +
+
+ +
+
+
+
+ Statusbar text. +
+ + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+ Maximized, Maximizable, Minimizable +
+ +
+
+ Content +
+
+ +
+
+
+
+ Statusbar text. +
+ + + + + + + + + + + + + + +
+
+ +
+ +
+ +
+ +
+
+ + + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/insertdatetime/editor_plugin.js --- a/includes/clientside/tinymce/plugins/insertdatetime/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/insertdatetime/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('insertdatetime');var TinyMCE_InsertDateTimePlugin={getInfo:function(){return{longname:'Insert date/time',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/insertdatetime',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},getControlHTML:function(cn){switch(cn){case"insertdate":return tinyMCE.getButtonHTML(cn,'lang_insertdate_desc','{$pluginurl}/images/insertdate.gif','mceInsertDate');case"inserttime":return tinyMCE.getButtonHTML(cn,'lang_inserttime_desc','{$pluginurl}/images/inserttime.gif','mceInsertTime')}return""},execCommand:function(editor_id,element,command,user_interface,value){function addZeros(value,len){value=""+value;if(value.length-1){nl[ci].style.zIndex=z[fi];nl[fi].style.zIndex=z[ci]}else{if(z[ci]>0)nl[ci].style.zIndex=z[ci]-1}}else{for(i=0;iz[ci]){fi=i;break}}if(fi>-1){nl[ci].style.zIndex=z[fi];nl[fi].style.zIndex=z[ci]}else nl[ci].style.zIndex=z[ci]+1}inst.repaint()},_getParentLayer:function(n){return tinyMCE.getParentNode(n,function(n){return n.nodeType==1&&new RegExp('absolute|relative|static','gi').test(n.style.position)})},_insertLayer:function(){var inst=tinyMCE.selectedInstance;var e=tinyMCE.getParentElement(inst.getFocusElement());var p=tinyMCE.getAbsPosition(e);var d=inst.getDoc();var ne=d.createElement('div');var h=inst.selection.getSelectedHTML();ne.style.position='absolute';ne.style.left=p.absLeft+'px';ne.style.top=(p.absTop>20?p.absTop:20)+'px';ne.style.width='100px';ne.style.height='100px';ne.className='mceVisualAid';if(!h)h=tinyMCE.getLang('lang_layer_content');ne.innerHTML=h;d.body.appendChild(ne)},_toggleAbsolute:function(){var inst=tinyMCE.selectedInstance;var le=this._getParentLayer(inst.getFocusElement());if(le==null)le=tinyMCE.getParentElement(inst.getFocusElement(),'div,p,img');if(le){if(le.style.position.toLowerCase()=="absolute"){le.style.position="";le.style.left="";le.style.top=""}else{le.style.position="absolute";if(le.style.left=="")le.style.left=20+'px';if(le.style.top=="")le.style.top=20+'px';if(le.style.width=="")le.style.width=le.width?(le.width+'px'):'100px';if(le.style.height=="")le.style.height=le.height?(le.height+'px'):'100px';tinyMCE.handleVisualAid(inst.getBody(),true,inst.visualAid,inst)}inst.repaint();tinyMCE.triggerNodeChange()}}};tinyMCE.addPlugin("layer",TinyMCE_LayerPlugin); \ No newline at end of file +(function(){tinymce.create('tinymce.plugins.Layer',{init:function(ed,url){var t=this;t.editor=ed;ed.addCommand('mceInsertLayer',t._insertLayer,t);ed.addCommand('mceMoveForward',function(){t._move(1);});ed.addCommand('mceMoveBackward',function(){t._move(-1);});ed.addCommand('mceMakeAbsolute',function(){t._toggleAbsolute();});ed.addButton('moveforward',{title:'layer.forward_desc',cmd:'mceMoveForward'});ed.addButton('movebackward',{title:'layer.backward_desc',cmd:'mceMoveBackward'});ed.addButton('absolute',{title:'layer.absolute_desc',cmd:'mceMakeAbsolute'});ed.addButton('insertlayer',{title:'layer.insertlayer_desc',cmd:'mceInsertLayer'});ed.onInit.add(function(){if(tinymce.isIE)ed.execCommand('2D-Position');});ed.onNodeChange.add(t._nodeChange,t);ed.onVisualAid.add(t._visualAid,t);},getInfo:function(){return{longname:'Layer',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer',version:tinymce.majorVersion+"."+tinymce.minorVersion};},_nodeChange:function(ed,cm,n){var le,p;le=this._getParentLayer(n);p=ed.dom.getParent(n,'DIV,P,IMG');if(!p){cm.setDisabled('absolute',1);cm.setDisabled('moveforward',1);cm.setDisabled('movebackward',1);}else{cm.setDisabled('absolute',0);cm.setDisabled('moveforward',!le);cm.setDisabled('movebackward',!le);cm.setActive('absolute',le&&le.style.position.toLowerCase()=="absolute");}},_visualAid:function(ed,e,s){var dom=ed.dom;tinymce.each(dom.select('div,p',e),function(e){if(/^(absolute|relative|static)$/i.test(e.style.position)){if(s)dom.addClass(e,'mceVisualAid');else dom.removeClass(e,'mceVisualAid');}});},_move:function(d){var ed=this.editor,i,z=[],le=this._getParentLayer(ed.selection.getNode()),ci=-1,fi=-1,nl;nl=[];tinymce.walk(ed.getBody(),function(n){if(n.nodeType==1&&/^(absolute|relative|static)$/i.test(n.style.position))nl.push(n);},'childNodes');for(i=0;i-1){nl[ci].style.zIndex=z[fi];nl[fi].style.zIndex=z[ci];}else{if(z[ci]>0)nl[ci].style.zIndex=z[ci]-1;}}else{for(i=0;iz[ci]){fi=i;break;}}if(fi>-1){nl[ci].style.zIndex=z[fi];nl[fi].style.zIndex=z[ci];}else nl[ci].style.zIndex=z[ci]+1;}ed.execCommand('mceRepaint');},_getParentLayer:function(n){return this.editor.dom.getParent(n,function(n){return n.nodeType==1&&/^(absolute|relative|static)$/i.test(n.style.position);});},_insertLayer:function(){var ed=this.editor,p=ed.dom.getPos(ed.dom.getParent(ed.selection.getNode(),'*'));ed.dom.add(ed.getBody(),'div',{style:{position:'absolute',left:p.x,top:(p.y>20?p.y:20),width:100,height:100},'class':'mceVisualAid'},ed.selection.getContent()||ed.getLang('layer.content'));},_toggleAbsolute:function(){var ed=this.editor,le=this._getParentLayer(ed.selection.getNode());if(!le)le=ed.dom.getParent(ed.selection.getNode(),'DIV,P,IMG');if(le){if(le.style.position.toLowerCase()=="absolute"){ed.dom.setStyles(le,{position:'',left:'',top:'',width:'',height:''});ed.dom.removeClass(le,'mceVisualAid');}else{if(le.style.left=="")le.style.left=20+'px';if(le.style.top=="")le.style.top=20+'px';if(le.style.width=="")le.style.width=le.width?(le.width+'px'):'100px';if(le.style.height=="")le.style.height=le.height?(le.height+'px'):'100px';le.style.position="absolute";ed.addVisual(ed.getBody());}ed.execCommand('mceRepaint');ed.nodeChanged();}}});tinymce.PluginManager.add('layer',tinymce.plugins.Layer);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/layer/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/layer/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,248 +1,209 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('layer'); +(function() { + tinymce.create('tinymce.plugins.Layer', { + init : function(ed, url) { + var t = this; + + t.editor = ed; + + // Register commands + ed.addCommand('mceInsertLayer', t._insertLayer, t); + + ed.addCommand('mceMoveForward', function() { + t._move(1); + }); + + ed.addCommand('mceMoveBackward', function() { + t._move(-1); + }); + + ed.addCommand('mceMakeAbsolute', function() { + t._toggleAbsolute(); + }); + + // Register buttons + ed.addButton('moveforward', {title : 'layer.forward_desc', cmd : 'mceMoveForward'}); + ed.addButton('movebackward', {title : 'layer.backward_desc', cmd : 'mceMoveBackward'}); + ed.addButton('absolute', {title : 'layer.absolute_desc', cmd : 'mceMakeAbsolute'}); + ed.addButton('insertlayer', {title : 'layer.insertlayer_desc', cmd : 'mceInsertLayer'}); + + ed.onInit.add(function() { + if (tinymce.isIE) + ed.execCommand('2D-Position'); + }); + + ed.onNodeChange.add(t._nodeChange, t); + ed.onVisualAid.add(t._visualAid, t); + }, + + getInfo : function() { + return { + longname : 'Layer', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + }, -var TinyMCE_LayerPlugin = { - getInfo : function() { - return { - longname : 'Layer', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, + // Private methods + + _nodeChange : function(ed, cm, n) { + var le, p; + + le = this._getParentLayer(n); + p = ed.dom.getParent(n, 'DIV,P,IMG'); + + if (!p) { + cm.setDisabled('absolute', 1); + cm.setDisabled('moveforward', 1); + cm.setDisabled('movebackward', 1); + } else { + cm.setDisabled('absolute', 0); + cm.setDisabled('moveforward', !le); + cm.setDisabled('movebackward', !le); + cm.setActive('absolute', le && le.style.position.toLowerCase() == "absolute"); + } + }, + + // Private methods - initInstance : function(inst) { - if (tinyMCE.isMSIE && !tinyMCE.isOpera) - inst.getDoc().execCommand('2D-Position'); - }, + _visualAid : function(ed, e, s) { + var dom = ed.dom; + + tinymce.each(dom.select('div,p', e), function(e) { + if (/^(absolute|relative|static)$/i.test(e.style.position)) { + if (s) + dom.addClass(e, 'mceVisualAid'); + else + dom.removeClass(e, 'mceVisualAid'); + } + }); + }, - handleEvent : function(e) { - var inst = tinyMCE.selectedInstance; - var w = inst.getWin(), le = inst._lastStyleElm, e; + _move : function(d) { + var ed = this.editor, i, z = [], le = this._getParentLayer(ed.selection.getNode()), ci = -1, fi = -1, nl; - if (tinyMCE.isGecko) { - e = this._getParentLayer(inst.getFocusElement()); + nl = []; + tinymce.walk(ed.getBody(), function(n) { + if (n.nodeType == 1 && /^(absolute|relative|static)$/i.test(n.style.position)) + nl.push(n); + }, 'childNodes'); + + // Find z-indexes + for (i=0; i -1) { + nl[ci].style.zIndex = z[fi]; + nl[fi].style.zIndex = z[ci]; + } else { + if (z[ci] > 0) + nl[ci].style.zIndex = z[ci] - 1; + } + } else { + // Move forward + + // Try find a higher one + for (i=0; i z[ci]) { + fi = i; + break; + } + } + + if (fi > -1) { + nl[ci].style.zIndex = z[fi]; + nl[fi].style.zIndex = z[ci]; + } else + nl[ci].style.zIndex = z[ci] + 1; } - } + + ed.execCommand('mceRepaint'); + }, + + _getParentLayer : function(n) { + return this.editor.dom.getParent(n, function(n) { + return n.nodeType == 1 && /^(absolute|relative|static)$/i.test(n.style.position); + }); + }, + + _insertLayer : function() { + var ed = this.editor, p = ed.dom.getPos(ed.dom.getParent(ed.selection.getNode(), '*')); - return true; - }, + ed.dom.add(ed.getBody(), 'div', { + style : { + position : 'absolute', + left : p.x, + top : (p.y > 20 ? p.y : 20), + width : 100, + height : 100 + }, + 'class' : 'mceVisualAid' + }, ed.selection.getContent() || ed.getLang('layer.content')); + }, + + _toggleAbsolute : function() { + var ed = this.editor, le = this._getParentLayer(ed.selection.getNode()); + + if (!le) + le = ed.dom.getParent(ed.selection.getNode(), 'DIV,P,IMG'); - handleVisualAid : function(el, deep, state, inst) { - var nl = inst.getDoc().getElementsByTagName("div"), i; + if (le) { + if (le.style.position.toLowerCase() == "absolute") { + ed.dom.setStyles(le, { + position : '', + left : '', + top : '', + width : '', + height : '' + }); + + ed.dom.removeClass(le, 'mceVisualAid'); + } else { + if (le.style.left == "") + le.style.left = 20 + 'px'; - for (i=0; i -1) { - nl[ci].style.zIndex = z[fi]; - nl[fi].style.zIndex = z[ci]; - } else { - if (z[ci] > 0) - nl[ci].style.zIndex = z[ci] - 1; - } - } else { - // Move forward - - // Try find a higher one - for (i=0; i z[ci]) { - fi = i; - break; - } - } - - if (fi > -1) { - nl[ci].style.zIndex = z[fi]; - nl[fi].style.zIndex = z[ci]; - } else - nl[ci].style.zIndex = z[ci] + 1; - } - - inst.repaint(); - }, - - _getParentLayer : function(n) { - return tinyMCE.getParentNode(n, function(n) { - return n.nodeType == 1 && new RegExp('absolute|relative|static', 'gi').test(n.style.position); - }); - }, - - _insertLayer : function() { - var inst = tinyMCE.selectedInstance; - var e = tinyMCE.getParentElement(inst.getFocusElement()); - var p = tinyMCE.getAbsPosition(e); - var d = inst.getDoc(); - var ne = d.createElement('div'); - var h = inst.selection.getSelectedHTML(); - - // Move div - ne.style.position = 'absolute'; - ne.style.left = p.absLeft + 'px'; - ne.style.top = (p.absTop > 20 ? p.absTop : 20) + 'px'; - ne.style.width = '100px'; - ne.style.height = '100px'; - ne.className = 'mceVisualAid'; - - if (!h) - h = tinyMCE.getLang('lang_layer_content'); - - ne.innerHTML = h; - - // Add it - d.body.appendChild(ne); - }, - - _toggleAbsolute : function() { - var inst = tinyMCE.selectedInstance; - var le = this._getParentLayer(inst.getFocusElement()); - - if (le == null) - le = tinyMCE.getParentElement(inst.getFocusElement(), 'div,p,img'); - - if (le) { - if (le.style.position.toLowerCase() == "absolute") { - le.style.position = ""; - le.style.left = ""; - le.style.top = ""; - } else { - le.style.position = "absolute"; - - if (le.style.left == "") - le.style.left = 20 + 'px'; - - if (le.style.top == "") - le.style.top = 20 + 'px'; - - if (le.style.width == "") - le.style.width = le.width ? (le.width + 'px') : '100px'; - - if (le.style.height == "") - le.style.height = le.height ? (le.height + 'px') : '100px'; - - tinyMCE.handleVisualAid(inst.getBody(), true, inst.visualAid, inst); - } - - inst.repaint(); - tinyMCE.triggerNodeChange(); - } - } -}; - -tinyMCE.addPlugin("layer", TinyMCE_LayerPlugin); + // Register plugin + tinymce.PluginManager.add('layer', tinymce.plugins.Layer); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/images/absolute.gif Binary file includes/clientside/tinymce/plugins/layer/images/absolute.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/images/backward.gif Binary file includes/clientside/tinymce/plugins/layer/images/backward.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/images/forward.gif Binary file includes/clientside/tinymce/plugins/layer/images/forward.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/images/insert_layer.gif Binary file includes/clientside/tinymce/plugins/layer/images/insert_layer.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/images/insertlayer.gif Binary file includes/clientside/tinymce/plugins/layer/images/insertlayer.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/images/movebackward.gif Binary file includes/clientside/tinymce/plugins/layer/images/movebackward.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/images/moveforward.gif Binary file includes/clientside/tinymce/plugins/layer/images/moveforward.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/langs/en.js --- a/includes/clientside/tinymce/plugins/layer/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('layer',{ -insertlayer_desc : 'Insert new layer', -forward_desc : 'Move forward', -backward_desc : 'Move backward', -absolute_desc : 'Toggle absolute positioning', -content : 'New layer...' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/layer/readme.txt --- a/includes/clientside/tinymce/plugins/layer/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/media/css/content.css --- a/includes/clientside/tinymce/plugins/media/css/content.css Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/media/css/content.css Fri Feb 22 12:51:53 2008 -0500 @@ -1,26 +1,6 @@ -.mceItemFlash, .mceItemShockWave, .mceItemQuickTime, .mceItemWindowsMedia, .mceItemRealMedia { - border: 1px dotted #cc0000; - background-position: center; - background-repeat: no-repeat; - background-color: #ffffcc; -} - -.mceItemShockWave { - background-image: url('../images/shockwave.gif'); -} - -.mceItemFlash { - background-image: url('../images/flash.gif'); -} - -.mceItemQuickTime { - background-image: url('../images/quicktime.gif'); -} - -.mceItemWindowsMedia { - background-image: url('../images/windowsmedia.gif'); -} - -.mceItemRealMedia { - background-image: url('../images/realmedia.gif'); -} +.mceItemFlash, .mceItemShockWave, .mceItemQuickTime, .mceItemWindowsMedia, .mceItemRealMedia {border:1px dotted #cc0000; background-position:center; background-repeat:no-repeat; background-color:#ffffcc;} +.mceItemShockWave {background-image: url(../img/shockwave.gif);} +.mceItemFlash {background-image:url(../img/flash.gif);} +.mceItemQuickTime {background-image:url(../img/quicktime.gif);} +.mceItemWindowsMedia {background-image:url(../img/windowsmedia.gif);} +.mceItemRealMedia {background-image:url(../img/realmedia.gif);} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/media/editor_plugin.js --- a/includes/clientside/tinymce/plugins/media/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/media/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('media');var TinyMCE_MediaPlugin={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}},initInstance:function(inst){if(inst.hasPlugin('flash')&&!tinyMCE.flashWarn){alert('Flash plugin is deprecated and should not be used together with the media plugin.');tinyMCE.flashWarn=true}if(!tinyMCE.settings['media_skip_plugin_css'])tinyMCE.importCSS(inst.getDoc(),tinyMCE.baseURL+"/plugins/media/css/content.css")},getControlHTML:function(cn){switch(cn){case"media":return tinyMCE.getButtonHTML(cn,'lang_media_desc','{$pluginurl}/images/media.gif','mceMedia')}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mceMedia":tinyMCE.openWindow({file:'../../plugins/media/media.htm',width:430+tinyMCE.getLang('lang_media_delta_width',0),height:470+tinyMCE.getLang('lang_media_delta_height',0)},{editor_id:editor_id,inline:"yes"});return true}return false},cleanup:function(type,content,inst){var nl,img,i,ne,d,s,ci;switch(type){case"insert_to_editor":img=tinyMCE.getParam("theme_href")+'/images/spacer.gif';content=content.replace(/]*>\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\(\{([^\)]*)\}\);\s*<\/script>/gi,'');content=content.replace(/]*)>/gi,'
');content=content.replace(/]*)>/gi,'
');content=content.replace(/<\/(object|embed)([^>]*)>/gi,'
');content=content.replace(/]*)>/gi,'
');content=content.replace(new RegExp('\\/ class="mceItemParam"><\\/div>','gi'),'class="mceItemParam">
');break;case"insert_to_editor_dom":d=inst.getDoc();nl=content.getElementsByTagName("img");for(i=0;i',startPos);attribs=TinyMCE_MediaPlugin._parseAttributes(content.substring(startPos+4,endPos));if(!/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(attribs['class']))continue;endPos+=2;at=attribs['title'];if(at){at=at.replace(/&(#39|apos);/g,"'");at=at.replace(/&#quot;/g,'"');try{pl=eval('x={'+at+'};')}catch(ex){pl={}}}if(!tinyMCE.getParam('media_use_script',false)){switch(attribs['class']){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=tinyMCE.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(!tinyMCE.getParam("relative_urls"))pl.src=tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'],pl.src);embedHTML=TinyMCE_MediaPlugin._getEmbed(ci,cb,mt,pl,attribs)}else{switch(attribs['class']){case'mceItemFlash':s='writeFlash';break;case'mceItemShockWave':s='writeShockWave';break;case'mceItemWindowsMedia':s='writeWindowsMedia';break;case'mceItemQuickTime':s='writeQuickTime';break;case'mceItemRealMedia':s='writeRealMedia';break}if(attribs.width)at=at.replace(/width:[^0-9]?[0-9]+%?[^0-9]?/g,"width:'"+attribs.width+"'");if(attribs.height)at=at.replace(/height:[^0-9]?[0-9]+%?[^0-9]?/g,"height:'"+attribs.height+"'");if(!tinyMCE.getParam("relative_urls")){pl.src=tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'],pl.src);at=at.replace(new RegExp("src:'[^']*'","g"),"src:'"+pl.src+"'")}embedHTML=''}chunkBefore=content.substring(0,startPos);chunkAfter=content.substring(endPos);content=chunkBefore+embedHTML+chunkAfter}break}return content},handleNodeChange:function(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){if(node==null)return;do{if(node.nodeName=="IMG"&&/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(tinyMCE.getAttrib(node,'class'))){tinyMCE.switchClass(editor_id+'_media','mceButtonSelected');return true}}while((node=node.parentNode));tinyMCE.switchClass(editor_id+'_media','mceButtonNormal');return true},_createImgFromEmbed:function(n,d,cl){var ne,at,i,ti='',an;ne=d.createElement('img');ne.src=tinyMCE.getParam("theme_href")+'/images/spacer.gif';ne.width=tinyMCE.getAttrib(n,'width');ne.height=tinyMCE.getAttrib(n,'height');ne.className=cl;at=n.attributes;for(i=0;i0?ti.substring(0,ti.length-1):ti;ne.title=ti;n.parentNode.replaceChild(ne,n)},_createImg:function(cl,d,n){var i,nl,ti="",an,av,al=new Array();ne=d.createElement('img');ne.src=tinyMCE.getParam("theme_href")+'/images/spacer.gif';ne.width=tinyMCE.getAttrib(n,'width');ne.height=tinyMCE.getAttrib(n,'height');ne.className=cl;al.id=tinyMCE.getAttrib(n,'id');al.name=tinyMCE.getAttrib(n,'name');al.width=tinyMCE.getAttrib(n,'width');al.height=tinyMCE.getAttrib(n,'height');al.bgcolor=tinyMCE.getAttrib(n,'bgcolor');al.align=tinyMCE.getAttrib(n,'align');al.class_name=tinyMCE.getAttrib(n,'mce_class');nl=n.getElementsByTagName('div');for(i=0;i0?ti.substring(0,ti.length-1):ti;ne.title=ti;return ne},_getEmbed:function(cls,cb,mt,p,at){var h='',n;p.width=at.width?at.width:p.width;p.height=at.height?at.height:p.height;h+='';if(n=='src'&&p[n].indexOf('://')!=-1&&mt=='application/x-mplayer2')h+=''}}h+=']*>\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\(\{([^\)]*)\}\);\s*<\/script>/gi,function(a,b,c){var o=eval("({"+c+"})");return''});h=h.replace(/]*)>/gi,'');h=h.replace(/]*)>/gi,'');h=h.replace(/<\/(object|embed)([^>]*)>/gi,'');h=h.replace(/]*)>/gi,function(a,b){return''});h=h.replace(/\/ class=\"mceItemParam\"><\/span>/gi,'class="mceItemParam">');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(/]+>/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='';}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(v&&!/^(width|height|codebase|classid)$/.test(k))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);}}});},_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'],function(n){var v=dom.getAttrib(n,'align');if(v)pa[v]=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 diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/media/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/media/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/media/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,174 +1,128 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 561 2008-01-23 15:18:19Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('media'); +(function() { + var each = tinymce.each; -var TinyMCE_MediaPlugin = { - 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 - }; - }, + tinymce.create('tinymce.plugins.MediaPlugin', { + init : function(ed, url) { + var t = this; + + t.editor = ed; + t.url = url; - initInstance : function(inst) { - // Warn if user has flash plugin and media plugin at the same time - if (inst.hasPlugin('flash') && !tinyMCE.flashWarn) { - alert('Flash plugin is deprecated and should not be used together with the media plugin.'); - tinyMCE.flashWarn = true; - } + function isMediaElm(n) { + return /^(mceItemFlash|mceItemShockWave|mceItemWindowsMedia|mceItemQuickTime|mceItemRealMedia)$/.test(n.className); + }; - if (!tinyMCE.settings['media_skip_plugin_css']) - tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/media/css/content.css"); - }, - - getControlHTML : function(cn) { - switch (cn) { - case "media": - return tinyMCE.getButtonHTML(cn, 'lang_media_desc', '{$pluginurl}/images/media.gif', 'mceMedia'); - } - - return ""; - }, + // Register commands + 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 + }); + }); - execCommand : function(editor_id, element, command, user_interface, value) { - // Handle commands - switch (command) { - case "mceMedia": - tinyMCE.openWindow({ - file : '../../plugins/media/media.htm', - width : 430 + tinyMCE.getLang('lang_media_delta_width', 0), - height : 470 + tinyMCE.getLang('lang_media_delta_height', 0) - }, { - editor_id : editor_id, - inline : "yes" - }); + // Register buttons + ed.addButton('media', {title : 'media.desc', cmd : 'mceMedia'}); - return true; - } - - // Pass to next handler in chain - return false; - }, + ed.onNodeChange.add(function(ed, cm, n) { + cm.setActive('media', n.nodeName == 'IMG' && isMediaElm(n)); + }); - cleanup : function(type, content, inst) { - var nl, img, i, ne, d, s, ci; + ed.onInit.add(function() { + var lo = { + mceItemFlash : 'flash', + mceItemShockWave : 'shockwave', + mceItemWindowsMedia : 'windowsmedia', + mceItemQuickTime : 'quicktime', + mceItemRealMedia : 'realmedia' + }; + + ed.dom.loadCSS(url + "/css/content.css"); - switch (type) { - case "insert_to_editor": - img = tinyMCE.getParam("theme_href") + '/images/spacer.gif'; - content = content.replace(/]*>\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\(\{([^\)]*)\}\);\s*<\/script>/gi, ''); - content = content.replace(/]*)>/gi, '
'); - content = content.replace(/]*)>/gi, '
'); - content = content.replace(/<\/(object|embed)([^>]*)>/gi, '
'); - content = content.replace(/]*)>/gi, '
'); - content = content.replace(new RegExp('\\/ class="mceItemParam"><\\/div>', 'gi'), 'class="mceItemParam">
'); - break; - - case "insert_to_editor_dom": - d = inst.getDoc(); - nl = content.getElementsByTagName("img"); - for (i=0; i]*>\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\(\{([^\)]*)\}\);\s*<\/script>/gi, function(a, b, c) { + var o = eval("({" + c + "})"); + + return '' + }); - case 'clsid:6bf52a52-394a-11d3-b153-00c04f79faa6': - nl[i].parentNode.replaceChild(TinyMCE_MediaPlugin._createImg('mceItemWindowsMedia', d, nl[i]), nl[i]); - break; + h = h.replace(/]*)>/gi, ''); + h = h.replace(/]*)>/gi, ''); + h = h.replace(/<\/(object|embed)([^>]*)>/gi, ''); + h = h.replace(/]*)>/gi, function(a, b) {return ''}); + h = h.replace(/\/ class=\"mceItemParam\"><\/span>/gi, 'class="mceItemParam">'); + + o.content = h; + }); + + ed.onSetContent.add(function() { + t._spansToImgs(ed.getBody()); + }); - case 'clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b': - nl[i].parentNode.replaceChild(TinyMCE_MediaPlugin._createImg('mceItemQuickTime', d, nl[i]), nl[i]); - break; + ed.onPreProcess.add(function(ed, o) { + var dom = ed.dom; + + if (o.set) { + t._spansToImgs(o.node); - case 'clsid:cfcdaa03-8be4-11cf-b84b-0020afbbccfa': - case 'clsid:22d6f312-b0f6-11d0-94ab-0080c74c7e95': - case 'clsid:05589fa1-c356-11ce-bf01-00aa0055595a': - nl[i].parentNode.replaceChild(TinyMCE_MediaPlugin._createImg('mceItemRealMedia', d, nl[i]), nl[i]); - break; - } + 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)); + } + }); } - // Handle embed (if any) - nl = tinyMCE.selectNodes(content, function (n) {return n.className == 'mceItemObjectEmbed';}); - for (i=0; i', startPos); - attribs = TinyMCE_MediaPlugin._parseAttributes(content.substring(startPos + 4, endPos)); - - // Is not flash, skip it - if (!/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(attribs['class'])) - continue; - - endPos += 2; + if (ed.getParam('media_use_script')) { + if (isMediaElm(n)) + n.className = n.className.replace(/mceItem/g, 'mceTemp'); - // Parse attributes - at = attribs['title']; - if (at) { - at = at.replace(/&(#39|apos);/g, "'"); - at = at.replace(/&#quot;/g, '"'); + return; + } - try { - pl = eval('x={' + at + '};'); - } catch (ex) { - pl = {}; - } - } - - // Use object/embed - if (!tinyMCE.getParam('media_use_script', false)) { - switch (attribs['class']) { + 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'; @@ -176,260 +130,194 @@ break; case 'mceItemShockWave': - ci = '166B1BCA-3F9C-11CF-8075-444553540000'; + 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 = tinyMCE.getParam('media_wmp6_compatible') ? '05589FA1-C356-11CE-BF01-00AA0055595A' : '6BF52A52-394A-11D3-B153-00C04F79FAA6'; + 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'; + 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'; + 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; } - // Force absolute URL - if (!tinyMCE.getParam("relative_urls")) - pl.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], pl.src); + if (ci) { + dom.replace(t._buildObj({ + classid : ci, + codebase : cb, + type : mt + }, n), n); + } + }); + } + }); - embedHTML = TinyMCE_MediaPlugin._getEmbed(ci, cb, mt, pl, attribs); - } else { - // Use script version - switch (attribs['class']) { - case 'mceItemFlash': - s = 'writeFlash'; - break; - - case 'mceItemShockWave': - s = 'writeShockWave'; - break; - - case 'mceItemWindowsMedia': - s = 'writeWindowsMedia'; - break; + ed.onPostProcess.add(function(ed, o) { + o.content = o.content.replace(/_value=/g, 'value='); + }); - case 'mceItemQuickTime': - s = 'writeQuickTime'; - break; + if (ed.getParam('media_use_script')) { + function getAttr(s, n) { + n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s); - case 'mceItemRealMedia': - s = 'writeRealMedia'; - break; - } + return n ? ed.dom.decode(n[1]) : ''; + }; - if (attribs.width) - at = at.replace(/width:[^0-9]?[0-9]+%?[^0-9]?/g, "width:'" + attribs.width + "'"); + ed.onPostProcess.add(function(ed, o) { + o.content = o.content.replace(/]+>/g, function(im) { + var cl = getAttr(im, 'class'); - if (attribs.height) - at = at.replace(/height:[^0-9]?[0-9]+%?[^0-9]?/g, "height:'" + attribs.height + "'"); - - // Force absolute URL - if (!tinyMCE.getParam("relative_urls")) { - pl.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], pl.src); - at = at.replace(new RegExp("src:'[^']*'", "g"), "src:'" + pl.src + "'"); + 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 = ''; } - embedHTML = ''; - } - - // Insert embed/object chunk - chunkBefore = content.substring(0, startPos); - chunkAfter = content.substring(endPos); - content = chunkBefore + embedHTML + chunkAfter; - } - break; - } - - return content; - }, - - handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { - if (node == null) - return; + return im; + }); + }); + } + }, - do { - if (node.nodeName == "IMG" && /mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(tinyMCE.getAttrib(node, 'class'))) { - tinyMCE.switchClass(editor_id + '_media', 'mceButtonSelected'); - return true; - } - } while ((node = node.parentNode)); - - tinyMCE.switchClass(editor_id + '_media', 'mceButtonNormal'); - - return true; - }, + 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 + }; + }, - _createImgFromEmbed : function(n, d, cl) { - var ne, at, i, ti = '', an; + // Private methods - ne = d.createElement('img'); - ne.src = tinyMCE.getParam("theme_href") + '/images/spacer.gif'; - ne.width = tinyMCE.getAttrib(n, 'width'); - ne.height = tinyMCE.getAttrib(n, 'height'); - ne.className = cl; + _buildObj : function(o, n) { + var ob, ed = this.editor, dom = ed.dom, p = this._parse(n.title); - at = n.attributes; - for (i=0; i 0 ? ti.substring(0, ti.length - 1) : ti; - ne.title = ti; + each (p, function(v, k) { + if (v && !/^(width|height|codebase|classid)$/.test(k)) + dom.add(ob, 'span', {mce_name : 'param', name : k, '_value' : v}); + }); - n.parentNode.replaceChild(ne, n); - }, - - _createImg : function(cl, d, n) { - var i, nl, ti = "", an, av, al = new Array(); + dom.add(ob, 'span', tinymce.extend({mce_name : 'embed', type : o.type}, p)); - ne = d.createElement('img'); - ne.src = tinyMCE.getParam("theme_href") + '/images/spacer.gif'; - ne.width = tinyMCE.getAttrib(n, 'width'); - ne.height = tinyMCE.getAttrib(n, 'height'); - ne.className = cl; + return ob; + }, - al.id = tinyMCE.getAttrib(n, 'id'); - al.name = tinyMCE.getAttrib(n, 'name'); - al.width = tinyMCE.getAttrib(n, 'width'); - al.height = tinyMCE.getAttrib(n, 'height'); - al.bgcolor = tinyMCE.getAttrib(n, 'bgcolor'); - al.align = tinyMCE.getAttrib(n, 'align'); - al.class_name = tinyMCE.getAttrib(n, 'mce_class'); + _spansToImgs : function(p) { + var t = this, dom = t.editor.dom, im, ci; - nl = n.getElementsByTagName('div'); - for (i=0; i 0 ? ti.substring(0, ti.length - 1) : ti; - ne.title = ti; + 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; - return ne; - }, + case 'clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b': + dom.replace(t._createImg('mceItemQuickTime', n), n); + break; - _getEmbed : function(cls, cb, mt, p, at) { - var h = '', n; - - p.width = at.width ? at.width : p.width; - p.height = at.height ? at.height : p.height; + case 'clsid:cfcdaa03-8be4-11cf-b84b-0020afbbccfa': + dom.replace(t._createImg('mceItemRealMedia', n), n); + break; - h += ''; + _createImg : function(cl, n) { + var im, dom = this.editor.dom, pa = {}, ti = ''; - // Add extra url parameter if it's an absolute URL on WMP - if (n == 'src' && p[n].indexOf('://') != -1 && mt == 'application/x-mplayer2') - h += ''; - } - } - - h += ''; + + h += ''); + +function init() { + var pl = "", f, val; + var type = "flash", fe, i; + + ed = tinyMCEPopup.editor; + + tinyMCEPopup.resizeToInnerSize(); + f = document.forms[0] + + fe = ed.selection.getNode(); + if (/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(ed.dom.getAttrib(fe, 'class'))) { + pl = "x={" + fe.title + "};"; + + switch (ed.dom.getAttrib(fe, 'class')) { + case 'mceItemFlash': + type = 'flash'; + break; + + case 'mceItemFlashVideo': + type = 'flv'; + break; + + case 'mceItemShockWave': + type = 'shockwave'; + break; + + case 'mceItemWindowsMedia': + type = 'wmp'; + break; + + case 'mceItemQuickTime': + type = 'qt'; + break; + + case 'mceItemRealMedia': + type = 'rmp'; + break; + } + + document.forms[0].insert.value = ed.getLang('update', 'Insert', true); + } + + document.getElementById('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media'); + document.getElementById('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','qt_qtsrc','media','media'); + document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor'); + + var html = getMediaListHTML('medialist','src','media','media'); + if (html == "") + document.getElementById("linklistrow").style.display = 'none'; + else + document.getElementById("linklistcontainer").innerHTML = html; + + // Resize some elements + if (isVisible('filebrowser')) + document.getElementById('src').style.width = '230px'; + + // Setup form + if (pl != "") { + pl = eval(pl); + + switch (type) { + case "flash": + setBool(pl, 'flash', 'play'); + setBool(pl, 'flash', 'loop'); + setBool(pl, 'flash', 'menu'); + setBool(pl, 'flash', 'swliveconnect'); + setStr(pl, 'flash', 'quality'); + setStr(pl, 'flash', 'scale'); + setStr(pl, 'flash', 'salign'); + setStr(pl, 'flash', 'wmode'); + setStr(pl, 'flash', 'base'); + setStr(pl, 'flash', 'flashvars'); + break; + + case "qt": + setBool(pl, 'qt', 'loop'); + setBool(pl, 'qt', 'autoplay'); + setBool(pl, 'qt', 'cache'); + setBool(pl, 'qt', 'controller'); + setBool(pl, 'qt', 'correction'); + setBool(pl, 'qt', 'enablejavascript'); + setBool(pl, 'qt', 'kioskmode'); + setBool(pl, 'qt', 'autohref'); + setBool(pl, 'qt', 'playeveryframe'); + setBool(pl, 'qt', 'tarsetcache'); + setStr(pl, 'qt', 'scale'); + setStr(pl, 'qt', 'starttime'); + setStr(pl, 'qt', 'endtime'); + setStr(pl, 'qt', 'tarset'); + setStr(pl, 'qt', 'qtsrcchokespeed'); + setStr(pl, 'qt', 'volume'); + setStr(pl, 'qt', 'qtsrc'); + break; + + case "shockwave": + setBool(pl, 'shockwave', 'sound'); + setBool(pl, 'shockwave', 'progress'); + setBool(pl, 'shockwave', 'autostart'); + setBool(pl, 'shockwave', 'swliveconnect'); + setStr(pl, 'shockwave', 'swvolume'); + setStr(pl, 'shockwave', 'swstretchstyle'); + setStr(pl, 'shockwave', 'swstretchhalign'); + setStr(pl, 'shockwave', 'swstretchvalign'); + break; + + case "wmp": + setBool(pl, 'wmp', 'autostart'); + setBool(pl, 'wmp', 'enabled'); + setBool(pl, 'wmp', 'enablecontextmenu'); + setBool(pl, 'wmp', 'fullscreen'); + setBool(pl, 'wmp', 'invokeurls'); + setBool(pl, 'wmp', 'mute'); + setBool(pl, 'wmp', 'stretchtofit'); + setBool(pl, 'wmp', 'windowlessvideo'); + setStr(pl, 'wmp', 'balance'); + setStr(pl, 'wmp', 'baseurl'); + setStr(pl, 'wmp', 'captioningid'); + setStr(pl, 'wmp', 'currentmarker'); + setStr(pl, 'wmp', 'currentposition'); + setStr(pl, 'wmp', 'defaultframe'); + setStr(pl, 'wmp', 'playcount'); + setStr(pl, 'wmp', 'rate'); + setStr(pl, 'wmp', 'uimode'); + setStr(pl, 'wmp', 'volume'); + break; + + case "rmp": + setBool(pl, 'rmp', 'autostart'); + setBool(pl, 'rmp', 'loop'); + setBool(pl, 'rmp', 'autogotourl'); + setBool(pl, 'rmp', 'center'); + setBool(pl, 'rmp', 'imagestatus'); + setBool(pl, 'rmp', 'maintainaspect'); + setBool(pl, 'rmp', 'nojava'); + setBool(pl, 'rmp', 'prefetch'); + setBool(pl, 'rmp', 'shuffle'); + setStr(pl, 'rmp', 'console'); + setStr(pl, 'rmp', 'controls'); + setStr(pl, 'rmp', 'numloop'); + setStr(pl, 'rmp', 'scriptcallbacks'); + break; + } + + setStr(pl, null, 'src'); + setStr(pl, null, 'id'); + setStr(pl, null, 'name'); + setStr(pl, null, 'vspace'); + setStr(pl, null, 'hspace'); + setStr(pl, null, 'bgcolor'); + setStr(pl, null, 'align'); + setStr(pl, null, 'width'); + setStr(pl, null, 'height'); + + if ((val = ed.dom.getAttrib(fe, "width")) != "") + pl.width = f.width.value = val; + + if ((val = ed.dom.getAttrib(fe, "height")) != "") + pl.height = f.height.value = val; + + oldWidth = pl.width ? parseInt(pl.width) : 0; + oldHeight = pl.height ? parseInt(pl.height) : 0; + } else + oldWidth = oldHeight = 0; + + selectByValue(f, 'media_type', type); + changedType(type); + updateColor('bgcolor_pick', 'bgcolor'); + + TinyMCE_EditableSelects.init(); + generatePreview(); +} + +function insertMedia() { + var fe, f = document.forms[0], h; + + if (!AutoValidator.validate(f)) { + alert(ed.getLang('invalid_data')); + return false; + } + + f.width.value = f.width.value == "" ? 100 : f.width.value; + f.height.value = f.height.value == "" ? 100 : f.height.value; + + fe = ed.selection.getNode(); + if (fe != null && /mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(ed.dom.getAttrib(fe, 'class'))) { + switch (f.media_type.options[f.media_type.selectedIndex].value) { + case "flash": + fe.className = "mceItemFlash"; + break; + + case "flv": + fe.className = "mceItemFlashVideo"; + break; + + case "shockwave": + fe.className = "mceItemShockWave"; + break; + + case "qt": + fe.className = "mceItemQuickTime"; + break; + + case "wmp": + fe.className = "mceItemWindowsMedia"; + break; + + case "rmp": + fe.className = "mceItemRealMedia"; + break; + } + + if (fe.width != f.width.value || fe.height != f.height.height) + ed.execCommand('mceRepaint'); + + fe.title = serializeParameters(); + fe.width = f.width.value; + fe.height = f.height.value; + fe.style.width = f.width.value + (f.width.value.indexOf('%') == -1 ? 'px' : ''); + fe.style.height = f.height.value + (f.height.value.indexOf('%') == -1 ? 'px' : ''); + fe.align = f.align.options[f.align.selectedIndex].value; + } else { + h = ' 0) { + var html = ""; + + html += ''; + + return html; + } + + return ""; +} + +function getType(v) { + var fo, i, c, el, x, f = document.forms[0]; + + fo = ed.getParam("media_types", "flash=swf;flv=flv;shockwave=dcr;qt=mov,qt,mpg,mp3,mp4,mpeg;shockwave=dcr;wmp=avi,wmv,wm,asf,asx,wmx,wvx;rmp=rm,ra,ram").split(';'); + + // YouTube + if (v.match(/v=(.+)(.*)/)) { + f.width.value = '425'; + f.height.value = '350'; + f.src.value = 'http://www.youtube.com/v/' + v.match(/v=(.*)(.*)/)[0].split('=')[1]; + return 'flash'; + } + + // Google video + if (v.indexOf('http://video.google.com/videoplay?docid=') == 0) { + f.width.value = '425'; + f.height.value = '326'; + f.src.value = 'http://video.google.com/googleplayer.swf?docId=' + v.substring('http://video.google.com/videoplay?docid='.length) + '&hl=en'; + return 'flash'; + } + + for (i=0; i 0 ? s.substring(0, s.length - 1) : s; + + return s; +} + +function setBool(pl, p, n) { + if (typeof(pl[n]) == "undefined") + return; + + document.forms[0].elements[p + "_" + n].checked = pl[n]; +} + +function setStr(pl, p, n) { + var f = document.forms[0], e = f.elements[(p != null ? p + "_" : '') + n]; + + if (typeof(pl[n]) == "undefined") + return; + + if (e.type == "text") + e.value = pl[n]; + else + selectByValue(f, (p != null ? p + "_" : '') + n, pl[n]); +} + +function getBool(p, n, d, tv, fv) { + var v = document.forms[0].elements[p + "_" + n].checked; + + tv = typeof(tv) == 'undefined' ? 'true' : "'" + jsEncode(tv) + "'"; + fv = typeof(fv) == 'undefined' ? 'false' : "'" + jsEncode(fv) + "'"; + + return (v == d) ? '' : n + (v ? ':' + tv + ',' : ':' + fv + ','); +} + +function getStr(p, n, d) { + var e = document.forms[0].elements[(p != null ? p + "_" : "") + n]; + var v = e.type == "text" ? e.value : e.options[e.selectedIndex].value; + + return ((n == d || v == '') ? '' : n + ":'" + jsEncode(v) + "',"); +} + +function getInt(p, n, d) { + var e = document.forms[0].elements[(p != null ? p + "_" : "") + n]; + var v = e.type == "text" ? e.value : e.options[e.selectedIndex].value; + + return ((n == d || v == '') ? '' : n + ":" + v.replace(/[^0-9]+/g, '') + ","); +} + +function jsEncode(s) { + s = s.replace(new RegExp('\\\\', 'g'), '\\\\'); + s = s.replace(new RegExp('"', 'g'), '\\"'); + s = s.replace(new RegExp("'", 'g'), "\\'"); + + return s; +} + +function generatePreview(c) { + var f = document.forms[0], p = document.getElementById('prev'), h = '', cls, pl, n, type, codebase, wp, hp, nw, nh; + + p.innerHTML = ''; + + nw = parseInt(f.width.value); + nh = parseInt(f.height.value); + + if (f.width.value != "" && f.height.value != "") { + if (f.constrain.checked) { + if (c == 'width' && oldWidth != 0) { + wp = nw / oldWidth; + nh = Math.round(wp * nh); + f.height.value = nh; + } else if (c == 'height' && oldHeight != 0) { + hp = nh / oldHeight; + nw = Math.round(hp * nw); + f.width.value = nw; + } + } + } + + if (f.width.value != "") + oldWidth = nw; + + if (f.height.value != "") + oldHeight = nh; + + // After constrain + pl = serializeParameters(); + + switch (f.media_type.options[f.media_type.selectedIndex].value) { + case "flash": + cls = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'; + codebase = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0'; + type = 'application/x-shockwave-flash'; + break; + + case "shockwave": + cls = 'clsid:166B1BCA-3F9C-11CF-8075-444553540000'; + codebase = 'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0'; + type = 'application/x-director'; + break; + + case "qt": + cls = 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B'; + codebase = 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0'; + type = 'video/quicktime'; + break; + + case "wmp": + cls = ed.getParam('media_wmp6_compatible') ? 'clsid:05589FA1-C356-11CE-BF01-00AA0055595A' : 'clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6'; + codebase = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701'; + type = 'application/x-mplayer2'; + break; + + case "rmp": + cls = 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA'; + codebase = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701'; + type = 'audio/x-pn-realaudio-plugin'; + break; + } + + if (pl == '') { + p.innerHTML = ''; + return; + } + + pl = eval('x={' + pl + '};'); + + if (!pl.src) { + p.innerHTML = ''; + return; + } + + pl.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(pl.src); + pl.width = !pl.width ? 100 : pl.width; + pl.height = !pl.height ? 100 : pl.height; + pl.id = !pl.id ? 'obj' : pl.id; + pl.name = !pl.name ? 'eobj' : pl.name; + pl.align = !pl.align ? '' : pl.align; + + h += ''; + + for (n in pl) { + h += ''; + + // Add extra url parameter if it's an absolute URL + if (n == 'src' && pl[n].indexOf('://') != -1) + h += ''; + } + + h += ''; - - h += ''); -} - -function init() { - var pl = "", f, val; - var type = "flash", fe, i; - - tinyMCEPopup.resizeToInnerSize(); - f = document.forms[0] - - fe = tinyMCE.selectedInstance.getFocusElement(); - if (/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(tinyMCE.getAttrib(fe, 'class'))) { - pl = "x={" + fe.title + "};"; - - switch (tinyMCE.getAttrib(fe, 'class')) { - case 'mceItemFlash': - type = 'flash'; - break; - - case 'mceItemShockWave': - type = 'shockwave'; - break; - - case 'mceItemWindowsMedia': - type = 'wmp'; - break; - - case 'mceItemQuickTime': - type = 'qt'; - break; - - case 'mceItemRealMedia': - type = 'rmp'; - break; - } - - document.forms[0].insert.value = tinyMCE.getLang('lang_update', 'Insert', true); - } - - document.getElementById('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media'); - document.getElementById('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','qt_qtsrc','media','media'); - document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor'); - - var html = getMediaListHTML('filebrowser','src','media','media'); - if (html == "") - document.getElementById("linklistrow").style.display = 'none'; - else - document.getElementById("linklistcontainer").innerHTML = html; - - // Resize some elements - if (isVisible('filebrowsercontainer')) - document.getElementById('src').style.width = '230px'; - - // Setup form - if (pl != "") { - pl = eval(pl); - - switch (type) { - case "flash": - setBool(pl, 'flash', 'play'); - setBool(pl, 'flash', 'loop'); - setBool(pl, 'flash', 'menu'); - setBool(pl, 'flash', 'swliveconnect'); - setStr(pl, 'flash', 'quality'); - setStr(pl, 'flash', 'scale'); - setStr(pl, 'flash', 'salign'); - setStr(pl, 'flash', 'wmode'); - setStr(pl, 'flash', 'base'); - setStr(pl, 'flash', 'flashvars'); - break; - - case "qt": - setBool(pl, 'qt', 'loop'); - setBool(pl, 'qt', 'autoplay'); - setBool(pl, 'qt', 'cache'); - setBool(pl, 'qt', 'controller'); - setBool(pl, 'qt', 'correction'); - setBool(pl, 'qt', 'enablejavascript'); - setBool(pl, 'qt', 'kioskmode'); - setBool(pl, 'qt', 'autohref'); - setBool(pl, 'qt', 'playeveryframe'); - setBool(pl, 'qt', 'tarsetcache'); - setStr(pl, 'qt', 'scale'); - setStr(pl, 'qt', 'starttime'); - setStr(pl, 'qt', 'endtime'); - setStr(pl, 'qt', 'tarset'); - setStr(pl, 'qt', 'qtsrcchokespeed'); - setStr(pl, 'qt', 'volume'); - setStr(pl, 'qt', 'qtsrc'); - break; - - case "shockwave": - setBool(pl, 'shockwave', 'sound'); - setBool(pl, 'shockwave', 'progress'); - setBool(pl, 'shockwave', 'autostart'); - setBool(pl, 'shockwave', 'swliveconnect'); - setStr(pl, 'shockwave', 'swvolume'); - setStr(pl, 'shockwave', 'swstretchstyle'); - setStr(pl, 'shockwave', 'swstretchhalign'); - setStr(pl, 'shockwave', 'swstretchvalign'); - break; - - case "wmp": - setBool(pl, 'wmp', 'autostart'); - setBool(pl, 'wmp', 'enabled'); - setBool(pl, 'wmp', 'enablecontextmenu'); - setBool(pl, 'wmp', 'fullscreen'); - setBool(pl, 'wmp', 'invokeurls'); - setBool(pl, 'wmp', 'mute'); - setBool(pl, 'wmp', 'stretchtofit'); - setBool(pl, 'wmp', 'windowlessvideo'); - setStr(pl, 'wmp', 'balance'); - setStr(pl, 'wmp', 'baseurl'); - setStr(pl, 'wmp', 'captioningid'); - setStr(pl, 'wmp', 'currentmarker'); - setStr(pl, 'wmp', 'currentposition'); - setStr(pl, 'wmp', 'defaultframe'); - setStr(pl, 'wmp', 'playcount'); - setStr(pl, 'wmp', 'rate'); - setStr(pl, 'wmp', 'uimode'); - setStr(pl, 'wmp', 'volume'); - break; - - case "rmp": - setBool(pl, 'rmp', 'autostart'); - setBool(pl, 'rmp', 'loop'); - setBool(pl, 'rmp', 'autogotourl'); - setBool(pl, 'rmp', 'center'); - setBool(pl, 'rmp', 'imagestatus'); - setBool(pl, 'rmp', 'maintainaspect'); - setBool(pl, 'rmp', 'nojava'); - setBool(pl, 'rmp', 'prefetch'); - setBool(pl, 'rmp', 'shuffle'); - setStr(pl, 'rmp', 'console'); - setStr(pl, 'rmp', 'controls'); - setStr(pl, 'rmp', 'numloop'); - setStr(pl, 'rmp', 'scriptcallbacks'); - break; - } - - setStr(pl, null, 'src'); - setStr(pl, null, 'id'); - setStr(pl, null, 'name'); - setStr(pl, null, 'vspace'); - setStr(pl, null, 'hspace'); - setStr(pl, null, 'bgcolor'); - setStr(pl, null, 'align'); - setStr(pl, null, 'width'); - setStr(pl, null, 'height'); - - if ((val = tinyMCE.getAttrib(fe, "width")) != "") - pl.width = f.width.value = val; - - if ((val = tinyMCE.getAttrib(fe, "height")) != "") - pl.height = f.height.value = val; - - oldWidth = pl.width ? parseInt(pl.width) : 0; - oldHeight = pl.height ? parseInt(pl.height) : 0; - } else - oldWidth = oldHeight = 0; - - selectByValue(f, 'media_type', type); - changedType(type); - updateColor('bgcolor_pick', 'bgcolor'); - - TinyMCE_EditableSelects.init(); - generatePreview(); -} - -function insertMedia() { - var fe, f = document.forms[0], h; - - if (!AutoValidator.validate(f)) { - alert(tinyMCE.getLang('lang_invalid_data')); - return false; - } - - f.width.value = f.width.value == "" ? 100 : f.width.value; - f.height.value = f.height.value == "" ? 100 : f.height.value; - - fe = tinyMCE.selectedInstance.getFocusElement(); - if (fe != null && /mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(tinyMCE.getAttrib(fe, 'class'))) { - switch (f.media_type.options[f.media_type.selectedIndex].value) { - case "flash": - fe.className = "mceItemFlash"; - break; - - case "shockwave": - fe.className = "mceItemShockWave"; - break; - - case "qt": - fe.className = "mceItemQuickTime"; - break; - - case "wmp": - fe.className = "mceItemWindowsMedia"; - break; - - case "rmp": - fe.className = "mceItemRealMedia"; - break; - } - - if (fe.width != f.width.value || fe.height != f.width.height) - tinyMCE.selectedInstance.repaint(); - - fe.title = serializeParameters(); - fe.width = f.width.value; - fe.height = f.height.value; - fe.style.width = f.width.value + (f.width.value.indexOf('%') == -1 ? 'px' : ''); - fe.style.height = f.height.value + (f.height.value.indexOf('%') == -1 ? 'px' : ''); - fe.align = f.align.options[f.align.selectedIndex].value; - } else { - h = ' 0) { - var html = ""; - - html += ''; - - return html; - } - - return ""; -} - -function getType(v) { - var fo = tinyMCE.getParam("media_types", "flash=swf;shockwave=dcr;qt=mov,qt,mpg,mp3,mp4,mpeg;shockwave=dcr;wmp=avi,wmv,wm,asf,asx,wmx,wvx;rmp=rm,ra,ram").split(';'), i, c, el, x; - - for (i=0; i 0 ? s.substring(0, s.length - 1) : s; - - return s; -} - -function setBool(pl, p, n) { - if (typeof(pl[n]) == "undefined") - return; - - document.forms[0].elements[p + "_" + n].checked = pl[n]; -} - -function setStr(pl, p, n) { - var f = document.forms[0], e = f.elements[(p != null ? p + "_" : '') + n]; - - if (typeof(pl[n]) == "undefined") - return; - - if (e.type == "text") - e.value = pl[n]; - else - selectByValue(f, (p != null ? p + "_" : '') + n, pl[n]); -} - -function getBool(p, n, d, tv, fv) { - var v = document.forms[0].elements[p + "_" + n].checked; - - tv = typeof(tv) == 'undefined' ? 'true' : "'" + jsEncode(tv) + "'"; - fv = typeof(fv) == 'undefined' ? 'false' : "'" + jsEncode(fv) + "'"; - - return (v == d) ? '' : n + (v ? ':' + tv + ',' : ':' + fv + ','); -} - -function getStr(p, n, d) { - var e = document.forms[0].elements[(p != null ? p + "_" : "") + n]; - var v = e.type == "text" ? e.value : e.options[e.selectedIndex].value; - - return ((n == d || v == '') ? '' : n + ":'" + jsEncode(v) + "',"); -} - -function getInt(p, n, d) { - var e = document.forms[0].elements[(p != null ? p + "_" : "") + n]; - var v = e.type == "text" ? e.value : e.options[e.selectedIndex].value; - - return ((n == d || v == '') ? '' : n + ":" + v.replace(/[^0-9]+/g, '') + ","); -} - -function jsEncode(s) { - s = s.replace(new RegExp('\\\\', 'g'), '\\\\'); - s = s.replace(new RegExp('"', 'g'), '\\"'); - s = s.replace(new RegExp("'", 'g'), "\\'"); - - return s; -} - -function generatePreview(c) { - var f = document.forms[0], p = document.getElementById('prev'), h = '', cls, pl, n, type, codebase, wp, hp, nw, nh; - - p.innerHTML = ''; - - nw = parseInt(f.width.value); - nh = parseInt(f.height.value); - - if (f.width.value != "" && f.height.value != "") { - if (f.constrain.checked) { - if (c == 'width' && oldWidth != 0) { - wp = nw / oldWidth; - nh = Math.round(wp * nh); - f.height.value = nh; - } else if (c == 'height' && oldHeight != 0) { - hp = nh / oldHeight; - nw = Math.round(hp * nw); - f.width.value = nw; - } - } - } - - if (f.width.value != "") - oldWidth = nw; - - if (f.height.value != "") - oldHeight = nh; - - // After constrain - pl = serializeParameters(); - - switch (f.media_type.options[f.media_type.selectedIndex].value) { - case "flash": - cls = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'; - codebase = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0'; - type = 'application/x-shockwave-flash'; - break; - - case "shockwave": - cls = 'clsid:166B1BCA-3F9C-11CF-8075-444553540000'; - codebase = 'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0'; - type = 'application/x-director'; - break; - - case "qt": - cls = 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B'; - codebase = 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0'; - type = 'video/quicktime'; - break; - - case "wmp": - cls = tinyMCE.getParam('media_wmp6_compatible') ? 'clsid:05589FA1-C356-11CE-BF01-00AA0055595A' : 'clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6'; - codebase = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701'; - type = 'application/x-mplayer2'; - break; - - case "rmp": - cls = 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA'; - codebase = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701'; - type = 'audio/x-pn-realaudio-plugin'; - break; - } - - if (pl == '') { - p.innerHTML = ''; - return; - } - - pl = eval('x={' + pl + '};'); - - if (!pl.src) { - p.innerHTML = ''; - return; - } - - pl.src = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], pl.src); - pl.width = !pl.width ? 100 : pl.width; - pl.height = !pl.height ? 100 : pl.height; - pl.id = !pl.id ? 'obj' : pl.id; - pl.name = !pl.name ? 'eobj' : pl.name; - pl.align = !pl.align ? '' : pl.align; - - h += ''; - - for (n in pl) { - h += ''; - - // Add extra url parameter if it's an absolute URL - if (n == 'src' && pl[n].indexOf('://') != -1) - h += ''; - } - - h += ' - {$lang_media_title} - - - - - - + {#media_dlg.title} + + + + + + - +
- {$lang_media_general} + {#media_dlg.general}
   
- + - + @@ -196,7 +199,7 @@
@@ -49,54 +51,55 @@ - + - +
 
- - - - - - -
x   
+ + + + + + +
x   
+
- {$lang_media_preview} + {#media_dlg.preview}
- {$lang_media_advanced} + {#media_dlg.advanced} - + - + - + - + @@ -185,7 +188,7 @@
@@ -108,23 +111,23 @@ - + - +
- {$lang_media_flash_options} + {#media_dlg.flash_options} - + - + - + - + @@ -176,7 +179,7 @@
- +
- +
- +
- +
- + - +
+
+ {#media_dlg.flv_options} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+
+
- {$lang_media_qt_options} + {#media_dlg.qt_options} @@ -234,7 +334,7 @@
- +
- - + +
- +
- +
- +
@@ -283,7 +383,7 @@ - +
@@ -294,7 +394,7 @@ - +
@@ -303,7 +403,7 @@ - +
@@ -314,7 +414,7 @@ - +
@@ -323,16 +423,16 @@ - +
- + @@ -342,31 +442,31 @@ - + - + - + - + - + - + - + @@ -380,7 +480,7 @@
- {$lang_media_wmp_options} + {#media_dlg.wmp_options}
@@ -388,7 +488,7 @@
- +
@@ -397,7 +497,7 @@ - +
@@ -408,7 +508,7 @@ - +
@@ -417,7 +517,7 @@ - +
@@ -428,7 +528,7 @@ - +
@@ -437,7 +537,7 @@ - +
@@ -448,7 +548,7 @@ - +
@@ -457,49 +557,49 @@ - +
- + - + - + - + - + - + - + - + - + - + @@ -507,7 +607,7 @@
- {$lang_media_rmp_options} + {#media_dlg.rmp_options} @@ -515,7 +615,7 @@
- +
@@ -524,7 +624,7 @@ - +
@@ -535,7 +635,7 @@ - +
@@ -544,7 +644,7 @@ - +
@@ -555,7 +655,7 @@ - +
@@ -564,7 +664,7 @@ - +
@@ -575,7 +675,7 @@ - +
@@ -584,7 +684,7 @@ - +
@@ -595,7 +695,7 @@ - +
@@ -606,57 +706,57 @@ - + - + - + - +
- {$lang_media_shockwave_options} + {#media_dlg.shockwave_options} - + - + - + - + @@ -678,7 +778,7 @@
- +
- +
@@ -690,7 +790,7 @@ - +
@@ -699,7 +799,7 @@ - +
@@ -711,11 +811,11 @@
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/nonbreaking/editor_plugin.js --- a/includes/clientside/tinymce/plugins/nonbreaking/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/nonbreaking/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('nonbreaking');var TinyMCE_NonBreakingPlugin={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}},getControlHTML:function(cn){switch(cn){case"nonbreaking":return tinyMCE.getButtonHTML(cn,'lang_nonbreaking_desc','{$pluginurl}/images/nonbreaking.gif','mceNonBreaking',false)}return""},execCommand:function(editor_id,element,command,user_interface,value){var inst=tinyMCE.getInstanceById(editor_id),h;switch(command){case"mceNonBreaking":h=(inst.visualChars&&inst.visualChars.state)?'·':' ';tinyMCE.execInstanceCommand(editor_id,'mceInsertContent',false,h);return true}return false},handleEvent:function(e){var inst,h;if(!tinyMCE.isOpera&&e.type=='keydown'&&e.keyCode==9&&tinyMCE.getParam('nonbreaking_force_tab',false)){inst=tinyMCE.selectedInstance;h=(inst.visualChars&&inst.visualChars.state)?'···':'   ';tinyMCE.execInstanceCommand(inst.editorId,'mceInsertContent',false,h);tinyMCE.cancelEvent(e);return false}return true}};tinyMCE.addPlugin("nonbreaking",TinyMCE_NonBreakingPlugin); \ No newline at end of file +(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)?'·':' ');});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 diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/nonbreaking/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/nonbreaking/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/nonbreaking/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,62 +1,50 @@ /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ + * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('nonbreaking'); +(function() { + tinymce.create('tinymce.plugins.Nonbreaking', { + init : function(ed, url) { + var t = this; + + t.editor = ed; + + // Register commands + ed.addCommand('mceNonBreaking', function() { + ed.execCommand('mceInsertContent', false, (ed.plugins.visualchars && ed.plugins.visualchars.state) ? '·' : ' '); + }); + + // Register buttons + ed.addButton('nonbreaking', {title : 'nonbreaking.nonbreaking_desc', cmd : 'mceNonBreaking'}); -var TinyMCE_NonBreakingPlugin = { - 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 - }; - }, + 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); + } + }); + } + }, - getControlHTML : function(cn) { - switch (cn) { - case "nonbreaking": - return tinyMCE.getButtonHTML(cn, 'lang_nonbreaking_desc', '{$pluginurl}/images/nonbreaking.gif', 'mceNonBreaking', false); + 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 + }; } - return ""; - }, - - - execCommand : function(editor_id, element, command, user_interface, value) { - var inst = tinyMCE.getInstanceById(editor_id), h; - - switch (command) { - case "mceNonBreaking": - h = (inst.visualChars && inst.visualChars.state) ? '·' : ' '; - tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false, h); - return true; - } - - return false; - }, + // Private methods + }); - handleEvent : function(e) { - var inst, h; - - if (!tinyMCE.isOpera && e.type == 'keydown' && e.keyCode == 9 && tinyMCE.getParam('nonbreaking_force_tab', false)) { - inst = tinyMCE.selectedInstance; - - h = (inst.visualChars && inst.visualChars.state) ? '···' : '   '; - tinyMCE.execInstanceCommand(inst.editorId, 'mceInsertContent', false, h); - - tinyMCE.cancelEvent(e); - return false; - } - - return true; - } -}; - -tinyMCE.addPlugin("nonbreaking", TinyMCE_NonBreakingPlugin); + // Register plugin + tinymce.PluginManager.add('nonbreaking', tinymce.plugins.Nonbreaking); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/nonbreaking/images/nonbreaking.gif Binary file includes/clientside/tinymce/plugins/nonbreaking/images/nonbreaking.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/nonbreaking/langs/en.js --- a/includes/clientside/tinymce/plugins/nonbreaking/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('nonbreaking',{ -desc : 'Insert non-breaking space character' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/noneditable/css/noneditable.css --- a/includes/clientside/tinymce/plugins/noneditable/css/noneditable.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -/* This is the CSS file for the noneditable elements plugin */ - -.mceEditable { - /*border: 1px dotted #0000cc;*/ -} - -.mceNonEditable { - /*border: 1px dotted #cc0000;*/ -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/noneditable/editor_plugin.js --- a/includes/clientside/tinymce/plugins/noneditable/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/noneditable/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -var TinyMCE_NonEditablePlugin={getInfo:function(){return{longname:'Non editable elements',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},initInstance:function(inst){tinyMCE.importCSS(inst.getDoc(),tinyMCE.baseURL+"/plugins/noneditable/css/noneditable.css");if(tinyMCE.isMSIE5_0)tinyMCE.settings['plugins']=tinyMCE.settings['plugins'].replace(/noneditable/gi,'Noneditable')},handleEvent:function(e){return this._moveSelection(e,tinyMCE.selectedInstance)},cleanup:function(type,content,inst){switch(type){case"insert_to_editor_dom":var nodes,i,editClass,nonEditClass,editable,elm;if(tinyMCE.isGecko)return content;nodes=tinyMCE.getNodeTree(content,[],1);editClass=tinyMCE.getParam("noneditable_editable_class","mceEditable");nonEditClass=tinyMCE.getParam("noneditable_noneditable_class","mceNonEditable");for(i=0;i',cls='mcePageBreak',sep=ed.getParam('pagebreak_separator',''),pbRE;pbRE=new RegExp(sep.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(a){return'\\'+a;}),'g');ed.addCommand('mcePageBreak',function(){ed.execCommand('mceInsertContent',0,pb);});ed.addButton('pagebreak',{title:'pagebreak.desc',cmd:cls});ed.onInit.add(function(){ed.dom.loadCSS(url+"/css/content.css");if(ed.theme.onResolveName){ed.theme.onResolveName.add(function(th,o){if(o.node.nodeName=='IMG'&&ed.dom.hasClass(o.node,cls))o.name='pagebreak';});}});ed.onClick.add(function(ed,e){e=e.target;if(e.nodeName==='IMG'&&ed.dom.hasClass(e,cls))ed.selection.select(e);});ed.onNodeChange.add(function(ed,cm,n){cm.setActive('pagebreak',n.nodeName==='IMG'&&ed.dom.hasClass(n,cls));});ed.onBeforeSetContent.add(function(ed,o){o.content=o.content.replace(pbRE,pb);});ed.onPostProcess.add(function(ed,o){if(o.get)o.content=o.content.replace(/]+>/g,function(im){if(im.indexOf('class="mcePageBreak')!==-1)im=sep;return im;});});},getInfo:function(){return{longname:'PageBreak',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/pagebreak',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('pagebreak',tinymce.plugins.PageBreakPlugin);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/pagebreak/editor_plugin_src.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/pagebreak/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,73 @@ +/** + * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * + * @author Moxiecode + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ + +(function() { + tinymce.create('tinymce.plugins.PageBreakPlugin', { + init : function(ed, url) { + var pb = '', cls = 'mcePageBreak', sep = ed.getParam('pagebreak_separator', ''), pbRE; + + pbRE = new RegExp(sep.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g, function(a) {return '\\' + a;}), 'g'); + + // Register commands + ed.addCommand('mcePageBreak', function() { + ed.execCommand('mceInsertContent', 0, pb); + }); + + // Register buttons + ed.addButton('pagebreak', {title : 'pagebreak.desc', cmd : cls}); + + ed.onInit.add(function() { + ed.dom.loadCSS(url + "/css/content.css"); + + if (ed.theme.onResolveName) { + ed.theme.onResolveName.add(function(th, o) { + if (o.node.nodeName == 'IMG' && ed.dom.hasClass(o.node, cls)) + o.name = 'pagebreak'; + }); + } + }); + + ed.onClick.add(function(ed, e) { + e = e.target; + + if (e.nodeName === 'IMG' && ed.dom.hasClass(e, cls)) + ed.selection.select(e); + }); + + ed.onNodeChange.add(function(ed, cm, n) { + cm.setActive('pagebreak', n.nodeName === 'IMG' && ed.dom.hasClass(n, cls)); + }); + + ed.onBeforeSetContent.add(function(ed, o) { + o.content = o.content.replace(pbRE, pb); + }); + + ed.onPostProcess.add(function(ed, o) { + if (o.get) + o.content = o.content.replace(/]+>/g, function(im) { + if (im.indexOf('class="mcePageBreak') !== -1) + im = sep; + + return im; + }); + }); + }, + + getInfo : function() { + return { + longname : 'PageBreak', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/pagebreak', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); + + // Register plugin + tinymce.PluginManager.add('pagebreak', tinymce.plugins.PageBreakPlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/pagebreak/img/pagebreak.gif Binary file includes/clientside/tinymce/plugins/pagebreak/img/pagebreak.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/pagebreak/img/trans.gif Binary file includes/clientside/tinymce/plugins/pagebreak/img/trans.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/paste/blank.htm --- a/includes/clientside/tinymce/plugins/paste/blank.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/paste/blank.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,17 +1,20 @@ - blank_page - - - - +blank_page + + + + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/paste/css/blank.css --- a/includes/clientside/tinymce/plugins/paste/css/blank.css Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/paste/css/blank.css Fri Feb 22 12:51:53 2008 -0500 @@ -1,13 +1,14 @@ +html, body {height:98%} body { - background-color: #FFFFFF; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 10px; - scrollbar-3dlight-color: #F0F0EE; - scrollbar-arrow-color: #676662; - scrollbar-base-color: #F0F0EE; - scrollbar-darkshadow-color: #DDDDDD; - scrollbar-face-color: #E0E0DD; - scrollbar-highlight-color: #F0F0EE; - scrollbar-shadow-color: #F0F0EE; - scrollbar-track-color: #F5F5F5; +background-color: #FFFFFF; +font-family: Verdana, Arial, Helvetica, sans-serif; +font-size: 10px; +scrollbar-3dlight-color: #F0F0EE; +scrollbar-arrow-color: #676662; +scrollbar-base-color: #F0F0EE; +scrollbar-darkshadow-color: #DDDDDD; +scrollbar-face-color: #E0E0DD; +scrollbar-highlight-color: #F0F0EE; +scrollbar-shadow-color: #F0F0EE; +scrollbar-track-color: #F5F5F5; } diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/paste/editor_plugin.js --- a/includes/clientside/tinymce/plugins/paste/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/paste/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('paste');var TinyMCE_PastePlugin={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}},initInstance:function(inst){if(tinyMCE.isMSIE&&tinyMCE.getParam("paste_auto_cleanup_on_paste",false))tinyMCE.addEvent(inst.getBody(),"paste",TinyMCE_PastePlugin._handlePasteEvent)},handleEvent:function(e){if(!tinyMCE.isRealIE&&tinyMCE.getParam("paste_auto_cleanup_on_paste",false)&&e.ctrlKey&&e.keyCode==86&&e.type=="keydown"){window.setTimeout('tinyMCE.selectedInstance.execCommand("mcePasteText",true)',1);return tinyMCE.cancelEvent(e)}return true},getControlHTML:function(cn){switch(cn){case"pastetext":return tinyMCE.getButtonHTML(cn,'lang_paste_text_desc','{$pluginurl}/images/pastetext.gif','mcePasteText',true);case"pasteword":return tinyMCE.getButtonHTML(cn,'lang_paste_word_desc','{$pluginurl}/images/pasteword.gif','mcePasteWord',true);case"selectall":return tinyMCE.getButtonHTML(cn,'lang_selectall_desc','{$pluginurl}/images/selectall.gif','mceSelectAll',true)}return''},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mcePasteText":if(user_interface){if((tinyMCE.isMSIE&&!tinyMCE.isOpera)&&!tinyMCE.getParam('paste_use_dialog',false))TinyMCE_PastePlugin._insertText(clipboardData.getData("Text"),true);else{var template=new Array();template['file']='../../plugins/paste/pastetext.htm';template['width']=450;template['height']=400;var plain_text="";tinyMCE.openWindow(template,{editor_id:editor_id,plain_text:plain_text,resizable:"yes",scrollbars:"no",inline:"yes",mceDo:'insert'})}}else TinyMCE_PastePlugin._insertText(value['html'],value['linebreaks']);return true;case"mcePasteWord":if(user_interface){if((tinyMCE.isMSIE&&!tinyMCE.isOpera)&&!tinyMCE.getParam('paste_use_dialog',false)){TinyMCE_PastePlugin._insertWordContent(TinyMCE_PastePlugin._clipboardHTML())}else{var template=new Array();template['file']='../../plugins/paste/pasteword.htm';template['width']=450;template['height']=400;var plain_text="";tinyMCE.openWindow(template,{editor_id:editor_id,plain_text:plain_text,resizable:"yes",scrollbars:"no",inline:"yes",mceDo:'insert'})}}else TinyMCE_PastePlugin._insertWordContent(value);return true;case"mceSelectAll":tinyMCE.execInstanceCommand(editor_id,'selectall');return true}return false},_handlePasteEvent:function(e){switch(e.type){case"paste":var html=TinyMCE_PastePlugin._clipboardHTML();var r,inst=tinyMCE.selectedInstance;if(inst&&(r=inst.getRng())&&r.text.length>0)tinyMCE.execCommand('delete');if(html&&html.length>0)tinyMCE.execCommand('mcePasteWord',false,html);tinyMCE.cancelEvent(e);return false}return true},_insertText:function(content,bLinebreaks){if(content&&content.length>0){if(bLinebreaks){if(tinyMCE.getParam("paste_create_paragraphs",true)){var rl=tinyMCE.getParam("paste_replace_list",'\u2122,TM,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');for(var i=0;i

","gi");content=tinyMCE.regexpReplace(content,"\r\r","

","gi");content=tinyMCE.regexpReplace(content,"\n\n","

","gi");if((pos=content.indexOf('

'))!=-1){tinyMCE.execCommand("Delete");var node=tinyMCE.selectedInstance.getFocusElement();var breakElms=new Array();do{if(node.nodeType==1){if(node.nodeName=="TD"||node.nodeName=="BODY")break;breakElms[breakElms.length]=node}}while(node=node.parentNode);var before="",after="

";before+=content.substring(0,pos);for(var i=0;i";after+="<"+breakElms[(breakElms.length-1)-i].nodeName+">"}before+="

";content=before+content.substring(pos+7)+after}}if(tinyMCE.getParam("paste_create_linebreaks",true)){content=tinyMCE.regexpReplace(content,"\r\n","
","gi");content=tinyMCE.regexpReplace(content,"\r","
","gi");content=tinyMCE.regexpReplace(content,"\n","
","gi")}}tinyMCE.execCommand("mceInsertRawHTML",false,content)}},_insertWordContent:function(content){if(content&&content.length>0){var bull=String.fromCharCode(8226);var middot=String.fromCharCode(183);var cb;if((cb=tinyMCE.getParam("paste_insert_word_content_callback",""))!="")content=eval(cb+"('before', content)");var rl=tinyMCE.getParam("paste_replace_list",'\u2122,TM,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');for(var i=0;i(.*?)<\/p>','gi'),'

$1

')}content=content.replace(new RegExp('tab-stops: list [0-9]+.0pt">','gi'),'">'+"--list--");content=content.replace(new RegExp(bull+"(.*?)
","gi"),"

"+middot+"$1

");content=content.replace(new RegExp('','gi'),""+bull);content=content.replace(/<\/o:p>/gi,"");content=content.replace(new RegExp('
]*>/gi,"");if(tinyMCE.getParam("paste_remove_styles",true))content=content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)','gi'),"<$1$3");content=content.replace(/<\/?font[^>]*>/gi,"");switch(tinyMCE.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="?'+TinyMCE_PastePlugin._reEscape(""+document.location)+'','gi'),'href="'+tinyMCE.settings['document_base_url']);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>/gi,"");content=content.replace(/-- page break --/gi,"");if(!tinyMCE.settings['force_p_newlines']){content=content.replace('','','gi');content=content.replace('

','

','gi')}if(!tinyMCE.isMSIE&&!tinyMCE.settings['force_p_newlines']){content=content.replace(/<\/?p[^>]*>/gi,"")}content=content.replace(/<\/?div[^>]*>/gi,"");if(tinyMCE.getParam("paste_convert_middot_lists",true)){var div=document.createElement("div");div.innerHTML=content;var className=tinyMCE.getParam("paste_unindented_list_class","unIndentedList");while(TinyMCE_PastePlugin._convertMiddots(div,"--list--"));while(TinyMCE_PastePlugin._convertMiddots(div,middot,className));while(TinyMCE_PastePlugin._convertMiddots(div,bull));content=div.innerHTML}if(tinyMCE.getParam("paste_convert_headers_to_strong",false)){content=content.replace(/ <\/h[1-6]>/gi,'

  

');content=content.replace(//gi,'

');content=content.replace(/<\/h[1-6]>/gi,'

');content=content.replace(/ <\/b>/gi,'  ');content=content.replace(/^( )*/gi,'')}content=content.replace(/--list--/gi,"");if((cb=tinyMCE.getParam("paste_insert_word_content_callback",""))!="")content=eval(cb+"('after', content)");tinyMCE.execCommand("mceInsertContent",false,content);if(tinyMCE.getParam('paste_force_cleanup_wordpaste',true))window.setTimeout('tinyMCE.execCommand("mceCleanup");',1);}},_reEscape:function(s){var l="?.\\*[](){}+^$:";var o="";for(var i=0;i0)ed.execCommand('delete');if(html&&html.length>0)ed.execCommand('mcePasteWord',false,html);return Event.cancel(e);},_insertText:function(content,bLinebreaks){if(content&&content.length>0){if(bLinebreaks){if(this.editor.getParam("paste_create_paragraphs",true)){var rl=this.editor.getParam("paste_replace_list",'\u2122,TM,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');for(var i=0;i

');content=content.replace(/\r\r/g,'

');content=content.replace(/\n\n/g,'

');if((pos=content.indexOf('

'))!=-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="

";before+=content.substring(0,pos);for(var i=0;i";after+="<"+breakElms[(breakElms.length-1)-i].nodeName+">";}before+="

";content=before+content.substring(pos+7)+after;}}if(this.editor.getParam("paste_create_linebreaks",true)){content=content.replace(/\r\n/g,'
');content=content.replace(/\r/g,'
');content=content.replace(/\n/g,'
');}}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);var cb;if((cb=this.editor.getParam("paste_insert_word_content_callback",""))!="")content=eval(cb+"('before', content)");var rl=this.editor.getParam("paste_replace_list",'\u2122,TM,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(',');for(var i=0;i(.*?)<\/p>','gi'),'

$1

');}content=content.replace(new RegExp('tab-stops: list [0-9]+.0pt">','gi'),'">'+"--list--");content=content.replace(new RegExp(bull+"(.*?)
","gi"),"

"+middot+"$1

");content=content.replace(new RegExp('','gi'),""+bull);content=content.replace(/<\/o:p>/gi,"");content=content.replace(new RegExp('
]*>/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>/gi,"");content=content.replace(/-- page break --/gi,"");if(!this.editor.getParam('force_p_newlines')){content=content.replace('','','gi');content=content.replace('

','

','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]>/gi,'

  

');content=content.replace(//gi,'

');content=content.replace(/<\/h[1-6]>/gi,'

');content=content.replace(/ <\/b>/gi,'  ');content=content.replace(/^( )*/gi,'');}content=content.replace(/--list--/gi,"");if((cb=this.editor.getParam("paste_insert_word_content_callback",""))!="")content=eval(cb+"('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 0) - tinyMCE.execCommand('delete'); - - if (html && html.length > 0) - tinyMCE.execCommand('mcePasteWord', false, html); - - tinyMCE.cancelEvent(e); - return false; - } - - return true; - }, - - _insertText : function(content, bLinebreaks) { - if (content && content.length > 0) { - if (bLinebreaks) { - // Special paragraph treatment - if (tinyMCE.getParam("paste_create_paragraphs", true)) { - var rl = tinyMCE.getParam("paste_replace_list", '\u2122,TM,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); - for (var i=0; i

", "gi"); - content = tinyMCE.regexpReplace(content, "\r\r", "

", "gi"); - content = tinyMCE.regexpReplace(content, "\n\n", "

", "gi"); - - // Has paragraphs - if ((pos = content.indexOf('

')) != -1) { - tinyMCE.execCommand("Delete"); - - var node = tinyMCE.selectedInstance.getFocusElement(); - - // Get list of elements to break - var breakElms = new Array(); + ed.addCommand('mcePasteWord', function(ui, v) { + if (ui) { + ed.windowManager.open({ + file : url + '/pasteword.htm', + width : 450, + height : 400, + inline : 1 + }, { + plugin_url : url + }); + } else + t._insertWordContent(v); + }); - do { - if (node.nodeType == 1) { - // Don't break tables and break at body - if (node.nodeName == "TD" || node.nodeName == "BODY") - break; - - breakElms[breakElms.length] = node; - } - } while(node = node.parentNode); - - var before = "", after = "

"; - before += content.substring(0, pos); - - for (var i=0; i"; - after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; - } - - before += "

"; - content = before + content.substring(pos+7) + after; - } - } + ed.addCommand('mceSelectAll', function() { + ed.execCommand('selectall'); + }); - if (tinyMCE.getParam("paste_create_linebreaks", true)) { - content = tinyMCE.regexpReplace(content, "\r\n", "
", "gi"); - content = tinyMCE.regexpReplace(content, "\r", "
", "gi"); - content = tinyMCE.regexpReplace(content, "\n", "
", "gi"); - } - } - - tinyMCE.execCommand("mceInsertRawHTML", false, content); - } - }, + // Register buttons + 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'}); - _insertWordContent : function(content) { - if (content && content.length > 0) { - // Cleanup Word content - var bull = String.fromCharCode(8226); - var middot = String.fromCharCode(183); - var cb; - - if ((cb = tinyMCE.getParam("paste_insert_word_content_callback", "")) != "") - content = eval(cb + "('before', content)"); - - var rl = tinyMCE.getParam("paste_replace_list", '\u2122,TM,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); - for (var i=0; i(.*?)<\/p>', 'gi'), '

$1

'); + if (ed.getParam("paste_auto_cleanup_on_paste", false)) { + ed.onPaste.add(function(ed, e) { + return t._handlePasteEvent(e) + }); } - content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--"); - content = content.replace(new RegExp(bull + "(.*?)
", "gi"), "

" + middot + "$1

"); - content = content.replace(new RegExp('', 'gi'), "" + bull); // Covert to bull list - content = content.replace(/<\/o:p>/gi, ""); - content = content.replace(new RegExp('
]*>/gi, ""); + _handlePasteEvent : function(e) { + var html = this._clipboardHTML(), ed = this.editor, sel = ed.selection, r; + + // Removes italic, strong etc, the if was needed due to bug #1437114 + 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); + }, - if (tinyMCE.getParam("paste_remove_styles", true)) - content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3"); + _insertText : function(content, bLinebreaks) { + if (content && content.length > 0) { + if (bLinebreaks) { + // Special paragraph treatment + if (this.editor.getParam("paste_create_paragraphs", true)) { + var rl = this.editor.getParam("paste_replace_list", '\u2122,TM,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); + for (var i=0; i]*>/gi, ""); + content = content.replace(/\r\n\r\n/g, '

'); + content = content.replace(/\r\r/g, '

'); + content = content.replace(/\n\n/g, '

'); - // Strips class attributes. - switch (tinyMCE.getParam("paste_strip_class_attributes", "all")) { - case "all": - content = content.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3"); - break; + // Has paragraphs + if ((pos = content.indexOf('

')) != -1) { + this.editor.execCommand("Delete"); + + var node = this.editor.selection.getNode(); + + // Get list of elements to break + var breakElms = []; + + do { + if (node.nodeType == 1) { + // Don't break tables and break at body + if (node.nodeName == "TD" || node.nodeName == "BODY") + break; + + breakElms[breakElms.length] = node; + } + } while(node = node.parentNode); + + var before = "", after = "

"; + before += content.substring(0, pos); + + for (var i=0; i"; + after += "<" + breakElms[(breakElms.length-1)-i].nodeName + ">"; + } - case "mso": - content = content.replace(new RegExp('<(\\w[^>]*) class="?mso([^ |>]*)([^>]*)', 'gi'), "<$1$3"); - break; - } + before += "

"; + content = before + content.substring(pos+7) + after; + } + } - content = content.replace(new RegExp('href="?' + TinyMCE_PastePlugin._reEscape("" + document.location) + '', 'gi'), 'href="' + tinyMCE.settings['document_base_url']); - 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>/gi, ""); // Remove pagebreaks - content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks + if (this.editor.getParam("paste_create_linebreaks", true)) { + content = content.replace(/\r\n/g, '
'); + content = content.replace(/\r/g, '
'); + content = content.replace(/\n/g, '
'); + } + } + + this.editor.execCommand("mceInsertRawHTML", false, content); + } + }, + + _insertWordContent : function(content) { + var t = this, ed = t.editor; + + if (content && content.length > 0) { + // Cleanup Word content + var bull = String.fromCharCode(8226); + var middot = String.fromCharCode(183); + var cb; + + if ((cb = this.editor.getParam("paste_insert_word_content_callback", "")) != "") + content = eval(cb + "('before', content)"); - // content = content.replace(/\/? */gi, "");   - // content = content.replace(/

 <\/p>/gi, ''); + var rl = this.editor.getParam("paste_replace_list", '\u2122,TM,\u2026,...,\u201c|\u201d,",\u2019,\',\u2013|\u2014|\u2015|\u2212,-').split(','); + for (var i=0; i(.*?)<\/p>', 'gi'), '

$1

'); + } + + content = content.replace(new RegExp('tab-stops: list [0-9]+.0pt">', 'gi'), '">' + "--list--"); + content = content.replace(new RegExp(bull + "(.*?)
", "gi"), "

" + middot + "$1

"); + content = content.replace(new RegExp('', 'gi'), "" + bull); // Covert to bull list + content = content.replace(/<\/o:p>/gi, ""); + content = content.replace(new RegExp('
]*>/gi, ""); + + if (this.editor.getParam("paste_remove_styles", true)) + content = content.replace(new RegExp('<(\\w[^>]*) style="([^"]*)"([^>]*)', 'gi'), "<$1$3"); + + content = content.replace(/<\/?font[^>]*>/gi, ""); - if (!tinyMCE.settings['force_p_newlines']) { - content = content.replace('', '' ,'gi'); - content = content.replace('

', '

' ,'gi'); - } + // Strips class attributes. + 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; + } - if (!tinyMCE.isMSIE && !tinyMCE.settings['force_p_newlines']) { - content = content.replace(/<\/?p[^>]*>/gi, ""); - } + 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>/gi, ""); // Remove pagebreaks + content = content.replace(/-- page break --/gi, ""); // Remove pagebreaks - content = content.replace(/<\/?div[^>]*>/gi, ""); + // content = content.replace(/\/? */gi, "");   + // content = content.replace(/

 <\/p>/gi, ''); + + if (!this.editor.getParam('force_p_newlines')) { + content = content.replace('', '' ,'gi'); + content = content.replace('

', '

' ,'gi'); + } + + if (!tinymce.isIE && !this.editor.getParam('force_p_newlines')) { + content = content.replace(/<\/?p[^>]*>/gi, ""); + } - // Convert all middlot lists to UL lists - if (tinyMCE.getParam("paste_convert_middot_lists", true)) { - var div = document.createElement("div"); - div.innerHTML = content; + content = content.replace(/<\/?div[^>]*>/gi, ""); + + // Convert all middlot lists to UL lists + if (this.editor.getParam("paste_convert_middot_lists", true)) { + var div = ed.dom.create("div", null, content); + + // Convert all middot paragraphs to li elements + var className = this.editor.getParam("paste_unindented_list_class", "unIndentedList"); + + while (this._convertMiddots(div, "--list--")) ; // bull + while (this._convertMiddots(div, middot, className)) ; // Middot + while (this._convertMiddots(div, bull)) ; // bull - // Convert all middot paragraphs to li elements - var className = tinyMCE.getParam("paste_unindented_list_class", "unIndentedList"); + content = div.innerHTML; + } + + // Replace all headers with strong and fix some other issues + if (this.editor.getParam("paste_convert_headers_to_strong", false)) { + content = content.replace(/ <\/h[1-6]>/gi, '

  

'); + content = content.replace(//gi, '

'); + content = content.replace(/<\/h[1-6]>/gi, '

'); + content = content.replace(/ <\/b>/gi, '  '); + content = content.replace(/^( )*/gi, ''); + } + + content = content.replace(/--list--/gi, ""); // Remove --list-- - while (TinyMCE_PastePlugin._convertMiddots(div, "--list--")) ; // bull - while (TinyMCE_PastePlugin._convertMiddots(div, middot, className)) ; // Middot - while (TinyMCE_PastePlugin._convertMiddots(div, bull)) ; // bull + if ((cb = this.editor.getParam("paste_insert_word_content_callback", "")) != "") + content = eval(cb + "('after', content)"); - content = div.innerHTML; - } + // Insert cleaned content + this.editor.execCommand("mceInsertContent", false, content); + + if (this.editor.getParam('paste_force_cleanup_wordpaste', true)) { + var ed = this.editor; - // Replace all headers with strong and fix some other issues - if (tinyMCE.getParam("paste_convert_headers_to_strong", false)) { - content = content.replace(/ <\/h[1-6]>/gi, '

  

'); - content = content.replace(//gi, '

'); - content = content.replace(/<\/h[1-6]>/gi, '

'); - content = content.replace(/ <\/b>/gi, '  '); - content = content.replace(/^( )*/gi, ''); + window.setTimeout(function() { + ed.execCommand("mceCleanup"); + }, 1); // Do normal cleanup detached from this thread + } + } + }, + + _reEscape : function(s) { + var l = "?.\\*[](){}+^$:"; + var o = ""; + + for (var i=0; i - {$lang_paste_text_desc} + {#paste.paste_text_desc} - - + + - +
-
{$lang_paste_text_desc}
+
{#paste.paste_text_desc}
- +

-
{$lang_paste_text_title}
+
{#paste_dlg.text_title}
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/paste/pasteword.htm --- a/includes/clientside/tinymce/plugins/paste/pasteword.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/paste/pasteword.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,27 +1,27 @@ - {$lang_paste_word_desc} - - + {#paste.paste_word_desc} + + - +
-
{$lang_paste_word_desc}
+
{#paste.paste_word_desc}
-
{$lang_paste_word_title}
+
{#paste_dlg.word_title}
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/paste/readme.txt --- a/includes/clientside/tinymce/plugins/paste/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/preview/editor_plugin.js --- a/includes/clientside/tinymce/plugins/preview/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/preview/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('preview');var TinyMCE_PreviewPlugin={getInfo:function(){return{longname:'Preview',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/preview',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},getControlHTML:function(cn){switch(cn){case"preview":return tinyMCE.getButtonHTML(cn,'lang_preview_desc','{$pluginurl}/images/preview.gif','mcePreview')}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mcePreview":var previewPage=tinyMCE.getParam("plugin_preview_pageurl",null);var previewWidth=tinyMCE.getParam("plugin_preview_width","550");var previewHeight=tinyMCE.getParam("plugin_preview_height","600");if(previewPage){var template=new Array();template['file']=previewPage;template['width']=previewWidth;template['height']=previewHeight;tinyMCE.openWindow(template,{editor_id:editor_id,resizable:"yes",scrollbars:"yes",inline:"yes",content:tinyMCE.getContent(),content_css:tinyMCE.getParam("content_css")})}else{var win=window.open("","mcePreview","menubar=no,toolbar=no,scrollbars=yes,resizable=yes,left=20,top=20,width="+previewWidth+",height="+previewHeight);var html="",i;var c=tinyMCE.getContent();var pos=c.indexOf('',pos);pos2=c.lastIndexOf('');c=c.substring(pos+1,pos2)}html+=tinyMCE.getParam('doctype');html+='';html+='';html+=''+tinyMCE.getLang('lang_preview_desc')+'';html+='';html+='';for(i=0;i';html+='';html+='';html+='';html+=c;html+='';html+='';win.document.write(html);win.document.close()}return true}return false},_setDoc:function(d){TinyMCE_PreviewPlugin._doc=d;d._embeds=new Array()},_setWin:function(d){TinyMCE_PreviewPlugin._win=d},_onLoad:function(){var nl,i,el=new Array(),d=TinyMCE_PreviewPlugin._doc,sv,ne;nl=d.getElementsByTagName("script");for(i=0;i';for(n in p)h+='';h+='',pos);pos2=c.lastIndexOf('');c=c.substring(pos+1,pos2);}html+=ed.getParam('doctype');html+='';html+='';html+=''+ed.getLang('preview.preview_desc')+'';html+='';html+='';for(i=0;i';html+='';html+='';html+=c;html+='';html+='';win.document.write(html);win.document.close();}},_onLoad:function(w,d){var t=this,nl,i,el=[],sv,ne;t._doc=d;w.writeFlash=t._writeFlash;w.writeShockWave=t._writeShockWave;w.writeQuickTime=t._writeQuickTime;w.writeRealMedia=t._writeRealMedia;w.writeWindowsMedia=t._writeWindowsMedia;w.writeEmbed=t._writeEmbed;nl=d.getElementsByTagName("script");for(i=0;i';for(n in p)h+='';h+='', pos); - pos2 = c.lastIndexOf(''); - c = c.substring(pos + 1, pos2); - } + // Use a custom preview page + if (page) { + ed.windowManager.open({ + file : ed.getParam("plugin_preview_pageurl", null), + width : w, + height : h + }, { + resizable : "yes", + scrollbars : "yes", + inline : 1 + }); + } else { + win = window.open("", "mcePreview", "menubar=no,toolbar=no,scrollbars=yes,resizable=yes,left=20,top=20,width=" + w + ",height=" + h); + html = ""; + c = ed.getContent(); + pos = c.indexOf(''; - html += ''; - html += ''; - - for (i=0; i'; + tinymce.map(css, function(u) { + return ed.documentBaseURI.toAbsolute(u); + }); - html += ''; - html += ''; - html += ''; - html += c; - html += ''; - html += ''; - - win.document.write(html); - win.document.close(); + if (pos != -1) { + pos = c.indexOf('>', pos); + pos2 = c.lastIndexOf(''); + c = c.substring(pos + 1, pos2); } - return true; - } + html += ed.getParam('doctype'); + html += ''; + html += ''; + html += '' + ed.getLang('preview.preview_desc') + ''; + html += ''; + html += ''; - return false; - }, - - _setDoc : function(d) { - TinyMCE_PreviewPlugin._doc = d; - d._embeds = new Array(); - }, + for (i=0; i'; - _setWin : function(d) { - TinyMCE_PreviewPlugin._win = d; - }, - - _onLoad : function() { - var nl, i, el = new Array(), d = TinyMCE_PreviewPlugin._doc, sv, ne; + html += ''; + html += ''; + html += c; + html += ''; + html += ''; - nl = d.getElementsByTagName("script"); - for (i=0; i'; + for (n in p) + h += ''; + + h += ' + Example of a custom preview page - Editor contents:
-{$content} +
+ +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/preview/images/preview.gif Binary file includes/clientside/tinymce/plugins/preview/images/preview.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/preview/langs/en.js --- a/includes/clientside/tinymce/plugins/preview/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('',{ -preview_desc : 'Preview' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/preview/readme.txt --- a/includes/clientside/tinymce/plugins/preview/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/print/editor_plugin.js --- a/includes/clientside/tinymce/plugins/print/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/print/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('print');var TinyMCE_PrintPlugin={getInfo:function(){return{longname:'Print',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/print',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},getControlHTML:function(cn){switch(cn){case"print":return tinyMCE.getButtonHTML(cn,'lang_print_desc','{$pluginurl}/images/print.gif','mcePrint')}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mcePrint":tinyMCE.getInstanceById(editor_id).contentWindow.print();return true}return false}};tinyMCE.addPlugin("print",TinyMCE_PrintPlugin); \ No newline at end of file +(function(){tinymce.create('tinymce.plugins.Print',{init:function(ed,url){ed.addCommand('mcePrint',function(){ed.getWin().print();});ed.addButton('print',{title:'print.print_desc',cmd:'mcePrint'});},getInfo:function(){return{longname:'Print',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/print',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('print',tinymce.plugins.Print);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/print/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/print/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/print/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,47 +1,31 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import theme specific language pack */ -tinyMCE.importPluginLanguagePack('print'); +(function() { + tinymce.create('tinymce.plugins.Print', { + init : function(ed, url) { + ed.addCommand('mcePrint', function() { + ed.getWin().print(); + }); -var TinyMCE_PrintPlugin = { - getInfo : function() { - return { - longname : 'Print', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/print', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, - - getControlHTML : function(cn) { - switch (cn) { - case "print": - return tinyMCE.getButtonHTML(cn, 'lang_print_desc', '{$pluginurl}/images/print.gif', 'mcePrint'); - } + ed.addButton('print', {title : 'print.print_desc', cmd : 'mcePrint'}); + }, - return ""; - }, + getInfo : function() { + return { + longname : 'Print', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/print', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); - /** - * Executes the search/replace commands. - */ - execCommand : function(editor_id, element, command, user_interface, value) { - // Handle commands - switch (command) { - case "mcePrint": - tinyMCE.getInstanceById(editor_id).contentWindow.print(); - return true; - } - - // Pass to next handler in chain - return false; - } -}; - -tinyMCE.addPlugin("print", TinyMCE_PrintPlugin); + // Register plugin + tinymce.PluginManager.add('print', tinymce.plugins.Print); +})(); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/print/images/print.gif Binary file includes/clientside/tinymce/plugins/print/images/print.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/print/langs/en.js --- a/includes/clientside/tinymce/plugins/print/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('',{ -print_desc : 'Print' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/print/readme.txt --- a/includes/clientside/tinymce/plugins/print/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/readme.txt --- a/includes/clientside/tinymce/plugins/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -This is the location you place TinyMCE plugins. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/safari/blank.htm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/safari/blank.htm Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,1 @@ + \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/safari/editor_plugin.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/safari/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,1 @@ +(function(){var Event=tinymce.dom.Event,grep=tinymce.grep,each=tinymce.each,inArray=tinymce.inArray,isOldWebKit=tinymce.isOldWebKit;tinymce.create('tinymce.plugins.Safari',{init:function(ed){var t=this,dom;if(!tinymce.isWebKit)return;t.editor=ed;t.webKitFontSizes=['x-small','small','medium','large','x-large','xx-large','-webkit-xxx-large'];t.namedFontSizes=['xx-small','x-small','small','medium','large','x-large','xx-large'];ed.addCommand('FormatBlock',function(u,v){var dom=ed.dom,e=dom.getParent(ed.selection.getNode(),dom.isBlock);if(e)dom.replace(dom.create(v),e,1);else ed.getDoc().execCommand("FormatBlock",false,v);});ed.addCommand('mceInsertContent',function(u,v){ed.getDoc().execCommand("InsertText",false,'mce_marker');ed.getBody().innerHTML=ed.getBody().innerHTML.replace(/mce_marker/g,v+'XX');ed.selection.select(ed.dom.get('_mce_tmp'));ed.getDoc().execCommand("Delete",false,' ');});ed.onKeyPress.add(function(ed,e){if(e.keyCode==13&&e.shiftKey){t._insertBR(ed);Event.cancel(e);}});ed.addQueryValueHandler('FontSize',function(u,v){var e,v;if((e=ed.dom.getParent(ed.selection.getStart(),'span'))&&(v=e.style.fontSize))return tinymce.inArray(t.namedFontSizes,v)+1;if((e=ed.dom.getParent(ed.selection.getEnd(),'span'))&&(v=e.style.fontSize))return tinymce.inArray(t.namedFontSizes,v)+1;return ed.getDoc().queryCommandValue('FontSize');});ed.addQueryValueHandler('FontName',function(u,v){var e,v;if((e=ed.dom.getParent(ed.selection.getStart(),'span'))&&(v=e.style.fontFamily))return v.replace(/, /g,',');if((e=ed.dom.getParent(ed.selection.getEnd(),'span'))&&(v=e.style.fontFamily))return v.replace(/, /g,',');return ed.getDoc().queryCommandValue('FontName');});ed.onClick.add(function(ed,e){e=e.target;if(e.nodeName=='IMG'){t.selElm=e;ed.selection.select(e);}else t.selElm=null;});ed.onBeforeExecCommand.add(function(ed,c,b){var r=t.bookmarkRng;if(r){ed.selection.setRng(r);t.bookmarkRng=null;}});ed.onInit.add(function(){t._fixWebKitSpans();ed.windowManager.onOpen.add(function(){var r=ed.selection.getRng();if(r.startContainer!=ed.getDoc()){t.bookmarkRng=r.cloneRange();}});ed.windowManager.onClose.add(function(){t.bookmarkRng=null;});if(isOldWebKit)t._patchSafari2x(ed);});ed.onSetContent.add(function(){dom=ed.dom;each(['strong','b','em','u','strike','sub','sup','a'],function(v){each(grep(dom.select(v)).reverse(),function(n){var nn=n.nodeName.toLowerCase(),st;if(nn=='a'){if(n.name)dom.replace(dom.create('img',{mce_name:'a',name:n.name,'class':'mceItemAnchor'}),n);return;}switch(nn){case'b':case'strong':if(nn=='b')nn='strong';st='font-weight: bold;';break;case'em':st='font-style: italic;';break;case'u':st='text-decoration: underline;';break;case'sub':st='vertical-align: sub;';break;case'sup':st='vertical-align: super;';break;case'strike':st='text-decoration: line-through;';break;}dom.replace(dom.create('span',{mce_name:nn,style:st,'class':'Apple-style-span'}),n,1);});});});ed.onPreProcess.add(function(ed,o){dom=ed.dom;each(grep(o.node.getElementsByTagName('span')).reverse(),function(n){var v,bg;if(o.get){if(dom.hasClass(n,'Apple-style-span')){bg=n.style.backgroundColor;switch(dom.getAttrib(n,'mce_name')){case'font':if(!ed.settings.convert_fonts_to_spans)dom.setAttrib(n,'style','');break;case'strong':case'em':case'sub':case'sup':dom.setAttrib(n,'style','');break;case'strike':case'u':if(!ed.settings.inline_styles)dom.setAttrib(n,'style','');else dom.setAttrib(n,'mce_name','');break;default:if(!ed.settings.inline_styles)dom.setAttrib(n,'style','');}if(bg)n.style.backgroundColor=bg;}}if(dom.hasClass(n,'mceItemRemoved'))dom.remove(n,1);});});ed.onPostProcess.add(function(ed,o){o.content=o.content.replace(/
<\/(h[1-6]|div|p|address|pre)>/g,'');o.content=o.content.replace(/ id=\"undefined\"/g,'');});},_fixWebKitSpans:function(){var t=this,ed=t.editor;if(!isOldWebKit){Event.add(ed.getDoc(),'DOMNodeInserted',function(e){e=e.target;if(e&&e.nodeType==1)t._fixAppleSpan(e);});}else{ed.onExecCommand.add(function(){each(ed.dom.select('span'),function(n){t._fixAppleSpan(n);});ed.nodeChanged();});}},_fixAppleSpan:function(e){var ed=this.editor,dom=ed.dom,fz=this.webKitFontSizes,fzn=this.namedFontSizes,s=ed.settings,st,p;if(dom.getAttrib(e,'mce_fixed'))return;if(e.nodeName=='SPAN'&&e.className=='Apple-style-span'){st=e.style;if(!s.convert_fonts_to_spans){if(st.fontSize){dom.setAttrib(e,'mce_name','font');dom.setAttrib(e,'size',inArray(fz,st.fontSize)+1);}if(st.fontFamily){dom.setAttrib(e,'mce_name','font');dom.setAttrib(e,'face',st.fontFamily);}if(st.color){dom.setAttrib(e,'mce_name','font');dom.setAttrib(e,'color',dom.toHex(st.color));}if(st.backgroundColor){dom.setAttrib(e,'mce_name','font');dom.setStyle(e,'background-color',st.backgroundColor);}}else{if(st.fontSize)dom.setStyle(e,'fontSize',fzn[inArray(fz,st.fontSize)]);}if(st.fontWeight=='bold')dom.setAttrib(e,'mce_name','strong');if(st.fontStyle=='italic')dom.setAttrib(e,'mce_name','em');if(st.textDecoration=='underline')dom.setAttrib(e,'mce_name','u');if(st.textDecoration=='line-through')dom.setAttrib(e,'mce_name','strike');if(st.verticalAlign=='super')dom.setAttrib(e,'mce_name','sup');if(st.verticalAlign=='sub')dom.setAttrib(e,'mce_name','sub');dom.setAttrib(e,'mce_fixed','1');}},_patchSafari2x:function(ed){var t=this,setContent,getNode,dom=ed.dom,lr;if(ed.windowManager.onBeforeOpen){ed.windowManager.onBeforeOpen.add(function(){r=ed.selection.getRng();});}ed.selection.select=function(n){this.getSel().setBaseAndExtent(n,0,n,1);};getNode=ed.selection.getNode;ed.selection.getNode=function(){return t.selElm||getNode.call(this);};ed.selection.getRng=function(){var t=this,s=t.getSel(),d=ed.getDoc(),r,rb,ra,di;if(s.anchorNode){r=d.createRange();try{rb=d.createRange();rb.setStart(s.anchorNode,s.anchorOffset);rb.collapse(1);ra=d.createRange();ra.setStart(s.focusNode,s.focusOffset);ra.collapse(1);di=rb.compareBoundaryPoints(rb.START_TO_END,ra)<0;r.setStart(di?s.anchorNode:s.focusNode,di?s.anchorOffset:s.focusOffset);r.setEnd(di?s.focusNode:s.anchorNode,di?s.focusOffset:s.anchorOffset);lr=r;}catch(ex){}}return r||lr;};setContent=ed.selection.setContent;ed.selection.setContent=function(h,s){var r=this.getRng(),b;try{setContent.call(this,h,s);}catch(ex){b=dom.create('body');b.innerHTML=h;each(b.childNodes,function(n){r.insertNode(n.cloneNode(true));});}};},_insertBR:function(ed){var dom=ed.dom,s=ed.selection,r=s.getRng(),br;r.insertNode(br=dom.create('br'));r.setStartAfter(br);r.setEndAfter(br);s.setRng(r);if(s.getSel().focusNode==br.previousSibling){s.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'),br));s.collapse(1);}ed.getWin().scrollTo(0,dom.getPos(s.getRng().startContainer).y);}});tinymce.PluginManager.add('safari',tinymce.plugins.Safari);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/safari/editor_plugin_src.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/safari/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,414 @@ +/** + * $Id: editor_plugin_src.js 264 2007-04-26 20:53:09Z spocke $ + * + * @author Moxiecode + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ + +(function() { + var Event = tinymce.dom.Event, grep = tinymce.grep, each = tinymce.each, inArray = tinymce.inArray, isOldWebKit = tinymce.isOldWebKit; + + tinymce.create('tinymce.plugins.Safari', { + init : function(ed) { + var t = this, dom; + + // Ignore on non webkit + if (!tinymce.isWebKit) + return; + + t.editor = ed; + t.webKitFontSizes = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '-webkit-xxx-large']; + t.namedFontSizes = ['xx-small', 'x-small','small','medium','large','x-large', 'xx-large']; + + // Safari will crash if the build in createlink command is used +/* ed.addCommand('CreateLink', function(u, v) { + ed.execCommand("mceInsertContent", false, '' + ed.selection.getContent() + ''); + });*/ + + // Workaround for FormatBlock bug, http://bugs.webkit.org/show_bug.cgi?id=16004 + ed.addCommand('FormatBlock', function(u, v) { + var dom = ed.dom, e = dom.getParent(ed.selection.getNode(), dom.isBlock); + + if (e) + dom.replace(dom.create(v), e, 1); + else + ed.getDoc().execCommand("FormatBlock", false, v); + }); + + // Workaround for InsertHTML bug, http://bugs.webkit.org/show_bug.cgi?id=16382 + ed.addCommand('mceInsertContent', function(u, v) { + ed.getDoc().execCommand("InsertText", false, 'mce_marker'); + ed.getBody().innerHTML = ed.getBody().innerHTML.replace(/mce_marker/g, v + 'XX'); + ed.selection.select(ed.dom.get('_mce_tmp')); + ed.getDoc().execCommand("Delete", false, ' '); + }); + + // Workaround for missing shift+enter support, http://bugs.webkit.org/show_bug.cgi?id=16973 + ed.onKeyPress.add(function(ed, e) { + if (e.keyCode == 13 && e.shiftKey) { + t._insertBR(ed); + Event.cancel(e); + } + }); + + // Safari returns incorrect values + ed.addQueryValueHandler('FontSize', function(u, v) { + var e, v; + + // Check for the real font size at the start of selection + if ((e = ed.dom.getParent(ed.selection.getStart(), 'span')) && (v = e.style.fontSize)) + return tinymce.inArray(t.namedFontSizes, v) + 1; + + // Check for the real font size at the end of selection + if ((e = ed.dom.getParent(ed.selection.getEnd(), 'span')) && (v = e.style.fontSize)) + return tinymce.inArray(t.namedFontSizes, v) + 1; + + // Return default value it's better than nothing right! + return ed.getDoc().queryCommandValue('FontSize'); + }); + + // Safari returns incorrect values + ed.addQueryValueHandler('FontName', function(u, v) { + var e, v; + + // Check for the real font name at the start of selection + if ((e = ed.dom.getParent(ed.selection.getStart(), 'span')) && (v = e.style.fontFamily)) + return v.replace(/, /g, ','); + + // Check for the real font name at the end of selection + if ((e = ed.dom.getParent(ed.selection.getEnd(), 'span')) && (v = e.style.fontFamily)) + return v.replace(/, /g, ','); + + // Return default value it's better than nothing right! + return ed.getDoc().queryCommandValue('FontName'); + }); + + // Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250 + ed.onClick.add(function(ed, e) { + e = e.target; + + if (e.nodeName == 'IMG') { + t.selElm = e; + ed.selection.select(e); + } else + t.selElm = null; + }); + + ed.onBeforeExecCommand.add(function(ed, c, b) { + var r = t.bookmarkRng; + + // Restore selection + if (r) { + ed.selection.setRng(r); + t.bookmarkRng = null; + //console.debug('restore', r.startContainer, r.startOffset, r.endContainer, r.endOffset); + } + }); + + ed.onInit.add(function() { + t._fixWebKitSpans(); + + ed.windowManager.onOpen.add(function() { + var r = ed.selection.getRng(); + + // Store selection if valid + if (r.startContainer != ed.getDoc()) { + t.bookmarkRng = r.cloneRange(); + //console.debug('store', r.startContainer, r.startOffset, r.endContainer, r.endOffset); + } + }); + + ed.windowManager.onClose.add(function() { + t.bookmarkRng = null; + }); + + if (isOldWebKit) + t._patchSafari2x(ed); + }); + + ed.onSetContent.add(function() { + dom = ed.dom; + + // Convert strong,b,em,u,strike to spans + each(['strong','b','em','u','strike','sub','sup','a'], function(v) { + each(grep(dom.select(v)).reverse(), function(n) { + var nn = n.nodeName.toLowerCase(), st; + + // Convert anchors into images + if (nn == 'a') { + if (n.name) + dom.replace(dom.create('img', {mce_name : 'a', name : n.name, 'class' : 'mceItemAnchor'}), n); + + return; + } + + switch (nn) { + case 'b': + case 'strong': + if (nn == 'b') + nn = 'strong'; + + st = 'font-weight: bold;'; + break; + + case 'em': + st = 'font-style: italic;'; + break; + + case 'u': + st = 'text-decoration: underline;'; + break; + + case 'sub': + st = 'vertical-align: sub;'; + break; + + case 'sup': + st = 'vertical-align: super;'; + break; + + case 'strike': + st = 'text-decoration: line-through;'; + break; + } + + dom.replace(dom.create('span', {mce_name : nn, style : st, 'class' : 'Apple-style-span'}), n, 1); + }); + }); + }); + + ed.onPreProcess.add(function(ed, o) { + dom = ed.dom; + + each(grep(o.node.getElementsByTagName('span')).reverse(), function(n) { + var v, bg; + + if (o.get) { + if (dom.hasClass(n, 'Apple-style-span')) { + bg = n.style.backgroundColor; + + switch (dom.getAttrib(n, 'mce_name')) { + case 'font': + if (!ed.settings.convert_fonts_to_spans) + dom.setAttrib(n, 'style', ''); + break; + + case 'strong': + case 'em': + case 'sub': + case 'sup': + dom.setAttrib(n, 'style', ''); + break; + + case 'strike': + case 'u': + if (!ed.settings.inline_styles) + dom.setAttrib(n, 'style', ''); + else + dom.setAttrib(n, 'mce_name', ''); + + break; + + default: + if (!ed.settings.inline_styles) + dom.setAttrib(n, 'style', ''); + } + + + if (bg) + n.style.backgroundColor = bg; + } + } + + if (dom.hasClass(n, 'mceItemRemoved')) + dom.remove(n, 1); + }); + }); + + ed.onPostProcess.add(function(ed, o) { + // Safari adds BR at end of all block elements + o.content = o.content.replace(/
<\/(h[1-6]|div|p|address|pre)>/g, ''); + + // Safari adds id="undefined" to HR elements + o.content = o.content.replace(/ id=\"undefined\"/g, ''); + }); + }, + + _fixWebKitSpans : function() { + var t = this, ed = t.editor; + + if (!isOldWebKit) { + // Use mutator events on new WebKit + Event.add(ed.getDoc(), 'DOMNodeInserted', function(e) { + e = e.target; + + if (e && e.nodeType == 1) + t._fixAppleSpan(e); + }); + } else { + // Do post command processing in old WebKit since the browser crashes on Mutator events :( + ed.onExecCommand.add(function() { + each(ed.dom.select('span'), function(n) { + t._fixAppleSpan(n); + }); + + ed.nodeChanged(); + }); + } + }, + + _fixAppleSpan : function(e) { + var ed = this.editor, dom = ed.dom, fz = this.webKitFontSizes, fzn = this.namedFontSizes, s = ed.settings, st, p; + + if (dom.getAttrib(e, 'mce_fixed')) + return; + + // Handle Apple style spans + if (e.nodeName == 'SPAN' && e.className == 'Apple-style-span') { + st = e.style; + + if (!s.convert_fonts_to_spans) { + if (st.fontSize) { + dom.setAttrib(e, 'mce_name', 'font'); + dom.setAttrib(e, 'size', inArray(fz, st.fontSize) + 1); + } + + if (st.fontFamily) { + dom.setAttrib(e, 'mce_name', 'font'); + dom.setAttrib(e, 'face', st.fontFamily); + } + + if (st.color) { + dom.setAttrib(e, 'mce_name', 'font'); + dom.setAttrib(e, 'color', dom.toHex(st.color)); + } + + if (st.backgroundColor) { + dom.setAttrib(e, 'mce_name', 'font'); + dom.setStyle(e, 'background-color', st.backgroundColor); + } + } else { + if (st.fontSize) + dom.setStyle(e, 'fontSize', fzn[inArray(fz, st.fontSize)]); + } + + if (st.fontWeight == 'bold') + dom.setAttrib(e, 'mce_name', 'strong'); + + if (st.fontStyle == 'italic') + dom.setAttrib(e, 'mce_name', 'em'); + + if (st.textDecoration == 'underline') + dom.setAttrib(e, 'mce_name', 'u'); + + if (st.textDecoration == 'line-through') + dom.setAttrib(e, 'mce_name', 'strike'); + + if (st.verticalAlign == 'super') + dom.setAttrib(e, 'mce_name', 'sup'); + + if (st.verticalAlign == 'sub') + dom.setAttrib(e, 'mce_name', 'sub'); + + dom.setAttrib(e, 'mce_fixed', '1'); + } + }, + + _patchSafari2x : function(ed) { + var t = this, setContent, getNode, dom = ed.dom, lr; + + // Inline dialogs + if (ed.windowManager.onBeforeOpen) { + ed.windowManager.onBeforeOpen.add(function() { + r = ed.selection.getRng(); + }); + } + + // Fake select on 2.x + ed.selection.select = function(n) { + this.getSel().setBaseAndExtent(n, 0, n, 1); + }; + + getNode = ed.selection.getNode; + ed.selection.getNode = function() { + return t.selElm || getNode.call(this); + }; + + // Fake range on Safari 2.x + ed.selection.getRng = function() { + var t = this, s = t.getSel(), d = ed.getDoc(), r, rb, ra, di; + + // Fake range on Safari 2.x + if (s.anchorNode) { + r = d.createRange(); + + try { + // Setup before range + rb = d.createRange(); + rb.setStart(s.anchorNode, s.anchorOffset); + rb.collapse(1); + + // Setup after range + ra = d.createRange(); + ra.setStart(s.focusNode, s.focusOffset); + ra.collapse(1); + + // Setup start/end points by comparing locations + di = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0; + r.setStart(di ? s.anchorNode : s.focusNode, di ? s.anchorOffset : s.focusOffset); + r.setEnd(di ? s.focusNode : s.anchorNode, di ? s.focusOffset : s.anchorOffset); + + lr = r; + } catch (ex) { + // Sometimes fails, at least we tried to do it by the book. I hope Safari 2.x will go disappear soooon!!! + } + } + + return r || lr; + }; + + // Fix setContent so it works + setContent = ed.selection.setContent; + ed.selection.setContent = function(h, s) { + var r = this.getRng(), b; + + try { + setContent.call(this, h, s); + } catch (ex) { + // Workaround for Safari 2.x + b = dom.create('body'); + b.innerHTML = h; + + each(b.childNodes, function(n) { + r.insertNode(n.cloneNode(true)); + }); + } + }; + }, + + _insertBR : function(ed) { + var dom = ed.dom, s = ed.selection, r = s.getRng(), br; + + // Insert BR element + r.insertNode(br = dom.create('br')); + + // Place caret after BR + r.setStartAfter(br); + r.setEndAfter(br); + s.setRng(r); + + // Could not place caret after BR then insert an nbsp entity and move the caret + if (s.getSel().focusNode == br.previousSibling) { + s.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'), br)); + s.collapse(1); + } + + // Scroll to new position, scrollIntoView can't be used due to bug: http://bugs.webkit.org/show_bug.cgi?id=16117 + ed.getWin().scrollTo(0, dom.getPos(s.getRng().startContainer).y); + } + }); + + // Register plugin + tinymce.PluginManager.add('safari', tinymce.plugins.Safari); +})(); + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/save/editor_plugin.js --- a/includes/clientside/tinymce/plugins/save/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/save/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('save');var TinyMCE_SavePlugin={getInfo:function(){return{longname:'Save',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/save',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},initInstance:function(inst){inst.addShortcut('ctrl','s','lang_save_desc','mceSave')},getControlHTML:function(cn){switch(cn){case"save":return tinyMCE.getButtonHTML(cn,'lang_save_desc','{$pluginurl}/images/save.gif','mceSave')}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mceSave":if(tinyMCE.getParam("fullscreen_is_enabled"))return true;var inst=tinyMCE.selectedInstance;var formObj=inst.formElement.form;if(tinyMCE.getParam("save_enablewhendirty")&&!inst.isDirty())return true;if(formObj){tinyMCE.triggerSave();var os;if((os=tinyMCE.getParam("save_onsavecallback"))){if(eval(os+'(inst);')){inst.startContent=tinyMCE.trim(inst.getBody().innerHTML);tinyMCE.triggerNodeChange(false,true)}return true}for(var i=0;i no need to copy any values! - - // copy values from one panel to the other (if they exist there) - var from_panel_name = tab.id.match(/^search/i) ? "replace_panel" : "search_panel"; - var to_panel_name = (from_panel_name == "search_panel") ? "replace_panel" : "search_panel"; - - // find all elements with IDs to copy their values - var elms = document.getElementById(from_panel_name).getElementsByTagName("*"); - for (var i = 0; i < elms.length; i++) { - if (elms[i].id && elms[i].id != "") { - var checked = "undefined"; - if (elms[i].type.toLowerCase() == "checkbox" || elms[i].type.toLowerCase() == "radio") - checked = elms[i].checked; - - // copy values if element exists in other panel - var to_elm_name = to_panel_name + elms[i].id.substring(from_panel_name.length, elms[i].id.length); - var to_elm = document.getElementById(to_elm_name); - if (to_elm) { - if (checked != "undefined") - to_elm.checked = checked; - else - to_elm.value = elms[i].value; - } - } - } - - return false; -} \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/searchreplace/langs/en.js --- a/includes/clientside/tinymce/plugins/searchreplace/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('',{ -searchreplace_search_desc : 'Find', -searchreplace_searchnext_desc : 'Find again', -searchreplace_replace_desc : 'Find/Replace', -searchreplace_notfound : 'The search has been completed. The search string could not be found.', -searchreplace_search_title : 'Find', -searchreplace_replace_title : 'Find/Replace', -searchreplace_allreplaced : 'All occurrences of the search string were replaced.', -searchreplace_findwhat : 'Find what', -searchreplace_replacewith : 'Replace with', -searchreplace_direction : 'Direction', -searchreplace_up : 'Up', -searchreplace_down : 'Down', -searchreplace_case : 'Match case', -searchreplace_findnext : 'Find next', -searchreplace_replace : 'Replace', -searchreplace_replaceall : 'Replace all', -searchreplace_cancel : 'Cancel' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/searchreplace/langs/en_dlg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/searchreplace/langs/en_dlg.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,16 @@ +tinyMCE.addI18n('en.searchreplace_dlg',{ +searchnext_desc:"Find again", +notfound:"The search has been completed. The search string could not be found.", +search_title:"Find", +replace_title:"Find/Replace", +allreplaced:"All occurrences of the search string were replaced.", +findwhat:"Find what", +replacewith:"Replace with", +direction:"Direction", +up:"Up", +down:"Down", +mcase:"Match case", +findnext:"Find next", +replace:"Replace", +replaceall:"Replace all" +}); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/searchreplace/readme.txt --- a/includes/clientside/tinymce/plugins/searchreplace/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/searchreplace/searchreplace.htm --- a/includes/clientside/tinymce/plugins/searchreplace/searchreplace.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/searchreplace/searchreplace.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,39 +1,39 @@ + - {$lang_searchreplace_replace_title} - - - - + {#searchreplace_dlg.replace_title} + + + + - +
-
- + @@ -43,7 +43,7 @@
- + - - - + + +
- +
@@ -54,22 +54,22 @@
- + - + @@ -79,7 +79,7 @@
- + - - - + + +
- +
@@ -91,15 +91,15 @@
- + - - + +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/css/props.css --- a/includes/clientside/tinymce/plugins/style/css/props.css Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/style/css/props.css Fri Feb 22 12:51:53 2008 -0500 @@ -1,62 +1,13 @@ -#text_font { - width: 250px; -} - -#text_size { - width: 70px; -} - -.mceAddSelectValue { - background-color: #DDDDDD; -} - -select, #block_text_indent, #box_width, #box_height, #box_padding_top, #box_padding_right, #box_padding_bottom, #box_padding_left { - width: 70px; -} - -#box_margin_top, #box_margin_right, #box_margin_bottom, #box_margin_left, #positioning_width, #positioning_height, #positioning_zindex { - width: 70px; -} - -#positioning_placement_top, #positioning_placement_right, #positioning_placement_bottom, #positioning_placement_left { - width: 70px; -} - -#positioning_clip_top, #positioning_clip_right, #positioning_clip_bottom, #positioning_clip_left { - width: 70px; -} - -.panel_wrapper div.current { - padding-top: 10px; - height: 230px; -} - -.delim { - border-left: 1px solid gray; -} - -.tdelim { - border-bottom: 1px solid gray; -} - -#block_display { - width: 145px; -} - -#list_type { - width: 115px; -} - -.disabled { - background-color: #EEEEEE; -} - -#apply { - font-weight: bold; - width: 78px; - height: 21px; - border: 0; - background-image: url('../images/apply_button_bg.gif'); - cursor: pointer; -} - +#text_font {width:250px;} +#text_size {width:70px;} +.mceAddSelectValue {background:#DDD;} +select, #block_text_indent, #box_width, #box_height, #box_padding_top, #box_padding_right, #box_padding_bottom, #box_padding_left {width:70px;} +#box_margin_top, #box_margin_right, #box_margin_bottom, #box_margin_left, #positioning_width, #positioning_height, #positioning_zindex {width:70px;} +#positioning_placement_top, #positioning_placement_right, #positioning_placement_bottom, #positioning_placement_left {width:70px;} +#positioning_clip_top, #positioning_clip_right, #positioning_clip_bottom, #positioning_clip_left {width:70px;} +.panel_wrapper div.current {padding-top:10px;height:230px;} +.delim {border-left:1px solid gray;} +.tdelim {border-bottom:1px solid gray;} +#block_display {width:145px;} +#list_type {width:115px;} +.disabled {background:#EEE;} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/editor_plugin.js --- a/includes/clientside/tinymce/plugins/style/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/style/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('style');var TinyMCE_StylePlugin={getInfo:function(){return{longname:'Style',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/style',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},getControlHTML:function(cn){switch(cn){case"styleprops":return tinyMCE.getButtonHTML(cn,'lang_style_styleinfo_desc','{$pluginurl}/images/styleprops.gif','mceStyleProps',true)}return""},execCommand:function(editor_id,element,command,user_interface,value){var e,inst;switch(command){case"mceStyleProps":TinyMCE_StylePlugin._styleProps();return true;case"mceSetElementStyle":inst=tinyMCE.getInstanceById(editor_id);e=inst.selection.getFocusElement();if(e){e.style.cssText=value;inst.repaint()}return true}return false},handleNodeChange:function(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){if(node.nodeName=='BODY')tinyMCE.switchClass(editor_id+'_styleprops','mceButtonDisabled');else tinyMCE.switchClass(editor_id+'_styleprops','mceButtonNormal')},_styleProps:function(){var e=tinyMCE.selectedInstance.selection.getFocusElement();if(!e||e.nodeName=='BODY')return;tinyMCE.openWindow({file:'../../plugins/style/props.htm',width:480+tinyMCE.getLang('lang_style_props_delta_width',0),height:320+tinyMCE.getLang('lang_style_props_delta_height',0)},{editor_id:tinyMCE.selectedInstance.editorId,inline:"yes",style_text:e.style.cssText})}};tinyMCE.addPlugin("style",TinyMCE_StylePlugin); \ No newline at end of file +(function(){tinymce.create('tinymce.plugins.StylePlugin',{init:function(ed,url){ed.addCommand('mceStyleProps',function(){ed.windowManager.open({file:url+'/props.htm',width:480+parseInt(ed.getLang('style.delta_width',0)),height:320+parseInt(ed.getLang('style.delta_height',0)),inline:1},{plugin_url:url,style_text:ed.selection.getNode().style.cssText});});ed.addCommand('mceSetElementStyle',function(ui,v){if(e=ed.selection.getNode()){ed.dom.setAttrib(e,'style',v);ed.execCommand('mceRepaint');}});ed.addButton('styleprops',{title:'style.desc',cmd:'mceStyleProps'});},getInfo:function(){return{longname:'Style',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/style',version:tinymce.majorVersion+"."+tinymce.minorVersion};}});tinymce.PluginManager.add('style',tinymce.plugins.StylePlugin);})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/style/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/style/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,83 +1,48 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('style'); - -var TinyMCE_StylePlugin = { - getInfo : function() { - return { - longname : 'Style', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/style', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, - - getControlHTML : function(cn) { - switch (cn) { - case "styleprops": - return tinyMCE.getButtonHTML(cn, 'lang_style_styleinfo_desc', '{$pluginurl}/images/styleprops.gif', 'mceStyleProps', true); - } - - return ""; - }, - - execCommand : function(editor_id, element, command, user_interface, value) { - var e, inst; - - // Handle commands - switch (command) { - case "mceStyleProps": - TinyMCE_StylePlugin._styleProps(); - return true; - - case "mceSetElementStyle": - inst = tinyMCE.getInstanceById(editor_id); - e = inst.selection.getFocusElement(); +(function() { + tinymce.create('tinymce.plugins.StylePlugin', { + init : function(ed, url) { + // Register commands + ed.addCommand('mceStyleProps', function() { + ed.windowManager.open({ + file : url + '/props.htm', + width : 480 + parseInt(ed.getLang('style.delta_width', 0)), + height : 320 + parseInt(ed.getLang('style.delta_height', 0)), + inline : 1 + }, { + plugin_url : url, + style_text : ed.selection.getNode().style.cssText + }); + }); - if (e) { - e.style.cssText = value; - inst.repaint(); + ed.addCommand('mceSetElementStyle', function(ui, v) { + if (e = ed.selection.getNode()) { + ed.dom.setAttrib(e, 'style', v); + ed.execCommand('mceRepaint'); } - - return true; - } + }); - // Pass to next handler in chain - return false; - }, - - handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { - if (node.nodeName == 'BODY') - tinyMCE.switchClass(editor_id + '_styleprops', 'mceButtonDisabled'); - else - tinyMCE.switchClass(editor_id + '_styleprops', 'mceButtonNormal'); - }, + // Register buttons + ed.addButton('styleprops', {title : 'style.desc', cmd : 'mceStyleProps'}); + }, - // Private plugin specific methods - - _styleProps : function() { - var e = tinyMCE.selectedInstance.selection.getFocusElement(); - - if (!e || e.nodeName == 'BODY') - return; + getInfo : function() { + return { + longname : 'Style', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/style', + version : tinymce.majorVersion + "." + tinymce.minorVersion + }; + } + }); - tinyMCE.openWindow({ - file : '../../plugins/style/props.htm', - width : 480 + tinyMCE.getLang('lang_style_props_delta_width', 0), - height : 320 + tinyMCE.getLang('lang_style_props_delta_height', 0) - }, { - editor_id : tinyMCE.selectedInstance.editorId, - inline : "yes", - style_text : e.style.cssText - }); - } -}; - -tinyMCE.addPlugin("style", TinyMCE_StylePlugin); + // Register plugin + tinymce.PluginManager.add('style', tinymce.plugins.StylePlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/images/apply_button_bg.gif Binary file includes/clientside/tinymce/plugins/style/images/apply_button_bg.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/images/style_info.gif Binary file includes/clientside/tinymce/plugins/style/images/style_info.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/images/styleprops.gif Binary file includes/clientside/tinymce/plugins/style/images/styleprops.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/js/props.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/style/js/props.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,636 @@ +tinyMCEPopup.requireLangPack(); + +var defaultFonts = "" + + "Arial, Helvetica, sans-serif=Arial, Helvetica, sans-serif;" + + "Times New Roman, Times, serif=Times New Roman, Times, serif;" + + "Courier New, Courier, mono=Courier New, Courier, mono;" + + "Times New Roman, Times, serif=Times New Roman, Times, serif;" + + "Georgia, Times New Roman, Times, serif=Georgia, Times New Roman, Times, serif;" + + "Verdana, Arial, Helvetica, sans-serif=Verdana, Arial, Helvetica, sans-serif;" + + "Geneva, Arial, Helvetica, sans-serif=Geneva, Arial, Helvetica, sans-serif"; + +var defaultSizes = "9;10;12;14;16;18;24;xx-small;x-small;small;medium;large;x-large;xx-large;smaller;larger"; +var defaultMeasurement = "+pixels=px;points=pt;em;in;cm;mm;picas;ems;exs;%"; +var defaultSpacingMeasurement = "pixels=px;points=pt;in;cm;mm;picas;+ems;exs;%"; +var defaultIndentMeasurement = "pixels=px;+points=pt;in;cm;mm;picas;ems;exs;%"; +var defaultWeight = "normal;bold;bolder;lighter;100;200;300;400;500;600;700;800;900"; +var defaultTextStyle = "normal;italic;oblique"; +var defaultVariant = "normal;small-caps"; +var defaultLineHeight = "normal"; +var defaultAttachment = "fixed;scroll"; +var defaultRepeat = "no-repeat;repeat;repeat-x;repeat-y"; +var defaultPosH = "left;center;right"; +var defaultPosV = "top;center;bottom"; +var defaultVAlign = "baseline;sub;super;top;text-top;middle;bottom;text-bottom"; +var defaultDisplay = "inline;block;list-item;run-in;compact;marker;table;inline-table;table-row-group;table-header-group;table-footer-group;table-row;table-column-group;table-column;table-cell;table-caption;none"; +var defaultBorderStyle = "none;solid;dashed;dotted;double;groove;ridge;inset;outset"; +var defaultBorderWidth = "thin;medium;thick"; +var defaultListType = "disc;circle;square;decimal;lower-roman;upper-roman;lower-alpha;upper-alpha;none"; + +function init() { + var ce = document.getElementById('container'), h; + + ce.style.cssText = tinyMCEPopup.getWindowArg('style_text'); + + h = getBrowserHTML('background_image_browser','background_image','image','advimage'); + document.getElementById("background_image_browser").innerHTML = h; + + document.getElementById('text_color_pickcontainer').innerHTML = getColorPickerHTML('text_color_pick','text_color'); + document.getElementById('background_color_pickcontainer').innerHTML = getColorPickerHTML('background_color_pick','background_color'); + document.getElementById('border_color_top_pickcontainer').innerHTML = getColorPickerHTML('border_color_top_pick','border_color_top'); + document.getElementById('border_color_right_pickcontainer').innerHTML = getColorPickerHTML('border_color_right_pick','border_color_right'); + document.getElementById('border_color_bottom_pickcontainer').innerHTML = getColorPickerHTML('border_color_bottom_pick','border_color_bottom'); + document.getElementById('border_color_left_pickcontainer').innerHTML = getColorPickerHTML('border_color_left_pick','border_color_left'); + + fillSelect(0, 'text_font', 'style_font', defaultFonts, ';', true); + fillSelect(0, 'text_size', 'style_font_size', defaultSizes, ';', true); + fillSelect(0, 'text_size_measurement', 'style_font_size_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'text_case', 'style_text_case', "capitalize;uppercase;lowercase", ';', true); + fillSelect(0, 'text_weight', 'style_font_weight', defaultWeight, ';', true); + fillSelect(0, 'text_style', 'style_font_style', defaultTextStyle, ';', true); + fillSelect(0, 'text_variant', 'style_font_variant', defaultVariant, ';', true); + fillSelect(0, 'text_lineheight', 'style_font_line_height', defaultLineHeight, ';', true); + fillSelect(0, 'text_lineheight_measurement', 'style_font_line_height_measurement', defaultMeasurement, ';', true); + + fillSelect(0, 'background_attachment', 'style_background_attachment', defaultAttachment, ';', true); + fillSelect(0, 'background_repeat', 'style_background_repeat', defaultRepeat, ';', true); + + fillSelect(0, 'background_hpos_measurement', 'style_background_hpos_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'background_vpos_measurement', 'style_background_vpos_measurement', defaultMeasurement, ';', true); + + fillSelect(0, 'background_hpos', 'style_background_hpos', defaultPosH, ';', true); + fillSelect(0, 'background_vpos', 'style_background_vpos', defaultPosV, ';', true); + + fillSelect(0, 'block_wordspacing', 'style_wordspacing', 'normal', ';', true); + fillSelect(0, 'block_wordspacing_measurement', 'style_wordspacing_measurement', defaultSpacingMeasurement, ';', true); + fillSelect(0, 'block_letterspacing', 'style_letterspacing', 'normal', ';', true); + fillSelect(0, 'block_letterspacing_measurement', 'style_letterspacing_measurement', defaultSpacingMeasurement, ';', true); + fillSelect(0, 'block_vertical_alignment', 'style_vertical_alignment', defaultVAlign, ';', true); + fillSelect(0, 'block_text_align', 'style_text_align', "left;right;center;justify", ';', true); + fillSelect(0, 'block_whitespace', 'style_whitespace', "normal;pre;nowrap", ';', true); + fillSelect(0, 'block_display', 'style_display', defaultDisplay, ';', true); + fillSelect(0, 'block_text_indent_measurement', 'style_text_indent_measurement', defaultIndentMeasurement, ';', true); + + fillSelect(0, 'box_width_measurement', 'style_box_width_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_height_measurement', 'style_box_height_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_float', 'style_float', 'left;right;none', ';', true); + fillSelect(0, 'box_clear', 'style_clear', 'left;right;both;none', ';', true); + fillSelect(0, 'box_padding_left_measurement', 'style_padding_left_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_padding_top_measurement', 'style_padding_top_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_padding_bottom_measurement', 'style_padding_bottom_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_padding_right_measurement', 'style_padding_right_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_margin_left_measurement', 'style_margin_left_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_margin_top_measurement', 'style_margin_top_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_margin_bottom_measurement', 'style_margin_bottom_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'box_margin_right_measurement', 'style_margin_right_measurement', defaultMeasurement, ';', true); + + fillSelect(0, 'border_style_top', 'style_border_style_top', defaultBorderStyle, ';', true); + fillSelect(0, 'border_style_right', 'style_border_style_right', defaultBorderStyle, ';', true); + fillSelect(0, 'border_style_bottom', 'style_border_style_bottom', defaultBorderStyle, ';', true); + fillSelect(0, 'border_style_left', 'style_border_style_left', defaultBorderStyle, ';', true); + + fillSelect(0, 'border_width_top', 'style_border_width_top', defaultBorderWidth, ';', true); + fillSelect(0, 'border_width_right', 'style_border_width_right', defaultBorderWidth, ';', true); + fillSelect(0, 'border_width_bottom', 'style_border_width_bottom', defaultBorderWidth, ';', true); + fillSelect(0, 'border_width_left', 'style_border_width_left', defaultBorderWidth, ';', true); + + fillSelect(0, 'border_width_top_measurement', 'style_border_width_top_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'border_width_right_measurement', 'style_border_width_right_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'border_width_bottom_measurement', 'style_border_width_bottom_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'border_width_left_measurement', 'style_border_width_left_measurement', defaultMeasurement, ';', true); + + fillSelect(0, 'list_type', 'style_list_type', defaultListType, ';', true); + fillSelect(0, 'list_position', 'style_list_position', "inside;outside", ';', true); + + fillSelect(0, 'positioning_type', 'style_positioning_type', "absolute;relative;static", ';', true); + fillSelect(0, 'positioning_visibility', 'style_positioning_visibility', "inherit;visible;hidden", ';', true); + + fillSelect(0, 'positioning_width_measurement', 'style_positioning_width_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'positioning_height_measurement', 'style_positioning_height_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'positioning_overflow', 'style_positioning_overflow', "visible;hidden;scroll;auto", ';', true); + + fillSelect(0, 'positioning_placement_top_measurement', 'style_positioning_placement_top_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'positioning_placement_right_measurement', 'style_positioning_placement_right_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'positioning_placement_bottom_measurement', 'style_positioning_placement_bottom_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'positioning_placement_left_measurement', 'style_positioning_placement_left_measurement', defaultMeasurement, ';', true); + + fillSelect(0, 'positioning_clip_top_measurement', 'style_positioning_clip_top_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'positioning_clip_right_measurement', 'style_positioning_clip_right_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'positioning_clip_bottom_measurement', 'style_positioning_clip_bottom_measurement', defaultMeasurement, ';', true); + fillSelect(0, 'positioning_clip_left_measurement', 'style_positioning_clip_left_measurement', defaultMeasurement, ';', true); + + TinyMCE_EditableSelects.init(); + setupFormData(); + showDisabledControls(); +} + +function setupFormData() { + var ce = document.getElementById('container'), f = document.forms[0], s, b, i; + + // Setup text fields + + selectByValue(f, 'text_font', ce.style.fontFamily, true, true); + selectByValue(f, 'text_size', getNum(ce.style.fontSize), true, true); + selectByValue(f, 'text_size_measurement', getMeasurement(ce.style.fontSize)); + selectByValue(f, 'text_weight', ce.style.fontWeight, true, true); + selectByValue(f, 'text_style', ce.style.fontStyle, true, true); + selectByValue(f, 'text_lineheight', getNum(ce.style.lineHeight), true, true); + selectByValue(f, 'text_lineheight_measurement', getMeasurement(ce.style.lineHeight)); + selectByValue(f, 'text_case', ce.style.textTransform, true, true); + selectByValue(f, 'text_variant', ce.style.fontVariant, true, true); + f.text_color.value = ce.style.color; + updateColor('text_color_pick', 'text_color'); + f.text_underline.checked = inStr(ce.style.textDecoration, 'underline'); + f.text_overline.checked = inStr(ce.style.textDecoration, 'overline'); + f.text_linethrough.checked = inStr(ce.style.textDecoration, 'line-through'); + f.text_blink.checked = inStr(ce.style.textDecoration, 'blink'); + + // Setup background fields + + f.background_color.value = ce.style.backgroundColor; + updateColor('background_color_pick', 'background_color'); + f.background_image.value = ce.style.backgroundImage.replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"); + selectByValue(f, 'background_repeat', ce.style.backgroundRepeat, true, true); + selectByValue(f, 'background_attachment', ce.style.backgroundAttachment, true, true); + selectByValue(f, 'background_hpos', getNum(getVal(ce.style.backgroundPosition, 0)), true, true); + selectByValue(f, 'background_hpos_measurement', getMeasurement(getVal(ce.style.backgroundPosition, 0))); + selectByValue(f, 'background_vpos', getNum(getVal(ce.style.backgroundPosition, 1)), true, true); + selectByValue(f, 'background_vpos_measurement', getMeasurement(getVal(ce.style.backgroundPosition, 1))); + + // Setup block fields + + selectByValue(f, 'block_wordspacing', getNum(ce.style.wordSpacing), true, true); + selectByValue(f, 'block_wordspacing_measurement', getMeasurement(ce.style.wordSpacing)); + selectByValue(f, 'block_letterspacing', getNum(ce.style.letterSpacing), true, true); + selectByValue(f, 'block_letterspacing_measurement', getMeasurement(ce.style.letterSpacing)); + selectByValue(f, 'block_vertical_alignment', ce.style.verticalAlign, true, true); + selectByValue(f, 'block_text_align', ce.style.textAlign, true, true); + f.block_text_indent.value = getNum(ce.style.textIndent); + selectByValue(f, 'block_text_indent_measurement', getMeasurement(ce.style.textIndent)); + selectByValue(f, 'block_whitespace', ce.style.whiteSpace, true, true); + selectByValue(f, 'block_display', ce.style.display, true, true); + + // Setup box fields + + f.box_width.value = getNum(ce.style.width); + selectByValue(f, 'box_width_measurement', getMeasurement(ce.style.width)); + + f.box_height.value = getNum(ce.style.height); + selectByValue(f, 'box_height_measurement', getMeasurement(ce.style.height)); + + if (tinymce.isGecko) + selectByValue(f, 'box_float', ce.style.cssFloat, true, true); + else + selectByValue(f, 'box_float', ce.style.styleFloat, true, true); + + selectByValue(f, 'box_clear', ce.style.clear, true, true); + + setupBox(f, ce, 'box_padding', 'padding', ''); + setupBox(f, ce, 'box_margin', 'margin', ''); + + // Setup border fields + + setupBox(f, ce, 'border_style', 'border', 'Style'); + setupBox(f, ce, 'border_width', 'border', 'Width'); + setupBox(f, ce, 'border_color', 'border', 'Color'); + + updateColor('border_color_top_pick', 'border_color_top'); + updateColor('border_color_right_pick', 'border_color_right'); + updateColor('border_color_bottom_pick', 'border_color_bottom'); + updateColor('border_color_left_pick', 'border_color_left'); + + // Setup list fields + + selectByValue(f, 'list_type', ce.style.listStyleType, true, true); + selectByValue(f, 'list_position', ce.style.listStylePosition, true, true); + f.list_bullet_image.value = ce.style.listStyleImage.replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"); + + // Setup box fields + + selectByValue(f, 'positioning_type', ce.style.position, true, true); + selectByValue(f, 'positioning_visibility', ce.style.visibility, true, true); + selectByValue(f, 'positioning_overflow', ce.style.overflow, true, true); + f.positioning_zindex.value = ce.style.zIndex ? ce.style.zIndex : ""; + + f.positioning_width.value = getNum(ce.style.width); + selectByValue(f, 'positioning_width_measurement', getMeasurement(ce.style.width)); + + f.positioning_height.value = getNum(ce.style.height); + selectByValue(f, 'positioning_height_measurement', getMeasurement(ce.style.height)); + + setupBox(f, ce, 'positioning_placement', '', '', new Array('top', 'right', 'bottom', 'left')); + + s = ce.style.clip.replace(new RegExp("rect\\('?([^']*)'?\\)", 'gi'), "$1"); + s = s.replace(/,/g, ' '); + + if (!hasEqualValues(new Array(getVal(s, 0), getVal(s, 1), getVal(s, 2), getVal(s, 3)))) { + f.positioning_clip_top.value = getNum(getVal(s, 0)); + selectByValue(f, 'positioning_clip_top_measurement', getMeasurement(getVal(s, 0))); + f.positioning_clip_right.value = getNum(getVal(s, 1)); + selectByValue(f, 'positioning_clip_right_measurement', getMeasurement(getVal(s, 1))); + f.positioning_clip_bottom.value = getNum(getVal(s, 2)); + selectByValue(f, 'positioning_clip_bottom_measurement', getMeasurement(getVal(s, 2))); + f.positioning_clip_left.value = getNum(getVal(s, 3)); + selectByValue(f, 'positioning_clip_left_measurement', getMeasurement(getVal(s, 3))); + } else { + f.positioning_clip_top.value = getNum(getVal(s, 0)); + selectByValue(f, 'positioning_clip_top_measurement', getMeasurement(getVal(s, 0))); + f.positioning_clip_right.value = f.positioning_clip_bottom.value = f.positioning_clip_left.value; + } + +// setupBox(f, ce, '', 'border', 'Color'); +} + +function getMeasurement(s) { + return s.replace(/^([0-9]+)(.*)$/, "$2"); +} + +function getNum(s) { + if (new RegExp('^[0-9]+[a-z%]+$', 'gi').test(s)) + return s.replace(/[^0-9]/g, ''); + + return s; +} + +function inStr(s, n) { + return new RegExp(n, 'gi').test(s); +} + +function getVal(s, i) { + var a = s.split(' '); + + if (a.length > 1) + return a[i]; + + return ""; +} + +function setValue(f, n, v) { + if (f.elements[n].type == "text") + f.elements[n].value = v; + else + selectByValue(f, n, v, true, true); +} + +function setupBox(f, ce, fp, pr, sf, b) { + if (typeof(b) == "undefined") + b = new Array('Top', 'Right', 'Bottom', 'Left'); + + if (isSame(ce, pr, sf, b)) { + f.elements[fp + "_same"].checked = true; + + setValue(f, fp + "_top", getNum(ce.style[pr + b[0] + sf])); + f.elements[fp + "_top"].disabled = false; + + f.elements[fp + "_right"].value = ""; + f.elements[fp + "_right"].disabled = true; + f.elements[fp + "_bottom"].value = ""; + f.elements[fp + "_bottom"].disabled = true; + f.elements[fp + "_left"].value = ""; + f.elements[fp + "_left"].disabled = true; + + if (f.elements[fp + "_top_measurement"]) { + selectByValue(f, fp + '_top_measurement', getMeasurement(ce.style[pr + b[0] + sf])); + f.elements[fp + "_left_measurement"].disabled = true; + f.elements[fp + "_bottom_measurement"].disabled = true; + f.elements[fp + "_right_measurement"].disabled = true; + } + } else { + f.elements[fp + "_same"].checked = false; + + setValue(f, fp + "_top", getNum(ce.style[pr + b[0] + sf])); + f.elements[fp + "_top"].disabled = false; + + setValue(f, fp + "_right", getNum(ce.style[pr + b[1] + sf])); + f.elements[fp + "_right"].disabled = false; + + setValue(f, fp + "_bottom", getNum(ce.style[pr + b[2] + sf])); + f.elements[fp + "_bottom"].disabled = false; + + setValue(f, fp + "_left", getNum(ce.style[pr + b[3] + sf])); + f.elements[fp + "_left"].disabled = false; + + if (f.elements[fp + "_top_measurement"]) { + selectByValue(f, fp + '_top_measurement', getMeasurement(ce.style[pr + b[0] + sf])); + selectByValue(f, fp + '_right_measurement', getMeasurement(ce.style[pr + b[1] + sf])); + selectByValue(f, fp + '_bottom_measurement', getMeasurement(ce.style[pr + b[2] + sf])); + selectByValue(f, fp + '_left_measurement', getMeasurement(ce.style[pr + b[3] + sf])); + f.elements[fp + "_left_measurement"].disabled = false; + f.elements[fp + "_bottom_measurement"].disabled = false; + f.elements[fp + "_right_measurement"].disabled = false; + } + } +} + +function isSame(e, pr, sf, b) { + var a = new Array(), i, x; + + if (typeof(b) == "undefined") + b = new Array('Top', 'Right', 'Bottom', 'Left'); + + if (typeof(sf) == "undefined" || sf == null) + sf = ""; + + a[0] = e.style[pr + b[0] + sf]; + a[1] = e.style[pr + b[1] + sf]; + a[2] = e.style[pr + b[2] + sf]; + a[3] = e.style[pr + b[3] + sf]; + + for (i=0; i 0 ? s.substring(1) : s; + + if (f.text_none.checked) + s = "none"; + + ce.style.textDecoration = s; + + // Build background styles + + ce.style.backgroundColor = f.background_color.value; + ce.style.backgroundImage = f.background_image.value != "" ? "url(" + f.background_image.value + ")" : ""; + ce.style.backgroundRepeat = f.background_repeat.value; + ce.style.backgroundAttachment = f.background_attachment.value; + + if (f.background_hpos.value != "") { + s = ""; + s += f.background_hpos.value + (isNum(f.background_hpos.value) ? f.background_hpos_measurement.value : "") + " "; + s += f.background_vpos.value + (isNum(f.background_vpos.value) ? f.background_vpos_measurement.value : ""); + ce.style.backgroundPosition = s; + } + + // Build block styles + + ce.style.wordSpacing = f.block_wordspacing.value + (isNum(f.block_wordspacing.value) ? f.block_wordspacing_measurement.value : ""); + ce.style.letterSpacing = f.block_letterspacing.value + (isNum(f.block_letterspacing.value) ? f.block_letterspacing_measurement.value : ""); + ce.style.verticalAlign = f.block_vertical_alignment.value; + ce.style.textAlign = f.block_text_align.value; + ce.style.textIndent = f.block_text_indent.value + (isNum(f.block_text_indent.value) ? f.block_text_indent_measurement.value : ""); + ce.style.whiteSpace = f.block_whitespace.value; + ce.style.display = f.block_display.value; + + // Build box styles + + ce.style.width = f.box_width.value + (isNum(f.box_width.value) ? f.box_width_measurement.value : ""); + ce.style.height = f.box_height.value + (isNum(f.box_height.value) ? f.box_height_measurement.value : ""); + ce.style.styleFloat = f.box_float.value; + + if (tinymce.isGecko) + ce.style.cssFloat = f.box_float.value; + + ce.style.clear = f.box_clear.value; + + if (!f.box_padding_same.checked) { + ce.style.paddingTop = f.box_padding_top.value + (isNum(f.box_padding_top.value) ? f.box_padding_top_measurement.value : ""); + ce.style.paddingRight = f.box_padding_right.value + (isNum(f.box_padding_right.value) ? f.box_padding_right_measurement.value : ""); + ce.style.paddingBottom = f.box_padding_bottom.value + (isNum(f.box_padding_bottom.value) ? f.box_padding_bottom_measurement.value : ""); + ce.style.paddingLeft = f.box_padding_left.value + (isNum(f.box_padding_left.value) ? f.box_padding_left_measurement.value : ""); + } else + ce.style.padding = f.box_padding_top.value + (isNum(f.box_padding_top.value) ? f.box_padding_top_measurement.value : ""); + + if (!f.box_margin_same.checked) { + ce.style.marginTop = f.box_margin_top.value + (isNum(f.box_margin_top.value) ? f.box_margin_top_measurement.value : ""); + ce.style.marginRight = f.box_margin_right.value + (isNum(f.box_margin_right.value) ? f.box_margin_right_measurement.value : ""); + ce.style.marginBottom = f.box_margin_bottom.value + (isNum(f.box_margin_bottom.value) ? f.box_margin_bottom_measurement.value : ""); + ce.style.marginLeft = f.box_margin_left.value + (isNum(f.box_margin_left.value) ? f.box_margin_left_measurement.value : ""); + } else + ce.style.margin = f.box_margin_top.value + (isNum(f.box_margin_top.value) ? f.box_margin_top_measurement.value : ""); + + // Build border styles + + if (!f.border_style_same.checked) { + ce.style.borderTopStyle = f.border_style_top.value; + ce.style.borderRightStyle = f.border_style_right.value; + ce.style.borderBottomStyle = f.border_style_bottom.value; + ce.style.borderLeftStyle = f.border_style_left.value; + } else + ce.style.borderStyle = f.border_style_top.value; + + if (!f.border_width_same.checked) { + ce.style.borderTopWidth = f.border_width_top.value + (isNum(f.border_width_top.value) ? f.border_width_top_measurement.value : ""); + ce.style.borderRightWidth = f.border_width_right.value + (isNum(f.border_width_right.value) ? f.border_width_right_measurement.value : ""); + ce.style.borderBottomWidth = f.border_width_bottom.value + (isNum(f.border_width_bottom.value) ? f.border_width_bottom_measurement.value : ""); + ce.style.borderLeftWidth = f.border_width_left.value + (isNum(f.border_width_left.value) ? f.border_width_left_measurement.value : ""); + } else + ce.style.borderWidth = f.border_width_top.value; + + if (!f.border_color_same.checked) { + ce.style.borderTopColor = f.border_color_top.value; + ce.style.borderRightColor = f.border_color_right.value; + ce.style.borderBottomColor = f.border_color_bottom.value; + ce.style.borderLeftColor = f.border_color_left.value; + } else + ce.style.borderColor = f.border_color_top.value; + + // Build list styles + + ce.style.listStyleType = f.list_type.value; + ce.style.listStylePosition = f.list_position.value; + ce.style.listStyleImage = f.list_bullet_image.value != "" ? "url(" + f.list_bullet_image.value + ")" : ""; + + // Build positioning styles + + ce.style.position = f.positioning_type.value; + ce.style.visibility = f.positioning_visibility.value; + + if (ce.style.width == "") + ce.style.width = f.positioning_width.value + (isNum(f.positioning_width.value) ? f.positioning_width_measurement.value : ""); + + if (ce.style.height == "") + ce.style.height = f.positioning_height.value + (isNum(f.positioning_height.value) ? f.positioning_height_measurement.value : ""); + + ce.style.zIndex = f.positioning_zindex.value; + ce.style.overflow = f.positioning_overflow.value; + + if (!f.positioning_placement_same.checked) { + ce.style.top = f.positioning_placement_top.value + (isNum(f.positioning_placement_top.value) ? f.positioning_placement_top_measurement.value : ""); + ce.style.right = f.positioning_placement_right.value + (isNum(f.positioning_placement_right.value) ? f.positioning_placement_right_measurement.value : ""); + ce.style.bottom = f.positioning_placement_bottom.value + (isNum(f.positioning_placement_bottom.value) ? f.positioning_placement_bottom_measurement.value : ""); + ce.style.left = f.positioning_placement_left.value + (isNum(f.positioning_placement_left.value) ? f.positioning_placement_left_measurement.value : ""); + } else { + s = f.positioning_placement_top.value + (isNum(f.positioning_placement_top.value) ? f.positioning_placement_top_measurement.value : ""); + ce.style.top = s; + ce.style.right = s; + ce.style.bottom = s; + ce.style.left = s; + } + + if (!f.positioning_clip_same.checked) { + s = "rect("; + s += (isNum(f.positioning_clip_top.value) ? f.positioning_clip_top.value + f.positioning_clip_top_measurement.value : "auto") + " "; + s += (isNum(f.positioning_clip_right.value) ? f.positioning_clip_right.value + f.positioning_clip_right_measurement.value : "auto") + " "; + s += (isNum(f.positioning_clip_bottom.value) ? f.positioning_clip_bottom.value + f.positioning_clip_bottom_measurement.value : "auto") + " "; + s += (isNum(f.positioning_clip_left.value) ? f.positioning_clip_left.value + f.positioning_clip_left_measurement.value : "auto"); + s += ")"; + + if (s != "rect(auto auto auto auto)") + ce.style.clip = s; + } else { + s = "rect("; + t = isNum(f.positioning_clip_top.value) ? f.positioning_clip_top.value + f.positioning_clip_top_measurement.value : "auto"; + s += t + " "; + s += t + " "; + s += t + " "; + s += t + ")"; + + if (s != "rect(auto auto auto auto)") + ce.style.clip = s; + } + + ce.style.cssText = ce.style.cssText; +} + +function isNum(s) { + return new RegExp('[0-9]+', 'g').test(s); +} + +function showDisabledControls() { + var f = document.forms, i, a; + + for (i=0; i 1) { + addSelectValue(f, s, p[0], p[1]); + + if (se) + selectByValue(f, s, p[1]); + } else { + addSelectValue(f, s, p[0], p[0]); + + if (se) + selectByValue(f, s, p[0]); + } + } +} + +function toggleSame(ce, pre) { + var el = document.forms[0].elements, i; + + if (ce.checked) { + el[pre + "_top"].disabled = false; + el[pre + "_right"].disabled = true; + el[pre + "_bottom"].disabled = true; + el[pre + "_left"].disabled = true; + + if (el[pre + "_top_measurement"]) { + el[pre + "_top_measurement"].disabled = false; + el[pre + "_right_measurement"].disabled = true; + el[pre + "_bottom_measurement"].disabled = true; + el[pre + "_left_measurement"].disabled = true; + } + } else { + el[pre + "_top"].disabled = false; + el[pre + "_right"].disabled = false; + el[pre + "_bottom"].disabled = false; + el[pre + "_left"].disabled = false; + + if (el[pre + "_top_measurement"]) { + el[pre + "_top_measurement"].disabled = false; + el[pre + "_right_measurement"].disabled = false; + el[pre + "_bottom_measurement"].disabled = false; + el[pre + "_left_measurement"].disabled = false; + } + } + + showDisabledControls(); +} + +function synch(fr, to) { + var f = document.forms[0]; + + f.elements[to].value = f.elements[fr].value; + + if (f.elements[fr + "_measurement"]) + selectByValue(f, to + "_measurement", f.elements[fr + "_measurement"].value); +} + +tinyMCEPopup.onInit.add(init); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/jscripts/props.js --- a/includes/clientside/tinymce/plugins/style/jscripts/props.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,633 +0,0 @@ -var defaultFonts = "" + - "Arial, Helvetica, sans-serif=Arial, Helvetica, sans-serif;" + - "Times New Roman, Times, serif=Times New Roman, Times, serif;" + - "Courier New, Courier, mono=Courier New, Courier, mono;" + - "Times New Roman, Times, serif=Times New Roman, Times, serif;" + - "Georgia, Times New Roman, Times, serif=Georgia, Times New Roman, Times, serif;" + - "Verdana, Arial, Helvetica, sans-serif=Verdana, Arial, Helvetica, sans-serif;" + - "Geneva, Arial, Helvetica, sans-serif=Geneva, Arial, Helvetica, sans-serif"; - -var defaultSizes = "9;10;12;14;16;18;24;xx-small;x-small;small;medium;large;x-large;xx-large;smaller;larger"; -var defaultMeasurement = "+pixels=px;points=pt;in;cm;mm;picas;ems;exs;%"; -var defaultSpacingMeasurement = "pixels=px;points=pt;in;cm;mm;picas;+ems;exs;%"; -var defaultIndentMeasurement = "pixels=px;+points=pt;in;cm;mm;picas;ems;exs;%"; -var defaultWeight = "normal;bold;bolder;lighter;100;200;300;400;500;600;700;800;900"; -var defaultTextStyle = "normal;italic;oblique"; -var defaultVariant = "normal;small-caps"; -var defaultLineHeight = "normal"; -var defaultAttachment = "fixed;scroll"; -var defaultRepeat = "no-repeat;repeat;repeat-x;repeat-y"; -var defaultPosH = "left;center;right"; -var defaultPosV = "top;center;bottom"; -var defaultVAlign = "baseline;sub;super;top;text-top;middle;bottom;text-bottom"; -var defaultDisplay = "inline;block;list-item;run-in;compact;marker;table;inline-table;table-row-group;table-header-group;table-footer-group;table-row;table-column-group;table-column;table-cell;table-caption;none"; -var defaultBorderStyle = "none;solid;dashed;dotted;double;groove;ridge;inset;outset"; -var defaultBorderWidth = "thin;medium;thick"; -var defaultListType = "disc;circle;square;decimal;lower-roman;upper-roman;lower-alpha;upper-alpha;none"; - -function init() { - var ce = document.getElementById('container'), h; - - ce.style.cssText = tinyMCEPopup.getWindowArg('style_text'); - - h = getBrowserHTML('background_image_browser','background_image','image','advimage'); - document.getElementById("background_image_browser").innerHTML = h; - - tinyMCEPopup.resizeToInnerSize(); - - document.getElementById('text_color_pickcontainer').innerHTML = getColorPickerHTML('text_color_pick','text_color'); - document.getElementById('background_color_pickcontainer').innerHTML = getColorPickerHTML('background_color_pick','background_color'); - document.getElementById('border_color_top_pickcontainer').innerHTML = getColorPickerHTML('border_color_top_pick','border_color_top'); - document.getElementById('border_color_right_pickcontainer').innerHTML = getColorPickerHTML('border_color_right_pick','border_color_right'); - document.getElementById('border_color_bottom_pickcontainer').innerHTML = getColorPickerHTML('border_color_bottom_pick','border_color_bottom'); - document.getElementById('border_color_left_pickcontainer').innerHTML = getColorPickerHTML('border_color_left_pick','border_color_left'); - - fillSelect(0, 'text_font', 'style_font', defaultFonts, ';', true); - fillSelect(0, 'text_size', 'style_font_size', defaultSizes, ';', true); - fillSelect(0, 'text_size_measurement', 'style_font_size_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'text_case', 'style_text_case', "capitalize;uppercase;lowercase", ';', true); - fillSelect(0, 'text_weight', 'style_font_weight', defaultWeight, ';', true); - fillSelect(0, 'text_style', 'style_font_style', defaultTextStyle, ';', true); - fillSelect(0, 'text_variant', 'style_font_variant', defaultVariant, ';', true); - fillSelect(0, 'text_lineheight', 'style_font_line_height', defaultLineHeight, ';', true); - fillSelect(0, 'text_lineheight_measurement', 'style_font_line_height_measurement', defaultMeasurement, ';', true); - - fillSelect(0, 'background_attachment', 'style_background_attachment', defaultAttachment, ';', true); - fillSelect(0, 'background_repeat', 'style_background_repeat', defaultRepeat, ';', true); - - fillSelect(0, 'background_hpos_measurement', 'style_background_hpos_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'background_vpos_measurement', 'style_background_vpos_measurement', defaultMeasurement, ';', true); - - fillSelect(0, 'background_hpos', 'style_background_hpos', defaultPosH, ';', true); - fillSelect(0, 'background_vpos', 'style_background_vpos', defaultPosV, ';', true); - - fillSelect(0, 'block_wordspacing', 'style_wordspacing', 'normal', ';', true); - fillSelect(0, 'block_wordspacing_measurement', 'style_wordspacing_measurement', defaultSpacingMeasurement, ';', true); - fillSelect(0, 'block_letterspacing', 'style_letterspacing', 'normal', ';', true); - fillSelect(0, 'block_letterspacing_measurement', 'style_letterspacing_measurement', defaultSpacingMeasurement, ';', true); - fillSelect(0, 'block_vertical_alignment', 'style_vertical_alignment', defaultVAlign, ';', true); - fillSelect(0, 'block_text_align', 'style_text_align', "left;right;center;justify", ';', true); - fillSelect(0, 'block_whitespace', 'style_whitespace', "normal;pre;nowrap", ';', true); - fillSelect(0, 'block_display', 'style_display', defaultDisplay, ';', true); - fillSelect(0, 'block_text_indent_measurement', 'style_text_indent_measurement', defaultIndentMeasurement, ';', true); - - fillSelect(0, 'box_width_measurement', 'style_box_width_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_height_measurement', 'style_box_height_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_float', 'style_float', 'left;right;none', ';', true); - fillSelect(0, 'box_clear', 'style_clear', 'left;right;both;none', ';', true); - fillSelect(0, 'box_padding_left_measurement', 'style_padding_left_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_padding_top_measurement', 'style_padding_top_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_padding_bottom_measurement', 'style_padding_bottom_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_padding_right_measurement', 'style_padding_right_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_margin_left_measurement', 'style_margin_left_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_margin_top_measurement', 'style_margin_top_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_margin_bottom_measurement', 'style_margin_bottom_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'box_margin_right_measurement', 'style_margin_right_measurement', defaultMeasurement, ';', true); - - fillSelect(0, 'border_style_top', 'style_border_style_top', defaultBorderStyle, ';', true); - fillSelect(0, 'border_style_right', 'style_border_style_right', defaultBorderStyle, ';', true); - fillSelect(0, 'border_style_bottom', 'style_border_style_bottom', defaultBorderStyle, ';', true); - fillSelect(0, 'border_style_left', 'style_border_style_left', defaultBorderStyle, ';', true); - - fillSelect(0, 'border_width_top', 'style_border_width_top', defaultBorderWidth, ';', true); - fillSelect(0, 'border_width_right', 'style_border_width_right', defaultBorderWidth, ';', true); - fillSelect(0, 'border_width_bottom', 'style_border_width_bottom', defaultBorderWidth, ';', true); - fillSelect(0, 'border_width_left', 'style_border_width_left', defaultBorderWidth, ';', true); - - fillSelect(0, 'border_width_top_measurement', 'style_border_width_top_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'border_width_right_measurement', 'style_border_width_right_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'border_width_bottom_measurement', 'style_border_width_bottom_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'border_width_left_measurement', 'style_border_width_left_measurement', defaultMeasurement, ';', true); - - fillSelect(0, 'list_type', 'style_list_type', defaultListType, ';', true); - fillSelect(0, 'list_position', 'style_list_position', "inside;outside", ';', true); - - fillSelect(0, 'positioning_type', 'style_positioning_type', "absolute;relative;static", ';', true); - fillSelect(0, 'positioning_visibility', 'style_positioning_visibility', "inherit;visible;hidden", ';', true); - - fillSelect(0, 'positioning_width_measurement', 'style_positioning_width_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'positioning_height_measurement', 'style_positioning_height_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'positioning_overflow', 'style_positioning_overflow', "visible;hidden;scroll;auto", ';', true); - - fillSelect(0, 'positioning_placement_top_measurement', 'style_positioning_placement_top_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'positioning_placement_right_measurement', 'style_positioning_placement_right_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'positioning_placement_bottom_measurement', 'style_positioning_placement_bottom_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'positioning_placement_left_measurement', 'style_positioning_placement_left_measurement', defaultMeasurement, ';', true); - - fillSelect(0, 'positioning_clip_top_measurement', 'style_positioning_clip_top_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'positioning_clip_right_measurement', 'style_positioning_clip_right_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'positioning_clip_bottom_measurement', 'style_positioning_clip_bottom_measurement', defaultMeasurement, ';', true); - fillSelect(0, 'positioning_clip_left_measurement', 'style_positioning_clip_left_measurement', defaultMeasurement, ';', true); - - TinyMCE_EditableSelects.init(); - setupFormData(); - showDisabledControls(); -} - -function setupFormData() { - var ce = document.getElementById('container'), f = document.forms[0], s, b, i; - - // Setup text fields - - selectByValue(f, 'text_font', ce.style.fontFamily, true, true); - selectByValue(f, 'text_size', getNum(ce.style.fontSize), true, true); - selectByValue(f, 'text_size_measurement', getMeasurement(ce.style.fontSize)); - selectByValue(f, 'text_weight', ce.style.fontWeight, true, true); - selectByValue(f, 'text_style', ce.style.fontStyle, true, true); - selectByValue(f, 'text_lineheight', getNum(ce.style.lineHeight), true, true); - selectByValue(f, 'text_lineheight_measurement', getMeasurement(ce.style.lineHeight)); - selectByValue(f, 'text_case', ce.style.textTransform, true, true); - selectByValue(f, 'text_variant', ce.style.fontVariant, true, true); - f.text_color.value = ce.style.color; - updateColor('text_color_pick', 'text_color'); - f.text_underline.checked = inStr(ce.style.textDecoration, 'underline'); - f.text_overline.checked = inStr(ce.style.textDecoration, 'overline'); - f.text_linethrough.checked = inStr(ce.style.textDecoration, 'line-through'); - f.text_blink.checked = inStr(ce.style.textDecoration, 'blink'); - - // Setup background fields - - f.background_color.value = ce.style.backgroundColor; - updateColor('background_color_pick', 'background_color'); - f.background_image.value = ce.style.backgroundImage.replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"); - selectByValue(f, 'background_repeat', ce.style.backgroundRepeat, true, true); - selectByValue(f, 'background_attachment', ce.style.backgroundAttachment, true, true); - selectByValue(f, 'background_hpos', getNum(getVal(ce.style.backgroundPosition, 0)), true, true); - selectByValue(f, 'background_hpos_measurement', getMeasurement(getVal(ce.style.backgroundPosition, 0))); - selectByValue(f, 'background_vpos', getNum(getVal(ce.style.backgroundPosition, 1)), true, true); - selectByValue(f, 'background_vpos_measurement', getMeasurement(getVal(ce.style.backgroundPosition, 1))); - - // Setup block fields - - selectByValue(f, 'block_wordspacing', getNum(ce.style.wordSpacing), true, true); - selectByValue(f, 'block_wordspacing_measurement', getMeasurement(ce.style.wordSpacing)); - selectByValue(f, 'block_letterspacing', getNum(ce.style.letterSpacing), true, true); - selectByValue(f, 'block_letterspacing_measurement', getMeasurement(ce.style.letterSpacing)); - selectByValue(f, 'block_vertical_alignment', ce.style.verticalAlign, true, true); - selectByValue(f, 'block_text_align', ce.style.textAlign, true, true); - f.block_text_indent.value = getNum(ce.style.textIndent); - selectByValue(f, 'block_text_indent_measurement', getMeasurement(ce.style.textIndent)); - selectByValue(f, 'block_whitespace', ce.style.whiteSpace, true, true); - selectByValue(f, 'block_display', ce.style.display, true, true); - - // Setup box fields - - f.box_width.value = getNum(ce.style.width); - selectByValue(f, 'box_width_measurement', getMeasurement(ce.style.width)); - - f.box_height.value = getNum(ce.style.height); - selectByValue(f, 'box_height_measurement', getMeasurement(ce.style.height)); - - if (tinyMCE.isGecko) - selectByValue(f, 'box_float', ce.style.cssFloat, true, true); - else - selectByValue(f, 'box_float', ce.style.styleFloat, true, true); - - selectByValue(f, 'box_clear', ce.style.clear, true, true); - - setupBox(f, ce, 'box_padding', 'padding', ''); - setupBox(f, ce, 'box_margin', 'margin', ''); - - // Setup border fields - - setupBox(f, ce, 'border_style', 'border', 'Style'); - setupBox(f, ce, 'border_width', 'border', 'Width'); - setupBox(f, ce, 'border_color', 'border', 'Color'); - - updateColor('border_color_top_pick', 'border_color_top'); - updateColor('border_color_right_pick', 'border_color_right'); - updateColor('border_color_bottom_pick', 'border_color_bottom'); - updateColor('border_color_left_pick', 'border_color_left'); - - // Setup list fields - - selectByValue(f, 'list_type', ce.style.listStyleType, true, true); - selectByValue(f, 'list_position', ce.style.listStylePosition, true, true); - f.list_bullet_image.value = ce.style.listStyleImage.replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"); - - // Setup box fields - - selectByValue(f, 'positioning_type', ce.style.position, true, true); - selectByValue(f, 'positioning_visibility', ce.style.visibility, true, true); - selectByValue(f, 'positioning_overflow', ce.style.overflow, true, true); - f.positioning_zindex.value = ce.style.zIndex ? ce.style.zIndex : ""; - - f.positioning_width.value = getNum(ce.style.width); - selectByValue(f, 'positioning_width_measurement', getMeasurement(ce.style.width)); - - f.positioning_height.value = getNum(ce.style.height); - selectByValue(f, 'positioning_height_measurement', getMeasurement(ce.style.height)); - - setupBox(f, ce, 'positioning_placement', '', '', new Array('top', 'right', 'bottom', 'left')); - - s = ce.style.clip.replace(new RegExp("rect\\('?([^']*)'?\\)", 'gi'), "$1"); - s = s.replace(/,/g, ' '); - - if (!hasEqualValues(new Array(getVal(s, 0), getVal(s, 1), getVal(s, 2), getVal(s, 3)))) { - f.positioning_clip_top.value = getNum(getVal(s, 0)); - selectByValue(f, 'positioning_clip_top_measurement', getMeasurement(getVal(s, 0))); - f.positioning_clip_right.value = getNum(getVal(s, 1)); - selectByValue(f, 'positioning_clip_right_measurement', getMeasurement(getVal(s, 1))); - f.positioning_clip_bottom.value = getNum(getVal(s, 2)); - selectByValue(f, 'positioning_clip_bottom_measurement', getMeasurement(getVal(s, 2))); - f.positioning_clip_left.value = getNum(getVal(s, 3)); - selectByValue(f, 'positioning_clip_left_measurement', getMeasurement(getVal(s, 3))); - } else { - f.positioning_clip_top.value = getNum(getVal(s, 0)); - selectByValue(f, 'positioning_clip_top_measurement', getMeasurement(getVal(s, 0))); - f.positioning_clip_right.value = f.positioning_clip_bottom.value = f.positioning_clip_left.value; - } - -// setupBox(f, ce, '', 'border', 'Color'); -} - -function getMeasurement(s) { - return s.replace(/^([0-9]+)(.*)$/, "$2"); -} - -function getNum(s) { - if (new RegExp('^[0-9]+[a-z%]+$', 'gi').test(s)) - return s.replace(/[^0-9]/g, ''); - - return s; -} - -function inStr(s, n) { - return new RegExp(n, 'gi').test(s); -} - -function getVal(s, i) { - var a = tinyMCE.explode(' ', s); - - if (a.length > 1) - return a[i]; - - return ""; -} - -function setValue(f, n, v) { - if (f.elements[n].type == "text") - f.elements[n].value = v; - else - selectByValue(f, n, v, true, true); -} - -function setupBox(f, ce, fp, pr, sf, b) { - if (typeof(b) == "undefined") - b = new Array('Top', 'Right', 'Bottom', 'Left'); - - if (isSame(ce, pr, sf, b)) { - f.elements[fp + "_same"].checked = true; - - setValue(f, fp + "_top", getNum(ce.style[pr + b[0] + sf])); - f.elements[fp + "_top"].disabled = false; - - f.elements[fp + "_right"].value = ""; - f.elements[fp + "_right"].disabled = true; - f.elements[fp + "_bottom"].value = ""; - f.elements[fp + "_bottom"].disabled = true; - f.elements[fp + "_left"].value = ""; - f.elements[fp + "_left"].disabled = true; - - if (f.elements[fp + "_top_measurement"]) { - selectByValue(f, fp + '_top_measurement', getMeasurement(ce.style[pr + b[0] + sf])); - f.elements[fp + "_left_measurement"].disabled = true; - f.elements[fp + "_bottom_measurement"].disabled = true; - f.elements[fp + "_right_measurement"].disabled = true; - } - } else { - f.elements[fp + "_same"].checked = false; - - setValue(f, fp + "_top", getNum(ce.style[pr + b[0] + sf])); - f.elements[fp + "_top"].disabled = false; - - setValue(f, fp + "_right", getNum(ce.style[pr + b[1] + sf])); - f.elements[fp + "_right"].disabled = false; - - setValue(f, fp + "_bottom", getNum(ce.style[pr + b[2] + sf])); - f.elements[fp + "_bottom"].disabled = false; - - setValue(f, fp + "_left", getNum(ce.style[pr + b[3] + sf])); - f.elements[fp + "_left"].disabled = false; - - if (f.elements[fp + "_top_measurement"]) { - selectByValue(f, fp + '_top_measurement', getMeasurement(ce.style[pr + b[0] + sf])); - selectByValue(f, fp + '_right_measurement', getMeasurement(ce.style[pr + b[1] + sf])); - selectByValue(f, fp + '_bottom_measurement', getMeasurement(ce.style[pr + b[2] + sf])); - selectByValue(f, fp + '_left_measurement', getMeasurement(ce.style[pr + b[3] + sf])); - f.elements[fp + "_left_measurement"].disabled = false; - f.elements[fp + "_bottom_measurement"].disabled = false; - f.elements[fp + "_right_measurement"].disabled = false; - } - } -} - -function isSame(e, pr, sf, b) { - var a = new Array(), i, x; - - if (typeof(b) == "undefined") - b = new Array('Top', 'Right', 'Bottom', 'Left'); - - if (typeof(sf) == "undefined" || sf == null) - sf = ""; - - a[0] = e.style[pr + b[0] + sf]; - a[1] = e.style[pr + b[1] + sf]; - a[2] = e.style[pr + b[2] + sf]; - a[3] = e.style[pr + b[3] + sf]; - - for (i=0; i 0 ? s.substring(1) : s; - - if (f.text_none.checked) - s = "none"; - - ce.style.textDecoration = s; - - // Build background styles - - ce.style.backgroundColor = f.background_color.value; - ce.style.backgroundImage = f.background_image.value != "" ? "url(" + f.background_image.value + ")" : ""; - ce.style.backgroundRepeat = f.background_repeat.value; - ce.style.backgroundAttachment = f.background_attachment.value; - - if (f.background_hpos.value != "") { - s = ""; - s += f.background_hpos.value + (isNum(f.background_hpos.value) ? f.background_hpos_measurement.value : "") + " "; - s += f.background_vpos.value + (isNum(f.background_vpos.value) ? f.background_vpos_measurement.value : ""); - ce.style.backgroundPosition = s; - } - - // Build block styles - - ce.style.wordSpacing = f.block_wordspacing.value + (isNum(f.block_wordspacing.value) ? f.block_wordspacing_measurement.value : ""); - ce.style.letterSpacing = f.block_letterspacing.value + (isNum(f.block_letterspacing.value) ? f.block_letterspacing_measurement.value : ""); - ce.style.verticalAlign = f.block_vertical_alignment.value; - ce.style.textAlign = f.block_text_align.value; - ce.style.textIndent = f.block_text_indent.value + (isNum(f.block_text_indent.value) ? f.block_text_indent_measurement.value : ""); - ce.style.whiteSpace = f.block_whitespace.value; - ce.style.display = f.block_display.value; - - // Build box styles - - ce.style.width = f.box_width.value + (isNum(f.box_width.value) ? f.box_width_measurement.value : ""); - ce.style.height = f.box_height.value + (isNum(f.box_height.value) ? f.box_height_measurement.value : ""); - ce.style.styleFloat = f.box_float.value; - - if (tinyMCE.isGecko) - ce.style.cssFloat = f.box_float.value; - - ce.style.clear = f.box_clear.value; - - if (!f.box_padding_same.checked) { - ce.style.paddingTop = f.box_padding_top.value + (isNum(f.box_padding_top.value) ? f.box_padding_top_measurement.value : ""); - ce.style.paddingRight = f.box_padding_right.value + (isNum(f.box_padding_right.value) ? f.box_padding_right_measurement.value : ""); - ce.style.paddingBottom = f.box_padding_bottom.value + (isNum(f.box_padding_bottom.value) ? f.box_padding_bottom_measurement.value : ""); - ce.style.paddingLeft = f.box_padding_left.value + (isNum(f.box_padding_left.value) ? f.box_padding_left_measurement.value : ""); - } else - ce.style.padding = f.box_padding_top.value + (isNum(f.box_padding_top.value) ? f.box_padding_top_measurement.value : ""); - - if (!f.box_margin_same.checked) { - ce.style.marginTop = f.box_margin_top.value + (isNum(f.box_margin_top.value) ? f.box_margin_top_measurement.value : ""); - ce.style.marginRight = f.box_margin_right.value + (isNum(f.box_margin_right.value) ? f.box_margin_right_measurement.value : ""); - ce.style.marginBottom = f.box_margin_bottom.value + (isNum(f.box_margin_bottom.value) ? f.box_margin_bottom_measurement.value : ""); - ce.style.marginLeft = f.box_margin_left.value + (isNum(f.box_margin_left.value) ? f.box_margin_left_measurement.value : ""); - } else - ce.style.margin = f.box_margin_top.value + (isNum(f.box_margin_top.value) ? f.box_margin_top_measurement.value : ""); - - // Build border styles - - if (!f.border_style_same.checked) { - ce.style.borderTopStyle = f.border_style_top.value; - ce.style.borderRightStyle = f.border_style_right.value; - ce.style.borderBottomStyle = f.border_style_bottom.value; - ce.style.borderLeftStyle = f.border_style_left.value; - } else - ce.style.borderStyle = f.border_style_top.value; - - if (!f.border_width_same.checked) { - ce.style.borderTopWidth = f.border_width_top.value + (isNum(f.border_width_top.value) ? f.border_width_top_measurement.value : ""); - ce.style.borderRightWidth = f.border_width_right.value + (isNum(f.border_width_right.value) ? f.border_width_right_measurement.value : ""); - ce.style.borderBottomWidth = f.border_width_bottom.value + (isNum(f.border_width_bottom.value) ? f.border_width_bottom_measurement.value : ""); - ce.style.borderLeftWidth = f.border_width_left.value + (isNum(f.border_width_left.value) ? f.border_width_left_measurement.value : ""); - } else - ce.style.borderWidth = f.border_width_top.value; - - if (!f.border_color_same.checked) { - ce.style.borderTopColor = f.border_color_top.value; - ce.style.borderRightColor = f.border_color_right.value; - ce.style.borderBottomColor = f.border_color_bottom.value; - ce.style.borderLeftColor = f.border_color_left.value; - } else - ce.style.borderColor = f.border_color_top.value; - - // Build list styles - - ce.style.listStyleType = f.list_type.value; - ce.style.listStylePosition = f.list_position.value; - ce.style.listStyleImage = f.list_bullet_image.value != "" ? "url(" + f.list_bullet_image.value + ")" : ""; - - // Build positioning styles - - ce.style.position = f.positioning_type.value; - ce.style.visibility = f.positioning_visibility.value; - - if (ce.style.width == "") - ce.style.width = f.positioning_width.value + (isNum(f.positioning_width.value) ? f.positioning_width_measurement.value : ""); - - if (ce.style.height == "") - ce.style.height = f.positioning_height.value + (isNum(f.positioning_height.value) ? f.positioning_height_measurement.value : ""); - - ce.style.zIndex = f.positioning_zindex.value; - ce.style.overflow = f.positioning_overflow.value; - - if (!f.positioning_placement_same.checked) { - ce.style.top = f.positioning_placement_top.value + (isNum(f.positioning_placement_top.value) ? f.positioning_placement_top_measurement.value : ""); - ce.style.right = f.positioning_placement_right.value + (isNum(f.positioning_placement_right.value) ? f.positioning_placement_right_measurement.value : ""); - ce.style.bottom = f.positioning_placement_bottom.value + (isNum(f.positioning_placement_bottom.value) ? f.positioning_placement_bottom_measurement.value : ""); - ce.style.left = f.positioning_placement_left.value + (isNum(f.positioning_placement_left.value) ? f.positioning_placement_left_measurement.value : ""); - } else { - s = f.positioning_placement_top.value + (isNum(f.positioning_placement_top.value) ? f.positioning_placement_top_measurement.value : ""); - ce.style.top = s; - ce.style.right = s; - ce.style.bottom = s; - ce.style.left = s; - } - - if (!f.positioning_clip_same.checked) { - s = "rect("; - s += (isNum(f.positioning_clip_top.value) ? f.positioning_clip_top.value + f.positioning_clip_top_measurement.value : "auto") + " "; - s += (isNum(f.positioning_clip_right.value) ? f.positioning_clip_right.value + f.positioning_clip_right_measurement.value : "auto") + " "; - s += (isNum(f.positioning_clip_bottom.value) ? f.positioning_clip_bottom.value + f.positioning_clip_bottom_measurement.value : "auto") + " "; - s += (isNum(f.positioning_clip_left.value) ? f.positioning_clip_left.value + f.positioning_clip_left_measurement.value : "auto"); - s += ")"; - - if (s != "rect(auto auto auto auto)") - ce.style.clip = s; - } else { - s = "rect("; - t = isNum(f.positioning_clip_top.value) ? f.positioning_clip_top.value + f.positioning_clip_top_measurement.value : "auto"; - s += t + " "; - s += t + " "; - s += t + " "; - s += t + ")"; - - if (s != "rect(auto auto auto auto)") - ce.style.clip = s; - } - - ce.style.cssText = tinyMCE.serializeStyle(tinyMCE.parseStyle(ce.style.cssText)); -} - -function isNum(s) { - return new RegExp('[0-9]+', 'g').test(s); -} - -function showDisabledControls() { - var f = document.forms, i, a; - - for (i=0; i 1) { - addSelectValue(f, s, p[0], p[1]); - - if (se) - selectByValue(f, s, p[1]); - } else { - addSelectValue(f, s, p[0], p[0]); - - if (se) - selectByValue(f, s, p[0]); - } - } -} - -function toggleSame(ce, pre) { - var el = document.forms[0].elements, i; - - if (ce.checked) { - el[pre + "_top"].disabled = false; - el[pre + "_right"].disabled = true; - el[pre + "_bottom"].disabled = true; - el[pre + "_left"].disabled = true; - - if (el[pre + "_top_measurement"]) { - el[pre + "_top_measurement"].disabled = false; - el[pre + "_right_measurement"].disabled = true; - el[pre + "_bottom_measurement"].disabled = true; - el[pre + "_left_measurement"].disabled = true; - } - } else { - el[pre + "_top"].disabled = false; - el[pre + "_right"].disabled = false; - el[pre + "_bottom"].disabled = false; - el[pre + "_left"].disabled = false; - - if (el[pre + "_top_measurement"]) { - el[pre + "_top_measurement"].disabled = false; - el[pre + "_right_measurement"].disabled = false; - el[pre + "_bottom_measurement"].disabled = false; - el[pre + "_left_measurement"].disabled = false; - } - } - - showDisabledControls(); -} - -function synch(fr, to) { - var f = document.forms[0]; - - f.elements[to].value = f.elements[fr].value; - - if (f.elements[fr + "_measurement"]) - selectByValue(f, to + "_measurement", f.elements[fr + "_measurement"].value); -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/langs/en.js --- a/includes/clientside/tinymce/plugins/style/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('style',{ -title : 'Edit CSS Style', -styleinfo_desc : 'Edit CSS Style', -apply : 'Apply', -text_tab : 'Text', -background_tab : 'Background', -block_tab : 'Block', -box_tab : 'Box', -border_tab : 'Border', -list_tab : 'List', -positioning_tab : 'Positioning', -text_props : 'Text', -text_font : 'Font', -text_size : 'Size', -text_weight : 'Weight', -text_style : 'Style', -text_variant : 'Variant', -text_lineheight : 'Line height', -text_case : 'Case', -text_color : 'Color', -text_decoration : 'Decoration', -text_overline : 'overline', -text_underline : 'underline', -text_striketrough : 'strikethrough', -text_blink : 'blink', -text_none : 'none', -background_color : 'Background color', -background_image : 'Background image', -background_repeat : 'Repeat', -background_attachment : 'Attachment', -background_hpos : 'Horizontal position', -background_vpos : 'Vertical position', -block_wordspacing : 'Word spacing', -block_letterspacing : 'Letter spacing', -block_vertical_alignment : 'Vertical alignment', -block_text_align : 'Text align', -block_text_indent : 'Text indent', -block_whitespace : 'Whitespace', -block_display : 'Display', -box_width : 'Width', -box_height : 'Height', -box_float : 'Float', -box_clear : 'Clear', -padding : 'Padding', -same : 'Same for all', -top : 'Top', -right : 'Right', -bottom : 'Bottom', -left : 'Left', -margin : 'Margin', -style : 'Style', -width : 'Width', -height : 'Height', -color : 'Color', -list_type : 'Type', -bullet_image : 'Bullet image', -position : 'Position', -positioning_type : 'Type', -visibility : 'Visibility', -zindex : 'Z-index', -overflow : 'Overflow', -placement : 'Placement', -clip : 'Clip' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/langs/en_dlg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/style/langs/en_dlg.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,63 @@ +tinyMCE.addI18n('en.style_dlg',{ +title:"Edit CSS Style", +apply:"Apply", +text_tab:"Text", +background_tab:"Background", +block_tab:"Block", +box_tab:"Box", +border_tab:"Border", +list_tab:"List", +positioning_tab:"Positioning", +text_props:"Text", +text_font:"Font", +text_size:"Size", +text_weight:"Weight", +text_style:"Style", +text_variant:"Variant", +text_lineheight:"Line height", +text_case:"Case", +text_color:"Color", +text_decoration:"Decoration", +text_overline:"overline", +text_underline:"underline", +text_striketrough:"strikethrough", +text_blink:"blink", +text_none:"none", +background_color:"Background color", +background_image:"Background image", +background_repeat:"Repeat", +background_attachment:"Attachment", +background_hpos:"Horizontal position", +background_vpos:"Vertical position", +block_wordspacing:"Word spacing", +block_letterspacing:"Letter spacing", +block_vertical_alignment:"Vertical alignment", +block_text_align:"Text align", +block_text_indent:"Text indent", +block_whitespace:"Whitespace", +block_display:"Display", +box_width:"Width", +box_height:"Height", +box_float:"Float", +box_clear:"Clear", +padding:"Padding", +same:"Same for all", +top:"Top", +right:"Right", +bottom:"Bottom", +left:"Left", +margin:"Margin", +style:"Style", +width:"Width", +height:"Height", +color:"Color", +list_type:"Type", +bullet_image:"Bullet image", +position:"Position", +positioning_type:"Type", +visibility:"Visibility", +zindex:"Z-index", +overflow:"Overflow", +placement:"Placement", +clip:"Clip" +}); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/props.htm --- a/includes/clientside/tinymce/plugins/style/props.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/style/props.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,26 +1,27 @@ + - {$lang_style_title} - - - - - + {#style_dlg.title} + + + + + - +
@@ -28,13 +29,13 @@
- + - + - + - + - + - + - + - + @@ -498,7 +499,7 @@ - + @@ -507,7 +508,7 @@ - +
@@ -44,23 +45,23 @@
@@ -68,17 +69,17 @@ - +
 
@@ -89,28 +90,28 @@ - + @@ -121,7 +122,7 @@
{$lang_style_text_decoration}{#style_dlg.text_decoration} - + - + - + - + - +
- + @@ -473,7 +474,7 @@ - + @@ -482,7 +483,7 @@ - +
@@ -133,7 +134,7 @@ - + @@ -448,7 +449,7 @@ - + @@ -457,7 +458,7 @@ - +
@@ -144,36 +145,36 @@ - + - + - + - + @@ -184,61 +185,61 @@
- +
 
- +
 
- + - + - + - + - + - + - +
- +
 
- +
 
- +
 
@@ -247,88 +248,88 @@
- + - + - + - +
- +
 
      
- +
 
      
- {$lang_style_padding} + {#style_dlg.padding} - + - + - + - + - + @@ -339,57 +340,57 @@
- {$lang_style_margin} + {#style_dlg.margin}
 
- +
 
- +
 
- +
 
- +
 
- + - + - + - + - + @@ -405,25 +406,25 @@ - + - + - + - + - + - + - + @@ -432,7 +433,7 @@ - +
 
- +
 
- +
 
- +
 
- +
 
   {$lang_style_style}{#style_dlg.style}  {$lang_style_width}{#style_dlg.width}  {$lang_style_color}{#style_dlg.color}
       
{$lang_style_top}{#style_dlg.top}    
 
{$lang_style_right}{#style_dlg.right}    
 
{$lang_style_bottom}{#style_dlg.bottom}    
 
{$lang_style_left}{#style_dlg.left}    
 
@@ -527,17 +528,17 @@
- + - + - +
@@ -546,96 +547,96 @@
- + - + - + - + - + - +
      
- +
 
      
- +
 
      
- {$lang_style_placement} + {#style_dlg.placement} - + - + - + - + - + @@ -646,57 +647,57 @@
- {$lang_style_clip} + {#style_dlg.clip}
 
{$lang_style_top}{#style_dlg.top} - +
 
{$lang_style_right}{#style_dlg.right} - +
 
{$lang_style_bottom}{#style_dlg.bottom} - +
 
{$lang_style_left}{#style_dlg.left} - +
 
- + - + - + - + - + @@ -710,14 +711,14 @@
-
+
-
 
+
 

- +
@@ -725,5 +726,6 @@
+ diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/style/readme.txt --- a/includes/clientside/tinymce/plugins/style/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/cell.htm --- a/includes/clientside/tinymce/plugins/table/cell.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/table/cell.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,85 +1,86 @@ + - {$lang_table_cell_title} - - - - + {#table_dlg.cell_title} + + + + - +
- {$lang_table_general_props} + {#table_dlg.general_props}
 
{$lang_style_top}{#style_dlg.top} - +
 
{$lang_style_right}{#style_dlg.right} - +
 
{$lang_style_bottom}{#style_dlg.bottom} - +
 
{$lang_style_left}{#style_dlg.left} - +
 
- + - + - + - + - + - + - + @@ -89,39 +90,39 @@
- {$lang_table_advanced_props} + {#table_dlg.advanced_props}
- + - + - + - + - + "; + } elseif(!$val && $warn) { + if($cv) $color='FFFFCC'; else $color='FFFFAA'; + echo ""; + $warned = true; + } else { + if($cv) $color='FFCCCC'; else $color='FFAAAA'; + echo ""; + $failed = true; + } +} +function is_apache() +{ + $r = strstr($_SERVER['SERVER_SOFTWARE'], 'Apache') ? true : false; + return $r; +} + +function config_write_test() +{ + if ( !is_writable(ENANO_ROOT.'/config.new.php') ) + return false; + // We need to actually _open_ the file to make sure it can be written, because sometimes this fails even when is_writable() returns + // true on Windows/IIS servers. Don't ask me why. + $h = @fopen( ENANO_ROOT . '/config.new.php', 'a+' ); + if ( !$h ) + return false; + fclose($h); + return true; +} + +?> +

get('sysreqs_heading'); ?>

+

get('sysreqs_blurb'); ?>

+ +
@@ -133,7 +134,7 @@ - + ([\s]*?)<\/tr>#is', '', $result); + $result = preg_replace('#

([\s]*?)<\/p>#is', '', $result); + $result = preg_replace('#
([\s]*?) +

get('license_heading'); ?>

+

get('license_blurb_thankyou'); ?>

+

get('license_blurb_pleaseread'); ?>

+ +
@@ -145,7 +146,7 @@ - + ' . "\n"; + flush(); +} + +function echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack) +{ + global $neutral_color; + global $lang; + + $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A'; + echo '' . "\n"; + flush(); + close_install_table(); + $post_data = ''; + $mysql_error = mysql_error(); + foreach ( $_POST as $key => $value ) + { + // FIXME: These should really also be sanitized for double quotes + $value = htmlspecialchars($value); + $key = htmlspecialchars($key); + $post_data .= " \n"; + } + if ( $stage_id == 'renameconfig' ) + echo '

' . $failure_explanation . '

'; + else + echo ' + ' . $post_data . ' + +

' . $lang->get('meta_msg_err_stagefailed_title') . '

+

' . $failure_explanation . '

+ ' . ( !empty($mysql_error) ? "

" . $lang->get('meta_msg_err_stagefailed_mysqlerror') . " $mysql_error

" : '' ) . ' +

' . $lang->get('meta_msg_err_stagefailed_body') . '

+

+ '; + global $ui; + $ui->show_footer(); + exit; +} + +?> diff -r d823e49e2e4e -r c433348f3628 install/includes/payload.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/payload.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,423 @@ +sql_query('SELECT config_value FROM ' . table_prefix . 'config WHERE config_name=\'install_aes_key\';'); + if ( !$q ) + $db->_die(); + if ( $db->numrows() < 1 ) + return false; + list($aes_key) = $db->fetchrow_num(); + $aes_key = $aes->hextostring($aes_key); + + $pass = $aes->decrypt($_POST['crypt_data'], $aes_key, ENC_HEX); + if ( !$pass ) + return false; + + return $pass; // Will be true if the password isn't crapped +} + +function stg_make_private_key() +{ + global $db; + static $site_key = false; + + if ( $site_key ) + return $site_key; + + // Is there already a key cached in the database? + $q = $db->sql_query('SELECT config_value FROM ' . table_prefix . 'config WHERE config_name=\'site_aes_key\';'); + if ( !$q ) + $db->_die(); + + if ( $db->numrows() > 0 ) + { + list($site_key) = $db->fetchrow_num(); + $db->free_result(); + return $site_key; + } + + $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); + // This will use /dev/urandom if possible + $site_key = $aes->gen_readymade_key(); + + // Stash it in the database, don't check for errors though because we can always regenerate it + $db->sql_query('INSERT INTO ' . table_prefix . 'config ( config_name, config_value ) VALUES ( \'site_aes_key\', \'' . $site_key . '\' );'); + + return $site_key; +} + +function stg_load_schema() +{ + global $db, $dbdriver, $installer_version, $lang_id, $languages; + static $sql_parser = false; + + if ( is_object($sql_parser) ) + return $sql_parser->parse(); + + $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); + + $site_key = stg_make_private_key(); + $site_key = $aes->hextostring($site_key); + $admin_pass_clean = stg_password_decode(); + $admin_pass = $aes->encrypt($admin_pass_clean, $site_key, ENC_HEX); + + unset($admin_pass_clean); // Security + + try + { + $sql_parser = new SQL_Parser( ENANO_ROOT . "/install/schemas/{$dbdriver}_stage2.sql" ); + } + catch ( Exception $e ) + { + echo "
$e
"; + return false; + } + + $wkt = ENANO_ROOT . "/language/{$languages[$lang_id]['dir']}/install/mainpage-default.wkt"; + if ( !file_exists( $wkt ) ) + { + echo '
Error: could not locate wikitext for main page (' . $wkt . ')
'; + return false; + } + $wkt = @file_get_contents($wkt); + if ( empty($wkt) ) + return false; + + $wkt = $db->escape($wkt); + + $vars = array( + 'TABLE_PREFIX' => table_prefix, + 'SITE_NAME' => $db->escape($_POST['site_name']), + 'SITE_DESC' => $db->escape($_POST['site_desc']), + 'COPYRIGHT' => $db->escape($_POST['copyright']), + // FIXME: update form + 'WIKI_MODE' => ( isset($_POST['wiki_mode']) ? '1' : '0' ), + 'ENABLE_CACHE' => ( is_writable( ENANO_ROOT . '/cache/' ) ? '1' : '0' ), + 'VERSION' => $installer_version['version'], + 'ADMIN_USER' => $db->escape($_POST['username']), + 'ADMIN_PASS' => $admin_pass, + 'ADMIN_EMAIL' => $db->escape($_POST['email']), + 'REAL_NAME' => '', // This has always been stubbed. + 'ADMIN_EMBED_PHP' => strval(AUTH_DISALLOW), + 'UNIX_TIME' => strval(time()), + 'MAIN_PAGE_CONTENT' => $wkt, + 'IP_ADDRESS' => $db->escape($_SERVER['REMOTE_ADDR']) + ); + + $sql_parser->assign_vars($vars); + return $sql_parser->parse(); +} + +function stg_deliver_payload() +{ + global $db; + $schema = stg_load_schema(); + foreach ( $schema as $sql ) + { + if ( !$db->sql_query($sql) ) + { + echo $db->get_error(); + return false; + } + } + return true; +} + +function stg_write_config() +{ + global $dbhost, $dbuser, $dbpasswd, $dbname, $dbdriver; + $db_data = array( + 'host' => str_replace("'", "\\'", $dbhost), + 'user' => str_replace("'", "\\'", $dbuser), + 'pass' => str_replace("'", "\\'", $dbpasswd), + 'name' => str_replace("'", "\\'", $dbname), + 'tp' => table_prefix, + 'drv' => $dbdriver + ); + + // Retrieves the existing key + $site_key = stg_make_private_key(); + + // Determine contentPath + switch ( @$_POST['url_scheme'] ) + { + case 'standard': + default: + $sp_append = '/index.php?title='; + break; + case 'shortened': + $sp_append = '/index.php/'; + break; + case 'rewrite': + $sp_append = '/'; + break; + } + + $scriptpath = scriptPath; + $contentpath = $scriptpath . $sp_append; + + $config_file = <<import( ENANO_ROOT . "/language/{$lang_info['dir']}/user.json" ); + $lang_local->import( ENANO_ROOT . "/language/{$lang_info['dir']}/tools.json" ); + $lang_local->import( ENANO_ROOT . "/language/{$lang_info['dir']}/admin.json" ); + + $q = $db->sql_query('SELECT lang_id FROM ' . table_prefix . 'language ORDER BY lang_id DESC LIMIT 1;'); + if ( !$q ) + $db->_die(); + + list($lang_id_int) = $db->fetchrow_num(); + $db->free_result(); + setConfig('default_language', $lang_id_int); + + return true; +} + +function stg_init_logs() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + global $installer_version; + + $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . enano_date('d M Y h:i a') . '\', \'' . $db->escape($_POST['admin_user']) . '\', \'' . $db->escape(enano_version()) . '\', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\');'); + if ( !$q ) + { + echo '

MySQL return: ' . $db->sql_error() . '

'; + return false; + } + + return true; +} + +function stg_aes_cleanup() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + $q = $db->sql_query('DELETE FROM ' . table_prefix . 'config WHERE config_name = \'install_aes_key\' OR config_name = \'site_aes_key\';'); + if ( !$q ) + $db->_die(); + return true; +} + +function _stg_rename_config_revert() +{ + if ( file_exists('./config.php') ) + { + @rename('./config.php', './config.new.php'); + } + + $handle = @fopen('./config.php.new', 'w'); + if ( !$handle ) + return false; + $contents = ''; + fwrite($handle, $contents); + fclose($handle); + return true; +} + +function stg_build_index() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + if ( $paths->rebuild_search_index() ) + return true; + return false; +} + +function stg_rename_config() +{ + if ( !@rename(ENANO_ROOT . '/config.new.php', ENANO_ROOT . '/config.php') ) + { + echo '

Can\'t rename config.php

'; + _stg_rename_config_revert(); + return false; + } + + if ( filesize(ENANO_ROOT . '/.htaccess.new') > 1 ) + { + // rename/possibly concatenate .htaccess.new + $htaccess_base = ''; + if ( file_exists(ENANO_ROOT . '/.htaccess') ) + $htaccess_base .= @file_get_contents(ENANO_ROOT . '/.htaccess'); + if ( strlen($htaccess_base) > 0 && !preg_match("/\n$/", $htaccess_base) ) + $htaccess_base .= "\n\n"; + $htaccess_base .= @file_get_contents(ENANO_ROOT . '/.htaccess.new'); + if ( file_exists(ENANO_ROOT . '/.htaccess') ) + { + $hh = @fopen(ENANO_ROOT . '/.htaccess', 'w'); + if ( !$hh ) + return false; + fwrite($hh, $htaccess_base); + fclose($hh); + @unlink(ENANO_ROOT . '/.htaccess.new'); + return true; + } + else + { + return @rename(ENANO_ROOT . '/.htaccess.new', ENANO_ROOT . '/.htaccess'); + } + } + else + { + @unlink(ENANO_ROOT . '/.htaccess.new'); + } + return true; +} + diff -r d823e49e2e4e -r c433348f3628 install/includes/sql_parse.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/sql_parse.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,149 @@ +sql_string = $sql; + } + else + { + if ( file_exists($sql) ) + { + $this->sql_string = @file_get_contents($sql); + if ( empty($this->sql_string) ) + { + throw new Exception('SQL file is blank or permissions are bad'); + } + } + else + { + throw new Exception('SQL file doesn\'t exist'); + } + } + $this->sql_array = false; + $this->tpl_strings = array(); + } + + /** + * Sets template variables. + * @param array Associative array of template variables to assign + */ + + public function assign_vars($vars) + { + if ( !is_array($vars) ) + return false; + $this->tpl_strings = array_merge($this->tpl_strings, $vars); + } + + /** + * Internal function to parse the SQL. + * @access private + */ + + private function parse_sql() + { + $this->sql_array = $this->sql_string; + foreach ( $this->tpl_strings as $key => $value ) + { + $this->sql_array = str_replace("{{{$key}}}", $value, $this->sql_array); + } + + // Build an array of queries + $this->sql_array = explode("\n", $this->sql_array); + + foreach ( $this->sql_array as $i => $sql ) + { + $query =& $this->sql_array[$i]; + $t = trim($query); + if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) + { + unset($this->sql_array[$i]); + unset($query); + } + } + unset($query); + + $this->sql_array = array_values($this->sql_array); + $this->sql_array = implode("\n", $this->sql_array); + $this->sql_array = explode(";\n", $this->sql_array); + + foreach ( $this->sql_array as $i => $sql ) + { + $query =& $this->sql_array[$i]; + if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) + { + $query .= ';'; + } + } + unset($query); + } + + /** + * Returns the parsed array of SQL queries. + * @param bool Optional. Defaults to false. If true, a parse is performed even if it already happened. + * @return array + */ + + public function parse($force_reparse = false) + { + if ( !$this->sql_array || $force_reparse ) + $this->parse_sql(); + return $this->sql_array; + } +} + +?> diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/confirm.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/confirm.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,44 @@ +show_header(); +?> +

get('confirm_title'); ?>

+

get('confirm_body'); ?>

+

get('confirm_info_aes_title'); ?> + get('confirm_info_aes_body', array('aes_bits' => AES_BITS)); ?> +

+
&$value ) + { + if ( !preg_match('/^[a-z0-9_]+$/', $key) ) + die('You idiot hacker...'); + if ( $key == '_cont' ) + continue; + $value_clean = str_replace(array('\\', '"', '<', '>'), array('\\\\', '\\"', '<', '>'), $value); + echo "\n "; + } +?> + +
+ +
+ diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/database.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/database.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,110 @@ +' . $lang->get('database_driver_heading') . ''; +echo '

' . $lang->get('database_driver_intro') . '

'; +if ( @file_exists('/etc/enano-is-virt-appliance') ) +{ + echo '

' . $lang->get('database_driver_msg_virt_appliance') . '

'; +} + +$mysql_disable_reason = ''; +$pgsql_disable_reason = ''; +$mysql_disable = ''; +$pgsql_disable = ''; +if ( !function_exists('mysql_connect') ) +{ + $mysql_disable = ' disabled="disabled"'; + $mysql_disable_reason = $lang->get('database_driver_err_no_mysql'); +} +if ( !function_exists('pg_connect') ) +{ + $pgsql_disable = ' disabled="disabled"'; + $pgsql_disable_reason = $lang->get('database_driver_err_no_pgsql'); +} + +echo '
'; +echo ''; +?> +
@@ -163,18 +164,18 @@
-
+
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/css/table.css --- a/includes/clientside/tinymce/plugins/table/css/table.css Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/table/css/table.css Fri Feb 22 12:51:53 2008 -0500 @@ -1,7 +1,7 @@ /* CSS file for table dialog in the table plugin */ .panel_wrapper div.current { - height: 220px; + height: 245px; } .advfield { diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/editor_plugin.js --- a/includes/clientside/tinymce/plugins/table/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/table/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('table');var TinyMCE_TablePlugin={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}},initInstance:function(inst){if(tinyMCE.isGecko){var doc=inst.getDoc();tinyMCE.addEvent(doc,"mouseup",TinyMCE_TablePlugin._mouseDownHandler)}inst.tableRowClipboard=null},getControlHTML:function(control_name){var controls=new Array(['table','table.gif','lang_table_desc','mceInsertTable',true],['delete_table','table_delete.gif','lang_table_del','mceTableDelete'],['delete_col','table_delete_col.gif','lang_table_delete_col_desc','mceTableDeleteCol'],['delete_row','table_delete_row.gif','lang_table_delete_row_desc','mceTableDeleteRow'],['col_after','table_insert_col_after.gif','lang_table_col_after_desc','mceTableInsertColAfter'],['col_before','table_insert_col_before.gif','lang_table_col_before_desc','mceTableInsertColBefore'],['row_after','table_insert_row_after.gif','lang_table_row_after_desc','mceTableInsertRowAfter'],['row_before','table_insert_row_before.gif','lang_table_row_before_desc','mceTableInsertRowBefore'],['row_props','table_row_props.gif','lang_table_row_desc','mceTableRowProps',true],['cell_props','table_cell_props.gif','lang_table_cell_desc','mceTableCellProps',true],['split_cells','table_split_cells.gif','lang_table_split_cells_desc','mceTableSplitCells',true],['merge_cells','table_merge_cells.gif','lang_table_merge_cells_desc','mceTableMergeCells',true]);for(var i=0;i4?but[4]:false)+(but.length>5?', \''+but[5]+'\'':'')+');return false;';if(but[0]==control_name)return tinyMCE.getButtonHTML(control_name,but[2],'{$pluginurl}/images/'+but[1],but[3],(but.length>4?but[4]:false))}if(control_name=="tablecontrols"){var html="";html+=tinyMCE.getControlHTML("table");html+=tinyMCE.getControlHTML("separator");html+=tinyMCE.getControlHTML("row_props");html+=tinyMCE.getControlHTML("cell_props");html+=tinyMCE.getControlHTML("separator");html+=tinyMCE.getControlHTML("row_before");html+=tinyMCE.getControlHTML("row_after");html+=tinyMCE.getControlHTML("delete_row");html+=tinyMCE.getControlHTML("separator");html+=tinyMCE.getControlHTML("col_before");html+=tinyMCE.getControlHTML("col_after");html+=tinyMCE.getControlHTML("delete_col");html+=tinyMCE.getControlHTML("separator");html+=tinyMCE.getControlHTML("split_cells");html+=tinyMCE.getControlHTML("merge_cells");return html}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){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":var inst=tinyMCE.getInstanceById(editor_id);inst.execCommand('mceBeginUndoLevel');TinyMCE_TablePlugin._doExecCommand(editor_id,element,command,user_interface,value);inst.execCommand('mceEndUndoLevel');return true}return false},handleNodeChange:function(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){var colspan="1",rowspan="1",tdElm;var inst=tinyMCE.getInstanceById(editor_id);tinyMCE.switchClass(editor_id+'_table','mceButtonNormal');tinyMCE.switchClass(editor_id+'_delete_table','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_row_props','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_cell_props','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_row_before','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_row_after','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_delete_row','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_col_before','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_col_after','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_delete_col','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_split_cells','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_merge_cells','mceButtonDisabled');if(tdElm=tinyMCE.getParentElement(node,"td,th")){tinyMCE.switchClass(editor_id+'_cell_props','mceButtonSelected');tinyMCE.switchClass(editor_id+'_delete_table','mceButtonNormal');tinyMCE.switchClass(editor_id+'_row_before','mceButtonNormal');tinyMCE.switchClass(editor_id+'_row_after','mceButtonNormal');tinyMCE.switchClass(editor_id+'_delete_row','mceButtonNormal');tinyMCE.switchClass(editor_id+'_col_before','mceButtonNormal');tinyMCE.switchClass(editor_id+'_col_after','mceButtonNormal');tinyMCE.switchClass(editor_id+'_delete_col','mceButtonNormal');colspan=tinyMCE.getAttrib(tdElm,"colspan");rowspan=tinyMCE.getAttrib(tdElm,"rowspan");colspan=colspan==""?"1":colspan;rowspan=rowspan==""?"1":rowspan;if(colspan!="1"||rowspan!="1")tinyMCE.switchClass(editor_id+'_split_cells','mceButtonNormal')}if(tinyMCE.getParentElement(node,"tr"))tinyMCE.switchClass(editor_id+'_row_props','mceButtonSelected');if(tinyMCE.getParentElement(node,"table")){tinyMCE.switchClass(editor_id+'_table','mceButtonSelected');tinyMCE.switchClass(editor_id+'_merge_cells','mceButtonNormal')}},_mouseDownHandler:function(e){var elm=tinyMCE.isMSIE?event.srcElement:e.target;var focusElm=tinyMCE.selectedInstance.getFocusElement();if(elm.nodeName=="BODY"&&(focusElm.nodeName=="TD"||focusElm.nodeName=="TH"||(focusElm.parentNode&&focusElm.parentNode.nodeName=="TD")||(focusElm.parentNode&&focusElm.parentNode.nodeName=="TH"))){window.setTimeout(function(){var tableElm=tinyMCE.getParentElement(focusElm,"table");tinyMCE.handleVisualAid(tableElm,true,tinyMCE.settings['visual'],tinyMCE.selectedInstance)},10)}},_doExecCommand:function(editor_id,element,command,user_interface,value){var inst=tinyMCE.getInstanceById(editor_id);var focusElm=inst.getFocusElement();var trElm=tinyMCE.getParentElement(focusElm,"tr");var tdElm=tinyMCE.getParentElement(focusElm,"td,th");var tableElm=tinyMCE.getParentElement(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;i0&&inArray(ar[i],v))return true;if(ar[i]==v)return true}return false}function makeTD(){var newTD=doc.createElement("td");newTD.innerHTML=" "}function getColRowSpan(td){var colspan=tinyMCE.getAttrib(td,"colspan");var rowspan=tinyMCE.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;y1){for(var i=x;i1)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;i1){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;i1){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);cpos.rowindex--;if(cpos.rowindex<0)cpos.rowindex=0;grid=getTableGrid(tableElm);inst.selection.selectNode(getCell(grid,cpos.rowindex,0),tinyMCE.isGecko,true);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);newTD.innerHTML=" ";newTD.rowSpan=tdElm.rowSpan;tdElm.parentNode.insertBefore(newTD,tdElm)}else tdElm.colSpan++;lastTDElm=tdElm}}grid=getTableGrid(tableElm);inst.selection.selectNode(getCell(grid,cpos.rowindex,cpos.cellindex+1),tinyMCE.isGecko,true);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);newTD.innerHTML=" ";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}}grid=getTableGrid(tableElm);inst.selection.selectNode(getCell(grid,cpos.rowindex,cpos.cellindex),tinyMCE.isGecko,true);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=tinyMCE.getParentElement(tableElm,"table");tableElm.parentNode.removeChild(tableElm);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}}cpos.cellindex--;if(cpos.cellindex<0)cpos.cellindex=0;grid=getTableGrid(tableElm);inst.selection.selectNode(getCell(grid,cpos.rowindex,0),tinyMCE.isGecko,true);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;i1)addRows(newTD,trElm,rowspan)}addRows(tdElm,trElm,rowspan)}tableElm=tinyMCE.getParentElement(inst.getFocusElement(),"table");break;case"mceTableMergeCells":var rows=new Array();var sel=inst.getSel();var grid=getTableGrid(tableElm);if(tinyMCE.isMSIE||sel.rangeCount==1){if(user_interface){var template=new Array();var sp=getColRowSpan(tdElm);template['file']='../../plugins/table/merge_cells.htm';template['width']=250;template['height']=105+(tinyMCE.isNS7?25:0);template['width']+=tinyMCE.getLang('lang_table_merge_cells_delta_width',0);template['height']+=tinyMCE.getLang('lang_table_merge_cells_delta_height',0);tinyMCE.openWindow(template,{editor_id:inst.editorId,inline:"yes",action:"update",numcols:sp.colspan,numrows:sp.rowspan});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;y0)rows[rows.length]=rowCells}}}else{var cells=new Array();var sel=inst.getSel();var lastTR=null;var curRow=null;var x1=-1,y1=-1,x2,y2;if(sel.rangeCount<2)return true;for(var i=0;i0)rows[rows.length]=rowCells}var curRow=new Array();var lastTR=null;for(var y=0;ycolSpan)colSpan=rowColSpan;lastRowSpan=-1}var lastColSpan=-1;for(var x=0;xrowSpan)rowSpan=colRowSpan;lastColSpan=-1}tdElm=rows[0][0];tdElm.rowSpan=rowSpan;tdElm.colSpan=colSpan;for(var y=0;y0))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--}}}}break}tableElm=tinyMCE.getParentElement(inst.getFocusElement(),"table");tinyMCE.handleVisualAid(tableElm,true,tinyMCE.settings['visual'],tinyMCE.selectedInstance);tinyMCE.triggerNodeChange();inst.repaint()}return true}return false}};tinyMCE.addPlugin("table",TinyMCE_TablePlugin); \ No newline at end of file +(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;if(ed.dom.getParent(e,'td')||ed.dom.getParent(e,'th')){m.removeAll();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.onNodeChange.add(function(ed,cm,n){var p=ed.dom.getParent(n,'td,th,caption');cm.setActive('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);});},execCommand:function(cmd,ui,val){var ed=this.editor,b;switch(cmd){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;i0&&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='
';}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;y1){for(var i=x;i1)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;i1){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';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';}newTD.colSpan=1;newTD.rowSpan=1;newTR.appendChild(newTD);lastCell=tdElm;}return newTR;}switch(command){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='
';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='
';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){inst.dom.remove(inst.dom.getParent(tableElm,"table"));return true;}var cells=trElm.cells;var nextTR=nextElm(trElm,"TR");for(var x=0;x1){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='
';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='
';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){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';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;y0)rows[rows.length]=rowCells;}}}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;i0)rows[rows.length]=rowCells;}var curRow=new Array();var lastTR=null;for(var y=0;ycolSpan)colSpan=rowColSpan;lastRowSpan=-1;}var lastColSpan=-1;for(var x=0;xrowSpan)rowSpan=colRowSpan;lastColSpan=-1;}tdElm=rows[0][0];tdElm.rowSpan=rowSpan;tdElm.colSpan=colSpan;for(var y=0;y0))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--;}}}}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 diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/table/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/table/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,879 +1,881 @@ /** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ + * $Id: editor_plugin_src.js 520 2008-01-07 16:30:32Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('table'); +(function() { + var each = tinymce.each; -var TinyMCE_TablePlugin = { - 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 - }; - }, + tinymce.create('tinymce.plugins.TablePlugin', { + init : function(ed, url) { + var t = this; - initInstance : function(inst) { - if (tinyMCE.isGecko) { - var doc = inst.getDoc(); - tinyMCE.addEvent(doc, "mouseup", TinyMCE_TablePlugin._mouseDownHandler); - } - - inst.tableRowClipboard = null; - }, + t.editor = ed; + t.url = url; - /** - * Returns the HTML contents of the table control. - */ - getControlHTML : function(control_name) { - var controls = new Array( - ['table', 'table.gif', 'lang_table_desc', 'mceInsertTable', true], - ['delete_table', 'table_delete.gif', 'lang_table_del', 'mceTableDelete'], - ['delete_col', 'table_delete_col.gif', 'lang_table_delete_col_desc', 'mceTableDeleteCol'], - ['delete_row', 'table_delete_row.gif', 'lang_table_delete_row_desc', 'mceTableDeleteRow'], - ['col_after', 'table_insert_col_after.gif', 'lang_table_col_after_desc', 'mceTableInsertColAfter'], - ['col_before', 'table_insert_col_before.gif', 'lang_table_col_before_desc', 'mceTableInsertColBefore'], - ['row_after', 'table_insert_row_after.gif', 'lang_table_row_after_desc', 'mceTableInsertRowAfter'], - ['row_before', 'table_insert_row_before.gif', 'lang_table_row_before_desc', 'mceTableInsertRowBefore'], - ['row_props', 'table_row_props.gif', 'lang_table_row_desc', 'mceTableRowProps', true], - ['cell_props', 'table_cell_props.gif', 'lang_table_cell_desc', 'mceTableCellProps', true], - ['split_cells', 'table_split_cells.gif', 'lang_table_split_cells_desc', 'mceTableSplitCells', true], - ['merge_cells', 'table_merge_cells.gif', 'lang_table_merge_cells_desc', 'mceTableMergeCells', true]); - - // Render table control - for (var i=0; i 4 ? but[4] : false) + (but.length > 5 ? ', \'' + but[5] + '\'' : '') + ');return false;'; - - if (but[0] == control_name) - return tinyMCE.getButtonHTML(control_name, but[2], '{$pluginurl}/images/'+ but[1], but[3], (but.length > 4 ? but[4] : false)); - } + // Register buttons + 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]}); + }); - // Special tablecontrols - if (control_name == "tablecontrols") { - var html = ""; + ed.onInit.add(function() { + if (ed && ed.plugins.contextmenu) { + ed.plugins.contextmenu.onContextMenu.add(function(th, m, e) { + var sm; - html += tinyMCE.getControlHTML("table"); - html += tinyMCE.getControlHTML("separator"); - html += tinyMCE.getControlHTML("row_props"); - html += tinyMCE.getControlHTML("cell_props"); - html += tinyMCE.getControlHTML("separator"); - html += tinyMCE.getControlHTML("row_before"); - html += tinyMCE.getControlHTML("row_after"); - html += tinyMCE.getControlHTML("delete_row"); - html += tinyMCE.getControlHTML("separator"); - html += tinyMCE.getControlHTML("col_before"); - html += tinyMCE.getControlHTML("col_after"); - html += tinyMCE.getControlHTML("delete_col"); - html += tinyMCE.getControlHTML("separator"); - html += tinyMCE.getControlHTML("split_cells"); - html += tinyMCE.getControlHTML("merge_cells"); - - return html; - } + if (ed.dom.getParent(e, 'td') || ed.dom.getParent(e, 'th')) { + m.removeAll(); + 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(); - return ""; - }, + // Cell menu + 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}); - /** - * Executes the table commands. - */ - execCommand : function(editor_id, element, command, user_interface, value) { - // Is table command - switch (command) { - 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": - var inst = tinyMCE.getInstanceById(editor_id); + // Row menu + 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'}); - inst.execCommand('mceBeginUndoLevel'); - TinyMCE_TablePlugin._doExecCommand(editor_id, element, command, user_interface, value); - inst.execCommand('mceEndUndoLevel'); - - return true; - } - - // Pass to next handler in chain - return false; - }, - - handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) { - var colspan = "1", rowspan = "1", tdElm; - - var inst = tinyMCE.getInstanceById(editor_id); + // Column menu + 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}); + }); + } + }); - // Reset table controls - tinyMCE.switchClass(editor_id + '_table', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_delete_table', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_row_props', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_cell_props', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_row_before', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_row_after', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_delete_row', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_col_before', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_col_after', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_delete_col', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_split_cells', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_merge_cells', 'mceButtonDisabled'); + ed.onNodeChange.add(function(ed, cm, n) { + var p = ed.dom.getParent(n, 'td,th,caption'); - // Within a td element - if (tdElm = tinyMCE.getParentElement(node, "td,th")) { - tinyMCE.switchClass(editor_id + '_cell_props', 'mceButtonSelected'); - tinyMCE.switchClass(editor_id + '_delete_table', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_row_before', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_row_after', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_delete_row', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_col_before', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_col_after', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_delete_col', 'mceButtonNormal'); - - colspan = tinyMCE.getAttrib(tdElm, "colspan"); - rowspan = tinyMCE.getAttrib(tdElm, "rowspan"); - - colspan = colspan == "" ? "1" : colspan; - rowspan = rowspan == "" ? "1" : rowspan; - - if (colspan != "1" || rowspan != "1") - tinyMCE.switchClass(editor_id + '_split_cells', 'mceButtonNormal'); - } + cm.setActive('table', !!p); + if (p && p.nodeName === 'CAPTION') + p = null; - // Within a tr element - if (tinyMCE.getParentElement(node, "tr")) - tinyMCE.switchClass(editor_id + '_row_props', 'mceButtonSelected'); - - // Within table - if (tinyMCE.getParentElement(node, "table")) { - tinyMCE.switchClass(editor_id + '_table', 'mceButtonSelected'); - tinyMCE.switchClass(editor_id + '_merge_cells', 'mceButtonNormal'); - } - }, - - // Private plugin internal methods + 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); + }); + }, - _mouseDownHandler : function(e) { - var elm = tinyMCE.isMSIE ? event.srcElement : e.target; - var focusElm = tinyMCE.selectedInstance.getFocusElement(); - - // If press on special Mozilla create TD/TR thingie - if (elm.nodeName == "BODY" && (focusElm.nodeName == "TD" || focusElm.nodeName == "TH" || (focusElm.parentNode && focusElm.parentNode.nodeName == "TD") ||(focusElm.parentNode && focusElm.parentNode.nodeName == "TH") )) { - window.setTimeout(function() { - var tableElm = tinyMCE.getParentElement(focusElm, "table"); - tinyMCE.handleVisualAid(tableElm, true, tinyMCE.settings['visual'], tinyMCE.selectedInstance); - }, 10); - } - }, + execCommand : function(cmd, ui, val) { + var ed = this.editor, b; - /** - * Executes the table commands. - */ - _doExecCommand : function(editor_id, element, command, user_interface, value) { - var inst = tinyMCE.getInstanceById(editor_id); - var focusElm = inst.getFocusElement(); - var trElm = tinyMCE.getParentElement(focusElm, "tr"); - var tdElm = tinyMCE.getParentElement(focusElm, "td,th"); - var tableElm = tinyMCE.getParentElement(focusElm, "table"); - var doc = inst.contentWindow.document; - var tableBorder = tableElm ? tableElm.getAttribute("border") : ""; + // Is table command + switch (cmd) { + 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'); - // Get first TD if no TD found - if (trElm && tdElm == null) - tdElm = trElm.cells[0]; - - // ------- Inner functions --------- - function inArray(ar, v) { - for (var i=0; i 0 && inArray(ar[i], v)) - return true; - - // Found value - if (ar[i] == v) return true; } + // Pass to next handler in chain return false; - } - - function makeTD() { - var newTD = doc.createElement("td"); - newTD.innerHTML = " "; - } - - function getColRowSpan(td) { - var colspan = tinyMCE.getAttrib(td, "colspan"); - var rowspan = tinyMCE.getAttrib(td, "rowspan"); + }, - colspan = colspan == "" ? 1 : parseInt(colspan); - rowspan = rowspan == "" ? 1 : parseInt(rowspan); - - return {colspan : colspan, rowspan : rowspan}; - } + 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 + }; + }, - function getCellPos(grid, td) { - var x, y; - - for (y=0; y 0 && inArray(ar[i], v)) + return true; - for (x2=xstart; x2 1) { // Remove due to colspan - for (var i=x; i 1) - td.rowSpan = sd.rowspan + 1; + // Recalculate grid and select + inst.execCommand('mceRepaint'); + td = getCell(grid, dy, dx); - lastElm = td; + if (td) { + inst.selection.select(td.firstChild || td); + inst.selection.collapse(1); } + }; - deleteMarked(tableElm); - } - } + function makeTD() { + var newTD = doc.createElement("td"); - function prevElm(node, name) { - while ((node = node.previousSibling) != null) { - if (node.nodeName == name) - return node; + if (!tinymce.isIE) + newTD.innerHTML = '
'; } - return null; - } - - function nextElm(node, names) { - var namesAr = names.split(','); + function getColRowSpan(td) { + var colspan = inst.dom.getAttrib(td, "colspan"); + var rowspan = inst.dom.getAttrib(td, "rowspan"); - while ((node = node.nextSibling) != null) { - for (var i=0; i 1) { - do { - var nexttd = nextElm(td, "TD,TH"); + return null; + } - if (td._delete) - td.parentNode.removeChild(td); - } while ((td = nexttd) != null); - } - } while ((tr = next) != null); - } + function getCell(grid, row, col) { + if (grid[row] && grid[row][col]) + return grid[row][col]; - function addRows(td_elm, tr_elm, rowspan) { - // Add rows - td_elm.rowSpan = 1; - var trNext = nextElm(tr_elm, "TR"); - for (var i=1; i 1) { // Remove due to colspan + for (var i=x; i 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; } - // Reset col/row span - newTD.colSpan = 1; - newTD.rowSpan = 1; + return null; + } + + function nextElm(node, names) { + var namesAr = names.split(','); - newTR.appendChild(newTD); + while ((node = node.nextSibling) != null) { + for (var i=0; i 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) { + // Add rows + td_elm.rowSpan = 1; + var trNext = nextElm(tr_elm, "TR"); + for (var i=1; i 1) { + var newTD = cells[x].cloneNode(true); + var sd = getColRowSpan(cells[x]); + + newTD.rowSpan = sd.rowspan - 1; + + var nextTD = nextTR.cells[x]; - // Create cells - for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) { - if (tdElm != lastTDElm) { - var sd = getColRowSpan(tdElm); + if (nextTD == null) + nextTR.appendChild(newTD); + else + nextTR.insertBefore(newTD, nextTD); + } + } + + // Delete cells + 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 (sd.rowspan > 1) { + tdElm.rowSpan = sd.rowspan - 1; + } else { + trElm = tdElm.parentNode; + + if (trElm.parentNode) + trElm._delete = true; + } - newTD.innerHTML = " "; - newTD.colSpan = tdElm.colSpan; + lastTDElm = tdElm; + } + } - newTR.appendChild(newTD); - } else - tdElm.rowSpan = sd['rowspan'] + 1; + deleteMarked(tableElm); + + select(0, -1); + break; - lastTDElm = tdElm; - } - } + case "mceTableInsertColBefore": + if (!trElm || !tdElm) + return true; + + var grid = getTableGrid(tableElm); + var cpos = getCellPos(grid, tdElm); + var lastTDElm = null; - trElm.parentNode.insertBefore(newTR, trElm); + for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { + if (tdElm != lastTDElm) { + var sd = getColRowSpan(tdElm); - grid = getTableGrid(tableElm); - inst.selection.selectNode(getCell(grid, cpos.rowindex + 1, cpos.cellindex), tinyMCE.isGecko, true); // Only collape on gecko - break; + if (sd['colspan'] == 1) { + var newTD = doc.createElement(tdElm.nodeName); + + if (!tinymce.isIE) + newTD.innerHTML = '
'; + + newTD.rowSpan = tdElm.rowSpan; - case "mceTableInsertRowAfter": - if (!trElm || !tdElm) - return true; + tdElm.parentNode.insertBefore(newTD, tdElm); + } else + tdElm.colSpan++; + + lastTDElm = tdElm; + } + } - var grid = getTableGrid(tableElm); - var cpos = getCellPos(grid, tdElm); - var newTR = doc.createElement("tr"); - var lastTDElm = null; + select(); + break; + + case "mceTableInsertColAfter": + if (!trElm || !tdElm) + return true; + + var grid = getTableGrid(tableElm); + var cpos = getCellPos(grid, tdElm); + var lastTDElm = null; - // Create cells - for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) { - if (tdElm != lastTDElm) { - var sd = getColRowSpan(tdElm); + 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 = '
'; - if (sd['rowspan'] == 1) { - var newTD = doc.createElement("td"); + newTD.rowSpan = tdElm.rowSpan; - newTD.innerHTML = " "; - newTD.colSpan = tdElm.colSpan; + var nextTD = nextElm(tdElm, "TD,TH"); + if (nextTD == null) + tdElm.parentNode.appendChild(newTD); + else + nextTD.parentNode.insertBefore(newTD, nextTD); + } else + tdElm.colSpan++; - newTR.appendChild(newTD); - } else - tdElm.rowSpan = sd['rowspan'] + 1; + lastTDElm = tdElm; + } + } + + select(1); + break; - lastTDElm = tdElm; + case "mceTableDeleteCol": + if (!trElm || !tdElm) + return true; + + var grid = getTableGrid(tableElm); + var cpos = getCellPos(grid, tdElm); + var lastTDElm = null; + + // Only one col, remove whole table + if (grid.length > 1 && grid[0].length <= 1) { + inst.dom.remove(inst.dom.getParent(tableElm, "table")); + return true; } - } - if (newTR.hasChildNodes()) { - var nextTR = nextElm(trElm, "TR"); - if (nextTR) - nextTR.parentNode.insertBefore(newTR, nextTR); - else - tableElm.appendChild(newTR); - } + // Delete cells + for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) { + if (tdElm != lastTDElm) { + var sd = getColRowSpan(tdElm); - grid = getTableGrid(tableElm); - inst.selection.selectNode(getCell(grid, cpos.rowindex, cpos.cellindex), tinyMCE.isGecko, true); // Only collape on gecko - break; + if (sd['colspan'] > 1) + tdElm.colSpan = sd['colspan'] - 1; + else { + if (tdElm.parentNode) + tdElm.parentNode.removeChild(tdElm); + } - case "mceTableDeleteRow": + lastTDElm = tdElm; + } + } + + select(-1); + break; + + case "mceTableSplitCells": if (!trElm || !tdElm) return true; - var grid = getTableGrid(tableElm); - var cpos = getCellPos(grid, tdElm); - - // Only one row, remove whole table - if (grid.length == 1) { - tableElm = tinyMCE.getParentElement(tableElm, "table"); // Look for table instead of tbody - tableElm.parentNode.removeChild(tableElm); - return true; - } - - // Move down row spanned cells - var cells = trElm.cells; - var nextTR = nextElm(trElm, "TR"); - for (var x=0; x 1) { - var newTD = cells[x].cloneNode(true); - var sd = getColRowSpan(cells[x]); - - newTD.rowSpan = sd.rowspan - 1; + var spandata = getColRowSpan(tdElm); - var nextTD = nextTR.cells[x]; - - if (nextTD == null) - nextTR.appendChild(newTD); - else - nextTR.insertBefore(newTD, nextTD); - } - } - - // Delete cells - 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; + var colspan = spandata["colspan"]; + var rowspan = spandata["rowspan"]; - if (trElm.parentNode) - trElm._delete = true; - } - - lastTDElm = tdElm; - } - } - - deleteMarked(tableElm); - - cpos.rowindex--; - if (cpos.rowindex < 0) - cpos.rowindex = 0; - - // Recalculate grid and select - grid = getTableGrid(tableElm); - inst.selection.selectNode(getCell(grid, cpos.rowindex, 0), tinyMCE.isGecko, true); // Only collape on gecko - break; + // Needs splitting + if (colspan > 1 || rowspan > 1) { + // Generate cols + tdElm.colSpan = 1; + for (var i=1; i 1) + addRows(newTD, trElm, rowspan); + } - tdElm.parentNode.insertBefore(newTD, tdElm); - } else - tdElm.colSpan++; - - lastTDElm = tdElm; - } + addRows(tdElm, trElm, rowspan); } - grid = getTableGrid(tableElm); - inst.selection.selectNode(getCell(grid, cpos.rowindex, cpos.cellindex + 1), tinyMCE.isGecko, true); // Only collape on gecko - break; + // Apply visual aids + tableElm = inst.dom.getParent(inst.selection.getNode(), "table"); + break; - case "mceTableInsertColAfter": - if (!trElm || !tdElm) - return true; - + case "mceTableMergeCells": + var rows = []; + var sel = inst.selection.getSel(); 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 || sel.rangeCount == 1) { + if (user_interface) { + // Setup template + var sp = getColRowSpan(tdElm); - newTD.innerHTML = " "; - 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++; + 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 + }); - lastTDElm = tdElm; - } - } - - grid = getTableGrid(tableElm); - inst.selection.selectNode(getCell(grid, cpos.rowindex, cpos.cellindex), tinyMCE.isGecko, true); // Only collape on gecko - break; + return true; + } else { + var numRows = parseInt(value['numrows']); + var numCols = parseInt(value['numcols']); + var cpos = getCellPos(grid, tdElm); - case "mceTableDeleteCol": - if (!trElm || !tdElm) - return true; + if (("" + numRows) == "NaN") + numRows = 1; - var grid = getTableGrid(tableElm); - var cpos = getCellPos(grid, tdElm); - var lastTDElm = null; + if (("" + numCols) == "NaN") + numCols = 1; - // Only one col, remove whole table - if (grid.length > 1 && grid[0].length <= 1) { - tableElm = tinyMCE.getParentElement(tableElm, "table"); // Look for table instead of tbody - tableElm.parentNode.removeChild(tableElm); - return true; - } + // Get rows and cells + var tRows = tableElm.rows; + for (var y=cpos.rowindex; y 1) - tdElm.colSpan = sd['colspan'] - 1; - else { - if (tdElm.parentNode) - tdElm.parentNode.removeChild(tdElm); + // Within range + if (cp.cellindex < cpos.cellindex+numCols && cp.rowindex < cpos.rowindex+numRows) + rowCells[rowCells.length] = td; + } + } + + if (rowCells.length > 0) + rows[rows.length] = rowCells; } - lastTDElm = tdElm; + //return true; } - } - - cpos.cellindex--; - if (cpos.cellindex < 0) - cpos.cellindex = 0; - - // Recalculate grid and select - grid = getTableGrid(tableElm); - inst.selection.selectNode(getCell(grid, cpos.rowindex, 0), tinyMCE.isGecko, true); // Only collape on gecko - break; - - case "mceTableSplitCells": - if (!trElm || !tdElm) - return true; - - var spandata = getColRowSpan(tdElm); - - var colspan = spandata["colspan"]; - var rowspan = spandata["rowspan"]; - - // Needs splitting - if (colspan > 1 || rowspan > 1) { - // Generate cols - tdElm.colSpan = 1; - for (var i=1; i 1) - addRows(newTD, trElm, rowspan); - } + } else { + var cells = []; + var sel = inst.selection.getSel(); + var lastTR = null; + var curRow = null; + var x1 = -1, y1 = -1, x2, y2; - addRows(tdElm, trElm, rowspan); - } - - // Apply visual aids - tableElm = tinyMCE.getParentElement(inst.getFocusElement(), "table"); - break; - - case "mceTableMergeCells": - var rows = new Array(); - var sel = inst.getSel(); - var grid = getTableGrid(tableElm); - - if (tinyMCE.isMSIE || sel.rangeCount == 1) { - if (user_interface) { - // Setup template - var template = new Array(); - var sp = getColRowSpan(tdElm); + // Only one cell selected, whats the point? + if (sel.rangeCount < 2) + return true; - template['file'] = '../../plugins/table/merge_cells.htm'; - template['width'] = 250; - template['height'] = 105 + (tinyMCE.isNS7 ? 25 : 0); - - // Language specific width and height addons - template['width'] += tinyMCE.getLang('lang_table_merge_cells_delta_width', 0); - template['height'] += tinyMCE.getLang('lang_table_merge_cells_delta_height', 0); - - // Open window - tinyMCE.openWindow(template, {editor_id : inst.editorId, inline : "yes", action : "update", numcols : sp.colspan, numrows : sp.rowspan}); + // Get all selected cells + for (var i=0; i 0) - rows[rows.length] = rowCells; - } - - // Find selected cells in grid and box - var curRow = new Array(); - var lastTR = null; - for (var y=0; y colSpan) + colSpan = rowColSpan; + + lastRowSpan = -1; + } + + // Validate vertical and get total rowspan + var lastColSpan = -1; + for (var x=0; x rowSpan) + rowSpan = colRowSpan; + + lastColSpan = -1; + } + + // Setup td + tdElm = rows[0][0]; + tdElm.rowSpan = rowSpan; + tdElm.colSpan = colSpan; + + // Merge cells + for (var y=0; y 0)) + tdElm.innerHTML += html; + + // Not current cell + 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; + + // Empty TR, remove it + 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--; + } + } } } - } - // Validate selection and get total rowspan and colspan - var rowSpan = 1, colSpan = 1; - - // Validate horizontal and get total colspan - var lastRowSpan = -1; - for (var y=0; y colSpan) - colSpan = rowColSpan; - - lastRowSpan = -1; - } - - // Validate vertical and get total rowspan - var lastColSpan = -1; - for (var x=0; x rowSpan) - rowSpan = colRowSpan; - - lastColSpan = -1; + break; } - // Setup td - tdElm = rows[0][0]; - tdElm.rowSpan = rowSpan; - tdElm.colSpan = colSpan; - - // Merge cells - for (var y=0; y 0)) - tdElm.innerHTML += html; - - // Not current cell - 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; - - // Empty TR, remove it - 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--; - } - } - } - } - - break; + tableElm = inst.dom.getParent(inst.selection.getNode(), "table"); + inst.addVisual(tableElm); + inst.nodeChanged(); } - tableElm = tinyMCE.getParentElement(inst.getFocusElement(), "table"); - tinyMCE.handleVisualAid(tableElm, true, tinyMCE.settings['visual'], tinyMCE.selectedInstance); - tinyMCE.triggerNodeChange(); - inst.repaint(); - } + return true; + } - return true; + // Pass to next handler in chain + return false; } + }); - // Pass to next handler in chain - return false; - } -}; - -tinyMCE.addPlugin("table", TinyMCE_TablePlugin); + // Register plugin + tinymce.PluginManager.add('table', tinymce.plugins.TablePlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/buttons.gif Binary file includes/clientside/tinymce/plugins/table/images/buttons.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table.gif Binary file includes/clientside/tinymce/plugins/table/images/table.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_cell_props.gif Binary file includes/clientside/tinymce/plugins/table/images/table_cell_props.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_delete.gif Binary file includes/clientside/tinymce/plugins/table/images/table_delete.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_delete_col.gif Binary file includes/clientside/tinymce/plugins/table/images/table_delete_col.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_delete_row.gif Binary file includes/clientside/tinymce/plugins/table/images/table_delete_row.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_insert_col_after.gif Binary file includes/clientside/tinymce/plugins/table/images/table_insert_col_after.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_insert_col_before.gif Binary file includes/clientside/tinymce/plugins/table/images/table_insert_col_before.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_insert_row_after.gif Binary file includes/clientside/tinymce/plugins/table/images/table_insert_row_after.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_insert_row_before.gif Binary file includes/clientside/tinymce/plugins/table/images/table_insert_row_before.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_merge_cells.gif Binary file includes/clientside/tinymce/plugins/table/images/table_merge_cells.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_row_props.gif Binary file includes/clientside/tinymce/plugins/table/images/table_row_props.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/images/table_split_cells.gif Binary file includes/clientside/tinymce/plugins/table/images/table_split_cells.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/js/cell.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/table/js/cell.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,258 @@ +tinyMCEPopup.requireLangPack(); + +var ed; + +function init() { + ed = tinyMCEPopup.editor; + tinyMCEPopup.resizeToInnerSize(); + + document.getElementById('backgroundimagebrowsercontainer').innerHTML = getBrowserHTML('backgroundimagebrowser','backgroundimage','image','table'); + document.getElementById('bordercolor_pickcontainer').innerHTML = getColorPickerHTML('bordercolor_pick','bordercolor'); + document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor') + + var inst = ed; + var tdElm = ed.dom.getParent(ed.selection.getNode(), "td,th"); + var formObj = document.forms[0]; + var st = ed.dom.parseStyle(ed.dom.getAttrib(tdElm, "style")); + + // Get table cell data + var celltype = tdElm.nodeName.toLowerCase(); + var align = ed.dom.getAttrib(tdElm, 'align'); + var valign = ed.dom.getAttrib(tdElm, 'valign'); + var width = trimSize(getStyle(tdElm, 'width', 'width')); + var height = trimSize(getStyle(tdElm, 'height', 'height')); + var bordercolor = convertRGBToHex(getStyle(tdElm, 'bordercolor', 'borderLeftColor')); + var bgcolor = convertRGBToHex(getStyle(tdElm, 'bgcolor', 'backgroundColor')); + var className = ed.dom.getAttrib(tdElm, 'class'); + var backgroundimage = getStyle(tdElm, 'background', 'backgroundImage').replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1");; + var id = ed.dom.getAttrib(tdElm, 'id'); + var lang = ed.dom.getAttrib(tdElm, 'lang'); + var dir = ed.dom.getAttrib(tdElm, 'dir'); + var scope = ed.dom.getAttrib(tdElm, 'scope'); + + // Setup form + addClassesToList('class', 'table_cell_styles'); + formObj.bordercolor.value = bordercolor; + formObj.bgcolor.value = bgcolor; + formObj.backgroundimage.value = backgroundimage; + formObj.width.value = width; + formObj.height.value = height; + formObj.id.value = id; + formObj.lang.value = lang; + formObj.style.value = ed.dom.serializeStyle(st); + selectByValue(formObj, 'align', align); + selectByValue(formObj, 'valign', valign); + selectByValue(formObj, 'class', className); + selectByValue(formObj, 'celltype', celltype); + selectByValue(formObj, 'dir', dir); + selectByValue(formObj, 'scope', scope); + + // Resize some elements + if (isVisible('backgroundimagebrowser')) + document.getElementById('backgroundimage').style.width = '180px'; + + updateColor('bordercolor_pick', 'bordercolor'); + updateColor('bgcolor_pick', 'bgcolor'); +} + +function updateAction() { + var el = ed.selection.getNode(); + var inst = ed; + var tdElm = ed.dom.getParent(el, "td,th"); + var trElm = ed.dom.getParent(el, "tr"); + var tableElm = ed.dom.getParent(el, "table"); + var formObj = document.forms[0]; + + ed.execCommand('mceBeginUndoLevel'); + + switch (getSelectValue(formObj, 'action')) { + case "cell": + var celltype = getSelectValue(formObj, 'celltype'); + var scope = getSelectValue(formObj, 'scope'); + + if (ed.getParam("accessibility_warnings")) { + if (celltype == "th" && scope == "") + var answer = confirm(ed.getLang('table_dlg.missing_scope', '', true)); + else + var answer = true; + + if (!answer) + return; + } + + updateCell(tdElm); + break; + + case "row": + var cell = trElm.firstChild; + + if (cell.nodeName != "TD" && cell.nodeName != "TH") + cell = nextCell(cell); + + do { + cell = updateCell(cell, true); + } while ((cell = nextCell(cell)) != null); + + break; + + case "all": + var rows = tableElm.getElementsByTagName("tr"); + + for (var i=0; i colLimit) { + alert(inst.getLang('table_col_limit', '', true, {cols : colLimit})); + return false; + } else if (rowLimit && rows > rowLimit) { + alert(inst.getLang('table_row_limit', '', true, {rows : rowLimit})); + return false; + } else if (cellLimit && cols * rows > cellLimit) { + alert(inst.getLang('table_cell_limit', '', true, {cells : cellLimit})); + return false; + } + + // Update table + if (action == "update") { + inst.execCommand('mceBeginUndoLevel'); + + dom.setAttrib(elm, 'cellPadding', cellpadding, true); + dom.setAttrib(elm, 'cellSpacing', cellspacing, true); + dom.setAttrib(elm, 'border', border); + dom.setAttrib(elm, 'align', align); + dom.setAttrib(elm, 'frame', frame); + dom.setAttrib(elm, 'rules', rules); + dom.setAttrib(elm, 'class', className); + dom.setAttrib(elm, 'style', style); + dom.setAttrib(elm, 'id', id); + dom.setAttrib(elm, 'summary', summary); + dom.setAttrib(elm, 'dir', dir); + dom.setAttrib(elm, 'lang', lang); + + capEl = inst.dom.select('caption', elm)[0]; + + if (capEl && !caption) + capEl.parentNode.removeChild(capEl); + + if (!capEl && caption) { + capEl = elm.ownerDocument.createElement('caption'); + + if (!tinymce.isIE) + capEl.innerHTML = '
'; + + elm.insertBefore(capEl, elm.firstChild); + } + + dom.setAttrib(elm, 'width', width, true); + + // Remove these since they are not valid XHTML + dom.setAttrib(elm, 'borderColor', ''); + dom.setAttrib(elm, 'bgColor', ''); + dom.setAttrib(elm, 'background', ''); + dom.setAttrib(elm, 'height', ''); + + if (background != '') + elm.style.backgroundImage = "url('" + background + "')"; + else + elm.style.backgroundImage = ''; + +/* if (tinyMCEPopup.getParam("inline_styles")) { + if (width != '') + elm.style.width = getCSSSize(width); + }*/ + + if (bordercolor != "") { + elm.style.borderColor = bordercolor; + elm.style.borderStyle = elm.style.borderStyle == "" ? "solid" : elm.style.borderStyle; + elm.style.borderWidth = border == "" ? "1px" : border; + } else + elm.style.borderColor = ''; + + elm.style.backgroundColor = bgcolor; + elm.style.height = getCSSSize(height); + + inst.addVisual(); + + // Fix for stange MSIE align bug + //elm.outerHTML = elm.outerHTML; + + inst.nodeChanged(); + inst.execCommand('mceEndUndoLevel'); + + // Repaint if dimensions changed + if (formObj.width.value != orgTableWidth || formObj.height.value != orgTableHeight) + inst.execCommand('mceRepaint'); + + tinyMCEPopup.close(); + return true; + } + + // Create new table + html += '/g, '>'); + + return ' ' + attrib + '="' + value + '"'; +} + +function init() { + tinyMCEPopup.resizeToInnerSize(); + + document.getElementById('backgroundimagebrowsercontainer').innerHTML = getBrowserHTML('backgroundimagebrowser','backgroundimage','image','table'); + document.getElementById('backgroundimagebrowsercontainer').innerHTML = getBrowserHTML('backgroundimagebrowser','backgroundimage','image','table'); + document.getElementById('bordercolor_pickcontainer').innerHTML = getColorPickerHTML('bordercolor_pick','bordercolor'); + document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor'); + + var cols = 2, rows = 2, border = tinyMCEPopup.getParam('table_default_border', '0'), cellpadding = tinyMCEPopup.getParam('table_default_cellpadding', ''), cellspacing = tinyMCEPopup.getParam('table_default_cellspacing', ''); + var align = "", width = "", height = "", bordercolor = "", bgcolor = "", className = ""; + var id = "", summary = "", style = "", dir = "", lang = "", background = "", bgcolor = "", bordercolor = "", rules, frame; + var inst = tinyMCEPopup.editor, dom = inst.dom; + var formObj = document.forms[0]; + var elm = dom.getParent(inst.selection.getNode(), "table"); + + action = tinyMCEPopup.getWindowArg('action'); + + if (!action) + action = elm ? "update" : "insert"; + + if (elm && action != "insert") { + var rowsAr = elm.rows; + var cols = 0; + for (var i=0; i cols) + cols = rowsAr[i].cells.length; + + cols = cols; + rows = rowsAr.length; + + st = dom.parseStyle(dom.getAttrib(elm, "style")); + border = trimSize(getStyle(elm, 'border', 'borderWidth')); + cellpadding = dom.getAttrib(elm, 'cellpadding', ""); + cellspacing = dom.getAttrib(elm, 'cellspacing', ""); + width = trimSize(getStyle(elm, 'width', 'width')); + height = trimSize(getStyle(elm, 'height', 'height')); + bordercolor = convertRGBToHex(getStyle(elm, 'bordercolor', 'borderLeftColor')); + bgcolor = convertRGBToHex(getStyle(elm, 'bgcolor', 'backgroundColor')); + align = dom.getAttrib(elm, 'align', align); + frame = dom.getAttrib(elm, 'frame'); + rules = dom.getAttrib(elm, 'rules'); + className = tinymce.trim(dom.getAttrib(elm, 'class').replace(/mceItem.+/g, '')); + id = dom.getAttrib(elm, 'id'); + summary = dom.getAttrib(elm, 'summary'); + style = dom.serializeStyle(st); + dir = dom.getAttrib(elm, 'dir'); + lang = dom.getAttrib(elm, 'lang'); + background = getStyle(elm, 'background', 'backgroundImage').replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"); + formObj.caption.checked = elm.getElementsByTagName('caption').length > 0; + + orgTableWidth = width; + orgTableHeight = height; + + action = "update"; + formObj.insert.value = inst.getLang('update'); + } + + addClassesToList('class', "table_styles"); + + // Update form + selectByValue(formObj, 'align', align); + selectByValue(formObj, 'frame', frame); + selectByValue(formObj, 'rules', rules); + selectByValue(formObj, 'class', className); + formObj.cols.value = cols; + formObj.rows.value = rows; + formObj.border.value = border; + formObj.cellpadding.value = cellpadding; + formObj.cellspacing.value = cellspacing; + formObj.width.value = width; + formObj.height.value = height; + formObj.bordercolor.value = bordercolor; + formObj.bgcolor.value = bgcolor; + formObj.id.value = id; + formObj.summary.value = summary; + formObj.style.value = style; + formObj.dir.value = dir; + formObj.lang.value = lang; + formObj.backgroundimage.value = background; + + updateColor('bordercolor_pick', 'bordercolor'); + updateColor('bgcolor_pick', 'bgcolor'); + + // Resize some elements + if (isVisible('backgroundimagebrowser')) + document.getElementById('backgroundimage').style.width = '180px'; + + // Disable some fields in update mode + if (action == "update") { + formObj.cols.disabled = true; + formObj.rows.disabled = true; + } +} + +function changedSize() { + var formObj = document.forms[0]; + var st = dom.parseStyle(formObj.style.value); + +/* var width = formObj.width.value; + if (width != "") + st['width'] = tinyMCEPopup.getParam("inline_styles") ? getCSSSize(width) : ""; + else + st['width'] = "";*/ + + var height = formObj.height.value; + if (height != "") + st['height'] = getCSSSize(height); + else + st['height'] = ""; + + formObj.style.value = dom.serializeStyle(st); +} + +function changedBackgroundImage() { + var formObj = document.forms[0]; + var st = dom.parseStyle(formObj.style.value); + + st['background-image'] = "url('" + formObj.backgroundimage.value + "')"; + + formObj.style.value = dom.serializeStyle(st); +} + +function changedBorder() { + var formObj = document.forms[0]; + var st = dom.parseStyle(formObj.style.value); + + // Update border width if the element has a color + if (formObj.border.value != "" && formObj.bordercolor.value != "") + st['border-width'] = formObj.border.value + "px"; + + formObj.style.value = dom.serializeStyle(st); +} + +function changedColor() { + var formObj = document.forms[0]; + var st = dom.parseStyle(formObj.style.value); + + st['background-color'] = formObj.bgcolor.value; + + if (formObj.bordercolor.value != "") { + st['border-color'] = formObj.bordercolor.value; + + // Add border-width if it's missing + if (!st['border-width']) + st['border-width'] = formObj.border.value == "" ? "1px" : formObj.border.value + "px"; + } + + formObj.style.value = dom.serializeStyle(st); +} + +function changedStyle() { + var formObj = document.forms[0]; + var st = dom.parseStyle(formObj.style.value); + + if (st['background-image']) + formObj.backgroundimage.value = st['background-image'].replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"); + else + formObj.backgroundimage.value = ''; + + if (st['width']) + formObj.width.value = trimSize(st['width']); + + if (st['height']) + formObj.height.value = trimSize(st['height']); + + if (st['background-color']) { + formObj.bgcolor.value = st['background-color']; + updateColor('bgcolor_pick','bgcolor'); + } + + if (st['border-color']) { + formObj.bordercolor.value = st['border-color']; + updateColor('bordercolor_pick','bordercolor'); + } +} + +tinyMCEPopup.onInit.add(init); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/jscripts/cell.js --- a/includes/clientside/tinymce/plugins/table/jscripts/cell.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,249 +0,0 @@ -function init() { - tinyMCEPopup.resizeToInnerSize(); - - document.getElementById('backgroundimagebrowsercontainer').innerHTML = getBrowserHTML('backgroundimagebrowser','backgroundimage','image','table'); - document.getElementById('bordercolor_pickcontainer').innerHTML = getColorPickerHTML('bordercolor_pick','bordercolor'); - document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor') - - var inst = tinyMCE.selectedInstance; - var tdElm = tinyMCE.getParentElement(inst.getFocusElement(), "td,th"); - var formObj = document.forms[0]; - var st = tinyMCE.parseStyle(tinyMCE.getAttrib(tdElm, "style")); - - // Get table cell data - var celltype = tdElm.nodeName.toLowerCase(); - var align = tinyMCE.getAttrib(tdElm, 'align'); - var valign = tinyMCE.getAttrib(tdElm, 'valign'); - var width = trimSize(getStyle(tdElm, 'width', 'width')); - var height = trimSize(getStyle(tdElm, 'height', 'height')); - var bordercolor = convertRGBToHex(getStyle(tdElm, 'bordercolor', 'borderLeftColor')); - var bgcolor = convertRGBToHex(getStyle(tdElm, 'bgcolor', 'backgroundColor')); - var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(tdElm, 'class'), false); - var backgroundimage = getStyle(tdElm, 'background', 'backgroundImage').replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1");; - var id = tinyMCE.getAttrib(tdElm, 'id'); - var lang = tinyMCE.getAttrib(tdElm, 'lang'); - var dir = tinyMCE.getAttrib(tdElm, 'dir'); - var scope = tinyMCE.getAttrib(tdElm, 'scope'); - - // Setup form - addClassesToList('class', 'table_cell_styles'); - formObj.bordercolor.value = bordercolor; - formObj.bgcolor.value = bgcolor; - formObj.backgroundimage.value = backgroundimage; - formObj.width.value = width; - formObj.height.value = height; - formObj.id.value = id; - formObj.lang.value = lang; - formObj.style.value = tinyMCE.serializeStyle(st); - selectByValue(formObj, 'align', align); - selectByValue(formObj, 'valign', valign); - selectByValue(formObj, 'class', className); - selectByValue(formObj, 'celltype', celltype); - selectByValue(formObj, 'dir', dir); - selectByValue(formObj, 'scope', scope); - - // Resize some elements - if (isVisible('backgroundimagebrowser')) - document.getElementById('backgroundimage').style.width = '180px'; - - updateColor('bordercolor_pick', 'bordercolor'); - updateColor('bgcolor_pick', 'bgcolor'); -} - -function updateAction() { - tinyMCEPopup.restoreSelection(); - - var inst = tinyMCE.selectedInstance; - var tdElm = tinyMCE.getParentElement(inst.getFocusElement(), "td,th"); - var trElm = tinyMCE.getParentElement(inst.getFocusElement(), "tr"); - var tableElm = tinyMCE.getParentElement(inst.getFocusElement(), "table"); - var formObj = document.forms[0]; - - inst.execCommand('mceBeginUndoLevel'); - - switch (getSelectValue(formObj, 'action')) { - case "cell": - var celltype = getSelectValue(formObj, 'celltype'); - var scope = getSelectValue(formObj, 'scope'); - - if (tinyMCE.getParam("accessibility_warnings")) { - if (celltype == "th" && scope == "") - var answer = confirm(tinyMCE.getLang('lang_table_missing_scope', '', true)); - else - var answer = true; - - if (!answer) - return; - } - - updateCell(tdElm); - break; - - case "row": - var cell = trElm.firstChild; - - if (cell.nodeName != "TD" && cell.nodeName != "TH") - cell = nextCell(cell); - - do { - cell = updateCell(cell, true); - } while ((cell = nextCell(cell)) != null); - - break; - - case "all": - var rows = tableElm.getElementsByTagName("tr"); - - for (var i=0; i colLimit) { - alert(tinyMCE.getLang('lang_table_col_limit', '', true, {cols : colLimit})); - return false; - } else if (rowLimit && rows > rowLimit) { - alert(tinyMCE.getLang('lang_table_row_limit', '', true, {rows : rowLimit})); - return false; - } else if (cellLimit && cols * rows > cellLimit) { - alert(tinyMCE.getLang('lang_table_cell_limit', '', true, {cells : cellLimit})); - return false; - } - - // Update table - if (action == "update") { - inst.execCommand('mceBeginUndoLevel'); - - tinyMCE.setAttrib(elm, 'cellPadding', cellpadding, true); - tinyMCE.setAttrib(elm, 'cellSpacing', cellspacing, true); - tinyMCE.setAttrib(elm, 'border', border, true); - tinyMCE.setAttrib(elm, 'align', align); - tinyMCE.setAttrib(elm, 'class', className); - tinyMCE.setAttrib(elm, 'style', style); - tinyMCE.setAttrib(elm, 'id', id); - tinyMCE.setAttrib(elm, 'summary', summary); - tinyMCE.setAttrib(elm, 'dir', dir); - tinyMCE.setAttrib(elm, 'lang', lang); - - capEl = elm.getElementsByTagName('caption')[0]; - - if (capEl && !caption) - capEl.parentNode.removeChild(capEl); - - if (!capEl && caption) { - capEl = elm.ownerDocument.createElement('caption'); - capEl.innerHTML = ' '; - elm.insertBefore(capEl, elm.firstChild); - } - - // Not inline styles - if (!tinyMCE.getParam("inline_styles")) - tinyMCE.setAttrib(elm, 'width', width, true); - - // Remove these since they are not valid XHTML - tinyMCE.setAttrib(elm, 'borderColor', ''); - tinyMCE.setAttrib(elm, 'bgColor', ''); - tinyMCE.setAttrib(elm, 'background', ''); - tinyMCE.setAttrib(elm, 'height', ''); - - if (background != '') - elm.style.backgroundImage = "url('" + background + "')"; - else - elm.style.backgroundImage = ''; - - if (tinyMCE.getParam("inline_styles")) - elm.style.borderWidth = border + "px"; - - if (tinyMCE.getParam("inline_styles")) { - if (width != '') - elm.style.width = getCSSSize(width); - } - - if (bordercolor != "") { - elm.style.borderColor = bordercolor; - elm.style.borderStyle = elm.style.borderStyle == "" ? "solid" : elm.style.borderStyle; - elm.style.borderWidth = border == "" ? "1px" : border; - } else - elm.style.borderColor = ''; - - elm.style.backgroundColor = bgcolor; - elm.style.height = getCSSSize(height); - - tinyMCE.handleVisualAid(tinyMCE.tableElm, false, inst.visualAid, inst); - - // Fix for stange MSIE align bug - tinyMCE.tableElm.outerHTML = tinyMCE.tableElm.outerHTML; - - tinyMCE.handleVisualAid(inst.getBody(), true, inst.visualAid, inst); - tinyMCE.triggerNodeChange(); - inst.execCommand('mceEndUndoLevel'); - - // Repaint if dimensions changed - if (formObj.width.value != orgTableWidth || formObj.height.value != orgTableHeight) - inst.repaint(); - - tinyMCEPopup.close(); - return true; - } - - // Create new table - html += '/g, '>'); - - return ' ' + attrib + '="' + value + '"'; -} - -function init() { - tinyMCEPopup.resizeToInnerSize(); - - document.getElementById('backgroundimagebrowsercontainer').innerHTML = getBrowserHTML('backgroundimagebrowser','backgroundimage','image','table'); - document.getElementById('backgroundimagebrowsercontainer').innerHTML = getBrowserHTML('backgroundimagebrowser','backgroundimage','image','table'); - document.getElementById('bordercolor_pickcontainer').innerHTML = getColorPickerHTML('bordercolor_pick','bordercolor'); - document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor'); - - var cols = 2, rows = 2, border = tinyMCE.getParam('table_default_border', '0'), cellpadding = tinyMCE.getParam('table_default_cellpadding', ''), cellspacing = tinyMCE.getParam('table_default_cellspacing', ''); - var align = "", width = "", height = "", bordercolor = "", bgcolor = "", className = ""; - var id = "", summary = "", style = "", dir = "", lang = "", background = "", bgcolor = "", bordercolor = ""; - var inst = tinyMCE.selectedInstance; - var formObj = document.forms[0]; - var elm = tinyMCE.getParentElement(inst.getFocusElement(), "table"); - - tinyMCE.tableElm = elm; - action = tinyMCE.getWindowArg('action'); - if (action == null) - action = tinyMCE.tableElm ? "update" : "insert"; - - if (tinyMCE.tableElm && action != "insert") { - var rowsAr = tinyMCE.tableElm.rows; - var cols = 0; - for (var i=0; i cols) - cols = rowsAr[i].cells.length; - - cols = cols; - rows = rowsAr.length; - - st = tinyMCE.parseStyle(tinyMCE.getAttrib(tinyMCE.tableElm, "style")); - border = trimSize(getStyle(elm, 'border', 'borderWidth')); - cellpadding = tinyMCE.getAttrib(tinyMCE.tableElm, 'cellpadding', ""); - cellspacing = tinyMCE.getAttrib(tinyMCE.tableElm, 'cellspacing', ""); - width = trimSize(getStyle(elm, 'width', 'width')); - height = trimSize(getStyle(elm, 'height', 'height')); - bordercolor = convertRGBToHex(getStyle(elm, 'bordercolor', 'borderLeftColor')); - bgcolor = convertRGBToHex(getStyle(elm, 'bgcolor', 'backgroundColor')); - align = tinyMCE.getAttrib(tinyMCE.tableElm, 'align', align); - className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(tinyMCE.tableElm, 'class'), false); - id = tinyMCE.getAttrib(tinyMCE.tableElm, 'id'); - summary = tinyMCE.getAttrib(tinyMCE.tableElm, 'summary'); - style = tinyMCE.serializeStyle(st); - dir = tinyMCE.getAttrib(tinyMCE.tableElm, 'dir'); - lang = tinyMCE.getAttrib(tinyMCE.tableElm, 'lang'); - background = getStyle(elm, 'background', 'backgroundImage').replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"); - formObj.caption.checked = tinyMCE.tableElm.getElementsByTagName('caption').length > 0; - - orgTableWidth = width; - orgTableHeight = height; - - action = "update"; - } - - addClassesToList('class', "table_styles"); - - // Update form - selectByValue(formObj, 'align', align); - selectByValue(formObj, 'class', className); - formObj.cols.value = cols; - formObj.rows.value = rows; - formObj.border.value = border; - formObj.cellpadding.value = cellpadding; - formObj.cellspacing.value = cellspacing; - formObj.width.value = width; - formObj.height.value = height; - formObj.bordercolor.value = bordercolor; - formObj.bgcolor.value = bgcolor; - formObj.id.value = id; - formObj.summary.value = summary; - formObj.style.value = style; - formObj.dir.value = dir; - formObj.lang.value = lang; - formObj.backgroundimage.value = background; - formObj.insert.value = tinyMCE.getLang('lang_' + action, 'Insert', true); - - updateColor('bordercolor_pick', 'bordercolor'); - updateColor('bgcolor_pick', 'bgcolor'); - - // Resize some elements - if (isVisible('backgroundimagebrowser')) - document.getElementById('backgroundimage').style.width = '180px'; - - // Disable some fields in update mode - if (action == "update") { - formObj.cols.disabled = true; - formObj.rows.disabled = true; - } -} - -function changedSize() { - var formObj = document.forms[0]; - var st = tinyMCE.parseStyle(formObj.style.value); - - var width = formObj.width.value; - if (width != "") - st['width'] = tinyMCE.getParam("inline_styles") ? getCSSSize(width) : ""; - else - st['width'] = ""; - - var height = formObj.height.value; - if (height != "") - st['height'] = getCSSSize(height); - else - st['height'] = ""; - - formObj.style.value = tinyMCE.serializeStyle(st); -} - -function changedBackgroundImage() { - var formObj = document.forms[0]; - var st = tinyMCE.parseStyle(formObj.style.value); - - st['background-image'] = "url('" + formObj.backgroundimage.value + "')"; - - formObj.style.value = tinyMCE.serializeStyle(st); -} - -function changedBorder() { - var formObj = document.forms[0]; - var st = tinyMCE.parseStyle(formObj.style.value); - - // Update border width if the element has a color - if (formObj.border.value != "" && formObj.bordercolor.value != "") - st['border-width'] = formObj.border.value + "px"; - - formObj.style.value = tinyMCE.serializeStyle(st); -} - -function changedColor() { - var formObj = document.forms[0]; - var st = tinyMCE.parseStyle(formObj.style.value); - - st['background-color'] = formObj.bgcolor.value; - - if (formObj.bordercolor.value != "") { - st['border-color'] = formObj.bordercolor.value; - - // Add border-width if it's missing - if (!st['border-width']) - st['border-width'] = formObj.border.value == "" ? "1px" : formObj.border.value + "px"; - } - - formObj.style.value = tinyMCE.serializeStyle(st); -} - -function changedStyle() { - var formObj = document.forms[0]; - var st = tinyMCE.parseStyle(formObj.style.value); - - if (st['background-image']) - formObj.backgroundimage.value = st['background-image'].replace(new RegExp("url\\('?([^']*)'?\\)", 'gi'), "$1"); - else - formObj.backgroundimage.value = ''; - - if (st['width']) - formObj.width.value = trimSize(st['width']); - - if (st['height']) - formObj.height.value = trimSize(st['height']); - - if (st['background-color']) { - formObj.bgcolor.value = st['background-color']; - updateColor('bgcolor_pick','bgcolor'); - } - - if (st['border-color']) { - formObj.bordercolor.value = st['border-color']; - updateColor('bordercolor_pick','bordercolor'); - } -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/langs/en.js --- a/includes/clientside/tinymce/plugins/table/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('table',{ -general_tab : 'General', -advanced_tab : 'Advanced', -general_props : 'General properties', -advanced_props : 'Advanced properties', -desc : 'Inserts a new table', -row_before_desc : 'Insert row before', -row_after_desc : 'Insert row after', -delete_row_desc : 'Delete row', -col_before_desc : 'Insert column before', -col_after_desc : 'Insert column after', -delete_col_desc : 'Remove column', -rowtype : 'Row in table part', -title : 'Insert/Modify table', -width : 'Width', -height : 'Height', -cols : 'Columns', -rows : 'Rows', -cellspacing : 'Cellspacing', -cellpadding : 'Cellpadding', -border : 'Border', -align : 'Alignment', -align_default : 'Default', -align_left : 'Left', -align_right : 'Right', -align_middle : 'Center', -row_title : 'Table row properties', -cell_title : 'Table cell properties', -cell_type : 'Cell type', -row_desc : 'Table row properties', -cell_desc : 'Table cell properties', -valign : 'Vertical alignment', -align_top : 'Top', -align_bottom : 'Bottom', -props_desc : 'Table properties', -bordercolor : 'Border color', -bgcolor : 'Background color', -merge_cells_title : 'Merge table cells', -split_cells_desc : 'Split table cells', -merge_cells_desc : 'Merge table cells', -cut_row_desc : 'Cut table row', -copy_row_desc : 'Copy table row', -paste_row_before_desc : 'Paste table row before', -paste_row_after_desc : 'Paste table row after', -id : 'Id', -style: 'Style', -langdir : 'Language direction', -langcode : 'Language code', -mime : 'Target MIME type', -ltr : 'Left to right', -rtl : 'Right to left', -bgimage : 'Background image', -summary : 'Summary', -td : "Data", -th : "Header", -cell_cell : 'Update current cell', -cell_row : 'Update all cells in row', -cell_all : 'Update all cells in table', -row_row : 'Update current row', -row_odd : 'Update odd rows in table', -row_even : 'Update even rows in table', -row_all : 'Update all rows in table', -thead : 'Table Head', -tbody : 'Table Body', -tfoot : 'Table Foot', -del : 'Delete table', -scope : 'Scope', -row : 'Row', -col : 'Col', -rowgroup : 'Row Group', -colgroup : 'Col Group', -col_limit : 'You\'ve exceeded the maximum number of columns of {$cols}.', -row_limit : 'You\'ve exceeded the maximum number of rows of {$rows}.', -cell_limit : 'You\'ve exceeded the maximum number of cells of {$cells}.', -missing_scope: 'Are you sure you want to continue without specifying a scope for this table header cell. Without it, it may be difficult for some users with disabilities to understand the content or data displayed of the table.', -caption : 'Table caption' -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/langs/en_dlg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/table/langs/en_dlg.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,74 @@ +tinyMCE.addI18n('en.table_dlg',{ +general_tab:"General", +advanced_tab:"Advanced", +general_props:"General properties", +advanced_props:"Advanced properties", +rowtype:"Row in table part", +title:"Insert/Modify table", +width:"Width", +height:"Height", +cols:"Cols", +rows:"Rows", +cellspacing:"Cellspacing", +cellpadding:"Cellpadding", +border:"Border", +align:"Alignment", +align_default:"Default", +align_left:"Left", +align_right:"Right", +align_middle:"Center", +row_title:"Table row properties", +cell_title:"Table cell properties", +cell_type:"Cell type", +valign:"Vertical alignment", +align_top:"Top", +align_bottom:"Bottom", +bordercolor:"Border color", +bgcolor:"Background color", +merge_cells_title:"Merge table cells", +id:"Id", +style:"Style", +langdir:"Language direction", +langcode:"Language code", +mime:"Target MIME type", +ltr:"Left to right", +rtl:"Right to left", +bgimage:"Background image", +summary:"Summary", +td:"Data", +th:"Header", +cell_cell:"Update current cell", +cell_row:"Update all cells in row", +cell_all:"Update all cells in table", +row_row:"Update current row", +row_odd:"Update odd rows in table", +row_even:"Update even rows in table", +row_all:"Update all rows in table", +thead:"Table Head", +tbody:"Table Body", +tfoot:"Table Foot", +scope:"Scope", +rowgroup:"Row Group", +colgroup:"Col Group", +col_limit:"You've exceeded the maximum number of columns of {$cols}.", +row_limit:"You've exceeded the maximum number of rows of {$rows}.", +cell_limit:"You've exceeded the maximum number of cells of {$cells}.", +missing_scope:"Are you sure you want to continue without specifying a scope for this table header cell. Without it, it may be difficult for some users with disabilities to understand the content or data displayed of the table.", +caption:"Table caption", +frame:"Frame", +frame_none:"none", +frame_groups:"groups", +frame_rows:"rows", +frame_cols:"cols", +frame_all:"all", +rules:"Rules", +rules_void:"void", +rules_above:"above", +rules_below:"below", +rules_hsides:"hsides", +rules_lhs:"lhs", +rules_rhs:"rhs", +rules_vsides:"vsides", +rules_box:"box", +rules_border:"border" +}); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/merge_cells.htm --- a/includes/clientside/tinymce/plugins/table/merge_cells.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/table/merge_cells.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,24 +1,24 @@ + - {$lang_table_merge_cells_title} - - - - + {#table_dlg.merge_cells_title} + + + + - +
- {$lang_table_merge_cells_title} + {#table_dlg.merge_cells_title}
- + - - +
{$lang_table_cols}:{#table_dlg.cols}:
{$lang_table_rows}:{#table_dlg.rows}:
@@ -26,11 +26,11 @@
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/readme.txt --- a/includes/clientside/tinymce/plugins/table/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/row.htm --- a/includes/clientside/tinymce/plugins/table/row.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/table/row.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,74 +1,75 @@ + - {$lang_table_row_title} - - - - + {#table_dlg.row_title} + + + + - +
- {$lang_table_general_props} + {#table_dlg.general_props} - + - + - + - + - +
@@ -77,39 +78,39 @@
- {$lang_table_advanced_props} + {#table_dlg.advanced_props} - + - + - + - + - + tag. + * @param object Form field + */ + +function set_focus(item) +{ + var hint_id = ( item.type == 'radio' ) ? 'hint_' + item.name + '_' + item.value : 'hint_' + item.name; + if ( document.getElementById(hint_id) ) + { + var el = document.getElementById(hint_id); + el.style.zIndex = String(getHighestZ() + 2); + domObjChangeOpac(0, el); + el.style.display = 'block'; + domOpacity(el, 0, 100, 400); + } + item = getParentTR(item); + if ( item.tagName == 'TR' ) + { + item.style.backgroundColor = '#FFFFE0'; + } +} + +/** + * Clears the background of the next-up tag. + * @param object Form field + */ + +function clear_focus(item) +{ + var hint_id = ( item.type == 'radio' ) ? 'hint_' + item.name + '_' + item.value : 'hint_' + item.name; + if ( document.getElementById(hint_id) ) + { + var el = document.getElementById(hint_id); + // el.style.display = 'none'; + domOpacity(el, 100, 0, 200); + setTimeout(function() + { + el.style.display = 'none'; + }, 250); + } + item = getParentTR(item); + if ( item.tagName == 'TR' ) + { + if ( IE ) + { + item.style.backgroundColor = 'transparent'; + } + else + { + item.style.backgroundColor = null; + } + } +} + +function getParentTR(item) +{ + var tagName = item.tagName; + while ( tagName != 'TR' && tagName != null ) + { + item = item.parentNode; + tagName = item.tagName; + } + if ( tagName == 'TR' && item.className != 'nohighlight' ) + { + return item; + } + return null; +} + +function init_hint(input, hint) +{ + hint.className = 'fieldtip_js'; + setTimeout(function() + { + if ( input.type == 'radio' ) + { + var tr = getParentTR(input).parentNode.parentNode.parentNode; + var span_width = $(tr).Width() - 24; + } + else + { + var span_width = $(input).Width() - 24; + } + var span_top = $(input).Top() + $(input).Height(); + var span_left = $(input).Left(); + hint.style.top = span_top + 'px'; + hint.style.left = span_left + 'px'; + hint.style.width = span_width + 'px'; + hint.style.display = 'none'; + }, 100); +} + +var set_inputs_to_highlight = function() +{ + var inputs = document.getElementsByTagName('input'); + for ( var i = 0; i < inputs.length; i++ ) + { + // Highlighting + var tr = getParentTR(inputs[i]); + if ( tr ) + { + inputs[i].onfocus = function() + { + set_focus(this); + } + inputs[i].onblur = function() + { + clear_focus(this); + } + } + // Hints + var hint_id = ( inputs[i].type == 'radio' ) ? 'hint_' + inputs[i].name + '_' + inputs[i].value : 'hint_' + inputs[i].name; + if ( document.getElementById(hint_id) ) + { + var el = document.getElementById(hint_id); + if ( el.tagName == 'SPAN' ) + { + init_hint(inputs[i], el); + } + } + } +} + +addOnloadHook(set_inputs_to_highlight); + +function install_set_ajax_loading() +{ + var base = document.getElementById('enano-body'); + var hider = document.createElement('div'); + hider.style.position = 'absolute'; + hider.style.backgroundColor = '#FFFFFF'; + hider.style.top = $(base).Top() + 'px'; + hider.style.left = $(base).Left() + 'px'; + hider.style.width = $(base).Width() + 'px'; + hider.style.height = $(base).Height() + 'px'; + hider.style.backgroundPosition = 'center center'; + hider.style.backgroundImage = 'url(../images/loading-big.gif)'; + hider.style.backgroundRepeat = 'no-repeat'; + hider.id = 'ajax_loader'; + domObjChangeOpac(0, hider); + var body = document.getElementsByTagName('body')[0]; + body.appendChild(hider); + opacity('ajax_loader', 0, 70, 750); +} + +function install_unset_ajax_loading() +{ + if ( document.getElementById('ajax_loader') ) + { + opacity('ajax_loader', 70, 0, 750); + setTimeout(function() + { + var body = document.getElementsByTagName('body')[0]; + body.removeChild(document.getElementById('ajax_loader')); + }, 1000); + } +} diff -r d823e49e2e4e -r c433348f3628 install/includes/libenanoinstall.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/libenanoinstall.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,119 @@ +' . "\n"; +} + +function close_install_table() +{ + echo '
@@ -121,7 +122,7 @@ - +
@@ -139,19 +140,19 @@
-
+
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/table/table.htm --- a/includes/clientside/tinymce/plugins/table/table.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/table/table.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,68 +1,68 @@ + - {$lang_table_title} - - - - - + {#table_dlg.title} + + + + + - +
- {$lang_table_general_props} - + {#table_dlg.general_props}
- + - + - + - + - + - + - + - + - + - - + +
@@ -70,44 +70,33 @@
- {$lang_table_advanced_props} + {#table_dlg.advanced_props} - + - + - + - - - - - - + - + ' . "\n"; - ob_flush(); -} - -function echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack) -{ - global $neutral_color; - - $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A'; - echo '' . "\n"; - ob_flush(); - close_install_table(); - $post_data = ''; - $mysql_error = mysql_error(); - foreach ( $_POST as $key => $value ) - { - // FIXME: These should really also be sanitized for double quotes - $value = htmlspecialchars($value); - $key = htmlspecialchars($key); - $post_data .= " \n"; - } - echo ' - ' . $post_data . ' - -

Enano installation failed.

-

' . $failure_explanation . '

- ' . ( !empty($mysql_error) ? "

The error returned from MySQL was: $mysql_error

" : '' ) . ' -

When you have corrected the error, click the button below to attempt to continue the installation.

-

- '; - global $template, $template_bak; - if ( is_object($template_bak) ) - $template_bak->footer(); - else - $template->footer(); - exit; -} - -// -// INSTALLER STAGES -// - -function stg_mysql_connect($act_get = false) -{ - global $db; - $db = new mysql(); - - static $conn = false; - if ( $act_get ) - return $conn; - - $db_user =& $_POST['db_user']; - $db_pass =& $_POST['db_pass']; - $db_name =& $_POST['db_name']; - - if ( !preg_match('/^[a-z0-9_-]+$/', $db_name) ) - { - $db_name = htmlspecialchars($db_name); - die("

SECURITY: malformed database name \"$db_name\"

"); - } - - // First, try to connect using the normal credentials - $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); - if ( !$conn ) - { - // Connection failed. Do we have the root username and password? - if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) - { - $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); - if ( !$conn_root ) - { - // Couldn't connect using either set of credentials. Bail out. - return false; - } - unset($db_user, $db_pass); - $db_user = mysql_real_escape_string($_POST['db_user']); - $db_pass = mysql_real_escape_string($_POST['db_pass']); - // Create the user account - $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'localhost' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); - if ( !$q ) - { - return false; - } - // Revoke privileges from test, we don't need them - $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'localhost';", $conn_root); - if ( !$q ) - { - return false; - } - if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) - { - // If not connecting to a server running on localhost, allow from any host - // this is safer than trying to detect the hostname of the webserver, but less secure - $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'%' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root); - if ( !$q ) - { - return false; - } - // Revoke privileges from test, we don't need them - $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'%';", $conn_root); - if ( !$q ) - { - return false; - } - } - mysql_close($conn_root); - $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); - if ( !$conn ) - { - // This should honestly never happen. - return false; - } - } - } - $q = @mysql_query("USE `$db_name`;", $conn); - if ( !$q ) - { - // access denied to the database; try the whole root schenanegan again - if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) - { - $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']); - if ( !$conn_root ) - { - // Couldn't connect as root; bail out - return false; - } - // create the database, if it doesn't exist - $q = @mysql_query("CREATE DATABASE IF NOT EXISTS `$db_name`;", $conn_root); - if ( !$q ) - { - // this really should never fail, so don't give any tolerance to it - return false; - } - unset($db_user, $db_pass); - $db_user = mysql_real_escape_string($_POST['db_user']); - $db_pass = mysql_real_escape_string($_POST['db_pass']); - // we're in with root rights; grant access to the database - $q = @mysql_query("GRANT ALL PRIVILEGES ON `$db_name`.* TO '{$db_user}'@'localhost';", $conn_root); - if ( !$q ) - { - return false; - } - if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' ) - { - $q = @mysql_query("GRANT ALL PRIVILEGES ON `$db_name`.* TO '{$db_user}'@'%';", $conn_root); - if ( !$q ) - { - return false; - } - } - mysql_close($conn_root); - // grant tables have hopefully been flushed, kill and reconnect our regular user connection - mysql_close($conn); - $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']); - if ( !$conn ) - { - return false; - } - } - else - { - return false; - } - // try again - $q = @mysql_query("USE `$db_name`;", $conn); - if ( !$q ) - { - // really failed this time; bail out - return false; - } - } - // initialize DBAL - $db->connect(true, $_POST['db_host'], $db_user, $db_pass, $db_name); - // connected and database exists - return true; -} - -function stg_pgsql_connect($act_get = false) -{ - global $db; - $db = new postgresql(); - - static $conn = false; - if ( $act_get ) - return $conn; - - $db_user =& $_POST['db_user']; - $db_pass =& $_POST['db_pass']; - $db_name =& $_POST['db_name']; - - if ( !preg_match('/^[a-z0-9_-]+$/', $db_name) ) - { - $db_name = htmlspecialchars($db_name); - die("

SECURITY: malformed database name \"$db_name\"

"); - } - - // First, try to connect using the normal credentials - $conn = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_user']} password={$_POST['db_pass']}"); - if ( !$conn ) - { - // Connection failed. Do we have the root username and password? - if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) - { - $conn_root = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_root_user']} password={$_POST['db_root_pass']}"); - if ( !$conn_root ) - { - // Couldn't connect using either set of credentials. Bail out. - return false; - } - unset($db_user, $db_pass); - $db_user = pg_escape_string($_POST['db_user']); - $db_pass = pg_escape_string($_POST['db_pass']); - // Create the user account - $q = @pg_query("CREATE ROLE '$db_user' WITH NOSUPERUSER UNENCRYPTED PASSWORD '$db_pass';", $conn_root); - if ( !$q ) - { - return false; - } - pg_close($conn_root); - $conn = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_user']} password={$_POST['db_pass']}"); - if ( !$conn ) - { - // This should honestly never happen. - return false; - } - } - } - if ( !$q ) - { - // access denied to the database; try the whole root schenanegan again - if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) ) - { - $conn_root = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_root_user']} password={$_POST['db_root_pass']}"); - if ( !$conn_root ) - { - // Couldn't connect as root; bail out - return false; - } - unset($db_user, $db_pass); - $db_user = pg_escape_string($_POST['db_user']); - $db_pass = pg_escape_string($_POST['db_pass']); - // create the database, if it doesn't exist - $q = @mysql_query("CREATE DATABASE $db_name WITH OWNER $db_user;", $conn_root); - if ( !$q ) - { - // this really should never fail, so don't give any tolerance to it - return false; - } - // Setting the owner to $db_user should grant all the rights we need - pg_close($conn_root); - // grant tables have hopefully been flushed, kill and reconnect our regular user connection - pg_close($conn); - $conn = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_user']} password={$_POST['db_pass']}"); - if ( !$conn ) - { - return false; - } - } - else - { - return false; - } - // try again - $q = @mysql_query("USE `$db_name`;", $conn); - if ( !$q ) - { - // really failed this time; bail out - return false; - } - } - // initialize DBAL - $db->connect(true, $_POST['db_host'], $db_user, $db_pass, $db_name); - // connected and database exists - return true; -} - -function stg_drop_tables() -{ - global $db; - // Our list of tables included in Enano - $tables = Array( 'categories', 'comments', 'config', 'logs', 'page_text', 'session_keys', 'pages', 'users', 'users_extra', 'themes', 'buddies', 'banlist', 'files', 'privmsgs', 'sidebar', 'hits', 'search_index', 'groups', 'group_members', 'acl', 'tags', 'page_groups', 'page_group_members' ); - - // Drop each table individually; if it fails, it probably means we're trying to drop a - // table that didn't exist in the Enano version we're deleting the database for. - foreach ( $tables as $table ) - { - // Remember that table_prefix is sanitized. - $table = "{$_POST['table_prefix']}$table"; - $db->sql_query("DROP TABLE $table;", $conn); - } - return true; -} - -function stg_decrypt_admin_pass($act_get = false) -{ - static $decrypted_pass = false; - if ( $act_get ) - return $decrypted_pass; - - $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); - - if ( !empty($_POST['crypt_data']) ) - { - require('config.new.php'); - if ( !isset($cryptkey) ) - { - return false; - } - define('_INSTRESUME_AES_KEYBACKUP', $key); - $key = hexdecode($cryptkey); - - $decrypted_pass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX); - - } - else - { - $decrypted_pass = $_POST['admin_pass']; - } - if ( empty($decrypted_pass) ) - return false; - return true; -} - -function stg_generate_aes_key($act_get = false) -{ - static $key = false; - if ( $act_get ) - return $key; - - $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); - $key = $aes->gen_readymade_key(); - return true; -} - -function stg_parse_schema($act_get = false) -{ - static $schema; - if ( $act_get ) - return $schema; - - global $db; - - $admin_pass = stg_decrypt_admin_pass(true); - $key = stg_generate_aes_key(true); - $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); - $key = $aes->hextostring($key); - $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); - - $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0'; - - $admin_user = $_POST['admin_user']; - $admin_user = str_replace('_', ' ', $admin_user); - $admin_user = $db->escape($admin_user); - - $schema = file_get_contents('schema.sql'); - $schema = str_replace('{{SITE_NAME}}', $db->escape($_POST['sitename'] ), $schema); - $schema = str_replace('{{SITE_DESC}}', $db->escape($_POST['sitedesc'] ), $schema); - $schema = str_replace('{{COPYRIGHT}}', $db->escape($_POST['copyright'] ), $schema); - $schema = str_replace('{{ADMIN_USER}}', $admin_user , $schema); - $schema = str_replace('{{ADMIN_PASS}}', $db->escape($admin_pass ), $schema); - $schema = str_replace('{{ADMIN_EMAIL}}', $db->escape($_POST['admin_email']), $schema); - $schema = str_replace('{{ENABLE_CACHE}}', $db->escape($cacheonoff ), $schema); - $schema = str_replace('{{REAL_NAME}}', '', $schema); - $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'], $schema); - $schema = str_replace('{{VERSION}}', ENANO_VERSION, $schema); - $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'], $schema); - // Not anymore!! :-D - // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION, $schema); - - if(isset($_POST['wiki_mode'])) - { - $schema = str_replace('{{WIKI_MODE}}', '1', $schema); - } - else - { - $schema = str_replace('{{WIKI_MODE}}', '0', $schema); - } - - // Build an array of queries - $schema = explode("\n", $schema); - - foreach ( $schema as $i => $sql ) - { - $query =& $schema[$i]; - $t = trim($query); - if ( empty($t) || preg_match('/^(\#|--)/i', $t) ) - { - unset($schema[$i]); - unset($query); - } - } - - $schema = array_values($schema); - $schema = implode("\n", $schema); - $schema = explode(";\n", $schema); - - foreach ( $schema as $i => $sql ) - { - $query =& $schema[$i]; - if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' ) - { - $query .= ';'; - } - } - - return true; -} - -function stg_install($_unused, $already_run) -{ - // This one's pretty easy. - $conn = stg_mysql_connect(true); - if ( !is_resource($conn) ) - return false; - $schema = stg_parse_schema(true); - if ( !is_array($schema) ) - return false; - - // If we're resuming installation, the encryption key was regenerated. - // This means we'll have to update the encrypted password in the database. - if ( $already_run ) - { - $admin_pass = stg_decrypt_admin_pass(true); - $key = stg_generate_aes_key(true); - $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); - $key = $aes->hextostring($key); - $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX); - $admin_user = mysql_real_escape_string($_POST['admin_user']); - $admin_user = str_replace('_', ' ', $admin_user); - - $q = @mysql_query("UPDATE {$_POST['table_prefix']}users SET password='$admin_pass' WHERE username='$admin_user';"); - if ( !$q ) - { - echo '

MySQL return: ' . mysql_error() . '

'; - return false; - } - - return true; - } - - // OK, do the loop, baby!!! - foreach($schema as $q) - { - $r = mysql_query($q, $conn); - if ( !$r ) - { - echo '

MySQL return: ' . mysql_error() . '

'; - return false; - } - } - - return true; -} - -function stg_write_config() -{ - $privkey = stg_generate_aes_key(true); - - switch($_POST['urlscheme']) - { - case "ugly": - default: - $cp = scriptPath.'/index.php?title='; - break; - case "short": - $cp = scriptPath.'/index.php/'; - break; - case "tiny": - $cp = scriptPath.'/'; - break; - } - - if ( $_POST['urlscheme'] == 'tiny' ) - { - $contents = '# Begin Enano rules -RewriteEngine on -RewriteCond %{REQUEST_FILENAME} !-d -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA] -RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L] -# End Enano rules -'; - if ( file_exists('./.htaccess') ) - $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+'); - else - $ht = fopen(ENANO_ROOT.'/.htaccess.new', 'w'); - if ( !$ht ) - return false; - fwrite($ht, $contents); - fclose($ht); - } - - $config_file = ''; - - $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w'); - if ( !$cf_handle ) - return false; - fwrite($cf_handle, $config_file); - - fclose($cf_handle); - - return true; -} - -function _stg_rename_config_revert() -{ - if ( file_exists('./config.php') ) - { - @rename('./config.php', './config.new.php'); - } - - $handle = @fopen('./config.php.new', 'w'); - if ( !$handle ) - return false; - $contents = ''; - fwrite($handle, $contents); - fclose($handle); - return true; -} - -function stg_build_index() -{ - global $db, $session, $paths, $template, $plugins; // Common objects; - if ( $paths->rebuild_search_index() ) - return true; - return false; -} - -function stg_rename_config() -{ - if ( !@rename('./config.new.php', './config.php') ) - { - echo '

Can\'t rename config.php

'; - _stg_rename_config_revert(); - return false; - } - - if ( $_POST['urlscheme'] == 'tiny' && !file_exists('./.htaccess') ) - { - if ( !@rename('./.htaccess.new', './.htaccess') ) - { - echo '

Can\'t rename .htaccess

'; - _stg_rename_config_revert(); - return false; - } - } - return true; -} - -function stg_start_api_success() -{ - return true; -} - -function stg_start_api_failure() -{ - return false; -} - -function stg_init_logs() -{ - global $db, $session, $paths, $template, $plugins; // Common objects - - $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . date('d M Y h:i a') . '\', \'' . mysql_real_escape_string($_POST['admin_user']) . '\', \'' . mysql_real_escape_string(ENANO_VERSION) . '\', \'' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '\');'); - if ( !$q ) - { - echo '

MySQL return: ' . mysql_error() . '

'; - return false; - } - - if ( !$session->get_permissions('clear_logs') ) - { - echo '

$session: denied clear_logs

'; - return false; - } - - PageUtils::flushlogs('Main_Page', 'Article'); - - return true; -} - -//die('Key size: ' . AES_BITS . '
Block size: ' . AES_BLOCKSIZE); - -if(!function_exists('wikiFormat')) -{ - function wikiFormat($message, $filter_links = true) - { - $wiki = & Text_Wiki::singleton('Mediawiki'); - $wiki->setRenderConf('Xhtml', 'code', 'css_filename', 'codefilename'); - $wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath); - $result = $wiki->transform($message, 'Xhtml'); - - // HTML fixes - $result = preg_replace('#([\s]*?)<\/tr>#is', '', $result); - $result = preg_replace('#

([\s]*?)<\/p>#is', '', $result); - $result = preg_replace('#
([\s]*?)

"; - } elseif(!$val && $warn) { - if($cv) $color='FFFFCC'; else $color='FFFFAA'; - echo ""; - $warned = true; - } else { - if($cv) $color='FFCCCC'; else $color='FFAAAA'; - echo ""; - $failed = true; - } -} -function is_apache() { $r = strstr($_SERVER['SERVER_SOFTWARE'], 'Apache') ? true : false; return $r; } - -function show_license($fb = false) -{ - ?> -
-

GNU General Public License

- -

Declaration of license usage

-

Enano is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

-

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 (below) for more details.

-

By clicking the button below or otherwise continuing the installation, you indicate your acceptance of this license agreement.

- -

Human-readable version

-

Enano is distributed under certain licensing terms that we believe make it of the greatest possible use to the public. The license we distribute it under, the GNU General Public License, provides certain terms and conditions that, rather than limit your use of Enano, allow you to get the most out of it. If you would like to read the full text, it can be found below. Here is a human-readable version that we think is a little easier to understand.

- -
    -
  • You may to run Enano for any purpose.
  • -
  • You may study how Enano works and adapt it to your needs.
  • -
  • You may redistribute copies so you can help your neighbor.
  • -
  • You may improve Enano and release your improvements to the public, so that the whole community benefits.
  • -
- -

You may exercise the freedoms specified here provided that you comply with the express conditions of this license. The principal conditions are:

- -
    -
  • You must conspicuously and appropriately publish on each copy distributed an appropriate copyright notice and disclaimer of warranty and keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of Enano a copy of the GNU General Public License along with Enano. Any translation of the GNU General Public License must be accompanied by the GNU General Public License.
  • -
  • If you modify your copy or copies of Enano or any portion of it, or develop a program based upon it, you may distribute the resulting work provided you do so under the GNU General Public License. Any translation of the GNU General Public License must be accompanied by the GNU General Public License.
  • -
  • If you copy or distribute Enano, you must accompany it with the complete corresponding machine-readable source code or with a written offer, valid for at least three years, to furnish the complete corresponding machine-readable source code.
  • -
- -

Disclaimer: The above text is not a license. It is simply a handy reference for understanding the Legal Code (the full license) – it is a human-readable expression of some of its key terms. Think of it as the user-friendly interface to the Legal Code beneath. The above text itself has no legal value, and its contents do not appear in the actual license.
Text copied from the Creative Commons GPL Deed page

- -

Notice for prerelease versions

-

This version of Enano is designed only for testing and evaluation purposes. It is not yet completely stable, and should not be used on production websites. As with any Enano version, Dan Fuhry and the Enano team cannot be responsible for any damage, physical or otherwise, to any property as a result of the use of Enano. While security is a number one priority, sometimes things slip through.

- -

Lawyer-readable version

- - Because I could never find the Create a Page button in PHP-Nuke.

'; - echo '

' . str_replace('http://enanocms.org/', 'http://www.2robots.com/2003/10/15/web-portals-suck/', $template->fading_button) . '

'; - echo '

It\'s not a portal, my friends.

'; - } - ?> -
- This option allows you to control whether anything between the standard <?php and ?> tags will be treated as - PHP code by Enano. If this option is enabled, and members of the Administrators group use these tags, Enano will - execute that code when the page is loaded. There are obvious potential security implications here, which should - be carefully considered before enabling this option.

-

If you are the only administrator of this site, or if you have a high level of trust for those will be administering - the site with you, you should enable this to allow extreme customization of pages.

-

Leave this option off if you are at all concerned about security – if your account is compromised and PHP embedding - is enabled, an attacker can run arbitrary code on your server! Enabling this will also allow administrators to - embed Javascript and arbitrary HTML and CSS.

-

If you don\'t have experience coding in PHP, you can safely disable this option. You may change this at any time - using the ACL editor by selecting the Administrators group and This Entire Website under the scope selection.

'; - break; - case 'url_schemes': - $title = 'URL schemes'; - $content = '

The URL scheme allows you to decide how the URLs to your Enano pages will look.

-

The first option (Standard URLs) works on any web server. You should select it if your server doesn\'t run Apache, or - if you are at all unsure of your server\'s configuration. With this scheme, URLs at your site will look like - http://yoursite.com/path-to-enano/index.php/Main_Page.

-

The second option, Small URLs, will be selected by default if Enano detects Apache. Small URLs are more friendly towards - search engines, but they don\'t work on very many non-Apache servers, or if PHP is set up through CGI on your server. Many - free and low-cost web hosts will configure PHP through CGI in order to keep your user account as the owner of any files that - Enano generates. With this scheme, URLs at your site will look like http://yoursite.com/path-to-enano/index.php/Main_Page. -

-

The last option, Tiny URLs, is the most friendly URL scheme for search engines, because your URLs won\'t have any special characters - at all in them. However, this only works if your webhost has configured Apache with support for mod_rewrite. Most of the time if your - host supports this you will see a listing for it in their feature matrix. None of the popular Linux distributions (such as Ubuntu, - Debian, Red Hat Enterprise Linux™, Fedora, openSUSE™, or CentOS) come with mod_rewrite enabled, so if you run a - home-brew server, you should consult your distribution\'s documentation for enabling mod_rewrite before selecting this option. - With this scheme, URLs at your site will look like http://yoursite.com/path-to-enano/Main_Page.

-

'; - break; - default: - $title = 'Invalid topic'; - $content = 'Invalid help topic.'; - break; - } - echo << - - - Enano installation quick help • {$title} - - - - -

{$title}

- {$content} -

- Close window -

- - -EOF; - exit; - break; - default: - break; -} - -$template = new template_nodb(); -$template->load_theme('oxygen', 'bleu', false); - -$modestrings = Array( - 'welcome' => 'Welcome', - 'license' => 'License Agreement', - 'sysreqs' => 'Server requirements', - 'database' => 'Select database driver', - 'database_mysql'=> 'Database information', - 'database_pgsql'=> 'Database information', - 'website' => 'Website configuration', - 'login' => 'Administration login', - 'confirm' => 'Confirm installation', - 'install' => 'Database installation', - 'finish' => 'Installation complete', - '_hiddenstages' => '...', // all stages below this line are hidden - 'showlicense' => 'License Agreement' - ); - -$sideinfo = ''; -$vars = $template->extract_vars('elements.tpl'); -$p = $template->makeParserText($vars['sidebar_button']); -$hidden = false; -foreach ( $modestrings as $id => $str ) -{ - if ( $_GET['mode'] == $id ) - { - $flags = 'style="font-weight: bold; text-decoration: underline;"'; - $this_page = $str; - } - else - { - $flags = ''; - } - if ( $id == '_hiddenstages' ) - $hidden = true; - if ( !$hidden ) - { - $p->assign_vars(Array( - 'HREF' => '#', - 'FLAGS' => $flags . ' onclick="return false;"', - 'TEXT' => $str - )); - $sideinfo .= $p->run(); - } -} - -$template->init_vars(); - -if(isset($_GET['mode']) && $_GET['mode'] == 'css') -{ - header('Content-type: text/css'); - echo $template->get_css(); - exit; -} - -$template->header(); -if ( !isset($_GET['mode']) ) -{ - $_GET['mode'] = 'welcome'; -} -switch($_GET['mode']) -{ - default: - case 'welcome': - ?> -
- [ Enano CMS Project logo ] -

Welcome to Enano

-

Version 1.0.3 – stable
- also affectionately known as "coblynau" :)

- You are about to install a NIGHTLY BUILD of Enano.
Nightly builds are NOT upgradeable and may contain serious flaws, security problems, or extraneous debugging information. Installing this version of Enano on a production site is NOT recommended.
'; - } - ?> -
- - - - -

Welcome to the Enano installer.

-

Thank you for choosing Enano as your CMS. You've selected the finest in design, the strongest in security, and the latest in Web 2.0 toys. Trust us, you'll like it.

-

To get started, please read and accept the following license agreement. You've probably seen it before.

- -
- -
@@ -119,7 +108,50 @@ - + + + + + + + + + + + + + + + + '; - deltaHeight -= 23; - } - - template['html'] += '
+ +
+ +
+ +
@@ -131,7 +163,7 @@ - + ';for(i=0;i';if((i+1)%8==0)h+=''}h+='
@@ -148,11 +180,11 @@
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/template/blank.htm --- a/includes/clientside/tinymce/plugins/template/blank.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/template/blank.htm Fri Feb 22 12:51:53 2008 -0500 @@ -3,21 +3,10 @@ blank_page - + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/template/editor_plugin.js --- a/includes/clientside/tinymce/plugins/template/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/template/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('template');var TinyMCE_TemplatePlugin={getInfo:function(){return{longname:'Template plugin',author:'Moxiecode Systems AB',authorurl:'http://www.moxiecode.com',infourl:'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/template',version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion}},initInstance:function(inst){var cdate,mdate,content,x=0,key,value,rvals,ds=inst.getData('template');cdate=tinyMCE.getParam("template_cdate_classes",'').split(/\s+/);mdate=tinyMCE.getParam("template_mdate_classes",'').split(/\s+/);content=tinyMCE.getParam("template_selected_content_classes",'').split(/\s+/);for(x=0;x0?nodeArray[0]:null;nodeArray=[];if(ds.currentAction=="insert"){if(telm){tinyMCE.execCommand('mceBeginUndoLevel');ds.currentAction="insert-new";TinyMCE_TemplatePlugin._insertTemplate(editor_id,telm,value.title,value.tsrc,true);ds.currentAction=="insert";tinyMCE.execCommand('mceEndUndoLevel');tinyMCE.execInstanceCommand(editor_id,'mceCleanup',false)}else tinyMCE.execCommand('mceInsertContent',false,this._replaceValues(value.body))}else{nodeArray=TinyMCE_TemplatePlugin._collectTemplateElements(ds.currentTmplNode);current=[];newTmpl=[];tinyMCE.getNodeTree(telm,newTmpl);for(x=0;x','gi'),'');content=content.replace(new RegExp('
(\s| | )?(|\s)?
','gi'),'');content=content.replace(new RegExp('','gi'),'');break;case"insert_to_editor":content=content.replace(new RegExp('','gi'),'
');content=content.replace(new RegExp('','gi'),'
');break;case"get_from_editor_dom":nodes=tinyMCE.selectNodes(content,function(n){return tinyMCE.hasCSSClass(n,TinyMCE_TemplatePlugin.TMPL_ELEMENT)});TinyMCE_TemplatePlugin._applyFunctions(nodes,type);break;case"insert_to_editor_dom":nodes=tinyMCE.selectNodes(content,function(n){return tinyMCE.hasCSSClass(n,TinyMCE_TemplatePlugin.TMPL_ELEMENT)});TinyMCE_TemplatePlugin._applyFunctions(nodes,type);break}return content},_convertToNode:function(html){var elm=document.createElement('div');elm.innerHTML=html;return elm},_prepareTemplateContent:function(elms){var x,n,nodes=[];if(!elms)return{};if(!elms.length)elms=[elms];for(x=0;x';html+=elm.innerHTML;html+='';tinyMCE.execInstanceCommand(editor_id,'mceInsertContent',false,html)},functions:{blank:function(elm,editor_event){},cdate:function(elm,editor_event){var d,dsrc;if(editor_event!=TinyMCE_TemplatePlugin.TMPL_TEMPLATE_EVENT)return;d=new Date();dsrc=elm.innerHTML.match(new RegExp("","gi"));if(dsrc)d=new Date(RegExp.$1);elm.innerHTML=TinyMCE_TemplatePlugin._getDateTime(d,tinyMCE.getParam("template_cdate_format",tinyMCE.getLang("lang_template_def_date_format")));elm.innerHTML+=""},mdate:function(elm,editor_event){var d=new Date();elm.innerHTML=TinyMCE_TemplatePlugin._getDateTime(d,tinyMCE.getParam("template_mdate_format",tinyMCE.getLang("lang_template_def_date_format")))},selectedContent:function(elm,editor_event){var ds=tinyMCE.selectedInstance.getData('template');if(editor_event!=TinyMCE_TemplatePlugin.TMPL_TEMPLATE_EVENT)return;if(ds.currentAction=="insert-new"&&!tinyMCE.hasCSSClass(elm,TinyMCE_TemplatePlugin.TMPL_SEL_HTML_DONE)){elm.innerHTML=tinyMCE.selectedInstance.selection.getSelectedHTML();tinyMCE.addCSSClass(elm,TinyMCE_TemplatePlugin.TMPL_SEL_HTML_DONE)}},generateReplacer:function(s){return function(elm,editor_event){elm.innerHTML=""+s}}},_getDateTime:function(d,fmt){if(!fmt)return"";function addZeros(value,len){var i;value=""+value;if(value.length 0 ? nodeArray[0] : null; - nodeArray = []; + el = dom.create('div', null, h); - if (ds.currentAction == "insert") { - //insert new template after applying all the template content functions + function hasClass(n, c) { + return new RegExp('\\b' + c + '\\b', 'g').test(n.className); + }; - // Is it a template or snippet - if (telm) { - tinyMCE.execCommand('mceBeginUndoLevel'); - ds.currentAction = "insert-new"; - TinyMCE_TemplatePlugin._insertTemplate(editor_id, telm, value.title, value.tsrc, true); - ds.currentAction == "insert"; - tinyMCE.execCommand('mceEndUndoLevel'); - tinyMCE.execInstanceCommand(editor_id, 'mceCleanup', false); - } else - tinyMCE.execCommand('mceInsertContent', false, this._replaceValues(value.body)); - } else { - // First collect the selected template in the editor - nodeArray = TinyMCE_TemplatePlugin._collectTemplateElements(ds.currentTmplNode); - current = []; - newTmpl = []; - tinyMCE.getNodeTree(telm, newTmpl); + each(dom.select('*', el), function(n) { + // Replace cdate + if (hasClass(n, ed.getParam('template_cdate_classes', 'cdate').replace(/\s+/g, '|'))) + n.innerHTML = t._getDateTime(new Date(), ed.getParam("template_cdate_format", ed.getLang("template.cdate_format"))); - for (x=0; x', 'gi'), - '' - ); - - // delete any empty template wrappers - content = content.replace( - new RegExp('
(\s| | )?(|\s)?
', 'gi'), - '' - ); - - // replace the closing wrapper tag - content = content.replace( - new RegExp('', 'gi'), - '' - ); - - break; - - case "insert_to_editor": - // replace HTML comment with DIV wrapper - content = content.replace( - new RegExp('', 'gi'), - '
' - ); - - content = content.replace( - new RegExp('', 'gi'), - '
' - ); - - break; - - case "get_from_editor_dom": - // apply template content replacement functions - nodes = tinyMCE.selectNodes(content, function(n) { - return tinyMCE.hasCSSClass(n, TinyMCE_TemplatePlugin.TMPL_ELEMENT); - } - ); - - TinyMCE_TemplatePlugin._applyFunctions(nodes, type); - - break; - - case "insert_to_editor_dom": - // apply template content replacement functions - nodes = tinyMCE.selectNodes(content, function(n) { - return tinyMCE.hasCSSClass(n, TinyMCE_TemplatePlugin.TMPL_ELEMENT); - } - ); - - TinyMCE_TemplatePlugin._applyFunctions(nodes, type); - - break; - } - - return content; - }, - - // Private plugin internal methods - - /** - * Creates a HTML DIV element and sets the innerHTML to equal the temlate innerHTML so that the template can be manipulated as DOM nodes. - * - * @param {string} Template innerHTML - * @return a HTML Element - * @type HTMLElement - */ - _convertToNode : function(html) { - var elm = document.createElement('div'); - - elm.innerHTML = html; - - return elm; - }, - - /** - * pass an array of template html elements and they will have the template class name added and any template functions applied - * - * @param {array} template HTML elements - * @return array of template HTML elements - * @type array - */ - _prepareTemplateContent : function(elms) { - var x, n, nodes = []; - - if (!elms) - return {}; - - if (!elms.length) - elms = [elms]; - - for (x = 0; x'; - html += elm.innerHTML; - html += ''; - - tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false, html); - }, - - /** - * template functions - functions for modifying template content - */ - functions : { - blank : function(elm, editor_event) {}, - - cdate : function(elm, editor_event) { - var d, dsrc; - - if (editor_event != TinyMCE_TemplatePlugin.TMPL_TEMPLATE_EVENT) - return; - - d = new Date(); - // find out if the creation date was previously stored - dsrc = elm.innerHTML.match(new RegExp("", "gi")); + return fmt; + } + }); - if (dsrc) - d = new Date(RegExp.$1); - - elm.innerHTML = TinyMCE_TemplatePlugin._getDateTime(d, tinyMCE.getParam("template_cdate_format", tinyMCE.getLang("lang_template_def_date_format"))); - //now we have to store the date value in a format easily read again, in case a future template change changes the date format... - elm.innerHTML += ""; - }, - - mdate : function(elm, editor_event) { - var d = new Date(); - elm.innerHTML = TinyMCE_TemplatePlugin._getDateTime(d, tinyMCE.getParam("template_mdate_format", tinyMCE.getLang("lang_template_def_date_format"))); - }, - - /** - * This will insert the currently selected editor content into the template element. - * It only does this if the template inserted is a new one and if the element does not have the special class. - * The special class name prevents this from happening more than once. - */ - selectedContent : function(elm, editor_event) { - var ds = tinyMCE.selectedInstance.getData('template'); - - if (editor_event != TinyMCE_TemplatePlugin.TMPL_TEMPLATE_EVENT) - return; - - if (ds.currentAction == "insert-new" && !tinyMCE.hasCSSClass(elm, TinyMCE_TemplatePlugin.TMPL_SEL_HTML_DONE)) { - elm.innerHTML = tinyMCE.selectedInstance.selection.getSelectedHTML(); - tinyMCE.addCSSClass(elm, TinyMCE_TemplatePlugin.TMPL_SEL_HTML_DONE); - } - }, - - /** - * When the plugin is initialised this generates the functions that insert configured strings into template elements. - */ - generateReplacer : function(s) { - return function(elm, editor_event) {elm.innerHTML = "" + s;}; - } - }, - - /** - * formats a date according to the format string - straight from the 'insert date/time' plugin - * - * @param {Date} date object - * @param {string} format string - * @return formatted date - * @type string - */ - _getDateTime : function(d,fmt) { - if (!fmt) - return ""; - - function addZeros(value, len) { - var i; - - value = "" + value; - - if (value.length < len) { - for (i=0; i<(len-value.length); i++) - value = "0" + value; - } - - return value; - } - - fmt = fmt.replace("%D", "%m/%d/%y"); - fmt = fmt.replace("%r", "%I:%M:%S %p"); - fmt = fmt.replace("%Y", "" + d.getFullYear()); - fmt = fmt.replace("%y", "" + d.getYear()); - fmt = fmt.replace("%m", addZeros(d.getMonth()+1, 2)); - fmt = fmt.replace("%d", addZeros(d.getDate(), 2)); - fmt = fmt.replace("%H", "" + addZeros(d.getHours(), 2)); - fmt = fmt.replace("%M", "" + addZeros(d.getMinutes(), 2)); - fmt = fmt.replace("%S", "" + addZeros(d.getSeconds(), 2)); - fmt = fmt.replace("%I", "" + ((d.getHours() + 11) % 12 + 1)); - fmt = fmt.replace("%p", "" + (d.getHours() < 12 ? "AM" : "PM")); - fmt = fmt.replace("%B", "" + tinyMCE.getLang("lang_template_months_long")[d.getMonth()]); - fmt = fmt.replace("%b", "" + tinyMCE.getLang("lang_template_months_short")[d.getMonth()]); - fmt = fmt.replace("%A", "" + tinyMCE.getLang("lang_template_day_long")[d.getDay()]); - fmt = fmt.replace("%a", "" + tinyMCE.getLang("lang_template_day_short")[d.getDay()]); - fmt = fmt.replace("%%", "%"); - - return fmt; - }, - - TMPL_ELEMENT : 'mceTmplElm', - TMPL : 'mceTmpl', - TMPL_BEGINS : 'mceTmplBegins', - TMPL_SEL_HTML_DONE : 'mceSelHTMLDone', - TMPL_ENDS : 'mceTmplEnds', - TMPL_DATE_SRC_ATTR : 'mcetmpldtesrc', - TMPL_TEMPLATE_EVENT : 'prepare_template' -}; - -tinyMCE.addPlugin("template", TinyMCE_TemplatePlugin); + // Register plugin + tinymce.PluginManager.add('template', tinymce.plugins.TemplatePlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/template/images/template.gif Binary file includes/clientside/tinymce/plugins/template/images/template.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/template/js/template.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/template/js/template.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,100 @@ +tinyMCEPopup.requireLangPack(); + +var TemplateDialog = { + preInit : function() { + var url = tinyMCEPopup.getParam("template_external_list_url"); + + if (url != null) + document.write(''); + }, + + init : function() { + var ed = tinyMCEPopup.editor, tsrc, sel, x, u; + + tsrc = ed.getParam("template_templates", false); + sel = document.getElementById('tpath'); + + // Setup external template list + if (!tsrc && typeof(tinyMCETemplateList) != 'undefined') { + for (x=0, tsrc = []; x'); + }); + }, + + selectTemplate : function(u) { + var d = window.frames['templatesrc'].document; + + if (!u) + return; + + d.body.innerHTML = this.templateHTML = this.getFileContents(u); + }, + + insert : function() { + tinyMCEPopup.execCommand('mceInsertTemplate', false, { + content : this.templateHTML, + selection : tinyMCEPopup.editor.selection.getContent() + }); + + tinyMCEPopup.close(); + }, + + getFileContents : function(u) { + var x, d, t = 'text/plain'; + + function g(s) { + x = 0; + + try { + x = new ActiveXObject(s); + } catch (s) { + } + + return x; + }; + + x = window.ActiveXObject ? g('Msxml2.XMLHTTP') || g('Microsoft.XMLHTTP') : new XMLHttpRequest(); + + // Synchronous AJAX load file + x.overrideMimeType && x.overrideMimeType(t); + x.open("GET", u, false); + x.send(null); + + return x.responseText; + } +}; + +TemplateDialog.preInit(); +tinyMCEPopup.onInit.add(TemplateDialog.init, TemplateDialog); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/template/jscripts/template.js --- a/includes/clientside/tinymce/plugins/template/jscripts/template.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -// Import external list url javascript -var url = tinyMCE.getParam("template_external_list_url"); -if (url != null) { - // Fix relative - if (url.charAt(0) != '/' && url.indexOf('://') == -1) - url = tinyMCE.documentBasePath + "/" + url; - - document.write(''); -} - -var TPU = { //Template Popup Utils - currentTemplateHTML : null, - templates : [], - inst : tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')), - plugin : tinyMCE.getWindowArg('pluginObj'), - data : tinyMCE.selectedInstance.getData('template'), - - init : function() { - document.forms[0].insert.value = tinyMCE.getLang('lang_' + this.data.currentAction, 'Insert', true); - TPU.loadTemplatePaths(); - - if (this.data.currentAction == "update") - document.getElementById('warning').innerHTML = tinyMCE.getLang('lang_template_warning'); - - this.resizeInputs(); - }, - - loadTemplatePaths : function() { - var tsrc, sel, x, u; - - tsrc = tinyMCE.getParam("template_templates", false); - sel = document.getElementById('tpath'); - - // Setup external template list - if (!tsrc && typeof(tinyMCETemplateList) != 'undefined') { - for (x=0, tsrc = []; x' + - 'blank_page' + - '' + - '' + - '' + - this.currentTemplateHTML + - '' + - ''; - } - - // Write HTML to preview iframe - d.body.innerHTML = this.currentTemplateHTML; - - // Display description - for (x = 0; x < TPU.templates.length; x++) { - if (TPU.templates[x].src == o.value) { - document.getElementById('tmpldesc').innerHTML = TPU.templates[x].description; - break; - } - } - }, - - insertTemplate : function() { - var sel, opt; - - sel = document.getElementById('tpath'); - opt = sel.options[sel.selectedIndex]; - - // Is it a template or snippet - if (TPU.currentTemplateHTML.indexOf('mceTmpl')) - tinyMCEPopup.execCommand('mceTemplate', false, {title : opt.text, tsrc : opt.value, body : TPU.currentTemplateHTML}); - else - tinyMCEPopup.execCommand('mceInsertContent', false, TPU.currentTemplateHTML); - - tinyMCEPopup.close(); - }, - - getFileContents : function(u) { - var x, d, t = 'text/plain'; - - function g(s) { - x = 0; - - try { - x = new ActiveXObject(s); - } catch (s) { - } - - return x; - }; - - x = window.ActiveXObject ? g('Msxml2.XMLHTTP') || g('Microsoft.XMLHTTP') : new XMLHttpRequest(); - - // Synchronous AJAX load file - x.overrideMimeType && x.overrideMimeType(t); - x.open("GET", u, false); - x.send(null); - - return x.responseText; - }, - - resizeInputs : function() { - var wHeight, wWidth, elm; - - if (!self.innerWidth) { - wHeight = document.body.clientHeight - 160; - wWidth = document.body.clientWidth - 40; - } else { - wHeight = self.innerHeight - 160; - wWidth = self.innerWidth - 40; - } - - elm = document.getElementById('templatesrc'); - - if (elm) { - elm.style.height = Math.abs(wHeight) + 'px'; - elm.style.width = Math.abs(wWidth - 5) + 'px'; - } - } -}; diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/template/langs/en.js --- a/includes/clientside/tinymce/plugins/template/langs/en.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -// UK lang variables - -tinyMCE.addToLang('template',{ -title : 'Templates', -label : 'Template', -desc_label : 'Description', -desc : 'Insert predefined template content', -select : 'Select a template', -preview : 'Preview', -warning : 'Warning: Updating a template with a different one may cause data loss.', -def_date_format : '%Y-%m-%d %H:%M:%S', -months_long : new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), -months_short : new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"), -day_long : new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"), -day_short : new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun") -}); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/template/langs/en_dlg.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/template/langs/en_dlg.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,15 @@ +tinyMCE.addI18n('en.template_dlg',{ +title:"Templates", +label:"Template", +desc_label:"Description", +desc:"Insert predefined template content", +select:"Select a template", +preview:"Preview", +warning:"Warning: Updating a template with a different one may cause data loss.", +mdate_format:"%Y-%m-%d %H:%M:%S", +cdate_format:"%Y-%m-%d %H:%M:%S", +months_long:"January,February,March,April,May,June,July,August,September,October,November,December", +months_short:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", +day_long:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday", +day_short:"Sun,Mon,Tue,Wed,Thu,Fri,Sat,Sun" +}); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/template/template.htm --- a/includes/clientside/tinymce/plugins/template/template.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/template/template.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,36 +1,38 @@ - {$lang_template_title} - - + {#template_dlg.title} + + - -
+ +
-
{$lang_template_desc}
-
- +
-
+
- {$lang_template_preview} + {#template_dlg.preview}
- +
- +
+ +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/visualchars/editor_plugin.js --- a/includes/clientside/tinymce/plugins/visualchars/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/visualchars/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('visualchars');var TinyMCE_VisualCharsPlugin={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}},initInstance:function(inst){inst.visualChars={state:false}},getControlHTML:function(cn){switch(cn){case"visualchars":return tinyMCE.getButtonHTML(cn,'lang_visualchars_desc','{$pluginurl}/images/visualchars.gif','mceVisualChars',false)}return""},execCommand:function(editor_id,element,command,user_interface,value){var inst=tinyMCE.getInstanceById(editor_id);switch(command){case"mceVisualChars":this._toggleVisualChars(editor_id,inst);return true}return false},cleanup:function(type,content,inst){if(type=="insert_to_editor_dom"||type=="get_from_editor_dom"){inst.visualChars.state=true;this._toggleVisualChars(inst.editorId,inst)}return content},_toggleVisualChars:function(editor_id,inst){var nl,i,h,d=inst.getDoc(),b=inst.getBody(),nv,s=inst.selection,bo;inst.visualChars.state=!inst.visualChars.state;bo=s.getBookmark(true);tinyMCE.switchClass(editor_id+'_visualchars',inst.visualChars.state?'mceButtonSelected':'mceButtonNormal');if(inst.visualChars.state){nl=tinyMCE.selectNodes(b,function(n){return n.nodeType==3&&n.nodeValue&&n.nodeValue.indexOf('\u00a0')!=-1});for(i=0;i$1');nv=nv.replace(/\u00a0/g,'\u00b7');tinyMCE.setOuterHTML(nl[i],nv,d)}}else{nl=tinyMCE.selectNodes(b,function(n){return n.nodeType==1&&n.nodeName=='SPAN'&&n.className=='mceItemHiddenVisualChar'});for(i=0;i$1');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$1'); + 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$1'); - nv = nv.replace(/\u00a0/g, '\u00b7'); - tinyMCE.setOuterHTML(nl[i], nv, d); + for (i=0; i - {$lang_xhtmlxtras_title_abbr_element} - - - - - - + {#xhtmlxtras_dlg.title_abbr_element} + + + + + + - +
- {$lang_xhtmlxtras_fieldset_attrib_tab} + {#xhtmlxtras_dlg.fieldset_attrib_tab}
- + - + - + - + - + - + @@ -65,7 +66,7 @@
- {$lang_xhtmlxtras_fieldset_events_tab} + {#xhtmlxtras_dlg.fieldset_events_tab}
::
::
::
::
::
::
@@ -133,13 +134,13 @@
- +
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/acronym.htm --- a/includes/clientside/tinymce/plugins/xhtmlxtras/acronym.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/acronym.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,61 +1,62 @@ + - {$lang_xhtmlxtras_title_acronym_element} - - - - - - + {#xhtmlxtras_dlg.title_acronym_element} + + + + + + - +
- {$lang_xhtmlxtras_fieldset_attrib_tab} + {#xhtmlxtras_dlg.fieldset_attrib_tab}
- + - + - + - + - + - + @@ -65,7 +66,7 @@
- {$lang_xhtmlxtras_fieldset_events_tab} + {#xhtmlxtras_dlg.fieldset_events_tab}
::
::
::
::
::
::
@@ -133,13 +134,13 @@
- +
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/attributes.htm --- a/includes/clientside/tinymce/plugins/xhtmlxtras/attributes.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/attributes.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,71 +1,72 @@ + - {$lang_xhtmlxtras_attribs_title} - - - - - + {#xhtmlxtras_dlg.attribs_title} + + + + + - +
- {$lang_xhtmlxtras_attribute_attrib_tab} + {#xhtmlxtras_dlg.attribute_attrib_tab}
- + - + - + - + - + - + - + - +
::
::
::
::
::
@@ -73,7 +74,7 @@
- {$lang_xhtmlxtras_attribute_events_tab} + {#xhtmlxtras_dlg.attribute_events_tab} @@ -141,10 +142,10 @@
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/cite.htm --- a/includes/clientside/tinymce/plugins/xhtmlxtras/cite.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/cite.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,61 +1,62 @@ + - {$lang_xhtmlxtras_title_cite_element} - - - - - - + {#xhtmlxtras_dlg.title_cite_element} + + + + + + - +
- {$lang_xhtmlxtras_fieldset_attrib_tab} + {#xhtmlxtras_dlg.fieldset_attrib_tab}
- + - + - + - + - + - + @@ -65,7 +66,7 @@
- {$lang_xhtmlxtras_fieldset_events_tab} + {#xhtmlxtras_dlg.fieldset_events_tab}
::
::
::
::
::
::
@@ -133,13 +134,13 @@
- +
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/css/popup.css --- a/includes/clientside/tinymce/plugins/xhtmlxtras/css/popup.css Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/css/popup.css Fri Feb 22 12:51:53 2008 -0500 @@ -1,46 +1,9 @@ -a.mceButtonNormal img, a.mceButtonSelected img {border: 1px solid #F0F0EE !important;} -a.mceButtonNormal img:hover, a.mceButtonSelected img:hover {border: 1px solid #0A246A !important; cursor: default; background-color: #B6BDD2;} - -img { - border: 0; -} - -input.field, select.field { - width: 200px; -} - -input.picker { - width: 179px; - margin-left: 5px; -} - -input.disabled { - border-color: #F2F2F2; -} - -img.picker { - vertical-align: text-bottom; - cursor: pointer; -} - -h1 { - padding: 0 0 5px 0; -} - -#remove { - font-weight: bold; - width: 90px; - height: 21px; - border: 0px; - background-image: url('../images/remove_button_bg.gif'); - cursor: pointer; - margin-left: 3px; -} - -.panel_wrapper div.current { - height: 160px; -} - -#xhtmlxtrasdel .panel_wrapper div.current, #xhtmlxtrasins .panel_wrapper div.current { - height: 220px; -} +input.field, select.field {width:200px;} +input.picker {width:179px; margin-left: 5px;} +input.disabled {border-color:#F2F2F2;} +img.picker {vertical-align:text-bottom; cursor:pointer;} +h1 {padding: 0 0 5px 0;} +.panel_wrapper div.current {height:160px;} +#xhtmlxtrasdel .panel_wrapper div.current, #xhtmlxtrasins .panel_wrapper div.current {height: 230px;} +a.browse span {display:block; width:20px; height:20px; background:url('../../../themes/advanced/img/icons.gif') -140px -20px;} +#datetime {width:180px;} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/del.htm --- a/includes/clientside/tinymce/plugins/xhtmlxtras/del.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/del.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,81 +1,82 @@ + - {$lang_xhtmlxtras_title_del_element} - - - - - - + {#xhtmlxtras_dlg.title_del_element} + + + + + + - +
- {$lang_xhtmlxtras_fieldset_general_tab} + {#xhtmlxtras_dlg.fieldset_general_tab}
- + - +
:: - +
{$lang_xhtmlxtras_insert_date}
::
- {$lang_xhtmlxtras_fieldset_attrib_tab} + {#xhtmlxtras_dlg.fieldset_attrib_tab} - + - + - + - + - + - + @@ -85,7 +86,7 @@
- {$lang_xhtmlxtras_fieldset_events_tab} + {#xhtmlxtras_dlg.fieldset_events_tab}
::
::
::
::
::
::
@@ -153,13 +154,13 @@
- +
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/editor_plugin.js --- a/includes/clientside/tinymce/plugins/xhtmlxtras/editor_plugin.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/editor_plugin.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importPluginLanguagePack('xhtmlxtras');var TinyMCE_XHTMLXtrasPlugin={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}},initInstance:function(inst){tinyMCE.importCSS(inst.getDoc(),tinyMCE.baseURL+"/plugins/xhtmlxtras/css/xhtmlxtras.css")},getControlHTML:function(cn){switch(cn){case"cite":return tinyMCE.getButtonHTML(cn,'lang_xhtmlxtras_cite_desc','{$pluginurl}/images/cite.gif','mceCite',true);case"acronym":return tinyMCE.getButtonHTML(cn,'lang_xhtmlxtras_acronym_desc','{$pluginurl}/images/acronym.gif','mceAcronym',true);case"abbr":return tinyMCE.getButtonHTML(cn,'lang_xhtmlxtras_abbr_desc','{$pluginurl}/images/abbr.gif','mceAbbr',true);case"del":return tinyMCE.getButtonHTML(cn,'lang_xhtmlxtras_del_desc','{$pluginurl}/images/del.gif','mceDel',true);case"ins":return tinyMCE.getButtonHTML(cn,'lang_xhtmlxtras_ins_desc','{$pluginurl}/images/ins.gif','mceIns',true);case"attribs":return tinyMCE.getButtonHTML(cn,'lang_xhtmlxtras_attribs_desc','{$pluginurl}/images/attribs.gif','mceAttributes',true)}return""},execCommand:function(editor_id,element,command,user_interface,value){var template,inst,elm;switch(command){case"mceCite":if(!this._anySel(editor_id))return true;template=new Array();template['file']='../../plugins/xhtmlxtras/cite.htm';template['width']=350;template['height']=250;tinyMCE.openWindow(template,{editor_id:editor_id});return true;case"mceAcronym":if(!this._anySel(editor_id))return true;template=new Array();template['file']='../../plugins/xhtmlxtras/acronym.htm';template['width']=350;template['height']=250;tinyMCE.openWindow(template,{editor_id:editor_id});return true;case"mceAbbr":if(!this._anySel(editor_id))return true;template=new Array();template['file']='../../plugins/xhtmlxtras/abbr.htm';template['width']=350;template['height']=250;tinyMCE.openWindow(template,{editor_id:editor_id});return true;case"mceIns":if(!this._anySel(editor_id))return true;template=new Array();template['file']='../../plugins/xhtmlxtras/ins.htm';template['width']=350;template['height']=310;tinyMCE.openWindow(template,{editor_id:editor_id});return true;case"mceDel":if(!this._anySel(editor_id))return true;template=new Array();template['file']='../../plugins/xhtmlxtras/del.htm';template['width']=350;template['height']=310;tinyMCE.openWindow(template,{editor_id:editor_id});return true;case"mceAttributes":inst=tinyMCE.getInstanceById(editor_id);elm=inst.getFocusElement();if(elm&&elm.nodeName!=='BODY'&&elm.className.indexOf('mceItem')==-1){tinyMCE.openWindow({file:'../../plugins/xhtmlxtras/attributes.htm',width:380,height:370},{editor_id:editor_id})}return true}return false},cleanup:function(type,content,inst){if(type=='insert_to_editor'&&tinyMCE.isIE&&!tinyMCE.isOpera){content=content.replace(/]+)>/gi,'');content=content.replace(/<\/abbr>/gi,'')}return content},handleNodeChange:function(editor_id,node,undo_index,undo_levels,visual_aid,any_selection){var elm=tinyMCE.getParentElement(node);if(node==null)return;tinyMCE.switchClass(editor_id+'_attribs','mceButtonDisabled');if(!any_selection){tinyMCE.switchClass(editor_id+'_cite','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_acronym','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_abbr','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_del','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_ins','mceButtonDisabled')}else{tinyMCE.switchClass(editor_id+'_cite','mceButtonNormal');tinyMCE.switchClass(editor_id+'_acronym','mceButtonNormal');tinyMCE.switchClass(editor_id+'_abbr','mceButtonNormal');tinyMCE.switchClass(editor_id+'_del','mceButtonNormal');tinyMCE.switchClass(editor_id+'_ins','mceButtonNormal')}if(elm&&elm.nodeName!='BODY'&&elm.className.indexOf('mceItem')==-1)tinyMCE.switchClass(editor_id+'_attribs','mceButtonNormal');switch(node.nodeName){case"CITE":tinyMCE.switchClass(editor_id+'_cite','mceButtonSelected');return true;case"ACRONYM":tinyMCE.switchClass(editor_id+'_acronym','mceButtonSelected');return true;case"abbr":case"HTML:ABBR":case"ABBR":tinyMCE.switchClass(editor_id+'_abbr','mceButtonSelected');return true;case"DEL":tinyMCE.switchClass(editor_id+'_del','mceButtonSelected');return true;case"INS":tinyMCE.switchClass(editor_id+'_ins','mceButtonSelected');return true}return true},_anySel:function(editor_id){var inst=tinyMCE.getInstanceById(editor_id),t=inst.selection.getSelectedText(),pe;pe=tinyMCE.getParentElement(inst.getFocusElement(),'CITE,ACRONYM,ABBR,HTML:ABBR,DEL,INS');return pe||inst.getFocusElement().nodeName=="IMG"||(t&&t.length>0)}};tinyMCE.addPlugin("xhtmlxtras",TinyMCE_XHTMLXtrasPlugin); \ No newline at end of file +(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(/]+)>/gi,'');o.content=o.content.replace(/<\/abbr>/gi,'');}};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 diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/xhtmlxtras/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/editor_plugin_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,199 +1,134 @@ - /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ +/** + * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ * - * @author Moxiecode - based on work by Andrew Tetlaw - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @author Moxiecode + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import plugin specific language pack */ -tinyMCE.importPluginLanguagePack('xhtmlxtras'); - -var TinyMCE_XHTMLXtrasPlugin = { - 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 - }; - }, - - initInstance : function(inst) { - tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/plugins/xhtmlxtras/css/xhtmlxtras.css"); - }, +(function() { + tinymce.create('tinymce.plugins.XHTMLXtrasPlugin', { + init : function(ed, url) { + // Register commands + 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 + }); + }); - getControlHTML : function(cn) { - switch (cn) { - case "cite": - return tinyMCE.getButtonHTML(cn, 'lang_xhtmlxtras_cite_desc', '{$pluginurl}/images/cite.gif', 'mceCite', true); - - case "acronym": - return tinyMCE.getButtonHTML(cn, 'lang_xhtmlxtras_acronym_desc', '{$pluginurl}/images/acronym.gif', 'mceAcronym', true); - - case "abbr": - return tinyMCE.getButtonHTML(cn, 'lang_xhtmlxtras_abbr_desc', '{$pluginurl}/images/abbr.gif', 'mceAbbr', true); - - case "del": - return tinyMCE.getButtonHTML(cn, 'lang_xhtmlxtras_del_desc', '{$pluginurl}/images/del.gif', 'mceDel', true); - - case "ins": - return tinyMCE.getButtonHTML(cn, 'lang_xhtmlxtras_ins_desc', '{$pluginurl}/images/ins.gif', 'mceIns', true); - - case "attribs": - return tinyMCE.getButtonHTML(cn, 'lang_xhtmlxtras_attribs_desc', '{$pluginurl}/images/attribs.gif', 'mceAttributes', true); - } - - return ""; - }, - - execCommand : function(editor_id, element, command, user_interface, value) { - var template, inst, elm; + 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 + }); + }); - switch (command) { - case "mceCite": - if (!this._anySel(editor_id)) - return true; - - template = new Array(); - template['file'] = '../../plugins/xhtmlxtras/cite.htm'; - template['width'] = 350; - template['height'] = 250; - tinyMCE.openWindow(template, {editor_id : editor_id}); - return true; - - case "mceAcronym": - if (!this._anySel(editor_id)) - return true; - - template = new Array(); - template['file'] = '../../plugins/xhtmlxtras/acronym.htm'; - template['width'] = 350; - template['height'] = 250; - tinyMCE.openWindow(template, {editor_id : editor_id}); - return true; + 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 + }); + }); - case "mceAbbr": - if (!this._anySel(editor_id)) - return true; - - template = new Array(); - template['file'] = '../../plugins/xhtmlxtras/abbr.htm'; - template['width'] = 350; - template['height'] = 250; - tinyMCE.openWindow(template, {editor_id : editor_id}); - return true; + 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 + }); + }); - case "mceIns": - if (!this._anySel(editor_id)) - return true; - - template = new Array(); - template['file'] = '../../plugins/xhtmlxtras/ins.htm'; - template['width'] = 350; - template['height'] = 310; - tinyMCE.openWindow(template, {editor_id : editor_id}); - return true; - - case "mceDel": - if (!this._anySel(editor_id)) - return true; + 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 + }); + }); - template = new Array(); - template['file'] = '../../plugins/xhtmlxtras/del.htm'; - template['width'] = 350; - template['height'] = 310; - tinyMCE.openWindow(template, {editor_id : editor_id}); - return true; - - case "mceAttributes": - inst = tinyMCE.getInstanceById(editor_id); - elm = inst.getFocusElement(); - - if (elm && elm.nodeName !== 'BODY' && elm.className.indexOf('mceItem') == -1) { - tinyMCE.openWindow({ - file : '../../plugins/xhtmlxtras/attributes.htm', - width : 380, - height : 370 - }, {editor_id : editor_id}); - } + ed.addCommand('mceAttributes', function() { + ed.windowManager.open({ + file : url + '/attributes.htm', + width : 380, + height : 370, + inline : 1 + }, { + plugin_url : url + }); + }); - return true; - } - - return false; - }, + // Register buttons + 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'}); - cleanup : function(type, content, inst) { - if (type == 'insert_to_editor' && tinyMCE.isIE && !tinyMCE.isOpera) { - content = content.replace(/]+)>/gi, ''); - content = content.replace(/<\/abbr>/gi, ''); - } + if (tinymce.isIE) { + function fix(ed, o) { + if (o.set) { + o.content = o.content.replace(/]+)>/gi, ''); + o.content = o.content.replace(/<\/abbr>/gi, ''); + } + }; - return content; - }, + ed.onBeforeSetContent.add(fix); + ed.onPostProcess.add(fix); + } - handleNodeChange : function(editor_id, node, undo_index,undo_levels, visual_aid, any_selection) { - var elm = tinyMCE.getParentElement(node); - - if (node == null) - return; - - tinyMCE.switchClass(editor_id + '_attribs', 'mceButtonDisabled'); + ed.onNodeChange.add(function(ed, cm, n, co) { + n = ed.dom.getParent(n, 'CITE,ACRONYM,ABBR,DEL,INS'); - if (!any_selection) { - // Disable the buttons - tinyMCE.switchClass(editor_id + '_cite', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_acronym', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_abbr', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_del', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_ins', 'mceButtonDisabled'); - } else { - // A selection means the buttons should be active. - tinyMCE.switchClass(editor_id + '_cite', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_acronym', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_abbr', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_del', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_ins', 'mceButtonNormal'); - } - - if (elm && elm.nodeName != 'BODY' && elm.className.indexOf('mceItem') == -1) - tinyMCE.switchClass(editor_id + '_attribs', 'mceButtonNormal'); - - switch (node.nodeName) { - case "CITE": - tinyMCE.switchClass(editor_id + '_cite', 'mceButtonSelected'); - return true; - - case "ACRONYM": - tinyMCE.switchClass(editor_id + '_acronym', 'mceButtonSelected'); - return true; + 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'); - case "abbr": // IE - case "HTML:ABBR": // FF - case "ABBR": - tinyMCE.switchClass(editor_id + '_abbr', 'mceButtonSelected'); - return true; + 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); + } + }); + }, - case "DEL": - tinyMCE.switchClass(editor_id + '_del', 'mceButtonSelected'); - return true; - - case "INS": - tinyMCE.switchClass(editor_id + '_ins', 'mceButtonSelected'); - return true; + 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 + }; } - - return true; - }, - - _anySel : function(editor_id) { - var inst = tinyMCE.getInstanceById(editor_id), t = inst.selection.getSelectedText(), pe; + }); - pe = tinyMCE.getParentElement(inst.getFocusElement(), 'CITE,ACRONYM,ABBR,HTML:ABBR,DEL,INS'); - - return pe || inst.getFocusElement().nodeName == "IMG" || (t && t.length > 0); - } -}; - -tinyMCE.addPlugin("xhtmlxtras", TinyMCE_XHTMLXtrasPlugin); + // Register plugin + tinymce.PluginManager.add('xhtmlxtras', tinymce.plugins.XHTMLXtrasPlugin); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/images/abbr.gif Binary file includes/clientside/tinymce/plugins/xhtmlxtras/images/abbr.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/images/acronym.gif Binary file includes/clientside/tinymce/plugins/xhtmlxtras/images/acronym.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/images/attribs.gif Binary file includes/clientside/tinymce/plugins/xhtmlxtras/images/attribs.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/images/cite.gif Binary file includes/clientside/tinymce/plugins/xhtmlxtras/images/cite.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/images/date_time.gif Binary file includes/clientside/tinymce/plugins/xhtmlxtras/images/date_time.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/images/del.gif Binary file includes/clientside/tinymce/plugins/xhtmlxtras/images/del.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/images/ins.gif Binary file includes/clientside/tinymce/plugins/xhtmlxtras/images/ins.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/images/remove_button_bg.gif Binary file includes/clientside/tinymce/plugins/xhtmlxtras/images/remove_button_bg.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/ins.htm --- a/includes/clientside/tinymce/plugins/xhtmlxtras/ins.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/ins.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,81 +1,82 @@ + - {$lang_xhtmlxtras_title_ins_element} - - - - - - + {#xhtmlxtras_dlg.title_ins_element} + + + + + + - +
- {$lang_xhtmlxtras_fieldset_general_tab} + {#xhtmlxtras_dlg.fieldset_general_tab}
- + - +
:: - +
{$lang_xhtmlxtras_insert_date}
::
- {$lang_xhtmlxtras_fieldset_attrib_tab} + {#xhtmlxtras_dlg.fieldset_attrib_tab} - + - + - + - + - + - + @@ -85,7 +86,7 @@
- {$lang_xhtmlxtras_fieldset_events_tab} + {#xhtmlxtras_dlg.fieldset_events_tab}
::
::
::
::
::
::
@@ -153,13 +154,13 @@
- +
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/js/abbr.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/js/abbr.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,25 @@ + /** + * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ + * + * @author Moxiecode - based on work by Andrew Tetlaw + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ + +function init() { + SXE.initElementDialog('abbr'); + if (SXE.currentAction == "update") { + SXE.showRemoveButton(); + } +} + +function insertAbbr() { + SXE.insertElement(tinymce.isIE ? 'html:abbr' : 'abbr'); + tinyMCEPopup.close(); +} + +function removeAbbr() { + SXE.removeElement('abbr'); + tinyMCEPopup.close(); +} + +tinyMCEPopup.onInit.add(init); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/js/acronym.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/js/acronym.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,25 @@ + /** + * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ + * + * @author Moxiecode - based on work by Andrew Tetlaw + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ + +function init() { + SXE.initElementDialog('acronym'); + if (SXE.currentAction == "update") { + SXE.showRemoveButton(); + } +} + +function insertAcronym() { + SXE.insertElement('acronym'); + tinyMCEPopup.close(); +} + +function removeAcronym() { + SXE.removeElement('acronym'); + tinyMCEPopup.close(); +} + +tinyMCEPopup.onInit.add(init); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/js/attributes.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/js/attributes.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,123 @@ + /** + * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ + * + * @author Moxiecode - based on work by Andrew Tetlaw + * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved. + */ + +function init() { + tinyMCEPopup.resizeToInnerSize(); + var inst = tinyMCEPopup.editor; + var dom = inst.dom; + var elm = inst.selection.getNode(); + var f = document.forms[0]; + var onclick = dom.getAttrib(elm, 'onclick'); + + setFormValue('title', dom.getAttrib(elm, 'title')); + setFormValue('id', dom.getAttrib(elm, 'id')); + setFormValue('style', dom.getAttrib(elm, "style")); + setFormValue('dir', dom.getAttrib(elm, 'dir')); + setFormValue('lang', dom.getAttrib(elm, 'lang')); + setFormValue('tabindex', dom.getAttrib(elm, 'tabindex', typeof(elm.tabindex) != "undefined" ? elm.tabindex : "")); + setFormValue('accesskey', dom.getAttrib(elm, 'accesskey', typeof(elm.accesskey) != "undefined" ? elm.accesskey : "")); + setFormValue('onfocus', dom.getAttrib(elm, 'onfocus')); + setFormValue('onblur', dom.getAttrib(elm, 'onblur')); + setFormValue('onclick', onclick); + setFormValue('ondblclick', dom.getAttrib(elm, 'ondblclick')); + setFormValue('onmousedown', dom.getAttrib(elm, 'onmousedown')); + setFormValue('onmouseup', dom.getAttrib(elm, 'onmouseup')); + setFormValue('onmouseover', dom.getAttrib(elm, 'onmouseover')); + setFormValue('onmousemove', dom.getAttrib(elm, 'onmousemove')); + setFormValue('onmouseout', dom.getAttrib(elm, 'onmouseout')); + setFormValue('onkeypress', dom.getAttrib(elm, 'onkeypress')); + setFormValue('onkeydown', dom.getAttrib(elm, 'onkeydown')); + setFormValue('onkeyup', dom.getAttrib(elm, 'onkeyup')); + className = dom.getAttrib(elm, 'class'); + + addClassesToList('classlist', 'advlink_styles'); + selectByValue(f, 'classlist', className, true); + + TinyMCE_EditableSelects.init(); +} + +function setFormValue(name, value) { + if(value && document.forms[0].elements[name]){ + document.forms[0].elements[name].value = value; + } +} + +function insertAction() { + var inst = tinyMCEPopup.editor; + var elm = inst.selection.getNode(); + + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + setAllAttribs(elm); + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); +} + +function setAttrib(elm, attrib, value) { + var formObj = document.forms[0]; + var valueElm = formObj.elements[attrib.toLowerCase()]; + var inst = tinyMCEPopup.editor; + var dom = inst.dom; + + if (typeof(value) == "undefined" || value == null) { + value = ""; + + if (valueElm) + value = valueElm.value; + } + + if (value != "") { + dom.setAttrib(elm, attrib.toLowerCase(), value); + + if (attrib == "style") + attrib = "style.cssText"; + + if (attrib.substring(0, 2) == 'on') + value = 'return true;' + value; + + if (attrib == "class") + attrib = "className"; + + eval('elm.' + attrib + "=value;"); + } else + elm.removeAttribute(attrib); +} + +function setAllAttribs(elm) { + var f = document.forms[0]; + + setAttrib(elm, 'title'); + setAttrib(elm, 'id'); + setAttrib(elm, 'style'); + setAttrib(elm, 'class', getSelectValue(f, 'classlist')); + setAttrib(elm, 'dir'); + setAttrib(elm, 'lang'); + setAttrib(elm, 'tabindex'); + setAttrib(elm, 'accesskey'); + setAttrib(elm, 'onfocus'); + setAttrib(elm, 'onblur'); + setAttrib(elm, 'onclick'); + setAttrib(elm, 'ondblclick'); + setAttrib(elm, 'onmousedown'); + setAttrib(elm, 'onmouseup'); + setAttrib(elm, 'onmouseover'); + setAttrib(elm, 'onmousemove'); + setAttrib(elm, 'onmouseout'); + setAttrib(elm, 'onkeypress'); + setAttrib(elm, 'onkeydown'); + setAttrib(elm, 'onkeyup'); + + // Refresh in old MSIE +// if (tinyMCE.isMSIE5) +// elm.outerHTML = elm.outerHTML; +} + +function insertAttribute() { + tinyMCEPopup.close(); +} + +tinyMCEPopup.onInit.add(init); +tinyMCEPopup.requireLangPack(); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/js/cite.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/js/cite.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,25 @@ + /** + * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ + * + * @author Moxiecode - based on work by Andrew Tetlaw + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ + +function init() { + SXE.initElementDialog('cite'); + if (SXE.currentAction == "update") { + SXE.showRemoveButton(); + } +} + +function insertCite() { + SXE.insertElement('cite'); + tinyMCEPopup.close(); +} + +function removeCite() { + SXE.removeElement('cite'); + tinyMCEPopup.close(); +} + +tinyMCEPopup.onInit.add(init); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/js/del.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/js/del.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,50 @@ + /** + * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ + * + * @author Moxiecode - based on work by Andrew Tetlaw + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ + +function init() { + SXE.initElementDialog('del'); + if (SXE.currentAction == "update") { + setFormValue('datetime', tinyMCEPopup.editor.dom.getAttrib(SXE.updateElement, 'datetime')); + setFormValue('cite', tinyMCEPopup.editor.dom.getAttrib(SXE.updateElement, 'cite')); + SXE.showRemoveButton(); + } +} + +function setElementAttribs(elm) { + setAllCommonAttribs(elm); + setAttrib(elm, 'datetime'); + setAttrib(elm, 'cite'); +} + +function insertDel() { + var elm = tinyMCEPopup.editor.dom.getParent(SXE.focusElement, 'DEL'); + + tinyMCEPopup.execCommand('mceBeginUndoLevel'); + if (elm == null) { + var s = SXE.inst.selection.getContent(); + if(s.length > 0) { + tinyMCEPopup.execCommand('mceInsertContent', false, '' + s + ''); + var elementArray = tinymce.grep(SXE.inst.dom.select('del'), function(n) {return n.id == '#sxe_temp_del#';}); + for (var i=0; i 0) { + tagName = element_name; + + if (tinymce.isIE && element_name.indexOf('html:') == 0) + element_name = element_name.substring(5).toLowerCase(); + + h = '<' + tagName + ' id="#sxe_temp_' + element_name + '#">' + s + ''; + + tinyMCEPopup.execCommand('mceInsertContent', false, h); + + var elementArray = tinymce.grep(SXE.inst.dom.select(element_name), function(n) {return n.id == '#sxe_temp_' + element_name + '#';}); + for (var i=0; i -1) ? true : false; +} + +SXE.removeClass = function(elm,cl) { + if(elm.className == null || elm.className == "" || !SXE.containsClass(elm,cl)) { + return true; + } + var classNames = elm.className.split(" "); + var newClassNames = ""; + for (var x = 0, cnl = classNames.length; x < cnl; x++) { + if (classNames[x] != cl) { + newClassNames += (classNames[x] + " "); + } + } + elm.className = newClassNames.substring(0,newClassNames.length-1); //removes extra space at the end +} + +SXE.addClass = function(elm,cl) { + if(!SXE.containsClass(elm,cl)) elm.className ? elm.className += " " + cl : elm.className = cl; + return true; +} \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/js/ins.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/plugins/xhtmlxtras/js/ins.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,49 @@ + /** + * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ + * + * @author Moxiecode - based on work by Andrew Tetlaw + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. + */ + +function init() { + SXE.initElementDialog('ins'); + if (SXE.currentAction == "update") { + setFormValue('datetime', tinyMCEPopup.editor.dom.getAttrib(SXE.updateElement, 'datetime')); + setFormValue('cite', tinyMCEPopup.editor.dom.getAttrib(SXE.updateElement, 'cite')); + SXE.showRemoveButton(); + } +} + +function setElementAttribs(elm) { + setAllCommonAttribs(elm); + setAttrib(elm, 'datetime'); + setAttrib(elm, 'cite'); +} + +function insertIns() { + var elm = tinyMCEPopup.editor.dom.getParent(SXE.focusElement, 'INS'); + tinyMCEPopup.execCommand('mceBeginUndoLevel'); + if (elm == null) { + var s = SXE.inst.selection.getContent(); + if(s.length > 0) { + tinyMCEPopup.execCommand('mceInsertContent', false, '' + s + ''); + var elementArray = tinymce.grep(SXE.inst.dom.select('ins'), function(n) {return n.id == '#sxe_temp_ins#';}); + for (var i=0; i 0) { - tinyMCEPopup.execCommand('mceInsertContent', false, '' + s + ''); - var elementArray = tinyMCE.getElementsByAttributeValue(SXE.inst.getBody(), 'del', 'id', '#sxe_temp_del#'); - for (var i=0; i 0) { - tagName = element_name; - - if (tinyMCE.isIE && !tinyMCE.isOpera && element_name.indexOf('html:') == 0) - element_name = element_name.substring(5).toLowerCase(); - - h = '<' + tagName + ' id="#sxe_temp_' + element_name + '#">' + s + ''; - - tinyMCEPopup.execCommand('mceInsertContent', false, h); - - var elementArray = tinyMCE.getElementsByAttributeValue(SXE.inst.getBody(), element_name, 'id', '#sxe_temp_' + element_name + '#'); - for (var i=0; i -1) ? true : false; -} - -SXE.removeClass = function(elm,cl) { - if(elm.className == null || elm.className == "" || !SXE.containsClass(elm,cl)) { - return true; - } - var classNames = elm.className.split(" "); - var newClassNames = ""; - for (var x = 0, cnl = classNames.length; x < cnl; x++) { - if (classNames[x] != cl) { - newClassNames += (classNames[x] + " "); - } - } - elm.className = newClassNames.substring(0,newClassNames.length-1); //removes extra space at the end -} - -SXE.addClass = function(elm,cl) { - if(!SXE.containsClass(elm,cl)) elm.className ? elm.className += " " + cl : elm.className = cl; - return true; -} \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/xhtmlxtras/jscripts/ins.js --- a/includes/clientside/tinymce/plugins/xhtmlxtras/jscripts/ins.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ - /** - * $Id: editor_plugin_src.js 42 2006-08-08 14:32:24Z spocke $ - * - * @author Moxiecode - based on work by Andrew Tetlaw - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. - */ - -function preinit() { - // Initialize - tinyMCE.setWindowArg('mce_windowresize', false); -} - -function init() { - tinyMCEPopup.resizeToInnerSize(); - SXE.initElementDialog('ins'); - if (SXE.currentAction == "update") { - setFormValue('datetime', tinyMCE.getAttrib(SXE.updateElement, 'datetime')); - setFormValue('cite', tinyMCE.getAttrib(SXE.updateElement, 'cite')); - SXE.showRemoveButton(); - } -} - -function setElementAttribs(elm) { - setAllCommonAttribs(elm); - setAttrib(elm, 'datetime'); - setAttrib(elm, 'cite'); -} - -function insertIns() { - var elm = tinyMCE.getParentElement(SXE.focusElement, 'ins'); - tinyMCEPopup.execCommand('mceBeginUndoLevel'); - if (elm == null) { - var s = SXE.inst.selection.getSelectedHTML(); - if(s.length > 0) { - tinyMCEPopup.execCommand('mceInsertContent', false, '' + s + ''); - var elementArray = tinyMCE.getElementsByAttributeValue(SXE.inst.getBody(), 'ins', 'id', '#sxe_temp_ins#'); - for (var i=0; i'+''+''+''+''+''}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case"mceZoom":tinyMCE.getInstanceById(editor_id).contentDocument.body.style.zoom=value;tinyMCE.getInstanceById(editor_id).contentDocument.body.style.mozZoom=value;return true}return false}};tinyMCE.addPlugin("zoom",TinyMCE_ZoomPlugin); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/zoom/editor_plugin_src.js --- a/includes/clientside/tinymce/plugins/zoom/editor_plugin_src.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/** - * $Id: editor_plugin_src.js 201 2007-02-12 15:56:56Z spocke $ - * - * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. - */ - -var TinyMCE_ZoomPlugin = { - getInfo : function() { - return { - longname : 'Zoom', - author : 'Moxiecode Systems AB', - authorurl : 'http://tinymce.moxiecode.com', - infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/zoom', - version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion - }; - }, - - /** - * Returns the HTML contents of the zoom control. - */ - getControlHTML : function(control_name) { - if (!tinyMCE.isMSIE || tinyMCE.isMSIE5_0 || tinyMCE.isOpera) - return ""; - - switch (control_name) { - case "zoom": - return ''; - } - - return ""; - }, - - /** - * Executes the mceZoom command. - */ - execCommand : function(editor_id, element, command, user_interface, value) { - // Handle commands - switch (command) { - case "mceZoom": - tinyMCE.getInstanceById(editor_id).contentDocument.body.style.zoom = value; - tinyMCE.getInstanceById(editor_id).contentDocument.body.style.mozZoom = value; - return true; - } - - // Pass to next handler in chain - return false; - } -}; - -tinyMCE.addPlugin("zoom", TinyMCE_ZoomPlugin); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/plugins/zoom/readme.txt --- a/includes/clientside/tinymce/plugins/zoom/readme.txt Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Check the TinyMCE documentation for details on this plugin. diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/switcher.js --- a/includes/clientside/tinymce/switcher.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -function readCookie(name) {var nameEQ = name + "=";var ca = document.cookie.split(';');for(var i=0;i < ca.length;i++){var c = ca[i];while (c.charAt(0)==' ') c = c.substring(1,c.length);if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);}return null;} -function createCookie(name,value,days){if (days){var date = new Date();date.setTime(date.getTime()+(days*24*60*60*1000));var expires = "; expires="+date.toGMTString();}else var expires = "";document.cookie = name+"="+value+expires+"; path=/";} -function eraseCookie(name) {createCookie(name,"",-1);} - -function initSwitcher() -{ - if(readCookie('tmce_demo_mode') == 'tinymce') - { - switchToMCE(); - } -} - -function switchToMCE() -{ - elem = document.getElementById('tMceEditor'); - tinyMCE.addMCEControl(elem, 'content', document); - createCookie('tmce_demo_mode', 'tinymce', 365); -} - -function switchToText() -{ - elem = document.getElementById('tMceEditor'); - tinyMCE.removeMCEControl('content'); - createCookie('tmce_demo_mode', 'text', 365); -} - -function switchEditor() -{ - if(readCookie('tmce_demo_mode') == 'tinymce') - { - switchToText(); - } - else - { - switchToMCE(); - } -} - -window.onload = initSwitcher; - -tinyMCE.init({ - mode : "exact", - elements : '', - theme_advanced_resize_horizontal : false, - theme_advanced_resizing : true, - theme_advanced_toolbar_location : "top", - theme_advanced_toolbar_align : "left", - theme_advanced_buttons1_add : "fontselect,fontsizeselect", - theme_advanced_statusbar_location : 'bottom' - }); - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/about.htm --- a/includes/clientside/tinymce/themes/advanced/about.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/advanced/about.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,35 +1,39 @@ + - {$lang_about_title} - - - - + {#advanced_dlg.about_title} + + + - +
-

{$lang_about_title}

-

Version: {$tinymce_version} ({$tinymce_releasedate})

+

{#advanced_dlg.about_title}

+

Version: ()

TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under LGPL by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREA fields or other HTML elements to editor instances.

Copyright © 2003-2007, Moxiecode Systems AB, All rights reserved.

For more information about this software visit the TinyMCE website.

-
+
+ Got Moxie? + Hosted By Sourceforge + Also on freshmeat +
-

{$lang_loaded_plugins}

+

{#advanced_dlg.about_loaded}

@@ -45,7 +49,7 @@
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/anchor.htm --- a/includes/clientside/tinymce/themes/advanced/anchor.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/advanced/anchor.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,33 +1,32 @@ + - {$lang_insert_anchor_title} - - + {#advanced_dlg.anchor_title} + + - - - + +
- + - +
{$lang_insert_anchor_title}{#advanced_dlg.anchor_title}
{$lang_insert_anchor_name}:{#advanced_dlg.anchor_name}:
- +
- +
- diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/charmap.htm --- a/includes/clientside/tinymce/themes/advanced/charmap.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/advanced/charmap.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,19 +1,19 @@ - {$lang_theme_charmap_title} + {#advanced_dlg.charmap_title} - - + + - + - + - ';deltaHeight-=23}template['html']+='
{$lang_theme_charmap_title}{#advanced_dlg.charmap_title}
- + + diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/color_picker.htm --- a/includes/clientside/tinymce/themes/advanced/color_picker.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/advanced/color_picker.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,27 +1,27 @@ + - {$lang_theme_colorpicker_title} - - - - + {#advanced_dlg.colorpicker_title} + + + - +
- {$lang_color_picker} + {#advanced_dlg.colorpicker_picker_title}
- +
@@ -34,7 +34,7 @@
- {$lang_web_colors} + {#advanced_dlg.colorpicker_palette_title}
@@ -45,7 +45,7 @@
- {$lang_named_colors} + {#advanced_dlg.colorpicker_named_title}
@@ -53,7 +53,7 @@
- {$lang_color_name} + {#advanced_dlg.colorpicker_name}
@@ -61,13 +61,13 @@
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/css/colorpicker.css --- a/includes/clientside/tinymce/themes/advanced/css/colorpicker.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* Colorpicker dialog specific CSS */ - -#preview { - float: right; - width: 50px; - height: 14px; - line-height: 1px; - border: 1px solid black; - margin-left: 5px; -} - -#colorpicker { - float: left; - cursor: crosshair; -} - -#light { - border: 1px solid gray; - margin-left: 5px; - float: left; - width: 15px; - cursor: crosshair; -} - -#light div { - overflow: hidden; -} - -#previewblock { - float: right; - padding-left: 10px; - height: 20px; -} - -.panel_wrapper div.current { - height: 175px; -} - -#namedcolors { - width: 150px; -} - -#namedcolors a { - display: block; - float: left; - width: 10px; height: 10px; - margin: 1px 1px 0 0; - overflow: hidden; -} - -#colornamecontainer { - margin-top: 5px; -} \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/css/editor_content.css --- a/includes/clientside/tinymce/themes/advanced/css/editor_content.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* This file contains the CSS data for the editable area(iframe) of TinyMCE */ -/* You can extend this CSS by adding your own CSS file with the the content_css option */ - -body, td, pre { - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 10px; -} - -body { - background-color: #FFFFFF; -} - -.mceVisualAid { - border: 1px dashed #BBBBBB !important; -} - -div.mceVisualAid { - background-image:url('../images/spacer.gif'); - visibility: visible !important; -} - -.mceItemAnchor { - width: 12px; - line-height: 6px; - overflow: hidden; - padding-left: 12px; - background-image: url('../images/anchor_symbol.gif'); - background-position: bottom; - background-repeat: no-repeat; -} - -/* Important is needed in Gecko browsers inorder to style links */ -/* -a { - color: green !important; -} -*/ - -/* Style selection range colors in Gecko browsers */ -/* -::-moz-selection { - background-color: red; - color: green; -} -*/ - -/* MSIE specific */ - -* html body { - scrollbar-3dlight-color: #F0F0EE; - scrollbar-arrow-color: #676662; - scrollbar-base-color: #F0F0EE; - scrollbar-darkshadow-color: #DDDDDD; - scrollbar-face-color: #E0E0DD; - scrollbar-highlight-color: #F0F0EE; - scrollbar-shadow-color: #F0F0EE; - scrollbar-track-color: #F5F5F5; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/css/editor_popup.css --- a/includes/clientside/tinymce/themes/advanced/css/editor_popup.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,331 +0,0 @@ -/* This file contains the CSS data for all popups in TinyMCE */ - -body { - background-color: #F0F0EE; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 11px; - scrollbar-3dlight-color: #F0F0EE; - scrollbar-arrow-color: #676662; - scrollbar-base-color: #F0F0EE; - scrollbar-darkshadow-color: #DDDDDD; - scrollbar-face-color: #E0E0DD; - scrollbar-highlight-color: #F0F0EE; - scrollbar-shadow-color: #F0F0EE; - scrollbar-track-color: #F5F5F5; - margin: 8px; -} - -td { - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 11px; -} - -input { - background: #FFFFFF; - border: 1px solid #cccccc; -} - -td, input, select, textarea { - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 10px; -} - -input, select, textarea { - border: 1px solid #808080; -} - -.input_noborder { - border: 0; -} - -#insert, .updateButton { - font-weight: bold; - width: 90px; - height: 21px; - border: 0; - background-image: url('../images/insert_button_bg.gif'); - cursor: pointer; -} - -#cancel { - font-weight: bold; - width: 90px; - height: 21px; - border: 0; - background-image: url('../images/cancel_button_bg.gif'); - cursor: pointer; -} - -/* Mozilla only style */ -html>body #insert, html>body #cancel { - padding-bottom: 2px; -} - -.title { - font-size: 12px; - font-weight: bold; - color: #2B6FB6; -} - -table.charmap { - border-style: solid; - border-width: 1px; - border-color: #AAAAAA; -} - -td.charmap, td.charmapOver { - color: #000000; - border-color: #AAAAAA; - border-style: solid; - border-width: 1px; - text-align: center; - font-size: 12px; -} - -td.charmapOver { - background-color: #CCCCCC; - cursor: default; -} - -a.charmap { - color: #000000; - text-decoration: none -} - -.wordWrapCode { - vertical-align: middle; - border: 1px none #000000; - background-color: transparent; -} - -input.radio { - border: 1px none #000000; - background-color: transparent; - vertical-align: middle; -} - -input.checkbox { - border: 1px none #000000; - background-color: transparent; - vertical-align: middle; -} - -.mceButtonNormal, .mceButtonOver, .mceButtonDown, .mceSeparator, .mceButtonDisabled, .mceButtonSelected { - margin-left: 1px; -} - -.mceButtonNormal { - border-top: 1px solid; - border-left: 1px solid; - border-bottom: 1px solid; - border-right: 1px solid; - border-color: #F0F0EE; - cursor: default; -} - -.mceButtonOver { - border: 1px solid #0A246A; - cursor: default; - background-color: #B6BDD2; -} - -.mceButtonDown { - cursor: default; - border: 1px solid #0A246A; - background-color: #8592B5; -} - -.mceButtonDisabled { - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - -moz-opacity:0.3; - opacity: 0.3; - border-top: 1px solid; - border-left: 1px solid; - border-bottom: 1px solid; - border-right: 1px solid; - border-color: #F0F0EE; - cursor: default; -} - -.mceActionPanel { - margin-top: 5px; -} - -/* Tabs classes */ - -.tabs { - float: left; - width: 100%; - line-height: normal; - background-image: url("../images/xp/tabs_bg.gif"); -} - -.tabs ul { - margin: 0; - padding: 0 0 0; - list-style: none; -} - -.tabs li { - float: left; - background: url("../images/xp/tab_bg.gif") no-repeat left top; - margin: 0; - margin-left: 0; - margin-right: 2px; - padding: 0 0 0 10px; - line-height: 18px; -} - -.tabs li.current { - background: url("../images/xp/tab_sel_bg.gif") no-repeat left top; - margin-right: 2px; -} - -.tabs span { - float: left; - display: block; - background: url("../images/xp/tab_end.gif") no-repeat right top; - padding: 0px 10px 0 0; -} - -.tabs .current span { - background: url("../images/xp/tab_sel_end.gif") no-repeat right top; -} - -.tabs a { - text-decoration: none; - font-family: Verdana, Arial; - font-size: 10px; -} - -.tabs a:link, .tabs a:visited, .tabs a:hover { - color: black; -} - -.tabs a:hover { -} - -.tabs .current { -} - -.tabs .current a, .tabs .current a:link, .tabs .current a:visited { -} - -.panel_wrapper div.panel { - display: none; -} - -.panel_wrapper div.current { - display: block; - width: 100%; - height: 300px; - overflow: visible; /* Should be auto but that breaks Safari */ -} - -.panel_wrapper { - border: 1px solid #919B9C; - border-top: 0px; - padding: 10px; - padding-top: 5px; - clear: both; - background-color: white; -} - -fieldset { - border: 1px solid #919B9C; - font-family: Verdana, Arial; - font-size: 10px; - padding: 0; - margin: 0; - padding: 4px; -} - -legend { - color: #2B6FB6; - font-weight: bold; -} - -.properties { - width: 100%; -} - -.properties .column1 { -} - -.properties .column2 { - text-align: left; -} - -a:link, a:visited { - color: black; -} - -a:hover { - color: #2B6FB6; -} - -#plugintable thead { - font-weight: bold; - background-color: #DDDDDD; -} - -#plugintable, #about #plugintable td { - border: 1px solid #919B9C; -} - -#plugintable { - width: 99%; - margin-top: 10px; -} - -#pluginscontainer { - height: 290px; - overflow: auto; -} - -/* MSIE Specific styles */ - -* html .panel_wrapper { - width: 100%; -} - -.column { - float: left; -} - -h1, h2, h3, h4 { - color: #2B6FB6; - margin: 0; - padding: 0; - padding-top: 5px; -} - -h3 { - font-size: 14px; -} - -#link .panel_wrapper, #link div.current { - height: 125px; -} - -#image .panel_wrapper, #image div.current { - height: 190px; -} - -label.msg { display: none; } -label.invalid { color: #EE0000; display: inline; } -input.invalid { border: 1px solid #EE0000; } - -/* Disables the advanced tab in the table plugin. */ -/* -#table #advanced_tab { - display: none; -} -*/ - -/* Disables the border input field and label in the table plugin. */ -/* -#table #border, #table #borderlabel { - display: none; -} -*/ diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/css/editor_ui.css --- a/includes/clientside/tinymce/themes/advanced/css/editor_ui.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* This file contains the CSS data for the editor UI of TinyMCE instances */ - -.mceToolbarTop a, .mceToolbarTop a:visited, .mceToolbarTop a:hover, .mceToolbarBottom a, .mceToolbarBottom a:visited, .mceToolbarBottom a:hover {border: 0; margin: 0; padding: 0; background: transparent;} -.mceSeparatorLine {border: 0; padding: 0; margin-left: 4px; margin-right: 2px;} -.mceSelectList {font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; font-size: 7pt !important; font-weight: normal; margin-top: 3px; padding: 0; display: inline; vertical-align: top; background-color: #F0F0EE;} -.mceLabel, .mceLabelDisabled {font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; font-size: 9pt;} -.mceLabel {color: #000000;} -.mceLabelDisabled {cursor: text; color: #999999;} -.mceEditor {background: #F0F0EE; border: 1px solid #cccccc; padding: 0; margin: 0;} -.mceEditorArea { font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; background: #FFFFFF; padding: 0; margin: 0; } -.mceToolbarTop, .mceToolbarBottom {background: #F0F0EE; line-height: 1px; font-size: 1px;} -.mceToolbarTop {border-bottom: 1px solid #cccccc; padding-bottom: 1px;} -.mceToolbarBottom {border-top: 1px solid #cccccc;} -.mceToolbarContainer {display: block; position: relative; left: 0; top: 0; width: 100%;} -.mceStatusbarTop, .mceStatusbarBottom, .mceStatusbar {height: 20px;} -.mceStatusbarTop .mceStatusbarPathText, .mceStatusbarBottom .mceStatusbarPathText, .mceStatusbar .mceStatusbarPathText {font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; font-size: 9pt; padding: 2px; line-height: 16px; overflow: visible;} -.mceStatusbarTop {border-bottom: 1px solid #cccccc;} -.mceStatusbarBottom {border-top: 1px solid #cccccc;} -.mceStatusbar {border-bottom: 1px solid #cccccc;} -.mcePathItem, .mcePathItem:link, .mcePathItem:visited, .mcePathItem:hover {text-decoration: none; font-family: 'MS Sans Serif', sans-serif, Verdana, Arial; font-size: 9pt; color: #000000;} -.mcePathItem:hover {text-decoration: underline;} -.mceStatusbarPathText {float: left;} -.mceStatusbarResize {float: right; background-image: url('../images/statusbar_resize.gif'); background-repeat: no-repeat; width: 11px; height: 20px; cursor: se-resize;} -.mceResizeBox {width: 10px; height: 10px; display: none; border: 1px dotted gray; margin: 0; padding: 0;} -.mceEditorIframe {border: 0;} - -/* Button CSS rules */ - -a.mceButtonDisabled img, a.mceButtonNormal img, a.mceButtonSelected img {width: 20px; height: 20px; cursor: default; margin-top: 1px; margin-left: 1px;} -a.mceButtonDisabled img {border: 0 !important;} -a.mceButtonNormal img, a.mceButtonSelected img {border: 1px solid #F0F0EE !important;} -a.mceButtonSelected img {border: 1px solid #6779AA !important; background-color: #D4D5D8;} -a.mceButtonNormal img:hover, a.mceButtonSelected img:hover {border: 1px solid #0A246A !important; cursor: default; background-color: #B6BDD2;} -a.mceButtonDisabled img {-moz-opacity:0.3; opacity: 0.3; border: 1px solid #F0F0EE !important; cursor: default;} -a.mceTiledButton img {background-image: url('../images/buttons.gif'); background-repeat: no-repeat;} - -/* Menu button CSS rules */ - -span.mceMenuButton img, span.mceMenuButtonSelected img {border: 1px solid #F0F0EE; margin-left: 1px;} -span.mceMenuButtonSelected img {border: 1px solid #6779AA; background-color: #B6BDD2;} -span.mceMenuButtonSelected img.mceMenuButton {border: 1px solid #F0F0EE; background-color: transparent;} -span.mceMenuButton img.mceMenuButton, span.mceMenuButtonSelected img.mceMenuButton {border-left: 0; margin-left: 0;} -span.mceMenuButton:hover img, span.mceMenuButtonSelected:hover img {border: 1px solid #0A246A; background-color: #B6BDD2;} -span.mceMenuButton:hover img.mceMenuButton, span.mceMenuButtonSelected:hover img.mceMenuButton {border-left: 0;} -span.mceMenuButtonFocus img {border: 1px solid gray; border-right: 0; margin-left: 1px; background-color: #F5F4F2;} -span.mceMenuButtonFocus img.mceMenuButton {border: 1px solid gray; border-left: 1px solid #F5F4F2; margin-left: 0;} -span.mceMenuHover img {border: 1px solid #0A246A; background-color: #B6BDD2;} -span.mceMenuButtonSelected.mceMenuHover img.mceMenuButton {border: 1px solid #0A246A; background-color: #B6BDD2; border-left: 0;} - -/* Menu */ - -.mceMenu {position: absolute; left: 0; top: 0; display: none; z-index: 1000; background-color: white; border: 1px solid gray; font-weight: normal;} -.mceMenu a, .mceMenuTitle, .mceMenuDisabled {display: block; width: 100%; text-decoration: none; background-color: white; font-family: Tahoma, Verdana, Arial, Helvetica; font-size: 11px; line-height: 20px; color: black;} -.mceMenu a:hover {background-color: #B6BDD2; color: black; text-decoration: none !important;} -.mceMenu span {padding-left: 10px; padding-right: 10px; display: block; line-height: 20px;} -.mceMenuSeparator {border-bottom: 1px solid gray; background-color: gray; height: 1px;} -.mceMenuTitle span {padding-left: 5px;} -.mceMenuTitle {background-color: #DDDDDD; font-weight: bold;} -.mceMenuDisabled {color: gray;} -span.mceMenuSelectedItem {background-image: url('../images/menu_check.gif'); background-repeat: no-repeat; background-position: 5px 8px; padding-left: 20px;} -span.mceMenuCheckItem {padding-left: 20px;} -span.mceMenuLine {display: block; position: absolute; left: 0; top: -1px; background-color: #F5F4F2; width: 30px; height: 1px; overflow: hidden; padding-left: 0; padding-right: 0;} -.mceColors table, .mceColors td {margin: 0; padding: 2px;} -a.mceMoreColors {width: auto; padding: 0; margin: 0 3px 3px 3px; text-align: center; border: 1px solid white; text-decoration: none !important;} -.mceColorPreview {position: absolute; overflow:hidden; left: 0; top: 0; margin-left: 3px; margin-top: 15px; width: 16px; height: 4px; background-color: red;} -a.mceMoreColors:hover {border: 1px solid #0A246A;} -.mceColors td a {width: 9px; height: 9px; overflow: hidden; border: 1px solid #808080;} - -/* MSIE 6 specific rules */ - -* html a.mceButtonNormal img, * html a.mceButtonSelected img, * html a.mceButtonDisabled img {border: 0 !important; margin-top: 2px; margin-bottom: 1px;} -* html a.mceButtonDisabled img {/* \*/ filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); /* */ border: 0 !important;} -* html a.mceButtonDisabled {border: 1px solid #F0F0EE !important;} -* html a.mceButtonNormal, * html a.mceButtonSelected {border: 1px solid #F0F0EE !important; cursor: default;} -* html a.mceButtonSelected {border: 1px solid #6779AA !important; background-color: #D4D5D8;} -* html a.mceButtonNormal:hover, * html a.mceButtonSelected:hover {border: 1px solid #0A246A !important; background-color: #B6BDD2; cursor: default;} -* html .mceSelectList {margin-top: 2px;} -* html span.mceMenuButton, * html span.mceMenuButtonFocus {position: relative; left: 0; top: 0;} -* html span.mceMenuButton img, * html span.mceMenuButtonSelected img, * html span.mceMenuButtonFocus img {position: relative; top: 1px;} -* html a.mceMoreColors {width: auto;} -* html .mceColors td a {width: 10px; height: 10px;} -* html .mceColorPreview {margin-left: 2px; margin-top: 14px;} - -/* MSIE 7 specific rules */ - -*:first-child+html a.mceButtonNormal img, *:first-child+html a.mceButtonSelected img, *:first-child+html a.mceButtonDisabled img {border: 0 !important; margin-top: 2px; margin-bottom: 1px;} -*:first-child+html a.mceButtonDisabled img { /* \*/ filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); /* */ border: 0 !important;} -*:first-child+html a.mceButtonDisabled {border: 1px solid #F0F0EE !important;} -*:first-child+html a.mceButtonNormal, *:first-child+html a.mceButtonSelected {border: 1px solid #F0F0EE !important; cursor: default;} -*:first-child+html a.mceButtonSelected {border: 1px solid #6779AA !important; background-color: #D4D5D8;} -*:first-child+html a.mceButtonNormal:hover, *:first-child+html a.mceButtonSelected:hover {border: 1px solid #0A246A !important; background-color: #B6BDD2; cursor: default;} -*:first-child+html .mceSelectList {margin-top: 2px;} -*:first-child+html span.mceMenuButton, *:first-child+html span.mceMenuButtonFocus {position: relative; left: 0; top: 0;} -*:first-child+html span.mceMenuButton img, *:first-child+html span.mceMenuButtonSelected img, *:first-child+html span.mceMenuButtonFocus img {position: relative; top: 1px;} -*:first-child+html a.mceMoreColors {width: 137px;} -*:first-child+html .mceColors td a {width: 10px; height: 10px;} -*:first-child+html .mceColorPreview {margin: 0; padding-left: 4px; margin-top: 14px; width: 14px;} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/about.htm --- a/includes/clientside/tinymce/themes/advanced/docs/en/about.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ - - -About TinyMCE - - - - - -
- - - - - -
-
-TinyMCE is a small WYSIWYG editor control for web browsers such as MSIE or Mozilla -that enables you to edit HTML contents in a more user friendly way. It has common -features that are found in most word processors and should not be difficult to -use.
-
-
- - - - - - -
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/common_buttons.htm --- a/includes/clientside/tinymce/themes/advanced/docs/en/common_buttons.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ - - -Common buttons - - - - - - - - - - - -
-
-Below is a short description about each button. -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bold text iconBold text style (Ctrl+B).
Italic text iconItalic text style (Ctrl+I).
Underline text icon.Underline text style (Ctrl+U).
Strikethrough text icon.Strikethrough text style.
Align left icon.Align left.
Align center icon.Align center.
Align right icon.Align right.
Align full icon.Align full.
Unordered list/bullet list icon.Unordered list/bullet list.
Ordered list/numbered list icon.Ordered list/numbered list
Outdent/decrease indentation icon.Outdent/decrease indentation.
Indent/increase indentation icon.Indent/increase indentation.
Undo the last operation.Undo the last operation (Ctrl+Z).
Redo the last operation icon.Redo the last operation (Ctrl+Y).
Insert a new link icon.Insert a new link, read more about this function in the Insert - link section.
Unlinks the current selection icon.Unlinks the current selection/removes all selected links.
Insert a new anchor icon.Insert a new anchor, read more about this function in the Insert anchor section.
Insert a new image icon.Insert a new image, read more about this function in the Insert - image section.
Cleanup code icon.Cleanup code/Removes unwanted formating. This function is useful when - you copy contents from for example a office product.
Show help icon.Shows this help window.
Source code editor icon.Opens HTML source code editor.
Insert table icon.Inserts a new table at the current location.
Adds a row above icon.Adds a row above the current one.
Adds a row under icon.Adds a row under the current one.
Remove row icon.Removes the row.
Add column before icon.Adds a column before the current one.
Add column after icon.Adds a column after the current one.
Remove column icon.Removes the current column.
Insert horizontal ruler icon.Inserts a new horizontal ruler
Remove formatting icon.Removes formatting from the selection.
Subscript icon.Makes the selection to be subscript.
Superscript icon.Makes the selection to be superscripted.
-
-
- - - - - - - - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/create_accessible_content.htm --- a/includes/clientside/tinymce/themes/advanced/docs/en/create_accessible_content.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ - - -Insert table button - - - - - - - - - - - -
-

TinyMCE can create HTML content that will be accessible to all users, including those with disabilities using assistive technologies, as well as those using text-based browsers, or those browsing the Web with images turned off.

- -

Things you can do to make your content accessible:

-
    -
  1. Include an Image Description: Blind users, or others who are unable to view images, will rely on the Image Description (or Alt text) to take the place of the image. If an image contains no meaning, such as a decoration or a spacer image, leave the Image Description empty. TinyMCE will then insert an empty Alt text attribute that will force assistive technologies to ignore the image.

  2. - -
  3. Add Scope to data table header cells: In the table cell editor dialog window, choose a Scope when creating Header cells so the column or row label in that cell becomes explicitely associated with its data cells. Table cell headers will then be announced with each data cell, making it easier for blind users using a screen reader to understand what the content of each cell represents.

  4. - -
  5. Structure content with properly nested headings: In the format selection menu choose Heading 1 to Heading 6 to represent headings in your content, rather than using other font formating options. Blind users using a screen reader can then extract the headings from the page to generate a summary of the content it contains, and use those headings to navigate quickly to subsections within the page.

  6. - -
  7. Include alternate content: Create an alternate page for non-HTML content such as Flash, Java applets, or embedded movies. This might be a static image, with a description of the image, and a description of the content that would have appeared in its place. An alternate HTML page could also be created, and a link to it included next to the non-HTML object. This will ensure that the content will be accessible to users of assistive technologies that can not view or play the content, and ensure the content will be available to those who do not have the appropriate plugin or helper application installed.

  8. - -
  9. Check accessbility: When the AChecker plugin is installed with TinyMCE, click on the Check Accessibility button to generate a report of potential accessibility problems.

  10. - -
- -

See the AChecker Web Site for further details about creating content that will be accessible to all users.
-

- -
- - - - - - - -
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/images/insert_anchor_window.gif Binary file includes/clientside/tinymce/themes/advanced/docs/en/images/insert_anchor_window.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/images/insert_image_window.gif Binary file includes/clientside/tinymce/themes/advanced/docs/en/images/insert_image_window.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/images/insert_link_window.gif Binary file includes/clientside/tinymce/themes/advanced/docs/en/images/insert_link_window.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/images/insert_table_window.gif Binary file includes/clientside/tinymce/themes/advanced/docs/en/images/insert_table_window.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/index.htm --- a/includes/clientside/tinymce/themes/advanced/docs/en/index.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ - - -Help Index - - - - - - - - - -
-
-Click the links below to go to the different help sections. - -
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/insert_anchor_button.htm --- a/includes/clientside/tinymce/themes/advanced/docs/en/insert_anchor_button.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ - - -Insert anchor button - - - - - - - - - - - -
-
-This button opens a new window with the insert/edit anchor function.
-
-Anchor dialog/window
-
-There are one field in this window, this is where you enter the name of you anchor point. Remember the anchor name needs to be unique.
-
-
- - - - - - -
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/insert_image_button.htm --- a/includes/clientside/tinymce/themes/advanced/docs/en/insert_image_button.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ - - -Insert image button - - - - - - - - - - - -
-
-The insert image button opens the window shown below.
-
-Insert image dialog/window
-
-You simply enter a URL to the image you want to link to and enter a image description, -this is then displayed as an alternative text descripton of the image on the page.
-
-Field descriptions:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Image URL URL/path to the image.
Image description Alternative description of image contents.
DimentionsImage width/height.
AlignmentImage alignment, useful when wrapping text around images.
BorderBorder thickness.
VSpaceVertical space, useful when wrapping text around images.
HSpaceHorizontal space, useful when wrapping text around images.
-
-
- - - - - - -
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/insert_link_button.htm --- a/includes/clientside/tinymce/themes/advanced/docs/en/insert_link_button.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ - - -Insert link button - - - - - - - - - - - -
-
-This button opens a new window with the insert/edit link function.
-
-Insert link dialog/window
-
-There are two fields in this window the first one "Link URL" is the -URL of the link. The target enables you to select how the link is to be opened.
-
-
- - - - - - -
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/insert_table_button.htm --- a/includes/clientside/tinymce/themes/advanced/docs/en/insert_table_button.htm Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ - - -Insert table button - - - - - - - - - - - -
-
-The insert table button opens the window shown below. This action enables you to create tables.
-
-Image of table window
-
-Field descriptions:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ColumnsNumber of columns in the table.
RowsNumber of rows in the new table.
CellpaddingCellpadding of the table .
CellspacingCellspacing of the table .
AlignmentTable alignment .
BorderBorder thinkness of table.
WidthWidth in pixels of table .
HeightHeight in pixels of table.
ClassStyle or CSS class of table.
-
-
-
- - - - - - -
- - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/docs/en/style.css --- a/includes/clientside/tinymce/themes/advanced/docs/en/style.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -body { background-color: #FFFFFF; } -body, td, .content { font-family: Verdana, Arial, helvetica, sans-serif; font-size: 12px; } -.title { font-family: Verdana, Arial, helvetica, sans-serif; font-size: 16px; font-weight: bold; } -.subtitle { font-size: 12px; font-weight: bold; } - -.toc_ul, .toc_li { margin-left: 8px; line-height: 16px; } -.step_ol, .step_li { margin-left: 11px; line-height: 16px; } -img { border: #000000 solid 1px; } - -a:visited { color: #666666; text-decoration: underline; } -a:active { color: #666666; text-decoration: underline; } -a:hover { color: #666666; text-decoration: underline; } -a { color: #666666; text-decoration: underline; } - -.pageheader { border: #E0E0E0 solid 1px; } -.pagefooter { border: #E0E0E0 solid 1px; } -.sample { background-color: #FFFFFF; border: #000000 solid 1px; } -.samplecontent { font-size: 10px; } - -.code { background-color: #FFFFFF; border: #000000 solid 1px; } -.codecontent { font-size: 10px; } -.codecontent a:visited { color: #666666; text-decoration: none; font-weight: bold } -.codecontent a:active { color: #666666; text-decoration: none; font-weight: bold } -.codecontent a:hover { color: #666666; text-decoration: none; font-weight: bold } -.codecontent a { color: #666666; text-decoration: none; font-weight: bold } - -hr { height: 1px; } - diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/editor_template.js --- a/includes/clientside/tinymce/themes/advanced/editor_template.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/advanced/editor_template.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -tinyMCE.importThemeLanguagePack('advanced');var TinyMCE_AdvancedTheme={_defColors:"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",_autoImportCSSClasses:true,_resizer:{},_buttons:[['bold','{$lang_bold_img}','lang_bold_desc','Bold'],['italic','{$lang_italic_img}','lang_italic_desc','Italic'],['underline','{$lang_underline_img}','lang_underline_desc','Underline'],['strikethrough','strikethrough.gif','lang_striketrough_desc','Strikethrough'],['justifyleft','justifyleft.gif','lang_justifyleft_desc','JustifyLeft'],['justifycenter','justifycenter.gif','lang_justifycenter_desc','JustifyCenter'],['justifyright','justifyright.gif','lang_justifyright_desc','JustifyRight'],['justifyfull','justifyfull.gif','lang_justifyfull_desc','JustifyFull'],['bullist','bullist.gif','lang_bullist_desc','InsertUnorderedList'],['numlist','numlist.gif','lang_numlist_desc','InsertOrderedList'],['outdent','outdent.gif','lang_outdent_desc','Outdent'],['indent','indent.gif','lang_indent_desc','Indent'],['cut','cut.gif','lang_cut_desc','Cut'],['copy','copy.gif','lang_copy_desc','Copy'],['paste','paste.gif','lang_paste_desc','Paste'],['undo','undo.gif','lang_undo_desc','Undo'],['redo','redo.gif','lang_redo_desc','Redo'],['link','link.gif','lang_link_desc','mceLink',true],['unlink','unlink.gif','lang_unlink_desc','unlink'],['image','image.gif','lang_image_desc','mceImage',true],['cleanup','cleanup.gif','lang_cleanup_desc','mceCleanup'],['help','help.gif','lang_help_desc','mceHelp'],['code','code.gif','lang_theme_code_desc','mceCodeEditor'],['hr','hr.gif','lang_theme_hr_desc','inserthorizontalrule'],['removeformat','removeformat.gif','lang_theme_removeformat_desc','removeformat'],['sub','sub.gif','lang_theme_sub_desc','subscript'],['sup','sup.gif','lang_theme_sup_desc','superscript'],['forecolor','forecolor.gif','lang_theme_forecolor_desc','forecolor',true],['forecolorpicker','forecolor.gif','lang_theme_forecolor_desc','forecolorpicker',true],['backcolor','backcolor.gif','lang_theme_backcolor_desc','HiliteColor',true],['backcolorpicker','backcolor.gif','lang_theme_backcolor_desc','backcolorpicker',true],['charmap','charmap.gif','lang_theme_charmap_desc','mceCharMap'],['visualaid','visualaid.gif','lang_theme_visualaid_desc','mceToggleVisualAid'],['anchor','anchor.gif','lang_theme_anchor_desc','mceInsertAnchor'],['newdocument','newdocument.gif','lang_newdocument_desc','mceNewDocument']],_buttonMap:'anchor,backcolor,bold,bullist,charmap,cleanup,code,copy,cut,forecolor,help,hr,image,indent,italic,justifycenter,justifyfull,justifyleft,justifyright,link,newdocument,numlist,outdent,paste,redo,removeformat,strikethrough,sub,sup,underline,undo,unlink,visualaid,advhr,ltr,rtl,emotions,flash,fullpage,fullscreen,iespell,insertdate,inserttime,pastetext,pasteword,selectall,preview,print,save,replace,search,table,cell_props,delete_col,delete_row,col_after,col_before,row_after,row_before,merge_cells,row_props,split_cells,delete_table',getControlHTML:function(button_name){var i,x,but;for(i=0;i4?but[4]:false),(but.length>5?but[5]:null));if(but[0]==button_name)return tinyMCE.getButtonHTML(but[0],but[2],'{$themeurl}/images/'+but[1],but[3],(but.length>4?but[4]:false),(but.length>5?but[5]:null))}switch(button_name){case"formatselect":var html='';return html;case"styleselect":return'';case"fontselect":var fontHTML='';return fontHTML;case"fontsizeselect":return'';case"|":case"separator":return'';case"spacer":return'';case"rowseparator":return'
'}return""},execCommand:function(editor_id,element,command,user_interface,value){switch(command){case'mceHelp':tinyMCE.openWindow({file:'about.htm',width:480,height:380},{tinymce_version:tinyMCE.majorVersion+"."+tinyMCE.minorVersion,tinymce_releasedate:tinyMCE.releaseDate,inline:"yes"});return true;case"mceLink":var inst=tinyMCE.getInstanceById(editor_id);var doc=inst.getDoc();var selectedText="";if(tinyMCE.isMSIE){var rng=doc.selection.createRange();selectedText=rng.text}else selectedText=inst.getSel().toString();if(!tinyMCE.linkElement){if((tinyMCE.selectedElement.nodeName.toLowerCase()!="img")&&(selectedText.length<=0))return true}var href="",target="",title="",onclick="",action="insert",style_class="";if(tinyMCE.selectedElement.nodeName.toLowerCase()=="a")tinyMCE.linkElement=tinyMCE.selectedElement;if(tinyMCE.linkElement!=null&&tinyMCE.getAttrib(tinyMCE.linkElement,'href')=="")tinyMCE.linkElement=null;if(tinyMCE.linkElement){href=tinyMCE.getAttrib(tinyMCE.linkElement,'href');target=tinyMCE.getAttrib(tinyMCE.linkElement,'target');title=tinyMCE.getAttrib(tinyMCE.linkElement,'title');onclick=tinyMCE.getAttrib(tinyMCE.linkElement,'onclick');style_class=tinyMCE.getAttrib(tinyMCE.linkElement,'class');if(onclick=="")onclick=tinyMCE.getAttrib(tinyMCE.linkElement,'onclick');onclick=tinyMCE.cleanupEventStr(onclick);href=eval(tinyMCE.settings['urlconverter_callback']+"(href, tinyMCE.linkElement, true);");mceRealHref=tinyMCE.getAttrib(tinyMCE.linkElement,'mce_href');if(mceRealHref!=""){href=mceRealHref;if(tinyMCE.getParam('convert_urls'))href=eval(tinyMCE.settings['urlconverter_callback']+"(href, tinyMCE.linkElement, true);")}action="update"}var template=new Array();template['file']='link.htm';template['width']=310;template['height']=200;template['width']+=tinyMCE.getLang('lang_insert_link_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_link_delta_height',0);if(inst.settings['insertlink_callback']){var returnVal=eval(inst.settings['insertlink_callback']+"(href, target, title, onclick, action, style_class);");if(returnVal&&returnVal['href'])TinyMCE_AdvancedTheme._insertLink(returnVal['href'],returnVal['target'],returnVal['title'],returnVal['onclick'],returnVal['style_class'])}else{tinyMCE.openWindow(template,{href:href,target:target,title:title,onclick:onclick,action:action,className:style_class,inline:"yes"})}return true;case"mceImage":var src="",alt="",border="",hspace="",vspace="",width="",height="",align="";var title="",onmouseover="",onmouseout="",action="insert";var img=tinyMCE.imgElement;var inst=tinyMCE.getInstanceById(editor_id);if(tinyMCE.selectedElement!=null&&tinyMCE.selectedElement.nodeName.toLowerCase()=="img"){img=tinyMCE.selectedElement;tinyMCE.imgElement=img}if(img){if(tinyMCE.getAttrib(img,'name').indexOf('mce_')==0)return true;src=tinyMCE.getAttrib(img,'src');alt=tinyMCE.getAttrib(img,'alt');if(alt=="")alt=tinyMCE.getAttrib(img,'title');if(tinyMCE.isGecko){var w=img.style.width;if(w!=null&&w!="")img.setAttribute("width",w);var h=img.style.height;if(h!=null&&h!="")img.setAttribute("height",h)}border=tinyMCE.getAttrib(img,'border');hspace=tinyMCE.getAttrib(img,'hspace');vspace=tinyMCE.getAttrib(img,'vspace');width=tinyMCE.getAttrib(img,'width');height=tinyMCE.getAttrib(img,'height');align=tinyMCE.getAttrib(img,'align');onmouseover=tinyMCE.getAttrib(img,'onmouseover');onmouseout=tinyMCE.getAttrib(img,'onmouseout');title=tinyMCE.getAttrib(img,'title');if(tinyMCE.isMSIE){width=img.attributes['width'].specified?width:"";height=img.attributes['height'].specified?height:""}src=eval(tinyMCE.settings['urlconverter_callback']+"(src, img, true);");mceRealSrc=tinyMCE.getAttrib(img,'mce_src');if(mceRealSrc!=""){src=mceRealSrc;if(tinyMCE.getParam('convert_urls'))src=eval(tinyMCE.settings['urlconverter_callback']+"(src, img, true);")}action="update"}var template=new Array();template['file']='image.htm?src={$src}';template['width']=355;template['height']=265+(tinyMCE.isMSIE?25:0);template['width']+=tinyMCE.getLang('lang_insert_image_delta_width',0);template['height']+=tinyMCE.getLang('lang_insert_image_delta_height',0);if(inst.settings['insertimage_callback']){var returnVal=eval(inst.settings['insertimage_callback']+"(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);");if(returnVal&&returnVal['src'])TinyMCE_AdvancedTheme._insertImage(returnVal['src'],returnVal['alt'],returnVal['border'],returnVal['hspace'],returnVal['vspace'],returnVal['width'],returnVal['height'],returnVal['align'],returnVal['title'],returnVal['onmouseover'],returnVal['onmouseout'])}else tinyMCE.openWindow(template,{src:src,alt:alt,border:border,hspace:hspace,vspace:vspace,width:width,height:height,align:align,title:title,onmouseover:onmouseover,onmouseout:onmouseout,action:action,inline:"yes"});return true;case"forecolor":var fcp=new TinyMCE_Layer(editor_id+'_fcPreview',false),p,img,elm;TinyMCE_AdvancedTheme._hideMenus(editor_id);if(!fcp.exists()){fcp.create('div','mceColorPreview',document.getElementById(editor_id+'_toolbar'));elm=fcp.getElement();elm._editor_id=editor_id;elm._command="forecolor";elm._switchId=editor_id+"_forecolor";tinyMCE.addEvent(elm,'click',TinyMCE_AdvancedTheme._handleMenuEvent);tinyMCE.addEvent(elm,'mouseover',TinyMCE_AdvancedTheme._handleMenuEvent);tinyMCE.addEvent(elm,'mouseout',TinyMCE_AdvancedTheme._handleMenuEvent)}img=tinyMCE.selectNodes(document.getElementById(editor_id+"_forecolor"),function(n){return n.nodeName=="IMG"})[0];p=tinyMCE.getAbsPosition(img,document.getElementById(editor_id+'_toolbar'));fcp.moveTo(p.absLeft,p.absTop);fcp.getElement().style.backgroundColor=value!=null?value:tinyMCE.getInstanceById(editor_id).foreColor;fcp.show();return false;case"forecolorpicker":this._pickColor(editor_id,'forecolor');return true;case"forecolorMenu":TinyMCE_AdvancedTheme._hideMenus(editor_id);var ml=new TinyMCE_Layer(editor_id+'_fcMenu');if(!ml.exists())ml.create('div','mceMenu',document.body,TinyMCE_AdvancedTheme._getColorHTML(editor_id,'theme_advanced_text_colors','forecolor'));tinyMCE.switchClass(editor_id+'_forecolor','mceMenuButtonFocus');ml.moveRelativeTo(document.getElementById(editor_id+"_forecolor"),'bl');ml.moveBy(tinyMCE.isMSIE&&!tinyMCE.isOpera?-1:1,-1);if(tinyMCE.isOpera)ml.moveBy(0,-2);ml.show();return true;case"HiliteColor":var bcp=new TinyMCE_Layer(editor_id+'_bcPreview',false),p,img;TinyMCE_AdvancedTheme._hideMenus(editor_id);if(!bcp.exists()){bcp.create('div','mceColorPreview',document.getElementById(editor_id+'_toolbar'));elm=bcp.getElement();elm._editor_id=editor_id;elm._command="HiliteColor";elm._switchId=editor_id+"_backcolor";tinyMCE.addEvent(elm,'click',TinyMCE_AdvancedTheme._handleMenuEvent);tinyMCE.addEvent(elm,'mouseover',TinyMCE_AdvancedTheme._handleMenuEvent);tinyMCE.addEvent(elm,'mouseout',TinyMCE_AdvancedTheme._handleMenuEvent)}img=tinyMCE.selectNodes(document.getElementById(editor_id+"_backcolor"),function(n){return n.nodeName=="IMG"})[0];p=tinyMCE.getAbsPosition(img,document.getElementById(editor_id+'_toolbar'));bcp.moveTo(p.absLeft,p.absTop);bcp.getElement().style.backgroundColor=value!=null?value:tinyMCE.getInstanceById(editor_id).backColor;bcp.show();return false;case"HiliteColorMenu":TinyMCE_AdvancedTheme._hideMenus(editor_id);var ml=new TinyMCE_Layer(editor_id+'_bcMenu');if(!ml.exists())ml.create('div','mceMenu',document.body,TinyMCE_AdvancedTheme._getColorHTML(editor_id,'theme_advanced_background_colors','HiliteColor'));tinyMCE.switchClass(editor_id+'_backcolor','mceMenuButtonFocus');ml.moveRelativeTo(document.getElementById(editor_id+"_backcolor"),'bl');ml.moveBy(tinyMCE.isMSIE&&!tinyMCE.isOpera?-1:1,-1);if(tinyMCE.isOpera)ml.moveBy(0,-2);ml.show();return true;case"backcolorpicker":this._pickColor(editor_id,'HiliteColor');return true;case"mceColorPicker":if(user_interface){var template=[];if(!value['callback']&&!value['color'])value['color']=value['document'].getElementById(value['element_id']).value;template['file']='color_picker.htm';template['width']=380;template['height']=250;template['close_previous']="no";template['width']+=tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_height',0);if(typeof(value['store_selection'])=="undefined")value['store_selection']=true;tinyMCE.lastColorPickerValue=value;tinyMCE.openWindow(template,{editor_id:editor_id,mce_store_selection:value['store_selection'],inline:"yes",command:"mceColorPicker",input_color:value['color']})}else{var savedVal=tinyMCE.lastColorPickerValue,elm;if(savedVal['callback']){savedVal['callback'](value);return true}elm=savedVal['document'].getElementById(savedVal['element_id']);elm.value=value;if(elm.onchange!=null&&elm.onchange!='')eval('elm.onchange();')}return true;case"mceCodeEditor":var template=new Array();template['file']='source_editor.htm';template['width']=parseInt(tinyMCE.getParam("theme_advanced_source_editor_width",720));template['height']=parseInt(tinyMCE.getParam("theme_advanced_source_editor_height",580));tinyMCE.openWindow(template,{editor_id:editor_id,resizable:"yes",scrollbars:"no",inline:"yes"});return true;case"mceCharMap":var template=new Array();template['file']='charmap.htm';template['width']=550+(tinyMCE.isOpera?40:0);template['height']=250;template['width']+=tinyMCE.getLang('lang_theme_advanced_charmap_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_charmap_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes"});return true;case"mceInsertAnchor":var template=new Array();template['file']='anchor.htm';template['width']=320;template['height']=90+(tinyMCE.isNS7?30:0);template['width']+=tinyMCE.getLang('lang_theme_advanced_anchor_delta_width',0);template['height']+=tinyMCE.getLang('lang_theme_advanced_anchor_delta_height',0);tinyMCE.openWindow(template,{editor_id:editor_id,inline:"yes"});return true;case"mceNewDocument":if(confirm(tinyMCE.getLang('lang_newdocument')))tinyMCE.execInstanceCommand(editor_id,'mceSetContent',false,' ');return true}return false},getEditorTemplate:function(settings,editorId){function removeFromArray(in_array,remove_array){var outArray=new Array(),skip;for(var i=0;i 

';var layoutManager=tinyMCE.getParam("theme_advanced_layout_manager","SimpleLayout");var styleSelectHTML='';if(settings['theme_advanced_styles']){var stylesAr=settings['theme_advanced_styles'].split(';');for(var i=0;i'+key+''}TinyMCE_AdvancedTheme._autoImportCSSClasses=false}switch(layoutManager){case"SimpleLayout":var toolbarHTML="";var toolbarLocation=tinyMCE.getParam("theme_advanced_toolbar_location","bottom");var toolbarAlign=tinyMCE.getParam("theme_advanced_toolbar_align","center");var pathLocation=tinyMCE.getParam("theme_advanced_path_location","none");var statusbarLocation=tinyMCE.getParam("theme_advanced_statusbar_location",pathLocation);var defVals={theme_advanced_buttons1:"bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,separator,sub,sup,separator,charmap"};toolbarHTML+='0){toolbarHTML+="
";deltaHeight-=23}}toolbarHTML+='
';template['html']='';if(toolbarLocation=="top")template['html']+='';if(statusbarLocation=="top"){template['html']+='';deltaHeight-=23}template['html']+='';if(toolbarLocation=="bottom")template['html']+='';if(toolbarLocation=="external"){var bod=document.body;var elm=document.createElement("div");toolbarHTML=tinyMCE.replaceVar(toolbarHTML,'style_select_options',styleSelectHTML);toolbarHTML=tinyMCE.applyTemplate(toolbarHTML,{editor_id:editorId});elm.className="mceToolbarExternal";elm.id=editorId+"_toolbar";elm.innerHTML='
'+toolbarHTML+'
'+statusbarHTML+'
'+toolbarHTML+'
'+toolbarHTML+'
';bod.appendChild(elm);deltaHeight=0;tinyMCE.getInstanceById(editorId).toolbarElement=elm;}else{tinyMCE.getInstanceById(editorId).toolbarElement=null}if(statusbarLocation=="bottom"){template['html']+='
'+statusbarHTML+'
';break;case"RowLayout":template['html']='';var containers=tinyMCE.getParam("theme_advanced_containers","",true,",");var defaultContainerCSS=tinyMCE.getParam("theme_advanced_containers_default_class","container");var defaultContainerAlign=tinyMCE.getParam("theme_advanced_containers_default_align","center");for(var i=0;i';else if(containers[i]=="mceElementpath"||containers[i]=="mceStatusbar"){var pathClass="mceStatusbar";if(i==containers.length-1){pathClass="mceStatusbarBottom"}else if(i==0){pathClass="mceStatusbar"}else{deltaHeight-=2}template['html']+='';deltaHeight-=22}else{var curContainer=tinyMCE.getParam("theme_advanced_container_"+containers[i],"",true,',');var curContainerHTML="";var curAlign=tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align",defaultContainerAlign);var curCSS=tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class",defaultContainerCSS);curContainer=removeFromArray(curContainer,tinyMCE.getParam("theme_advanced_disable","",true,','));for(var j=0;j0){curContainerHTML+="
";deltaHeight-=23}template['html']+='
'}}template['html']+='
'+statusbarHTML+'
'+curContainerHTML+'
';break;case"CustomLayout":var customLayout=tinyMCE.getParam("theme_advanced_custom_layout","");if(customLayout!=""&&eval("typeof("+customLayout+")")!="undefined"){template=eval(customLayout+"(template);")}break}if(resizing)template['html']+='';template['html']=tinyMCE.replaceVar(template['html'],'style_select_options',styleSelectHTML);if(!template['delta_width'])template['delta_width']=0;if(!template['delta_height'])template['delta_height']=deltaHeight;return template},initInstance:function(inst){if(tinyMCE.getParam("theme_advanced_resizing",false)){if(tinyMCE.getParam("theme_advanced_resizing_use_cookie",true)){var w=TinyMCE_AdvancedTheme._getCookie("TinyMCE_"+inst.editorId+"_width");var h=TinyMCE_AdvancedTheme._getCookie("TinyMCE_"+inst.editorId+"_height");TinyMCE_AdvancedTheme._resizeTo(inst,w,h,tinyMCE.getParam("theme_advanced_resize_horizontal",true))}}inst.addShortcut('ctrl','k','lang_link_desc','mceLink')},removeInstance:function(inst){new TinyMCE_Layer(inst.editorId+'_fcMenu').remove();new TinyMCE_Layer(inst.editorId+'_bcMenu').remove()},hideInstance:function(inst){TinyMCE_AdvancedTheme._hideMenus(inst.editorId)},_handleMenuEvent:function(e){var te=tinyMCE.isMSIE?window.event.srcElement:e.target;tinyMCE._menuButtonEvent(e.type=="mouseover"?"over":"out",document.getElementById(te._switchId));if(e.type=="click")tinyMCE.execInstanceCommand(te._editor_id,te._command)},_hideMenus:function(id){var fcml=new TinyMCE_Layer(id+'_fcMenu'),bcml=new TinyMCE_Layer(id+'_bcMenu');if(fcml.exists()&&fcml.isVisible()){tinyMCE.switchClass(id+'_forecolor','mceMenuButton');fcml.hide()}if(bcml.exists()&&bcml.isVisible()){tinyMCE.switchClass(id+'_backcolor','mceMenuButton');bcml.hide()}},handleNodeChange:function(editor_id,node,undo_index,undo_levels,visual_aid,any_selection,setup_content){var alignNode,breakOut,classNode;function selectByValue(select_elm,value,first_index){first_index=typeof(first_index)=="undefined"?false:true;if(select_elm){for(var i=0;i=0;i--){var nodeName=path[i].nodeName.toLowerCase();var nodeData="";if(nodeName.indexOf("html:")==0)nodeName=nodeName.substring(5);if(nodeName=="b"){nodeName="strong"}if(nodeName=="i"){nodeName="em"}if(nodeName=="span"){var cn=tinyMCE.getAttrib(path[i],"class");if(cn!=""&&cn.indexOf('mceItem')==-1)nodeData+="class: "+cn+" ";var st=tinyMCE.getAttrib(path[i],"style");if(st!=""){st=tinyMCE.serializeStyle(tinyMCE.parseStyle(st));nodeData+="style: "+tinyMCE.xmlEncode(st)+" "}}if(nodeName=="font"){if(tinyMCE.getParam("convert_fonts_to_spans"))nodeName="span";var face=tinyMCE.getAttrib(path[i],"face");if(face!="")nodeData+="font: "+tinyMCE.xmlEncode(face)+" ";var size=tinyMCE.getAttrib(path[i],"size");if(size!="")nodeData+="size: "+tinyMCE.xmlEncode(size)+" ";var color=tinyMCE.getAttrib(path[i],"color");if(color!="")nodeData+="color: "+tinyMCE.xmlEncode(color)+" "}if(tinyMCE.getAttrib(path[i],'id')!=""){nodeData+="id: "+path[i].getAttribute('id')+" "}var className=tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i],"class"),false);if(className!=""&&className.indexOf('mceItem')==-1)nodeData+="class: "+className+" ";if(tinyMCE.getAttrib(path[i],'src')!=""){var src=tinyMCE.getAttrib(path[i],"mce_src");if(src=="")src=tinyMCE.getAttrib(path[i],"src");nodeData+="src: "+tinyMCE.xmlEncode(src)+" "}if(path[i].nodeName=='A'&&tinyMCE.getAttrib(path[i],'href')!=""){var href=tinyMCE.getAttrib(path[i],"mce_href");if(href=="")href=tinyMCE.getAttrib(path[i],"href");nodeData+="href: "+tinyMCE.xmlEncode(href)+" "}className=tinyMCE.getAttrib(path[i],"class");if((nodeName=="img"||nodeName=="span")&&className.indexOf('mceItem')!=-1){nodeName=className.replace(/mceItem([a-z]+)/gi,'$1').toLowerCase();nodeData=path[i].getAttribute('title')}if(nodeName=="a"&&(anchor=tinyMCE.getAttrib(path[i],"name"))!=""){nodeName="a";nodeName+="#"+tinyMCE.xmlEncode(anchor);nodeData=""}if(tinyMCE.getAttrib(path[i],'name').indexOf("mce_")!=0){var className=tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i],"class"),false);if(className!=""&&className.indexOf('mceItem')==-1){nodeName+="."+className}}var cmd='tinyMCE.execInstanceCommand(\''+editor_id+'\',\'mceSelectNodeDepth\',false,\''+i+'\');';html+=''+nodeName+'';if(i>0){html+=" » "}}pathElm.innerHTML=''+tinyMCE.getLang('lang_theme_path')+": "+html+' '}tinyMCE.switchClass(editor_id+'_justifyleft','mceButtonNormal');tinyMCE.switchClass(editor_id+'_justifyright','mceButtonNormal');tinyMCE.switchClass(editor_id+'_justifycenter','mceButtonNormal');tinyMCE.switchClass(editor_id+'_justifyfull','mceButtonNormal');tinyMCE.switchClass(editor_id+'_bold','mceButtonNormal');tinyMCE.switchClass(editor_id+'_italic','mceButtonNormal');tinyMCE.switchClass(editor_id+'_underline','mceButtonNormal');tinyMCE.switchClass(editor_id+'_strikethrough','mceButtonNormal');tinyMCE.switchClass(editor_id+'_bullist','mceButtonNormal');tinyMCE.switchClass(editor_id+'_numlist','mceButtonNormal');tinyMCE.switchClass(editor_id+'_sub','mceButtonNormal');tinyMCE.switchClass(editor_id+'_sup','mceButtonNormal');tinyMCE.switchClass(editor_id+'_anchor','mceButtonNormal');tinyMCE.switchClass(editor_id+'_link','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_unlink','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_outdent','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_image','mceButtonNormal');tinyMCE.switchClass(editor_id+'_hr','mceButtonNormal');if(node.nodeName=="A"&&tinyMCE.getAttrib(node,"class").indexOf('mceItemAnchor')!=-1)tinyMCE.switchClass(editor_id+'_anchor','mceButtonSelected');var anchorLink=tinyMCE.getParentElement(node,"a","href");if(anchorLink||any_selection){tinyMCE.switchClass(editor_id+'_link',anchorLink?'mceButtonSelected':'mceButtonNormal');tinyMCE.switchClass(editor_id+'_unlink',anchorLink?'mceButtonSelected':'mceButtonNormal')}tinyMCE.switchClass(editor_id+'_visualaid',visual_aid?'mceButtonSelected':'mceButtonNormal');if(undo_levels!=-1){tinyMCE.switchClass(editor_id+'_undo','mceButtonDisabled');tinyMCE.switchClass(editor_id+'_redo','mceButtonDisabled')}if(tinyMCE.getParentElement(node,"li,blockquote"))tinyMCE.switchClass(editor_id+'_outdent','mceButtonNormal');if(undo_index!=-1&&(undo_index0))tinyMCE.switchClass(editor_id+'_redo','mceButtonNormal');if(undo_index!=-1&&(undo_index>0&&undo_levels>0))tinyMCE.switchClass(editor_id+'_undo','mceButtonNormal');var selectElm=document.getElementById(editor_id+"_styleSelect");if(selectElm){TinyMCE_AdvancedTheme._setupCSSClasses(editor_id);classNode=node;breakOut=false;var index=0;do{if(classNode&&classNode.className){for(var i=0;i");else selectByValue(selectElm,"")}var selectElm=document.getElementById(editor_id+"_fontNameSelect");if(selectElm){if(!tinyMCE.isSafari&&!(tinyMCE.isMSIE&&!tinyMCE.isOpera)){var face=inst.queryCommandValue('FontName');face=face==null||face==""?"":face;selectByValue(selectElm,face,face!="")}else{var elm=tinyMCE.getParentElement(node,"font","face");if(elm){var family=tinyMCE.getAttrib(elm,"face");if(family=='')family=''+elm.style.fontFamily;if(!selectByValue(selectElm,family,family!=""))selectByValue(selectElm,"")}else selectByValue(selectElm,"")}}var selectElm=document.getElementById(editor_id+"_fontSizeSelect");if(selectElm){if(!tinyMCE.isSafari&&!tinyMCE.isOpera){var size=inst.queryCommandValue('FontSize');selectByValue(selectElm,size==null||size==""?"0":size)}else{var elm=tinyMCE.getParentElement(node,"font","size");if(elm){var size=tinyMCE.getAttrib(elm,"size");if(size==''){var sizes=new Array('','8px','10px','12px','14px','18px','24px','36px');size=''+elm.style.fontSize;for(var i=0;i0)selectElm.setAttribute('cssImported','true')}},_setCookie:function(name,value,expires,path,domain,secure){var curCookie=name+"="+escape(value)+((expires)?"; expires="+expires.toGMTString():"")+((path)?"; path="+escape(path):"")+((domain)?"; domain="+domain:"")+((secure)?"; secure":"");document.cookie=curCookie},_getCookie:function(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))},_resizeTo:function(inst,w,h,set_w){var editorContainer=document.getElementById(inst.editorId+'_parent');var tableElm=editorContainer.firstChild;var iframe=inst.iframeElement;if(w==null||w=="null"){set_w=false;w=0}if(h==null||h=="null")return;w=parseInt(w);h=parseInt(h);if(tinyMCE.isGecko){w+=2;h+=2}var dx=w-tableElm.clientWidth;var dy=h-tableElm.clientHeight;w=w<1?30:w;h=h<1?30:h;if(set_w)tableElm.style.width=w+"px";tableElm.style.height=h+"px";iw=iframe.clientWidth+dx;ih=iframe.clientHeight+dy;iw=iw<1?30:iw;ih=ih<1?30:ih;if(tinyMCE.isGecko){iw-=2;ih-=2}if(set_w)iframe.style.width=iw+"px";iframe.style.height=ih+"px";if(set_w){var tableBodyElm=tableElm.firstChild;var minIframeWidth=tableBodyElm.scrollWidth;if(inst.iframeElement.clientWidth
';if(tinyMCE.getParam("theme_advanced_more_colors",true))h+=''+tinyMCE.getLang('lang_more_colors')+'';return h},_pickColor:function(id,cm){var inputColor,inst=tinyMCE.selectedInstance;if(cm=='forecolor'&&inst)inputColor=inst.foreColor;if((cm=='backcolor'||cm=='HiliteColor')&&inst)inputColor=inst.backColor;tinyMCE.execCommand('mceColorPicker',true,{color:inputColor,callback:function(c){tinyMCE.execInstanceCommand(id,cm,false,c)}})},_insertImage:function(src,alt,border,hspace,vspace,width,height,align,title,onmouseover,onmouseout){tinyMCE.execCommand('mceBeginUndoLevel');if(src=="")return;if(!tinyMCE.imgElement&&tinyMCE.isSafari){var html="";html+=''+alt+'';tinyMCE.execCommand("mceInsertContent",false,html)}else{if(!tinyMCE.imgElement&&tinyMCE.selectedInstance){if(tinyMCE.isSafari)tinyMCE.execCommand("mceInsertContent",false,'');else tinyMCE.selectedInstance.contentDocument.execCommand("insertimage",false,tinyMCE.uniqueURL);tinyMCE.imgElement=tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body,"img","src",tinyMCE.uniqueURL)}}if(tinyMCE.imgElement){var needsRepaint=false;var msrc=src;src=eval(tinyMCE.settings['urlconverter_callback']+"(src, tinyMCE.imgElement);");if(tinyMCE.getParam('convert_urls'))msrc=src;if(onmouseover&&onmouseover!="")onmouseover="this.src='"+eval(tinyMCE.settings['urlconverter_callback']+"(onmouseover, tinyMCE.imgElement);")+"';";if(onmouseout&&onmouseout!="")onmouseout="this.src='"+eval(tinyMCE.settings['urlconverter_callback']+"(onmouseout, tinyMCE.imgElement);")+"';";if(typeof(title)=="undefined")title=alt;if(width!=tinyMCE.imgElement.getAttribute("width")||height!=tinyMCE.imgElement.getAttribute("height")||align!=tinyMCE.imgElement.getAttribute("align"))needsRepaint=true;tinyMCE.setAttrib(tinyMCE.imgElement,'src',src);tinyMCE.setAttrib(tinyMCE.imgElement,'mce_src',msrc);tinyMCE.setAttrib(tinyMCE.imgElement,'alt',alt);tinyMCE.setAttrib(tinyMCE.imgElement,'title',title);tinyMCE.setAttrib(tinyMCE.imgElement,'align',align);tinyMCE.setAttrib(tinyMCE.imgElement,'border',border,true);tinyMCE.setAttrib(tinyMCE.imgElement,'hspace',hspace,true);tinyMCE.setAttrib(tinyMCE.imgElement,'vspace',vspace,true);tinyMCE.setAttrib(tinyMCE.imgElement,'width',width,true);tinyMCE.setAttrib(tinyMCE.imgElement,'height',height,true);tinyMCE.setAttrib(tinyMCE.imgElement,'onmouseover',onmouseover);tinyMCE.setAttrib(tinyMCE.imgElement,'onmouseout',onmouseout);if(width&&width!="")tinyMCE.imgElement.style.pixelWidth=width;if(height&&height!="")tinyMCE.imgElement.style.pixelHeight=height;if(needsRepaint)tinyMCE.selectedInstance.repaint()}tinyMCE.execCommand('mceEndUndoLevel')},_insertLink:function(href,target,title,onclick,style_class){tinyMCE.execCommand('mceBeginUndoLevel');if(tinyMCE.selectedInstance&&tinyMCE.selectedElement&&tinyMCE.selectedElement.nodeName.toLowerCase()=="img"){var doc=tinyMCE.selectedInstance.getDoc();var linkElement=tinyMCE.getParentElement(tinyMCE.selectedElement,"a");var newLink=false;if(!linkElement){linkElement=doc.createElement("a");newLink=true}var mhref=href;var thref=eval(tinyMCE.settings['urlconverter_callback']+"(href, linkElement);");mhref=tinyMCE.getParam('convert_urls')?href:mhref;tinyMCE.setAttrib(linkElement,'href',thref);tinyMCE.setAttrib(linkElement,'mce_href',mhref);tinyMCE.setAttrib(linkElement,'target',target);tinyMCE.setAttrib(linkElement,'title',title);tinyMCE.setAttrib(linkElement,'onclick',onclick);tinyMCE.setAttrib(linkElement,'class',style_class);if(newLink){linkElement.appendChild(tinyMCE.selectedElement.cloneNode(true));tinyMCE.selectedElement.parentNode.replaceChild(linkElement,tinyMCE.selectedElement)}return}if(!tinyMCE.linkElement&&tinyMCE.selectedInstance){if(tinyMCE.isSafari){tinyMCE.execCommand("mceInsertContent",false,''+tinyMCE.selectedInstance.selection.getSelectedHTML()+'')}else tinyMCE.selectedInstance.contentDocument.execCommand("createlink",false,tinyMCE.uniqueURL);tinyMCE.linkElement=tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body,"a","href",tinyMCE.uniqueURL);var elementArray=tinyMCE.getElementsByAttributeValue(tinyMCE.selectedInstance.contentDocument.body,"a","href",tinyMCE.uniqueURL);for(var i=0;i'),'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:'Simple theme',author:'Moxiecode Systems AB',authorurl:'http://tinymce.moxiecode.com',version:tinymce.majorVersion+"."+tinymce.minorVersion}},_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;dc=s.theme_advanced_containers_default_class||'';da=s.theme_advanced_containers_default_align||'center';each((s.theme_advanced_containers||'').split(','),function(c,i){var v=s['theme_advanced_container_'+c]||'';switch(c.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:n=DOM.add(DOM.add(tb,'tr'),'td',{'class':'mceToolbar '+(s['theme_advanced_container_'+c+'_class']||dc),align:s['theme_advanced_container_'+c+'_align']||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(s.theme_advanced_disable.split(','),function(v){di[v]=1;});t._disabled=di;}else di=t._disabled;each(v.split(','),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=[];n=DOM.add(DOM.add(c,'tr'),'td',{'class':'mceToolbar',align:s.theme_advanced_toolbar_align});if(!ed.getParam('accessibility_focus')||ed.getParam('tab_focus'))h.push(DOM.createHTML('a',{href:'#',onfocus:'tinyMCE.get(\''+ed.id+'\').focus();'},''));h.push(DOM.createHTML('a',{href:'#',accesskey:'q',title:ed.getLang("advanced.toolbar_focus")},''));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();'},''));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')+': ':' ');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':'resize'});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=o.cw+'px';c.style.height=o.ch+'px';DOM.get(ed.id+'_ifr').style.height=(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(document,'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(document,'mouseup',function(e){var ifr;Event.remove(document,'mousemove',mf);Event.remove(document,'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=(r.w+r.dx)+'px';c.style.height=(r.h+r.dy)+'px';ifr.style.height=(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':"#"+(de++)+"",onmousedown:"return false;",title:ti},na);if(p.hasChildNodes()){p.insertBefore(document.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;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,{func:function(co){t.editor.execCommand('ForeColor',false,co);}});},_mceBackColor:function(){var t=this;this._mceColorPicker(0,{func:function(co){t.editor.execCommand('HiliteColor',false,co);}});}});tinymce.ThemeManager.add('advanced',tinymce.themes.AdvancedTheme);}()); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/editor_template_src.js --- a/includes/clientside/tinymce/themes/advanced/editor_template_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/advanced/editor_template_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1574 +1,999 @@ /** - * $Id: editor_template_src.js 218 2007-02-13 11:08:01Z spocke $ + * $Id: editor_template_src.js 555 2008-01-19 19:08:37Z spocke $ * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -/* Import theme specific language pack */ -tinyMCE.importThemeLanguagePack('advanced'); +(function() { + var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID; + + // Tell it to load theme specific language pack(s) + tinymce.ThemeManager.requireLangPack('advanced'); + + tinymce.create('tinymce.themes.AdvancedTheme', { + // Control name lookup, format: title, command + 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; + + t.editor = ed; + t.url = url; + t.onResolveName = new tinymce.util.Dispatcher(this); -var TinyMCE_AdvancedTheme = { - // Private theme fields - _defColors : "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", - _autoImportCSSClasses : true, - _resizer : {}, - _buttons : [ - // Control id, button img, button title, command, user_interface, value - ['bold', '{$lang_bold_img}', 'lang_bold_desc', 'Bold'], - ['italic', '{$lang_italic_img}', 'lang_italic_desc', 'Italic'], - ['underline', '{$lang_underline_img}', 'lang_underline_desc', 'Underline'], - ['strikethrough', 'strikethrough.gif', 'lang_striketrough_desc', 'Strikethrough'], - ['justifyleft', 'justifyleft.gif', 'lang_justifyleft_desc', 'JustifyLeft'], - ['justifycenter', 'justifycenter.gif', 'lang_justifycenter_desc', 'JustifyCenter'], - ['justifyright', 'justifyright.gif', 'lang_justifyright_desc', 'JustifyRight'], - ['justifyfull', 'justifyfull.gif', 'lang_justifyfull_desc', 'JustifyFull'], - ['bullist', 'bullist.gif', 'lang_bullist_desc', 'InsertUnorderedList'], - ['numlist', 'numlist.gif', 'lang_numlist_desc', 'InsertOrderedList'], - ['outdent', 'outdent.gif', 'lang_outdent_desc', 'Outdent'], - ['indent', 'indent.gif', 'lang_indent_desc', 'Indent'], - ['cut', 'cut.gif', 'lang_cut_desc', 'Cut'], - ['copy', 'copy.gif', 'lang_copy_desc', 'Copy'], - ['paste', 'paste.gif', 'lang_paste_desc', 'Paste'], - ['undo', 'undo.gif', 'lang_undo_desc', 'Undo'], - ['redo', 'redo.gif', 'lang_redo_desc', 'Redo'], - ['link', 'link.gif', 'lang_link_desc', 'mceLink', true], - ['unlink', 'unlink.gif', 'lang_unlink_desc', 'unlink'], - ['image', 'image.gif', 'lang_image_desc', 'mceImage', true], - ['cleanup', 'cleanup.gif', 'lang_cleanup_desc', 'mceCleanup'], - ['help', 'help.gif', 'lang_help_desc', 'mceHelp'], - ['code', 'code.gif', 'lang_theme_code_desc', 'mceCodeEditor'], - ['hr', 'hr.gif', 'lang_theme_hr_desc', 'inserthorizontalrule'], - ['removeformat', 'removeformat.gif', 'lang_theme_removeformat_desc', 'removeformat'], - ['sub', 'sub.gif', 'lang_theme_sub_desc', 'subscript'], - ['sup', 'sup.gif', 'lang_theme_sup_desc', 'superscript'], - ['forecolor', 'forecolor.gif', 'lang_theme_forecolor_desc', 'forecolor', true], - ['forecolorpicker', 'forecolor.gif', 'lang_theme_forecolor_desc', 'forecolorpicker', true], - ['backcolor', 'backcolor.gif', 'lang_theme_backcolor_desc', 'HiliteColor', true], - ['backcolorpicker', 'backcolor.gif', 'lang_theme_backcolor_desc', 'backcolorpicker', true], - ['charmap', 'charmap.gif', 'lang_theme_charmap_desc', 'mceCharMap'], - ['visualaid', 'visualaid.gif', 'lang_theme_visualaid_desc', 'mceToggleVisualAid'], - ['anchor', 'anchor.gif', 'lang_theme_anchor_desc', 'mceInsertAnchor'], - ['newdocument', 'newdocument.gif', 'lang_newdocument_desc', 'mceNewDocument'] - ], + // Default settings + t.settings = s = extend({ + theme_advanced_path : true, + theme_advanced_toolbar_location : 'bottom', + theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect", + theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code", + theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap", + theme_advanced_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 (s.theme_advanced_path_location) + s.theme_advanced_statusbar_location = s.theme_advanced_path_location; + + if (s.theme_advanced_statusbar_location == 'none') + s.theme_advanced_statusbar_location = 0; + + // Init editor + ed.onInit.add(function() { + ed.onNodeChange.add(t._nodeChanged, t); + 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; - _buttonMap : 'anchor,backcolor,bold,bullist,charmap,cleanup,code,copy,cut,forecolor,help,hr,image,indent,italic,justifycenter,justifyfull,justifyleft,justifyright,link,newdocument,numlist,outdent,paste,redo,removeformat,strikethrough,sub,sup,underline,undo,unlink,visualaid,advhr,ltr,rtl,emotions,flash,fullpage,fullscreen,iespell,insertdate,inserttime,pastetext,pasteword,selectall,preview,print,save,replace,search,table,cell_props,delete_col,delete_row,col_after,col_before,row_after,row_before,merge_cells,row_props,split_cells,delete_table', + 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")); + }, - /** - * Returns HTML code for the specificed control. - */ - getControlHTML : function(button_name) { - var i, x, but; + createControl : function(n, cf) { + var cd, c; + + if (c = cf.createControl(n)) + return c; + + switch (n) { + case "styleselect": + return this._createStyleSelect(); - // Lookup button in button list - for (i=0; i 4 ? but[4] : false), (but.length > 5 ? but[5] : null)); + 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 (but[0] == button_name) - return tinyMCE.getButtonHTML(but[0], but[2], '{$themeurl}/images/' + but[1], but[3], (but.length > 4 ? but[4] : false), (but.length > 5 ? but[5] : null)); - } + if (f) { + f.call(this, ui, val); + return true; + } + + return false; + }, + + _importClasses : function() { + 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']); + }); + } + }, - // Custom controlls other than buttons - switch (button_name) { - case "formatselect": - var html = ''; + c = t.editor.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', cmd : 'FontSize'}); - return html; + each(t.settings.theme_advanced_font_sizes.split(','), function(v) { + c.add(lo[parseInt(v) - 1], v, {'style' : 'font-size:' + fz[v - 1] + 'pt', 'class' : 'fontSize' + v}); + }); + + return c; + }, - case "styleselect": - return ''; + _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'}); - case "fontselect": - var fontHTML = ''; - return fontHTML; + if (s.theme_advanced_more_colors) { + o.more_colors_func = function() { + t._mceColorPicker(0, { + color : c.value, + func : function(co) { + c.setColor(co); + } + }); + }; + } - case "fontsizeselect": - return ''; + 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; - case "|": - case "separator": - return ''; + o.title = 'advanced.backcolor_desc'; + o.cmd = 'HiliteColor'; + o.scope = this; + + c = t.editor.controlManager.createColorSplitButton('backcolor', o); - case "spacer": - return ''; + return c; + }, + + renderUI : function(o) { + var n, ic, tb, t = this, ed = t.editor, s = t.settings, sc, p, nl; + + n = p = DOM.create('div', {id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin'}); + + if (!DOM.boxModel) + n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'}); - case "rowseparator": - return '
'; - } + 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; - return ""; - }, + 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; - /** - * Theme specific execcommand handling. - */ - execCommand : function(editor_id, element, command, user_interface, value) { - switch (command) { - case 'mceHelp': - tinyMCE.openWindow({ - file : 'about.htm', - width : 480, - height : 380 - }, { - tinymce_version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion, - tinymce_releasedate : tinyMCE.releaseDate, - inline : "yes" - }); - return true; + // Add classes to first and last TRs + nl = sc.rows; + DOM.addClass(nl[0], 'first'); + DOM.addClass(nl[nl.length - 1], 'last'); + + // Add classes to first and last TDs + each(DOM.select('tr', tb), function(n) { + DOM.addClass(n.firstChild, 'first'); + DOM.addClass(n.childNodes[n.childNodes.length - 1], 'last'); + }); + + 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.href.replace(/^[^#]*#/, '')); + + return Event.cancel(e); + } + }); +/* + if (DOM.get(ed.id + '_path_row')) { + Event.add(ed.id + '_tbl', 'mouseover', function(e) { + var re; + + e = e.target; - case "mceLink": - var inst = tinyMCE.getInstanceById(editor_id); - var doc = inst.getDoc(); - var selectedText = ""; + if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) { + re = DOM.get(ed.id + '_path_row'); + t.lastPath = re.innerHTML; + DOM.setHTML(re, e.parentNode.title); + } + }); + + Event.add(ed.id + '_tbl', 'mouseout', function(e) { + if (t.lastPath) { + DOM.setHTML(ed.id + '_path_row', t.lastPath); + t.lastPath = 0; + } + }); + } +*/ - if (tinyMCE.isMSIE) { - var rng = doc.selection.createRange(); - selectedText = rng.text; - } else - selectedText = inst.getSel().toString(); + if (!ed.getParam('accessibility_focus') || ed.getParam('tab_focus')) + Event.add(DOM.add(p, 'a', {href : '#'}, ''), 'focus', function() {tinyMCE.get(ed.id).focus();}); + + if (s.theme_advanced_toolbar_location == 'external') + o.deltaHeight = 0; - if (!tinyMCE.linkElement) { - if ((tinyMCE.selectedElement.nodeName.toLowerCase() != "img") && (selectedText.length <= 0)) - return true; - } + t.deltaHeight = o.deltaHeight; + o.targetNode = null; - var href = "", target = "", title = "", onclick = "", action = "insert", style_class = ""; + return { + iframeContainer : ic, + editorContainer : ed.id + '_parent', + sizeContainer : sc, + deltaHeight : o.deltaHeight + }; + }, - if (tinyMCE.selectedElement.nodeName.toLowerCase() == "a") - tinyMCE.linkElement = tinyMCE.selectedElement; + getInfo : function() { + return { + longname : 'Simple theme', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + version : tinymce.majorVersion + "." + tinymce.minorVersion + } + }, - // Is anchor not a link - if (tinyMCE.linkElement != null && tinyMCE.getAttrib(tinyMCE.linkElement, 'href') == "") - tinyMCE.linkElement = null; + _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 (tinyMCE.linkElement) { - href = tinyMCE.getAttrib(tinyMCE.linkElement, 'href'); - target = tinyMCE.getAttrib(tinyMCE.linkElement, 'target'); - title = tinyMCE.getAttrib(tinyMCE.linkElement, 'title'); - onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick'); - style_class = tinyMCE.getAttrib(tinyMCE.linkElement, 'class'); + // Create toolbar container at top + if (lo == 'top') + t._addToolbars(tb, o); + + // Create external toolbar + 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); - // Try old onclick to if copy/pasted content - if (onclick == "") - onclick = tinyMCE.getAttrib(tinyMCE.linkElement, 'onclick'); + ed.onMouseUp.add(function() { + var e = DOM.get(ed.id + '_external'); + DOM.show(e); + + DOM.hide(lastExtID); - onclick = tinyMCE.cleanupEventStr(onclick); + var f = Event.add(ed.id + '_external_close', 'click', function() { + DOM.hide(ed.id + '_external'); + Event.remove(ed.id + '_external_close', 'click', f); + }); - href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);"); + DOM.show(e); + DOM.setStyle(e, 'top', 0 - DOM.getRect(ed.id + '_tblext').h - 1); + + // Fixes IE rendering bug + DOM.hide(e); + DOM.show(e); + e.style.filter = ''; - // Use mce_href if defined - mceRealHref = tinyMCE.getAttrib(tinyMCE.linkElement, 'mce_href'); - if (mceRealHref != "") { - href = mceRealHref; + lastExtID = ed.id + '_external'; + + e = null; + }); + } + + if (sl == 'top') + t._addStatusBar(tb, o); - if (tinyMCE.getParam('convert_urls')) - href = eval(tinyMCE.settings['urlconverter_callback'] + "(href, tinyMCE.linkElement, true);"); - } + // Create iframe container + if (!s.theme_advanced_toolbar_container) { + n = DOM.add(tb, 'tr'); + n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); + } + + // Create toolbar container at bottom + if (lo == 'bottom') + t._addToolbars(tb, o); - action = "update"; - } + if (sl == 'bottom') + t._addStatusBar(tb, o); + + return ic; + }, - var template = new Array(); + _rowLayout : function(s, tb, o) { + var t = this, ed = t.editor, dc, da, cf = ed.controlManager, n, ic, to; + + dc = s.theme_advanced_containers_default_class || ''; + da = s.theme_advanced_containers_default_align || 'center'; + + each((s.theme_advanced_containers || '').split(','), function(c, i) { + var v = s['theme_advanced_container_' + c] || ''; - template['file'] = 'link.htm'; - template['width'] = 310; - template['height'] = 200; + switch (c.toLowerCase()) { + case 'mceeditor': + n = DOM.add(tb, 'tr'); + n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'}); + break; - // Language specific width and height addons - template['width'] += tinyMCE.getLang('lang_insert_link_delta_width', 0); - template['height'] += tinyMCE.getLang('lang_insert_link_delta_height', 0); + case 'mceelementpath': + t._addStatusBar(tb, o); + break; + + default: + n = DOM.add(DOM.add(tb, 'tr'), 'td', { + 'class' : 'mceToolbar ' + (s['theme_advanced_container_' + c + '_class'] || dc), + align : s['theme_advanced_container_' + c + '_align'] || da + }); - if (inst.settings['insertlink_callback']) { - var returnVal = eval(inst.settings['insertlink_callback'] + "(href, target, title, onclick, action, style_class);"); - if (returnVal && returnVal['href']) - TinyMCE_AdvancedTheme._insertLink(returnVal['href'], returnVal['target'], returnVal['title'], returnVal['onclick'], returnVal['style_class']); - } else { - tinyMCE.openWindow(template, {href : href, target : target, title : title, onclick : onclick, action : action, className : style_class, inline : "yes"}); + to = cf.createToolbar("toolbar" + i); + t._addControls(v, to); + DOM.setHTML(n, to.renderHTML()); + o.deltaHeight -= s.theme_advanced_row_height; } + }); - return true; + 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(s.theme_advanced_disable.split(','), function(v) { + di[v] = 1; + }); - case "mceImage": - var src = "", alt = "", border = "", hspace = "", vspace = "", width = "", height = "", align = ""; - var title = "", onmouseover = "", onmouseout = "", action = "insert"; - var img = tinyMCE.imgElement; - var inst = tinyMCE.getInstanceById(editor_id); + t._disabled = di; + } else + di = t._disabled; + + each(v.split(','), function(n) { + var c; + + if (di && di[n]) + return; - if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") { - img = tinyMCE.selectedElement; - tinyMCE.imgElement = img; + // Compatiblity with 2.x + 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; } - if (img) { - // Is it a internal MCE visual aid image, then skip this one. - if (tinyMCE.getAttrib(img, 'name').indexOf('mce_') == 0) - return true; + c = t.createControl(n, cf); - src = tinyMCE.getAttrib(img, 'src'); - alt = tinyMCE.getAttrib(img, 'alt'); + if (c) + tb.add(c); + }); + }, - // Try polling out the title - if (alt == "") - alt = tinyMCE.getAttrib(img, 'title'); + _addToolbars : function(c, o) { + var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = []; - // Fix width/height attributes if the styles is specified - if (tinyMCE.isGecko) { - var w = img.style.width; - if (w != null && w != "") - img.setAttribute("width", w); + n = DOM.add(DOM.add(c, 'tr'), 'td', {'class' : 'mceToolbar', align : s.theme_advanced_toolbar_align}); + + if (!ed.getParam('accessibility_focus') || ed.getParam('tab_focus')) + h.push(DOM.createHTML('a', {href : '#', onfocus : 'tinyMCE.get(\'' + ed.id + '\').focus();'}, '')); - var h = img.style.height; - if (h != null && h != "") - img.setAttribute("height", h); - } + h.push(DOM.createHTML('a', {href : '#', accesskey : 'q', title : ed.getLang("advanced.toolbar_focus")}, '')); + + // Create toolbar and add the controls + for (i=1; (v = s['theme_advanced_buttons' + i]); i++) { + tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i}); - border = tinyMCE.getAttrib(img, 'border'); - hspace = tinyMCE.getAttrib(img, 'hspace'); - vspace = tinyMCE.getAttrib(img, 'vspace'); - width = tinyMCE.getAttrib(img, 'width'); - height = tinyMCE.getAttrib(img, 'height'); - align = tinyMCE.getAttrib(img, 'align'); - onmouseover = tinyMCE.getAttrib(img, 'onmouseover'); - onmouseout = tinyMCE.getAttrib(img, 'onmouseout'); - title = tinyMCE.getAttrib(img, 'title'); + if (s['theme_advanced_buttons' + i + '_add']) + v += ',' + s['theme_advanced_buttons' + i + '_add']; - // Is realy specified? - if (tinyMCE.isMSIE) { - width = img.attributes['width'].specified ? width : ""; - height = img.attributes['height'].specified ? height : ""; - } + if (s['theme_advanced_buttons' + i + '_add_before']) + v = s['theme_advanced_buttons' + i + '_add_before'] + ',' + v; - //onmouseover = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseover)); - //onmouseout = tinyMCE.getImageSrc(tinyMCE.cleanupEventStr(onmouseout)); + t._addControls(v, tb); - src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);"); + //n.appendChild(n = tb.render()); + h.push(tb.renderHTML()); - // Use mce_src if defined - mceRealSrc = tinyMCE.getAttrib(img, 'mce_src'); - if (mceRealSrc != "") { - src = mceRealSrc; + o.deltaHeight -= s.theme_advanced_row_height; + } - if (tinyMCE.getParam('convert_urls')) - src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, img, true);"); - } - - //if (onmouseover != "") - // onmouseover = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, img, true);"); + h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '')); + DOM.setHTML(n, h.join('')); + }, - //if (onmouseout != "") - // onmouseout = eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, img, true);"); - - action = "update"; - } + _addStatusBar : function(tb, o) { + var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td; - var template = new Array(); - - template['file'] = 'image.htm?src={$src}'; - template['width'] = 355; - template['height'] = 265 + (tinyMCE.isMSIE ? 25 : 0); + 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') + ': ' : ' '); + DOM.add(n, 'a', {href : '#', accesskey : 'x'}); - // Language specific width and height addons - template['width'] += tinyMCE.getLang('lang_insert_image_delta_width', 0); - template['height'] += tinyMCE.getLang('lang_insert_image_delta_height', 0); + if (s.theme_advanced_resizing && !tinymce.isOldWebKit) { + DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'resize'}); - if (inst.settings['insertimage_callback']) { - var returnVal = eval(inst.settings['insertimage_callback'] + "(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout, action);"); - if (returnVal && returnVal['src']) - TinyMCE_AdvancedTheme._insertImage(returnVal['src'], returnVal['alt'], returnVal['border'], returnVal['hspace'], returnVal['vspace'], returnVal['width'], returnVal['height'], returnVal['align'], returnVal['title'], returnVal['onmouseover'], returnVal['onmouseout']); - } else - tinyMCE.openWindow(template, {src : src, alt : alt, border : border, hspace : hspace, vspace : vspace, width : width, height : height, align : align, title : title, onmouseover : onmouseover, onmouseout : onmouseout, action : action, inline : "yes"}); - - return true; + 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'); - case "forecolor": - var fcp = new TinyMCE_Layer(editor_id + '_fcPreview', false), p, img, elm; - - TinyMCE_AdvancedTheme._hideMenus(editor_id); + if (!o) + return; - if (!fcp.exists()) { - fcp.create('div', 'mceColorPreview', document.getElementById(editor_id + '_toolbar')); - elm = fcp.getElement(); - elm._editor_id = editor_id; - elm._command = "forecolor"; - elm._switchId = editor_id + "_forecolor"; - tinyMCE.addEvent(elm, 'click', TinyMCE_AdvancedTheme._handleMenuEvent); - tinyMCE.addEvent(elm, 'mouseover', TinyMCE_AdvancedTheme._handleMenuEvent); - tinyMCE.addEvent(elm, 'mouseout', TinyMCE_AdvancedTheme._handleMenuEvent); + if (s.theme_advanced_resize_horizontal) + c.style.width = o.cw + 'px'; + + c.style.height = o.ch + 'px'; + DOM.get(ed.id + '_ifr').style.height = (parseInt(o.ch) + t.deltaHeight) + 'px'; + }); } - img = tinyMCE.selectNodes(document.getElementById(editor_id + "_forecolor"), function(n) {return n.nodeName == "IMG";})[0]; - p = tinyMCE.getAbsPosition(img, document.getElementById(editor_id + '_toolbar')); - - fcp.moveTo(p.absLeft, p.absTop); - fcp.getElement().style.backgroundColor = value != null ? value : tinyMCE.getInstanceById(editor_id).foreColor; - fcp.show(); - - return false; + ed.onPostRender.add(function() { + Event.add(ed.id + '_resize', 'mousedown', function(e) { + var c, p, w, h, n, pa; - case "forecolorpicker": - this._pickColor(editor_id, 'forecolor'); - return true; - - case "forecolorMenu": - TinyMCE_AdvancedTheme._hideMenus(editor_id); - - // Create color layer - var ml = new TinyMCE_Layer(editor_id + '_fcMenu'); + // Measure container + c = DOM.get(ed.id + '_tbl'); + w = c.clientWidth; + h = c.clientHeight; - if (!ml.exists()) - ml.create('div', 'mceMenu', document.body, TinyMCE_AdvancedTheme._getColorHTML(editor_id, 'theme_advanced_text_colors', 'forecolor')); - - tinyMCE.switchClass(editor_id + '_forecolor', 'mceMenuButtonFocus'); - ml.moveRelativeTo(document.getElementById(editor_id + "_forecolor"), 'bl'); - - ml.moveBy(tinyMCE.isMSIE && !tinyMCE.isOpera ? -1 : 1, -1); + 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; - if (tinyMCE.isOpera) - ml.moveBy(0, -2); + // Setup placeholder + p = DOM.add(DOM.get(ed.id + '_parent'), 'div', {'class' : 'mcePlaceHolder'}); + DOM.setStyles(p, {width : w, height : h}); - ml.show(); - return true; - - case "HiliteColor": - var bcp = new TinyMCE_Layer(editor_id + '_bcPreview', false), p, img; - - TinyMCE_AdvancedTheme._hideMenus(editor_id); + // Replace with placeholder + DOM.hide(c); + DOM.show(p); - if (!bcp.exists()) { - bcp.create('div', 'mceColorPreview', document.getElementById(editor_id + '_toolbar')); - elm = bcp.getElement(); - elm._editor_id = editor_id; - elm._command = "HiliteColor"; - elm._switchId = editor_id + "_backcolor"; - tinyMCE.addEvent(elm, 'click', TinyMCE_AdvancedTheme._handleMenuEvent); - tinyMCE.addEvent(elm, 'mouseover', TinyMCE_AdvancedTheme._handleMenuEvent); - tinyMCE.addEvent(elm, 'mouseout', TinyMCE_AdvancedTheme._handleMenuEvent); - } + // Create internal resize obj + r = { + x : e.screenX, + y : e.screenY, + w : w, + h : h, + dx : null, + dy : null + }; - img = tinyMCE.selectNodes(document.getElementById(editor_id + "_backcolor"), function(n) {return n.nodeName == "IMG";})[0]; - p = tinyMCE.getAbsPosition(img, document.getElementById(editor_id + '_toolbar')); - - bcp.moveTo(p.absLeft, p.absTop); - bcp.getElement().style.backgroundColor = value != null ? value : tinyMCE.getInstanceById(editor_id).backColor; - bcp.show(); - - return false; - - case "HiliteColorMenu": - TinyMCE_AdvancedTheme._hideMenus(editor_id); + // Start listening + mf = Event.add(document, 'mousemove', function(e) { + var w, h; - // Create color layer - var ml = new TinyMCE_Layer(editor_id + '_bcMenu'); - - if (!ml.exists()) - ml.create('div', 'mceMenu', document.body, TinyMCE_AdvancedTheme._getColorHTML(editor_id, 'theme_advanced_background_colors', 'HiliteColor')); - - tinyMCE.switchClass(editor_id + '_backcolor', 'mceMenuButtonFocus'); - ml.moveRelativeTo(document.getElementById(editor_id + "_backcolor"), 'bl'); - - ml.moveBy(tinyMCE.isMSIE && !tinyMCE.isOpera ? -1 : 1, -1); - - if (tinyMCE.isOpera) - ml.moveBy(0, -2); + // Calc delta values + r.dx = e.screenX - r.x; + r.dy = e.screenY - r.y; - ml.show(); - return true; - - case "backcolorpicker": - this._pickColor(editor_id, 'HiliteColor'); - return true; + // Boundery fix box + 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); - case "mceColorPicker": - if (user_interface) { - var template = []; - - if (!value['callback'] && !value['color']) - value['color'] = value['document'].getElementById(value['element_id']).value; + // Resize placeholder + if (s.theme_advanced_resize_horizontal) + p.style.width = w + 'px'; + + p.style.height = h + 'px'; + + return Event.cancel(e); + }); - template['file'] = 'color_picker.htm'; - template['width'] = 380; - template['height'] = 250; - template['close_previous'] = "no"; - - template['width'] += tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_width', 0); - template['height'] += tinyMCE.getLang('lang_theme_advanced_colorpicker_delta_height', 0); + me = Event.add(document, 'mouseup', function(e) { + var ifr; - if (typeof(value['store_selection']) == "undefined") - value['store_selection'] = true; + // Stop listening + Event.remove(document, 'mousemove', mf); + Event.remove(document, 'mouseup', me); - tinyMCE.lastColorPickerValue = value; - tinyMCE.openWindow(template, {editor_id : editor_id, mce_store_selection : value['store_selection'], inline : "yes", command : "mceColorPicker", input_color : value['color']}); - } else { - var savedVal = tinyMCE.lastColorPickerValue, elm; - - if (savedVal['callback']) { - savedVal['callback'](value); - return true; - } + c.style.display = ''; + DOM.remove(p); - elm = savedVal['document'].getElementById(savedVal['element_id']); - elm.value = value; + if (r.dx === null) + return; - if (elm.onchange != null && elm.onchange != '') - eval('elm.onchange();'); - } - return true; - - case "mceCodeEditor": - var template = new Array(); + ifr = DOM.get(ed.id + '_ifr'); - template['file'] = 'source_editor.htm'; - template['width'] = parseInt(tinyMCE.getParam("theme_advanced_source_editor_width", 720)); - template['height'] = parseInt(tinyMCE.getParam("theme_advanced_source_editor_height", 580)); - - tinyMCE.openWindow(template, {editor_id : editor_id, resizable : "yes", scrollbars : "no", inline : "yes"}); - return true; + if (s.theme_advanced_resize_horizontal) + c.style.width = (r.w + r.dx) + 'px'; - case "mceCharMap": - var template = new Array(); - - template['file'] = 'charmap.htm'; - template['width'] = 550 + (tinyMCE.isOpera ? 40 : 0); - template['height'] = 250; + c.style.height = (r.h + r.dy) + 'px'; + ifr.style.height = (ifr.clientHeight + r.dy) + 'px'; - template['width'] += tinyMCE.getLang('lang_theme_advanced_charmap_delta_width', 0); - template['height'] += tinyMCE.getLang('lang_theme_advanced_charmap_delta_height', 0); - - tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"}); - return true; - - case "mceInsertAnchor": - var template = new Array(); + if (s.theme_advanced_resizing_use_cookie) { + Cookie.setHash("TinyMCE_" + ed.id + "_size", { + cw : r.w + r.dx, + ch : r.h + r.dy + }); + } + }); - template['file'] = 'anchor.htm'; - template['width'] = 320; - template['height'] = 90 + (tinyMCE.isNS7 ? 30 : 0); - - template['width'] += tinyMCE.getLang('lang_theme_advanced_anchor_delta_width', 0); - template['height'] += tinyMCE.getLang('lang_theme_advanced_anchor_delta_height', 0); + return Event.cancel(e); + }); + }); + } - tinyMCE.openWindow(template, {editor_id : editor_id, inline : "yes"}); - return true; - - case "mceNewDocument": - if (confirm(tinyMCE.getLang('lang_newdocument'))) - tinyMCE.execInstanceCommand(editor_id, 'mceSetContent', false, ' '); + o.deltaHeight -= 21; + n = tb = null; + }, - return true; - } + _nodeChanged : function(ed, cm, n, co) { + var t = this, p, de = 0, v, c, s = t.settings; - return false; - }, + tinymce.each(t.stateControls, function(c) { + cm.setActive(c, ed.queryCommandState(t.controls[c][1])); + }); - /** - * Editor instance template function. - */ - getEditorTemplate : function(settings, editorId) { - function removeFromArray(in_array, remove_array) { - var outArray = new Array(), skip; - - for (var i=0; i 

'; - var layoutManager = tinyMCE.getParam("theme_advanced_layout_manager", "SimpleLayout"); - - // Setup style select options -- MOVED UP FOR EXTERNAL TOOLBAR COMPATABILITY! - var styleSelectHTML = ''; - if (settings['theme_advanced_styles']) { - var stylesAr = settings['theme_advanced_styles'].split(';'); - - for (var i=0; i' + key + ''; + if (c = cm.get('unlink')) { + c.setDisabled(!p && co); + c.setActive(!!p && !p.name); } - TinyMCE_AdvancedTheme._autoImportCSSClasses = false; - } - - switch(layoutManager) { - case "SimpleLayout" : //the default TinyMCE Layout (for backwards compatibility)... - var toolbarHTML = ""; - var toolbarLocation = tinyMCE.getParam("theme_advanced_toolbar_location", "bottom"); - var toolbarAlign = tinyMCE.getParam("theme_advanced_toolbar_align", "center"); - var pathLocation = tinyMCE.getParam("theme_advanced_path_location", "none"); // Compatiblity - var statusbarLocation = tinyMCE.getParam("theme_advanced_statusbar_location", pathLocation); - var defVals = { - theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,formatselect", - theme_advanced_buttons2 : "bullist,numlist,separator,outdent,indent,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,help,code", - theme_advanced_buttons3 : "hr,removeformat,visualaid,separator,sub,sup,separator,charmap" - }; - - // Add accessibility control - toolbarHTML += ' 0) { - toolbarHTML += "
"; - deltaHeight -= 23; - } - } - - // Add accessibility control - toolbarHTML += '
'; - - // Setup template html - template['html'] = ''; - - if (toolbarLocation == "top") - template['html'] += ''; - - if (statusbarLocation == "top") { - template['html'] += ''; - deltaHeight -= 23; - } - - template['html'] += ''; - - if (toolbarLocation == "bottom") - template['html'] += ''; - - // External toolbar changes - if (toolbarLocation == "external") { - var bod = document.body; - var elm = document.createElement ("div"); - - toolbarHTML = tinyMCE.replaceVar(toolbarHTML, 'style_select_options', styleSelectHTML); - toolbarHTML = tinyMCE.applyTemplate(toolbarHTML, {editor_id : editorId}); - - elm.className = "mceToolbarExternal"; - elm.id = editorId+"_toolbar"; - elm.innerHTML = '
' + toolbarHTML + '
' + statusbarHTML + '
' + toolbarHTML + '
'+toolbarHTML+'
'; - bod.appendChild (elm); - // bod.style.marginTop = elm.offsetHeight + "px"; - - deltaHeight = 0; - tinyMCE.getInstanceById(editorId).toolbarElement = elm; - - //template['html'] = '
'+toolbarHTML+'
' + template["html"]; - } else { - tinyMCE.getInstanceById(editorId).toolbarElement = null; - } - - if (statusbarLocation == "bottom") { - template['html'] += '
' + statusbarHTML + '
'; - //"SimpleLayout" - break; - - case "RowLayout" : //Container Layout - containers defined in "theme_advanced_containers" are rendered from top to bottom. - template['html'] = ''; - - var containers = tinyMCE.getParam("theme_advanced_containers", "", true, ","); - var defaultContainerCSS = tinyMCE.getParam("theme_advanced_containers_default_class", "container"); - var defaultContainerAlign = tinyMCE.getParam("theme_advanced_containers_default_align", "center"); - - //Render Containers: - for (var i = 0; i < containers.length; i++) - { - if (containers[i] == "mceEditor") //Exceptions for mceEditor and ... - template['html'] += ''; - else if (containers[i] == "mceElementpath" || containers[i] == "mceStatusbar") // ... mceElementpath: - { - var pathClass = "mceStatusbar"; - - if (i == containers.length-1) - { - pathClass = "mceStatusbarBottom"; - } - else if (i == 0) - { - pathClass = "mceStatusbar"; - } - else - { - deltaHeight-=2; - } - - template['html'] += ''; - deltaHeight -= 22; - } else { // Render normal Container - var curContainer = tinyMCE.getParam("theme_advanced_container_"+containers[i], "", true, ','); - var curContainerHTML = ""; - var curAlign = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_align", defaultContainerAlign); - var curCSS = tinyMCE.getParam("theme_advanced_container_"+containers[i]+"_class", defaultContainerCSS); - - curContainer = removeFromArray(curContainer, tinyMCE.getParam("theme_advanced_disable", "", true, ',')); - - for (var j=0; j 0) { - curContainerHTML += "
"; - deltaHeight -= 23; - } - - template['html'] += '
'; - } - } - - template['html'] += '
' + statusbarHTML + '
' + curContainerHTML + '
'; - //RowLayout - break; - - case "CustomLayout" : //User defined layout callback... - var customLayout = tinyMCE.getParam("theme_advanced_custom_layout",""); - - if (customLayout != "" && eval("typeof(" + customLayout + ")") != "undefined") { - template = eval(customLayout + "(template);"); - } - break; - } - - if (resizing) - template['html'] += ''; - - template['html'] = tinyMCE.replaceVar(template['html'], 'style_select_options', styleSelectHTML); - - // Set to default values - if (!template['delta_width']) - template['delta_width'] = 0; - - if (!template['delta_height']) - template['delta_height'] = deltaHeight; - - return template; - }, - - initInstance : function(inst) { - if (tinyMCE.getParam("theme_advanced_resizing", false)) { - if (tinyMCE.getParam("theme_advanced_resizing_use_cookie", true)) { - var w = TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_width"); - var h = TinyMCE_AdvancedTheme._getCookie("TinyMCE_" + inst.editorId + "_height"); - - TinyMCE_AdvancedTheme._resizeTo(inst, w, h, tinyMCE.getParam("theme_advanced_resize_horizontal", true)); - } - } + if (c = cm.get('anchor')) { + c.setActive(!!p && p.name); - inst.addShortcut('ctrl', 'k', 'lang_link_desc', 'mceLink'); - }, - - removeInstance : function(inst) { - new TinyMCE_Layer(inst.editorId + '_fcMenu').remove(); - new TinyMCE_Layer(inst.editorId + '_bcMenu').remove(); - }, - - hideInstance : function(inst) { - TinyMCE_AdvancedTheme._hideMenus(inst.editorId); - }, - - _handleMenuEvent : function(e) { - var te = tinyMCE.isMSIE ? window.event.srcElement : e.target; - tinyMCE._menuButtonEvent(e.type == "mouseover" ? "over" : "out", document.getElementById(te._switchId)); - - if (e.type == "click") - tinyMCE.execInstanceCommand(te._editor_id, te._command); - }, - - _hideMenus : function(id) { - var fcml = new TinyMCE_Layer(id + '_fcMenu'), bcml = new TinyMCE_Layer(id + '_bcMenu'); - - if (fcml.exists() && fcml.isVisible()) { - tinyMCE.switchClass(id + '_forecolor', 'mceMenuButton'); - fcml.hide(); - } - - if (bcml.exists() && bcml.isVisible()) { - tinyMCE.switchClass(id + '_backcolor', 'mceMenuButton'); - bcml.hide(); - } - }, - - /** - * Node change handler. - */ - handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection, setup_content) { - var alignNode, breakOut, classNode; - - function selectByValue(select_elm, value, first_index) { - first_index = typeof(first_index) == "undefined" ? false : true; - - if (select_elm) { - for (var i=0; i=0; i--) { - var nodeName = path[i].nodeName.toLowerCase(); - var nodeData = ""; - - if (nodeName.indexOf("html:") == 0) - nodeName = nodeName.substring(5); - - if (nodeName == "b") { - nodeName = "strong"; - } - - if (nodeName == "i") { - nodeName = "em"; - } - - if (nodeName == "span") { - var cn = tinyMCE.getAttrib(path[i], "class"); - if (cn != "" && cn.indexOf('mceItem') == -1) - nodeData += "class: " + cn + " "; - - var st = tinyMCE.getAttrib(path[i], "style"); - if (st != "") { - st = tinyMCE.serializeStyle(tinyMCE.parseStyle(st)); - nodeData += "style: " + tinyMCE.xmlEncode(st) + " "; - } - } - - if (nodeName == "font") { - if (tinyMCE.getParam("convert_fonts_to_spans")) - nodeName = "span"; - - var face = tinyMCE.getAttrib(path[i], "face"); - if (face != "") - nodeData += "font: " + tinyMCE.xmlEncode(face) + " "; - - var size = tinyMCE.getAttrib(path[i], "size"); - if (size != "") - nodeData += "size: " + tinyMCE.xmlEncode(size) + " "; - - var color = tinyMCE.getAttrib(path[i], "color"); - if (color != "") - nodeData += "color: " + tinyMCE.xmlEncode(color) + " "; - } - - if (tinyMCE.getAttrib(path[i], 'id') != "") { - nodeData += "id: " + path[i].getAttribute('id') + " "; - } - - var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i], "class"), false); - if (className != "" && className.indexOf('mceItem') == -1) - nodeData += "class: " + className + " "; - - if (tinyMCE.getAttrib(path[i], 'src') != "") { - var src = tinyMCE.getAttrib(path[i], "mce_src"); - - if (src == "") - src = tinyMCE.getAttrib(path[i], "src"); - - nodeData += "src: " + tinyMCE.xmlEncode(src) + " "; - } - - if (path[i].nodeName == 'A' && tinyMCE.getAttrib(path[i], 'href') != "") { - var href = tinyMCE.getAttrib(path[i], "mce_href"); - - if (href == "") - href = tinyMCE.getAttrib(path[i], "href"); - - nodeData += "href: " + tinyMCE.xmlEncode(href) + " "; - } - - className = tinyMCE.getAttrib(path[i], "class"); - if ((nodeName == "img" || nodeName == "span") && className.indexOf('mceItem') != -1) { - nodeName = className.replace(/mceItem([a-z]+)/gi, '$1').toLowerCase(); - nodeData = path[i].getAttribute('title'); - } - - if (nodeName == "a" && (anchor = tinyMCE.getAttrib(path[i], "name")) != "") { - nodeName = "a"; - nodeName += "#" + tinyMCE.xmlEncode(anchor); - nodeData = ""; - } - - if (tinyMCE.getAttrib(path[i], 'name').indexOf("mce_") != 0) { - var className = tinyMCE.getVisualAidClass(tinyMCE.getAttrib(path[i], "class"), false); - if (className != "" && className.indexOf('mceItem') == -1) { - nodeName += "." + className; - } - } - - var cmd = 'tinyMCE.execInstanceCommand(\'' + editor_id + '\',\'mceSelectNodeDepth\',false,\'' + i + '\');'; - html += '' + nodeName + ''; - - if (i > 0) { - html += " » "; + if (tinymce.isWebKit) { + p = DOM.getParent(n, 'IMG'); + c.setActive(!!p && DOM.getAttrib(p, 'mce_name') == 'a'); } } - pathElm.innerHTML = '' + tinyMCE.getLang('lang_theme_path') + ": " + html + ' '; - } + 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(); + } - // Reset old states - tinyMCE.switchClass(editor_id + '_justifyleft', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_justifyright', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_justifycenter', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_justifyfull', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_bold', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_italic', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_underline', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_strikethrough', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_sub', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_sup', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_anchor', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_link', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_unlink', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_outdent', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_image', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_hr', 'mceButtonNormal'); + if (c = cm.get('formatselect')) { + p = DOM.getParent(n, DOM.isBlock); - if (node.nodeName == "A" && tinyMCE.getAttrib(node, "class").indexOf('mceItemAnchor') != -1) - tinyMCE.switchClass(editor_id + '_anchor', 'mceButtonSelected'); + if (p) + c.select(p.nodeName.toLowerCase()); + } - // Get link - var anchorLink = tinyMCE.getParentElement(node, "a", "href"); + if (c = cm.get('fontselect')) + c.select(ed.queryCommandValue('FontName')); + + if (c = cm.get('fontsizeselect')) + c.select(ed.queryCommandValue('FontSize')); - if (anchorLink || any_selection) { - tinyMCE.switchClass(editor_id + '_link', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_unlink', anchorLink ? 'mceButtonSelected' : 'mceButtonNormal'); - } - - // Handle visual aid - tinyMCE.switchClass(editor_id + '_visualaid', visual_aid ? 'mceButtonSelected' : 'mceButtonNormal'); + 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, ''); - if (undo_levels != -1) { - tinyMCE.switchClass(editor_id + '_undo', 'mceButtonDisabled'); - tinyMCE.switchClass(editor_id + '_redo', 'mceButtonDisabled'); - } + ed.dom.getParent(n, function(n) { + var na = n.nodeName.toLowerCase(), u, pi, ti = ''; - // Within li, blockquote - if (tinyMCE.getParentElement(node, "li,blockquote")) - tinyMCE.switchClass(editor_id + '_outdent', 'mceButtonNormal'); + // Ignore non element and hidden elements + if (n.nodeType != 1 || (DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved'))) + return; - // Has redo levels - if (undo_index != -1 && (undo_index < undo_levels-1 && undo_levels > 0)) - tinyMCE.switchClass(editor_id + '_redo', 'mceButtonNormal'); - - // Has undo levels - if (undo_index != -1 && (undo_index > 0 && undo_levels > 0)) - tinyMCE.switchClass(editor_id + '_undo', 'mceButtonNormal'); + // Fake name + if (v = DOM.getAttrib(n, 'mce_name')) + na = v; + + // Handle prefix + if (tinymce.isIE && n.scopeName !== 'HTML') + na = n.scopeName + ':' + na; - // Select class in select box - var selectElm = document.getElementById(editor_id + "_styleSelect"); - - if (selectElm) { - TinyMCE_AdvancedTheme._setupCSSClasses(editor_id); + // Remove internal prefix + na = na.replace(/mce\:/g, ''); - classNode = node; - breakOut = false; - var index = 0; + // Handle node name + switch (na) { + case 'b': + na = 'strong'; + break; - do { - if (classNode && classNode.className) { - for (var i=0; i"); - else - selectByValue(selectElm, ""); - } + if (v = DOM.getAttrib(n, 'href')) + ti += 'href: ' + v + ' '; - // Select fontselect - var selectElm = document.getElementById(editor_id + "_fontNameSelect"); - if (selectElm) { - if (!tinyMCE.isSafari && !(tinyMCE.isMSIE && !tinyMCE.isOpera)) { - var face = inst.queryCommandValue('FontName'); + break; - face = face == null || face == "" ? "" : face; + case 'font': + if (s.convert_fonts_to_spans) + na = 'span'; - selectByValue(selectElm, face, face != ""); - } else { - var elm = tinyMCE.getParentElement(node, "font", "face"); + if (v = DOM.getAttrib(n, 'face')) + ti += 'font: ' + v + ' '; - if (elm) { - var family = tinyMCE.getAttrib(elm, "face"); + if (v = DOM.getAttrib(n, 'size')) + ti += 'size: ' + v + ' '; - if (family == '') - family = '' + elm.style.fontFamily; + if (v = DOM.getAttrib(n, 'color')) + ti += 'color: ' + v + ' '; - if (!selectByValue(selectElm, family, family != "")) - selectByValue(selectElm, ""); - } else - selectByValue(selectElm, ""); - } - } + break; + + case 'span': + if (v = DOM.getAttrib(n, 'style')) + ti += 'style: ' + v + ' '; - // Select fontsize - var selectElm = document.getElementById(editor_id + "_fontSizeSelect"); - if (selectElm) { - if (!tinyMCE.isSafari && !tinyMCE.isOpera) { - var size = inst.queryCommandValue('FontSize'); - selectByValue(selectElm, size == null || size == "" ? "0" : size); - } else { - var elm = tinyMCE.getParentElement(node, "font", "size"); - if (elm) { - var size = tinyMCE.getAttrib(elm, "size"); + break; + } + + if (v = DOM.getAttrib(n, 'id')) + ti += 'id: ' + v + ' '; - if (size == '') { - var sizes = new Array('', '8px', '10px', '12px', '14px', '18px', '24px', '36px'); - - size = '' + elm.style.fontSize; + if (v = n.className) { + v = v.replace(/(webkit-[\w\-]+|Apple-[\w\-]+|mceItem\w+|mceVisualAid)/g, ''); - for (var i=0; i 0) - selectElm.setAttribute('cssImported', 'true'); - } - }, + _mceHelp : function() { + var ed = this.editor; - _setCookie : function(name, value, expires, path, domain, secure) { - var curCookie = name + "=" + escape(value) + - ((expires) ? "; expires=" + expires.toGMTString() : "") + - ((path) ? "; path=" + escape(path) : "") + - ((domain) ? "; domain=" + domain : "") + - ((secure) ? "; secure" : ""); + ed.windowManager.open({ + url : tinymce.baseURL + '/themes/advanced/about.htm', + width : 480, + height : 380, + inline : true + }, { + theme_url : this.url + }); + }, - document.cookie = curCookie; - }, + _mceColorPicker : function(u, v) { + var ed = this.editor; - _getCookie : function(name) { - var dc = document.cookie; - var prefix = name + "="; - var begin = dc.indexOf("; " + prefix); - - if (begin == -1) { - begin = dc.indexOf(prefix); + v = v || {}; - 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)); - }, + 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 + }); + }, - _resizeTo : function(inst, w, h, set_w) { - var editorContainer = document.getElementById(inst.editorId + '_parent'); - var tableElm = editorContainer.firstChild; - var iframe = inst.iframeElement; - - if (w == null || w == "null") { - set_w = false; - w = 0; - } - - if (h == null || h == "null") - return; - - w = parseInt(w); - h = parseInt(h); + _mceCodeEditor : function(ui, val) { + var ed = this.editor; - if (tinyMCE.isGecko) { - w += 2; - h += 2; - } - - var dx = w - tableElm.clientWidth; - var dy = h - tableElm.clientHeight; - - w = w < 1 ? 30 : w; - h = h < 1 ? 30 : h; - - if (set_w) - tableElm.style.width = w + "px"; - - tableElm.style.height = h + "px"; + 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 + }); + }, - iw = iframe.clientWidth + dx; - ih = iframe.clientHeight + dy; - - iw = iw < 1 ? 30 : iw; - ih = ih < 1 ? 30 : ih; + _mceImage : function(ui, val) { + var ed = this.editor; - if (tinyMCE.isGecko) { - iw -= 2; - ih -= 2; - } - - if (set_w) - iframe.style.width = iw + "px"; - - iframe.style.height = ih + "px"; + 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 + }); + }, - // Is it to small, make it bigger again - if (set_w) { - var tableBodyElm = tableElm.firstChild; - var minIframeWidth = tableBodyElm.scrollWidth; - if (inst.iframeElement.clientWidth < minIframeWidth) { - dx = minIframeWidth - inst.iframeElement.clientWidth; - - inst.iframeElement.style.width = (iw + dx) + "px"; - } - } + _mceLink : function(ui, val) { + var ed = this.editor; - // Remove pesky table controls - inst.useCSS = false; - }, + 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 + }); + }, - /** - * Handles resizing events. - */ - _resizeEventHandler : function(e) { - var resizer = TinyMCE_AdvancedTheme._resizer; - - // Do nothing - if (!resizer.resizing) - return; - - e = typeof(e) == "undefined" ? window.event : e; + _mceNewDocument : function() { + var ed = this.editor; - var dx = e.screenX - resizer.downX; - var dy = e.screenY - resizer.downY; - var resizeBox = resizer.resizeBox; - var editorId = resizer.editorId; - - switch (e.type) { - case "mousemove": - var w, h; + ed.windowManager.confirm('advanced.newdocument', function(s) { + if (s) + ed.execCommand('mceSetContent', false, ''); + }); + }, - w = resizer.width + dx; - h = resizer.height + dy; - - w = w < 1 ? 1 : w; - h = h < 1 ? 1 : h; - - if (resizer.horizontal) - resizeBox.style.width = w + "px"; + _mceForeColor : function() { + var t = this; - resizeBox.style.height = h + "px"; - break; - - case "mouseup": - TinyMCE_AdvancedTheme._setResizing(e, editorId, false); - TinyMCE_AdvancedTheme._resizeTo(tinyMCE.getInstanceById(editorId), resizer.width + dx, resizer.height + dy, resizer.horizontal); + this._mceColorPicker(0, { + func : function(co) { + t.editor.execCommand('ForeColor', false, co); + } + }); + }, - // Expire in a month - if (tinyMCE.getParam("theme_advanced_resizing_use_cookie", true)) { - var expires = new Date(); - expires.setTime(expires.getTime() + 3600000 * 24 * 30); + _mceBackColor : function() { + var t = this; - // Set the cookies - TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + editorId + "_width", "" + (resizer.horizontal ? resizer.width + dx : ""), expires); - TinyMCE_AdvancedTheme._setCookie("TinyMCE_" + editorId + "_height", "" + (resizer.height + dy), expires); + this._mceColorPicker(0, { + func : function(co) { + t.editor.execCommand('HiliteColor', false, co); } - break; + }); } - }, - - /** - * Starts/stops the editor resizing. - */ - _setResizing : function(e, editor_id, state) { - e = typeof(e) == "undefined" ? window.event : e; - - var resizer = TinyMCE_AdvancedTheme._resizer; - var editorContainer = document.getElementById(editor_id + '_parent'); - var editorArea = document.getElementById(editor_id + '_parent').firstChild; - var resizeBox = document.getElementById(editor_id + '_resize_box'); - var inst = tinyMCE.getInstanceById(editor_id); - - if (state) { - // Place box over editor area - var width = editorArea.clientWidth; - var height = editorArea.clientHeight; - - resizeBox.style.width = width + "px"; - resizeBox.style.height = height + "px"; - - resizer.iframeWidth = inst.iframeElement.clientWidth; - resizer.iframeHeight = inst.iframeElement.clientHeight; - - // Hide editor and show resize box - editorArea.style.display = "none"; - resizeBox.style.display = "block"; - - // Add event handlers, only once - if (!resizer.eventHandlers) { - if (tinyMCE.isMSIE) - tinyMCE.addEvent(document, "mousemove", TinyMCE_AdvancedTheme._resizeEventHandler); - else - tinyMCE.addEvent(window, "mousemove", TinyMCE_AdvancedTheme._resizeEventHandler); - - tinyMCE.addEvent(document, "mouseup", TinyMCE_AdvancedTheme._resizeEventHandler); - - resizer.eventHandlers = true; - } - - resizer.resizing = true; - resizer.downX = e.screenX; - resizer.downY = e.screenY; - resizer.width = parseInt(resizeBox.style.width); - resizer.height = parseInt(resizeBox.style.height); - resizer.editorId = editor_id; - resizer.resizeBox = resizeBox; - resizer.horizontal = tinyMCE.getParam("theme_advanced_resize_horizontal", true); - } else { - resizer.resizing = false; - resizeBox.style.display = "none"; - editorArea.style.display = tinyMCE.isMSIE && !tinyMCE.isOpera ? "block" : "table"; - tinyMCE.execCommand('mceResetDesignMode'); - } - }, - - _getColorHTML : function(id, n, cm) { - var i, h, cl; - - h = ''; - cl = tinyMCE.getParam(n, TinyMCE_AdvancedTheme._defColors).split(','); - - h += ''; - for (i=0; i'; - - if ((i+1) % 8 == 0) - h += ''; - } - - h += '
'; - - if (tinyMCE.getParam("theme_advanced_more_colors", true)) - h += '' + tinyMCE.getLang('lang_more_colors') + ''; - - return h; - }, - - _pickColor : function(id, cm) { - var inputColor, inst = tinyMCE.selectedInstance; - - if (cm == 'forecolor' && inst) - inputColor = inst.foreColor; - - if ((cm == 'backcolor' || cm == 'HiliteColor') && inst) - inputColor = inst.backColor; - - tinyMCE.execCommand('mceColorPicker', true, {color : inputColor, callback : function(c) { - tinyMCE.execInstanceCommand(id, cm, false, c); - }}); - }, - - _insertImage : function(src, alt, border, hspace, vspace, width, height, align, title, onmouseover, onmouseout) { - tinyMCE.execCommand('mceBeginUndoLevel'); - - if (src == "") - return; - - if (!tinyMCE.imgElement && tinyMCE.isSafari) { - var html = ""; - - html += '' + alt + ''; - - tinyMCE.execCommand("mceInsertContent", false, html); - } else { - if (!tinyMCE.imgElement && tinyMCE.selectedInstance) { - if (tinyMCE.isSafari) - tinyMCE.execCommand("mceInsertContent", false, ''); - else - tinyMCE.selectedInstance.contentDocument.execCommand("insertimage", false, tinyMCE.uniqueURL); - - tinyMCE.imgElement = tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "img", "src", tinyMCE.uniqueURL); - } - } - - if (tinyMCE.imgElement) { - var needsRepaint = false; - var msrc = src; + }); - src = eval(tinyMCE.settings['urlconverter_callback'] + "(src, tinyMCE.imgElement);"); - - if (tinyMCE.getParam('convert_urls')) - msrc = src; - - if (onmouseover && onmouseover != "") - onmouseover = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseover, tinyMCE.imgElement);") + "';"; - - if (onmouseout && onmouseout != "") - onmouseout = "this.src='" + eval(tinyMCE.settings['urlconverter_callback'] + "(onmouseout, tinyMCE.imgElement);") + "';"; - - // Use alt as title if it's undefined - if (typeof(title) == "undefined") - title = alt; - - if (width != tinyMCE.imgElement.getAttribute("width") || height != tinyMCE.imgElement.getAttribute("height") || align != tinyMCE.imgElement.getAttribute("align")) - needsRepaint = true; - - tinyMCE.setAttrib(tinyMCE.imgElement, 'src', src); - tinyMCE.setAttrib(tinyMCE.imgElement, 'mce_src', msrc); - tinyMCE.setAttrib(tinyMCE.imgElement, 'alt', alt); - tinyMCE.setAttrib(tinyMCE.imgElement, 'title', title); - tinyMCE.setAttrib(tinyMCE.imgElement, 'align', align); - tinyMCE.setAttrib(tinyMCE.imgElement, 'border', border, true); - tinyMCE.setAttrib(tinyMCE.imgElement, 'hspace', hspace, true); - tinyMCE.setAttrib(tinyMCE.imgElement, 'vspace', vspace, true); - tinyMCE.setAttrib(tinyMCE.imgElement, 'width', width, true); - tinyMCE.setAttrib(tinyMCE.imgElement, 'height', height, true); - tinyMCE.setAttrib(tinyMCE.imgElement, 'onmouseover', onmouseover); - tinyMCE.setAttrib(tinyMCE.imgElement, 'onmouseout', onmouseout); - - // Fix for bug #989846 - Image resize bug - if (width && width != "") - tinyMCE.imgElement.style.pixelWidth = width; - - if (height && height != "") - tinyMCE.imgElement.style.pixelHeight = height; - - if (needsRepaint) - tinyMCE.selectedInstance.repaint(); - } - - tinyMCE.execCommand('mceEndUndoLevel'); - }, - - _insertLink : function(href, target, title, onclick, style_class) { - tinyMCE.execCommand('mceBeginUndoLevel'); - - if (tinyMCE.selectedInstance && tinyMCE.selectedElement && tinyMCE.selectedElement.nodeName.toLowerCase() == "img") { - var doc = tinyMCE.selectedInstance.getDoc(); - var linkElement = tinyMCE.getParentElement(tinyMCE.selectedElement, "a"); - var newLink = false; - - if (!linkElement) { - linkElement = doc.createElement("a"); - newLink = true; - } - - var mhref = href; - var thref = eval(tinyMCE.settings['urlconverter_callback'] + "(href, linkElement);"); - mhref = tinyMCE.getParam('convert_urls') ? href : mhref; - - tinyMCE.setAttrib(linkElement, 'href', thref); - tinyMCE.setAttrib(linkElement, 'mce_href', mhref); - tinyMCE.setAttrib(linkElement, 'target', target); - tinyMCE.setAttrib(linkElement, 'title', title); - tinyMCE.setAttrib(linkElement, 'onclick', onclick); - tinyMCE.setAttrib(linkElement, 'class', style_class); - - if (newLink) { - linkElement.appendChild(tinyMCE.selectedElement.cloneNode(true)); - tinyMCE.selectedElement.parentNode.replaceChild(linkElement, tinyMCE.selectedElement); - } - - return; - } - - if (!tinyMCE.linkElement && tinyMCE.selectedInstance) { - if (tinyMCE.isSafari) { - tinyMCE.execCommand("mceInsertContent", false, '' + tinyMCE.selectedInstance.selection.getSelectedHTML() + ''); - } else - tinyMCE.selectedInstance.contentDocument.execCommand("createlink", false, tinyMCE.uniqueURL); - - tinyMCE.linkElement = tinyMCE.getElementByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL); - - var elementArray = tinyMCE.getElementsByAttributeValue(tinyMCE.selectedInstance.contentDocument.body, "a", "href", tinyMCE.uniqueURL); - - for (var i=0; i - {$lang_insert_image_title} - - - - + {#advanced_dlg.image_title} + + + + - -
+ + @@ -19,68 +20,53 @@
- + - - - + + + + - - + + - - + - - + + - - + + - - + + - - + +
- +
 
+ x -
@@ -88,11 +74,11 @@
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/anchor.gif Binary file includes/clientside/tinymce/themes/advanced/images/anchor.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/anchor_symbol.gif Binary file includes/clientside/tinymce/themes/advanced/images/anchor_symbol.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/backcolor.gif Binary file includes/clientside/tinymce/themes/advanced/images/backcolor.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/bold.gif Binary file includes/clientside/tinymce/themes/advanced/images/bold.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/bold_de_se.gif Binary file includes/clientside/tinymce/themes/advanced/images/bold_de_se.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/bold_es.gif Binary file includes/clientside/tinymce/themes/advanced/images/bold_es.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/bold_fr.gif Binary file includes/clientside/tinymce/themes/advanced/images/bold_fr.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/bold_ru.gif Binary file includes/clientside/tinymce/themes/advanced/images/bold_ru.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/bold_tw.gif Binary file includes/clientside/tinymce/themes/advanced/images/bold_tw.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/browse.gif Binary file includes/clientside/tinymce/themes/advanced/images/browse.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/bullist.gif Binary file includes/clientside/tinymce/themes/advanced/images/bullist.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/button_menu.gif Binary file includes/clientside/tinymce/themes/advanced/images/button_menu.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/buttons.gif Binary file includes/clientside/tinymce/themes/advanced/images/buttons.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/cancel_button_bg.gif Binary file includes/clientside/tinymce/themes/advanced/images/cancel_button_bg.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/charmap.gif Binary file includes/clientside/tinymce/themes/advanced/images/charmap.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/cleanup.gif Binary file includes/clientside/tinymce/themes/advanced/images/cleanup.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/close.gif Binary file includes/clientside/tinymce/themes/advanced/images/close.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/code.gif Binary file includes/clientside/tinymce/themes/advanced/images/code.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/color.gif Binary file includes/clientside/tinymce/themes/advanced/images/color.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/colors.jpg Binary file includes/clientside/tinymce/themes/advanced/images/colors.jpg has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/copy.gif Binary file includes/clientside/tinymce/themes/advanced/images/copy.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/custom_1.gif Binary file includes/clientside/tinymce/themes/advanced/images/custom_1.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/cut.gif Binary file includes/clientside/tinymce/themes/advanced/images/cut.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/forecolor.gif Binary file includes/clientside/tinymce/themes/advanced/images/forecolor.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/help.gif Binary file includes/clientside/tinymce/themes/advanced/images/help.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/hr.gif Binary file includes/clientside/tinymce/themes/advanced/images/hr.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/image.gif Binary file includes/clientside/tinymce/themes/advanced/images/image.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/indent.gif Binary file includes/clientside/tinymce/themes/advanced/images/indent.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/insert_button_bg.gif Binary file includes/clientside/tinymce/themes/advanced/images/insert_button_bg.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/italic.gif Binary file includes/clientside/tinymce/themes/advanced/images/italic.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/italic_de_se.gif Binary file includes/clientside/tinymce/themes/advanced/images/italic_de_se.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/italic_es.gif Binary file includes/clientside/tinymce/themes/advanced/images/italic_es.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/italic_ru.gif Binary file includes/clientside/tinymce/themes/advanced/images/italic_ru.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/italic_tw.gif Binary file includes/clientside/tinymce/themes/advanced/images/italic_tw.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/justifycenter.gif Binary file includes/clientside/tinymce/themes/advanced/images/justifycenter.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/justifyfull.gif Binary file includes/clientside/tinymce/themes/advanced/images/justifyfull.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/justifyleft.gif Binary file includes/clientside/tinymce/themes/advanced/images/justifyleft.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/justifyright.gif Binary file includes/clientside/tinymce/themes/advanced/images/justifyright.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/link.gif Binary file includes/clientside/tinymce/themes/advanced/images/link.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/menu_check.gif Binary file includes/clientside/tinymce/themes/advanced/images/menu_check.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/newdocument.gif Binary file includes/clientside/tinymce/themes/advanced/images/newdocument.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/numlist.gif Binary file includes/clientside/tinymce/themes/advanced/images/numlist.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/opacity.png Binary file includes/clientside/tinymce/themes/advanced/images/opacity.png has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/outdent.gif Binary file includes/clientside/tinymce/themes/advanced/images/outdent.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/paste.gif Binary file includes/clientside/tinymce/themes/advanced/images/paste.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/redo.gif Binary file includes/clientside/tinymce/themes/advanced/images/redo.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/removeformat.gif Binary file includes/clientside/tinymce/themes/advanced/images/removeformat.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/separator.gif Binary file includes/clientside/tinymce/themes/advanced/images/separator.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/spacer.gif Binary file includes/clientside/tinymce/themes/advanced/images/spacer.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/statusbar_resize.gif Binary file includes/clientside/tinymce/themes/advanced/images/statusbar_resize.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/strikethrough.gif Binary file includes/clientside/tinymce/themes/advanced/images/strikethrough.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/sub.gif Binary file includes/clientside/tinymce/themes/advanced/images/sub.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/sup.gif Binary file includes/clientside/tinymce/themes/advanced/images/sup.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/underline.gif Binary file includes/clientside/tinymce/themes/advanced/images/underline.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/underline_es.gif Binary file includes/clientside/tinymce/themes/advanced/images/underline_es.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/underline_fr.gif Binary file includes/clientside/tinymce/themes/advanced/images/underline_fr.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/underline_ru.gif Binary file includes/clientside/tinymce/themes/advanced/images/underline_ru.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/underline_tw.gif Binary file includes/clientside/tinymce/themes/advanced/images/underline_tw.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/undo.gif Binary file includes/clientside/tinymce/themes/advanced/images/undo.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/unlink.gif Binary file includes/clientside/tinymce/themes/advanced/images/unlink.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/visualaid.gif Binary file includes/clientside/tinymce/themes/advanced/images/visualaid.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/xp/tab_bg.gif Binary file includes/clientside/tinymce/themes/advanced/images/xp/tab_bg.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/xp/tab_end.gif Binary file includes/clientside/tinymce/themes/advanced/images/xp/tab_end.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/xp/tab_sel_bg.gif Binary file includes/clientside/tinymce/themes/advanced/images/xp/tab_sel_bg.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/xp/tab_sel_end.gif Binary file includes/clientside/tinymce/themes/advanced/images/xp/tab_sel_end.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/images/xp/tabs_bg.gif Binary file includes/clientside/tinymce/themes/advanced/images/xp/tabs_bg.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/img/colorpicker.jpg Binary file includes/clientside/tinymce/themes/advanced/img/colorpicker.jpg has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/img/icons.gif Binary file includes/clientside/tinymce/themes/advanced/img/icons.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/js/about.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/js/about.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,76 @@ +tinyMCEPopup.requireLangPack(); + +function init() { + var ed, tcont; + + tinyMCEPopup.resizeToInnerSize(); + ed = tinyMCEPopup.editor; + + // Give FF some time + window.setTimeout('insertHelpIFrame();', 10); + + tcont = document.getElementById('plugintablecontainer'); + document.getElementById('plugins_tab').style.display = 'none'; + + var html = ""; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + html += ''; + + tinymce.each(ed.plugins, function(p, n) { + var info; + + if (!p.getInfo) + return; + + html += ''; + + info = p.getInfo(); + + if (info.infourl != null && info.infourl != '') + html += ''; + else + html += ''; + + if (info.authorurl != null && info.authorurl != '') + html += ''; + else + html += ''; + + html += ''; + html += ''; + + document.getElementById('plugins_tab').style.display = ''; + + }); + + html += ''; + html += '
' + ed.getLang('advanced_dlg.about_plugin') + '' + ed.getLang('advanced_dlg.about_author') + '' + ed.getLang('advanced_dlg.about_version') + '
' + info.longname + '' + info.longname + '' + info.author + '' + info.author + '' + info.version + '
'; + + tcont.innerHTML = html; + + tinyMCEPopup.dom.get('version').innerHTML = tinymce.majorVersion + "." + tinymce.minorVersion; + tinyMCEPopup.dom.get('date').innerHTML = tinymce.releaseDate; +} + +function insertHelpIFrame() { + var html; + + if (tinyMCEPopup.getParam('docs_url')) { + html = ''; + document.getElementById('iframecontainer').innerHTML = html; + document.getElementById('help_tab').style.display = 'block'; + } +} + +tinyMCEPopup.onInit.add(init); + +// For modal dialogs in IE +if (tinymce.isIE) + document.write(''); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/js/anchor.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/js/anchor.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,33 @@ +tinyMCEPopup.requireLangPack(); + +var AnchorDialog = { + init : function(ed) { + var action, elm, f = document.forms[0]; + + this.editor = ed; + elm = ed.dom.getParent(ed.selection.getNode(), 'A,IMG'); + v = ed.dom.getAttrib(elm, 'name'); + + if (v) + f.anchorName.value = v; + + f.insert.value = ed.getLang(elm ? 'update' : 'insert'); + }, + + update : function() { + var ed = this.editor; + + tinyMCEPopup.restoreSelection(); + ed.selection.collapse(1); + + // Webkit acts weird if empty inline element is inserted so we need to use a image instead + if (tinymce.isWebKit) + ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('img', {mce_name : 'a', name : document.forms[0].anchorName.value, 'class' : 'mceItemAnchor'})); + else + ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', {name : document.forms[0].anchorName.value, 'class' : 'mceItemAnchor'}, '')); + + tinyMCEPopup.close(); + } +}; + +tinyMCEPopup.onInit.add(AnchorDialog.init, AnchorDialog); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/js/charmap.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/js/charmap.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,328 @@ +tinyMCEPopup.requireLangPack(); + +var charmap = [ + [' ', ' ', true, 'no-break space'], + ['&', '&', true, 'ampersand'], + ['"', '"', true, 'quotation mark'], +// finance + ['¢', '¢', true, 'cent sign'], + ['€', '€', true, 'euro sign'], + ['£', '£', true, 'pound sign'], + ['¥', '¥', true, 'yen sign'], +// signs + ['©', '©', true, 'copyright sign'], + ['®', '®', true, 'registered sign'], + ['™', '™', true, 'trade mark sign'], + ['‰', '‰', true, 'per mille sign'], + ['µ', 'µ', true, 'micro sign'], + ['·', '·', true, 'middle dot'], + ['•', '•', true, 'bullet'], + ['…', '…', true, 'three dot leader'], + ['′', '′', true, 'minutes / feet'], + ['″', '″', true, 'seconds / inches'], + ['§', '§', true, 'section sign'], + ['¶', '¶', true, 'paragraph sign'], + ['ß', 'ß', true, 'sharp s / ess-zed'], +// quotations + ['‹', '‹', true, 'single left-pointing angle quotation mark'], + ['›', '›', true, 'single right-pointing angle quotation mark'], + ['«', '«', true, 'left pointing guillemet'], + ['»', '»', true, 'right pointing guillemet'], + ['‘', '‘', true, 'left single quotation mark'], + ['’', '’', true, 'right single quotation mark'], + ['“', '“', true, 'left double quotation mark'], + ['”', '”', true, 'right double quotation mark'], + ['‚', '‚', true, 'single low-9 quotation mark'], + ['„', '„', true, 'double low-9 quotation mark'], + ['<', '<', true, 'less-than sign'], + ['>', '>', true, 'greater-than sign'], + ['≤', '≤', true, 'less-than or equal to'], + ['≥', '≥', true, 'greater-than or equal to'], + ['–', '–', true, 'en dash'], + ['—', '—', true, 'em dash'], + ['¯', '¯', true, 'macron'], + ['‾', '‾', true, 'overline'], + ['¤', '¤', true, 'currency sign'], + ['¦', '¦', true, 'broken bar'], + ['¨', '¨', true, 'diaeresis'], + ['¡', '¡', true, 'inverted exclamation mark'], + ['¿', '¿', true, 'turned question mark'], + ['ˆ', 'ˆ', true, 'circumflex accent'], + ['˜', '˜', true, 'small tilde'], + ['°', '°', true, 'degree sign'], + ['−', '−', true, 'minus sign'], + ['±', '±', true, 'plus-minus sign'], + ['÷', '÷', true, 'division sign'], + ['⁄', '⁄', true, 'fraction slash'], + ['×', '×', true, 'multiplication sign'], + ['¹', '¹', true, 'superscript one'], + ['²', '²', true, 'superscript two'], + ['³', '³', true, 'superscript three'], + ['¼', '¼', true, 'fraction one quarter'], + ['½', '½', true, 'fraction one half'], + ['¾', '¾', true, 'fraction three quarters'], +// math / logical + ['ƒ', 'ƒ', true, 'function / florin'], + ['∫', '∫', true, 'integral'], + ['∑', '∑', true, 'n-ary sumation'], + ['∞', '∞', true, 'infinity'], + ['√', '√', true, 'square root'], + ['∼', '∼', false,'similar to'], + ['≅', '≅', false,'approximately equal to'], + ['≈', '≈', true, 'almost equal to'], + ['≠', '≠', true, 'not equal to'], + ['≡', '≡', true, 'identical to'], + ['∈', '∈', false,'element of'], + ['∉', '∉', false,'not an element of'], + ['∋', '∋', false,'contains as member'], + ['∏', '∏', true, 'n-ary product'], + ['∧', '∧', false,'logical and'], + ['∨', '∨', false,'logical or'], + ['¬', '¬', true, 'not sign'], + ['∩', '∩', true, 'intersection'], + ['∪', '∪', false,'union'], + ['∂', '∂', true, 'partial differential'], + ['∀', '∀', false,'for all'], + ['∃', '∃', false,'there exists'], + ['∅', '∅', false,'diameter'], + ['∇', '∇', false,'backward difference'], + ['∗', '∗', false,'asterisk operator'], + ['∝', '∝', false,'proportional to'], + ['∠', '∠', false,'angle'], +// undefined + ['´', '´', true, 'acute accent'], + ['¸', '¸', true, 'cedilla'], + ['ª', 'ª', true, 'feminine ordinal indicator'], + ['º', 'º', true, 'masculine ordinal indicator'], + ['†', '†', true, 'dagger'], + ['‡', '‡', true, 'double dagger'], +// alphabetical special chars + ['À', 'À', true, 'A - grave'], + ['Á', 'Á', true, 'A - acute'], + ['Â', 'Â', true, 'A - circumflex'], + ['Ã', 'Ã', true, 'A - tilde'], + ['Ä', 'Ä', true, 'A - diaeresis'], + ['Å', 'Å', true, 'A - ring above'], + ['Æ', 'Æ', true, 'ligature AE'], + ['Ç', 'Ç', true, 'C - cedilla'], + ['È', 'È', true, 'E - grave'], + ['É', 'É', true, 'E - acute'], + ['Ê', 'Ê', true, 'E - circumflex'], + ['Ë', 'Ë', true, 'E - diaeresis'], + ['Ì', 'Ì', true, 'I - grave'], + ['Í', 'Í', true, 'I - acute'], + ['Î', 'Î', true, 'I - circumflex'], + ['Ï', 'Ï', true, 'I - diaeresis'], + ['Ð', 'Ð', true, 'ETH'], + ['Ñ', 'Ñ', true, 'N - tilde'], + ['Ò', 'Ò', true, 'O - grave'], + ['Ó', 'Ó', true, 'O - acute'], + ['Ô', 'Ô', true, 'O - circumflex'], + ['Õ', 'Õ', true, 'O - tilde'], + ['Ö', 'Ö', true, 'O - diaeresis'], + ['Ø', 'Ø', true, 'O - slash'], + ['Œ', 'Œ', true, 'ligature OE'], + ['Š', 'Š', true, 'S - caron'], + ['Ù', 'Ù', true, 'U - grave'], + ['Ú', 'Ú', true, 'U - acute'], + ['Û', 'Û', true, 'U - circumflex'], + ['Ü', 'Ü', true, 'U - diaeresis'], + ['Ý', 'Ý', true, 'Y - acute'], + ['Ÿ', 'Ÿ', true, 'Y - diaeresis'], + ['Þ', 'Þ', true, 'THORN'], + ['à', 'à', true, 'a - grave'], + ['á', 'á', true, 'a - acute'], + ['â', 'â', true, 'a - circumflex'], + ['ã', 'ã', true, 'a - tilde'], + ['ä', 'ä', true, 'a - diaeresis'], + ['å', 'å', true, 'a - ring above'], + ['æ', 'æ', true, 'ligature ae'], + ['ç', 'ç', true, 'c - cedilla'], + ['è', 'è', true, 'e - grave'], + ['é', 'é', true, 'e - acute'], + ['ê', 'ê', true, 'e - circumflex'], + ['ë', 'ë', true, 'e - diaeresis'], + ['ì', 'ì', true, 'i - grave'], + ['í', 'í', true, 'i - acute'], + ['î', 'î', true, 'i - circumflex'], + ['ï', 'ï', true, 'i - diaeresis'], + ['ð', 'ð', true, 'eth'], + ['ñ', 'ñ', true, 'n - tilde'], + ['ò', 'ò', true, 'o - grave'], + ['ó', 'ó', true, 'o - acute'], + ['ô', 'ô', true, 'o - circumflex'], + ['õ', 'õ', true, 'o - tilde'], + ['ö', 'ö', true, 'o - diaeresis'], + ['ø', 'ø', true, 'o slash'], + ['œ', 'œ', true, 'ligature oe'], + ['š', 'š', true, 's - caron'], + ['ù', 'ù', true, 'u - grave'], + ['ú', 'ú', true, 'u - acute'], + ['û', 'û', true, 'u - circumflex'], + ['ü', 'ü', true, 'u - diaeresis'], + ['ý', 'ý', true, 'y - acute'], + ['þ', 'þ', true, 'thorn'], + ['ÿ', 'ÿ', true, 'y - diaeresis'], + ['Α', 'Α', true, 'Alpha'], + ['Β', 'Β', true, 'Beta'], + ['Γ', 'Γ', true, 'Gamma'], + ['Δ', 'Δ', true, 'Delta'], + ['Ε', 'Ε', true, 'Epsilon'], + ['Ζ', 'Ζ', true, 'Zeta'], + ['Η', 'Η', true, 'Eta'], + ['Θ', 'Θ', true, 'Theta'], + ['Ι', 'Ι', true, 'Iota'], + ['Κ', 'Κ', true, 'Kappa'], + ['Λ', 'Λ', true, 'Lambda'], + ['Μ', 'Μ', true, 'Mu'], + ['Ν', 'Ν', true, 'Nu'], + ['Ξ', 'Ξ', true, 'Xi'], + ['Ο', 'Ο', true, 'Omicron'], + ['Π', 'Π', true, 'Pi'], + ['Ρ', 'Ρ', true, 'Rho'], + ['Σ', 'Σ', true, 'Sigma'], + ['Τ', 'Τ', true, 'Tau'], + ['Υ', 'Υ', true, 'Upsilon'], + ['Φ', 'Φ', true, 'Phi'], + ['Χ', 'Χ', true, 'Chi'], + ['Ψ', 'Ψ', true, 'Psi'], + ['Ω', 'Ω', true, 'Omega'], + ['α', 'α', true, 'alpha'], + ['β', 'β', true, 'beta'], + ['γ', 'γ', true, 'gamma'], + ['δ', 'δ', true, 'delta'], + ['ε', 'ε', true, 'epsilon'], + ['ζ', 'ζ', true, 'zeta'], + ['η', 'η', true, 'eta'], + ['θ', 'θ', true, 'theta'], + ['ι', 'ι', true, 'iota'], + ['κ', 'κ', true, 'kappa'], + ['λ', 'λ', true, 'lambda'], + ['μ', 'μ', true, 'mu'], + ['ν', 'ν', true, 'nu'], + ['ξ', 'ξ', true, 'xi'], + ['ο', 'ο', true, 'omicron'], + ['π', 'π', true, 'pi'], + ['ρ', 'ρ', true, 'rho'], + ['ς', 'ς', true, 'final sigma'], + ['σ', 'σ', true, 'sigma'], + ['τ', 'τ', true, 'tau'], + ['υ', 'υ', true, 'upsilon'], + ['φ', 'φ', true, 'phi'], + ['χ', 'χ', true, 'chi'], + ['ψ', 'ψ', true, 'psi'], + ['ω', 'ω', true, 'omega'], +// symbols + ['ℵ', 'ℵ', false,'alef symbol'], + ['ϖ', 'ϖ', false,'pi symbol'], + ['ℜ', 'ℜ', false,'real part symbol'], + ['ϑ','ϑ', false,'theta symbol'], + ['ϒ', 'ϒ', false,'upsilon - hook symbol'], + ['℘', '℘', false,'Weierstrass p'], + ['ℑ', 'ℑ', false,'imaginary part'], +// arrows + ['←', '←', true, 'leftwards arrow'], + ['↑', '↑', true, 'upwards arrow'], + ['→', '→', true, 'rightwards arrow'], + ['↓', '↓', true, 'downwards arrow'], + ['↔', '↔', true, 'left right arrow'], + ['↵', '↵', false,'carriage return'], + ['⇐', '⇐', false,'leftwards double arrow'], + ['⇑', '⇑', false,'upwards double arrow'], + ['⇒', '⇒', false,'rightwards double arrow'], + ['⇓', '⇓', false,'downwards double arrow'], + ['⇔', '⇔', false,'left right double arrow'], + ['∴', '∴', false,'therefore'], + ['⊂', '⊂', false,'subset of'], + ['⊃', '⊃', false,'superset of'], + ['⊄', '⊄', false,'not a subset of'], + ['⊆', '⊆', false,'subset of or equal to'], + ['⊇', '⊇', false,'superset of or equal to'], + ['⊕', '⊕', false,'circled plus'], + ['⊗', '⊗', false,'circled times'], + ['⊥', '⊥', false,'perpendicular'], + ['⋅', '⋅', false,'dot operator'], + ['⌈', '⌈', false,'left ceiling'], + ['⌉', '⌉', false,'right ceiling'], + ['⌊', '⌊', false,'left floor'], + ['⌋', '⌋', false,'right floor'], + ['⟨', '〈', false,'left-pointing angle bracket'], + ['⟩', '〉', false,'right-pointing angle bracket'], + ['◊', '◊', true,'lozenge'], + ['♠', '♠', false,'black spade suit'], + ['♣', '♣', true, 'black club suit'], + ['♥', '♥', true, 'black heart suit'], + ['♦', '♦', true, 'black diamond suit'], + [' ', ' ', false,'en space'], + [' ', ' ', false,'em space'], + [' ', ' ', false,'thin space'], + ['‌', '‌', false,'zero width non-joiner'], + ['‍', '‍', false,'zero width joiner'], + ['‎', '‎', false,'left-to-right mark'], + ['‏', '‏', false,'right-to-left mark'], + ['­', '­', false,'soft hyphen'] +]; + +tinyMCEPopup.onInit.add(function() { + tinyMCEPopup.dom.setHTML('charmap', renderCharMapHTML()); +}); + +function renderCharMapHTML() { + var charsPerRow = 20, tdWidth=20, tdHeight=20, i; + var html = ''; + var cols=-1; + + for (i=0; i' + + charmap[i][1] + + ''; + if ((cols+1) % charsPerRow == 0) + html += ''; + } + } + + if (cols % charsPerRow > 0) { + var padd = charsPerRow - (cols % charsPerRow); + for (var i=0; i '; + } + + html += '
'; + + return html; +} + +function insertChar(chr) { + tinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';'); + + // Refocus in window + if (tinyMCEPopup.isWindow) + window.focus(); + + tinyMCEPopup.editor.focus(); + tinyMCEPopup.close(); +} + +function previewChar(codeA, codeB, codeN) { + var elmA = document.getElementById('codeA'); + var elmB = document.getElementById('codeB'); + var elmV = document.getElementById('codeV'); + var elmN = document.getElementById('codeN'); + + if (codeA=='#160;') { + elmV.innerHTML = '__'; + } else { + elmV.innerHTML = '&' + codeA; + } + + elmB.innerHTML = '&' + codeA; + elmA.innerHTML = '&' + codeB; + elmN.innerHTML = codeN; +} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/js/color_picker.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/js/color_picker.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,245 @@ +tinyMCEPopup.requireLangPack(); + +var detail = 50, strhex = "0123456789abcdef", i, isMouseDown = false, isMouseOver = false; + +var colors = new Array( + "#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033", + "#330066","#330099","#3300cc","#3300ff","#660000","#660033","#660066","#660099", + "#6600cc","#6600ff","#990000","#990033","#990066","#990099","#9900cc","#9900ff", + "#cc0000","#cc0033","#cc0066","#cc0099","#cc00cc","#cc00ff","#ff0000","#ff0033", + "#ff0066","#ff0099","#ff00cc","#ff00ff","#003300","#003333","#003366","#003399", + "#0033cc","#0033ff","#333300","#333333","#333366","#333399","#3333cc","#3333ff", + "#663300","#663333","#663366","#663399","#6633cc","#6633ff","#993300","#993333", + "#993366","#993399","#9933cc","#9933ff","#cc3300","#cc3333","#cc3366","#cc3399", + "#cc33cc","#cc33ff","#ff3300","#ff3333","#ff3366","#ff3399","#ff33cc","#ff33ff", + "#006600","#006633","#006666","#006699","#0066cc","#0066ff","#336600","#336633", + "#336666","#336699","#3366cc","#3366ff","#666600","#666633","#666666","#666699", + "#6666cc","#6666ff","#996600","#996633","#996666","#996699","#9966cc","#9966ff", + "#cc6600","#cc6633","#cc6666","#cc6699","#cc66cc","#cc66ff","#ff6600","#ff6633", + "#ff6666","#ff6699","#ff66cc","#ff66ff","#009900","#009933","#009966","#009999", + "#0099cc","#0099ff","#339900","#339933","#339966","#339999","#3399cc","#3399ff", + "#669900","#669933","#669966","#669999","#6699cc","#6699ff","#999900","#999933", + "#999966","#999999","#9999cc","#9999ff","#cc9900","#cc9933","#cc9966","#cc9999", + "#cc99cc","#cc99ff","#ff9900","#ff9933","#ff9966","#ff9999","#ff99cc","#ff99ff", + "#00cc00","#00cc33","#00cc66","#00cc99","#00cccc","#00ccff","#33cc00","#33cc33", + "#33cc66","#33cc99","#33cccc","#33ccff","#66cc00","#66cc33","#66cc66","#66cc99", + "#66cccc","#66ccff","#99cc00","#99cc33","#99cc66","#99cc99","#99cccc","#99ccff", + "#cccc00","#cccc33","#cccc66","#cccc99","#cccccc","#ccccff","#ffcc00","#ffcc33", + "#ffcc66","#ffcc99","#ffcccc","#ffccff","#00ff00","#00ff33","#00ff66","#00ff99", + "#00ffcc","#00ffff","#33ff00","#33ff33","#33ff66","#33ff99","#33ffcc","#33ffff", + "#66ff00","#66ff33","#66ff66","#66ff99","#66ffcc","#66ffff","#99ff00","#99ff33", + "#99ff66","#99ff99","#99ffcc","#99ffff","#ccff00","#ccff33","#ccff66","#ccff99", + "#ccffcc","#ccffff","#ffff00","#ffff33","#ffff66","#ffff99","#ffffcc","#ffffff" +); + +var named = { + '#F0F8FF':'AliceBlue','#FAEBD7':'AntiqueWhite','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige', + '#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'BlanchedAlmond','#0000FF':'Blue','#8A2BE2':'BlueViolet','#A52A2A':'Brown', + '#DEB887':'BurlyWood','#5F9EA0':'CadetBlue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'CornflowerBlue', + '#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'DarkBlue','#008B8B':'DarkCyan','#B8860B':'DarkGoldenRod', + '#A9A9A9':'DarkGray','#A9A9A9':'DarkGrey','#006400':'DarkGreen','#BDB76B':'DarkKhaki','#8B008B':'DarkMagenta','#556B2F':'DarkOliveGreen', + '#FF8C00':'Darkorange','#9932CC':'DarkOrchid','#8B0000':'DarkRed','#E9967A':'DarkSalmon','#8FBC8F':'DarkSeaGreen','#483D8B':'DarkSlateBlue', + '#2F4F4F':'DarkSlateGray','#2F4F4F':'DarkSlateGrey','#00CED1':'DarkTurquoise','#9400D3':'DarkViolet','#FF1493':'DeepPink','#00BFFF':'DeepSkyBlue', + '#696969':'DimGray','#696969':'DimGrey','#1E90FF':'DodgerBlue','#B22222':'FireBrick','#FFFAF0':'FloralWhite','#228B22':'ForestGreen', + '#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'GhostWhite','#FFD700':'Gold','#DAA520':'GoldenRod','#808080':'Gray','#808080':'Grey', + '#008000':'Green','#ADFF2F':'GreenYellow','#F0FFF0':'HoneyDew','#FF69B4':'HotPink','#CD5C5C':'IndianRed','#4B0082':'Indigo','#FFFFF0':'Ivory', + '#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'LavenderBlush','#7CFC00':'LawnGreen','#FFFACD':'LemonChiffon','#ADD8E6':'LightBlue', + '#F08080':'LightCoral','#E0FFFF':'LightCyan','#FAFAD2':'LightGoldenRodYellow','#D3D3D3':'LightGray','#D3D3D3':'LightGrey','#90EE90':'LightGreen', + '#FFB6C1':'LightPink','#FFA07A':'LightSalmon','#20B2AA':'LightSeaGreen','#87CEFA':'LightSkyBlue','#778899':'LightSlateGray','#778899':'LightSlateGrey', + '#B0C4DE':'LightSteelBlue','#FFFFE0':'LightYellow','#00FF00':'Lime','#32CD32':'LimeGreen','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon', + '#66CDAA':'MediumAquaMarine','#0000CD':'MediumBlue','#BA55D3':'MediumOrchid','#9370D8':'MediumPurple','#3CB371':'MediumSeaGreen','#7B68EE':'MediumSlateBlue', + '#00FA9A':'MediumSpringGreen','#48D1CC':'MediumTurquoise','#C71585':'MediumVioletRed','#191970':'MidnightBlue','#F5FFFA':'MintCream','#FFE4E1':'MistyRose','#FFE4B5':'Moccasin', + '#FFDEAD':'NavajoWhite','#000080':'Navy','#FDF5E6':'OldLace','#808000':'Olive','#6B8E23':'OliveDrab','#FFA500':'Orange','#FF4500':'OrangeRed','#DA70D6':'Orchid', + '#EEE8AA':'PaleGoldenRod','#98FB98':'PaleGreen','#AFEEEE':'PaleTurquoise','#D87093':'PaleVioletRed','#FFEFD5':'PapayaWhip','#FFDAB9':'PeachPuff', + '#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'PowderBlue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'RosyBrown','#4169E1':'RoyalBlue', + '#8B4513':'SaddleBrown','#FA8072':'Salmon','#F4A460':'SandyBrown','#2E8B57':'SeaGreen','#FFF5EE':'SeaShell','#A0522D':'Sienna','#C0C0C0':'Silver', + '#87CEEB':'SkyBlue','#6A5ACD':'SlateBlue','#708090':'SlateGray','#708090':'SlateGrey','#FFFAFA':'Snow','#00FF7F':'SpringGreen', + '#4682B4':'SteelBlue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet', + '#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'WhiteSmoke','#FFFF00':'Yellow','#9ACD32':'YellowGreen' +}; + +function init() { + var inputColor = convertRGBToHex(tinyMCEPopup.getWindowArg('input_color')); + + tinyMCEPopup.resizeToInnerSize(); + + generatePicker(); + + if (inputColor) { + changeFinalColor(inputColor); + + col = convertHexToRGB(inputColor); + + if (col) + updateLight(col.r, col.g, col.b); + } +} + +function insertAction() { + var color = document.getElementById("color").value, f = tinyMCEPopup.getWindowArg('func'); + + tinyMCEPopup.restoreSelection(); + + if (f) + f(color); + + tinyMCEPopup.close(); +} + +function showColor(color, name) { + if (name) + document.getElementById("colorname").innerHTML = name; + + document.getElementById("preview").style.backgroundColor = color; + document.getElementById("color").value = color.toLowerCase(); +} + +function convertRGBToHex(col) { + var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi"); + + if (!col) + return col; + + var rgb = col.replace(re, "$1,$2,$3").split(','); + if (rgb.length == 3) { + r = parseInt(rgb[0]).toString(16); + g = parseInt(rgb[1]).toString(16); + b = parseInt(rgb[2]).toString(16); + + r = r.length == 1 ? '0' + r : r; + g = g.length == 1 ? '0' + g : g; + b = b.length == 1 ? '0' + b : b; + + return "#" + r + g + b; + } + + return col; +} + +function convertHexToRGB(col) { + if (col.indexOf('#') != -1) { + col = col.replace(new RegExp('[^0-9A-F]', 'gi'), ''); + + r = parseInt(col.substring(0, 2), 16); + g = parseInt(col.substring(2, 4), 16); + b = parseInt(col.substring(4, 6), 16); + + return {r : r, g : g, b : b}; + } + + return null; +} + +function generatePicker() { + var el = document.getElementById('light'), h = '', i; + + for (i = 0; i < detail; i++){ + h += '
'; + } + + el.innerHTML = h; +} + +function generateWebColors() { + var el = document.getElementById('webcolors'), h = '', i; + + if (el.className == 'generated') + return; + + h += '' + + ''; + + for (i=0; i' + + '' + + ''; + if ((i+1) % 18 == 0) + h += ''; + } + + h += '
'; + + el.innerHTML = h; + el.className = 'generated'; +} + +function generateNamedColors() { + var el = document.getElementById('namedcolors'), h = '', n, v, i = 0; + + if (el.className == 'generated') + return; + + for (n in named) { + v = named[n]; + h += '' + } + + el.innerHTML = h; + el.className = 'generated'; +} + +function dechex(n) { + return strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16); +} + +function computeColor(e) { + var x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB; + + x = e.offsetX ? e.offsetX : (e.target ? e.clientX - e.target.x : 0); + y = e.offsetY ? e.offsetY : (e.target ? e.clientY - e.target.y : 0); + + partWidth = document.getElementById('colors').width / 6; + partDetail = detail / 2; + imHeight = document.getElementById('colors').height; + + r = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255; + g = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255 + (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth); + b = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth); + + coef = (imHeight - y) / imHeight; + r = 128 + (r - 128) * coef; + g = 128 + (g - 128) * coef; + b = 128 + (b - 128) * coef; + + changeFinalColor('#' + dechex(r) + dechex(g) + dechex(b)); + updateLight(r, g, b); +} + +function updateLight(r, g, b) { + var i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color; + + for (i=0; i=0) && (i'); + }, + + init : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor; + + // Setup browse button + document.getElementById('srcbrowsercontainer').innerHTML = getBrowserHTML('srcbrowser','src','image','theme_advanced_image'); + if (isVisible('srcbrowser')) + document.getElementById('src').style.width = '180px'; + + e = ed.selection.getNode(); + + this.fillFileList('image_list', 'tinyMCEImageList'); + + if (e.nodeName == 'IMG') { + f.src.value = ed.dom.getAttrib(e, 'src'); + f.alt.value = ed.dom.getAttrib(e, 'alt'); + f.border.value = this.getAttrib(e, 'border'); + f.vspace.value = this.getAttrib(e, 'vspace'); + f.hspace.value = this.getAttrib(e, 'hspace'); + f.width.value = ed.dom.getAttrib(e, 'width'); + f.height.value = ed.dom.getAttrib(e, 'height'); + f.insert.value = ed.getLang('update'); + this.styleVal = ed.dom.getAttrib(e, 'style'); + selectByValue(f, 'image_list', f.src.value); + selectByValue(f, 'align', this.getAttrib(e, 'align')); + this.updateStyle(); + } + }, + + fillFileList : function(id, l) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + l = window[l]; + + if (l && l.length > 0) { + lst.options[lst.options.length] = new Option('', ''); + + tinymce.each(l, function(o) { + lst.options[lst.options.length] = new Option(o[0], o[1]); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + update : function() { + var f = document.forms[0], nl = f.elements, ed = tinyMCEPopup.editor, args = {}, el; + + if (f.src.value === '') { + ed.dom.remove(ed.selection.getNode()); + ed.execCommand('mceRepaint'); + tinyMCEPopup.close(); + return; + } + + if (!ed.settings.inline_styles) { + args = tinymce.extend(args, { + vspace : nl.vspace.value, + hspace : nl.hspace.value, + border : nl.border.value, + align : getSelectValue(f, 'align') + }); + } else + args.style = this.styleVal; + + tinymce.extend(args, { + src : f.src.value, + alt : f.alt.value, + width : f.width.value, + height : f.height.value + }); + + el = ed.selection.getNode(); + + if (el && el.nodeName == 'IMG') { + ed.dom.setAttribs(el, args); + } else { + ed.execCommand('mceInsertContent', false, ''); + ed.dom.setAttribs('__mce_tmp', args); + ed.dom.setAttrib('__mce_tmp', 'id', ''); + } + + tinyMCEPopup.close(); + }, + + updateStyle : function() { + var dom = tinyMCEPopup.dom, st, v, f = document.forms[0]; + + if (tinyMCEPopup.editor.settings.inline_styles) { + st = tinyMCEPopup.dom.parseStyle(this.styleVal); + + // Handle align + v = getSelectValue(f, 'align'); + if (v) { + if (v == 'left' || v == 'right') { + st['float'] = v; + delete st['vertical-align']; + } else { + st['vertical-align'] = v; + delete st['float']; + } + } else { + delete st['float']; + delete st['vertical-align']; + } + + // Handle border + v = f.border.value; + if (v || v == '0') { + if (v == '0') + st['border'] = '0'; + else + st['border'] = v + 'px solid black'; + } else + delete st['border']; + + // Handle hspace + v = f.hspace.value; + if (v) { + delete st['margin']; + st['margin-left'] = v + 'px'; + st['margin-right'] = v + 'px'; + } else { + delete st['margin-left']; + delete st['margin-right']; + } + + // Handle vspace + v = f.vspace.value; + if (v) { + delete st['margin']; + st['margin-top'] = v + 'px'; + st['margin-bottom'] = v + 'px'; + } else { + delete st['margin-top']; + delete st['margin-bottom']; + } + + // Merge + st = tinyMCEPopup.dom.parseStyle(dom.serializeStyle(st)); + this.styleVal = dom.serializeStyle(st); + } + }, + + getAttrib : function(e, at) { + var ed = tinyMCEPopup.editor, dom = ed.dom, v, v2; + + if (ed.settings.inline_styles) { + switch (at) { + case 'align': + if (v = dom.getStyle(e, 'float')) + return v; + + if (v = dom.getStyle(e, 'vertical-align')) + return v; + + break; + + case 'hspace': + v = dom.getStyle(e, 'margin-left') + v2 = dom.getStyle(e, 'margin-right'); + if (v && v == v2) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + + case 'vspace': + v = dom.getStyle(e, 'margin-top') + v2 = dom.getStyle(e, 'margin-bottom'); + if (v && v == v2) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + + case 'border': + v = 0; + + tinymce.each(['top', 'right', 'bottom', 'left'], function(sv) { + sv = dom.getStyle(e, 'border-' + sv + '-width'); + + // False or not the same as prev + if (!sv || (sv != v && v !== 0)) { + v = 0; + return false; + } + + if (sv) + v = sv; + }); + + if (v) + return parseInt(v.replace(/[^0-9]/g, '')); + + break; + } + } + + if (v = dom.getAttrib(e, at)) + return v; + + return ''; + }, + + resetImageData : function() { + var f = document.forms[0]; + + f.width.value = f.height.value = ""; + }, + + updateImageData : function() { + var f = document.forms[0], t = ImageDialog; + + if (f.width.value == "") + f.width.value = t.preloadImg.width; + + if (f.height.value == "") + f.height.value = t.preloadImg.height; + }, + + getImageData : function() { + var f = document.forms[0]; + + this.preloadImg = new Image(); + this.preloadImg.onload = this.updateImageData; + this.preloadImg.onerror = this.resetImageData; + this.preloadImg.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(f.src.value); + } +}; + +ImageDialog.preInit(); +tinyMCEPopup.onInit.add(ImageDialog.init, ImageDialog); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/js/link.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/js/link.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,124 @@ +tinyMCEPopup.requireLangPack(); + +var LinkDialog = { + preInit : function() { + var url; + + if (url = tinyMCEPopup.getParam("external_link_list_url")) + document.write(''); + }, + + init : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor; + + // Setup browse button + document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser', 'href', 'file', 'theme_advanced_link'); + if (isVisible('hrefbrowser')) + document.getElementById('href').style.width = '180px'; + + this.fillClassList('class_list'); + this.fillFileList('link_list', 'tinyMCELinkList'); + this.fillTargetList('target_list'); + + if (e = ed.dom.getParent(ed.selection.getNode(), 'A')) { + f.href.value = ed.dom.getAttrib(e, 'href'); + f.linktitle.value = ed.dom.getAttrib(e, 'title'); + f.insert.value = ed.getLang('update'); + selectByValue(f, 'link_list', f.href.value); + selectByValue(f, 'target_list', ed.dom.getAttrib(e, 'target')); + selectByValue(f, 'class_list', ed.dom.getAttrib(e, 'class')); + } + }, + + update : function() { + var f = document.forms[0], ed = tinyMCEPopup.editor, e, b; + + // Remove element if there is no href + if (!f.href.value) { + e = ed.dom.getParent(ed.selection.getNode(), 'A'); + if (e) { + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + b = ed.selection.getBookmark(); + ed.dom.remove(e, 1); + ed.selection.moveToBookmark(b); + tinyMCEPopup.execCommand("mceEndUndoLevel"); + tinyMCEPopup.close(); + return; + } + } + + ed.execCommand('mceInsertLink', false, { + href : f.href.value, + title : f.linktitle.value, + target : f.target_list ? f.target_list.options[f.target_list.selectedIndex].value : null, + 'class' : f.class_list ? f.class_list.options[f.class_list.selectedIndex].value : null + }); + + tinyMCEPopup.close(); + }, + + checkPrefix : function(n) { + if (n.value && Validator.isEmail(n) && !/^\s*mailto:/i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_email'))) + n.value = 'mailto:' + n.value; + + if (/^\s*www./i.test(n.value) && confirm(tinyMCEPopup.getLang('advanced_dlg.link_is_external'))) + n.value = 'http://' + n.value; + }, + + fillFileList : function(id, l) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + l = window[l]; + + if (l && l.length > 0) { + lst.options[lst.options.length] = new Option('', ''); + + tinymce.each(l, function(o) { + lst.options[lst.options.length] = new Option(o[0], o[1]); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + fillClassList : function(id) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v, cl; + + if (v = tinyMCEPopup.getParam('theme_advanced_styles')) { + cl = []; + + tinymce.each(v.split(';'), function(v) { + var p = v.split('='); + + cl.push({'title' : p[0], 'class' : p[1]}); + }); + } else + cl = tinyMCEPopup.editor.dom.getClasses(); + + if (cl.length > 0) { + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); + + tinymce.each(cl, function(o) { + lst.options[lst.options.length] = new Option(o.title || o['class'], o['class']); + }); + } else + dom.remove(dom.getParent(id, 'tr')); + }, + + fillTargetList : function(id) { + var dom = tinyMCEPopup.dom, lst = dom.get(id), v; + + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('not_set'), ''); + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_same'), '_self'); + lst.options[lst.options.length] = new Option(tinyMCEPopup.getLang('advanced_dlg.link_target_blank'), '_blank'); + + if (v = tinyMCEPopup.getParam('theme_advanced_link_targets')) { + tinymce.each(v.split(','), function(v) { + v = v.split('='); + html += ''; + }); + } + } +}; + +LinkDialog.preInit(); +tinyMCEPopup.onInit.add(LinkDialog.init, LinkDialog); diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/js/source_editor.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/js/source_editor.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,62 @@ +tinyMCEPopup.requireLangPack(); +tinyMCEPopup.onInit.add(onLoadInit); + +function saveContent() { + tinyMCEPopup.editor.setContent(document.getElementById('htmlSource').value); + tinyMCEPopup.close(); +} + +function onLoadInit() { + tinyMCEPopup.resizeToInnerSize(); + + // Remove Gecko spellchecking + if (tinymce.isGecko) + document.body.spellcheck = tinyMCEPopup.editor.getParam("gecko_spellcheck"); + + document.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent(); + + if (tinyMCEPopup.editor.getParam("theme_advanced_source_editor_wrap", true)) { + setWrap('soft'); + document.getElementById('wraped').checked = true; + } + + resizeInputs(); +} + +function setWrap(val) { + var v, n, s = document.getElementById('htmlSource'); + + s.wrap = val; + + if (!tinymce.isIE) { + v = s.value; + n = s.cloneNode(false); + n.setAttribute("wrap", val); + s.parentNode.replaceChild(n, s); + n.value = v; + } +} + +function toggleWordWrap(elm) { + if (elm.checked) + setWrap('soft'); + else + setWrap('off'); +} + +var wHeight=0, wWidth=0, owHeight=0, owWidth=0; + +function resizeInputs() { + var el = document.getElementById('htmlSource'); + + if (!tinymce.isIE) { + wHeight = self.innerHeight - 65; + wWidth = self.innerWidth - 16; + } else { + wHeight = document.body.clientHeight - 70; + wWidth = document.body.clientWidth - 16; + } + + el.style.height = Math.abs(wHeight) + 'px'; + el.style.width = Math.abs(wWidth) + 'px'; +} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/jscripts/about.js --- a/includes/clientside/tinymce/themes/advanced/jscripts/about.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -function init() { - var inst; - - tinyMCEPopup.resizeToInnerSize(); - inst = tinyMCE.selectedInstance; - - // Give FF some time - window.setTimeout('insertHelpIFrame();', 10); - - var tcont = document.getElementById('plugintablecontainer'); - var plugins = tinyMCE.getParam('plugins', '', true, ','); - if (plugins.length == 0) - document.getElementById('plugins_tab').style.display = 'none'; - - var html = ""; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - - for (var i=0; i' + info.longname + ''; - else - html += ''; - - if (info.authorurl != null && info.authorurl != '') - html += ''; - else - html += ''; - - html += ''; - html += ''; - } - - html += ''; - html += '
' + tinyMCE.getLang('lang_plugin') + '' + tinyMCE.getLang('lang_author') + '' + tinyMCE.getLang('lang_version') + '
' + info.longname + '' + info.author + '' + info.author + '' + info.version + '
'; - - tcont.innerHTML = html; -} - -function getPluginInfo(name) { - if (tinyMCE.plugins[name].getInfo) - return tinyMCE.plugins[name].getInfo(); - - return { - longname : name, - authorurl : '', - infourl : '', - author : '--', - version : '--' - }; -} - -function insertHelpIFrame() { - var html = ''; - - document.getElementById('iframecontainer').innerHTML = html; - - html = ''; - html += 'Got Moxie? '; - html += 'Hosted By Sourceforge '; - html += 'Also on freshmeat '; - - document.getElementById('buttoncontainer').innerHTML = html; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/jscripts/anchor.js --- a/includes/clientside/tinymce/themes/advanced/jscripts/anchor.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -var action, element; - -function init() { - tinyMCEPopup.resizeToInnerSize(); - - var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')); - var anchor = tinyMCE.getParentElement(inst.getFocusElement(), "a", "name"); - var img = inst.getFocusElement(); - action = 'insert'; - - if (anchor != null) { - element = anchor; - action = "update"; - } - - if (tinyMCE.getAttrib(img, "class") == "mceItemAnchor") { - element = img; - action = "update"; - } - - if (action == "update") - document.forms[0].anchorName.value = element.nodeName == "IMG" ? element.getAttribute("title") : element.getAttribute("name"); - - document.forms[0].insert.value = tinyMCE.getLang('lang_' + action, 'Insert', true); -} - -function insertAnchor() { - var inst = tinyMCE.getInstanceById(tinyMCE.getWindowArg('editor_id')); - var name = document.forms[0].anchorName.value, e; - - tinyMCEPopup.execCommand("mceBeginUndoLevel"); - - if (action == "update") { - if (element.nodeName == "IMG") - element.setAttribute("title", name); - else - element.setAttribute("name", name); - } else { - var rng = inst.getRng(); - - if (rng.collapse) - rng.collapse(false); - - name = name.replace(/&/g, '&'); - name = name.replace(/\"/g, '"'); - name = name.replace(//g, '>'); - - // Fix for bug #1447335 - if (tinyMCE.isGecko) - html = ''; - else - html = ''; - - tinyMCEPopup.execCommand("mceInsertContent", false, html); - - // Fix for bug #1447335 force cursor after the anchor element - if (tinyMCE.isGecko) { - e = inst.getDoc().getElementById('mceNewAnchor'); - - if (e) { - inst.selection.selectNode(e, true, false, false); - e.removeAttribute('id'); - } - } - - tinyMCE.handleVisualAid(inst.getBody(), true, inst.visualAid, inst); - } - - tinyMCEPopup.execCommand("mceEndUndoLevel"); - - tinyMCE.triggerNodeChange(); - tinyMCEPopup.close(); -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/jscripts/charmap.js --- a/includes/clientside/tinymce/themes/advanced/jscripts/charmap.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,326 +0,0 @@ -function init() { - tinyMCEPopup.resizeToInnerSize(); -} - -var charmap = new Array(); - -// for mor details please see w3c.org -// now here is the complete list ;) - -charmap = [ - [' ', ' ', true, 'no-break space'], - ['&', '&', true, 'ampersand'], - ['"', '"', true, 'quotation mark'], -// finance - ['¢', '¢', true, 'cent sign'], - ['€', '€', true, 'euro sign'], - ['£', '£', true, 'pound sign'], - ['¥', '¥', true, 'yen sign'], -// signs - ['©', '©', true, 'copyright sign'], - ['®', '®', true, 'registered sign'], - ['™', '™', true, 'trade mark sign'], - ['‰', '‰', true, 'per mille sign'], - ['µ', 'µ', true, 'micro sign'], - ['·', '·', true, 'middle dot'], - ['•', '•', true, 'bullet'], - ['…', '…', true, 'three dot leader'], - ['′', '′', true, 'minutes / feet'], - ['″', '″', true, 'seconds / inches'], - ['§', '§', true, 'section sign'], - ['¶', '¶', true, 'paragraph sign'], - ['ß', 'ß', true, 'sharp s / ess-zed'], -// quotations - ['‹', '‹', true, 'single left-pointing angle quotation mark'], - ['›', '›', true, 'single right-pointing angle quotation mark'], - ['«', '«', true, 'left pointing guillemet'], - ['»', '»', true, 'right pointing guillemet'], - ['‘', '‘', true, 'left single quotation mark'], - ['’', '’', true, 'right single quotation mark'], - ['“', '“', true, 'left double quotation mark'], - ['”', '”', true, 'right double quotation mark'], - ['‚', '‚', true, 'single low-9 quotation mark'], - ['„', '„', true, 'double low-9 quotation mark'], - ['<', '<', true, 'less-than sign'], - ['>', '>', true, 'greater-than sign'], - ['≤', '≤', true, 'less-than or equal to'], - ['≥', '≥', true, 'greater-than or equal to'], - ['–', '–', true, 'en dash'], - ['—', '—', true, 'em dash'], - ['¯', '¯', true, 'macron'], - ['‾', '‾', true, 'overline'], - ['¤', '¤', true, 'currency sign'], - ['¦', '¦', true, 'broken bar'], - ['¨', '¨', true, 'diaeresis'], - ['¡', '¡', true, 'inverted exclamation mark'], - ['¿', '¿', true, 'turned question mark'], - ['ˆ', 'ˆ', true, 'circumflex accent'], - ['˜', '˜', true, 'small tilde'], - ['°', '°', true, 'degree sign'], - ['−', '−', true, 'minus sign'], - ['±', '±', true, 'plus-minus sign'], - ['÷', '÷', true, 'division sign'], - ['⁄', '⁄', true, 'fraction slash'], - ['×', '×', true, 'multiplication sign'], - ['¹', '¹', true, 'superscript one'], - ['²', '²', true, 'superscript two'], - ['³', '³', true, 'superscript three'], - ['¼', '¼', true, 'fraction one quarter'], - ['½', '½', true, 'fraction one half'], - ['¾', '¾', true, 'fraction three quarters'], -// math / logical - ['ƒ', 'ƒ', true, 'function / florin'], - ['∫', '∫', true, 'integral'], - ['∑', '∑', true, 'n-ary sumation'], - ['∞', '∞', true, 'infinity'], - ['√', '√', true, 'square root'], - ['∼', '∼', false,'similar to'], - ['≅', '≅', false,'approximately equal to'], - ['≈', '≈', true, 'almost equal to'], - ['≠', '≠', true, 'not equal to'], - ['≡', '≡', true, 'identical to'], - ['∈', '∈', false,'element of'], - ['∉', '∉', false,'not an element of'], - ['∋', '∋', false,'contains as member'], - ['∏', '∏', true, 'n-ary product'], - ['∧', '∧', false,'logical and'], - ['∨', '∨', false,'logical or'], - ['¬', '¬', true, 'not sign'], - ['∩', '∩', true, 'intersection'], - ['∪', '∪', false,'union'], - ['∂', '∂', true, 'partial differential'], - ['∀', '∀', false,'for all'], - ['∃', '∃', false,'there exists'], - ['∅', '∅', false,'diameter'], - ['∇', '∇', false,'backward difference'], - ['∗', '∗', false,'asterisk operator'], - ['∝', '∝', false,'proportional to'], - ['∠', '∠', false,'angle'], -// undefined - ['´', '´', true, 'acute accent'], - ['¸', '¸', true, 'cedilla'], - ['ª', 'ª', true, 'feminine ordinal indicator'], - ['º', 'º', true, 'masculine ordinal indicator'], - ['†', '†', true, 'dagger'], - ['‡', '‡', true, 'double dagger'], -// alphabetical special chars - ['À', 'À', true, 'A - grave'], - ['Á', 'Á', true, 'A - acute'], - ['Â', 'Â', true, 'A - circumflex'], - ['Ã', 'Ã', true, 'A - tilde'], - ['Ä', 'Ä', true, 'A - diaeresis'], - ['Å', 'Å', true, 'A - ring above'], - ['Æ', 'Æ', true, 'ligature AE'], - ['Ç', 'Ç', true, 'C - cedilla'], - ['È', 'È', true, 'E - grave'], - ['É', 'É', true, 'E - acute'], - ['Ê', 'Ê', true, 'E - circumflex'], - ['Ë', 'Ë', true, 'E - diaeresis'], - ['Ì', 'Ì', true, 'I - grave'], - ['Í', 'Í', true, 'I - acute'], - ['Î', 'Î', true, 'I - circumflex'], - ['Ï', 'Ï', true, 'I - diaeresis'], - ['Ð', 'Ð', true, 'ETH'], - ['Ñ', 'Ñ', true, 'N - tilde'], - ['Ò', 'Ò', true, 'O - grave'], - ['Ó', 'Ó', true, 'O - acute'], - ['Ô', 'Ô', true, 'O - circumflex'], - ['Õ', 'Õ', true, 'O - tilde'], - ['Ö', 'Ö', true, 'O - diaeresis'], - ['Ø', 'Ø', true, 'O - slash'], - ['Œ', 'Œ', true, 'ligature OE'], - ['Š', 'Š', true, 'S - caron'], - ['Ù', 'Ù', true, 'U - grave'], - ['Ú', 'Ú', true, 'U - acute'], - ['Û', 'Û', true, 'U - circumflex'], - ['Ü', 'Ü', true, 'U - diaeresis'], - ['Ý', 'Ý', true, 'Y - acute'], - ['Ÿ', 'Ÿ', true, 'Y - diaeresis'], - ['Þ', 'Þ', true, 'THORN'], - ['à', 'à', true, 'a - grave'], - ['á', 'á', true, 'a - acute'], - ['â', 'â', true, 'a - circumflex'], - ['ã', 'ã', true, 'a - tilde'], - ['ä', 'ä', true, 'a - diaeresis'], - ['å', 'å', true, 'a - ring above'], - ['æ', 'æ', true, 'ligature ae'], - ['ç', 'ç', true, 'c - cedilla'], - ['è', 'è', true, 'e - grave'], - ['é', 'é', true, 'e - acute'], - ['ê', 'ê', true, 'e - circumflex'], - ['ë', 'ë', true, 'e - diaeresis'], - ['ì', 'ì', true, 'i - grave'], - ['í', 'í', true, 'i - acute'], - ['î', 'î', true, 'i - circumflex'], - ['ï', 'ï', true, 'i - diaeresis'], - ['ð', 'ð', true, 'eth'], - ['ñ', 'ñ', true, 'n - tilde'], - ['ò', 'ò', true, 'o - grave'], - ['ó', 'ó', true, 'o - acute'], - ['ô', 'ô', true, 'o - circumflex'], - ['õ', 'õ', true, 'o - tilde'], - ['ö', 'ö', true, 'o - diaeresis'], - ['ø', 'ø', true, 'o slash'], - ['œ', 'œ', true, 'ligature oe'], - ['š', 'š', true, 's - caron'], - ['ù', 'ù', true, 'u - grave'], - ['ú', 'ú', true, 'u - acute'], - ['û', 'û', true, 'u - circumflex'], - ['ü', 'ü', true, 'u - diaeresis'], - ['ý', 'ý', true, 'y - acute'], - ['þ', 'þ', true, 'thorn'], - ['ÿ', 'ÿ', true, 'y - diaeresis'], - ['Α', 'Α', true, 'Alpha'], - ['Β', 'Β', true, 'Beta'], - ['Γ', 'Γ', true, 'Gamma'], - ['Δ', 'Δ', true, 'Delta'], - ['Ε', 'Ε', true, 'Epsilon'], - ['Ζ', 'Ζ', true, 'Zeta'], - ['Η', 'Η', true, 'Eta'], - ['Θ', 'Θ', true, 'Theta'], - ['Ι', 'Ι', true, 'Iota'], - ['Κ', 'Κ', true, 'Kappa'], - ['Λ', 'Λ', true, 'Lambda'], - ['Μ', 'Μ', true, 'Mu'], - ['Ν', 'Ν', true, 'Nu'], - ['Ξ', 'Ξ', true, 'Xi'], - ['Ο', 'Ο', true, 'Omicron'], - ['Π', 'Π', true, 'Pi'], - ['Ρ', 'Ρ', true, 'Rho'], - ['Σ', 'Σ', true, 'Sigma'], - ['Τ', 'Τ', true, 'Tau'], - ['Υ', 'Υ', true, 'Upsilon'], - ['Φ', 'Φ', true, 'Phi'], - ['Χ', 'Χ', true, 'Chi'], - ['Ψ', 'Ψ', true, 'Psi'], - ['Ω', 'Ω', true, 'Omega'], - ['α', 'α', true, 'alpha'], - ['β', 'β', true, 'beta'], - ['γ', 'γ', true, 'gamma'], - ['δ', 'δ', true, 'delta'], - ['ε', 'ε', true, 'epsilon'], - ['ζ', 'ζ', true, 'zeta'], - ['η', 'η', true, 'eta'], - ['θ', 'θ', true, 'theta'], - ['ι', 'ι', true, 'iota'], - ['κ', 'κ', true, 'kappa'], - ['λ', 'λ', true, 'lambda'], - ['μ', 'μ', true, 'mu'], - ['ν', 'ν', true, 'nu'], - ['ξ', 'ξ', true, 'xi'], - ['ο', 'ο', true, 'omicron'], - ['π', 'π', true, 'pi'], - ['ρ', 'ρ', true, 'rho'], - ['ς', 'ς', true, 'final sigma'], - ['σ', 'σ', true, 'sigma'], - ['τ', 'τ', true, 'tau'], - ['υ', 'υ', true, 'upsilon'], - ['φ', 'φ', true, 'phi'], - ['χ', 'χ', true, 'chi'], - ['ψ', 'ψ', true, 'psi'], - ['ω', 'ω', true, 'omega'], -// symbols - ['ℵ', 'ℵ', false,'alef symbol'], - ['ϖ', 'ϖ', false,'pi symbol'], - ['ℜ', 'ℜ', false,'real part symbol'], - ['ϑ','ϑ', false,'theta symbol'], - ['ϒ', 'ϒ', false,'upsilon - hook symbol'], - ['℘', '℘', false,'Weierstrass p'], - ['ℑ', 'ℑ', false,'imaginary part'], -// arrows - ['←', '←', true, 'leftwards arrow'], - ['↑', '↑', true, 'upwards arrow'], - ['→', '→', true, 'rightwards arrow'], - ['↓', '↓', true, 'downwards arrow'], - ['↔', '↔', true, 'left right arrow'], - ['↵', '↵', false,'carriage return'], - ['⇐', '⇐', false,'leftwards double arrow'], - ['⇑', '⇑', false,'upwards double arrow'], - ['⇒', '⇒', false,'rightwards double arrow'], - ['⇓', '⇓', false,'downwards double arrow'], - ['⇔', '⇔', false,'left right double arrow'], - ['∴', '∴', false,'therefore'], - ['⊂', '⊂', false,'subset of'], - ['⊃', '⊃', false,'superset of'], - ['⊄', '⊄', false,'not a subset of'], - ['⊆', '⊆', false,'subset of or equal to'], - ['⊇', '⊇', false,'superset of or equal to'], - ['⊕', '⊕', false,'circled plus'], - ['⊗', '⊗', false,'circled times'], - ['⊥', '⊥', false,'perpendicular'], - ['⋅', '⋅', false,'dot operator'], - ['⌈', '⌈', false,'left ceiling'], - ['⌉', '⌉', false,'right ceiling'], - ['⌊', '⌊', false,'left floor'], - ['⌋', '⌋', false,'right floor'], - ['⟨', '〈', false,'left-pointing angle bracket'], - ['⟩', '〉', false,'right-pointing angle bracket'], - ['◊', '◊', true,'lozenge'], - ['♠', '♠', false,'black spade suit'], - ['♣', '♣', true, 'black club suit'], - ['♥', '♥', true, 'black heart suit'], - ['♦', '♦', true, 'black diamond suit'], - [' ', ' ', false,'en space'], - [' ', ' ', false,'em space'], - [' ', ' ', false,'thin space'], - ['‌', '‌', false,'zero width non-joiner'], - ['‍', '‍', false,'zero width joiner'], - ['‎', '‎', false,'left-to-right mark'], - ['‏', '‏', false,'right-to-left mark'], - ['­', '­', false,'soft hyphen'] -]; - -function renderCharMapHTML() { - var charsPerRow = 20, tdWidth=20, tdHeight=20; - var html = ''; - var cols=-1; - for (var i=0; i' - + charmap[i][1] - + ''; - if ((cols+1) % charsPerRow == 0) - html += ''; - } - } - if (cols % charsPerRow > 0) { - var padd = charsPerRow - (cols % charsPerRow); - for (var i=0; i '; - } - html += '
'; - document.write(html); -} - -function insertChar(chr) { - tinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';'); - - // Refocus in window - if (tinyMCEPopup.isWindow) - window.focus(); - - tinyMCEPopup.close(); -} - -function previewChar(codeA, codeB, codeN) { - var elmA = document.getElementById('codeA'); - var elmB = document.getElementById('codeB'); - var elmV = document.getElementById('codeV'); - var elmN = document.getElementById('codeN'); - - if (codeA=='#160;') { - elmV.innerHTML = '__'; - } else { - elmV.innerHTML = '&' + codeA; - } - - elmB.innerHTML = '&' + codeA; - elmA.innerHTML = '&' + codeB; - elmN.innerHTML = codeN; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/jscripts/color_picker.js --- a/includes/clientside/tinymce/themes/advanced/jscripts/color_picker.js Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,249 +0,0 @@ -var detail = 50, strhex = "0123456789abcdef", i, isMouseDown = false, isMouseOver = false; - -var colors = new Array( - "#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033", - "#330066","#330099","#3300cc","#3300ff","#660000","#660033","#660066","#660099", - "#6600cc","#6600ff","#990000","#990033","#990066","#990099","#9900cc","#9900ff", - "#cc0000","#cc0033","#cc0066","#cc0099","#cc00cc","#cc00ff","#ff0000","#ff0033", - "#ff0066","#ff0099","#ff00cc","#ff00ff","#003300","#003333","#003366","#003399", - "#0033cc","#0033ff","#333300","#333333","#333366","#333399","#3333cc","#3333ff", - "#663300","#663333","#663366","#663399","#6633cc","#6633ff","#993300","#993333", - "#993366","#993399","#9933cc","#9933ff","#cc3300","#cc3333","#cc3366","#cc3399", - "#cc33cc","#cc33ff","#ff3300","#ff3333","#ff3366","#ff3399","#ff33cc","#ff33ff", - "#006600","#006633","#006666","#006699","#0066cc","#0066ff","#336600","#336633", - "#336666","#336699","#3366cc","#3366ff","#666600","#666633","#666666","#666699", - "#6666cc","#6666ff","#996600","#996633","#996666","#996699","#9966cc","#9966ff", - "#cc6600","#cc6633","#cc6666","#cc6699","#cc66cc","#cc66ff","#ff6600","#ff6633", - "#ff6666","#ff6699","#ff66cc","#ff66ff","#009900","#009933","#009966","#009999", - "#0099cc","#0099ff","#339900","#339933","#339966","#339999","#3399cc","#3399ff", - "#669900","#669933","#669966","#669999","#6699cc","#6699ff","#999900","#999933", - "#999966","#999999","#9999cc","#9999ff","#cc9900","#cc9933","#cc9966","#cc9999", - "#cc99cc","#cc99ff","#ff9900","#ff9933","#ff9966","#ff9999","#ff99cc","#ff99ff", - "#00cc00","#00cc33","#00cc66","#00cc99","#00cccc","#00ccff","#33cc00","#33cc33", - "#33cc66","#33cc99","#33cccc","#33ccff","#66cc00","#66cc33","#66cc66","#66cc99", - "#66cccc","#66ccff","#99cc00","#99cc33","#99cc66","#99cc99","#99cccc","#99ccff", - "#cccc00","#cccc33","#cccc66","#cccc99","#cccccc","#ccccff","#ffcc00","#ffcc33", - "#ffcc66","#ffcc99","#ffcccc","#ffccff","#00ff00","#00ff33","#00ff66","#00ff99", - "#00ffcc","#00ffff","#33ff00","#33ff33","#33ff66","#33ff99","#33ffcc","#33ffff", - "#66ff00","#66ff33","#66ff66","#66ff99","#66ffcc","#66ffff","#99ff00","#99ff33", - "#99ff66","#99ff99","#99ffcc","#99ffff","#ccff00","#ccff33","#ccff66","#ccff99", - "#ccffcc","#ccffff","#ffff00","#ffff33","#ffff66","#ffff99","#ffffcc","#ffffff" -); - -var named = { - '#F0F8FF':'AliceBlue','#FAEBD7':'AntiqueWhite','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige', - '#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'BlanchedAlmond','#0000FF':'Blue','#8A2BE2':'BlueViolet','#A52A2A':'Brown', - '#DEB887':'BurlyWood','#5F9EA0':'CadetBlue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'CornflowerBlue', - '#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'DarkBlue','#008B8B':'DarkCyan','#B8860B':'DarkGoldenRod', - '#A9A9A9':'DarkGray','#A9A9A9':'DarkGrey','#006400':'DarkGreen','#BDB76B':'DarkKhaki','#8B008B':'DarkMagenta','#556B2F':'DarkOliveGreen', - '#FF8C00':'Darkorange','#9932CC':'DarkOrchid','#8B0000':'DarkRed','#E9967A':'DarkSalmon','#8FBC8F':'DarkSeaGreen','#483D8B':'DarkSlateBlue', - '#2F4F4F':'DarkSlateGray','#2F4F4F':'DarkSlateGrey','#00CED1':'DarkTurquoise','#9400D3':'DarkViolet','#FF1493':'DeepPink','#00BFFF':'DeepSkyBlue', - '#696969':'DimGray','#696969':'DimGrey','#1E90FF':'DodgerBlue','#B22222':'FireBrick','#FFFAF0':'FloralWhite','#228B22':'ForestGreen', - '#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'GhostWhite','#FFD700':'Gold','#DAA520':'GoldenRod','#808080':'Gray','#808080':'Grey', - '#008000':'Green','#ADFF2F':'GreenYellow','#F0FFF0':'HoneyDew','#FF69B4':'HotPink','#CD5C5C':'IndianRed','#4B0082':'Indigo','#FFFFF0':'Ivory', - '#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'LavenderBlush','#7CFC00':'LawnGreen','#FFFACD':'LemonChiffon','#ADD8E6':'LightBlue', - '#F08080':'LightCoral','#E0FFFF':'LightCyan','#FAFAD2':'LightGoldenRodYellow','#D3D3D3':'LightGray','#D3D3D3':'LightGrey','#90EE90':'LightGreen', - '#FFB6C1':'LightPink','#FFA07A':'LightSalmon','#20B2AA':'LightSeaGreen','#87CEFA':'LightSkyBlue','#778899':'LightSlateGray','#778899':'LightSlateGrey', - '#B0C4DE':'LightSteelBlue','#FFFFE0':'LightYellow','#00FF00':'Lime','#32CD32':'LimeGreen','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon', - '#66CDAA':'MediumAquaMarine','#0000CD':'MediumBlue','#BA55D3':'MediumOrchid','#9370D8':'MediumPurple','#3CB371':'MediumSeaGreen','#7B68EE':'MediumSlateBlue', - '#00FA9A':'MediumSpringGreen','#48D1CC':'MediumTurquoise','#C71585':'MediumVioletRed','#191970':'MidnightBlue','#F5FFFA':'MintCream','#FFE4E1':'MistyRose','#FFE4B5':'Moccasin', - '#FFDEAD':'NavajoWhite','#000080':'Navy','#FDF5E6':'OldLace','#808000':'Olive','#6B8E23':'OliveDrab','#FFA500':'Orange','#FF4500':'OrangeRed','#DA70D6':'Orchid', - '#EEE8AA':'PaleGoldenRod','#98FB98':'PaleGreen','#AFEEEE':'PaleTurquoise','#D87093':'PaleVioletRed','#FFEFD5':'PapayaWhip','#FFDAB9':'PeachPuff', - '#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'PowderBlue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'RosyBrown','#4169E1':'RoyalBlue', - '#8B4513':'SaddleBrown','#FA8072':'Salmon','#F4A460':'SandyBrown','#2E8B57':'SeaGreen','#FFF5EE':'SeaShell','#A0522D':'Sienna','#C0C0C0':'Silver', - '#87CEEB':'SkyBlue','#6A5ACD':'SlateBlue','#708090':'SlateGray','#708090':'SlateGrey','#FFFAFA':'Snow','#00FF7F':'SpringGreen', - '#4682B4':'SteelBlue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet', - '#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'WhiteSmoke','#FFFF00':'Yellow','#9ACD32':'YellowGreen' -}; - -function init() { - var inputColor = convertRGBToHex(tinyMCE.getWindowArg('input_color')); - - if (tinyMCE.isMSIE) - tinyMCEPopup.resizeToInnerSize(); - - generatePicker(); - - if (inputColor) { - changeFinalColor(inputColor); - - col = convertHexToRGB(inputColor); - - if (col) - updateLight(col.r, col.g, col.b); - } -} - -function insertAction() { - var color = document.getElementById("color").value; - - tinyMCEPopup.execCommand(tinyMCE.getWindowArg('command'), false, color); - tinyMCEPopup.close(); -} - -function showColor(color, name) { - if (name) - document.getElementById("colorname").innerHTML = name; - - document.getElementById("preview").style.backgroundColor = color; - document.getElementById("color").value = color; -} - -function convertRGBToHex(col) { - var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi"); - - if (!col) - return col; - - var rgb = col.replace(re, "$1,$2,$3").split(','); - if (rgb.length == 3) { - r = parseInt(rgb[0]).toString(16); - g = parseInt(rgb[1]).toString(16); - b = parseInt(rgb[2]).toString(16); - - r = r.length == 1 ? '0' + r : r; - g = g.length == 1 ? '0' + g : g; - b = b.length == 1 ? '0' + b : b; - - return "#" + r + g + b; - } - - return col; -} - -function convertHexToRGB(col) { - if (col.indexOf('#') != -1) { - col = col.replace(new RegExp('[^0-9A-F]', 'gi'), ''); - - r = parseInt(col.substring(0, 2), 16); - g = parseInt(col.substring(2, 4), 16); - b = parseInt(col.substring(4, 6), 16); - - return {r : r, g : g, b : b}; - } - - return null; -} - -function generatePicker() { - var el = document.getElementById('light'), h = '', i; - - for (i = 0; i < detail; i++){ - h += '
'; - } - - el.innerHTML = h; -} - -function generateWebColors() { - var el = document.getElementById('webcolors'), h = '', i; - - if (el.className == 'generated') - return; - - h += '' - + ''; - - for (i=0; i' - + '' - + '' + colors[i] +  ''; - if ((i+1) % 18 == 0) - h += ''; - } - - h += '
'; - - el.innerHTML = h; - el.className = 'generated'; -} - -function generateNamedColors() { - var el = document.getElementById('namedcolors'), h = '', n, v, i = 0; - - if (el.className == 'generated') - return; - - for (n in named) { - v = named[n]; - h += '' - } - - el.innerHTML = h; - el.className = 'generated'; -} - -function selectColor() { - var color = document.getElementById("color").value; - - if(window.opener) - window.opener.tinyMCE.execInstanceCommand(tinyMCE.getWindowArg('editor_id'),tinyMCE.getWindowArg('command'),false,color); - - window.close(); -} - -function dechex(n) { - return strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16); -} - -function computeColor(e) { - var x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB; - - x = e.offsetX ? e.offsetX : (e.target ? e.clientX - e.target.x : 0); - y = e.offsetY ? e.offsetY : (e.target ? e.clientY - e.target.y : 0); - - partWidth = document.getElementById('colorpicker').width / 6; - partDetail = detail / 2; - imHeight = document.getElementById('colorpicker').height; - - r = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255; - g = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255 + (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth); - b = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth); - - coef = (imHeight - y) / imHeight; - r = 128 + (r - 128) * coef; - g = 128 + (g - 128) * coef; - b = 128 + (b - 128) * coef; - - changeFinalColor('#' + dechex(r) + dechex(g) + dechex(b)); - updateLight(r, g, b); -} - -function updateLight(r, g, b) { - var i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color; - - for (i=0; i=0) && (i'); -} - -function insertImage() { - var src = document.forms[0].src.value; - var alt = document.forms[0].alt.value; - var border = document.forms[0].border.value; - var vspace = document.forms[0].vspace.value; - var hspace = document.forms[0].hspace.value; - var width = document.forms[0].width.value; - var height = document.forms[0].height.value; - var align = document.forms[0].align.options[document.forms[0].align.selectedIndex].value; - - tinyMCEPopup.restoreSelection(); - tinyMCE.themes['advanced']._insertImage(src, alt, border, hspace, vspace, width, height, align); - tinyMCEPopup.close(); -} - -function init() { - tinyMCEPopup.resizeToInnerSize(); - - document.getElementById('srcbrowsercontainer').innerHTML = getBrowserHTML('srcbrowser','src','image','theme_advanced_image'); - - var formObj = document.forms[0]; - - for (var i=0; i 0) { - for (var i=0; i'); -} - -function init() { - tinyMCEPopup.resizeToInnerSize(); - - document.getElementById('hrefbrowsercontainer').innerHTML = getBrowserHTML('hrefbrowser','href','file','theme_advanced_link'); - - // Handle file browser - if (isVisible('hrefbrowser')) - document.getElementById('href').style.width = '180px'; - - var formObj = document.forms[0]; - - for (var i=0; i 0) { - var formObj = document.forms[0]; - - for (var i=0; i - {$lang_insert_link_title} - - - - + {#advanced_dlg.link_title} + + + + + - -
+ + @@ -20,79 +22,41 @@ - + - - - + + + + + + + + - - + + - - - - - - - - + + + +
- +
 
-
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/content.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/skins/default/content.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,18 @@ +body, td, pre {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px; } +body {background:#FFF;} +.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceVisualAid {border: 1px dashed #BBB;} +a.mceItemAnchor {width:12px; line-height:6px; overflow:hidden; padding-left:12px; background:url(img/items.gif) no-repeat bottom left;} +img.mceItemAnchor {width:12px; height:12px; background:url(img/items.gif) no-repeat;} +img {border:0;} + +/* IE */ +* html body { +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/dialog.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/skins/default/dialog.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,111 @@ +/* Generic */ +body { +font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDDDDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +background:#F0F0EE; +padding:0; +margin:8px 8px 0 8px; +} + +html {background:#F0F0EE;} +td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +textarea {resize:none;outline:none;} +a:link, a:visited {color:black;} +a:hover {color:#2B6FB6;} + +/* Forms */ +fieldset {margin:0; padding:4px; border:1px solid #919B9C; font-family:Verdana, Arial; font-size:10px;} +legend {color:#2B6FB6; font-weight:bold;} +label.msg {display:none;} +label.invalid {color:#EE0000; display:inline;} +input.invalid {border:1px solid #EE0000;} +input {background:#FFF; border:1px solid #CCC;} +input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +input, select, textarea {border:1px solid #808080;} +input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} +input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} +.input_noborder {border:0;} + +/* Buttons */ +#insert, #cancel, input.button, .updateButton { +border:0; margin:0; padding:0; +font-weight:bold; +width:94px; height:26px; +background:url(img/buttons.png) 0 -26px; +cursor:pointer; +padding-bottom:2px; +} + +#insert {background:url(img/buttons.png) 0 -52px;} +#cancel {background:url(img/buttons.png) 0 0;} + +/* Browse */ +a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} +.mceOldBoxModel a.browse span {width:22px; height:20px;} +a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} +a.browse span.disabled {border:1px solid white; -moz-opacity:0.3; opacity:0.3; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);} +a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} +a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} +.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} +a.pickcolor:hover span {background-color:#B2BBD0;} +a.pickcolor:hover span.disabled {} + +/* Charmap */ +table.charmap {border-style:solid; border-width:1px; border-color:#AAA;} +td.charmap, td.charmapOver {color:#000; border-color:#AAA; border-style:solid; border-width:1px; text-align:center; font-size:12px;} +td.charmapOver {background:#CCC; cursor:default;} +a.charmap {color:#000; text-decoration:none} + +/* Source */ +.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} +.mceActionPanel {margin-top:5px;} + +/* Tabs classes */ +.tabs {width:100%; height:18px; line-height:normal; background:url(img/tabs.gif) repeat-x 0 -72px;} +.tabs ul {margin:0; padding:0; list-style:none;} +.tabs li {float:left; background:url(img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:18px;} +.tabs li.current {background:url(img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} +.tabs span {float:left; display:block; background:url(img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} +.tabs .current span {background:url(img/tabs.gif) no-repeat right -54px;} +.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} +.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} + +/* Panels */ +.panel_wrapper div.panel {display:none;} +.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} +.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} + +/* Columns */ +.column {float:left;} +.properties {width:100%;} +.properties .column1 {} +.properties .column2 {text-align:left;} + +/* Titles */ +h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} +h3 {font-size:14px;} +.title {font-size:12px; font-weight:bold; color:#2B6FB6;} + +/* Dialog specific */ +#link .panel_wrapper, #link div.current {height:125px;} +#image .panel_wrapper, #image div.current {height:200px;} +#plugintable thead {font-weight:bold; background:#DDD;} +#plugintable, #about #plugintable td {border:1px solid #919B9C;} +#plugintable {width:96%; margin-top:10px;} +#pluginscontainer {height:290px; overflow:auto;} +#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} +#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} +#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} +#colorpicker #light div {overflow:hidden;} +#colorpicker #previewblock {float:right; padding-left:10px; height:20px;} +#colorpicker .panel_wrapper div.current {height:175px;} +#colorpicker #namedcolors {width:150px;} +#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} +#colorpicker #colornamecontainer {margin-top:5px;} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/img/buttons.png Binary file includes/clientside/tinymce/themes/advanced/skins/default/img/buttons.png has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/img/items.gif Binary file includes/clientside/tinymce/themes/advanced/skins/default/img/items.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/img/menu_arrow.gif Binary file includes/clientside/tinymce/themes/advanced/skins/default/img/menu_arrow.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/img/menu_check.gif Binary file includes/clientside/tinymce/themes/advanced/skins/default/img/menu_check.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/img/progress.gif Binary file includes/clientside/tinymce/themes/advanced/skins/default/img/progress.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/img/tabs.gif Binary file includes/clientside/tinymce/themes/advanced/skins/default/img/tabs.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/default/ui.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/skins/default/ui.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,193 @@ +/* Reset */ +.defaultSkin table, .defaultSkin tbody, .defaultSkin a, .defaultSkin img, .defaultSkin tr, .defaultSkin div, .defaultSkin td, .defaultSkin iframe, .defaultSkin span, .defaultSkin *, .defaultSkin .text {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000; vertical-align:baseline; width:auto; border-collapse:separate} +.defaultSkin a:hover, .defaultSkin a:link, .defaultSkin a:visited, .defaultSkin a:active {text-decoration:none; font-weight:normal; cursor:default; color:#000} +.defaultSkin table td {vertical-align:middle} + +/* Containers */ +.defaultSkin table {background:#F0F0EE} +.defaultSkin iframe {display:block; background:#FFF} +.defaultSkin .mceToolbar {height:26px} +.defaultSkin .left {text-align:left} +.defaultSkin .right {text-align:right} + +/* External */ +.defaultSkin .mceExternalToolbar {position:absolute; border:1px solid #CCC; border-bottom:0; display:none;} +.defaultSkin .mceExternalToolbar td.mceToolbar {padding-right:13px;} +.defaultSkin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../../img/icons.gif) -820px 0} + +/* Layout */ +.defaultSkin table.mceLayout {border:0; border-left:1px solid #CCC; border-right:1px solid #CCC} +.defaultSkin table.mceLayout tr.first td {border-top:1px solid #CCC} +.defaultSkin table.mceLayout tr.last td {border-bottom:1px solid #CCC} +.defaultSkin table.mceToolbar, .defaultSkin tr.first .mceToolbar tr td, .defaultSkin tr.last .mceToolbar tr td {border:0; margin:0; padding:0;} +.defaultSkin td.mceToolbar {padding-top:1px; vertical-align:top} +.defaultSkin .mceIframeContainer {border-top:1px solid #CCC; border-bottom:1px solid #CCC} +.defaultSkin .mceStatusbar {position:relative; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; padding:2px; color:#000; display:block} +.defaultSkin .mceStatusbar a.resize {display:block; position:absolute; top:0; right:0; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize} +.defaultSkin .mceStatusbar a:hover {text-decoration:underline} +.defaultSkin table.mceToolbar {margin-left:3px} +.defaultSkin span.icon, .defaultSkin img.icon {display:block; width:20px; height:20px} +.defaultSkin .icon {background:url(../../img/icons.gif) no-repeat 20px 20px} + +/* Button */ +.defaultSkin .mceButton {display:block; border:1px solid #F0F0EE; width:20px; height:20px; margin-right:1px;} +.defaultSkin a.mceButtonEnabled:hover {border:1px solid #0A246A; background-color:#B2BBD0} +.defaultSkin a.mceButtonActive, .defaultSkin a.mceButtonSelected {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSkin .mceButtonDisabled .icon {opacity:0.3; filter:alpha(opacity=30)} + +/* Separator */ +.defaultSkin .mceSeparator {display:block; background:url(../../img/icons.gif) -180px 0; width:2px; height:20px; margin:2px 2px 0 4px} + +/* ListBox */ +.defaultSkin .mceListBox, .defaultSkin .mceListBox a {display:block} +.defaultSkin .mceListBox .text {padding-left:4px; width:70px; text-align:left; border:1px solid #CCC; border-right:0; background:#FFF; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden} +.defaultSkin .mceListBox .open {width:9px; height:20px; background:url(../../img/icons.gif) -741px 0; margin-right:2px; border:1px solid #CCC;} +.defaultSkin table.mceListBoxEnabled:hover .text, .defaultSkin .mceListBoxHover .text, .defaultSkin .mceListBoxSelected .text {border:1px solid #A2ABC0; border-right:0; background:#FFF} +.defaultSkin table.mceListBoxEnabled:hover .open, .defaultSkin .mceListBoxHover .open, .defaultSkin .mceListBoxSelected .open {background-color:#FFF; border:1px solid #A2ABC0} +.defaultSkin .mceListBoxDisabled a.text {color:gray; background-color:transparent;} +.defaultSkin .mceListBoxMenu {overflow:auto; overflow-x:hidden} +.defaultSkin .mceOldBoxModel .mceListBox .text {height:22px} +.defaultSkin .mceOldBoxModel .mceListBox .open {width:11px; height:22px;} +.defaultSkin select.mceNativeListBox {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:7pt; background:#F0F0EE; border:1px solid gray; margin-right:2px;} + +/* SplitButton */ +.defaultSkin .mceSplitButton {width:32px; height:20px} +.defaultSkin .mceSplitButton a, .defaultSkin .mceSplitButton span {height:20px; display:block} +.defaultSkin .mceSplitButton a.action {width:20px; border:1px solid #F0F0EE; border-right:0;} +.defaultSkin .mceSplitButton span.action {width:20px; background:url(../../img/icons.gif) 20px 20px;} +.defaultSkin .mceSplitButton a.open {width:9px; border:1px solid #F0F0EE;} +.defaultSkin .mceSplitButton span.open {width:9px; background:url(../../img/icons.gif) -741px 0;} +.defaultSkin table.mceSplitButtonEnabled:hover a.action, .defaultSkin .mceSplitButtonHover a.action, .defaultSkin .mceSplitButtonSelected a.action {border:1px solid #0A246A; border-right:0; background-color:#B2BBD0} +.defaultSkin table.mceSplitButtonEnabled:hover a.open, .defaultSkin .mceSplitButtonHover a.open, .defaultSkin .mceSplitButtonSelected a.open {border:1px solid #0A246A;} +.defaultSkin table.mceSplitButtonEnabled:hover span.open, .defaultSkin .mceSplitButtonHover span.open, .defaultSkin .mceSplitButtonSelected span.open {background-color:#B2BBD0} +.defaultSkin .mceSplitButtonDisabled .action, .defaultSkin .mceSplitButtonDisabled span.open {opacity:0.3; filter:alpha(opacity=30)} +.defaultSkin .mceSplitButtonActive a.action {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSkin .mceSplitButtonActive a.open {border-left:0;} + +/* ColorSplitButton */ +.defaultSkin div.mceColorSplitMenu table {background:#FFF; border:1px solid gray} +.defaultSkin .mceColorSplitMenu td {padding:2px} +.defaultSkin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden; border:1px solid #808080} +.defaultSkin .mceColorSplitMenu td.morecolors {padding:1px 3px 1px 1px} +.defaultSkin .mceColorSplitMenu a.morecolors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px; border:1px solid #FFF} +.defaultSkin .mceColorSplitMenu a.morecolors:hover {border:1px solid #0A246A; background-color:#B6BDD2} +.defaultSkin a.mceMoreColors:hover {border:1px solid #0A246A} +.defaultSkin .mceColorPreview {position:absolute; top:15px; left:2px; width:16px; height:4px; overflow:hidden} + +/* Menu */ +.defaultSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #D4D0C8} +.defaultSkin .noIcons span.icon {width:0;} +.defaultSkin .noIcons a .text {padding-left:10px} +.defaultSkin .mceMenu table {background:#FFF} +.defaultSkin .mceMenu a, .defaultSkin .mceMenu span, .defaultSkin .mceMenu {display:block} +.defaultSkin .mceMenu td {height:20px} +.defaultSkin .mceMenu a {position:relative;padding:3px 0 4px 0} +.defaultSkin .mceMenu .text {position:relative; display:block; font-family:Tahoma,Verdana,Arial,Helvetica; color:#000; cursor:default; margin:0; padding:0 25px 0 25px; display:block} +.defaultSkin .mceMenu span.text, .defaultSkin .mceMenu .preview {font-size:11px} +.defaultSkin .mceMenu pre.text {font-family:Monospace} +.defaultSkin .mceMenu .icon {position:absolute; top:0; left:0; width:22px;} +.defaultSkin .mceMenu .mceMenuItemEnabled a:hover, .defaultSkin .mceMenu .mceMenuItemActive {background-color:#dbecf3} +.defaultSkin td.mceMenuItemSeparator {background:#DDD; height:1px} +.defaultSkin .mceMenuItemTitle a {border:0; background:#EEE; border-bottom:1px solid #DDD} +.defaultSkin .mceMenuItemTitle span.text {color:#000; font-weight:bold; padding-left:4px} +.defaultSkin .mceMenuItemDisabled .text {color:#888} +.defaultSkin .mceMenuItemSelected .icon {background:url(img/menu_check.gif)} +.defaultSkin .noIcons .mceMenuItemSelected a {background:url(img/menu_arrow.gif) no-repeat -6px center} +.defaultSkin .mceMenu span.mceMenuLine {display:none} +.defaultSkin .mceMenuItemSub a {background:url(img/menu_arrow.gif) no-repeat top right;} + +/* Progress,Resize */ +.defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; filter:alpha(opacity=50); background:#FFF} +.defaultSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} +.defaultSkin .mcePlaceHolder {border:1px dotted gray} + +/* Theme */ +.defaultSkin span.bold {background-position:0 0} +.defaultSkin span.italic {background-position:-60px 0} +.defaultSkin span.underline {background-position:-140px 0} +.defaultSkin span.strikethrough {background-position:-120px 0} +.defaultSkin span.undo {background-position:-160px 0} +.defaultSkin span.redo {background-position:-100px 0} +.defaultSkin span.cleanup {background-position:-40px 0} +.defaultSkin span.bullist {background-position:-20px 0} +.defaultSkin span.numlist {background-position:-80px 0} +.defaultSkin span.justifyleft {background-position:-460px 0} +.defaultSkin span.justifyright {background-position:-480px 0} +.defaultSkin span.justifycenter {background-position:-420px 0} +.defaultSkin span.justifyfull {background-position:-440px 0} +.defaultSkin span.anchor {background-position:-200px 0} +.defaultSkin span.indent {background-position:-400px 0} +.defaultSkin span.outdent {background-position:-540px 0} +.defaultSkin span.link {background-position:-500px 0} +.defaultSkin span.unlink {background-position:-640px 0} +.defaultSkin span.sub {background-position:-600px 0} +.defaultSkin span.sup {background-position:-620px 0} +.defaultSkin span.removeformat {background-position:-580px 0} +.defaultSkin span.newdocument {background-position:-520px 0} +.defaultSkin span.image {background-position:-380px 0} +.defaultSkin span.help {background-position:-340px 0} +.defaultSkin span.code {background-position:-260px 0} +.defaultSkin span.hr {background-position:-360px 0} +.defaultSkin span.visualaid {background-position:-660px 0} +.defaultSkin span.charmap {background-position:-240px 0} +.defaultSkin span.paste {background-position:-560px 0} +.defaultSkin span.copy {background-position:-700px 0} +.defaultSkin span.cut {background-position:-680px 0} +.defaultSkin span.blockquote {background-position:-220px 0} +.defaultSkin .forecolor span.action {background-position:-720px 0} +.defaultSkin .backcolor span.action {background-position:-760px 0} +.defaultSkin .forecolorpicker {background-position:-720px 0} +.defaultSkin .backcolorpicker {background-position:-760px 0} + +/* Plugins */ +.defaultSkin span.advhr {background-position:-0px -20px} +.defaultSkin span.ltr {background-position:-20px -20px} +.defaultSkin span.rtl {background-position:-40px -20px} +.defaultSkin span.emotions {background-position:-60px -20px} +.defaultSkin span.fullpage {background-position:-80px -20px} +.defaultSkin span.fullscreen {background-position:-100px -20px} +.defaultSkin span.iespell {background-position:-120px -20px} +.defaultSkin span.insertdate {background-position:-140px -20px} +.defaultSkin span.inserttime {background-position:-160px -20px} +.defaultSkin span.absolute {background-position:-180px -20px} +.defaultSkin span.backward {background-position:-200px -20px} +.defaultSkin span.forward {background-position:-220px -20px} +.defaultSkin span.insert_layer {background-position:-240px -20px} +.defaultSkin span.insertlayer {background-position:-260px -20px} +.defaultSkin span.movebackward {background-position:-280px -20px} +.defaultSkin span.moveforward {background-position:-300px -20px} +.defaultSkin span.media {background-position:-320px -20px} +.defaultSkin span.nonbreaking {background-position:-340px -20px} +.defaultSkin span.pastetext {background-position:-360px -20px} +.defaultSkin span.pasteword {background-position:-380px -20px} +.defaultSkin span.selectall {background-position:-400px -20px} +.defaultSkin span.preview {background-position:-420px -20px} +.defaultSkin span.print {background-position:-440px -20px} +.defaultSkin span.cancel {background-position:-460px -20px} +.defaultSkin span.save {background-position:-480px -20px} +.defaultSkin span.replace {background-position:-500px -20px} +.defaultSkin span.search {background-position:-520px -20px} +.defaultSkin span.styleprops {background-position:-560px -20px} +.defaultSkin span.table {background-position:-580px -20px} +.defaultSkin span.cell_props {background-position:-600px -20px} +.defaultSkin span.delete_table {background-position:-620px -20px} +.defaultSkin span.delete_col {background-position:-640px -20px} +.defaultSkin span.delete_row {background-position:-660px -20px} +.defaultSkin span.col_after {background-position:-680px -20px} +.defaultSkin span.col_before {background-position:-700px -20px} +.defaultSkin span.row_after {background-position:-720px -20px} +.defaultSkin span.row_before {background-position:-740px -20px} +.defaultSkin span.merge_cells {background-position:-760px -20px} +.defaultSkin span.table_props {background-position:-980px -20px} +.defaultSkin span.row_props {background-position:-780px -20px} +.defaultSkin span.split_cells {background-position:-800px -20px} +.defaultSkin span.template {background-position:-820px -20px} +.defaultSkin span.visualchars {background-position:-840px -20px} +.defaultSkin span.abbr {background-position:-860px -20px} +.defaultSkin span.acronym {background-position:-880px -20px} +.defaultSkin span.attribs {background-position:-900px -20px} +.defaultSkin span.cite {background-position:-920px -20px} +.defaultSkin span.del {background-position:-940px -20px} +.defaultSkin span.ins {background-position:-960px -20px} +.defaultSkin span.pagebreak {background-position:0 -40px} +.defaultSkin .spellchecker span.action {background-position:-540px -20px} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/o2k7/content.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/skins/o2k7/content.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,18 @@ +body, td, pre {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px;} +body {background:#FFF;} +.mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceVisualAid {border: 1px dashed #BBB;} +a.mceItemAnchor {width:12px; line-height:6px; overflow:hidden; padding-left:12px; background:url(../default/img/items.gif) no-repeat bottom left;} +img.mceItemAnchor {width:12px; height:12px; background:url(../default/img/items.gif) no-repeat;} +img {border:0;} + +/* IE */ +* html body { +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/o2k7/dialog.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/skins/o2k7/dialog.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,111 @@ +/* Generic */ +body { +font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px; +scrollbar-3dlight-color:#F0F0EE; +scrollbar-arrow-color:#676662; +scrollbar-base-color:#F0F0EE; +scrollbar-darkshadow-color:#DDDDDD; +scrollbar-face-color:#E0E0DD; +scrollbar-highlight-color:#F0F0EE; +scrollbar-shadow-color:#F0F0EE; +scrollbar-track-color:#F5F5F5; +background:#F0F0EE; +padding:0; +margin:8px 8px 0 8px; +} + +html {background:#F0F0EE;} +td {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +textarea {resize:none;outline:none;} +a:link, a:visited {color:black;} +a:hover {color:#2B6FB6;} + +/* Forms */ +fieldset {margin:0; padding:4px; border:1px solid #919B9C; font-family:Verdana, Arial; font-size:10px;} +legend {color:#2B6FB6; font-weight:bold;} +label.msg {display:none;} +label.invalid {color:#EE0000; display:inline;} +input.invalid {border:1px solid #EE0000;} +input {background:#FFF; border:1px solid #CCC;} +input, select, textarea {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} +input, select, textarea {border:1px solid #808080;} +input.radio {border:1px none #000000; background:transparent; vertical-align:middle;} +input.checkbox {border:1px none #000000; background:transparent; vertical-align:middle;} +.input_noborder {border:0;} + +/* Buttons */ +#insert, #cancel, input.button, .updateButton { +border:0; margin:0; padding:0; +font-weight:bold; +width:94px; height:26px; +background:url(../default/img/buttons.png) 0 -26px; +cursor:pointer; +padding-bottom:2px; +} + +#insert {background:url(../default/img/buttons.png) 0 -52px;} +#cancel {background:url(../default/img/buttons.png) 0 0;} + +/* Browse */ +a.browse span {display:block; width:20px; height:18px; background:url(../../img/icons.gif) -860px 0; border:1px solid #FFF; margin-left:1px;} +.mceOldBoxModel a.browse span {width:22px; height:20px;} +a.browse:hover span {border:1px solid #0A246A; background-color:#B2BBD0;} +a.browse span.disabled {border:1px solid white; -moz-opacity:0.3; opacity:0.3; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30);} +a.browse:hover span.disabled {border:1px solid white; background-color:transparent;} +a.pickcolor span {display:block; width:20px; height:16px; background:url(../../img/icons.gif) -840px 0; margin-left:2px;} +.mceOldBoxModel a.pickcolor span {width:21px; height:17px;} +a.pickcolor:hover span {background-color:#B2BBD0;} +a.pickcolor:hover span.disabled {} + +/* Charmap */ +table.charmap {border-style:solid; border-width:1px; border-color:#AAA;} +td.charmap, td.charmapOver {color:#000; border-color:#AAA; border-style:solid; border-width:1px; text-align:center; font-size:12px;} +td.charmapOver {background:#CCC; cursor:default;} +a.charmap {color:#000; text-decoration:none} + +/* Source */ +.wordWrapCode {vertical-align:middle; border:1px none #000000; background:transparent;} +.mceActionPanel {margin-top:5px;} + +/* Tabs classes */ +.tabs {width:100%; height:18px; line-height:normal; background:url(../default/img/tabs.gif) repeat-x 0 -72px;} +.tabs ul {margin:0; padding:0; list-style:none;} +.tabs li {float:left; background:url(../default/img/tabs.gif) no-repeat 0 0; margin:0 2px 0 0; padding:0 0 0 10px; line-height:18px;} +.tabs li.current {background:url(../default/img/tabs.gif) no-repeat 0 -18px; margin-right:2px;} +.tabs span {float:left; display:block; background:url(../default/img/tabs.gif) no-repeat right -36px; padding:0px 10px 0 0;} +.tabs .current span {background:url(../default/img/tabs.gif) no-repeat right -54px;} +.tabs a {text-decoration:none; font-family:Verdana, Arial; font-size:10px;} +.tabs a:link, .tabs a:visited, .tabs a:hover {color:black;} + +/* Panels */ +.panel_wrapper div.panel {display:none;} +.panel_wrapper div.current {display:block; width:100%; height:300px; overflow:visible;} +.panel_wrapper {border:1px solid #919B9C; border-top:0px; padding:10px; padding-top:5px; clear:both; background:white;} + +/* Columns */ +.column {float:left;} +.properties {width:100%;} +.properties .column1 {} +.properties .column2 {text-align:left;} + +/* Titles */ +h1, h2, h3, h4 {color:#2B6FB6; margin:0; padding:0; padding-top:5px;} +h3 {font-size:14px;} +.title {font-size:12px; font-weight:bold; color:#2B6FB6;} + +/* Dialog specific */ +#link .panel_wrapper, #link div.current {height:125px;} +#image .panel_wrapper, #image div.current {height:200px;} +#plugintable thead {font-weight:bold; background:#DDD;} +#plugintable, #about #plugintable td {border:1px solid #919B9C;} +#plugintable {width:96%; margin-top:10px;} +#pluginscontainer {height:290px; overflow:auto;} +#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;} +#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;} +#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;} +#colorpicker #light div {overflow:hidden;} +#colorpicker #previewblock {float:right; padding-left:10px; height:20px;} +#colorpicker .panel_wrapper div.current {height:175px;} +#colorpicker #namedcolors {width:150px;} +#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;} +#colorpicker #colornamecontainer {margin-top:5px;} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/o2k7/img/button_bg.png Binary file includes/clientside/tinymce/themes/advanced/skins/o2k7/img/button_bg.png has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/skins/o2k7/ui.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/advanced/skins/o2k7/ui.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,193 @@ +/* Reset */ +.o2k7Skin table, .o2k7Skin tbody, .o2k7Skin a, .o2k7Skin img, .o2k7Skin tr, .o2k7Skin div, .o2k7Skin td, .o2k7Skin iframe, .o2k7Skin span, .o2k7Skin *, .o2k7Skin .text {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000; vertical-align:baseline; width:auto; border-collapse:separate} +.o2k7Skin a:hover, .o2k7Skin a:link, .o2k7Skin a:visited, .o2k7Skin a:active {text-decoration:none; font-weight:normal; cursor:default; color:#000} +.o2k7Skin table td {vertical-align:middle} + +/* Containers */ +.o2k7Skin table {background:#E5EFFD} +.o2k7Skin iframe {display:block; background:#FFF} +.o2k7Skin .mceToolbar {height:26px} + +/* External */ +.o2k7Skin .mceExternalToolbar {position:absolute; border:1px solid #ABC6DD; border-bottom:0; display:none} +.o2k7Skin .mceExternalToolbar td.mceToolbar {padding-right:13px;} +.o2k7Skin .mceExternalClose {position:absolute; top:3px; right:3px; width:7px; height:7px; background:url(../../img/icons.gif) -820px 0} + +/* Layout */ +.o2k7Skin table.mceLayout {border:0; border-left:1px solid #ABC6DD; border-right:1px solid #ABC6DD} +.o2k7Skin table.mceLayout tr.first td {border-top:1px solid #ABC6DD} +.o2k7Skin table.mceLayout tr.last td {border-bottom:1px solid #ABC6DD} +.o2k7Skin table.mceToolbar, .o2k7Skin tr.first .mceToolbar tr td, .o2k7Skin tr.last .mceToolbar tr td {border:0; margin:0; padding:0} +.o2k7Skin .mceIframeContainer {border-top:1px solid #ABC6DD; border-bottom:1px solid #ABC6DD} +.o2k7Skin .mceStatusbar {display:block; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; height:20px;} +.o2k7Skin .mceStatusbar div {float:left; padding:2px;} +.o2k7Skin .mceStatusbar a.resize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize} +.o2k7Skin .mceStatusbar a:hover {text-decoration:underline} +.o2k7Skin table.mceToolbar {margin-left:3px} +.o2k7Skin .mceToolbar .mceToolbarStart span {display:block; background:url(img/button_bg.png) -22px 0; width:1px; height:22px; } +.o2k7Skin .mceToolbar .mceToolbarEnd span {display:block; background:url(img/button_bg.png) -22px 0; width:1px; height:22px} +.o2k7Skin .mceToolbar .mceToolbarEndListBox span {display:none} +.o2k7Skin span.icon, .o2k7Skin img.icon {display:block; width:20px; height:20px} +.o2k7Skin .icon {background:url(../../img/icons.gif) no-repeat 20px 20px} + +/* Button */ +.o2k7Skin .mceButton {display:block; background:url(img/button_bg.png); width:22px; height:22px} +.o2k7Skin a.mceButton span, .o2k7Skin a.mceButton img {margin-left:1px} +.o2k7Skin .mceOldBoxModel a.mceButton span, .o2k7Skin .mceOldBoxModel a.mceButton img {margin:0 0 0 1px} +.o2k7Skin a.mceButtonEnabled:hover {background-color:#B2BBD0; background-position:0 -22px} +.o2k7Skin a.mceButtonActive, .o2k7Skin a.mceButtonSelected {background-position:0 -44px} +.o2k7Skin .mceButtonDisabled .icon {opacity:0.3; filter:alpha(opacity=30)} + +/* Separator */ +.o2k7Skin .mceSeparator {display:block; background:url(img/button_bg.png) -22px 0; width:5px; height:22px} + +/* ListBox */ +.o2k7Skin .mceListBox, .o2k7Skin .mceListBox a {display:block} +.o2k7Skin .mceListBox .text {padding-left:4px; text-align:left; width:70px; border:1px solid #b3c7e1; border-right:0; background:#eaf2fb; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; height:20px; line-height:20px; overflow:hidden} +.o2k7Skin .mceListBox .open {width:14px; height:22px; background:url(img/button_bg.png) -66px 0; margin-right:2px} +.o2k7Skin table.mceListBoxEnabled:hover .text, .o2k7Skin .mceListBoxHover .text, .o2k7Skin .mceListBoxSelected .text {background:#FFF} +.o2k7Skin table.mceListBoxEnabled:hover .open, .o2k7Skin .mceListBoxHover .open, .o2k7Skin .mceListBoxSelected .open {background-position:-66px -22px} +.o2k7Skin .mceListBoxDisabled .text {color:gray} +.o2k7Skin .mceListBoxMenu {overflow:auto; overflow-x:hidden} +.o2k7Skin .mceOldBoxModel .mceListBox .text {height:22px} +.o2k7Skin select.mceListBox {font-family:Tahoma,Verdana,Arial,Helvetica; font-size:12px; border:1px solid #b3c7e1; background:#FFF;} + +/* SplitButton */ +.o2k7Skin .mceSplitButton, .o2k7Skin .mceSplitButton a, .o2k7Skin .mceSplitButton span {display:block; height:22px} +.o2k7Skin .mceSplitButton {background:url(img/button_bg.png)} +.o2k7Skin .mceSplitButton a.action {width:22px} +.o2k7Skin .mceSplitButton span.action {width:22px; background:url(../../img/icons.gif) 20px 20px} +.o2k7Skin .mceSplitButton a.open {width:10px} +.o2k7Skin .mceSplitButton span.open {width:10px; background:url(img/button_bg.png) -44px 0} +.o2k7Skin table.mceSplitButtonEnabled:hover a.action, .o2k7Skin .mceSplitButtonHover a.action, .o2k7Skin .mceSplitButtonSelected {background:url(img/button_bg.png) 0 -22px} +.o2k7Skin table.mceSplitButtonEnabled:hover span.open, .o2k7Skin .mceSplitButtonHover span.open, .o2k7Skin .mceSplitButtonSelected span.open {background-position:-44px -44px} +.o2k7Skin .mceSplitButtonDisabled .action {opacity:0.3; filter:alpha(opacity=30)} +.o2k7Skin .mceSplitButtonActive {background-position:0 -44px} + +/* ColorSplitButton */ +.o2k7Skin div.mceColorSplitMenu table {background:#FFF; border:1px solid gray} +.o2k7Skin .mceColorSplitMenu td {padding:2px} +.o2k7Skin .mceColorSplitMenu a {display:block; width:9px; height:9px; overflow:hidden; border:1px solid #808080} +.o2k7Skin .mceColorSplitMenu td.morecolors {padding:1px 3px 1px 1px} +.o2k7Skin .mceColorSplitMenu a.morecolors {width:100%; height:auto; text-align:center; font-family:Tahoma,Verdana,Arial,Helvetica; font-size:11px; line-height:20px; border:1px solid #FFF} +.o2k7Skin .mceColorSplitMenu a.morecolors:hover {border:1px solid #0A246A; background-color:#B6BDD2} +.o2k7Skin a.mceMoreColors:hover {border:1px solid #0A246A} +.o2k7Skin .mceColorPreview {position:absolute; top:15px; left:2px; width:16px; height:4px; overflow:hidden} + +/* Menu */ +.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD} +.o2k7Skin .noIcons span.icon {width:0;} +.o2k7Skin .noIcons a .text {padding-left:10px} +.o2k7Skin .mceMenu table {background:#FFF} +.o2k7Skin .mceMenu a, .o2k7Skin .mceMenu span, .o2k7Skin .mceMenu {display:block} +.o2k7Skin .mceMenu td {height:20px} +.o2k7Skin .mceMenu a {position:relative;padding:3px 0 4px 0} +.o2k7Skin .mceMenu .text {position:relative; display:block; font-family:Tahoma,Verdana,Arial,Helvetica; color:#000; cursor:default; margin:0; padding:0 25px 0 25px; display:block} +.o2k7Skin .mceMenu span.text, .o2k7Skin .mceMenu .preview {font-size:11px} +.o2k7Skin .mceMenu pre.text {font-family:Monospace} +.o2k7Skin .mceMenu .icon {position:absolute; top:0; left:0; width:22px;} +.o2k7Skin .mceMenu .mceMenuItemEnabled a:hover, .o2k7Skin .mceMenu .mceMenuItemActive {background-color:#dbecf3} +.o2k7Skin td.mceMenuItemSeparator {background:#DDD; height:1px} +.o2k7Skin .mceMenuItemTitle a {border:0; background:#E5EFFD; border-bottom:1px solid #ABC6DD} +.o2k7Skin .mceMenuItemTitle span.text {color:#000; font-weight:bold; padding-left:4px} +.o2k7Skin .mceMenuItemDisabled .text {color:#888} +.o2k7Skin .mceMenuItemSelected .icon {background:url(../default/img/menu_check.gif)} +.o2k7Skin .noIcons .mceMenuItemSelected a {background:url(../default/img/menu_arrow.gif) no-repeat -6px center} +.o2k7Skin .mceMenu span.mceMenuLine {display:none} +.o2k7Skin .mceMenuItemSub a {background:url(../default/img/menu_arrow.gif) no-repeat top right;} + +/* Progress,Resize */ +.o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; filter:alpha(opacity=50); background:#FFF} +.o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px} +.o2k7Skin .mcePlaceHolder {border:1px dotted gray} + +/* Theme */ +.o2k7Skin span.bold {background-position:0 0} +.o2k7Skin span.italic {background-position:-60px 0} +.o2k7Skin span.underline {background-position:-140px 0} +.o2k7Skin span.strikethrough {background-position:-120px 0} +.o2k7Skin span.undo {background-position:-160px 0} +.o2k7Skin span.redo {background-position:-100px 0} +.o2k7Skin span.cleanup {background-position:-40px 0} +.o2k7Skin span.bullist {background-position:-20px 0} +.o2k7Skin span.numlist {background-position:-80px 0} +.o2k7Skin span.justifyleft {background-position:-460px 0} +.o2k7Skin span.justifyright {background-position:-480px 0} +.o2k7Skin span.justifycenter {background-position:-420px 0} +.o2k7Skin span.justifyfull {background-position:-440px 0} +.o2k7Skin span.anchor {background-position:-200px 0} +.o2k7Skin span.indent {background-position:-400px 0} +.o2k7Skin span.outdent {background-position:-540px 0} +.o2k7Skin span.link {background-position:-500px 0} +.o2k7Skin span.unlink {background-position:-640px 0} +.o2k7Skin span.sub {background-position:-600px 0} +.o2k7Skin span.sup {background-position:-620px 0} +.o2k7Skin span.removeformat {background-position:-580px 0} +.o2k7Skin span.newdocument {background-position:-520px 0} +.o2k7Skin span.image {background-position:-380px 0} +.o2k7Skin span.help {background-position:-340px 0} +.o2k7Skin span.code {background-position:-260px 0} +.o2k7Skin span.hr {background-position:-360px 0} +.o2k7Skin span.visualaid {background-position:-660px 0} +.o2k7Skin span.charmap {background-position:-240px 0} +.o2k7Skin span.paste {background-position:-560px 0} +.o2k7Skin span.copy {background-position:-700px 0} +.o2k7Skin span.cut {background-position:-680px 0} +.o2k7Skin span.blockquote {background-position:-220px 0} +.o2k7Skin .forecolor span.action {background-position:-720px 0} +.o2k7Skin .backcolor span.action {background-position:-760px 0} +.o2k7Skin .forecolorpicker {background-position:-720px 0} +.o2k7Skin .backcolorpicker {background-position:-760px 0} + +/* Plugins */ +.o2k7Skin span.advhr {background-position:-0px -20px} +.o2k7Skin span.ltr {background-position:-20px -20px} +.o2k7Skin span.rtl {background-position:-40px -20px} +.o2k7Skin span.emotions {background-position:-60px -20px} +.o2k7Skin span.fullpage {background-position:-80px -20px} +.o2k7Skin span.fullscreen {background-position:-100px -20px} +.o2k7Skin span.iespell {background-position:-120px -20px} +.o2k7Skin span.insertdate {background-position:-140px -20px} +.o2k7Skin span.inserttime {background-position:-160px -20px} +.o2k7Skin span.absolute {background-position:-180px -20px} +.o2k7Skin span.backward {background-position:-200px -20px} +.o2k7Skin span.forward {background-position:-220px -20px} +.o2k7Skin span.insert_layer {background-position:-240px -20px} +.o2k7Skin span.insertlayer {background-position:-260px -20px} +.o2k7Skin span.movebackward {background-position:-280px -20px} +.o2k7Skin span.moveforward {background-position:-300px -20px} +.o2k7Skin span.media {background-position:-320px -20px} +.o2k7Skin span.nonbreaking {background-position:-340px -20px} +.o2k7Skin span.pastetext {background-position:-360px -20px} +.o2k7Skin span.pasteword {background-position:-380px -20px} +.o2k7Skin span.selectall {background-position:-400px -20px} +.o2k7Skin span.preview {background-position:-420px -20px} +.o2k7Skin span.print {background-position:-440px -20px} +.o2k7Skin span.cancel {background-position:-460px -20px} +.o2k7Skin span.save {background-position:-480px -20px} +.o2k7Skin span.replace {background-position:-500px -20px} +.o2k7Skin span.search {background-position:-520px -20px} +.o2k7Skin span.styleprops {background-position:-560px -20px} +.o2k7Skin span.table {background-position:-580px -20px} +.o2k7Skin span.cell_props {background-position:-600px -20px} +.o2k7Skin span.delete_table {background-position:-620px -20px} +.o2k7Skin span.delete_col {background-position:-640px -20px} +.o2k7Skin span.delete_row {background-position:-660px -20px} +.o2k7Skin span.col_after {background-position:-680px -20px} +.o2k7Skin span.col_before {background-position:-700px -20px} +.o2k7Skin span.row_after {background-position:-720px -20px} +.o2k7Skin span.row_before {background-position:-740px -20px} +.o2k7Skin span.merge_cells {background-position:-760px -20px} +.o2k7Skin span.table_props {background-position:-980px -20px} +.o2k7Skin span.row_props {background-position:-780px -20px} +.o2k7Skin span.split_cells {background-position:-800px -20px} +.o2k7Skin span.template {background-position:-820px -20px} +.o2k7Skin span.visualchars {background-position:-840px -20px} +.o2k7Skin span.abbr {background-position:-860px -20px} +.o2k7Skin span.acronym {background-position:-880px -20px} +.o2k7Skin span.attribs {background-position:-900px -20px} +.o2k7Skin span.cite {background-position:-920px -20px} +.o2k7Skin span.del {background-position:-940px -20px} +.o2k7Skin span.ins {background-position:-960px -20px} +.o2k7Skin span.pagebreak {background-position:0 -40px} +.o2k7Skin .spellchecker span.action {background-position:-540px -20px} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/advanced/source_editor.htm --- a/includes/clientside/tinymce/themes/advanced/source_editor.htm Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/advanced/source_editor.htm Fri Feb 22 12:51:53 2008 -0500 @@ -1,30 +1,30 @@ - {$lang_theme_code_title} - - + {#advanced_dlg.code_title} + + - +
-
{$lang_theme_code_title}
+
{#advanced_dlg.code_title}
- +

- +
- +
- +
diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/css/editor_content.css --- a/includes/clientside/tinymce/themes/simple/css/editor_content.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -body, td, pre { - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 10px; -} - -body { - background-color: #FFFFFF; -} - -.mceVisualAid { - border: 1px dashed #BBBBBB; -} - -/* MSIE specific */ - -* html body { - scrollbar-3dlight-color: #F0F0EE; - scrollbar-arrow-color: #676662; - scrollbar-base-color: #F0F0EE; - scrollbar-darkshadow-color: #DDDDDD; - scrollbar-face-color: #E0E0DD; - scrollbar-highlight-color: #F0F0EE; - scrollbar-shadow-color: #F0F0EE; - scrollbar-track-color: #F5F5F5; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/css/editor_popup.css --- a/includes/clientside/tinymce/themes/simple/css/editor_popup.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -body { - background-color: #F0F0EE; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 11px; - scrollbar-3dlight-color: #F0F0EE; - scrollbar-arrow-color: #676662; - scrollbar-base-color: #F0F0EE; - scrollbar-darkshadow-color: #DDDDDD; - scrollbar-face-color: #E0E0DD; - scrollbar-highlight-color: #F0F0EE; - scrollbar-shadow-color: #F0F0EE; - scrollbar-track-color: #F5F5F5; -} - -td { - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 11px; -} - -input { - background: #FFFFFF; - border: 1px solid #cccccc; -} - -td, input, select, textarea { - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 10px; -} - -input, select, textarea { - border: 1px solid #808080; -} - -.input_noborder { - border: 0; -} - -.title { - font-size: 12px; - font-weight: bold; -} \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/css/editor_ui.css --- a/includes/clientside/tinymce/themes/simple/css/editor_ui.css Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -.mceSeparatorLine { - border: 0; - padding: 0; - margin-left: 4px; - margin-right: 2px; -} - -.mceSelectList { - font-family: "MS Sans Serif"; - font-size: 7pt; - font-weight: normal; - margin-top: 2px; -} - -.mceLabel, .mceLabelDisabled { - font-family: "MS Sans Serif"; - font-size: 9pt; -} - -.mceLabel { - color: #000000; -} - -.mceLabelDisabled { - cursor: text; - color: #999999; -} - -.mceEditor { - background: #F0F0EE; - border: 1px solid #cccccc; -} - -.mceEditorArea { - font-family: "MS Sans Serif"; - background: #FFFFFF; -} - -.mceToolbar { - background: #F0F0EE; - border-top: 1px solid #cccccc; - line-height: 1px; - font-size: 1px; - padding-bottom: 1px; -} - -.mceEditorIframe { - border: 0; -} - -/* Button CSS rules */ - -a.mceButtonDisabled img, a.mceButtonNormal img, a.mceButtonSelected img { - width: 20px; - height: 20px; - cursor: default; - margin-top: 1px; - margin-left: 1px; -} - -a.mceButtonDisabled img { - border: 0 !important; -} - -a.mceButtonNormal img, a.mceButtonSelected img { - border: 1px solid #F0F0EE !important; -} - -a.mceButtonSelected img { - border: 1px solid #C0C0BB !important; -} - -a.mceButtonNormal img:hover, a.mceButtonSelected img:hover { - border: 1px solid #0A246A !important; - cursor: default; - background-color: #B6BDD2; -} - -a.mceButtonDisabled img { - -moz-opacity:0.3; - opacity: 0.3; - border: 1px solid #F0F0EE !important; - cursor: default; -} - -a.mceTiledButton img { - background-image: url('../images/buttons.gif'); - background-repeat: no-repeat; -} - -/* MSIE specific rules */ - -* html a.mceButtonNormal img, * html a.mceButtonSelected img, * html a.mceButtonDisabled img { - border: 0px !important; - margin-top: 2px; - margin-bottom: 1px; -} - -* html a.mceButtonDisabled img { - filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); - border: 0px !important; -} - -* html a.mceButtonDisabled { - border: 1px solid #F0F0EE !important; -} - -* html a.mceButtonNormal, * html a.mceButtonSelected { - border: 1px solid #F0F0EE; - cursor: default; -} - -* html a.mceButtonSelected { - border: 1px solid #C0C0BB; -} - -* html a.mceButtonNormal:hover, * html a.mceButtonSelected:hover { - border: 1px solid #0A246A; - cursor: default; - background-color: #B6BDD2; -} - -* html .mceSelectList { - margin-top: 2px; -} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/editor_template.js --- a/includes/clientside/tinymce/themes/simple/editor_template.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/simple/editor_template.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -var TinyMCE_SimpleTheme={_buttonMap:'bold,bullist,cleanup,italic,numlist,redo,strikethrough,underline,undo',getEditorTemplate:function(){var html='';html+='';html+='';html+='
';html+='IFRAME';html+='
';html+=tinyMCE.getButtonHTML('bold','lang_bold_desc','{$themeurl}/images/{$lang_bold_img}','Bold');html+=tinyMCE.getButtonHTML('italic','lang_italic_desc','{$themeurl}/images/{$lang_italic_img}','Italic');html+=tinyMCE.getButtonHTML('underline','lang_underline_desc','{$themeurl}/images/{$lang_underline_img}','Underline');html+=tinyMCE.getButtonHTML('strikethrough','lang_striketrough_desc','{$themeurl}/images/strikethrough.gif','Strikethrough');html+='';html+=tinyMCE.getButtonHTML('undo','lang_undo_desc','{$themeurl}/images/undo.gif','Undo');html+=tinyMCE.getButtonHTML('redo','lang_redo_desc','{$themeurl}/images/redo.gif','Redo');html+='';html+=tinyMCE.getButtonHTML('cleanup','lang_cleanup_desc','{$themeurl}/images/cleanup.gif','mceCleanup');html+='';html+=tinyMCE.getButtonHTML('bullist','lang_bullist_desc','{$themeurl}/images/bullist.gif','InsertUnorderedList');html+=tinyMCE.getButtonHTML('numlist','lang_numlist_desc','{$themeurl}/images/numlist.gif','InsertOrderedList');html+='
';return{delta_width:0,delta_height:20,html:html}},handleNodeChange:function(editor_id,node){tinyMCE.switchClass(editor_id+'_bold','mceButtonNormal');tinyMCE.switchClass(editor_id+'_italic','mceButtonNormal');tinyMCE.switchClass(editor_id+'_underline','mceButtonNormal');tinyMCE.switchClass(editor_id+'_strikethrough','mceButtonNormal');tinyMCE.switchClass(editor_id+'_bullist','mceButtonNormal');tinyMCE.switchClass(editor_id+'_numlist','mceButtonNormal');do{switch(node.nodeName.toLowerCase()){case"b":case"strong":tinyMCE.switchClass(editor_id+'_bold','mceButtonSelected');break;case"i":case"em":tinyMCE.switchClass(editor_id+'_italic','mceButtonSelected');break;case"u":tinyMCE.switchClass(editor_id+'_underline','mceButtonSelected');break;case"strike":tinyMCE.switchClass(editor_id+'_strikethrough','mceButtonSelected');break;case"ul":tinyMCE.switchClass(editor_id+'_bullist','mceButtonSelected');break;case"ol":tinyMCE.switchClass(editor_id+'_numlist','mceButtonSelected');break}}while((node=node.parentNode)!=null)}};tinyMCE.addTheme("simple",TinyMCE_SimpleTheme);tinyMCE.addButtonMap(TinyMCE_SimpleTheme._buttonMap); \ No newline at end of file +(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(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('div',{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 last',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 diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/editor_template_src.js --- a/includes/clientside/tinymce/themes/simple/editor_template_src.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/themes/simple/editor_template_src.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,84 +1,85 @@ /** - * $Id: editor_template_src.js 162 2007-01-03 16:16:52Z spocke $ + * $Id: editor_template_src.js 520 2008-01-07 16:30:32Z spocke $ + * + * This file is meant to showcase how to create a simple theme. The advanced + * theme is more suitable for production use. * * @author Moxiecode - * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved. + * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved. */ -var TinyMCE_SimpleTheme = { - // List of button ids in tile map - _buttonMap : 'bold,bullist,cleanup,italic,numlist,redo,strikethrough,underline,undo', +(function() { + var DOM = tinymce.DOM; + + // Tell it to load theme specific language pack(s) + tinymce.ThemeManager.requireLangPack('simple'); - getEditorTemplate : function() { - var html = ''; + 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; - html += ''; - html += ''; - html += '
'; - html += 'IFRAME'; - html += '
'; - html += tinyMCE.getButtonHTML('bold', 'lang_bold_desc', '{$themeurl}/images/{$lang_bold_img}', 'Bold'); - html += tinyMCE.getButtonHTML('italic', 'lang_italic_desc', '{$themeurl}/images/{$lang_italic_img}', 'Italic'); - html += tinyMCE.getButtonHTML('underline', 'lang_underline_desc', '{$themeurl}/images/{$lang_underline_img}', 'Underline'); - html += tinyMCE.getButtonHTML('strikethrough', 'lang_striketrough_desc', '{$themeurl}/images/strikethrough.gif', 'Strikethrough'); - html += ''; - html += tinyMCE.getButtonHTML('undo', 'lang_undo_desc', '{$themeurl}/images/undo.gif', 'Undo'); - html += tinyMCE.getButtonHTML('redo', 'lang_redo_desc', '{$themeurl}/images/redo.gif', 'Redo'); - html += ''; - html += tinyMCE.getButtonHTML('cleanup', 'lang_cleanup_desc', '{$themeurl}/images/cleanup.gif', 'mceCleanup'); - html += ''; - html += tinyMCE.getButtonHTML('bullist', 'lang_bullist_desc', '{$themeurl}/images/bullist.gif', 'InsertUnorderedList'); - html += tinyMCE.getButtonHTML('numlist', 'lang_numlist_desc', '{$themeurl}/images/numlist.gif', 'InsertOrderedList'); - html += '
'; + 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"); + }); - return { - delta_width : 0, - delta_height : 20, - html : html - }; - }, + DOM.loadCSS(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('div', {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'); + + // Create iframe container + n = DOM.add(tb, 'tr'); + n = ic = DOM.add(DOM.add(n, 'td'), 'div', {'class' : 'mceIframeContainer'}); - handleNodeChange : function(editor_id, node) { - // Reset old states - tinyMCE.switchClass(editor_id + '_bold', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_italic', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_underline', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_strikethrough', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonNormal'); - tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonNormal'); + // Create toolbar container + n = DOM.add(DOM.add(tb, 'tr', {'class' : 'last'}), 'td', {'class' : 'mceToolbar last', align : 'center'}); - // Handle elements - do { - switch (node.nodeName.toLowerCase()) { - case "b": - case "strong": - tinyMCE.switchClass(editor_id + '_bold', 'mceButtonSelected'); - break; - - case "i": - case "em": - tinyMCE.switchClass(editor_id + '_italic', 'mceButtonSelected'); - break; + // Create toolbar + 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); - case "u": - tinyMCE.switchClass(editor_id + '_underline', 'mceButtonSelected'); - break; + return { + iframeContainer : ic, + editorContainer : ed.id + '_container', + sizeContainer : sc, + deltaHeight : -20 + }; + }, - case "strike": - tinyMCE.switchClass(editor_id + '_strikethrough', 'mceButtonSelected'); - break; - - case "ul": - tinyMCE.switchClass(editor_id + '_bullist', 'mceButtonSelected'); - break; + getInfo : function() { + return { + longname : 'Simple theme', + author : 'Moxiecode Systems AB', + authorurl : 'http://tinymce.moxiecode.com', + version : tinymce.majorVersion + "." + tinymce.minorVersion + } + } + }); - case "ol": - tinyMCE.switchClass(editor_id + '_numlist', 'mceButtonSelected'); - break; - } - } while ((node = node.parentNode) != null); - } -}; - -tinyMCE.addTheme("simple", TinyMCE_SimpleTheme); -tinyMCE.addButtonMap(TinyMCE_SimpleTheme._buttonMap); + tinymce.ThemeManager.add('simple', tinymce.themes.SimpleTheme); +})(); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/bold.gif Binary file includes/clientside/tinymce/themes/simple/images/bold.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/bold_de_se.gif Binary file includes/clientside/tinymce/themes/simple/images/bold_de_se.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/bold_fr.gif Binary file includes/clientside/tinymce/themes/simple/images/bold_fr.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/bold_ru.gif Binary file includes/clientside/tinymce/themes/simple/images/bold_ru.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/bold_tw.gif Binary file includes/clientside/tinymce/themes/simple/images/bold_tw.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/bullist.gif Binary file includes/clientside/tinymce/themes/simple/images/bullist.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/buttons.gif Binary file includes/clientside/tinymce/themes/simple/images/buttons.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/cleanup.gif Binary file includes/clientside/tinymce/themes/simple/images/cleanup.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/italic.gif Binary file includes/clientside/tinymce/themes/simple/images/italic.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/italic_de_se.gif Binary file includes/clientside/tinymce/themes/simple/images/italic_de_se.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/italic_ru.gif Binary file includes/clientside/tinymce/themes/simple/images/italic_ru.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/italic_tw.gif Binary file includes/clientside/tinymce/themes/simple/images/italic_tw.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/numlist.gif Binary file includes/clientside/tinymce/themes/simple/images/numlist.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/redo.gif Binary file includes/clientside/tinymce/themes/simple/images/redo.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/separator.gif Binary file includes/clientside/tinymce/themes/simple/images/separator.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/spacer.gif Binary file includes/clientside/tinymce/themes/simple/images/spacer.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/strikethrough.gif Binary file includes/clientside/tinymce/themes/simple/images/strikethrough.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/underline.gif Binary file includes/clientside/tinymce/themes/simple/images/underline.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/underline_fr.gif Binary file includes/clientside/tinymce/themes/simple/images/underline_fr.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/underline_ru.gif Binary file includes/clientside/tinymce/themes/simple/images/underline_ru.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/underline_tw.gif Binary file includes/clientside/tinymce/themes/simple/images/underline_tw.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/images/undo.gif Binary file includes/clientside/tinymce/themes/simple/images/undo.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/img/icons.gif Binary file includes/clientside/tinymce/themes/simple/img/icons.gif has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/langs/en.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/simple/langs/en.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,11 @@ +tinyMCE.addI18n('en.simple',{ +bold_desc:"Bold (Ctrl+B)", +italic_desc:"Italic (Ctrl+I)", +underline_desc:"Underline (Ctrl+U)", +striketrough_desc:"Strikethrough", +bullist_desc:"Unordered list", +numlist_desc:"Ordered list", +undo_desc:"Undo (Ctrl+Z)", +redo_desc:"Redo (Ctrl+Y)", +cleanup_desc:"Cleanup messy code" +}); \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/skins/default/content.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/simple/skins/default/content.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,25 @@ +body, td, pre { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +body { + background-color: #FFFFFF; +} + +.mceVisualAid { + border: 1px dashed #BBBBBB; +} + +/* MSIE specific */ + +* html body { + scrollbar-3dlight-color: #F0F0EE; + scrollbar-arrow-color: #676662; + scrollbar-base-color: #F0F0EE; + scrollbar-darkshadow-color: #DDDDDD; + scrollbar-face-color: #E0E0DD; + scrollbar-highlight-color: #F0F0EE; + scrollbar-shadow-color: #F0F0EE; + scrollbar-track-color: #F5F5F5; +} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/skins/default/ui.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/simple/skins/default/ui.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,32 @@ +/* Reset */ +.defaultSimpleSkin table, .defaultSimpleSkin tbody, .defaultSimpleSkin a, .defaultSimpleSkin img, .defaultSimpleSkin tr, .defaultSimpleSkin div, .defaultSimpleSkin td, .defaultSimpleSkin iframe, .defaultSimpleSkin span, .defaultSimpleSkin * {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000} + +/* Containers */ +.defaultSimpleSkin {position:relative} +.defaultSimpleSkin table.mceLayout {background:#F0F0EE; border:1px solid #CCC;} +.defaultSimpleSkin iframe {display:block; background:#FFF; border-bottom:1px solid #CCC;} +.defaultSimpleSkin .mceToolbar {height:24px;} + +/* Layout */ +.defaultSimpleSkin span.icon, .defaultSimpleSkin img.icon {display:block; width:20px; height:20px} +.defaultSimpleSkin .icon {background:url(../../img/icons.gif) no-repeat 20px 20px} + +/* Button */ +.defaultSimpleSkin .mceButton {display:block; border:1px solid #F0F0EE; width:20px; height:20px} +.defaultSimpleSkin a.mceButtonEnabled:hover {border:1px solid #0A246A; background-color:#B2BBD0} +.defaultSimpleSkin a.mceButtonActive {border:1px solid #0A246A; background-color:#C2CBE0} +.defaultSimpleSkin .mceButtonDisabled span {opacity:0.3; filter:alpha(opacity=30)} + +/* Separator */ +.defaultSimpleSkin .mceSeparator {display:block; background:url(../../img/icons.gif) -180px 0; width:2px; height:20px; margin:0 2px 0 4px} + +/* Theme */ +.defaultSimpleSkin span.bold {background-position:0 0} +.defaultSimpleSkin span.italic {background-position:-60px 0} +.defaultSimpleSkin span.underline {background-position:-140px 0} +.defaultSimpleSkin span.strikethrough {background-position:-120px 0} +.defaultSimpleSkin span.undo {background-position:-160px 0} +.defaultSimpleSkin span.redo {background-position:-100px 0} +.defaultSimpleSkin span.cleanup {background-position:-40px 0} +.defaultSimpleSkin span.insertunorderedlist {background-position:-20px 0} +.defaultSimpleSkin span.insertorderedlist {background-position:-80px 0} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/skins/o2k7/content.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/simple/skins/o2k7/content.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,17 @@ +body, td, pre {font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px;} + +body {background: #FFF;} +.mceVisualAid {border: 1px dashed #BBB;} + +/* IE */ + +* html body { +scrollbar-3dlight-color: #F0F0EE; +scrollbar-arrow-color: #676662; +scrollbar-base-color: #F0F0EE; +scrollbar-darkshadow-color: #DDDDDD; +scrollbar-face-color: #E0E0DD; +scrollbar-highlight-color: #F0F0EE; +scrollbar-shadow-color: #F0F0EE; +scrollbar-track-color: #F5F5F5; +} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/skins/o2k7/img/button_bg.png Binary file includes/clientside/tinymce/themes/simple/skins/o2k7/img/button_bg.png has changed diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/themes/simple/skins/o2k7/ui.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/includes/clientside/tinymce/themes/simple/skins/o2k7/ui.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,35 @@ +/* Reset */ +.o2k7SimpleSkin table, .o2k7SimpleSkin tbody, .o2k7SimpleSkin a, .o2k7SimpleSkin img, .o2k7SimpleSkin tr, .o2k7SimpleSkin div, .o2k7SimpleSkin td, .o2k7SimpleSkin iframe, .o2k7SimpleSkin span, .o2k7SimpleSkin * {border:0; margin:0; padding:0; background:transparent; white-space:nowrap; text-decoration:none; font-weight:normal; cursor:default; color:#000} + +/* Containers */ +.o2k7SimpleSkin {position:relative} +.o2k7SimpleSkin table.mceLayout {background:#E5EFFD; border:1px solid #ABC6DD;} +.o2k7SimpleSkin iframe {display:block; background:#FFF; border-bottom:1px solid #ABC6DD;} +.o2k7SimpleSkin .mceToolbar {height:26px;} + +/* Layout */ +.o2k7SimpleSkin .mceToolbar .mceToolbarStart span {display:block; background:url(img/button_bg.png) -22px 0; width:1px; height:22px; } +.o2k7SimpleSkin .mceToolbar .mceToolbarEnd span {display:block; background:url(img/button_bg.png) -22px 0; width:1px; height:22px} +.o2k7SimpleSkin span.icon, .o2k7SimpleSkin img.icon {display:block; width:20px; height:20px} +.o2k7SimpleSkin .icon {background:url(../../img/icons.gif) no-repeat 20px 20px} + +/* Button */ +.o2k7SimpleSkin .mceButton {display:block; background:url(img/button_bg.png); width:22px; height:22px} +.o2k7SimpleSkin a.mceButton span, .o2k7SimpleSkin a.mceButton img {margin:1px 0 0 1px} +.o2k7SimpleSkin a.mceButtonEnabled:hover {background-color:#B2BBD0; background-position:0 -22px} +.o2k7SimpleSkin a.mceButtonActive {background-position:0 -44px} +.o2k7SimpleSkin .mceButtonDisabled span {opacity:0.3; filter:alpha(opacity=30)} + +/* Separator */ +.o2k7SimpleSkin .mceSeparator {display:block; background:url(img/button_bg.png) -22px 0; width:5px; height:22px} + +/* Theme */ +.o2k7SimpleSkin span.bold {background-position:0 0} +.o2k7SimpleSkin span.italic {background-position:-60px 0} +.o2k7SimpleSkin span.underline {background-position:-140px 0} +.o2k7SimpleSkin span.strikethrough {background-position:-120px 0} +.o2k7SimpleSkin span.undo {background-position:-160px 0} +.o2k7SimpleSkin span.redo {background-position:-100px 0} +.o2k7SimpleSkin span.cleanup {background-position:-40px 0} +.o2k7SimpleSkin span.insertunorderedlist {background-position:-20px 0} +.o2k7SimpleSkin span.insertorderedlist {background-position:-80px 0} diff -r d823e49e2e4e -r c433348f3628 includes/clientside/tinymce/tiny_mce.js --- a/includes/clientside/tinymce/tiny_mce.js Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/clientside/tinymce/tiny_mce.js Fri Feb 22 12:51:53 2008 -0500 @@ -1,1 +1,1 @@ -function TinyMCE_Engine(){var ua;this.majorVersion="2";this.minorVersion="1.0";this.releaseDate="2007-02-13";this.instances=new Array();this.switchClassCache=new Array();this.windowArgs=new Array();this.loadedFiles=new Array();this.pendingFiles=new Array();this.loadingIndex=0;this.configs=new Array();this.currentConfig=0;this.eventHandlers=new Array();this.log=new Array();this.undoLevels=[];this.undoIndex=0;this.typingUndoIndex=-1;ua=navigator.userAgent;this.isMSIE=(navigator.appName=="Microsoft Internet Explorer");this.isMSIE5=this.isMSIE&&(ua.indexOf('MSIE 5')!=-1);this.isMSIE5_0=this.isMSIE&&(ua.indexOf('MSIE 5.0')!=-1);this.isMSIE7=this.isMSIE&&(ua.indexOf('MSIE 7')!=-1);this.isGecko=ua.indexOf('Gecko')!=-1;this.isSafari=ua.indexOf('Safari')!=-1;this.isOpera=ua.indexOf('Opera')!=-1;this.isMac=ua.indexOf('Mac')!=-1;this.isNS7=ua.indexOf('Netscape/7')!=-1;this.isNS71=ua.indexOf('Netscape/7.1')!=-1;this.dialogCounter=0;this.plugins=new Array();this.themes=new Array();this.menus=new Array();this.loadedPlugins=new Array();this.buttonMap=new Array();this.isLoaded=false;if(this.isOpera){this.isMSIE=true;this.isGecko=false;this.isSafari=false}this.isIE=this.isMSIE;this.isRealIE=this.isMSIE&&!this.isOpera;this.idCounter=0};TinyMCE_Engine.prototype={init:function(settings){var theme,nl,baseHREF="",i;if(this.isMSIE5_0)return;this.settings=settings;if(typeof(document.execCommand)=='undefined')return;if(!tinyMCE.baseURL){var elements=document.getElementsByTagName('script');nl=document.getElementsByTagName('base');for(i=0;i');this._def("font_size_classes",'');this._def("font_size_style_values",'xx-small,x-small,small,medium,large,x-large,xx-large',true);this._def("event_elements",'a,img',true);this._def("convert_urls",true);this._def("table_inline_editing",false);this._def("object_resizing",true);this._def("custom_shortcuts",true);this._def("convert_on_click",false);this._def("content_css",'');this._def("fix_list_elements",true);this._def("fix_table_elements",false);this._def("strict_loading_mode",document.contentType=='application/xhtml+xml');this._def("hidden_tab_class",'');this._def("display_tab_class",'');this._def("gecko_spellcheck",false);this._def("hide_selects_on_submit",true);if(this.isMSIE&&!this.isOpera)this.settings.strict_loading_mode=false;if(this.isMSIE&&this.settings['browsers'].indexOf('msie')==-1)return;if(this.isGecko&&this.settings['browsers'].indexOf('gecko')==-1)return;if(this.isSafari&&this.settings['browsers'].indexOf('safari')==-1)return;if(this.isOpera&&this.settings['browsers'].indexOf('opera')==-1)return;baseHREF=tinyMCE.settings['document_base_url'];var h=document.location.href;var p=h.indexOf('://');if(p>0&&document.location.protocol!="file:"){p=h.indexOf('/',p+3);h=h.substring(0,p);if(baseHREF.indexOf('://')==-1)baseHREF=h+baseHREF;tinyMCE.settings['document_base_url']=baseHREF;tinyMCE.settings['document_base_prefix']=h}if(baseHREF.indexOf('?')!=-1)baseHREF=baseHREF.substring(0,baseHREF.indexOf('?'));this.settings['base_href']=baseHREF.substring(0,baseHREF.lastIndexOf('/'))+"/";theme=this.settings['theme'];this.inlineStrict='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';this.inlineTransitional='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';this.blockElms='H[1-6]|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|FORM|NOSCRIPT|NOFRAMES|MENU|ISINDEX|SAMP';this.blockRegExp=new RegExp("^("+this.blockElms+")$","i");this.posKeyCodes=new Array(13,45,36,35,33,34,37,38,39,40);this.uniqueURL='javascript:void(091039730);';this.uniqueTag='';this.callbacks=new Array('onInit','getInfo','getEditorTemplate','setupContent','onChange','onPageLoad','handleNodeChange','initInstance','execCommand','getControlHTML','handleEvent','cleanup','removeInstance');this.settings['theme_href']=tinyMCE.baseURL+"/themes/"+theme;if(!tinyMCE.isIE||tinyMCE.isOpera)this.settings['force_br_newlines']=false;if(tinyMCE.getParam("popups_css",false)){var cssPath=tinyMCE.getParam("popups_css","");if(cssPath.indexOf('://')==-1&&cssPath.charAt(0)!='/')this.settings['popups_css']=this.documentBasePath+"/"+cssPath;else this.settings['popups_css']=cssPath}else this.settings['popups_css']=tinyMCE.baseURL+"/themes/"+theme+"/css/editor_popup.css";if(tinyMCE.getParam("editor_css",false)){var cssPath=tinyMCE.getParam("editor_css","");if(cssPath.indexOf('://')==-1&&cssPath.charAt(0)!='/')this.settings['editor_css']=this.documentBasePath+"/"+cssPath;else this.settings['editor_css']=cssPath}else{if(this.settings.editor_css!='')this.settings['editor_css']=tinyMCE.baseURL+"/themes/"+theme+"/css/editor_ui.css"}if(tinyMCE.settings['debug']){var msg="Debug: \n";msg+="baseURL: "+this.baseURL+"\n";msg+="documentBasePath: "+this.documentBasePath+"\n";msg+="content_css: "+this.settings['content_css']+"\n";msg+="popups_css: "+this.settings['popups_css']+"\n";msg+="editor_css: "+this.settings['editor_css']+"\n";alert(msg)}if(this.configs.length==0){if(typeof(TinyMCECompressed)=="undefined"){tinyMCE.addEvent(window,"DOMContentLoaded",TinyMCE_Engine.prototype.onLoad);if(tinyMCE.isRealIE){if(document.body)tinyMCE.addEvent(document.body,"readystatechange",TinyMCE_Engine.prototype.onLoad);else tinyMCE.addEvent(document,"readystatechange",TinyMCE_Engine.prototype.onLoad)}tinyMCE.addEvent(window,"load",TinyMCE_Engine.prototype.onLoad);tinyMCE._addUnloadEvents()}}this.loadScript(tinyMCE.baseURL+'/themes/'+this.settings['theme']+'/editor_template'+tinyMCE.srcMode+'.js');this.loadScript(tinyMCE.baseURL+'/langs/'+this.settings['language']+'.js');this.loadCSS(this.settings['editor_css']);var p=tinyMCE.getParam('plugins','',true,',');if(p.length>0){for(var i=0;i&"\']','g');this.xmlEncodeRe=new RegExp('[<>&"]','g');},_addUnloadEvents:function(){if(tinyMCE.isIE){if(tinyMCE.settings['add_unload_trigger']){tinyMCE.addEvent(window,"unload",TinyMCE_Engine.prototype.unloadHandler);tinyMCE.addEvent(window.document,"beforeunload",TinyMCE_Engine.prototype.unloadHandler)}}else{if(tinyMCE.settings['add_unload_trigger'])tinyMCE.addEvent(window,"unload",function(){tinyMCE.triggerSave(true,true)})}},_def:function(key,def_val,t){var v=tinyMCE.getParam(key,def_val);v=t?v.replace(/\s+/g,""):v;this.settings[key]=v},hasPlugin:function(n){return typeof(this.plugins[n])!="undefined"&&this.plugins[n]!=null},addPlugin:function(n,p){var op=this.plugins[n];p.baseURL=op?op.baseURL:tinyMCE.baseURL+"/plugins/"+n;this.plugins[n]=p;this.loadNextScript()},setPluginBaseURL:function(n,u){var op=this.plugins[n];if(op)op.baseURL=u;else this.plugins[n]={baseURL:u}},loadPlugin:function(n,u){u=u.indexOf('.js')!=-1?u.substring(0,u.lastIndexOf('/')):u;u=u.charAt(u.length-1)=='/'?u.substring(0,u.length-1):u;this.plugins[n]={baseURL:u};this.loadScript(u+"/editor_plugin"+(tinyMCE.srcMode?'_src':'')+".js")},hasTheme:function(n){return typeof(this.themes[n])!="undefined"&&this.themes[n]!=null},addTheme:function(n,t){this.themes[n]=t;this.loadNextScript()},addMenu:function(n,m){this.menus[n]=m},hasMenu:function(n){return typeof(this.plugins[n])!="undefined"&&this.plugins[n]!=null},loadScript:function(url){var i;for(i=0;i');this.loadedFiles[this.loadedFiles.length]=url},loadNextScript:function(){var d=document,se;if(!tinyMCE.settings.strict_loading_mode)return;if(this.loadingIndex0){for(i=0,lflen=this.loadedFiles.length;i');this.loadedFiles[this.loadedFiles.length]=ar[x]}}}},importCSS:function(doc,css){var css_ary=css.replace(/\s+/,'').split(',');var csslen,elm,headArr,x,css_file;for(x=0,csslen=css_ary.length;x0){if(css_file.indexOf('://')==-1&&css_file.charAt(0)!='/')css_file=this.documentBasePath+"/"+css_file;if(typeof(doc.createStyleSheet)=="undefined"){elm=doc.createElement("link");elm.rel="stylesheet";elm.href=css_file;if((headArr=doc.getElementsByTagName("head"))!=null&&headArr.length>0)headArr[0].appendChild(elm)}else doc.createStyleSheet(css_file)}}},confirmAdd:function(e,settings){var elm=tinyMCE.isIE?event.srcElement:e.target;var elementId=elm.name?elm.name:elm.id;tinyMCE.settings=settings;if(tinyMCE.settings['convert_on_click']||(!elm.getAttribute('mce_noask')&&confirm(tinyMCELang['lang_edit_confirm'])))tinyMCE.addMCEControl(elm,elementId);elm.setAttribute('mce_noask','true')},updateContent:function(form_element_name){var formElement=document.getElementById(form_element_name);for(var n in tinyMCE.instances){var inst=tinyMCE.instances[n];if(!tinyMCE.isInstance(inst))continue;inst.switchSettings();if(inst.formElement==formElement){var doc=inst.getDoc();tinyMCE._setHTML(doc,inst.formElement.value);if(!tinyMCE.isIE)doc.body.innerHTML=tinyMCE._cleanupHTML(inst,doc,this.settings,doc.body,inst.visualAid)}}},addMCEControl:function(replace_element,form_element_name,target_document){var id="mce_editor_"+tinyMCE.idCounter++;var inst=new TinyMCE_Control(tinyMCE.settings);inst.editorId=id;this.instances[id]=inst;inst._onAdd(replace_element,form_element_name,target_document)},removeInstance:function(ti){var t=[],n,i;for(n in tinyMCE.instances){i=tinyMCE.instances[n];if(tinyMCE.isInstance(i)&&ti!=i)t[n]=i}tinyMCE.instances=t;n=[];t=tinyMCE.undoLevels;for(i=0;i0){tinyMCE.nextUndoRedoAction='Undo';inst=this.undoLevels[--this.undoIndex];inst.select();if(!tinyMCE.nextUndoRedoInstanceId)inst.execCommand('Undo')}}else inst.execCommand('Undo');return true;case"Redo":if(this.getParam('custom_undo_redo_global')){if(this.undoIndex<=this.undoLevels.length-1){tinyMCE.nextUndoRedoAction='Redo';inst=this.undoLevels[this.undoIndex++];inst.select();if(!tinyMCE.nextUndoRedoInstanceId)inst.execCommand('Redo')}}else inst.execCommand('Redo');return true;case'mceFocus':var inst=tinyMCE.getInstanceById(value);if(inst)inst.getWin().focus();return;case"mceAddControl":case"mceAddEditor":tinyMCE.addMCEControl(tinyMCE._getElementById(value),value);return;case"mceAddFrameControl":tinyMCE.addMCEControl(tinyMCE._getElementById(value['element'],value['document']),value['element'],value['document']);return;case"mceRemoveControl":case"mceRemoveEditor":tinyMCE.removeMCEControl(value);return;case"mceToggleEditor":var inst=tinyMCE.getInstanceById(value),pe,te;if(inst){pe=document.getElementById(inst.editorId+'_parent');te=inst.oldTargetElement;if(typeof(inst.enabled)=='undefined')inst.enabled=true;inst.enabled=!inst.enabled;if(!inst.enabled){pe.style.display='none';te.value=inst.getHTML();te.style.display=inst.oldTargetDisplay;tinyMCE.dispatchCallback(inst,'hide_instance_callback','hideInstance',inst)}else{pe.style.display='block';te.style.display='none';inst.setHTML(te.value);inst.useCSS=false;tinyMCE.dispatchCallback(inst,'show_instance_callback','showInstance',inst)}}else tinyMCE.addMCEControl(tinyMCE._getElementById(value),value);return;case"mceResetDesignMode":if(!tinyMCE.isIE){for(var n in tinyMCE.instances){if(!tinyMCE.isInstance(tinyMCE.instances[n]))continue;try{tinyMCE.instances[n].getDoc().designMode="on"}catch(e){}}}return}if(inst){inst.execCommand(command,user_interface,value)}else if(tinyMCE.settings['focus_alert'])alert(tinyMCELang['lang_focus_alert'])},_createIFrame:function(replace_element,doc,win){var iframe,id=replace_element.getAttribute("id");var aw,ah;if(typeof(doc)=="undefined")doc=document;if(typeof(win)=="undefined")win=window;iframe=doc.createElement("iframe");aw=""+tinyMCE.settings['area_width'];ah=""+tinyMCE.settings['area_height'];if(aw.indexOf('%')==-1){aw=parseInt(aw);aw=(isNaN(aw)||aw<0)?300:aw;aw=aw+"px"}if(ah.indexOf('%')==-1){ah=parseInt(ah);ah=(isNaN(ah)||ah<0)?240:ah;ah=ah+"px"}iframe.setAttribute("id",id);iframe.setAttribute("name",id);iframe.setAttribute("class","mceEditorIframe");iframe.setAttribute("border","0");iframe.setAttribute("frameBorder","0");iframe.setAttribute("marginWidth","0");iframe.setAttribute("marginHeight","0");iframe.setAttribute("leftMargin","0");iframe.setAttribute("topMargin","0");iframe.setAttribute("width",aw);iframe.setAttribute("height",ah);iframe.setAttribute("allowtransparency","true");iframe.className='mceEditorIframe';if(tinyMCE.settings["auto_resize"])iframe.setAttribute("scrolling","no");if(tinyMCE.isRealIE)iframe.setAttribute("src",this.settings['default_document']);iframe.style.width=aw;iframe.style.height=ah;if(tinyMCE.settings.strict_loading_mode)iframe.style.marginBottom='-5px';if(tinyMCE.isRealIE)replace_element.outerHTML=iframe.outerHTML;else replace_element.parentNode.replaceChild(iframe,replace_element);if(tinyMCE.isRealIE)return win.frames[id];else return iframe},setupContent:function(editor_id){var inst=tinyMCE.instances[editor_id],i;var doc=inst.getDoc();var head=doc.getElementsByTagName('head').item(0);var content=inst.startContent;if(tinyMCE.settings.strict_loading_mode){content=content.replace(/</g,'<');content=content.replace(/>/g,'>');content=content.replace(/"/g,'"');content=content.replace(/&/g,'&')}tinyMCE.selectedInstance=inst;inst.switchSettings();if(!tinyMCE.isIE&&tinyMCE.getParam("setupcontent_reload",false)&&doc.title!="blank_page"){try{doc.location.href=tinyMCE.baseURL+"/blank.htm"}catch(ex){}window.setTimeout("tinyMCE.setupContent('"+editor_id+"');",1000);return}if(!head){window.setTimeout("tinyMCE.setupContent('"+editor_id+"');",10);return}tinyMCE.importCSS(inst.getDoc(),tinyMCE.baseURL+"/themes/"+inst.settings['theme']+"/css/editor_content.css");tinyMCE.importCSS(inst.getDoc(),inst.settings['content_css']);tinyMCE.dispatchCallback(inst,'init_instance_callback','initInstance',inst);if(tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')){inst.addShortcut('ctrl','z','lang_undo_desc','Undo');inst.addShortcut('ctrl','y','lang_redo_desc','Redo')}for(i=1;i<=6;i++)inst.addShortcut('ctrl',''+i,'','FormatBlock',false,'');inst.addShortcut('ctrl','7','','FormatBlock',false,'

');inst.addShortcut('ctrl','8','','FormatBlock',false,'

');inst.addShortcut('ctrl','9','','FormatBlock',false,'
');if(tinyMCE.isGecko){inst.addShortcut('ctrl','b','lang_bold_desc','Bold');inst.addShortcut('ctrl','i','lang_italic_desc','Italic');inst.addShortcut('ctrl','u','lang_underline_desc','Underline')}if(tinyMCE.getParam("convert_fonts_to_spans"))inst.getBody().setAttribute('id','mceSpanFonts');if(tinyMCE.settings['nowrap'])doc.body.style.whiteSpace="nowrap";doc.body.dir=this.settings['directionality'];doc.editorId=editor_id;if(!tinyMCE.isIE)doc.documentElement.editorId=editor_id;inst.setBaseHREF(tinyMCE.settings['base_href']);if(tinyMCE.settings['convert_newlines_to_brs']){content=tinyMCE.regexpReplace(content,"\r\n","
","gi");content=tinyMCE.regexpReplace(content,"\r","
","gi");content=tinyMCE.regexpReplace(content,"\n","
","gi")}content=tinyMCE.storeAwayURLs(content);content=tinyMCE._customCleanup(inst,"insert_to_editor",content);if(tinyMCE.isIE){window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["'+editor_id+'"].getDoc(), "'+editor_id+'");}catch(e){}',500);if(tinyMCE.settings["force_br_newlines"])doc.styleSheets[0].addRule("p","margin: 0;");var body=inst.getBody();body.editorId=editor_id}content=tinyMCE.cleanupHTMLCode(content);if(!tinyMCE.isIE){var contentElement=inst.getDoc().createElement("body");var doc=inst.getDoc();contentElement.innerHTML=content;if(tinyMCE.isGecko&&tinyMCE.settings['remove_lt_gt'])content=content.replace(new RegExp('<>','g'),"");if(tinyMCE.settings['cleanup_on_startup'])tinyMCE.setInnerHTML(inst.getBody(),tinyMCE._cleanupHTML(inst,doc,this.settings,contentElement));else tinyMCE.setInnerHTML(inst.getBody(),content);tinyMCE.convertAllRelativeURLs(inst.getBody())}else{if(tinyMCE.settings['cleanup_on_startup']){tinyMCE._setHTML(inst.getDoc(),content);eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}')}else tinyMCE._setHTML(inst.getDoc(),content)}tinyMCE.handleVisualAid(inst.getBody(),true,tinyMCE.settings['visual'],inst);tinyMCE.dispatchCallback(inst,'setupcontent_callback','setupContent',editor_id,inst.getBody(),inst.getDoc());if(!tinyMCE.isIE)tinyMCE.addEventHandlers(inst);if(tinyMCE.isIE){tinyMCE.addEvent(inst.getBody(),"blur",TinyMCE_Engine.prototype._eventPatch);tinyMCE.addEvent(inst.getBody(),"beforedeactivate",TinyMCE_Engine.prototype._eventPatch);if(!tinyMCE.isOpera){tinyMCE.addEvent(doc.body,"mousemove",TinyMCE_Engine.prototype.onMouseMove);tinyMCE.addEvent(doc.body,"beforepaste",TinyMCE_Engine.prototype._eventPatch);tinyMCE.addEvent(doc.body,"drop",TinyMCE_Engine.prototype._eventPatch)}}inst.select();tinyMCE.selectedElement=inst.contentWindow.document.body;tinyMCE._customCleanup(inst,"insert_to_editor_dom",inst.getBody());tinyMCE._customCleanup(inst,"setup_content_dom",inst.getBody());tinyMCE._setEventsEnabled(inst.getBody(),false);tinyMCE.cleanupAnchors(inst.getDoc());if(tinyMCE.getParam("convert_fonts_to_spans"))tinyMCE.convertSpansToFonts(inst.getDoc());inst.startContent=tinyMCE.trim(inst.getBody().innerHTML);inst.undoRedo.add({content:inst.startContent});if(tinyMCE.isGecko){tinyMCE.selectNodes(inst.getBody(),function(n){if(n.nodeType==3||n.nodeType==8)n.nodeValue=n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"','gi'),"");return false})}if(tinyMCE.isGecko)inst.getBody().spellcheck=tinyMCE.getParam("gecko_spellcheck");tinyMCE._removeInternal(inst.getBody());inst.select();tinyMCE.triggerNodeChange(false,true)},storeAwayURLs:function(s){if(!s.match(/(mce_src|mce_href)/gi,s)){s=s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"','gi'),'src="$1" mce_src="$1"');s=s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"','gi'),'href="$1" mce_href="$1"')}return s},_removeInternal:function(n){if(tinyMCE.isGecko){tinyMCE.selectNodes(n,function(n){if(n.nodeType==3||n.nodeType==8)n.nodeValue=n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"','gi'),"");return false})}},removeTinyMCEFormElements:function(form_obj){var i,elementId;if(!tinyMCE.getParam('hide_selects_on_submit'))return;if(typeof(form_obj)=="undefined"||form_obj==null)return;if(form_obj.nodeName!="FORM"){if(form_obj.form)form_obj=form_obj.form;else form_obj=tinyMCE.getParentElement(form_obj,"form")}if(form_obj==null)return;for(i=0;i");rng.collapse(false);rng.select();tinyMCE.execCommand("mceAddUndoLevel");tinyMCE.triggerNodeChange(false);return false}}if(e.keyCode==8||e.keyCode==46){tinyMCE.selectedElement=e.target;tinyMCE.linkElement=tinyMCE.getParentElement(e.target,"a");tinyMCE.imgElement=tinyMCE.getParentElement(e.target,"img");tinyMCE.triggerNodeChange(false)}return false;break;case"keyup":case"keydown":tinyMCE.hideMenus();tinyMCE.hasMouseMoved=false;if(inst&&inst.handleShortcut(e))return false;if(e.target.editorId)tinyMCE.instances[e.target.editorId].select();if(tinyMCE.selectedInstance)tinyMCE.selectedInstance.switchSettings();var inst=tinyMCE.selectedInstance;if(tinyMCE.isGecko&&tinyMCE.settings['force_p_newlines']&&(e.keyCode==8||e.keyCode==46)&&!e.shiftKey){if(TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance,e.type)){tinyMCE.execCommand("mceAddUndoLevel");e.preventDefault();return false}}tinyMCE.selectedElement=null;tinyMCE.selectedNode=null;var elm=tinyMCE.selectedInstance.getFocusElement();tinyMCE.linkElement=tinyMCE.getParentElement(elm,"a");tinyMCE.imgElement=tinyMCE.getParentElement(elm,"img");tinyMCE.selectedElement=elm;if(tinyMCE.isGecko&&e.type=="keyup"&&e.keyCode==9)tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(),true,tinyMCE.settings['visual'],tinyMCE.selectedInstance);if(tinyMCE.isIE&&e.type=="keydown"&&e.keyCode==13)tinyMCE.enterKeyElement=tinyMCE.selectedInstance.getFocusElement();if(tinyMCE.isIE&&e.type=="keyup"&&e.keyCode==13){var elm=tinyMCE.enterKeyElement;if(elm){var re=new RegExp('^HR|IMG|BR$','g');var dre=new RegExp('^H[1-6]$','g');if(!elm.hasChildNodes()&&!re.test(elm.nodeName)){if(dre.test(elm.nodeName))elm.innerHTML="  ";else elm.innerHTML=" "}}}var keys=tinyMCE.posKeyCodes;var posKey=false;for(var i=0;i';h+='';h+=''}else{h+='';h+='';h+=''}return h},getMenuButtonHTML:function(id,lang,img,mcmd,cmd,ui,val){var h='',m,x;mcmd='tinyMCE.execInstanceCommand(\'{$editor_id}\',\''+mcmd+'\');';cmd='tinyMCE.execInstanceCommand(\'{$editor_id}\',\''+cmd+'\'';if(typeof(ui)!="undefined"&&ui!=null)cmd+=','+ui;if(typeof(val)!="undefined"&&val!=null)cmd+=",'"+val+"'";cmd+=');';if(tinyMCE.getParam('button_tile_map')&&(!tinyMCE.isIE||tinyMCE.isOpera)&&(m=tinyMCE.buttonMap[id])!=null&&(tinyMCE.getParam("language")=="en"||img.indexOf('$lang')==-1)){x=0-(m*20)==0?'0':0-(m*20);if(tinyMCE.isRealIE)h+='';else h+='';h+='';h+='';h+='';h+=''}else{if(tinyMCE.isRealIE)h+='';else h+='';h+='';h+='';h+='';h+=''}return h},_menuButtonEvent:function(e,o){if(o.className=='mceMenuButtonFocus')return;if(e=='over')o.className=o.className+' mceMenuHover';else o.className=o.className.replace(/\s.*$/,'')},addButtonMap:function(m){var i,a=m.replace(/\s+/,'').split(',');for(i=0;i0);if(tinyMCE.settings['custom_undo_redo']){undoIndex=inst.undoRedo.undoIndex;undoLevels=inst.undoRedo.undoLevels.length}tinyMCE.dispatchCallback(inst,'handle_node_change_callback','handleNodeChange',editorId,elm,undoIndex,undoLevels,inst.visualAid,anySelection,setup_content)}if(this.selectedInstance&&(typeof(focus)=="undefined"||focus))this.selectedInstance.contentWindow.focus()},_customCleanup:function(inst,type,content){var pl,po,i;var customCleanup=tinyMCE.settings['cleanup_callback'];if(customCleanup!=""&&eval("typeof("+customCleanup+")")!="undefined")content=eval(customCleanup+"(type, content, inst);");po=tinyMCE.themes[tinyMCE.settings['theme']];if(po&&po.cleanup)content=po.cleanup(type,content,inst);pl=inst.plugins;for(i=0;i0)className+=" ";className+=classNames[i]}return className},handleVisualAid:function(el,deep,state,inst,skip_dispatch){if(!el)return;if(!skip_dispatch)tinyMCE.dispatchCallback(inst,'handle_visual_aid_callback','handleVisualAid',el,deep,state,inst);var tableElement=null;switch(el.nodeName){case"TABLE":var oldW=el.style.width;var oldH=el.style.height;var bo=tinyMCE.getAttrib(el,"border");bo=bo==""||bo=="0"?true:false;tinyMCE.setAttrib(el,"class",tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el,"class"),state&&bo));el.style.width=oldW;el.style.height=oldH;for(var y=0;y0)return inst.cssClasses;if(typeof(editor_id)=="undefined"&&typeof(doc)=="undefined"){var instance;for(var instanceName in tinyMCE.instances){instance=tinyMCE.instances[instanceName];if(!tinyMCE.isInstance(instance))continue;break}doc=instance.getDoc()}if(typeof(doc)=="undefined"){var instance=tinyMCE.getInstanceById(editor_id);doc=instance.getDoc()}if(doc){var styles=doc.styleSheets;if(styles&&styles.length>0){for(var x=0;x'+tinyMCE.replaceVar(v,"pluginurl",o.baseURL)+'';return tinyMCE.replaceVar(v,"pluginurl",o.baseURL)}}o=tinyMCE.themes[tinyMCE.settings['theme']];if(o.getControlHTML&&(v=o.getControlHTML(c))!=''){if(rtl)return''+v+'';return v}return''},evalFunc:function(f,idx,a,o){o=!o?window:o;f=typeof(f)=='function'?f:o[f];return f.apply(o,Array.prototype.slice.call(a,idx))},dispatchCallback:function(i,p,n){return this.callFunc(i,p,n,0,this.dispatchCallback.arguments)},executeCallback:function(i,p,n){return this.callFunc(i,p,n,1,this.executeCallback.arguments)},execCommandCallback:function(i,p,n){return this.callFunc(i,p,n,2,this.execCommandCallback.arguments)},callFunc:function(ins,p,n,m,a){var l,i,on,o,s,v;s=m==2;l=tinyMCE.getParam(p,'');if(l!=''&&(v=tinyMCE.evalFunc(l,3,a))==s&&m>0)return true;if(ins!=null){for(i=0,l=ins.plugins;i0)return true}}l=tinyMCE.themes;for(on in l){o=l[on];if(o[n]&&(v=tinyMCE.evalFunc(n,3,a,o))==s&&m>0)return true}return false},xmlEncode:function(s,skip_apos){return s?(''+s).replace(!skip_apos?this.xmlEncodeAposRe:this.xmlEncodeRe,function(c,b){switch(c){case'&':return'&';case'"':return'"';case'\'':return''';case'<':return'<';case'>':return'>'}return c}):s},extend:function(p,np){var o={};o.parent=p;for(n in p)o[n]=p[n];for(n in np)o[n]=np[n];return o},hideMenus:function(){var e=tinyMCE.lastSelectedMenuBtn;if(tinyMCE.lastMenu){tinyMCE.lastMenu.hide();tinyMCE.lastMenu=null}if(e){tinyMCE.switchClass(e,tinyMCE.lastMenuBtnClass);tinyMCE.lastSelectedMenuBtn=null}}};var TinyMCE=TinyMCE_Engine;var tinyMCE=new TinyMCE_Engine();var tinyMCELang={};function TinyMCE_Control(settings){var t,i,to,fu,p,x,fn,fu,pn,s=settings;this.undoRedoLevel=true;this.isTinyMCE_Control=true;this.settings=s;this.settings['theme']=tinyMCE.getParam("theme","default");this.settings['width']=tinyMCE.getParam("width",-1);this.settings['height']=tinyMCE.getParam("height",-1);this.selection=new TinyMCE_Selection(this);this.undoRedo=new TinyMCE_UndoRedo(this);this.cleanup=new TinyMCE_Cleanup();this.shortcuts=new Array();this.hasMouseMoved=false;this.foreColor=this.backColor="#999999";this.data={};this.cssClasses=[];this.cleanup.init({valid_elements:s.valid_elements,extended_valid_elements:s.extended_valid_elements,valid_child_elements:s.valid_child_elements,entities:s.entities,entity_encoding:s.entity_encoding,debug:s.cleanup_debug,indent:s.apply_source_formatting,invalid_elements:s.invalid_elements,verify_html:s.verify_html,fix_content_duplication:s.fix_content_duplication,convert_fonts_to_spans:s.convert_fonts_to_spans});t=this.settings['theme'];if(!tinyMCE.hasTheme(t)){fn=tinyMCE.callbacks;to={};for(i=0;i0){for(i=0;i1&&tinyMCE.currentConfig!=this.settings['index']){tinyMCE.settings=this.settings;tinyMCE.currentConfig=this.settings['index']}},select:function(){var oldInst=tinyMCE.selectedInstance;if(oldInst!=this){if(oldInst)oldInst.execCommand('mceEndTyping');tinyMCE.dispatchCallback(this,'select_instance_callback','selectInstance',this,oldInst);tinyMCE.selectedInstance=this}},getBody:function(){return this.contentBody?this.contentBody:this.getDoc().body},getDoc:function(){return this.contentWindow.document},getWin:function(){return this.contentWindow},getContainerWin:function(){return this.containerWindow?this.containerWindow:window},getViewPort:function(){return tinyMCE.getViewPort(this.getWin())},getParentNode:function(n,f){return tinyMCE.getParentNode(n,f,this.getBody())},getParentElement:function(n,na,f){return tinyMCE.getParentElement(n,na,f,this.getBody())},getParentBlockElement:function(n){return tinyMCE.getParentBlockElement(n,this.getBody())},resizeToContent:function(){var d=this.getDoc(),b=d.body,de=d.documentElement;this.iframeElement.style.height=(tinyMCE.isRealIE)?b.scrollHeight:de.offsetHeight+'px'},addShortcut:function(m,k,d,cmd,ui,va){var n=typeof(k)=="number",ie=tinyMCE.isIE,c,sc,i,scl=this.shortcuts;if(!tinyMCE.getParam('custom_shortcuts'))return false;m=m.toLowerCase();k=ie&&!n?k.toUpperCase():k;c=n?null:k.charCodeAt(0);d=d&&d.indexOf('lang_')==0?tinyMCE.getLang(d):d;sc={alt:m.indexOf('alt')!=-1,ctrl:m.indexOf('ctrl')!=-1,shift:m.indexOf('shift')!=-1,charCode:c,keyCode:n?k:(ie?c:null),desc:d,cmd:cmd,ui:ui,val:va};for(i=0;i0)rng.pasteHTML('
'+rng.htmlText+"
");tinyMCE.triggerNodeChange();return}}}switch(command){case"mceRepaint":this.repaint();return true;case"unlink":if(tinyMCE.isGecko&&this.getSel().isCollapsed){focusElm=tinyMCE.getParentElement(focusElm,'A');if(focusElm)this.selection.selectNode(focusElm,false)}this.getDoc().execCommand(command,user_interface,value);tinyMCE.isGecko&&this.getSel().collapseToEnd();tinyMCE.triggerNodeChange();return true;case"InsertUnorderedList":case"InsertOrderedList":this.getDoc().execCommand(command,user_interface,value);tinyMCE.triggerNodeChange();break;case"Strikethrough":this.getDoc().execCommand(command,user_interface,value);tinyMCE.triggerNodeChange();break;case"mceSelectNode":this.selection.selectNode(value);tinyMCE.triggerNodeChange();tinyMCE.selectedNode=value;break;case"FormatBlock":if(value==null||value==""){var elm=tinyMCE.getParentElement(this.getFocusElement(),"p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp");if(elm)this.execCommand("mceRemoveNode",false,elm)}else{if(!this.cleanup.isValid(value))return true;if(tinyMCE.isGecko&&new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>','gi').test(value))value=value.replace(/[^a-z]/gi,'');if(tinyMCE.isIE&&new RegExp('blockquote|code|samp','gi').test(value)){var b=this.selection.getBookmark();this.getDoc().execCommand("FormatBlock",false,'

');tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()),value);this.selection.moveToBookmark(b)}else this.getDoc().execCommand("FormatBlock",false,value)}tinyMCE.triggerNodeChange();break;case"mceRemoveNode":if(!value)value=tinyMCE.getParentElement(this.getFocusElement());if(tinyMCE.isIE){value.outerHTML=value.innerHTML}else{var rng=value.ownerDocument.createRange();rng.setStartBefore(value);rng.setEndAfter(value);rng.deleteContents();rng.insertNode(rng.createContextualFragment(value.innerHTML))}tinyMCE.triggerNodeChange();break;case"mceSelectNodeDepth":var parentNode=this.getFocusElement();for(var i=0;parentNode;i++){if(parentNode.nodeName.toLowerCase()=="body")break;if(parentNode.nodeName.toLowerCase()=="#text"){i--;parentNode=parentNode.parentNode;continue}if(i==value){this.selection.selectNode(parentNode,false);tinyMCE.triggerNodeChange();tinyMCE.selectedNode=parentNode;return}parentNode=parentNode.parentNode}break;case"mceSetStyleInfo":case"SetStyleInfo":var rng=this.getRng();var sel=this.getSel();var scmd=value['command'];var sname=value['name'];var svalue=value['value']==null?'':value['value'];var wrapper=value['wrapper']?value['wrapper']:"span";var parentElm=null;var invalidRe=new RegExp("^BODY|HTML$","g");var invalidParentsRe=tinyMCE.settings['merge_styles_invalid_parents']!=''?new RegExp(tinyMCE.settings['merge_styles_invalid_parents'],"gi"):null;if(tinyMCE.isIE){if(rng.item)parentElm=rng.item(0);else{var pelm=rng.parentElement();var prng=doc.selection.createRange();prng.moveToElementText(pelm);if(rng.htmlText==prng.htmlText||rng.boundingWidth==0){if(invalidParentsRe==null||!invalidParentsRe.test(pelm.nodeName))parentElm=pelm}}}else{var felm=this.getFocusElement();if(sel.isCollapsed||(new RegExp('td|tr|tbody|table','gi').test(felm.nodeName)&&sel.anchorNode==felm.parentNode))parentElm=felm}if(parentElm&&!invalidRe.test(parentElm.nodeName)){if(scmd=="setstyle")tinyMCE.setStyleAttrib(parentElm,sname,svalue);if(scmd=="setattrib")tinyMCE.setAttrib(parentElm,sname,svalue);if(scmd=="removeformat"){parentElm.style.cssText='';tinyMCE.setAttrib(parentElm,'class','')}var ch=tinyMCE.getNodeTree(parentElm,new Array(),1);for(var z=0;z=0;i--){var elm=nodes[i];var isNew=tinyMCE.getAttrib(elm,"mce_new")=="true";elm.removeAttribute("mce_new");if(elm.childNodes&&elm.childNodes.length==1&&elm.childNodes[0].nodeType==1){this._mergeElements(scmd,elm,elm.childNodes[0],isNew);continue}if(elm.parentNode.childNodes.length==1&&!invalidRe.test(elm.nodeName)&&!invalidRe.test(elm.parentNode.nodeName)){if(invalidParentsRe==null||!invalidParentsRe.test(elm.parentNode.nodeName))this._mergeElements(scmd,elm.parentNode,elm,false)}}var nodes=doc.getElementsByTagName(wrapper);for(var i=nodes.length-1;i>=0;i--){var elm=nodes[i];var isEmpty=true;var tmp=doc.createElement("body");tmp.appendChild(elm.cloneNode(false));tmp.innerHTML=tmp.innerHTML.replace(new RegExp('style=""|class=""','gi'),'');if(new RegExp('','gi').test(tmp.innerHTML)){for(var x=0;x0){value=tinyMCE.replaceVar(value,"selection",selectedText);tinyMCE.execCommand('mceInsertContent',false,value)}tinyMCE.triggerNodeChange();break;case"mceSetAttribute":if(typeof(value)=='object'){var targetElms=(typeof(value['targets'])=="undefined")?"p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address":value['targets'];var targetNode=tinyMCE.getParentElement(this.getFocusElement(),targetElms);if(targetNode){targetNode.setAttribute(value['name'],value['value']);tinyMCE.triggerNodeChange()}}break;case"mceSetCSSClass":this.execCommand("mceSetStyleInfo",false,{command:"setattrib",name:"class",value:value});break;case"mceInsertRawHTML":var key='tiny_mce_marker';this.execCommand('mceBeginUndoLevel');this.execCommand('mceInsertContent',false,key);var scrollX=this.getBody().scrollLeft+this.getDoc().documentElement.scrollLeft;var scrollY=this.getBody().scrollTop+this.getDoc().documentElement.scrollTop;var html=this.getBody().innerHTML;if((pos=html.indexOf(key))!=-1)tinyMCE.setInnerHTML(this.getBody(),html.substring(0,pos)+value+html.substring(pos+key.length));this.contentWindow.scrollTo(scrollX,scrollY);this.execCommand('mceEndUndoLevel');break;case"mceInsertContent":if(!value)value='';var insertHTMLFailed=false;if(tinyMCE.isGecko||tinyMCE.isOpera){try{if(value.indexOf('<')==-1&&!value.match(/(&| |<|>)/g)){var r=this.getRng();var n=this.getDoc().createTextNode(tinyMCE.entityDecode(value));var s=this.getSel();var r2=r.cloneRange();s.removeAllRanges();r.deleteContents();r.insertNode(n);r2.selectNode(n);r2.collapse(false);s.removeAllRanges();s.addRange(r2)}else{value=tinyMCE.fixGeckoBaseHREFBug(1,this.getDoc(),value);this.getDoc().execCommand('inserthtml',false,value);tinyMCE.fixGeckoBaseHREFBug(2,this.getDoc(),value)}}catch(ex){insertHTMLFailed=true}if(!insertHTMLFailed){tinyMCE.triggerNodeChange();return}}if(!tinyMCE.isIE){var isHTML=value.indexOf('<')!=-1;var sel=this.getSel();var rng=this.getRng();if(isHTML){if(tinyMCE.isSafari){var tmpRng=this.getDoc().createRange();tmpRng.setStart(this.getBody(),0);tmpRng.setEnd(this.getBody(),0);value=tmpRng.createContextualFragment(value)}else value=rng.createContextualFragment(value)}else{var el=document.createElement("div");el.innerHTML=value;value=el.firstChild.nodeValue;value=doc.createTextNode(value)}if(tinyMCE.isSafari&&!isHTML){this.execCommand('InsertText',false,value.nodeValue);tinyMCE.triggerNodeChange();return true}else if(tinyMCE.isSafari&&isHTML){rng.deleteContents();rng.insertNode(value);tinyMCE.triggerNodeChange();return true}rng.deleteContents();if(rng.startContainer.nodeType==3){var node=rng.startContainer.splitText(rng.startOffset);node.parentNode.insertBefore(value,node)}else rng.insertNode(value);if(!isHTML){sel.selectAllChildren(doc.body);sel.removeAllRanges();var rng=doc.createRange();rng.selectNode(value);rng.collapse(false);sel.addRange(rng)}else rng.collapse(false);tinyMCE.fixGeckoBaseHREFBug(2,this.getDoc(),value)}else{var rng=doc.selection.createRange(),tmpRng=null;var c=value.indexOf('"}if(hc){cn=n.childNodes;for(i=0,l=cn.length;i';return h},_serializeAttribute:function(n,r,an){var av='',t,os=this.settings.on_save;if(os&&(an.indexOf('mce_')==0||an.indexOf('_moz')==0))return'';if(os&&this.mceAttribs[an])av=this._getAttrib(n,this.mceAttribs[an]);if(av.length==0)av=this._getAttrib(n,an);if(av.length==0&&r.defaultAttribs&&(t=r.defaultAttribs[an])){av=t;if(av=="mce_empty")return" "+an+'=""'}if(r.forceAttribs&&(t=r.forceAttribs[an]))av=t;if(os&&av.length!=0&&/^(src|href|longdesc)$/.test(an))av=this._urlConverter(this,n,av);if(av.length!=0&&r.validAttribValues&&r.validAttribValues[an]&&!r.validAttribValues[an].test(av))return"";if(av.length!=0&&av=="{$uid}")av="uid_"+(this.idCount++);if(av.length!=0){if(an.indexOf('on')!=0)av=this.xmlEncode(av,1);return" "+an+"="+'"'+av+'"'}return""},formatHTML:function(h){var s=this.settings,p='',i=0,li=0,o='',l;h=h.replace(/]*)>(.*?)<\/pre>/gi,function(a,b,c){c=c.replace(//gi,'\n');return''+c+''});h=h.replace(/\r/g,'');h='\n'+h;h=h.replace(new RegExp('\\n\\s+','gi'),'\n');h=h.replace(this.nlBeforeRe,'\n<$1$2>');h=h.replace(this.nlAfterRe,'<$1$2>\n');h=h.replace(this.nlBeforeAfterRe,'\n<$1$2$3>\n');h+='\n';while((i=h.indexOf('\n',i+1))!=-1){if((l=h.substring(li+1,i)).length!=0){if(this.ouRe.test(l)&&p.length>=s.indent_levels)p=p.substring(s.indent_levels);o+=p+l+'\n';if(this.inRe.test(l))p+=this.inStr}li=i}return o},xmlEncode:function(s,skip_apos){var cl=this,re=!skip_apos?this.xmlEncodeAposRe:this.xmlEncodeRe;this._setupEntities();switch(this.settings.entity_encoding){case"raw":return tinyMCE.xmlEncode(s,skip_apos);case"named":return s.replace(re,function(c,b){b=cl.entities[c.charCodeAt(0)];return b?'&'+b+';':c});case"numeric":return s.replace(re,function(c,b){return b?'&#'+c.charCodeAt(0)+';':c})}return s},split:function(re,s){var c=s.split(re);var i,l,o=new Array();for(i=0,l=c.length;i':'>'+h+'';return o};TinyMCE_Engine.prototype.createTag=function(d,tn,a,h){var o=d.createElement(tn);if(a){for(n in a){if(typeof(a[n])!='function'&&a[n]!=null)tinyMCE.setAttrib(o,n,a[n])}}if(h)o.innerHTML=h;return o};TinyMCE_Engine.prototype.getElementByAttributeValue=function(n,e,a,v){return(n=this.getElementsByAttributeValue(n,e,a,v)).length==0?null:n[0]};TinyMCE_Engine.prototype.getElementsByAttributeValue=function(n,e,a,v){var i,nl=n.getElementsByTagName(e),o=new Array();for(i=0;i]*)>/gi,'');h=h.replace(/]*)>/gi,'');h=h.replace(/]*)>/gi,'');h=h.replace(/]*)>/gi,'');h=h.replace(/<\/strong>/gi,'');h=h.replace(/<\/em>/gi,'')}if(tinyMCE.isRealIE){h=h.replace(/\s\/>/g,'>');h=h.replace(/]*)>\u00A0?<\/p>/gi,' 

');h=h.replace(/]*)>\s* \s*<\/p>/gi,' 

');h=h.replace(/]*)>\s+<\/p>/gi,' 

');e.innerHTML=tinyMCE.uniqueTag+h;e.firstChild.removeNode(true);nl=e.getElementsByTagName("p");for(i=nl.length-1;i>=0;i--){n=nl[i];if(n.nodeName=='P'&&!n.hasChildNodes()&&!n.mce_keep)n.parentNode.removeChild(n)}}else{h=this.fixGeckoBaseHREFBug(1,e,h);e.innerHTML=h;this.fixGeckoBaseHREFBug(2,e,h)}};TinyMCE_Engine.prototype.getOuterHTML=function(e){if(tinyMCE.isIE)return e.outerHTML;var d=e.ownerDocument.createElement("body");d.appendChild(e.cloneNode(true));return d.innerHTML};TinyMCE_Engine.prototype.setOuterHTML=function(e,h,d){var d=typeof(d)=="undefined"?e.ownerDocument:d,i,nl,t;if(tinyMCE.isIE&&e.nodeType==1)e.outerHTML=h;else{t=d.createElement("body");t.innerHTML=h;for(i=0,nl=t.childNodes;i-1;i--){if(ar[i].specified&&ar[i].nodeValue)ne.setAttribute(ar[i].nodeName.toLowerCase(),ar[i].nodeValue)}ar=e.childNodes;for(i=0;i=strTok2.length){for(var i=0;i=strTok2.length||strTok1[i]!=strTok2[i]){breakPoint=i+1;break}}}if(strTok1.length=strTok1.length||strTok1[i]!=strTok2[i]){breakPoint=i+1;break}}}if(breakPoint==1)return targetURL.path;for(var i=0;i<(strTok1.length-(breakPoint-1));i++)outPath+="../";for(var i=breakPoint-1;i=0;i--){if(baseURLParts[i].length==0)continue;newBaseURLParts[newBaseURLParts.length]=baseURLParts[i]}baseURLParts=newBaseURLParts.reverse();var newRelURLParts=new Array();var numBack=0;for(var i=relURLParts.length-1;i>=0;i--){if(relURLParts[i].length==0||relURLParts[i]==".")continue;if(relURLParts[i]=='..'){numBack++;continue}if(numBack>0){numBack--;continue}newRelURLParts[newRelURLParts.length]=relURLParts[i]}relURLParts=newRelURLParts.reverse();var len=baseURLParts.length-numBack;var absPath=(len<=0?"":"/")+baseURLParts.slice(0,len).join('/')+"/"+relURLParts.join('/');var start="",end="";relURL.protocol=baseURL.protocol;relURL.host=baseURL.host;relURL.port=baseURL.port;if(relURL.path.charAt(relURL.path.length-1)=="/")absPath+="/";relURL.path=absPath;return this.serializeURL(relURL)};TinyMCE_Engine.prototype.convertURL=function(url,node,on_save){var prot=document.location.protocol;var host=document.location.hostname;var port=document.location.port;if(prot=="file:")return url;url=tinyMCE.regexpReplace(url,'(http|https):///','/');if(url.indexOf('mailto:')!=-1||url.indexOf('javascript:')!=-1||tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0)=="#")return url;if(!tinyMCE.isIE&&!on_save&&url.indexOf("://")==-1&&url.charAt(0)!='/')return tinyMCE.settings['base_href']+url;if(on_save&&tinyMCE.getParam('relative_urls')){var curl=tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'],url);if(curl.charAt(0)=='/')curl=tinyMCE.settings['document_base_prefix']+curl;var urlParts=tinyMCE.parseURL(curl);var tmpUrlParts=tinyMCE.parseURL(tinyMCE.settings['document_base_url']);if(urlParts['host']==tmpUrlParts['host']&&(urlParts['port']==tmpUrlParts['port']))return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'],curl)}if(!tinyMCE.getParam('relative_urls')){var urlParts=tinyMCE.parseURL(url);var baseUrlParts=tinyMCE.parseURL(tinyMCE.settings['base_href']);url=tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'],url);if(urlParts['anchor']&&urlParts['path']==baseUrlParts['path'])return"#"+urlParts['anchor']}if(tinyMCE.getParam('remove_script_host')){var start="",portPart="";if(port!="")portPart=":"+port;start=prot+"//"+host+portPart+"/";if(url.indexOf(start)==0)url=url.substring(start.length-1)}return url};TinyMCE_Engine.prototype.convertAllRelativeURLs=function(body){var i,elms,src,href,mhref,msrc;elms=body.getElementsByTagName("img");for(i=0;ibookmark.index){try{rng.addElement(nl[bookmark.index])}catch(ex){}}}else{try{if(bookmark.start<0)return true;rng=inst.getSel().createRange();rng.moveToElementText(inst.getBody());rng.collapse(true);rng.moveStart('character',bookmark.start);rng.moveEnd('character',bookmark.length)}catch(ex){return true}}rng.select();win.scrollTo(bookmark.scrollX,bookmark.scrollY);return true}if(tinyMCE.isGecko||tinyMCE.isOpera){if(!sel)return false;if(bookmark.rng){sel.removeAllRanges();sel.addRange(bookmark.rng)}if(bookmark.start!=-1&&bookmark.end!=-1){try{sd=this._getTextPos(b,bookmark.start,bookmark.end);rng=doc.createRange();rng.setStart(sd.startNode,sd.startOffset);rng.setEnd(sd.endNode,sd.endOffset);sel.removeAllRanges();sel.addRange(rng);win.focus()}catch(ex){}}win.scrollTo(bookmark.scrollX,bookmark.scrollY);return true}return false},_getPosText:function(r,sn,en){var w=document.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+=n.nodeValue?n.nodeValue.length:0}return null},_getTextPos:function(r,sp,ep){var w=document.createTreeWalker(r,NodeFilter.SHOW_TEXT,null,false),n,p=0,d={};while((n=w.nextNode())!=null){p+=n.nodeValue?n.nodeValue.length:0;if(p>=sp&&!d.startNode){d.startNode=n;d.startOffset=sp-(p-n.nodeValue.length)}if(p>=ep){d.endNode=n;d.endOffset=ep-(p-n.nodeValue.length);return d}}return null},selectNode:function(node,collapse,select_text_node,to_start){var inst=this.instance,sel,rng,nodes;if(!node)return;if(typeof(collapse)=="undefined")collapse=true;if(typeof(select_text_node)=="undefined")select_text_node=false;if(typeof(to_start)=="undefined")to_start=true;if(inst.settings.auto_resize)inst.resizeToContent();if(tinyMCE.isRealIE){rng=inst.getDoc().body.createTextRange();try{rng.moveToElementText(node);if(collapse)rng.collapse(to_start);rng.select()}catch(e){}}else{sel=this.getSel();if(!sel)return;if(tinyMCE.isSafari){sel.setBaseAndExtent(node,0,node,node.innerText.length);if(collapse){if(to_start)sel.collapseToStart();else sel.collapseToEnd()}this.scrollToNode(node);return}rng=inst.getDoc().createRange();if(select_text_node){nodes=tinyMCE.getNodeTree(node,new Array(),3);if(nodes.length>0)rng.selectNodeContents(nodes[0]);else rng.selectNodeContents(node)}else rng.selectNode(node);if(collapse){if(!to_start&&node.nodeType==3){rng.setStart(node,node.nodeValue.length);rng.setEnd(node,node.nodeValue.length)}else rng.collapse(to_start)}sel.removeAllRanges();sel.addRange(rng)}this.scrollToNode(node);tinyMCE.selectedElement=null;if(node.nodeType==1)tinyMCE.selectedElement=node},scrollToNode:function(node){var inst=this.instance,w=inst.getWin(),vp=inst.getViewPort(),pos=tinyMCE.getAbsPosition(node),cvp,p,cwin;if(pos.absLeftvp.left+vp.width||pos.absTopvp.top+(vp.height-25))w.scrollTo(pos.absLeft,pos.absTop-vp.height+25);if(inst.settings.auto_resize){cwin=inst.getContainerWin();cvp=tinyMCE.getViewPort(cwin);p=this.getAbsPosition(node);if(p.absLeftcvp.left+cvp.width||p.absTopcvp.top+cvp.height)cwin.scrollTo(p.absLeft,p.absTop-cvp.height+25)}},getAbsPosition:function(n){var pos=tinyMCE.getAbsPosition(n),ipos=tinyMCE.getAbsPosition(this.instance.iframeElement);return{absLeft:ipos.absLeft+pos.absLeft,absTop:ipos.absTop+pos.absTop}},getSel:function(){var inst=this.instance;if(tinyMCE.isRealIE)return inst.getDoc().selection;return inst.contentWindow.getSelection()},getRng:function(){var s=this.getSel();if(s==null)return null;if(tinyMCE.isRealIE)return s.createRange();if(tinyMCE.isSafari&&!s.getRangeAt)return''+window.getSelection();if(s.rangeCount>0)return s.getRangeAt(0);return null},isCollapsed:function(){var r=this.getRng();if(r.item)return false;return r.boundingWidth==0||this.getSel().isCollapsed},collapse:function(b){var r=this.getRng(),s=this.getSel();if(r.select){r.collapse(b);r.select()}else{if(b)s.collapseToStart();else s.collapseToEnd()}},getFocusElement:function(){var inst=this.instance,doc,rng,sel,elm;if(tinyMCE.isRealIE){doc=inst.getDoc();rng=doc.selection.createRange();elm=rng.item?rng.item(0):rng.parentElement()}else{if(!tinyMCE.isSafari&&inst.isHidden())return inst.getBody();sel=this.getSel();rng=this.getRng();if(!sel||!rng)return null;elm=rng.commonAncestorContainer;if(!rng.collapsed){if(rng.startContainer==rng.endContainer){if(rng.startOffset-rng.endOffset<2){if(rng.startContainer.hasChildNodes())elm=rng.startContainer.childNodes[rng.startOffset]}}}elm=tinyMCE.getParentElement(elm);}return elm}};function TinyMCE_UndoRedo(inst){this.instance=inst;this.undoLevels=new Array();this.undoIndex=0;this.typingUndoIndex=-1;this.undoRedo=true};TinyMCE_UndoRedo.prototype={add:function(l){var b,customUndoLevels,newHTML,inst=this.instance,i,ul,ur;if(l){this.undoLevels[this.undoLevels.length]=l;return true}if(this.typingUndoIndex!=-1){this.undoIndex=this.typingUndoIndex;if(tinyMCE.typingUndoIndex!=-1)tinyMCE.undoIndex=tinyMCE.typingUndoIndex}newHTML=tinyMCE.trim(inst.getBody().innerHTML);if(this.undoLevels[this.undoIndex]&&newHTML!=this.undoLevels[this.undoIndex].content){tinyMCE.dispatchCallback(inst,'onchange_callback','onChange',inst);customUndoLevels=tinyMCE.settings['custom_undo_redo_levels'];if(customUndoLevels!=-1&&this.undoLevels.length>customUndoLevels){for(i=0;i0){this.undoIndex--;tinyMCE.setInnerHTML(inst.getBody(),this.undoLevels[this.undoIndex].content);inst.repaint();if(inst.settings.custom_undo_redo_restore_selection)inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark)}},redo:function(){var inst=this.instance;tinyMCE.execCommand("mceEndTyping");if(this.undoIndex<(this.undoLevels.length-1)){this.undoIndex++;tinyMCE.setInnerHTML(inst.getBody(),this.undoLevels[this.undoIndex].content);inst.repaint();if(inst.settings.custom_undo_redo_restore_selection)inst.selection.moveToBookmark(this.undoLevels[this.undoIndex].bookmark)}tinyMCE.triggerNodeChange()}};var TinyMCE_ForceParagraphs={_insertPara:function(inst,e){var doc=inst.getDoc(),sel=inst.getSel(),body=inst.getBody(),win=inst.contentWindow,rng=sel.getRangeAt(0);var rootElm=doc.documentElement,blockName="P",startNode,endNode,startBlock,endBlock;var rngBefore,rngAfter,direct,startNode,startOffset,endNode,endOffset,b=tinyMCE.isOpera?inst.selection.getBookmark():null;var paraBefore,paraAfter,startChop,endChop,contents;function isEmpty(para){function isEmptyHTML(html){return html.replace(new RegExp('[ \t\r\n]+','g'),'').toLowerCase()==""}if(para.getElementsByTagName("img").length>0)return false;if(para.getElementsByTagName("table").length>0)return false;if(para.getElementsByTagName("hr").length>0)return false;var nodes=tinyMCE.getNodeTree(para,new Array(),3);for(var i=0;i <"+blockName+"> ";paraAfter=body.childNodes[1]}inst.selection.moveToBookmark(b);inst.selection.selectNode(paraAfter,true,true);return true}if(startChop.nodeName==blockName)rngBefore.setStart(startChop,0);else rngBefore.setStartBefore(startChop);rngBefore.setEnd(startNode,startOffset);paraBefore.appendChild(rngBefore.cloneContents());rngAfter.setEndAfter(endChop);rngAfter.setStart(endNode,endOffset);contents=rngAfter.cloneContents();if(contents.firstChild&&contents.firstChild.nodeName==blockName){paraAfter.innerHTML=contents.firstChild.innerHTML}else paraAfter.appendChild(contents);if(isEmpty(paraBefore))paraBefore.innerHTML=" ";if(isEmpty(paraAfter))paraAfter.innerHTML=" ";rng=doc.createRange();if(!startChop.previousSibling&&startChop.parentNode.nodeName.toUpperCase()==blockName){rng.setStartBefore(startChop.parentNode)}else{if(rngBefore.startContainer.nodeName.toUpperCase()==blockName&&rngBefore.startOffset==0)rng.setStartBefore(rngBefore.startContainer);else rng.setStart(rngBefore.startContainer,rngBefore.startOffset)}if(!endChop.nextSibling&&endChop.parentNode.nodeName.toUpperCase()==blockName)rng.setEndAfter(endChop.parentNode);else rng.setEnd(rngAfter.endContainer,rngAfter.endOffset);rng.deleteContents();if(tinyMCE.isOpera){rng.insertNode(paraBefore);rng.insertNode(paraAfter)}else{rng.insertNode(paraAfter);rng.insertNode(paraBefore)}paraAfter.normalize();paraBefore.normalize();inst.selection.moveToBookmark(b);inst.selection.selectNode(paraAfter,true,true);return true},_handleBackSpace:function(inst){var r=inst.getRng(),sn=r.startContainer,nv,s=false;if(sn&&sn.nextSibling&&sn.nextSibling.nodeName=="BR"&&sn.parentNode.nodeName!="BODY"){nv=sn.nodeValue;if(nv!=null&&r.startOffset==nv.length)sn.nextSibling.parentNode.removeChild(sn.nextSibling)}if(inst.settings.auto_resize)inst.resizeToContent();return s}};function TinyMCE_Layer(id,bm){this.id=id;this.blockerElement=null;this.events=false;this.element=null;this.blockMode=typeof(bm)!='undefined'?bm:true;this.doc=document};TinyMCE_Layer.prototype={moveRelativeTo:function(re,p){var rep=this.getAbsPosition(re);var w=parseInt(re.offsetWidth);var h=parseInt(re.offsetHeight);var e=this.getElement();var ew=parseInt(e.offsetWidth);var eh=parseInt(e.offsetHeight);var x,y;switch(p){case"tl":x=rep.absLeft;y=rep.absTop;break;case"tr":x=rep.absLeft+w;y=rep.absTop;break;case"bl":x=rep.absLeft;y=rep.absTop+h;break;case"br":x=rep.absLeft+w;y=rep.absTop+h;break;case"cc":x=rep.absLeft+(w/ 2) - (ew /2);y=rep.absTop+(h/ 2) - (eh /2);break}this.moveTo(x,y)},moveBy:function(x,y){var e=this.getElement();this.moveTo(parseInt(e.style.left)+x,parseInt(e.style.top)+y)},moveTo:function(x,y){var e=this.getElement();e.style.left=x+"px";e.style.top=y+"px";this.updateBlocker()},resizeBy:function(w,h){var e=this.getElement();this.resizeTo(parseInt(e.style.width)+w,parseInt(e.style.height)+h)},resizeTo:function(w,h){var e=this.getElement();if(w!=null)e.style.width=w+"px";if(h!=null)e.style.height=h+"px";this.updateBlocker()},show:function(){var el=this.getElement();if(el){el.style.display='block';this.updateBlocker()}},hide:function(){var el=this.getElement();if(el){el.style.display='none';this.updateBlocker()}},isVisible:function(){return this.getElement().style.display=='block'},getElement:function(){if(!this.element)this.element=this.doc.getElementById(this.id);return this.element},setBlockMode:function(s){this.blockMode=s},updateBlocker:function(){var e,b,x,y,w,h;b=this.getBlocker();if(b){if(this.blockMode){e=this.getElement();x=this.parseInt(e.style.left);y=this.parseInt(e.style.top);w=this.parseInt(e.offsetWidth);h=this.parseInt(e.offsetHeight);b.style.left=x+'px';b.style.top=y+'px';b.style.width=w+'px';b.style.height=h+'px';b.style.display=e.style.display}else b.style.display='none'}},getBlocker:function(){var d,b;if(!this.blockerElement&&this.blockMode){d=this.doc;b=d.getElementById(this.id+"_blocker");if(!b){b=d.createElement("iframe");b.setAttribute('id',this.id+"_blocker");b.style.cssText='display: none; position: absolute; left: 0; top: 0';b.src='javascript:false;';b.frameBorder='0';b.scrolling='no';d.body.appendChild(b)}this.blockerElement=b}return this.blockerElement},getAbsPosition:function(n){var p={absLeft:0,absTop:0};while(n){p.absLeft+=n.offsetLeft;p.absTop+=n.offsetTop;n=n.offsetParent}return p},create:function(n,c,p,h){var d=this.doc,e=d.createElement(n);e.setAttribute('id',this.id);if(c)e.className=c;if(!p)p=d.body;if(h)e.innerHTML=h;p.appendChild(e);return this.element=e},exists:function(){return this.doc.getElementById(this.id)!=null},parseInt:function(s){if(s==null||s=='')return 0;return parseInt(s)},remove:function(){var e=this.getElement(),b=this.getBlocker();if(e)e.parentNode.removeChild(e);if(b)b.parentNode.removeChild(b)}};function TinyMCE_Menu(){var id;if(typeof(tinyMCE.menuCounter)=="undefined")tinyMCE.menuCounter=0;id="mc_menu_"+tinyMCE.menuCounter++;TinyMCE_Layer.call(this,id,true);this.id=id;this.items=new Array();this.needsUpdate=true};TinyMCE_Menu.prototype=tinyMCE.extend(TinyMCE_Layer.prototype,{init:function(s){var n;this.settings={separator_class:'mceMenuSeparator',title_class:'mceMenuTitle',disabled_class:'mceMenuDisabled',menu_class:'mceMenu',drop_menu:true};for(n in s)this.settings[n]=s[n];this.create('div',this.settings.menu_class)},clear:function(){this.items=new Array()},addTitle:function(t){this.add({type:'title',text:t})},addDisabled:function(t){this.add({type:'disabled',text:t})},addSeparator:function(){this.add({type:'separator'})},addItem:function(t,js){this.add({text:t,js:js})},add:function(mi){this.items[this.items.length]=mi;this.needsUpdate=true},update:function(){var e=this.getElement(),h='',i,t,m=this.items,s=this.settings;if(this.settings.drop_menu)h+='';h+='';for(i=0;i'}h+='
';break;case'title':h+='
'+t+'';break;case'disabled':h+='
'+t+'';break;default:h+='
'+t+''}h+='
';e.innerHTML=h;this.needsUpdate=false;this.updateBlocker()},show:function(){var nl,i;if(tinyMCE.lastMenu==this)return;if(this.needsUpdate)this.update();if(tinyMCE.lastMenu&&tinyMCE.lastMenu!=this)tinyMCE.lastMenu.hide();TinyMCE_Layer.prototype.show.call(this);if(!tinyMCE.isOpera){}tinyMCE.lastMenu=this}});if(!Function.prototype.call){Function.prototype.call=function(){var a=arguments,s=a[0],i,as='',r,o;for(i=1;i1?',':'')+'a['+i+']';o=s._fu;s._fu=this;r=eval('s._fu('+as+')');s._fu=o;return r}};TinyMCE_Engine.prototype.debug=function(){var m="",a,i,l=tinyMCE.log.length;for(i=0,a=this.debug.arguments;i=items.length){for(i=0;i=items.length||base[i]!=items[i]){bp=i+1;break;}}}if(base.length=base.length||base[i]!=items[i]){bp=i+1;break;}}}if(bp==1)return path;for(i=0;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='[';i0?',':'')+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);t=w.setInterval(function(){if(x.readyState==4||c++>10000){w.clearInterval(t);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;}},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});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.files={};t.cssFlicker=false;t.counter=0;t.boxModel=!tinymce.isIE||d.compatMode=="CSS1Compat";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(function(){t.doc=t.root=null;});},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?window: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==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){if(typeof(e)=='string')return this.doc.getElementById(e);return e;},select:function(pa,s){var t=this,cs,c,pl,o=[],x,i,l,n;s=t.get(s)||t.doc;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=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+'';return o+' />';},remove:function(n,k){return this.run(n,function(n){var p;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['-moz-opacity']=s['-khtml-opacity']=v;break;case'float':isIE?s.styleFloat=v:s.cssFloat=v;break;}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)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;}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)return false;if(!is(dv))dv="";if(/^(src|href|style|coords)$/.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: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)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'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+=window.self!=window.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){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];};each(st.split(';'),function(v){var sv,ur=[];if(v){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('+t.encode(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){switch(k){case'color':case'background-color':v=v.toLowerCase();break;}s+=(s?' ':'')+k+': '+v+';';}});return s;},loadCSS:function(u){var t=this,d=this.doc;if(!u)u='';each(u.split(','),function(u){if(t.files[u])return;t.files[u]=true;if(!d.createStyleSheet)t.add(t.select('head')[0],'link',{rel:'stylesheet',href:u});else d.createStyleSheet(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;h=t.processHTML(h);if(isIE){try{e.innerHTML='
'+h;e.removeChild(e.firstChild);}catch(ex){x=t.create('div');x.innerHTML='
'+h;each(x.childNodes,function(n,i){if(i>1)e.appendChild(n);});}}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>|]+)>/gi,'<$1b$2>');h=h.replace(/<(\/?)em>|]+)>/gi,'<$1i$2>');}h=h.replace(/]+)\/>|/gi,'');if(s.keep_values){if(h.indexOf('/g,''); }, pickColor : function(e, element_id) { - tinyMCE.selectedInstance.execCommand('mceColorPicker', true, { - element_id : element_id, - document : document, - window : window, - store_selection : false + this.execCommand('mceColorPicker', true, { + color : document.getElementById(element_id).value, + func : function(c) { + document.getElementById(element_id).value = c; + + try { + document.getElementById(element_id).onchange(); + } catch (ex) { + // Try fire event, ignore errors + } + } }); }, openBrowser : function(element_id, type, option) { - var cb = tinyMCE.getParam(option, tinyMCE.getParam("file_browser_callback")); - var url = document.getElementById(element_id).value; + tinyMCEPopup.restoreSelection(); + this.editor.execCallback('file_browser_callback', element_id, document.getElementById(element_id).value, type, window); + }, - tinyMCE.setWindowArg("window", window); - tinyMCE.setWindowArg("document", document); + close : function() { + var t = this; - // Call to external callback - if (eval('typeof(tinyMCEPopup.windowOpener.' + cb + ')') == "undefined") - alert("Callback function: " + cb + " could not be found."); - else - eval("tinyMCEPopup.windowOpener." + cb + "(element_id, url, type, window);"); + t.dom = t.dom.doc = null; // Cleanup + t.editor.windowManager.close(window, t.id); + }, + + // Internal functions + + _restoreSelection : function() { + var e = window.event.srcElement; + + if (e.nodeName == 'INPUT' && (e.type == 'submit' || e.type == 'button')) + tinyMCEPopup.restoreSelection(); }, - importClass : function(c) { - window[c] = function() {}; +/* _restoreSelection : function() { + var e = window.event.srcElement; + + // If user focus a non text input or textarea + if ((e.nodeName != 'INPUT' && e.nodeName != 'TEXTAREA') || e.type != 'text') + tinyMCEPopup.restoreSelection(); + },*/ + + _onDOMLoaded : function() { + var t = this, ti = document.title, bm, h; + + // Translate page + h = document.body.innerHTML; + + // Replace a=x with a="x" in IE + if (tinymce.isIE) + h = h.replace(/ (value|title|alt)=([^\s>]+)/gi, ' $1="$2"'); + + document.body.innerHTML = t.editor.translate(h); + document.title = ti = t.editor.translate(ti); + document.body.style.display = ''; - for (var n in window.opener[c].prototype) - window[c].prototype[n] = window.opener[c].prototype[n]; + // Restore selection in IE when focus is placed on a non textarea or input element of the type text + if (tinymce.isIE) + document.attachEvent('onmouseup', tinyMCEPopup._restoreSelection); + + t.restoreSelection(); + + // Call onInit + tinymce.each(t.listeners, function(o) { + o.func.call(o.scope, t.editor); + }); + + t.resizeToInnerSize(); + + if (t.isWindow) + window.focus(); + else + t.editor.windowManager.setTitle(ti, t.id); + + if (!tinymce.isIE && !t.isWindow) { + tinymce.dom.Event._add(document, 'focus', function() { + t.editor.windowManager.focus(t.id) + }); + } - window[c].constructor = window.opener[c].constructor; - } + // Patch for accessibility + tinymce.each(t.dom.select('select'), function(e) { + e.onkeydown = tinyMCEPopup._accessHandler; + }); + + // Move focus to window + window.focus(); + }, + + _accessHandler : function(e) { + var e = e || window.event; + + if (e.keyCode == 13 || e.keyCode == 32) { + e = e.target || e.srcElement; + + if (e.onchange) + e.onchange(); + + return tinymce.dom.Event.cancel(e); + } + }, + + _wait : function() { + var t = this, ti; - }; - -// Setup global instance -var tinyMCEPopup = new TinyMCE_Popup(); + if (tinymce.isIE && document.location.protocol != 'https:') { + // Fake DOMContentLoaded on IE + document.write(''); - } - - this.loadedFiles[this.loadedFiles.length] = url; - }, - - loadNextScript : function() { - var d = document, se; - - if (!tinyMCE.settings.strict_loading_mode) - return; - - if (this.loadingIndex < this.pendingFiles.length) { - try { - /* - se = d.createElementNS('http://www.w3.org/1999/xhtml', 'script'); - se.setAttribute('language', 'javascript'); - se.setAttribute('type', 'text/javascript'); - se.setAttribute('src', this.pendingFiles[this.loadingIndex++]); - */ - - se = d.createElement('script'); - se.language = 'javascript'; - se.type = 'text/javascript'; - se.src = this.pendingFiles[this.loadingIndex++]; - - d.getElementsByTagName("head")[0].appendChild(se); - } catch(e) { - var error = e.toString(); - alert(error); - } - } else - this.loadingIndex = -1; // Done with loading - }, - - loadCSS : function(url) { - var ar = url.replace(/\s+/, '').split(','); - var lflen = 0, csslen = 0; - var skip = false; - var x = 0, i = 0, nl, le; - - for (x = 0,csslen = ar.length; x 0) { - /* Make sure it doesn't exist. */ - for (i=0, lflen=this.loadedFiles.length; i'); - } - - this.loadedFiles[this.loadedFiles.length] = ar[x]; + // Hashtables + for (n in o) { + if (o.hasOwnProperty(n)) { + if (cb.call(s, o[n], n, o) === false) + return 0; } } } - }, - - importCSS : function(doc, css) { - var css_ary = css.replace(/\s+/, '').split(','); - var csslen, elm, headArr, x, css_file; - - for (x = 0, csslen = css_ary.length; x 0) { - // Is relative, make absolute - if (css_file.indexOf('://') == -1 && css_file.charAt(0) != '/') - css_file = this.documentBasePath + "/" + css_file; - - if (typeof(doc.createStyleSheet) == "undefined") { - elm = doc.createElement("link"); - - elm.rel = "stylesheet"; - elm.href = css_file; - - if ((headArr = doc.getElementsByTagName("head")) != null && headArr.length > 0) - headArr[0].appendChild(elm); - } else - doc.createStyleSheet(css_file); - } - } - }, - - confirmAdd : function(e, settings) { - var elm = tinyMCE.isIE ? event.srcElement : e.target; - var elementId = elm.name ? elm.name : elm.id; - - tinyMCE.settings = settings; - - if (tinyMCE.settings['convert_on_click'] || (!elm.getAttribute('mce_noask') && confirm(tinyMCELang['lang_edit_confirm']))) - tinyMCE.addMCEControl(elm, elementId); - - elm.setAttribute('mce_noask', 'true'); - }, - - updateContent : function(form_element_name) { - // Find MCE instance linked to given form element and copy it's value - var formElement = document.getElementById(form_element_name); - for (var n in tinyMCE.instances) { - var inst = tinyMCE.instances[n]; - if (!tinyMCE.isInstance(inst)) - continue; - - inst.switchSettings(); - - if (inst.formElement == formElement) { - var doc = inst.getDoc(); - - tinyMCE._setHTML(doc, inst.formElement.value); - - if (!tinyMCE.isIE) - doc.body.innerHTML = tinyMCE._cleanupHTML(inst, doc, this.settings, doc.body, inst.visualAid); - } - } - }, - - addMCEControl : function(replace_element, form_element_name, target_document) { - var id = "mce_editor_" + tinyMCE.idCounter++; - - var inst = new TinyMCE_Control(tinyMCE.settings); - - inst.editorId = id; - this.instances[id] = inst; - - inst._onAdd(replace_element, form_element_name, target_document); - }, - - removeInstance : function(ti) { - var t = [], n, i; - - // Remove from instances - for (n in tinyMCE.instances) { - i = tinyMCE.instances[n]; - - if (tinyMCE.isInstance(i) && ti != i) - t[n] = i; - } - - tinyMCE.instances = t; - - // Remove from global undo/redo - n = []; - t = tinyMCE.undoLevels; - - for (i=0; i 0) { - tinyMCE.nextUndoRedoAction = 'Undo'; - inst = this.undoLevels[--this.undoIndex]; - inst.select(); - - if (!tinyMCE.nextUndoRedoInstanceId) - inst.execCommand('Undo'); - } - } else - inst.execCommand('Undo'); - return true; - - case "Redo": - if (this.getParam('custom_undo_redo_global')) { - if (this.undoIndex <= this.undoLevels.length - 1) { - tinyMCE.nextUndoRedoAction = 'Redo'; - inst = this.undoLevels[this.undoIndex++]; - inst.select(); - - if (!tinyMCE.nextUndoRedoInstanceId) - inst.execCommand('Redo'); - } - } else - inst.execCommand('Redo'); - - return true; - - case 'mceFocus': - var inst = tinyMCE.getInstanceById(value); - if (inst) - inst.getWin().focus(); - return; - - case "mceAddControl": - case "mceAddEditor": - tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); - return; - - case "mceAddFrameControl": - tinyMCE.addMCEControl(tinyMCE._getElementById(value['element'], value['document']), value['element'], value['document']); - return; - - case "mceRemoveControl": - case "mceRemoveEditor": - tinyMCE.removeMCEControl(value); - return; - - case "mceToggleEditor": - var inst = tinyMCE.getInstanceById(value), pe, te; - - if (inst) { - pe = document.getElementById(inst.editorId + '_parent'); - te = inst.oldTargetElement; - - if (typeof(inst.enabled) == 'undefined') - inst.enabled = true; - - inst.enabled = !inst.enabled; - - if (!inst.enabled) { - pe.style.display = 'none'; - te.value = inst.getHTML(); - te.style.display = inst.oldTargetDisplay; - tinyMCE.dispatchCallback(inst, 'hide_instance_callback', 'hideInstance', inst); - } else { - pe.style.display = 'block'; - te.style.display = 'none'; - inst.setHTML(te.value); - inst.useCSS = false; - tinyMCE.dispatchCallback(inst, 'show_instance_callback', 'showInstance', inst); - } - } else - tinyMCE.addMCEControl(tinyMCE._getElementById(value), value); - - return; - - case "mceResetDesignMode": - // Resets the designmode state of the editors in Gecko - if (!tinyMCE.isIE) { - for (var n in tinyMCE.instances) { - if (!tinyMCE.isInstance(tinyMCE.instances[n])) - continue; - - try { - tinyMCE.instances[n].getDoc().designMode = "on"; - } catch (e) { - // Ignore any errors - } - } - } - - return; - } - - if (inst) { - inst.execCommand(command, user_interface, value); - } else if (tinyMCE.settings['focus_alert']) - alert(tinyMCELang['lang_focus_alert']); - }, - - _createIFrame : function(replace_element, doc, win) { - var iframe, id = replace_element.getAttribute("id"); - var aw, ah; - - if (typeof(doc) == "undefined") - doc = document; - - if (typeof(win) == "undefined") - win = window; - - iframe = doc.createElement("iframe"); - - aw = "" + tinyMCE.settings['area_width']; - ah = "" + tinyMCE.settings['area_height']; - - if (aw.indexOf('%') == -1) { - aw = parseInt(aw); - aw = (isNaN(aw) || aw < 0) ? 300 : aw; - aw = aw + "px"; - } - - if (ah.indexOf('%') == -1) { - ah = parseInt(ah); - ah = (isNaN(ah) || ah < 0) ? 240 : ah; - ah = ah + "px"; - } - - iframe.setAttribute("id", id); - iframe.setAttribute("name", id); - iframe.setAttribute("class", "mceEditorIframe"); - iframe.setAttribute("border", "0"); - iframe.setAttribute("frameBorder", "0"); - iframe.setAttribute("marginWidth", "0"); - iframe.setAttribute("marginHeight", "0"); - iframe.setAttribute("leftMargin", "0"); - iframe.setAttribute("topMargin", "0"); - iframe.setAttribute("width", aw); - iframe.setAttribute("height", ah); - iframe.setAttribute("allowtransparency", "true"); - iframe.className = 'mceEditorIframe'; - - if (tinyMCE.settings["auto_resize"]) - iframe.setAttribute("scrolling", "no"); - - // Must have a src element in MSIE HTTPs breaks aswell as absoute URLs - if (tinyMCE.isRealIE) - iframe.setAttribute("src", this.settings['default_document']); - - iframe.style.width = aw; - iframe.style.height = ah; - - // Ugly hack for Gecko problem in strict mode - if (tinyMCE.settings.strict_loading_mode) - iframe.style.marginBottom = '-5px'; - - // MSIE 5.0 issue - if (tinyMCE.isRealIE) - replace_element.outerHTML = iframe.outerHTML; - else - replace_element.parentNode.replaceChild(iframe, replace_element); - - if (tinyMCE.isRealIE) - return win.frames[id]; - else - return iframe; - }, - - setupContent : function(editor_id) { - var inst = tinyMCE.instances[editor_id], i; - var doc = inst.getDoc(); - var head = doc.getElementsByTagName('head').item(0); - var content = inst.startContent; - - // HTML values get XML encoded in strict mode - if (tinyMCE.settings.strict_loading_mode) { - content = content.replace(/</g, '<'); - content = content.replace(/>/g, '>'); - content = content.replace(/"/g, '"'); - content = content.replace(/&/g, '&'); - } - - tinyMCE.selectedInstance = inst; - inst.switchSettings(); - - // Not loaded correctly hit it again, Mozilla bug #997860 - if (!tinyMCE.isIE && tinyMCE.getParam("setupcontent_reload", false) && doc.title != "blank_page") { - // This part will remove the designMode status - // Failes first time in Firefox 1.5b2 on Mac - try {doc.location.href = tinyMCE.baseURL + "/blank.htm";} catch (ex) {} - window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 1000); - return; - } - - if (!head) { - window.setTimeout("tinyMCE.setupContent('" + editor_id + "');", 10); - return; - } - - // Import theme specific content CSS the user specific - tinyMCE.importCSS(inst.getDoc(), tinyMCE.baseURL + "/themes/" + inst.settings['theme'] + "/css/editor_content.css"); - tinyMCE.importCSS(inst.getDoc(), inst.settings['content_css']); - tinyMCE.dispatchCallback(inst, 'init_instance_callback', 'initInstance', inst); - - // Setup keyboard shortcuts - if (tinyMCE.getParam('custom_undo_redo_keyboard_shortcuts')) { - inst.addShortcut('ctrl', 'z', 'lang_undo_desc', 'Undo'); - inst.addShortcut('ctrl', 'y', 'lang_redo_desc', 'Redo'); - } - - // BlockFormat shortcuts keys - for (i=1; i<=6; i++) - inst.addShortcut('ctrl', '' + i, '', 'FormatBlock', false, ''); - - inst.addShortcut('ctrl', '7', '', 'FormatBlock', false, '

'); - inst.addShortcut('ctrl', '8', '', 'FormatBlock', false, '

'); - inst.addShortcut('ctrl', '9', '', 'FormatBlock', false, '
'); - - // Add default shortcuts for gecko - if (tinyMCE.isGecko) { - inst.addShortcut('ctrl', 'b', 'lang_bold_desc', 'Bold'); - inst.addShortcut('ctrl', 'i', 'lang_italic_desc', 'Italic'); - inst.addShortcut('ctrl', 'u', 'lang_underline_desc', 'Underline'); - } - - // Setup span styles - if (tinyMCE.getParam("convert_fonts_to_spans")) - inst.getBody().setAttribute('id', 'mceSpanFonts'); - - if (tinyMCE.settings['nowrap']) - doc.body.style.whiteSpace = "nowrap"; - - doc.body.dir = this.settings['directionality']; - doc.editorId = editor_id; - - // Add on document element in Mozilla - if (!tinyMCE.isIE) - doc.documentElement.editorId = editor_id; - - inst.setBaseHREF(tinyMCE.settings['base_href']); - - // Replace new line characters to BRs - if (tinyMCE.settings['convert_newlines_to_brs']) { - content = tinyMCE.regexpReplace(content, "\r\n", "
", "gi"); - content = tinyMCE.regexpReplace(content, "\r", "
", "gi"); - content = tinyMCE.regexpReplace(content, "\n", "
", "gi"); - } - - // Open closed anchors - // content = content.replace(new RegExp('', 'gi'), ''); - - // Call custom cleanup code - content = tinyMCE.storeAwayURLs(content); - content = tinyMCE._customCleanup(inst, "insert_to_editor", content); - - if (tinyMCE.isIE) { - // Ugly!!! - window.setInterval('try{tinyMCE.getCSSClasses(tinyMCE.instances["' + editor_id + '"].getDoc(), "' + editor_id + '");}catch(e){}', 500); - - if (tinyMCE.settings["force_br_newlines"]) - doc.styleSheets[0].addRule("p", "margin: 0;"); - - var body = inst.getBody(); - body.editorId = editor_id; - } - - content = tinyMCE.cleanupHTMLCode(content); - - // Fix for bug #958637 - if (!tinyMCE.isIE) { - var contentElement = inst.getDoc().createElement("body"); - var doc = inst.getDoc(); - - contentElement.innerHTML = content; - - // Remove weridness! - if (tinyMCE.isGecko && tinyMCE.settings['remove_lt_gt']) - content = content.replace(new RegExp('<>', 'g'), ""); - - if (tinyMCE.settings['cleanup_on_startup']) - tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, doc, this.settings, contentElement)); - else - tinyMCE.setInnerHTML(inst.getBody(), content); - - tinyMCE.convertAllRelativeURLs(inst.getBody()); - } else { - if (tinyMCE.settings['cleanup_on_startup']) { - tinyMCE._setHTML(inst.getDoc(), content); - - // Produces permission denied error in MSIE 5.5 - eval('try {tinyMCE.setInnerHTML(inst.getBody(), tinyMCE._cleanupHTML(inst, inst.contentDocument, this.settings, inst.getBody()));} catch(e) {}'); - } else - tinyMCE._setHTML(inst.getDoc(), content); - } - - // Fix for bug #957681 - //inst.getDoc().designMode = inst.getDoc().designMode; - - tinyMCE.handleVisualAid(inst.getBody(), true, tinyMCE.settings['visual'], inst); - tinyMCE.dispatchCallback(inst, 'setupcontent_callback', 'setupContent', editor_id, inst.getBody(), inst.getDoc()); - - // Re-add design mode on mozilla - if (!tinyMCE.isIE) - tinyMCE.addEventHandlers(inst); - - // Add blur handler - if (tinyMCE.isIE) { - tinyMCE.addEvent(inst.getBody(), "blur", TinyMCE_Engine.prototype._eventPatch); - tinyMCE.addEvent(inst.getBody(), "beforedeactivate", TinyMCE_Engine.prototype._eventPatch); // Bug #1439953 - - // Workaround for drag drop/copy paste base href bug - if (!tinyMCE.isOpera) { - tinyMCE.addEvent(doc.body, "mousemove", TinyMCE_Engine.prototype.onMouseMove); - tinyMCE.addEvent(doc.body, "beforepaste", TinyMCE_Engine.prototype._eventPatch); - tinyMCE.addEvent(doc.body, "drop", TinyMCE_Engine.prototype._eventPatch); - } - } - - // Trigger node change, this call locks buttons for tables and so forth - inst.select(); - tinyMCE.selectedElement = inst.contentWindow.document.body; - - // Call custom DOM cleanup - tinyMCE._customCleanup(inst, "insert_to_editor_dom", inst.getBody()); - tinyMCE._customCleanup(inst, "setup_content_dom", inst.getBody()); - tinyMCE._setEventsEnabled(inst.getBody(), false); - tinyMCE.cleanupAnchors(inst.getDoc()); - - if (tinyMCE.getParam("convert_fonts_to_spans")) - tinyMCE.convertSpansToFonts(inst.getDoc()); - - inst.startContent = tinyMCE.trim(inst.getBody().innerHTML); - inst.undoRedo.add({ content : inst.startContent }); - - // Cleanup any mess left from storyAwayURLs - if (tinyMCE.isGecko) { - // Remove mce_src from textnodes and comments - tinyMCE.selectNodes(inst.getBody(), function(n) { - if (n.nodeType == 3 || n.nodeType == 8) - n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); - - return false; - }); - } - - // Remove Gecko spellchecking - if (tinyMCE.isGecko) - inst.getBody().spellcheck = tinyMCE.getParam("gecko_spellcheck"); - - // Cleanup any mess left from storyAwayURLs - tinyMCE._removeInternal(inst.getBody()); - - inst.select(); - tinyMCE.triggerNodeChange(false, true); - }, - - storeAwayURLs : function(s) { - // Remove all mce_src, mce_href and replace them with new ones - // s = s.replace(new RegExp('mce_src\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); - // s = s.replace(new RegExp('mce_href\\s*=\\s*\"[^ >\"]*\"', 'gi'), ''); - - if (!s.match(/(mce_src|mce_href)/gi, s)) { - s = s.replace(new RegExp('src\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'src="$1" mce_src="$1"'); - s = s.replace(new RegExp('href\\s*=\\s*\"([^ >\"]*)\"', 'gi'), 'href="$1" mce_href="$1"'); - } - - return s; - }, - - _removeInternal : function(n) { - if (tinyMCE.isGecko) { - // Remove mce_src from textnodes and comments - tinyMCE.selectNodes(n, function(n) { - if (n.nodeType == 3 || n.nodeType == 8) - n.nodeValue = n.nodeValue.replace(new RegExp('\\s(mce_src|mce_href)=\"[^\"]*\"', 'gi'), ""); - - return false; - }); - } - }, - - removeTinyMCEFormElements : function(form_obj) { - var i, elementId; - - // Skip form element removal - if (!tinyMCE.getParam('hide_selects_on_submit')) - return; - - // Check if form is valid - if (typeof(form_obj) == "undefined" || form_obj == null) - return; - - // If not a form, find the form - if (form_obj.nodeName != "FORM") { - if (form_obj.form) - form_obj = form_obj.form; - else - form_obj = tinyMCE.getParentElement(form_obj, "form"); - } - - // Still nothing - if (form_obj == null) - return; - - // Disable all UI form elements that TinyMCE created - for (i=0; i"); - rng.collapse(false); - rng.select(); - - tinyMCE.execCommand("mceAddUndoLevel"); - tinyMCE.triggerNodeChange(false); - return false; - } - } - - // Backspace or delete - if (e.keyCode == 8 || e.keyCode == 46) { - tinyMCE.selectedElement = e.target; - tinyMCE.linkElement = tinyMCE.getParentElement(e.target, "a"); - tinyMCE.imgElement = tinyMCE.getParentElement(e.target, "img"); - tinyMCE.triggerNodeChange(false); - } - - return false; - break; - - case "keyup": - case "keydown": - tinyMCE.hideMenus(); - tinyMCE.hasMouseMoved = false; - - if (inst && inst.handleShortcut(e)) - return false; - - if (e.target.editorId) - tinyMCE.instances[e.target.editorId].select(); - - if (tinyMCE.selectedInstance) - tinyMCE.selectedInstance.switchSettings(); - - var inst = tinyMCE.selectedInstance; - - // Handle backspace - if (tinyMCE.isGecko && tinyMCE.settings['force_p_newlines'] && (e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) { - // Insert P element instead of BR - if (TinyMCE_ForceParagraphs._handleBackSpace(tinyMCE.selectedInstance, e.type)) { - // Cancel event - tinyMCE.execCommand("mceAddUndoLevel"); - e.preventDefault(); - return false; - } - } - - tinyMCE.selectedElement = null; - tinyMCE.selectedNode = null; - var elm = tinyMCE.selectedInstance.getFocusElement(); - tinyMCE.linkElement = tinyMCE.getParentElement(elm, "a"); - tinyMCE.imgElement = tinyMCE.getParentElement(elm, "img"); - tinyMCE.selectedElement = elm; - - // Update visualaids on tabs - if (tinyMCE.isGecko && e.type == "keyup" && e.keyCode == 9) - tinyMCE.handleVisualAid(tinyMCE.selectedInstance.getBody(), true, tinyMCE.settings['visual'], tinyMCE.selectedInstance); - - // Fix empty elements on return/enter, check where enter occured - if (tinyMCE.isIE && e.type == "keydown" && e.keyCode == 13) - tinyMCE.enterKeyElement = tinyMCE.selectedInstance.getFocusElement(); - - // Fix empty elements on return/enter - if (tinyMCE.isIE && e.type == "keyup" && e.keyCode == 13) { - var elm = tinyMCE.enterKeyElement; - if (elm) { - var re = new RegExp('^HR|IMG|BR$','g'); // Skip these - var dre = new RegExp('^H[1-6]$','g'); // Add double on these - - if (!elm.hasChildNodes() && !re.test(elm.nodeName)) { - if (dre.test(elm.nodeName)) - elm.innerHTML = "  "; - else - elm.innerHTML = " "; - } - } - } - - // Check if it's a position key - var keys = tinyMCE.posKeyCodes; - var posKey = false; - for (var i=0; i'; - h += ''; - h += ''; - } else { - // Normal button - h += ''; - h += ''; - h += ''; - } - - return h; + + return 1; }, - getMenuButtonHTML : function(id, lang, img, mcmd, cmd, ui, val) { - var h = '', m, x; - - mcmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + mcmd + '\');'; - cmd = 'tinyMCE.execInstanceCommand(\'{$editor_id}\',\'' + cmd + '\''; - - if (typeof(ui) != "undefined" && ui != null) - cmd += ',' + ui; - - if (typeof(val) != "undefined" && val != null) - cmd += ",'" + val + "'"; - - cmd += ');'; - - // Use tilemaps when enabled and found and never in MSIE since it loads the tile each time from cache if cahce is disabled - if (tinyMCE.getParam('button_tile_map') && (!tinyMCE.isIE || tinyMCE.isOpera) && (m = tinyMCE.buttonMap[id]) != null && (tinyMCE.getParam("language") == "en" || img.indexOf('$lang') == -1)) { - x = 0 - (m * 20) == 0 ? '0' : 0 - (m * 20); - - if (tinyMCE.isRealIE) - h += ''; - else - h += ''; - - h += ''; - h += ''; - h += ''; - h += ''; - } else { - if (tinyMCE.isRealIE) - h += ''; - else - h += ''; - - h += ''; - h += ''; - h += ''; - h += ''; - } - - return h; - }, - - _menuButtonEvent : function(e, o) { - if (o.className == 'mceMenuButtonFocus') - return; - - if (e == 'over') - o.className = o.className + ' mceMenuHover'; - else - o.className = o.className.replace(/\s.*$/, ''); - }, - - addButtonMap : function(m) { - var i, a = m.replace(/\s+/, '').split(','); - - for (i=0; i 0); - - if (tinyMCE.settings['custom_undo_redo']) { - undoIndex = inst.undoRedo.undoIndex; - undoLevels = inst.undoRedo.undoLevels.length; - } - - tinyMCE.dispatchCallback(inst, 'handle_node_change_callback', 'handleNodeChange', editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content); - } - - if (this.selectedInstance && (typeof(focus) == "undefined" || focus)) - this.selectedInstance.contentWindow.focus(); - }, - - _customCleanup : function(inst, type, content) { - var pl, po, i; - - // Call custom cleanup - var customCleanup = tinyMCE.settings['cleanup_callback']; - if (customCleanup != "" && eval("typeof(" + customCleanup + ")") != "undefined") - content = eval(customCleanup + "(type, content, inst);"); - - // Trigger theme cleanup - po = tinyMCE.themes[tinyMCE.settings['theme']]; - if (po && po.cleanup) - content = po.cleanup(type, content, inst); - - // Trigger plugin cleanups - pl = inst.plugins; - for (i=0; i 0) - className += " "; - - className += classNames[i]; - } - - return className; - }, - - handleVisualAid : function(el, deep, state, inst, skip_dispatch) { - if (!el) - return; - - if (!skip_dispatch) - tinyMCE.dispatchCallback(inst, 'handle_visual_aid_callback', 'handleVisualAid', el, deep, state, inst); - - var tableElement = null; - - switch (el.nodeName) { - case "TABLE": - var oldW = el.style.width; - var oldH = el.style.height; - var bo = tinyMCE.getAttrib(el, "border"); - - bo = bo == "" || bo == "0" ? true : false; - - tinyMCE.setAttrib(el, "class", tinyMCE.getVisualAidClass(tinyMCE.getAttrib(el, "class"), state && bo)); - - el.style.width = oldW; - el.style.height = oldH; - - for (var y=0; y<\/o:p>", "
"); - html = tinyMCE.regexpReplace(html, " <\/o:p>", ""); - html = tinyMCE.regexpReplace(html, "", ""); - html = tinyMCE.regexpReplace(html, "

<\/p>", ""); - html = tinyMCE.regexpReplace(html, "

<\/p>\r\n

<\/p>", ""); - html = tinyMCE.regexpReplace(html, "

 <\/p>", "
"); - html = tinyMCE.regexpReplace(html, "

\s*(

\s*)?", "

"); - html = tinyMCE.regexpReplace(html, "<\/p>\s*(<\/p>\s*)?", "

"); - }*/ - - // Always set the htmlText output - tinyMCE.setInnerHTML(doc.body, html); - } - - tinyMCE.cleanupAnchors(doc); - - if (tinyMCE.getParam("convert_fonts_to_spans")) - tinyMCE.convertSpansToFonts(doc); - }, - - getEditorId : function(form_element) { - var inst = this.getInstanceById(form_element); - if (!inst) - return null; - - return inst.editorId; - }, - - getInstanceById : function(editor_id) { - var inst = this.instances[editor_id]; - if (!inst) { - for (var n in tinyMCE.instances) { - var instance = tinyMCE.instances[n]; - if (!tinyMCE.isInstance(instance)) - continue; - - if (instance.formTargetElementId == editor_id) { - inst = instance; - break; - } - } - } - - return inst; - }, - - queryInstanceCommandValue : function(editor_id, command) { - var inst = tinyMCE.getInstanceById(editor_id); - if (inst) - return inst.queryCommandValue(command); - - return false; - }, - - queryInstanceCommandState : function(editor_id, command) { - var inst = tinyMCE.getInstanceById(editor_id); - if (inst) - return inst.queryCommandState(command); - - return null; - }, - - setWindowArg : function(n, v) { - this.windowArgs[n] = v; - }, - - getWindowArg : function(n, d) { - return (typeof(this.windowArgs[n]) == "undefined") ? d : this.windowArgs[n]; - }, - - getCSSClasses : function(editor_id, doc) { - var inst = tinyMCE.getInstanceById(editor_id); - - // Is cached, use that - if (inst && inst.cssClasses.length > 0) - return inst.cssClasses; - - if (typeof(editor_id) == "undefined" && typeof(doc) == "undefined") { - var instance; - - for (var instanceName in tinyMCE.instances) { - instance = tinyMCE.instances[instanceName]; - if (!tinyMCE.isInstance(instance)) - continue; - - break; - } - - doc = instance.getDoc(); - } - - if (typeof(doc) == "undefined") { - var instance = tinyMCE.getInstanceById(editor_id); - doc = instance.getDoc(); - } - - if (doc) { - var styles = doc.styleSheets; - - if (styles && styles.length > 0) { - for (var x=0; x' + tinyMCE.replaceVar(v, "pluginurl", o.baseURL) + '
'; - - return tinyMCE.replaceVar(v, "pluginurl", o.baseURL); - } - } - - o = tinyMCE.themes[tinyMCE.settings['theme']]; - if (o.getControlHTML && (v = o.getControlHTML(c)) != '') { - if (rtl) - return '' + v + ''; - - return v; - } - - return ''; - }, - - evalFunc : function(f, idx, a, o) { - o = !o ? window : o; - f = typeof(f) == 'function' ? f : o[f]; - - return f.apply(o, Array.prototype.slice.call(a, idx)); - }, - - dispatchCallback : function(i, p, n) { - return this.callFunc(i, p, n, 0, this.dispatchCallback.arguments); - }, - - executeCallback : function(i, p, n) { - return this.callFunc(i, p, n, 1, this.executeCallback.arguments); - }, - - execCommandCallback : function(i, p, n) { - return this.callFunc(i, p, n, 2, this.execCommandCallback.arguments); - }, - - callFunc : function(ins, p, n, m, a) { - var l, i, on, o, s, v; - - s = m == 2; - - l = tinyMCE.getParam(p, ''); - - if (l != '' && (v = tinyMCE.evalFunc(l, 3, a)) == s && m > 0) - return true; - - if (ins != null) { - for (i=0, l = ins.plugins; i 0) - return true; - } - } - - l = tinyMCE.themes; - for (on in l) { - o = l[on]; - - if (o[n] && (v = tinyMCE.evalFunc(n, 3, a, o)) == s && m > 0) - return true; - } - - return false; - }, - - xmlEncode : function(s, skip_apos) { - return s ? ('' + s).replace(!skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe, function (c, b) { - switch (c) { - case '&': - return '&'; - - case '"': - return '"'; - - case '\'': - return '''; // ' is not working in MSIE - - case '<': - return '<'; - - case '>': - return '>'; - } - - return c; - }) : s; - }, - - extend : function(p, np) { - var o = {}; - - o.parent = p; - - for (n in p) - o[n] = p[n]; - - for (n in np) - o[n] = np[n]; + grep : function(a, f) { + var o = []; + + tinymce.each(a, function(v) { + if (!f || f(v)) + o.push(v); + }); return o; }, - hideMenus : function() { - var e = tinyMCE.lastSelectedMenuBtn; - - if (tinyMCE.lastMenu) { - tinyMCE.lastMenu.hide(); - tinyMCE.lastMenu = null; - } - - if (e) { - tinyMCE.switchClass(e, tinyMCE.lastMenuBtnClass); - tinyMCE.lastSelectedMenuBtn = null; + inArray : function(a, v) { + var i, l; + + if (a) { + for (i = 0, l = a.length; i < l; i++) { + if (a[i] === v) + return i; + } } - } - - }; - -// Global instances -var TinyMCE = TinyMCE_Engine; // Compatiblity with gzip compressors -var tinyMCE = new TinyMCE_Engine(); -var tinyMCELang = {}; - -/* file:jscripts/tiny_mce/classes/TinyMCE_Control.class.js */ - -function TinyMCE_Control(settings) { - - var t, i, to, fu, p, x, fn, fu, pn, s = settings; - - this.undoRedoLevel = true; - this.isTinyMCE_Control = true; - - // Default settings - this.settings = s; - this.settings['theme'] = tinyMCE.getParam("theme", "default"); - this.settings['width'] = tinyMCE.getParam("width", -1); - this.settings['height'] = tinyMCE.getParam("height", -1); - this.selection = new TinyMCE_Selection(this); - this.undoRedo = new TinyMCE_UndoRedo(this); - this.cleanup = new TinyMCE_Cleanup(); - this.shortcuts = new Array(); - this.hasMouseMoved = false; - this.foreColor = this.backColor = "#999999"; - this.data = {}; - this.cssClasses = []; - - this.cleanup.init({ - valid_elements : s.valid_elements, - extended_valid_elements : s.extended_valid_elements, - valid_child_elements : s.valid_child_elements, - entities : s.entities, - entity_encoding : s.entity_encoding, - debug : s.cleanup_debug, - indent : s.apply_source_formatting, - invalid_elements : s.invalid_elements, - verify_html : s.verify_html, - fix_content_duplication : s.fix_content_duplication, - convert_fonts_to_spans : s.convert_fonts_to_spans - }); - - // Wrap old theme - t = this.settings['theme']; - if (!tinyMCE.hasTheme(t)) { - fn = tinyMCE.callbacks; - to = {}; - - for (i=0; i 0) { - for (i=0; i 1 && tinyMCE.currentConfig != this.settings['index']) { - tinyMCE.settings = this.settings; - tinyMCE.currentConfig = this.settings['index']; - } - }, - - select : function() { - var oldInst = tinyMCE.selectedInstance; - - if (oldInst != this) { - if (oldInst) - oldInst.execCommand('mceEndTyping'); - - tinyMCE.dispatchCallback(this, 'select_instance_callback', 'selectInstance', this, oldInst); - tinyMCE.selectedInstance = this; - } - }, - - getBody : function() { - return this.contentBody ? this.contentBody : this.getDoc().body; - }, - - getDoc : function() { -// return this.contentDocument ? this.contentDocument : this.contentWindow.document; // Removed due to IE 5.5 ? - return this.contentWindow.document; - }, - - getWin : function() { - return this.contentWindow; - }, - - getContainerWin : function() { - return this.containerWindow ? this.containerWindow : window; - }, - - getViewPort : function() { - return tinyMCE.getViewPort(this.getWin()); - }, - - getParentNode : function(n, f) { - return tinyMCE.getParentNode(n, f, this.getBody()); - }, - - getParentElement : function(n, na, f) { - return tinyMCE.getParentElement(n, na, f, this.getBody()); - }, - - getParentBlockElement : function(n) { - return tinyMCE.getParentBlockElement(n, this.getBody()); + trim : function(s) { + return (s ? '' + s : '').replace(/^\s*|\s*$/g, ''); }, - resizeToContent : function() { - var d = this.getDoc(), b = d.body, de = d.documentElement; - - this.iframeElement.style.height = (tinyMCE.isRealIE) ? b.scrollHeight : de.offsetHeight + 'px'; - }, - - addShortcut : function(m, k, d, cmd, ui, va) { - var n = typeof(k) == "number", ie = tinyMCE.isIE, c, sc, i, scl = this.shortcuts; - - if (!tinyMCE.getParam('custom_shortcuts')) - return false; - - m = m.toLowerCase(); - k = ie && !n ? k.toUpperCase() : k; - c = n ? null : k.charCodeAt(0); - d = d && d.indexOf('lang_') == 0 ? tinyMCE.getLang(d) : d; - - sc = { - alt : m.indexOf('alt') != -1, - ctrl : m.indexOf('ctrl') != -1, - shift : m.indexOf('shift') != -1, - charCode : c, - keyCode : n ? k : (ie ? c : null), - desc : d, - cmd : cmd, - ui : ui, - val : va - }; - - for (i=0; i : + s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s); + cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name + + // Create namespace for new class + ns = t.createNS(s[3].replace(/\.\w+$/, '')); + + // Class already exists + if (ns[cn]) + return; + + // Make pure static class + if (s[2] == 'static') { + ns[cn] = p; + + if (this.onCreate) + this.onCreate(s[2], s[3], ns[cn]); + return; } - var st = tinyMCE.parseStyle(tinyMCE.getAttrib(pa, "style")); - var stc = tinyMCE.parseStyle(tinyMCE.getAttrib(ch, "style")); - var className = tinyMCE.getAttrib(pa, "class"); - - // Removed class adding due to bug #1478272 - className = tinyMCE.getAttrib(ch, "class"); - - if (override) { - for (var n in st) { - if (typeof(st[n]) == 'function') - continue; - - stc[n] = st[n]; - } - } else { - for (var n in stc) { - if (typeof(stc[n]) == 'function') - continue; - - st[n] = stc[n]; - } - } - - tinyMCE.setAttrib(pa, "style", tinyMCE.serializeStyle(st)); - tinyMCE.setAttrib(pa, "class", tinyMCE.trim(className)); - ch.className = ""; - ch.style.cssText = ""; - ch.removeAttribute("class"); - ch.removeAttribute("style"); - }, - - _setUseCSS : function(b) { - var d = this.getDoc(); - - try {d.execCommand("useCSS", false, !b);} catch (ex) {} - try {d.execCommand("styleWithCSS", false, b);} catch (ex) {} - - if (!tinyMCE.getParam("table_inline_editing")) - try {d.execCommand('enableInlineTableEditing', false, "false");} catch (ex) {} - - if (!tinyMCE.getParam("object_resizing")) - try {d.execCommand('enableObjectResizing', false, "false");} catch (ex) {} - }, - - execCommand : function(command, user_interface, value) { - var doc = this.getDoc(), win = this.getWin(), focusElm = this.getFocusElement(); - - // Is not a undo specific command - if (!new RegExp('mceStartTyping|mceEndTyping|mceBeginUndoLevel|mceEndUndoLevel|mceAddUndoLevel', 'gi').test(command)) - this.undoBookmark = null; - - // Mozilla issue - if (!tinyMCE.isIE && !this.useCSS) { - this._setUseCSS(false); - this.useCSS = true; - } - - //debug("command: " + command + ", user_interface: " + user_interface + ", value: " + value); - this.contentDocument = doc; // <-- Strange, unless this is applied Mozilla 1.3 breaks - - // Don't dispatch key commands - if (!/mceStartTyping|mceEndTyping/.test(command)) { - if (tinyMCE.execCommandCallback(this, 'execcommand_callback', 'execCommand', this.editorId, this.getBody(), command, user_interface, value)) - return; - } - - // Fix align on images - if (focusElm && focusElm.nodeName == "IMG") { - var align = focusElm.getAttribute('align'); - var img = command == "JustifyCenter" ? focusElm.cloneNode(false) : focusElm; - - switch (command) { - case "JustifyLeft": - if (align == 'left') - img.removeAttribute('align'); - else - img.setAttribute('align', 'left'); - - // Remove the div - var div = focusElm.parentNode; - if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) - div.parentNode.replaceChild(img, div); - - this.selection.selectNode(img); - this.repaint(); - tinyMCE.triggerNodeChange(); - return; - - case "JustifyCenter": - img.removeAttribute('align'); - - // Is centered - var div = tinyMCE.getParentElement(focusElm, "div"); - if (div && div.style.textAlign == "center") { - // Remove div - if (div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) - div.parentNode.replaceChild(img, div); - } else { - // Add div - var div = this.getDoc().createElement("div"); - div.style.textAlign = 'center'; - div.appendChild(img); - focusElm.parentNode.replaceChild(div, focusElm); - } - - this.selection.selectNode(img); - this.repaint(); - tinyMCE.triggerNodeChange(); - return; - - case "JustifyRight": - if (align == 'right') - img.removeAttribute('align'); - else - img.setAttribute('align', 'right'); - - // Remove the div - var div = focusElm.parentNode; - if (div && div.nodeName == "DIV" && div.childNodes.length == 1 && div.parentNode) - div.parentNode.replaceChild(img, div); - - this.selection.selectNode(img); - this.repaint(); - tinyMCE.triggerNodeChange(); - return; - } - } - - if (tinyMCE.settings['force_br_newlines']) { - var alignValue = ""; - - if (doc.selection.type != "Control") { - switch (command) { - case "JustifyLeft": - alignValue = "left"; - break; - - case "JustifyCenter": - alignValue = "center"; - break; - - case "JustifyFull": - alignValue = "justify"; - break; - - case "JustifyRight": - alignValue = "right"; - break; - } - - if (alignValue != "") { - var rng = doc.selection.createRange(); - - if ((divElm = tinyMCE.getParentElement(rng.parentElement(), "div")) != null) - divElm.setAttribute("align", alignValue); - else if (rng.pasteHTML && rng.htmlText.length > 0) - rng.pasteHTML('
' + rng.htmlText + "
"); - - tinyMCE.triggerNodeChange(); - return; - } - } + // Create default constructor + if (!p[cn]) { + p[cn] = function() {}; + de = 1; } - switch (command) { - case "mceRepaint": - this.repaint(); - return true; - - case "unlink": - // Unlink if caret is inside link - if (tinyMCE.isGecko && this.getSel().isCollapsed) { - focusElm = tinyMCE.getParentElement(focusElm, 'A'); - - if (focusElm) - this.selection.selectNode(focusElm, false); - } - - this.getDoc().execCommand(command, user_interface, value); - - tinyMCE.isGecko && this.getSel().collapseToEnd(); - - tinyMCE.triggerNodeChange(); - - return true; - - case "InsertUnorderedList": - case "InsertOrderedList": - this.getDoc().execCommand(command, user_interface, value); - tinyMCE.triggerNodeChange(); - break; - - case "Strikethrough": - this.getDoc().execCommand(command, user_interface, value); - tinyMCE.triggerNodeChange(); - break; - - case "mceSelectNode": - this.selection.selectNode(value); - tinyMCE.triggerNodeChange(); - tinyMCE.selectedNode = value; - break; - - case "FormatBlock": - if (value == null || value == "") { - var elm = tinyMCE.getParentElement(this.getFocusElement(), "p,div,h1,h2,h3,h4,h5,h6,pre,address,blockquote,dt,dl,dd,samp"); - - if (elm) - this.execCommand("mceRemoveNode", false, elm); - } else { - if (!this.cleanup.isValid(value)) - return true; - - if (tinyMCE.isGecko && new RegExp('<(div|blockquote|code|dt|dd|dl|samp)>', 'gi').test(value)) - value = value.replace(/[^a-z]/gi, ''); - - if (tinyMCE.isIE && new RegExp('blockquote|code|samp', 'gi').test(value)) { - var b = this.selection.getBookmark(); - this.getDoc().execCommand("FormatBlock", false, '

'); - tinyMCE.renameElement(tinyMCE.getParentBlockElement(this.getFocusElement()), value); - this.selection.moveToBookmark(b); - } else - this.getDoc().execCommand("FormatBlock", false, value); - } - - tinyMCE.triggerNodeChange(); - - break; - - case "mceRemoveNode": - if (!value) - value = tinyMCE.getParentElement(this.getFocusElement()); - - if (tinyMCE.isIE) { - value.outerHTML = value.innerHTML; - } else { - var rng = value.ownerDocument.createRange(); - rng.setStartBefore(value); - rng.setEndAfter(value); - rng.deleteContents(); - rng.insertNode(rng.createContextualFragment(value.innerHTML)); - } - - tinyMCE.triggerNodeChange(); - - break; - - case "mceSelectNodeDepth": - var parentNode = this.getFocusElement(); - for (var i=0; parentNode; i++) { - if (parentNode.nodeName.toLowerCase() == "body") - break; - - if (parentNode.nodeName.toLowerCase() == "#text") { - i--; - parentNode = parentNode.parentNode; - continue; - } - - if (i == value) { - this.selection.selectNode(parentNode, false); - tinyMCE.triggerNodeChange(); - tinyMCE.selectedNode = parentNode; - return; - } - - parentNode = parentNode.parentNode; - } - - break; - - case "mceSetStyleInfo": - case "SetStyleInfo": - var rng = this.getRng(); - var sel = this.getSel(); - var scmd = value['command']; - var sname = value['name']; - var svalue = value['value'] == null ? '' : value['value']; - //var svalue = value['value'] == null ? '' : value['value']; - var wrapper = value['wrapper'] ? value['wrapper'] : "span"; - var parentElm = null; - var invalidRe = new RegExp("^BODY|HTML$", "g"); - var invalidParentsRe = tinyMCE.settings['merge_styles_invalid_parents'] != '' ? new RegExp(tinyMCE.settings['merge_styles_invalid_parents'], "gi") : null; - - // Whole element selected check - if (tinyMCE.isIE) { - // Control range - if (rng.item) - parentElm = rng.item(0); - else { - var pelm = rng.parentElement(); - var prng = doc.selection.createRange(); - prng.moveToElementText(pelm); - - if (rng.htmlText == prng.htmlText || rng.boundingWidth == 0) { - if (invalidParentsRe == null || !invalidParentsRe.test(pelm.nodeName)) - parentElm = pelm; - } - } - } else { - var felm = this.getFocusElement(); - if (sel.isCollapsed || (new RegExp('td|tr|tbody|table', 'gi').test(felm.nodeName) && sel.anchorNode == felm.parentNode)) - parentElm = felm; - } - - // Whole element selected - if (parentElm && !invalidRe.test(parentElm.nodeName)) { - if (scmd == "setstyle") - tinyMCE.setStyleAttrib(parentElm, sname, svalue); - - if (scmd == "setattrib") - tinyMCE.setAttrib(parentElm, sname, svalue); - - if (scmd == "removeformat") { - parentElm.style.cssText = ''; - tinyMCE.setAttrib(parentElm, 'class', ''); - } - - // Remove style/attribs from all children - var ch = tinyMCE.getNodeTree(parentElm, new Array(), 1); - for (var z=0; z=0; i--) { - var elm = nodes[i]; - var isNew = tinyMCE.getAttrib(elm, "mce_new") == "true"; - - elm.removeAttribute("mce_new"); - - // Is only child a element - if (elm.childNodes && elm.childNodes.length == 1 && elm.childNodes[0].nodeType == 1) { - //tinyMCE.debug("merge1" + isNew); - this._mergeElements(scmd, elm, elm.childNodes[0], isNew); - continue; - } - - // Is I the only child - if (elm.parentNode.childNodes.length == 1 && !invalidRe.test(elm.nodeName) && !invalidRe.test(elm.parentNode.nodeName)) { - //tinyMCE.debug("merge2" + isNew + "," + elm.nodeName + "," + elm.parentNode.nodeName); - if (invalidParentsRe == null || !invalidParentsRe.test(elm.parentNode.nodeName)) - this._mergeElements(scmd, elm.parentNode, elm, false); - } - } - - // Remove empty wrappers - var nodes = doc.getElementsByTagName(wrapper); - for (var i=nodes.length-1; i>=0; i--) { - var elm = nodes[i]; - var isEmpty = true; - - // Check if it has any attribs - var tmp = doc.createElement("body"); - tmp.appendChild(elm.cloneNode(false)); - - // Is empty span, remove it - tmp.innerHTML = tmp.innerHTML.replace(new RegExp('style=""|class=""', 'gi'), ''); - //tinyMCE.debug(tmp.innerHTML); - if (new RegExp('', 'gi').test(tmp.innerHTML)) { - for (var x=0; x 0) { - value = tinyMCE.replaceVar(value, "selection", selectedText); - tinyMCE.execCommand('mceInsertContent', false, value); - } - - tinyMCE.triggerNodeChange(); - break; - - case "mceSetAttribute": - if (typeof(value) == 'object') { - var targetElms = (typeof(value['targets']) == "undefined") ? "p,img,span,div,td,h1,h2,h3,h4,h5,h6,pre,address" : value['targets']; - var targetNode = tinyMCE.getParentElement(this.getFocusElement(), targetElms); - - if (targetNode) { - targetNode.setAttribute(value['name'], value['value']); - tinyMCE.triggerNodeChange(); - } - } - break; - - case "mceSetCSSClass": - this.execCommand("mceSetStyleInfo", false, {command : "setattrib", name : "class", value : value}); - break; - - case "mceInsertRawHTML": - var key = 'tiny_mce_marker'; - - this.execCommand('mceBeginUndoLevel'); - - // Insert marker key - this.execCommand('mceInsertContent', false, key); - - // Store away scroll pos - var scrollX = this.getBody().scrollLeft + this.getDoc().documentElement.scrollLeft; - var scrollY = this.getBody().scrollTop + this.getDoc().documentElement.scrollTop; - - // Find marker and replace with RAW HTML - var html = this.getBody().innerHTML; - if ((pos = html.indexOf(key)) != -1) - tinyMCE.setInnerHTML(this.getBody(), html.substring(0, pos) + value + html.substring(pos + key.length)); - - // Restore scoll pos - this.contentWindow.scrollTo(scrollX, scrollY); - - this.execCommand('mceEndUndoLevel'); - - break; - - case "mceInsertContent": - // Force empty string - if (!value) - value = ''; - - var insertHTMLFailed = false; - - // Removed since it produced problems in IE - // this.getWin().focus(); - - if (tinyMCE.isGecko || tinyMCE.isOpera) { - try { - // Is plain text or HTML, &,   etc will be encoded wrong in FF - if (value.indexOf('<') == -1 && !value.match(/(&| |<|>)/g)) { - var r = this.getRng(); - var n = this.getDoc().createTextNode(tinyMCE.entityDecode(value)); - var s = this.getSel(); - var r2 = r.cloneRange(); - - // Insert text at cursor position - s.removeAllRanges(); - r.deleteContents(); - r.insertNode(n); - - // Move the cursor to the end of text - r2.selectNode(n); - r2.collapse(false); - s.removeAllRanges(); - s.addRange(r2); - } else { - value = tinyMCE.fixGeckoBaseHREFBug(1, this.getDoc(), value); - this.getDoc().execCommand('inserthtml', false, value); - tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); - } - } catch (ex) { - insertHTMLFailed = true; - } - - if (!insertHTMLFailed) { - tinyMCE.triggerNodeChange(); - return; - } - } - - if (!tinyMCE.isIE) { - var isHTML = value.indexOf('<') != -1; - var sel = this.getSel(); - var rng = this.getRng(); - - if (isHTML) { - if (tinyMCE.isSafari) { - var tmpRng = this.getDoc().createRange(); - - tmpRng.setStart(this.getBody(), 0); - tmpRng.setEnd(this.getBody(), 0); - - value = tmpRng.createContextualFragment(value); - } else - value = rng.createContextualFragment(value); - } else { - // Setup text node - var el = document.createElement("div"); - el.innerHTML = value; - value = el.firstChild.nodeValue; - value = doc.createTextNode(value); - } - - // Insert plain text in Safari - if (tinyMCE.isSafari && !isHTML) { - this.execCommand('InsertText', false, value.nodeValue); - tinyMCE.triggerNodeChange(); - return true; - } else if (tinyMCE.isSafari && isHTML) { - rng.deleteContents(); - rng.insertNode(value); - tinyMCE.triggerNodeChange(); - return true; - } - - rng.deleteContents(); - - // If target node is text do special treatment, (Mozilla 1.3 fix) - if (rng.startContainer.nodeType == 3) { - var node = rng.startContainer.splitText(rng.startOffset); - node.parentNode.insertBefore(value, node); - } else - rng.insertNode(value); - - if (!isHTML) { - // Removes weird selection trails - sel.selectAllChildren(doc.body); - sel.removeAllRanges(); - - // Move cursor to end of content - var rng = doc.createRange(); - - rng.selectNode(value); - rng.collapse(false); - - sel.addRange(rng); - } else - rng.collapse(false); - - tinyMCE.fixGeckoBaseHREFBug(2, this.getDoc(), value); - } else { - var rng = doc.selection.createRange(), tmpRng = null; - var c = value.indexOf('"; - } - - if (hc) { - cn = n.childNodes; - - for (i=0, l=cn.length; i'; - - return h; - }, - - _serializeAttribute : function(n, r, an) { - var av = '', t, os = this.settings.on_save; - - if (os && (an.indexOf('mce_') == 0 || an.indexOf('_moz') == 0)) - return ''; - - if (os && this.mceAttribs[an]) - av = this._getAttrib(n, this.mceAttribs[an]); - - if (av.length == 0) - av = this._getAttrib(n, an); - - if (av.length == 0 && r.defaultAttribs && (t = r.defaultAttribs[an])) { - av = t; - - if (av == "mce_empty") - return " " + an + '=""'; - } - - if (r.forceAttribs && (t = r.forceAttribs[an])) - av = t; - - if (os && av.length != 0 && /^(src|href|longdesc)$/.test(an)) - av = this._urlConverter(this, n, av); - - if (av.length != 0 && r.validAttribValues && r.validAttribValues[an] && !r.validAttribValues[an].test(av)) - return ""; - - if (av.length != 0 && av == "{$uid}") - av = "uid_" + (this.idCount++); - - if (av.length != 0) { - if (an.indexOf('on') != 0) - av = this.xmlEncode(av, 1); - - return " " + an + "=" + '"' + av + '"'; - } - - return ""; - }, - - formatHTML : function(h) { - var s = this.settings, p = '', i = 0, li = 0, o = '', l; - - // Replace BR in pre elements to \n - h = h.replace(/]*)>(.*?)<\/pre>/gi, function (a, b, c) { - c = c.replace(//gi, '\n'); - return '' + c + ''; - }); - - h = h.replace(/\r/g, ''); // Windows sux, isn't carriage return a thing of the past :) - h = '\n' + h; - h = h.replace(new RegExp('\\n\\s+', 'gi'), '\n'); // Remove previous formatting - h = h.replace(this.nlBeforeRe, '\n<$1$2>'); - h = h.replace(this.nlAfterRe, '<$1$2>\n'); - h = h.replace(this.nlBeforeAfterRe, '\n<$1$2$3>\n'); - h += '\n'; - - //tinyMCE.debug(h); - - while ((i = h.indexOf('\n', i + 1)) != -1) { - if ((l = h.substring(li + 1, i)).length != 0) { - if (this.ouRe.test(l) && p.length >= s.indent_levels) - p = p.substring(s.indent_levels); - - o += p + l + '\n'; - - if (this.inRe.test(l)) - p += this.inStr; - } - - li = i; - } - - //tinyMCE.debug(h); return o; }, - xmlEncode : function(s, skip_apos) { - var cl = this, re = !skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe; - - this._setupEntities(); // Will intialize lookup table - - switch (this.settings.entity_encoding) { - case "raw": - return tinyMCE.xmlEncode(s, skip_apos); - - case "named": - return s.replace(re, function (c, b) { - b = cl.entities[c.charCodeAt(0)]; - - return b ? '&' + b + ';' : c; - }); - - case "numeric": - return s.replace(re, function (c, b) { - return b ? '&#' + c.charCodeAt(0) + ';' : c; - }); - } - - return s; - }, - - split : function(re, s) { - var c = s.split(re); - var i, l, o = new Array(); - - for (i=0, l=c.length; i' : '>' + h + ''; - - return o; -}; - -TinyMCE_Engine.prototype.createTag = function(d, tn, a, h) { - var o = d.createElement(tn); - - if (a) { - for (n in a) { - if (typeof(a[n]) != 'function' && a[n] != null) - tinyMCE.setAttrib(o, n, a[n]); + }); + +/* file:jscripts/tiny_mce/classes/util/URI.js */ + +(function() { + var each = tinymce.each; + + tinymce.create('tinymce.util.URI', { + URI : function(u, s) { + var t = this, o, a, b; + + // Default settings + s = t.settings = s || {}; + + // Strange app protocol or local anchor + if (/^(mailto|news|javascript|about):/i.test(u) || /^\s*#/.test(u)) { + t.source = u; + return; + } + + // Absolute path with no host, fake host and protocol + if (u.indexOf('/') === 0 && u.indexOf('//') !== 0) + u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u; + + // Relative path + if (u.indexOf('://') === -1 && u.indexOf('//') !== 0) + u = (s.base_uri.protocol || 'http') + '://mce_host' + t.toAbsPath(s.base_uri.path, u); + + // Parse URL (Credits goes to Steave, http://blog.stevenlevithan.com/archives/parseuri) + u = u.replace(/@@/g, '(mce_at)'); // Zope 3 workaround, they use @@something + 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]; + + // Zope 3 workaround, they use @@something + 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 = ''; + } + + //t.path = t.path || '/'; + }, + + setPath : function(p) { + var t = this; + + p = /^(.*?)\/?(\w+)?$/.exec(p); + + // Update path parts + t.path = p[0]; + t.directory = p[1]; + t.file = p[2]; + + // Rebuild source + t.source = ''; + t.getURI(); + }, + + toRelative : function(u) { + var t = this, o; + + u = new tinymce.util.URI(u, {base_uri : t}); + + // Not on same domain/port or protocol + 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); + + // Add query + if (u.query) + o += '?' + u.query; + + // Add anchor + 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; + + // Split the paths + 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 = []; + + // Split paths + base = base.split('/'); + path = path.split('/'); + + // Remove empty chunks + each(base, function(k) { + if (k) + o.push(k); + }); + + base = o; + + // Merge relURLParts chunks + for (i = path.length - 1, o = []; i >= 0; i--) { + // Ignore empty or . + if (path[i].length == 0 || path[i] == ".") + continue; + + // Is parent + if (path[i] == '..') { + nb++; + continue; + } + + // Move up + if (nb > 0) { + nb--; + continue; + } + + o.push(path[i]); + } + + i = base.length - nb; + + // If /a/b/c or / + if (i <= 0) + return '/' + o.reverse().join('/'); + + return '/' + base.slice(0, i).join('/') + '/' + o.reverse().join('/'); + }, + + getURI : function(nh) { + var s, t = this; + + // Rebuild source + 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; + } + + }); +})(); + +/* file:jscripts/tiny_mce/classes/util/Cookie.js */ + +(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; + + // Strict mode + 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); + } + + }); +})(); + +/* file:jscripts/tiny_mce/classes/util/JSON.js */ + +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 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) { + // Ignore } } - if (h) - o.innerHTML = h; - - return o; -}; - -TinyMCE_Engine.prototype.getElementByAttributeValue = function(n, e, a, v) { - return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0]; -}; - -TinyMCE_Engine.prototype.getElementsByAttributeValue = function(n, e, a, v) { - var i, nl = n.getElementsByTagName(e), o = new Array(); - - for (i=0; i]*)>/gi, ''); - h = h.replace(/]*)>/gi, ''); - h = h.replace(/]*)>/gi, ''); - h = h.replace(/]*)>/gi, ''); - h = h.replace(/<\/strong>/gi, ''); - h = h.replace(/<\/em>/gi, ''); - } - - if (tinyMCE.isRealIE) { - // Since MSIE handles invalid HTML better that valid XHTML we - // need to make some things invalid.


gets converted to
. - h = h.replace(/\s\/>/g, '>'); - - // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones - h = h.replace(/]*)>\u00A0?<\/p>/gi, ' 

'); // Keep empty paragraphs - h = h.replace(/]*)>\s* \s*<\/p>/gi, ' 

'); // Keep empty paragraphs - h = h.replace(/]*)>\s+<\/p>/gi, ' 

'); // Keep empty paragraphs - - // Remove first comment - e.innerHTML = tinyMCE.uniqueTag + h; - e.firstChild.removeNode(true); - - // Remove weird auto generated empty paragraphs unless it's supposed to be there - nl = e.getElementsByTagName("p"); - for (i=nl.length-1; i>=0; i--) { - n = nl[i]; - - if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep) - n.parentNode.removeChild(n); + }); + +/* file:jscripts/tiny_mce/classes/util/XHR.js */ + +tinymce.create('static tinymce.util.XHR', { + send : function(o) { + var x, t, w = window, c = 0; + + // Default settings + 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); + + // Wait for response, onReadyStateChange can not be used since it leaks memory in IE + t = w.setInterval(function() { + if (x.readyState == 4 || c++ > 10000) { + w.clearInterval(t); + + 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; + } + }, 10); + } + + } +}); + +/* file:jscripts/tiny_mce/classes/util/JSONRequest.js */ + +(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 + }); + + XHR.send(o); + }, + + 'static' : { + sendRPC : function(o) { + return new tinymce.util.JSONRequest().send(o); + } } - } else { - h = this.fixGeckoBaseHREFBug(1, e, h); - e.innerHTML = h; - this.fixGeckoBaseHREFBug(2, e, h); - } -}; - -TinyMCE_Engine.prototype.getOuterHTML = function(e) { - if (tinyMCE.isIE) - return e.outerHTML; - - var d = e.ownerDocument.createElement("body"); - d.appendChild(e.cloneNode(true)); - return d.innerHTML; -}; - -TinyMCE_Engine.prototype.setOuterHTML = function(e, h, d) { - var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t; - - if (tinyMCE.isIE && e.nodeType == 1) - e.outerHTML = h; - else { - t = d.createElement("body"); - t.innerHTML = h; - - for (i=0, nl=t.childNodes; i= 0; i--) + cs += '}, ' + (i ? 'n' : 's') + ');'; + + cs += '})'; + + // Compile CSS pattern function + t.cache[pa] = cs = eval(cs); + } + + // Run selector function + cs(isIE ? collectIE : collect, s); + }); + + // Cleanup + each(o, function(n) { + if (isIE) + n.removeAttribute('mce_save'); + else + delete n.mce_save; + }); + + return o; + }, + + // #endif + + 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 + ''; + + return o + ' />'; + }, + + remove : function(n, k) { + return this.run(n, function(n) { + var p; + + p = n.parentNode; + + if (!p) + return null; + + if (k) { + each (n.childNodes, function(c) { + p.insertBefore(c.cloneNode(true), n); + }); + } + + return p.removeChild(n); + }); + }, + + // #if !jquery + + setStyle : function(n, na, v) { + var t = this; + + return t.run(n, function(e) { + var s, i; + + s = e.style; + + // Camelcase it, if needed + na = na.replace(/-(\D)/g, function(a, b){ + return b.toUpperCase(); + }); + + // Default px suffix on these + if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v))) + v += 'px'; + + switch (na) { + case 'opacity': + // IE specific opacity + if (isIE) { + s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")"; + + if (!n.currentStyle || !n.currentStyle.hasLayout) + s.display = 'inline-block'; + } + + // Fix for older browsers + s['-moz-opacity'] = s['-khtml-opacity'] = v; + break; + + case 'float': + isIE ? s.styleFloat = v : s.cssFloat = v; + break; + } + + s[na] = v || ''; + + // Force update of the style data + if (t.settings.update_styles) + t.setAttrib(e, 'mce_style'); + }); + }, + + getStyle : function(n, na, c) { + n = this.get(n); + + if (!n) + return false; + + // Gecko + if (this.doc.defaultView && c) { + // Remove camelcase + na = na.replace(/[A-Z]/g, function(a){ + return '-' + a; + }); + + try { + return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na); + } catch (ex) { + // Old safari might fail + return null; + } + } + + // Camelcase it, if needed + na = na.replace(/-(\D)/g, function(a, b){ + return b.toUpperCase(); + }); + + if (na == 'float') + na = isIE ? 'styleFloat' : 'cssFloat'; + + // IE & Opera + 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); + }); + + // Update style info + s.update_styles = ol; + if (s.update_styles) + t.setAttrib(e, s.cssText); + }, + + setAttrib : function(e, n, v) { + var t = this; + + // Strict XML mode + 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) + 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; + } + + 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); + }); + }); + }, + + // #endif + + getAttrib : function(e, n, dv) { + var v, t = this; + + e = t.get(e); + + if (!e) + return false; + + if (!is(dv)) + dv = ""; + + // Try the mce variant for these + if (/^(src|href|style|coords)$/.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: + 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) + e.setAttribute('mce_style', v); + } + + break; + } + + // Remove Apple and WebKit stuff + if (isWebKit && n === "class" && v) + v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, ''); + + // Handle IE issues + if (isIE) { + switch (n) { + case 'rowspan': + case 'colspan': + // IE returns 1 as default value + if (v === 1) + v = ''; + + break; + + case 'size': + // IE returns +0 as default value for size + if (v === '+0') + v = ''; + + break; + + case 'hspace': + // IE returns -1 as default value + if (v === -1) + v = ''; + + break; + + case 'tabindex': + // IE returns 32768 as default value + if (v === 32768) + v = ''; + + break; + + case 'shape': + v = v.toLowerCase(); + break; + + default: + // IE has odd anonymous function for event attributes + 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); + + // Use getBoundingClientRect on IE, Opera has it but it's not perfect + if (n && isIE) { + n = n.getBoundingClientRect(); + e = t.boxModel ? d.documentElement : d.body; + x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border + x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x; + n.top += window.self != window.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset + + 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) { + 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; + + // Get values and check it it needs compressing + 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; + + // Compress + 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; + + // Compress + o[ta] = o[a] + ' ' + o[b] + ' ' + o[c]; + delete o[a]; + delete o[b]; + delete o[c]; + }; + + each(st.split(';'), function(v) { + var sv, ur = []; + + if (v) { + 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(' + t.encode(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) { + // Remove pointless border + if (o.border == 'medium none') + o.border = ''; + } + + return o; + }, + + serializeStyle : function(o) { + var s = ''; + + each(o, function(v, k) { + if (k && v) { + switch (k) { + case 'color': + case 'background-color': + v = v.toLowerCase(); + break; + } + + s += (s ? ' ' : '') + k + ': ' + v + ';'; + } + }); + + return s; + }, + + loadCSS : function(u) { + var t = this, d = this.doc; + + if (!u) + u = ''; + + each(u.split(','), function(u) { + if (t.files[u]) + return; + + t.files[u] = true; + + if (!d.createStyleSheet) + t.add(t.select('head')[0], 'link', {rel : 'stylesheet', href : u}); + else + d.createStyleSheet(u); + }); + }, + + // #if !jquery + + 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'; + }, + + // #endif + + uniqueId : function(p) { + return (!p ? 'mce_' : p) + (this.counter++); + }, + + setHTML : function(e, h) { + var t = this; + + return this.run(e, function(e) { + var x; + + h = t.processHTML(h); + + if (isIE) { + try { + // IE will remove comments from the beginning + // unless you padd the contents with something + e.innerHTML = '
' + h; + e.removeChild(e.firstChild); + } catch (ex) { + // IE sometimes produces an unknown runtime error on innerHTML + // This seems to fix this issue, don't know why. + x = t.create('div'); + x.innerHTML = '
' + h; + + each (x.childNodes, function(n, i) { + // Skip the BR + if (i > 1) + e.appendChild(n); + }); + } + } else + e.innerHTML = h; + + return h; + }); + }, + + processHTML : function(h) { + var t = this, s = t.settings; + + if (!s.process_html) + return h; + + // Convert strong and em to b and i in FF since it can't handle them + if (tinymce.isGecko) { + h = h.replace(/<(\/?)strong>|]+)>/gi, '<$1b$2>'); + h = h.replace(/<(\/?)em>|]+)>/gi, '<$1i$2>'); + } + + // Fix some issues + h = h.replace(/]+)\/>|/gi, ''); // Force open + + // Store away src and href in mce_src and mce_href since browsers mess them up + if (s.keep_values) { + // Wrap scripts in comments for serialization purposes + if (h.indexOf('/g, ''; } $db->free_result(); - echo '

Other changes:

'; + echo '

' . $lang->get('history_heading_other') . '

'; $q = 'SELECT time_id,action,date_string,page_id,namespace,author,edit_summary,minor_edit FROM ' . table_prefix.'logs WHERE log_type=\'page\' AND action!=\'edit\' AND page_id=\'' . $paths->page_id . '\' AND namespace=\'' . $paths->namespace . '\' ORDER BY time_id DESC;'; - if(!$db->sql_query($q)) $db->_die('The history data for the page "' . $paths->cpage['name'] . '" could not be selected.'); - if($db->numrows() < 1) echo 'No history entries in this category.'; - else { + if ( !$db->sql_query($q) ) + { + $db->_die('The history data for the page "' . htmlspecialchars($paths->cpage['name']) . '" could not be selected.'); + } + if ( $db->numrows() < 1 ) + { + echo $lang->get('history_no_entries'); + } + else + { - echo '
'; + echo '
+
Date/timeUserMinorAction takenExtra info
+ + + + + + + '; $cls = 'row2'; while($r = $db->fetchrow()) { @@ -669,7 +478,7 @@ echo ''; // Date and time - echo ''; + echo ''; // User echo ''; // Actions! - echo ''; - echo ''; - - //echo '(rollback) ' . $r['date_string'] . ' ' . $r['author'] . ' (Userpage, Contrib): '; - - if($r['minor_edit']) echo ' - minor edit'; - echo '
'; + echo ''; + echo ''; echo ''; } @@ -717,9 +521,13 @@ * @return string */ - function rollback($id) + public static function rollback($id) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + + // FIXME: l10n + if ( !$session->get_permissions('history_rollback') ) { return('You are not authorized to perform rollbacks.'); @@ -780,32 +588,29 @@ case "page": switch($rb['action']) { - case "edit": - if ( !$perms->get_permissions('edit_page') ) - return "You don't have permission to edit pages, so rolling back edits can't be allowed either."; - $t = $db->escape($rb['page_text']); - $e = $db->sql_query('UPDATE ' . table_prefix.'page_text SET page_text=\'' . $t . '\',char_tag=\'' . $rb['char_tag'] . '\' WHERE page_id=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\''); + // Support for rolling back edits removed in 1.1.2 - moved to page editor system + case "rename": + if ( !$perms->get_permissions('rename') ) + return "You don't have permission to rename pages, so rolling back renames can't be allowed either."; + + $t = $rb['edit_summary']; + // result prediction + $subst = array( + 'page_name_old' => get_page_title_ns($rb['page_id'], $rb['namespace']), + 'page_name_new' => $t + ); + + $e = PageUtils::rename($rb['page_id'], $rb['namespace'], $t); + + $e = ( $e == $lang->get('ajax_rename_success', $subst) ); + if ( !$e ) { - return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); + return "An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); } else { - return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been rolled back to the state it was in on ' . $rb['date_string'] . '.'; - } - break; - case "rename": - if ( !$perms->get_permissions('rename') ) - return "You don't have permission to rename pages, so rolling back renames can't be allowed either."; - $t = $db->escape($rb['edit_summary']); - $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET name=\'' . $t . '\' WHERE urlname=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\''); - if ( !$e ) - { - return "An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); - } - else - { - return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been rolled back to the name it had ("' . $rb['edit_summary'] . '") before ' . $rb['date_string'] . '.'; + return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been rolled back to the name it had ("' . $rb['edit_summary'] . '") before ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; } break; case "prot": @@ -813,27 +618,27 @@ return "You don't have permission to protect pages, so rolling back protection can't be allowed either."; $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET protected=0 WHERE urlname=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\''); if ( !$e ) - return "An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); + return "An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); else - return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been unprotected according to the log created at ' . $rb['date_string'] . '.'; + return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been unprotected according to the log created at ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; break; case "semiprot": if ( !$perms->get_permissions('protect') ) return "You don't have permission to protect pages, so rolling back protection can't be allowed either."; $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET protected=0 WHERE urlname=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\''); if ( !$e ) - return "An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); + return "An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); else - return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been unprotected according to the log created at ' . $rb['date_string'] . '.'; + return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been unprotected according to the log created at ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; break; case "unprot": if ( !$perms->get_permissions('protect') ) return "You don't have permission to protect pages, so rolling back protection can't be allowed either."; $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET protected=1 WHERE urlname=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\''); if ( !$e ) - return "An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); + return "An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace(); else - return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been protected according to the log created at ' . $rb['date_string'] . '.'; + return 'The page "' . $paths->pages[$paths->nslist[$rb['namespace']].$rb['page_id']]['name'].'" has been protected according to the log created at ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; break; case "delete": if ( !$perms->get_permissions('history_rollback_extra') ) @@ -841,11 +646,11 @@ if ( isset($paths->pages[$paths->cpage['urlname']]) ) return 'You cannot raise a dead page that is alive.'; $name = str_replace('_', ' ', $rb['page_id']); - $e = $db->sql_query('INSERT INTO ' . table_prefix.'pages(name,urlname,namespace) VALUES( \'' . $name . '\', \'' . $rb['page_id'] . '\',\'' . $rb['namespace'] . '\' )');if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); - $e = $db->sql_query('SELECT page_text,char_tag FROM ' . table_prefix.'logs WHERE page_id=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\' AND log_type=\'page\' AND action=\'edit\' ORDER BY time_id DESC;'); if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); + $e = $db->sql_query('INSERT INTO ' . table_prefix.'pages(name,urlname,namespace) VALUES( \'' . $name . '\', \'' . $rb['page_id'] . '\',\'' . $rb['namespace'] . '\' )');if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); + $e = $db->sql_query('SELECT page_text,char_tag FROM ' . table_prefix.'logs WHERE page_id=\'' . $rb['page_id'] . '\' AND namespace=\'' . $rb['namespace'] . '\' AND log_type=\'page\' AND action=\'edit\' ORDER BY time_id DESC;'); if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); $r = $db->fetchrow(); - $e = $db->sql_query('INSERT INTO ' . table_prefix.'page_text(page_id,namespace,page_text,char_tag) VALUES(\'' . $rb['page_id'] . '\',\'' . $rb['namespace'] . '\',\'' . $db->escape($r['page_text']) . '\',\'' . $r['char_tag'] . '\')'); if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".mysql_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); - return 'The page "' . $name . '" has been undeleted according to the log created at ' . $rb['date_string'] . '.'; + $e = $db->sql_query('INSERT INTO ' . table_prefix.'page_text(page_id,namespace,page_text,char_tag) VALUES(\'' . $rb['page_id'] . '\',\'' . $rb['namespace'] . '\',\'' . $db->escape($r['page_text']) . '\',\'' . $r['char_tag'] . '\')'); if(!$e) return("An error occurred during the rollback operation.\nMySQL said: ".$db->get_error()."\n\nSQL backtrace:\n".$db->sql_backtrace()); + return 'The page "' . $name . '" has been undeleted according to the log created at ' . enano_date('d M Y h:i a', intval($rb['time_id'])) . '.'; break; case "reupload": if ( !$session->get_permissions('history_rollback_extra') ) @@ -853,12 +658,12 @@ return 'Administrative privileges are required for file rollbacks.'; } $newtime = time(); - $newdate = date('d M Y h:i a'); + $newdate = enano_date('d M Y h:i a'); if(!$db->sql_query('UPDATE ' . table_prefix.'logs SET time_id=' . $newtime . ',date_string=\'' . $newdate . '\' WHERE time_id=' . $id)) - return 'Error during query: '.mysql_error(); + return 'Error during query: '.$db->get_error(); if(!$db->sql_query('UPDATE ' . table_prefix.'files SET time_id=' . $newtime . ' WHERE time_id=' . $id)) - return 'Error during query: '.mysql_error(); - return 'The file has been rolled back to the version uploaded on '.date('d M Y h:i a', (int)$id).'.'; + return 'Error during query: '.$db->get_error(); + return 'The file has been rolled back to the version uploaded on '.enano_date('d M Y h:i a', (int)$id).'.'; break; default: return('Rollback of the action "' . $rb['action'] . '" is not yet supported.'); @@ -884,7 +689,7 @@ * @return string javascript code */ - function addcomment($page_id, $namespace, $name, $subject, $text, $captcha_code = false, $captcha_id = false) + public static function addcomment($page_id, $namespace, $name, $subject, $text, $captcha_code = false, $captcha_id = false) { global $db, $session, $paths, $template, $plugins; // Common objects $_ob = ''; @@ -903,7 +708,7 @@ if(getConfig('approve_comments')=='1') $appr = '0'; else $appr = '1'; $q = 'INSERT INTO ' . table_prefix.'comments(page_id,namespace,subject,comment_data,name,user_id,approved,time) VALUES(\'' . $page_id . '\',\'' . $namespace . '\',\'' . $subj . '\',\'' . $text . '\',\'' . $name . '\',' . $session->user_id . ',' . $appr . ','.time().')'; $e = $db->sql_query($q); - if(!$e) die('alert(unescape(\''.rawurlencode('Error inserting comment data: '.mysql_error().'\n\nQuery:\n' . $q) . '\'))'); + if(!$e) die('alert(unescape(\''.rawurlencode('Error inserting comment data: '.$db->get_error().'\n\nQuery:\n' . $q) . '\'))'); else $_ob .= '
Your comment has been posted.
'; return PageUtils::comments($page_id, $namespace, false, Array(), $_ob); } @@ -919,9 +724,10 @@ * @access private */ - function comments_raw($page_id, $namespace, $action = false, $flags = Array(), $_ob = '') + public static function comments_raw($page_id, $namespace, $action = false, $flags = Array(), $_ob = '') { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; $pname = $paths->nslist[$namespace] . $page_id; @@ -941,7 +747,7 @@ $q = 'DELETE FROM ' . table_prefix.'comments WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND name=\'' . $n . '\' AND subject=\'' . $s . '\' AND comment_data=\'' . $t . '\' LIMIT 1;'; } $e=$db->sql_query($q); - if(!$e) die('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n' . $q) . '\'));'); + if(!$e) die('alert(unesape(\''.rawurlencode('Error during query: '.$db->get_error().'\n\nQuery:\n' . $q) . '\'));'); break; case "approve": if(isset($flags['id'])) @@ -955,15 +761,15 @@ } $q = 'SELECT approved FROM ' . table_prefix.'comments WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND ' . $where . ' LIMIT 1;'; $e = $db->sql_query($q); - if(!$e) die('alert(unesape(\''.rawurlencode('Error selecting approval status: '.mysql_error().'\n\nQuery:\n' . $q) . '\'));'); + if(!$e) die('alert(unesape(\''.rawurlencode('Error selecting approval status: '.$db->get_error().'\n\nQuery:\n' . $q) . '\'));'); $r = $db->fetchrow(); $db->free_result(); $a = ( $r['approved'] ) ? '0' : '1'; $q = 'UPDATE ' . table_prefix.'comments SET approved=' . $a . ' WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND ' . $where . ';'; $e=$db->sql_query($q); - if(!$e) die('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n' . $q) . '\'));'); - if($a=='1') $v = 'Unapprove'; - else $v = 'Approve'; + if(!$e) die('alert(unesape(\''.rawurlencode('Error during query: '.$db->get_error().'\n\nQuery:\n' . $q) . '\'));'); + if($a=='1') $v = $lang->get('comment_btn_mod_unapprove'); + else $v = $lang->get('comment_btn_mod_approve'); echo 'document.getElementById("mdgApproveLink'.intval($_GET['id']).'").innerHTML="' . $v . '";'; break; } @@ -984,29 +790,39 @@ if(!$e) $db->_die('The comment text data could not be selected.'); $num_app = $db->numrows(); $db->free_result(); - $lq = $db->sql_query('SELECT c.comment_id,c.subject,c.name,c.comment_data,c.approved,c.time,c.user_id,u.user_level,u.signature + $lq = $db->sql_query('SELECT c.comment_id,c.subject,c.name,c.comment_data,c.approved,c.time,c.user_id,c.ip_address,u.user_level,u.signature,u.user_has_avatar,u.avatar_type FROM ' . table_prefix.'comments AS c LEFT JOIN ' . table_prefix.'users AS u ON c.user_id=u.user_id WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' ORDER BY c.time ASC;'); - if(!$lq) _die('The comment text data could not be selected. '.mysql_error()); - $_ob .= '

Article Comments

'; + if(!$lq) _die('The comment text data could not be selected. '.$db->get_error()); + $_ob .= '

' . $lang->get('comment_heading') . '

'; + $n = ( $session->get_permissions('mod_comments')) ? $db->numrows() : $num_app; - if($n==1) $s = 'is ' . $n . ' comment'; else $s = 'are ' . $n . ' comments'; - if($n < 1) + + $subst = array( + 'num_comments' => $n, + 'page_type' => $template->namespace_string + ); + + $_ob .= '

'; + $_ob .= ( $n == 0 ) ? $lang->get('comment_msg_count_zero', $subst) : ( $n == 1 ? $lang->get('comment_msg_count_one', $subst) : $lang->get('comment_msg_count_plural', $subst) ); + + if ( $session->get_permissions('mod_comments') && $num_unapp > 0 ) { - $_ob .= '

There are currently no comments on this '.strtolower($namespace).''; - if($namespace != 'Article') $_ob .= ' page'; - $_ob .= '.

'; - } else $_ob .= '

There ' . $s . ' on this article.'; - if($session->get_permissions('mod_comments') && $num_unapp > 0) $_ob .= ' ' . $num_unapp . ' of those are unapproved.'; - elseif(!$session->get_permissions('mod_comments') && $num_unapp > 0) { $u = ($num_unapp == 1) ? "is $num_unapp comment" : "are $num_unapp comments"; $_ob .= ' However, there ' . $u . ' awating approval.'; } + $_ob .= ' ' . $lang->get('comment_msg_count_unapp_mod', array( 'num_unapp' => $num_unapp )) . ''; + } + else if ( !$session->get_permissions('mod_comments') && $num_unapp > 0 ) + { + $ls = ( $num_unapp == 1 ) ? 'comment_msg_count_unapp_one' : 'comment_msg_count_unapp_plural'; + $_ob .= ' ' . $lang->get($ls, array( 'num_unapp' => $num_unapp )) . ''; + } $_ob .= '

'; $list = 'list = { '; // _die(htmlspecialchars($ttext)); $i = -1; - while($row = $db->fetchrow($lq)) + while ( $row = $db->fetchrow($lq) ) { $i++; $strings = Array(); @@ -1020,34 +836,35 @@ // Determine the name, and whether to link to the user page or not $name = ''; - if($row['user_id'] > 0) $name .= ''; + if($row['user_id'] > 1) $name .= ''; $name .= $row['name']; - if($row['user_id'] > 0) $name .= ''; + if($row['user_id'] > 1) $name .= ''; $strings['NAME'] = $name; unset($name); // Subject $s = $row['subject']; - if(!$row['approved']) $s .= ' (Unapproved)'; + if(!$row['approved']) $s .= ' ' . $lang->get('comment_msg_note_unapp') . ''; $strings['SUBJECT'] = $s; // Date and time - $strings['DATETIME'] = date('F d, Y h:i a', $row['time']); + $strings['DATETIME'] = enano_date('F d, Y h:i a', $row['time']); // User level switch($row['user_level']) { default: case USER_LEVEL_GUEST: - $l = 'Guest'; + $l = $lang->get('user_type_guest'); break; case USER_LEVEL_MEMBER: - $l = 'Member'; + case USER_LEVEL_CHPREF: + $l = $lang->get('user_type_member'); break; case USER_LEVEL_MOD: - $l = 'Moderator'; + $l = $lang->get('user_type_mod'); break; case USER_LEVEL_ADMIN: - $l = 'Administrator'; + $l = $lang->get('user_type_admin'); break; } $strings['USER_LEVEL'] = $l; unset($l); @@ -1058,10 +875,10 @@ if($session->get_permissions('edit_comments')) { // Edit link - $strings['EDIT_LINK'] = 'edit'; + $strings['EDIT_LINK'] = '' . $lang->get('comment_btn_edit') . ''; // Delete link - $strings['DELETE_LINK'] = 'delete'; + $strings['DELETE_LINK'] = '' . $lang->get('comment_btn_delete') . ''; } else { @@ -1073,24 +890,34 @@ } // Send PM link - $strings['SEND_PM_LINK'] = ( $session->user_logged_in && $row['user_id'] > 0 ) ? 'Send private message
' : ''; + $strings['SEND_PM_LINK'] = ( $session->user_logged_in && $row['user_id'] > 1 ) ? '' . $lang->get('comment_btn_send_privmsg') . '
' : ''; // Add Buddy link - $strings['ADD_BUDDY_LINK'] = ( $session->user_logged_in && $row['user_id'] > 0 ) ? 'Add to buddy list' : ''; + $strings['ADD_BUDDY_LINK'] = ( $session->user_logged_in && $row['user_id'] > 1 ) ? '' . $lang->get('comment_btn_add_buddy') . '' : ''; // Mod links $applink = ''; $applink .= ''; - if($row['approved']) $applink .= 'Unapprove'; - else $applink .= 'Approve'; + if($row['approved']) $applink .= $lang->get('comment_btn_mod_unapprove'); + else $applink .= $lang->get('comment_btn_mod_approve'); $applink .= ''; $strings['MOD_APPROVE_LINK'] = $applink; unset($applink); - $strings['MOD_DELETE_LINK'] = 'Delete'; + $strings['MOD_DELETE_LINK'] = '' . $lang->get('comment_btn_mod_delete') . ''; + $strings['MOD_IP_LINK'] = '' . ( ( empty($row['ip_address']) ) ? $lang->get('comment_btn_mod_ip_missing') : $lang->get('comment_btn_mod_ip_notimplemented') ) . ''; // Signature $strings['SIGNATURE'] = ''; if($row['signature'] != '') $strings['SIGNATURE'] = RenderMan::render($row['signature']); + // Avatar + if ( $row['user_has_avatar'] == 1 ) + { + $bool['user_has_avatar'] = true; + $strings['AVATAR_ALT'] = $lang->get('usercp_avatar_image_alt', array('username' => $row['name'])); + $strings['AVATAR_URL'] = make_avatar_url(intval($row['user_id']), $row['avatar_type']); + $strings['USERPAGE_LINK'] = makeUrlNS('User', $row['name']); + } + $bool['auth_mod'] = ($session->get_permissions('mod_comments')) ? true : false; $bool['can_edit'] = ( ( $session->user_logged_in && $row['name'] == $session->username && $session->get_permissions('edit_comments') ) || $session->get_permissions('mod_comments') ) ? true : false; $bool['signature'] = ( $strings['SIGNATURE'] == '' ) ? false : true; @@ -1103,32 +930,31 @@ } if(getConfig('comments_need_login') != '2' || $session->user_logged_in) { - if(!$session->get_permissions('post_comments')) - { - $_ob .= '

Got something to say?

Access to post comments on this page is denied.

'; - } - else + if($session->get_permissions('post_comments')) { - $_ob .= '

Got something to say?

If you have comments or suggestions on this article, you can shout it out here.'; - if(getConfig('approve_comments')=='1') $_ob .= ' Before your comment will be visible to the public, a moderator will have to approve it.'; - if(getConfig('comments_need_login') == '1' && !$session->user_logged_in) $_ob .= ' Because you are not logged in, you will need to enter a visual confirmation before your comment will be posted.'; + $_ob .= '

' . $lang->get('comment_postform_title') . '

'; + $_ob .= $lang->get('comment_postform_blurb'); + if(getConfig('approve_comments')=='1') $_ob .= ' ' . $lang->get('comment_postform_blurb_unapp'); + if(getConfig('comments_need_login') == '1' && !$session->user_logged_in) + { + $_ob .= ' ' . $lang->get('comment_postform_blurb_captcha'); + } $sn = $session->user_logged_in ? $session->username . '' : ''; - $_ob .= ' + $_ob .= '
-

Comment form

' . $lang->get('history_col_datetime') . '' . $lang->get('history_col_user') . '' . $lang->get('history_col_minor') . '' . $lang->get('history_col_action_taken') . '' . $lang->get('history_col_extra') . '
' . $r['date_string'] . '' . enano_date('d M Y h:i a', intval($r['time_id'])) . ''; // Some of these are sanitized at insert-time. Others follow the newer Enano policy of stripping HTML at runtime. - if ($r['action']=='prot') echo 'Protected pageReason: ' . $r['edit_summary']; - elseif($r['action']=='unprot') echo 'Unprotected pageReason: ' . $r['edit_summary']; - elseif($r['action']=='semiprot') echo 'Semi-protected pageReason: ' . $r['edit_summary']; - elseif($r['action']=='rename') echo 'Renamed pageOld title: '.htmlspecialchars($r['edit_summary']); - elseif($r['action']=='create') echo 'Created page'; - elseif($r['action']=='delete') echo 'Deleted pageReason: ' . $r['edit_summary']; - elseif($r['action']=='reupload') echo 'Uploaded new file versionReason: '.htmlspecialchars($r['edit_summary']); + if ($r['action']=='prot') echo $lang->get('history_log_protect') . '' . $lang->get('history_extra_reason') . ' ' . $r['edit_summary']; + elseif($r['action']=='unprot') echo $lang->get('history_log_unprotect') . '' . $lang->get('history_extra_reason') . ' ' . $r['edit_summary']; + elseif($r['action']=='semiprot') echo $lang->get('history_log_semiprotect') . '' . $lang->get('history_extra_reason') . ' ' . $r['edit_summary']; + elseif($r['action']=='rename') echo $lang->get('history_log_rename') . '' . $lang->get('history_extra_oldtitle') . ' '.htmlspecialchars($r['edit_summary']); + elseif($r['action']=='create') echo $lang->get('history_log_create') . ''; + elseif($r['action']=='delete') echo $lang->get('history_log_delete') . '' . $lang->get('history_extra_reason') . ' ' . $r['edit_summary']; + elseif($r['action']=='reupload') echo $lang->get('history_log_uploadnew') . '' . $lang->get('history_extra_reason') . ' '.htmlspecialchars($r['edit_summary']); echo 'View user contribsRevert action' . $lang->get('history_action_contrib') . '' . $lang->get('history_action_revert') . '
- - '; + + '; if(getConfig('comments_need_login') == '1' && !$session->user_logged_in) { $session->kill_captcha(); $captcha = $session->make_captcha(); - $_ob .= ''; + $_ob .= ''; } $_ob .= ' - - + +
Your name or screen name:' . $sn . '
Comment subject:
' . $lang->get('comment_postform_field_name') . '' . $sn . '
' . $lang->get('comment_postform_field_subject') . '
Visual confirmation:
Please enter the code you see on the right.
Visual confirmation
Code:
' . $lang->get('comment_postform_field_captcha_title') . '
' . $lang->get('comment_postform_field_captcha_blurb') . '
Visual confirmation
' . $lang->get('comment_postform_field_captcha_label') . '
Comment text:
(most HTML will be stripped)
' . $lang->get('comment_postform_field_comment') . '
'; @@ -1157,7 +983,7 @@ * @return string */ - function comments($page_id, $namespace, $action = false, $id = -1, $_ob = '') + public static function comments($page_id, $namespace, $action = false, $id = -1, $_ob = '') { global $db, $session, $paths, $template, $plugins; // Common objects $r = PageUtils::comments_raw($page_id, $namespace, $action, $id, $_ob); @@ -1174,7 +1000,7 @@ * @return string */ - function comments_html($page_id, $namespace, $action = false, $id = -1, $_ob = '') + public static function comments_html($page_id, $namespace, $action = false, $id = -1, $_ob = '') { global $db, $session, $paths, $template, $plugins; // Common objects $r = PageUtils::comments_raw($page_id, $namespace, $action, $id, $_ob); @@ -1193,7 +1019,7 @@ * @return string */ - function savecomment($page_id, $namespace, $subject, $text, $old_subject, $old_text, $id = -1) + public static function savecomment($page_id, $namespace, $subject, $text, $old_subject, $old_text, $id = -1) { global $db, $session, $paths, $template, $plugins; // Common objects if(!$session->get_permissions('edit_comments')) @@ -1207,7 +1033,7 @@ if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.

Please log in and try again.'); $q = 'SELECT c.name FROM ' . table_prefix.'comments c, ' . table_prefix.'users u WHERE comment_data=\'' . $old_text . '\' AND subject=\'' . $old_subject . '\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND u.user_id=c.user_id;'; $s = $db->sql_query($q); - if(!$s) _die('SQL error during safety check: '.mysql_error().'

Attempted SQL:
'.htmlspecialchars($q).'
'); + if(!$s) _die('SQL error during safety check: '.$db->get_error().'

Attempted SQL:
'.htmlspecialchars($q).'
'); $r = $db->fetchrow($s); $db->free_result(); if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); @@ -1230,7 +1056,7 @@ Performed SQL: ' . $sql . ' - Error returned by MySQL: '.mysql_error()).'");'; + Error returned by MySQL: '.$db->get_error()).'");'; } } @@ -1244,7 +1070,7 @@ * @return string */ - function savecomment_neater($page_id, $namespace, $subject, $text, $id) + public static function savecomment_neater($page_id, $namespace, $subject, $text, $id) { global $db, $session, $paths, $template, $plugins; // Common objects if(!is_int($id)) die('PageUtils::savecomment: $id is not an integer, aborting for safety'); @@ -1256,7 +1082,7 @@ if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.

Please log in and try again.'); $q = 'SELECT c.name FROM ' . table_prefix.'comments c, ' . table_prefix.'users u WHERE comment_id=' . $id . ' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND u.user_id=c.user_id;'; $s = $db->sql_query($q); - if(!$s) _die('SQL error during safety check: '.mysql_error().'

Attempted SQL:
'.htmlspecialchars($q).'
'); + if(!$s) _die('SQL error during safety check: '.$db->get_error().'

Attempted SQL:
'.htmlspecialchars($q).'
'); $r = $db->fetchrow($s); if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); $db->free_result(); @@ -1271,7 +1097,7 @@ Performed SQL: ' . $sql . ' - Error returned by MySQL: '.mysql_error(); + Error returned by MySQL: '.$db->get_error(); } /** @@ -1285,7 +1111,7 @@ * @return string */ - function deletecomment($page_id, $namespace, $name, $subj, $text, $id) + public static function deletecomment($page_id, $namespace, $name, $subj, $text, $id) { global $db, $session, $paths, $template, $plugins; // Common objects @@ -1303,14 +1129,14 @@ if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.

Please log in and try again.'); $q = 'SELECT c.name FROM ' . table_prefix.'comments c, ' . table_prefix.'users u WHERE comment_data=\'' . $t . '\' AND subject=\'' . $s . '\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND u.user_id=c.user_id;'; $s = $db->sql_query($q); - if(!$s) _die('SQL error during safety check: '.mysql_error().'

Attempted SQL:
'.htmlspecialchars($q).'
'); + if(!$s) _die('SQL error during safety check: '.$db->get_error().'

Attempted SQL:
'.htmlspecialchars($q).'
'); $r = $db->fetchrow($s); if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); $db->free_result(); } $q = 'DELETE FROM ' . table_prefix.'comments WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND name=\'' . $n . '\' AND subject=\'' . $s . '\' AND comment_data=\'' . $t . '\' LIMIT 1;'; $e=$db->sql_query($q); - if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n' . $q) . '\'));'); + if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.$db->get_error().'\n\nQuery:\n' . $q) . '\'));'); return('good'); } @@ -1322,7 +1148,7 @@ * @return string */ - function deletecomment_neater($page_id, $namespace, $id) + public static function deletecomment_neater($page_id, $namespace, $id) { global $db, $session, $paths, $template, $plugins; // Common objects @@ -1337,14 +1163,14 @@ if(!$session->user_logged_in) _die('AJAX comment save safety check failed because you are not logged in. Sometimes this can happen because you are using a browser that does not send cookies as part of AJAX requests.

Please log in and try again.'); $q = 'SELECT c.name FROM ' . table_prefix.'comments c, ' . table_prefix.'users u WHERE comment_id=' . $id . ' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND u.user_id=c.user_id;'; $s = $db->sql_query($q); - if(!$s) _die('SQL error during safety check: '.mysql_error().'

Attempted SQL:
'.htmlspecialchars($q).'
'); + if(!$s) _die('SQL error during safety check: '.$db->get_error().'

Attempted SQL:
'.htmlspecialchars($q).'
'); $r = $db->fetchrow($s); if($db->numrows() < 1 || $r['name'] != $session->username) _die('Safety check failed, probably due to a hacking attempt.'); $db->free_result(); } $q = 'DELETE FROM ' . table_prefix.'comments WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\' AND comment_id=' . $id . ' LIMIT 1;'; $e=$db->sql_query($q); - if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.mysql_error().'\n\nQuery:\n' . $q) . '\'));'); + if(!$e) return('alert(unesape(\''.rawurlencode('Error during query: '.$db->get_error().'\n\nQuery:\n' . $q) . '\'));'); return('good'); } @@ -1356,9 +1182,10 @@ * @return string error string or success message */ - function rename($page_id, $namespace, $name) + public static function rename($page_id, $namespace, $name) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; $pname = $paths->nslist[$namespace] . $page_id; @@ -1367,11 +1194,11 @@ if( empty($name)) { - die('Name is too short'); + return($lang->get('ajax_rename_too_short')); } if( ( $session->get_permissions('rename') && ( ( $prot && $session->get_permissions('even_when_protected') ) || !$prot ) ) && ( $paths->namespace != 'Special' && $paths->namespace != 'Admin' )) { - $e = $db->sql_query('INSERT INTO ' . table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'rename\', \'' . $db->escape($paths->page_id) . '\', \'' . $paths->namespace . '\', \'' . $db->escape($session->username) . '\', \'' . $db->escape($paths->cpage['name']) . '\')'); + $e = $db->sql_query('INSERT INTO ' . table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.enano_date('d M Y h:i a').'\', \'page\', \'rename\', \'' . $db->escape($paths->page_id) . '\', \'' . $paths->namespace . '\', \'' . $db->escape($session->username) . '\', \'' . $db->escape($paths->cpage['name']) . '\')'); if ( !$e ) { $db->_die('The page title could not be updated.'); @@ -1383,12 +1210,16 @@ } else { - return('The page "' . $paths->pages[$pname]['name'] . '" has been renamed to "' . $name . '". You are encouraged to leave a comment explaining your action.' . "\n\n" . 'You will see the change take effect the next time you reload this page.'); + $subst = array( + 'page_name_old' => $paths->pages[$pname]['name'], + 'page_name_new' => $name + ); + return $lang->get('ajax_rename_success', $subst); } } else { - return('Access is denied.'); + return($lang->get('etc_access_denied')); } } @@ -1399,10 +1230,19 @@ * @return string error/success string */ - function flushlogs($page_id, $namespace) + public static function flushlogs($page_id, $namespace) { global $db, $session, $paths, $template, $plugins; // Common objects - if(!$session->get_permissions('clear_logs')) die('Administrative privileges are required to flush logs, you loser.'); + global $lang; + if ( !is_object($lang) && defined('IN_ENANO_INSTALL') ) + { + // This is a special exception for the Enano installer, which doesn't init languages yet. + $lang = new Language('eng'); + } + if(!$session->get_permissions('clear_logs') && !defined('IN_ENANO_INSTALL')) + { + return $lang->get('etc_access_denied'); + } $e = $db->sql_query('DELETE FROM ' . table_prefix.'logs WHERE page_id=\'' . $db->escape($page_id) . '\' AND namespace=\'' . $db->escape($namespace) . '\';'); if(!$e) $db->_die('The log entries could not be deleted.'); @@ -1415,10 +1255,10 @@ $row = $db->fetchrow(); $db->free_result(); $minor_edit = ( ENANO_DBLAYER == 'MYSQL' ) ? 'false' : '0'; - $q='INSERT INTO ' . table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.date('d M Y h:i a').'\', \'' . $page_id . '\', \'' . $namespace . '\', \'' . $db->escape($row['page_text']) . '\', \'' . $row['char_tag'] . '\', \'' . $session->username . '\', \''."Automatic backup created when logs were purged".'\', '.$minor_edit.');'; + $q='INSERT INTO ' . table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.enano_date('d M Y h:i a').'\', \'' . $page_id . '\', \'' . $namespace . '\', \'' . $db->escape($row['page_text']) . '\', \'' . $row['char_tag'] . '\', \'' . $session->username . '\', \''."Automatic backup created when logs were purged".'\', '.$minor_edit.');'; if(!$db->sql_query($q)) $db->_die('The history (log) entry could not be inserted into the logs table.'); } - return('The logs for this page have been cleared. A backup of this page has been added to the logs table so that this page can be restored in case of vandalism or spam later.'); + return $lang->get('ajax_clearlogs_success'); } /** @@ -1429,17 +1269,18 @@ * @return string */ - function deletepage($page_id, $namespace, $reason) + public static function deletepage($page_id, $namespace, $reason) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; $perms = $session->fetch_page_acl($page_id, $namespace); $x = trim($reason); if ( empty($x) ) { - return 'Invalid reason for deletion passed'; + return $lang->get('ajax_delete_need_reason'); } if(!$perms->get_permissions('delete_page')) return('Administrative privileges are required to delete pages, you loser.'); - $e = $db->sql_query('INSERT INTO ' . table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'delete\', \'' . $page_id . '\', \'' . $namespace . '\', \'' . $session->username . '\', \'' . $db->escape(htmlspecialchars($reason)) . '\')'); + $e = $db->sql_query('INSERT INTO ' . table_prefix.'logs(time_id,date_string,log_type,action,page_id,namespace,author,edit_summary) VALUES('.time().', \''.enano_date('d M Y h:i a').'\', \'page\', \'delete\', \'' . $page_id . '\', \'' . $namespace . '\', \'' . $session->username . '\', \'' . $db->escape(htmlspecialchars($reason)) . '\')'); if(!$e) $db->_die('The page log entry could not be inserted.'); $e = $db->sql_query('DELETE FROM ' . table_prefix.'categories WHERE page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''); if(!$e) $db->_die('The page categorization entries could not be deleted.'); @@ -1451,7 +1292,7 @@ if(!$e) $db->_die('The page entry could not be deleted.'); $e = $db->sql_query('DELETE FROM ' . table_prefix.'files WHERE page_id=\'' . $page_id . '\''); if(!$e) $db->_die('The file entry could not be deleted.'); - return('This page has been deleted. Note that there is still a log of edits and actions in the database, and anyone with admin rights can raise this page from the dead unless the log is cleared. If the deleted file is an image, there may still be cached thumbnails of it in the cache/ directory, which is inaccessible to users.'); + return $lang->get('ajax_delete_success'); } /** @@ -1461,12 +1302,13 @@ * @return string */ - function delvote($page_id, $namespace) + public static function delvote($page_id, $namespace) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( !$session->get_permissions('vote_delete') ) { - return 'Access denied'; + return $lang->get('etc_access_denied'); } if ( $namespace == 'Admin' || $namespace == 'Special' || $namespace == 'System' ) @@ -1505,7 +1347,7 @@ if ( in_array($session->username, $ips['u']) || in_array($_SERVER['REMOTE_ADDR'], $ips['ip']) ) { - return 'It appears that you have already voted to have this page deleted.'; + return $lang->get('ajax_delvote_already_voted'); } $ips['u'][] = $session->username; @@ -1517,7 +1359,7 @@ $q = 'UPDATE ' . table_prefix.'pages SET delvotes=' . $cv . ',delvote_ips=\'' . $ips . '\' WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''; $w = $db->sql_query($q); - return 'Your vote to have this page deleted has been cast.'."\nYou are encouraged to leave a comment explaining the reason for your vote."; + return $lang->get('ajax_delvote_success'); } /** @@ -1527,14 +1369,21 @@ * @return string */ - function resetdelvotes($page_id, $namespace) + public static function resetdelvotes($page_id, $namespace) { global $db, $session, $paths, $template, $plugins; // Common objects - if(!$session->get_permissions('vote_reset')) die('You need moderator rights in order to do this, stinkin\' hacker.'); + global $lang; + if(!$session->get_permissions('vote_reset')) + { + return $lang->get('etc_access_denied'); + } $q = 'UPDATE ' . table_prefix.'pages SET delvotes=0,delvote_ips=\'' . $db->escape(serialize(array('ip'=>array(),'u'=>array()))) . '\' WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\''; $e = $db->sql_query($q); if(!$e) $db->_die('The number of delete votes was not reset.'); - else return('The number of votes for having this page deleted has been reset to zero.'); + else + { + return $lang->get('ajax_delvote_reset_success'); + } } /** @@ -1543,12 +1392,11 @@ * @return string JSON string with an array containing a list of themes */ - function getstyles() + public static function getstyles() { - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); if ( !preg_match('/^([a-z0-9_-]+)$/', $_GET['id']) ) - return $json->encode(false); + return enano_json_encode(false); $dir = './themes/' . $_GET['id'] . '/css/'; $list = Array(); @@ -1568,10 +1416,10 @@ } else { - return($json->encode(Array('mode' => 'error', 'error' => $dir.' is not a dir'))); + return(enano_json_encode(Array('mode' => 'error', 'error' => $dir.' is not a dir'))); } - return $json->encode($list); + return enano_json_encode($list); } /** @@ -1581,7 +1429,7 @@ * @return string Javascript code */ - function catedit($page_id, $namespace) + public static function catedit($page_id, $namespace) { $d = PageUtils::catedit_raw($page_id, $namespace); return $d[0] . ' /* BEGIN CONTENT */ document.getElementById("ajaxEditContainer").innerHTML = unescape(\''.rawurlencode($d[1]).'\');'; @@ -1592,13 +1440,15 @@ * @access private */ - function catedit_raw($page_id, $namespace) + public static function catedit_raw($page_id, $namespace) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + ob_start(); $_ob = ''; $e = $db->sql_query('SELECT category_id FROM ' . table_prefix.'categories WHERE page_id=\'' . $paths->page_id . '\' AND namespace=\'' . $paths->namespace . '\''); - if(!$e) jsdie('Error selecting category information for current page: '.mysql_error()); + if(!$e) jsdie('Error selecting category information for current page: '.$db->get_error()); $cat_current = Array(); while($r = $db->fetchrow()) { @@ -1632,11 +1482,11 @@ } echo 'catlist = new Array();'; // Initialize the client-side category list - $_ob .= '

Select which categories this page should be included in.

+ $_ob .= '

' . $lang->get('catedit_title') . '

'; if ( sizeof($cat_info) < 1 ) { - $_ob .= '

There are no categories on this site yet.

'; + $_ob .= '

' . $lang->get('catedit_no_categories') . '

'; } for ( $i = 0; $i < sizeof($cat_info) / 2; $i++ ) { @@ -1657,7 +1507,7 @@ $disabled = ( sizeof($cat_info) < 1 ) ? 'disabled="disabled"' : ''; - $_ob .= '
'; + $_ob .= '
'; $cont = ob_get_contents(); ob_end_clean(); @@ -1673,7 +1523,7 @@ * @return string "GOOD" on success, error string on failure */ - function catsave($page_id, $namespace, $which_cats) + public static function catsave($page_id, $namespace, $which_cats) { global $db, $session, $paths, $template, $plugins; // Common objects if(!$session->get_permissions('edit_cat')) return('Insufficient privileges to change category information'); @@ -1745,7 +1595,7 @@ * @return string "GOOD" on success, error string on failure */ - function setwikimode($page_id, $namespace, $level) + public static function setwikimode($page_id, $namespace, $level) { global $db, $session, $paths, $template, $plugins; // Common objects if(!$session->get_permissions('set_wiki_mode')) return('Insufficient access rights'); @@ -1756,7 +1606,7 @@ $q = $db->sql_query('UPDATE ' . table_prefix.'pages SET wiki_mode=' . $level . ' WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';'); if ( !$q ) { - return('Error during update query: '.mysql_error()."\n\nSQL Backtrace:\n".$db->sql_backtrace()); + return('Error during update query: '.$db->get_error()."\n\nSQL Backtrace:\n".$db->sql_backtrace()); } return('GOOD'); } @@ -1769,16 +1619,17 @@ * @return string */ - function setpass($page_id, $namespace, $pass) + public static function setpass($page_id, $namespace, $pass) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; // Determine permissions if($paths->pages[$paths->nslist[$namespace].$page_id]['password'] != '') $a = $session->get_permissions('password_reset'); else $a = $session->get_permissions('password_set'); if(!$a) - return 'Access is denied'; + return $lang->get('etc_access_denied'); if(!isset($pass)) return('Password was not set on URL'); $p = $pass; if ( !preg_match('#([0-9a-f]){40,40}#', $p) ) @@ -1791,14 +1642,17 @@ $e = $db->sql_query('UPDATE ' . table_prefix.'pages SET password=\'' . $p . '\' WHERE urlname=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';'); if ( !$e ) { - die('PageUtils::setpass(): Error during update query: '.mysql_error()."\n\nSQL Backtrace:\n".$db->sql_backtrace()); + die('PageUtils::setpass(): Error during update query: '.$db->get_error()."\n\nSQL Backtrace:\n".$db->sql_backtrace()); } // Is the new password blank? if ( $p == '' ) { - return('The password for this page has been disabled.'); + return $lang->get('ajax_password_disable_success'); } - else return('The password for this page has been set.'); + else + { + return $lang->get('ajax_password_success'); + } } /** @@ -1807,9 +1661,10 @@ * @return string */ - function genPreview($text) + public static function genPreview($text) { - $ret = '
Reminder: This is only a preview - your changes to this page have not yet been saved.
'; + global $lang; + $ret = '
' . $lang->get('editor_preview_blurb') . '
'; $text = RenderMan::render(RenderMan::preprocess_text($text, false, false)); ob_start(); eval('?>' . $text); @@ -1827,7 +1682,7 @@ * @return string */ - function scrollBox($text, $height = 250) + public static function scrollBox($text, $height = 250) { return '
' . $text . '
'; } @@ -1841,17 +1696,18 @@ * @return string XHTML-formatted diff */ - function pagediff($page_id, $namespace, $id1, $id2) + public static function pagediff($page_id, $namespace, $id1, $id2) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if(!$session->get_permissions('history_view')) - return 'Access denied'; + return $lang->get('etc_access_denied'); if(!preg_match('#^([0-9]+)$#', (string)$id1) || !preg_match('#^([0-9]+)$#', (string)$id2 )) return 'SQL injection attempt'; // OK we made it through security // Safest way to make sure we don't end up with the revisions in wrong columns is to make 2 queries - if(!$q1 = $db->sql_query('SELECT page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE time_id=' . $id1 . ' AND log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';')) return 'MySQL error: '.mysql_error(); - if(!$q2 = $db->sql_query('SELECT page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE time_id=' . $id2 . ' AND log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';')) return 'MySQL error: '.mysql_error(); + if(!$q1 = $db->sql_query('SELECT page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE time_id=' . $id1 . ' AND log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';')) return 'MySQL error: '.$db->get_error(); + if(!$q2 = $db->sql_query('SELECT page_text,char_tag,author,edit_summary FROM ' . table_prefix.'logs WHERE time_id=' . $id2 . ' AND log_type=\'page\' AND action=\'edit\' AND page_id=\'' . $page_id . '\' AND namespace=\'' . $namespace . '\';')) return 'MySQL error: '.$db->get_error(); $row1 = $db->fetchrow($q1); $db->free_result($q1); $row2 = $db->fetchrow($q2); @@ -1859,10 +1715,10 @@ if(sizeof($row1) < 1 || sizeof($row2) < 2) return 'Couldn\'t find any rows that matched the query. The time ID probably doesn\'t exist in the logs table.'; $text1 = $row1['page_text']; $text2 = $row2['page_text']; - $time1 = date('F d, Y h:i a', $id1); - $time2 = date('F d, Y h:i a', $id2); + $time1 = enano_date('F d, Y h:i a', $id1); + $time2 = enano_date('F d, Y h:i a', $id2); $_ob = " -

Comparing revisions: {$time1} → {$time2}

+

" . $lang->get('history_lbl_comparingrevisions') . " {$time1} → {$time2}

"; // Free some memory unset($row1, $row2, $q1, $q2); @@ -1873,20 +1729,20 @@ /** * Gets ACL information about the selected page for target type X and target ID Y. - * @param string $page_id The page ID - * @param string $namespace The namespace * @param array $parms What to select. This is an array purely for JSON compatibility. It should be an associative array with keys target_type and target_id. * @return array */ - function acl_editor($parms = Array()) + public static function acl_editor($parms = Array()) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + if(!$session->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN) { return Array( 'mode' => 'error', - 'error' => 'You are not authorized to view or edit access control lists.' + 'error' => $lang->get('acl_err_access_denied') ); } $parms['page_id'] = ( isset($parms['page_id']) ) ? $parms['page_id'] : false; @@ -1904,7 +1760,7 @@ { return Array( 'mode' => 'error', - 'error' => 'It seems that (a) the file acledit.tpl is missing from these theme, and (b) the JSON response is working.', + 'error' => $lang->get('acl_err_missing_template'), ); } $return['template'] = $template->extract_vars('acledit.tpl'); @@ -1957,19 +1813,19 @@ AND u.username=\'' . $db->escape($parms['target_id']) . '\' ' . $page_where_clause . ';'); if(!$q) - return(Array('mode'=>'error','error'=>mysql_error())); + return(Array('mode'=>'error','error'=>$db->get_error())); if($db->numrows() < 1) { $return['type'] = 'new'; $q = $db->sql_query('SELECT user_id FROM ' . table_prefix.'users WHERE username=\'' . $db->escape($parms['target_id']) . '\';'); if(!$q) - return(Array('mode'=>'error','error'=>mysql_error())); + return(Array('mode'=>'error','error'=>$db->get_error())); if($db->numrows() < 1) - return Array('mode'=>'error','error'=>'The username you entered was not found.'); + return Array('mode'=>'error','error'=>$lang->get('acl_err_user_not_found')); $row = $db->fetchrow(); $return['target_name'] = $return['target_id']; $return['target_id'] = intval($row['user_id']); - $return['current_perms'] = $session->acl_types; + $return['current_perms'] = array(); } else { @@ -1977,7 +1833,7 @@ $row = $db->fetchrow(); $return['target_name'] = $return['target_id']; $return['target_id'] = intval($row['user_id']); - $return['current_perms'] = $session->acl_merge($perms_obj->acl_types, $session->string_to_perm($row['rules'])); + $return['current_perms'] = $session->string_to_perm($row['rules']); } $db->free_result(); // Eliminate types that don't apply to this namespace @@ -2004,19 +1860,19 @@ AND g.group_id=\''.intval($parms['target_id']).'\' ' . $page_where_clause . ';'); if(!$q) - return(Array('mode'=>'error','error'=>mysql_error())); + return(Array('mode'=>'error','error'=>$db->get_error())); if($db->numrows() < 1) { $return['type'] = 'new'; $q = $db->sql_query('SELECT group_id,group_name FROM ' . table_prefix.'groups WHERE group_id=\''.intval($parms['target_id']).'\';'); if(!$q) - return(Array('mode'=>'error','error'=>mysql_error())); + return(Array('mode'=>'error','error'=>$db->get_error())); if($db->numrows() < 1) - return Array('mode'=>'error','error'=>'The group ID you submitted is not valid.'); + return Array('mode'=>'error','error'=>$lang->get('acl_err_bad_group_id')); $row = $db->fetchrow(); $return['target_name'] = $row['group_name']; $return['target_id'] = intval($row['group_id']); - $return['current_perms'] = $session->acl_types; + $return['current_perms'] = array(); } else { @@ -2024,7 +1880,7 @@ $row = $db->fetchrow(); $return['target_name'] = $row['group_name']; $return['target_id'] = intval($row['group_id']); - $return['current_perms'] = $session->acl_merge($session->acl_types, $session->string_to_perm($row['rules'])); + $return['current_perms'] = $session->string_to_perm($row['rules']); } $db->free_result(); // Eliminate types that don't apply to this namespace @@ -2054,25 +1910,30 @@ case 'save_edit': if ( defined('ENANO_DEMO_MODE') ) { - return Array('mode'=>'error','error'=>'Editing access control lists is disabled in the administration demo.'); + return Array('mode'=>'error','error'=>$lang->get('acl_err_demo')); } $q = $db->sql_query('DELETE FROM ' . table_prefix.'acl WHERE target_type='.intval($parms['target_type']).' AND target_id='.intval($parms['target_id']).' ' . $page_where_clause_lite . ';'); if(!$q) - return Array('mode'=>'error','error'=>mysql_error()); - $rules = $session->perm_to_string($parms['perms']); - if ( sizeof ( $rules ) < 1 ) + return Array('mode'=>'error','error'=>$db->get_error()); + if ( sizeof ( $parms['perms'] ) < 1 ) { - return array( - 'mode' => 'error', - 'error' => 'Supplied rule list has a length of zero' - ); + // As of 1.1.x, this returns success because the rule length is zero if the user selected "inherit" in all columns + return Array( + 'mode' => 'success', + 'target_type' => $parms['target_type'], + 'target_id' => $parms['target_id'], + 'target_name' => $parms['target_name'], + 'page_id' => $page_id, + 'namespace' => $namespace, + ); } + $rules = $session->perm_to_string($parms['perms']); $q = ($page_id && $namespace) ? 'INSERT INTO ' . table_prefix.'acl ( target_type, target_id, page_id, namespace, rules ) VALUES( '.intval($parms['target_type']).', '.intval($parms['target_id']).', \'' . $db->escape($page_id) . '\', \'' . $db->escape($namespace) . '\', \'' . $db->escape($rules) . '\' )' : 'INSERT INTO ' . table_prefix.'acl ( target_type, target_id, rules ) VALUES( '.intval($parms['target_type']).', '.intval($parms['target_id']).', \'' . $db->escape($rules) . '\' )'; - if(!$db->sql_query($q)) return Array('mode'=>'error','error'=>mysql_error()); + if(!$db->sql_query($q)) return Array('mode'=>'error','error'=>$db->get_error()); return Array( 'mode' => 'success', 'target_type' => $parms['target_type'], @@ -2085,12 +1946,12 @@ case 'delete': if ( defined('ENANO_DEMO_MODE') ) { - return Array('mode'=>'error','error'=>'Editing access control lists is disabled in the administration demo.'); + return Array('mode'=>'error','error'=>$lang->get('acl_err_demo')); } $q = $db->sql_query('DELETE FROM ' . table_prefix.'acl WHERE target_type='.intval($parms['target_type']).' AND target_id='.intval($parms['target_id']).' ' . $page_where_clause_lite . ';'); if(!$q) - return Array('mode'=>'error','error'=>mysql_error()); + return Array('mode'=>'error','error'=>$db->get_error()); return Array( 'mode' => 'delete', 'target_type' => $parms['target_type'], @@ -2114,13 +1975,12 @@ * @return string */ - function acl_json($parms = '{ }') + public static function acl_json($parms = '{ }') { global $db, $session, $paths, $template, $plugins; // Common objects - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - $parms = $json->decode($parms); + $parms = enano_json_decode($parms); $ret = PageUtils::acl_editor($parms); - $ret = $json->encode($ret); + $ret = enano_json_encode($ret); return $ret; } @@ -2129,9 +1989,10 @@ * @param array The request data, if any, this should be in the format required by PageUtils::acl_editor() */ - function aclmanager($parms) + public static function aclmanager($parms) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; ob_start(); // Convenience $formstart = '
' . htmlspecialchars($response['text']) . ''; break; case 'stage1': - echo '

Manage page access

-

Please select who should be affected by this access rule.

'; + echo '

' . $lang->get('acl_lbl_welcome_title') . '

+

' . $lang->get('acl_lbl_welcome_body') . '

'; echo $formstart; - echo '

+ echo '

A group of pages

+ $groupsel = '

-

+

' . $template->username_field('data[target_id_user]') . '

-

What should this access rule control?

-

+

' . $lang->get('acl_lbl_scope') . '

+

' . $groupsel . ' -

+

- +
'; echo $formend; break; case 'success': echo '
- Permissions updated
- The permissions for ' . $response['target_name'] . ' on this page have been updated successfully.
+ ' . $lang->get('acl_lbl_save_success_title') . '
+ ' . $lang->get('acl_lbl_save_success_body', array( 'target_name' => $response['target_name'] )) . '
' . $formstart . ' @@ -2201,14 +2063,14 @@ - + ' . $formend . '
'; break; case 'delete': echo '
- Rule deleted
- The selected access rule has been successfully deleted.
+ ' . $lang->get('acl_lbl_delete_success_title') . '
+ ' . $lang->get('acl_lbl_delete_success_body', array('target_name' => $response['target_name'])) . '
' . $formstart . ' @@ -2217,22 +2079,27 @@ - + ' . $formend . '
'; break; case 'seltarget': if ( $response['type'] == 'edit' ) { - echo '

Editing permissions

'; + echo '

' . $lang->get('acl_lbl_editwin_title_edit') . '

'; } else { - echo '

Create new rule

'; + echo '

' . $lang->get('acl_lbl_editwin_title_create') . '

'; } - $type = ( $response['target_type'] == ACL_TYPE_GROUP ) ? 'group' : 'user'; - $scope = ( $response['page_id'] ) ? ( $response['namespace'] == '__PageGroup' ? 'this group of pages' : 'this page' ) : 'this entire site'; - echo 'This panel allows you to edit what the ' . $type . ' "' . $response['target_name'] . '" can do on ' . $scope . '. Unless you set a permission to "Deny", these permissions may be overridden by other rules.'; + $type = ( $response['target_type'] == ACL_TYPE_GROUP ) ? $lang->get('acl_target_type_group') : $lang->get('acl_target_type_user'); + $scope = ( $response['page_id'] ) ? ( $response['namespace'] == '__PageGroup' ? $lang->get('acl_scope_type_pagegroup') : $lang->get('acl_scope_type_thispage') ) : $lang->get('acl_scope_type_wholesite'); + $subs = array( + 'target_type' => $type, + 'target' => $response['target_name'], + 'scope_type' => $scope + ); + echo $lang->get('acl_lbl_editwin_body', $subs); echo $formstart; $parser = $template->makeParserText( $response['template']['acl_field_begin'] ); echo $parser->run(); @@ -2241,6 +2108,7 @@ foreach ( $response['acl_types'] as $acl_type => $value ) { $vars = Array( + 'FIELD_INHERIT_CHECKED' => '', 'FIELD_DENY_CHECKED' => '', 'FIELD_DISALLOW_CHECKED' => '', 'FIELD_WIKIMODE_CHECKED' => '', @@ -2251,6 +2119,10 @@ switch ( $response['current_perms'][$acl_type] ) { + case 'i': + default: + $vars['FIELD_INHERIT_CHECKED'] = 'checked="checked"'; + break; case AUTH_ALLOW: $vars['FIELD_ALLOW_CHECKED'] = 'checked="checked"'; break; @@ -2258,7 +2130,6 @@ $vars['FIELD_WIKIMODE_CHECKED'] = 'checked="checked"'; break; case AUTH_DISALLOW: - default: $vars['FIELD_DISALLOW_CHECKED'] = 'checked="checked"'; break; case AUTH_DENY: @@ -2266,7 +2137,14 @@ break; } $vars['FIELD_NAME'] = 'data[perms][' . $acl_type . ']'; - $vars['FIELD_DESC'] = $response['acl_descs'][$acl_type]; + if ( preg_match('/^([a-z0-9_]+)$/', $response['acl_descs'][$acl_type]) ) + { + $vars['FIELD_DESC'] = $lang->get($response['acl_descs'][$acl_type]); + } + else + { + $vars['FIELD_DESC'] = $response['acl_descs'][$acl_type]; + } $parser->assign_vars($vars); echo $parser->run(); } @@ -2279,7 +2157,7 @@ - ' . ( ( $response['type'] == 'edit' ) ? '  ' : '' ) . ' + ' . ( ( $response['type'] == 'edit' ) ? '  ' : '' ) . '
'; echo $formend; break; @@ -2303,7 +2181,7 @@ * @access private */ - function acl_preprocess($parms) + public static function acl_preprocess($parms) { if ( !isset($parms['mode']) ) // Nothing to do @@ -2348,7 +2226,7 @@ return $parms; } - function acl_postprocess($response) + public static function acl_postprocess($response) { if(!isset($response['mode'])) { diff -r d823e49e2e4e -r c433348f3628 includes/paths.php --- a/includes/paths.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/paths.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /** * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * paths.php - The part of Enano that actually manages content. Everything related to page handling and namespaces is in here. * @@ -45,52 +45,55 @@ // ACL types // These can also be added from within plugins - $session->register_acl_type('read', AUTH_ALLOW, 'Read page(s)'); - $session->register_acl_type('post_comments', AUTH_ALLOW, 'Post comments', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('edit_comments', AUTH_ALLOW, 'Edit own comments', Array('post_comments'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('edit_page', AUTH_WIKIMODE, 'Edit page', Array('view_source'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('view_source', AUTH_WIKIMODE, 'View source', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); // Only used if the page is protected - $session->register_acl_type('mod_comments', AUTH_DISALLOW, 'Moderate comments', Array('edit_comments'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('history_view', AUTH_WIKIMODE, 'View history/diffs', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('history_rollback', AUTH_DISALLOW, 'Rollback history', Array('history_view'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('history_rollback_extra', AUTH_DISALLOW, 'Undelete page(s)', Array('history_rollback'), 'Article|User|Project|Template|File|Help|System|Category|Special'); - $session->register_acl_type('protect', AUTH_DISALLOW, 'Protect page(s)', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('rename', AUTH_WIKIMODE, 'Rename page(s)', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('clear_logs', AUTH_DISALLOW, 'Clear page logs (dangerous)', Array('read', 'protect', 'even_when_protected'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('vote_delete', AUTH_ALLOW, 'Vote to delete', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('vote_reset', AUTH_DISALLOW, 'Reset delete votes', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('delete_page', AUTH_DISALLOW, 'Delete page(s)', Array(), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('tag_create', AUTH_ALLOW, 'Tag page(s)', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('tag_delete_own', AUTH_ALLOW, 'Remove own page tags', Array('read', 'tag_create'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('tag_delete_other', AUTH_DISALLOW, 'Remove others\' page tags', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('set_wiki_mode', AUTH_DISALLOW, 'Set per-page wiki mode', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('password_set', AUTH_DISALLOW, 'Set password', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('password_reset', AUTH_DISALLOW, 'Disable/reset password', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('mod_misc', AUTH_DISALLOW, 'Super moderator (generate SQL backtraces, view IP addresses, and send large numbers of private messages)', Array(), 'All'); - $session->register_acl_type('edit_cat', AUTH_WIKIMODE, 'Edit categorization', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('even_when_protected', AUTH_DISALLOW, 'Allow editing, renaming, and categorization even when protected', Array('edit_page', 'rename', 'mod_comments', 'edit_cat'), 'Article|User|Project|Template|File|Help|System|Category'); - $session->register_acl_type('upload_files', AUTH_DISALLOW, 'Upload files', Array('create_page'), 'Article|User|Project|Template|File|Help|System|Category|Special'); - $session->register_acl_type('upload_new_version', AUTH_WIKIMODE, 'Upload new versions of files', Array('upload_files'), 'Article|User|Project|Template|File|Help|System|Category|Special'); - $session->register_acl_type('create_page', AUTH_WIKIMODE, 'Create pages', Array(), 'Article|User|Project|Template|File|Help|System|Category|Special'); - $session->register_acl_type('php_in_pages', AUTH_DISALLOW, 'Embed PHP code in pages', Array('edit_page'), 'Article|User|Project|Template|File|Help|System|Category|Admin'); - $session->register_acl_type('edit_acl', AUTH_DISALLOW, 'Edit access control lists', Array('read', 'post_comments', 'edit_comments', 'edit_page', 'view_source', 'mod_comments', 'history_view', 'history_rollback', 'history_rollback_extra', 'protect', 'rename', 'clear_logs', 'vote_delete', 'vote_reset', 'delete_page', 'set_wiki_mode', 'password_set', 'password_reset', 'mod_misc', 'edit_cat', 'even_when_protected', 'upload_files', 'upload_new_version', 'create_page', 'php_in_pages')); + $session->register_acl_type('read', AUTH_ALLOW, 'perm_read'); + $session->register_acl_type('post_comments', AUTH_ALLOW, 'perm_post_comments', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('edit_comments', AUTH_ALLOW, 'perm_edit_comments', Array('post_comments'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('edit_page', AUTH_WIKIMODE, 'perm_edit_page', Array('view_source'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('edit_wysiwyg', AUTH_ALLOW, 'perm_edit_wysiwyg', Array('edit_page'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('view_source', AUTH_WIKIMODE, 'perm_view_source', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); // Only used if the page is protected + $session->register_acl_type('mod_comments', AUTH_DISALLOW, 'perm_mod_comments', Array('edit_comments'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('history_view', AUTH_WIKIMODE, 'perm_history_view', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('history_rollback', AUTH_DISALLOW, 'perm_history_rollback', Array('history_view'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('history_rollback_extra', AUTH_DISALLOW, 'perm_history_rollback_extra', Array('history_rollback'), 'Article|User|Project|Template|File|Help|System|Category|Special'); + $session->register_acl_type('protect', AUTH_DISALLOW, 'perm_protect', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('rename', AUTH_WIKIMODE, 'perm_rename', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('clear_logs', AUTH_DISALLOW, 'perm_clear_logs', Array('read', 'protect', 'even_when_protected'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('vote_delete', AUTH_ALLOW, 'perm_vote_delete', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('vote_reset', AUTH_DISALLOW, 'perm_vote_reset', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('delete_page', AUTH_DISALLOW, 'perm_delete_page', Array(), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('tag_create', AUTH_ALLOW, 'perm_tag_create', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('tag_delete_own', AUTH_ALLOW, 'perm_tag_delete_own', Array('read', 'tag_create'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('tag_delete_other', AUTH_DISALLOW, 'perm_tag_delete_other', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('set_wiki_mode', AUTH_DISALLOW, 'perm_set_wiki_mode', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('password_set', AUTH_DISALLOW, 'perm_password_set', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('password_reset', AUTH_DISALLOW, 'perm_password_reset', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('mod_misc', AUTH_DISALLOW, 'perm_mod_misc', Array(), 'All'); + $session->register_acl_type('edit_cat', AUTH_WIKIMODE, 'perm_edit_cat', Array('read'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('even_when_protected', AUTH_DISALLOW, 'perm_even_when_protected', Array('edit_page', 'rename', 'mod_comments', 'edit_cat'), 'Article|User|Project|Template|File|Help|System|Category'); + $session->register_acl_type('upload_files', AUTH_DISALLOW, 'perm_upload_files', Array('create_page'), 'Article|User|Project|Template|File|Help|System|Category|Special'); + $session->register_acl_type('upload_new_version', AUTH_WIKIMODE, 'perm_upload_new_version', Array('upload_files'), 'Article|User|Project|Template|File|Help|System|Category|Special'); + $session->register_acl_type('create_page', AUTH_WIKIMODE, 'perm_create_page', Array(), 'Article|User|Project|Template|File|Help|System|Category|Special'); + $session->register_acl_type('html_in_pages', AUTH_DISALLOW, 'perm_html_in_pages', Array('edit_page'), 'Article|User|Project|Template|File|Help|System|Category|Admin'); + $session->register_acl_type('php_in_pages', AUTH_DISALLOW, 'perm_php_in_pages', Array('edit_page', 'html_in_pages'), 'Article|User|Project|Template|File|Help|System|Category|Admin'); + $session->register_acl_type('edit_acl', AUTH_DISALLOW, 'perm_edit_acl', Array('read', 'post_comments', 'edit_comments', 'edit_page', 'view_source', 'mod_comments', 'history_view', 'history_rollback', 'history_rollback_extra', 'protect', 'rename', 'clear_logs', 'vote_delete', 'vote_reset', 'delete_page', 'set_wiki_mode', 'password_set', 'password_reset', 'mod_misc', 'edit_cat', 'even_when_protected', 'upload_files', 'upload_new_version', 'create_page', 'php_in_pages')); // DO NOT add new admin pages here! Use a plugin to call $paths->addAdminNode(); - $this->addAdminNode('General', 'General Configuration', 'GeneralConfig'); - $this->addAdminNode('General', 'File uploads', 'UploadConfig'); - $this->addAdminNode('General', 'Allowed file types', 'UploadAllowedMimeTypes'); - $this->addAdminNode('General', 'Manage Plugins', 'PluginManager'); - $this->addAdminNode('General', 'Backup database', 'DBBackup'); - $this->addAdminNode('Content', 'Manage Pages', 'PageManager'); - $this->addAdminNode('Content', 'Edit page content', 'PageEditor'); - $this->addAdminNode('Content', 'Manage page groups', 'PageGroups'); - $this->addAdminNode('Appearance', 'Manage themes', 'ThemeManager'); - $this->addAdminNode('Users', 'Manage users', 'UserManager'); - $this->addAdminNode('Users', 'Edit groups', 'GroupManager'); - $this->addAdminNode('Users', 'COPPA support', 'COPPA'); - $this->addAdminNode('Users', 'Mass e-mail', 'MassEmail'); - $this->addAdminNode('Security', 'Security log', 'SecurityLog'); - $this->addAdminNode('Security', 'Ban control', 'BanControl'); + $this->addAdminNode('adm_cat_general', 'adm_page_general_config', 'GeneralConfig'); + $this->addAdminNode('adm_cat_general', 'adm_page_file_uploads', 'UploadConfig'); + $this->addAdminNode('adm_cat_general', 'adm_page_file_types', 'UploadAllowedMimeTypes'); + $this->addAdminNode('adm_cat_general', 'adm_page_plugins', 'PluginManager'); + $this->addAdminNode('adm_cat_general', 'adm_page_db_backup', 'DBBackup'); + $this->addAdminNode('adm_cat_general', 'adm_page_lang_manager', 'LangManager'); + $this->addAdminNode('adm_cat_content', 'adm_page_manager', 'PageManager'); + $this->addAdminNode('adm_cat_content', 'adm_page_editor', 'PageEditor'); + $this->addAdminNode('adm_cat_content', 'adm_page_pg_groups', 'PageGroups'); + $this->addAdminNode('adm_cat_appearance', 'adm_page_themes', 'ThemeManager'); + $this->addAdminNode('adm_cat_users', 'adm_page_users', 'UserManager'); + $this->addAdminNode('adm_cat_users', 'adm_page_user_groups', 'GroupManager'); + $this->addAdminNode('adm_cat_users', 'adm_page_coppa', 'COPPA'); + $this->addAdminNode('adm_cat_users', 'adm_page_mass_email', 'MassEmail'); + $this->addAdminNode('adm_cat_security', 'adm_page_security_log', 'SecurityLog'); + $this->addAdminNode('adm_cat_security', 'adm_page_ban_control', 'BanControl'); $code = $plugins->setHook('acl_rule_init'); foreach ( $code as $cmd ) @@ -101,13 +104,36 @@ $this->wiki_mode = (int)getConfig('wiki_mode')=='1'; $this->template_cache = Array(); } - function pathManager() + function parse_url($sanitize = true) { - $this->__construct(); + $title = ''; + if( isset($_GET['title']) ) + { + $title = $_GET['title']; + } + elseif( isset($_SERVER['PATH_INFO']) ) + { + $title = substr($_SERVER['PATH_INFO'], ( strpos($_SERVER['PATH_INFO'], '/') ) + 1 ); + } + else + { + // This method really isn't supported because apache has a habit of passing dots as underscores, thus corrupting the request + // If you really want to try it, the URI format is yoursite.com/?/Page_title + if ( count($_GET) > 0 ) + { + list($getkey) = array_keys($_GET); + if ( substr($getkey, 0, 1) == '/' ) + { + $title = substr($getkey, 1); + } + } + } + return ( $sanitize ) ? sanitize_page_id($title) : $title; } function init() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; $code = $plugins->setHook('paths_init_before'); foreach ( $code as $cmd ) @@ -125,7 +151,15 @@ { $r['urlname_nons'] = $r['urlname']; - $r['urlname'] = $this->nslist[$r['namespace']] . $r['urlname']; // Applies the User:/File:/etc prefixes to the URL names + if ( isset($this->nslist[$r['namespace']]) ) + { + $r['urlname'] = $this->nslist[$r['namespace']] . $r['urlname']; // Applies the User:/File:/etc prefixes to the URL names + } + else + { + $ns_char = substr($this->nslist['Special'], -1); + $r['urlname'] = $r['namespace'] . $ns_char . $r['urlname']; + } if ( $r['delvotes'] == null) { @@ -149,107 +183,40 @@ } $db->free_result(); - if ( defined('ENANO_INTERFACE_INDEX') || defined('ENANO_INTERFACE_AJAX') || defined('IN_ENANO_INSTALL') || defined('IN_ENANO_UPGRADE') ) + if ( defined('ENANO_INTERFACE_INDEX') || defined('ENANO_INTERFACE_AJAX') || defined('IN_ENANO_UPGRADE') ) { - if( isset($_GET['title']) ) + $title = $this->parse_url(false); + if ( empty($title) ) + { + $this->main_page(); + } + if ( strstr($title, ' ') || strstr($title, '+') || strstr($title, '%20') ) { - if ( $_GET['title'] == '' && getConfig('main_page') != '' ) - { - $this->main_page(); - } - if(strstr($_GET['title'], ' ')) - { - $loc = urldecode(rawurldecode($_SERVER['REQUEST_URI'])); - $loc = str_replace(' ', '_', $loc); - $loc = str_replace('+', '_', $loc); - $loc = str_replace('%20', '_', $loc); - redirect($loc, 'Redirecting...', 'Space detected in the URL, please wait whilst you are redirected', 0); - exit; - } - $url_namespace_special = substr($_GET['title'], 0, strlen($this->nslist['Special']) ); - $url_namespace_template = substr($_GET['title'], 0, strlen($this->nslist['Template']) ); - if($url_namespace_special == $this->nslist['Special'] || $url_namespace_template == $this->nslist['Template'] ) - { - $ex = explode('/', $_GET['title']); - $this->page = $ex[0]; - } - else - { - $this->page = $_GET['title']; - } - $this->fullpage = $_GET['title']; + $title = sanitize_page_id($title); + redirect(makeUrl($title), '', '', 0); } - elseif( isset($_SERVER['PATH_INFO']) ) + $title = sanitize_page_id($title); + // We've got the title, pull the namespace from it + $namespace = 'Article'; + $page_id = $title; + foreach ( $this->nslist as $ns => $prefix ) { - $pi = explode('/', $_SERVER['PATH_INFO']); - - if( !isset($pi[1]) || (isset($pi[1]) && $pi[1] == '' && getConfig('main_page') != '') ) - { - $this->main_page(); - } - if( strstr($pi[1], ' ') ) - { - $loc = str_replace(' ', '_', urldecode(rawurldecode($_SERVER['REQUEST_URI']))); - $loc = str_replace('+', '_', $loc); - $loc = str_replace('%20', '_', $loc); - redirect($loc, 'Redirecting...', 'Please wait whilst you are redirected', 3); - exit; - } - unset($pi[0]); - if( substr($pi[1], 0, strlen($this->nslist['Special'])) == $this->nslist['Special'] || substr($pi[1], 0, strlen($this->nslist['Template'])) == $this->nslist['Template'] ) + $prefix_len = strlen($prefix); + if ( substr($title, 0, $prefix_len) == $prefix ) { - $pi2 = $pi[1]; - } - else - { - $pi2 = implode('/', $pi); - } - $this->page = $pi2; - $this->fullpage = implode('/', $pi); - } - else - { - $k = array_keys($_GET); - foreach($k as $c) - { - if(substr($c, 0, 1) == '/') - { - $this->page = substr($c, 1, strlen($c)); - - // Bugfix for apache somehow passing dots as underscores - global $mime_types; - - $exts = array_keys($mime_types); - $exts = '(' . implode('|', $exts) . ')'; - - if ( preg_match( '#_'.$exts.'#i', $this->page ) ) - { - $this->page = preg_replace( '#_'.$exts.'#i', '.\\1', $this->page ); - } - - $this->fullpage = $this->page; - - if(substr($this->page, 0, strlen($this->nslist['Special']))==$this->nslist['Special'] || substr($this->page, 0, strlen($this->nslist['Template']))==$this->nslist['Template']) - { - $ex = explode('/', $this->page); - $this->page = $ex[0]; - } - if(strstr($this->page, ' ')) - { - $loc = str_replace(' ', '_', urldecode(rawurldecode($_SERVER['REQUEST_URI']))); - $loc = str_replace('+', '_', $loc); - $loc = str_replace('%20', '_', $loc); - redirect($loc, 'Redirecting...', 'Space in the URL detected, please wait whilst you are redirected', 0); - exit; - } - break; - } - } - if(!$this->page && !($this->page == '' && getConfig('main_page') == '')) - { - $this->main_page(); + $page_id = substr($title, $prefix_len); + $namespace = $ns; } } + $this->namespace = $namespace; + $this->fullpage = $title; + if ( $namespace == 'Special' || $namespace == 'Admin' ) + { + list($page_id) = explode('/', $page_id); + } + $this->page = $this->nslist[$namespace] . $page_id; + $this->page_id = $page_id; + // die("All done setting parameters. What we've got:
namespace: $namespace
fullpage: $this->fullpage
page: $this->page
page_id: $this->page_id"); } else { @@ -393,8 +360,7 @@ { $main_page = makeUrl($this->pages[0]['urlname']); } - $sp_link = 'here'; - redirect($main_page, 'Can\'t load special page', 'The special page you requested could not be found. This may be due to a plugin failing to load. A list of all special pages on this website can be viewed '.$sp_link.'. You will be redirected to the main page in 15 seconds.', 14); + redirect($main_page, $lang->get('page_msg_special_404_title'), $lang->get('page_msg_special_404_body', array('sp_link' => makeUrlNS('Special', 'SpecialPages'))), 15); exit; } // Allow the user to create/modify his user page uncondtionally (admins can still protect the page) @@ -414,12 +380,21 @@ } $session->init_permissions(); + profiler_log('Paths and CMS core initted'); } function add_page($flags) { + global $lang; $flags['urlname_nons'] = $flags['urlname']; $flags['urlname'] = $this->nslist[$flags['namespace']] . $flags['urlname']; // Applies the User:/File:/etc prefixes to the URL names + + if ( is_object($lang) ) + { + if ( preg_match('/^[a-z0-9]+_[a-z0-9_]+$/', $flags['name']) ) + $flags['name'] = $lang->get($flags['name']); + } + $pages_len = sizeof($this->pages)/2; $this->pages[$pages_len] = $flags; $this->pages[$flags['urlname']] =& $this->pages[$pages_len]; @@ -442,7 +417,7 @@ function sysmsg($n) { global $db, $session, $paths, $template, $plugins; // Common objects - $q = $db->sql_query('SELECT page_text, char_tag FROM '.table_prefix.'page_text WHERE page_id=\''.$db->escape($n).'\' AND namespace=\'System\''); + $q = $db->sql_query('SELECT page_text, char_tag FROM '.table_prefix.'page_text WHERE page_id=\''.$db->escape(sanitize_page_id($n)).'\' AND namespace=\'System\''); if( !$q ) { $db->_die('Error during generic selection of system page data.'); @@ -457,98 +432,46 @@ $message = $r['page_text']; $message = preg_replace('/(.*?)<\/noinclude>/is', '', $message); + $message = preg_replace('/(.*?)<\/nodisplay>/is', '\\1', $message); return $message; } function get_pageid_from_url() { - if(isset($_GET['title'])) - { - if( $_GET['title'] == '' && getConfig('main_page') != '' ) - { - $this->main_page(); - } - if(strstr($_GET['title'], ' ')) - { - $loc = urldecode(rawurldecode($_SERVER['REQUEST_URI'])); - $loc = str_replace(' ', '_', $loc); - $loc = str_replace('+', '_', $loc); - header('Location: '.$loc); - exit; - } - $ret = $_GET['title']; - } - elseif(isset($_SERVER['PATH_INFO'])) + $url = $this->parse_url(); + if ( substr($url, 0, strlen($this->nslist['Special'])) == $this->nslist['Special'] || + substr($url, 0, strlen($this->nslist['Admin'])) == $this->nslist['Admin']) { - $pi = explode('/', $_SERVER['PATH_INFO']); - - if(!isset($pi[1]) || (isset($pi[1]) && $pi[1] == '')) - { - return false; - } - - if(strstr($pi[1], ' ')) - { - $loc = urldecode(rawurldecode($_SERVER['REQUEST_URI'])); - $loc = str_replace(' ', '_', $loc); - $loc = str_replace('+', '_', $loc); - header('Location: '.$loc); - exit; - } - unset($pi[0]); - $pi[1] = implode('/', $pi); - $ret = $pi[1]; + list($url) = explode('/', $url); } - else - { - $k = array_keys($_GET); - foreach($k as $c) - { - if(substr($c, 0, 1) == '/') - { - $ret = substr($c, 1, strlen($c)); - if(substr($ret, 0, strlen($this->nslist['Special'])) == $this->nslist['Special'] || - substr($ret, 0, strlen($this->nslist['Admin'])) == $this->nslist['Admin']) - { - $ret = explode('/', $ret); - $ret = $ret[0]; - } - break; - } - } - } - - if ( isset($ret) ) - { - if ( substr($ret, 0, ( strlen($this->nslist['Special']) )) == $this->nslist['Special'] && strstr($ret, '/') ) - { - list ( $ret ) = explode('/', $ret); - } - } - - return ( isset($ret) ) ? $ret : false; + return $url; } // Parses a (very carefully formed) array into Javascript code compatible with the Tigra Tree Menu used in the admin menu function parseAdminTree() { + global $lang; + $k = array_keys($this->admin_tree); $i = 0; $ret = ''; - $ret .= "var TREE_ITEMS = [\n ['Administration panel home', 'javascript:ajaxPage(\'".$this->nslist['Admin']."Home\');',\n "; + $ret .= "var TREE_ITEMS = [\n ['" . $lang->get('adm_btn_home') . "', 'javascript:ajaxPage(\'".$this->nslist['Admin']."Home\');',\n "; foreach($k as $key) { $i++; - $ret .= "['".$key."', 'javascript:trees[0].toggle($i)', \n"; + $name = ( preg_match('/^[a-z0-9_]+$/', $key) ) ? $lang->get($key) : $key; + $ret .= "['".$name."', 'javascript:trees[0].toggle($i)', \n"; foreach($this->admin_tree[$key] as $c) { $i++; - $ret .= " ['".$c['name']."', 'javascript:ajaxPage(\\'".$this->nslist['Admin'].$c['pageid']."\\');'],\n"; + $name = ( preg_match('/^[a-z0-9_]+$/', $key) ) ? $lang->get($c['name']) : $c['name']; + + $ret .= " ['".$name."', 'javascript:ajaxPage(\\'".$this->nslist['Admin'].$c['pageid']."\\');'],\n"; } $ret .= " ],\n"; } - $ret .= " ['Log out of admin panel', 'javascript:ajaxPage(\\'".$this->nslist['Admin']."AdminLogout\\');'],\n"; - $ret .= " ['Loading keep-alive control...', 'javascript:ajaxToggleKeepalive();', - ['About keep-alive', 'javascript:aboutKeepAlive();'] + $ret .= " ['" . $lang->get('adm_btn_logout') . "', 'javascript:ajaxPage(\\'".$this->nslist['Admin']."AdminLogout\\');'],\n"; + $ret .= " ['" . $lang->get('adm_btn_keepalive_loading') . "', 'javascript:ajaxToggleKeepalive();', + ['" . $lang->get('adm_btn_keepalive_about') . "', 'javascript:aboutKeepAlive();'] ],\n"; // I used this while I painstakingly wrote the Runt code that auto-expands certain nodes based on the value of a bitfield stored in a cookie. *shudders* // $ret .= " ['(debug) Clear menu bitfield', 'javascript:createCookie(\\'admin_menu_state\\', \\'1\\', 365);'],\n"; @@ -568,80 +491,22 @@ } function getParam($id = 0) { - // using !empty here is a bugfix for IIS 5.x on Windows 2000 Server - // It may affect other IIS versions as well - if(isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO'])) - { - $pi = explode('/', $_SERVER['PATH_INFO']); - $id = $id + 2; - return isset($pi[$id]) ? $pi[$id] : false; - } - else if( isset($_GET['title']) ) - { - $pi = explode('/', $_GET['title']); - $id = $id + 1; - return isset($pi[$id]) ? $pi[$id] : false; - } - else - { - $k = array_keys($_GET); - foreach($k as $c) - { - if(substr($c, 0, 1) == '/') - { - // Bugfix for apache somehow passing dots as underscores - global $mime_types; - $exts = array_keys($mime_types); - $exts = '(' . implode('|', $exts) . ')'; - if ( preg_match( '#_'.$exts.'#i', $c ) ) - $c = preg_replace( '#_'.$exts.'#i', '.\\1', $c ); - - $pi = explode('/', $c); - $id = $id + 2; - return isset($pi[$id]) ? $pi[$id] : false; - } - } - return false; - } + $title = $this->parse_url(false); + $regex = '/^' . str_replace('/', '\\/', preg_quote($this->nslist[$this->namespace])) . '\\/?/'; + $title = preg_replace($regex, '', $title); + $title = explode('/', $title); + $id = $id + 1; + return ( isset($title[$id]) ) ? $title[$id] : false; } function getAllParams() { - // using !empty here is a bugfix for IIS 5.x on Windows 2000 Server - // It may affect other IIS versions as well - if(isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO'])) - { - $pi = explode('/', $_SERVER['PATH_INFO']); - unset($pi[0], $pi[1]); - return implode('/', $pi); - } - else if( isset($_GET['title']) ) - { - $pi = explode('/', $_GET['title']); - unset($pi[0]); - return implode('/', $pi); - } - else - { - $k = array_keys($_GET); - foreach($k as $c) - { - if(substr($c, 0, 1) == '/') - { - // Bugfix for apache somehow passing dots as underscores - global $mime_types; - $exts = array_keys($mime_types); - $exts = '(' . implode('|', $exts) . ')'; - if ( preg_match( '#_'.$exts.'#i', $c ) ) - $c = preg_replace( '#_'.$exts.'#i', '.\\1', $c ); - - $pi = explode('/', $c); - unset($pi[0], $pi[1]); - return implode('/', $pi); - } - } - return false; - } + $title = $this->parse_url(false); + $regex = '/^' . str_replace('/', '\\/', preg_quote($this->nslist[$this->namespace])) . '\\/?/'; + $title = preg_replace($regex, '', $title); + $title = explode('/', $title); + unset($title[0]); + return implode('/', $title); } /** @@ -875,7 +740,7 @@ } - /* + /** * Creates an instance of the Searcher class, including index info * @return object */ diff -r d823e49e2e4e -r c433348f3628 includes/plugins.php --- a/includes/plugins.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/plugins.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -16,7 +16,7 @@ var $hook_list; var $load_list; var $loaded_plugins; - var $system_plugins = Array('SpecialUserFuncs.php','SpecialUserPrefs.php','SpecialPageFuncs.php','SpecialAdmin.php','SpecialCSS.php','SpecialUpdownload.php','SpecialSearch.php','PrivateMessages.php','SpecialGroups.php'); + var $system_plugins = Array('SpecialUserFuncs.php','SpecialUserPrefs.php','SpecialPageFuncs.php','SpecialAdmin.php','SpecialCSS.php','SpecialUpdownload.php','SpecialSearch.php','PrivateMessages.php','SpecialGroups.php', 'SpecialRecentChanges.php'); function loadAll() { $dir = ENANO_ROOT.'/plugins/'; @@ -39,7 +39,9 @@ { $this->load_list[] = $dir . $file; $plugid = substr($file, 0, strlen($file)-4); - $f = file_get_contents($dir . $file); + $f = @file_get_contents($dir . $file); + if ( empty($f) ) + continue; $f = explode("\n", $f); $f = array_slice($f, 2, 7); $f[0] = substr($f[0], 13); @@ -78,7 +80,7 @@ */ if(isset($this->hook_list[$name]) && is_array($this->hook_list[$name])) { - return $this->hook_list[$name]; + return array(implode("\n", $this->hook_list[$name])); } else { diff -r d823e49e2e4e -r c433348f3628 includes/render.php --- a/includes/render.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/render.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * render.php - handles fetching pages and parsing them into HTML * @@ -15,7 +15,7 @@ class RenderMan { - function strToPageID($string) + public static function strToPageID($string) { global $db, $session, $paths, $template, $plugins; // Common objects $k = array_keys($paths->nslist); @@ -38,7 +38,7 @@ return Array($pg, $ns); } - function getPage($page_id, $namespace, $wiki = 1, $smilies = true, $filter_links = true, $redir = true, $render = true) + public static function getPage($page_id, $namespace, $wiki = 1, $smilies = true, $filter_links = true, $redir = true, $render = true) { global $db, $session, $paths, $template, $plugins; // Common objects @@ -112,7 +112,7 @@ return ($render) ? RenderMan::render($message, $wiki, $smilies, $filter_links) : $message; } - function getTemplate($id, $parms) + public static function getTemplate($id, $parms) { global $db, $session, $paths, $template, $plugins; // Common objects if(!isset($paths->pages[$paths->nslist['Template'].$id])) @@ -150,7 +150,7 @@ return $text; } - function fetch_template_text($id) + public static function fetch_template_text($id) { global $db, $session, $paths, $template, $plugins; // Common objects if(!isset($paths->pages[$paths->nslist['Template'].$id])) @@ -176,7 +176,7 @@ return $text; } - function render($text, $wiki = 1, $smilies = true, $filter_links = true) + public static function render($text, $wiki = 1, $smilies = true, $filter_links = true) { global $db, $session, $paths, $template, $plugins; // Common objects if($smilies) @@ -194,7 +194,7 @@ return $text; } - function PlainTextRender($text, $wiki = 1, $smilies = false, $filter_links = true) + public static function PlainTextRender($text, $wiki = 1, $smilies = false, $filter_links = true) { global $db, $session, $paths, $template, $plugins; // Common objects if($smilies) @@ -212,13 +212,30 @@ return $text; } - function next_gen_wiki_format($text, $plaintext = false, $filter_links = true, $do_params = false) + public static function next_gen_wiki_format($text, $plaintext = false, $filter_links = true, $do_params = false) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + + profiler_log("RenderMan: starting wikitext render"); + $random_id = md5( time() . mt_rand() ); // Strip out sections and PHP code + $nw = preg_match_all('#(.*?)<\/nowiki>#is', $text, $nowiki); + + for($i=0;$i'.$nowiki[1][$i].'', '{NOWIKI:'.$random_id.':'.$i.'}', $text); + } + + $code = $plugins->setHook('render_wikiformat_veryearly'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + $php = preg_match_all('#<\?php(.*?)\?>#is', $text, $phpsec); for($i=0;$i', '{PHP:'.$random_id.':'.$i.'}', $text); } - $nw = preg_match_all('#(.*?)<\/nowiki>#is', $text, $nowiki); - - for($i=0;$i'.$nowiki[1][$i].'', '{NOWIKI:'.$random_id.':'.$i.'}', $text); - } - $text = preg_replace('/(.*?)<\/noinclude>/is', '\\1', $text); if ( $paths->namespace == 'Template' ) { $text = preg_replace('/(.*?)<\/nodisplay>/is', '', $text); } + preg_match_all('/([\w\W]+?)<\/lang>/', $text, $langmatch); + foreach ( $langmatch[0] as $i => $match ) + { + if ( $langmatch[1][$i] == $lang->lang_code ) + { + $text = str_replace_once($match, $langmatch[2][$i], $text); + } + else + { + $text = str_replace_once($match, '', $text); + } + } + $code = $plugins->setHook('render_wikiformat_pre'); foreach ( $code as $cmd ) { @@ -272,10 +295,13 @@ $text = RenderMan::include_templates($text); } + // Before shipping it out to the renderer, replace spaces in between headings and paragraphs: + $text = preg_replace('/<\/(h[0-9]|div|p)>([\s]+)<(h[0-9]|div|p)( .+?)?>/i', '<\\3\\4>', $text); + $text = process_tables($text); $text = RenderMan::parse_internal_links($text); - $wiki =& Text_Wiki::singleton('Mediawiki'); + $wiki = Text_Wiki::singleton('Mediawiki'); if($plaintext) { $wiki->setRenderConf('Plain', 'wikilink', 'view_url', contentPath); @@ -321,11 +347,13 @@ $result = str_replace('{PHP:'.$random_id.':'.$i.'}', '', $result); } + profiler_log("RenderMan: finished wikitext render"); + return $result; } - function wikiFormat($message, $filter_links = true, $do_params = false, $plaintext = false) + public static function wikiFormat($message, $filter_links = true, $do_params = false, $plaintext = false) { global $db, $session, $paths, $template, $plugins; // Common objects @@ -408,7 +436,7 @@ return $result; } - function destroy_javascript($message, $_php = false) + public static function destroy_javascript($message, $_php = false) { $message = preg_replace('#<(script|object|applet|embed|iframe|frame|form|input|select)(.*?)>#is', '<\\1\\2>', $message); $message = preg_replace('##is', '</\\1\\2>', $message); @@ -425,12 +453,12 @@ return $message; } - function strip_php($message) + public static function strip_php($message) { return RenderMan::destroy_javascript($message, true); } - function sanitize_html($text) + public static function sanitize_html($text) { $text = htmlspecialchars($text); $allowed_tags = Array('b', 'i', 'u', 'pre', 'code', 'tt', 'br', 'p', 'nowiki', '!--([\w\W]+)--'); @@ -449,7 +477,7 @@ * @return string */ - function parse_internal_links($text) + public static function parse_internal_links($text) { global $db, $session, $paths, $template, $plugins; // Common objects @@ -503,7 +531,7 @@ * [bar] => dolor sit amet */ - function parse_template_vars($input) + public static function parse_template_vars($input) { if ( !preg_match('/^(\|[ ]*([A-z0-9_]+)([ ]*)=([ ]*)(.+?))*$/is', trim($input)) ) { @@ -570,7 +598,7 @@ * */ - function include_templates($text) + public static function include_templates($text) { global $db, $session, $paths, $template, $plugins; // Common objects // $template_regex = "/\{\{([^\]]+?)((\n([ ]*?)[A-z0-9]+([ ]*?)=([ ]*?)(.+?))*)\}\}/is"; @@ -609,14 +637,25 @@ * @param string $text * @param bool $strip_all_php - if true, strips all PHP regardless of user permissions. Else, strips PHP only if user level < USER_LEVEL_ADMIN. */ - function preprocess_text($text, $strip_all_php = true, $sqlescape = true) + public static function preprocess_text($text, $strip_all_php = true, $sqlescape = true) { global $db, $session, $paths, $template, $plugins; // Common objects $random_id = md5( time() . mt_rand() ); - $can_do_php = ( $session->get_permissions('php_in_pages') && !$strip_all_php ); + $code = $plugins->setHook('render_sanitize_pre'); + foreach ( $code as $cmd ) + { + eval($cmd); + } - if ( !$can_do_php ) + $can_do_php = ( $session->get_permissions('php_in_pages') && !$strip_all_php ); + $can_do_html = $session->get_permissions('html_in_pages'); + + if ( $can_do_html && !$can_do_php ) + { + $text = preg_replace('#<(\?|\?php|%)(.*?)(\?|%)>#is', '<\\1\\2\\3>', $text); + } + else if ( !$can_do_html && !$can_do_php ) { $text = sanitize_html($text, true); // If we can't do PHP, we can't do Javascript either. @@ -641,10 +680,16 @@ $text = str_replace(''.$nowiki[1][$i].'', '{NOWIKI:'.$random_id.':'.$i.'}', $text); } - $text = str_replace('~~~~~', date('G:i, j F Y (T)'), $text); - $text = str_replace('~~~~', "[[User:$session->username|$session->username]] ".date('G:i, j F Y (T)'), $text); + $text = str_replace('~~~~~', enano_date('G:i, j F Y (T)'), $text); + $text = str_replace('~~~~', "[[User:$session->username|$session->username]] ".enano_date('G:i, j F Y (T)'), $text); $text = str_replace('~~~', "[[User:$session->username|$session->username]] ", $text); + $code = $plugins->setHook('render_sanitize_post'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + // Reinsert sections for($i=0;$i<$nw;$i++) { @@ -664,7 +709,7 @@ return $text; } - function smilieyize($text, $complete_urls = false) + public static function smilieyize($text, $complete_urls = false) { $random_id = md5( time() . mt_rand() ); @@ -736,7 +781,8 @@ $keys = array_keys($smileys); foreach($keys as $k) { - $t = str_hex($k); + $t = hexencode($k, ' ', ''); + $t = trim($t); $t = explode(' ', $t); $s = ''; foreach($t as $b) @@ -764,7 +810,7 @@ * @return array key 0 is the escaped text, key 1 is the character tag * / - function escape_page_text($text) + public static function escape_page_text($text) { $char_tag = md5(microtime() . mt_rand()); $text = str_replace("'", "{APOS:$char_tag}", $text); @@ -781,7 +827,7 @@ * @return string * / - function unescape_page_text($text, $char_tag) + public static function unescape_page_text($text, $char_tag) { $text = str_replace("{APOS:$char_tag}", "'", $text); $text = str_replace("{QUOT:$char_tag}", '"', $text); @@ -796,7 +842,7 @@ * @param $str2 string the second block of text * @return string */ - function diff($str1, $str2) + public static function diff($str1, $str2) { global $db, $session, $paths, $template, $plugins; // Common objects $str1 = explode("\n", $str1); @@ -813,7 +859,7 @@ * @return string */ - function process_image_tags($text, &$taglist) + public static function process_image_tags($text, &$taglist) { global $db, $session, $paths, $template, $plugins; // Common objects @@ -822,7 +868,7 @@ $taglist = array(); // Wicked huh? - $regex = '/\[\[:' . $paths->nslist['File'] . '([\w\s0-9_\(\)!@%\^\+\|\.-]+?)((\|thumb)|(\|([0-9]+)x([0-9]+)))?(\|left|\|right)?(\|raw|\|(.+))?\]\]/i'; + $regex = '/\[\[:' . str_replace('/', '\\/', preg_quote($paths->nslist['File'])) . '([\w\s0-9_\(\)!@%\^\+\|\.-]+?)((\|thumb)|(\|([0-9]+)x([0-9]+)))?(\|left|\|right)?(\|raw|\|(.+))?\]\]/i'; preg_match_all($regex, $text, $matches); @@ -965,7 +1011,7 @@ * @param array The list of image tags created by RenderMan::process_image_tags() */ - function process_imgtags_stage2($text, $taglist) + public static function process_imgtags_stage2($text, $taglist) { $s_delim = "\xFF"; $f_delim = "\xFF"; diff -r d823e49e2e4e -r c433348f3628 includes/rijndael.php --- a/includes/rijndael.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/rijndael.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,1099 +1,1083 @@ - - * Ported to PHP by Dan Fuhry - * @package phijndael - * @author Fritz Schneider - * @author Dan Fuhry - * @license BSD-style license - */ - -define ('ENC_HEX', 201); -define ('ENC_BASE64', 202); -define ('ENC_BINARY', 203); - -$_aes_objcache = array(); - -class AESCrypt { - - var $debug = false; - var $mcrypt = false; - var $decrypt_cache = array(); - - // Rijndael parameters -- Valid values are 128, 192, or 256 - - var $keySizeInBits = 128; - var $blockSizeInBits = 128; - - /////// You shouldn't have to modify anything below this line except for - /////// the function getRandomBytes(). - // - // Note: in the following code the two dimensional arrays are indexed as - // you would probably expect, as array[row][column]. The state arrays - // are 2d arrays of the form state[4][Nb]. - - - // The number of rounds for the cipher, indexed by [Nk][Nb] - var $roundsArray = Array(0,0,0,0,Array(0,0,0,0,10,0, 12,0, 14),0, - Array(0,0,0,0,12,0, 12,0, 14),0, - Array(0,0,0,0,14,0, 14,0, 14) ); - - // The number of bytes to shift by in shiftRow, indexed by [Nb][row] - var $shiftOffsets = Array(0,0,0,0,Array(0,1, 2, 3),0,Array(0,1, 2, 3),0,Array(0,1, 3, 4) ); - - // The round constants used in subkey expansion - var $Rcon = Array( - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, - 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, - 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, - 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, - 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 ); - - // Precomputed lookup table for the SBox - var $SBox = Array( - 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, - 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, - 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, - 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, - 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, - 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, - 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, - 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, - 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, - 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, - 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, - 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, - 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, - 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, - 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, - 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, - 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, - 22 ); - - // Precomputed lookup table for the inverse SBox - var $SBoxInverse = Array( - 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, - 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, - 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, - 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, - 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, - 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, - 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, - 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, - 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, - 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, - 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, - 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, - 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, - 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, - 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, - 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, - 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, - 125 ); - - function AESCrypt($ks = 128, $bs = 128, $debug = false) - { - $this->__construct($ks, $bs, $debug); - } - - function __construct($ks = 128, $bs = 128, $debug = false) - { - $this->keySizeInBits = $ks; - $this->blockSizeInBits = $bs; - - // Use the Mcrypt library? This speeds things up dramatically. - if(defined('MCRYPT_RIJNDAEL_' . $ks) && defined('MCRYPT_ACCEL')) - { - eval('$mcb = MCRYPT_RIJNDAEL_' . $ks.';'); - $bks = mcrypt_module_get_algo_block_size($mcb); - $bks = $bks * 8; - if ( $bks != $bs ) - { - $mcb = false; - echo (string)$bks; - } - } - else - { - $mcb = false; - } - - $this->mcrypt = $mcb; - - // Cipher parameters ... do not change these - $this->Nk = $this->keySizeInBits / 32; - $this->Nb = $this->blockSizeInBits / 32; - $this->Nr = $this->roundsArray[$this->Nk][$this->Nb]; - $this->debug = $debug; - } - - function singleton($key_size, $block_size) - { - global $_aes_objcache; - if ( isset($_aes_objcache["$key_size,$block_size"]) ) - { - return $_aes_objcache["$key_size,$block_size"]; - } - - $_aes_objcache["$key_size,$block_size"] = new AESCrypt($key_size, $block_size); - return $_aes_objcache["$key_size,$block_size"]; - } - - // Error handler - - function trigger_error($text, $level = E_USER_NOTICE) - { - $bt = debug_backtrace(); - $lastfunc =& $bt[1]; - switch($level) - { - case E_USER_NOTICE: - default: - $desc = 'Notice'; - break; - case E_USER_WARNING: - $desc = 'Warning'; - break; - case E_USER_ERROR: - $desc = 'Fatal'; - break; - } - ob_start(); - if($this->debug || $level == E_USER_ERROR) echo "AES encryption: {$desc}: $text in {$lastfunc['file']} on line {$lastfunc['line']} in function {$lastfunc['function']}
"; - if($this->debug) - { - //echo '
'.enano_debug_print_backtrace(true).'
'; - } - ob_end_flush(); - if($level == E_USER_ERROR) - { - echo '

This can sometimes happen if you are upgrading Enano to a new version and did not log out first. Click here to force cookies to clear and try again. You will be logged out.

'; - exit; - } - } - - function array_slice_js_compat($array, $start, $finish = 0) - { - $len = $finish - $start; - if($len < 0) $len = 0 - $len; - //if($this->debug) echo (string)$len . ' '; - //if(count($array) < $start + $len) - // $this->trigger_error('Index out of range', E_USER_WARNING); - return array_slice($array, $start, $len); - } - - function concat($s1, $s2) - { - if(is_array($s1) && is_array($s2)) - return array_merge($s1, $s2); - elseif( ( is_array($s1) && !is_array($s2) ) || ( !is_array($s1) && is_array($s2) ) ) - { - $this->trigger_error('incompatible types - you can\'t combine a non-array with an array', E_USER_WARNING); - return false; - } - else - return $s1 . $s2; - } - - // This method circularly shifts the array left by the number of elements - // given in its parameter. It returns the resulting array and is used for - // the ShiftRow step. Note that shift() and push() could be used for a more - // elegant solution, but they require IE5.5+, so I chose to do it manually. - - function cyclicShiftLeft($theArray, $positions) { - if(!is_int($positions)) - { - $this->trigger_error('$positions is not an integer! Backtrace:
'.print_r(debug_backtrace(), true).'
', E_USER_WARNING); - return false; - } - $second = array_slice($theArray, 0, $positions); - $first = array_slice($theArray, $positions); - $theArray = array_merge($first, $second); - return $theArray; - } - - // Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec. - - function xtime($poly) { - $poly <<= 1; - return (($poly & 0x100) ? ($poly ^ 0x11B) : ($poly)); - } - - // Multiplies the two elements of GF(2^8) together and returns the result. - // See the Rijndael spec, but should be straightforward: for each power of - // the indeterminant that has a 1 coefficient in x, add y times that power - // to the result. x and y should be bytes representing elements of GF(2^8) - - function mult_GF256($x, $y) { - $result = 0; - - for ($bit = 1; $bit < 256; $bit *= 2, $y = $this->xtime($y)) { - if ($x & $bit) - $result ^= $y; - } - return $result; - } - - // Performs the substitution step of the cipher. State is the 2d array of - // state information (see spec) and direction is string indicating whether - // we are performing the forward substitution ("encrypt") or inverse - // substitution (anything else) - - function byteSub(&$state, $direction) { - //global $this->SBox, $this->SBoxInverse, $this->Nb; - if ($direction == "encrypt") // Point S to the SBox we're using - $S =& $this->SBox; - else - $S =& $this->SBoxInverse; - for ($i = 0; $i < 4; $i++) // Substitute for every byte in state - for ($j = 0; $j < $this->Nb; $j++) - $state[$i][$j] = $S[$state[$i][$j]]; - } - - // Performs the row shifting step of the cipher. - - function shiftRow(&$state, $direction) { - //global $this->Nb, $this->shiftOffsets; - for ($i=1; $i<4; $i++) // Row 0 never shifts - if ($direction == "encrypt") - $state[$i] = $this->cyclicShiftLeft($state[$i], $this->shiftOffsets[$this->Nb][$i]); - else - $state[$i] = $this->cyclicShiftLeft($state[$i], $this->Nb - $this->shiftOffsets[$this->Nb][$i]); - - } - - // Performs the column mixing step of the cipher. Most of these steps can - // be combined into table lookups on 32bit values (at least for encryption) - // to greatly increase the speed. - - function mixColumn(&$state, $direction) { - //global $this->Nb; - $b = Array(); // Result of matrix multiplications - for ($j = 0; $j < $this->Nb; $j++) { // Go through each column... - for ($i = 0; $i < 4; $i++) { // and for each row in the column... - if ($direction == "encrypt") - $b[$i] = $this->mult_GF256($state[$i][$j], 2) ^ // perform mixing - $this->mult_GF256($state[($i+1)%4][$j], 3) ^ - $state[($i+2)%4][$j] ^ - $state[($i+3)%4][$j]; - else - $b[$i] = $this->mult_GF256($state[$i][$j], 0xE) ^ - $this->mult_GF256($state[($i+1)%4][$j], 0xB) ^ - $this->mult_GF256($state[($i+2)%4][$j], 0xD) ^ - $this->mult_GF256($state[($i+3)%4][$j], 9); - } - for ($i = 0; $i < 4; $i++) // Place result back into column - $state[$i][$j] = $b[$i]; - } - } - - // Adds the current round key to the state information. Straightforward. - - function addRoundKey(&$state, $roundKey) { - //global $this->Nb; - for ($j = 0; $j < $this->Nb; $j++) { // Step through columns... - $state[0][$j] ^= ( $roundKey[$j] & 0xFF); // and XOR - $state[1][$j] ^= (($roundKey[$j]>>8) & 0xFF); - $state[2][$j] ^= (($roundKey[$j]>>16) & 0xFF); - $state[3][$j] ^= (($roundKey[$j]>>24) & 0xFF); - } - } - - // This function creates the expanded key from the input (128/192/256-bit) - // key. The parameter key is an array of bytes holding the value of the key. - // The returned value is an array whose elements are the 32-bit words that - // make up the expanded key. - - function keyExpansion($key) { - //global $this->keySizeInBits, $this->blockSizeInBits, $this->roundsArray, $this->Nk, $this->Nb, $this->Nr, $this->Nk, $this->SBox, $this->Rcon; - $expandedKey = Array(); - - // in case the key size or parameters were changed... - $this->Nk = $this->keySizeInBits / 32; - $this->Nb = $this->blockSizeInBits / 32; - $this->Nr = $this->roundsArray[$this->Nk][$this->Nb]; - - for ($j=0; $j < $this->Nk; $j++) // Fill in input key first - $expandedKey[$j] = - ($key[4*$j]) | ($key[4*$j+1]<<8) | ($key[4*$j+2]<<16) | ($key[4*$j+3]<<24); - - // Now walk down the rest of the array filling in expanded key bytes as - // per Rijndael's spec - for ($j = $this->Nk; $j < $this->Nb * ($this->Nr + 1); $j++) { // For each word of expanded key - $temp = $expandedKey[$j - 1]; - if ($j % $this->Nk == 0) - $temp = ( ($this->SBox[($temp>>8) & 0xFF]) | - ($this->SBox[($temp>>16) & 0xFF]<<8) | - ($this->SBox[($temp>>24) & 0xFF]<<16) | - ($this->SBox[$temp & 0xFF]<<24) ) ^ $this->Rcon[floor($j / $this->Nk) - 1]; - elseif ($this->Nk > 6 && $j % $this->Nk == 4) - $temp = ($this->SBox[($temp>>24) & 0xFF]<<24) | - ($this->SBox[($temp>>16) & 0xFF]<<16) | - ($this->SBox[($temp>>8) & 0xFF]<<8) | - ($this->SBox[ $temp & 0xFF]); - $expandedKey[$j] = $expandedKey[$j-$this->Nk] ^ $temp; - } - return $expandedKey; - } - - // Rijndael's round functions... - - function RijndaelRound(&$state, $roundKey) { - $this->byteSub($state, "encrypt"); - $this->shiftRow($state, "encrypt"); - $this->mixColumn($state, "encrypt"); - $this->addRoundKey($state, $roundKey); - } - - function InverseRijndaelRound(&$state, $roundKey) { - $this->addRoundKey($state, $roundKey); - $this->mixColumn($state, "decrypt"); - $this->shiftRow($state, "decrypt"); - $this->byteSub($state, "decrypt"); - } - - function FinalRijndaelRound(&$state, $roundKey) { - $this->byteSub($state, "encrypt"); - $this->shiftRow($state, "encrypt"); - $this->addRoundKey($state, $roundKey); - } - - function InverseFinalRijndaelRound(&$state, $roundKey){ - $this->addRoundKey($state, $roundKey); - $this->shiftRow($state, "decrypt"); - $this->byteSub($state, "decrypt"); - } - - // encrypt is the basic encryption function. It takes parameters - // block, an array of bytes representing a plaintext block, and expandedKey, - // an array of words representing the expanded key previously returned by - // keyExpansion(). The ciphertext block is returned as an array of bytes. - - function cryptBlock($block, $expandedKey) { - //global $this->blockSizeInBits, $this->Nb, $this->Nr; - $t=count($block)*8; - if (!is_array($block) || count($block)*8 != $this->blockSizeInBits) - { - $this->trigger_error('block is bad or block size is wrong
'.print_r($block, true).'

Aiming for size '.$this->blockSizeInBits.', got '.$t.'.', E_USER_WARNING); - return false; - } - if (!$expandedKey) - return; - - $block = $this->packBytes($block); - $this->addRoundKey($block, $expandedKey); - for ($i=1; $i<$this->Nr; $i++) - $this->RijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$i, $this->Nb*($i+1))); - $this->FinalRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$this->Nr)); - $ret = $this->unpackBytes($block); - return $ret; - } - - // decrypt is the basic decryption function. It takes parameters - // block, an array of bytes representing a ciphertext block, and expandedKey, - // an array of words representing the expanded key previously returned by - // keyExpansion(). The decrypted block is returned as an array of bytes. - - function unCryptBlock($block, $expandedKey) { - $t = count($block)*8; - if (!is_array($block) || count($block)*8 != $this->blockSizeInBits) - { - $this->trigger_error('$block is not a valid rijndael-block array: '.$this->byteArrayToHex($block).'

'.print_r($block, true).'

Block size is '.$t.', should be '.$this->blockSizeInBits.'

', E_USER_WARNING); - return false; - } - if (!$expandedKey) - { - $this->trigger_error('$expandedKey is invalid', E_USER_WARNING); - return false; - } - - $block = $this->packBytes($block); - $this->InverseFinalRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$this->Nr)); - for ($i = $this->Nr - 1; $i>0; $i--) - { - $this->InverseRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$i, $this->Nb*($i+1))); - } - $this->addRoundKey($block, $expandedKey); - $ret = $this->unpackBytes($block); - if(!is_array($ret)) - { - $this->trigger_error('$ret is not an array', E_USER_WARNING); - } - return $ret; - } - - // This method takes a byte array (byteArray) and converts it to a string by - // applying String.fromCharCode() to each value and concatenating the result. - // The resulting string is returned. Note that this function SKIPS zero bytes - // under the assumption that they are padding added in formatPlaintext(). - // Obviously, do not invoke this method on raw data that can contain zero - // bytes. It is really only appropriate for printable ASCII/Latin-1 - // values. Roll your own function for more robust functionality :) - - function byteArrayToString($byteArray) { - $result = ""; - for($i=0; $i "10ff". The function returns a - // string. - - /* - function byteArrayToHex($byteArray) { - $result = ""; - if (!$byteArray) - return; - for ($i=0; $i [16, 255]. This - // function returns an array. - - /* - function hexToByteArray($hexString) { - $byteArray = Array(); - if (strlen($hexString) % 2) // must have even length - return; - if (strstr($hexString, "0x") == $hexString || strstr($hexString, "0X") == $hexString) - $hexString = substr($hexString, 2); - for ($i = 0; $ienano_str_split($str, 2); - foreach($str as $s) - { - $arr[] = intval(hexdec($s)); - } - return $arr; - } - - // This function packs an array of bytes into the four row form defined by - // Rijndael. It assumes the length of the array of bytes is divisible by - // four. Bytes are filled in according to the Rijndael spec (starting with - // column 0, row 0 to 3). This function returns a 2d array. - - function packBytes($octets) { - $state = Array(); - if (!$octets || count($octets) % 4) - return; - - $state[0] = Array(); $state[1] = Array(); - $state[2] = Array(); $state[3] = Array(); - for ($j=0; $jblockSizeInBits; - $bpb = $this->blockSizeInBits / 8; // bytes per block - - // if primitive string or String instance - if (is_string($plaintext)) { - $plaintext = $this->enano_str_split($plaintext); - // Unicode issues here (ignoring high byte) - for ($i=0; $icharCodeAt($plaintext[$i], 0) & 0xFF; - } - - for ($i = $bpb - (sizeof($plaintext) % $bpb); $i > 0 && $i < $bpb; $i--) - $plaintext[] = 0; - - return $plaintext; - } - - // Returns an array containing "howMany" random bytes. YOU SHOULD CHANGE THIS - // TO RETURN HIGHER QUALITY RANDOM BYTES IF YOU ARE USING THIS FOR A "REAL" - // APPLICATION. (edit: done, mt_rand() is relatively secure) - - function getRandomBytes($howMany) { - $bytes = Array(); - for ($i=0; $i<$howMany; $i++) - $bytes[$i] = mt_rand(0, 255); - return $bytes; - } - - // rijndaelEncrypt(plaintext, key, mode) - // Encrypts the plaintext using the given key and in the given mode. - // The parameter "plaintext" can either be a string or an array of bytes. - // The parameter "key" must be an array of key bytes. If you have a hex - // string representing the key, invoke hexToByteArray() on it to convert it - // to an array of bytes. The third parameter "mode" is a string indicating - // the encryption mode to use, either "ECB" or "CBC". If the parameter is - // omitted, ECB is assumed. - // - // An array of bytes representing the cihpertext is returned. To convert - // this array to hex, invoke byteArrayToHex() on it. If you are using this - // "for real" it is a good idea to change the function getRandomBytes() to - // something that returns truly random bits. - - function rijndaelEncrypt($plaintext, $key, $mode = 'ECB') { - //global $this->blockSizeInBits, $this->keySizeInBits; - $bpb = $this->blockSizeInBits / 8; // bytes per block - // var ct; // ciphertext - - if($mode == 'CBC') - { - if (!is_string($plaintext) || !is_array($key)) - { - $this->trigger_error('In CBC mode the first and second parameters should be strings', E_USER_WARNING); - return false; - } - } else { - if (!is_array($plaintext) || !is_array($key)) - { - $this->trigger_error('In ECB mode the first and second parameters should be byte arrays', E_USER_WARNING); - return false; - } - } - if (sizeof($key)*8 != $this->keySizeInBits) - { - $this->trigger_error('The key needs to be '. ( $this->keySizeInBits / 8 ) .' bytes in length', E_USER_WARNING); - return false; - } - if ($mode == "CBC") - $ct = $this->getRandomBytes($bpb); // get IV - else { - $mode = "ECB"; - $ct = Array(); - } - - // convert plaintext to byte array and pad with zeros if necessary. - $plaintext = $this->formatPlaintext($plaintext); - - $expandedKey = $this->keyExpansion($key); - - for ($block=0; $blockarray_slice_js_compat($plaintext, $block*$bpb, ($block+1)*$bpb); - if ($mode == "CBC") - { - for ($i=0; $i<$bpb; $i++) - { - $aBlock[$i] ^= $ct[$block*$bpb + $i]; - } - } - $cp = $this->cryptBlock($aBlock, $expandedKey); - $ct = $this->concat($ct, $cp); - } - - return $ct; - } - - // rijndaelDecrypt(ciphertext, key, mode) - // Decrypts the using the given key and mode. The parameter "ciphertext" - // must be an array of bytes. The parameter "key" must be an array of key - // bytes. If you have a hex string representing the ciphertext or key, - // invoke hexToByteArray() on it to convert it to an array of bytes. The - // parameter "mode" is a string, either "CBC" or "ECB". - // - // An array of bytes representing the plaintext is returned. To convert - // this array to a hex string, invoke byteArrayToHex() on it. To convert it - // to a string of characters, you can use byteArrayToString(). - - function rijndaelDecrypt($ciphertext, $key, $mode = 'ECB') { - //global $this->blockSizeInBits, $this->keySizeInBits; - $bpb = $this->blockSizeInBits / 8; // bytes per block - $pt = Array(); // plaintext array - // $aBlock; // a decrypted block - // $block; // current block number - - if (!$ciphertext) - { - $this->trigger_error('$ciphertext should be a byte array', E_USER_WARNING); - return false; - } - if( !is_array($key) ) - { - $this->trigger_error('$key should be a byte array', E_USER_WARNING); - return false; - } - if( is_string($ciphertext) ) - { - $this->trigger_error('$ciphertext should be a byte array', E_USER_WARNING); - return false; - } - if (sizeof($key)*8 != $this->keySizeInBits) - { - $this->trigger_error('Encryption key is the wrong length', E_USER_WARNING); - return false; - } - if (!$mode) - $mode = "ECB"; // assume ECB if mode omitted - - $expandedKey = $this->keyExpansion($key); - - // work backwards to accomodate CBC mode - for ($block=(sizeof($ciphertext) / $bpb)-1; $block>0; $block--) - { - if( ( $block*$bpb ) + ( ($block+1)*$bpb ) > count($ciphertext) ) - { - //$this->trigger_error('$ciphertext index out of bounds', E_USER_ERROR); - } - $current_block = $this->array_slice_js_compat($ciphertext, $block*$bpb, ($block+1)*$bpb); - if(count($current_block) * 8 != $this->blockSizeInBits) - { - // $c=count($current_block)*8; - // $this->trigger_error('We got a '.$c.'-bit block, instead of '.$this->blockSizeInBits.'', E_USER_ERROR); - } - $aBlock = $this->uncryptBlock($current_block, $expandedKey); - if(!$aBlock) - { - $this->trigger_error('Shared block decryption routine returned false', E_USER_WARNING); - return false; - } - if ($mode == "CBC") - for ($i=0; $i<$bpb; $i++) - $pt[($block-1)*$bpb + $i] = $aBlock[$i] ^ $ciphertext[($block-1)*$bpb + $i]; - else - $pt = $this->concat($aBlock, $pt); - } - - // do last block if ECB (skips the IV in CBC) - if ($mode == "ECB") - { - $x = $this->uncryptBlock($this->array_slice_js_compat($ciphertext, 0, $bpb), $expandedKey); - if(!$x) - { - $this->trigger_error('ECB block decryption routine returned false', E_USER_WARNING); - return false; - } - $pt = $this->concat($x, $pt); - if(!$pt) - { - $this->trigger_error('ECB concatenation routine returned false', E_USER_WARNING); - return false; - } - } - - return $pt; - } - - /** - * Wrapper for encryption. - * @param string $text the text to encrypt - * @param string $key the raw binary key to encrypt with - * @param int $return_encoding optional - can be ENC_BINARY, ENC_HEX or ENC_BASE64 - */ - - function encrypt($text, $key, $return_encoding = ENC_HEX) - { - if ( $text == '' ) - return ''; - if ( $this->mcrypt && $this->blockSizeInBits == mcrypt_module_get_algo_block_size(eval('return MCRYPT_RIJNDAEL_'.$this->keySizeInBits.';')) ) - { - $iv_size = mcrypt_get_iv_size($this->mcrypt, MCRYPT_MODE_ECB); - $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); - $cryptext = mcrypt_encrypt($this->mcrypt, $key, $text, MCRYPT_MODE_ECB, $iv); - switch($return_encoding) - { - case ENC_HEX: - default: - $cryptext = $this->strtohex($cryptext); - break; - case ENC_BINARY: - $cryptext = $cryptext; - break; - case ENC_BASE64: - $cryptext = base64_encode($cryptext); - break; - } - } - else - { - $key = $this->prepare_string($key); - $text = $this->prepare_string($text); - $cryptext = $this->rijndaelEncrypt($text, $key, 'ECB'); - if(!is_array($cryptext)) - { - echo 'Warning: encryption failed for string: '.print_r($text,true).'
'; - return false; - } - switch($return_encoding) - { - case ENC_HEX: - default: - $cryptext = $this->byteArrayToHex($cryptext); - break; - case ENC_BINARY: - $cryptext = $this->byteArrayToString($cryptext); - break; - case ENC_BASE64: - $cryptext = base64_encode($this->byteArrayToString($cryptext)); - break; - } - } - return $cryptext; - } - - /** - * Wrapper for decryption. - * @param string $text the encrypted text - * @param string $key the raw binary key used to encrypt the text - * @param int $input_encoding the encoding used for the encrypted string. Can be ENC_BINARY, ENC_HEX, or ENC_BASE64. - * @return string - */ - - function decrypt($text, $key, $input_encoding = ENC_HEX) - { - if ( $text == '' ) - return ''; - $text_orig = $text; - if ( isset($this->decrypt_cache[$key]) && is_array($this->decrypt_cache[$key]) ) - { - if ( isset($this->decrypt_cache[$key][$text]) ) - { - return $this->decrypt_cache[$key][$text]; - } - } - switch($input_encoding) - { - case ENC_BINARY: - default: - break; - case ENC_HEX: - $text = $this->hextostring($text); - break; - case ENC_BASE64: - $text = base64_decode($text); - break; - } - //$mod = strlen($text) % $this->blockSizeInBits; - //if($mod != 96) - //die('modulus check failed: '.$mod); - if ( $this->mcrypt ) - { - $iv_size = mcrypt_get_iv_size($this->mcrypt, MCRYPT_MODE_ECB); - $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); - $dypt = mcrypt_decrypt($this->mcrypt, $key, $text, MCRYPT_MODE_ECB, $iv); - } - else - { - $etext = $this->prepare_string($text); - $ekey = $this->prepare_string($key); - $mod = count($etext) % $this->blockSizeInBits; - $dypt = $this->rijndaelDecrypt($etext, $ekey, 'ECB'); - if(!$dypt) - { - echo '
'.print_r($dypt, true).'
'; - $this->trigger_error('Rijndael main decryption routine failed', E_USER_ERROR); - } - $dypt = $this->byteArrayToString($dypt); - } - if ( !isset($this->decrypt_cache[$key]) ) - $this->decrypt_cache[$key] = array(); - - $this->decrypt_cache[$key][$text_orig] = $dypt; - - return $dypt; - } - - /** - * Enano-ese equivalent of str_split() which is only found in PHP5 - * @param $text string the text to split - * @param $inc int size of each block - * @return array - */ - - function enano_str_split($text, $inc = 1) - { - if($inc < 1) return false; - if($inc >= strlen($text)) return Array($text); - $len = ceil(strlen($text) / $inc); - $ret = Array(); - for($i=0;$itrigger_error('First parameter should be an array', E_USER_WARNING); - return false; - } - $ret = ''; - foreach($arr as $a) - { - if($a != 0) $ret .= chr($a); - } - return $ret; - } - */ - - function strtohex($str) - { - $str = $this->enano_str_split($str); - $ret = ''; - foreach($str as $s) - { - $chr = dechex(ord($s)); - if(strlen($chr) < 2) $chr = '0' . $chr; - $ret .= $chr; - } - return $ret; - } - - function gen_readymade_key() - { - $key = $this->strtohex($this->randkey($this->keySizeInBits / 8)); - return $key; - } - - function prepare_string($text) - { - $ret = $this->hexToByteArray($this->strtohex($text)); - if(count($ret) != strlen($text)) - { - die('Could not convert string "' . $text . '" to hex byte array for encryption'); - } - return $ret; - } - - /** - * Decodes a hex string. - * @param string $hex The hex code to decode - * @return string - */ - - function hextostring($hex) - { - $hex = $this->enano_str_split($hex, 2); - $bin_key = ''; - foreach($hex as $nibble) - { - $byte = chr(hexdec($nibble)); - $bin_key .= $byte; - } - return $bin_key; - } -} - -/** - * XXTEA encryption arithmetic library. - * - * Copyright (C) 2006 Ma Bingyao - * Version: 1.5 - * LastModified: Dec 5, 2006 - * This library is free. You can redistribute it and/or modify it. - * - * From dandaman32: I am treating this code as GPL, as implied by the license statement above. - */ -class TEACrypt extends AESCrypt { - function long2str($v, $w) { - $len = count($v); - $n = ($len - 1) << 2; - if ($w) { - $m = $v[$len - 1]; - if (($m < $n - 3) || ($m > $n)) return false; - $n = $m; - } - $s = array(); - for ($i = 0; $i < $len; $i++) { - $s[$i] = pack("V", $v[$i]); - } - if ($w) { - return substr(join('', $s), 0, $n); - } - else { - return join('', $s); - } - } - - function str2long($s, $w) { - $v = unpack("V*", $s. str_repeat("\0", (4 - strlen($s) % 4) & 3)); - $v = array_values($v); - if ($w) { - $v[count($v)] = strlen($s); - } - return $v; - } - - function int32($n) { - while ($n >= 2147483648) $n -= 4294967296; - while ($n <= -2147483649) $n += 4294967296; - return (int)$n; - } - - // The third parameter is to ensure compatibility with php 6.0-dev - function encrypt($str, $key, $unused = ENC_HEX) { - if ($str == "") - { - return ""; - } - $v = $this->str2long($str, true); - $k = $this->str2long($key, false); - if (count($k) < 4) { - for ($i = count($k); $i < 4; $i++) { - $k[$i] = 0; - } - } - $n = count($v) - 1; - - $z = $v[$n]; - $y = $v[0]; - $delta = 0x9E3779B9; - $q = floor(6 + 52 / ($n + 1)); - $sum = 0; - while (0 < $q--) { - $sum = $this->int32($sum + $delta); - $e = $sum >> 2 & 3; - for ($p = 0; $p < $n; $p++) { - $y = $v[$p + 1]; - $mx = $this->int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ $this->int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)); - $z = $v[$p] = $this->int32($v[$p] + $mx); - } - $y = $v[0]; - $mx = $this->int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ $this->int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)); - $z = $v[$n] = $this->int32($v[$n] + $mx); - } - return $this->long2str($v, false); - } - - // The third parameter is to ensure compatibility with php 6.0-dev - function decrypt($str, $key, $unused = ENC_HEX) { - if ($str == "") { - return ""; - } - $v = $this->str2long($str, false); - $k = $this->str2long($key, false); - if (count($k) < 4) { - for ($i = count($k); $i < 4; $i++) { - $k[$i] = 0; - } - } - $n = count($v) - 1; - - $z = $v[$n]; - $y = $v[0]; - $delta = 0x9E3779B9; - $q = floor(6 + 52 / ($n + 1)); - $sum = $this->int32($q * $delta); - while ($sum != 0) { - $e = $sum >> 2 & 3; - for ($p = $n; $p > 0; $p--) { - $z = $v[$p - 1]; - $mx = $this->int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ $this->int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)); - $y = $v[$p] = $this->int32($v[$p] - $mx); - } - $z = $v[$n]; - $mx = $this->int32((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ $this->int32(($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)); - $y = $v[0] = $this->int32($v[0] - $mx); - $sum = $this->int32($sum - $delta); - } - return $this->long2str($v, true); - } -} - -?> + + * Ported to PHP by Dan Fuhry + * @package phijndael + * @author Fritz Schneider + * @author Dan Fuhry + * @license BSD-style license + */ + +define ('ENC_BASE64', 202); +define ('ENC_BINARY', 203); + +$_aes_objcache = array(); + +class AESCrypt { + + var $debug = false; + var $mcrypt = false; + var $decrypt_cache = array(); + + // Rijndael parameters -- Valid values are 128, 192, or 256 + + var $keySizeInBits = 128; + var $blockSizeInBits = 128; + + /////// You shouldn't have to modify anything below this line except for + /////// the function getRandomBytes(). + // + // Note: in the following code the two dimensional arrays are indexed as + // you would probably expect, as array[row][column]. The state arrays + // are 2d arrays of the form state[4][Nb]. + + + // The number of rounds for the cipher, indexed by [Nk][Nb] + var $roundsArray = Array(0,0,0,0,Array(0,0,0,0,10,0, 12,0, 14),0, + Array(0,0,0,0,12,0, 12,0, 14),0, + Array(0,0,0,0,14,0, 14,0, 14) ); + + // The number of bytes to shift by in shiftRow, indexed by [Nb][row] + var $shiftOffsets = Array(0,0,0,0,Array(0,1, 2, 3),0,Array(0,1, 2, 3),0,Array(0,1, 3, 4) ); + + // The round constants used in subkey expansion + var $Rcon = Array( + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, + 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, + 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 ); + + // Precomputed lookup table for the SBox + var $SBox = Array( + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, + 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, + 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, + 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, + 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, + 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, + 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, + 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, + 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, + 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, + 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, + 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, + 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, + 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, + 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, + 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, + 22 ); + + // Precomputed lookup table for the inverse SBox + var $SBoxInverse = Array( + 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, + 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, + 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, + 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, + 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, + 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, + 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, + 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, + 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, + 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, + 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, + 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, + 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, + 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, + 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, + 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, + 125 ); + + function __construct($ks = 128, $bs = 128, $debug = false) + { + $this->keySizeInBits = $ks; + $this->blockSizeInBits = $bs; + + // Use the Mcrypt library? This speeds things up dramatically. + if(defined('MCRYPT_RIJNDAEL_' . $ks) && defined('MCRYPT_ACCEL')) + { + eval('$mcb = MCRYPT_RIJNDAEL_' . $ks.';'); + $bks = mcrypt_module_get_algo_block_size($mcb); + $bks = $bks * 8; + if ( $bks != $bs ) + { + $mcb = false; + echo (string)$bks; + } + } + else + { + $mcb = false; + } + + $this->mcrypt = $mcb; + + // Cipher parameters ... do not change these + $this->Nk = $this->keySizeInBits / 32; + $this->Nb = $this->blockSizeInBits / 32; + $this->Nr = $this->roundsArray[$this->Nk][$this->Nb]; + $this->debug = $debug; + } + + public static function singleton($key_size, $block_size) + { + static $_aes_objcache; + if ( isset($_aes_objcache["$key_size,$block_size"]) ) + { + return $_aes_objcache["$key_size,$block_size"]; + } + + $_aes_objcache["$key_size,$block_size"] = new AESCrypt($key_size, $block_size); + return $_aes_objcache["$key_size,$block_size"]; + } + + // Error handler + + function trigger_error($text, $level = E_USER_NOTICE) + { + $bt = debug_backtrace(); + $lastfunc =& $bt[1]; + switch($level) + { + case E_USER_NOTICE: + default: + $desc = 'Notice'; + break; + case E_USER_WARNING: + $desc = 'Warning'; + break; + case E_USER_ERROR: + $desc = 'Fatal'; + break; + } + ob_start(); + if($this->debug || $level == E_USER_ERROR) echo "AES encryption: {$desc}: $text in {$lastfunc['file']} on line {$lastfunc['line']} in function {$lastfunc['function']}
"; + if($this->debug) + { + //echo '
'.enano_debug_print_backtrace(true).'
'; + } + ob_end_flush(); + if($level == E_USER_ERROR) + { + echo '

This can sometimes happen if you are upgrading Enano to a new version and did not log out first. Click here to force cookies to clear and try again. You will be logged out.

'; + exit; + } + } + + function array_slice_js_compat($array, $start, $finish = 0) + { + $len = $finish - $start; + if($len < 0) $len = 0 - $len; + //if($this->debug) echo (string)$len . ' '; + //if(count($array) < $start + $len) + // $this->trigger_error('Index out of range', E_USER_WARNING); + return array_slice($array, $start, $len); + } + + function concat($s1, $s2) + { + if(is_array($s1) && is_array($s2)) + return array_merge($s1, $s2); + elseif( ( is_array($s1) && !is_array($s2) ) || ( !is_array($s1) && is_array($s2) ) ) + { + $this->trigger_error('incompatible types - you can\'t combine a non-array with an array', E_USER_WARNING); + return false; + } + else + return $s1 . $s2; + } + + // This method circularly shifts the array left by the number of elements + // given in its parameter. It returns the resulting array and is used for + // the ShiftRow step. Note that shift() and push() could be used for a more + // elegant solution, but they require IE5.5+, so I chose to do it manually. + + function cyclicShiftLeft($theArray, $positions) { + if(!is_int($positions)) + { + $this->trigger_error('$positions is not an integer! Backtrace:
'.print_r(debug_backtrace(), true).'
', E_USER_WARNING); + return false; + } + $second = array_slice($theArray, 0, $positions); + $first = array_slice($theArray, $positions); + $theArray = array_merge($first, $second); + return $theArray; + } + + // Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec. + + function xtime($poly) { + $poly <<= 1; + return (($poly & 0x100) ? ($poly ^ 0x11B) : ($poly)); + } + + // Multiplies the two elements of GF(2^8) together and returns the result. + // See the Rijndael spec, but should be straightforward: for each power of + // the indeterminant that has a 1 coefficient in x, add y times that power + // to the result. x and y should be bytes representing elements of GF(2^8) + + function mult_GF256($x, $y) { + $result = 0; + + for ($bit = 1; $bit < 256; $bit *= 2, $y = $this->xtime($y)) { + if ($x & $bit) + $result ^= $y; + } + return $result; + } + + // Performs the substitution step of the cipher. State is the 2d array of + // state information (see spec) and direction is string indicating whether + // we are performing the forward substitution ("encrypt") or inverse + // substitution (anything else) + + function byteSub(&$state, $direction) { + //global $this->SBox, $this->SBoxInverse, $this->Nb; + if ($direction == "encrypt") // Point S to the SBox we're using + $S =& $this->SBox; + else + $S =& $this->SBoxInverse; + for ($i = 0; $i < 4; $i++) // Substitute for every byte in state + for ($j = 0; $j < $this->Nb; $j++) + $state[$i][$j] = $S[$state[$i][$j]]; + } + + // Performs the row shifting step of the cipher. + + function shiftRow(&$state, $direction) { + //global $this->Nb, $this->shiftOffsets; + for ($i=1; $i<4; $i++) // Row 0 never shifts + if ($direction == "encrypt") + $state[$i] = $this->cyclicShiftLeft($state[$i], $this->shiftOffsets[$this->Nb][$i]); + else + $state[$i] = $this->cyclicShiftLeft($state[$i], $this->Nb - $this->shiftOffsets[$this->Nb][$i]); + + } + + // Performs the column mixing step of the cipher. Most of these steps can + // be combined into table lookups on 32bit values (at least for encryption) + // to greatly increase the speed. + + function mixColumn(&$state, $direction) { + //global $this->Nb; + $b = Array(); // Result of matrix multiplications + for ($j = 0; $j < $this->Nb; $j++) { // Go through each column... + for ($i = 0; $i < 4; $i++) { // and for each row in the column... + if ($direction == "encrypt") + $b[$i] = $this->mult_GF256($state[$i][$j], 2) ^ // perform mixing + $this->mult_GF256($state[($i+1)%4][$j], 3) ^ + $state[($i+2)%4][$j] ^ + $state[($i+3)%4][$j]; + else + $b[$i] = $this->mult_GF256($state[$i][$j], 0xE) ^ + $this->mult_GF256($state[($i+1)%4][$j], 0xB) ^ + $this->mult_GF256($state[($i+2)%4][$j], 0xD) ^ + $this->mult_GF256($state[($i+3)%4][$j], 9); + } + for ($i = 0; $i < 4; $i++) // Place result back into column + $state[$i][$j] = $b[$i]; + } + } + + // Adds the current round key to the state information. Straightforward. + + function addRoundKey(&$state, $roundKey) { + //global $this->Nb; + for ($j = 0; $j < $this->Nb; $j++) { // Step through columns... + $state[0][$j] ^= ( $roundKey[$j] & 0xFF); // and XOR + $state[1][$j] ^= (($roundKey[$j]>>8) & 0xFF); + $state[2][$j] ^= (($roundKey[$j]>>16) & 0xFF); + $state[3][$j] ^= (($roundKey[$j]>>24) & 0xFF); + } + } + + // This function creates the expanded key from the input (128/192/256-bit) + // key. The parameter key is an array of bytes holding the value of the key. + // The returned value is an array whose elements are the 32-bit words that + // make up the expanded key. + + function keyExpansion($key) { + //global $this->keySizeInBits, $this->blockSizeInBits, $this->roundsArray, $this->Nk, $this->Nb, $this->Nr, $this->Nk, $this->SBox, $this->Rcon; + $expandedKey = Array(); + + // in case the key size or parameters were changed... + $this->Nk = $this->keySizeInBits / 32; + $this->Nb = $this->blockSizeInBits / 32; + $this->Nr = $this->roundsArray[$this->Nk][$this->Nb]; + + for ($j=0; $j < $this->Nk; $j++) // Fill in input key first + $expandedKey[$j] = + ($key[4*$j]) | ($key[4*$j+1]<<8) | ($key[4*$j+2]<<16) | ($key[4*$j+3]<<24); + + // Now walk down the rest of the array filling in expanded key bytes as + // per Rijndael's spec + for ($j = $this->Nk; $j < $this->Nb * ($this->Nr + 1); $j++) { // For each word of expanded key + $temp = $expandedKey[$j - 1]; + if ($j % $this->Nk == 0) + $temp = ( ($this->SBox[($temp>>8) & 0xFF]) | + ($this->SBox[($temp>>16) & 0xFF]<<8) | + ($this->SBox[($temp>>24) & 0xFF]<<16) | + ($this->SBox[$temp & 0xFF]<<24) ) ^ $this->Rcon[floor($j / $this->Nk) - 1]; + elseif ($this->Nk > 6 && $j % $this->Nk == 4) + $temp = ($this->SBox[($temp>>24) & 0xFF]<<24) | + ($this->SBox[($temp>>16) & 0xFF]<<16) | + ($this->SBox[($temp>>8) & 0xFF]<<8) | + ($this->SBox[ $temp & 0xFF]); + $expandedKey[$j] = $expandedKey[$j-$this->Nk] ^ $temp; + } + return $expandedKey; + } + + // Rijndael's round functions... + + function RijndaelRound(&$state, $roundKey) { + $this->byteSub($state, "encrypt"); + $this->shiftRow($state, "encrypt"); + $this->mixColumn($state, "encrypt"); + $this->addRoundKey($state, $roundKey); + } + + function InverseRijndaelRound(&$state, $roundKey) { + $this->addRoundKey($state, $roundKey); + $this->mixColumn($state, "decrypt"); + $this->shiftRow($state, "decrypt"); + $this->byteSub($state, "decrypt"); + } + + function FinalRijndaelRound(&$state, $roundKey) { + $this->byteSub($state, "encrypt"); + $this->shiftRow($state, "encrypt"); + $this->addRoundKey($state, $roundKey); + } + + function InverseFinalRijndaelRound(&$state, $roundKey){ + $this->addRoundKey($state, $roundKey); + $this->shiftRow($state, "decrypt"); + $this->byteSub($state, "decrypt"); + } + + // encrypt is the basic encryption function. It takes parameters + // block, an array of bytes representing a plaintext block, and expandedKey, + // an array of words representing the expanded key previously returned by + // keyExpansion(). The ciphertext block is returned as an array of bytes. + + function cryptBlock($block, $expandedKey) { + //global $this->blockSizeInBits, $this->Nb, $this->Nr; + $t=count($block)*8; + if (!is_array($block) || count($block)*8 != $this->blockSizeInBits) + { + $this->trigger_error('block is bad or block size is wrong
'.print_r($block, true).'

Aiming for size '.$this->blockSizeInBits.', got '.$t.'.', E_USER_WARNING); + return false; + } + if (!$expandedKey) + return; + + $block = $this->packBytes($block); + $this->addRoundKey($block, $expandedKey); + for ($i=1; $i<$this->Nr; $i++) + $this->RijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$i, $this->Nb*($i+1))); + $this->FinalRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$this->Nr)); + $ret = $this->unpackBytes($block); + return $ret; + } + + // decrypt is the basic decryption function. It takes parameters + // block, an array of bytes representing a ciphertext block, and expandedKey, + // an array of words representing the expanded key previously returned by + // keyExpansion(). The decrypted block is returned as an array of bytes. + + function unCryptBlock($block, $expandedKey) { + $t = count($block)*8; + if (!is_array($block) || count($block)*8 != $this->blockSizeInBits) + { + $this->trigger_error('$block is not a valid rijndael-block array: '.$this->byteArrayToHex($block).'

'.print_r($block, true).'

Block size is '.$t.', should be '.$this->blockSizeInBits.'

', E_USER_WARNING); + return false; + } + if (!$expandedKey) + { + $this->trigger_error('$expandedKey is invalid', E_USER_WARNING); + return false; + } + + $block = $this->packBytes($block); + $this->InverseFinalRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$this->Nr)); + for ($i = $this->Nr - 1; $i>0; $i--) + { + $this->InverseRijndaelRound($block, $this->array_slice_js_compat($expandedKey, $this->Nb*$i, $this->Nb*($i+1))); + } + $this->addRoundKey($block, $expandedKey); + $ret = $this->unpackBytes($block); + if(!is_array($ret)) + { + $this->trigger_error('$ret is not an array', E_USER_WARNING); + } + return $ret; + } + + // This method takes a byte array (byteArray) and converts it to a string by + // applying String.fromCharCode() to each value and concatenating the result. + // The resulting string is returned. Note that this function SKIPS zero bytes + // under the assumption that they are padding added in formatPlaintext(). + // Obviously, do not invoke this method on raw data that can contain zero + // bytes. It is really only appropriate for printable ASCII/Latin-1 + // values. Roll your own function for more robust functionality :) + + function byteArrayToString($byteArray) { + $result = ""; + for($i=0; $i "10ff". The function returns a + // string. + + /* + function byteArrayToHex($byteArray) { + $result = ""; + if (!$byteArray) + return; + for ($i=0; $i [16, 255]. This + // function returns an array. + + /* + function hexToByteArray($hexString) { + $byteArray = Array(); + if (strlen($hexString) % 2) // must have even length + return; + if (strstr($hexString, "0x") == $hexString || strstr($hexString, "0X") == $hexString) + $hexString = substr($hexString, 2); + for ($i = 0; $ienano_str_split($str, 2); + foreach($str as $s) + { + $arr[] = intval(hexdec($s)); + } + return $arr; + } + + // This function packs an array of bytes into the four row form defined by + // Rijndael. It assumes the length of the array of bytes is divisible by + // four. Bytes are filled in according to the Rijndael spec (starting with + // column 0, row 0 to 3). This function returns a 2d array. + + function packBytes($octets) { + $state = Array(); + if (!$octets || count($octets) % 4) + return; + + $state[0] = Array(); $state[1] = Array(); + $state[2] = Array(); $state[3] = Array(); + for ($j=0; $jblockSizeInBits; + $bpb = $this->blockSizeInBits / 8; // bytes per block + + // if primitive string or String instance + if (is_string($plaintext)) { + $plaintext = $this->enano_str_split($plaintext); + // Unicode issues here (ignoring high byte) + for ($i=0; $icharCodeAt($plaintext[$i], 0) & 0xFF; + } + + for ($i = $bpb - (sizeof($plaintext) % $bpb); $i > 0 && $i < $bpb; $i--) + $plaintext[] = 0; + + return $plaintext; + } + + // Returns an array containing "howMany" random bytes. YOU SHOULD CHANGE THIS + // TO RETURN HIGHER QUALITY RANDOM BYTES IF YOU ARE USING THIS FOR A "REAL" + // APPLICATION. (edit: done, mt_rand() is relatively secure) + + function getRandomBytes($howMany) { + $bytes = Array(); + for ($i=0; $i<$howMany; $i++) + $bytes[$i] = mt_rand(0, 255); + return $bytes; + } + + // rijndaelEncrypt(plaintext, key, mode) + // Encrypts the plaintext using the given key and in the given mode. + // The parameter "plaintext" can either be a string or an array of bytes. + // The parameter "key" must be an array of key bytes. If you have a hex + // string representing the key, invoke hexToByteArray() on it to convert it + // to an array of bytes. The third parameter "mode" is a string indicating + // the encryption mode to use, either "ECB" or "CBC". If the parameter is + // omitted, ECB is assumed. + // + // An array of bytes representing the cihpertext is returned. To convert + // this array to hex, invoke byteArrayToHex() on it. If you are using this + // "for real" it is a good idea to change the function getRandomBytes() to + // something that returns truly random bits. + + function rijndaelEncrypt($plaintext, $key, $mode = 'ECB') { + //global $this->blockSizeInBits, $this->keySizeInBits; + $bpb = $this->blockSizeInBits / 8; // bytes per block + // var ct; // ciphertext + + if($mode == 'CBC') + { + if (!is_string($plaintext) || !is_array($key)) + { + $this->trigger_error('In CBC mode the first and second parameters should be strings', E_USER_WARNING); + return false; + } + } else { + if (!is_array($plaintext) || !is_array($key)) + { + $this->trigger_error('In ECB mode the first and second parameters should be byte arrays', E_USER_WARNING); + return false; + } + } + if (sizeof($key)*8 != $this->keySizeInBits) + { + $this->trigger_error('The key needs to be '. ( $this->keySizeInBits / 8 ) .' bytes in length', E_USER_WARNING); + return false; + } + if ($mode == "CBC") + $ct = $this->getRandomBytes($bpb); // get IV + else { + $mode = "ECB"; + $ct = Array(); + } + + // convert plaintext to byte array and pad with zeros if necessary. + $plaintext = $this->formatPlaintext($plaintext); + + $expandedKey = $this->keyExpansion($key); + + for ($block=0; $blockarray_slice_js_compat($plaintext, $block*$bpb, ($block+1)*$bpb); + if ($mode == "CBC") + { + for ($i=0; $i<$bpb; $i++) + { + $aBlock[$i] ^= $ct[$block*$bpb + $i]; + } + } + $cp = $this->cryptBlock($aBlock, $expandedKey); + $ct = $this->concat($ct, $cp); + } + + return $ct; + } + + // rijndaelDecrypt(ciphertext, key, mode) + // Decrypts the using the given key and mode. The parameter "ciphertext" + // must be an array of bytes. The parameter "key" must be an array of key + // bytes. If you have a hex string representing the ciphertext or key, + // invoke hexToByteArray() on it to convert it to an array of bytes. The + // parameter "mode" is a string, either "CBC" or "ECB". + // + // An array of bytes representing the plaintext is returned. To convert + // this array to a hex string, invoke byteArrayToHex() on it. To convert it + // to a string of characters, you can use byteArrayToString(). + + function rijndaelDecrypt($ciphertext, $key, $mode = 'ECB') { + //global $this->blockSizeInBits, $this->keySizeInBits; + $bpb = $this->blockSizeInBits / 8; // bytes per block + $pt = Array(); // plaintext array + // $aBlock; // a decrypted block + // $block; // current block number + + if (!$ciphertext) + { + $this->trigger_error('$ciphertext should be a byte array', E_USER_WARNING); + return false; + } + if( !is_array($key) ) + { + $this->trigger_error('$key should be a byte array', E_USER_WARNING); + return false; + } + if( is_string($ciphertext) ) + { + $this->trigger_error('$ciphertext should be a byte array', E_USER_WARNING); + return false; + } + if (sizeof($key)*8 != $this->keySizeInBits) + { + $this->trigger_error('Encryption key is the wrong length', E_USER_WARNING); + return false; + } + if (!$mode) + $mode = "ECB"; // assume ECB if mode omitted + + $expandedKey = $this->keyExpansion($key); + + // work backwards to accomodate CBC mode + for ($block=(sizeof($ciphertext) / $bpb)-1; $block>0; $block--) + { + if( ( $block*$bpb ) + ( ($block+1)*$bpb ) > count($ciphertext) ) + { + //$this->trigger_error('$ciphertext index out of bounds', E_USER_ERROR); + } + $current_block = $this->array_slice_js_compat($ciphertext, $block*$bpb, ($block+1)*$bpb); + if(count($current_block) * 8 != $this->blockSizeInBits) + { + // $c=count($current_block)*8; + // $this->trigger_error('We got a '.$c.'-bit block, instead of '.$this->blockSizeInBits.'', E_USER_ERROR); + } + $aBlock = $this->uncryptBlock($current_block, $expandedKey); + if(!$aBlock) + { + $this->trigger_error('Shared block decryption routine returned false', E_USER_WARNING); + return false; + } + if ($mode == "CBC") + for ($i=0; $i<$bpb; $i++) + $pt[($block-1)*$bpb + $i] = $aBlock[$i] ^ $ciphertext[($block-1)*$bpb + $i]; + else + $pt = $this->concat($aBlock, $pt); + } + + // do last block if ECB (skips the IV in CBC) + if ($mode == "ECB") + { + $x = $this->uncryptBlock($this->array_slice_js_compat($ciphertext, 0, $bpb), $expandedKey); + if(!$x) + { + $this->trigger_error('ECB block decryption routine returned false', E_USER_WARNING); + return false; + } + $pt = $this->concat($x, $pt); + if(!$pt) + { + $this->trigger_error('ECB concatenation routine returned false', E_USER_WARNING); + return false; + } + } + + return $pt; + } + + /** + * Wrapper for encryption. + * @param string $text the text to encrypt + * @param string $key the raw binary key to encrypt with + * @param int $return_encoding optional - can be ENC_BINARY, ENC_HEX or ENC_BASE64 + */ + + function encrypt($text, $key, $return_encoding = ENC_HEX) + { + if ( $text == '' ) + return ''; + if ( $this->mcrypt && $this->blockSizeInBits == mcrypt_module_get_algo_block_size(eval('return MCRYPT_RIJNDAEL_'.$this->keySizeInBits.';')) ) + { + $iv_size = mcrypt_get_iv_size($this->mcrypt, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); + $cryptext = mcrypt_encrypt($this->mcrypt, $key, $text, MCRYPT_MODE_ECB, $iv); + switch($return_encoding) + { + case ENC_HEX: + default: + $cryptext = $this->strtohex($cryptext); + break; + case ENC_BINARY: + $cryptext = $cryptext; + break; + case ENC_BASE64: + $cryptext = base64_encode($cryptext); + break; + } + } + else + { + $key = $this->prepare_string($key); + $text = $this->prepare_string($text); + profiler_log('AES: Started encryption of a string'); + $cryptext = $this->rijndaelEncrypt($text, $key, 'ECB'); + profiler_log('AES: Finished encryption of a string'); + if(!is_array($cryptext)) + { + echo 'Warning: encryption failed for string: '.print_r($text,true).'
'; + return false; + } + switch($return_encoding) + { + case ENC_HEX: + default: + $cryptext = $this->byteArrayToHex($cryptext); + break; + case ENC_BINARY: + $cryptext = $this->byteArrayToString($cryptext); + break; + case ENC_BASE64: + $cryptext = base64_encode($this->byteArrayToString($cryptext)); + break; + } + } + return $cryptext; + } + + /** + * Wrapper for decryption. + * @param string $text the encrypted text + * @param string $key the raw binary key used to encrypt the text + * @param int $input_encoding the encoding used for the encrypted string. Can be ENC_BINARY, ENC_HEX, or ENC_BASE64. + * @return string + */ + + function decrypt($text, $key, $input_encoding = ENC_HEX) + { + if ( $text == '' ) + return ''; + + switch($input_encoding) + { + case ENC_BINARY: + default: + break; + case ENC_HEX: + $text = $this->hextostring($text); + break; + case ENC_BASE64: + $text = base64_decode($text); + break; + } + + // Run memory-cache check + if ( isset($this->decrypt_cache[$key]) && is_array($this->decrypt_cache[$key]) ) + { + if ( isset($this->decrypt_cache[$key][$text]) ) + { + return $this->decrypt_cache[$key][$text]; + } + } + + // Run disk-cache check + $hash = sha1($text . '::' . $key); + if ( $dypt = aes_decrypt_cache_fetch($hash) ) + return $dypt; + + $text_bin = $text; + $key_bin = $key; + + if ( $this->mcrypt ) + { + $iv_size = mcrypt_get_iv_size($this->mcrypt, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); + $dypt = mcrypt_decrypt($this->mcrypt, $key, $text, MCRYPT_MODE_ECB, $iv); + } + else + { + $etext = $this->prepare_string($text); + $ekey = $this->prepare_string($key); + $mod = count($etext) % $this->blockSizeInBits; + profiler_log('AES: Started decryption of a string'); + $dypt = $this->rijndaelDecrypt($etext, $ekey, 'ECB'); + profiler_log('AES: Finished decryption of a string'); + if(!$dypt) + { + echo '
'.print_r($dypt, true).'
'; + $this->trigger_error('Rijndael main decryption routine failed', E_USER_ERROR); + } + $dypt = $this->byteArrayToString($dypt); + } + if ( !isset($this->decrypt_cache[$key_bin]) ) + $this->decrypt_cache[$key_bin] = array(); + + $this->decrypt_cache[$key_bin][$text_bin] = $dypt; + + aes_decrypt_cache_store($text_bin, $dypt, $key_bin); + + return $dypt; + } + + /** + * Enano-ese equivalent of str_split() which is only found in PHP5 + * @param $text string the text to split + * @param $inc int size of each block + * @return array + */ + + function enano_str_split($text, $inc = 1) + { + if($inc < 1) return false; + if($inc >= strlen($text)) return Array($text); + $len = ceil(strlen($text) / $inc); + $ret = Array(); + for($i=0;$itrigger_error('First parameter should be an array', E_USER_WARNING); + return false; + } + $ret = ''; + foreach($arr as $a) + { + if($a != 0) $ret .= chr($a); + } + return $ret; + } + */ + + function strtohex($str) + { + $str = $this->enano_str_split($str); + $ret = ''; + foreach($str as $s) + { + $chr = dechex(ord($s)); + if(strlen($chr) < 2) $chr = '0' . $chr; + $ret .= $chr; + } + return $ret; + } + + function gen_readymade_key() + { + $key = $this->strtohex($this->randkey($this->keySizeInBits / 8)); + return $key; + } + + function prepare_string($text) + { + $ret = $this->hexToByteArray($this->strtohex($text)); + if(count($ret) != strlen($text)) + { + die('Could not convert string "' . $text . '" to hex byte array for encryption'); + } + return $ret; + } + + /** + * Decodes a hex string. + * @param string $hex The hex code to decode + * @return string + */ + + function hextostring($hex) + { + $hex = $this->enano_str_split($hex, 2); + $bin_key = ''; + foreach($hex as $nibble) + { + $byte = chr(hexdec($nibble)); + $bin_key .= $byte; + } + return $bin_key; + } +} + +function aes_decrypt_cache_store($encrypted, $decrypted, $key) +{ + $cache_file = ENANO_ROOT . '/cache/aes_decrypt.php'; + // only cache if $decrypted is long enough to actually warrant caching + if ( strlen($decrypted) < 32 ) + { + profiler_log("AES: Skipped caching a string (probably a password, we dunno) because it's too short"); + return false; + } + if ( file_exists($cache_file) ) + { + require_once($cache_file); + global $aes_decrypt_cache; + $cachekey = sha1($encrypted . '::' . $key); + $aes_decrypt_cache[$cachekey] = $decrypted; + + if ( count($aes_decrypt_cache) > 5000 ) + { + // we've got a lot of strings in the cache, clear out a few + $keys = array_keys($aes_decrypt_cache); + for ( $i = 0; $i < 2500; $i++ ) + { + unset($aes_decrypt_cache[$keys[$i]]); + unset($aes_decrypt_cache[$keys[$i]]); + } + } + } + else + { + $aes_decrypt_cache = array( + sha1($encrypted . '::' . $key) => $decrypted + ); + } + // call var_export and collect contents + ob_start(); + var_export($aes_decrypt_cache); + $dec_cache_string = ob_get_contents(); + ob_end_clean(); + $f = @fopen($cache_file, 'w'); + if ( !$f ) + return false; + fwrite($f, " diff -r d823e49e2e4e -r c433348f3628 includes/search.php --- a/includes/search.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/search.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * search.php - algorithm used to search pages * @@ -75,7 +75,7 @@ $words = explode(' ', $letters); foreach($words as $c => $w) { - if(strlen($w) < 2 || in_array($w, $stopwords) || strlen($w) > 63) + if(strlen($w) < 2 || in_array($w, $stopwords) || strlen($w) > 63 || preg_match('/[\']{2,}/', $w)) unset($words[$c]); else $words[$c] = $w; @@ -112,12 +112,15 @@ * @param string Search query * @param string Will be filled with any warnings encountered whilst parsing the query * @param bool Case sensitivity - defaults to false + * @param array|reference Will be filled with the parsed list of words. * @return array */ -function perform_search($query, &$warnings, $case_sensitive = false) +function perform_search($query, &$warnings, $case_sensitive = false, &$word_list) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + $warnings = array(); $query = parse_search_query($query, $warnings); @@ -165,7 +168,7 @@ if ( count($query['any']) < 1 && count($query['req']) < 1 && count($query_phrase['any']) < 1 && count($query_phrase['req']) < 1 ) { // This is both because of technical restrictions and devastation that would occur on shared servers/large sites. - $warnings[] = 'You need to have at least one keyword in your search query. Searching only for pages not containing a term is not allowed.'; + $warnings[] = $lang->get('search_err_query_no_positive'); return array(); } @@ -522,13 +525,13 @@ if ( isset($scores[$idstring]) ) { $page_data[$idstring] = array( - 'page_name' => $page['name'], + 'page_name' => highlight_search_result($page['name'], $word_list, $case_sensitive), 'page_text' => '', 'page_id' => $page['urlname_nons'], 'namespace' => $page['namespace'], 'score' => $scores[$idstring], 'page_length' => 1, - 'page_note' => '[Special page]' + 'page_note' => '[' . $lang->get('search_result_tag_special') . ']' ); } } @@ -592,6 +595,11 @@ // if ( $score > $divisor ) // $score = $divisor; $datum['score'] = round($score / $divisor, 2) * 100; + + // Highlight the URL + $datum['url_highlight'] = makeUrlComplete($datum['namespace'], $datum['page_id']); + $datum['url_highlight'] = preg_replace('/\?.+$/', '', $datum['url_highlight']); + $datum['url_highlight'] = highlight_search_result($datum['url_highlight'], $word_list, $case_sensitive); // Store it in our until-now-unused results array $results[] = $datum; @@ -613,6 +621,8 @@ function parse_search_query($query, &$warnings) { + global $lang; + $stopwords = get_stopwords(); $ret = array( 'any' => array(), @@ -663,7 +673,7 @@ if ( $ticker == 20 ) { - $warnings[] = 'Some of your search terms were excluded because searches are limited to 20 terms to prevent excessive server load.'; + $warnings[] = $lang->get('search_err_query_too_many_terms'); break; } @@ -672,13 +682,13 @@ $word = substr ( $atom, 2, ( strlen( $atom ) - 3 ) ); if ( strlen ( $word ) < 2 || in_array($word, $stopwords) ) { - $warnings[] = 'One or more of your search terms was excluded because either it was less than 2 characters in length or is a common word (a stopword) that is typically found on a large number of pages. Examples of stopwords include "the", "this", "which", "with", etc.'; + $warnings[] = $lang->get('search_err_query_has_stopwords'); $ticker--; continue; } if(in_array($word, $ret['req'])) { - $warnings[] = 'One or more of your search terms was excluded because duplicate terms were encountered.'; + $warnings[] = $lang->get('search_err_query_dup_terms'); $ticker--; continue; } @@ -689,13 +699,13 @@ $word = substr ( $atom, 2, ( strlen( $atom ) - 3 ) ); if ( strlen ( $word ) < 4 ) { - $warnings[] = 'One or more of your search terms was excluded because terms must be at least 4 characters in length.'; + $warnings[] = $lang->get('search_err_query_term_too_short'); $ticker--; continue; } if(in_array($word, $ret['not'])) { - $warnings[] = 'One or more of your search terms was excluded because duplicate terms were encountered.'; + $warnings[] = $lang->get('search_err_query_dup_terms'); $ticker--; continue; } @@ -706,13 +716,13 @@ $word = substr ( $atom, 1 ); if ( strlen ( $word ) < 2 || in_array($word, $stopwords) ) { - $warnings[] = 'One or more of your search terms was excluded because either it was less than 2 characters in length or is a common word (a stopword) that is typically found on a large number of pages. Examples of stopwords include "the", "this", "which", "with", etc.'; + $warnings[] = $lang->get('search_err_query_has_stopwords'); $ticker--; continue; } if(in_array($word, $ret['req'])) { - $warnings[] = 'One or more of your search terms was excluded because duplicate terms were encountered.'; + $warnings[] = $lang->get('search_err_query_dup_terms'); $ticker--; continue; } @@ -723,13 +733,13 @@ $word = substr ( $atom, 1 ); if ( strlen ( $word ) < 2 || in_array($word, $stopwords) ) { - $warnings[] = 'One or more of your search terms was excluded because either it was less than 2 characters in length or is a common word (a stopword) that is typically found on a large number of pages. Examples of stopwords include "the", "this", "which", "with", etc.'; + $warnings[] = $lang->get('search_err_query_has_stopwords'); $ticker--; continue; } if(in_array($word, $ret['not'])) { - $warnings[] = 'One or more of your search terms was excluded because duplicate terms were encountered.'; + $warnings[] = $lang->get('search_err_query_dup_terms'); $ticker--; continue; } @@ -740,13 +750,13 @@ $word = substr ( $atom, 1, ( strlen ( $atom ) - 2 ) ); if ( strlen ( $word ) < 2 || in_array($word, $stopwords) ) { - $warnings[] = 'One or more of your search terms was excluded because either it was less than 2 characters in length or is a common word (a stopword) that is typically found on a large number of pages. Examples of stopwords include "the", "this", "which", "with", etc.'; + $warnings[] = $lang->get('search_err_query_has_stopwords'); $ticker--; continue; } if(in_array($word, $ret['any'])) { - $warnings[] = 'One or more of your search terms was excluded because duplicate terms were encountered.'; + $warnings[] = $lang->get('search_err_query_dup_terms'); $ticker--; continue; } @@ -757,13 +767,13 @@ $word = $atom; if ( strlen ( $word ) < 2 || in_array($word, $stopwords) ) { - $warnings[] = 'One or more of your search terms was excluded because either it was less than 2 characters in length or is a common word (a stopword) that is typically found on a large number of pages. Examples of stopwords include "the", "this", "which", "with", etc.'; + $warnings[] = $lang->get('search_err_query_has_stopwords'); $ticker--; continue; } if(in_array($word, $ret['any'])) { - $warnings[] = 'One or more of your search terms was excluded because duplicate terms were encountered.'; + $warnings[] = $lang->get('search_err_query_dup_terms'); $ticker--; continue; } diff -r d823e49e2e4e -r c433348f3628 includes/sessions.php --- a/includes/sessions.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/sessions.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * sessions.php - everything related to security and user management * @@ -13,9 +13,6 @@ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. */ -// Prepare a string for insertion into a MySQL database -function filter($str) { return $db->escape($str); } - /** * Anything and everything related to security and user management. This includes AES encryption, which is illegal in some countries. * Documenting the API was not easy - I hope you folks enjoy it. @@ -50,11 +47,11 @@ var $username; /** - * User ID of currently logged-in user, or -1 if not logged in + * User ID of currently logged-in user, or 1 if not logged in * @var int */ - var $user_id; + var $user_id = 1; /** * Real name of currently logged-in user, or blank if not logged in @@ -157,7 +154,7 @@ * @var string */ - var $auth_level = -1; + var $auth_level = 1; /** * State variable to track if a session timed out @@ -324,13 +321,15 @@ } /** - * PHP 4 compatible constructor. + * PHP 4 compatible constructor. Deprecated in 1.1.x. */ + /* function sessionManager() { $this->__construct(); } + */ /** * Wrapper function to sanitize strings for MySQL and HTML @@ -370,6 +369,8 @@ function start() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + global $timezone; if($this->started) return; $this->started = true; $user = false; @@ -389,19 +390,23 @@ if(!$this->compat && $userdata['account_active'] != 1 && $data[1] != 'Special' && $data[1] != 'Admin') { + $language = intval(getConfig('default_language')); + $lang = new Language($language); + @setlocale(LC_ALL, $lang->lang_code); + $this->logout(); $a = getConfig('account_activation'); switch($a) { case 'none': default: - $solution = 'Your account was most likely deactivated by an administrator. Please contact the site administration for further assistance.'; + $solution = $lang->get('user_login_noact_solution_none'); break; case 'user': - $solution = 'Please check your e-mail; you should have been sent a message with instructions on how to activate your account. If you do not receive an e-mail from this site within 24 hours, please contact the site administration for further assistance.'; + $solution = $lang->get('user_login_noact_solution_user'); break; case 'admin': - $solution = 'This website has been configured so that all user accounts must be activated by the administrator before they can be used, so your account will most likely be activated the next time an administrator visits the site.'; + $solution = $lang->get('user_login_noact_solution_admin'); break; } @@ -422,14 +427,14 @@ $this->auth_level = USER_LEVEL_MEMBER; $this->user_level = USER_LEVEL_MEMBER; $this->logout(); - redirect(scriptPath . '/', 'Logged out', 'You have successfully been logged out. All cookies cleared.', 4); + redirect(scriptPath . '/', $lang->get('user_login_noact_msg_logout_success_title'), $lang->get('user_login_noact_msg_logout_success_body'), 5); } if ( $can_request && !isset($_POST['activation_request']) ) { - $form = '

If you are having trouble or did not receive the e-mail, you can request account activation from the administrators of this site.

+ $form = '

' . $lang->get('user_login_noact_msg_ask_admins') . '

-

+

'; } else @@ -437,21 +442,21 @@ if ( $can_request && isset($_POST['activation_request']) ) { $this->admin_activation_request($userdata['username']); - $form = '

A request has just been sent to the administrators of this site. They will be able to activate your account or send you another activation e-mail if needed.

+ $form = '

' . $lang->get('user_login_noact_msg_admins_just_asked') . '

-

+

'; } else { - $form = '

There is an active request in the administrators\' control panel for your account to be activated.

+ $form = '

' . $lang->get('user_login_noact_msg_admins_asked') . '

-

+

'; } } - die_semicritical('Account error', '

It appears that your user account has not yet been activated. '.$solution.'

' . $form); + die_semicritical($lang->get('user_login_noact_title'), '

' . $lang->get('user_login_noact_msg_intro') . ' '.$solution.'

' . $form); } $this->sid = $_COOKIE['sid']; @@ -470,9 +475,7 @@ $this->signature = $userdata['signature']; $this->reg_time = $userdata['reg_time']; } - // Small security risk here - it allows someone who has already authenticated as an administrator to store the "super" key in - // the cookie. Change this to USER_LEVEL_MEMBER to override that. The same 15-minute restriction applies to this "exploit". - $this->auth_level = $userdata['auth_level']; + $this->auth_level = USER_LEVEL_MEMBER; if(!isset($template->named_theme_list[$this->theme])) { if($this->compat || !is_object($template)) @@ -487,6 +490,15 @@ } } $user = true; + $GLOBALS['timezone'] = $userdata['user_timezone']; + + // Set language + if ( !defined('ENANO_ALLOW_LOAD_NOLANG') ) + { + $lang_id = intval($userdata['user_lang']); + $lang = new Language($lang_id); + @setlocale(LC_ALL, $lang->lang_code); + } if(isset($_REQUEST['auth']) && !$this->sid_super) { @@ -547,6 +559,7 @@ $this->style = 'default'; } + profiler_log('Sessions started'); } # Logins @@ -558,37 +571,95 @@ * @param string $aes_key The MD5 hash of the encryption key, hex-encoded * @param string $challenge The 256-bit MD5 challenge string - first 128 bits should be the hash, the last 128 should be the challenge salt * @param int $level The privilege level we're authenticating for, defaults to 0 + * @param array $captcha_hash Optional. If we're locked out and the lockout policy is captcha, this should be the identifier for the code. + * @param array $captcha_code Optional. If we're locked out and the lockout policy is captcha, this should be the code the user entered. + * @param bool $lookup_key Optional. If true (default) this queries the database for the "real" encryption key. Else, uses what is given. * @return string 'success' on success, or error string on failure */ - function login_with_crypto($username, $aes_data, $aes_key_id, $challenge, $level = USER_LEVEL_MEMBER) + function login_with_crypto($username, $aes_data, $aes_key_id, $challenge, $level = USER_LEVEL_MEMBER, $captcha_hash = false, $captcha_code = false, $lookup_key = true) { global $db, $session, $paths, $template, $plugins; // Common objects $privcache = $this->private_key; + + if ( !defined('IN_ENANO_INSTALL') ) + { + $timestamp_cutoff = time() - $duration; + $q = $this->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;'); + $fails = $db->numrows(); + // Lockout stuff + $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5; + $duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15; + // convert to minutes + $duration = $duration * 60; + $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout'; + if ( $policy == 'captcha' && $captcha_hash && $captcha_code ) + { + // policy is captcha -- check if it's correct, and if so, bypass lockout check + $real_code = $this->get_captcha($captcha_hash); + } + if ( $policy != 'disable' && !( $policy == 'captcha' && isset($real_code) && strtolower($real_code) == strtolower($captcha_code) ) ) + { + $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); + if ( $fails >= $threshold ) + { + // ooh boy, somebody's in trouble ;-) + $row = $db->fetchrow(); + $db->free_result(); + return array( + 'success' => false, + 'error' => 'locked_out', + 'lockout_threshold' => $threshold, + 'lockout_duration' => ( $duration / 60 ), + 'lockout_fails' => $fails, + 'lockout_policy' => $policy, + 'time_rem' => ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ), + 'lockout_last_time' => $row['timestamp'] + ); + } + } + $db->free_result(); + } // Instanciate the Rijndael encryption object $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); // Fetch our decryption key - $aes_key = $this->fetch_public_key($aes_key_id); - if ( !$aes_key ) + if ( $lookup_key ) { - // It could be that our key cache is full. If it seems larger than 65KB, clear it - if ( strlen(getConfig('login_key_cache')) > 65000 ) + $aes_key = $this->fetch_public_key($aes_key_id); + if ( !$aes_key ) { - setConfig('login_key_cache', ''); - return 'It seems that the list of encryption keys used for login information has reached its maximum length, thus preventing new keys from being inserted. The list has been automatically cleared. Please try logging in again; if you are still unable to log in, please contact the site administration.'; + // It could be that our key cache is full. If it seems larger than 65KB, clear it + if ( strlen(getConfig('login_key_cache')) > 65000 ) + { + setConfig('login_key_cache', ''); + return array( + 'success' => false, + 'error' => 'key_not_found_cleared', + ); + } + return array( + 'success' => false, + 'error' => 'key_not_found' + ); } - return 'Couldn\'t look up public key "'.htmlspecialchars($aes_key_id).'" for decryption'; + } + else + { + $aes_key =& $aes_key_id; } // Convert the key to a binary string $bin_key = hexdecode($aes_key); if(strlen($bin_key) != AES_BITS / 8) - return 'The decryption key is the wrong length'; + return array( + 'success' => false, + 'error' => 'key_wrong_length' + ); // Decrypt our password $password = $aes->decrypt($aes_data, $bin_key, ENC_HEX); @@ -607,10 +678,32 @@ { // This wasn't logged in <1.0.2, dunno how it slipped through if($level > USER_LEVEL_MEMBER) - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); - return "The username and/or password is incorrect."; + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + + if ( $policy != 'disable' && !defined('IN_ENANO_INSTALL') ) + { + $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); + // increment fail count + $this->sql('INSERT INTO '.table_prefix.'lockout(ipaddr, timestamp, action) VALUES(\'' . $ipaddr . '\', ' . time() . ', \'credential\');'); + $fails++; + // ooh boy, somebody's in trouble ;-) + return array( + 'success' => false, + 'error' => ( $fails >= $threshold ) ? 'locked_out' : 'invalid_credentials', + 'lockout_threshold' => $threshold, + 'lockout_duration' => ( $duration / 60 ), + 'lockout_fails' => $fails, + 'time_rem' => ( $duration / 60 ), + 'lockout_policy' => $policy + ); + } + + return array( + 'success' => false, + 'error' => 'invalid_credentials' + ); } $row = $db->fetchrow(); @@ -629,7 +722,7 @@ eval($cmd); } - redirect($url, 'Login sucessful', 'Please wait while you are transferred to the Password Reset form.'); + redirect($url, '', '', 0); exit; } } @@ -648,20 +741,27 @@ { // Our password field is up-to-date with the >=1.0RC1 encryption standards, so decrypt the password in the table and see if we have a match; if so then do challenge authentication $real_pass = $aes->decrypt(hexdecode($row['password']), $this->private_key, ENC_BINARY); - if($password == $real_pass) + if($password === $real_pass && is_string($password)) { - // Yay! We passed AES authentication, now do an MD5 challenge check to make sure we weren't spoofed - $chal = substr($challenge, 0, 32); - $salt = substr($challenge, 32, 32); - $correct_challenge = md5( $real_pass . $salt ); - if($chal == $correct_challenge) - $success = true; + // Yay! We passed AES authentication. Previously an MD5 challenge was done here, this was deemed redundant in 1.1.3. + // It didn't seem to provide any additional security... + $success = true; } } if($success) { if($level > $row['user_level']) - return 'You are not authorized for this level of access.'; + return array( + 'success' => false, + 'error' => 'too_big_for_britches' + ); + + /* + return array( + 'success' => false, + 'error' => 'Successful authentication, but session manager is in debug mode - remove the "return array(...);" in includes/sessions.php:' . ( __LINE__ - 2 ) + ); + */ $sess = $this->register_session(intval($row['user_id']), $username, $password, $level); if($sess) @@ -672,28 +772,54 @@ $this->style = $row['style']; if($level > USER_LEVEL_MEMBER) - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_good\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_good\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); $code = $plugins->setHook('login_success'); foreach ( $code as $cmd ) { eval($cmd); } - return 'success'; + return array( + 'success' => true + ); } else - return 'Your login credentials were correct, but an internal error occurred while registering the session key in the database.'; + return array( + 'success' => false, + 'error' => 'backend_fail' + ); } else { if($level > USER_LEVEL_MEMBER) - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); - return 'The username and/or password is incorrect.'; + // Do we also need to increment the lockout countdown? + if ( $policy != 'disable' && !defined('IN_ENANO_INSTALL') ) + { + $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); + // increment fail count + $this->sql('INSERT INTO '.table_prefix.'lockout(ipaddr, timestamp, action) VALUES(\'' . $ipaddr . '\', ' . time() . ', \'credential\');'); + $fails++; + return array( + 'success' => false, + 'error' => ( $fails >= $threshold ) ? 'locked_out' : 'invalid_credentials', + 'lockout_threshold' => $threshold, + 'lockout_duration' => ( $duration / 60 ), + 'lockout_fails' => $fails, + 'time_rem' => ( $duration / 60 ), + 'lockout_policy' => $policy + ); + } + + return array( + 'success' => false, + 'error' => 'invalid_credentials' + ); } } @@ -707,7 +833,7 @@ * @param int $level The privilege level we're authenticating for, defaults to 0 */ - function login_without_crypto($username, $password, $already_md5ed = false, $level = USER_LEVEL_MEMBER) + function login_without_crypto($username, $password, $already_md5ed = false, $level = USER_LEVEL_MEMBER, $captcha_hash = false, $captcha_code = false) { global $db, $session, $paths, $template, $plugins; // Common objects @@ -723,6 +849,50 @@ return $this->login_compat($username, $pass_hashed, $level); } + if ( !defined('IN_ENANO_INSTALL') ) + { + // Lockout stuff + $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5; + $duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15; + // convert to minutes + $duration = $duration * 60; + + // get the lockout status + $timestamp_cutoff = time() - $duration; + $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); + $q = $this->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;'); + $fails = $db->numrows(); + + $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout'; + $captcha_good = false; + if ( $policy == 'captcha' && $captcha_hash && $captcha_code ) + { + // policy is captcha -- check if it's correct, and if so, bypass lockout check + $real_code = $this->get_captcha($captcha_hash); + $captcha_good = ( strtolower($real_code) === strtolower($captcha_code) ); + } + if ( $policy != 'disable' && !$captcha_good ) + { + if ( $fails >= $threshold ) + { + // ooh boy, somebody's in trouble ;-) + $row = $db->fetchrow(); + $db->free_result(); + return array( + 'success' => false, + 'error' => 'locked_out', + 'lockout_threshold' => $threshold, + 'lockout_duration' => ( $duration / 60 ), + 'lockout_fails' => $fails, + 'lockout_policy' => $policy, + 'time_rem' => ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ), + 'lockout_last_time' => $row['timestamp'] + ); + } + } + $db->free_result(); + } + // Instanciate the Rijndael encryption object $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); @@ -731,14 +901,35 @@ // Retrieve the real password from the database $this->sql('SELECT password,old_encryption,user_id,user_level,temp_password,temp_password_time FROM '.table_prefix.'users WHERE ' . ENANO_SQLFUNC_LOWERCASE . '(username)=\''.$this->prepare_text(strtolower($username)).'\';'); - if ( $db->numrows() < 1 ) + if($db->numrows() < 1) { // This wasn't logged in <1.0.2, dunno how it slipped through if($level > USER_LEVEL_MEMBER) - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); - return "The username and/or password is incorrect."; + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + + // Do we also need to increment the lockout countdown? + if ( @$policy != 'disable' && !defined('IN_ENANO_INSTALL') ) + { + $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); + // increment fail count + $this->sql('INSERT INTO '.table_prefix.'lockout(ipaddr, timestamp, action) VALUES(\'' . $ipaddr . '\', ' . time() . ', \'credential\');'); + $fails++; + return array( + 'success' => false, + 'error' => ( $fails >= $threshold ) ? 'locked_out' : 'invalid_credentials', + 'lockout_threshold' => $threshold, + 'lockout_duration' => ( $duration / 60 ), + 'lockout_fails' => $fails, + 'lockout_policy' => $policy + ); + } + + return array( + 'success' => false, + 'error' => 'invalid_credentials' + ); } $row = $db->fetchrow(); @@ -788,14 +979,17 @@ if($success) { if((int)$level > (int)$row['user_level']) - return 'You are not authorized for this level of access.'; + return array( + 'success' => false, + 'error' => 'too_big_for_britches' + ); $sess = $this->register_session(intval($row['user_id']), $username, $real_pass, $level); if($sess) { if($level > USER_LEVEL_MEMBER) - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_good\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_good\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); $code = $plugins->setHook('login_success'); foreach ( $code as $cmd ) @@ -803,19 +997,44 @@ eval($cmd); } - return 'success'; + return array( + 'success' => true + ); } else - return 'Your login credentials were correct, but an internal error occured while registering the session key in the database.'; + return array( + 'success' => false, + 'error' => 'backend_fail' + ); } else { if($level > USER_LEVEL_MEMBER) - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'admin_auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')'); else - $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\')'); - return 'The username and/or password is incorrect.'; + // Do we also need to increment the lockout countdown? + if ( $policy != 'disable' && !defined('IN_ENANO_INSTALL') ) + { + $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); + // increment fail count + $this->sql('INSERT INTO '.table_prefix.'lockout(ipaddr, timestamp, action) VALUES(\'' . $ipaddr . '\', ' . time() . ', \'credential\');'); + $fails++; + return array( + 'success' => false, + 'error' => ( $fails >= $threshold ) ? 'locked_out' : 'invalid_credentials', + 'lockout_threshold' => $threshold, + 'lockout_duration' => ( $duration / 60 ), + 'lockout_fails' => $fails, + 'lockout_policy' => $policy + ); + } + + return array( + 'success' => false, + 'error' => 'invalid_credentials' + ); } } @@ -949,6 +1168,7 @@ function register_guest_session() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; $this->username = $_SERVER['REMOTE_ADDR']; $this->user_level = USER_LEVEL_GUEST; if($this->compat || defined('IN_ENANO_INSTALL')) @@ -962,6 +1182,13 @@ $this->style = ( isset($_GET['style']) && file_exists(ENANO_ROOT.'/themes/'.$this->theme . '/css/'.$_GET['style'].'.css' )) ? $_GET['style'] : substr($template->named_theme_list[$this->theme]['default_style'], 0, strlen($template->named_theme_list[$this->theme]['default_style'])-4); } $this->user_id = 1; + // This is a VERY special case we are allowing. It lets the installer create languages using the Enano API. + if ( !defined('ENANO_ALLOW_LOAD_NOLANG') ) + { + $language = ( isset($_GET['lang']) && preg_match('/^[a-z0-9_]+$/', @$_GET['lang']) ) ? $_GET['lang'] : intval(getConfig('default_language')); + $lang = new Language($language); + @setlocale(LC_ALL, $lang->lang_code); + } } /** @@ -973,7 +1200,8 @@ function validate_session($key) { global $db, $session, $paths, $template, $plugins; // Common objects - $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE, true); + profiler_log("SessionManager: checking session: " . sha1($key)); + $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); $decrypted_key = $aes->decrypt($key, $this->private_key, ENC_HEX); if ( !$decrypted_key ) @@ -992,8 +1220,8 @@ $salt = $db->escape($keydata[3]); // using a normal call to $db->sql_query to avoid failing on errors here $query = $db->sql_query('SELECT u.user_id AS uid,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,' . "\n" - . ' u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms,' . "\n" - . ' x.* FROM '.table_prefix.'session_keys AS k' . "\n" + . ' u.reg_time,u.account_active,u.activation_key,u.user_lang,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms,' . "\n" + . ' u.user_timezone, x.* FROM '.table_prefix.'session_keys AS k' . "\n" . ' LEFT JOIN '.table_prefix.'users AS u' . "\n" . ' ON ( u.user_id=k.user_id )' . "\n" . ' LEFT JOIN '.table_prefix.'users_extra AS x' . "\n" @@ -1002,11 +1230,11 @@ . ' ON ( p.message_to=u.username AND p.message_read=0 )' . "\n" . ' WHERE k.session_key=\''.$keyhash.'\'' . "\n" . ' AND k.salt=\''.$salt.'\'' . "\n" - . ' GROUP BY u.user_id,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,x.user_id, x.user_aim, x.user_yahoo, x.user_msn, x.user_xmpp, x.user_homepage, x.user_location, x.user_job, x.user_hobbies, x.email_public;'); + . ' GROUP BY u.user_id,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,u.user_lang,k.source_ip,k.time,k.auth_level,x.user_id, x.user_aim, x.user_yahoo, x.user_msn, x.user_xmpp, x.user_homepage, x.user_location, x.user_job, x.user_hobbies, x.email_public;'); if ( !$query ) { - $query = $this->sql('SELECT u.user_id AS uid,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms FROM '.table_prefix.'session_keys AS k + $query = $this->sql('SELECT u.user_id AS uid,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,u.reg_time,u.account_active,u.activation_key,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms, 1440 AS user_timezone FROM '.table_prefix.'session_keys AS k LEFT JOIN '.table_prefix.'users AS u ON ( u.user_id=k.user_id ) LEFT JOIN '.table_prefix.'privmsgs AS p @@ -1066,13 +1294,18 @@ $user_extra = array(); foreach ( array('user_aim', 'user_yahoo', 'user_msn', 'user_xmpp', 'user_homepage', 'user_location', 'user_job', 'user_hobbies', 'email_public') as $column ) { - $user_extra[$column] = $row[$column]; + if ( isset($row[$column]) ) + $user_extra[$column] = $row[$column]; } $this->user_extra = $user_extra; // Leave the rest to PHP's automatic garbage collector ;-) $row['password'] = md5($real_pass); + $row['user_timezone'] = intval($row['user_timezone']) - 1440; + + profiler_log("SessionManager: finished session check"); + return $row; } @@ -1087,7 +1320,7 @@ global $db, $session, $paths, $template, $plugins; // Common objects $key = $db->escape($key); - $query = $this->sql('SELECT u.user_id,u.username,u.password,u.email,u.real_name,u.user_level,k.source_ip,k.salt,k.time,k.auth_level FROM '.table_prefix.'session_keys AS k + $query = $this->sql('SELECT u.user_id,u.username,u.password,u.email,u.real_name,u.user_level,k.source_ip,k.salt,k.time,k.auth_level,1440 AS user_timezone FROM '.table_prefix.'session_keys AS k LEFT JOIN '.table_prefix.'users AS u ON u.user_id=k.user_id WHERE k.session_key=\''.$key.'\';'); @@ -1132,6 +1365,8 @@ return false; } + $row['user_timezone'] = intval($row['user_timezone']) - 1440; + return $row; } @@ -1149,7 +1384,14 @@ if($level > USER_LEVEL_CHPREF) { $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); - if(!$this->user_logged_in || $this->auth_level < USER_LEVEL_MOD) return 'success'; + if(!$this->user_logged_in || $this->auth_level < ( USER_LEVEL_MEMBER + 1)) + { + return 'success'; + } + // See if we can get rid of the cached decrypted session key + $key_bin = $aes->hextostring(strrev($this->sid_super)); + $key_hash = sha1($key_bin . '::' . $this->private_key); + aes_decrypt_cache_destroy($key_hash); // Destroy elevated privileges $keyhash = md5(strrev($this->sid_super)); $this->sql('DELETE FROM '.table_prefix.'session_keys WHERE session_key=\''.$keyhash.'\' AND user_id=\'' . $this->user_id . '\';'); @@ -1160,6 +1402,11 @@ { if($this->user_logged_in) { + $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); + // See if we can get rid of the cached decrypted session key + $key_bin = $aes->hextostring($this->sid); + $key_hash = sha1($key_bin . '::' . $this->private_key); + aes_decrypt_cache_destroy($key_hash); // Completely destroy our session if($this->auth_level > USER_LEVEL_CHPREF) { @@ -1358,6 +1605,8 @@ function check_banlist() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + $col_reason = ( $this->compat ) ? '"No reason entered (session manager is in compatibility mode)" AS reason' : 'reason'; $banned = false; if ( $this->user_logged_in ) @@ -1388,9 +1637,9 @@ $q = $this->sql($sql); if ( $db->numrows() > 0 ) { - while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) + while ( list($reason_temp, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) { - if ( $ban_type == BAN_IP && $row['is_regex'] != 1 ) + if ( $ban_type == BAN_IP && $is_regex != 1 ) { // check range $regexp = parse_ip_range_regex($ban_value); @@ -1400,6 +1649,7 @@ } if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) ) { + $reason = $reason_temp; $banned = true; } } @@ -1407,6 +1657,7 @@ { // User is banned $banned = true; + $reason = $reason_temp; } } } @@ -1432,7 +1683,7 @@ $q = $this->sql($sql); if ( $db->numrows() > 0 ) { - while ( list($reason, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) + while ( list($reason_temp, $ban_value, $ban_type, $is_regex) = $db->fetchrow_num() ) { if ( $ban_type == BAN_IP && $row['is_regex'] != 1 ) { @@ -1442,12 +1693,14 @@ continue; if ( preg_match("/$regexp/", $_SERVER['REMOTE_ADDR']) ) { + $reason = $reason_temp; $banned = true; } } else { // User is banned + $reason = $reason_temp; $banned = true; } } @@ -1457,7 +1710,7 @@ if ( $banned && $paths->get_pageid_from_url() != $paths->nslist['Special'].'CSS' ) { // This guy is banned - kill the session, kill the database connection, bail out, and be pretty about it - die_semicritical('Ban notice', '
You have been banned from this website. Please contact the site administrator for more information.

Reason:
'.$reason.'
'); + die_semicritical($lang->get('user_ban_msg_title'), '

' . $lang->get('user_ban_msg_body') . '

' . $lang->get('user_ban_lbl_reason') . '
' . $reason . '
'); exit; } } @@ -1476,11 +1729,19 @@ function create_user($username, $password, $email, $real_name = '', $coppa = false) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; // Initialize AES $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); - if(!preg_match('#^'.$this->valid_username.'$#', $username)) return 'The username you chose contains invalid characters.'; + // Since we're recording IP addresses, make sure the user's IP is safe. + $ip =& $_SERVER['REMOTE_ADDR']; + if ( !is_valid_ip($ip) ) + return 'Invalid IP'; + + if ( !preg_match('#^'.$this->valid_username.'$#', $username) ) + return $lang->get('user_reg_err_username_banned_chars'); + $username = str_replace('_', ' ', $username); $user_orig = $username; $username = $this->prepare_text($username); @@ -1491,31 +1752,23 @@ $q = $this->sql('SELECT * FROM '.table_prefix.'users WHERE ' . ENANO_SQLFUNC_LOWERCASE . '(username)=\''.strtolower($username).'\' OR email=\''.$email.'\''.$nameclause.';'); if($db->numrows() > 0) { - $r = 'The '; - $i=0; $row = $db->fetchrow(); - // Wow! An error checker that actually speaks English with the properest grammar! :-P + $str = 'user_reg_err_dupe'; + if ( $row['username'] == $username ) { - $r .= 'username'; - $i++; + $str .= '_username'; } if ( $row['email'] == $email ) { - if($i) $r.=', '; - $r .= 'e-mail address'; - $i++; + $str .= '_email'; } if ( $row['real_name'] == $real_name && $real_name != '' ) { - if($i) $r.=', and '; - $r .= 'real name'; - $i++; + $str .= '_realname'; } - $r .= ' that you entered '; - $r .= ( $i == 1 ) ? 'is' : 'are'; - $r .= ' already in use by another user.'; - return $r; + + return $lang->get($str); } // Is the password strong enough? @@ -1525,7 +1778,7 @@ $pass_score = password_score($password); if ( $pass_score < $min_score ) { - return 'The password you entered did not meet the complexity requirements for this site. Please choose a stronger password.'; + return $lang->get('user_reg_err_password_too_weak'); } } @@ -1554,16 +1807,15 @@ $actkey = sha1 ( microtime() . mt_rand() ); // We good, create the user - $this->sql('INSERT INTO '.table_prefix.'users ( username, password, email, real_name, theme, style, reg_time, account_active, activation_key, user_level, user_coppa ) VALUES ( \''.$username.'\', \''.$password.'\', \''.$email.'\', \''.$real_name.'\', \''.$template->default_theme.'\', \''.$template->default_style.'\', '.time().', '.$active.', \''.$actkey.'\', '.USER_LEVEL_CHPREF.', ' . $coppa_col . ' );'); + $this->sql('INSERT INTO '.table_prefix.'users ( username, password, email, real_name, theme, style, reg_time, account_active, activation_key, user_level, user_coppa, user_registration_ip ) VALUES ( \''.$username.'\', \''.$password.'\', \''.$email.'\', \''.$real_name.'\', \''.$template->default_theme.'\', \''.$template->default_style.'\', '.time().', '.$active.', \''.$actkey.'\', '.USER_LEVEL_CHPREF.', ' . $coppa_col . ', \'' . $ip . '\' );'); // Get user ID and create users_extra entry $q = $this->sql('SELECT user_id FROM '.table_prefix."users WHERE username='$username';"); if ( $db->numrows() > 0 ) { - $row = $db->fetchrow(); + list($user_id) = $db->fetchrow_num(); $db->free_result(); - $user_id =& $row['user_id']; $this->sql('INSERT INTO '.table_prefix.'users_extra(user_id) VALUES(' . $user_id . ');'); } @@ -1609,7 +1861,7 @@ if(!$a) { $this->admin_activation_request($username); - return 'The activation e-mail could not be sent due to an internal error. This could possibly be due to an incorrect SMTP configuration. A request has been sent to the administrator to activate your account for you. ' . $a; + return $lang->get('user_reg_err_actmail_failed') . ' ' . $a; } break; case 'admin': @@ -1638,6 +1890,7 @@ function send_activation_mail($u, $actkey = false) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; $q = $this->sql('SELECT username,email FROM '.table_prefix.'users WHERE user_id=2 OR user_level=' . USER_LEVEL_ADMIN . ' ORDER BY user_id ASC;'); $un = $db->fetchrow(); $admin_user = $un['username']; @@ -1645,31 +1898,21 @@ $r = $db->fetchrow(); if ( empty($r['email']) ) $db->_die('BUG: $session->send_activation_mail(): no e-mail address in row'); - $message = 'Dear '.$u.', -Thank you for registering on '.getConfig('site_name').'. Your account creation is almost complete. To complete the registration process, please click the following link or paste it into your web browser: -'; - if(isset($_SERVER['HTTPS'])) $prot = 'https'; - else $prot = 'http'; - if($_SERVER['SERVER_PORT'] == '80') $p = ''; - else $p = ':'.$_SERVER['SERVER_PORT']; - $sidbak = false; - if($this->sid_super) - $sidbak = $this->sid_super; - $this->sid_super = false; - $aklink = makeUrlNS('Special', 'ActivateAccount/'.str_replace(' ', '_', $u).'/'. ( ( is_string($actkey) ) ? $actkey : $r['activation_key'] ) ); - if($sidbak) - $this->sid_super = $sidbak; - unset($sidbak); - $message .= "$prot://".$_SERVER['HTTP_HOST'].$p.$aklink; - $message .= "\n\nSincerely yours, \n$admin_user and the ".$_SERVER['HTTP_HOST']." administration team"; + $aklink = makeUrlComplete('Special', 'ActivateAccount/'.str_replace(' ', '_', $u).'/'. ( ( is_string($actkey) ) ? $actkey : $r['activation_key'] ) ); + $message = $lang->get('user_reg_activation_email', array( + 'activation_link' => $aklink, + 'admin_user' => $admin_user, + 'username' => $u + )); + if(getConfig('smtp_enabled') == '1') { - $result = smtp_send_email($r['email'], getConfig('site_name').' website account activation', preg_replace("#(?get('user_reg_activation_email_subject'), preg_replace("#(?get('user_reg_activation_email_subject'), preg_replace("#(?sql('SELECT username,email FROM '.table_prefix.'users WHERE user_id=2 OR user_level=' . USER_LEVEL_ADMIN . ' ORDER BY user_id ASC;'); $un = $db->fetchrow(); @@ -1707,33 +1950,15 @@ unset($sidbak); $link = "$prot://".$_SERVER['HTTP_HOST'].scriptPath; - $message = 'Dear parent or legal guardian, -A child under the username ' . $u . ' recently registered on our website. The child provided your e-mail address as the one of his or her authorized parent or legal guardian, and to comply with the United States Childrens\' Online Privacy Protection act, we ask that all parents of children ages 13 or under please mail us a written form authorizing their child\'s use of our website. - -If you wish for your child to be allowed access to our website, please print and fill out the form below, and mail it to this address: - -' . getConfig('coppa_address') . ' - -If you do NOT wish for your child to be allowed access to our site, you do not need to do anything - your child will not be able to access our site as a registered user unless you authorize their account activation. - -Authorization form: --------------------------------- Cut here -------------------------------- - -I, _______________________________________, the legal parent or guardian of the child registered on the website "' . getConfig('site_name') . '" as ' . $u . ', hereby give my authorization for the child\'s e-mail address, instant messaging information, location, and real name, to be collected and stored in a database owned and maintained by ' . getConfig('site_name') . ' at the child\'s option, and for the administrators of this website to use this information according to the privacy policy displayed on their website <' . $link . '>. - -Child\'s name: _____________________________________ - -Child\'s e-mail address: _____________________________________ -(optional - if you don\'t provide this, we\'ll just send site-related e-mails to your e-mail address) - -Signature of parent or guardian: - -____________________________________________________ - -Date (YYYY-MM-DD): ______ / _____ / _____ - --------------------------------- Cut here --------------------------------'; - $message .= "\n\nSincerely yours, \n$admin_user and the ".$_SERVER['HTTP_HOST']." administration team"; + $message = $lang->get( + 'user_reg_activation_email_coppa', + array( + 'username' => $u, + 'admin_user' => $admin_user, + 'site_link' => $link + ) + ); + if(getConfig('smtp_enabled') == '1') { @@ -1764,6 +1989,8 @@ function mail_password_reset($user) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + if(is_int($user)) { $q = $this->sql('SELECT user_id,username,email FROM '.table_prefix.'users WHERE user_id='.$user.';'); // This is SAFE! This is only called if $user is an integer @@ -1783,24 +2010,13 @@ $this->register_temp_password($row['user_id'], $temp_pass); $site_name = getConfig('site_name'); - - $message = "Dear {$row['username']}, - -Someone (hopefully you) on the {$site_name} website requested that a new password be created. - -The request was sent from the IP address {$_SERVER['REMOTE_ADDR']}. - -If you did not request the new password, then you do not need to do anything; the password will be invalidated after 24 hours. - -If you did request this password, then please log in using the password shown below: - - Password: {$temp_pass} - -After you log in using this password, you will be able to reset your real password. You can only log in using this temporary password once. - -Sincerely yours, -The {$site_name} administration team -"; + + $message = $lang->get('userfuncs_passreset_email', array( + 'username' => $row['username'], + 'site_name' => $site_name, + 'remote_addr' => $_SERVER['REMOTE_ADDR'], + 'temp_pass' => $temp_pass + )); if(getConfig('smtp_enabled') == '1') { @@ -1842,7 +2058,7 @@ function admin_activation_request($u) { global $db; - $this->sql('INSERT INTO '.table_prefix.'logs(log_type, action, time_id, date_string, author, edit_summary) VALUES(\'admin\', \'activ_req\', '.time().', \''.date('d M Y h:i a').'\', \''.$this->username.'\', \''.$db->escape($u).'\');'); + $this->sql('INSERT INTO '.table_prefix.'logs(log_type, action, time_id, date_string, author, edit_summary) VALUES(\'admin\', \'activ_req\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$this->username.'\', \''.$db->escape($u).'\');'); } /** @@ -1858,11 +2074,11 @@ $r = mysql_affected_rows(); if ( $r > 0 ) { - $e = $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'activ_good\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($user).'\', \''.$_SERVER['REMOTE_ADDR'].'\')'); + $e = $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'activ_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($user).'\', \''.$_SERVER['REMOTE_ADDR'].'\')'); } else { - $e = $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'activ_bad\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($user).'\', \''.$_SERVER['REMOTE_ADDR'].'\')'); + $e = $this->sql('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary) VALUES(\'security\', \'activ_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($user).'\', \''.$_SERVER['REMOTE_ADDR'].'\')'); } return $r; } @@ -1876,46 +2092,71 @@ function userlevel_to_string($user_level, $short = false) { - if ( $short ) + global $lang; + + static $levels = array( + 'short' => array( + USER_LEVEL_GUEST => 'Guest', + USER_LEVEL_MEMBER => 'Member', + USER_LEVEL_CHPREF => 'Sensitive preferences changeable', + USER_LEVEL_MOD => 'Moderator', + USER_LEVEL_ADMIN => 'Administrative' + ), + 'long' => array( + USER_LEVEL_GUEST => 'Low - guest privileges', + USER_LEVEL_MEMBER => 'Standard - normal member level', + USER_LEVEL_CHPREF => 'Medium - user can change his/her own e-mail address and password', + USER_LEVEL_MOD => 'High - moderator privileges', + USER_LEVEL_ADMIN => 'Highest - administrative privileges' + ), + 'l10n' => false + ); + + if ( is_object($lang) && !$levels['l10n'] ) { - switch ( $user_level ) - { - case USER_LEVEL_GUEST: - return 'Guest'; - case USER_LEVEL_MEMBER: - return 'Member'; - case USER_LEVEL_CHPREF: - return 'Sensitive preferences changeable'; - case USER_LEVEL_MOD: - return 'Moderator'; - case USER_LEVEL_ADMIN: - return 'Administrative'; - default: - return "Level $user_level"; - } + $levels = array( + 'short' => array( + USER_LEVEL_GUEST => $lang->get('user_level_short_guest'), + USER_LEVEL_MEMBER => $lang->get('user_level_short_member'), + USER_LEVEL_CHPREF => $lang->get('user_level_short_chpref'), + USER_LEVEL_MOD => $lang->get('user_level_short_mod'), + USER_LEVEL_ADMIN => $lang->get('user_level_short_admin') + ), + 'long' => array( + USER_LEVEL_GUEST => $lang->get('user_level_long_guest'), + USER_LEVEL_MEMBER => $lang->get('user_level_long_member'), + USER_LEVEL_CHPREF => $lang->get('user_level_long_chpref'), + USER_LEVEL_MOD => $lang->get('user_level_long_mod'), + USER_LEVEL_ADMIN => $lang->get('user_level_long_admin') + ), + 'l10n' => true + ); + } + + $key = ( $short ) ? 'short' : 'long'; + if ( isset($levels[$key][$user_level]) ) + { + return $levels[$key][$user_level]; } else { - switch ( $user_level ) + if ( $short ) { - case USER_LEVEL_GUEST: - return 'Low - guest privileges'; - case USER_LEVEL_MEMBER: - return 'Standard - normal member level'; - case USER_LEVEL_CHPREF: - return 'Medium - user can change his/her own e-mail address and password'; - case USER_LEVEL_MOD: - return 'High - moderator privileges'; - case USER_LEVEL_ADMIN: - return 'Highest - administrative privileges'; - default: - return "Unknown ($user_level)"; + return ( is_object($lang) ) ? $lang->get('user_level_short_unknown', array('user_level' => $user_level)) : "Unknown - $user_level"; + } + else + { + return ( is_object($lang) ) ? $lang->get('user_level_long_unknown', array('user_level' => $user_level)) : "Unknown level ($user_level)"; } } + + return 'Linux rocks!'; + } /** * Updates a user's information in the database. Note that any of the values except $user_id can be false if you want to preserve the old values. + * Not localized because this really isn't used a whole lot anymore. * @param int $user_id The user ID of the user to update - this cannot be changed * @param string $username The new username * @param string $old_pass The current password - only required if sessionManager::$user_level < USER_LEVEL_ADMIN. This should usually be an UNENCRYPTED string. This can also be an array - if it is, key 0 is treated as data AES-encrypted with key 1 @@ -2345,6 +2586,8 @@ $s = ''; foreach($perms as $perm => $ac) { + if ( $ac == 'i' ) + continue; $s .= "$perm=$ac;"; } return $s; @@ -2393,6 +2636,31 @@ } /** + * Merges two ACL arrays, but instead of calculating inheritance for missing permission types, just returns 'i' for that type. Useful + * for explicitly requiring inheritance in ACL editing interfaces + * @param array $perm1 The first set of permissions + * @param array $perm2 The second, authoritative set of permissions + */ + + function acl_merge_inherit($perm1, $perm2) + { + foreach ( $perm1 as $type => $level ) + { + $perm1[$type][$level] = 'i'; + } + $ret = $perm1; + foreach ( $perm2 as $type => $level ) + { + if ( isset( $ret[$type] ) ) + { + if ( $ret[$type] != AUTH_DENY ) + $ret[$type] = $level; + } + } + return $ret; + } + + /** * Merges the ACL array sent with the current permissions table, deciding precedence based on whether defaults are in effect or not. * @param array The array to merge into the master ACL list * @param bool If true, $perm is treated as the "new default" @@ -2491,32 +2759,83 @@ /** * Makes a CAPTCHA code and caches the code in the database * @param int $len The length of the code, in bytes + * @param string Optional, the hash to reuse * @return string A unique identifier assigned to the code. This hash should be passed to sessionManager::getCaptcha() to retrieve the code. */ - function make_captcha($len = 7) + function make_captcha($len = 7, $hash = '') { + global $db, $session, $paths, $template, $plugins; // Common objects $code = $this->generate_captcha_code($len); - $hash = md5(microtime() . mt_rand()); - $this->sql('INSERT INTO '.table_prefix.'session_keys(session_key,salt,auth_level,source_ip,user_id) VALUES(\''.$hash.'\', \'\', -1, \''.ip2hex($_SERVER['REMOTE_ADDR']).'\', -2);'); + if ( !preg_match('/^[a-f0-9]{32}([a-z0-9]{8})?$/', $hash) ) + $hash = md5(microtime() . mt_rand()); + $session_data = $db->escape(serialize(array())); + + // sanity check + if ( !is_valid_ip(@$_SERVER['REMOTE_ADDR']) || !is_int($this->user_id) ) + return false; + + $this->sql('DELETE FROM ' . table_prefix . "captcha WHERE session_id = '$hash';"); + $this->sql('INSERT INTO ' . table_prefix . 'captcha(session_id, code, session_data, source_ip, user_id)' . " VALUES('$hash', '$code', '$session_data', '{$_SERVER['REMOTE_ADDR']}', {$this->user_id});"); return $hash; } /** - * Generates the actual confirmation code text. - * @param int String length + * Generates a "pronouncable" or "human-friendly" word using various phonics rules + * @param int Optional. The length of the word. * @return string */ function generate_captcha_code($len = 7) { - $chars = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'); - $s = ''; + // don't use k and x, they get mixed up a lot + $consonants = 'bcdfghmnpqrsvwyz'; + $vowels = 'aeiou'; + $prev = 'vowel'; + $prev_l = ''; + $word = ''; + $allow_next_vowel = true; for ( $i = 0; $i < $len; $i++ ) { - $s .= $chars[mt_rand(0, count($chars)-1)]; + if ( $prev == 'vowel' ) + { + $allow_next_vowel = false; + if ( $prev_l == 'o' && mt_rand(0, 3) == 3 && $allow_next_vowel ) + $word .= 'i'; + else if ( $prev_l == 'q' && mt_rand(0, 3) != 1 && $allow_next_vowel ) + $word .= 'u'; + else if ( $prev_l == 'o' && mt_rand(0, 3) == 2 && $allow_next_vowel ) + $word .= 'u'; + else if ( $prev_l == 'a' && mt_rand(0, 3) == 3 && $allow_next_vowel ) + $word .= 'i'; + else if ( $prev_l == 'a' && mt_rand(0, 10) == 7 && $allow_next_vowel ) + $word .= 'o'; + else if ( $prev_l == 'a' && mt_rand(0, 7) == 2 && $allow_next_vowel ) + $word .= 'u'; + else + { + $allow_next_vowel = true; + $word .= $consonants{mt_rand(0, (strlen($consonants)-1))}; + } + } + else if ( $prev == 'consonant' ) + { + if ( $prev_l == 'p' && mt_rand(0, 7) == 4 ) + $word .= 't'; + else if ( $prev_l == 'p' && mt_rand(0, 5) == 1 ) + $word .= 'h'; + else + $word .= $vowels{mt_rand(0, (strlen($vowels)-1))}; + } + $prev_l = substr($word, -1); + $l = ( mt_rand(0, 1) == 1 ) ? strtoupper($prev_l) : strtolower($prev_l); + $word = substr($word, 0, -1) . $l; + if ( strstr('aeiou', $prev_l) ) + $prev = 'vowel'; + else + $prev = 'consonant'; } - return $s; + return $word; } /** @@ -2528,15 +2847,33 @@ function get_captcha($hash) { global $db, $session, $paths, $template, $plugins; // Common objects - $s = $this->sql('SELECT salt FROM '.table_prefix.'session_keys WHERE session_key=\''.$db->escape($hash).'\' AND source_ip=\''.ip2hex($_SERVER['REMOTE_ADDR']).'\';'); - if ( $db->numrows() < 1 ) + + if ( !preg_match('/^[a-f0-9]{32}([a-z0-9]{8})?$/', $hash) ) { + die("session manager: bad captcha_hash $hash"); + return false; + } + + // sanity check + if ( !is_valid_ip(@$_SERVER['REMOTE_ADDR']) ) + { + die("session manager insanity: bad REMOTE_ADDR or invalid UID"); return false; } - $r = $db->fetchrow(); + + $q = $this->sql('SELECT code_id, code FROM ' . table_prefix . "captcha WHERE session_id = '$hash' AND source_ip = '{$_SERVER['REMOTE_ADDR']}';"); + if ( $db->numrows() < 1 ) + { + die("session manager: no rows for captcha_code $hash"); + return false; + } + + list($code_id, $code) = $db->fetchrow_num(); + $db->free_result(); - $this->sql('DELETE FROM ' . table_prefix . 'session_keys WHERE salt=\'' . $db->escape($r['salt']) . '\';'); - return $r['salt']; + $this->sql('DELETE FROM ' . table_prefix . "captcha WHERE code_id = $code_id;"); + + return $code; } /** @@ -2545,7 +2882,6 @@ function kill_captcha() { - // $this->sql('DELETE FROM '.table_prefix.'session_keys WHERE user_id=-2 AND source_ip=\''.ip2hex($_SERVER['REMOTE_ADDR']).'\';'); return true; } @@ -2639,6 +2975,245 @@ return $code; } + /** + * Backend code for the JSON login interface. Basically a frontend to the session API that takes all parameters in one huge array. + * @param array LoginAPI request + * @return array LoginAPI response + */ + + function process_login_request($req) + { + global $db, $session, $paths, $template, $plugins; // Common objects + + // Setup EnanoMath and Diffie-Hellman + global $dh_supported; + $dh_supported = true; + try + { + require_once(ENANO_ROOT . '/includes/diffiehellman.php'); + } + catch ( Exception $e ) + { + $dh_supported = false; + } + global $_math; + + // Check for the mode + if ( !isset($req['mode']) ) + { + return array( + 'mode' => 'error', + 'error' => 'ERR_JSON_NO_MODE' + ); + } + + // Main processing switch + switch ( $req['mode'] ) + { + default: + return array( + 'mode' => 'error', + 'error' => 'ERR_JSON_INVALID_MODE' + ); + break; + case 'getkey': + + $this->start(); + + // Query database for lockout info + $locked_out = false; + // are we locked out? + $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5; + $duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15; + // convert to minutes + $duration = $duration * 60; + $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout'; + if ( $policy != 'disable' ) + { + $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); + $timestamp_cutoff = time() - $duration; + $q = $this->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;'); + $fails = $db->numrows(); + $row = $db->fetchrow(); + $locked_out = ( $fails >= $threshold ); + $lockdata = array( + 'locked_out' => $locked_out, + 'lockout_threshold' => $threshold, + 'lockout_duration' => ( $duration / 60 ), + 'lockout_fails' => $fails, + 'lockout_policy' => $policy, + 'lockout_last_time' => $row['timestamp'], + 'time_rem' => ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ), + 'captcha' => '' + ); + $db->free_result(); + } + + $response = array('mode' => 'build_box'); + $response['allow_diffiehellman'] = $dh_supported; + + $response['username'] = ( $this->user_logged_in ) ? $this->username : false; + $response['aes_key'] = $this->rijndael_genkey(); + + // Lockout info + $response['locked_out'] = $locked_out; + + $response['lockout_info'] = $lockdata; + if ( $policy == 'captcha' && $locked_out ) + { + $response['lockout_info']['captcha'] = $this->make_captcha(); + } + + // Can we do Diffie-Hellman? If so, generate and stash a public/private key pair. + if ( $dh_supported ) + { + $dh_key_priv = dh_gen_private(); + $dh_key_pub = dh_gen_public($dh_key_priv); + $dh_key_priv = $_math->str($dh_key_priv); + $dh_key_pub = $_math->str($dh_key_pub); + $response['dh_public_key'] = $dh_key_pub; + // store the keys in the DB + $q = $db->sql_query('INSERT INTO ' . table_prefix . "diffiehellman( public_key, private_key ) VALUES ( '$dh_key_pub', '$dh_key_priv' );"); + if ( !$q ) + $db->die_json(); + } + + return $response; + break; + case 'login_dh': + // User is requesting a login and has sent Diffie-Hellman data. + + // + // KEY RECONSTRUCTION + // + + $userinfo_crypt = $req['userinfo']; + $dh_public = $req['dh_public_key']; + $dh_hash = $req['dh_secret_hash']; + + // Check the key + if ( !preg_match('/^[0-9]+$/', $dh_public) || !preg_match('/^[0-9]+$/', $req['dh_client_key']) ) + { + return array( + 'mode' => 'error', + 'error' => 'ERR_DH_KEY_NOT_NUMERIC' + ); + } + + // Fetch private key + $q = $db->sql_query('SELECT private_key, key_id FROM ' . table_prefix . "diffiehellman WHERE public_key = '$dh_public';"); + if ( !$q ) + $db->die_json(); + + if ( $db->numrows() < 1 ) + { + return array( + 'mode' => 'error', + 'error' => 'ERR_DH_KEY_NOT_FOUND' + ); + } + + list($dh_private, $dh_key_id) = $db->fetchrow_num(); + $db->free_result(); + + // We have the private key, now delete the key pair, we no longer need it + $q = $db->sql_query('DELETE FROM ' . table_prefix . "diffiehellman WHERE key_id = $dh_key_id;"); + if ( !$q ) + $db->die_json(); + + // Generate the shared secret + $dh_secret = dh_gen_shared_secret($dh_private, $req['dh_client_key']); + $dh_secret = $_math->str($dh_secret); + + // Did we get all our math right? + $dh_secret_check = sha1($dh_secret); + if ( $dh_secret_check !== $dh_hash ) + { + return array( + 'mode' => 'error', + 'error' => 'ERR_DH_HASH_NO_MATCH' + ); + } + + // All good! Generate the AES key + $aes_key = substr(sha256($dh_secret), 0, ( AES_BITS / 4 )); + case 'login_aes': + if ( $req['mode'] == 'login_aes' ) + { + // login_aes-specific code + $aes_key = $this->fetch_public_key($req['key_aes']); + if ( !$aes_key ) + { + return array( + 'mode' => 'error', + 'error' => 'ERR_AES_LOOKUP_FAILED' + ); + } + $userinfo_crypt = $req['userinfo']; + } + // shared between the two systems from here on out + + // decrypt user info + $aes_key = hexdecode($aes_key); + $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); + $userinfo_json = $aes->decrypt($userinfo_crypt, $aes_key, ENC_HEX); + if ( !$userinfo_json ) + { + return array( + 'mode' => 'error', + 'error' => 'ERR_AES_DECRYPT_FAILED' + ); + } + // de-JSON user info + try + { + $userinfo = enano_json_decode($userinfo_json); + } + catch ( Exception $e ) + { + return array( + 'mode' => 'error', + 'error' => 'ERR_USERINFO_DECODE_FAILED' + ); + } + + if ( !isset($userinfo['username']) || !isset($userinfo['password']) ) + { + return array( + 'mode' => 'error', + 'error' => 'ERR_USERINFO_MISSING_VALUES' + ); + } + + $username =& $userinfo['username']; + $password =& $userinfo['password']; + + // attempt the login + // function login_without_crypto($username, $password, $already_md5ed = false, $level = USER_LEVEL_MEMBER, $captcha_hash = false, $captcha_code = false) + $login_result = $this->login_without_crypto($username, $password, false, intval($req['level']), @$req['captcha_hash'], @$req['captcha_code']); + + if ( $login_result['success'] ) + { + return array( + 'mode' => 'login_success', + 'key' => ( $this->sid_super ) ? $this->sid_super : false + ); + } + else + { + return array( + 'mode' => 'login_failure', + 'error_code' => $login_result['error'], + // Use this to provide a way to respawn the login box + 'respawn_info' => $this->process_login_request(array('mode' => 'getkey')) + ); + } + + break; + } + + } + } /** @@ -2913,7 +3488,7 @@ { if ( isset($perm[$i]) ) { - if ( $is_everyone && !$this->acl_defaults_used[$i] ) + if ( $is_everyone && !@$this->acl_defaults_used[$i] ) continue; // Decide precedence if ( isset($this->acl_defaults_used[$i]) ) diff -r d823e49e2e4e -r c433348f3628 includes/stats.php --- a/includes/stats.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/stats.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * stats.php - handles statistics for pages (disablable in the admin CP) * diff -r d823e49e2e4e -r c433348f3628 includes/tagcloud.php --- a/includes/tagcloud.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/tagcloud.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -132,6 +132,7 @@ function make_html($span_class = 'normal', $div_align = 'center') { + global $lang; $html = array(); $max = max($this->words); $size = $this->get_cloud_size(); @@ -147,8 +148,8 @@ $newline = ( $inc == 5 ) ? "
" : ''; ( $inc == 5 ) ? $inc = 0 : null; $url = makeUrlNS('Special', 'TagCloud/' . htmlspecialchars($word)); - $s = ( $popularity != 1 ) ? 's' : ''; - $html[] = "$word"; // $newline"; + $popstring = ( $popularity == 1 ) ? $lang->get('pagetools_tagcloug_tip_popularity_one') : $lang->get('pagetools_tagcloug_tip_popularity_plural', array('popularity' => $popularity)); + $html[] = "$word"; // $newline"; } } $html = '
' . implode("\n", $html) . '
'; diff -r d823e49e2e4e -r c433348f3628 includes/template.php --- a/includes/template.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/template.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -42,7 +42,7 @@ $this->theme_loaded = false; $this->fading_button = '
-  +
'; $this->theme_list = Array(); @@ -81,11 +81,7 @@ $this->style_list = $list; } - function template() - { - $this->__construct(); - } - function sidebar_widget($t, $h) + function sidebar_widget($t, $h, $use_normal_section = false) { global $db, $session, $paths, $template, $plugins; // Common objects if(!defined('ENANO_TEMPLATE_LOADED')) @@ -95,9 +91,18 @@ if(!$this->sidebar_widgets) $this->sidebar_widgets = ''; $tplvars = $this->extract_vars('elements.tpl'); - $parser = $this->makeParserText($tplvars['sidebar_section_raw']); - $parser->assign_vars(Array('TITLE'=>$t,'CONTENT'=>$h)); - $this->plugin_blocks[$t] = $h; + + if ( $use_normal_section ) + { + $parser = $this->makeParserText($tplvars['sidebar_section']); + } + else + { + $parser = $this->makeParserText($tplvars['sidebar_section_raw']); + } + + $parser->assign_vars(Array('TITLE' => '{TITLE}','CONTENT' => $h)); + $this->plugin_blocks[$t] = $parser->run(); $this->sidebar_widgets .= $parser->run(); } function add_header($html) @@ -134,6 +139,9 @@ { global $db, $session, $paths, $template, $plugins; // Common objects global $email; + global $lang; + + profiler_log("template: starting var init"); if(!$this->theme || !$this->style) { @@ -153,7 +161,36 @@ { $this->add_header(' '); } @@ -162,40 +199,41 @@ switch($paths->namespace) { case "Article": default: - $ns = 'article'; + $ns = $lang->get('onpage_lbl_page_article'); break; case "Admin": - $ns = 'administration page'; + $ns = $lang->get('onpage_lbl_page_admin'); break; case "System": - $ns = 'system message'; + $ns = $lang->get('onpage_lbl_page_system'); break; case "File": - $ns = 'uploaded file'; + $ns = $lang->get('onpage_lbl_page_file'); break; case "Help": - $ns = 'documentation page'; + $ns = $lang->get('onpage_lbl_page_help'); break; case "User": - $ns = 'user page'; + $ns = $lang->get('onpage_lbl_page_user'); break; case "Special": - $ns = 'special page'; + $ns = $lang->get('onpage_lbl_page_special'); break; case "Template": - $ns = 'template'; + $ns = $lang->get('onpage_lbl_page_template'); break; case "Project": - $ns = 'project page'; + $ns = $lang->get('onpage_lbl_page_project'); break; case "Category": - $ns = 'category'; + $ns = $lang->get('onpage_lbl_page_category'); break; case "Anonymous": $ns = 'external page'; break; } $this->namespace_string = $ns; + unset($ns); $code = $plugins->setHook('page_type_string_set'); foreach ( $code as $cmd ) { @@ -214,7 +252,7 @@ if ( true || !$paths->anonymous_page ) { $parser->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxReset()); return false; }" title="View the page contents, all of the page contents, and nothing but the page contents (alt-a)" accesskey="a"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxReset()); return false; }" title="' . $lang->get('onpage_tip_article') . '" accesskey="a"', 'PARENTFLAGS' => 'id="mdgToolbar_article"', 'HREF' => makeUrl($paths->page, null, true), 'TEXT' => $this->namespace_string @@ -255,14 +293,25 @@ $n = ( $session->get_permissions('mod_comments') ) ? (string)$nc : (string)$na; if ( $session->get_permissions('mod_comments') && $nu > 0 ) { - $n .= ' total/'.$nu.' unapp.'; + $subst = array( + 'num_comments' => $nc, + 'num_unapp' => $nu + ); + $btn_text = $lang->get('onpage_btn_discussion_unapp', $subst); + } + else + { + $subst = array( + 'num_comments' => $nc + ); + $btn_text = $lang->get('onpage_btn_discussion', $subst); } $button->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxComments()); return false; }" title="View the comments that other users have posted about this page (alt-c)" accesskey="c"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxComments()); return false; }" title="' . $lang->get('onpage_tip_comments') . '" accesskey="c"', 'PARENTFLAGS' => 'id="mdgToolbar_discussion"', 'HREF' => makeUrl($paths->page, 'do=comments', true), - 'TEXT' => 'discussion ('.$n.')', + 'TEXT' => $btn_text, )); $tb .= $button->run(); @@ -271,21 +320,21 @@ if($session->get_permissions('read') && ($paths->namespace != 'Special' && $paths->namespace != 'Admin' && $paths->namespace != 'Anonymous') && ( $session->get_permissions('edit_page') && ( ( $paths->page_protected && $session->get_permissions('even_when_protected') ) || !$paths->page_protected ) ) ) { $button->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxEditor()); return false; }" title="Edit the contents of this page (alt-e)" accesskey="e"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxEditor()); return false; }" title="' . $lang->get('onpage_tip_edit') . '" accesskey="e"', 'PARENTFLAGS' => 'id="mdgToolbar_edit"', 'HREF' => makeUrl($paths->page, 'do=edit', true), - 'TEXT' => 'edit this page' + 'TEXT' => $lang->get('onpage_btn_edit') )); $tb .= $button->run(); // View source button } - else if($session->get_permissions('view_source') && ( !$session->get_permissions('edit_page') || !$session->get_permissions('even_when_protected') && $paths->page_protected ) && $paths->namespace != 'Special' && $paths->namespace != 'Admin') + else if($session->get_permissions('view_source') && ( !$session->get_permissions('edit_page') || !$session->get_permissions('even_when_protected') && $paths->page_protected ) && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $paths->namespace != 'Anonymous') { $button->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxViewSource()); return false; }" title="View the source code (wiki markup) that this page uses (alt-e)" accesskey="e"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxEditor()); return false; }" title="' . $lang->get('onpage_tip_viewsource') . '" accesskey="e"', 'PARENTFLAGS' => 'id="mdgToolbar_edit"', 'HREF' => makeUrl($paths->page, 'do=viewsource', true), - 'TEXT' => 'view source' + 'TEXT' => $lang->get('onpage_btn_viewsource') )); $tb .= $button->run(); } @@ -293,10 +342,10 @@ if ( $session->get_permissions('read') /* && $paths->wiki_mode */ && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $session->get_permissions('history_view') ) { $button->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxHistory()); return false; }" title="View a log of actions taken on this page (alt-h)" accesskey="h"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxHistory()); return false; }" title="' . $lang->get('onpage_tip_history') . '" accesskey="h"', 'PARENTFLAGS' => 'id="mdgToolbar_history"', 'HREF' => makeUrl($paths->page, 'do=history', true), - 'TEXT' => 'history' + 'TEXT' => $lang->get('onpage_btn_history') )); $tb .= $button->run(); } @@ -308,9 +357,9 @@ if ( $session->get_permissions('read') && $paths->page_exists && ( $session->get_permissions('rename') && ( $paths->page_protected && $session->get_permissions('even_when_protected') || !$paths->page_protected ) ) && $paths->namespace != 'Special' && $paths->namespace != 'Admin' ) { $menubtn->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxRename()); return false; }" title="Change the display name of this page (alt-r)" accesskey="r"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxRename()); return false; }" title="' . $lang->get('onpage_tip_rename') . '" accesskey="r"', 'HREF' => makeUrl($paths->page, 'do=rename', true), - 'TEXT' => 'rename', + 'TEXT' => $lang->get('onpage_btn_rename'), )); $this->toolbar_menu .= $menubtn->run(); } @@ -319,9 +368,9 @@ if ( $paths->wiki_mode && $session->get_permissions('vote_delete') && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin') { $menubtn->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxDelVote()); return false; }" title="Vote to have this page deleted (alt-d)" accesskey="d"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxDelVote()); return false; }" title="' . $lang->get('onpage_tip_delvote') . '" accesskey="d"', 'HREF' => makeUrl($paths->page, 'do=delvote', true), - 'TEXT' => 'vote to delete this page', + 'TEXT' => $lang->get('onpage_btn_votedelete'), )); $this->toolbar_menu .= $menubtn->run(); } @@ -330,9 +379,9 @@ if ( $session->get_permissions('read') && $paths->wiki_mode && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $session->get_permissions('vote_reset') && $paths->cpage['delvotes'] > 0) { $menubtn->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxResetDelVotes()); return false; }" title="Vote to have this page deleted (alt-y)" accesskey="y"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxResetDelVotes()); return false; }" title="' . $lang->get('onpage_tip_resetvotes') . '" accesskey="y"', 'HREF' => makeUrl($paths->page, 'do=resetvotes', true), - 'TEXT' => 'reset deletion votes', + 'TEXT' => $lang->get('onpage_btn_votedelete_reset'), )); $this->toolbar_menu .= $menubtn->run(); } @@ -341,9 +390,9 @@ if ( $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' ) { $menubtn->assign_vars(array( - 'FLAGS' => 'title="View a version of this page that is suitable for printing"', + 'FLAGS' => 'title="' . $lang->get('onpage_tip_printable') . '"', 'HREF' => makeUrl($paths->page, 'printable=yes', true), - 'TEXT' => 'view printable version', + 'TEXT' => $lang->get('onpage_btn_printable'), )); $this->toolbar_menu .= $menubtn->run(); } @@ -353,7 +402,7 @@ { $label = $this->makeParserText($tplvars['toolbar_label']); - $label->assign_vars(array('TEXT' => 'protection:')); + $label->assign_vars(array('TEXT' => $lang->get('onpage_lbl_protect'))); $t0 = $label->run(); $ctmp = ''; @@ -362,9 +411,9 @@ $ctmp=' style="text-decoration: underline;"'; } $menubtn->assign_vars(array( - 'FLAGS' => 'accesskey="i" onclick="if ( !KILL_SWITCH ) { ajaxProtect(1); return false; }" id="protbtn_1" title="Prevents all non-administrators from editing this page. [alt-i]"'.$ctmp, + 'FLAGS' => 'accesskey="i" onclick="if ( !KILL_SWITCH ) { ajaxProtect(1); return false; }" id="protbtn_1" title="' . $lang->get('onpage_tip_protect_on') . '"'.$ctmp, 'HREF' => makeUrl($paths->page, 'do=protect&level=1', true), - 'TEXT' => 'on' + 'TEXT' => $lang->get('onpage_btn_protect_on') )); $t1 = $menubtn->run(); @@ -374,9 +423,9 @@ $ctmp=' style="text-decoration: underline;"'; } $menubtn->assign_vars(array( - 'FLAGS' => 'accesskey="o" onclick="if ( !KILL_SWITCH ) { ajaxProtect(0); return false; }" id="protbtn_0" title="Allows everyone to edit this page. [alt-o]"'.$ctmp, + 'FLAGS' => 'accesskey="o" onclick="if ( !KILL_SWITCH ) { ajaxProtect(0); return false; }" id="protbtn_0" title="' . $lang->get('onpage_tip_protect_off') . '"'.$ctmp, 'HREF' => makeUrl($paths->page, 'do=protect&level=0', true), - 'TEXT' => 'off' + 'TEXT' => $lang->get('onpage_btn_protect_off') )); $t2 = $menubtn->run(); @@ -386,9 +435,9 @@ $ctmp = ' style="text-decoration: underline;"'; } $menubtn->assign_vars(array( - 'FLAGS' => 'accesskey="p" onclick="if ( !KILL_SWITCH ) { ajaxProtect(2); return false; }" id="protbtn_2" title="Allows only users who have been registered for 4 days to edit this page. [alt-p]"'.$ctmp, + 'FLAGS' => 'accesskey="p" onclick="if ( !KILL_SWITCH ) { ajaxProtect(2); return false; }" id="protbtn_2" title="' . $lang->get('onpage_tip_protect_semi') . '"'.$ctmp, 'HREF' => makeUrl($paths->page, 'do=protect&level=2', true), - 'TEXT' => 'semi' + 'TEXT' => $lang->get('onpage_btn_protect_semi') )); $t3 = $menubtn->run(); @@ -407,7 +456,7 @@ { // label at start $label = $this->makeParserText($tplvars['toolbar_label']); - $label->assign_vars(array('TEXT' => 'page wiki mode:')); + $label->assign_vars(array('TEXT' => $lang->get('onpage_lbl_wikimode'))); $t0 = $label->run(); // on button @@ -419,7 +468,7 @@ $menubtn->assign_vars(array( 'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(1); return false; }" id="wikibtn_1" title="Forces wiki functions to be allowed on this page."'. */ $ctmp, 'HREF' => makeUrl($paths->page, 'do=setwikimode&level=1', true), - 'TEXT' => 'on' + 'TEXT' => $lang->get('onpage_btn_wikimode_on') )); $t1 = $menubtn->run(); @@ -432,7 +481,7 @@ $menubtn->assign_vars(array( 'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(0); return false; }" id="wikibtn_0" title="Forces wiki functions to be disabled on this page."'. */ $ctmp, 'HREF' => makeUrl($paths->page, 'do=setwikimode&level=0', true), - 'TEXT' => 'off' + 'TEXT' => $lang->get('onpage_btn_wikimode_off') )); $t2 = $menubtn->run(); @@ -445,7 +494,7 @@ $menubtn->assign_vars(array( 'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(2); return false; }" id="wikibtn_2" title="Causes this page to use the global wiki mode setting (default)"'. */ $ctmp, 'HREF' => makeUrl($paths->page, 'do=setwikimode&level=2', true), - 'TEXT' => 'global' + 'TEXT' => $lang->get('onpage_btn_wikimode_global') )); $t3 = $menubtn->run(); @@ -464,9 +513,9 @@ if ( $session->get_permissions('read') && $session->get_permissions('clear_logs') && $paths->namespace != 'Special' && $paths->namespace != 'Admin' ) { $menubtn->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxClearLogs()); return false; }" title="Remove all edit and action logs for this page from the database. IRREVERSIBLE! (alt-l)" accesskey="l"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxClearLogs()); return false; }" title="' . $lang->get('onpage_tip_flushlogs') . '" accesskey="l"', 'HREF' => makeUrl($paths->page, 'do=flushlogs', true), - 'TEXT' => 'clear page logs', + 'TEXT' => $lang->get('onpage_btn_clearlogs'), )); $this->toolbar_menu .= $menubtn->run(); } @@ -474,18 +523,26 @@ // Delete page button if ( $session->get_permissions('read') && $session->get_permissions('delete_page') && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' ) { - $s = 'delete this page'; + $s = $lang->get('onpage_btn_deletepage'); if ( $paths->cpage['delvotes'] == 1 ) { - $s .= ' ('.$paths->cpage['delvotes'].' vote)'; + $subst = array( + 'num_votes' => $paths->cpage['delvotes'], + 'plural' => '' + ); + $s .= $lang->get('onpage_btn_deletepage_votes', $subst); } else if ( $paths->cpage['delvotes'] > 1 ) { - $s .= ' ('.$paths->cpage['delvotes'].' votes)'; + $subst = array( + 'num_votes' => $paths->cpage['delvotes'], + 'plural' => $lang->get('meta_plural') + ); + $s .= $lang->get('onpage_btn_deletepage_votes', $subst); } $menubtn->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxDeletePage()); return false; }" title="Delete this page. This is always reversible unless the logs are cleared. (alt-k)" accesskey="k"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxDeletePage()); return false; }" title="' . $lang->get('onpage_tip_deletepage') . '" accesskey="k"', 'HREF' => makeUrl($paths->page, 'do=deletepage', true), 'TEXT' => $s, )); @@ -513,13 +570,13 @@ { // label at start $label = $this->makeParserText($tplvars['toolbar_label']); - $label->assign_vars(array('TEXT' => 'page password:')); + $label->assign_vars(array('TEXT' => $lang->get('onpage_lbl_password'))); $t0 = $label->run(); $menubtn->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxSetPassword()); return false; }" title="Require a password in order for this page to be viewed"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxSetPassword()); return false; }" title="' . $lang->get('onpage_tip_password') . '"', 'HREF' => '#', - 'TEXT' => 'set', + 'TEXT' => $lang->get('onpage_btn_password_set'), )); $t = $menubtn->run(); @@ -530,9 +587,9 @@ if ( !$paths->anonymous_page && ( $session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN ) ) { $menubtn->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { return ajaxOpenACLManager(); }" title="Manage who can do what with this page (alt-m)" accesskey="m"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { return ajaxOpenACLManager(); }" title="' . $lang->get('onpage_tip_aclmanager') . '" accesskey="m"', 'HREF' => makeUrl($paths->page, 'do=aclmanager', true), - 'TEXT' => 'manage page access', + 'TEXT' => $lang->get('onpage_btn_acl'), )); $this->toolbar_menu .= $menubtn->run(); } @@ -541,9 +598,9 @@ if ( $session->user_level >= USER_LEVEL_ADMIN && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' ) { $menubtn->assign_vars(array( - 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxAdminPage()); return false; }" title="Administrative options for this page" accesskey="g"', + 'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxAdminPage()); return false; }" title="' . $lang->get('onpage_tip_adminoptions') . '" accesskey="g"', 'HREF' => makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'PageManager', true), - 'TEXT' => 'administrative options', + 'TEXT' => $lang->get('onpage_btn_admin'), )); $this->toolbar_menu .= $menubtn->run(); } @@ -551,10 +608,10 @@ if ( strlen($this->toolbar_menu) > 0 ) { $button->assign_vars(array( - 'FLAGS' => 'id="mdgToolbar_moreoptions" onclick="if ( !KILL_SWITCH ) { return false; }" title="Additional options for working with this page"', + 'FLAGS' => 'id="mdgToolbar_moreoptions" onclick="if ( !KILL_SWITCH ) { return false; }" title="' . $lang->get('onpage_tip_moreoptions') . '"', 'PARENTFLAGS' => '', 'HREF' => makeUrl($paths->page, 'do=moreoptions', true), - 'TEXT' => 'more options' + 'TEXT' => $lang->get('onpage_btn_moreoptions') )); $tb .= $button->run(); } @@ -603,6 +660,10 @@ // Add the e-mail address client code to the header $this->add_header($email->jscode()); + // Add language file + $lang_uri = makeUrlNS('Special', 'LangExportJSON/' . $lang->lang_id, false, true); + $this->add_header(""); + // Generate the code for the Log out and Change theme sidebar buttons // Once again, the new template parsing system can be used here @@ -611,7 +672,7 @@ $parser->assign_vars(Array( 'HREF'=>makeUrlNS('Special', 'Logout'), 'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { mb_logout(); return false; }"', - 'TEXT'=>'Log out', + 'TEXT'=>$lang->get('sidebar_btn_logout'), )); $logout_link = $parser->run(); @@ -619,7 +680,7 @@ $parser->assign_vars(Array( 'HREF'=>makeUrlNS('Special', 'Login/' . $paths->page), 'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { ajaxStartLogin(); return false; }"', - 'TEXT'=>'Log in', + 'TEXT'=>$lang->get('sidebar_btn_login'), )); $login_link = $parser->run(); @@ -627,7 +688,7 @@ $parser->assign_vars(Array( 'HREF'=>makeUrlNS('Special', 'ChangeStyle/'.$paths->page), 'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { ajaxChangeStyle(); return false; }"', - 'TEXT'=>'Change theme', + 'TEXT'=>$lang->get('sidebar_btn_changestyle'), )); $theme_link = $parser->run(); @@ -635,7 +696,7 @@ $parser->assign_vars(Array( 'HREF'=>makeUrlNS('Special', 'Administration'), 'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { void(ajaxStartAdminLogin()); return false; }"', - 'TEXT'=>'Administration', + 'TEXT'=>$lang->get('sidebar_btn_administration'), )); $admin_link = $parser->run(); @@ -656,6 +717,7 @@ var scriptPath=\''. scriptPath .'\'; var contentPath=\''.contentPath.'\'; var ENANO_SID =\'' . $SID . '\'; + var user_level=' . $session->user_level . '; var auth_level=' . $session->auth_level . '; var USER_LEVEL_GUEST = ' . USER_LEVEL_GUEST . '; var USER_LEVEL_MEMBER = ' . USER_LEVEL_MEMBER . '; @@ -681,7 +743,9 @@ } } $js_dynamic .= '\'; - var ENANO_CURRENT_THEME = \''. $session->theme .'\';'; + var ENANO_CURRENT_THEME = \''. $session->theme .'\'; + var ENANO_LANG_ID = ' . $lang->lang_id . '; + var ENANO_PAGE_TYPE = "' . addslashes($this->namespace_string) . '";'; foreach($paths->nslist as $k => $c) { $js_dynamic .= "namespace_list['{$k}'] = '$c';"; @@ -739,11 +803,15 @@ { eval($cmd); } + + profiler_log("template: finished var init"); } function header($simple = false) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + ob_start(); if(!$this->theme_loaded) @@ -769,21 +837,37 @@ { $login_link = makeUrlNS('Special', 'Login/' . $paths->fullpage, 'level=' . $session->user_level, true); echo '
'; - echo 'Your administrative session has timed out. Log in again'; + echo $lang->get('user_msg_elev_timed_out', array( 'login_link' => $login_link )); echo '
'; } if ( $this->site_disabled && $session->user_level >= USER_LEVEL_ADMIN && ( $paths->page != $paths->nslist['Special'] . 'Administration' ) ) { $admin_link = makeUrlNS('Special', 'Administration', 'module=' . $paths->nslist['Admin'] . 'GeneralConfig', true); - echo '
The site is currently disabled and thus is only accessible to administrators.
- You can re-enable the site through the administration panel. + echo '
' . $lang->get('page_sitedisabled_admin_msg_title') . '
+ ' . $lang->get('page_sitedisabled_admin_msg_body', array('admin_link' => $admin_link)) . '
'; } } + function footer($simple = false) { + echo $this->getFooter($simple); + ob_end_flush(); + } + + function getHeader() + { + $headers_sent = true; + if(!defined('ENANO_HEADERS_SENT')) + define('ENANO_HEADERS_SENT', ''); + if(!$this->no_headers) return $this->process_template('header.tpl'); + } + function getFooter($simple = false) + { global $db, $session, $paths, $template, $plugins; // Common objects - if(!$this->no_headers) { + global $lang; + if ( !$this->no_headers ) + { if(!defined('ENANO_HEADERS_SENT')) $this->header(); @@ -791,57 +875,46 @@ global $_starttime; if(isset($_GET['sqldbg']) && $session->get_permissions('mod_misc')) { - echo '

Query list as requested on URI

';
+        echo '

' . $lang->get('page_heading_sql_list') . '

';
         echo htmlspecialchars($db->sql_backtrace());
         echo '
'; } - $f = microtime_float(); - $f = $f - $_starttime; - $f = round($f, 4); - $dbg = 'Time: '.$f.'s | Queries: '.$db->num_queries; $t = ( $simple ) ? $this->process_template('simple-footer.tpl') : $this->process_template('footer.tpl'); - $t = str_replace('[[Stats]]', $dbg, $t); - $t = str_replace('[[NumQueries]]', (string)$db->num_queries, $t); - $t = str_replace('[[GenTime]]', (string)$f, $t); - echo $t; - - ob_end_flush(); - } - else return ''; - } - function getHeader() - { - $headers_sent = true; - if(!defined('ENANO_HEADERS_SENT')) - define('ENANO_HEADERS_SENT', ''); - if(!$this->no_headers) return $this->process_template('header.tpl'); - } - function getFooter() - { - global $db, $session, $paths, $template, $plugins; // Common objects - if(!$this->no_headers) { - global $_starttime; - $t = ''; - - if(isset($_GET['sqldbg']) && $session->get_permissions('mod_misc')) - { - $t .= '

Query list as requested on URI

';
-        $t .= $db->sql_backtrace();
-        $t .= '
'; - } $f = microtime_float(); $f = $f - $_starttime; - $f = round($f, 4); - $dbg = 'Time: '.$f.'s | Queries: '.$db->num_queries; - $t.= $this->process_template('footer.tpl'); + $f = round($f, 2); + + $t_loc = $lang->get('page_msg_stats_gentime_short', array('time' => $f)); + $t_loc_long = $lang->get('page_msg_stats_gentime_long', array('time' => $f)); + $q_loc = '' . $lang->get('page_msg_stats_sql', array('nq' => $db->num_queries)) . ''; + $dbg = $t_loc; + $dbg_long = $t_loc_long; + if ( $session->user_level >= USER_LEVEL_ADMIN ) + { + $dbg .= "  |  $q_loc"; + $dbg_long .= "  |  $q_loc"; + } + $t = str_replace('[[Stats]]', $dbg, $t); + $t = str_replace('[[StatsLong]]', $dbg_long, $t); $t = str_replace('[[NumQueries]]', (string)$db->num_queries, $t); $t = str_replace('[[GenTime]]', (string)$f, $t); + $t = str_replace('[[NumQueriesLoc]]', $q_loc, $t); + $t = str_replace('[[GenTimeLoc]]', $t_loc, $t); + $t = str_replace('[[EnanoPoweredLink]]', $lang->get('page_enano_powered', array('about_uri' => $this->tpl_strings['URL_ABOUT_ENANO'])), $t); + $t = str_replace('[[EnanoPoweredLinkLong]]', $lang->get('page_enano_powered_long', array('about_uri' => $this->tpl_strings['URL_ABOUT_ENANO'])), $t); + + if ( defined('ENANO_DEBUG') ) + $t = str_replace('', '
' . profiler_make_html() . '
', $t); + return $t; } - else return ''; + else + { + return ''; + } } /** @@ -878,7 +951,7 @@ // This is a bad coding practice so this function will always be picky. if ( !$this->theme ) { - die('$template->extract_vars(): theme (' . $this->theme . ') not yet loaded, so we can\'t open template files yet...this is a bug and should be reported.

Backtrace, most recent call first:
'.enano_debug_print_backtrace(true).'
'); + die('$template->extract_vars(): theme not yet loaded, so we can\'t open template files yet...this is a bug and should be reported.

Backtrace, most recent call first:
'.enano_debug_print_backtrace(true).'
'); } // Full pathname of template file @@ -965,7 +1038,7 @@ $keywords = implode('|', $keywords); // Matches - // 1 2 3 4 56 7 8 + // 1 2 3 4 56 7 8 $regexp = '/()(.*)(()(.*))?()/isU'; /* @@ -1107,7 +1180,7 @@ // matches the MD5 of the file that the compiled file was compiled from. if ( isset($md5) && $md5 == md5($text) ) { - return str_replace('\\"', '"', $tpl_text); + return $this->compile_template_text_post(str_replace('\\"', '"', $tpl_text)); } } @@ -1146,7 +1219,7 @@ fclose($h); } - return $text; //('
'.htmlspecialchars($text).'
'); + return $this->compile_template_text_post($text); //('
'.htmlspecialchars($text).'
'); } @@ -1159,7 +1232,7 @@ function compile_template_text($text) { // this might do something else in the future, possibly cache large templates - return $this->compile_tpl_code($text); + return $this->compile_template_text_post($this->compile_tpl_code($text)); } /** @@ -1171,9 +1244,30 @@ function parse($text) { $text = $this->compile_template_text($text); + $text = $this->compile_template_text_post($text); return eval($text); } + /** + * Post-processor for template code. Basically what this does is it localizes {lang:foo} blocks. + * @param string Mostly-processed TPL code + * @return string + */ + + function compile_template_text_post($text) + { + global $lang; + preg_match_all('/\{lang:([a-z0-9]+_[a-z0-9_]+)\}/', $text, $matches); + foreach ( $matches[1] as $i => $string_id ) + { + $string = $lang->get($string_id); + $string = str_replace('\\', '\\\\', $string); + $string = str_replace('\'', '\\\'', $string); + $text = str_replace_once($matches[0][$i], $string, $text); + } + return $text; + } + // Steps to turn this: // [[Project:Community Portal]] // into this: @@ -1203,10 +1297,13 @@ function tplWikiFormat($message, $filter_links = false, $filename = 'elements.tpl') { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + $filter_links = false; $tplvars = $this->extract_vars($filename); if($session->sid_super) $as = htmlspecialchars(urlSeparator).'auth='.$session->sid_super; else $as = ''; + error_reporting(E_ALL); $random_id = sha1(microtime().''); // A temp value /* @@ -1330,6 +1427,15 @@ } } + preg_match_all('/\{lang:([a-z0-9]+_[a-z0-9_]+)\}/', $message, $matches); + foreach ( $matches[1] as $i => $string_id ) + { + $string = $lang->get($string_id); + $string = str_replace('\\', '\\\\', $string); + $string = str_replace('\'', '\\\'', $string); + $message = str_replace_once($matches[0][$i], $string, $message); + } + /* * HTML RENDERER */ @@ -1489,25 +1595,28 @@ function tinymce_textarea($name, $content = '', $rows = 20, $cols = 60) { + global $lang; $randomid = md5(microtime() . mt_rand()); $html = ''; $html .= ''; - $html .= '
text editor  |  graphical editor
'; + $html .= '
' . $lang->get('etc_tinymce_btn_text') . '  |  ' . $lang->get('etc_tinymce_btn_graphical') . '
'; $html .= ''; + } + $js_dynamic .= ''; + // The rewritten template engine will process all required vars during the load_template stage instead of (cough) re-processing everything each time around. $tpl_strings = Array( 'PAGE_NAME'=>$this_page, 'PAGE_URLNAME'=>'Null', - 'SITE_NAME'=>'Enano Installation', + 'SITE_NAME'=> ( defined('IN_ENANO_INSTALL') && is_object($lang) ) ? $lang->get('meta_site_name') : 'Critical error', 'USERNAME'=>'admin', - 'SITE_DESC'=>'Install Enano on your server.', + 'SITE_DESC'=>( defined('IN_ENANO_INSTALL') && is_object($lang) ) ? $lang->get('meta_site_desc') : 'This site is experiencing a problem and cannot load.', 'TOOLBAR'=>$tb, 'SCRIPTPATH'=>scriptPath, 'CONTENTPATH'=>contentPath, @@ -1854,7 +1980,7 @@ 'ADMIN_SID_AMP_HTML'=>'', 'ADDITIONAL_HEADERS'=>$this->additional_headers, 'SIDEBAR_EXTRA'=>'', - 'COPYRIGHT'=>'Enano and all of its code, graphics, and more code is copyright © 2006 Dan Fuhry.
This program is Free Software; see the file "GPL" included with this package for details.', + 'COPYRIGHT'=>( defined('IN_ENANO_INSTALL') && is_object($lang) ) ? $lang->get('meta_enano_copyright') : ( defined('ENANO_CONFIG_FETCHED') ? getConfig('copyright_notice') : '' ), 'TOOLBAR_EXTRAS'=>'', 'REQUEST_URI'=>( isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '' ).$_SERVER['REQUEST_URI'], 'STYLE_LINK'=>$slink, @@ -1863,9 +1989,10 @@ 'TEMPLATE_DIR'=>scriptPath.'/themes/'.$this->theme, 'THEME_ID'=>$this->theme, 'STYLE_ID'=>$this->style, - 'JS_DYNAMIC_VARS'=>'', + 'JS_DYNAMIC_VARS'=>$js_dynamic, 'SIDEBAR_RIGHT'=>'', - 'REPORT_URI' => '' + 'REPORT_URI' => '', + 'URL_ABOUT_ENANO' => 'http://enanocms.org/' ); $this->tpl_strings = array_merge($tpl_strings, $this->tpl_strings); @@ -1881,7 +2008,7 @@ } $p = $this->makeParserText($tplvars['sidebar_section']); $p->assign_vars(Array( - 'TITLE'=>'Installation progress', + 'TITLE'=>$lang->get('meta_sidebar_heading'), 'CONTENT'=>$sidebar, )); $sidebar = $p->run(); @@ -1912,28 +2039,55 @@ function footer($simple = false) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + if(!$this->no_headers) { global $_starttime; - $f = microtime(true); + $filename = ( $simple ) ? 'simple-footer.tpl' : 'footer.tpl'; + $t = $this->process_template($filename); + + $f = microtime_float(); $f = $f - $_starttime; $f = round($f, 4); - if(defined('IN_ENANO_INSTALL')) $nq = 'N/A'; - else $nq = $db->num_queries; - if($nq == 0) $nq = 'N/A'; - $dbg = 'Time: '.$f.'s | Queries: '.$nq; - $filename = ( $simple ) ? 'simple-footer.tpl' : 'footer.tpl'; - $t = $this->process_template($filename); - $t = str_replace('[[Stats]]', $dbg, $t); - if ( is_object($db) ) + + if ( is_object($lang) ) { - $t = str_replace('[[NumQueries]]', (string)$db->num_queries, $t); + $t_loc = $lang->get('page_msg_stats_gentime_short', array('time' => $f)); + $t_loc_long = $lang->get('page_msg_stats_gentime_long', array('time' => $f)); + $q_loc = '' . $lang->get('page_msg_stats_sql', array('nq' => ( is_object($db) ? $db->num_queries : 'N/A' ))) . ''; + $dbg = $t_loc; + $dbg_long = $t_loc_long; + if ( $session->user_level >= USER_LEVEL_ADMIN ) + { + $dbg .= "  |  $q_loc"; + $dbg_long .= "  |  $q_loc"; + } + $t = str_replace('[[EnanoPoweredLink]]', $lang->get('page_enano_powered', array('about_uri' => $this->tpl_strings['URL_ABOUT_ENANO'])), $t); + $t = str_replace('[[EnanoPoweredLinkLong]]', $lang->get('page_enano_powered_long', array('about_uri' => $this->tpl_strings['URL_ABOUT_ENANO'])), $t); } else { - $t = str_replace('[[NumQueries]]', '0', $t); + $t_loc = "Time: {$f}s"; + $t_loc_long = "Generated in {$f}sec"; + $q_loc = '' . ( is_object($db) ? "{$db->num_queries} SQL" : 'Queries: N/A' ) . ''; + $dbg = $t_loc; + $dbg_long = $t_loc_long; + if ( $session->user_level >= USER_LEVEL_ADMIN ) + { + $dbg .= "  |  $q_loc"; + $dbg_long .= "  |  $q_loc"; + } + $t = str_replace('[[EnanoPoweredLink]]', 'Powered by Enano', $t); + $t = str_replace('[[EnanoPoweredLinkLong]]', 'Website engine powered by Enano', $t); } + + $t = str_replace('[[Stats]]', $dbg, $t); + $t = str_replace('[[StatsLong]]', $dbg_long, $t); + $t = str_replace('[[NumQueries]]', ( is_object($db) ? (string)$db->num_queries : '0' ), $t); $t = str_replace('[[GenTime]]', (string)$f, $t); + $t = str_replace('[[NumQueriesLoc]]', $q_loc, $t); + $t = str_replace('[[GenTimeLoc]]', $t_loc, $t); echo $t; } @@ -2066,9 +2220,9 @@ /** * PHP 4 constructor. */ - function templateIndividualSafe($text, $parent) + function templateIndividual($text) { - $this->__construct($text, $parent); + $this->__construct($text); } /** * Assigns an array of string values to the template. Strings can be accessed from the template by inserting {KEY_NAME} in the template file. diff -r d823e49e2e4e -r c433348f3628 includes/wikiengine/Tables.php --- a/includes/wikiengine/Tables.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/wikiengine/Tables.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -587,6 +587,7 @@ 'nowiki' => array(), 'noinclude' => array(), 'nodisplay' => array(), + 'lang' => array('code'), # XHTML stuff 'acronym' => $common diff -r d823e49e2e4e -r c433348f3628 includes/wikiformat.php --- a/includes/wikiformat.php Fri Feb 22 12:46:51 2008 -0500 +++ b/includes/wikiformat.php Fri Feb 22 12:51:53 2008 -0500 @@ -107,6 +107,18 @@ if (is_array($rules)) { $this->rules = $rules; } + + global $plugins; + // This code can be run from the installer, so in some cases $plugins + // isn't initted. (Bug in 1.1.2, fixed for 1.1.3) + if ( is_object($plugins) ) + { + $code = $plugins->setHook('text_wiki_construct'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + } $this->addPath( 'parse', @@ -119,11 +131,11 @@ } - function &singleton($parser = 'Default', $rules = null) + public static function singleton($parser = 'Default', $rules = null) { static $only = array(); if (!isset($only[$parser])) { - $ret =& Text_Wiki::factory($parser, $rules); + $ret = Text_Wiki::factory($parser, $rules); if (!$ret) { return $ret; } @@ -132,7 +144,7 @@ return $only[$parser]; } - function &factory($parser = 'Default', $rules = null) + public static function factory($parser = 'Default', $rules = null) { $d=getcwd(); chdir(ENANO_ROOT); @@ -154,7 +166,7 @@ chdir($d); - $obj =& new $class($rules); + $obj = new $class($rules); return $obj; } @@ -514,7 +526,7 @@ } } - $this->parseObj[$rule] =& new $class($this); + $this->parseObj[$rule] = new $class($this); } @@ -536,7 +548,7 @@ } } - $this->renderObj[$rule] =& new $class($this); + $this->renderObj[$rule] = new $class($this); } function loadFormatObj($format) @@ -556,7 +568,7 @@ } } - $this->formatObj[$format] =& new $class($this); + $this->formatObj[$format] = new $class($this); } function addPath($type, $dir) @@ -613,7 +625,7 @@ function isError(&$obj) { - return is_a($obj, 'PEAR_Error'); + return ( @get_class($obj) == 'PEAR_Error' ); } } diff -r d823e49e2e4e -r c433348f3628 index.php --- a/index.php Fri Feb 22 12:46:51 2008 -0500 +++ b/index.php Fri Feb 22 12:51:53 2008 -0500 @@ -2,7 +2,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0.3 (Dyrad) + * Version 1.1.2 * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -17,13 +17,16 @@ */ define('ENANO_INTERFACE_INDEX', ''); + + // For the mighty and brave. + // define('ENANO_DEBUG', ''); // Set up gzip encoding before any output is sent - $aggressive_optimize_html = false; + $aggressive_optimize_html = true; global $do_gzip; - $do_gzip = false; + $do_gzip = true; if(isset($_SERVER['PATH_INFO'])) $v = $_SERVER['PATH_INFO']; elseif(isset($_GET['title'])) $v = $_GET['title']; @@ -34,15 +37,6 @@ error_reporting(E_ALL); - // if(!strstr($v, 'CSS') && !strstr($v, 'UploadFile') && !strstr($v, 'DownloadFile')) // These pages are blacklisted because we can't have debugConsole's HTML output disrupting the flow of header() calls and whatnot - // { - // $do_gzip = ( function_exists('gzcompress') && ( isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') ) ) ? true : false; - // // Uncomment the following line to enable debugConsole (requires PHP 5 or later) - // // define('ENANO_DEBUG', ''); - // } - - if(defined('ENANO_DEBUG')) $do_gzip = false; - if($aggressive_optimize_html || $do_gzip) { ob_start(); @@ -97,11 +91,12 @@ if(!$q) $db->_die('The comment data could not be selected.'); $row = $db->fetchrow(); $db->free_result(); + $row['subject'] = str_replace('\'', ''', $row['subject']); echo '
'; echo "
- - - + + +
Subject:
Comment:
" . $lang->get('comment_postform_field_subject') . "
" . $lang->get('comment_postform_field_comment') . "
"; echo '
'; break; @@ -129,32 +124,106 @@ } if(isset($_POST['_save'])) { - $e = PageUtils::savepage($paths->page_id, $paths->namespace, $_POST['page_text'], $_POST['edit_summary'], isset($_POST['minor'])); - if ( $e == 'good' ) + $captcha_valid = true; + if ( !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) { - redirect(makeUrl($paths->page), 'Changes saved', 'Your changes to this page have been saved. Redirecting...', 3); + $captcha_valid = false; + if ( isset($_POST['captcha_id']) && isset($_POST['captcha_code']) ) + { + $hash_correct = strtolower($session->get_captcha($_POST['captcha_id'])); + $hash_input = strtolower($_POST['captcha_code']); + if ( $hash_input === $hash_correct ) + $captcha_valid = true; + } + } + if ( $captcha_valid ) + { + $e = PageUtils::savepage($paths->page_id, $paths->namespace, $_POST['page_text'], $_POST['edit_summary'], isset($_POST['minor'])); + if ( $e == 'good' ) + { + redirect(makeUrl($paths->page), $lang->get('editor_msg_save_success_title'), $lang->get('editor_msg_save_success_body'), 3); + } } } $template->header(); + if ( isset($captcha_valid) ) + { + echo '
' . $lang->get('editor_err_captcha_wrong') . '
'; + } if(isset($_POST['_preview'])) { $text = $_POST['page_text']; + $edsumm = $_POST['edit_summary']; echo PageUtils::genPreview($_POST['page_text']); + $text = htmlspecialchars($text); + $revid = 0; + } + else + { + $revid = ( isset($_GET['revid']) ) ? intval($_GET['revid']) : 0; + $page = new PageProcessor($paths->page_id, $paths->namespace, $revid); + $text = $page->fetch_source(); + $edsumm = ''; + // $text = RenderMan::getPage($paths->cpage['urlname_nons'], $paths->namespace, 0, false, false, false, false); } - else $text = RenderMan::getPage($paths->page_id, $paths->namespace, 0, false, false, false, false); + if ( $revid > 0 ) + { + echo '
' . $lang->get('editor_msg_editing_old_revision') . '
'; + // Retrieve information about this revision and the current one + $q = $db->sql_query('SELECT l1.author AS currentrev_author, l2.author AS oldrev_author FROM ' . table_prefix . 'logs AS l1 + LEFT JOIN ' . table_prefix . 'logs AS l2 + ON ( l2.time_id = ' . $revid . ' + AND l2.log_type = \'page\' + AND l2.action = \'edit\' + AND l2.page_id = \'ACL_Tests\' + AND l2.namespace = \'Article\' + ) + WHERE l1.log_type = \'page\' + AND l1.action = \'edit\' + AND l1.page_id = \'ACL_Tests\' + AND l1.namespace = \'Article\' + AND l1.time_id >= ' . $revid . ' + ORDER BY l1.time_id DESC;'); + if ( !$q ) + $db->die_json(); + + $rev_count = $db->numrows() - 1; + $row = $db->fetchrow(); + $undo_info = array( + 'old_author' => $row['oldrev_author'], + 'current_author' => $row['currentrev_author'], + 'undo_count' => $rev_count, + 'last_rev_id' => $revid + ); + $db->free_result(); + } echo '



'; - if($paths->wiki_mode) - echo 'Edit summary:

'; + $edsumm = ( $revid > 0 ) ? $lang->get('editor_reversion_edit_summary', $undo_info) : $edsumm; + echo $lang->get('editor_lbl_edit_summary') . '

'; + if ( !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' ) + { + echo '
'; + echo '' . $lang->get('editor_lbl_field_captcha') . '
' + . '
' + . $lang->get('editor_msg_captcha_pleaseenter') . '

' + . $lang->get('editor_msg_captcha_blind'); + echo '
'; + $hash = $session->make_captcha(); + echo '
'; + echo ''; + echo $lang->get('editor_lbl_field_captcha_code') . ' '; + echo '
'; + } echo '
- - - - + + + +
'; if ( getConfig('wiki_edit_notice') == '1' ) @@ -167,12 +236,13 @@ case 'viewsource': $template->header(); $text = RenderMan::getPage($paths->page_id, $paths->namespace, 0, false, false, false, false); + $text = htmlspecialchars($text); echo '

'; echo '
- +
'; $template->footer(); @@ -214,7 +284,7 @@ break; case 'moreoptions': $template->header(); - echo ''; + echo ''; $template->footer(); break; case 'protect': @@ -223,32 +293,33 @@ { if(!preg_match('#^([0-2]*){1}$#', $_POST['level'])) die_friendly('Error protecting page', '

Request validation failed

'); PageUtils::protect($paths->page_id, $paths->namespace, intval($_POST['level']), $_POST['reason']); - die_friendly('Page protected', '

The protection setting has been applied. Return to the page.

'); + + die_friendly($lang->get('page_protect_lbl_success_title'), '

' . $lang->get('page_protect_lbl_success_body', array( 'page_link' => makeUrl($paths->page) )) . '

'); } $template->header(); ?>
- Error: you must enter a reason for protecting this page.

'; ?> -

Reason for protecting the page:

+ ' . $lang->get('page_protect_err_need_reason') . '

'; ?> +

get('page_protect_lbl_reason'); ?>


- Protecion level to be applied: get('page_protect_lbl_level'); ?> get('page_protect_lbl_level_none'); break; case '1': - echo 'Full protection'; + echo $lang->get('page_protect_lbl_level_full'); break; case '2': - echo 'Semi-protection'; + echo $lang->get('page_protect_lbl_level_semi'); break; default: echo 'None; Warning: request validation will fail after clicking submit'; } ?>

-

+

footer(); @@ -257,37 +328,37 @@ if(!empty($_POST['newname'])) { $r = PageUtils::rename($paths->page_id, $paths->namespace, $_POST['newname']); - die_friendly('Page renamed', '

'.nl2br($r).' Return to the page.

'); + die_friendly($lang->get('page_rename_success_title'), '

'.nl2br($r).' ' . $lang->get('etc_return_to_page') . '.

'); } $template->header(); ?>
- Error: you must enter a new name for this page.

'; ?> -

Please enter a new name for this page:

+ ' . $lang->get('page_rename_err_need_name') . '

'; ?> +

get('page_rename_lbl'); ?>

-

+

footer(); break; case 'flushlogs': - if(!$session->get_permissions('clear_logs')) die_friendly('Access denied', '

Flushing the logs for a page requires administrative rights.

'); + if(!$session->get_permissions('clear_logs')) + { + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('etc_access_denied') . '

'); + } if(isset($_POST['_downthejohn'])) { $template->header(); $result = PageUtils::flushlogs($paths->page_id, $paths->namespace); - echo '

'.$result.' Return to the page.

'; + echo '

'.$result.' ' . $lang->get('etc_return_to_page') . '.

'; $template->footer(); break; } $template->header(); ?>
-

You are about to destroy all logged edits and actions on this page.

-

Unlike deleting or editing this page, this action is not reversible! You should only do this if you are desparate for - database space.

-

Do you really want to continue?

-

+ get('page_flushlogs_warning_stern'); ?> +

footer(); @@ -297,55 +368,66 @@ { $template->header(); $result = PageUtils::delvote($paths->page_id, $paths->namespace); - echo '

'.$result.' Return to the page.

'; + echo '

'.$result.' ' . $lang->get('etc_return_to_page') . '.

'; $template->footer(); break; } $template->header(); ?>
-

Your vote counts.

-

If you think that this page is not relavent to the content on this site, or if it looks like this page was only created in - an attempt to spam the site, you can request that this page be deleted by an administrator.

-

After you vote, you should leave a comment explaining the reason for your vote, especially if you are the first person to - vote against this page.

-

So far, cpage['delvotes'] == 1 ) ? $paths->cpage['delvotes'] . ' person has' : $paths->cpage['delvotes'] . ' people have'; ?> voted to delete this page.

-

+ get('page_delvote_warning_stern'); + echo '

'; + switch($paths->cpage['delvotes']) + { + case 0: echo $lang->get('page_delvote_count_zero'); break; + case 1: echo $lang->get('page_delvote_count_one'); break; + default: echo $lang->get('page_delvote_count_plural', array('delvotes' => $paths->cpage['delvotes'])); break; + } + echo '

'; + ?> +

footer(); break; case 'resetvotes': - if(!$session->get_permissions('vote_reset')) die_friendly('Access denied', '

Resetting the deletion votes against this page requires admin rights.

'); + if(!$session->get_permissions('vote_reset')) + { + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('etc_access_denied') . '

'); + } if(isset($_POST['_youmaylivealittlelonger'])) { $template->header(); $result = PageUtils::resetdelvotes($paths->page_id, $paths->namespace); - echo '

'.$result.' Return to the page.

'; + echo '

'.$result.' ' . $lang->get('etc_return_to_page') . '.

'; $template->footer(); break; } $template->header(); ?>
-

This action will reset the number of votes against this page to zero. Are you sure you want to do this?

-

+

get('ajax_delvote_reset_confirm'); ?>

+

footer(); break; case 'deletepage': - if(!$session->get_permissions('delete_page')) die_friendly('Access denied', '

Deleting pages requires admin rights.

'); + if(!$session->get_permissions('delete_page')) + { + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('etc_access_denied') . '

'); + } if(isset($_POST['_adiossucker'])) { $reason = ( isset($_POST['reason']) ) ? $_POST['reason'] : false; if ( empty($reason) ) - $error = 'Please enter a reason for deleting this page.'; + $error = $lang->get('ajax_delete_prompt_reason'); else { $template->header(); $result = PageUtils::deletepage($paths->page_id, $paths->namespace, $reason); - echo '

'.$result.' Return to the page.

'; + echo '

'.$result.' ' . $lang->get('etc_return_to_page') . '.

'; $template->footer(); break; } @@ -353,19 +435,19 @@ $template->header(); ?>
-

You are about to destroy this page.

-

While the deletion of the page itself is completely reversible, it is impossible to recover any comments or category information on this page. If this is a file page, the file along with all older revisions of it will be permanently deleted. Also, any custom information that this page is tagged with, such as a custom name, protection status, or additional settings such as whether to allow comments, will be permanently lost.

-

Are you absolutely sure that you want to continue?
- You will not be asked again.

+ get('page_delete_warning_stern'); ?> $error

"; ?> -

Reason for deleting:

-

+

get('page_delete_lbl_reason'); ?>

+

footer(); break; case 'setwikimode': - if(!$session->get_permissions('set_wiki_mode')) die_friendly('Access denied', '

Changing the wiki mode setting requires admin rights.

'); + if(!$session->get_permissions('set_wiki_mode')) + { + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('etc_access_denied') . '

'); + } if ( isset($_POST['finish']) ) { $level = intval($_POST['level']); @@ -376,7 +458,7 @@ $q = $db->sql_query('UPDATE '.table_prefix.'pages SET wiki_mode=' . $level . ' WHERE urlname=\'' . $db->escape($paths->page_id) . '\' AND namespace=\'' . $paths->namespace . '\';'); if ( !$q ) $db->_die(); - redirect(makeUrl($paths->page), htmlspecialchars($paths->cpage['name']), 'Wiki mode for this page has been set. Redirecting you to the page...', 2); + redirect(makeUrl($paths->page), htmlspecialchars($paths->cpage['name']), $lang->get('page_wikimode_success_redirect'), 2); } else { @@ -390,17 +472,13 @@ echo '
'; echo ''; echo ''; - $level_txt = ( $level == 0 ) ? 'disabled' : ( ( $level == 1 ) ? 'enabled' : 'use the global setting' ); - $blurb = ( $level == 0 || ( $level == 2 && getConfig('wiki_mode') != '1' ) ) ? 'Because this will disable the wiki behavior on this page, several features, most - notably the ability for users to vote to have this page deleted, will be disabled as they are not relevant to non-wiki pages. In addition, users will not be able - to edit this page unless an ACL rule specifically permits them.' : 'Because this will enable the wiki behavior on this page, users will gain the ability to - freely edit this page unless an ACL rule specifically denies them. If your site is public and gets good traffic, you should be aware of the possiblity of vandalism, and you need to be ready to revert - malicious edits to this page.'; + $level_txt = ( $level == 0 ) ? 'page_wikimode_level_off' : ( ( $level == 1 ) ? 'page_wikimode_level_on' : 'page_wikimode_level_global' ); + $blurb = ( $level == 0 || ( $level == 2 && getConfig('wiki_mode') != '1' ) ) ? 'page_wikimode_blurb_disable' : 'page_wikimode_blurb_enable'; ?> -

You are changing wiki mode for this page.

-

Wiki features will be set to .

-

If you want to continue, please click the button below.

-

+

get('page_wikimode_heading'); ?>

+

get($level_txt) . ' ' . $lang->get($blurb); ?>

+

get('page_wikimode_warning'); ?>

+

'; $template->footer(); @@ -419,16 +497,16 @@ case 'detag': if ( $session->user_level < USER_LEVEL_ADMIN ) { - die_friendly('Access denied', '

You need to be an administrator to detag pages.

'); + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('etc_access_denied') . '

'); } if ( $paths->page_exists ) { - die_friendly('Invalid request', '

The detag action is only valid for pages that have been deleted in the past.

'); + die_friendly($lang->get('etc_invalid_request_short'), '

' . $lang->get('page_detag_err_page_exists') . '

'); } $q = $db->sql_query('DELETE FROM '.table_prefix.'tags WHERE page_id=\'' . $db->escape($paths->page_id) . '\' AND namespace=\'' . $paths->namespace . '\';'); if ( !$q ) $db->_die('Detag query, index.php:'.__LINE__); - die_friendly('Page detagged', '

All stale tags have been removed from this page.

'); + die_friendly($lang->get('page_detag_success_title'), '

' . $lang->get('page_detag_success_body') . '

'); break; case 'aclmanager': $data = ( isset($_POST['data']) ) ? $_POST['data'] : Array('mode' => 'listgroups'); diff -r d823e49e2e4e -r c433348f3628 install.php --- a/install.php Fri Feb 22 12:46:51 2008 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1914 +0,0 @@ -The Enano installer has found a Enano installation in this directory. You MUST delete config.php if you want to re-install Enano.

If you wish to upgrade an older Enano installation to this version, please use the upgrade script.

'); - exit; -} - -function microtime_float() -{ - list($usec, $sec) = explode(" ", microtime()); - return ((float)$usec + (float)$sec); -} - -define('IN_ENANO_INSTALL', 'true'); - -define('ENANO_VERSION', '1.0.3'); -// In beta versions, define ENANO_BETA_VERSION here - -if(!defined('scriptPath')) { - $sp = dirname($_SERVER['REQUEST_URI']); - if($sp == '/' || $sp == '\\') $sp = ''; - define('scriptPath', $sp); -} - -if(!defined('contentPath')) { - $sp = dirname($_SERVER['REQUEST_URI']); - if($sp == '/' || $sp == '\\') $sp = ''; - define('contentPath', $sp); -} -global $_starttime, $this_page, $sideinfo; -$_starttime = microtime(true); - -global $db; - -// Determine directory (special case for development servers) -if ( strpos(__FILE__, '/repo/') && file_exists('.enanodev') ) -{ - $filename = str_replace('/repo/', '/', __FILE__); -} -else -{ - $filename = __FILE__; -} - -define('ENANO_ROOT', dirname($filename)); - -function is_page($p) -{ - return true; -} - -require('includes/wikiformat.php'); -require('includes/constants.php'); -require('includes/rijndael.php'); -require('includes/functions.php'); -require('includes/dbal.php'); - -strip_magic_quotes_gpc(); -$neutral_color = 'C'; - -// -// INSTALLER LIBRARY -// - -function run_installer_stage($stage_id, $stage_name, $function, $failure_explanation, $allow_skip = true) -{ - static $resumed = false; - static $resume_stack = array(); - - if ( empty($resume_stack) && isset($_POST['resume_stack']) && preg_match('/[a-z_]+((\|[a-z_]+)+)/', $_POST['resume_stack']) ) - { - $resume_stack = explode('|', $_POST['resume_stack']); - } - - $already_run = false; - if ( in_array($stage_id, $resume_stack) ) - { - $already_run = true; - } - - if ( !$resumed ) - { - if ( !isset($_GET['stage']) ) - $resumed = true; - if ( isset($_GET['stage']) && $_GET['stage'] == $stage_id ) - { - $resumed = true; - } - } - if ( !$resumed && $allow_skip ) - { - echo_stage_success($stage_id, $stage_name); - return false; - } - if ( !function_exists($function) ) - die('libenanoinstall: CRITICAL: function "' . $function . '" for ' . $stage_id . ' doesn\'t exist'); - $result = @call_user_func($function, false, $already_run); - if ( $result ) - { - echo_stage_success($stage_id, $stage_name); - $resume_stack[] = $stage_id; - return true; - } - else - { - echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack); - return false; - } -} - -function start_install_table() -{ - echo '' . "\n"; - ob_start(); -} - -function close_install_table() -{ - echo '
' . "\n\n"; - ob_end_flush(); -} - -function echo_stage_success($stage_id, $stage_name) -{ - global $neutral_color; - $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A'; - echo '
' . htmlspecialchars($stage_name) . 'Done
' . htmlspecialchars($stage_name) . 'Failed
$descTest passed
$desc
$extended_desc
Test passed with warning
$desc
$extended_desc
Test failed
- - - -

Before clicking continue:
• Ensure that you agree with the terms of the license
• Have your database host, name, username, and password available

- -
- -

Checking your server

-

Enano has several requirements that must be met before it can be installed. If all is good then note any warnings and click Continue below.

- - =4.3.0', 'It seems that the version of PHP that your server is running is too old to support Enano properly. If this is your server, please upgrade to the most recent version of PHP, remembering to use the --with-mysql configure option if you compile it yourself. If this is not your server, please contact your webhost and ask them if it would be possible to upgrade PHP. If this is not possible, you will need to switch to a different webhost in order to use Enano.'); - run_test('return version_compare(\'5.2.0\', PHP_VERSION, \'<\');', 'PHP 5.2.0 or later', 'Your server does not have support for PHP 5.2.0. While you may continue installing Enano, please be warned that as of December 31, 2007, all support for Enano on PHP 4 servers is discontinued. If you have at least PHP 5.0.0, support will still be available, but there are many security problems in PHP versions under 5.2.0 that Enano cannot effectively prevent.', true); - run_test('return function_exists(\'mysql_connect\');', 'MySQL extension for PHP', 'It seems that your PHP installation does not have the MySQL extension enabled. The MySQL database driver will be unavailable. In many cases this is OK if you have another supported database type available. If this is your own server, you may need to just enable the "libmysql.so" extension in php.ini. If you do not have the MySQL extension installed, you will need to either use your distribution\'s package manager to install it, or you will have to compile PHP from source. If you compile PHP from source, please remember to use the "--with-mysql" configure option, and you will have to have the MySQL development files installed (they usually are). If this is not your server, please contact your hosting company and ask them to install the PHP MySQL extension.', true); - run_test('return function_exists(\'pg_connect\');', 'PostgreSQL extension for PHP', 'It seems that your PHP installation does not have the PostgreSQL extension enabled. Because of this, you won\'t be able to use the PostgreSQL database driver. This is OK in the majority of cases. If you want to use PostgreSQL support, you\'ll need to either compile the PHP extension for Postgres or install the extension with your distribution\'s package manager. Windows administrators will need enable php_pgsql.dll in their php.ini.', true); - run_test('return @ini_get(\'file_uploads\');', 'File upload support', 'It seems that your server does not support uploading files. Enano *requires* this functionality in order to work properly. Please ask your server administrator to set the "file_uploads" option in php.ini to "On".'); - run_test('return is_apache();', 'Apache HTTP Server', 'Apparently your server is running a web server other than Apache. Enano will work nontheless, but there are some known bugs with non-Apache servers, and the "fancy" URLs will not work properly. The "Standard URLs" option will be set on the website configuration page, only change it if you are absolutely certain that your server is running Apache.', true); - //run_test('return function_exists(\'finfo_file\');', 'Fileinfo PECL extension', 'The MIME magic PHP extension is used to determine the type of a file by looking for a certain "magic" string of characters inside it. This functionality is used by Enano to more effectively prevent malicious file uploads. The MIME magic option will be disabled by default.', true); - run_test('return is_writable(ENANO_ROOT.\'/config.new.php\');', 'Configuration file writable', 'It looks like the configuration file, config.new.php, is not writable. Enano needs to be able to write to this file in order to install.

If you are installing Enano on a SourceForge web site:
SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.'); - run_test('return file_exists(\'/usr/bin/convert\');', 'ImageMagick support', 'Enano uses ImageMagick to scale images into thumbnails. Because ImageMagick was not found on your server, Enano will use the width= and height= attributes on the <img> tag to scale images. This can cause somewhat of a performance increase, but bandwidth usage will be higher, especially if you use high-resolution images on your site.

If you are sure that you have ImageMagick, you can set the location of the "convert" program using the administration panel after installation is complete.', true); - run_test('return is_writable(ENANO_ROOT.\'/cache/\');', 'Cache directory writable', 'Apparently the cache/ directory is not writable. Enano will still work, but you will not be able to cache thumbnails, meaning the server will need to re-render them each time they are requested. In some cases, this can cause a significant slowdown.', true); - run_test('return is_writable(ENANO_ROOT.\'/files/\');', 'File uploads directory writable', 'It seems that the directory where uploaded files are stored (' . ENANO_ROOT . '/files) cannot be written by the server. Enano will still function, but file uploads will not function, and will be disabled by default.', true); - if ( !function_exists('mysql_connect') && !function_exists('pg_connect') ) - { - run_test('return false;', 'No database drivers are available.', 'You need to have at least one database driver working to install Enano. See the warnings on MySQL and PostgreSQL above for more information on installing these database drivers.', false); - } - echo '
'; - if(!$failed) - { - ?> - -
'; - } else { - echo ''; - run_test('return true;', 'Your server meets all the requirements for running Enano.
Click the button below to continue the installation.', 'You should never see this text. Congratulations for being an Enano hacker!'); - echo '
'; - } - ?> -
- - - - -

Before clicking continue:
• Ensure that you are satisfied with any scalebacks that may have been made to accomodate your server configuration
• Have your database host, name, username, and password available

-
- - '; - run_test('return false;', 'Your server does not meet the requirements for Enano to run.', 'As a precaution, Enano will not install until the above requirements have been met. Contact your server administrator or hosting company and convince them to upgrade. Good luck.'); - echo '
'; - } - } - ?> - - -

Now we need some information that will allow Enano to contact your database server. Enano uses MySQL as a data storage backend, - and we need to have access to a MySQL server in order to continue.

-

If you do not have access to a MySQL server, and you are using your own server, you can download MySQL for free from - MySQL.com. Please note that, like Enano, MySQL is licensed under the GNU GPL. - If you need to modify MySQL and then distribute your modifications, you must either distribute them under the terms of the GPL - or purchase a proprietary license.

- MySQL login information for this virtual appliance:

Database hostname: localhost
Database login: username "enano", password: "clurichaun" (without quotes)
Database name: enano_www1

'; - } - ?> -
- - - - - - - - - - - - - -

Database information

Database hostname
This is the hostname (or sometimes the IP address) of your MySQL server. In many cases, this is "localhost".
Good/bad icon
Database name
The name of the actual database. If you don't already have a database, you can create one here, if you have the username and password of a MySQL user with administrative rights.
Good/bad icon
Database login
These fields should be the username and password of a user with "select", "insert", "update", "delete", "create table", and "replace" privileges for your database.
Good/bad icon

Optional information

Table prefix
The value that you enter here will be added to the beginning of the name of each Enano table. You may use lowercase letters (a-z), numbers (0-9), and underscores (_).
Good/bad icon
Database administrative login
If the MySQL database or username that you entered above does not exist yet, you can create them here, assuming that you have the login information for an administrative user (such as root). Leave these fields blank unless you need to use them.
Good/bad icon
MySQL versionMySQL version information will be checked when you click "Test Connection".Good/bad icon
Delete existing tables?
If this option is checked, all the tables that will be used by Enano will be dropped (deleted) before the schema is executed. Do NOT use this option unless specifically instructed to.
- -
- restart the installation.'; - $template->footer(); - exit; - } - unset($_POST['_cont']); - ?> - -
- '."\n"; - } - ?> -

The next step is to enter some information about your website. You can always change this information later, using the administration panel.

- - - - - - -
Website name
The display name of your website. Allowed characters are uppercase and lowercase letters, numerals, and spaces. This must not be blank or "Enano".
Good/bad icon
Website description
This text will be shown below the name of your website.
Good/bad icon
Copyright info
This should be a one-line legal notice that will appear at the bottom of all your pages.
Good/bad icon
Wiki mode
This feature allows people to create and edit pages on your site. Enano keeps a history of all page modifications, and you can protect pages to prevent editing.
URL scheme
Choose how the page URLs will look. Depending on your server configuration, you may need to select the first option. If you don't know, select the first option, and you can always change it later.
name="urlscheme" value="ugly" id="ugly">
name="urlscheme" value="short" id="short">

Which URL scheme should I choose?
- -
- restart the installation.'; - $template->footer(); - exit; - } - unset($_POST['_cont']); - require('config.new.php'); - $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); - if ( isset($crypto_key) ) - { - $cryptkey = $crypto_key; - } - if(!isset($cryptkey) || ( isset($cryptkey) && strlen($cryptkey) != AES_BITS / 4) ) - { - $cryptkey = $aes->gen_readymade_key(); - $handle = @fopen(ENANO_ROOT.'/config.new.php', 'w'); - if(!$handle) - { - echo '

ERROR: Cannot open config.php for writing - exiting!

'; - $template->footer(); - exit; - } - fwrite($handle, ''); - fclose($handle); - } - // Sorry for the ugly hack, but this f***s up jEdit badly. - echo ' - - '; - ?> -
- '."\n"; - } - ?> -

Next, enter your desired username and password. The account you create here will be used to administer your site.

- - - - - - - - - - - -
Administration username
The administration username you will use to log into your site.
This cannot be "anonymous" or in the form of an IP address.
Good/bad icon
Administration password:Good/bad icon
Enter it again to confirm:
Your e-mail address:Good/bad icon
- Allow administrators to embed PHP code into pages:
- Do not under any circumstances enable this option without reading these - important security implications. - -
-    - -
If your browser supports Javascript, the password you enter here will be encrypted with AES before it is sent to the server.
- -
- - - -
- - restart the installation.'; - $template->footer(); - exit; - } - unset($_POST['_cont']); - ?> -
- '."\n"; - } - ?> -

Enano is ready to install.

-

The wizard has finished collecting information and is ready to install the database schema. Please review the information below, - and then click the button below to install the database.

-
    -
  • Database hostname:
  • -
  • Database name:
  • -
  • Database user:
  • -
  • Database password: <hidden>
  • -
  • Site name:
  • -
  • Site description:
  • -
  • Administration username:
  • -
  • Cipher strength: -bit AES
    Cipher strength is defined in the file constants.php; if you desire to change the cipher strength, you may do so and then restart installation. Unless your site is mission-critical, changing the cipher strength is not necessary.
  • -
- -
- restart the installation.'; - $template->footer(); - exit; - } - switch($_POST['urlscheme']) - { - case "ugly": - default: - $cp = scriptPath.'/index.php?title='; - break; - case "short": - $cp = scriptPath.'/index.php/'; - break; - case "tiny": - $cp = scriptPath.'/'; - break; - } - function err($t) { global $template; echo $t; $template->footer(); exit; } - - // $stages = array('connect', 'decrypt', 'genkey', 'parse', 'sql', 'writeconfig', 'renameconfig', 'startapi', 'initlogs'); - - if ( !preg_match('/^[a-z0-9_]*$/', $_POST['table_prefix']) ) - err('Hacking attempt was detected in table_prefix.'); - - start_install_table(); - - // Are we just trying to auto-rename the config files? If so, skip everything else - if ( !isset($_GET['stage']) || ( isset($_GET['stage']) && $_GET['stage'] != 'renameconfig' ) ) - { - - // The stages connect, decrypt, genkey, and parse are preprocessing and don't do any actual data modification. - // Thus, they need to be run on each retry, e.g. never skipped. - run_installer_stage('connect', 'Connect to MySQL', 'stg_mysql_connect', 'MySQL denied our attempt to connect to the database. This is most likely because your login information was incorrect. You will most likely need to restart the installation.', false); - if ( isset($_POST['drop_tables']) ) - { - // Are we supposed to drop any existing tables? If so, do it now - run_installer_stage('drop', 'Drop existing Enano tables', 'stg_drop_tables', 'This step never returns failure'); - } - run_installer_stage('decrypt', 'Decrypt administration password', 'stg_decrypt_admin_pass', 'The administration password you entered couldn\'t be decrypted. It is possible that your server did not properly store the encryption key in the configuration file. Please check the file permissions on config.new.php. You may have to return to the login stage of the installation, clear your browser cache, and then rerun this installation.', false); - run_installer_stage('genkey', 'Generate ' . AES_BITS . '-bit AES private key', 'stg_generate_aes_key', 'Enano encountered an internal error while generating the site encryption key. Please contact the Enano team for support.', false); - run_installer_stage('parse', 'Prepare to execute schema file', 'stg_parse_schema', 'Enano encountered an internal error while parsing the SQL file that contains the database structure and initial data. Please contact the Enano team for support.', false); - run_installer_stage('sql', 'Execute installer schema', 'stg_install', 'The installation failed because an SQL query wasn\'t quite correct. It is possible that you entered malformed data into a form field, or there may be a bug in Enano with your version of MySQL. Please contact the Enano team for support.', false); - run_installer_stage('writeconfig', 'Write configuration files', 'stg_write_config', 'Enano was unable to write the configuration file with your site\'s database credentials. This is almost always because your configuration file does not have the correct permissions. On Windows servers, you may see this message even if the check on the System Requirements page passed. Temporarily running IIS as the Administrator user may help.'); - - // Mainstream installation complete - Enano should be usable now - // The stage of starting the API is special because it has to be called out of function context. - // To alleviate this, we have two functions, one that returns success and one that returns failure - // If the Enano API load is successful, the success function is called to report the action to the user - // If unsuccessful, the failure report is sent - - $template_bak = $template; - - $_GET['title'] = 'Main_Page'; - require('includes/common.php'); - - if ( is_object($db) && is_object($session) ) - { - run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_success', '...', false); - } - else - { - run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_failure', 'The Enano API could not be started. This is an error that should never occur; please contact the Enano team for support.', false); - } - - // We need to be logged in (with admin rights) before logs can be flushed - $admin_password = stg_decrypt_admin_pass(true); - $session->login_without_crypto($_POST['admin_user'], $admin_password, false); - - // Now that login cookies are set, initialize the session manager and ACLs - $session->start(); - $paths->init(); - - run_installer_stage('initlogs', 'Initialize logs', 'stg_init_logs', 'The session manager denied the request to flush logs for the main page.
- While under most circumstances you can still finish the installation after renaming your configuration files, you should be aware that some servers cannot - properly set cookies due to limitations with PHP. These limitations are exposed primarily when this issue is encountered during installation. If you choose - to finish the installation, please be aware that you may be unable to log into your site.'); - - run_installer_stage('buildindex', 'Initialize search index', 'stg_build_index', 'Something went wrong while the page manager was attempting to build a search index.'); - - /* - * HACKERS: - * If you're making a custom distribution of Enano, put all your custom plugin-related code here. - * You have access to the full Enano API as well as being logged in with complete admin rights. - * Don't do anything horrendously fancy here, unless you add a new stage (or more than one) and - * have the progress printed out properly. - */ - - } // check for stage == renameconfig - else - { - // If we did skip the main installer routine, set $template_bak to make the reversal later work properly - $template_bak = $template; - } - - // Final step is to rename the config file - // In early revisions of 1.0.2, this step was performed prior to the initialization of the Enano API. It was decided to move - // this stage to the end because it will fail more often than any other stage, thus making alternate routes imperative. If this - // stage fails, then no big deal, we'll just have the user rename the files manually and then let them see the pretty success message. - run_installer_stage('renameconfig', 'Rename configuration files', 'stg_rename_config', 'Enano couldn\'t rename the configuration files to their correct production names. Please CHMOD the folder where your Enano files are to 777 and click the retry button below, or perform the following rename operations and then finish the installation.
  • Rename config.new.php to config.php
  • Rename .htaccess.new to .htaccess (only if you selected Tiny URLs)
'); - - close_install_table(); - - unset($template); - $template =& $template_bak; - - echo '

Installation of Enano is complete.

Review any warnings above, and then click here to finish the installation.'; - - // echo ''; - - break; - case "finish": - echo '

Congratulations!

-

You have finished installing Enano on this server.

-

Now what?

-

Click the link below to see the main page for your website. Where to go from here:

-
    -
  • The first thing you should do is log into your site using the Log in link on the sidebar.
  • -
  • Go into the Administration panel, expand General, and click General Configuration. There you will be able to configure some basic information about your site.
  • -
  • Visit the Enano Plugin Gallery to download and use plugins on your site.
  • -
  • Periodically create a backup of your database and filesystem, in case something goes wrong. This should be done at least once a week – more for wiki-based sites.
  • -
  • Hire some moderators, to help you keep rowdy users tame.
  • -
  • Tell the Enano team what you think.
  • -
  • Spread the word about Enano by adding a link to the Enano homepage on your sidebar! You can enable this option in the General Configuration section of the administration panel.
  • -
-

Go to your website...

'; - break; - // this stage is never shown during the installation, but is provided for legal purposes - case "showlicense": - show_license(true); - break; -} -$template->footer(); - -?> diff -r d823e49e2e4e -r c433348f3628 install/.htaccess --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/.htaccess Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,8 @@ +# Used for testing mod_rewrite. + +RewriteEngine on + +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule (.*) install.php?do=modrewrite_test&str=$1 + diff -r d823e49e2e4e -r c433348f3628 install/images/balancer.png Binary file install/images/balancer.png has changed diff -r d823e49e2e4e -r c433348f3628 install/images/css/installer.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/images/css/installer.css Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,231 @@ +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 + * Copyright (C) 2006-2007 Dan Fuhry + * Installation package + * installer.css - visual styling rules for the installer + * + * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + * + * 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 details. + */ + +body { + font-family: DejaVu Sans, Arial, Helvetica, sans-serif; + font-size: 9pt; + margin: 0; + padding: 0; +} + +div#header { + margin: 0px auto; + width: 800px; + padding: 10px 0; +} + +div#step { + float: right; + font-size: 12pt; + color: #D84308; + line-height: 48px; + background-image: url(../icons/install.png); + background-position: right center; + background-repeat: no-repeat; + padding-right: 56px; + margin: 10px 0 0 0; +} + +div.stages-holder { + color: #ffffff; + background-color: #2f527a; + width: 100%; +} + +ul.stages { + margin: 0; + line-height: 24px; + font-size: 8pt; + padding: 0; +} +ul.stages-fixed { + /* + width: 840px; + */ + display: table; + margin: 0 auto; +} +li.stage { + list-style-type: none; + float: left; + text-align: center; + padding: 3px 20px 3px 20px; +} +li.stage-active { + font-weight: bold; + padding: 1px 20px 5px 20px; + background-image: url(../marker.gif); + background-position: center bottom; + background-repeat: no-repeat; + background-color: #5f82aa; +} +div#enano-fill { + background-image: url(../substages.png); + background-repeat: repeat-x; +} +div#enano-body { + width: 780px; + padding: 10px; + margin: 0 auto; +} +div#enano-body a { + color: #003366; + text-decoration: underline; +} +div#enano-body a:hover { + color: #0055AA; +} +div#copyright { + border-top: 1px dotted #003399; + font-size: 6pt; + padding: 10px; + background-image: url(../substages.png); + background-repeat: repeat-x; + width: 77%; + margin: 20px auto 0 auto; + text-align: center; + color: #808080; +} +td.balancer { + width: 21px; + background-image: url(../balancer.png); + background-position: center center; + background-repeat: no-repeat; +} +ul.icons { + margin: 0; + padding: 0; + list-style-type: none; + display: table; +} +ul.icons li:first-child { + border-top-color: #FFFFFF; +} +ul.icons li { + /* Invisible border to prevent size-switching later */ + border: 1px solid #FFFFFF; + border-top-color: #F0F0F0; + margin: 0 0 -2px 0; + padding: 0; + display: block; +} +ul.icons li:hover { + border-color: #D0D0D0; + -moz-border-radius: 5px; +} +a.icon { + display: block; + font-size: 18pt; + line-height: 48px; + padding: 10px 20px 10px 68px; + background-position: 10px center; + background-repeat: no-repeat; + color: #002266; + text-decoration: none !important; +} +a.icon:hover { + cursor: pointer; + color: #002266 !important; + background-color: #F0F0F0; +} +a.icon-disabled { + color: #808080 !important; + opacity: 0.7; + filter: alpha(opacity=70); +} +a.icon-disabled:hover { + color: #808080 !important; + background-color: #FCFCFC; + border-color: #F8F8F8; +} +a.icon small, a.icon-disabled small { + display: block; + font-size: 8pt; + line-height: normal; + margin-top: -10px; +} +a.readme { + background-image: url(../icons/readme.png); +} +a.install { + background-image: url(../icons/install.png); +} +a.install-disabled { + background-image: url(../icons/install-disabled.png); +} +a.upgrade { + background-image: url(../icons/upgrade.png); +} +a.upgrade-disabled { + background-image: url(../icons/upgrade-disabled.png); +} + +.scroller { + padding: 10px; + border: 1px dotted #002266; + background-color: #F0F0F0; + max-height: 500px; + clip: rect(0px, auto, auto, 0px); + overflow: auto; +} + +div#installnotice { + margin: 5% 0 0 0; +} + +table#installmenu { + margin: 0 auto 5% auto; +} +span.fieldtip_js { + display: block; + background-color: #F0F0FF; + padding: 10px; + border: 1px solid #245687; + position: absolute; +} + +/* Inputs, form controls */ + +input[type ^="button"], button { + background-color: #F8F8FB; + color: #202020; + border-color: #B0B0B8 #D0D0D8 #D0D0D8 #B0B0B8; + border-width: 1px; + border-style: solid; +} +input[type ^="submit"] { + background-color: #4F729A; + color: #FFFFFF; + border-width: 1px; + border-style: solid; + border-color: #1F426A #7FA2CA #7FA2CA #1F426A; +} +input[type ^="submit"]:hover, input[type ^="submit"]:focus { + background-color: #5f82aa; +} +input[type ^="text"], input[type ^="password"] { + color: #202020; + background-color: #F0F0F4; + border: 1px solid #D6D6E9; +} +input[type ^="text"]:hover, input[type ^="password"]:hover { + color: #202020; + background-color: #F4F4F8; + border: 1px solid #D6D6E9; +} +input[type ^="text"]:focus, input[type ^="password"]:focus { + color: #202020; + background-color: #FFFFFF; + border: 1px solid #D6D6E9; +} diff -r d823e49e2e4e -r c433348f3628 install/images/enano-artwork/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/images/enano-artwork/README Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,8 @@ +The images in this directory are copyright (C) 2007 Dan Fuhry. Except +as permitted by applicable law, they may not be used in any way other +than to promote the unmodified Enano CMS. You also may not modify and +then distribute the images in this directory, or distribute them sep- +arately from the Enano packages. The goal here is to establish a uni- +que identity for Enano through the use of a logo, and that identity +would be confused if this logo is used for unofficial Enano distros. + diff -r d823e49e2e4e -r c433348f3628 install/images/enano-artwork/installer-greeting.png Binary file install/images/enano-artwork/installer-greeting.png has changed diff -r d823e49e2e4e -r c433348f3628 install/images/enano-artwork/installer-header-blue.png Binary file install/images/enano-artwork/installer-header-blue.png has changed diff -r d823e49e2e4e -r c433348f3628 install/images/icons/install-disabled.png Binary file install/images/icons/install-disabled.png has changed diff -r d823e49e2e4e -r c433348f3628 install/images/icons/install.png Binary file install/images/icons/install.png has changed diff -r d823e49e2e4e -r c433348f3628 install/images/icons/readme.png Binary file install/images/icons/readme.png has changed diff -r d823e49e2e4e -r c433348f3628 install/images/icons/src/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/images/icons/src/README Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,3 @@ +These icons are from the Flygo icon set, which is based on icons from the Tango +Desktop Project. They are released under the GNU General Public License. + diff -r d823e49e2e4e -r c433348f3628 install/images/icons/src/accessories-text-editor.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/images/icons/src/accessories-text-editor.svg Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,916 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Lapo Calamandrei + + + + Text editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r d823e49e2e4e -r c433348f3628 install/images/icons/src/system-installer.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/images/icons/src/system-installer.svg Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,495 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + System - Installer + + + jakub Steiner + + + http://jimmac.musichall.cz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r d823e49e2e4e -r c433348f3628 install/images/icons/src/system-software-update.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/images/icons/src/system-software-update.svg Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,1378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Software Update + + + Jakub Steiner + + + + + + + + + http://jimmac.musichall.cz + + + network update + software + synchronize + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r d823e49e2e4e -r c433348f3628 install/images/icons/upgrade-disabled.png Binary file install/images/icons/upgrade-disabled.png has changed diff -r d823e49e2e4e -r c433348f3628 install/images/icons/upgrade.png Binary file install/images/icons/upgrade.png has changed diff -r d823e49e2e4e -r c433348f3628 install/images/marker.gif Binary file install/images/marker.gif has changed diff -r d823e49e2e4e -r c433348f3628 install/images/substages.png Binary file install/images/substages.png has changed diff -r d823e49e2e4e -r c433348f3628 install/includes/common.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/common.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,157 @@ + '1.1.3', + 'type' => 'alpha' + // If type is set to "rc", "beta", or "alpha", optionally another version number can be issued with the key 'sub': + // 'sub' => '3' will produce Enano 1.1.1a3 / Enano 1.1.1 alpha 3 +); + +function installer_enano_version($long = false) +{ + global $installer_version; + static $keywords = array( + 'alpha' => 'a', + 'beta' => 'b', + 'RC' => 'rc' + ); + $v = $installer_version['version']; + if ( isset($installer_version['sub']) ) + { + $v .= ( $short ) ? $keywords[$installer_version['type']] : " {$installer_version['type']} "; + $v .= $installer_version['sub']; + } + return $v; +} + +// Determine Enano root directory + +if ( !defined('ENANO_ROOT') ) +{ + $enano_root = dirname(dirname(dirname(__FILE__))); + if ( preg_match('#/repo$#', $enano_root) && file_exists("$enano_root/../.enanodev") ) + { + $enano_root = preg_replace('#/repo$#', '', $enano_root); + } + + define('ENANO_ROOT', $enano_root); +} + +chdir(ENANO_ROOT); + +// Determine our scriptPath +if ( isset($_SERVER['REQUEST_URI']) && !defined('scriptPath') ) +{ + // Use reverse-matching to determine where the REQUEST_URI overlaps the Enano root. + $requri = $_SERVER['REQUEST_URI']; + if ( isset($_SERVER['PATH_INFO']) && !preg_match('/index\.php$/', $_SERVER['PATH_INFO']) ) + { + $requri = preg_replace(';' . preg_quote($_SERVER['PATH_INFO']) . '$;', '', $requri); + } + if ( !preg_match('/\.php$/', $requri) ) + { + // user requested http://foo/enano as opposed to http://foo/enano/index.php + $requri .= '/index.php'; + } + $sp = dirname($_SERVER['REQUEST_URI']); + if ( $sp == '/' || $sp == '\\' ) + { + $sp = ''; + } + $sp = preg_replace('#/install$#', '', $sp); + define('scriptPath', $sp); +} + +// is Enano already installed? +@include(ENANO_ROOT . '/config.php'); +if ( defined('ENANO_INSTALLED') && defined('ENANO_DANGEROUS') ) +{ + $title = 'Installation locked'; + require('includes/common.php'); + $template->header(); + echo '

The installer has detected that an installation of Enano already exists on your server. You MUST delete config.php if you wish to reinstall Enano.

'; + $template->footer(); + exit(); +} + +if ( !function_exists('microtime_float') ) +{ + function microtime_float() + { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } +} + +define('IN_ENANO_INSTALL', 1); + +require_once(ENANO_ROOT . '/install/includes/ui.php'); +require_once(ENANO_ROOT . '/includes/functions.php'); +require_once(ENANO_ROOT . '/includes/json.php'); +require_once(ENANO_ROOT . '/includes/constants.php'); +require_once(ENANO_ROOT . '/includes/rijndael.php'); + +// If we have at least PHP 5, load json2 +if ( version_compare(PHP_VERSION, '5.0.0', '>=') ) +{ + require_once(ENANO_ROOT . '/includes/json2.php'); +} + +strip_magic_quotes_gpc(); + +// Build a list of available languages +$dir = @opendir( ENANO_ROOT . '/language' ); +if ( !$dir ) + die('CRITICAL: could not open language directory'); + +$languages = array(); +// Use the old PHP4-compatible JSON decoder +$json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); + +while ( $dh = @readdir($dir) ) +{ + if ( $dh == '.' || $dh == '..' ) + continue; + if ( file_exists( ENANO_ROOT . "/language/$dh/meta.json" ) ) + { + // Found a language directory, determine metadata + $meta = @file_get_contents( ENANO_ROOT . "/language/$dh/meta.json" ); + if ( empty($meta) ) + // Could not read metadata file, continue silently + continue; + $meta = $json->decode($meta); + if ( isset($meta['lang_name_english']) && isset($meta['lang_name_native']) && isset($meta['lang_code']) ) + { + $languages[$meta['lang_code']] = array( + 'name' => $meta['lang_name_native'], + 'name_eng' => $meta['lang_name_english'], + 'dir' => $dh + ); + } + } +} + +if ( count($languages) < 1 ) +{ + die('CRITICAL: No languages are available'); +} + +// List of available DB drivers +$supported_drivers = array('mysql', 'postgresql'); + +?> diff -r d823e49e2e4e -r c433348f3628 install/includes/js/formutils.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/js/formutils.js Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,169 @@ +/** + * Images used for form field validation + * @var string img_bad: Shown on field validation failure + * @var string img_good: Shown on field validation success + * @var string img_neu: Shown when a field's value matches known good regexp but still needs testing (e.g. DB info) + */ + +var img_bad = '../images/checkbad.png'; +var img_good = '../images/check.png'; +var img_neu = '../images/checkunk.png'; + +/** + * Highlights the background of the next-up
' . "\n\n"; + flush(); +} + +function echo_stage_success($stage_id, $stage_name) +{ + global $neutral_color; + $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A'; + echo '
' . htmlspecialchars($stage_name) . 'Done
' . htmlspecialchars($stage_name) . 'Failed
+ + + > + get('database_driver_mysql'); ?>
+ get('database_driver_mysql_intro'); ?> +
$mysql_disable_reason"; + } + ?> + +
+ + + > + get('database_driver_pgsql'); ?>
+ get('database_driver_pgsql_intro'); ?> +
$pgsql_disable_reason"; + } + ?> + +
+
+ + /> + + + +
+ + /> + + + +
+ + + + '; +} + +echo ''; diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/database_mysql.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/database_mysql.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,512 @@ + false, + 'host_good' => true, + 'creating_user' => false, + 'db_exist' => false, + 'creating_db' => false, + 'creating_db_grant' => false, + 'root_fail' => false, + 'version' => array( + 'version' => 'unknown', + 'good' => 'indeterminate' + ), + 'last_error' => '' + ); + + if ( !isset($_POST['info']) ) + die(); + + $info = $_POST['info']; + + // From here on out will be JSON responses + header('Content-type: application/json'); + + try + { + $info = @enano_json_decode($info); + } + catch ( Zend_Json_Exception $e ) + { + die(enano_json_encode(array( + 'mode' => 'error', + 'error' => 'Exception in JSON decoder' + ))); + } + + // Try to connect as the normal user + $test = @mysql_connect($info['db_host'], $info['db_user'], $info['db_pass']); + if ( !$test ) + { + $return['creating_user'] = true; + $return['last_error'] = mysql_error(); + if ( strstr( $return['last_error'], 'Lost connection' ) || strstr( $return['last_error'], 'Unknown MySQL server host' ) ) + { + $return['host_good'] = false; + } + // Doing that failed. If we have root credentials, test those + if ( !empty($info['db_root_user']) && !empty($info['db_root_pass']) ) + { + // Log in with root rights and if that works, tell 'em we'll reset the password or create + // the account if it doesn't exist already. This is done with GRANT ALL PRIVILEGES ON enano_db.* + // etc etc, a little hackish but known to work with MySQL >= 4.1. + $test_root = @mysql_connect($info['db_host'], $info['db_root_user'], $info['db_root_pass']); + if ( $test_root ) + { + // We logged in with root rights, assume that we have appropriate permissions. + // If not, well, the installation will fail. Tough on the user, but creating + // test databases/users is too risky. + + // Does the database exist? + $q = @mysql_query('USE `' . mysql_real_escape_string($info['db_name']) . '`;', $test_root); + if ( !$q ) + { + // Nope, we'll have to create it + $return['creating_db'] = true; + $return['last_error'] = mysql_error(); + } + + $version = mysql_get_server_info($test_root); + $return['version'] = array( + 'version' => $version, + 'good' => version_compare($version, '4.0.17', '>=') + ); + + $return['can_install'] = ( $return['version']['good'] ) ? true : false; + } + else + { + // Well that helped. Root credentials are bad. + $return['creating_db'] = true; + $return['root_fail'] = true; + } + } + else + { + // No root credentials, fail out + $return['root_fail'] = true; + } + } + else + { + // We're connected; do we have permission to use the database? + $have_database = false; + $q = @mysql_query('USE `' . mysql_real_escape_string($info['db_name']) . '`;', $test); + if ( $q ) + { + // Permissions are good and we're all connected. Perform version check... + $version = mysql_get_server_info($test); + $return['version'] = array( + 'version' => $version, + 'good' => version_compare($version, '4.0.17', '>=') + ); + + $return['can_install'] = ( $return['version']['good'] ) ? true : false; + } + else + { + $return['last_error'] = mysql_error(); + $return['creating_db'] = true; + + // We don't have permission to use the database or it doesn't exist. + // See if we have a root login to work with, if not then fail + if ( !empty($info['db_root_user']) && !empty($info['db_root_pass']) ) + { + // Log in with root rights and if that works, tell 'em we'll create the database. + $test_root = @mysql_connect($info['db_host'], $info['db_root_user'], $info['db_root_pass']); + if ( $test_root ) + { + // We logged in with root rights, assume that we have appropriate permissions. + // If not, well, the installation will fail. Tough on the user, but creating + // test databases/users is too risky. + + // See if the database already exists + $dbname = mysql_real_escape_string($info['db_name']); + $q = @mysql_query("SHOW DATABASES LIKE '$dbname';", $test_root); + if ( $q ) + { + if ( mysql_num_rows($q) > 0 ) + { + $return['creating_db'] = false; + $return['creating_db_grant'] = true; + } + @mysql_free_result($q); + } + + $version = mysql_get_server_info($test); + $return['version'] = array( + 'version' => $version, + 'good' => version_compare($version, '4.0.17', '>=') + ); + + $return['can_install'] = ( $return['version']['good'] ) ? true : false; + } + else + { + // Well that helped. Root credentials are bad. + $return['creating_db'] = true; + $return['root_fail'] = true; + } + } + // No root credentials, fail out + } + } + + if ( isset($test) && @is_resource($test) ) + @mysql_close($test); + + if ( isset($test_root) && @is_resource($test_root) ) + @mysql_close($test_root); + + echo enano_json_encode($return); + + exit(); +} + +$ui->add_header(''); +$ui->show_header(); + +?> + +
+ MySQL logo +
+ +

get('dbmysql_blurb_needdb'); ?>

+

get('dbmysql_blurb_howtomysql'); ?>

+ + ' . $lang->get('database_vm_login_info', array( 'host' => 'localhost', 'user' => 'enano', 'pass' => 'clurichaun', 'name' => 'enano_www1' )) . ' +

'; +} +?> + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

get('dbmysql_table_title'); ?>

+
+ get('dbmysql_field_hostname_title'); ?> +
get('dbmysql_field_hostname_body'); ?> +
+
+ + + Good/bad icon +
+ get('dbmysql_field_dbname_title'); ?>
+ get('dbmysql_field_dbname_body'); ?>
+ +
+ + + Good/bad icon +
+ get('dbmysql_field_dbauth_title'); ?>
+ get('dbmysql_field_dbauth_body'); ?>
+ +
+
+
+ +
+ Good/bad icon +
+

get('database_heading_optionalinfo'); ?>

+
+ get('dbmysql_field_tableprefix_title'); ?>
+ get('dbmysql_field_tableprefix_body'); ?> +
+ + + Good/bad icon +
+ get('dbmysql_field_rootauth_title'); ?>
+ get('dbmysql_field_rootauth_body'); ?>
+ +
+
+
+ +
+ Good/bad icon +
+ get('dbmysql_field_mysqlversion_title'); ?> + + get('dbmysql_field_mysqlversion_blurb_willbechecked'); ?> + + Good/bad icon +
+ get('dbmysql_field_droptables_title'); ?>
+ get('dbmysql_field_droptables_body'); ?> +
+ +
+ +
+
+ + + + + + +
+ + +

+ get('meta_lbl_before_continue'); ?>
+ • get('database_objective_test'); ?>
+ • get('database_objective_uncrypt'); ?> +

+
+ +
+ + + diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/database_post.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/database_post.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,222 @@ +show_header(); + echo '

That table prefix isn\'t going to work.

'; + return true; +} + +$result = $dbal->connect(true, $db_host, $db_user, $db_pass, $db_name); + +// If connection failed, we have the root login, AND we're on MySQL, try to force our way in +if ( !$result && !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) && $driver == 'mysql' ) +{ + // Allow a jump / breakout + switch ( 'foo' ) { case 'foo': + + // Try to connect to the DB as root + $result_root = $dbal->connect(true, $db_host, $db_root_user, $db_root_pass, 'mysql'); + if ( !$result_root ) + break; + + $q = $dbal->sql_query('CREATE DATABASE IF NOT EXISTS `' . $dbal->escape($db_name) . '`;'); + if ( !$q ) + break; + + if ( $db_host == 'localhost' || $db_host == '127.0.0.1' ) + { + $q = $dbal->sql_query('GRANT ALL PRIVILEGES ON `' . $dbal->escape($db_name) . '`.* TO \'' . $dbal->escape($db_user) . '\'@\'localhost\'' . "\n" . + ' IDENTIFIED BY \'' . $dbal->escape($db_pass) . '\' WITH GRANT OPTION'); + } + else + { + $q = $dbal->sql_query('GRANT ALL PRIVILEGES ON `' . $dbal->escape($db_name) . '`.* TO \'' . $dbal->escape($db_user) . '\'@\'%\'' . "\n" . + ' IDENTIFIED BY \'' . $dbal->escape($db_pass) . '\' WITH GRANT OPTION'); + } + + if ( !$q ) + break; + + $dbal->close(); + $result = $dbal->connect(true, $db_host, $db_user, $db_pass, $db_name); + + break; + } +} + +$ui->show_header(); + +if ( $result ) +{ + // We're good, do table drop if requested + if ( isset($_POST['drop_tables']) ) + { + global $system_table_list; + foreach ( $system_table_list as $table ) + { + $dbal->sql_query("DROP TABLE {$db_prefix}$table"); + } + } + // Write out a config file + $ch = @fopen( ENANO_ROOT . '/config.new.php', 'w' ); + if ( !$ch ) + { + ?> +
+

Configuration file generation failed.

+

Couldn't open the configuration file to write out database settings. Check your file permissions.

+

+ +

+
+ That table prefix isn\'t going to work.

'; + return true; + } + fwrite($ch, " +

Can't load schema file

+

The SQL schema file couldn't be loaded.

+ $e"; ?> + sql_query('SELECT config_name, config_value FROM ' . $db_prefix . 'config LIMIT 1;'); + if ( !$q ) + { + $sql_parser->assign_vars(array( + 'TABLE_PREFIX' => $db_prefix + )); + $sql = $sql_parser->parse(); + foreach ( $sql as $q ) + { + if ( !$dbal->sql_query($q) ) + { + ?> +
+ + +

get('database_msg_sql_fail_title'); ?>

+

get('database_msg_sql_fail_body'); ?>

+

get('database_msg_post_fail_desc'); ?> + sql_error(); + ?> +

+

+ +

+
+ free_result(); + if ( !$dbal->sql_query('DELETE FROM ' . $db_prefix . 'config WHERE config_name = \'install_aes_key\';') ) + { + $dbal->_die('install database_post.php trying to remove old AES installer key'); + } + } + $dbal->close(); + ?> +
+ + +

get('database_msg_success_title'); ?>

+

get('database_msg_success_body'); ?>

+

get('database_msg_success_redirect'); ?>

+
+ + +
+ + +

get('database_msg_post_fail_title'); ?>

+

get('database_msg_post_fail_body'); ?>

+

get('database_msg_post_fail_desc'); ?> + sql_error(); + ?> +

+

+ +

+
+ false, + 'host_good' => true, + 'creating_user' => false, + 'db_exist' => false, + 'creating_db' => false, + 'creating_db_grant' => false, + 'root_fail' => false, + 'version' => array( + 'version' => 'unknown', + 'good' => 'indeterminate' + ), + 'last_error' => '' + ); + + if ( !isset($_POST['info']) ) + die(); + + $info = $_POST['info']; + + // From here on out will be JSON responses + header('Content-type: application/json'); + + try + { + $info = @enano_json_decode($info); + } + catch ( Zend_Json_Exception $e ) + { + die(enano_json_encode(array( + 'mode' => 'error', + 'error' => 'Exception in JSON decoder' + ))); + } + + // Try to connect as the normal user + // generate connection string + $conn_string = "dbname = '" . addslashes($info['db_name']) . "' port = '5432' host = '" . addslashes($info['db_host']) . "' " . + "user= '" . addslashes($info['db_user']) . "' password = '" . addslashes($info['db_pass']) . "'"; + $test = @pg_connect($conn_string); + if ( !$test ) + { + // Connection as normal user failed. PgSQL doesn't give us an error string so + // just try to connect as root. If even that fails, exit with an error + $return['creating_user'] = true; + if ( !empty($info['db_root_user']) && !empty($info['db_root_pass']) ) + { + $conn_string_root = "dbname = '" . addslashes($info['db_name']) . "' port = '5432' host = '" . addslashes($info['db_host']) . "' " . + "user= '" . addslashes($info['db_root_user']) . "' password = '" . addslashes($info['db_root_pass']) . "'"; + // Attempt connection as root + $test_root = @pg_connect($conn_string_root); + if ( !$test_root ) + { + $return['root_fail'] = true; + } + else + { + $return['can_install'] = true; + } + } + } + else + { + $return['can_install'] = true; + } + + $did_version_check = false; + + if ( isset($test) && @is_resource($test) ) + { + $server_info = @pg_version($test); + if ( isset($server_info['server']) ) + { + $did_version_check = true; + $return['version'] = array( + 'version' => $server_info['server'], + 'good' => ( version_compare($server_info['server'], '8.2.5', '>=') ) + ); + } + @pg_close($test); + } + + if ( isset($test_root) && @is_resource($test_root) ) + { + $server_info = @pg_version($test_root); + if ( isset($server_info['server']) ) + { + $did_version_check = true; + $return['version'] = array( + 'version' => $server_info['server'], + 'good' => ( version_compare($server_info['server'], '8.2.5', '>=') ) + ); + } + @pg_close($test_root); + } + + if ( !$did_version_check ) + { + $return['version'] = array( + 'version' => 'indeterminate', + 'good' => false + ); + } + else + { + if ( !$return['version']['good'] ) + { + $return['can_install'] = false; + } + } + + echo enano_json_encode($return); + + exit(); +} + +$ui->add_header(''); +$ui->show_header(); + +?> + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

get('dbpgsql_table_title'); ?>

+
+ get('dbpgsql_field_hostname_title'); ?> +
get('dbpgsql_field_hostname_body'); ?> +
+
+ + + Good/bad icon +
+ get('dbpgsql_field_dbname_title'); ?>
+ get('dbpgsql_field_dbname_body'); ?>
+ +
+ + + Good/bad icon +
+ get('dbpgsql_field_dbauth_title'); ?>
+ get('dbpgsql_field_dbauth_body'); ?>
+ +
+
+
+ +
+ Good/bad icon +
+

get('database_heading_optionalinfo'); ?>

+
+ get('dbpgsql_field_tableprefix_title'); ?>
+ get('dbpgsql_field_tableprefix_body'); ?> +
+ + + Good/bad icon +
+ get('dbpgsql_field_rootauth_title'); ?>
+ get('dbpgsql_field_rootauth_body'); ?>
+ +
+
+
+ +
+ Good/bad icon +
+ get('dbpgsql_field_pgsqlversion_title'); ?> + + get('dbpgsql_field_pgsqlversion_blurb_willbechecked'); ?> + + Good/bad icon +
+ get('dbpgsql_field_droptables_title'); ?>
+ get('dbpgsql_field_droptables_body'); ?> +
+ +
+ +
+
+ + + + + + +
+ + +

+ get('meta_lbl_before_continue'); ?>
+ • get('database_objective_test'); ?>
+ • get('database_objective_uncrypt'); ?> +

+
+ +
+ + + diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/finish.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/finish.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,72 @@ +show_header(); + echo '

Installation error

+

ERROR: That database driver is not supported.

'; + return true; +} + +$ui->show_header(); +flush(); + +?> +

get('finish_heading_progress'); ?>

+

get('finish_msg_progress'); ?>

+ +get('install_stg_load_title'), 'stg_load_files', $lang->get('install_stg_load_body'), false); +run_installer_stage('cleanup', $lang->get('install_stg_cleanup_title'), 'stg_aes_cleanup', $lang->get('install_stg_cleanup_body'), false); +run_installer_stage('buildindex', $lang->get('install_stg_buildindex_title'), 'stg_build_index', $lang->get('install_stg_buildindex_body')); +run_installer_stage('renameconfig', $lang->get('install_stg_rename_title'), 'stg_rename_config', $lang->get('install_stg_rename_body', array('mainpage_link' => scriptPath . '/index.php'))); + +close_install_table(); + +?> +

get('finish_msg_success_title'); ?>

+

get('finish_msg_success_body', array('mainpage_link' => makeUrlNS('Article', 'Main_Page'))); ?>

+get('finish_body'); + echo '

' . $lang->get('finish_link_mainpage', array('mainpage_link' => scriptPath . '/index.php')) . '

'; +?> +close(); + diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/install.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/install.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,125 @@ +show_header(); + echo '

Installation error

+

ERROR: That database driver is not supported.

'; + return true; +} + +$db = new $dbdriver(); +$result = $db->connect(true, $dbhost, $dbuser, $dbpasswd, $dbname); +if ( !$result ) +{ + $ui->show_header(); + // FIXME: l10n + ?> +
+ + +

get('database_msg_post_fail_title'); ?>

+

get('database_msg_post_fail_body'); ?>

+

get('database_msg_post_fail_desc'); ?> + sql_error(); + ?> +

+

+ +

+
+ show_header(); +flush(); + +?> +

get('install_title'); ?>

+

get('install_body'); ?>

+ +

get('install_heading_progress'); ?>

+ +get('install_stg_load_title'), 'stg_load_files', $lang->get('install_stg_load_body'), false); +run_installer_stage('setpass', $lang->get('install_stg_setpass_title'), 'stg_password_decode', $lang->get('install_stg_setpass_body')); +run_installer_stage('genaes', $lang->get('install_stg_genaes_title'), 'stg_make_private_key', $lang->get('install_stg_genaes_body')); +run_installer_stage('sqlparse', $lang->get('install_stg_sqlparse_title'), 'stg_load_schema', $lang->get('install_stg_sqlparse_body')); +run_installer_stage('payload', $lang->get('install_stg_payload_title'), 'stg_deliver_payload', $lang->get('install_stg_payload_body')); +run_installer_stage('writeconfig', $lang->get('install_stg_writeconfig_title'), 'stg_write_config', $lang->get('install_stg_writeconfig_body')); + +// Now that the config is written, shutdown our primitive API and startup the full Enano API +$db->close(); + +@define('ENANO_ALLOW_LOAD_NOLANG', 1); +require(ENANO_ROOT . '/includes/common.php'); + +if ( is_object($db) && is_object($session) ) +{ + run_installer_stage('startapi', $lang->get('install_stg_startapi_title'), 'stg_sim_good', '...', false); +} +else +{ + run_installer_stage('startapi', $lang->get('install_stg_startapi_title'), 'stg_sim_bad', $lang->get('install_stg_startapi_body'), false); +} + +// Import languages +run_installer_stage('importlang', $lang->get('install_stg_importlang_title'), 'stg_language_setup', $lang->get('install_stg_importlang_body')); + +// Init logs +run_installer_stage('initlogs', $lang->get('install_stg_initlogs_title'), 'stg_init_logs', $lang->get('install_stg_initlogs_body')); + +close_install_table(); + +?> +
+ +
+ +
+
+close(); + diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/license.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/license.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,101 @@ + +
+ +

get('license_info_unstable_title'); ?>

+

get('license_info_unstable_body'); ?>

+ +

get('license_section_gpl_heading'); ?>

+ lang_code != 'eng' ): ?> +

get('license_gpl_blurb_inenglish'); ?>

+ + + Because I could never find the Create a Page button in PHP-Nuke.

'; + echo '

' . str_replace('http://enanocms.org/', 'http://www.2robots.com/2003/10/15/web-portals-suck/', $template->fading_button) . '

'; + echo '

It\'s not a portal, my friends.

'; + } + ?> +
+ setRenderConf('Xhtml', 'code', 'css_filename', 'codefilename'); + $wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', scriptPath . '/index.php?title='); + $result = $wiki->transform($message, 'Xhtml'); + + // HTML fixes + $result = preg_replace('#
+ + + + +
+ + +

+ get('meta_lbl_before_continue'); ?>
+ • get('license_objective_ensure_agree'); ?>
+ • get('license_objective_have_db_info'); ?> +

+
+ + + diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/login.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/login.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,228 @@ +connect(true, $dbhost, $dbuser, $dbpasswd, $dbname); +if ( !$result ) + die('DB privileges were revoked'); + +// Is the key in the database? +$q = $db->sql_query('SELECT config_value FROM ' . table_prefix . 'config WHERE config_name = \'install_aes_key\';'); +if ( !$q ) + $db->_die(); +if ( $db->numrows() > 0 ) +{ + list($install_aes_key) = $db->fetchrow_num(); +} +else +{ + $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE); + $install_aes_key = $aes->gen_readymade_key(); + + if ( ! $db->sql_query('INSERT INTO ' . table_prefix . 'config ( config_name, config_value ) VALUES ( \'install_aes_key\', \'' . $install_aes_key .'\' ); ') ) + $db->_die(); +} +$db->free_result($q); + +$ui->add_header(''); +$ui->show_header(); + +// FIXME: l10n +?> +

get('login_welcome_title'); ?>

+get('login_welcome_body'); ?> + + + +
&$value ) + { + if ( !preg_match('/^[a-z0-9_]+$/', $key) ) + die('You idiot hacker...'); + if ( $key == '_cont' ) + continue; + $value_clean = str_replace(array('\\', '"', '<', '>'), array('\\\\', '\\"', '<', '>'), $value); + echo "\n "; + } + + $https = ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ); + $scriptpath_full = 'http' . ( $https ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . scriptPath . '/'; + ?> + + + + + + + + + + + + + + + + + + + + + + + + +
+ get('login_field_username'); ?> + + + + Good/bad icon +
+ get('login_field_password'); ?>
+ get('login_aes_blurb'); ?> +
+
+
+
+
+ get('login_field_password_confirm'); ?> +
+ Good/bad icon +
+ get('login_field_email'); ?> + + + + Good/bad icon +
+ +
+ +
+
diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/sysreqs.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/sysreqs.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,147 @@ +
$descTest passed
$desc
$extended_desc
Test passed with warning
$desc
$extended_desc
Test failed
+ +get('sysreqs_req_php5'), $lang->get('sysreqs_req_desc_php5'), true); +run_test('return function_exists(\'mysql_connect\');', $lang->get('sysreqs_req_mysql'), $lang->get('sysreqs_req_desc_mysql') ); +run_test('return function_exists(\'pg_connect\');', $lang->get('sysreqs_req_postgres'), $lang->get('sysreqs_req_desc_postgres'), true); +run_test('return @ini_get(\'file_uploads\');', $lang->get('sysreqs_req_uploads'), $lang->get('sysreqs_req_desc_uploads') ); +run_test('return is_apache();', $lang->get('sysreqs_req_apache'), $lang->get('sysreqs_req_desc_apache'), true); +run_test('return config_write_test();', $lang->get('sysreqs_req_config'), $lang->get('sysreqs_req_desc_config') ); +run_test('return file_exists(\'/usr/bin/convert\');', $lang->get('sysreqs_req_magick'), $lang->get('sysreqs_req_desc_magick'), true); +run_test('return is_writable(ENANO_ROOT.\'/cache/\');', $lang->get('sysreqs_req_cachewriteable'), $lang->get('sysreqs_req_desc_cachewriteable'), true); +run_test('return is_writable(ENANO_ROOT.\'/files/\');', $lang->get('sysreqs_req_fileswriteable'), $lang->get('sysreqs_req_desc_fileswriteable'), true); +if ( !function_exists('mysql_connect') && !function_exists('pg_connect') ) +{ + // FIXME: l10n + run_test('return false;', 'No database drivers are available.', 'You need to have at least one database driver working to install Enano. See the warnings on MySQL and PostgreSQL above for more information on installing these database drivers.', false); +} +echo '
'; +echo '
'; +if(!$failed) +{ + ?> + + +'; + run_test('return false;', $lang->get('sysreqs_summary_fail_title'), $lang->get('sysreqs_summary_fail_body')); + echo '
'; + } +} + +?> diff -r d823e49e2e4e -r c433348f3628 install/includes/stages/website.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/stages/website.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,256 @@ +add_header(''); +$ui->show_header(); + +?> + + + +
&$value ) + { + if ( !preg_match('/^[a-z0-9_]+$/', $key) ) + die('You idiot hacker...'); + if ( $key == '_cont' ) + continue; + $value_clean = str_replace(array('\\', '"', '<', '>'), array('\\\\', '\\"', '<', '>'), $value); + echo "\n "; + } + + $https = ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ); + $scriptpath_full = 'http' . ( $https ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . scriptPath . '/'; + ?> + + + + + + + + + + + + + + + + + + + + + + + +
+ get('website_field_name'); ?>
+ get('website_field_name_hint'); ?> +
+ +
+ get('website_field_desc'); ?>
+ get('website_field_desc_hint'); ?> +
+ +
+ get('website_field_copyright'); ?>
+ get('website_field_copyright_hint'); ?> +
+ +
+ get('website_field_urlscheme'); ?>
+ get('website_field_urlscheme_hint'); ?> +
+ + + + + + +
+ + + + +

get('website_field_urlscheme_opt_standard_hint'); ?>

+

get('website_field_urlscheme_lbl_example'); ?>

+
+
+ + + + + + +
+ + + + +

get('website_field_urlscheme_opt_shortened_hint'); ?>

+

get('website_field_urlscheme_lbl_example'); ?>

+
+
+ + + + + + +
+ + + + +

get('website_field_urlscheme_opt_rewrite_hint'); ?>

+

get('website_field_urlscheme_lbl_example'); ?>

+
+
+ +

+ get('website_btn_urlscheme_detect'); ?> +

+ +
+ +
+ +
+ +
+ +
+ diff -r d823e49e2e4e -r c433348f3628 install/includes/ui.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/includes/ui.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,243 @@ + section + * @var array Will be implode()'ed + */ + + var $additional_headers = array(); + + /** + * Constructor. + * @param string The name displayed in the tag + * @param bool If true, the simplified header format is displayed. + */ + + function __construct($app_name, $simple_header) + { + $this->stages = array( + 'main' => array(), + 'hide' => array() + ); + $this->app_name = $app_name; + $this->simple = ( $simple_header ) ? true : false; + } + + /** + * Adds more text to the HTML header. + * @param string + */ + + function add_header($html) + { + $this->additional_headers[] = $html; + } + + /** + * Adds a stage to the installer. + * @param string Title of the stage, should be already put through $lang->get() + * @param bool If true, the stage is shown among possible stages at the top of the window. If false, acts as a hidden stage + * @return string Unique identifier for stage, used later on set_visible_stage() + */ + + function add_stage($stage, $visible = true) + { + $key = ( $visible ) ? 'main' : 'hide'; + $guid = md5(microtime() . mt_rand()); + $this->stages[$key][$guid] = $stage; + if ( empty($this->current_stage) ) + $this->current_stage = $guid; + return $guid; + } + + /** + * Resets the active stage of installation. This is for the UI only; it doesn't actually change how the backend works. + * @param string GUID of stage, returned from add_stage() + * @return bool true on success, false if stage GUID not found + */ + + function set_visible_stage($guid) + { + foreach ( $this->stages['main'] as $key => $stage_name ) + { + if ( $key == $guid ) + { + $this->current_stage = $guid; + return true; + } + } + foreach ( $this->stages['hide'] as $key => $stage_name ) + { + if ( $key == $guid ) + { + $this->current_stage = $guid; + return true; + } + } + return false; + } + + /** + * Outputs the HTML headers and start of the <body>, including stage indicator + */ + + function show_header() + { + // Determine the name of the current stage + $stage_name = false; + + if ( isset($this->stages['main'][$this->current_stage]) ) + $stage_name = $this->stages['main'][$this->current_stage]; + else if ( isset($this->stages['hide'][$this->current_stage]) ) + $stage_name = $this->stages['hide'][$this->current_stage]; + else + // Can't determine name of stage + return false; + + $this->app_name = htmlspecialchars($this->app_name); + $stage_name = htmlspecialchars($stage_name); + + global $lang; + if ( is_object($lang) && isset($GLOBALS['lang_uri']) ) + { + $lang_uri = sprintf($GLOBALS['lang_uri'], $lang->lang_code); + $this->add_header('<script type="text/javascript" src="' . $lang_uri . '"></script>'); + } + + $additional_headers = implode("\n ", $this->additional_headers); + $title = addslashes(str_replace(' ', '_', $stage_name)); + $js_dynamic = '<script type="text/javascript"> + var title="' . $title . '"; + var scriptPath="'.scriptPath.'"; + var ENANO_SID=""; + var AES_BITS='.AES_BITS.'; + var AES_BLOCKSIZE=' . AES_BLOCKSIZE . '; + var pagepass=\'\'; + var ENANO_LANG_ID = 1; + var DISABLE_MCE = true; + </script>'; + + echo <<<EOF +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>{$stage_name} • {$this->app_name} + + + + $js_dynamic + + $additional_headers + + +
+ +EOF; + if ( !$this->simple ) + { + $step = ( !empty($this->step) ) ? '
' . htmlspecialchars($this->step) . '
' : ''; + echo << + $step + Enano logo +
+ +EOF; + } + $stages_class = ( $this->simple ) ? 'stages' : 'stages stages-fixed'; + echo << +
    + +EOF; + foreach ( $this->stages['main'] as $guid => $stage ) + { + $class = ( $guid == $this->current_stage ) ? 'stage stage-active' : 'stage'; + $stage = htmlspecialchars($stage); + echo "
  • $stage
  • \n "; + } + echo "
\n
\n
\n"; + echo "
\n "; + echo "
\n "; + } + + /** + * Displays the page footer. + */ + + function show_footer() + { + echo << + Enano and its various components, related documentation, and artwork are copyright © 2006-2008 Dan Fuhry.
+ This program is Free Software; see the file "GPL" included with this package for details. +
+
+
+
+ + +EOF; + } + +} + +?> diff -r d823e49e2e4e -r c433348f3628 install/index.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/index.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,128 @@ +__construct('Enano installation', true); +} +$ui->add_stage('Welcome', true); +$ui->add_stage('Installation', true); +$ui->add_stage('Upgrade', true); +$ui->add_stage('Readme', true); + +$ui->show_header(); + +if ( defined('ENANO_INSTALLED') ) +{ + // Is Enano installed? If so, load the config and check version info + define('IN_ENANO_UPGRADE', 'true'); + // common.php above calls chdir() to the ENANO_ROOT, so this loads the full Enano API. + require('includes/common.php'); +} + +?> + +
+ +
+ Enano hasn't been installed yet!
+ You'll need to install the Enano database before you can use your site. To get started, click the Install button below. +
+ +
+ A configuration file (config.php) exists but doesn't set the ENANO_INSTALLED constant.
+

Didn't expect to see this message? + It's possible that your configuration file has become corrupted and no longer sets information that Enano needs to connect + to the database. You should have a look at your config.php by downloading it with FTP or viewing it over SSH. + If the file appears to have been tampered with, please contact the Enano team + for support immediately.

+

Most importantly, if you suspect a security breach, you should contact the Enano team + via e-mail. If you have the capability to use PGP encryption, you should do + so; our public key is available here.

+
+
+ + + + + + +
+ + Enano CMS + + + +
+ +show_footer(); + +?> diff -r d823e49e2e4e -r c433348f3628 install/install.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/install.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,282 @@ +load_file(ENANO_ROOT . '/language/' . $language_dir . '/install.json'); + $lang_uri = 'install.php?do=lang_js&language=%s'; + + // Init UI + $ui = new Enano_Installer_UI($lang->get('meta_site_name'), false); + + // Add stages + foreach ( $stages as $stage ) + { + $stage_ids[$stage] = $ui->add_stage($lang->get("{$stage}_modetitle"), true); + } + + // Determine stage + if ( isset($_REQUEST['stage']) && isset($stage_ids[$_REQUEST['stage']]) ) + { + $ui->set_visible_stage($stage_ids[$_REQUEST['stage']]); + $stage = $_REQUEST['stage']; + } + else + { + $stage = 'license'; + } + + $stage_num = array_search($stage, $stages); + if ( $stage_num ) + { + $stage_num++; + $ui->step = $lang->get('meta_step', array('step' => $stage_num, 'title' => $lang->get("{$stage}_modetitle_long"))); + } +} +else +{ + $ui = new Enano_Installer_UI('Enano installation', false); + + if ( version_compare(PHP_VERSION, '5.0.0', '<') ) + { + $ui->__construct('Enano installation', false); + } + + $ui->step = 'Step 1: Choose language'; + + $stage = 'language'; + $stage_ids['language'] = $ui->add_stage('Language', true); + $stage_ids['license'] = $ui->add_stage('License', true); + $stage_ids['sysreqs'] = $ui->add_stage('Requirements', true); + $stage_ids['database'] = $ui->add_stage('Database', true); + $stage_ids['website'] = $ui->add_stage('Site info', true); + $stage_ids['login'] = $ui->add_stage('Admin login', true); + $stage_ids['confirm'] = $ui->add_stage('Review', true); + $stage_ids['install'] = $ui->add_stage('Install', true); + $stage_ids['finish'] = $ui->add_stage('Finish', true); +} + +// If we don't have PHP 5, show a friendly error message and bail out +if ( version_compare(PHP_VERSION, '5.0.0', '<') || isset($_GET['debug_warn_php4']) ) +{ + $ui->set_visible_stage( + $ui->add_stage('PHP compatibility notice', false) + ); + $ui->step = ''; + $ui->show_header(); + + // This isn't localized because all localization code is dependent on + // PHP 5 (loading lang.php will throw a parser error under PHP4). This + // one message probably doesn't need to be localized anyway. + + ?> +

+ Your server doesn't have support for PHP 5. +

+

+ PHP 5 is the latest version of the language on which Enano was built. Its many new features have been available since early 2004, yet + many web hosts have not migrated to it because of the work involved. In 2007, Zend Corporation announced that support for the aging + PHP 4.x would be discontinued at the end of the year. An initiative called GoPHP5 was started to + encourage web hosts to migrate to PHP 5. +

+

+ Because of the industry's decision to not support PHP 4 any longer, the Enano team decided that it was time to begin using the powerful + features of PHP 5 at the expense of PHP 4 compatibility. Therefore, this version of Enano cannot be installed on your server until it + is upgraded to at least PHP 5.0.0, and preferably the latest available version. + +

+

+ If you need to use Enano but can't upgrade your PHP because you're on a shared or reseller hosting service, you can use the + 1.0.x series of Enano on your site. While the Enano team attempts to make this + older series work on PHP 4, official support is not provided for installations of Enano on PHP 4. +

+ show_footer(); + exit(); +} + +if ( isset($_SERVER['PATH_INFO']) && !isset($_GET['str']) && isset($_GET['do']) ) +{ + $_GET['str'] = substr($_SERVER['PATH_INFO'], 1); +} + +if ( isset($_GET['do']) ) +{ + switch ( $_GET['do'] ) + { + case 'lang_js': + if ( !isset($_GET['language']) ) + die(); + $lang_id = $_GET['language']; + header('Content-type: text/javascript'); + if ( !isset($languages[$lang_id]) ) + { + die('// Bad language ID'); + } + $language_dir = $languages[$lang_id]['dir']; + + // Include language lib and additional PHP5-only JSON functions + require_once( ENANO_ROOT . '/includes/json2.php' ); + require_once( ENANO_ROOT . '/includes/lang.php' ); + + // Initialize language support + $lang = new Language($lang_id); + $lang->load_file(ENANO_ROOT . '/language/' . $language_dir . '/install.json'); + $lang->load_file(ENANO_ROOT . '/language/' . $language_dir . '/core.json'); + $lang->load_file(ENANO_ROOT . '/language/' . $language_dir . '/user.json'); + + $time_now = microtime_float(); + $test = "if ( typeof(enano_lang) != 'object' ) +{ + var enano_lang = new Object(); + var enano_lang_code = new Object(); +} + +enano_lang[{$lang->lang_id}] = " . enano_json_encode($lang->strings) . "; +enano_lang_code[{$lang->lang_id}] = '{$lang->lang_code}';"; + $time_total = round(microtime_float() - $time_now, 4); + echo "// Generated in $time_total seconds\n"; + echo $test; + + exit(); + case 'modrewrite_test': + // Include language lib and additional PHP5-only JSON functions + require_once( ENANO_ROOT . '/includes/json2.php' ); + + if ( isset($_GET['str']) && in_array($_GET['str'], array('standard', 'shortened', 'rewrite')) ) + { + echo 'good_' . $_GET['str']; + } + else + { + echo 'bad'; + } + exit(); + } +} + +switch ( $stage ) +{ + default: + $ui->show_header(); + echo '

Invalid stage.

'; + break; + case 'language': + $ui->show_header(); + ?> +

Welcome to Enano.

+

Bienvenido a Enano / + Wilkommen in Enano / + Bienvenue à Enano / + Benvenuti a Enano / + 欢迎 Enano / + Enano ã¸ã‚ˆã†ã“ã。 +

+

+ Please select a language: / + Por favor, seleccione un idioma: / + Bitte wählen Sie eine Sprache: / + S’il vous plaît choisir une langue: / + Selezionare una lingua: / + 请选择一ç§è¯­è¨€ï¼š / + 言語をé¸æŠžã—ã¦ãã ã•ã„:

+
+ + +
+ show_header(); + require( ENANO_ROOT . '/includes/wikiformat.php' ); + require( ENANO_ROOT . '/install/includes/stages/license.php' ); + break; + case 'sysreqs': + $ui->show_header(); + require( ENANO_ROOT . '/install/includes/stages/sysreqs.php' ); + break; + case 'database': + if ( isset($_POST['driver']) && in_array($_POST['driver'], $supported_drivers) ) + { + // This is SAFE! It's validated against the array in in_array() above. + $driver = $_POST['driver']; + require( ENANO_ROOT . "/install/includes/stages/database_{$driver}.php" ); + } + else + { + $ui->show_header(); + // No driver selected - give the DB drive selection page + require( ENANO_ROOT . '/install/includes/stages/database.php' ); + } + break; + case 'website': + require( ENANO_ROOT . '/install/includes/stages/website.php' ); + break; + case 'login': + require( ENANO_ROOT . '/install/includes/stages/login.php' ); + break; + case 'confirm': + require( ENANO_ROOT . '/install/includes/stages/confirm.php' ); + break; + case 'install': + require( ENANO_ROOT . '/install/includes/stages/install.php' ); + break; + case 'finish': + require( ENANO_ROOT . '/install/includes/stages/finish.php' ); + break; +} + +$ui->show_footer(); + +?> diff -r d823e49e2e4e -r c433348f3628 install/readme.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/readme.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,41 @@ +add_stage('Readme and important information', true); + +$ui->set_visible_stage($stg_readme); + +$ui->show_header(); + +?> +

Readme

+

This document contains important information you'll want to know before you install Enano. For installation instructions, please + see the Enano installation guide. Return to welcome menu »

+
+show_footer(); + +?> diff -r d823e49e2e4e -r c433348f3628 install/schemas/mysql_stage1.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/mysql_stage1.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,17 @@ +-- Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between +-- Version 1.1.1 +-- Copyright (C) 2006-2007 Dan Fuhry + +-- This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +-- 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 details. + +-- mysql_stage1.sql - MySQL installation schema, early stage + +CREATE TABLE {{TABLE_PREFIX}}config( + config_name varchar(63), + config_value text +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + diff -r d823e49e2e4e -r c433348f3628 install/schemas/mysql_stage2.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/mysql_stage2.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,389 @@ +-- Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between +-- Version 1.1.1 +-- Copyright (C) 2006-2007 Dan Fuhry + +-- This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +-- 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 details. + +-- mysql_stage2.sql - MySQL installation schema, main payload + +CREATE TABLE {{TABLE_PREFIX}}categories( + page_id varchar(64), + namespace varchar(64), + category_id varchar(64) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}comments( + comment_id int(12) NOT NULL auto_increment, + page_id text, + namespace text, + subject text, + comment_data text, + name text, + approved tinyint(1) default 1, + user_id mediumint(8) NOT NULL DEFAULT -1, + time int(12) NOT NULL DEFAULT 0, + ip_address varchar(39), + PRIMARY KEY ( comment_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}logs( + log_id int(15) NOT NULL auto_increment, + log_type varchar(16), + action varchar(16), + time_id int(12) NOT NULL DEFAULT '0', + date_string varchar(63), + page_id text, + namespace text, + page_text text, + char_tag varchar(40), + author varchar(63), + edit_summary text, + minor_edit tinyint(1), + is_draft tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY ( log_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}page_text( + page_id varchar(255), + namespace varchar(16) NOT NULL DEFAULT 'Article', + page_text text, + char_tag varchar(63), + FULLTEXT KEY {{TABLE_PREFIX}}page_search_idx (page_id, namespace, page_text) +) ENGINE = MYISAM CHARACTER SET `utf8`; + +CREATE TABLE {{TABLE_PREFIX}}pages( + page_order int(8), + name varchar(255), + urlname varchar(255), + namespace varchar(16) NOT NULL DEFAULT 'Article', + special tinyint(1) default '0', + visible tinyint(1) default '1', + comments_on tinyint(1) default '1', + protected tinyint(1) NOT NULL DEFAULT 0, + wiki_mode tinyint(1) NOT NULL DEFAULT 2, + delvotes int(10) NOT NULL DEFAULT 0, + password varchar(40) NOT NULL DEFAULT '', + delvote_ips text DEFAULT NULL +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}session_keys( + session_key varchar(32), + salt varchar(32), + user_id mediumint(8), + auth_level tinyint(1) NOT NULL DEFAULT '0', + source_ip varchar(10) default '0x7f000001', + time bigint(15) default '0' +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}themes( + theme_id varchar(63), + theme_name text, + theme_order smallint(5) NOT NULL DEFAULT '1', + default_style varchar(63) NOT NULL DEFAULT '', + enabled tinyint(1) NOT NULL DEFAULT '1', + group_list text DEFAULT NULL, + group_policy ENUM('allow', 'deny') NOT NULL DEFAULT 'deny' +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}users( + user_id mediumint(8) NOT NULL auto_increment, + username text, + password varchar(255), + email text, + real_name text, + user_level tinyint(1) NOT NULL DEFAULT 2, + theme varchar(64) NOT NULL DEFAULT 'bleu.css', + style varchar(64) NOT NULL DEFAULT 'default', + signature text, + reg_time int(11) NOT NULL DEFAULT 0, + account_active tinyint(1) NOT NULL DEFAULT 0, + activation_key varchar(40) NOT NULL DEFAULT 0, + old_encryption tinyint(1) NOT NULL DEFAULT 0, + temp_password text, + temp_password_time int(12) NOT NULL DEFAULT 0, + user_coppa tinyint(1) NOT NULL DEFAULT 0, + user_lang smallint(5) NOT NULL DEFAULT 1, + user_has_avatar tinyint(1) NOT NULL DEFAULT 0, + avatar_type ENUM('jpg', 'png', 'gif') NOT NULL DEFAULT 'png', + user_registration_ip varchar(39), + user_rank int(12) UNSIGNED NOT NULL DEFAULT 1, + user_timezone int(12) UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY (user_id) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}users_extra( + user_id mediumint(8) NOT NULL, + user_aim varchar(63), + user_yahoo varchar(63), + user_msn varchar(255), + user_xmpp varchar(255), + user_homepage text, + user_location text, + user_job text, + user_hobbies text, + email_public tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY ( user_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}banlist( + ban_id mediumint(8) NOT NULL auto_increment, + ban_type tinyint(1), + ban_value varchar(64), + is_regex tinyint(1) DEFAULT 0, + reason text, + PRIMARY KEY ( ban_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}files( + file_id int(12) NOT NULL auto_increment, + time_id int(12) NOT NULL, + page_id varchar(63) NOT NULL, + filename varchar(127) default NULL, + size bigint(15) NOT NULL, + mimetype varchar(63) default NULL, + file_extension varchar(8) default NULL, + file_key varchar(32) NOT NULL, + PRIMARY KEY (file_id) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}buddies( + buddy_id int(15) NOT NULL auto_increment, + user_id mediumint(8), + buddy_user_id mediumint(8), + is_friend tinyint(1) NOT NULL DEFAULT '1', + PRIMARY KEY (buddy_id) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}privmsgs( + message_id int(15) NOT NULL auto_increment, + message_from varchar(63), + message_to varchar(255), + date int(12), + subject varchar(63), + message_text text, + folder_name varchar(63), + message_read tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (message_id) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}sidebar( + item_id smallint(3) NOT NULL auto_increment, + item_order smallint(3) NOT NULL DEFAULT 0, + item_enabled tinyint(1) NOT NULL DEFAULT 1, + sidebar_id smallint(3) NOT NULL DEFAULT 1, + block_name varchar(63) NOT NULL, + block_type tinyint(1) NOT NULL DEFAULT 0, + block_content text, + PRIMARY KEY ( item_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}hits( + hit_id bigint(20) NOT NULL auto_increment, + username varchar(63) NOT NULL, + time int(12) NOT NULL DEFAULT 0, + page_id varchar(63), + namespace varchar(63), + PRIMARY KEY ( hit_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}search_index( + word varchar(64) NOT NULL, + page_names text, + PRIMARY KEY ( word ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}groups( + group_id mediumint(5) UNSIGNED NOT NULL auto_increment, + group_name varchar(64), + group_type tinyint(1) NOT NULL DEFAULT 1, + PRIMARY KEY ( group_id ), + system_group tinyint(1) NOT NULL DEFAULT 0 +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}group_members( + member_id int(12) UNSIGNED NOT NULL auto_increment, + group_id mediumint(5) UNSIGNED NOT NULL, + user_id int(12) NOT NULL, + is_mod tinyint(1) NOT NULL DEFAULT 0, + pending tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY ( member_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}acl( + rule_id int(12) UNSIGNED NOT NULL auto_increment, + target_type tinyint(1) UNSIGNED NOT NULL, + target_id int(12) UNSIGNED NOT NULL, + page_id varchar(255), + namespace varchar(24), + rules text, + PRIMARY KEY ( rule_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.0.1 + +CREATE TABLE {{TABLE_PREFIX}}page_groups( + pg_id mediumint(8) NOT NULL auto_increment, + pg_type tinyint(2) NOT NULL DEFAULT 1, + pg_name varchar(255) NOT NULL DEFAULT '', + pg_target varchar(255) DEFAULT NULL, + PRIMARY KEY ( pg_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.0.1 + +CREATE TABLE {{TABLE_PREFIX}}page_group_members( + pg_member_id int(12) NOT NULL auto_increment, + pg_id mediumint(8) NOT NULL, + page_id varchar(63) NOT NULL, + namespace varchar(63) NOT NULL DEFAULT 'Article', + PRIMARY KEY ( pg_member_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.0.1 + +CREATE TABLE {{TABLE_PREFIX}}tags( + tag_id int(12) NOT NULL auto_increment, + tag_name varchar(63) NOT NULL DEFAULT 'bla', + page_id varchar(255) NOT NULL, + namespace varchar(255) NOT NULL, + user_id mediumint(8) NOT NULL DEFAULT 1, + PRIMARY KEY ( tag_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}lockout( + id int(12) NOT NULL auto_increment, + ipaddr varchar(40) NOT NULL, + action ENUM('credential', 'level') NOT NULL DEFAULT 'credential', + timestamp int(12) NOT NULL DEFAULT 0, + PRIMARY KEY ( id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}language( + lang_id smallint(5) NOT NULL auto_increment, + lang_code varchar(16) NOT NULL, + lang_name_default varchar(64) NOT NULL, + lang_name_native varchar(64) NOT NULL, + last_changed int(12) NOT NULL DEFAULT 0, + PRIMARY KEY ( lang_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}language_strings( + string_id bigint(15) NOT NULL auto_increment, + lang_id smallint(5) NOT NULL, + string_category varchar(32) NOT NULL, + string_name varchar(64) NOT NULL, + string_content longtext NOT NULL, + PRIMARY KEY ( string_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}ranks( + rank_id int(12) NOT NULL auto_increment, + rank_title varchar(63) NOT NULL DEFAULT '', + rank_style varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY ( rank_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}captcha( + code_id int(12) NOT NULL auto_increment, + session_id varchar(40) NOT NULL DEFAULT '', + code varchar(64) NOT NULL DEFAULT '', + session_data text, + source_ip varchar(39), + user_id int(12), + PRIMARY KEY ( code_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +-- Added in 1.1.3 +-- Storing obscenely huge integers as strings since that's how php processes them. + +CREATE TABLE {{TABLE_PREFIX}}diffiehellman ( + key_id int(12) NOT NULL auto_increment, + private_key text, + public_key text, + PRIMARY KEY ( key_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +INSERT INTO {{TABLE_PREFIX}}config(config_name, config_value) VALUES + ('site_name', '{{SITE_NAME}}'), + ('main_page', 'Main_Page'), + ('site_desc', '{{SITE_DESC}}'), + ('wiki_mode', '{{WIKI_MODE}}'), + ('wiki_edit_notice', '0'), + ('sflogo_enabled', '0'), + ('sflogo_groupid', ''), + ('sflogo_type', '1'), + ('w3c_vh32', '0'), + ('w3c_vh40', '0'), + ('w3c_vh401', '0'), + ('w3c_vxhtml10', '0'), + ('w3c_vxhtml11', '0'), + ('w3c_vcss', '0'), + ('approve_comments', '0'), + ('enable_comments', '1'), + ('plugin_SpecialAdmin.php', '1'), + ('plugin_SpecialPageFuncs.php', '1'), + ('plugin_SpecialUserFuncs.php', '1'), + ('plugin_SpecialCSS.php', '1'), + ('copyright_notice', '{{COPYRIGHT}}'), + ('wiki_edit_notice_text', '== Why can I edit this page? ==\n\nEveryone can edit almost any page in this website. This concept is called a wiki. It gives everyone the opportunity to make a change for the best. While some spam and vandalism may occur, it is believed that most contributions will be legitimate and helpful.\n\nFor security purposes, a history of all page edits is kept, and administrators are able to restore vandalized or spammed pages with just a few clicks.'), + ('cache_thumbs', '{{ENABLE_CACHE}}'), + ('max_file_size', '256000'),('enano_version', '{{VERSION}}'),( 'allowed_mime_types', 'cbf:len=185;crc=55fb6f14;data=0[1],1[4],0[3],1[1],0[22],1[1],0[16],1[3],0[16],1[1],0[1],1[2],0[6],1[1],0[1],1[1],0[4],1[2],0[3],1[1],0[48],1[2],0[2],1[1],0[4],1[1],0[37]|end' ), + ('contact_email', '{{ADMIN_EMAIL}}'), + ('powered_btn', '1'); + +INSERT INTO {{TABLE_PREFIX}}page_text(page_id, namespace, page_text, char_tag) VALUES + ('Main_Page', 'Article', '{{MAIN_PAGE_CONTENT}}', ''); + +INSERT INTO {{TABLE_PREFIX}}logs(time_id, date_string, log_type, action, page_id, namespace, author, page_text) VALUES + ({{UNIX_TIME}}, 'DEPRECATED', 'page', 'edit', 'Main_Page', 'Article', '{{ADMIN_USER}}', '{{MAIN_PAGE_CONTENT}}'); + +INSERT INTO {{TABLE_PREFIX}}pages(page_order, name, urlname, namespace, special, visible, comments_on, protected, delvotes, delvote_ips) VALUES + (NULL, 'Main Page', 'Main_Page', 'Article', 0, 1, 1, 1, 0, ''); + +INSERT INTO {{TABLE_PREFIX}}themes(theme_id, theme_name, theme_order, default_style, enabled) VALUES + ('oxygen', 'Oxygen', 1, 'bleu.css', 1), + ('stpatty', 'St. Patty', 2, 'shamrock.css', 1); + +INSERT INTO {{TABLE_PREFIX}}users(user_id, username, password, email, real_name, user_level, theme, style, signature, reg_time, account_active, user_registration_ip) VALUES + (1, 'Anonymous', 'invalid-pass-hash', 'anonspam@enanocms.org', 'None', 1, 'oxygen', 'bleu', '', 0, 0, '{{IP_ADDRESS}}'), + (2, '{{ADMIN_USER}}', '{{ADMIN_PASS}}', '{{ADMIN_EMAIL}}', '{{REAL_NAME}}', 9, 'oxygen', 'bleu', '', UNIX_TIMESTAMP(), 1, '{{IP_ADDRESS}}'); + +INSERT INTO {{TABLE_PREFIX}}users_extra(user_id) VALUES + (2); + +INSERT INTO {{TABLE_PREFIX}}ranks(rank_id, rank_title, rank_style) VALUES + (1, 'user_rank_member', ''), + (2, 'user_rank_mod', 'font-weight: bold; color: #00AA00;'), + (3, 'user_rank_admin', 'font-weight: bold; color: #AA0000;'); + +INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type,system_group) VALUES(1, 'Everyone', 3, 1), + (2,'Administrators',3,1), + (3,'Moderators',3,1); + +INSERT INTO {{TABLE_PREFIX}}group_members(group_id,user_id,is_mod) VALUES(2, 2, 1); + +INSERT INTO {{TABLE_PREFIX}}acl(target_type,target_id,page_id,namespace,rules) VALUES + (1,2,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=4;clear_logs=4;vote_delete=4;vote_reset=4;delete_page=4;tag_create=4;tag_delete_own=4;tag_delete_other=4;set_wiki_mode=4;password_set=4;password_reset=4;mod_misc=4;edit_cat=4;even_when_protected=4;upload_files=4;upload_new_version=4;create_page=4;html_in_pages=4;php_in_pages={{ADMIN_EMBED_PHP}};edit_acl=4;'), + (1,3,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=3;clear_logs=2;vote_delete=4;vote_reset=4;delete_page=4;set_wiki_mode=2;password_set=2;password_reset=2;mod_misc=2;edit_cat=4;even_when_protected=4;upload_files=2;upload_new_version=3;create_page=3;php_in_pages=2;edit_acl=2;'); + +INSERT INTO {{TABLE_PREFIX}}sidebar(item_id, item_order, sidebar_id, block_name, block_type, block_content) VALUES + (1, 1, 1, '{lang:sidebar_title_navigation}', 1, '[[Main_Page|{lang:sidebar_btn_home}]]'), + (2, 2, 1, '{lang:sidebar_title_tools}', 1, '[[$NS_SPECIAL$CreatePage|{lang:sidebar_btn_createpage}]]\n[[$NS_SPECIAL$UploadFile|{lang:sidebar_btn_uploadfile}]]\n[[$NS_SPECIAL$SpecialPages|{lang:sidebar_btn_specialpages}]]\n{if auth_admin}\n$ADMIN_LINK$\n[[$NS_SPECIAL$EditSidebar|{lang:sidebar_btn_editsidebar}]]\n{/if}'), + (3, 3, 1, '$USERNAME$', 1, '[[$NS_USER$$USERNAME$|{lang:sidebar_btn_userpage}]]\n[[$NS_SPECIAL$Contributions/$USERNAME$|{lang:sidebar_btn_mycontribs}]]\n{if user_logged_in}\n[[$NS_SPECIAL$Preferences|{lang:sidebar_btn_preferences}]]\n[[$NS_SPECIAL$PrivateMessages|{lang:sidebar_btn_privatemessages}]]\n[[$NS_SPECIAL$Usergroups|{lang:sidebar_btn_groupcp}]]\n$THEME_LINK$\n{/if}\n{if user_logged_in}\n$LOGOUT_LINK$\n{else}\n[[$NS_SPECIAL$Register|{lang:sidebar_btn_register}]]\n$LOGIN_LINK$\n[[$NS_SPECIAL$Login/$NS_SPECIAL$PrivateMessages|{lang:sidebar_btn_privatemessages}]]\n{/if}'), + (4, 4, 1, '{lang:sidebar_title_search}', 1, '

$INPUT_AUTH$

'), + (5, 2, 2, '{lang:sidebar_title_links}', 4, 'Links'); + diff -r d823e49e2e4e -r c433348f3628 install/schemas/postgresql_stage1.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/postgresql_stage1.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,17 @@ +-- Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between +-- Version 1.1.1 +-- Copyright (C) 2006-2007 Dan Fuhry + +-- This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +-- 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 details. + +-- mysql_stage1.sql - MySQL installation schema, early stage + +CREATE TABLE {{TABLE_PREFIX}}config( + config_name varchar(63), + config_value text +); + diff -r d823e49e2e4e -r c433348f3628 install/schemas/postgresql_stage2.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/postgresql_stage2.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,386 @@ +-- Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between +-- Version 1.1.1 +-- Copyright (C) 2006-2007 Dan Fuhry + +-- This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +-- 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 details. + +-- postgresql_stage2.sql - PostgreSQL installation schema, main payload + +CREATE TABLE {{TABLE_PREFIX}}categories( + page_id varchar(64), + namespace varchar(64), + category_id varchar(64) +); + +CREATE TABLE {{TABLE_PREFIX}}comments( + comment_id SERIAL, + page_id text, + namespace text, + subject text, + comment_data text, + name text, + approved smallint DEFAULT 1, + user_id int NOT NULL DEFAULT -1, + time int NOT NULL DEFAULT 0, + ip_address varchar(39), + PRIMARY KEY ( comment_id ) +); + +CREATE TABLE {{TABLE_PREFIX}}logs( + log_id SERIAL, + log_type varchar(16), + action varchar(16), + time_id int NOT NULL DEFAULT '0', + date_string varchar(63), + page_id text, + namespace text, + page_text text, + char_tag varchar(40), + author varchar(63), + edit_summary text, + minor_edit smallint, + is_draft smallint NOT NULL DEFAULT 0, + PRIMARY KEY ( log_id ) +); + +CREATE TABLE {{TABLE_PREFIX}}page_text( + page_id varchar(255), + namespace varchar(16) NOT NULL DEFAULT 'Article', + page_text text, + char_tag varchar(63) +); + +CREATE TABLE {{TABLE_PREFIX}}pages( + page_order int, + name varchar(255), + urlname varchar(255), + namespace varchar(16) NOT NULL DEFAULT 'Article', + special smallint DEFAULT '0', + visible smallint DEFAULT '1', + comments_on smallint DEFAULT '1', + protected smallint NOT NULL DEFAULT 0, + wiki_mode smallint NOT NULL DEFAULT 2, + delvotes int NOT NULL DEFAULT 0, + password varchar(40) NOT NULL DEFAULT '', + delvote_ips text DEFAULT NULL +); + +CREATE TABLE {{TABLE_PREFIX}}session_keys( + session_key varchar(32), + salt varchar(32), + user_id int, + auth_level smallint NOT NULL DEFAULT '0', + source_ip varchar(10) DEFAULT '0x7f000001', + time bigint DEFAULT '0' +); + +CREATE TABLE {{TABLE_PREFIX}}themes( + theme_id varchar(63), + theme_name text, + theme_order smallint NOT NULL DEFAULT '1', + default_style varchar(63) NOT NULL DEFAULT '', + enabled smallint NOT NULL DEFAULT '1', + group_list text DEFAULT NULL, + group_policy varchar(5) NOT NULL DEFAULT 'deny', + CHECK (group_policy IN ('allow', 'deny')) +); + +CREATE TABLE {{TABLE_PREFIX}}users( + user_id SERIAL, + username text, + password varchar(255), + email text, + real_name text, + user_level smallint NOT NULL DEFAULT 2, + theme varchar(64) NOT NULL DEFAULT 'bleu.css', + style varchar(64) NOT NULL DEFAULT 'DEFAULT', + signature text, + reg_time int NOT NULL DEFAULT 0, + account_active smallint NOT NULL DEFAULT 0, + activation_key varchar(40) NOT NULL DEFAULT 0, + old_encryption smallint NOT NULL DEFAULT 0, + temp_password text, + temp_password_time int NOT NULL DEFAULT 0, + user_coppa smallint NOT NULL DEFAULT 0, + user_lang smallint NOT NULL, + user_has_avatar smallint NOT NULL, + avatar_type varchar(3) NOT NULL, + user_registration_ip varchar(39), + user_rank int NOT NULL DEFAULT 1, + user_timezone int NOT NULL DEFAULT 0, + CHECK (avatar_type IN ('jpg', 'png', 'gif')), + PRIMARY KEY (user_id) +); + +CREATE TABLE {{TABLE_PREFIX}}users_extra( + user_id int NOT NULL, + user_aim varchar(63), + user_yahoo varchar(63), + user_msn varchar(255), + user_xmpp varchar(255), + user_homepage text, + user_location text, + user_job text, + user_hobbies text, + email_public smallint NOT NULL DEFAULT 0, + PRIMARY KEY ( user_id ) +); + +CREATE TABLE {{TABLE_PREFIX}}banlist( + ban_id SERIAL, + ban_type smallint, + ban_value varchar(64), + is_regex smallint DEFAULT 0, + reason text, + PRIMARY KEY ( ban_id ) +); + +CREATE TABLE {{TABLE_PREFIX}}files( + file_id SERIAL, + time_id int NOT NULL, + page_id varchar(63) NOT NULL, + filename varchar(127) DEFAULT NULL, + size bigint NOT NULL, + mimetype varchar(63) DEFAULT NULL, + file_extension varchar(8) DEFAULT NULL, + file_key varchar(32) NOT NULL, + PRIMARY KEY (file_id) +); + +CREATE TABLE {{TABLE_PREFIX}}buddies( + buddy_id SERIAL, + user_id int, + buddy_user_id int, + is_friend smallint NOT NULL DEFAULT '1', + PRIMARY KEY (buddy_id) +); + +CREATE TABLE {{TABLE_PREFIX}}privmsgs( + message_id SERIAL, + message_from varchar(63), + message_to varchar(255), + date int, + subject varchar(63), + message_text text, + folder_name varchar(63), + message_read smallint NOT NULL DEFAULT 0, + PRIMARY KEY (message_id) +); + +CREATE TABLE {{TABLE_PREFIX}}sidebar( + item_id SERIAL, + item_order smallint NOT NULL DEFAULT 0, + item_enabled smallint NOT NULL DEFAULT 1, + sidebar_id smallint NOT NULL DEFAULT 1, + block_name varchar(63) NOT NULL, + block_type smallint NOT NULL DEFAULT 0, + block_content text, + PRIMARY KEY ( item_id ) +); + +CREATE TABLE {{TABLE_PREFIX}}hits( + hit_id SERIAL, + username varchar(63) NOT NULL, + time int NOT NULL DEFAULT 0, + page_id varchar(63), + namespace varchar(63), + PRIMARY KEY ( hit_id ) +); + +CREATE TABLE {{TABLE_PREFIX}}search_index( + word varchar(64) NOT NULL, + page_names text, + PRIMARY KEY ( word ) +); + +CREATE TABLE {{TABLE_PREFIX}}groups( + group_id SERIAL, + group_name varchar(64), + group_type smallint NOT NULL DEFAULT 1, + PRIMARY KEY ( group_id ), + system_group smallint NOT NULL DEFAULT 0 +); + +CREATE TABLE {{TABLE_PREFIX}}group_members( + member_id SERIAL, + group_id int NOT NULL, + user_id int NOT NULL, + is_mod smallint NOT NULL DEFAULT 0, + pending smallint NOT NULL DEFAULT 0, + PRIMARY KEY ( member_id ) +); + +CREATE TABLE {{TABLE_PREFIX}}acl( + rule_id SERIAL, + target_type smallint NOT NULL, + target_id int NOT NULL, + page_id varchar(255), + namespace varchar(24), + rules text, + PRIMARY KEY ( rule_id ) +); + +-- Added in 1.0.1 + +CREATE TABLE {{TABLE_PREFIX}}page_groups( + pg_id SERIAL, + pg_type smallint NOT NULL DEFAULT 1, + pg_name varchar(255) NOT NULL DEFAULT '', + pg_target varchar(255) DEFAULT NULL, + PRIMARY KEY ( pg_id ) +); + +-- Added in 1.0.1 + +CREATE TABLE {{TABLE_PREFIX}}page_group_members( + pg_member_id SERIAL, + pg_id int NOT NULL, + page_id varchar(63) NOT NULL, + namespace varchar(63) NOT NULL DEFAULT 'Article', + PRIMARY KEY ( pg_member_id ) +); + +-- Added in 1.0.1 + +CREATE TABLE {{TABLE_PREFIX}}tags( + tag_id SERIAL, + tag_name varchar(63) NOT NULL DEFAULT 'bla', + page_id varchar(255) NOT NULL, + namespace varchar(255) NOT NULL, + user_id int NOT NULL DEFAULT 1, + PRIMARY KEY ( tag_id ) +); + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}lockout( + id SERIAL, + ipaddr varchar(40) NOT NULL, + action varchar(20) NOT NULL DEFAULT 'credential', + timestamp int NOT NULL DEFAULT 0, + CHECK ( action IN ('credential', 'level') ) +); + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}language( + lang_id SERIAL, + lang_code varchar(16) NOT NULL, + lang_name_DEFAULT varchar(64) NOT NULL, + lang_name_native varchar(64) NOT NULL, + last_changed int NOT NULL DEFAULT 0 +); + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}language_strings( + string_id SERIAL, + lang_id int NOT NULL, + string_category varchar(32) NOT NULL, + string_name varchar(64) NOT NULL, + string_content text NOT NULL +); + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}ranks( + rank_id SERIAL, + rank_title varchar(63) NOT NULL DEFAULT '', + rank_style varchar(255) NOT NULL DEFAULT '' +); + +-- Added in 1.1.1 + +CREATE TABLE {{TABLE_PREFIX}}captcha( + code_id SERIAL, + session_id varchar(40) NOT NULL DEFAULT '', + code varchar(64) NOT NULL DEFAULT '', + session_data text, + source_ip varchar(39), + user_id int +); + +-- Added in 1.1.3 +-- Storing obscenely huge integers as strings since that's how php processes them. + +CREATE TABLE {{TABLE_PREFIX}}diffiehellman ( + key_id SERIAL, + private_key text, + public_key text, + PRIMARY KEY ( key_id ) +); + +INSERT INTO {{TABLE_PREFIX}}config(config_name, config_value) VALUES + ('site_name', '{{SITE_NAME}}'), + ('main_page', 'Main_Page'), + ('site_desc', '{{SITE_DESC}}'), + ('wiki_mode', '{{WIKI_MODE}}'), + ('wiki_edit_notice', '0'), + ('sflogo_enabled', '0'), + ('sflogo_groupid', ''), + ('sflogo_type', '1'), + ('w3c_vh32', '0'), + ('w3c_vh40', '0'), + ('w3c_vh401', '0'), + ('w3c_vxhtml10', '0'), + ('w3c_vxhtml11', '0'), + ('w3c_vcss', '0'), + ('approve_comments', '0'), + ('enable_comments', '1'), + ('plugin_SpecialAdmin.php', '1'), + ('plugin_SpecialPageFuncs.php', '1'), + ('plugin_SpecialUserFuncs.php', '1'), + ('plugin_SpecialCSS.php', '1'), + ('copyright_notice', '{{COPYRIGHT}}'), + ('wiki_edit_notice_text', '== Why can I edit this page? ==\n\nEveryone can edit almost any page in this website. This concept is called a wiki. It gives everyone the opportunity to make a change for the best. While some spam and vandalism may occur, it is believed that most contributions will be legitimate and helpful.\n\nFor security purposes, a history of all page edits is kept, and administrators are able to restore vandalized or spammed pages with just a few clicks.'), + ('cache_thumbs', '{{ENABLE_CACHE}}'), + ('max_file_size', '256000'),('enano_version', '{{VERSION}}'),( 'allowed_mime_types', 'cbf:len=185;crc=55fb6f14;data=0[1],1[4],0[3],1[1],0[22],1[1],0[16],1[3],0[16],1[1],0[1],1[2],0[6],1[1],0[1],1[1],0[4],1[2],0[3],1[1],0[48],1[2],0[2],1[1],0[4],1[1],0[37]|end' ), + ('contact_email', '{{ADMIN_EMAIL}}'), + ('powered_btn', '1'); + +INSERT INTO {{TABLE_PREFIX}}page_text(page_id, namespace, page_text, char_tag) VALUES + ('Main_Page', 'Article', '{{MAIN_PAGE_CONTENT}}', ''); + +INSERT INTO {{TABLE_PREFIX}}logs(time_id, date_string, log_type, action, page_id, namespace, author, page_text) VALUES + ({{UNIX_TIME}}, 'DEPRECATED', 'page', 'edit', 'Main_Page', 'Article', '{{ADMIN_USER}}', '{{MAIN_PAGE_CONTENT}}'); + +INSERT INTO {{TABLE_PREFIX}}pages(page_order, name, urlname, namespace, special, visible, comments_on, protected, delvotes, delvote_ips) VALUES + (NULL, 'Main Page', 'Main_Page', 'Article', 0, 1, 1, 1, 0, ''); + +INSERT INTO {{TABLE_PREFIX}}themes(theme_id, theme_name, theme_order, DEFAULT_style, enabled) VALUES + ('oxygen', 'Oxygen', 1, 'bleu.css', 1), + ('stpatty', 'St. Patty', 2, 'shamrock.css', 1); + +INSERT INTO {{TABLE_PREFIX}}users(user_id, username, password, email, real_name, user_level, theme, style, signature, reg_time, account_active, user_registration_ip, user_lang, user_has_avatar, avatar_type) VALUES + (1, 'Anonymous', 'invalid-pass-hash', 'anonspam@enanocms.org', 'None', 1, 'oxygen', 'bleu', '', 0, 0, '', 0, 0, 'png'), + (2, '{{ADMIN_USER}}', '{{ADMIN_PASS}}', '{{ADMIN_EMAIL}}', '{{REAL_NAME}}', 9, 'oxygen', 'bleu', '', {{UNIX_TIME}}, 1, '{{IP_ADDRESS}}', 0, 0, 'png'); + +INSERT INTO {{TABLE_PREFIX}}users_extra(user_id) VALUES + (2); + +INSERT INTO {{TABLE_PREFIX}}ranks(rank_id, rank_title, rank_style) VALUES + (1, 'user_rank_member', ''), + (2, 'user_rank_mod', 'font-weight: bold; color: #00AA00;'), + (3, 'user_rank_admin', 'font-weight: bold; color: #AA0000;'); + +INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type,system_group) VALUES(1, 'Everyone', 3, 1), + (2,'Administrators',3,1), + (3,'Moderators',3,1); + +INSERT INTO {{TABLE_PREFIX}}group_members(group_id,user_id,is_mod) VALUES(2, 2, 1); + +INSERT INTO {{TABLE_PREFIX}}acl(target_type,target_id,page_id,namespace,rules) VALUES + (1,2,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=4;clear_logs=4;vote_delete=4;vote_reset=4;delete_page=4;tag_create=4;tag_delete_own=4;tag_delete_other=4;set_wiki_mode=4;password_set=4;password_reset=4;mod_misc=4;edit_cat=4;even_when_protected=4;upload_files=4;upload_new_version=4;create_page=4;html_in_pages=4;php_in_pages={{ADMIN_EMBED_PHP}};edit_acl=4;'), + (1,3,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=3;clear_logs=2;vote_delete=4;vote_reset=4;delete_page=4;set_wiki_mode=2;password_set=2;password_reset=2;mod_misc=2;edit_cat=4;even_when_protected=4;upload_files=2;upload_new_version=3;create_page=3;php_in_pages=2;edit_acl=2;'); + +INSERT INTO {{TABLE_PREFIX}}sidebar(item_id, item_order, sidebar_id, block_name, block_type, block_content) VALUES + (1, 1, 1, '{lang:sidebar_title_navigation}', 1, '[[Main_Page|{lang:sidebar_btn_home}]]'), + (2, 2, 1, '{lang:sidebar_title_tools}', 1, '[[$NS_SPECIAL$CreatePage|{lang:sidebar_btn_createpage}]]\n[[$NS_SPECIAL$UploadFile|{lang:sidebar_btn_uploadfile}]]\n[[$NS_SPECIAL$SpecialPages|{lang:sidebar_btn_specialpages}]]\n{if auth_admin}\n$ADMIN_LINK$\n[[$NS_SPECIAL$EditSidebar|{lang:sidebar_btn_editsidebar}]]\n{/if}'), + (3, 3, 1, '$USERNAME$', 1, '[[$NS_USER$$USERNAME$|{lang:sidebar_btn_userpage}]]\n[[$NS_SPECIAL$Contributions/$USERNAME$|{lang:sidebar_btn_mycontribs}]]\n{if user_logged_in}\n[[$NS_SPECIAL$Preferences|{lang:sidebar_btn_preferences}]]\n[[$NS_SPECIAL$PrivateMessages|{lang:sidebar_btn_privatemessages}]]\n[[$NS_SPECIAL$Usergroups|{lang:sidebar_btn_groupcp}]]\n$THEME_LINK$\n{/if}\n{if user_logged_in}\n$LOGOUT_LINK$\n{else}\n[[$NS_SPECIAL$Register|{lang:sidebar_btn_register}]]\n$LOGIN_LINK$\n[[$NS_SPECIAL$Login/$NS_SPECIAL$PrivateMessages|{lang:sidebar_btn_privatemessages}]]\n{/if}'), + (4, 4, 1, '{lang:sidebar_title_search}', 1, '

$INPUT_AUTH$

'), + (5, 2, 2, '{lang:sidebar_title_links}', 4, 'Links'); + diff -r d823e49e2e4e -r c433348f3628 install/schemas/upgrade/1.1.1-1.1.2-mysql.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/upgrade/1.1.1-1.1.2-mysql.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,36 @@ +-- Enano CMS +-- Upgrade schema - Enano 1.1.1 - 1.1.2 + +ALTER TABLE {{TABLE_PREFIX}}logs ADD COLUMN log_id int(15) NOT NULL auto_increment, ADD PRIMARY KEY ( log_id ); +ALTER TABLE {{TABLE_PREFIX}}logs ADD COLUMN is_draft tinyint(1) NOT NULL DEFAULT 0; + +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_rank int(12) UNSIGNED NOT NULL DEFAULT 1, + ADD COLUMN user_timezone int(12) UNSIGNED NOT NULL DEFAULT 0; + +ALTER TABLE {{TABLE_PREFIX}}tags CHANGE user user_id mediumint(8) NOT NULL DEFAULT 1; +ALTER TABLE {{TABLE_PREFIX}}themes + ADD COLUMN group_list text DEFAULT NULL, + ADD COLUMN group_policy ENUM('allow', 'deny') NOT NULL DEFAULT 'deny'; + +CREATE TABLE {{TABLE_PREFIX}}ranks( + rank_id int(12) NOT NULL auto_increment, + rank_title varchar(63) NOT NULL DEFAULT '', + rank_style varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY ( rank_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +CREATE TABLE {{TABLE_PREFIX}}captcha( + code_id int(12) NOT NULL auto_increment, + session_id varchar(40) NOT NULL DEFAULT '', + code varchar(64) NOT NULL DEFAULT '', + session_data text, + source_ip varchar(39), + user_id int(12), + PRIMARY KEY ( code_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + +INSERT INTO {{TABLE_PREFIX}}ranks(rank_id, rank_title, rank_style) VALUES + (1, 'user_rank_member', ''), + (2, 'user_rank_mod', 'font-weight: bold; color: #00AA00;'), + (3, 'user_rank_admin', 'font-weight: bold; color: #AA0000;'); + diff -r d823e49e2e4e -r c433348f3628 install/schemas/upgrade/1.1.1-1.1.2-postgresql.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/upgrade/1.1.1-1.1.2-postgresql.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,35 @@ +-- Enano CMS +-- Upgrade schema - Enano 1.1.1 - 1.1.2 + +ALTER TABLE {{TABLE_PREFIX}}logs ADD COLUMN log_id SERIAL, ADD PRIMARY KEY ( log_id ); +ALTER TABLE {{TABLE_PREFIX}}logs ADD COLUMN is_draft smallint NOT NULL DEFAULT 0; + +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_rank int NOT NULL DEFAULT 1, + ADD COLUMN user_timezone int NOT NULL DEFAULT 0; +ALTER TABLE {{TABLE_PREFIX}}themes + ADD COLUMN group_list text DEFAULT NULL, + ADD COLUMN group_policy varchar(5) NOT NULL DEFAULT 'deny', + ADD CHECK (group_policy IN ('allow', 'deny')); + +CREATE TABLE {{TABLE_PREFIX}}ranks( + rank_id SERIAL, + rank_title varchar(63) NOT NULL DEFAULT '', + rank_style varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY ( rank_id ) +); + +CREATE TABLE {{TABLE_PREFIX}}captcha( + code_id SERIAL, + session_id varchar(40) NOT NULL DEFAULT '', + code varchar(64) NOT NULL DEFAULT '', + session_data text, + source_ip varchar(39), + user_id int(12), + PRIMARY KEY ( code_id ) +); + +INSERT INTO {{TABLE_PREFIX}}ranks(rank_id, rank_title, rank_style) VALUES + (1, 'user_rank_member', ''), + (2, 'user_rank_mod', 'font-weight: bold; color: #00AA00;'), + (3, 'user_rank_admin', 'font-weight: bold; color: #AA0000;'); + diff -r d823e49e2e4e -r c433348f3628 install/schemas/upgrade/1.1.2-1.1.3-mysql.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/upgrade/1.1.2-1.1.3-mysql.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,11 @@ +-- Enano CMS +-- Upgrade schema: 1.1.2 - 1.1.3 + +-- Storing obscenely huge integers as strings since that's how php processes them. + +CREATE TABLE {{TABLE_PREFIX}}diffiehellman ( + key_id int(12) NOT NULL auto_increment, + private_key text, + public_key text, + PRIMARY KEY ( key_id ) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; diff -r d823e49e2e4e -r c433348f3628 install/schemas/upgrade/1.1.2-1.1.3-postgresql.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/upgrade/1.1.2-1.1.3-postgresql.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,11 @@ +-- Enano CMS +-- Upgrade schema: 1.1.2 - 1.1.3 + +-- Storing obscenely huge integers as strings since that's how php processes them. + +CREATE TABLE {{TABLE_PREFIX}}diffiehellman ( + key_id SERIAL, + private_key text, + public_key text, + PRIMARY KEY ( key_id ) +); diff -r d823e49e2e4e -r c433348f3628 install/schemas/upgrade/migration/1.0-1.1-mysql.sql --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/upgrade/migration/1.0-1.1-mysql.sql Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,51 @@ +-- Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between +-- Version 1.1.1 +-- Copyright (C) 2006-2007 Dan Fuhry + +-- This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +-- 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 details. + +-- 1.0-1.1-mysql.sql - Enano 1.0.x to 1.1.x migration queries, MySQL + +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_lang smallint(5) NOT NULL; +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_has_avatar tinyint(1) NOT NULL; +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN avatar_type ENUM('jpg', 'png', 'gif') NOT NULL; +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_registration_ip varchar(39); +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_timezone int(12) NOT NULL DEFAULT 0; +ALTER TABLE {{TABLE_PREFIX}}comments ADD COLUMN ip_address varchar(39); + +CREATE TABLE {{TABLE_PREFIX}}lockout( + id int(12) NOT NULL auto_increment, + ipaddr varchar(40) NOT NULL, + action ENUM('credential', 'level') NOT NULL DEFAULT 'credential', + timestamp int(12) NOT NULL DEFAULT 0, + PRIMARY KEY ( id ) +) CHARACTER SET `utf8`; + +CREATE TABLE {{TABLE_PREFIX}}language( + lang_id smallint(5) NOT NULL auto_increment, + lang_code varchar(16) NOT NULL, + lang_name_default varchar(64) NOT NULL, + lang_name_native varchar(64) NOT NULL, + last_changed int(12) NOT NULL DEFAULT 0, + PRIMARY KEY ( lang_id ) +) CHARACTER SET `utf8`; + +CREATE TABLE {{TABLE_PREFIX}}language_strings( + string_id bigint(15) NOT NULL auto_increment, + lang_id smallint(5) NOT NULL, + string_category varchar(32) NOT NULL, + string_name varchar(64) NOT NULL, + string_content longtext NOT NULL, + PRIMARY KEY ( string_id ) +); + +UPDATE {{TABLE_PREFIX}}sidebar SET block_name = '{lang:sidebar_title_navigation}', block_type = 1, block_content = '[[Main_Page|{lang:sidebar_btn_home}]]' WHERE item_id = 1; +UPDATE {{TABLE_PREFIX}}sidebar SET block_name = '{lang:sidebar_title_tools}', block_type = 1, block_content = '[[$NS_SPECIAL$CreatePage|{lang:sidebar_btn_createpage}]]\n[[$NS_SPECIAL$UploadFile|{lang:sidebar_btn_uploadfile}]]\n[[$NS_SPECIAL$SpecialPages|{lang:sidebar_btn_specialpages}]]\n{if auth_admin}\n$ADMIN_LINK$\n[[$NS_SPECIAL$EditSidebar|{lang:sidebar_btn_editsidebar}]]\n{/if}' WHERE item_id = 2; +UPDATE {{TABLE_PREFIX}}sidebar SET block_name = '$USERNAME$', block_type = 1, block_content = '[[$NS_USER$$USERNAME$|{lang:sidebar_btn_userpage}]]\n[[$NS_SPECIAL$Contributions/$USERNAME$|{lang:sidebar_btn_mycontribs}]]\n{if user_logged_in}\n[[$NS_SPECIAL$Preferences|{lang:sidebar_btn_preferences}]]\n[[$NS_SPECIAL$PrivateMessages|{lang:sidebar_btn_privatemessages}]]\n[[$NS_SPECIAL$Usergroups|{lang:sidebar_btn_groupcp}]]\n$THEME_LINK$\n{/if}\n{if user_logged_in}\n$LOGOUT_LINK$\n{else}\n[[$NS_SPECIAL$Register|{lang:sidebar_btn_register}]]\n$LOGIN_LINK$\n[[$NS_SPECIAL$Login/$NS_SPECIAL$PrivateMessages|{lang:sidebar_btn_privatemessages}]]\n{/if}' WHERE item_id = 3; +UPDATE {{TABLE_PREFIX}}sidebar SET block_name = '{lang:sidebar_title_search}', block_type = 1, block_content = '

$INPUT_AUTH$

' WHERE item_id = 4; +UPDATE {{TABLE_PREFIX}}sidebar SET block_name = '{lang:sidebar_title_links}', block_type = 4, block_content = 'Links' WHERE item_id = 5; + diff -r d823e49e2e4e -r c433348f3628 install/schemas/upgrade/migration/1.0-1.1.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/schemas/upgrade/migration/1.0-1.1.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,50 @@ +$e"); + } + + $sql_parser->assign_vars(array( + 'TABLE_PREFIX' => table_prefix + )); + + $sql_list = $sql_parser->parse(); + foreach ( $sql_list as $sql ) + { + if ( !$db->sql_query($sql) ) + $db->_die(); + } + + // Install default language + $lang_id = 'eng'; + $lang_data =& $languages[$lang_id]; + $lang_dir = ENANO_ROOT . "/language/{$lang_data['dir']}/"; + // function install_language($lang_code, $lang_name_neutral, $lang_name_local, $lang_file = false) + install_language($lang_id, $lang_data['name_eng'], $lang_data['name'], $lang_dir . 'core.json'); + $lang_local = new Language($lang_id); + $lang_local->import($lang_dir . "tools.json"); + $lang_local->import($lang_dir . "user.json"); + $lang_local->import($lang_dir . "admin.json"); + + // This doesn't set to installer_enano_version() because it only + // migrates the database from 1.0.x to 1.1.x status and runs the + // core logic required to transform a 1.0.x installation into + // a 1.1.x installation. Thus, when upgrading, the upgrade script + // still needs to run all later upgrade schema files in addition + // to this migration code. + setConfig('enano_version', '1.1.1'); + + return true; +} + diff -r d823e49e2e4e -r c433348f3628 install/upgrade.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/install/upgrade.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,262 @@ +__construct('Enano upgrader', false); +} +$stg_welcome = $ui->add_stage('Welcome', true); +$stg_confirm = $ui->add_stage('Confirmation', true); +$stg_upgrade = $ui->add_stage('Perform upgrade', true); +$stg_finish = $ui->add_stage('Finish', true); +$stg_php4 = $ui->add_stage('PHP4 compatibility notice', false); + +if ( version_compare(PHP_VERSION, '5.0.0', '<') || isset($_GET['debug_warn_php4']) ) +{ + $ui->set_visible_stage($stg_php4); + $ui->step = ''; + + $ui->show_header(); + + // This isn't localized because all localization code is dependent on + // PHP 5 (loading lang.php will throw a parser error under PHP4). This + // one message probably doesn't need to be localized anyway. + + ?> +

+ Your server doesn't have support for PHP 5. +

+

+ PHP 5 is the latest version of the language on which Enano was built. Its many new features have been available since early 2004, yet + many web hosts have not migrated to it because of the work involved. In 2007, Zend Corporation announced that support for the aging + PHP 4.x would be discontinued at the end of the year. An initiative called GoPHP5 was started to + encourage web hosts to migrate to PHP 5. +

+

+ Because of the industry's decision to not support PHP 4 any longer, the Enano team decided that it was time to begin using the powerful + features of PHP 5 at the expense of PHP 4 compatibility. Therefore, this version of Enano cannot be installed on your server until it + is upgraded to at least PHP 5.0.0, and preferably the latest available version. + +

+

+ If you need to use Enano but can't upgrade your PHP because you're on a shared or reseller hosting service, you can use the + 1.0.x series of Enano on your site. While the Enano team attempts to make this + older series work on PHP 4, official support is not provided for installations of Enano on PHP 4. +

+ show_footer(); + exit(0); +} + +// Version check +if ( enano_version() == installer_enano_version() ) +{ + $ui->show_header(); + echo '

Already upgraded

' . '

You don\'t need to migrate, you\'re already on crack the 1.1 platform.

'; + $ui->show_footer(); + exit(); +} + +// Start session manager +$session->start(); +if ( !$session->user_logged_in || ( $session->user_logged_in && $session->auth_level < USER_LEVEL_ADMIN ) ) +{ + if ( isset($_POST['do_login']) ) + { + if ( !$session->user_logged_in ) + { + $result = $session->login_without_crypto($_POST['username'], $_POST['password'], false, USER_LEVEL_MEMBER); + } + $result = $session->login_without_crypto($_POST['username'], $_POST['password'], false, USER_LEVEL_ADMIN); + if ( $result['success'] ) + { + header('HTTP/1.1 302 Some kind of redirect with implied no content'); + header('Location: ' . scriptPath . '/install/' . $session->append_sid('upgrade.php')); + exit(); + } + } + + $ui->show_header(); + + ?> +

Authentication needed

+ '; + + if ( isset($result) ) + { + echo 'Session manager returned error: ' . $result['error'] . ''; + } + + ?> +

You need an active admin session to continue.

+

+ Username:   
+ Password:   
+ +

+ '; + + $ui->show_footer(); + exit(); +} + +if ( isset($_GET['stage']) && @$_GET['stage'] == 'pimpmyenano' ) +{ + $ui->set_visible_stage($stg_upgrade); +} +else +{ + $ui->set_visible_stage($stg_confirm); +} + +// The real migration code +$ui->show_header(); + +if ( isset($_GET['stage']) && @$_GET['stage'] == 'pimpmyenano' ) +{ + // Do we need to run the migration first? + if ( substr(enano_version(), 0, 4) != '1.1.' ) + { + require(ENANO_ROOT . '/install/upgrade/migration/1.0-1.1.php'); + $result = MIGRATE(); + if ( !$result ) + { + echo 'Migration failed, there should be an error message above.'; + $ui->show_footer(); + exit; + } + } + // Main upgrade stage + + // Init vars + $version_flipped = array_flip($enano_versions); + $version_curr = enano_version(); + $version_target = installer_enano_version(); + + // Calculate which scripts to run + if ( !isset($version_flipped[$version_curr]) ) + { + echo '

ERROR: Unsupported version

'; + $ui->show_footer(); + exit; + } + if ( !isset($version_flipped[$version_target]) ) + { + echo '

ERROR: Upgrader doesn\'t support its own version

'; + $ui->show_footer(); + exit; + } + $upg_queue = array(); + for ( $i = $version_flipped[$version_curr]; $i < $version_flipped[$version_target]; $i++ ) + { + if ( !isset($enano_versions[$i + 1]) ) + { + echo '

ERROR: Unsupported intermediate version

'; + $ui->show_footer(); + exit; + } + $ver_this = $enano_versions[$i]; + $ver_next = $enano_versions[$i + 1]; + $upg_queue[] = array($ver_this, $ver_next); + } + + // Verify that all upgrade scripts are usable + foreach ( $upg_queue as $verset ) + { + $file = ENANO_ROOT . "/install/schemas/upgrade/{$verset[0]}-{$verset[1]}-$dbdriver.sql"; + if ( !file_exists($file) ) + { + echo "

ERROR: Couldn't find required schema file: $file

"; + $ui->show_footer(); + exit; + } + } + // Perform upgrade + foreach ( $upg_queue as $verset ) + { + $file = ENANO_ROOT . "/install/schemas/upgrade/{$verset[0]}-{$verset[1]}-$dbdriver.sql"; + try + { + $parser = new SQL_Parser($file); + } + catch(Exception $e) + { + die("
$e
"); + } + + $parser->assign_vars(array( + 'TABLE_PREFIX' => table_prefix + )); + + $sql_list = $parser->parse(); + + foreach ( $sql_list as $sql ) + { + if ( !$db->sql_query($sql) ) + $db->_die(); + } + + // Is there an additional script (logic) to be run after the schema? + $postscript = ENANO_ROOT . "/install/schemas/upgrade/{$verset[0]}-{$verset[1]}.php"; + if ( file_exists($postscript) ) + @include($postscript); + + // The advantage of calling setConfig on the system version here? + // Simple. If the upgrade fails, it will pick up from the last + // version, not try to start again from the beginning. This will + // still cause errors in most cases though. Eventually we probably + // need some sort of query-numbering system that tracks in-progress + // upgrades. + + setConfig('enano_version', $verset[1]); + } + echo '

All done!

'; +} +else +{ + ?> +

Nothing's really implemented for now except the actual migration code, which is not very smart. Just do the upgrade and get it over with.

+ show_footer(); + diff -r d823e49e2e4e -r c433348f3628 language/english/admin.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/language/english/admin.json Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,913 @@ +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 + * Copyright (C) 2006-2007 Dan Fuhry + * + * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + * + * 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 details. + */ + +var enano_lang = { + categories: [ + 'meta', 'adm', 'acl', 'adminusers', + 'acphome', 'acpgc', 'acpup', 'acpft', 'acppl', 'acppm', 'acped', 'acpdb', 'acplm', 'acppg', 'acpum', 'acpug', 'acpcp', 'acpmm', 'acpsl', + 'acpbc', 'acplo', 'acptm', 'sbedit', + ], + strings: { + meta: { + adm: 'Administration panel nav menu', + acl: 'Access control list editor', + acphome: 'ACP: Home', + acpgc: 'ACP: General configuration', + acpup: 'ACP: File uploads', + acpft: 'ACP: Allowed file types', + acppl: 'ACP: Manage plugins', + acpdb: 'ACP: Database backup', + acplm: 'ACP: Language manager', + acppm: 'ACP: Manage pages', + acped: 'ACP: Edit page content', + acptm: 'ACP: Theme manager', + acppg: 'ACP: Page groups', + acpum: 'ACP: User management', + acpug: 'ACP: User group management', + acpcp: 'ACP: COPPA support', + acpmm: 'ACP: Mass e-mail', + acpsl: 'ACP: Security log', + acpbc: 'ACP: Ban control', + acplo: 'ACP: Logout page', + sbedit: 'Sidebar editor', + }, + adm: { + page_tagline: 'Administer your Enano website.', + + cat_general: 'General', + cat_content: 'Content', + cat_appearance: 'Appearance', + cat_users: 'Users', + cat_security: 'Security', + cat_plugins: 'Plugin configuration', + + page_general_config: 'General configuration', + page_file_uploads: 'File uploads', + page_file_types: 'Allowed file types', + page_plugins: 'Manage plugins', + page_db_backup: 'Backup database', + page_lang_manager: 'Language manager', + + page_manager: 'Manage pages', + page_editor: 'Edit page content', + page_pg_groups: 'Manage page groups', + + page_themes: 'Manage themes', + + page_users: 'Manage users', + page_user_groups: 'Edit user groups', + page_coppa: 'COPPA support', + page_mass_email: 'Mass e-mail', + + page_security_log: 'Security log', + page_ban_control: 'Ban control', + + btn_home: 'Administration panel home', + btn_logout: 'Log out of admin panel', + btn_keepalive_off: 'Turn on keep-alive', + btn_keepalive_on: 'Turn off keep-alive', + btn_keepalive_about: 'About keep-alive', + btn_keepalive_loading: 'Loading keep-alive button...', + + err_not_auth_title: 'Error: Not authenticated', + err_not_auth_body: 'It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.', + }, + acl: { + err_access_denied: 'You are not authorized to view or edit access control lists.', + err_missing_template: 'It seems that (a) the file acledit.tpl is missing from this theme, and (b) the JSON response is working.', + err_user_not_found: 'The username you entered was not found.', + err_bad_group_id: 'The group ID you submitted is not valid.', + err_demo: 'Editing access control lists is disabled in the administration demo.', + err_zero_list: 'Supplied rule list has a length of zero', + err_pleaseselect_targettype: 'Please select a target type.', + err_pleaseselect_username: 'Please enter a username.', + + radio_usergroup: 'A usergroup', + radio_user: 'A specific user', + radio_scope_thispage: 'Only this page', + radio_scope_wholesite: 'The entire website', + radio_scope_pagegroup: 'A group of pages', + + lbl_scope: 'What should this access rule control?', + lbl_welcome_title: 'Manage page access', + lbl_welcome_body: 'Please select who should be affected by this access rule.', + lbl_editwin_title_create: 'Create access rule', + lbl_editwin_title_edit: 'Editing permissions', + lbl_editwin_body: 'This panel allows you to edit what the %target_type% "%target%" can do on %scope_type%. Unless you set a permission to "Deny", these permissions may be overridden by other rules.', + lbl_deleterule: 'Delete this rule', + lbl_save_success_title: 'Permissions updated', + lbl_save_success_body: 'The permissions for %target_name% on this page have been updated successfully. If you changed permissions that affect your user account, you may not see changes until you reload the page.', + lbl_delete_success_title: 'Rule deleted', + lbl_delete_success_body: 'The access rules for %target_name% on this page have been deleted.', + lbl_field_inherit: 'Inherit', + lbl_field_deny: 'Deny', + lbl_field_disallow: 'Disallow', + lbl_field_wikimode: 'Wiki mode', + lbl_field_allow: 'Allow', + lbl_help: '

+ Permission types: +

+
    +
  • Allow means that the user is allowed to access the item
  • +
  • Wiki mode means the user can access the item if wiki mode is active (per-page wiki mode is taken into account)
  • +
  • Disallow means the user is denied access unless something allows it.
  • +
  • Deny means that the user is denied access to the item. This setting overrides all other permissions.
  • +
  • Inherit forces the permission to be unset and thus inherited from the defaults. Setting every permission to Inherit is the same as deleting the rule.
  • +
', + + scope_type_wholesite: 'this entire site', + scope_type_thispage: 'this page', + scope_type_pagegroup: 'this group of pages', + + target_type_user: 'user', + target_type_group: 'group', + + msg_guest_howto: 'To edit permissions for guests, select "a specific user", and enter Anonymous as the username.', + msg_deleterule_confirm: 'Do you really want to delete this rule?', + msg_closeacl_confirm: 'Do you really want to close the ACL manager?', + + btn_success_dismiss: 'dismiss', + btn_success_close: 'close manager', + btn_deleterule: 'Delete rule', + btn_createrule: 'Create rule', + btn_returnto_editor: 'Return to ACL editor', + btn_returnto_userscope: 'Return to user/scope selection', + }, + acphome: { + heading_main: 'Welcome to Runt, the Enano administration panel.', + welcome_line1: 'Thank you for choosing Enano as your CMS. This screen allows you to see some information about your website, plus some details about how your site is doing statistically.', + welcome_line2: 'Using the links on the left you can control every aspect of your website\'s look and feel, plus you can manage users, work with pages, and install plugins to make your Enano installation even better.', + msg_demo_title: 'Enano is running in demo mode.', + msg_demo_body: 'If you borked something up, or if you\'re done testing, you can reset this site. The site is reset automatically once every two hours. When a reset is performed, all custom modifications to the site are lost and replaced with default values.', + msg_install_files: 'NOTE: It appears that your install.php and/or schema.sql files still exist. It is HIGHLY RECOMMENDED that you delete or rename these files, to prevent getting your server hacked.', + heading_updates: 'Check for updates', + msg_updates_info: 'Periodically, new releases of Enano will be made available. Click the button below to check for updates to Enano. During this process, a request will be sent to the Enano CMS server (germantown.enanocms.org) over HTTP for an XML file containing a list of the latest releases. No information about your Enano installation will be transmitted.', + btn_check_updates: 'Check for updates', + msg_inactive_users_one: 'It appears that 1 user is awaiting account activation. You can activate the account by going to the User Manager.', + msg_inactive_users_plural: 'It appears that %num_users% users are awaiting account activation. You can activate those accounts by going to the User Manager.', + heading_top_pages: 'Most requested pages', + th_toppages_page: 'Page', + th_toppages_hits: 'Hits', + heading_seclog: 'Security log', + msg_seclog_info: 'This list shows the 5 most recent actions/attempted actions performed by administrators on this site. This also includes attempts to view blocked pages and use the administration panel without appropriate privileges. You can view a complete list using the link below.', + btn_seclog_full: 'Full security log', + }, + acpgc: { + err_avatar_dir_invalid: 'You have entered an invalid avatar directory.', + msg_save_success: 'Your changes to the site configuration have been saved.', + + // Section: global site options + heading_main: 'Global site options', + heading_submain: 'These options control the entire site.', + field_site_name: 'Site name:', + field_site_desc: 'Site description:', + field_main_page: 'Main page:', + field_copyright: 'Copyright notice shown on pages:', + field_copyright_hint: 'Hint: If you\'re using Windows, you can make a "©" symbol by holding ALT and pressing 0169 on the numeric keypad.', + field_contactemail: 'Contact e-mail', + field_contactemail_hint: 'All e-mail sent from this site will appear to have come from the address shown here.', + + // Section: wiki mode + heading_wikimode: 'Wiki mode', + field_wikimode_intro: 'Enano can also act as a wiki, meaning anyone can edit and create pages. To enable Wiki Mode, check the box to the right.', + field_wikimode_info_sanitize: 'In Wiki Mode, certain HTML tags such as <script> and <object> are disabled, and all PHP code is disabled, except if the person editing the page is an administrator.', + field_wikimode_info_history: 'Also, Enano keeps complete page history, which makes restoring vandalized pages easy. You can also protect pages so that they cannot be edited.', + field_wikimode: 'Enable Wiki Mode', + field_editnotice_title: 'Edit page notice', + field_editnotice_info: 'When Wiki Mode is enabled, anyone can edit pages. Check the box below and enter a message to display it whenever the page editor is opened. Administrators often use this field to display a legal disclaimer or a notice of what license the user agrees to submit their content under.', + field_editnotice: 'Show a message whenever pages are edited', + field_edit_require_captcha_title: 'Require visual confirmation for guests editing pages', + field_edit_require_captcha_hint: 'If this is enabled, guests will be asked to enter a visual confirmation code before saving changes to a page.', + field_edit_require_captcha: 'Require guests to complete a CAPTCHA when editing pages', + + // Section: statistics and hit counting + heading_stats: 'Statistics and hit counting', + stats_intro: 'Enano has the ability to show statistics for every page on the site. This allows you to keep very close track of who is visiting your site, and from where.', + stats_hint_privacy: 'Unfortunately, some users don\'t like being logged. For this reason, you should state clearly what is logged (usually the username or IP address, current time, page name, and referer URL) in your privacy policy. If your site is primarily geared towards children, and you are a United States citizen, you are required to have a privacy policy stating exactly what is being logged under the terms of the Childrens\' Online Privacy Protection Act.', + field_stats_enable: 'Log all page hits', + field_stats_hint: 'This excludes special and administration pages.', + + // Section: comment system + heading_comments: 'Comment system', + field_enable_comments: 'Enable the comment system', + field_approve_comments: 'Require approval before article comments can be shown', + field_comment_allow_guests: 'Allow guests to post comments', + field_comment_allow_guests_yes: 'Yes', + field_comment_allow_guests_captcha: 'Require visual confirmation', + field_comment_allow_guests_no: 'No (require login)', + + // Section: disable site + heading_disablesite: 'Disable all site access', + field_disablesite_hint: 'Disabling the site allows you to work on the site without letting non-administrators see or use it.', + field_disablesite: 'Disable this site', + field_disablesite_message: 'Message to show to users:', + + // Main section: users and communication + heading_users: 'Users and communication', + + // Section: account activation + heading_activate: 'User account activation', + activate_intro_line1: 'If you would like to require users to confirm their e-mail addresses by way of account activation, you can enable this behavior here. If this option is set to "None", users will be able to register and use this site without confirming their e-mail addresses. If this option is set to "User", users will automatically be sent e-mails upon registration with a link to activate their accounts. And lastly, if this option is set to "Admin", users\' accounts will not be active until an administrator activates the account.', + activate_intro_line2: 'You may also disable registration completely if needed.', + activate_intro_sfnet_warning: 'Note: because of abuse by project administrators, sending account activation e-mails will not work on SourceForge.net servers.', + field_activate: 'Account activation:', + field_activate_disable: 'Disable registration', + field_activate_none: 'None', + field_activate_user: 'User', + field_activate_admin: 'Admin', + + // Section: terms of use (TOU) + heading_tou: 'Registration agreement/Terms of Use', + field_tou: 'Registration agreement', + field_tou_hint: 'The text you enter here will be displayed to users upon any attempt to create an account on this site.', + + // Section: account lockouts + heading_lockout: 'Account lockouts', + lockout_intro: 'Configure Enano to prevent or restrict logins for a specified period of time if a user enters an incorrect password a specific number of times.', + field_lockout_threshold: 'Lockout threshold:', + field_lockout_threshold_hint: 'How many times can a user enter wrong credentials before a lockout goes into effect?', + field_lockout_duration: 'Lockout duration:', + field_lockout_duration_hint: 'This is how long an account lockout should last, in minutes.', + field_lockout_policy: 'Lockout policy:', + field_lockout_policy_hint: 'What should be done when a lockout goes into effect?', + field_lockout_policy_nothing: 'Don\'t do anything', + field_lockout_policy_captcha: 'Require visual confirmation', + field_lockout_policy_lockout: 'Prevent all login attempts', + + // Section: password strength + heading_passstrength: 'Password strength', + field_passstrength_title: 'Enable password strength analysis', + field_passstrength_hint: 'This should be enabled in most cases. When this is enabled, a strength meter and a numerical score will be displayed wherever a password can be changed.', + field_passstrength: 'Enabled', + field_passminimum_title: 'Minimum strength score', + field_passminimum_hint: 'This is the lowest score a password will be allowed to have. -10 will allow any password. A score of under -3 is considered weak, under 1 is fair, under 4 is good, under 10 is strong, and 10 and above are very strong. The scale is open-ended. This only has an effect if the meter is enabled above.', + + // Section: e-mail + heading_email: 'E-mail sent from the site', + field_email_method: 'E-mail sending method:', + field_email_method_hint: 'Try using the built-in e-mail method first. If that doesn\'t work, you will need to enter valid SMTP information here.', + field_email_method_builtin: 'PHP\'s built-in mail() function', + field_email_method_smtp: 'Use an external SMTP server', + field_email_smtp_hostname: 'SMTP hostname:', + field_email_smtp_hostname_hint: 'This option only applies to the external SMTP mode.', + field_email_smtp_auth: 'SMTP credentials:', + field_email_smtp_username: 'Username:', + field_email_smtp_password: 'Password:', + + // Section: avatars + heading_avatars: 'Avatars', + avatars_intro: 'Avatars are small images that users can display on their profiles and in comments.', + field_avatar_enable: 'Enable avatar support:', + field_avatar_enable_hint: 'Supported formats are JPEG, PNG, and GIF™.', + field_avatar_enable_label: 'Enabled', + field_avatar_max_filesize: 'Maximum avatar file size:', + field_avatar_max_filesize_hint: 'For smaller sites, the highest value for this should be about 50KB, 51200. Larger sites with more visitors will likely want to use something much smaller, such as 10KB.', + field_avatar_max_dimensions: 'Maximum avatar dimensions:', + field_avatar_max_dimensions_hint: 'The format is width × height. Typically you want to have this square (the same width and height). These are only maximum dimensions; users are not prevented from having smaller images.', + field_avatar_allow_anim_title: 'Allow animated avatars:', + field_avatar_allow_anim_hint: 'If this is checked, users can upload APNG and Animated GIF™ avatars. Sometimes such images can be specifically made to be distracting, like rapidly flashing images. If this is unchecked, these formats will be blocked, and only still PNGs and GIFs will be allowed.', + field_avatar_allow_anim: 'Don\'t block animated images', + field_avatar_upload_methods: 'Allowed upload methods:', + field_avatar_upload_file: 'Allow users to upload image files from their computers', + field_avatar_upload_http: 'Allow users to enter a URL to their desired avatar', + field_avatar_directory: 'Avatar storage directory:', + field_avatar_directory_hint: 'This should be relative to your Enano root and should contain only alphanumeric characters and forward slashes, even if your server runs Windows.', + + // Main section: sidebar links + heading_sidebar: 'Sidebar links', + + // Section: promote Enano + heading_promoteenano: 'Promote Enano', + field_enano_link_title: 'If you think Enano is nice, or if you want to show your support for the Enano team, you can do so by placing a link to the Enano homepage in your Links sidebar block. You absolutely don\'t have to do this, and you won\'t get degraded support if you don\'t. Because Enano is still relatively new in the CMS world, it needs all the attention it can get - and you can easily help to spread the word using this link. Note that this is different from the "Powered by Enano" link in the footer of the page - our philosophy and guidelines regarding the About Enano page and its associated link on every page are discussed on the Enano website.', + field_enano_link: 'Place a link to enanocms.org on the sidebar', + + // Section: SF.net logo + heading_sfnet_logo: 'SourceForge.net logo', + sfnet_intro: 'All projects hosted by SourceForge.net are required to display an official SourceForge.net logo on their pages. If you want to display a SourceForge.net logo on the sidebar, check the box below, enter your group ID, and select an image type.', + field_sfnet_display: 'Display the SourceForge.net logo on the right sidebar', + field_sfnet_group_id: 'Group ID:', + field_sfnet_logo_style: 'Logo style:', + field_sfnet_logo_style_1: '88x31%this.etc_unit_pixels_short%, white', + field_sfnet_logo_style_2: '125x37%this.etc_unit_pixels_short%, white', + field_sfnet_logo_style_3: '125x37%this.etc_unit_pixels_short%, black', + field_sfnet_logo_style_4: '125x37%this.etc_unit_pixels_short%, blue', + field_sfnet_logo_style_5: '210x62%this.etc_unit_pixels_short%, white', + field_sfnet_logo_style_6: '210x62%this.etc_unit_pixels_short%, black', + field_sfnet_logo_style_7: '210x62%this.etc_unit_pixels_short%, blue', + + // Section: W3C validation buttons + heading_w3clogos: 'W3C compliance logos', + w3clogos_intro: 'Enano generates (by default) Valid XHTML 1.1 code, plus valid CSS. If you want to show this off, check the appropriate boxes below.', + w3clogos_btn_html32: 'HTML 3.2', + w3clogos_btn_html40: 'HTML 4.0', + w3clogos_btn_html401: 'HTML 4.01', + w3clogos_btn_xhtml10: 'XHTML 1.0', + w3clogos_btn_xhtml11: 'XHTML 1.1', + w3clogos_btn_css: 'CSS', + + // Section Defective By Design link + heading_dbd: 'Defective By Design Anti-DRM button', + dbd_intro: 'The Enano project is strongly against Digital Restrictions Management.', + dbd_explain: 'DRM removes the freedoms that every consumer should have: to freely copy and use digital media items they legally purchased to their own devices. Showing your opposition to DRM is as easy as checking the box below to place a link to DefectiveByDesign.org on your sidebar.', + field_stopdrm: 'Help stop DRM by placing a link to DBD on the sidebar!', + + // Save button + btn_save_changes: 'Save changes' + }, + acpup: { + heading_main: 'File upload configuration', + intro: 'Enano supports the ability to upload files to your website and store the files in the database. This enables you to embed images and such into pages without manually writing the HTML. However, the upload feature can sometimes pose a risk to your site, as viruses and executable files can sometimes be uploaded.', + field_enable: 'Enable file uploads', + field_max_size: 'Maximum file size:', + info_magick: 'You can allow Enano to generate thumbnails of images automatically. This feature requires ImageMagick to work properly. If your server does not have ImageMagick on it, Enano will try to use the GD library (if available) to scale images. This can be slower, but it works on a wider range of servers. If even that does not work, Enano will simply make your users\' browsers scale the images. In most cases this is fine, but if you are uploading large (>100KB) images and embedding them inside of pages, you should try to enable ImageMagick or configure GD because transferring these large images many times can cost you quite a lot of bandwidth.', + field_magick_enable: 'Use ImageMagick to scale images', + field_magick_path: 'Path to ImageMagick:', + err_magick_not_found: 'Warning: the file "%magick_path%" was not found, and the ImageMagick file path was not updated.', + // Translators: for the path here, please be sure to use a double-backslash in the Windows path. Avoid translating the file paths + // anyway since they're generally the same even on non-English Windows systems. + field_magick_path_hint: 'On Linux and Unix servers, the most likely options here are /usr/bin/convert and /usr/local/bin/convert. If you server runs Windows, then ImageMagick is most likely to be C:\\Windows\\Convert.exe or C:\\Windows\\System32\\Convert.exe.', + info_cache: 'If you use ImageMagick to scale images, your server will be very busy constantly scaling images if your website is busy, and your site may experience slowdowns. You can dramatically speed up this scaling process if you use a directory to cache thumbnail images.', + info_cache_chmod: 'Please note: the cache/ directory on your server must be writable by the server. While this is not usually a problem on Windows servers, most Linux/Unix servers will require you to CHMOD the cache/ directory to 777. See your FTP client\'s user guide for more information on how to do this.', + msg_cache_not_writable: ' At present, it seems that the cache directory is not writable. The checkbox below has been disabled to maintain the stability of Enano.', + field_cache: 'Cache thumbnailed images', + info_history: 'Lastly, you can choose whether file history will be saved. If this option is turned on, you will be able to roll back any malicious changes made to uploaded files, but this requires a significant amount of filesystem storage. You should probably leave this option enabled unless you have less than 250MB of disk space on your hosting account or server.', + field_history: 'Keep a history of uploaded files', + btn_save: 'Save changes', + }, + acpft: { + // Nope. There isn't anything else. Sorry to disappoint. + heading_main: 'Allowed file types', + hint: 'Using the form below, you can decide which file types are allowed to be uploaded to this site.', + msg_saved: 'Your changes have been saved.', + msg_demo_mode: 'Hmm, enabling executables, are we? Tsk tsk. I\'d love to know what\'s in that EXE file you want to upload. OK, maybe you didn\'t enable EXEs. But nevertheless, changing allowed filetypes is disabled in the demo.', + }, + acppl: { + err_heading: 'Error disabling plugin', + err_demo_plugin: 'The demo lockdown plugin cannot be disabled in demo mode.', + err_system_plugin: 'The plugin you selected cannot be disabled because it is a system plugin.', + err_open_dir: 'The plugins/ directory could not be opened.', + err_missing_dir: 'The plugins/ directory is missing from your Enano installation.', + col_filename: 'Plugin filename', + col_name: 'Plugin name', + col_description: 'Description', + col_author: 'Author', + col_version: 'Version', + btn_enable: 'Enable', + btn_disable: 'Disable', + btn_hide_system: 'Hide system plugins', + btn_show_system: 'Show system plugins', + lbl_system_plugin: '[System]', + }, + acppm: { + heading_main: 'Edit page properties', + hint: 'This panel allows you to edit various properties of pages that aren\'t visible anywhere else. In addition to renaming pages, you can also change their URL string and options such as whether to index the page for searching or bypass Enano\'s template engine.', + err_page_not_found: 'No pages matching that search string could be found.', + msg_results_ambiguous_title: 'Ambiguous search results', + msg_results_ambiguous_body: 'Multiple pages that matched your search terms were found. Please select the page you wish to modify:', + ambig_btn_viewpage: 'View', + err_ambig_absolute: 'Your database is corrupt as it contains multiple pages with the same urlname and namespace.', + lbl_field_search: 'Search for a page title or URL string:', + heading_select_page_from_list: 'Select page from a list', + hint_select_page_from_list: 'You can also select the page you want to modify from the list below. The list is broken into sections of 100 pages, so if you have a lot of pages on your site, you can click the pagination control below to view more pages.', + + // Edit form + heading_editing: 'Editing page:', + lbl_page_name: 'Page\'s title:', + lbl_page_urlname: 'URL string:', + lbl_page_urlname_hint: 'No spaces, and don\'t enter the namespace prefix (e.g. User:). Changing this value is usually not a good idea, especially for templates and project pages, because it will invalidate the page\'s current URL.', + lbl_namespace: 'Namespace (URL prefix):', + ns_article: '[No prefix, default Article namespace]', + heading_advanced: 'Advanced options', + lbl_enable_comments_title: 'Allow comments to be posted on this page?', + lbl_enable_comments_hint: 'This option has no effect if comments are disabled globally in the administration panel. This option is enabled by default.', + lbl_enable_comments: 'Enable comments on this page', + lbl_special_title: 'Mark page as self-contained?', + lbl_special_hint: 'This option enables you to use your own HTML headers and other code. If you enable this, only the raw contents of the page will be displayed instead of Enano\'s full page formatting and styles. It is recommended that only advanced users enable this feature. As with other Enano pages, you may use PHP code in your pages (dependent on permissions), meaning you can use Enano\'s API on the page.', + lbl_special: 'Bypass the template engine for this page', + lbl_visible_title: 'Make page publicly listed?', + lbl_visible_hint: 'If you enable this option, this page will be indexed for searching and will appear in public page lists such as Special:AllPages. This option is enabled by default. Disabling this does not protect the page from unauthorized access. If you want to keep this page from being accessed without authorization, you should create abstract new ACL rule or password-protect the page.', + lbl_visible: 'Allow page to be indexed and listed', + lbl_protected_title: 'Protect page from edits?', + lbl_protected_off: 'Unprotected', + lbl_protected_on: 'Fully protected', + lbl_protected_semi: 'Semi-protected', + lbl_protected_hint: 'This option only has an effect if Wiki Mode is enabled. Selecting Unprotected means that any user (unless specifically blacklisted) can edit this page. Fully protected means that only administrators can edit the page. Semi-protected restricts editing to administrators and users that have been registered for at least four days.

Above all, no users except administrators can edit this page unless an ACL specifically allows it or Wiki Mode is enabled.', + lbl_wikimode_title: 'Enable Wiki Mode for this page?', + lbl_wikimode_on: 'Enabled', + lbl_wikimode_off: 'Disabled', + lbl_wikimode_global: 'Inherit global setting', + lbl_wikimode_hint: 'By default, all pages use the Wiki Mode setting defined in General Configuration. You can override that using this field. Be aware that there are advantages and disadvantages to Wiki Mode. For example, Wiki Mode encourages collaboration, but also permits vandalism. See the Enano Documentation article on Wiki Mode for more information.', + lbl_delete_title: 'Delete this page?', + lbl_delete_hint: 'Remember that deleting pages is always reversible unless you clear the page\'s logs after deleting it.', + lbl_delete: 'Delete this page when I click Save', + + err_invalid_page_name: 'Please enter a name for the page.', + err_invalid_url_string: 'Please enter a URL string for the page.', + err_invalid_namespace: 'The namespace you selected is, for whatever reason, not valid.', + err_invalid_protection: 'The protection level selected is invalid.', + err_invalid_wiki_mode: 'The Wiki Mode level selected is invalid.', + err_header: 'There were one or more problems that prevented the page from being saved:', + delete_reason: 'Administrative deletion from admin CP; contact webmaster for details', + + msg_save_success: 'Your changes to the page have been saved. View page »', + }, + acped: { + heading_main: 'Edit page content', + hint: 'This panel allows you to edit the contents of pages that are stored in the database.', + // The rest of this section is identical to the first parts of the acppm category by default (you can copy and paste). + err_page_not_found: 'No pages matching that search string could be found.', + msg_results_ambiguous_title: 'Ambiguous search results', + msg_results_ambiguous_body: 'Multiple pages that matched your search terms were found. Please select the page you wish to edit:', + ambig_btn_viewpage: 'View', + err_ambig_absolute: 'Your database is corrupt as it contains multiple pages with the same urlname and namespace.', + lbl_field_search: 'Search for a page title or URL string:', + heading_select_page_from_list: 'Select page from a list', + hint_select_page_from_list: 'You can also select the page you want to edit from the list below. The list is broken into sections of 100 pages, so if you have a lot of pages on your site, you can click the pagination control below to view more pages.', + }, + acptm: { + heading_edit_themes: 'Installed themes', + btn_system_themes_show: '» Show system themes', + btn_system_themes_hide: '» Hide system themes', + btn_theme_edit: 'Edit', + btn_theme_system: 'System theme', + heading_install_themes: 'Themes available for installation', + btn_theme_install: 'Install', + + // Editor + heading_theme_edit: 'Editing theme: %theme_name%', + field_theme_name: 'Theme name:', + field_default_style: 'Select a default style:', + field_default_theme: 'Site-wide default theme:', + field_default_msg_current: 'This is the current default', + field_default_btn_make_default: 'Make this the default theme when I click Save', + heading_theme_groups: 'User and group policy', + }, + acpdb: { + err_not_supported_title: 'Not supported', + err_not_supported_desc: 'This function is only supported under the MySQL database driver.', + err_demo_mode_title: 'Access denied', + err_demo_mode_desc: 'Since you\'re using the Enano demo, we can\'t allow database backups. Sorry.', + + intro: 'This page allows you to back up your Enano database should something go miserably wrong.', + lbl_system_tables: 'Export tables that are part of the Enano core', + lbl_additional_tables: 'Additional tables to export:', + lbl_include_structure: 'Include table structure', + lbl_include_data: 'Include table data', + btn_create_backup: 'Create backup', + }, + acplm: { + // Language installation + heading_install: 'Languages available for installation', + col_lang_id: 'ID', + col_lang_code: 'Shorthand code', + col_lang_name: 'Language name (native)', + col_lang_name_eng: 'Language name (English)', + btn_install_language: 'Install', + err_lang_install_demo: 'Modifying, installing, and uninstalling languages is disabled in the demo for security reasons.', + msg_lang_install_success: 'The language pack %lang_name% has been installed.', + + // Editor portal + heading_editor_portal: 'Edit installed languages', + portal_btn_edit: 'Modify', + portal_btn_unin: 'Uninstall', + + // Properties table + heading_modify: 'Edit language info', + th_lang_basic: 'Basic language properties', + field_lang_name_native: 'Language name (native):', + field_lang_name_english: 'Language name (in English):', + field_lang_code: 'Shorthand code:', + field_lang_code_hint: 'You can\'t change this because it needs to be compliant with ISO 639-3.', + msg_basic_save_success: 'Changes saved.', + + // String editor portal + heading_edit_strings_portal: 'Edit strings', + msg_edit_strings_portal_intro: 'You can edit the actual language strings used in this language. Be sure to preserve any variables (in the format of %variable_name%) even if you\'re translating a language. If you\'re translating all of Enano into a new language, you should edit the JSON files instead of using this console, so that comments in the language files can be preserved.', + btn_edit_strings_portal: 'Edit strings »', + + // Re-import button and explanation + heading_reimport_portal: 'Re-import this language', + msg_reimport_portal_intro: 'If you accidentally changed a lot of strings, you can re-import this language from the original language files. This will destroy any modifications you have made to the default set of strings, but any strings you\'ve added will be preserved. This is almost the same effect as re-installing the language. Don\'t stop this process while it\'s running, the re-import can take a long time.', + btn_reimport: 'Re-import language', + msg_reimport_success: 'The language was re-imported successfully. All Enano preset strings for this language have been restored.', + + // String editor + editor_heading: 'Editing category: %cat_name%', + editor_col_string_name: 'String name', + editor_col_string_content: 'String', + editor_btn_revert: 'Revert', + editor_btn_cancel: 'Cancel', + msg_string_save_success: 'Your changes have been saved.', + + // Backup interface + heading_backup: 'Backup language', + backup_intro: 'You can back up this language to make preserving custom strings easier if you ever migrate your Enano installation or re-install. Backed-up language files can be restored by using FTP or equivalent to copy the backup file to the language\'s folder, renaming it to "backup.json", and re-importing the language.', + btn_create_backup: 'Download backup', + + // Uninstaller + uninstall_confirm_title: 'Confirm uninstallation of language', + uninstall_confirm_body: 'Do you really want to uninstall this language? If you continue, all users that have selected this language will be reset to use the default. It is recommended that you create a backup of this language before you uninstall it if you have changed any strings.', + btn_uninstall_confirm: 'Confirm uninstallation', + btn_uninstall_cancel: 'Cancel', + err_cant_uninstall_default: 'You cannot uninstall the default language.', + msg_uninstall_success: 'The language has been uninstalled.', + }, + acppg: { + // Main menu + heading_main: 'Manage page groups', + hint_intro: 'Enano\'s page grouping system allows you to build sets of pages that can be controlled by a single ACL rule. This makes managing features such as a members-only section of your site a lot easier. If you don\'t use the ACL system, you probably don\'t need to use page groups.', + col_group_name: 'Group name', + col_type: 'Type', + col_target: 'Target', + col_actions: 'Actions', + gtype_catlink: 'Link to category', + gtype_tagged: 'Group of pages with one tag', + gtype_static: 'Static group of pages', + gtype_regex: 'Regular expression match', + gtype_regex_long: 'Perl-compatible regular expression (advanced)', + lbl_tag: 'Tag:', + lbl_category: 'Category:', + lbl_regex: 'Expression:', + btn_edit: 'Edit', + btn_delete: 'Delete', + msg_no_groups: 'No page groups defined.', + btn_create_new: 'Create new group', + + // Creation form + err_no_cats: 'There aren\'t any categories on this site.', + th_create: 'Create page group', + field_group_name: 'Group name:', + field_group_name_hint: 'This should be short, descriptive, and human-readable.', + field_group_type: 'Group type:', + + field_member_pages: 'Member pages:', + field_member_pages_hint: 'Click the "plus" button to add more fields.', + field_target_category: 'Include pages in this category:', + field_target_category_hint: 'Pages in subcategories are not included, however subcategory pages themselves are.', + field_target_category_hint2: 'Reminder: Enano does not automatically place any access controls on the category. If you don\'t want users to be able to freely add and remove pages from the category (assuming Wiki Mode is enabled for the category) then you need to enable protection on the category using the button on the more options menu.', + field_target_tag: 'Include pages with this tag:', + field_target_regex: 'Regular expression:', + field_target_regex_hint: 'Be sure to include the starting and ending delimiters and any flags you might need.
+ These pages might help: Pattern modifiersPattern syntax
+ Examples: /^(Special|Admin):/i/^Image:([0-9]+)$/
+ Developers, remember that this will be matched against the full page identifier string. This means that /^About_Enano$/ will NOT match the page Special:About_Enano.', + btn_create_finish: 'Create page group', + + err_need_name: 'Please enter a name for the page group.', + err_need_tag: 'Please enter a page tag.', + err_need_cat: 'Please create a category page before linking a page group to a category.', + err_need_page: 'Please specify at least one page to place in this group.', + err_need_regex: 'Please specify a regular expression to match page IDs against.', + msg_create_success: 'The page group "%group_name%" has been created.', + + // Delete form + th_delete_confirm: 'Confirm deletion', + msg_delete_confirm: 'Are you sure you want to delete this page group?', + btn_delete_confirm: 'Yes, delete group', + msg_delete_success: 'The group "%pg_name%" has been deleted.', + + // Editor + th_editing_group: 'Editing page group:', + btn_save_name: 'Save group name', + th_remove_selected: 'Remove pages from this group', + field_remove: 'Remove pages:', + btn_do_remove: 'Remove selected', + btn_save_update: 'Save and update', + btn_cancel_all: 'Cancel all changes', + th_onthefly: 'On-the-fly tools', + field_add_page: 'Add page:', + field_add_page_hint: 'You can add multiple pages by entering part of a page title, and it will be auto-completed. Press Enter to quickly add the page. This only works if you a really up-to-date browser.', + + // Validation messages and errors + err_ajaxadd_need_title: 'Please enter a page title.', + err_ajaxadd_already_in: 'The page you are trying to add is already in this group.', + ajaxadd_success: 'The page has been added to the specified group.', + err_save_need_name: 'Please enter a valid name for this group.', + msg_save_name_updated: 'The group name was updated successfully.', + err_save_need_tag: 'Please enter a valid tag.', + msg_save_tag_updated: 'The affecting tag was updated.', + err_save_need_regex: 'Please enter an expression to match against.', + msg_save_regex_updated: 'The expression to match against was updated.', + err_save_bad_category: 'No category ID specified on POST URI.', + msg_save_cat_updated: 'The affecting category was updated.', + err_save_no_pages: 'No pages were selected for deletion, and thus none were deleted.', + msg_save_pages_deleted: 'The requested page group members have been deleted.', + }, + acpum: { + heading_main: 'User administration panel', + hint_intro: 'From this panel you can modify or delete user accounts.', + field_search_user: 'Search for user:', + field_search_user_hint: 'If your browser supports AJAX, this will provide suggestions for you.', + btn_search_user_go: 'Go', + heading_clear_sessions: 'Clear session key table', + hint_clear_sessions: 'It\'s a good idea to clean out your session keys table every once in a while, since this helps to reduce database size. During this process you will be logged off and (hopefully) logged back on automatically. If you do this, all users besides you will be logged off, so be sure to do this at a time when traffic is low.', + btn_clear_sessions: 'Clear session keys', + + heading_activation_one: '1 user is awaiting account activation', + heading_activation_plural: '%count% users are awaiting account activation', + col_activate_timestamp: 'Date of request', + col_activate_requestedby: 'Requested by', + col_activate_requestedfor: 'Requested for', + col_activate_coppauser: 'COPPA user', + col_activate_actions: 'Actions', + coppauser_yes: 'Yes', + coppauser_no: 'No', + btn_activate_now: 'Activate now', + btn_send_email: 'Send activation e-mail', + btn_activate_deny: 'Deny request', + msg_activate_success: 'The user account "%username%" has been activated.', + err_activate_fail: 'The user account %username% has NOT been activated, possibly because the account is already active.', + msg_activate_email_success: 'The user %username% has been sent an e-mail with an activation link.', + err_activate_email_fail: 'The user account %username% has not been activated, probably because of a bad SMTP configuration.', + msg_activate_deny_success: 'All activation requests for the user %username% have been deleted.', + + msg_sessionclear_success: 'The session key table has been cleared. Your database should be a little bit smaller now.', + err_sessionclear_demo: 'Sorry Charlie, no can do. You might mess up other people logged into the demo site.', + + // VALIDATION ERRORS + err_bad_username: 'The username you entered could not be found.', + err_validation_fail: 'Your request could not be processed due to the following validation errors:', + err_nosave_demo: 'Users cannot be modified or deleted in demo mode.', + msg_delete_success: 'The user account has been deleted.', + // Note the difference between this and err_bad_username. err_bad_username is shown when the username entered + // doesn't match any usernames in the database (e.g. no search results); err_illegal_username is shown when + // the admin tries to change the username to one that has illegal characters in it. + err_illegal_username: 'The username you entered contains invalid characters.', + err_no_aes_key: 'Session manager denied public encryption key lookup request', + err_illegal_email: 'You have entered an invalid e-mail address.', + msg_save_success: 'Your changes have been saved.', + + // EDITOR SMARTFORM + heading_editing_user: 'Editing user:', + heading_basic_options: 'Basic options', + + field_username: 'Username:', + field_username_hint: 'Must be at least 2 characters in length', + msg_same_user_username: 'You cannot change your own username. To change your username you must log into a different administrative account.', + + field_password: 'Password:', + field_password_hint: 'Password strength requirements are not enforced here.', + msg_password_unchanged: 'Password will be left unchanged.', + btn_reset_password: 'Reset password...', + msg_same_user_password: 'To change your password, please use the user preferences panel.', + field_password_title: 'Change password to:', + field_newpassword: 'New password:', + field_newpassword_confirm: 'Confirm:', + + field_email: 'E-mail address:', + msg_same_user_email: 'To change your e-mail address, please use the user preferences panel.', + + field_realname: 'Real name:', + msg_same_user_realname: 'To change your real name on file, please use the user preferences panel.', + + field_signature: 'Signature:', + + heading_imcontact: 'Instant messenger contact information', + + field_aim: 'AIM handle:', + field_wlm: 'WLM handle:', + field_wlm_hint: 'If you don\'t specify the domain (@whatever.com), "@hotmail.com" will be assumed.', + field_yim: 'Yahoo! IM handle:', + field_xmpp: 'Jabber™/XMPP handle:', + + heading_contact_extra: 'Extra contact information', + + field_homepage: 'Homepage:', + field_homepage_hint: 'Please remember the http:// prefix.', + field_location: 'Location:', + field_job: 'Job:', + field_hobbies: 'Hobbies:', + field_email_public: 'E-mail address is public', + field_email_public_hint: 'If this is checked, the user\'s e-mail address will be displayed on your the page. To protect the address from spambots, it will be encrypted.', + + avatar_heading: 'Avatar settings', + avatar_image_none: 'This user does not currently have an avatar.', + avatar_lbl_change: 'Change avatar:', + avatar_lbl_keep: 'Keep current setting', + avatar_lbl_remove: 'Delete this user\'s avatar', + avatar_lbl_set_http: 'Replace avatar using a new image from a URL', + avatar_lbl_set_file: 'Replace avatar using a new image from my computer', + + heading_adminonly: 'Administrator-only options', + + field_active_title: 'User account is active', + field_active_hint: 'If this is unchecked, the existing activation key will be overwritten in the database, thus invalidating any activation e-mails sent to the user.', + field_active: 'Account is active and enabled', + field_userlevel: 'User\'s site access level', + field_userlevel_hint: 'If this is changed, the relevant group memberships will be updated accordingly.', + field_reg_ip: 'Registered from IP:', + + field_deleteaccount_title: 'Delete user account', + field_deleteaccount: 'Permanently delete this user account when I click Save', + msg_delete_own_account: 'WARNING! This will delete your own user account!', + field_deleteaccount_hint: 'Even if you delete this user account, the username will be shown in page edit history, comments, and other areas of the site. Deleting a user account CANNOT BE UNDONE and should only be done in extreme circumstances. If the user has violated the site policy, deleting the account will not prevent him from using the site or creating a new account, for that you need to add a new ban rule.', + + btn_save: 'Save changes', + }, + acpug: { + heading_main: 'Manage Usergroups', + heading_edit_existing: 'Edit an existing group', + btn_edit_stage1: 'Edit group', + heading_create_new: 'Create a new group', + field_group_name: 'Group name:', + btn_create_stage1: 'Continue', + + // Edit form + heading_edit_name: 'Edit group name', + btn_cant_delete: 'Can\'t delete system group', + btn_delete_group: 'Delete this group', + btn_save_name: 'Save name', + heading_edit_members: 'Edit group members', + msg_no_members: 'This group has no members.', + lbl_member_mod: 'Mod', + btn_remove_member: 'Remove member', + heading_add_member: 'Add a new member', + field_username: 'Username:', + field_make_mod: 'Is a group moderator', + field_make_mod_hint: '(can add and delete other members)', + btn_add_user: 'Add user to group', + + // Create form + err_group_name_invalid: 'The group name you chose is invalid.', + heading_creating_group: 'Creating group:', + field_group_mod: 'Group moderator', + field_group_type: 'Group status', + btn_create_stage2: 'Create group', + err_already_exist: 'The group name you entered already exists.', + err_bad_username: 'The username you entered could not be found.', + err_bad_insert_id: 'The group ID could not be looked up.', + heading_info: 'Information', + msg_create_success: 'The group %g_name% has been created successfully.', + + // More editor bits, validation messages + err_nodelete_system_group: 'The group "%g_name%" could not be deleted because it is a system group required for site functionality.', + msg_delete_success: 'The group "%g_name%" has been deleted. Return to the group manager.', + msg_name_update_success: 'The group name has been updated.', + msg_user_added: 'The user "%username%" has been added to this usergroup.', + err_username_not_exist: 'The user "%username%" could not be added.
This username does not exist.', + }, + acpcp: { + heading_main: 'Background information', + intro: 'The United States Childrens\' Online Privacy Protection Act (COPPA) was a law passed in 2001 that requires sites oriented towards children under 13 years old or with a significant amount of under-13 children clearly state what information is being collected in a privacy policy and obtain authorization from a parent or legal guardian before allowing children to use the site. Enano provides an easy way to allow you, as the website administrator, to obtain this authorization.', + msg_save_success: 'Your changes have been saved.', + th_form: 'COPPA support', + field_enable_title: 'Enable COPPA support:', + field_enable: 'COPPA enabled', + field_enable_hint: 'If this is checked, users will be asked if they are under 13 years of age before registering', + field_address: 'Your mailing address:', + field_address_hint: 'This is the address to which parents will send authorization forms.', + }, + acpmm: { + heading_main: 'Send mass e-mail', + err_need_subject: 'Please enter a subject.', + err_need_message: 'Please enter a message.', + msg_send_success: 'Your message has been sent.', + err_send_fail: 'Could not send message for the following reason(s):', + err_demo: 'This function is disabled in the demo. You think demo@enanocms.org likes getting "test" mass e-mails?', + field_group_to: 'Send message to:', + field_group_to_hint: 'By default, this message will be sent to the group selected here. You may instead send the message to a specific list of users by entering them in the second row, with usernames separated by a single comma (no space).', + field_username: 'Usernames:', + field_subject: 'Subject:', + field_message: 'Message:', + btn_send: 'Send message', + msg_send_takeawhile: 'Please be warned: it may take a LONG time to send this message. Please do not stop the script until the process is finished.', + }, + acpsl: { + heading_main: 'System security log', + col_type: 'Type', + col_date: 'Date', + col_username: 'Username', + col_ip: 'IP Address', + entry_admin_auth_good: 'Successful elevated authentication
Authentication level: %level%', + entry_admin_auth_bad: 'Failed elevated authentication
Attempted auth level: %level%', + entry_activ_good: 'Successful account activation', + entry_auth_good: 'Successful regular user logon', + entry_activ_bad: 'Failed account activation', + entry_auth_bad: 'Failed regular user logon', + entry_sql_inject: 'SQL injection attempt
Offending query: %query%
', + entry_db_backup: 'Database backup created
Tables: %tables%', + entry_install_enano: 'Installed Enano version %version%', + entry_upgrade_enano: 'Upgraded Enano to version %version%', + entry_illegal_page: 'Unauthorized viewing attempt
Page: %illegal_link%', + entry_upload_enable: 'Enabled file uploads', + entry_upload_disable: 'Disabled file uploads', + entry_magick_enable: 'Enabled ImageMagick for uploaded images', + entry_magick_disable: 'Disabled ImageMagick for uploaded images', + entry_filehist_enable: 'Enabled revision tracking for uploaded files', + entry_filehist_disable: 'Disabled revision tracking for uploaded files', + entry_magick_path: 'Changed path to ImageMagick executable', + entry_plugin_disable: 'Disabled plugin: %plugin%', + entry_plugin_enable: 'Enabled plugin: %plugin%', + entry_seclog_unauth: 'Unauthorized attempt to call security log fetcher', + entry_u_from_admin: 'User %username% demoted from Administrators group', + entry_u_from_mod: 'User %username% demoted from Moderators group', + entry_u_to_admin: 'User %username% added to Administrators group', + entry_u_to_mod: 'User %username% added to Moderators group', + entry_view_comment_ip: 'IP address viewed on comment by %username%', + tip_reverse_dns: 'Click for reverse DNS info', + }, + acpbc: { + err_empty: 'Please enter something to ban.', + err_invalid_ip_range: 'The IP address range you entered is invalid.', + err_demo: 'This function is disabled in the demo. Just because you don\'t like %ban_target% doesn\'t mean we don\'t like %ban_target%.', + col_type: 'Type', + col_value: 'Value', + col_regex: 'Regular Expression', + msg_no_rules: 'No ban rules yet.', + ban_type_ip: 'IP address', + ban_type_username: 'Username', + ban_type_email: 'E-mail address', + btn_delete: 'Delete', + // Some languages like Chinese don't literally have the word "yes", so this would be something + // along the lines of "This is a regular expression" / "This is not..." in Chinese. Hence the + // separation of this from a generic "yes" string. + ban_regex_yes: 'Yes', + ban_regex_no: 'No', + heading_create_new: 'Create new ban rule', + field_type: 'Type:', + field_rule: 'Rule:', + field_rule_hint: 'You can ban multiple IP addresses, users, or e-mail addresses by separating entries with a single comma (User1,User2). Do not put a space after the comma. For IP addresses, you may specify ranges like 172|192.168.4-30|90-167.1-90, which will turn into 172 and 192 . 168 . 4-30 and 90-167 . 1 - 90, which matches 18,899 IP addresses.', + field_reason: 'Reason to show to the banned user:', + field_regex: 'This rule is a regular expression', + field_regex_hint: '(advanced users only)', + btn_create: 'Create new ban rule', + }, + acplo: { + heading_main: 'You have now been logged out of the administration panel.', + msg_logout_complete: 'You will continue to be logged into the website, but you will need to re-authenticate before you can access the administration panel again.

Return to the Main Page.', + }, + sbedit: { + msg_order_update_success: 'The sidebar order information was updated successfully.', + err_demo_php_disable: 'Adding PHP code blocks in the Enano administration demo has been disabled for security reasons.', + msg_item_added: 'The item was added.', + + create_intro: 'What type of block should this be?', + block_type_wiki: 'Wiki-formatted block', + block_type_tpl: 'Template-formatted block (old pre-beta 3 behavior)', + block_type_html: 'Raw HTML block', + block_type_php: 'PHP code block (danger, Will Robinson!)', + block_type_plugin: 'Use code from a plugin', + field_block_title: 'Block title:', + field_block_sidebar: 'Which sidebar:', + field_block_sidebar_left: 'Left', + field_block_sidebar_right: 'Right', + field_wikitext: 'Wikitext:', + field_tplcode: 'Template code:', + field_html: 'HTML to place inside the sidebar:', + field_php_disabled: 'Creating PHP blocks in demo mode is disabled for security reasons.', + field_php: '

+ WARNING: If you don\'t know what you\'re doing, or if you are not fluent in PHP, stop now and choose a different block type. You will brick your Enano installation if you are not careful here. + ALWAYS remember to write secure code! The Enano team is not responsible if someone drops all your tables because of an SQL injection vulnerability in your sidebar code. You are probably better off using the template-formatted block type. +

+

+ + It is especially important to note that this code is NOT checked for errors! If there is a syntax error in your code here, it will prevent any pages from loading AT ALL. So you need to use an external PHP editor (like jEdit) to check your syntax before you hit save. + You have been warned. +

+

+ Also, you should avoid using output buffering functions (ob_[start|end|get_contents|clean]) here, because Enano uses those to track output from this script. +

+

+ The standard <?php and ?> tags work here. Don\'t use an initial "<?php" or it will cause a parse error. +

+

+ PHP code: +

', + field_plugin: 'Plugin:', + btn_create_block: 'Create new block', + + msg_block_moved: 'Item moved.', + msg_block_deleted: 'Item deleted.', + msg_plugin_not_loaded: 'Plugin isn\'t loaded', + note_block_unnamed: 'Unnamed', + hint_rename: 'Double-click to rename this block', + note_block_disabled: '(disabled)', + tip_disenable: 'Enable or disable this block', + tip_edit: 'Edit the contents of this block', + tip_delete: 'Permanently delete this block', + tip_move: 'Move this block to the other sidebar', + msg_delete_confirm: 'Do you really want to delete this block?', + btn_revert: 'Revert', + btn_create_new_stage1: 'Create new block', + btn_main_page: 'Main Page', + msg_cant_edit_plugin_title: 'This block cannot be edited.', + msg_cant_edit_plugin_body: 'This is a plugin block, and cannot be edited. <%close_link%>Close', + btn_edit_save: 'save', + btn_edit_cancel: 'cancel', + msg_discard_confirm: 'Do you really want to discard your changes?', + msg_discard_order_confirm: 'Do you really want to revert your changes?\nNote: this does not revert edits or deletions, those are saved as soon as you confirm the action.', + } + } +}; + +// All done! :-) + diff -r d823e49e2e4e -r c433348f3628 language/english/core.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/language/english/core.json Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,690 @@ +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 + * Copyright (C) 2006-2007 Dan Fuhry + * + * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + * + * 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 details. + */ + +// This is the main language file for Enano. Feel free to use it as a base for your own translations. +// All text in this file before the first left curly brace and all text after the last curly brace will +// be trimmed. So you can use a limited amount of Javascript in this so that the language can be imported +// via Javascript as well. + +var enano_lang = { + categories: [ + 'meta', 'page', 'comment', 'onpage', 'etc', 'editor', 'history', 'catedit', 'tags', 'delvote', 'ajax', 'sidebar', 'perm', 'plugin', 'paginate', 'upload', 'tz', + ], + strings: { + meta: { + meta: 'Category names and basic metadata', + page: 'Page creation and control', + comment: 'Comment display', + onpage: 'On-page buttons and controls', + etc: 'Miscellaneous strings', + editor: 'Page editor interface', + history: 'Page history and log viewer', + catedit: 'Categorization box and editor', + tags: 'Page tagging interface', + delvote: 'Page deletion vote interface', + ajax: 'On-page AJAX applets', + sidebar: 'Default sidebar blocks and buttons', + perm: 'Page actions (for ACLs)', + plugin: 'Plugin names and descriptions', + paginate: 'Pagination widget', + upload: 'File upload interface', + tz: 'Time zones', + plural: 's', + enano_about_th: 'About the Enano Content Management System', + enano_about_poweredby: '

This website is powered by Enano, the lightweight and open source CMS that everyone can use. Enano is copyright © 2006-2007 Dan Fuhry. For legal information, along with a list of libraries that Enano uses, please see Legal Information.

The developers and maintainers of Enano strongly believe that software should not only be free to use, but free to be modified, distributed, and used to create derivative works. For more information about Free Software, check out the Wikipedia page or the Free Software Foundation\'s homepage.

', + enano_about_gpl: '

This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

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 details.

You should have received a copy of the GNU General Public License along with this program; if not, write to:

Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301, USA

Alternatively, you can read it online.

', + enano_about_lbl_enanoversion: 'Enano version:', + enano_about_lbl_webserver: 'Web server:', + enano_about_lbl_serverplatform: 'Server platform:', + enano_about_lbl_phpversion: 'PHP version:', + enano_about_lbl_mysqlversion: 'MySQL version:', + enano_about_lbl_pgsqlversion: 'PostgreSQL version:', + }, + page: { + sitedisabled_admin_msg_title: 'The site is currently disabled and thus is only accessible to administrators.', + sitedisabled_admin_msg_body: 'You can re-enable the site through the administration panel.', + + heading_sql_list: 'Query list as requested on URI', + + msg_stats_gentime_long: 'Generated in %time%sec', + msg_stats_gentime_short: 'Time: %time%s', + msg_stats_sql: '%nq% SQL', + + w3c_valid_html32: 'Valid HTML 3.2', + w3c_valid_html40: 'Valid HTML 4.0', + w3c_valid_html401: 'Valid HTML 4.01', + w3c_valid_html50: 'Valid HTML 5.0', + w3c_valid_xhtml10: 'Valid XHTML 1.0', + w3c_valid_xhtml11: 'Valid XHTML 1.1', + w3c_valid_css: 'Valid CSS', + enano_powered: 'Powered by Enano', + enano_powered_long: 'Website engine powered by Enano', + + protect_lbl_success_title: 'Page protected', + protect_lbl_success_body: 'The protection setting has been applied. Return to the page.', + protect_err_need_reason: 'Error: you must enter a reason for protecting this page.', + protect_lbl_reason: 'Reason for protecting the page:', + protect_lbl_level: 'Protecion level to be applied:', + protect_lbl_level_none: 'No protection', + protect_lbl_level_semi: 'Semi-protection', + protect_lbl_level_full: 'Full protection', + protect_btn_submit: 'Protect page', + + rename_err_need_name: 'Error: you must enter a new name for this page.', + rename_lbl: 'Please enter a new name for this page:', + rename_btn_submit: 'Rename page', + rename_success_title: 'Page renamed', + + flushlogs_warning_stern: '

You are about to destroy all logged edits and actions on this page.

Unlike deleting or editing this page, this action is not reversible! You should only do this if you are desparate for database space.

Do you really want to continue?

', + flushlogs_btn_submit: 'Flush logs', + + delvote_warning_stern: '

Your vote counts.

If you think that this page is not relavent to the content on this site, or if it looks like this page was only created in an attempt to spam the site, you can request that this page be deleted by an administrator.

After you vote, you should leave a comment explaining the reason for your vote, especially if you are the first person to vote against this page.

', + + delvote_count_zero: 'So far, no one has voted for the deletion of this page.', + delvote_count_one: 'So far, one person has voted to delete this page.', + delvote_count_plural: 'So far, %delvotes% people have voted to delete this page.', + delvote_btn_submit: 'Vote to delete this page', + delvote_reset_btn_submit: 'Reset votes', + + delete_warning_stern: '

You are about to destroy this page.

While the deletion of the page itself is completely reversible, it is impossible to recover any comments or category information on this page. If this is a file page, the file along with all older revisions of it will be permanently deleted. Also, any custom information that this page is tagged with, such as a custom name, protection status, or additional settings such as whether to allow comments, will be permanently lost.

Are you absolutely sure that you want to continue?
You will not be asked again.

', + delete_err_need_reason: 'Please enter a reason for deleting this page.', + delete_btn_submit: 'Delete this page', + delete_lbl_reason: 'Reason for deleting:', + + wikimode_success_redirect: 'Wiki mode for this page has been set. Redirecting you to the page...', + wikimode_level_on: 'Wiki features will be enabled.', + wikimode_level_off: 'Wiki features will be disabled.', + wikimode_level_global: 'Wiki features will be synchronized to the global setting.', + wikimode_heading: 'You are changing wiki mode for this page.', + wikimode_warning: 'If you want to continue, please click the button below.', + wikimode_blurb_disable: 'Because this will disable the wiki behavior on this page, several features, most notably the ability for users to vote to have this page deleted, will be disabled as they are not relevant to non-wiki pages. In addition, users will not be able to edit this page unless an ACL rule specifically permits them.', + wikimode_blurb_enable: 'Because this will enable the wiki behavior on this page, users will gain the ability to freely edit this page unless an ACL rule specifically denies them. If your site is public and gets good traffic, you should be aware of the possiblity of vandalism, and you need to be ready to revert malicious edits to this page.', + wikimode_btn_submit: 'Set wiki mode', + + detag_err_page_exists: 'The detag action is only valid for pages that have been deleted in the past.', + detag_success_title: 'Page detagged', + detag_success_body: 'All stale tags have been removed from this page.', + + err_custompage_function_missing_title: 'Page backend not found', + err_custompage_function_missing_body: 'The administration page you are looking for was properly registered using the page API, but the backend function (%function_name%) was not found. If this is a plugin page, then this is almost certainly a bug with the plugin.', + err_redirects_exceeded: 'The maximum number of internal redirects has been exceeded.', + err_redirect_to_nonexistent: 'This page redirects to another page that doesn\'t exist.', + err_redirect_infinite_loop: 'This page infinitely redirects with another page (or another series of pages), and the infinite redirect was trapped.', + err_redirect_to_special: 'This page redirects to a Special or Administration page, which is not allowed.', + err_access_denied_title: 'You don\'t have permission to view this page.', + err_access_denied_body: '

Your user account doesn\'t have the necessary permission to view this page. There are a number of possible reasons for this:

+
    +
  • You aren\'t logged in. Some pages are restricted to logged-in users.
  • +
  • The page you\'re trying to view is protected so that only members of a specific usergroup are allowed to read it.
  • +
+

If you would like to inquire further about this message, you may contact the %site_administration%.

', + err_access_denied_siteadmin: 'site administrator', + msg_this_is_a_redirector: 'This page is a redirector.
+ This means that this page will not show its own content by default. Instead it will display the contents of the page it redirects to.

+ To create a redirect page, make the first characters in the page content #redirect [[Page_ID]]. For more information, see the + Enano Wiki formatting guide.

+ This page redirects to %redirect_target%.', + msg_redirected_from: '(Redirected from %from%)', + msg_redirected_from_to: '(Redirected from %from% to %to%)', + + msg_passrequired: 'Access to this page requires a password. Please enter the password for this page below:', + msg_pass_wrong: 'The password you entered for this page was incorrect. Please enter the password for this page below:', + lbl_password: 'Password:', + + msg_404_title: 'There is no page with this title yet.', + msg_404_body_userpage: 'This user has not created his or her user page yet.', + msg_404_body: 'You have requested a page that doesn\'t exist yet.', + msg_404_create: 'You can create this page, or return to the homepage.', + msg_404_gohome: 'Return to the homepage.', + msg_404_was_deleted: 'This page was deleted on %delete_time%. The stated reason was:

%delete_reason%

You can probably roll back the deletion.', + msg_404_admin_opts: 'Additional admin options: detag page', + msg_404_http_response: 'HTTP Error: 404 Not Found', + + msg_archived_title: 'Notice:', + msg_archived_body: 'The page you are viewing was archived on %archive_date% at %archive_time%.
View current version | Restore this version', + + msg_special_404_title: 'Can\'t load special page', + msg_special_404_body: 'The special page you requested could not be found. This may be due to a plugin failing to load. A list of all special pages on this website can be viewed here. You will be redirected to the main page in 15 seconds.', + msg_admin_404_title: 'Administration page not found', + msg_admin_404_body: '

You\'ve requested an administration page, but the function %func_name% doesn\'t exist, so the page can\'t be loaded.

+

Plugin developer?

+

Create a function called %func_name% - it should be loaded when you refresh this page.

+

Otherwise...

+

If you\'re trying to use a plugin\'s administration page, contact the developer of the plugin. If you\'re trying to use a function that is built into Enano (not added by a plugin), then please contact the Enano development team.

', + + msg_general_error: 'General error in page fetcher', + + autosuggest_heading: 'Page name matches', + autosuggest_col_name: 'Page title', + autosuggest_col_page_id: 'Page ID', + }, + comment: { + lbl_subject: 'Subject', + lbl_mod_options: 'Moderator options:', + heading: 'Article comments', + btn_send_privmsg: 'Send private message', + btn_add_buddy: 'Add to buddy list', + btn_edit: 'edit', + btn_delete: 'delete', + btn_mod_approve: 'Approve', + btn_mod_unapprove: 'Unapprove', + btn_mod_delete: 'Delete', + btn_mod_ip_logged: 'View IP', + btn_mod_ip_missing: 'IP not logged', + btn_mod_ip_notimplemented: 'Use AJAX interface to view IPs', + btn_save: 'save', + + msg_comment_posted: 'Your comment has been posted. If it does not appear right away, it is probably awaiting approval.', + + msg_count_zero: 'There are no comments on this %page_type%.', + msg_count_one: 'There is 1 comment on this %page_type%.', + msg_count_plural: 'There are %num_comments% comments on this %page_type%.', + + msg_count_unapp_mod: '%num_unapp% of those are unapproved.', + msg_count_unapp_one: 'However, there is 1 additional comment awaiting approval.', + msg_count_unapp_plural: 'However, there are %num_unapp% additional comments awaiting approval.', + + msg_note_unapp: '(Unapproved)', + + msg_ip_address: 'IP address:', + + msg_delete_confirm: 'Do you really want to delete this comment?', + + postform_title: 'Got something to say?', + postform_blurb: 'If you have comments or suggestions on this article, you can shout it out here.', + postform_blurb_unapp: 'Before your post will be visible to the public, a moderator will have to approve it.', + postform_blurb_captcha: 'Because you are not logged in, you will need to enter a visual confirmation before your comment will be posted.', + postform_blurb_link: 'Leave a comment...', + postform_field_name: 'Your name/screen name:', + postform_field_subject: 'Comment subject:', + postform_field_comment: 'Comment:', + postform_field_captcha_title: 'Visual confirmation:', + postform_field_captcha_blurb: 'Please enter the confirmation code seen in the image on the right into the box. If you cannot read the code, please click on the image to generate a new one. This helps to prevent automated bot posting.', + postform_field_captcha_label: 'Confirmation code:', + postform_field_captcha_cantread_js: 'If you can\'t read the code, click on the image to generate a new one.', + postform_field_captcha_cantread_nojs: 'If you can\'t read the code, please refresh this page to generate a new one.', + postform_btn_submit: 'Submit comment', + + on_friend_list: 'On your friend list', + on_foe_list: 'On your foe list', + }, + onpage: { + lbl_pagetools: 'Page tools', + lbl_page_article: 'article', + lbl_page_admin: 'administration page', + lbl_page_system: 'system message', + lbl_page_file: 'uploaded file', + lbl_page_help: 'documentation page', + lbl_page_user: 'user page', + lbl_page_special: 'special page', + lbl_page_template: 'template', + lbl_page_project: 'project page', + lbl_page_category: 'category', + + btn_discussion: 'discussion (%num_comments%)', + btn_discussion_unapp: 'discussion (%num_comments% total, %num_unapp% unapp.)', + btn_edit: 'edit this page', + btn_viewsource: 'view source', + btn_history: 'history', + btn_moreoptions: 'more options', + + btn_rename: 'rename', + btn_printable: 'view printable version', + btn_votedelete: 'vote to delete this page', + btn_votedelete_reset: 'reset deletion votes', + lbl_wikimode: 'page wiki mode:', + btn_wikimode_on: 'on', + btn_wikimode_off: 'off', + btn_wikimode_global: 'global', + lbl_protect: 'protection:', + btn_protect_on: 'on', + btn_protect_off: 'off', + btn_protect_semi: 'semi', + btn_clearlogs: 'clear page logs', + btn_deletepage: 'delete this page', + btn_deletepage_votes: ' (%num_votes% vote%plural%)', + lbl_password: 'page password:', + btn_password_set: 'set', + btn_acl: 'manage page access', + btn_admin: 'administrative options', + + tip_article: 'View the page contents, all of the page contents, and nothing but the page contents (alt-a)', + tip_comments: 'View the comments that other users have posted about this page (alt-c)', + tip_edit: 'Edit the contents of this page (alt-e)', + tip_viewsource: 'View the source code (wiki markup) that this page uses (alt-e)', + tip_history: 'View a log of actions taken on this page (alt-h)', + tip_rename: 'Change the display name of this page (alt-r)', + tip_delvote: 'Vote to have this page deleted (alt-d)', + tip_resetvotes: 'Clear the list of votes for deletion against this page (alt-y)', + tip_printable: 'View a version of this page that is suitable for printing', + tip_protect_on: 'Prevents all non-administrators from editing this page. [alt-i]', + tip_protect_off: 'Allows everyone to edit this page. [alt-o]', + tip_protect_semi: 'Allows only users who have been registered for 4 days to edit this page. [alt-p]', + tip_flushlogs: 'Remove all edit and action logs for this page from the database. IRREVERSIBLE! (alt-l)', + tip_deletepage: 'Delete this page. This is always reversible unless the logs are cleared. (alt-k)', + tip_adminoptions: 'Administrative options for this page', + tip_moreoptions: 'Additional options for working with this page', + tip_password: 'Require a password in order for this page to be viewed', + tip_aclmanager: 'Manage who can do what with this page (alt-m)', + + cat_heading_subcategories: 'Subcategories', + cat_msg_no_subcategories: 'No subcategories.', + cat_heading_pages: 'Pages', + cat_msg_no_pages: 'No pages in this category.', + + filebox_heading: 'Uploaded file', + filebox_msg_not_found: 'There are no files uploaded with this name yet. Upload a file...', + filebox_lbl_type: 'Type:', + filebox_lbl_size: 'Size: %size%', + filebox_lbl_uploaded: 'Uploaded:', + filebox_msg_virus_warning: 'This file type may contain viruses or other code that could harm your computer. You should exercise caution if you download it.', + filebox_btn_download: 'Download this file', + filebox_btn_upload_new: 'Upload new version', + filebox_heading_history: 'File history', + filebox_btn_this_version: 'this ver', + filebox_btn_revert: 'revert', + + }, + editor: { + err_server: 'There was a problem starting the editor', + err_access_denied_title: 'Not authorized to view source', + err_access_denied_body: 'You are not authorized to edit or view the source of this page.', + err_save_title: 'There was a problem saving the page.', + err_save_body: 'A few problems were encountered while your page was being saved:', + err_obsolete_title: 'Someone else modified this page while you were editing it', + err_obsolete_body: 'While you were editing this page, %author% modified this page. The edit took place on %timestamp%. You can view the latest version of the page, or click %this.editor_btn_save% again to replace the page with your revision.', + err_need_captcha_title: 'Missing confirmation code', + err_need_captcha_body: 'Please enter the confirmation code in the box labeled "%this.editor_lbl_field_captcha_code%". %this.editor_msg_captcha_blind%', + err_no_text_title: 'No text entered', + err_no_text_body: 'Please enter the text that will be in this page.', + // Server-side errors + err_no_rows: 'Page doesn\'t exist in the database', + err_no_permission: 'You do not have permission to edit this page.', + err_page_protected: 'This page is protected, and you do not have permission to edit protected pages.', + err_captcha_wrong: 'The confirmation code you entered is incorrect.', + + msg_editor_heading: 'Editing page', + msg_saved: 'Your changes to this page have been saved.', + msg_revert_confirm: 'Do you really want to revert your changes?', + msg_discard_confirm: 'Do you really want to discard your changes?', + msg_confirm_ajax: 'Do you really want to do this?\nYour changes to this page have not been saved. If you continue, your changes will be lost.', + msg_unload: 'If you do, any changes that you have made to this page will be lost.', + msg_revert_confirm_title: 'Do you really want to revert your changes?', + msg_revert_confirm_body: 'If you choose to continue, all of the changes you have made to this page will be lost, and the editor will be set with the latest published (not draft) copy of the page.', + msg_cancel_confirm_title: 'Do you want to cancel your changes?', + msg_cancel_confirm_body: 'Are you sure you want to discard the changes you made? If you continue, your changes cannot be recovered.', + msg_diff: 'Below is a summarization of the differences between the current revision of the page (left), and your version (right).', + msg_diff_empty: 'There are no differences between the text in the editor and the current revision of the page.', + msg_editing_old_revision: 'You are editing an old revision of this page. If you click Save, newer revisions of this page will be undone.', + msg_have_draft_title: 'A draft copy of this page is available.', + msg_have_draft_body: '%author% saved a draft version of this page on %time%. You can use the draft copy, or edit the current published version (below). If you edit the published version, the draft copy will remain available, but will not reflect your changes. It is recommended that you edit the draft version instead of editing the published version.', + btn_graphical: 'graphical editor', + btn_wikitext: 'wikitext editor', + lbl_edit_summary: 'Brief summary of your changes:', + lbl_edit_summary_explain: 'Please summarize and briefly explain what you changed on the page.', + lbl_minor_edit: 'Mark revision as trivial:', + lbl_minor_edit_field: 'This is a minor edit', + lbl_minor_edit_explain: 'Select this if you\'re only making a minor change to the page', + btn_save: 'Save', + btn_savedraft: 'Save draft', + btn_preview: 'Preview', + btn_revert: 'Revert', + btn_cancel: 'Cancel', + btn_diff: 'Show changes', + btn_closeviewer: 'Close viewer', + msg_draft_saving: 'Saving...', + msg_draft_saved: 'Saved at %time%', + preview_blurb: 'Reminder: This is only a preview - your changes to this page have not yet been saved.', + msg_save_success_title: 'Changes saved', + msg_save_success_body: 'Your changes to this page have been saved. Redirecting...', + reversion_edit_summary: 'Undid %undo_count% revision(s) by %current_author% to revision %last_rev_id% by %old_author%', + + msg_captcha_pleaseenter: 'Please enter the code shown in the image to the right into the text box. This process helps to ensure that this page is not being edited by an automated bot. If the image to the right is illegible, you can regenerate it by clicking on the image (only works if your browser supports Javascript).', + msg_captcha_blind: 'If you are visually impaired or otherwise cannot read the text shown to the right, please contact the site management and they will be able to make your requested edits.', + lbl_field_captcha: 'Visual confirmation', + lbl_field_captcha_code: 'Code:', + }, + history: { + summary_clearlogs: 'Automatic backup created when logs were purged', + page_subtitle: 'History of edits and actions', + heading_edits: 'Edits:', + heading_other: 'Other changes:', + no_entries: 'No history entries in this category.', + btn_compare: 'Compare selected revisions', + col_diff: 'Diff', + col_datetime: 'Date/time', + col_user: 'User', + col_page: 'Page', + col_summary: 'Edit summary', + col_minor: 'Minor', + col_actions: 'Actions', + col_action_taken: 'Action taken', + col_extra: 'Extra info', + extra_reason: 'Reason:', + extra_oldtitle: 'Old title:', + tip_rdns: 'Click cell background for reverse DNS info', + action_view: 'View', + action_contrib: 'User contribs', + action_restore: 'Restore', + action_revert: 'Revert action', + log_protect: 'Protected page', + log_unprotect: 'Unprotected page', + log_semiprotect: 'Semi-protected page', + log_rename: 'Renamed page', + log_create: 'Created page', + log_delete: 'Deleted page', + log_uploadnew: 'Uploaded new file version', + lbl_comparingrevisions: 'Comparing revisions:', + summary_none_given: 'No edit summary provided.', + }, + catedit: { + title: 'Select which categories this page should be included in.', + no_categories: 'There are no categories on this site yet.', + catbox_lbl_categories: 'Categories:', + catbox_lbl_uncategorized: '(Uncategorized)', + catbox_link_edit: 'edit categorization', + catbox_link_showcategorization: 'show page categorization', + }, + tags: { + catbox_link: 'show page tags', + lbl_page_tags: 'Page tags:', + lbl_no_tags: 'No tags on this page', + btn_add_tag: '(add a tag)', + lbl_add_tag: 'Add a tag:', + btn_add: '+ Add', + }, + delvote: { + lbl_votes_one: 'There is one user that thinks this page should be deleted.', + lbl_votes_plural: 'There are %num_users% users that think this page should be deleted.', + lbl_users_that_voted: 'Users that voted:', + btn_deletepage: 'Delete page', + btn_resetvotes: 'Reset votes', + }, + ajax: { + // Client-side messages + protect_prompt_reason: 'Reason for (un)protecting:', + rename_prompt: 'What title should this page be renamed to?\nNote: This does not and will never change the URL of this page, that must be done from the admin panel.', + delete_prompt_reason: 'Please enter your reason for deleting this page.', + delete_confirm: 'You are about to REVERSIBLY delete this page. Do you REALLY want to do this?\n\n(Comments and categorization data, as well as any attached files, will be permanently lost)', + delvote_confirm: 'Are you sure that you want to vote that this page be deleted?', + delvote_reset_confirm: 'This action will reset the number of votes against this page to zero. Do you really want to do this?', + clearlogs_confirm: 'You are about to DESTROY all log entries for this page. As opposed to (example) deleting this page, this action is completely IRREVERSIBLE and should not be used except in dire circumstances. Do you REALLY want to do this?', + clearlogs_confirm_nag: 'You\'re ABSOLUTELY sure???', + changestyle_select: '[Select]', + changestyle_title: 'Change your theme', + changestyle_pleaseselect_theme: 'Please select a theme from the list.', + changestyle_lbl_theme: 'Theme:', + changestyle_lbl_style: 'Style:', + changestyle_success: 'Your theme preference has been changed.\nWould you like to reload the page now to see the changes?', + killphp_confirm: 'Are you really sure you want to do this? Some pages might not function if this emergency-only feature is activated.', + killphp_success: 'Embedded PHP in pages has been disabled.', + lbl_moreoptions_nojs: 'More options for this page', + + // Server-side responses + rename_too_short: 'The name you entered is too short. Please enter a longer name for this page.', + rename_success: 'The page "%page_name_old%" has been renamed to "%page_name_new%". You are encouraged to leave a comment explaining your action.\n\nYou will see the change take effect the next time you reload this page.', + clearlogs_success: 'The logs for this page have been cleared. A backup of this page has been added to the logs table so that this page can be restored in case of vandalism or spam later.', + delete_need_reason: 'Invalid reason for deletion passed. Please enter a reason for deleting this page.', + delete_success: 'This page has been deleted. Note that there is still a log of edits and actions in the database, and anyone with admin rights can raise this page from the dead unless the log is cleared. If the deleted file is an image, there may still be cached thumbnails of it in the cache/ directory, which is inaccessible to users.', + delvote_success: 'Your vote to have this page deleted has been cast.\nYou are encouraged to leave a comment explaining the reason for your vote.', + delvote_already_voted: 'It appears that you have already voted to have this page deleted.', + delvote_reset_success: 'The number of votes for having this page deleted has been reset to zero.', + password_success: 'The password for this page has been set.', + password_disable_success: 'The password for this page has been disabled.', + + }, + sidebar: { + title_navigation: 'Navigation', + title_tools: 'Tools', + title_search: 'Search', + title_links: 'Links', + + btn_home: 'Home', + btn_createpage: 'Create a page', + btn_uploadfile: 'Upload file', + btn_specialpages: 'Special pages', + btn_administration: 'Administration', + btn_editsidebar: 'Edit the sidebar', + btn_search_go: 'Go', + + btn_userpage: 'User page', + btn_mycontribs: 'My contributions', + btn_preferences: 'Preferences', + btn_privatemessages: 'Private messages', + btn_groupcp: 'Group control panel', + btn_register: 'Create an account', + btn_login: 'Log in', + btn_logout: 'Log out', + btn_changestyle: 'Change theme', + btn_recent_changes: 'Recent edits', + }, + perm: { + read: 'Read page(s)', + post_comments: 'Post comments', + edit_comments: 'Edit own comments', + edit_page: 'Edit page', + view_source: 'View source', + edit_wysiwyg: 'Use graphical editor (WEAK)', + mod_comments: 'Moderate comments', + history_view: 'View history/diffs', + history_rollback: 'Rollback history', + history_rollback_extra: 'Undelete page(s)', + protect: 'Protect page(s)', + rename: 'Rename page(s)', + clear_logs: 'Clear page logs (dangerous)', + vote_delete: 'Vote to delete', + vote_reset: 'Reset delete votes', + delete_page: 'Delete page(s)', + tag_create: 'Tag page(s)', + tag_delete_own: 'Remove own page tags', + tag_delete_other: 'Remove others\' page tags', + set_wiki_mode: 'Set per-page wiki mode', + password_set: 'Set password', + password_reset: 'Disable/reset password', + mod_misc: 'Super moderator (generate SQL backtraces, view IP addresses, and send large numbers of private messages)', + edit_cat: 'Edit categorization', + even_when_protected: 'Allow editing, renaming, and categorization even when protected', + upload_files: 'Upload files', + upload_new_version: 'Upload new versions of files', + create_page: 'Create pages', + html_in_pages: 'Embed unrestricted HTML in pages', + php_in_pages: 'Embed PHP code in pages', + edit_acl: 'Edit access control lists', + }, + plugin: { + specialadmin_title: 'Runt - the Enano administration panel', + specialadmin_desc: 'Provides the page Special:Administration, which is the AJAX frontend to the various Admin pagelets. This plugin cannot be disabled.', + privatemessages_title: 'Private Message frontend', + privatemessages_desc: 'Provides the page Special:PrivateMessages, which is used to manage private message functions. Also handles buddy lists.', + specialcss_title: 'CSS Backend', + specialcss_desc: 'Provides the page Special:CSS, which is used in template files to reference the style sheet. Disabling or deleting this plugin will result in site instability.', + specialgroups_title: 'Group control panel', + specialgroups_desc: 'Provides group moderators and site administrators with the ability to control who is part of their groups.', + specialpagefuncs_title: 'Special page-related pages', + specialpagefuncs_desc: 'Provides the page Special:CreatePage, which can be used to create new pages. Also adds the About Enano and GNU General Public License pages.', + specialsearch_title: 'Search UI/frontend', + specialsearch_desc: 'Provides the page Special:Search, which is a frontend to the Enano search engine.', + specialupdownload_title: 'Upload/download frontend', + specialupdownload_desc: 'Provides the pages Special:UploadFile and Special:DownloadFile. UploadFile is used to upload files to the site, and DownloadFile fetches the file from the database, creates thumbnails if necessary, and sends the file to the user.', + specialuserfuncs_title: 'Special user/login-related pages', + specialuserfuncs_desc: 'Provides the pages Special:Login, Special:Logout, Special:Register, and Special:Preferences.', + specialuserprefs_title: 'User control panel', + specialuserprefs_desc: 'Provides the page Special:Preferences.', + }, + paginate: { + lbl_page: 'Page:', + btn_first: 'First', + btn_last: 'Last', + btn_prev: 'Prev', + btn_next: 'Next', + lbl_goto_page: 'Go to page:', + err_bad_page_title: 'Invalid entry', + err_bad_page_body: 'Please enter a page number between 1 and %max%.', + }, + upload: { + err_disabled_site: 'File uploads are disabled this website.', + err_disabled_acl: 'File uploads are disabled for your user account or group.', + + err_title: 'Upload failed', + err_cant_get_file_meta: 'The server could not retrieve the array $_FILES[\'data\'].', + err_too_big_or_small: 'The file you uploaded is either too large or 0 bytes in length.', + err_banned_ext: 'The file type ".%ext%" is not allowed.', + err_banned_chars: 'The filename contains invalid characters.', + err_already_exists: 'The file already exists. You can upload a new version of this file.', + err_replace_protected: 'Either the file does not exist (and therefore cannot be updated) or the file is protected.', + err_move_failed: 'Could not move uploaded file to the new location.', + err_replace_denied: 'Uploading new versions of files has been disabled for your user account or group.', + + success_title: 'Upload complete', + success_body: 'Your file has been uploaded successfully. View the file\'s page.', + + intro: 'Using this form you can upload a file to the %config.site_name% site.', + max_filesize: 'The maximum file size is %config.max_file_size% %this.etc_unit_bytes% (%size%).', + field_file: 'File:', + field_renameto: 'Rename to:', + field_comments: 'Comments:
(can be wiki-formatted)', + field_reason: 'Reason for uploading the new version:', + btn_upload: 'Upload file', + + err_not_found_title: 'File not found', + err_not_found_body: 'The file "%filename%" cannot be found.', + }, + tz: { + // Thanks to phpBB for this timezone data. + // Do not add or remove from this list - contact the core team to have changes made to this list. + hrs_n12: 'UTC - 12 hours', + hrs_n11: 'UTC - 11 hours', + hrs_n10: 'UTC - 10 hours', + hrs_n9p5: 'UTC - 9:30 hours', + hrs_n9: 'UTC - 9 hours', + hrs_n8: 'UTC - 8 hours', + hrs_n7: 'UTC - 7 hours', + hrs_n6: 'UTC - 6 hours', + hrs_n5: 'UTC - 5 hours', + hrs_n4: 'UTC - 4 hours', + hrs_n3p5: 'UTC - 3:30 hours', + hrs_n3: 'UTC - 3 hours', + hrs_n2: 'UTC - 2 hours', + hrs_n1: 'UTC - 1 hour', + hrs_0: 'UTC', + hrs_1: 'UTC + 1 hour', + hrs_2: 'UTC + 2 hours', + hrs_3: 'UTC + 3 hours', + hrs_3p5: 'UTC + 3:30 hours', + hrs_4: 'UTC + 4 hours', + hrs_4p5: 'UTC + 4:30 hours', + hrs_5: 'UTC + 5 hours', + hrs_5p5: 'UTC + 5:30 hours', + hrs_5p75: 'UTC + 5:45 hours', + hrs_6: 'UTC + 6 hours', + hrs_6p5: 'UTC + 6:30 hours', + hrs_7: 'UTC + 7 hours', + hrs_8: 'UTC + 8 hours', + hrs_8p75: 'UTC + 8:45 hours', + hrs_9: 'UTC + 9 hours', + hrs_9p5: 'UTC + 9:30 hours', + hrs_10: 'UTC + 10 hours', + hrs_10p5: 'UTC + 10:30 hours', + hrs_11: 'UTC + 11 hours', + hrs_11p5: 'UTC + 11:30 hours', + hrs_12: 'UTC + 12 hours', + hrs_12p75: 'UTC + 12:45 hours', + hrs_13: 'UTC + 13 hours', + hrs_14: 'UTC + 14 hours', + title_n12: '[UTC - 12] Baker Island Time', + title_n11: '[UTC - 11] Niue Time, Samoa Standard Time', + title_n10: '[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time', + title_n9p5: '[UTC - 9:30] Marquesas Islands Time', + title_n9: '[UTC - 9] Alaska Standard Time, Gambier Island Time', + title_n8: '[UTC - 8] Pacific Standard Time', + title_n7: '[UTC - 7] Mountain Standard Time', + title_n6: '[UTC - 6] Central Standard Time', + title_n5: '[UTC - 5] Eastern Standard Time', + title_n4: '[UTC - 4] Atlantic Standard Time', + title_n3p5: '[UTC - 3:30] Newfoundland Standard Time', + title_n3: '[UTC - 3] Amazon Standard Time, Central Greenland Time', + title_n2: '[UTC - 2] Fernando de Noronha Time, South Georgia & the South Sandwich Islands Time', + title_n1: '[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time', + title_0: '[UTC] Western European Time, Greenwich Mean Time', + title_1: '[UTC + 1] Central European Time, West African Time', + title_2: '[UTC + 2] Eastern European Time, Central African Time', + title_3: '[UTC + 3] Moscow Standard Time, Eastern African Time', + title_3p5: '[UTC + 3:30] Iran Standard Time', + title_4: '[UTC + 4] Gulf Standard Time, Samara Standard Time', + title_4p5: '[UTC + 4:30] Afghanistan Time', + title_5: '[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time', + title_5p5: '[UTC + 5:30] Indian Standard Time, Sri Lanka Time', + title_5p75: '[UTC + 5:45] Nepal Time', + title_6: '[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time', + title_6p5: '[UTC + 6:30] Cocos Islands Time, Myanmar Time', + title_7: '[UTC + 7] Indochina Time, Krasnoyarsk Standard Time', + title_8: '[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time', + title_8p75: '[UTC + 8:45] Southeastern Western Australia Standard Time', + title_9: '[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time', + title_9p5: '[UTC + 9:30] Australian Central Standard Time', + title_10: '[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time', + title_10p5: '[UTC + 10:30] Lord Howe Standard Time', + title_11: '[UTC + 11] Solomon Island Time, Magadan Standard Time', + title_11p5: '[UTC + 11:30] Norfolk Island Time', + title_12: '[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time', + title_12p75: '[UTC + 12:45] Chatham Islands Time', + title_13: '[UTC + 13] Tonga Time, Phoenix Islands Time', + title_14: '[UTC + 14] Line Island Time', + // This is a JSON string that lists all the timezones that are defined here. + list: '{"n12":-12,"n11":-11,"n10":-10,"n9p5":-9.5,"n9":-9,"n8":-8,"n7":-7,"n6":-6,"n5":-5,"n4":-4,"n3p5":-3.5,"n3":-3,"n2":-2,"n1":-1,"0":0,"1":1,"2":2,"3":3,"3p5":3.5,"4":4,"4p5":4.5,"5":5,"5p5":5.5,"5p75":5.75,"6":6,"6p5":6.5,"7":7,"8":8,"8p75":8.75,"9":9,"9p5":9.5,"10":10,"10p5":10.5,"11":11,"11p5":11.5,"12":12,"12p75":12.75,"13":13,"14":14}', + }, + etc: { + redirect_title: 'Redirecting...', + redirect_body: 'Please wait while you are redirected.', + redirect_timeout: 'If you are not redirected within %timeout% seconds, please click here.', + // Generic "Save Changes" button + save_changes: 'Save changes', + // Generic "Cancel changes" button + cancel_changes: 'Cancel changes', + // Generic wizard buttons + wizard_next: 'Next >', + wizard_back: '< Back', + wizard_previous: '< Previous', + // Generic link to main page + btn_main_page: 'Main page', + // Generic switchable editor buttons + tinymce_btn_text: 'text editor', + tinymce_btn_graphical: 'graphical editor', + // Generic "Notice:" label + lbl_notice: 'Notice:', + // Generic "Access denied" + access_denied: 'Access to the specified file, resource, or action is denied.', + access_denied_short: 'Access denied', + return_to_page: 'Return to the page', + invalid_request_short: 'Invalid request', + // Message box buttons + ok: 'OK', + cancel: 'Cancel', + yes: 'Yes', + no: 'No', + unit_bytes: 'bytes', + unit_kilobytes: 'kilobytes', + unit_megabytes: 'megabytes', + unit_gigabytes: 'gigabytes', + unit_terabytes: 'terabytes', + unit_kilobytes_short: 'KB', + unit_megabytes_short: 'MB', + unit_gigabytes_short: 'GB', + unit_terabytes_short: 'TB', + unit_pixels: 'pixels', + unit_pixels_short: 'px', + } + } +}; + +// All done! :-) + diff -r d823e49e2e4e -r c433348f3628 language/english/install.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/language/english/install.json Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,365 @@ +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 + * Copyright (C) 2006-2007 Dan Fuhry + * + * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + * + * 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 details. + */ + +// Enano installer strings +// Language: ISO-639-3 eng (English) + +var enano_lang_install = { + categories: [ + 'meta', 'language', 'welcome', 'license', 'sysreqs', 'database', 'dbmysql', 'dbpgsql', 'website', 'login', 'confirm', 'install', 'finish', 'pophelp', + ], + strings: { + meta: { + site_name: 'Enano installation', + site_desc: 'Install Enano on your server.', + enano_copyright: 'Enano and its various components, related documentation, and artwork are copyright © 2006 Dan Fuhry.
This program is Free Software; see the file "GPL" included with this package for details.', + sidebar_heading: 'Installation progress', + btn_article: 'installation page', + btn_continue: 'Continue', + lbl_before_continue: 'Before continuing:', + step: 'Step %step%: %title%', + + msg_err_verification: 'One or more of the form fields is incorrect. Please correct any information in the form that has an "X" next to it.', + + msg_err_stagefailed_title: 'Enano installation failed.', + msg_err_stagefailed_body: 'When you have corrected the error, click the button below to attempt to continue the installation.', + msg_err_stagefailed_mysqlerror: 'The error returned from MySQL was:', + btn_retry_installation: 'Retry installation', + }, + language: { + modetitle: 'Language', + }, + welcome: { + modetitle: 'Welcome', + heading: 'Welcome to Enano', + version: 'version', + branch_stable: 'stable', + branch_unstable: 'unstable', + aka: 'also affectionately known as "%codename%" :)', + btn_start: 'Start installation', + }, + license: { + modetitle: 'License', + modetitle_long: 'License agreement', + heading: 'Welcome to the Enano installer.', + blurb_thankyou: 'Thank you for choosing Enano as your CMS. You\'ve selected the finest in design, the strongest in security, and the latest in Web 2.0 toys. Trust us, you\'ll like it.', + blurb_pleaseread: 'To get started, please read and accept the following license agreement. You\'ve probably seen it before.', + info_unstable_title: 'Notice for prerelease versions', + info_unstable_body: 'This version of Enano is designed only for testing and evaluation purposes. It is not yet completely stable, and should not be used on production websites. As with any Enano version, Dan Fuhry and the Enano team cannot be responsible for any damage, physical or otherwise, to any property as a result of the use of Enano. While security is a number one priority, sometimes things slip through.', + section_gpl_heading: 'Lawyer-readable version', + btn_i_agree: 'I agree to the license terms', + objective_ensure_agree: 'Ensure that you agree with the terms of the license', + objective_have_db_info: 'Have your database host, name, username, and password available', + gpl_blurb_inenglish: 'You may view a copy of the GNU General Public License in English in the file GPL-EN included with this package.', + }, + sysreqs: { + modetitle: 'Requirements', + modetitle_long: 'Server requirements', + heading: 'Checking your server', + blurb: 'Enano has several requirements that must be met before it can be installed. If all is good then note any warnings and click Continue below.', + req_php: 'PHP Version >=4.3.0', + req_php5: 'PHP 5.2.0 or later', + req_postgres: 'PostgreSQL extension for PHP', + req_mysql: 'MySQL extension for PHP', + req_uploads: 'File upload support', + req_apache: 'Apache HTTP Server', + req_config: 'Configuration file writable', + req_magick: 'ImageMagick support', + req_cachewriteable: 'Cache directory writable', + req_fileswriteable: 'File uploads directory writable', + + req_desc_php: 'It seems that the version of PHP that your server is running is too old to support Enano properly. If this is your server, please upgrade to the most recent version of PHP, remembering to use the --with-mysql configure option if you compile it yourself. If this is not your server, please contact your webhost and ask them if it would be possible to upgrade PHP. If this is not possible, you will need to switch to a different webhost in order to use Enano.', + req_desc_php5: 'Your server does not have support for PHP 5.2.0. While you may continue installing Enano, please be warned that as of December 31, 2007, all support for Enano on PHP 4 servers is discontinued. If you have at least PHP 5.0.0, support will still be available, but there are many security problems in PHP versions under 5.2.0 that Enano cannot effectively prevent.', + req_desc_postgres: 'It seems that your PHP installation does not have the PostgreSQL extension enabled. Because of this, you won\'t be able to use the PostgreSQL database driver. This is OK in the majority of cases. If you want to use PostgreSQL support, you\'ll need to either compile the PHP extension for Postgres or install the extension with your distribution\'s package manager. Windows administrators will need enable php_pgsql.dll in their php.ini.', + req_desc_mysql: 'It seems that your PHP installation does not have the MySQL extension enabled. If this is your own server, you may need to just enable the "libmysql.so" extension in php.ini. If you do not have the MySQL extension installed, you will need to either use your distribution\'s package manager to install it, or you will have to compile PHP from source. If you compile PHP from source, please remember to use the "--with-mysql" configure option, and you will have to have the MySQL development files installed (they usually are). If this is not your server, please contact your hosting company and ask them to install the PHP MySQL extension.', + req_desc_uploads: 'It seems that your server does not support uploading files. Enano *requires* this functionality in order to work properly. Please ask your server administrator to set the "file_uploads" option in php.ini to "On".', + req_desc_apache: 'Apparently your server is running a web server other than Apache. Enano will work nontheless, but there are some known bugs with non-Apache servers, and the "fancy" URLs will not work properly. The "Standard URLs" option will be set on the website configuration page, only change it if you are absolutely certain that your server is running Apache.', + req_desc_config: 'It looks like the configuration file, config.new.php, is not writable. Enano needs to be able to write to this file in order to install.

If you are installing Enano on a SourceForge web site:
SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.', + req_desc_magick: 'Enano uses ImageMagick to scale images into thumbnails. Because ImageMagick was not found on your server, Enano will use the width= and height= attributes on the <img> tag to scale images. This can cause somewhat of a performance increase, but bandwidth usage will be higher, especially if you use high-resolution images on your site.

If you are sure that you have ImageMagick, you can set the location of the "convert" program using the administration panel after installation is complete.', + req_desc_cachewriteable: 'Apparently the cache/ directory is not writable. Enano will still work, but you will not be able to cache thumbnails, meaning the server will need to re-render them each time they are requested. In some cases, this can cause a significant slowdown.', + req_desc_fileswriteable: 'It seems that the directory where uploaded files are stored (%enano_root%/files) cannot be written by the server. Enano will still function, but file uploads will not function, and will be disabled by default.', + + summary_success_title: 'Your server meets all the requirements for running Enano.', + summary_success_body: 'Click the button below to continue the installation.', + + summary_warn_title: 'Some of the features of Enano have been turned off to accommodate your server.', + summary_warn_body: 'Enano has detected that some of the features or configuration settings on your server are not optimal for the best behavior and/or performance for Enano. As a result, Enano has disabled these features as a precaution to prevent errors and potential security issues.', + + summary_fail_title: 'Your server does not meet the requirements for Enano to run.', + summary_fail_body: 'As a precaution, Enano will not install until the above requirements have been met. Contact your server administrator or hosting company and convince them to upgrade. Good luck.', + + objective_scalebacks: 'Review the list above to ensure that you are satisfied with any of Enano\'s workarounds for your server. If you need a particular feature and that feature is listed as disabled above, you should take the opportunity now to correct the problem.' + }, + database: { + modetitle: 'Database', + modetitle_long: 'Database information', + heading_optionalinfo: 'Optional information', + + driver_heading: 'Choose a database driver', + driver_intro: 'The next step is to choose the database driver that Enano will use. In most cases this is MySQL, but there are certain advantages to PostgreSQL, which is made available only experimentally.', + driver_msg_virt_appliance: 'You\'re using the Enano virtual appliance.
Unless you configured the appliance manually, PostgreSQL support is not available. In 99% of cases you\'ll want to click MySQL below.', + driver_err_no_mysql: 'You don\'t have the MySQL PHP extension installed.', + driver_err_no_pgsql: 'You don\'t have the PostgreSQL PHP extensnion installed.', + driver_mysql: 'MySQL', + driver_mysql_intro: 'Click this button to use MySQL as the database backend for your site. Most web hosts support MySQL, and if you have administrative access to your MySQL server, you can create a new database and user during this installation process if you haven\'t done so already.', + driver_pgsql: 'PostgreSQL', + driver_pgsql_intro: 'Click this button to use PostgreSQL as the database backend for your site. While not as widely supported, PostgreSQL has more liberal licensing conditions and when properly configured is faster than MySQL. Some plugins may not work with the PostgreSQL driver.', + + objective_test: 'Check your MySQL connection using the "Test Connection" button.', + objective_uncrypt: 'Be aware that your database information will be transmitted unencrypted several times.', + + // database_post module + btn_go_back: 'Go back', + msg_success_title: 'Connection successful', + msg_success_body: 'The database has been contacted and initial tables created successfully. Redirecting...', + msg_success_redirect: 'Click if you\'re not redirected within 2 seconds', + + msg_post_fail_title: 'Database connection failed', + msg_post_fail_body: 'The installer couldn\'t connect to the database because something went wrong while the connection attempt was being made. Please press your browser\'s back button and correct your database information.', + msg_post_fail_desc: 'Error description:', + + msg_sql_fail_title: 'Database operation failed', + msg_sql_fail_body: 'The installer couldn\'t create one of the tables used for installation.', + }, + dbmysql: { + msg_err_mysql_connect: 'Error: The database server "%db_host%" couldn\'t be contacted.
%mysql_error%', + msg_err_mysql_auth: 'Error: Access to MySQL under the specified credentials was denied.
%mysql_error%', + msg_err_mysql_dbperm: 'Error: Access to the specified database using those login credentials was denied.
%mysql_error%', + msg_err_mysql_dbexist: 'Error: The specified database does not exist
%mysql_error%', + msg_err_mysql_version: 'Error: Your version of MySQL (%mysql_version%) is older than 4.1.17. Enano will still work, but there is a known bug with the comment system and MySQL 4.1.11 that involves some comments not being displayed, due to an issue with the PHP function mysql_fetch_row().', + + msg_warn_creating_db: 'Warning: The database you specified does not exist. It will be created during installation.', + msg_warn_creating_user: 'Warning: The specified regular user does not exist or the password is incorrect. The user will be created during installation. If the user already exists, the password will be reset.', + msg_warn_mysql_version: 'The MySQL version that your server is running could not be determined.', + + msg_info_mysql_good: 'Your version of MySQL meets Enano requirements.', + msg_test_success: 'All checks passed! You can use this database configuration with Enano.', + + blurb_needdb: 'Now we need some information that will allow Enano to contact your database server. Enano uses MySQL as a data storage backend, and we need to have access to a MySQL server in order to continue.', + blurb_howtomysql: 'If you do not have access to a MySQL server, and you are using your own server, you can download MySQL for free from MySQL.com. Please note that, like Enano, MySQL is licensed under the GNU GPL. If you need to modify MySQL and then distribute your modifications, you must either distribute them under the terms of the GPL or purchase a proprietary license.', + + vm_login_info: 'MySQL login information for this virtual appliance:

Database hostname: %host%
Database login: username "%user%", password: "%pass%" (without quotes)
Database name: %name%', + + table_title: 'Database information', + + field_hostname_title: 'Database hostname', + field_hostname_body: 'This is the hostname (or sometimes the IP address) of your MySQL server. In many cases, this is "localhost".', + field_dbname_title: 'Database name', + field_dbname_body: 'The name of the actual database. If you don\'t already have a database, you can create one here, if you have the username and password of a MySQL user with administrative rights.', + field_dbauth_title: 'Database login', + field_dbauth_body: 'These fields should be the username and password of a user with "select", "insert", "update", "delete", "create table", and "replace" privileges for your database.', + field_tableprefix_title: 'Table prefix', + field_tableprefix_body: 'The value that you enter here will be added to the beginning of the name of each Enano table. You may use lowercase letters (a-z), numbers (0-9), and underscores (_).', + field_rootauth_title: 'Database administrative login', + field_rootauth_body: 'If the MySQL database or username that you entered above does not exist yet, you can create them here, assuming that you have the login information for an administrative user (such as root). Leave these fields blank unless you need to use them.', + field_mysqlversion_title: 'MySQL version', + field_mysqlversion_blurb_willbechecked: 'MySQL version information will be checked when you click "Test Connection".', + field_droptables_title: 'Delete existing tables?', + field_droptables_body: 'If this option is checked, all the tables that will be used by Enano will be dropped (deleted) before the schema is executed. Do NOT use this option unless specifically instructed to.', + field_droptables_lbl: 'Drop existing tables', + + btn_testconnection: 'Test connection', + }, + dbpgsql: { + msg_err_connect: 'There was a problem connecting to PostgreSQL. Please check your connection information above.', + msg_err_version: 'Error: Your version of PostgreSQL (%pg_version%) is older than 8.2.5. Enano cannot be installed.', + + msg_warn_pg_version: 'The PostgreSQL version that your server is running could not be determined.', + msg_err_auth: 'Access to the database was denied. Ensure that your database exists and that your username and password are correct.', + + msg_info_version_good: 'Your version of PostgreSQL meets Enano requirements.', + msg_test_success: 'All checks passed! You can use this database configuration with Enano.', + + blurb_needdb: 'Now we need some information that will allow Enano to contact your database server. Enano uses PostgreSQL as a data storage backend, and we need to have access to a PostgreSQL server in order to continue.', + blurb_howtomysql: 'If you do not have access to a PostgreSQL server, and you are using your own server, you can download PostgreSQL for free from PostgreSQL.com. Please note that, like Enano, PostgreSQL is licensed under the GNU GPL. If you need to modify PostgreSQL and then distribute your modifications, you must either distribute them under the terms of the GPL or purchase a proprietary license.', + + vm_login_info: 'PostgreSQL login information for this virtual appliance:

Database hostname: %host%
Database login: username "%user%", password: "%pass%" (without quotes)
Database name: %name%', + + table_title: 'Database information', + + field_hostname_title: 'Database hostname', + field_hostname_body: 'This is the hostname (or sometimes the IP address) of your PostgreSQL server. In many cases, this is "localhost".', + field_dbname_title: 'Database name', + field_dbname_body: 'The name of the actual database. If you don\'t already have a database, you can create one here, if you have the username and password of a PostgreSQL user with administrative rights.', + field_dbauth_title: 'Database login', + field_dbauth_body: 'These fields should be the username and password of a user with "select", "insert", "update", "delete", "create table", and "replace" privileges for your database.', + field_tableprefix_title: 'Table prefix', + field_tableprefix_body: 'The value that you enter here will be added to the beginning of the name of each Enano table. You may use lowercase letters (a-z), numbers (0-9), and underscores (_).', + field_rootauth_title: 'Database administrative login', + field_rootauth_body: 'If the PostgreSQL database or username that you entered above does not exist yet, you can create them here, assuming that you have the login information for an administrative user (such as root). Leave these fields blank unless you need to use them.', + field_pgsqlversion_title: 'PostgreSQL version', + field_pgsqlversion_blurb_willbechecked: 'PostgreSQL version information will be checked when you click "Test Connection".', + field_droptables_title: 'Delete existing tables?', + field_droptables_body: 'If this option is checked, all the tables that will be used by Enano will be dropped (deleted) before the schema is executed. Do NOT use this option unless specifically instructed to.', + field_droptables_lbl: 'Drop existing tables', + + btn_testconnection: 'Test connection', + }, + website: { + modetitle: 'Site info', + modetitle_long: 'Website information', + header_blurb: 'The next step is to enter some information about your website. You can always change this information later, using the administration panel.', + + msg_ajax_test_fail_title: 'All tests failed', + msg_ajax_test_fail_body: 'None of the URL handling tests worked; you may have problems using Enano on your server.', + msg_bestmethod_rewrite: 'The installer has detected that using rewritten URLs is the best level that will work.', + msg_bestmethod_shortened: 'The installer has detected that using shortened URLs is the best level that will work.', + msg_bestmethod_standard: 'The installer has detected that using standard URLs is the only level that will work.', + + field_name: 'Pick a name', + field_name_hint: 'Now for the fun part - it\'s time to name your website. Try to pick something that doesn\'t include any special characters, since this can make project-page URLs look botched.', + field_desc: 'Enter a short description', + field_desc_hint: 'Here you should enter a very short description of your site. Sometimes this is a slogan or, depending on the theme you\'ve chosen, a set of keywords that can go into a META description tag.', + field_copyright: 'Copyright info', + field_copyright_hint: 'The text you enter here will be shown at the bottom of most pages. Typically this is where a copyright notice would go. Keep it short and sweet; you can use internal links to link to project pages you\'ll create later.', + field_urlscheme: 'URL formatting', + field_urlscheme_hint: 'This lets you choose how URLs within your site will be formatted. If the setting you pick doesn\'t work, you can change it by editing config.php after installation.', + field_urlscheme_lbl_example: 'Example:', + field_urlscheme_opt_standard: 'Standard URLs', + field_urlscheme_opt_standard_hint: 'Compatible with all servers. This is the default option and should be used unless you\'re sure that one of the other options below will work.', + field_urlscheme_opt_shortened: 'Shortened URLs', + field_urlscheme_opt_shortened_hint: 'This eliminates the "?title=" portion of your URL, and instead uses a slash. This is occasionally more friendly to search engines.', + field_urlscheme_opt_rewrite: 'Rewritten URLs', + field_urlscheme_opt_rewrite_hint: 'Using this option, you can completely eliminate the "index.php" from URLs. This is the most friendly option to search engines and looks very professional, but requires support for URL rewriting on your server. If you\'re running Apache and have the right permissions, Enano can configure this automatically. Otherwise, you\'ll need to configure your server manually and have a knowledge of regular expressions for this option to work.', + btn_urlscheme_detect: 'Auto-detect the best formatting scheme', + + objective_verify: 'Verify that your site information is correct. Again, all of the above settings can be changed from the administration panel.', + }, + login: { + modetitle: 'Admin login', + header_blurb: 'Next, enter your desired username and password. The account you create here will be used to administer your site.', + modetitle_long: 'Administration login', + + welcome_title: 'Administration account', + welcome_body: '

Now it\'s time to create the account you\'ll use to administer your site. The e-mail address you enter here will also be used for the global contact address; you can change this after installation is finished if need be.

+

Do not forget the information you enter here. Otherwise you will be unable to administer your site.

', + err_verify_failure: 'One or more of the form fields contains an incorrect value. Please correct any fields that have an X next to them.', + err_rijndael_failed: 'Received a bad response from rijndaelEncrypt(). Shift-click "reload" or "refresh" (depending on your browser) and try again.', + field_username: 'Username', + field_password: 'Password', + aes_blurb: 'This will be encrypted with AES before it\'s sent to the server.', + field_password_confirm: '(confirm)', + field_email: 'E-mail', + + objective_remember: 'Remember the username and password you enter here! You will not be able to administer your site without the information you enter on this page.', + }, + confirm: { + modetitle: 'Review', + modetitle_long: 'Confirm installation', + + title: 'Enano is ready to install.', + body: 'Almost there! You\'ve entered all the information we need for now. Click the button below to install the Enano database.', + info_aes_title: 'A note on AES encryption:', + info_aes_body: 'Enano is currently configured to use %aes_bits%-bit AES encryption. While the default value of 192 bits is perfectly acceptable for most sites, those in need of extreme security will want to change this value to 256 bits (the maximum available strength). If you need to change the cipher strength, please edit the file includes/constants.php and then restart this installation. Do not click Continue below until you redo the installation process up until this point, or you will experience severe problems with logging into your site.', + + btn_install_enano: 'Install Enano!', + }, + install: { + modetitle: 'Install', + modetitle_long: 'Database installation', + + title: 'Installing Enano', + body: 'Please wait while Enano creates its database and initial content on your server.', + heading_progress: 'Installation progress', + + stg_load_title: 'Load installer files', + stg_load_body: 'One of the files needed for installation couldn\'t be loaded. Please check your Enano directory.', + stg_setpass_title: 'Retrieve administrator password', + stg_setpass_body: 'The administrator password couldn\'t be decrypted. This really shouldn\'t happen.', + stg_genaes_title: 'Generate private key', + stg_genaes_body: 'Couldn\'t generate a private key for the site. This really shouldn\'t happen.', + stg_sqlparse_title: 'Prepare database schema', + stg_sqlparse_body: 'Couldn\'t load or parse the schema file. This really shouldn\'t happen.', + stg_payload_title: 'Install database', + stg_payload_body: 'There was a problem with an SQL query. Details are above.', + stg_writeconfig_title: 'Write configuration files', + stg_writeconfig_body: 'Enano was unable to write the configuration file with your site\'s database credentials. This is almost always because your configuration file does not have the correct permissions. On Windows servers, you may see this message even if the check on the System Requirements page passed. Temporarily running IIS as the Administrator user may help.', + + stg_startapi_title: 'Start the Enano API', + stg_startapi_body: 'The Enano API could not be started. This is an error that should never occur; please contact the Enano team for support.', + stg_importlang_title: 'Import default language', + stg_importlang_body: 'Enano couldn\'t import the English language file.', + stg_initlogs_title: 'Initialize logs', + stg_initlogs_body: 'The session manager denied the request to flush logs for the main page.
+ While under most circumstances you can still finish the installation, you should be aware that some servers cannot + properly set cookies due to limitations with PHP. These limitations are exposed primarily when this issue is encountered during installation. If you choose + to finish the installation, please be aware that you may be unable to log into your site.', + + stg_cleanup_title: 'Clean up encryption keys', + stg_cleanup_body: 'There was a database error while removing the temporary encryption keys from the database. For maximum site security you should delete the config entries install_aes_key and site_aes_key manually.', + stg_rename_title: 'Rename configuration files', + stg_rename_body: 'Enano couldn\'t rename the configuration files to their correct production names. Please perform the following rename operations and then follow the instructions to finish the installation below. +
    +
  • Rename config.new.php to config.php
  • +
  • Rename .htaccess.new to .htaccess (only if you selected the Rewrite URL scheme)
  • +
+ %this.finish_body% + %this.finish_link_mainpage%', + stg_buildindex_title: 'Initialize search index', + stg_buildindex_body: 'Something went wrong while the page manager was attempting to build a search index.', + }, + finish: { + modetitle: 'Finish', + modetitle_long: 'Complete installation', + + heading_progress: 'Performing final installation steps', + msg_progress: 'Enano is cleaning up and performing some final installation tasks. Please wait...', + msg_success_title: 'Congratulations! You\'ve finished installing Enano.', + msg_success_body: 'Enano has finished setting up on your server. Now you can go to your new website and start creating content!', + + body: '

Wait... Now what?

+

Click the link below to see the main page for your website. Where to go from here:

+
    +
  • The first thing you should do is log into your site using the Log in link on the sidebar.
  • +
  • Go into the Administration panel, expand General, and click General Configuration. There you will be able to configure some basic information about your site.
  • +
  • Visit the Enano Plugin Gallery to download and use plugins on your site.
  • +
  • Periodically create a backup of your database and filesystem, in case something goes wrong. This should be done at least once a week – more for wiki-based sites.
  • +
  • Hire some moderators, to help you keep rowdy users tame.
  • +
  • Tell the Enano team what you think.
  • +
  • Spread the word about Enano by adding a link to the Enano homepage on your sidebar! You can enable this option in the General Configuration section of the administration panel.
  • +
', + link_mainpage: 'Go to your website...', + }, + pophelp: { + admin_embed_php_title: 'Allow administrators to embed PHP', + admin_embed_php_body: '

This option allows you to control whether anything between the standard <?php and ?> tags will be treated as + PHP code by Enano. If this option is enabled, and members of the Administrators group use these tags, Enano will + execute that code when the page is loaded. There are obvious potential security implications here, which should + be carefully considered before enabling this option.

+

If you are the only administrator of this site, or if you have a high level of trust for those will be administering + the site with you, you should enable this to allow extreme customization of pages.

+

Leave this option off if you are at all concerned about security – if your account is compromised and PHP embedding + is enabled, an attacker can run arbitrary code on your server! Enabling this will also allow administrators to + embed Javascript and arbitrary HTML and CSS.

+

If you don\'t have experience coding in PHP, you can safely disable this option. You may change this at any time + using the ACL editor by selecting the Administrators group and This Entire Website under the scope selection.

', + url_schemes_title: 'URL schemes', + url_schemes_body: '

The URL scheme allows you to decide how the URLs to your Enano pages will look.

+

The first option (Standard URLs) works on any web server. You should select it if your server doesn\'t run Apache, or + if you are at all unsure of your server\'s configuration. With this scheme, URLs at your site will look like + http://yoursite.com/path-to-enano/index.php/Main_Page.

+

The second option, Small URLs, will be selected by default if Enano detects Apache. Small URLs are more friendly towards + search engines, but they don\'t work on very many non-Apache servers, or if PHP is set up through CGI on your server. Many + free and low-cost web hosts will configure PHP through CGI in order to keep your user account as the owner of any files that + Enano generates. With this scheme, URLs at your site will look like http://yoursite.com/path-to-enano/index.php/Main_Page. +

+

The last option, Tiny URLs, is the most friendly URL scheme for search engines, because your URLs won\'t have any special characters + at all in them. However, this only works if your webhost has configured Apache with support for mod_rewrite. Most of the time if your + host supports this you will see a listing for it in their feature matrix. None of the popular Linux distributions (such as Ubuntu, + Debian, Red Hat Enterprise Linux™, Fedora, openSUSE™, or CentOS) come with mod_rewrite enabled, so if you run a + home-brew server, you should consult your distribution\'s documentation for enabling mod_rewrite before selecting this option. + With this scheme, URLs at your site will look like http://yoursite.com/path-to-enano/Main_Page.

+

', + btn_close_window: 'Close window', + } + } +} diff -r d823e49e2e4e -r c433348f3628 language/english/install/license-deed.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/language/english/install/license-deed.html Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,25 @@ +

GNU General Public License

+ +

Declaration of license usage

+ +

Enano is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

+

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 (below) for more details.

+

By clicking the button below or otherwise continuing the installation, you indicate your acceptance of this license agreement.

+ +

Human-readable version

+

Enano is distributed under certain licensing terms that we believe make it of the greatest possible use to the public. The license we distribute it under, the GNU General Public License, provides certain terms and conditions that, rather than limit your use of Enano, allow you to get the most out of it. If you would like to read the full text, it can be found below. Here is a human-readable version that we think is a little easier to understand.

+
    +
  • You may to run Enano for any purpose.
  • +
  • You may study how Enano works and adapt it to your needs.
  • +
  • You may redistribute copies so you can help your neighbor.
  • +
  • You may improve Enano and release your improvements to the public, so that the whole community benefits.
  • +
+

You may exercise the freedoms specified here provided that you comply with the express conditions of this license. The principal conditions are:

+
    +
  • You must conspicuously and appropriately publish on each copy distributed an appropriate copyright notice and disclaimer of warranty and keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of Enano a copy of the GNU General Public License along with Enano. Any translation of the GNU General Public License must be accompanied by the GNU General Public License.
  • +
  • If you modify your copy or copies of Enano or any portion of it, or develop a program based upon it, you may distribute the resulting work provided you do so under the GNU General Public License. Any translation of the GNU General Public License must be accompanied by the GNU General Public License.
  • +
  • If you copy or distribute Enano, you must accompany it with the complete corresponding machine-readable source code or with a written offer, valid for at least three years, to furnish the complete corresponding machine-readable source code.
  • +
+

+ Disclaimer: The above text is not a license. It is simply a handy reference for understanding the Legal Code (the full license) – it is a human-readable expression of some of its key terms. Think of it as the user-friendly interface to the Legal Code beneath. The above text itself has no legal value, and its contents do not appear in the actual license.
Text copied from the Creative Commons GPL Deed page +

diff -r d823e49e2e4e -r c433348f3628 language/english/install/mainpage-default.wkt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/language/english/install/mainpage-default.wkt Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,11 @@ +=== Enano has been successfully installed and is working. === + +If you can see this message, it means that you've finished the Enano setup process and are ready to start building your website. Congratulations! + +To edit this front page, click the Log In button to the left, enter the credentials you provided during the installation, and click the Edit This Page button that appears on the blue toolbar just above this text. You can also [http://docs.enanocms.org/Help:2.4 learn more] about editing pages. + +To create more pages, use the Create a Page button to the left. If you enabled wiki mode, you don't have to log in first, however your IP address will be shown in the page history. + +Visit the [http://docs.enanocms.org/Help:Contents Enano documentation project website] to learn more about administering your site effectively and keeping things secure. + +'''NOTE:''' You have just installed an unstable version of Enano. This release is completely unsupported and may contain security issues or serious usability bugs. You should not use this release on a production website. The Enano team will not provide any type of support at all for this experimental release. diff -r d823e49e2e4e -r c433348f3628 language/english/meta.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/language/english/meta.json Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,6 @@ +{ + // Language metadata + lang_name_english: 'English', + lang_name_native: 'English', + lang_code: 'eng' +} diff -r d823e49e2e4e -r c433348f3628 language/english/tools.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/language/english/tools.json Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,149 @@ +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 + * Copyright (C) 2006-2007 Dan Fuhry + * + * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + * + * 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 details. + */ + +var enano_lang = { + categories: [ + 'meta', 'search', 'specialpage', 'pagetools' + ], + strings: { + meta: { + search: 'Search page', + specialpage: 'Special pages', + pagetools: 'Userspace page-management tools', + }, + specialpage: { + administration: 'Administration', + manage_sidebar: 'Manage the Sidebar', + css: 'Templated style sheet generator', + groupcp: 'Group Membership', + create_page: 'Create page', + all_pages: 'All pages', + special_pages: 'List of special pages', + about_enano: 'About Enano', + gnu_gpl: 'GNU General Public License', + tag_cloud: 'Tag cloud', + search_rebuild: 'Rebuild search index', + search: 'Search', + upload_file: 'Upload file', + download_file: 'Download file', + log_in: 'Log in', + log_out: 'Log out', + register: 'Register', + preferences: 'Edit Profile', + contributions: 'User contributions', + change_theme: 'Change my preferred theme', + activate_account: 'Activate user account', + captcha: 'CAPTCHA image generator', + password_reset: 'Reset forgotten password', + member_list: 'Member list', + language_export: 'Language exporter', + private_messages: 'Private Messages', + recent_changes: 'Recent changes', + }, + search: { + th_advanced_search: 'Advanced Search', + + err_query_title: 'Some problems were encountered during your search.', + err_query_body: 'There was a problem with your search query, and as a result there may be a reduced number of search results.', + err_query_too_many_terms: 'Some of your search terms were excluded because searches are limited to 20 terms to prevent excessive server load.', + err_query_has_stopwords: 'One or more of your search terms was excluded because either it was less than 2 characters in length or is a common word (a stopword) that is typically found on a large number of pages. Examples of stopwords include "the", "this", "which", "with", etc.', + err_query_dup_terms: 'One or more of your search terms was excluded because duplicate terms were encountered.', + err_query_term_too_short: 'One or more of your search terms was excluded because terms must be at least 4 characters in length.', + err_query_no_positive: 'You need to have at least one keyword in your search query. Searching only for pages not containing a term is not allowed.', + + btn_search: 'Search', + // note the case difference with th_advanced_search + btn_advanced_search: 'Advanced search', + + msg_no_results: 'No results.', + msg_result_detail: 'Results %start_string% - %per_string% of about %num_results% for %q_trim% in %search_time%s.', + body_no_results_title: 'Your search for "%query%" didn\'t turn up any results.', + body_no_results_body: '

There are a few things you can try:

+
    +
  • Were you looking for a specific Special page? Special pages are not searchable. You may want to see a list of special pages.
  • +
  • If you have the appropriate permissions, you can start the %query% page.
  • +
  • Try using fewer keywords. You can get broader results if you remove quotes from your search query.
  • +
  • Did your search trigger any warnings? Sometimes a search can be cancelled if there aren\'t any terms in a search query that are 4 characters or greater in length.
  • +
', + + lbl_site_search: 'Site search', + lbl_relevance: 'Relevance:', + lbl_field_any: 'Search for pages with any of these words:', + lbl_field_exact: 'with this exact phrase:', + lbl_field_none: 'with none of these words:', + lbl_field_all: 'with all of these words:', + lbl_field_casesensitive: 'Case-sensitive search:', + + result_tag_special: 'Special page', + }, + pagetools: { + + // Create a page + create_err_invalid_namespace: 'You have selected an invalid page type.', + create_err_invalid_urlname: 'Please enter a title for your page and a custom URL if desired.', + create_err_already_exists: 'A page with that URL already exists. Please enter another title or enter a custom URL. (You can have two pages with the same name, but not two pages with the same URL.)', + create_err_no_permission: 'You don\'t have permission to create this page. Try another URL or title; if that does not work, please contact the site administration for permission to create pages.', + create_err_nodb_namespace: 'You cannot create Special or Admin pages - they can\'t be stored in the database.', + create_err_reserved_prefix: 'The prefix "Project:" is reserved for internal links and can\'t be used on a page name.', + + create_blurb: 'Add a new page to the site.', + create_field_title: 'Page title:', + create_field_namespace: 'Page type:', + create_group_advanced: 'Advanced options', + create_field_url_auto: 'Generate a URL based on the title', + create_field_url_manual: 'Enter a custom page URL', + create_field_url: 'Page ID:', + create_field_preview: 'Preview of URL:', + create_field_preview_hint: '(Requires Javascript support)', + create_btn_create: 'Create page', + + // All pages + allpages_blurb: 'Below is a list of all of the pages on this website.', + + // Special pages + specialpages_blurb: 'Below is a list of all of the special pages on this website.', + + // GPL page + gpl_blurb: 'The following text represents the license that the Enano content management system is under. To make it easier to read, the text has been wiki-formatted; in no other way has it been changed.', + // The following three strings will be used only in non-English languages. A Spanish example is provided here. + + // "Version in Spanish" + gpl_title_native: 'Versión en español', + // "Version in English" + gpl_title_english: 'Versión en inglés', + // "View the license in English" + gpl_link_to_english: 'Vea la licencia en inglés', + + gpl_err_file_missing: 'It appears that the file "GPL" is missing from your Enano installation. You may find a wiki-formatted copy of the GPL at: http://enanocms.org/GPL. In the mean time, you may wish to contact the site administration and ask them to replace the GPL file.', + + // Tag cloud + tagcloud_pagelist_th: 'Pages tagged "%tag%"', + tagcloud_blurb: 'Summary of page tagging', + tagcloud_msg_no_tags: 'No pages are tagged yet.', + tagcloud_btn_return: 'Return to tag cloud', + tagcloud_instructions: 'Hover your mouse over a tag to see how many pages have the tag. Click on a tag to see a list of the pages that have it.', + tagcloud_sidebar_title: 'Tag cloud', + tagcloud_sidebar_btn_larger: 'Larger version', + tagcloug_tip_popularity_one: '1 page', + tagcloug_tip_popularity_plural: '%popularity% pages', + + // Recent changes + rc_btn_diff: 'diff', + rc_btn_hist: 'hist', + rc_btn_pm: 'PM', + rc_btn_usertalk: 'comment', + }, + } +}; + +// All done! :-) + diff -r d823e49e2e4e -r c433348f3628 language/english/user.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/language/english/user.json Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,609 @@ +/* + * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between + * Version 1.1.1 + * Copyright (C) 2006-2007 Dan Fuhry + * + * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + * + * 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 details. + */ + +var enano_lang = { + categories: [ + 'meta', 'user', 'usercp', 'groupcp', 'privmsgs', 'userfuncs', 'userpage', + ], + strings: { + meta: { + user: 'Login, logout, and authentication', + usercp: 'User control panel', + groupcp: 'Group control panel', + privmsgs: 'Private message and buddy list CP', + userfuncs: 'User management pages', + userpage: 'User pages', + }, + user: { + login_message_short: 'Please enter your username and password to log in.', + login_message_short_elev: 'Please re-enter your login details', + login_body: 'Logging in enables you to use your preferences and access member information. If you don\'t have a username and password here, you can create an account.', + login_body_elev: 'You are requesting that a sensitive operation be performed. To continue, please re-enter your password to confirm your identity.', + login_field_username: 'Username', + login_field_password: 'Password', + login_forgotpass_blurb: 'Forgot your password? No problem.', + login_createaccount_blurb: 'Maybe you need to create an account.', + login_field_captcha: 'Code in image', + login_nocrypt_title: 'Important note regarding cryptography:', + login_nocrypt_body: 'Some countries do not allow the import or use of cryptographic technology. If you live in one of the countries listed below, you should log in without using encryption.', + login_nocrypt_countrylist: 'This restriction applies to the following countries: Belarus, China, India, Israel, Kazakhstan, Mongolia, Pakistan, Russia, Saudi Arabia, Singapore, Tunisia, Venezuela, and Vietnam.', + login_usecrypt_title: 'Encryption is currently turned off.', + login_usecrypt_body: 'If you are not in one of the countries listed below, you should enable encryption to secure the logon process.', + login_usecrypt_countrylist: 'The cryptography restriction applies to the following countries: Belarus, China, India, Israel, Kazakhstan, Mongolia, Pakistan, Russia, Saudi Arabia, Singapore, Tunisia, Venezuela, and Vietnam.', + login_success_title: 'Login successful', + login_success_body: 'You have successfully logged into the %config.site_name% site as "%username%". Redirecting to %redir_target%...', + login_success_body_mainpage: 'the main page', + login_success_short: 'Success.', + + login_noact_title: 'Account error', + login_noact_msg_intro: 'It appears that your user account has not yet been activated.', + login_noact_solution_none: 'Your account was most likely deactivated by an administrator. Please contact the site administration for further assistance.', + login_noact_solution_user: 'Please check your e-mail; you should have been sent a message with instructions on how to activate your account. If you do not receive an e-mail from this site within 24 hours, please contact the site administration for further assistance.', + login_noact_solution_admin: 'This website has been configured so that all user accounts must be activated by the administrator before they can be used, so your account will most likely be activated the next time an administrator visits the site.', + login_noact_msg_logout_success_title: 'Logged out', + login_noact_msg_logout_success_body: 'You have successfully been logged out. All cookies cleared.', + login_noact_msg_ask_admins: 'If you are having trouble or did not receive the e-mail, you can request account activation from the administrators of this site.', + login_noact_msg_admins_just_asked: 'A request has just been sent to the administrators of this site. They will be able to activate your account or send you another activation e-mail if needed.', + login_noact_msg_admins_asked: 'There is an active request in the administrators\' control panel for your account to be activated.', + login_noact_btn_request_activation: 'Request account activation', + login_noact_btn_log_out: 'Log out', + + login_ajax_fetching_key: 'Fetching an encryption key...', + login_ajax_generating_key: 'Performing Diffie-Hellman key generation...', + login_ajax_prompt_title: 'Please enter your username and password to continue.', + login_ajax_prompt_title_elev: 'You are requesting a sensitive operation.', + login_ajax_prompt_body_elev: 'Please re-enter your login details to verify your identity.', + login_ajax_link_fullform: 'Trouble logging in? Try the full login form.', + login_ajax_link_fullform_dh: 'Don\'t stop this process even if your browser asks you to. If this takes more than 10 seconds, you might want to try the full login form.', + login_ajax_link_forgotpass: 'Did you forget your password?', + login_ajax_loggingin: 'Logging in...', + login_ajax_msg_used_temp_pass: 'You have logged in using a temporary password. Before you can log in, you must finish resetting your password. Do you want to reset your real password now?', + login_ajax_check_dh: 'Enable strong encryption during logon? Learn more', + + err_key_not_found: 'Enano couldn\'t look up the encryption key used to encrypt your password. This most often happens if a cache rotation occurred during your login attempt, or if you refreshed the login page.', + err_key_not_found_cleared: 'It seems that the list of encryption keys used for login information has reached its maximum length, thus preventing new keys from being inserted. The list has been automatically cleared. Please try logging in again; if you are still unable to log in, please contact the site administration.', + err_key_wrong_length: 'The encryption key was the wrong length.', + err_too_big_for_britches: 'You are trying to authenticate at a level that your user account does not permit.', + err_invalid_credentials: 'You have entered an invalid username or password. Please enter your login details again.', + err_invalid_credentials_lockout: ' You have used up %fails% out of %config.lockout_threshold% login attempts. After you have used up all %config.lockout_threshold% login attempts, you will be locked out from logging in for %config.lockout_duration% minutes.', + err_invalid_credentials_lockout_captcha: ' You have used up %fails% out of %config.lockout_threshold% login attempts. After you have used up all %config.lockout_threshold% login attempts, you will have to enter a visual confirmation code while logging in, effective for %config.lockout_duration% minutes.', + err_backend_fail: 'You entered the right credentials and everything was validated, but for some reason Enano couldn\'t register your session. This is an internal problem with the site and you are encouraged to contact site administration.', + err_locked_out: 'You have used up all %config.lockout_threshold% allowed login attempts. Please wait %time_rem% minute%plural% before attempting to log in again%captcha_blurb%.', + err_locked_out_captcha_blurb: ', or enter the visual confirmation code shown above in the appropriate box', + + logout_success_title: 'Logged out', + logout_success_body: 'You have been successfully logged out, and all cookies have been cleared. You will now be transferred to the main page.', + logout_confirm_title: 'Are you sure you want to log out?', + logout_confirm_body: 'If you log out, you will no longer be able to access your user preferences, your private messages, or certain areas of this site until you log in again.', + logout_confirm_title_elev: 'Are you sure you want to de-authenticate?', + logout_confirm_body_elev: 'If you de-authenticate, you will no longer be able to use the administration panel until you re-authenticate again. You may do so at any time using the Administration button on the sidebar.', + logout_err_title: 'An error occurred during the logout process.', + // Unused at this point + logout_err_not_loggedin: 'You don\'t seem to be logged in.', + + // User levels + level_short_guest: 'Guest', + level_short_member: 'Member', + level_short_chpref: 'Sensitive preferences changeable', + level_short_mod: 'Moderator', + level_short_admin: 'Administrative', + level_long_guest: 'Low - guest privileges', + level_long_member: 'Standard - normal member level', + level_long_chpref: 'Medium - user can change his/her own e-mail address and password', + level_long_mod: 'High - moderator privileges', + level_long_admin: 'Highest - administrative privileges', + + ban_msg_title: 'Ban notice', + ban_msg_body: 'You have been banned from this website. Please contact the site administrator for more information.', + ban_lbl_reason: 'Reason:', + + keepalive_info_title: 'About the keep-alive feature', + keepalive_info_body: 'Keep-alive is a new Enano feature that keeps your administrative session from timing out while you are using the administration panel. This feature can be useful if you are editing a large page or doing something in the administration interface that will take longer than 15 minutes.

For security reasons, Enano mandates that high-privilege logins last only 15 minutes, with the time being reset each time a page is loaded (or, more specifically, each time the session API is started). The consequence of this is that if you are performing an action in the administration panel that takes more than 15 minutes, your session may be terminated. The keep-alive feature attempts to relieve this by sending a "ping" to the server every 10 minutes.

Please note that keep-alive state is determined by a cookie. Thus, if you log out and then back in as a different administrator, keep-alive will use the same setting that was used when you were logged in as the first administrative user. In the same way, if you log into the administration panel under your account from another computer, keep-alive will be set to "off".

For more information:
Overview of Enano\'s security model', + + type_guest: 'Guest', + type_member: 'Member', + type_mod: 'Moderator', + type_admin: 'Administrator', + + msg_elev_timed_out: 'Your administrative session has timed out. Log in again', + + reg_err_captcha: 'The confirmation code you entered was incorrect.', + reg_err_disabled_title: 'Registration disabled', + reg_err_disabled_body: 'The administrator has disabled the registration of new accounts on this site.', + reg_err_disabled_body_adminblurb: 'Oops...it seems that you are the administrator...hehe...you can also force account registration to work.', + reg_err_username_invalid: 'Your username must be at least two characters in length and may not contain any of the following characters: < > _ & ? \' " % / \\.', + // Not exactly an error + reg_err_password_good: 'The password you entered is valid.', + reg_err_alert_password_tooshort: 'Your password must be 6 characters or greater in length.', + reg_err_alert_password_nomatch: 'The passwords you entered do not match.', + reg_err_missing_key: 'Couldn\'t look up public encryption key', + reg_err_accept_tou: 'Please read and accept the Terms of Use before creating your account.', + reg_err_username_banned_chars: 'The username you chose contains invalid characters.', + reg_err_dupe_username: 'The username you selected is already in use by another user.', + reg_err_dupe_username_email: 'The username and e-mail address you selected are already in use by another user.', + reg_err_dupe_username_email_realname: 'The username, e-mail address, and real name you selected are already in use by another user.', + reg_err_dupe_email: 'The e-mail address you selected is already in use by another user.', + reg_err_dupe_email_realname: 'The e-mail address and real name you selected are already in use by another user.', + reg_err_dupe_realname: 'The real name you selected is already in use by another user.', + reg_err_password_too_weak: 'The password you entered did not meet the complexity requirements for this site. Please choose a stronger password.', + reg_err_actmail_failed: 'The activation e-mail could not be sent due to an internal error. This could possibly be due to an incorrect SMTP configuration. A request has been sent to the administrator to activate your account for you.', + + reg_msg_greatercontrol: 'A user account enables you to have greater control over your browsing experience.', + reg_msg_table_title: 'Create a user account', + reg_msg_table_subtitle: 'Please tell us a little bit about yourself.', + reg_msg_username_checking: 'Checking availability...', + reg_msg_username_available: 'This username is available.', + reg_msg_username_unavailable: 'This username is already taken.', + reg_msg_password_length: 'Your password must be at least six characters in length.', + reg_msg_password_score: 'It needs to score at least %config.pw_strength_minimum% for your registration to be accepted.', + reg_msg_password_needmatch: 'The passwords you entered do not match.', + reg_msg_email_activuser: 'An e-mail with an account activation key will be sent to this address, so please ensure that it is correct.', + reg_msg_realname_optional: 'Giving your real name is totally optional. If you choose to provide your real name, it will be used to provide attribution for any edits or contributions you may make to this site.', + reg_msg_captcha_pleaseenter: 'Please enter the code shown in the image to the right into the text box. The code is case-insensitive and the numeral zero is never used. This process helps to ensure that this registration is not being performed by an automated bot. If the image to the right is illegible, you can generate a new image.', + reg_msg_captcha_blind: 'If you are visually impaired or otherwise cannot read the text shown to the right, please contact the site management and they will create an account for you.', + reg_msg_please_read_tou:'Please read and agree to the following terms before registering. By continuing to create an account you agree to be legally bound by the terms below.', + reg_msg_success_title: 'Registration successful', + reg_msg_success_body: 'Thank you for registering, your user account has been created.', + reg_msg_success_activ_none: 'You may now log in with the username and password that you created.', + reg_msg_success_activ_user: 'Because this site requires account activation, you have been sent an e-mail with further instructions. Please follow the instructions in that e-mail to continue your registration.', + reg_msg_success_activ_admin: 'Because this site requires administrative account activation, you cannot use your account at the moment. A notice has been sent to the site administration team that will alert them that your account has been created.', + reg_msg_success_activ_coppa: 'However, in compliance with the Childrens\' Online Privacy Protection Act, you must have your parent or legal guardian activate your account. Please ask them to check their e-mail for further information.', + + reg_lbl_field_username: 'Preferred username:', + reg_lbl_field_password: 'Password:', + reg_lbl_field_password_confirm: 'Enter your password again to confirm.', + reg_lbl_field_email: 'E-mail address:', + reg_lbl_field_email_coppa: 'Your parent or guardian\'s e-mail address:', + reg_lbl_field_realname: 'Real name:', + reg_lbl_field_captcha: 'Visual confirmation', + reg_lbl_field_captcha_code: 'Code:', + reg_lbl_field_tou: 'I agree to abide by the terms and conditions stated above', + + reg_btn_create_account: 'Create my account', + + reg_coppa_title: 'Before you can register, please tell us your age.', + reg_coppa_link_atleast13: 'I was born on or before %yo13_date% and am at least 13 years of age', + reg_coppa_link_not13: 'I was born after %yo13_date% and am less than 13 years of age', + + reg_activation_email_subject: '%config.site_name% website account activation', + reg_activation_email: 'Dear %username%, +Thank you for registering on %config.site_name%. Your account creation is almost complete. To complete the registration process, please click the following link or paste it into your web browser: + + %activation_link% + +Sincerely yours, +%admin_user% and the %config.site_name% administration team', + + reg_activation_email_coppa: 'Dear parent or legal guardian, +A child under the username %username% recently registered on our website. The child provided your e-mail address as the one of his or her authorized parent or legal guardian, and to comply with the United States Childrens\' Online Privacy Protection act, we ask that all parents of children ages 13 or under please mail us a written form authorizing their child\'s use of our website. + +If you wish for your child to be allowed access to our website, please print and fill out the form below, and mail it to this address: + +%config.coppa_address% + +If you do NOT wish for your child to be allowed access to our site, you do not need to do anything - your child will not be able to access our site as a registered user unless you authorize their account activation. + +Authorization form: +-------------------------------- Cut here -------------------------------- + +I, _______________________________________, the legal parent or guardian of the child registered on the website "%config.site_name%" as %username%, hereby give my authorization for the child\'s e-mail address, instant messaging information, location, and real name, to be collected and stored in a database owned and maintained by %config.site_name% at the child\'s option, and for the administrators of this website to use this information according to the privacy policy displayed on their website <%site_link%>. + +Child\'s name: _____________________________________ + +Child\'s e-mail address: _____________________________________ +(optional - if you don\'t provide this, we\'ll just send site-related e-mails to your e-mail address) + +Signature of parent or guardian: + +____________________________________________________ + +Date (YYYY-MM-DD): ______ / _____ / _____ + +-------------------------------- Cut here -------------------------------- + +Sincerely yours, +%admin_user% and the %config.site_name% administration team', + + autofill_heading_suggestions: 'Username suggestions', + autofill_msg_no_suggestions: 'No suggestions', + }, + usercp: { + // Meta + sec_profile: 'Profile/membership', + sec_pm: 'Private messages', + + sec_profile_emailpassword: 'Edit e-mail address and password', + sec_profile_signature: 'Edit signature', + sec_profile_publicinfo: 'Edit public profile', + sec_profile_usergroups: 'Group memberships', + sec_profile_avatar: 'Avatar settings', + + sec_pm_inbox: 'Inbox', + sec_pm_outbox: 'Outbox', + sec_pm_sent: 'Sent items', + sec_pm_drafts: 'Drafts', + sec_pm_archive: 'Archive', + + btn_memberlist: 'list of registered members', + + // CP home + intro_heading_main: '%username%, welcome to your control panel', + intro_para1: 'Here you can make changes to your profile, view statistics on yourself on this site, and set your preferences.', + intro_para2: 'Your user page (comments) is your free writing space. You can use it to tell the other members of this site a little bit about yourself. If you haven\'t already made a user page, why not make one now?', + intro_para3: 'Use the menu at the top to navigate around. If you have any questions, you may contact the %admin_contact_link%.', + intro_para3_admin_link: 'administrator', + + // E-mail / password change form + emailpassword_title: 'Change E-mail Address or Password', + emailpassword_err_email_no_match: 'The e-mail addresses you entered did not match.', + emailpassword_err_list: 'The following errors were encountered while saving your e-mail address:', + emailpassword_err_title: 'Error updating e-mail address', + emailpassword_err_demo: 'You can\'t change your password in demo mode.', + emailpassword_err_password_too_short: 'The new password must be 6 characters or greater in length.', + emailpassword_err_password_too_weak: 'Your password did not meet the complexity score requirement for this site. Your password scored %score%, while a score of at least %config.pw_strength_minimum% is needed.', + emailpassword_msg_profile_success: 'Profile changed', + emailpassword_msg_pass_success: 'Password changed', + emailpassword_msg_need_activ_user: 'Your password and e-mail address have been changed. Since e-mail activation is required on this site, you will need to re-activate your account to continue. An e-mail has been sent to the new e-mail address with an activation link. You must click that link in order to log in again.', + emailpassword_msg_need_activ_admin: 'Your password and e-mail address have been changed. Since administrative activation is requires on this site, a request has been sent to the administrators to activate your account for you. You will not be able to use your account until it is activated by an administrator.', + emailpassword_msg_password_changed: 'Your password has been changed, and you will now be redirected back to the user control panel.', + emailpassword_err_password_no_match: 'The passwords you entered do not match.', + emailpassword_grp_chpasswd: 'Change password', + emailpassword_field_newpass: 'Type a new password:', + emailpassword_field_newpass_confirm: 'Type the password again to confirm:', + emailpassword_msg_password_min_score: 'Your password needs to score at least %config.pw_strength_minimum% in order to be accepted.', + // The following is NOT an in-joke. ;-) + emailpassword_grp_chemail: 'Change e-mail address', + emailpassword_field_newemail: 'New e-mail address:', + emailpassword_field_newemail_confirm: 'Confirm e-mail address:', + + // Signature editor + signature_title: 'Editing signature', + signature_msg_saved: 'Your signature has been saved.', + signature_btn_save: 'Save signature', + + // Additional profile info + publicinfo_title: 'Editing public profile', + publicinfo_msg_save_success: 'Your profile has been updated.', + publicinfo_heading_main: 'Your public profile', + publicinfo_note_optional: 'Please note that all of the information you enter here will be publicly viewable. All of the fields on this page are optional and may be left blank if you so desire.', + publicinfo_field_realname: 'Real name:', + publicinfo_field_language: 'Preferred language:', + publicinfo_field_language_hint: 'Select the language special pages and page controls should appear in.', + publicinfo_field_changetheme_title: 'Change theme:', + publicinfo_field_changetheme_hint: 'If you don\'t like the look of the site, need a visual break, or are just curious, we might have some different themes for you to try out!', + publicinfo_field_changetheme: 'Change my theme...', + publicinfo_field_timezone: 'Time zone:', + publicinfo_field_timezone_hint: 'Select the time zone you live in and when Daylight Savings Time occurs, if at all.', + publicinfo_th_im: 'Instant messenger contact information', + publicinfo_field_aim: 'AIM handle:', + publicinfo_field_wlm: 'WLM handle:
If you don\'t specify the domain (@whatever.com), "@hotmail.com" will be assumed.', + publicinfo_field_yim: 'Yahoo! IM handle:', + publicinfo_field_xmpp: 'Jabber™/XMPP handle:', + publicinfo_th_contact: 'Extra contact information', + publicinfo_field_homepage: 'Your homepage:
Please remember the http:// prefix.', + publicinfo_field_location: 'Your location:', + publicinfo_field_job: 'Your job:', + publicinfo_field_hobbies: 'Your hobbies:', + publicinfo_field_email_public: 'E-mail address is public', + publicinfo_field_email_public_hint: 'If this is checked, your e-mail address will be displayed on your user page. To protect your address from spambots, your e-mail address will be encrypted.', + publicinfo_btn_save: 'Save profile', + + // Avatar management + avatar_err_disabled_title: 'Avatar support is disabled.', + avatar_err_disabled_body: 'The administrator has not enabled avatar support for this site.', + avatar_table_title: 'Avatar settings', + avatar_label_current: 'Current avatar:', + avatar_image_alt: '%username%\'s avatar', + avatar_image_none: 'You don\'t have an avatar currently.', + avatar_lbl_change: 'Change your avatar:', + avatar_lbl_keep: 'Keep my current avatar', + avatar_lbl_remove: 'Delete my avatar', + avatar_lbl_set_http: 'Upload a new avatar from the Web', + avatar_lbl_set_file: 'Upload a new avatar from my computer', + avatar_lbl_url: 'URL to image:', + avatar_lbl_url_desc: 'This must start with the http:// prefix and must be a valid URL. The image will be copied from the existing URL to this server - dynamic avatars are not supported.', + avatar_lbl_file: 'Upload file:', + avatar_lbl_file_desc: 'Your browser needs to support file uploads for this option to work.', + avatar_limits: 'The image cannot be more than %config.avatar_max_size% bytes in size. The maximum dimensions are %config.avatar_max_width% × %config.avatar_max_height% pixels. Allowed formats are PNG, GIF, and JPEG.', + avatar_delete_success: 'Your avatar has been deleted.', + avatar_bad_write: 'Either the remote server had trouble finding the image, or your image exceeded the allowed file size.', + avatar_bad_filetype: 'The file you selected is invalid. You must choose a file in PNG, JPEG, or GIF format.', + avatar_disallowed_animation: 'You have chosen an animated image, which is not allowed. Please choose a non-animated image.', + avatar_corrupt_image: 'The image you selected is corrupt. Please choose another image.', + avatar_too_large: 'The image you uploaded exceeds the maximum dimensions (%config.avatar_max_width% × %config.avatar_max_height%px) allowed on this site. Please choose another image.', + avatar_move_failed: 'Your image was accepted, but there was a problem moving the image file to the correct location.', + avatar_upload_success: 'Your avatar has been updated.', + avatar_file_too_large: 'The image you uploaded exceeds the maximum file size allowed for avatars on this site.', + + // Password strength widget + pwstrength_score_verystrong: 'Very strong (score: %score%)', + pwstrength_score_strong: 'Strong (score: %score%)', + pwstrength_score_good: 'Good (score: %score%)', + pwstrength_score_fair: 'Fair (score: %score%)', + pwstrength_score_weak: 'Weak (score: %score%)', + }, + groupcp: { + status_mod: 'You are a moderator of this group.', + status_member: 'You are a member of this group.', + status_not_member: 'You are not a member of this group.', + + err_state_system_group: 'Because this is a system group, you can\'t make it open or allow membership requests.', + err_user_not_found: 'The username you entered could not be found.', + + type_hidden: 'Hidden group', + type_closed: 'Closed group', + type_request: 'Members can request to join', + type_open: 'Anyone can join', + + lbl_current_memberships: 'Current group memberships:', + lbl_non_memberships: 'Groups you are outside of:', + lbl_group_name: 'Group name:', + lbl_status: 'Membership status:', + lbl_state: 'Group state:', + lbl_make_mod: 'User is a group moderator', + lbl_username: 'Username:', + lbl_moderator: 'Group moderator:', + + msg_membership_requested: 'A request has been sent to the moderator(s) of this group to add you.', + msg_status_pending: '(Your request to join is awaiting approval)', + msg_no_mods: 'This group has no moderators.', + msg_no_members: 'This group has no members.', + msg_system_group: '(system group)', + msg_pending_updated: 'Pending members status updated successfully.', + msg_state_updated: 'The group state was updated.', + msg_user_already_in_mod_updated: 'The user "%username%" is already in this group, so their moderator status was updated.', + msg_user_already_in: 'The user "%username%" is already in this group.', + msg_user_added: 'The user "%username%" has been added to this usergroup.', + msg_self_added: 'You have been added to this group.', + + btn_view: 'View information', + btn_request_join: 'Request membership', + btn_join: 'Join this group', + btn_approve_pending: 'Approve membership', + btn_reject_pending: 'Reject membership', + btn_remove_selected: 'Remove selected users', + btn_add_member: 'Add member', + + grp_administrators: 'Administrators', + grp_moderators: 'Moderators', + + th_select_group: 'Group membership details', + th_group_info: 'Group information', + th_pending_memberships: 'Pending memberships', + th_group_members: 'Group members', + th_group_mods: 'Group moderators', + th_add_member: 'Add a new member to this group', + th_username: 'Username', + th_email: 'E-mail', + th_reg_time: 'Registered', + th_comments: 'Total comments', + th_select: 'Select', + th_remove: 'Remove?', + }, + privmsgs: { + err_need_login: 'You need to be logged in to view private messages.', + err_not_authorized_read: 'You are not authorized to view this message.', + err_not_authorized_edit: 'You are not authorized to alter this message.', + err_send_submit: 'Your message could not be sent because the following problems were encountered:', + err_need_username: 'Please enter the username to which you want to send your message.', + err_need_subject: 'Please enter a subject for your message.', + err_need_message: 'Please enter a message to send.', + err_limit_exceeded_title: 'Recipient limit exceeded', + err_limit_exceeded_body: 'You can only send this message to a maximum of %limit% users.', + err_folder_not_exist: 'The folder "%folder_name%" does not exist. Return to your inbox.', + + msg_message_status: 'Message status', + msg_message_moved: 'Your message has been moved to the folder "%folder%".', + msg_message_deleted: 'The message has been deleted.', + msg_message_sent: 'Your message has been sent. You may edit the message if you wish; one copy for each recipient will be in your outbox until each recipient has read it. Return to your inbox.', + msg_draft_saved: 'Your message has been saved to your Drafts folder.', + msg_no_messages: 'No messages in this folder.', + + lbl_message_from: 'Private message from %sender%', + lbl_subject: 'Subject:', + lbl_date: 'Date:', + lbl_message: 'Message:', + lbl_compose_th: 'Compose new private message', + lbl_compose_to: 'To:', + lbl_compose_to_max: 'Separate multiple names with a single comma; you may send this message to up to %limit% users.', + lbl_edit_th: 'Edit draft', + + btn_send_reply: 'Send reply', + btn_archive: 'Archive message', + btn_return_to_inbox: 'Return to inbox', + btn_send: 'Send message', + btn_savedraft: 'Save as draft', + btn_archive_selected: 'Archive selected', + btn_delete_selected: 'Delete selected', + btn_delete_all: 'Delete all', + btn_compose: 'New message', + + sidebar_th_privmsgs: 'Private messages', + folder_inbox: 'Inbox', + folder_outbox: 'Outbox', + folder_sent: 'Sent items', + folder_drafts: 'Drafts', + folder_archive: 'Archive', + sidebar_th_buddies: 'Buddies', + sidebar_friend_list: 'Friend list', + sidebar_foe_list: 'Foe list', + + folder_th_foldername: 'Folder:', + folder_th_to: 'To', + folder_th_from: 'From', + folder_th_subject: 'Subject', + folder_th_date: 'Date', + folder_th_mark: 'Mark', + + // Buddy / foe lists + th_buddy_list: 'Buddy list for %username%', + msg_no_buddies: 'No buddies in your list.', + btn_pm_all_buddies: 'Send a PM to all buddies', + heading_add_buddy: 'Add a new friend', + btn_add: 'Add', + lbl_username: 'Username:', + btn_buddy_remove: 'Remove', + btn_buddy_send_pm: 'Send private message', + + th_foe_list: 'Foe list for %username%', + msg_no_foes: 'No foes in your list.', + heading_add_foe: 'Add a new foe', + + // AJAX interface (up and coming) + ajax_err_need_js: 'It looks like your browser doesn\'t have support for Javascript. You\'ll need to have Javascript support in order to use the new Private Message interface. You can also switch to the old interface, which doesn\'t require Javascript support.', + ajax_err_json: 'The server had a problem processing your request.', + + ajax_btn_compose: 'Compose message', + ajax_btn_archive: 'Archive', + ajax_btn_unarchive: 'Restore to inbox', + ajax_btn_mark_read: 'Mark as read', + ajax_btn_mark_unread: 'Mark as unread', + ajax_btn_delete: 'Move to trash', + ajax_btn_delete_forever: 'Delete forever', + ajax_btn_refresh: 'Refresh', + ajax_btn_reply: 'Reply', + + ajax_folder_inbox: 'Inbox', + ajax_folder_starred: 'Starred', + ajax_folder_sent: 'Sent messages', + ajax_folder_drafts: 'Drafts', + ajax_folder_archive: 'Archive', + ajax_folder_trash: 'Trash', + + ajax_msg_loading: 'Loading...', + + ajax_lbl_sender: '%sender% to %recipient%', + ajax_me: 'me', + + ajax_teaser_inbox: 'No new mail.', + ajax_teaser_starred: 'You haven\'t starred any messages yet. Starring a message lets you give it a special status that separates it from the rest of your mail so it\'s easier to find. You can star a message by clicking the small gray star next to a message in your inbox or archive.', + ajax_teaser_sent: 'You haven\'t sent any messages yet. When you send a message, a copy of it will appear here.', + + ajax_no_subject: '[No subject]', + }, + userfuncs: { + + // Special:Contributions + contribs_err_no_user: 'You need to select a user to view contributions for.', + contribs_heading_edits: 'Page edits', + contribs_msg_no_edits: 'This user has not made any edits.', + contribs_heading_other: 'Other changes made by this user', + contribs_msg_no_other: 'This user has not made any non-editing changes.', + + // Special:ChangeStyle + changetheme_heading_theme: 'Please select a new theme:', + changetheme_heading_style: 'Please select a stylesheet:', + changetheme_btn_continue: 'Continue', + changetheme_btn_allclear: 'Change style', + changetheme_success_title: 'Theme changed', + changetheme_success_body: 'Your theme preferences have been updated. Redirecting you to the last viewed page...', + + // Special:ActivateAccount + activate_err_badlink_title: 'Account activation error', + activate_err_badlink_body: 'This page can only be accessed using links sent to users via e-mail.', + activate_err_bad_key: 'The activation key was probably incorrect, or the account is already active.', + activate_success_title: 'Activation successful', + activate_success_body: 'Your account is now active. Thank you for registering.', + + // Special:PasswordReset + passreset_blurb_line1: 'Don\'t worry, it happens to the best of us.', + passreset_blurb_line2: 'To reset your password, just enter your username below, and a new password will be e-mailed to you.', + passreset_lbl_username: 'Username:', + passreset_btn_mailpasswd: 'Mail new password', + passreset_email: "Dear %username%, + +Someone (hopefully you) on the %site_name% website requested that a new password be created. + +The request was sent from the IP address %remote_addr%. + +If you did not request the new password, then you do not need to do anything; the password will be invalidated after 24 hours. + +If you did request this password, then please log in using the password shown below: + + Password: %temp_pass% + +After you log in using this password, you will be able to reset your real password. You can only log in using this temporary password once. + +Sincerely yours, +The %site_name% administration team +", + passreset_stage1_success: 'An e-mail has been sent to the e-mail address on file for your username with a new password in it. Please check your e-mail for further instructions.', + passreset_stage1_error: 'Error occured, your new password was not sent.', + passreset_stage2_th: 'Reset password', + passreset_stage2_lbl_password: 'Password:', + passreset_stage2_lbl_confirm: 'Confirm:', + passreset_stage2_lbl_strength: 'Password strength rating:', + passreset_stage2_blurb_strength: 'Your password needs to have a score of at least %config.pw_strength_minimum%.', + passreset_stage2_btn_submit: 'Reset password', + passreset_stage2_success: 'Your password has been reset. Return to the main page.', + + passreset_err_no_match: 'The passwords you entered do not match.', + passreset_err_too_short: 'The new password must be 6 characters or greater in length.', + passreset_err_failed_score: 'ERROR: Your password did not pass the complexity score requirement. You need %config.pw_strength_minimum% points to pass; your password received a score of %inp_score%. Go back', + passreset_err_pass_expired: 'Your temporary password has expired. Please request another one.', + + // Special:Memberlist + ml_column_username: 'Username', + ml_column_userlevel: 'Title', + ml_column_email: 'E-mail', + ml_column_regtime: 'Registered', + ml_level_guest: 'Guest', + ml_level_member: 'Member', + ml_level_mod: 'Moderator', + ml_level_admin: 'Site administrator', + ml_level_unknown: 'Unknown (level %level%)', + ml_email_nonpublic: 'Non-public', + ml_date_daysago: '%days_ago% days ago', + ml_date_today: 'Today', + ml_date_yesterday: 'Yesterday', + ml_btn_adminuser: 'Administer user', + ml_tip_userpage: 'Click to view this user\'s userpage', + ml_tip_nouserpage: 'This user hasn\'t created a userpage yet, but you can still view profile details by clicking this link.', + ml_lbl_finduser: 'Find a member:', + ml_btn_go: 'Go', + ml_tip_wildcard: 'You may use the following wildcards: * to match multiple characters, ? to match a single character.', + ml_err_nousers_find: 'Sorry - no users that matched your query could be found. Please try some different search terms.', + ml_err_nousers: 'Sorry - no users with usernames that start with that letter could be found.', + ml_msg_matches_zero: 'Search returned no matches', + ml_msg_matches_one: 'Search returned 1 match', + ml_msg_matches: 'Search returned %matches% matches', + }, + userpage: { + page_title: '%username%\'s user page', + heading_basics: 'All about %username%', + lbl_joined: 'Joined:', + lbl_num_comments: 'Total comments:', + lbl_real_name: 'Real name:', + btn_administer_user: 'Administer user', + heading_comments: '%username%\'s latest comments', + comments_lbl_posted: 'Posted', + msg_no_comments: 'This user has not posted any comments.', + heading_contact: 'Get in touch', + lbl_email: 'E-mail address:', + btn_send_pm: 'Send %username% a Private Message!', + btn_send_pm_guest: 'You could send %username% a Private Message if you were logged in.', + lbl_aim: 'AIM:', + lbl_yim: 'Yahoo! IM:', + lbl_wlm: 'WLM:', + lbl_xmpp: 'XMPP/Jabber™:', + heading_real_life: '%username% in real life', + lbl_location: 'Location:', + lbl_job: 'Job/occupation:', + lbl_hobbies: 'Enjoys:', + msg_no_contact_info: '%username% hasn\'t posted any real-life contact information.', + msg_user_not_exist: 'Additional information: user "%username%" does not exist.', + } + } +}; + +// All done! :-) + diff -r d823e49e2e4e -r c433348f3628 licenses/index.html --- a/licenses/index.html Fri Feb 22 12:46:51 2008 -0500 +++ b/licenses/index.html Fri Feb 22 12:51:53 2008 -0500 @@ -106,12 +106,13 @@

The MIT/X License

View the text of this license

    -
  • FastJSON - a JSON encoder/decoder. Copyright © 2006 - 2007 Andrea Giammarchi.
  • +
  • FastJSON - a JSON encoder/decoder. Only used when PHP4 compatibility is a must (early in the installer). Copyright © 2006 - 2007 Andrea Giammarchi.

Unknown license

diff -r d823e49e2e4e -r c433348f3628 plugins/PrivateMessages.php --- a/plugins/PrivateMessages.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/PrivateMessages.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ attachHook('base_classes_initted', ' +$plugins->attachHook('session_started', ' global $paths; $paths->add_page(Array( - \'name\'=>\'Private Messages\', + \'name\'=>\'specialpage_private_messages\', \'urlname\'=>\'PrivateMessages\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', @@ -35,12 +35,19 @@ function page_Special_PrivateMessages() { global $db, $session, $paths, $template, $plugins; // Common objects - if(!$session->user_logged_in) die_friendly('Access denied', '

You need to log in to view your private messages.

'); + global $lang; + if ( !$session->user_logged_in ) + { + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('privmsgs_err_need_login', array('login_link' => makeUrlNS('Special', 'Login/' . $paths->page))) . '

'); + } $argv = Array(); $argv[] = $paths->getParam(0); $argv[] = $paths->getParam(1); $argv[] = $paths->getParam(2); - if(!$argv[0]) $argv[0] = 'InVaLiD'; + if ( !$argv[0] ) + { + $argv[0] = 'InVaLiD'; + } switch($argv[0]) { default: @@ -48,112 +55,195 @@ break; case 'View': $id = $argv[1]; - if(!preg_match('#^([0-9]+)$#', $id)) die_friendly('Message error', '

Invalid message ID

'); + if ( !preg_match('#^([0-9]+)$#', $id) ) + { + die_friendly('Message error', '

Invalid message ID

'); + } $q = $db->sql_query('SELECT p.message_from, p.message_to, p.subject, p.message_text, p.date, p.folder_name, u.signature FROM '.table_prefix.'privmsgs AS p LEFT JOIN '.table_prefix.'users AS u ON (p.message_from=u.username) WHERE message_id='.$id.''); - if(!$q) $db->_die('The message data could not be selected.'); + if ( !$q ) + { + $db->_die('The message data could not be selected.'); + } $r = $db->fetchrow(); $db->free_result(); - if( ($r['message_to'] != $session->username && $r['message_from'] != $session->username ) || $r['folder_name']=='drafts' ) die_friendly('Access denied', '

You are not authorized to view this message.

'); - if($r['message_to'] == $session->username) + if ( ($r['message_to'] != $session->username && $r['message_from'] != $session->username ) || $r['folder_name']=='drafts' ) + { + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('privmsgs_err_not_authorized_read') . '

'); + } + if ( $r['message_to'] == $session->username ) { $q = $db->sql_query('UPDATE '.table_prefix.'privmsgs SET message_read=1 WHERE message_id='.$id.''); $db->free_result(); - if(!$q) $db->_die('Could not mark message as read'); + if ( !$q ) + { + $db->_die('Could not mark message as read'); + } } $template->header(); userprefs_show_menu(); ?>
- - - - + + + - +
Private message from
Subject:
Date:
Message:get('privmsgs_lbl_message_from', array('sender' => htmlspecialchars($r['message_from']))); ?>
get('privmsgs_lbl_subject') ?>
get('privmsgs_lbl_date') ?>
get('privmsgs_lbl_message') ?>'; echo RenderMan::render($r['signature']); } ?>
Send reply | Delete message | Archive message | Return to inbox
get('privmsgs_btn_send_reply'); ?> | Delete message | get('privmsgs_btn_archive'); ?> | get('privmsgs_btn_return_to_inbox'); ?>
footer(); break; case 'Move': $id = $argv[1]; - if(!preg_match('#^([0-9]+)$#', $id)) die_friendly('Message error', '

Invalid message ID

'); + if ( !preg_match('#^([0-9]+)$#', $id) ) + { + die_friendly('Message error', '

Invalid message ID

'); + } $q = $db->sql_query('SELECT message_to FROM '.table_prefix.'privmsgs WHERE message_id='.$id.''); - if(!$q) $db->_die('The message data could not be selected.'); + if ( !$q ) + { + $db->_die('The message data could not be selected.'); + } $r = $db->fetchrow(); $db->free_result(); - if($r['message_to'] != $session->username) die_friendly('Access denied', '

You are not authorized to alter this message.

'); + if ( $r['message_to'] != $session->username ) + { + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('privmsgs_err_not_authorized_edit') . '

'); + } $fname = $argv[2]; - if(!$fname || ( $fname != 'Inbox' && $fname != 'Outbox' && $fname != 'Sent' && $fname != 'Drafts' && $fname != 'Archive' ) ) die_friendly('Invalid request', '

The folder name "'.$fname.'" is invalid.

'); + if ( !$fname || ( $fname != 'Inbox' && $fname != 'Outbox' && $fname != 'Sent' && $fname != 'Drafts' && $fname != 'Archive' ) ) + { + die_friendly('Invalid request', '

The folder name "'.$fname.'" is invalid.

'); + } $q = $db->sql_query('UPDATE '.table_prefix.'privmsgs SET folder_name=\''.strtolower($fname).'\' WHERE message_id='.$id.';'); $db->free_result(); - if(!$q) $db->_die('The message was not successfully moved.'); - die_friendly('Message status', '

Your message has been moved to the folder "'.$fname.'".

Return to inbox

'); + if ( !$q ) + { + $db->_die('The message was not successfully moved.'); + } + die_friendly($lang->get('privmsgs_msg_message_status'), '

' . $lang->get('privmsgs_msg_message_moved', array('folder' => $fname)) . '

' . $lang->get('privmsgs_btn_return_to_inbox') . '

'); break; case 'Delete': $id = $argv[1]; - if(!preg_match('#^([0-9]+)$#', $id)) die_friendly('Message error', '

Invalid message ID

'); + if ( !preg_match('#^([0-9]+)$#', $id) ) + { + die_friendly('Message error', '

Invalid message ID

'); + } $q = $db->sql_query('SELECT message_to FROM '.table_prefix.'privmsgs WHERE message_id='.$id.''); - if(!$q) $db->_die('The message data could not be selected.'); + if ( !$q ) + { + $db->_die('The message data could not be selected.'); + } $r = $db->fetchrow(); - if($r['message_to'] != $session->username) die_friendly('Access denied', '

You are not authorized to delete this message.

'); + if ( $r['message_to'] != $session->username ) + { + die_friendly($lang->get('etc_access_denied_short'), '

You are not authorized to delete this message.

'); + } $q = $db->sql_query('DELETE FROM '.table_prefix.'privmsgs WHERE message_id='.$id.';'); - if(!$q) $db->_die('The message was not successfully deleted.'); + if ( !$q ) + { + $db->_die('The message was not successfully deleted.'); + } $db->free_result(); - die_friendly('Message status', '

The message has been deleted.

Return to inbox

'); + die_friendly($lang->get('privmsgs_msg_message_status'), '

' . $lang->get('privmsgs_msg_message_deleted') . '

' . $lang->get('privmsgs_btn_return_to_inbox') . '

'); break; case 'Compose': - if($argv[1]=='Send' && isset($_POST['_send'])) + if ( $argv[1]=='Send' && isset($_POST['_send']) ) { // Check each POST DATA parameter... - if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) die_friendly('Sending of message failed', '

Please enter the username to which you want to send your message.

'); - if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) die_friendly('Sending of message failed', '

Please enter a subject for your message.

'); - if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) die_friendly('Sending of message failed', '

Please enter a message to send.

'); - $namelist = $_POST['to']; - $namelist = str_replace(', ', ',', $namelist); - $namelist = explode(',', $namelist); - foreach($namelist as $n) { $n = $db->escape($n); } - $subject = RenderMan::preprocess_text($_POST['subject']); - $message = RenderMan::preprocess_text($_POST['message']); - $base_query = 'INSERT INTO '.table_prefix.'privmsgs(message_from,message_to,date,subject,message_text,folder_name,message_read) VALUES'; - foreach($namelist as $n) + $errors = array(); + if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_username'); + } + if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_subject'); + } + if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_message'); + } + if ( count($errors) < 1 ) { - $base_query .= '(\''.$session->username.'\', \''.$n.'\', '.time().', \''.$subject.'\', \''.$message.'\', \'inbox\', 0),'; + $namelist = $_POST['to']; + $namelist = str_replace(', ', ',', $namelist); + $namelist = explode(',', $namelist); + foreach($namelist as $n) { $n = $db->escape($n); } + $subject = RenderMan::preprocess_text($_POST['subject']); + $message = RenderMan::preprocess_text($_POST['message']); + $base_query = 'INSERT INTO '.table_prefix.'privmsgs(message_from,message_to,date,subject,message_text,folder_name,message_read) VALUES'; + foreach($namelist as $n) + { + $base_query .= '(\''.$session->username.'\', \''.$n.'\', '.time().', \''.$subject.'\', \''.$message.'\', \'inbox\', 0),'; + } + $base_query = substr($base_query, 0, strlen($base_query)-1) . ';'; + $result = $db->sql_query($base_query); + $db->free_result(); + if ( !$result ) + { + $db->_die('The message could not be sent.'); + } + else + { + die_friendly($lang->get('privmsgs_msg_message_status'), '

' . $lang->get('privmsgs_msg_message_sent', array('inbox_link' => makeUrlNS('Special', 'PrivateMessages/Folder/Inbox'))) . '

'); + } + return; } - $base_query = substr($base_query, 0, strlen($base_query)-1) . ';'; - $result = $db->sql_query($base_query); - $db->free_result(); - if(!$result) $db->_die('The message could not be sent.'); - else die_friendly('Message status', '

Your message has been sent. You may edit the message if you wish; one copy for each recipient will be in your outbox until each recipient has read it. Return to your inbox.

'); - return; - } elseif($argv[1]=='Send' && isset($_POST['_savedraft'])) { - // Check each POST DATA parameter... - if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) die_friendly('Sending of message failed', '

Please enter the username to which you want to send your message.

'); - if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) die_friendly('Sending of message failed', '

Please enter a subject for your message.

'); - if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) die_friendly('Sending of message failed', '

Please enter a message to send.

'); - $namelist = $_POST['to']; - $namelist = str_replace(', ', ',', $namelist); - $namelist = explode(',', $namelist); - foreach($namelist as $n) { $n = $db->escape($n); } - if(count($namelist) > MAX_PMS_PER_BATCH && $session->get_permssions('mod_misc')) die_friendly('Limit exceeded', '

You can only send this message to a maximum of '.MAX_PMS_PER_BATCH.' users.

'); - $subject = $db->escape($_POST['subject']); - $message = RenderMan::preprocess_text($_POST['message']); - $base_query = 'INSERT INTO '.table_prefix.'privmsgs(message_from,message_to,date,subject,message_text,folder_name,message_read) VALUES'; - foreach($namelist as $n) + } + else if ( $argv[1] == 'Send' && isset($_POST['_savedraft'] ) ) + { + $errors = array(); + if ( !isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '') ) + { + $errors[] = $lang->get('privmsgs_err_need_username'); + } + if ( !isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '') ) + { + $errors[] = $lang->get('privmsgs_err_need_subject'); + } + if ( !isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '') ) + { + $errors[] = $lang->get('privmsgs_err_need_message'); + } + if ( count($errors) < 1 ) { - $base_query .= '(\''.$session->username.'\', \''.$n.'\', '.time().', \''.$subject.'\', \''.$message.'\', \'drafts\', 0),'; + $namelist = $_POST['to']; + $namelist = str_replace(', ', ',', $namelist); + $namelist = explode(',', $namelist); + foreach($namelist as $n) + { + $n = $db->escape($n); + } + if ( count($namelist) > MAX_PMS_PER_BATCH && !$session->get_permssions('mod_misc') ) + { + die_friendly($lang->get('privmsgs_err_limit_exceeded_title'), '

' . $lang->get('privmsgs_err_limit_exceeded_body', array('limit' => MAX_PMS_PER_BATCH)) . '

'); + } + $subject = $db->escape($_POST['subject']); + $message = RenderMan::preprocess_text($_POST['message']); + $base_query = 'INSERT INTO '.table_prefix.'privmsgs(message_from,message_to,date,subject,message_text,folder_name,message_read) VALUES'; + foreach($namelist as $n) + { + $base_query .= '(\''.$session->username.'\', \''.$n.'\', '.time().', \''.$subject.'\', \''.$message.'\', \'drafts\', 0),'; + } + $base_query = substr($base_query, 0, strlen($base_query) - 1) . ';'; + $result = $db->sql_query($base_query); + $db->free_result(); + if ( !$result ) + { + $db->_die('The message could not be saved.'); + } } - $base_query = substr($base_query, 0, strlen($base_query)-1) . ';'; - $result = $db->sql_query($base_query); - $db->free_result(); - if(!$result) $db->_die('The message could not be saved.'); - } elseif(isset($_POST['_inbox'])) { - header('Location: '.makeUrlNS('Special', 'PrivateMessages/Folder/Inbox')); + } + else if(isset($_POST['_inbox'])) + { + redirect(makeUrlNS('Special', 'PrivateMessages/Folder/Inbox'), '', '', 0); } if($argv[1] == 'ReplyTo' && preg_match('#^([0-9]+)$#', $argv[2])) { @@ -162,12 +252,17 @@ $subj = ''; $id = $argv[2]; $q = $db->sql_query('SELECT p.message_from, p.message_to, p.subject, p.message_text, p.date, p.folder_name, u.signature FROM '.table_prefix.'privmsgs AS p LEFT JOIN '.table_prefix.'users AS u ON (p.message_from=u.username) WHERE message_id='.$id.';'); - if(!$q) $db->_die('The message data could not be selected.'); + if ( !$q ) + $db->_die('The message data could not be selected.'); + $r = $db->fetchrow(); $db->free_result(); - if( ($r['message_to'] != $session->username && $r['message_from'] != $session->username ) || $r['folder_name']=='drafts' ) die_friendly('Access denied', '

You are not authorized to view the contents of this message.

'); + if ( ($r['message_to'] != $session->username && $r['message_from'] != $session->username ) || $r['folder_name'] == 'drafts' ) + { + die_friendly($lang->get('etc_access_denied_short'), '

You are not authorized to view the contents of this message.

'); + } $subj = 'Re: ' . $r['subject']; - $text = "\n\n\nOn ".date('M j, Y G:i', $r['date']).", ".$r['message_from']." wrote:\n> ".str_replace("\n", "\n> ", $r['message_text']); // Way less complicated than using a regex ;-) + $text = "\n\n\nOn " . enano_date('M j, Y G:i', $r['date']) . ", " . $r['message_from'] . " wrote:\n> " . str_replace("\n", "\n> ", $r['message_text']); // Way less complicated than using a regex ;-) $tbuf = $text; while( preg_match("/\n([\> ]*?)\> \>/", $text) ) @@ -179,23 +274,85 @@ } $to = $r['message_from']; - } else { - if(( $argv[1]=='to' || $argv[1]=='To' ) && $argv[2]) $to = $argv[2]; - else $to = ''; + } + else + { + if ( ( $argv[1]=='to' || $argv[1]=='To' ) && $argv[2] ) + { + $to = htmlspecialchars($argv[2]); + } + else + { + $to = ''; + } $text = ''; $subj = ''; } $template->header(); userprefs_show_menu(); - echo '
'; + if ( isset($errors) && count($errors) > 0 ) + { + echo '
+ ' . $lang->get('privmsgs_err_send_submit') . ' +
    +
  • ' . implode('
  • ', $errors) . '
  • +
+
'; + } + echo ''; + + if ( isset($_POST['_savedraft']) ) + { + echo '
' . $lang->get('privmsgs_msg_draft_saved') . '
'; + } ?>
- - - - - + + + + + + + + + + + + + + + + + +
Compose new private message
To:
Separate multiple names with a single comma; you
can send this message to up to users.
username_field('to', (isset($_POST['_savedraft'])) ? $_POST['to'] : $to ); ?>
Subject:
Message:
get('privmsgs_lbl_compose_th'); ?>
+ get('privmsgs_lbl_compose_to'); ?>
+ get('privmsgs_lbl_compose_to_max', array('limit' => MAX_PMS_PER_BATCH)); ?> +
+ username_field('to', (isset($_POST['_savedraft'])) ? $_POST['to'] : $to ); ?> +
+ get('privmsgs_lbl_subject'); ?> + + +
+ get('privmsgs_lbl_message'); ?> + + tinymce_textarea('message', $content, 20, 40); + ?> +
+ + + +
'; @@ -203,61 +360,162 @@ break; case 'Edit': $id = $argv[1]; - if(!preg_match('#^([0-9]+)$#', $id)) die_friendly('Message error', '

Invalid message ID

'); + if ( !preg_match('#^([0-9]+)$#', $id) ) + { + die_friendly('Message error', '

Invalid message ID

'); + } $q = $db->sql_query('SELECT message_from, message_to, subject, message_text, date, folder_name, message_read FROM '.table_prefix.'privmsgs WHERE message_id='.$id.''); - if(!$q) $db->_die('The message data could not be selected.'); + if ( !$q ) + { + $db->_die('The message data could not be selected.'); + } $r = $db->fetchrow(); $db->free_result(); - if($r['message_from'] != $session->username || $r['message_read'] == 1 ) die_friendly('Access denied', '

You are not authorized to edit this message.

'); + if ( $r['message_from'] != $session->username || $r['message_read'] == 1 ) + { + die_friendly($lang->get('etc_access_denied_short'), '

You are not authorized to edit this message.

'); + } $fname = $argv[2]; if(isset($_POST['_send'])) { // Check each POST DATA parameter... - if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) die_friendly('Sending of message failed', '

Please enter the username to which you want to send your message.

'); - if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) die_friendly('Sending of message failed', '

Please enter a subject for your message.

'); - if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) die_friendly('Sending of message failed', '

Please enter a message to send.

'); - $namelist = $_POST['to']; - $namelist = str_replace(', ', ',', $namelist); - $namelist = explode(',', $namelist); - foreach($namelist as $n) { $n = $db->escape($n); } - $subject = RenderMan::preprocess_text($_POST['subject']); - $message = RenderMan::preprocess_text($_POST['message']); - $base_query = 'UPDATE '.table_prefix.'privmsgs SET subject=\''.$subject.'\',message_to=\''.$namelist[0].'\',message_text=\''.$message.'\',folder_name=\'inbox\' WHERE message_id='.$id.';'; - $result = $db->sql_query($base_query); - $db->free_result(); - if(!$result) $db->_die('The message could not be sent.'); - else die_friendly('Message status', '

Your message has been sent. You may edit the message if you wish; one copy for each recipient will be in your outbox until each recipient has read it. Return to your inbox.

'); - return; - } elseif(isset($_POST['_savedraft'])) { + $errors = array(); + if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_username'); + } + if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_subject'); + } + if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_message'); + } + if ( count($errors) < 1 ) + { + $namelist = $_POST['to']; + $namelist = str_replace(', ', ',', $namelist); + $namelist = explode(',', $namelist); + foreach ($namelist as $n) + { + $n = $db->escape($n); + } + $subject = RenderMan::preprocess_text($_POST['subject']); + $message = RenderMan::preprocess_text($_POST['message']); + $base_query = 'UPDATE '.table_prefix.'privmsgs SET subject=\''.$subject.'\',message_to=\''.$namelist[0].'\',message_text=\''.$message.'\',folder_name=\'inbox\' WHERE message_id='.$id.';'; + $result = $db->sql_query($base_query); + $db->free_result(); + if ( !$result ) + { + $db->_die('The message could not be sent.'); + } + else + { + die_friendly($lang->get('privmsgs_msg_message_status'), '

' . $lang->get('privmsgs_msg_message_sent', array('inbox_link' => makeUrlNS('Special', 'PrivateMessages/Folder/Inbox'))) . '

'); + } + return; + } + } + else if ( isset($_POST['_savedraft']) ) + { // Check each POST DATA parameter... - if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) die_friendly('Sending of message failed', '

Please enter the username to which you want to send your message.

'); - if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) die_friendly('Sending of message failed', '

Please enter a subject for your message.

'); - if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) die_friendly('Sending of message failed', '

Please enter a message to send.

'); - $namelist = $_POST['to']; - $namelist = str_replace(', ', ',', $namelist); - $namelist = explode(',', $namelist); - foreach($namelist as $n) { $n = $db->escape($n); } - $subject = $db->escape($_POST['subject']); - $message = RenderMan::preprocess_text($_POST['message']); - $base_query = 'UPDATE '.table_prefix.'privmsgs SET subject=\''.$subject.'\',message_to=\''.$namelist[0].'\',message_text=\''.$message.'\' WHERE message_id='.$id.';'; - $result = $db->sql_query($base_query); - $db->free_result(); - if(!$result) $db->_die('The message could not be saved.'); + $errors = array(); + if(!isset($_POST['to']) || ( isset($_POST['to']) && $_POST['to'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_username'); + } + if(!isset($_POST['subject']) || ( isset($_POST['subject']) && $_POST['subject'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_subject'); + } + if(!isset($_POST['message']) || ( isset($_POST['message']) && $_POST['message'] == '')) + { + $errors[] = $lang->get('privmsgs_err_need_message'); + } + if ( count($errors) < 1 ) + { + $namelist = $_POST['to']; + $namelist = str_replace(', ', ',', $namelist); + $namelist = explode(',', $namelist); + foreach ( $namelist as $n ) + { + $n = $db->escape($n); + } + $subject = $db->escape($_POST['subject']); + $message = RenderMan::preprocess_text($_POST['message']); + $base_query = 'UPDATE '.table_prefix.'privmsgs SET subject=\''.$subject.'\',message_to=\''.$namelist[0].'\',message_text=\''.$message.'\' WHERE message_id='.$id.';'; + $result = $db->sql_query($base_query); + $db->free_result(); + if ( !$result ) + { + $db->_die('The message could not be saved.'); + } + } } - if($argv[1]=='to' && $argv[2]) $to = $argv[2]; - else $to = ''; + if ( $argv[1]=='to' && $argv[2] ) + { + $to = htmlspecialchars($argv[2]); + } + else + { + $to = ''; + } $template->header(); userprefs_show_menu(); echo ''; + + if ( isset($_POST['_savedraft']) ) + { + echo '
' . $lang->get('privmsgs_msg_draft_saved') . '
'; + } ?>
- - - - - + + + + + + + + + + + + + + + + +
Edit draft
To:
Separate multiple names with a single comma
Subject:
Message:
get('privmsgs_lbl_edit_th'); ?>
+ get('privmsgs_lbl_compose_to'); ?>
+ get('privmsgs_lbl_compose_to_max', array('limit' => MAX_PMS_PER_BATCH)); ?> +
+ username_field('to', (isset($_POST['_savedraft'])) ? $_POST['to'] : $r['message_to'] ); ?> +
+ get('privmsgs_lbl_subject'); ?> + + +
+ get('privmsgs_lbl_message'); ?> + + tinymce_textarea('message', $content, 20, 40); + ?> +
+ + +
'; @@ -269,7 +527,10 @@ switch($argv[1]) { default: - echo '

The folder "'.$argv[1].'" does not exist. Return to your inbox.

'; + echo '

' . $lang->get('privmsgs_err_folder_not_exist', array( + 'folder_name' => htmlspecialchars($argv[1]), + 'inbox_url' => makeUrlNS('Special', 'PrivateMessages/Folder/Inbox') + )) . '

'; break; case 'Inbox': case 'Outbox': @@ -281,15 +542,15 @@ @@ -312,36 +573,88 @@ $q = $db->sql_query('SELECT p.message_id, p.message_from, p.message_to, p.date, p.subject, p.message_read FROM '.table_prefix.'privmsgs AS p WHERE p.folder_name=\''.$fname.'\' AND p.message_from=\''.$session->username.'\' ORDER BY date DESC;'); break; } - if($argv[1] == 'Drafts' || $argv[1] == 'Outbox') $act = 'Edit'; - else $act = 'View'; - if(!$q) $db->_die('The private message data could not be selected.'); - echo '
'; + if ( !$q ) + { + $db->_die('The private message data could not be selected.'); + } + if ( $argv[1] == 'Drafts' || $argv[1] == 'Outbox' ) + { + $act = 'Edit'; + } + else + { + $act = 'View'; + } + echo ' +
+
Folder: '.$argv[1].'
'; - if($fname == 'drafts' || $fname == 'Outbox') echo 'To'; else echo 'From'; - echo 'SubjectDateMark
+ + + + + + + + + '; if($db->numrows() < 1) - echo ''; - else { + { + echo ''; + } + else + { $cls = 'row2'; - while($r = $db->fetchrow()) + while ( $r = $db->fetchrow() ) { if($cls == 'row2') $cls='row1'; else $cls = 'row2'; $mto = str_replace(' ', '_', $r['message_to']); $mfr = str_replace(' ', '_', $r['message_from']); echo ''; + if ( $r['message_read'] == 0 ) + { + echo ''; + } + echo ''; } $db->free_result(); } - echo ''; + echo ' + + '; echo '
' . $lang->get('privmsgs_folder_th_foldername') . ' ' . $lang->get('privmsgs_folder_' . strtolower($argv[1])) . '
'; + if ( $fname == 'drafts' || $fname == 'Outbox' ) + { + echo $lang->get('privmsgs_folder_th_to'); + } + else + { + echo $lang->get('privmsgs_folder_th_from'); + } + echo '' . $lang->get('privmsgs_folder_th_subject') . '' . $lang->get('privmsgs_folder_th_date') . '' . $lang->get('privmsgs_folder_th_mark') . '
No messages in this folder.
' . $lang->get('privmsgs_msg_no_messages') . '
'; - if($fname == 'drafts' || $fname == 'outbox') echo $r['message_to']; else echo $r['message_from']; + if ( $fname == 'drafts' || $fname == 'outbox' ) + { + echo $r['message_to']; + } + else + { + echo $r['message_from']; + } + echo ''; - if($r['message_read'] == 0) echo ''; + + if ( $r['message_read'] == 0 ) + { + echo ''; + } echo $r['subject']; - if($r['message_read'] == 0) echo ''; - echo ''.date('M j, Y G:i', $r['date']).'
'.enano_date('M j, Y G:i', $r['date']).'
+ + + + +

- New message + ' . $lang->get('privmsgs_btn_compose') . ' '; break; } @@ -406,14 +719,14 @@ $r = $db->fetchrow(); $db->free_result(); $q = $db->sql_query('INSERT INTO '.table_prefix.'buddies(user_id,buddy_user_id,is_friend) VALUES('.$session->user_id.', '.$r['user_id'].', 1);'); - if(!$q) echo '

Warning:

Buddy could not be added: '.mysql_error().'

'; + if(!$q) echo '

Warning:

Buddy could not be added: '.$db->get_error().'

'; $db->free_result(); } } elseif($argv[1] == 'Remove' && preg_match('#^([0-9]+)$#', $argv[2])) { // Using WHERE user_id prevents users from deleting others' buddies $q = $db->sql_query('DELETE FROM '.table_prefix.'buddies WHERE user_id='.$session->user_id.' AND buddy_id='.$argv[2].';'); $db->free_result(); - if(!$q) echo '

Warning:

Buddy could not be deleted: '.mysql_error().'

'; + if(!$q) echo '

Warning:

Buddy could not be deleted: '.$db->get_error().'

'; if(mysql_affected_rows() < 1) echo '

Warning:

No rows were affected. Either the selected buddy ID does not exist or you tried to delete someone else\'s buddy.

'; } $template->header(); @@ -423,15 +736,15 @@ @@ -441,26 +754,26 @@ else { $allbuds = ''; - echo '
'; - if($db->numrows() < 1) echo ''; + echo '
Buddy list for '.$session->username.'
No buddies in your list.
'; + if($db->numrows() < 1) echo ''; $cls = 'row2'; while ( $row = $db->fetchrow() ) { if($cls=='row2') $cls = 'row1'; else $cls = 'row2'; - echo ''; + echo ''; $allbuds .= str_replace(' ', '_', $row['username']).','; } $db->free_result(); $allbuds = substr($allbuds, 0, strlen($allbuds)-1); if($cls=='row2') $cls = 'row1'; else $cls = 'row2'; - echo ''; + echo ''; echo '
' . $lang->get('privmsgs_th_buddy_list', array('username' => htmlspecialchars($session->username))) . '
' . $lang->get('privmsgs_msg_no_buddies') . '
nslist['User'].str_replace(' ', '_', $row['username'])) ? '' : 'class="wikilink-nonexistent" ' ) .'>'.$row['username'].'Send private messageRemove
nslist['User'].str_replace(' ', '_', $row['username'])) ? '' : 'class="wikilink-nonexistent" ' ) .'>'.$row['username'].'' . $lang->get('privmsgs_btn_buddy_send_pm') . '' . $lang->get('privmsgs_btn_buddy_remove') . '
Send a PM to all buddies
' . $lang->get('privmsgs_btn_pm_all_buddies') . '
'; } echo '
-

Add a new friend

'; - echo '

Username: '.$template->username_field('buddyname').'

'; +

' . $lang->get('privmsgs_heading_add_buddy') . '

'; + echo '

' . $lang->get('privmsgs_lbl_username') . ' '.$template->username_field('buddyname').'

'; echo '
'; ?> @@ -478,61 +791,60 @@ { $r = $db->fetchrow(); $q = $db->sql_query('INSERT INTO '.table_prefix.'buddies(user_id,buddy_user_id,is_friend) VALUES('.$session->user_id.', '.$r['user_id'].', 0);'); - if(!$q) echo '

Warning:

Buddy could not be added: '.mysql_error().'

'; + if(!$q) echo '

Warning:

Buddy could not be added: '.$db->get_error().'

'; } $db->free_result(); } elseif($argv[1] == 'Remove' && preg_match('#^([0-9]+)$#', $argv[2])) { // Using WHERE user_id prevents users from deleting others' buddies $q = $db->sql_query('DELETE FROM '.table_prefix.'buddies WHERE user_id='.$session->user_id.' AND buddy_id='.$argv[2].';'); $db->free_result(); - if(!$q) echo '

Warning:

Buddy could not be deleted: '.mysql_error().'

'; + if(!$q) echo '

Warning:

Buddy could not be deleted: '.$db->get_error().'

'; if(mysql_affected_rows() < 1) echo '

Warning:

No rows were affected. Either the selected buddy ID does not exist or you tried to delete someone else\'s buddy.

'; } $template->header(); userprefs_show_menu(); ?> - - - -
-
- - - - - - - - - -
Private messages
Inbox
Outbox
Sent Items
Drafts
Archive
Buddies
Friend list
Foe list
-
+ + + + diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialAdmin.php --- a/plugins/SpecialAdmin.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/SpecialAdmin.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ attachHook('base_classes_initted', ' +$plugins->attachHook('session_started', ' global $paths; $paths->add_page(Array( - \'name\'=>\'Administration\', + \'name\'=>\'specialpage_administration\', \'urlname\'=>\'Administration\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Manage the Sidebar\', + \'name\'=>\'specialpage_manage_sidebar\', \'urlname\'=>\'EditSidebar\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', @@ -40,67 +40,108 @@ '); // Admin pages that were too enormous to be in this file were split off into the plugins/admin/ directory in 1.0.1 +require(ENANO_ROOT . '/plugins/admin/PageManager.php'); +require(ENANO_ROOT . '/plugins/admin/PageEditor.php'); require(ENANO_ROOT . '/plugins/admin/PageGroups.php'); +require(ENANO_ROOT . '/plugins/admin/GroupManager.php'); require(ENANO_ROOT . '/plugins/admin/SecurityLog.php'); require(ENANO_ROOT . '/plugins/admin/UserManager.php'); +require(ENANO_ROOT . '/plugins/admin/LangManager.php'); +require(ENANO_ROOT . '/plugins/admin/ThemeManager.php'); + +// For convenience and nothing more. +function acp_start_form() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + echo ''; +} // function names are IMPORTANT!!! The name pattern is: page__ function page_Admin_Home() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; + return; + } + + if ( $paths->getParam(0) == 'updates.xml' ) + { + require_once(ENANO_ROOT . '/includes/http.php'); + $req = new Request_HTTP('germantown.enanocms.org', '/meta/updates.xml'); + $response = $req->get_response_body(); + header('Content-type: application/xml'); + if ( $req->response_code != HTTP_OK ) + { + // Error in response + echo 'response_code . ' ' . $req->response_string . ' +]]>'; + } + else + { + // Retrieve first update + $first_update = preg_match('//', $response, $match); + if ( !$first_update ) + { + echo ''; + } + if ( version_compare(enano_version(true), $match[2], '<') ) + { + $response = str_replace_once('', " \n ", $response); + } + echo $response; + } return; } // Basic information - echo RenderMan::render( -'== Welcome to Runt, the Enano administration panel. == - -Thank you for choosing Enano as your CMS. This screen allows you to see some information about your website, plus some details about how your site is doing statistically. - -Using the links on the left you can control every aspect of your website\'s look and feel, plus you can manage users, work with pages, and install plugins to make your Enano installation even better.'); + echo '

' . $lang->get('acphome_heading_main') . '

'; + echo '

' . $lang->get('acphome_welcome_line1') . '

'; + echo '

' . $lang->get('acphome_welcome_line2') . '

'; // Demo mode if ( defined('ENANO_DEMO_MODE') ) { - echo '

Enano is running in demo mode.

-

If you borked something up, or if you\'re done testing, you can reset this site. The site is reset automatically once every two hours. When a reset is performed, all custom modifications to the site are lost and replaced with default values.

'; - } - - // If we're on PHP4, warn the user - // Enano is not supported on PHP4 after December 31, 2007. - if ( version_compare(PHP_VERSION, '5.0.0', '<') ) - { - echo '
- Your server is running PHP ' . PHP_VERSION . '.
- As of December 31, 2007, servers running the PHP 4.x interpreter are not eligible for support on the Enano forums. While you - may be able to obtain support elsewhere, all official Enano support channels do not provide any type of support for servers - running this outdated and vulnerable version of PHP.
-
- This notice will not show if PHP 5.0.0 or later is detected. You may want to ask your web host to upgrade their PHP - installation. If you\'re refused, point them to GoPHP5.org and explain that they are opening - themselves to security problems by not upgrading. -
'; + echo '

' . $lang->get('acphome_msg_demo_title') . '

+

' . $lang->get('acphome_msg_demo_body', array('reset_url' => makeUrlNS('Special', 'DemoReset', false, true))) . '

'; } // Check for the installer scripts if( ( file_exists(ENANO_ROOT.'/install.php') || file_exists(ENANO_ROOT.'/schema.sql') ) && !defined('ENANO_DEMO_MODE') ) { - echo '
NOTE: It appears that your install.php and/or schema.sql files still exist. It is HIGHLY RECOMMENDED that you delete or rename these files, to prevent getting your server hacked.
'; + echo '
+ ' . $lang->get('acphome_msg_install_files') . ' +
'; } + echo '

' . $lang->get('acphome_heading_updates') . '

'; + echo '

' . $lang->get('acphome_msg_updates_info', array('updates_url' => 'http://germantown.enanocms.org/meta/updates.xml')) . '

'; + echo '
'; + // Inactive users - $q = $db->sql_query('SELECT * FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\';'); - if($q) - if($db->numrows() > 0) + $q = $db->sql_query('SELECT time_id FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\';'); + if ( $q ) + { + if ( $db->numrows() > 0 ) { $n = $db->numrows(); - if($n == 1) $s = $n . ' user is'; - else $s = $n . ' users are'; - echo '
It appears that '.$s.' awaiting account activation. You can activate those accounts by going to the User Manager.
'; + $um_flags = 'href="#" onclick="ajaxPage(\''.$paths->nslist['Admin'].'UserManager\'); return false;"'; + if ( $n == 1 ) + $s = $lang->get('acphome_msg_inactive_users_one', array('um_flags' => $um_flags)); + else + $s = $lang->get('acphome_msg_inactive_users_plural', array('um_flags' => $um_flags)); + echo '
+ ' . $s . ' +
'; } + } $db->free_result(); // Stats if(getConfig('log_hits') == '1') @@ -109,31 +150,44 @@ //die('
'.print_r($stats,true).'
'); $c = 0; $cls = 'row2'; - echo '

Most requested pages

+ + sql_query('SELECT u.username,b.buddy_id FROM '.table_prefix.'buddies AS b LEFT JOIN '.table_prefix.'users AS u ON ( u.user_id=b.buddy_user_id ) WHERE b.user_id='.$session->user_id.' AND is_friend=0;'); if(!$q) $db->_die('The buddy list could not be selected.'); else { $allbuds = ''; - echo '
'; - if($db->numrows() < 1) echo ''; + echo '
Foe list for '.$session->username.'
No foes in your list.
'; + if($db->numrows() < 1) echo ''; $cls = 'row2'; while ( $row = $db->fetchrow() ) { if($cls=='row2') $cls = 'row1'; else $cls = 'row2'; - echo ''; + echo ''; $allbuds .= str_replace(' ', '_', $row['username']).','; } + $db->free_result(); $allbuds = substr($allbuds, 0, strlen($allbuds)-1); if($cls=='row2') $cls = 'row1'; else $cls = 'row2'; - //echo ''; echo '
' . $lang->get('privmsgs_th_foe_list', array('username' => htmlspecialchars($session->username))) . '
' . $lang->get('privmsgs_msg_no_foes') . '
nslist['User'].str_replace(' ', '_', $row['username'])) ? '' : 'class="wikilink-nonexistent" ' ) .'>'.$row['username'].'Send private messageRemove
nslist['User'].str_replace(' ', '_', $row['username'])) ? '' : 'class="wikilink-nonexistent" ' ) .'>'.$row['username'].'' . $lang->get('privmsgs_btn_buddy_send_pm') . '' . $lang->get('privmsgs_btn_buddy_remove') . '
Send a PM to all buddies
'; } - $db->free_result(); echo '
-

Add a new foe

'; - echo '

Username: '.$template->username_field('buddyname').'

'; +

' . $lang->get('privmsgs_heading_add_foe') . '

'; + echo '

' . $lang->get('privmsgs_lbl_username') . ' '.$template->username_field('buddyname').'

'; echo '
'; ?>
'; + echo '

' . $lang->get('acphome_heading_top_pages') . '

+
+
PageHits
+ + + + '; foreach($stats as $data) { - echo ''; + echo ''; $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; - echo ''; - echo ''; + echo ''; + echo ''; } - echo '
' . $lang->get('acphome_th_toppages_page') . '' . $lang->get('acphome_th_toppages_hits') . '
'.$data['page_title'].''.$data['num_hits'].'
+ '.$data['page_title'].''.$data['num_hits'] + . '
'; + echo '
+
'; } // Security log - echo '

Security log

'; + echo '

' . $lang->get('acphome_heading_seclog') . '

'; + echo '

' . $lang->get('acphome_msg_seclog_info') . '

'; $seclog = get_security_log(5); echo $seclog; - echo '

Full security log

'; + echo '

' . $lang->get('acphome_btn_seclog_full') . '

'; } function page_Admin_GeneralConfig() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } @@ -155,6 +209,8 @@ if(isset($_POST['editmsg'])) setConfig('wiki_edit_notice', '1'); else setConfig('wiki_edit_notice', '0'); setConfig('wiki_edit_notice_text', $_POST['editmsg_text']); + if(isset($_POST['guest_edit_require_captcha'])) setConfig('guest_edit_require_captcha', '1'); + else setConfig('guest_edit_require_captcha', '0'); // Stats if(isset($_POST['log_hits'])) setConfig('log_hits', '1'); @@ -219,7 +275,48 @@ setConfig('pw_strength_minimum', $strength); } - echo '
Your changes to the site configuration have been saved.

'; + setConfig('register_tou', RenderMan::preprocess_text($_POST['register_tou'], true, false)); + + // Account lockout policy + if ( preg_match('/^[0-9]+$/', $_POST['lockout_threshold']) ) + setConfig('lockout_threshold', $_POST['lockout_threshold']); + + if ( preg_match('/^[0-9]+$/', $_POST['lockout_duration']) ) + setConfig('lockout_duration', $_POST['lockout_duration']); + + if ( in_array($_POST['lockout_policy'], array('disable', 'captcha', 'lockout')) ) + setConfig('lockout_policy', $_POST['lockout_policy']); + + // Avatar settings + setConfig('avatar_enable', ( isset($_POST['avatar_enable']) ? '1' : '0' )); + // for these next three values, set the config value if it's a valid integer; this is + // done by using strval(intval($foo)) === $foo, which flattens $foo to an integer and + // then converts it back to a string. This effectively verifies that var $foo is both + // set and that it's a valid string representing an integer. + setConfig('avatar_max_size', ( strval(intval($_POST['avatar_max_size'])) === $_POST['avatar_max_size'] ? $_POST['avatar_max_size'] : '10240' )); + setConfig('avatar_max_width', ( strval(intval($_POST['avatar_max_width'])) === $_POST['avatar_max_width'] ? $_POST['avatar_max_width'] : '96' )); + setConfig('avatar_max_height', ( strval(intval($_POST['avatar_max_height'])) === $_POST['avatar_max_height'] ? $_POST['avatar_max_height'] : '96' )); + setConfig('avatar_enable_anim', ( isset($_POST['avatar_enable_anim']) ? '1' : '0' )); + setConfig('avatar_upload_file', ( isset($_POST['avatar_upload_file']) ? '1' : '0' )); + setConfig('avatar_upload_http', ( isset($_POST['avatar_upload_http']) ? '1' : '0' )); + + if ( is_dir(ENANO_ROOT . '/' . $_POST['avatar_directory']) ) + { + if ( preg_match('/^([A-z0-9_-]+)(\/([A-z0-9_-]+))*$/', $_POST['avatar_directory']) ) + { + setConfig('avatar_directory', $_POST['avatar_directory']); + } + else + { + echo '
' . $lang->get('acpgc_err_avatar_dir_invalid') . '
'; + } + } + else + { + echo '
' . $lang->get('acpgc_err_avatar_dir_invalid') . '
'; + } + + echo '
' . $lang->get('acpgc_msg_save_success') . '

'; } else if ( isset($_POST['submit']) && defined('ENANO_DEMO_MODE') ) @@ -233,28 +330,28 @@ - Global site options - These options control the entire site. + get('acpgc_heading_main'); ?> + get('acpgc_heading_submain'); ?> - Site name: - Site description: - Main page: pagename_field('main_page', htmlspecialchars(str_replace('_', ' ', getConfig('main_page')))); ?> - Copyright notice shown on pages: - Hint: If you're using Windows, you can make a "©" symbol by holding ALT and pressing 0169 on the numeric keypad. - Contact e-mail
All e-mail sent from this site will appear to have come from the address shown here. + get('acpgc_field_site_name'); ?> + get('acpgc_field_site_desc'); ?> + get('acpgc_field_main_page'); ?> pagename_field('main_page', htmlspecialchars(str_replace('_', ' ', getConfig('main_page')))); ?> + get('acpgc_field_copyright'); ?> + get('acpgc_field_copyright_hint'); ?> + get('acpgc_field_contactemail'); ?>
get('acpgc_field_contactemail_hint'); ?> - Wiki mode + get('acpgc_heading_wikimode'); ?> - Enano can also act as a wiki, meaning anyone can edit and create pages. To enable Wiki Mode, check the box to the right.

- In Wiki Mode, certain HTML tags such as <script> and <object> are disabled, and all PHP code is disabled, except if the person editing the page is an administrator.

- Also, Enano keeps complete page history, which makes restoring vandalized pages easy. You can also protect pages so that they cannot be edited. + get('acpgc_field_wikimode_intro'); ?>

+ get('acpgc_field_wikimode_info_sanitize'); ?>

+ get('acpgc_field_wikimode_info_history'); ?> - /> + /> @@ -262,11 +359,12 @@ - Edit page notice
- When Wiki Mode is enabled, anyone can edit pages. Check the box below and enter a message to display it whenever the page editor is opened. + get('acpgc_field_editnotice_title'); ?>
+ get('acpgc_field_editnotice_info'); ?> - /> + /> + @@ -276,23 +374,88 @@ + + + get('acpgc_field_edit_require_captcha_title'); ?>
+ get('acpgc_field_edit_require_captcha_hint'); ?> + + + + + + - Statistics and hit counting + get('acpgc_heading_stats'); ?> - Enano has the ability to show statistics for every page on the site. This allows you to keep very close track of who is visiting your site, and from where.

Unfortunately, some users don't like being logged. For this reason, you should state clearly what is logged (usually the username or IP address, current time, page name, and referer URL) in your privacy policy. If your site is primarily geared towards children, and you are a United States citizen, you are required to have a privacy policy stating exactly what is being logged under the terms of the Childrens' Online Privacy Protection Act. -
This excludes special and administration pages. + + get('acpgc_stats_intro'); ?>

+ get('acpgc_stats_hint_privacy'); ?> + + +
+ get('acpgc_field_stats_hint'); ?> + - Comment system - /> - /> - Guest comment posting allowed - - + + + get('acpgc_heading_comments'); ?> + + + + + + + + + /> + + + + + + + + + /> + + + + + + get('acpgc_field_comment_allow_guests'); ?> + + + + + + + + + - - - - Promote Enano - - - - If you think Enano is nice, or if you want to show your support for the Enano team, you can do so by placing a link to the Enano - homepage in your Links sidebar block. You absolutely don't have to do this, and you won't get degraded support if you don't. Because - Enano is still relatively new in the CMS world, it needs all the attention it can get - and you can easily help to spread the word - using this link. - - - - - - - Disable all site access + get('acpgc_heading_disablesite'); ?> - Disabling the site allows you to work on the site without letting non-administrators see or use it. - + + get('acpgc_field_disablesite_hint'); ?> + + + + + + +
+ +
+ + + + + - + - + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
get('acpgc_heading_users'); ?>
User account activation
get('acpgc_heading_activate'); ?>
- If you would like to require users to confirm their e-mail addresses by way of account activation, you can enable this behavior here. If this option is set to "None", users will be able to register and use this site without confirming their e-mail addresses. If this option is set to "User", users will automatically be sent e-mails upon registration with a link to activate their accounts. And lastly, if this option is set to "Admin", users' accounts will not be active until an administrator activates the account.

- You may also disable registration completely if needed.

- Note: because of abuse by project administrators, sending account activation e-mails will not work on SourceForge.net servers. + get('acpgc_activate_intro_line1'); ?>

+ get('acpgc_activate_intro_line2'); ?>

+ get('acpgc_activate_intro_sfnet_warning'); ?>
Account activation: + get('acpgc_field_activate'); ?> Disable registration
'; - echo ''; - echo ''; - echo ''; + echo '
'; + echo ''; + echo ''; + echo ''; + ?> +
+ get('acpgc_heading_tou'); ?> +
+ get('acpgc_field_tou'); ?>
+ get('acpgc_field_tou_hint'); ?> +
+ tinymce_textarea('register_tou', $terms, 10, 40); ?>
Password strength
get('acpgc_heading_lockout'); ?>
get('acpgc_lockout_intro'); ?>
get('acpgc_field_lockout_threshold'); ?>
+ get('acpgc_field_lockout_threshold_hint'); ?> +
+ +
get('acpgc_field_lockout_duration'); ?>
+ get('acpgc_field_lockout_duration_hint'); ?> +
+ +
get('acpgc_field_lockout_policy'); ?>
+ get('acpgc_field_lockout_policy_hint'); ?> +
+
+
+ +
get('acpgc_heading_passstrength'); ?>
- Enable password strength analysis
- This should be enabled in most cases. When this is enabled, a strength meter and a numerical score will be displayed wherever a password can be changed. + get('acpgc_field_passstrength_title'); ?>
+ get('acpgc_field_passstrength_hint'); ?>
- +
- Minimum strength score
- This is the lowest score a password will be allowed to have. -10 will allow any password. A score of under -3 is considered weak, under 1 is fair, under 4 is good, under 10 is strong, and 10 and above are very strong. The scale is open-ended. This only has an effect if the meter is enabled above. + get('acpgc_field_passminimum_title'); ?>
+ get('acpgc_field_passminimum_hint'); ?>
@@ -391,85 +610,261 @@ -
E-mail sent from the site
E-mail sending method:
Try using the built-in e-mail method first. If that doesn't work, you will need to enter valid SMTP information here.

-
SMTP hostname:
This option only applies to the external SMTP mode.
SMTP credentials:
This option only applies to the external SMTP mode.
Username:
- Password:
+ get('acpgc_heading_email'); ?> +
+ get('acpgc_field_email_method'); ?>
+ get('acpgc_field_email_method_hint'); ?> +
+ + +
+ + +
+ get('acpgc_field_email_smtp_hostname'); ?>
+ get('acpgc_field_email_smtp_hostname_hint'); ?> +
+ +
+ get('acpgc_field_email_smtp_auth'); ?>
+ get('acpgc_field_email_smtp_hostname_hint'); ?> +
+ get('acpgc_field_email_smtp_username'); ?>
+ get('acpgc_field_email_smtp_password'); ?> +
get('acpgc_heading_avatars'); ?>
+ get('acpgc_avatars_intro'); ?> + +
+ get('acpgc_field_avatar_enable'); ?>
+ get('acpgc_field_avatar_enable_hint'); ?> +
+ +
+ get('acpgc_field_avatar_max_filesize'); ?>
+ get('acpgc_field_avatar_max_filesize_hint'); ?> +
+ /> get('etc_unit_bytes'); ?> +
+ get('acpgc_field_avatar_max_dimensions'); ?>
+ get('acpgc_field_avatar_max_dimensions_hint'); ?> +
+ /> × + /> get('etc_unit_pixels'); ?> +
+ get('acpgc_field_avatar_allow_anim_title'); ?>
+ get('acpgc_field_avatar_allow_anim_hint'); ?> +
+ +
+ get('acpgc_field_avatar_upload_methods'); ?>
+ +
+ + +
+ + +
+ get('acpgc_field_avatar_directory'); ?>
+ get('acpgc_field_avatar_directory_hint'); ?> +
+ /> +
+
+ +
+ + + + + + + + + + + + + + + - + - + - + - + - - + + - - - - - - + + + + + + - - - + + + + + + + + + + + + + +
get('acpgc_heading_sidebar'); ?>
get('acpgc_heading_promoteenano'); ?>
+ get('acpgc_field_enano_link_title'); ?> + + +
SourceForge.net logo
get('acpgc_heading_sfnet_logo'); ?>
- All projects hosted by SourceForge.net are required to display an official SourceForge.net logo on their pages. If you want - to display a SourceForge.net logo on the sidebar, check the box below, enter your group ID, and select an image type. + get('acpgc_sfnet_intro'); ?>
Display the SourceForge.net logo on the right sidebarget('acpgc_field_sfnet_display'); ?> />
Group ID:get('acpgc_field_sfnet_group_id'); ?>
Logo style:get('acpgc_field_sfnet_logo_style'); ?>
W3C compliance logos
Enano generates (by default) Valid XHTML 1.1 code, plus valid CSS. If you want to show this off, check the appropriate boxes below.
get('acpgc_heading_w3clogos'); ?>
get('acpgc_w3clogos_intro'); ?>
id="w3c-vh32" name="w3c-vh32" />
id="w3c-vh40" name="w3c-vh40" />
id="w3c-vh401" name="w3c-vh401" />
id="w3c-vxhtml10" name="w3c-vxhtml10" />
id="w3c-vxhtml11" name="w3c-vxhtml11" />
id="w3c-vcss" name="w3c-vcss" />
id="w3c-vh32" name="w3c-vh32" />
id="w3c-vh40" name="w3c-vh40" />
id="w3c-vh401" name="w3c-vh401" />
id="w3c-vxhtml10" name="w3c-vxhtml10" />
id="w3c-vxhtml11" name="w3c-vxhtml11" />
id="w3c-vcss" name="w3c-vcss" />
Defective By Design Anti-DRM button
The Enano project is strongly against Digital Restrictions Management. DRM removes the freedoms that every consumer should have: to freely copy and use digital media items they legally purchased to their own devices. Showing your opposition to DRM is as easy as checking the box below to place a link to DefectiveByDesign.org on your sidebar.
/>
+ get('acpgc_heading_dbd'); ?> +
+ get('acpgc_dbd_intro'); ?> + get('acpgc_dbd_explain'); ?> +
+ + + /> +
+
+ +
+ - +
@@ -480,9 +875,12 @@ function page_Admin_UploadConfig() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } @@ -540,6 +938,9 @@ } if(file_exists($_POST['imagemagick_path']) && $_POST['imagemagick_path'] != getConfig('imagemagick_path')) { + if ( defined('ENANO_DEMO_MODE') ) + // Hackish but safe. + $_POST['imagemagick_path'] = '/usr/bin/convert'; $old = getConfig('imagemagick_path'); $oldnew = "{$old}||{$_POST['imagemagick_path']}"; $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'magick_path\',' . time() . ',\'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\',\'' . $db->escape($session->username) . '\',\'' . $db->escape($oldnew) . '\');'); @@ -549,7 +950,7 @@ } else if ( $_POST['imagemagick_path'] != getConfig('imagemagick_path') ) { - echo 'Warning: the file "'.htmlspecialchars($_POST['imagemagick_path']).'" was not found, and the ImageMagick file path was not updated.'; + echo '' . $lang->get('acpup_err_magick_not_found', array('magick_path' => htmlspecialchars($_POST['imagemagick_path']))) . ''; } $max_upload = floor((float)$_POST['max_file_size'] * (int)$_POST['fs_units']); if ( $max_upload > 1048576 && defined('ENANO_DEMO_MODE') ) @@ -561,76 +962,192 @@ setConfig('max_file_size', $max_upload.''); } } - echo ''; + acp_start_form(); ?> -

File upload configuration

-

Enano supports the ability to upload files to your website and store the files in the database. This enables you to embed images - and such into pages without manually writing the HTML. However, the upload feature can sometimes pose a risk to your site, as viruses - and executable files can sometimes be uploaded.

-

-

Maximum file size:

-

You can allow Enano to generate thumbnails of images automatically. This feature requires ImageMagick to work properly. If your server - does not have ImageMagick on it, Enano will simply make your users' browsers scale the images. In most cases this is fine, but if you - are uploading large (>100KB) images and embedding them inside of pages, you should try to enable ImageMagick because transferring these - large images many times can cost you quite a lot of bandwidth.

-


- Path to ImageMagick:
- On Linux and Unix servers, the most likely options here are /usr/bin/convert and /usr/local/bin/convert. If you server runs Windows, then - ImageMagick is most likely to be C:\Windows\Convert.exe or C:\Windows\System32\Convert.exe. -

-

If you use ImageMagick to scale images, your server will be very busy constantly scaling images if your website is busy, and your site - may experience slowdowns. You can dramatically speed up this scaling process if you use a directory to cache thumbnail images.

-

Please note: the cache/ directory on your server must be writable by the server. While this is not usually a problem on - Windows servers, most Linux/Unix servers will require you to CHMOD the cache/ directory to 777. See your FTP client's user guide for - more information on how to do this.At present, it seems that the cache directory - is not writable. The checkbox below has been disabled to maintain the stability of Enano.'; ?>

-

-

Lastly, you can choose whether file history will be saved. If this option is turned on, you will be able to roll back any malicious - changes made to uploaded files, but this requires a significant amount of database storage. You should probably leave this option - enabled unless you have less than 250MB of MySQL database space.

-

+

get('acpup_heading_main'); ?>

+ +

+ get('acpup_intro'); ?> +

+

+ +

+

+ get('acpup_field_max_size'); ?> + + +

+ +

get('acpup_info_magick'); ?>

+

+ +
+ get('acpup_field_magick_path'); ?>
+ get('acpup_field_magick_path_hint'); ?> +

+ +

get('acpup_info_cache'); ?>

+

+ get('acpup_info_cache_chmod'); ?> + + get('acpup_msg_cache_not_writable'); + ?> +

+ +

+ +

+ +

get('acpup_info_history'); ?>

+

+ +

+
-

+

'; } -function page_Admin_PluginManager() { +function page_Admin_UploadAllowedMimeTypes() +{ global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; + return; + } + + global $mime_types, $mimetype_exps, $mimetype_extlist; + if(isset($_POST['save']) && !defined('ENANO_DEMO_MODE')) + { + $bits = ''; + $keys = array_keys($mime_types); + foreach($keys as $i => $k) + { + if(isset($_POST['ext_'.$k])) $bits .= '1'; + else $bits .= '0'; + } + $bits = compress_bitfield($bits); + setConfig('allowed_mime_types', $bits); + echo '
' . $lang->get('acpft_msg_saved') . '
'; + } + else if ( isset($_POST['save']) && defined('ENANO_DEMO_MODE') ) + { + echo '
' . $lang->get('acpft_msg_demo_mode') . '
'; + } + $allowed = fetch_allowed_extensions(); + ?> +

get('acpft_heading_main'); ?>

+

get('acpft_hint'); ?>

+ '."\n".' '."\n".' '."\n "; + ksort($mime_types); + foreach($mime_types as $e => $m) + { + $c++; + $t++; + if($c == 3) + { + $c = 0; + $cl = ( $cl == 'row1' ) ? 'row2' : 'row1'; + echo ''."\n".' '."\n "; + } + $seed = "extchkbx_{$e}_".md5(microtime() . mt_rand()); + $chk = (!empty($allowed[$e])) ? ' checked="checked"' : ''; + echo " \n "; + } + while($c < 2) + { + $c++; + echo " \n "; + } + echo ''; + echo ''."\n".'
\n \n
'."\n".'
'; + echo ''; + ?> + auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } if(isset($_GET['action'])) { - switch($_GET['action']) + if ( !isset($_GET['plugin']) ) + { + echo '
No plugin specified.
'; + } + else if ( !preg_match('/^[A-z0-9_\.-]+\.php$/', $_GET['plugin']) ) { - case "enable": - $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'plugin_enable\',' . time() . ',\'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\',"' . $db->escape($session->username) . '","' . $db->escape($_GET['plugin']) . '");'); - if ( !$q ) - $db->_die(); - setConfig('plugin_'.$_GET['plugin'], '1'); - break; - case "disable": - if ( defined('ENANO_DEMO_MODE') && strstr($_GET['plugin'], 'Demo') ) - { - echo('

Error disabling plugin

The demo lockdown plugin cannot be disabled in demo mode.

'); - break; - } - if ( !in_array($_GET['plugin'], $plugins->system_plugins) ) - { - $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'plugin_disable\',' . time() . ',\'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\',"' . $db->escape($session->username) . '","' . $db->escape($_GET['plugin']) . '");'); + echo '
Hacking attempt
'; + } + else + { + $plugin =& $_GET['plugin']; + switch($_GET['action']) + { + case "enable": + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'plugin_enable\',' . time() . ',\'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\',"' . $db->escape($session->username) . '","' . $db->escape($_GET['plugin']) . '");'); if ( !$q ) $db->_die(); - setConfig('plugin_'.$_GET['plugin'], '0'); - } - else - { - echo('

Error disabling plugin

The plugin you selected cannot be disabled because it is a system plugin.

'); - } - break; + setConfig("plugin_$plugin", '1'); + break; + case "disable": + if ( defined('ENANO_DEMO_MODE') && strstr($_GET['plugin'], 'Demo') ) + { + echo('

' . $lang->get('acppl_err_heading') . '

+

' . $lang->get('acppl_err_demo_plugin') . '

'); + break; + } + if ( !in_array($plugin, $plugins->system_plugins) ) + { + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES(\'security\',\'plugin_disable\',' . time() . ',\'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\',"' . $db->escape($session->username) . '","' . $db->escape($_GET['plugin']) . '");'); + if ( !$q ) + $db->_die(); + setConfig("plugin_$plugin", '0'); + } + else + { + echo '

' . $lang->get('acppl_err_heading') . '

+

' . $lang->get('acppl_err_system_plugin') . '

'; + } + break; + } } } $dir = './plugins/'; @@ -673,23 +1190,37 @@ $thelist[$file]['auth'] = $f[3]; $thelist[$file]['vers'] = $f[4]; $thelist[$file]['aweb'] = $f[5]; + + if ( preg_match('/^[a-z0-9]+_[a-z0-9_]+$/', $thelist[$file]['name']) ) + $thelist[$file]['name'] = $lang->get($thelist[$file]['name']); + + if ( preg_match('/^[a-z0-9]+_[a-z0-9_]+$/', $thelist[$file]['desc']) ) + $thelist[$file]['desc'] = $lang->get($thelist[$file]['desc']); + } } closedir($dh); } else { - echo '
The plugins/ directory could not be opened.
'; + echo '
' . $lang->get('acppl_err_open_dir') . '
'; return; } } else { - echo '
The plugins/ directory is missing from your Enano installation.
'; + echo '
' . $lang->get('acppl_err_missing_dir') . '
'; return; } echo('
- '); + + + + + + + + '); $plugin_files_1 = array_keys($plugin_list); $plugin_files_2 = array_keys($system); $plugin_files = array_values(array_merge($plugin_files_1, $plugin_files_2)); @@ -698,7 +1229,7 @@ { $cls = ( $cls == 'row2' ) ? 'row3' : 'row2'; $this_plugin = ( isset($system[$plugin_files[$i]]) ) ? $system[$plugin_files[$i]] : $plugin_list[$plugin_files[$i]]; - $is_system = ( $system[$plugin_files[$i]] ); + $is_system = ( @$system[$plugin_files[$i]] ); $bgcolor = ''; if ( $is_system && $cls == 'row2' ) $bgcolor = ' style="background-color: #FFD8D8;"'; @@ -715,521 +1246,180 @@ { if ( getConfig('plugin_'.$plugin_files[$i]) == '1' ) { - echo 'Disable'; + echo '' . $lang->get('acppl_btn_disable') . ''; } else { - echo 'Enable'; + echo '' . $lang->get('acppl_btn_enable') . ''; } } else { - echo '[System]'; + echo $lang->get('acppl_lbl_system_plugin'); } echo ''; } $showhide_link = ( $show_system ) ? - 'Hide system plugins' : - 'Show system plugins' ; + '' . $lang->get('acppl_btn_hide_system') . '' : + '' . $lang->get('acppl_btn_show_system') . '' ; echo ''; echo '
Plugin filenamePlugin nameDescriptionAuthorVersion
' . $lang->get('acppl_col_filename') . '' . $lang->get('acppl_col_name') . '' . $lang->get('acppl_col_description') . '' . $lang->get('acppl_col_author') . '' . $lang->get('acppl_col_version') . '
'.$showhide_link.'
'; } -function page_Admin_UploadAllowedMimeTypes() +function page_Admin_DBBackup() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; - return; - } - - global $mime_types, $mimetype_exps, $mimetype_extlist; - if(isset($_POST['save']) && !defined('ENANO_DEMO_MODE')) - { - $bits = ''; - $keys = array_keys($mime_types); - foreach($keys as $i => $k) - { - if(isset($_POST['ext_'.$k])) $bits .= '1'; - else $bits .= '0'; - } - $bits = compress_bitfield($bits); - setConfig('allowed_mime_types', $bits); - echo '
Your changes have been saved.
'; - } - else if ( isset($_POST['save']) && defined('ENANO_DEMO_MODE') ) - { - echo '
Hmm, enabling executables, are we? Tsk tsk. I\'d love to know what\'s in that EXE file you want to upload. OK, maybe you didn\'t enable EXEs. But nevertheless, changing allowed filetypes is disabled in the demo.
'; - } - $allowed = fetch_allowed_extensions(); - ?> -

Allowed file types

-

Using the form below, you can decide which file types are allowed to be uploaded to this site.

- nslist['Special'].'Administration', (( isset($_GET['sqldbg'])) ? 'sqldbg&' : '') .'module='.$paths->cpage['module']).'" method="post">'; - $c = -1; - $t = -1; - $cl = 'row1'; - echo "\n".'
'."\n".' '."\n".' '."\n "; - ksort($mime_types); - foreach($mime_types as $e => $m) - { - $c++; - $t++; - if($c == 3) - { - $c = 0; - $cl = ( $cl == 'row1' ) ? 'row2' : 'row1'; - echo ''."\n".' '."\n "; - } - $seed = "extchkbx_{$e}_".md5(microtime() . mt_rand()); - $chk = (!empty($allowed[$e])) ? ' checked="checked"' : ''; - echo " \n "; - } - while($c < 2) - { - $c++; - echo " \n "; - } - echo ''; - echo ''."\n".'
\n \n
'."\n".'
'; - echo ''; - ?> - auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) - { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; - return; - } - - ?> -

Editing and managing the Enano sidebar

-

The Enano sidebar is a versatile tool when scripted correctly. You don't have to be a programmer to enjoy the features the Sidebar - provides; however, editing the sidebar requires a small bit of programming knowledge and an understanding of Enano's system message - markup language. -

-

The Enano system markup language is somewhat similar to HTML, in that it uses tags (<example>like this</example>) for the - main syntax. However, Enano uses curly brackets ({ and }) as opposed to less-than and greater-than signs (< and >).

-

Programming the Enano sidebar requires the use of two tags: {slider} and {if}. The {slider} tag is used to create a new heading - on the sidebar, and all text enclosed in that tag will be collapsed when the heading is clicked. To specify the text on the heading, - use an equals sign (=) after the "slider" text. Then insert any links (they should be wiki-formatted) to internal Enano pages and - external sites.

-

So here is what the language for the default sidebar's "Navigation" heading looks like:

-
{slider=Navigation}
-  [[Main Page|Home]]
-  [[Enano:Sidebar|Edit the sidebar]]
-{/slider}
-

Pretty simple, huh? Good, now we're going to learn another common aspect of Enano programming: conditionals. The {if} tag allows you - to decide whether a portion of the sidebar will be displayed based on a template variable. Currently the only available conditions are - "user_logged_in" and "auth_admin", but more will be added soon. To use a conditional, enter {if conditional_name}, and then the - wiki-formatted text that you want to be under that condition, and then close the tag with {/if}. In the same way, you can reverse the - effect with {!if}. With {!if}, the closing tag is still {/if}, so keep that in mind. An {else} tag will be supported soon.

-

Now it's time for some real fun: variables. All template variables can be accessed from the sidebar. A variable is simply the - variable name, prefixed by a dollar sign ($). Some of the most common variables are $USERNAME, $SITE_NAME, $SITE_DESC, and $PAGE_NAME. - The sidebar also has some special variables that it uses for some of its links. The logout link can be added with $LOGOUT_LINK, and - the "change theme" button can be added with $STYLE_LINK.

-

So here is the Enano markup for the portion of the sidebar that contains the user tools:

-
{slider=$USERNAME}
-  [[User:$USERNAME|User page]]
-  [[Special:Contributions?user=$USERNAME|My Contributions]]
-  {if user_logged_in}
-    [[Special:Preferences|Preferences]]
-    $THEME_LINK
-  {/if}
-  {if auth_admin}
-    [[Special:Administration|Administration]]
-  {/if}
-  {if user_logged_in}
-    $LOGOUT_LINK
-  {/if}
-  {!if user_logged_in}
-    Create an account
-    Log in
-  {/if}
-{/slider}
- auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) - { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } - if(isset($_POST['do_create_stage1'])) + if ( ENANO_DBLAYER != 'MYSQL' ) + die('

' . $lang->get('acpdb_err_not_supported_title') . '

+

' . $lang->get('acpdb_err_not_supported_desc') . '

'); + + if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes' && defined('ENANO_DEMO_MODE') ) + { + redirect(makeUrlComplete('Special', 'Administration'), $lang->get('acpdb_err_demo_mode_title'), $lang->get('acpdb_err_demo_mode_desc'), 5); + } + + global $system_table_list; + if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes') { - if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name'])) - { - echo '

The group name you chose is invalid.

'; - return; - } - echo '
'; - echo '
- - - - - - - - - -
Creating group: '.$_POST['create_group_name'].'
Group moderator' . $template->username_field('group_mod') . '
Group status -
-
-
- -
- - -
-
'; - echo '
'; - return; - } - elseif(isset($_POST['do_create_stage2'])) - { - if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name'])) + + if(defined('SQL_BACKUP_CRYPT')) + // Try to increase our time limit + @set_time_limit(0); + // Do the actual export + $aesext = ( defined('SQL_BACKUP_CRYPT') ) ? '.tea' : ''; + $filename = 'enano_backup_' . enano_date('ymd') . '.sql' . $aesext; + ob_start(); + // Spew some headers + $headdate = enano_date('F d, Y \a\t h:i a'); + echo <<
username} + +HEADER; + // build the table list + $base = ( isset($_POST['do_system_tables']) ) ? $system_table_list : Array(); + $add = ( isset($_POST['additional_tables'])) ? $_POST['additional_tables'] : Array(); + $tables = array_merge($base, $add); + + // Log it! + $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'db_backup\', '.time().', \''.enano_date('d M Y h:i a').'\', \''.$db->escape($session->username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', \'' . $db->escape(implode(', ', $tables)) . '\')'); + if ( !$e ) + $db->_die(); + + foreach($tables as $i => $t) { - echo '

The group name you chose is invalid.

'; - return; - } - if(!in_array(intval($_POST['group_status']), Array(GROUP_CLOSED, GROUP_OPEN, GROUP_HIDDEN, GROUP_REQUEST))) - { - echo '

Hacking attempt

'; - return; - } - $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';'); - if(!$e) - { - echo $db->get_error(); - return; - } - if($db->numrows() > 0) - { - echo '

The group name you entered already exists.

'; - return; - } - $db->free_result(); - $q = $db->sql_query('INSERT INTO '.table_prefix.'groups(group_name,group_type) VALUES( \''.$db->escape($_POST['create_group_name']).'\', ' . intval($_POST['group_status']) . ' )'); - if(!$q) - { - echo $db->get_error(); - return; - } - $e = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['group_mod']).'\';'); - if(!$e) - { - echo $db->get_error(); - return; - } - if($db->numrows() < 1) - { - echo '

The username you entered could not be found.

'; - return; + if(!preg_match('#^([a-z0-9_]+)$#i', $t)) + die('Hacking attempt'); + // if($t == table_prefix.'files' && isset($_POST['do_data'])) + // unset($tables[$i]); } - $row = $db->fetchrow(); - $id = $row['user_id']; - $db->free_result(); - $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';'); - if(!$e) - { - echo $db->get_error(); - return; - } - if($db->numrows() < 1) - { - echo '

The group ID could not be looked up.

'; - return; - } - $row = $db->fetchrow(); - $gid = $row['group_id']; - $db->free_result(); - $e = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.$gid.', '.$id.', 1);'); - if(!$e) - { - echo $db->get_error(); - return; - } - echo "
- Information
- The group {$_POST['create_group_name']} has been created successfully. -
"; - } - if(isset($_POST['do_edit']) || isset($_POST['edit_do'])) - { - // Fetch the group name - $q = $db->sql_query('SELECT group_name,system_group FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';'); - if(!$q) + foreach($tables as $t) { - echo $db->get_error(); - return; - } - if($db->numrows() < 1) - { - echo '

Error: couldn\'t look up group name

'; - } - $row = $db->fetchrow(); - $name = $row['group_name']; - $db->free_result(); - if(isset($_POST['edit_do'])) - { - if(isset($_POST['edit_do']['del_group'])) - { - if ( $row['system_group'] == 1 ) - { - echo '
The group "' . $name . '" could not be deleted because it is a system group required for site functionality.
'; - } - else - { - $q = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE group_id='.intval($_POST['group_edit_id']).';'); - if(!$q) - { - echo $db->get_error(); - return; - } - $q = $db->sql_query('DELETE FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';'); - if(!$q) - { - echo $db->get_error(); - return; - } - echo '
The group "'.$name.'" has been deleted. Return to the group manager.
'; - return; - } - } - if(isset($_POST['edit_do']['save_name'])) + // THE FOLLOWING COMMENT DOES NOT APPLY AS OF 1.0. + // Sorry folks - this script CAN'T backup enano_files and enano_search_index due to the sheer size of the tables. + // If encryption is enabled the log data will be excluded too. + $result = export_table( + $t, + isset($_POST['do_struct']), + ( isset($_POST['do_data']) ), + false + ) . "\n"; + if ( !$result ) { - if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['group_name'])) - { - echo '

The group name you chose is invalid.

'; - return; - } - $q = $db->sql_query('UPDATE '.table_prefix.'groups SET group_name=\''.$db->escape($_POST['group_name']).'\' - WHERE group_id='.intval($_POST['group_edit_id']).';'); - if(!$q) - { - echo $db->get_error(); - return; - } - else - { - echo '
- The group name has been updated. -
'; - } - $name = $_POST['group_name']; - - } - $q = $db->sql_query('SELECT member_id FROM '.table_prefix.'group_members - WHERE group_id='.intval($_POST['group_edit_id']).';'); - if(!$q) - { - echo $db->get_error(); - return; + $db->_die(); } - if($db->numrows() > 0) - { - while($row = $db->fetchrow($q)) - { - if(isset($_POST['edit_do']['del_' . $row['member_id']])) - { - $e = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE member_id='.$row['member_id']); - if(!$e) - { - echo $db->get_error(); - return; - } - } - } - } - $db->free_result(); - if(isset($_POST['edit_do']['add_member'])) - { - $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['edit_add_username']).'\';'); - if(!$q) - { - echo $db->get_error(); - return; - } - if($db->numrows() > 0) - { - $row = $db->fetchrow(); - $user_id = $row['user_id']; - $is_mod = ( isset( $_POST['add_mod'] ) ) ? '1' : '0'; - $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.intval($_POST['group_edit_id']).','.$user_id.','.$is_mod.');'); - if(!$q) - { - echo $db->get_error(); - return; - } - else - { - echo '
- The user "'.$_POST['edit_add_username'].'" has been added to this usergroup. -
'; - } - } - else - echo '
The user "'.$_POST['edit_add_username'].'" could not be added.
This username does not exist.
'; - } + echo $result; } - $sg_disabled = ( $row['system_group'] == 1 ) ? ' value="Can\'t delete system group" disabled="disabled" style="color: #FF9773" ' : ' value="Delete this group" style="color: #FF3713" '; - echo '
'; - echo '
- - - - - - - - -
Edit group name
- Group name: -
- - -
-
- '; - echo '
'; - echo '
'; - echo '
- - '; - $q = $db->sql_query('SELECT m.member_id,m.is_mod,u.username FROM '.table_prefix.'group_members AS m - LEFT JOIN '.table_prefix.'users AS u - ON u.user_id=m.user_id - WHERE m.group_id='.intval($_POST['group_edit_id']).' - ORDER BY m.is_mod DESC, u.username ASC;'); - if(!$q) - { - echo $db->get_error(); - return; - } - if($db->numrows() < 1) - { - echo ''; - } - else + $data = ob_get_contents(); + ob_end_clean(); + if(defined('SQL_BACKUP_CRYPT')) { - $cls = 'row2'; - while($row = $db->fetchrow()) - { - $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; - $mod = ( $row['is_mod'] == 1 ) ? 'Mod' : ''; - echo ' - - - - '; - } + // Free some memory, we don't need this stuff any more + $db->close(); + unset($paths, $db, $template, $plugins); + $tea = new TEACrypt(); + $data = $tea->encrypt($data, $session->private_key); } - $db->free_result(); - echo '
Edit group members
This group has no members.
- ' . $row['username'] . ' - - '.$mod.' - - -
-
- '; - echo '
'; - echo '
'; - echo '
- - - - - - - - - - - - - -
Add a new member
- Username: ' . $template->username_field('edit_add_username') . ' -
- (can add and delete other members) -
- -
-
- '; - echo '
'; - return; - } - echo '

Manage Usergroups

'; - echo '
'; - $q = $db->sql_query('SELECT group_id,group_name FROM '.table_prefix.'groups ORDER BY group_name ASC;'); - if(!$q) - { - echo $db->get_error(); + header('Content-disposition: attachment; filename='.$filename.''); + header('Content-type: application/octet-stream'); + header('Content-length: '.strlen($data)); + echo $data; + exit; } else { - echo '
- - - - '; - echo ''; - echo ' -
Edit an existing group
-
-

'; + // Show the UI + echo '
'; + ?> +

get('acpdb_intro'); ?>

+

+

get('acpdb_lbl_additional_tables'); ?>

+

+

+


+ +

+

+ '; } - echo ''; - echo '
- - - - '; - echo ''; - echo ' -
Create a new group
Group name:
-
'; - echo '
'; } +/* + * Admin:PageManager sources are in /plugins/admin/PageManager.php. + */ + +/* + * Admin:PageEditor sources are in /plugins/admin/PageEditor.php. + */ + +/* + * Admin:ThemeManager sources are in /plugins/admin/ThemeManager.php. + */ + +/* + * Admin:GroupManager sources are in /plugins/admin/GroupManager.php. + */ + function page_Admin_COPPA() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } - echo '

Background information

'; + echo '

' . $lang->get('acpcp_heading_main') . '

'; echo '

- The United States Childrens\' Online Privacy Protection Act (COPPA) was a law passed in 2001 that requires sites oriented towards - children under 13 years old or with a significant amount of under-13 children clearly state what information is being collected - in a privacy policy and obtain authorization from a parent or legal guardian before allowing children to use the site. Enano - provides an easy way to allow you, as the website administrator, to obtain this authorization. + ' . $lang->get('acpcp_intro') . '

'; // Start form @@ -1243,33 +1433,33 @@ $address = $_POST['coppa_address']; // RenderMan::preprocess_text($_POST['coppa_address'], true, false); setConfig('coppa_address', $address); - echo '
Your changes have been saved.
'; + echo '
' . $lang->get('acpcp_msg_save_success') . '
'; } - echo '
'; + acp_start_form(); echo '
'; echo ''; echo ''; echo ''; echo ''; @@ -1288,680 +1478,15 @@ } -function page_Admin_PageManager() -{ - global $db, $session, $paths, $template, $plugins; // Common objects - if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) - { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; - return; - } - - - echo '

Page management

'; - - if(isset($_POST['search']) || isset($_POST['select']) || ( isset($_GET['source']) && $_GET['source'] == 'ajax' )) { - // The object of the game: using only the text a user entered, guess the page ID and namespace. *sigh* I HATE writing search algorithms... - $source = ( isset($_GET['source']) ) ? $_GET['source'] : false; - if ( $source == 'ajax' ) - { - $_POST['search'] = true; - $_POST['page_url'] = $_GET['page_id']; - } - if(isset($_POST['search'])) $pid = $_POST['page_url']; - elseif(isset($_POST['select'])) $pid = $_POST['page_force_url']; - else { echo 'Internal error selecting page search terms'; return false; } - // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary - $k = array_keys($paths->nslist); - for($i=0;$inslist);$i++) - { - $ln = strlen($paths->nslist[$k[$i]]); - if(substr($pid, 0, $ln) == $paths->nslist[$k[$i]]) - { - $ns = $k[$i]; - $page_id = substr($pid, $ln, strlen($pid)); - } - } - // The namespace is in $ns and the page name or ID (we don't know which yet) is in $page_id - // Now, iterate through $paths->pages searching for a page with this name or ID - for($i=0;$ipages)/2;$i++) - { - if(!isset($final_pid)) - { - if ($paths->pages[$i]['urlname_nons'] == str_replace(' ', '_', $page_id)) $final_pid = str_replace(' ', '_', $page_id); - elseif($paths->pages[$i]['name'] == $page_id) $final_pid = $paths->pages[$i]['urlname_nons']; - elseif(strtolower($paths->pages[$i]['urlname_nons']) == strtolower(str_replace(' ', '_', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons']; - elseif(strtolower($paths->pages[$i]['name']) == strtolower(str_replace('_', ' ', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons']; - if(isset($final_pid)) { $_POST['name'] = $paths->pages[$i]['name']; $_POST['urlname'] = $paths->pages[$i]['urlname_nons']; } - } - } - if(!isset($final_pid)) { echo 'The page you searched for cannot be found. Back'; return false; } - $_POST['namespace'] = $ns; - $_POST['old_namespace'] = $ns; - $_POST['page_id'] = $final_pid; - $_POST['old_page_id'] = $final_pid; - if(!isset($paths->pages[$paths->nslist[$_POST['namespace']].$_POST['urlname']])) { echo 'The page you searched for cannot be found. Back'; return false; } - } - - if(isset($_POST['page_id']) && isset($_POST['namespace']) && !isset($_POST['cancel'])) - { - $cpage = $paths->pages[$paths->nslist[$_POST['old_namespace']].$_POST['old_page_id']]; - if(isset($_POST['submit'])) - { - switch(true) - { - case true: - // Create a list of things to update - $page_info = Array( - 'name'=>$_POST['name'], - 'urlname'=>sanitize_page_id($_POST['page_id']), - 'namespace'=>$_POST['namespace'], - 'special'=>isset($_POST['special']) ? '1' : '0', - 'visible'=>isset($_POST['visible']) ? '1' : '0', - 'comments_on'=>isset($_POST['comments_on']) ? '1' : '0', - 'protected'=>isset($_POST['protected']) ? '1' : '0' - ); - - $updating_urlname_or_namespace = ( $page_info['namespace'] != $cpage['namespace'] || $page_info['urlname'] != $cpage['urlname_nons'] ); - - if ( !isset($paths->nslist[ $page_info['namespace'] ]) ) - { - echo '
The namespace you selected is not properly registered.
'; - break; - } - if ( isset($paths->pages[ $paths->nslist[$page_info['namespace']] . $page_info[ 'urlname' ] ]) && $updating_urlname_or_namespace ) - { - echo '
There is already a page that exists with that URL string and namespace.
'; - break; - } - // Build the query - $q = 'UPDATE '.table_prefix.'pages SET '; - $k = array_keys($page_info); - foreach($k as $c) - { - $q .= $c.'=\''.$db->escape($page_info[$c]).'\','; - } - $q = substr($q, 0, strlen($q)-1); - // Build the WHERE statements - $q .= ' WHERE '; - $k = array_keys($cpage); - if ( !isset($cpage) ) - die('[internal] no cpage'); - foreach($k as $c) - { - if($c != 'urlname_nons' && $c != 'urlname' && $c != 'really_protected') - { - $q .= $c.'=\''.$db->escape($cpage[$c]).'\' AND '; - } - else if($c == 'urlname') - { - $q .= $c.'=\''.$db->escape($cpage['urlname_nons']).'\' AND '; - } - } - // Trim off the last " AND " and append a semicolon - $q = substr($q, 0, strlen($q)-5) . ';'; - // Send the completed query to MySQL - $e = $db->sql_query($q); - if(!$e) $db->_die('The page data could not be updated.'); - // Update any additional tables - $q = Array( - 'UPDATE '.table_prefix.'categories SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', - 'UPDATE '.table_prefix.'comments SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', - 'UPDATE '.table_prefix.'logs SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', - 'UPDATE '.table_prefix.'page_text SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', - 'UPDATE '.table_prefix.'acl SET page_id=\''.$page_info['urlname'].'\',namespace=\''.$page_info['namespace'].'\' WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';' - ); - foreach($q as $cq) - { - $e = $db->sql_query($cq); - if(!$e) $db->_die('Some of the additional tables containing page information could not be updated.'); - } - // Update $cpage - $cpage = $page_info; - $cpage['urlname_nons'] = $cpage['urlname']; - $cpage['urlname'] = $paths->nslist[$cpage['namespace']].$cpage['urlname']; - $_POST['old_page_id'] = $page_info['urlname']; - $_POST['old_namespace'] = $page_info['namespace']; - echo '
Your changes have been saved.
'; - break; - } - } elseif(isset($_POST['delete'])) { - $q = Array( - 'DELETE FROM '.table_prefix.'categories WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', - 'DELETE FROM '.table_prefix.'comments WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', - 'DELETE FROM '.table_prefix.'logs WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', - 'DELETE FROM '.table_prefix.'page_text WHERE page_id=\'' . $db->escape($_POST['old_page_id']) . '\' AND namespace=\'' . $db->escape($_POST['old_namespace']) . '\';', - ); - foreach($q as $cq) - { - $e = $db->sql_query($cq); - if(!$e) $db->_die('Some of the additional tables containing page information could not be updated.'); - } - - if(!$db->sql_query( - 'DELETE FROM '.table_prefix.'pages WHERE urlname="'.$db->escape($_POST['old_page_id']).'" AND namespace="'.$db->escape($_POST['old_namespace']).'";' - )) $db->_die('The page could not be deleted.'); - echo '
This page has been deleted.

Return to Page manager
Admin home

'; - return; - } - $url = makeUrlNS('Special', 'Administration', 'module='.$paths->cpage['module'], true); - echo ''; - ?> -

Modify page:

-
- COPPA support + ' . $lang->get('acpcp_th_form') . '
- Enable COPPA support: + ' . $lang->get('acpcp_field_enable_title') . ' -
- If this is checked, users will be asked if they are under 13 years of age before registering +
+ ' . $lang->get('acpcp_field_enable_hint') . '
- Your mailing address:
- This is the address to which parents will send authorization forms. + ' . $lang->get('acpcp_field_address') . '
+ ' . $lang->get('acpcp_field_address_hint') . '
@@ -1278,7 +1468,7 @@ echo '
- +
- - - - - - - - - - -
Namespace:
Page title:
Page URL string:
No spaces, and don't enter the namespace prefix (e.g. User:).
Changing this value is usually not a good idea, especially for templates and project pages.
name="comments_on" type="checkbox" id="cmt" />
name="special" type="checkbox" id="spc" />
This option enables you to use your own HTML headers and other code. It is recommended that only advanced users enable this feature. As with other Enano pages, you may use PHP code in your pages, meaning you can use Enano's API on the page.
name="visible" type="checkbox" id="vis" />
Unchecking this checkbox prevents the page for being indexed for searching. The index is rebuilt each time a page is saved, and you can force an index rebuild by going to the page nslist['Special']; ?>SearchRebuild.
name="protected" type="checkbox" id="prt" />
This option only has an effect when Wiki Mode is enabled.

- - -
- '; - } else { - echo '

Please select a page

'; - echo ''; - ?> -

Search for page title (remember prefixes like User: and File:) pagename_field('page_url'); ?>

-

Select page title from a list:

- '; - - } -} - -function page_Admin_PageEditor() -{ - global $db, $session, $paths, $template, $plugins; // Common objects - if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) - { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; - return; - } - - - echo '

Edit page content

'; - - if(isset($_POST['search']) || isset($_POST['select'])) { - // The object of the game: using only the text a user entered, guess the page ID and namespace. *sigh* I HATE writing search algorithms... - if(isset($_POST['search'])) $pid = $_POST['page_url']; - elseif(isset($_POST['select'])) $pid = $_POST['page_force_url']; - else { echo 'Internal error selecting page search terms'; return false; } - // Look for a namespace prefix in the urlname, and assign a different namespace, if necessary - $k = array_keys($paths->nslist); - for($i=0;$inslist);$i++) - { - $ln = strlen($paths->nslist[$k[$i]]); - if(substr($pid, 0, $ln) == $paths->nslist[$k[$i]]) - { - $ns = $k[$i]; - $page_id = substr($pid, $ln, strlen($pid)); - } - } - // The namespace is in $ns and the page name or ID (we don't know which yet) is in $page_id - // Now, iterate through $paths->pages searching for a page with this name or ID - for($i=0;$ipages)/2;$i++) - { - if(!isset($final_pid)) - { - if ($paths->pages[$i]['urlname_nons'] == str_replace(' ', '_', $page_id)) $final_pid = str_replace(' ', '_', $page_id); - elseif($paths->pages[$i]['name'] == $page_id) $final_pid = $paths->pages[$i]['urlname_nons']; - elseif(strtolower($paths->pages[$i]['urlname_nons']) == strtolower(str_replace(' ', '_', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons']; - elseif(strtolower($paths->pages[$i]['name']) == strtolower(str_replace('_', ' ', $page_id))) $final_pid = $paths->pages[$i]['urlname_nons']; - if(isset($final_pid)) { $_POST['name'] = $paths->pages[$i]['name']; $_POST['urlname'] = $paths->pages[$i]['urlname_nons']; } - } - } - if(!isset($final_pid)) { echo 'The page you searched for cannot be found. Back'; return false; } - $_POST['namespace'] = $ns; - $_POST['page_id'] = $final_pid; - if(!isset($paths->pages[$paths->nslist[$_POST['namespace']].$_POST['urlname']])) { echo 'The page you searched for cannot be found. Back'; return false; } - } - - if(isset($_POST['page_id']) && !isset($_POST['cancel'])) - { - echo ''; - if(!isset($_POST['content']) || isset($_POST['revert'])) $content = RenderMan::getPage($_POST['page_id'], $_POST['namespace'], 0, false, false, false, false); - else $content = $_POST['content']; - if(isset($_POST['save'])) - { - $data = $content; - $id = md5( microtime() . mt_rand() ); - - $minor = isset($_POST['minor']) ? 'true' : 'false'; - $q='INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,page_id,namespace,page_text,char_tag,author,edit_summary,minor_edit) VALUES(\'page\', \'edit\', '.time().', \''.date('d M Y h:i a').'\', \'' . $db->escape($_POST['page_id']) . '\', \'' . $db->escape($_POST['namespace']) . '\', \''.$db->escape($data).'\', \''.$id.'\', \''.$session->username.'\', \''.$db->escape(htmlspecialchars($_POST['summary'])).'\', '.$minor.');'; - if(!$db->sql_query($q)) $db->_die('The history (log) entry could not be inserted into the logs table.'); - - $query = 'UPDATE '.table_prefix.'page_text SET page_text=\''.$db->escape($data).'\',char_tag=\''.$id.'\' WHERE page_id=\'' . $db->escape($_POST['page_id']) . '\' AND namespace=\'' . $db->escape($_POST['namespace']) . '\';'; - $e = $db->sql_query($query); - if(!$e) echo '
The page data could not be saved. MySQL said: '.mysql_error().'

Query:
'.$query.'
'; - else echo '
Your page has been saved. View page...
'; - } elseif(isset($_POST['preview'])) { - echo '

Preview

Reminder: This is only a preview; your changes to this page have not yet been saved.

'.RenderMan::render($content).'
'; - } - ?> -

-
- Edit summary:
- -

-

- - -        -

- '; - } else { - echo '

Please select a page

'; - echo ''; - ?> -

Search for page title (remember prefixes like User: and File:) pagename_field('page_url'); ?>

-

Select page title from a list:

- '; - } -} - -function page_Admin_ThemeManager() -{ - - global $db, $session, $paths, $template, $plugins; // Common objects - if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) - { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; - return; - } - - - // Get the list of styles in the themes/ dir - $h = opendir('./themes'); - $l = Array(); - if(!$h) die('Error opening directory "./themes" for reading.'); - while(false !== ($n = readdir($h))) { - if($n != '.' && $n != '..' && is_dir('./themes/'.$n)) - $l[] = $n; - } - closedir($h); - echo(' -

Theme Management

-

Install, uninstall, and manage Enano themes.

- '); - if(isset($_POST['disenable'])) { - $q = 'SELECT enabled FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\''; - $s = $db->sql_query($q); - if(!$s) die('Error selecting enabled/disabled state value: '.mysql_error().'
SQL:
'.$q); - $r = $db->fetchrow_num($s); - $db->free_result(); - if($r[0] == 1) $e = 0; - else $e = 1; - $s=true; - if($e==0) - { - $c = $db->sql_query('SELECT * FROM '.table_prefix.'themes WHERE enabled=1'); - if(!$c) $db->_die('The backup check for having at least on theme enabled failed.'); - if($db->numrows() <= 1) { echo '
You cannot disable the last remaining theme.
'; $s=false; } - } - $db->free_result(); - if($s) { - $q = 'UPDATE '.table_prefix.'themes SET enabled='.$e.' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\''; - $a = $db->sql_query($q); - if(!$a) die('Error updating enabled/disabled state value: '.mysql_error().'
SQL:
'.$q); - else echo('
The theme "'.$_POST['theme_id'].'" has been '. ( ( $e == '1' ) ? 'enabled' : 'disabled' ).'.
'); - } - } - elseif(isset($_POST['edit'])) { - - $dir = './themes/'.$_POST['theme_id'].'/css/'; - $list = Array(); - // Open a known directory, and proceed to read its contents - if (is_dir($dir)) { - if ($dh = opendir($dir)) { - while (($file = readdir($dh)) !== false) { - if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') { - $list[$file] = capitalize_first_letter(substr($file, 0, strlen($file)-4)); - } - } - closedir($dh); - } - } - $lk = array_keys($list); - - $q = 'SELECT theme_name,default_style FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\''; - $s = $db->sql_query($q); - if(!$s) die('Error selecting name value: '.mysql_error().'
SQL:
'.$q); - $r = $db->fetchrow_num($s); - $db->free_result(); - echo(''); - echo('
- Theme name displayed to users:

- Default stylesheet:

- -
'); - echo(''); - } - elseif(isset($_POST['editsave'])) { - $q = 'UPDATE '.table_prefix.'themes SET theme_name=\'' . $db->escape($_POST['name']) . '\',default_style=\''.$db->escape($_POST['defaultcss']).'\' WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\''; - $s = $db->sql_query($q); - if(!$s) die('Error updating name value: '.mysql_error().'
SQL:
'.$q); - else echo('
Theme data updated.
'); - } - elseif(isset($_POST['up'])) { - // If there is only one theme or if the selected theme is already at the top, do nothing - $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;'; - $s = $db->sql_query($q); - if(!$s) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); - $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\''; - $sn = $db->sql_query($q); - if(!$sn) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); - $r = $db->fetchrow_num($sn); - if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == 1 /* ...and check if this theme is already at the top */ ) { echo('
This theme is already at the top of the list, or there is only one theme installed.
'); } else { - // Get the order IDs of the selected theme and the theme before it - $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\'' . $db->escape($_POST['theme_id']) . '\''; - $s = $db->sql_query($q); - if(!$s) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); - $r = $db->fetchrow_num($s); - $r = $r[0]; - $rb = $r - 1; - // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;) - $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.''; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); - $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); - $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0'; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); - echo('
Theme moved up.
'); - } - $db->free_result($s); - $db->free_result($sn); - } - elseif(isset($_POST['down'])) { - // If there is only one theme or if the selected theme is already at the top, do nothing - $q = 'SELECT theme_order FROM '.table_prefix.'themes ORDER BY theme_order;'; - $s = $db->sql_query($q); - if(!$s) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); - $r = $db->fetchrow_num($s); - if( /* check for only one theme... */ $db->numrows($s) < 2 || $r[0] == $db->numrows($s) /* ...and check if this theme is already at the bottom */ ) { echo('
This theme is already at the bottom of the list, or there is only one theme installed.
'); } else { - // Get the order IDs of the selected theme and the theme before it - $q = 'SELECT theme_order FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\''; - $s = $db->sql_query($q); - if(!$s) die('Error selecting order information: '.mysql_error().'
SQL:
'.$q); - $r = $db->fetchrow_num($s); - $r = $r[0]; - $rb = $r + 1; - // Thank God for jEdit's rectangular selection and the ablity to edit multiple lines at the same time ;) - $q = 'UPDATE '.table_prefix.'themes SET theme_order=0 WHERE theme_order='.$rb.''; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); - $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$rb.' WHERE theme_order='.$r.''; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); - $q = 'UPDATE '.table_prefix.'themes SET theme_order='.$r.' WHERE theme_order=0'; /* Check for errors... */ $s = $db->sql_query($q); if(!$s) die('Error updating order information: '.mysql_error().'
SQL:
'.$q); - echo('
Theme moved down.
'); - } - } - else if(isset($_POST['uninstall'])) - { - $q = 'SELECT * FROM '.table_prefix.'themes;'; - $s = $db->sql_query($q); - if ( !$s ) - { - die('Error getting theme count: '.mysql_error().'
SQL:
'.$q); - } - $n = $db->numrows($s); - $db->free_result(); - - if ( $_POST['theme_id'] == 'oxygen' ) - { - echo '
The Oxygen theme is used by Enano for installation, upgrades, and error messages, and cannot be uninstalled.
'; - } - else - { - if($n < 2) - { - echo '
The theme could not be uninstalled because it is the only theme left.
'; - } - else - { - $q = 'DELETE FROM '.table_prefix.'themes WHERE theme_id=\''.$db->escape($_POST['theme_id']).'\' LIMIT 1;'; - $s = $db->sql_query($q); - if ( !$s ) - { - die('Error deleting theme data: '.mysql_error().'
SQL:
'.$q); - } - else - { - echo('
Theme uninstalled.
'); - } - } - } - } - elseif(isset($_POST['install'])) { - $q = 'SELECT theme_id FROM '.table_prefix.'themes;'; - $s = $db->sql_query($q); - if(!$s) die('Error getting theme count: '.mysql_error().'
SQL:
'.$q); - $n = $db->numrows($s); - $n++; - $theme_id = $_POST['theme_id']; - $theme = Array(); - include('./themes/'.$theme_id.'/theme.cfg'); - if ( !isset($theme['theme_id']) ) - { - echo '
Could not load theme.cfg (theme metadata file)
'; - } - else - { - $default_style = false; - if ( $dh = opendir('./themes/' . $theme_id . '/css') ) - { - while ( $file = readdir($dh) ) - { - if ( $file != '_printable.css' && preg_match('/\.css$/i', $file) ) - { - $default_style = $file; - break; - } - } - closedir($dh); - } - else - { - die('The /css subdirectory could not be located in the theme\'s directory'); - } - - if ( $default_style ) - { - $q = 'INSERT INTO '.table_prefix.'themes(theme_id,theme_name,theme_order,enabled,default_style) VALUES(\''.$db->escape($theme['theme_id']).'\', \''.$db->escape($theme['theme_name']).'\', '.$n.', 1, \'' . $db->escape($default_style) . '\')'; - $s = $db->sql_query($q); - if(!$s) die('Error inserting theme data: '.mysql_error().'
SQL:
'.$q); - else echo('
Theme "'.$theme['theme_name'].'" installed.
'); - } - else - { - echo '
Could not determine the default style for the theme.
'; - } - } - } - echo(' -

Currently installed themes

-
-

- -

-
-

Install a new theme

- '); - $theme = Array(); - $obb = ''; - for($i=0;$isql_query($q); - if(!$s) die('Error selecting list of currently installed themes: '.mysql_error().'
Attempted SQL:
'.$q); - if($db->numrows($s) < 1) { - $obb .= ''; - } - $db->free_result(); - } - } - if($obb != '') { - echo('

'); - echo(''); - echo(' - -

'); - } else echo('

All themes are currently installed.

'); -} - -function page_Admin_BanControl() -{ - global $db, $session, $paths, $template, $plugins; // Common objects - if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) - { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; - return; - } - - if(isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['id']) && $_GET['id'] != '') - { - $e = $db->sql_query('DELETE FROM '.table_prefix.'banlist WHERE ban_id=' . $db->escape($_GET['id']) . ''); - if(!$e) $db->_die('The ban list entry was not deleted.'); - } - if(isset($_POST['create']) && !defined('ENANO_DEMO_MODE')) - { - $type = intval($_POST['type']); - $value = trim($_POST['value']); - if ( !in_array($type, array(BAN_IP, BAN_USER, BAN_EMAIL)) ) - { - echo '
Hacking attempt.
'; - } - else if ( empty($value) ) - { - echo '
Please enter something to ban.
'; - } - else - { - $entries = array(); - $input = explode(',', $_POST['value']); - $error = false; - foreach ( $input as $entry ) - { - $entry = trim($entry); - if ( empty($entry) ) - { - echo '
Malformed entry.
'; - $error = true; - break; - } - if ( $type == BAN_IP ) - { - if ( !isset($_POST['regex']) ) - { - // as of 1.0.2 parsing is done at runtime - $entries[] = $entry; - } - else - { - $entries[] = $entry; - } - } - else - { - $entries[] = $entry; - } - } - if ( !$error ) - { - $regex = ( isset($_POST['regex']) ) ? '1' : '0'; - $to_insert = array(); - $reason = $db->escape($_POST['reason']); - foreach ( $entries as $entry ) - { - $entry = $db->escape($entry); - $to_insert[] = "($type, '$entry', '$reason', $regex)"; - } - $q = 'INSERT INTO '.table_prefix."banlist(ban_type, ban_value, reason, is_regex)\n VALUES" . implode(",\n ", $to_insert) . ';'; - @set_time_limit(0); - $e = $db->sql_query($q); - if(!$e) $db->_die('The banlist could not be updated.'); - } - } - } - else if ( isset($_POST['create']) && defined('ENANO_DEMO_MODE') ) - { - echo '
This function is disabled in the demo. Just because you don\'t like ' . htmlspecialchars($_POST['value']) . ' doesn\'t mean we don\'t like ' . htmlspecialchars($_POST['value']) . '.
'; - } - $q = $db->sql_query('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;'); - if(!$q) $db->_die('The banlist data could not be selected.'); - echo '
- '; - echo ''; - if($db->numrows() < 1) echo ''; - $cls = 'row2'; - while($r = $db->fetchrow()) - { - $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; - if($r['ban_type']==BAN_IP) $t = 'IP address'; - elseif($r['ban_type']==BAN_USER) $t = 'Username'; - elseif($r['ban_type']==BAN_EMAIL) $t = 'E-mail address'; - if($r['is_regex']) $g = 'Yes'; else $g = 'No'; - echo ''; - } - $db->free_result(); - echo '
TypeValueRegular Expression
No ban rules yet.
'.$t.''.$r['ban_value'].''.$g.'Delete
'; - echo '

Create new ban rule

'; - echo '
'; - ?> - Type:
- Rule:
- You can ban multiple IP addresses, users, or e-mail addresses by separating entries with a single comma (User1,User2). Do not put a space after the comma. For IP addresses, you may specify ranges like 172|192.168.4-30|90-167.1-90, which will turn into 172 and 192 . 168 . 4-30 and 90-167 . 1 - 90, which matches 18,899 IP addresses.
- Reason to show to the banned user:
- (advanced users only)
- - '; -} - function page_Admin_MassEmail() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } @@ -1991,9 +1516,9 @@ $message = stripslashes(trim($_POST['message'])); if ( empty($subject) ) - $errors[] = 'Please enter a subject.'; + $errors[] = $lang->get('acpmm_err_need_subject'); if ( empty($message) ) - $errors[] = 'Please enter a message.'; + $errors[] = $lang->get('acpmm_err_need_message'); // Get list of members if ( !empty($_POST['userlist']) ) @@ -2073,6 +1598,7 @@ $mail->extra_headers($email_headers); + // FIXME: how to handle l10n with this? $tpl = 'The following message was mass-mailed by {SENDER}, one of the administrators from {SITE_NAME}. If this message contains spam or any comments which you find abusive or offensive, please contact the administration team at: {CONTACT_EMAIL} @@ -2096,32 +1622,31 @@ $mail->send(); $mail->reset(); - echo '
Your message has been sent.
'; + echo '
' . $lang->get('acpmm_msg_send_success') . '
'; } else { - echo '
Could not send message for the following reason(s):
  • ' . implode('
  • ', $errors) . '
'; + echo '
' . $lang->get('acpmm_err_send_fail') . '
  • ' . implode('
  • ', $errors) . '
'; } } else if ( isset($_POST['do_send']) && defined('ENANO_DEMO_MODE') ) { - echo '
This function is disabled in the demo. You think demo@enanocms.org likes getting "test" mass e-mails?
'; + echo '
' . $lang->get('acpmm_err_demo') . '
'; } - echo ''; + acp_start_form(); ?>
- + @@ -2172,142 +1703,171 @@ echo ''; } -function page_Admin_DBBackup() +function page_Admin_BanControl() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } - if ( ENANO_DBLAYER != 'MYSQL' ) - die('

Not supported

-

This function is only supported under the MySQL database driver.

'); - - if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes' && defined('ENANO_DEMO_MODE') ) + if(isset($_GET['action']) && $_GET['action'] == 'delete' && isset($_GET['id']) && $_GET['id'] != '') { - redirect(makeUrlComplete('Special', 'Administration'), 'Access denied', 'You\'ve got to be kidding me. Forget it, kid.', 4 ); + $e = $db->sql_query('DELETE FROM '.table_prefix.'banlist WHERE ban_id=' . intval($_GET['id']) . ''); + if ( !$e ) + $db->_die('The ban list entry was not deleted.'); } - - global $system_table_list; - if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes') + if(isset($_POST['create']) && !defined('ENANO_DEMO_MODE')) { - - if(defined('SQL_BACKUP_CRYPT')) - // Try to increase our time limit - @set_time_limit(0); - // Do the actual export - $aesext = ( defined('SQL_BACKUP_CRYPT') ) ? '.tea' : ''; - $filename = 'enano_backup_' . date('ymd') . '.sql' . $aesext; - ob_start(); - // Spew some headers - $headdate = date('F d, Y \a\t h:i a'); - echo <<
username} - -HEADER; - // build the table list - $base = ( isset($_POST['do_system_tables']) ) ? $system_table_list : Array(); - $add = ( isset($_POST['additional_tables'])) ? $_POST['additional_tables'] : Array(); - $tables = array_merge($base, $add); - - // Log it! - $e = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'db_backup\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($session->username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', \'' . $db->escape(implode(', ', $tables)) . '\')'); - if ( !$e ) - $db->_die(); - - foreach($tables as $i => $t) + $type = intval($_POST['type']); + $value = trim($_POST['value']); + if ( !in_array($type, array(BAN_IP, BAN_USER, BAN_EMAIL)) ) { - if(!preg_match('#^([a-z0-9_]+)$#i', $t)) - die('Hacking attempt'); - // if($t == table_prefix.'files' && isset($_POST['do_data'])) - // unset($tables[$i]); + echo '
Hacking attempt.
'; } - foreach($tables as $t) + else if ( empty($value) ) + { + echo '
' . $lang->get('acpbc_err_empty') . '
'; + } + else { - // THE FOLLOWING COMMENT DOES NOT APPLY AS OF 1.0. - // Sorry folks - this script CAN'T backup enano_files and enano_search_index due to the sheer size of the tables. - // If encryption is enabled the log data will be excluded too. - $result = export_table( - $t, - isset($_POST['do_struct']), - ( isset($_POST['do_data']) ), - false - ) . "\n"; - if ( !$result ) + $entries = array(); + $input = explode(',', $_POST['value']); + $error = false; + foreach ( $input as $entry ) { - $db->_die(); + $entry = trim($entry); + if ( empty($entry) ) + { + echo '
' . $lang->get('acpbc_err_invalid_ip_range') . '
'; + $error = true; + break; + } + if ( $type == BAN_IP ) + { + if ( !isset($_POST['regex']) ) + { + // as of 1.0.2 parsing is done at runtime + $entries[] = $entry; + } + else + { + $entries[] = $entry; + } + } + else + { + $entries[] = $entry; + } } - echo $result; + if ( !$error ) + { + $regex = ( isset($_POST['regex']) ) ? '1' : '0'; + $to_insert = array(); + $reason = $db->escape($_POST['reason']); + foreach ( $entries as $entry ) + { + $entry = $db->escape($entry); + $to_insert[] = "($type, '$entry', '$reason', $regex)"; + } + $q = 'INSERT INTO '.table_prefix."banlist(ban_type, ban_value, reason, is_regex)\n VALUES" . implode(",\n ", $to_insert) . ';'; + @set_time_limit(0); + $e = $db->sql_query($q); + if(!$e) $db->_die('The banlist could not be updated.'); + } } - $data = ob_get_contents(); - ob_end_clean(); - if(defined('SQL_BACKUP_CRYPT')) - { - // Free some memory, we don't need this stuff any more - $db->close(); - unset($paths, $db, $template, $plugins); - $tea = new TEACrypt(); - $data = $tea->encrypt($data, $session->private_key); - } - header('Content-disposition: attachment, filename="'.$filename.'";'); - header('Content-type: application/transact-sql'); - header('Content-length: '.strlen($data)); - echo $data; - exit; + } + else if ( isset($_POST['create']) && defined('ENANO_DEMO_MODE') ) + { + echo '
' . $lang->get('acpbc_err_demo', array('ban_target' => htmlspecialchars($_POST['value']))) . '
'; } - else + $q = $db->sql_query('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;'); + if ( !$q ) + $db->_die('The banlist data could not be selected.'); + echo '
+
Send mass e-mailget('acpmm_heading_main'); ?>
- Send message to:
+ get('acpmm_field_group_to'); ?>
- By default, this message will be sent to the group selected here. You may instead send the message to a specific - list of users by entering them in the second row, with usernames separated by a single comma (no space). + get('acpmm_field_group_to_hint'); ?>
@@ -2132,7 +1657,13 @@ $db->_die(); while ( $row = $db->fetchrow() ) { - echo ''; + list($g_name) = array_values($row); + $g_name_langstr = 'groupcp_grp_' . strtolower($g_name); + if ( ($g_langstr = $lang->get($g_name_langstr)) != $g_name_langstr ) + { + $g_name = $g_langstr; + } + echo ''; } ?> @@ -2140,12 +1671,12 @@
- Usernames: + get('acpmm_field_username'); ?>
- Subject: + get('acpmm_field_subject'); ?> @@ -2153,7 +1684,7 @@
- Message: + get('acpmm_field_message'); ?> @@ -2161,8 +1692,8 @@
-
- Please be warned: it may take a LONG time to send this message. Please do not stop the script until the process is finished. +
+ get('acpmm_msg_send_takeawhile'); ?>
'; + echo ' + + + + + '; + if ( $db->numrows() < 1 ) + { + echo ''; + } + $cls = 'row2'; + while ( $r = $db->fetchrow() ) { - // Show the UI - echo ''; - ?> -

This page allows you to back up your Enano database should something go miserably wrong.

-

-

Additional tables to export:

-

-

-


- -

-

- '; + $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; + if ( $r['ban_type'] == BAN_IP ) + $t = $lang->get('acpbc_ban_type_ip'); + else if ( $r['ban_type'] == BAN_USER ) + $t = $lang->get('acpbc_ban_type_username'); + else if ( $r['ban_type'] == BAN_EMAIL ) + $t = $lang->get('acpbc_ban_type_email'); + $g = ( $r['is_regex'] ) ? '' . $lang->get('acpbc_ban_regex_yes') . '' : $lang->get('acpbc_ban_regex_no'); + echo ' + + + + + '; } + $db->free_result(); + echo '
' . $lang->get('acpbc_col_type') . '' . $lang->get('acpbc_col_value') . '' . $lang->get('acpbc_col_regex') . '
' . $lang->get('acpbc_msg_no_rules') . '
'.$t.''.htmlspecialchars($r['ban_value']).''.$g.'' . $lang->get('acpbc_btn_delete') . '
'; + echo '

' . $lang->get('acpbc_heading_create_new') . '

'; + acp_start_form(); + ?> + + get('acpbc_field_type'); ?> + +
+ + get('acpbc_field_rule'); ?> +
+ get('acpbc_field_rule_hint'); ?>
+ + get('acpbc_field_reason'); ?> +
+ + + get('acpbc_field_regex_hint'); ?>
+ + + '; } function page_Admin_AdminLogout() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { - echo '

Error: Not authenticated

It looks like your administration session is invalid or you are not authorized to access this administration page. Please re-authenticate to continue.

'; + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; return; } $session->logout(USER_LEVEL_ADMIN); - echo '

You have now been logged out of the administration panel.

You will continue to be logged into the website, but you will need to re-authenticate before you can access the administration panel again.

Return to the Main Page.

'; + echo '

' . $lang->get('acplo_heading_main') . '

+

' . $lang->get('acplo_msg_logout_complete', array('mainpage_link' => makeUrl(getConfig('main_page')))) . '

'; } function page_Special_Administration() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if($session->auth_level < USER_LEVEL_ADMIN) { redirect(makeUrlNS('Special', 'Login/'.$paths->page, 'level='.USER_LEVEL_ADMIN), 'Not authorized', 'You need an authorization level of '.USER_LEVEL_ADMIN.' to use this page, your auth level is: ' . $session->auth_level, 0); @@ -2321,7 +1881,7 @@ { $template->header(); } - echo 'Administer your Enano website.'; + echo $lang->get('adm_page_tagline'); ?> '; } ?>
@@ -2470,6 +2030,7 @@ function page_Special_EditSidebar() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if($session->auth_level < USER_LEVEL_ADMIN) { @@ -2484,10 +2045,6 @@ $template->add_header(''); $template->add_header(''); - // Knock the sidebars dead to keep javascript in plugins from interfering - $template->tpl_strings['SIDEBAR_LEFT'] = ''; - $template->tpl_strings['SIDEBAR_RIGHT'] = ''; - $template->load_theme('oxygen', 'bleu'); $template->init_vars(); @@ -2522,7 +2079,7 @@ $queries = Array(); foreach($orders as $k => $v) { - $queries[] = 'UPDATE '.table_prefix.'sidebar SET item_order='.$om[$k].' WHERE item_id='.$v[1].';'; + $queries[] = 'UPDATE '.table_prefix.'sidebar SET item_order='.intval($om[$k]).' WHERE item_id='.intval($v[1]).';'; } foreach($queries as $sql) { @@ -2535,7 +2092,7 @@ exit; } } - echo '
The sidebar order information was updated successfully.
'; + echo '
' . $lang->get('sbedit_msg_order_update_success') . '
'; } elseif(isset($_POST['create'])) { @@ -2566,14 +2123,14 @@ if ( defined('ENANO_DEMO_MODE') && intval($_POST['type']) == BLOCK_PHP ) { - echo '
Adding PHP code blocks in the Enano administration demo has been disabled for security reasons.
'; + echo '
' . $lang->get('sbedit_err_demo_php_disable') . '
'; $_POST['php_content'] = '?><Nulled>'; $content = $_POST['php_content']; } // Get the value of item_order - $q = $db->sql_query('SELECT * FROM '.table_prefix.'sidebar WHERE sidebar_id='.$db->escape($_POST['sidebar_id']).';'); + $q = $db->sql_query('SELECT * FROM '.table_prefix.'sidebar WHERE sidebar_id='.intval($_POST['sidebar_id']).';'); if(!$q) $db->_die('The order number could not be selected'); $io = $db->numrows(); @@ -2588,7 +2145,7 @@ exit; } - echo '
The item was added.
'; + echo '
' . $lang->get('sbedit_msg_item_added') . '
'; } @@ -2622,28 +2179,32 @@

- What type of block should this be? + get('sbedit_create_intro'); ?>

- Block title:
- Which sidebar: + get('sbedit_field_block_title'); ?>
+ get('sbedit_field_block_sidebar'); ?> +

- Wikitext: + get('sbedit_field_wikitext'); ?>

@@ -2652,7 +2213,7 @@

- Template code: + get('sbedit_field_tplcode'); ?>

@@ -2661,7 +2222,7 @@

- HTML to place inside the sidebar: + get('sbedit_field_html'); ?>

@@ -2670,26 +2231,10 @@

-

Creating PHP blocks in demo mode is disabled for security reasons.

+

get('sbedit_field_php_disabled'); ?>

-

- WARNING: If you don't know what you're doing, or if you are not fluent in PHP, stop now and choose a different block type. You will brick your Enano installation if you are not careful here. - ALWAYS remember to write secure code! The Enano team is not responsible if someone drops all your tables because of an SQL injection vulnerability in your sidebar code. You are probably better off using the template-formatted block type. -

-

- - It is especially important to note that this code is NOT checked for errors! If there is a syntax error in your code here, it will prevent any pages from loading AT ALL. So you need to use an external PHP editor (like jEdit) to check your syntax before you hit save. - You have been warned. -

-

- Also, you should avoid using output buffering functions (ob_[start|end|get_contents|clean]) here, because Enano uses those to track output from this script. -

-

- The standard <?php and ?> tags work here. Don't use an initial "<?php" or it will cause a parse error. -

-

- PHP code: -

+ get('sbedit_field_php'); ?> +

@@ -2698,7 +2243,7 @@

- Plugin: + get('sbedit_field_plugin'); ?>

  - +   +

@@ -2746,7 +2291,7 @@ $template->footer(); exit; } - echo '
Item moved.
'; + echo '
' . $lang->get('sbedit_msg_block_moved') . '
'; break; case 'delete': $query = $db->sql_query('DELETE FROM '.table_prefix.'sidebar WHERE item_id=' . intval($_GET['id']) . ';'); // Already checked for injection attempts ;-) @@ -2761,7 +2306,7 @@ ob_end_clean(); die('GOOD'); } - echo '
Item deleted.
'; + echo '
' . $lang->get('sbedit_msg_block_deleted') . '
'; break; case 'disenable'; $q = $db->sql_query('SELECT item_enabled FROM '.table_prefix.'sidebar WHERE item_id=' . intval($_GET['id']) . ';'); @@ -2871,7 +2416,7 @@ $c = preg_replace('#(.*?)#is', '\\2', $c); break; case BLOCK_PLUGIN: - $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : 'Can\'t find plugin block'; + $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : $lang->get('sbedit_msg_plugin_not_loaded'); break; } die('var status = \'GOOD\'; var content = unescape(\''.hexencode($c).'\');'); @@ -2888,11 +2433,11 @@ $parser->assign_vars(Array( 'HREF'=>'#', 'FLAGS'=>'onclick="return false;"', - 'TEXT'=>'Change theme' + 'TEXT' => $lang->get('sidebar_btn_changestyle') )); $template->tpl_strings['THEME_LINK'] = $parser->run(); $parser->assign_vars(Array( - 'TEXT'=>'Log out', + 'TEXT' => $lang->get('sidebar_btn_logout'), )); $template->tpl_strings['LOGOUT_LINK'] = $parser->run(); @@ -2951,20 +2496,20 @@ break; case BLOCK_PLUGIN: $parser = $template->makeParserText($vars['sidebar_section_raw']); - $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : 'Can\'t find plugin block'; + $c = ($template->fetch_block($row['block_content'])) ? $template->fetch_block($row['block_content']) : $lang->get('sbedit_msg_plugin_not_loaded'); break; } - $block_name = $template->tplWikiFormat($row['block_name']); + $block_name = $row['block_name']; // $template->tplWikiFormat($row['block_name']); if ( empty($block_name) ) - $block_name = '<Unnamed>'; - $t = '' . $block_name . ''; - if($row['item_enabled'] == 0) $t .= ' (disabled)'; - else $t .= ' '; + $block_name = '<' . $lang->get('sbedit_note_block_unnamed') . '>'; + $t = '' . $block_name . ''; + if($row['item_enabled'] == 0) $t .= ' ' . $lang->get('sbedit_note_block_disabled') . ''; + else $t .= ' '; $side = ( $row['sidebar_id'] == SIDEBAR_LEFT ) ? SIDEBAR_RIGHT : SIDEBAR_LEFT; - $tb = 'Enable/disable this block - Edit this block - Delete this block - Move this block'; + $tb = '' . $lang->get('sbedit_tip_disenable') . ' + ' . $lang->get('sbedit_tip_edit') . ' + ' . $lang->get('sbedit_tip_delete') . ' + ' . $lang->get('sbedit_tip_move') . ''; $as = ''; $ae = '  '.$tb; $parser->assign_vars(Array('CONTENT'=>$c,'TITLE'=>$t,'ADMIN_START'=>$as,'ADMIN_END'=>$ae)); @@ -2982,10 +2527,10 @@ echo ""; echo ' '; diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialCSS.php --- a/plugins/SpecialCSS.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/SpecialCSS.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ attachHook('base_classes_initted', ' +$plugins->attachHook('session_started', ' global $paths; $paths->add_page(Array( - \'name\'=>\'CSS\', + \'name\'=>\'specialpage_css\', \'urlname\'=>\'CSS\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialGroups.php --- a/plugins/SpecialGroups.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/SpecialGroups.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ attachHook('base_classes_initted', ' +$plugins->attachHook('session_started', ' global $paths; $paths->add_page(Array( - \'name\'=>\'Group Membership\', + \'name\'=>\'specialpage_groupcp\', \'urlname\'=>\'Usergroups\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', @@ -34,6 +34,7 @@ { global $db, $session, $paths, $template, $plugins; // Common objects global $email; // Import e-mail encryption functions + global $lang; if ( !$session->user_logged_in ) { @@ -43,6 +44,7 @@ } $template->header(); + userprefs_show_menu(); if ( isset($_POST['do_view']) || isset($_POST['do_view_n']) || ( isset($_GET['act']) && isset($_POST['group_id']) ) ) { $gid = ( isset ( $_POST['do_view_n'] ) ) ? intval($_POST['group_id_n']) : intval($_POST['group_id']); @@ -102,20 +104,20 @@ } $status = ( $is_member && $is_mod ) - ? 'You are a moderator of this group.' + ? $lang->get('groupcp_status_mod') : ( ( $is_member && !$is_mod ) - ? 'You are a member of this group.' - : 'You are not a member of this group.' + ? $lang->get('groupcp_status_member') + : $lang->get('groupcp_status_not_member') ); $can_do_admin_stuff = ( $is_mod || $session->user_level >= USER_LEVEL_ADMIN ); switch ( $row['group_type'] ) { - case GROUP_HIDDEN: $g_state = 'Hidden group'; break; - case GROUP_CLOSED: $g_state = 'Closed group'; break; - case GROUP_REQUEST: $g_state = 'Members can request to join'; break; - case GROUP_OPEN: $g_state = 'Anyone can join'; break; + case GROUP_HIDDEN: $g_state = $lang->get('groupcp_type_hidden'); break; + case GROUP_CLOSED: $g_state = $lang->get('groupcp_type_closed'); break; + case GROUP_REQUEST: $g_state = $lang->get('groupcp_type_request'); break; + case GROUP_OPEN: $g_state = $lang->get('groupcp_type_open'); break; } if ( isset($_GET['act']) && $can_do_admin_stuff ) @@ -139,7 +141,7 @@ $r = $db->fetchrow(); if ( $r['system_group'] == 1 && ( intval($_POST['group_state']) == GROUP_OPEN || intval($_POST['group_state']) == GROUP_REQUEST ) ) { - echo '
Because this is a system group, you can\'t make it open or allow membership requests.
'; + echo '
' . $lang->get('groupcp_err_state_system_group') . '
'; $error = true; } if ( !$error ) @@ -148,7 +150,7 @@ if (!$q) $db->_die('SpecialGroups.php, line ' . __LINE__); $row['group_type'] = $_POST['group_state']; - echo '
The group state was updated.
'; + echo '
' . $lang->get('groupcp_msg_state_updated') . '
'; } break; case 'adduser': @@ -160,7 +162,7 @@ $db->_die('SpecialGroups.php, line ' . __LINE__); if ($db->numrows() < 1) { - echo '
The username you entered could not be found.
'; + echo '
' . $lang->get('groupcp_err_user_not_found') . '
'; break; } $r = $db->fetchrow(); @@ -184,11 +186,11 @@ if ( $member['member_id'] == $r['member_id'] ) $members[$i]['is_mod'] = (int)$mod; } - echo '
The user "' . $username . '" is already in this group, so their moderator status was updated.
'; + echo '
' . $lang->get('groupcp_msg_user_already_in_mod_updated', array('username' => $username)) . '
'; } else { - echo '
The user "' . $username . '" is already in this group.
'; + echo '
' . $lang->get('groupcp_msg_user_already_in', array('username' => $username)) . '
'; } break; } @@ -198,7 +200,7 @@ $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES(' . intval($_POST['group_id']) . ', ' . $uid . ', ' . $mod . ');'); if (!$q) $db->_die('SpecialGroups.php, line ' . __LINE__); - echo '
The user "' . $username . '" has been added to this usergroup.
'; + echo '
' . $lang->get('groupcp_msg_user_added', array('username' => $username)) . '
'; $q = $db->sql_query('SELECT u.username,u.email,u.reg_time,m.member_id,m.user_id,m.is_mod,COUNT(c.comment_id) AS num_comments FROM '.table_prefix.'users AS u @@ -255,17 +257,17 @@ } } } - echo '
Pending members status updated successfully.
'; + echo '
' . $lang->get('groupcp_msg_pending_updated') . '
'; break; } } - if ( isset($_GET['act']) && $_GET['act'] == 'update' && !$is_member && $row['group_type'] == GROUP_OPEN ) + if ( isset($_GET['act']) && $_GET['act'] == 'update' && !$is_member && $row['group_type'] == GROUP_OPEN && !$can_do_admin_stuff ) { $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id) VALUES(' . $gid . ', ' . $session->user_id . ');'); if (!$q) $db->_die('SpecialGroups.php, line ' . __LINE__); - echo '
You have been added to this group.
'; + echo '
' . $lang->get('groupcp_msg_self_added') . '
'; $q = $db->sql_query('SELECT u.username,u.email,u.reg_time,m.member_id,m.user_id,m.is_mod,COUNT(c.comment_id) AS num_comments FROM '.table_prefix.'users AS u @@ -288,55 +290,60 @@ } - if ( isset($_GET['act']) && $_GET['act'] == 'update' && !$is_member && $row['group_type'] == GROUP_REQUEST && !$is_pending ) + if ( isset($_GET['act']) && $_GET['act'] == 'update' && !$is_member && $row['group_type'] == GROUP_REQUEST && !$is_pending && !$can_do_admin_stuff ) { $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,pending) VALUES(' . $gid . ', ' . $session->user_id . ', 1);'); if (!$q) $db->_die('SpecialGroups.php, line ' . __LINE__); - echo '
A request has been sent to the moderator(s) of this group to add you.
'; + echo '
' . $lang->get('groupcp_msg_membership_requested') . '
'; } $state_btns = ( $can_do_admin_stuff ) ? - ' - - - ' + ' + + + ' : $g_state; if ( !$can_do_admin_stuff && $row['group_type'] == GROUP_REQUEST && !$is_member ) { if ( $is_pending ) - $state_btns .= ' (Your request to join is awaiting approval)'; + $state_btns .= ' ' . $lang->get('groupcp_msg_status_pending'); else - $state_btns .= ' '; + $state_btns .= ' '; } if ( !$can_do_admin_stuff && $row['group_type'] == GROUP_OPEN && !$is_member ) { - $state_btns .= ' '; + $state_btns .= ' '; } + $g_name_local = 'groupcp_grp_' . strtolower($row['group_name']); + $str = $lang->get($g_name_local); + if ( $str != $g_name_local ) + $row['group_name'] = $str; + echo '
- + - - + + - + - + ' . ( ( $is_mod || $session->user_level >= USER_LEVEL_ADMIN ) ? ' ' : '' ) . ' @@ -348,21 +355,21 @@ { echo ' -

Pending memberships

+

' . $lang->get('groupcp_th_pending_memberships') . '

Group information' . $lang->get('groupcp_th_group_info') . '
Group name:' . $row['group_name'] . ( $row['system_group'] == 1 ? ' (system group)' : '' ) . '' . $lang->get('groupcp_lbl_group_name') . '' . $row['group_name'] . ( $row['system_group'] == 1 ? ' ' . $lang->get('groupcp_msg_system_group') : '' ) . '
Membership status:' . $lang->get('groupcp_lbl_status') . ' ' . $status . '
Group state:' . $lang->get('groupcp_lbl_state') . ' ' . $state_btns . '
- +
- - - - - + + + + + '; $cls = 'row2'; foreach ( $pending as $member ) { - $date = date('F d, Y', $member['reg_time']); + $date = enano_date('F d, Y', $member['reg_time']); $cls = ( $cls == 'row2' ) ? 'row1' : 'row2'; $addy = $email->encryptEmail($member['email']); @@ -378,26 +385,26 @@
With selected: - - + +
'; } echo ' -

Group members

+

' . $lang->get('groupcp_th_group_members') . '

UsernameE-mailRegisteredTotal commentsSelect' . $lang->get('groupcp_th_username') . '' . $lang->get('groupcp_th_email') . '' . $lang->get('groupcp_th_reg_time') . '' . $lang->get('groupcp_th_comments') . '' . $lang->get('groupcp_th_select') . '
- - - - - ' . ( ( $can_do_admin_stuff ) ? " - - " : '' ) . ' + + + + + ' . ( ( $can_do_admin_stuff ) ? ' + + ' : '' ) . ' - + '; $mod_printed = false; $mem_printed = false; @@ -408,7 +415,7 @@ if ( $member['is_mod'] != 1 ) break; - $date = date('F d, Y', $member['reg_time']); + $date = enano_date('F d, Y', $member['reg_time']); $cls = ( $cls == 'row2' ) ? 'row1' : 'row2'; $addy = $email->encryptEmail($member['email']); @@ -425,14 +432,14 @@ "; } if (!$mod_printed) - echo ''; - echo ''; + echo ''; + echo ''; foreach ( $members as $member ) { if ( $member['is_mod'] == 1 ) continue; - $date = date('F d, Y', $member['reg_time']); + $date = enano_date('F d, Y', $member['reg_time']); $cls = ( $cls == 'row2' ) ? 'row1' : 'row2'; $addy = $email->encryptEmail($member['email']); @@ -449,12 +456,12 @@ "; } if (!$mem_printed) - echo ''; + echo ''; echo '
UsernameE-mailRegisteredTotal commentsRemove?' . $lang->get('groupcp_th_username') . '' . $lang->get('groupcp_th_email') . '' . $lang->get('groupcp_th_reg_time') . '' . $lang->get('groupcp_th_comments') . '' . $lang->get('groupcp_th_remove') . '
Group moderators' . $lang->get('groupcp_th_group_mods') . '
This group has no moderators.
Group members
' . $lang->get('groupcp_msg_no_mods') . '
' . $lang->get('groupcp_th_group_members') . '
This group has no members.
' . $lang->get('groupcp_msg_no_members') . '
'; if ( $can_do_admin_stuff ) { - echo "
"; + echo "
get('groupcp_btn_remove_selected') . "\" />
"; } echo ' '; @@ -464,17 +471,17 @@
- + - + - +
Add a new member to this group' . $lang->get('groupcp_th_add_member') . '
Username:' . $template->username_field('add_username') . '' . $lang->get('groupcp_lbl_username') . '' . $template->username_field('add_username') . '
Group moderator:' . $lang->get('groupcp_lbl_moderator') . '
- +
@@ -489,11 +496,11 @@ echo '
- + '; diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialPageFuncs.php --- a/plugins/SpecialPageFuncs.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/SpecialPageFuncs.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ attachHook('base_classes_initted', ' +$plugins->attachHook('session_started', ' global $paths; $paths->add_page(Array( - \'name\'=>\'Create page\', + \'name\'=>\'specialpage_create_page\', \'urlname\'=>\'CreatePage\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'All pages\', + \'name\'=>\'specialpage_all_pages\', \'urlname\'=>\'AllPages\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'List of special pages\', + \'name\'=>\'specialpage_special_pages\', \'urlname\'=>\'SpecialPages\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'About Enano\', + \'name\'=>\'specialpage_about_enano\', \'urlname\'=>\'About_Enano\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'GNU General Public License\', + \'name\'=>\'specialpage_gnu_gpl\', \'urlname\'=>\'GNU_General_Public_License\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Tag cloud\', + \'name\'=>\'specialpage_tag_cloud\', \'urlname\'=>\'TagCloud\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', @@ -72,6 +72,185 @@ function page_Special_CreatePage() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + + $whitelist_ns = array('Article', 'User', 'Help', 'Template', 'Category', 'Project'); + $code = $plugins->setHook('page_create_ns_whitelist'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + + $errors = array(); + + switch ( isset($_POST['page_title']) ) + { + case true: + // "Create page" was clicked + + // + // VALIDATION CODE + // + + // Check namespace + $namespace = ( isset($_POST['namespace']) ) ? $_POST['namespace'] : 'Article'; + if ( !in_array($namespace, $whitelist_ns) ) + { + $errors[] = $lang->get('pagetools_create_err_invalid_namespace'); + } + + // Check title and figure out urlname + $title = $_POST['page_title']; + $urlname = $_POST['page_title']; + if ( @$_POST['custom_url'] === 'yes' && isset($_POST['urlname']) ) + { + $urlname = $_POST['urlname']; + } + $urlname = sanitize_page_id($urlname); + if ( $urlname == '.00' || empty($urlname) ) + { + $errors[] = $lang->get('pagetools_create_err_invalid_urlname'); + } + + // Validate page existence + $pathskey = $paths->nslist[$namespace] . $urlname; + if ( isPage($pathskey) ) + { + $errors[] = $lang->get('pagetools_create_err_already_exists'); + } + + // Validate permissions + $perms = $session->fetch_page_acl($urlname, $namespace); + if ( !$perms->get_permissions('create_page') ) + { + $errors[] = $lang->get('pagetools_create_err_no_permission'); + } + + // Run hooks + $code = $plugins->setHook('page_create_request'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + + // Create the page + if ( count($errors) < 1 ) + { + $page = new PageProcessor($urlname, $namespace); + $page->create_page($title); + if ( $error = $page->pop_error() ) + { + do + { + $errors[] = $error; + } + while ( $error = $page->pop_error() ); + } + else + { + redirect(makeUrlNS($namespace, $urlname) . '#do:edit', '', '', 0); + return true; + } + } + + break; + } + + $template->header(); + + echo $lang->get('pagetools_create_blurb'); + + if ( count($errors) > 0 ) + { + echo '
' . implode("
\n ", $errors) . '
'; + } + + ?> + + + + '; + + echo '

'; + echo $lang->get('pagetools_create_field_title'); + echo ' '; + echo '

'; + + echo '

'; + echo $lang->get('pagetools_create_field_namespace'); + echo ' '; + echo '

'; + + echo '
'; + echo '' . $lang->get('pagetools_create_group_advanced') . ''; + + echo '

'; + echo ''; + echo '

'; + + echo '

'; + echo ''; + echo '

'; + + echo ''; + + echo '

'; + echo $lang->get('pagetools_create_field_preview') . '
'; + echo '' . $lang->get('pagetools_create_field_preview_hint') . ''; + echo '

'; + + echo '
'; + + echo '

'; + echo ''; + echo '

'; + + echo ''; + + echo ''; + + $template->footer(); +} + +function page_Special_CreatePage_Old() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + if ( isset($_POST['do']) ) { $p = $_POST['pagename']; @@ -88,7 +267,8 @@ { $template->header(); - echo '

The page could not be created.

The name "'.$p.'" is invalid.

'; + echo '

' . $lang->get('pagetools_create_err_title') . '

+

' . $lang->get('pagetools_create_err_name_invalid', array('page_name' => htmlspecialchars($p))) . '

'; $template->footer(); $db->close(); @@ -102,7 +282,8 @@ { $template->header(); - echo '

The page could not be created.

The name "'.$paths->nslist[$namespace].$p.'" is invalid.

'; + echo '

' . $lang->get('pagetools_create_err_title') . '

+

' . $lang->get('pagetools_create_err_name_invalid', array('page_name' => htmlspecialchars($paths->nslist[$namespace].$p))) . '

'; $template->footer(); $db->close(); @@ -118,7 +299,8 @@ { $template->header(); - echo '

The page could not be created.

The page title can\'t start with "Project:" because this prefix is reserved for a parser shortcut.

'; + echo '

' . $lang->get('pagetools_create_err_title') . '

+

' . $lang->get('pagetools_create_err_project_shortcut', array('page_name' => htmlspecialchars($p))) . '

'; $template->footer(); $db->close(); @@ -129,7 +311,7 @@ $tn = $paths->nslist[$_POST['namespace']] . $urlname; if ( isset($paths->pages[$tn]) ) { - die_friendly('Error creating page', '

The page already exists.

'); + die_friendly($lang->get('pagetools_create_err_title'), '

' . $lang->get('pagetools_create_err_already_exist') . '

'); } if ( $paths->nslist[$namespace] == substr($urlname, 0, strlen($paths->nslist[$namespace]) ) ) @@ -154,9 +336,9 @@ $perms = $session->fetch_page_acl($urlname, $namespace); if ( !$perms->get_permissions('create_page') ) - die_friendly('Error creating page', '

An access control rule is preventing you from creating pages.

'); + die_friendly($lang->get('pagetools_create_err_title'), '

An access control rule is preventing you from creating pages.

'); - $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace) VALUES('.time().', \''.date('d M Y h:i a').'\', \'page\', \'create\', \''.$session->username.'\', \''.$urlname.'\', \''.$_POST['namespace'].'\');'); + $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace) VALUES('.time().', \''.enano_date('d M Y h:i a').'\', \'page\', \'create\', \''.$session->username.'\', \''.$urlname.'\', \''.$_POST['namespace'].'\');'); if ( !$q ) { $db->_die('The page log could not be updated.'); @@ -188,7 +370,7 @@ exit; } */ - echo RenderMan::render('Using the form below you can create a page.'); + echo '

' . $lang->get('pagetools_create_blurb') . '

'; ?>

@@ -199,7 +381,7 @@ { if ( $paths->nslist[$k[$i]] == '' ) { - $s = '[No prefix]'; + $s = $lang->get('pagetools_create_namespace_none'); } else { @@ -212,7 +394,7 @@ } ?>

-

+

footer(); @@ -263,9 +445,11 @@ { // This should be an easy one global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + $template->header(); $sz = sizeof( $paths->pages ) / 2; - echo '

Below is a list of all of the pages on this website.

'; + echo '

' . $lang->get('pagetools_allpages_blurb') . '

'; $q = $db->sql_query('SELECT COUNT(urlname) FROM '.table_prefix.'pages WHERE visible!=0;'); if ( !$q ) @@ -326,9 +510,11 @@ { // This should be an easy one global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + $template->header(); $sz = sizeof($paths->pages) / 2; - echo '

Below is a list of all of the special pages on this website.

Group membership details' . $lang->get('groupcp_th_select_group') . '
- Current group memberships: + ' . $lang->get('groupcp_lbl_current_memberships') . ' '; $taboo = Array('Everyone'); @@ -506,11 +513,15 @@ $group = htmlspecialchars($group); if ( $group != 'Everyone' ) { + $g_name_local = 'groupcp_grp_' . strtolower($group); + $str = $lang->get($g_name_local); + if ( $str != $g_name_local ) + $group = $str; echo ''; } } echo ' - '; + '; } else { @@ -531,7 +542,7 @@ { echo '
- Non-memberships: + ' . $lang->get('groupcp_lbl_non_memberships') . ' - +
'; + echo '

' . $lang->get('pagetools_specialpages_blurb') . '

'; $cclass='row1'; for ( $i = 0; $i < $sz; $i = $i) { @@ -365,6 +551,8 @@ function page_Special_About_Enano() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + $platform = 'Unknown'; $uname = @file_get_contents('/proc/sys/kernel/ostype'); if($uname == "Linux\n") @@ -384,24 +572,53 @@
- - +
About the Enano Content Management System

This website is powered by Enano, the lightweight and open source - CMS that everyone can use. Enano is copyright © 2006-2007 Dan Fuhry. For legal information, along with a list of libraries that Enano - uses, please see Legal Information.

-

The developers and maintainers of Enano strongly believe that software should not only be free to use, but free to be modified, - distributed, and used to create derivative works. For more information about Free Software, check out the - Wikipedia page or - the Free Software Foundation's homepage.

-

This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

-

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 details.

-

You should have received a copy of - the GNU General Public License along with this program; if not, write to:

-

Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor
- Boston, MA 02110-1301, USA

-

Alternatively, you can read it online.

+
get('meta_enano_about_th'); ?>
+ get('meta_enano_about_poweredby'); + $subst = array( + 'gpl_link' => makeUrlNS('Special', 'GNU_General_Public_License') + ); + echo $lang->get('meta_enano_about_gpl', $subst); + if ( $lang->lang_code != 'eng' ): + // Do not remove this block of code. Doing so is a violation of the GPL. (A copy of the GPL in other languages + // must be accompanied by a copy of the English GPL.) + ?> +

(English)

+

+ This website is powered by Enano, the lightweight and open source CMS that everyone can use. + Enano is copyright © 2006-2007 Dan Fuhry. For legal information, along with a list of libraries that Enano uses, please + see Legal Information. +

+

+ The developers and maintainers of Enano strongly believe that software should not only be free to use, but free to be modified, + distributed, and used to create derivative works. For more information about Free Software, check out the + Wikipedia page or + the Free Software Foundation's homepage. +

+

+ This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. +

+

+ 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 details. +

+

+ You should have received a copy of + the GNU General Public License along with this program; if not, write to: +

+

+ Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor
+ Boston, MA 02110-1301, USA +

+

+ Alternatively, you can read it online. +

+
@@ -440,23 +657,23 @@
- Enano version: - Web server: - Server platform: - PHP version: + get('meta_enano_about_lbl_enanoversion'); ?> + get('meta_enano_about_lbl_webserver'); ?> + get('meta_enano_about_lbl_serverplatform'); ?> + get('meta_enano_about_lbl_phpversion'); ?> - MySQL version:_conn); ?> + get('meta_enano_about_lbl_mysqlversion'); ?>_conn); ?> _conn); $pg_version = $pg_serverdata['server']; ?> - PostgreSQL version: + get('meta_enano_about_lbl_pgsqlversion'); ?> header(); - if(file_exists(ENANO_ROOT.'/GPL')) + if(file_exists(ENANO_ROOT . '/GPL')) { + echo '

' . $lang->get('pagetools_gpl_blurb', array('about_url' => makeUrlNS('Special', 'About_Enano'))) . '

'; + + if ( $lang->lang_code != 'eng' ): + // Do not remove this block of code. Doing so is a violation of the GPL. (A copy of the GPL in other languages + // must be accompanied by a copy of the English GPL.) echo '

The following text represents the license that the Enano content management system is under. To make it easier to read, the text has been wiki-formatted; in no other way has it been changed.

'; + endif; + + if ( file_exists(ENANO_ROOT . "/GPL_{$lang->lang_code}") ) + { + echo '

' . $lang->get('pagetools_gpl_title_native') . '

'; + echo '

' . $lang->get('pagetools_gpl_link_to_english') . ' / View the license in English' . '

'; + echo RenderMan::render( file_get_contents ( ENANO_ROOT . "/GPL_{$lang->lang_code}" ) ); + echo '

' . $lang->get('pagetools_gpl_title_english') . ' / English version

'; + } + echo RenderMan::render( file_get_contents ( ENANO_ROOT . '/GPL' ) ); } else { - echo '

It appears that the file "GPL" is missing from your Enano installation. You may find a wiki-formatted copy of the GPL at: http://enanocms.org/GPL.

'; + echo '

' . $lang->get('pagetools_gpl_err_file_missing') . '

'; + if ( $lang->lang_code != 'eng') + // Also print out English version + // Do not remove the following line of code; doing so would be a violation of the GPL. + echo '

It appears that the file "GPL" is missing from your Enano installation. You may find a wiki-formatted copy of the GPL at: http://enanocms.org/GPL. In the mean time, you may wish to contact the site administration and ask them to replace the GPL file.

'; } $template->footer(); } @@ -486,6 +724,7 @@ function page_Special_TagCloud() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; $template->header(); @@ -499,7 +738,7 @@ { echo '
'; - echo ''; + echo ''; echo ''; $i = 0; $td_class = 'row1'; @@ -528,7 +767,7 @@ } // " workaround for jEdit highlighting bug echo ' - + '; echo '
Pages tagged "' . htmlspecialchars($tag) . '"
' . $lang->get('pagetools_tagcloud_pagelist_th', array('tag' => htmlspecialchars($tag))) . '
« Return to tag cloud« ' . $lang->get('pagetools_tagcloud_btn_return') . '
'; echo '
'; @@ -543,17 +782,17 @@ $db->_die(); if ( $db->numrows() < 1 ) { - echo '

No pages are tagged yet.

'; + echo '

' . $lang->get('pagetools_tagcloud_msg_no_tags') . '

'; } else { - echo '

Summary of page tagging

'; + echo '

' . $lang->get('pagetools_tagcloud_blurb') . '

'; while ( $row = $db->fetchrow() ) { $cloud->add_word($row['tag_name']); } echo $cloud->make_html('normal'); - echo '

Hover your mouse over a tag to see how many pages have the tag. Click on a tag to see a list of the pages that have it.

'; + echo '

' . $lang->get('pagetools_tagcloud_instructions') . '

'; } } @@ -564,6 +803,7 @@ function sidebar_add_tag_cloud() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; $cloud = new TagCloud(); $q = $db->sql_query('SELECT tag_name FROM '.table_prefix.'tags;'); @@ -571,7 +811,7 @@ $db->_die(); if ( $db->numrows() < 1 ) { - $sb_html = 'No pages are tagged yet.'; + $sb_html = $lang->get('pagetools_tagcloud_msg_no_tags'); } else { @@ -579,9 +819,9 @@ { $cloud->add_word($row['tag_name']); } - $sb_html = $cloud->make_html('small', 'justify') . '
Larger version'; + $sb_html = $cloud->make_html('small', 'justify') . '
' . $lang->get('pagetools_tagcloud_sidebar_btn_larger') . ''; } - $template->sidebar_widget('Tag cloud', "
$sb_html
"); + $template->sidebar_widget($lang->get('pagetools_tagcloud_sidebar_title'), "
$sb_html
"); } $plugins->attachHook('compile_template', 'sidebar_add_tag_cloud();'); diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialRecentChanges.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/SpecialRecentChanges.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,206 @@ +attachHook('session_started', ' + global $paths; + $paths->add_page(Array( + \'name\'=>\'specialpage_recent_changes\', + \'urlname\'=>\'RecentChanges\', + \'namespace\'=>\'Special\', + \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', + )); + '); + +function page_Special_RecentChanges() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + + // One super-loaded SQL query to fetch all the info we need: + // (theoretical) + // SELECT ( CHAR_LENGTH(l1.page_text) - CHAR_LENGTH(l2.page_text) ) AS size_change, l1.author, l1.page_id, l1.namespace, l1.edit_summary, + // l1.time_id AS currev_time, l2.time_id AS oldrev_time + // FROM logs AS l1 + // LEFT JOIN logs AS l2 + // ON ( l1.log_type = l2.log_type AND l1.action = 'edit' AND l1.action = l2.action AND l2.time_id < l1.time_id AND l1.page_id = l2.page_id AND l1.namespace = l2.namespace ) + // WHERE l2.time_id IS NOT NULL + // GROUP BY l1.page_id, l1.namespace + // ORDER BY l2.time_id DESC, l1.time_id DESC; + // (the actual query is generated based on filter criteria) + // How it works: + // * Join the logs table with itself + // * Select the size_change virtual column, which is based on current_rev_length - old_rev_length + // * Use GROUP BY to group rows from the same page together + // * Make sure that the time_id in the second instance (l2) of enano_logs is LESS than the time_id in the first instance (l1) + // * Use ORDER BY to ensure that the latest revision before current is selected + + $where_extra = ''; + if ( isset($_GET['filter_author']) && is_array($_GET['filter_author']) ) + { + $f_author = $_GET['filter_author']; + foreach ( $f_author as &$author ) + { + $author = $db->escape($author); + } + $f_author = "\n AND (\n l1.author = '" . implode("'\n OR l1.author = '", $f_author) . "'\n )"; + $where_extra .= $f_author; + } + + if ( ENANO_DBLAYER == 'MYSQL' ) + { + $sql = 'SELECT ( CHAR_LENGTH(l1.page_text) - CHAR_LENGTH(l2.page_text) ) AS size_change, l1.author, l1.page_id, l1.namespace, l1.edit_summary, + l1.time_id AS currev_time, l2.time_id AS oldrev_time + FROM ' . table_prefix . 'logs AS l1 + LEFT JOIN ' . table_prefix . 'logs AS l2 + ON ( l1.log_type = l2.log_type AND l1.action = \'edit\' AND l1.action = l2.action AND l2.time_id < l1.time_id AND l1.page_id = l2.page_id AND l1.namespace = l2.namespace AND l2.is_draft != 1 ) + WHERE l2.time_id IS NOT NULL' . $where_extra . ' + AND l1.is_draft != 1 + GROUP BY oldrev_time + ORDER BY l1.time_id DESC, l2.time_id DESC;'; + } + else + { + $sql = 'SELECT DISTINCT ON (l1.time_id) ( CHAR_LENGTH(l1.page_text) - CHAR_LENGTH(l2.page_text) ) AS size_change, l1.author, l1.page_id, l1.namespace, l1.edit_summary, + l1.time_id AS currev_time, l2.time_id AS oldrev_time + FROM ' . table_prefix . 'logs AS l1 + LEFT JOIN ' . table_prefix . 'logs AS l2 + ON ( l1.log_type = l2.log_type AND l1.action = \'edit\' AND l1.action = l2.action AND l2.time_id < l1.time_id AND l1.page_id = l2.page_id AND l1.namespace = l2.namespace ) + WHERE l2.time_id IS NOT NULL' . $where_extra . ' + GROUP BY l1.time_id, l1.page_id, l1.namespace, l1.author, l1.edit_summary, l2.time_id, l1.page_text, l2.page_text + ORDER BY l1.time_id DESC, l2.time_id DESC;'; + } + + $template->header(); + + $q = $db->sql_unbuffered_query($sql); + if ( !$q ) + $db->_die(); + + if ( $row = $db->fetchrow($q) ) + { + echo '

'; + do + { + $css = rch_get_css($row['size_change']); + $pagekey = ( isset($paths->nslist[$row['namespace']]) ) ? $paths->nslist[$row['namespace']] . $row['page_id'] : $row['namespace'] . ':' . $row['page_id']; + $pagekey = sanitize_page_id($pagekey); + + // diff button + echo '('; + if ( isPage($pagekey) ) + { + echo ''; + } + echo $lang->get('pagetools_rc_btn_diff'); + if ( isPage($pagekey) ) + { + echo ''; + } + echo ') '; + + // hist button + echo '('; + if ( isPage($pagekey) ) + { + echo ''; + } + echo $lang->get('pagetools_rc_btn_hist'); + if ( isPage($pagekey) ) + { + echo ''; + } + echo ') . . '; + + // link to the page + $cls = ( isPage($pagekey) ) ? '' : ' class="wikilink-nonexistent"'; + echo '' . htmlspecialchars(get_page_title_ns($row['page_id'], $row['namespace'])) . '; '; + + // date + $today = time() - ( time() % 86400 ); + $date = ( $row['currev_time'] > $today ) ? '' : MemberlistFormatter::format_date($row['currev_time']) . ' '; + $date .= date('h:i s', $row['currev_time']); + echo "$date . . "; + + // size counter + $size_change = number_format($row['size_change']); + if ( substr($size_change, 0, 1) != '-' ) + $size_change = "+$size_change"; + + echo "({$size_change})"; + + // link to userpage + echo ' . . '; + $cls = ( isPage($paths->nslist['User'] . $row['author']) ) ? '' : ' class="wikilink-nonexistent"'; + echo '' . htmlspecialchars($row['author']) . ' '; + echo '('; + echo ''; + echo $lang->get('pagetools_rc_btn_pm'); + echo ', '; + echo ''; + echo $lang->get('pagetools_rc_btn_usertalk'); + echo ''; + echo ') . . '; + + // Edit summary + echo '('; + if ( empty($row['edit_summary']) ) + { + echo '' . $lang->get('history_summary_none_given') . ''; + } + else + { + echo RenderMan::parse_internal_links(htmlspecialchars($row['edit_summary'])); + } + echo ')'; + + echo '
'; + } + while ( $row = $db->fetchrow($q) ); + echo '

'; + } + + $template->footer(); +} + +function rch_get_css($change_size) +{ + // Hardly changed at all? Return a gray + if ( $change_size <= 5 && $change_size >= -5 ) + return 'color: #808080;'; + // determine saturation based on size of change (1-500 bytes) + $change_abs = abs($change_size); + $index = 0x70 * ( $change_abs / 500 ); + if ( $index > 0x70 ) + $index = 0x70; + $index = $index + 0x40; + $index = dechex($index); + if ( strlen($index) < 2 ) + $index = "0$index"; + $css = ( $change_size > 0 ) ? "color: #00{$index}00;" : "color: #{$index}0000;"; + if ( $change_abs > 500 ) + $css .= ' font-weight: bold;'; + return $css; +} + +?> diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialSearch.php --- a/plugins/SpecialSearch.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/SpecialSearch.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ attachHook('base_classes_initted', ' +$plugins->attachHook('session_started', ' global $paths; $paths->add_page(Array( - \'name\'=>\'Rebuild search index\', + \'name\'=>\'specialpage_search_rebuild\', \'urlname\'=>\'SearchRebuild\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Search\', + \'name\'=>\'specialpage_search\', \'urlname\'=>\'Search\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', @@ -40,7 +40,10 @@ function page_Special_SearchRebuild() { global $db, $session, $paths, $template, $plugins; // Common objects - if(!$session->get_permissions('mod_misc')) die_friendly('Unauthorized', '

You need to be an administrator to rebuild the search index

'); + if ( !$session->get_permissions('mod_misc') ) + { + die_friendly('Unauthorized', '

You need to be an administrator to rebuild the search index

'); + } $template->header(); @set_time_limit(0); if($paths->rebuild_search_index(true)) @@ -54,6 +57,8 @@ { global $db, $session, $paths, $template, $plugins; // Common objects global $aggressive_optimize_html; + global $lang; + $aggressive_optimize_html = false; if ( !$q = $paths->getParam(0) ) @@ -95,7 +100,7 @@ $qin = ( isset($q) ) ? str_replace('"', '\"', htmlspecialchars($q)) : ''; $search_form = '
-   Advanced search +   ' . $lang->get('search_btn_advanced_search') . ' ' . ( $session->auth_level > USER_LEVEL_MEMBER ? '' : '' ) . '
'; @@ -103,7 +108,7 @@ { $search_start = microtime_float(); - $results = perform_search($q, $warn, ( isset($_GET['match_case']) )); + $results = perform_search($q, $warn, ( isset($_GET['match_case']) ), $word_list); $warn = array_unique($warn); if ( file_exists( ENANO_ROOT . '/themes/' . $template->theme . '/search-result.tpl' ) ) @@ -122,7 +127,7 @@ {PAGE_TEXT} {PAGE_URL} - {PAGE_LENGTH} {PAGE_LENGTH_UNIT} - - Relevance: {RELEVANCE_SCORE}% + {lang:search_lbl_relevance} {RELEVANCE_SCORE}%

@@ -138,22 +143,25 @@ if ( !empty($result['page_text']) ) $result['page_text'] .= '
'; $result['page_name'] = str_replace(array('', ''), array('', ''), $result['page_name']); + $result['url_highlight'] = str_replace(array('', ''), array('', ''), $result['url_highlight']); if ( $result['page_length'] >= 1048576 ) { $result['page_length'] = round($result['page_length'] / 1048576, 1); - $length_unit = 'MB'; + $length_unit = $lang->get('etc_unit_megabytes_short'); } else if ( $result['page_length'] >= 1024 ) { $result['page_length'] = round($result['page_length'] / 1024, 1); - $length_unit = 'KB'; + $length_unit = $lang->get('etc_unit_kilobytes_short'); } else { - $length_unit = 'bytes'; + $length_unit = $lang->get('etc_unit_bytes'); } - $url = makeUrlComplete($result['namespace'], $result['page_id']); - $url = preg_replace('/\?.+$/', '', $url); + //$url = makeUrlComplete($result['namespace'], $result['page_id']); + //$url = preg_replace('/\?.+$/', '', $url); + $url = $result['url_highlight']; + $parser->assign_vars(array( 'PAGE_TITLE' => $result['page_name'], 'PAGE_TEXT' => $result['page_text'], @@ -193,13 +201,20 @@ $q_trim = ( strlen($q) > 30 ) ? substr($q, 0, 27) . '...' : $q; $q_trim = htmlspecialchars($q_trim); - $result_string = ( count($results) > 0 ) ? "Results $start_string - $per_string of about $num_results for " . $q_trim . " in {$search_time}s." : 'No results.'; + $result_detail = $lang->get('search_msg_result_detail', array( + 'start_string' => $start_string, + 'per_string' => $per_string, + 'q_trim' => $q_trim, + 'num_results' => $num_results, + 'search_time' => $search_time + )); + $result_string = ( count($results) > 0 ) ? $result_detail : $lang->get('search_msg_no_results'); echo '
' . $result_string . '
- Site search + ' . $lang->get('search_lbl_site_search') . '
' . $search_form . ' @@ -208,8 +223,8 @@ if ( count($warn) > 0 ) { echo '
'; - echo 'Some problems were encountered during your search.
- There was a problem with your search query, and as a result there may be a reduced number of search results.'; + echo '' . $lang->get('search_err_query_title') . '
+ ' . $lang->get('search_err_query_body'); echo '
  • ' . implode('
  • ', $warn) . '
'; echo '
'; } @@ -228,14 +243,12 @@ else { // No results for the search - echo '

Your search for "' . htmlspecialchars($q) . '" didn\'t turn up any results.

'; - echo '

There are a few things you can try:

'; - echo '
    -
  • Were you looking for a specific Special page? Special pages are not searchable. You may want to see a list of special pages.
  • -
  • If you have the appropriate permissions, you can start the ' . htmlspecialchars($q) . ' page.
  • -
  • Try using fewer keywords. You can get broader results if you remove quotes from your search query.
  • -
  • Did your search trigger any warnings? Sometimes a search can be cancelled if there aren\'t any terms in a search query that are 4 characters or greater in length.
  • -
'; + echo '

' . $lang->get('search_body_no_results_title', array('query' => htmlspecialchars($q))) . '

'; + echo $lang->get('search_body_no_results_body', array( + 'query' => htmlspecialchars($q), + 'create_url' => makeUrl($q), + 'special_url' => makeUrlNS('Special', 'SpecialPages'), + )); } $code = $plugins->setHook('search_results'); foreach ( $code as $cmd ) @@ -254,26 +267,26 @@ endif; ?>
- + - + - + - + - +
Advanced Search
get('search_th_advanced_search'); ?>
Search for pages with any of these words:get('search_lbl_field_any'); ?>
with this exact phrase:get('search_lbl_field_exact'); ?>
with none of these words:get('search_lbl_field_none'); ?>
with all of these words:get('search_lbl_field_all'); ?>
- + @@ -281,7 +294,7 @@
- +
diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialUpdownload.php --- a/plugins/SpecialUpdownload.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/SpecialUpdownload.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ attachHook('base_classes_initted', ' +$plugins->attachHook('session_started', ' global $paths; $paths->add_page(Array( - \'name\'=>\'Upload file\', + \'name\'=>\'specialpage_upload_file\', \'urlname\'=>\'UploadFile\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Download file\', + \'name\'=>\'specialpage_download_file\', \'urlname\'=>\'DownloadFile\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', @@ -43,11 +43,12 @@ function page_Special_UploadFile() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; global $mime_types; - if(getConfig('enable_uploads')!='1') { die_friendly('Access denied', '

File uploads are disabled this website.

'); } + if(getConfig('enable_uploads')!='1') { die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('upload_err_disabled_site') . '

'); } if ( !$session->get_permissions('upload_files') ) { - die_friendly('Access denied', '

File uploads are disabled for your user account or group.

'); + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('upload_err_disabled_acl') . '

'); } if(isset($_POST['doit'])) { @@ -61,42 +62,18 @@ } if ( !is_array($file) ) { - die_friendly('Upload failed', '

The server could not retrieve the array $_FILES[\'data\'].

'); + die_friendly($lang->get('upload_err_title'), '

' . $lang->get('upload_err_cant_get_file_meta') . '

'); } if ( $file['size'] == 0 || $file['size'] > (int)getConfig('max_file_size') ) { - die_friendly('Upload failed', '

The file you uploaded is either too large or 0 bytes in length.

'); + die_friendly($lang->get('upload_err_title'), '

' . $lang->get('upload_err_too_big_or_small') . '

'); } - /* - $allowed_mime_types = Array( - 'text/plain', - 'image/png', - 'image/jpeg', - 'image/tiff', - 'image/gif', - 'text/html', // Safe because the file is stashed in the database - 'application/x-bzip2', - 'application/x-gzip', - 'text/x-c++' - ); - if(function_exists('finfo_open') && $fi = finfo_open(FILEINFO_MIME, ENANO_ROOT.'/includes/magic')) // First try to use the fileinfo extension, this is the best way to determine the mimetype - { - if(!$fi) die_friendly('Upload failed', '

Enano was unable to determine the format of the uploaded file.

'.@finfo_file($fi, $file['tmp_name']).'

'); - $type = @finfo_file($fi, $file['tmp_name']); - @finfo_close($fi); - } - elseif(function_exists('mime_content_type')) - $type = mime_content_type($file['tmp_name']); // OK, no fileinfo function. Use a (usually) built-in PHP function - elseif(isset($file['type'])) - $type = $file['type']; // LAST RESORT: use the mimetype the browser sent us, though this is likely to be spoofed - else // DANG! Not even the browser told us. Bail out. - die_friendly('Upload failed', '

Enano was unable to determine the format of the uploaded file.

'); - */ + $types = fetch_allowed_extensions(); $ext = strtolower(substr($file['name'], strrpos($file['name'], '.')+1, strlen($file['name']))); if ( !isset($types[$ext]) || ( isset($types[$ext]) && !$types[$ext] ) ) { - die_friendly('Upload failed', '

The file type ".'.$ext.'" is not allowed.

'); + die_friendly($lang->get('upload_err_title'), '

' . $lang->get('upload_err_banned_ext', array('ext' => htmlspecialchars($ext))) . '

'); } $type = $mime_types[$ext]; //$type = explode(';', $type); $type = $type[0]; @@ -112,12 +89,16 @@ $bad_chars = Array(':', '\\', '/', '<', '>', '|', '*', '?', '"', '#', '+'); foreach($bad_chars as $ch) { - if(strstr($filename, $ch) || preg_match('/^([ ]+)$/is', $filename)) die_friendly('Upload failed', '

The filename contains invalid characters.

'); + if(strstr($filename, $ch) || preg_match('/^([ ]+)$/is', $filename)) + { + die_friendly($lang->get('upload_err_title'), '

' . $lang->get('upload_err_banned_chars') . '

'); + } } if ( isset ( $paths->pages[ $paths->nslist['File'] . $filename ] ) && !isset ( $_POST['update'] ) ) { - die_friendly('Upload failed', '

The file already exists. You can upload a new version of this file.

'); + $upload_link = makeUrlNS('Special', 'UploadFile/'.$filename); + die_friendly($lang->get('upload_err_title'), '

' . $lang->get('upload_err_already_exists', array('upload_link' => $upload_link)) . '

'); } else if ( isset($_POST['update']) && ( !isset($paths->pages[$paths->nslist['File'].$filename]) || @@ -126,7 +107,7 @@ ) ) { - die_friendly('Upload failed', '

Either the file does not exist (and therefore cannot be updated) or the file is protected.

'); + die_friendly($lang->get('upload_err_title'), '

' . $lang->get('upload_err_replace_protected') . '

'); } $utime = time(); @@ -144,7 +125,7 @@ if(!@move_uploaded_file($file['tmp_name'], $targetname)) { - die_friendly('Upload failed', '

Could not move uploaded file to the new location.

'); + die_friendly($lang->get('upload_err_title'), '

' . $lang->get('upload_err_move_failed') . '

'); } if(getConfig('file_history') != '1') @@ -154,15 +135,15 @@ if(!$db->sql_query('INSERT INTO '.table_prefix.'files(time_id,page_id,filename,size,mimetype,file_extension,file_key) VALUES('.$utime.', \''.$urln.'\', \''.$filename.'\', '.$flen.', \''.$type.'\', \''.$ext.'\', \''.$key.'\')')) $db->_die('The file data entry could not be inserted.'); if(!isset($_POST['update'])) { - if(!$db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace) VALUES('.$utime.', \''.date('d M Y h:i a').'\', \'page\', \'create\', \''.$session->username.'\', \''.$filename.'\', \''.'File'.'\');')) $db->_die('The page log could not be updated.'); + if(!$db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace) VALUES('.$utime.', \''.enano_date('d M Y h:i a').'\', \'page\', \'create\', \''.$session->username.'\', \''.$filename.'\', \''.'File'.'\');')) $db->_die('The page log could not be updated.'); if(!$db->sql_query('INSERT INTO '.table_prefix.'pages(name,urlname,namespace,protected,delvotes,delvote_ips) VALUES(\''.$filename.'\', \''.$urln.'\', \'File\', 0, 0, \'\')')) $db->_die('The page listing entry could not be inserted.'); if(!$db->sql_query('INSERT INTO '.table_prefix.'page_text(page_id,namespace,page_text,char_tag) VALUES(\''.$urln.'\', \'File\', \''.$comments.'\', \''.$chartag.'\')')) $db->_die('The page text entry could not be inserted.'); } else { - if(!$db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace,edit_summary) VALUES('.$utime.', \''.date('d M Y h:i a').'\', \'page\', \'reupload\', \''.$session->username.'\', \''.$filename.'\', \''.'File'.'\', \''.$comments.'\');')) $db->_die('The page log could not be updated.'); + if(!$db->sql_query('INSERT INTO '.table_prefix.'logs(time_id,date_string,log_type,action,author,page_id,namespace,edit_summary) VALUES('.$utime.', \''.enano_date('d M Y h:i a').'\', \'page\', \'reupload\', \''.$session->username.'\', \''.$filename.'\', \''.'File'.'\', \''.$comments.'\');')) $db->_die('The page log could not be updated.'); } - die_friendly('Upload complete', '

Your file has been uploaded successfully. View the file\'s page.

'); + die_friendly($lang->get('upload_success_title'), '

' . $lang->get('upload_success_body', array('file_link' => makeUrlNS('File', $filename))) . '

'); } else { @@ -170,51 +151,56 @@ $fn = $paths->getParam(0); if ( $fn && !$session->get_permissions('upload_new_version') ) { - die_friendly('Access denied', '

Uploading new versions of files has been disabled for your user account or group.

'); + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('upload_err_replace_denied') . '

'); } ?> -

Using this form you can upload a file to the site.

-

The maximum file size is get('upload_intro'); ?>

+

= 1048576) { $fs = round($fs / 1048576, 1); - echo ' ('.$fs.' MB)'; + $unitized = $fs . ' ' . $lang->get('etc_unit_megabytes_short'); } elseif($fs >= 1024) { $fs = round($fs / 1024, 1); - echo ' ('.$fs.' KB)'; + $unitized = $fs . ' ' . $lang->get('etc_unit_kilobytes_short'); } - ?>.

+ + echo $lang->get('upload_max_filesize', array( + 'size' => $unitized + )); + ?>

- - + + '; - else echo ''; + if(!$fn) echo ''; + else echo ''; ?>
File:
Rename to: />
get('upload_field_file'); ?>
get('upload_field_renameto'); ?> />
Comments:
(can be wiki-formatted)
Reason for uploading the new version:
' . $lang->get('upload_field_comments') . '
' . $lang->get('upload_field_reason') . '
'; ?> - +
footer(); } -} +} function page_Special_DownloadFile() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; global $do_gzip; $filename = rawurldecode($paths->getParam(0)); $timeid = $paths->getParam(1); @@ -235,7 +221,7 @@ if ( $db->numrows() < 1 ) { header('HTTP/1.1 404 Not Found'); - die_friendly('File not found', '

The file "'.$filename.'" cannot be found.

'); + die_friendly($lang->get('upload_err_not_found_title'), '

' . $lang->get('upload_err_not_found_body', array('filename' => htmlspecialchars($filename))) . '

'); } $row = $db->fetchrow(); $db->free_result(); @@ -244,7 +230,7 @@ $perms = $session->fetch_page_acl($row['page_id'], 'File'); if ( !$perms->get_permissions('read') ) { - die_friendly('Access denied', '

Access to the specified file is denied.

'); + die_friendly($lang->get('etc_access_denied_short'), '

' . $lang->get('etc_access_denied') . '

'); } $fname = ENANO_ROOT . '/files/' . $row['file_key'] . '_' . $row['time_id'] . $row['file_extension']; @@ -307,7 +293,7 @@ header('Content-disposition: attachment, filename="' . $filename . '";'); } header('Content-length: '.$len); - header('Last-Modified: '.date('r', $row['time_id'])); + header('Last-Modified: '.enano_date('r', $row['time_id'])); // using this method limits RAM consumption while ( !feof($handle) ) diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialUserFuncs.php --- a/plugins/SpecialUserFuncs.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/SpecialUserFuncs.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ attachHook('base_classes_initted', ' +$plugins->attachHook('session_started', ' global $paths; $paths->add_page(Array( - \'name\'=>\'Log in\', + \'name\'=>\'specialpage_log_in\', \'urlname\'=>\'Login\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Log out\', + \'name\'=>\'specialpage_log_out\', \'urlname\'=>\'Logout\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Register\', + \'name\'=>\'specialpage_register\', \'urlname\'=>\'Register\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Edit Profile\', + \'name\'=>\'specialpage_preferences\', \'urlname\'=>\'Preferences\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Contributions\', + \'name\'=>\'specialpage_contributions\', \'urlname\'=>\'Contributions\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Change style\', + \'name\'=>\'specialpage_change_theme\', \'urlname\'=>\'ChangeStyle\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Activate user account\', + \'name\'=>\'specialpage_activate_account\', \'urlname\'=>\'ActivateAccount\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Captcha\', + \'name\'=>\'specialpage_captcha\', \'urlname\'=>\'Captcha\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Forgot password\', + \'name\'=>\'specialpage_password_reset\', \'urlname\'=>\'PasswordReset\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); $paths->add_page(Array( - \'name\'=>\'Member list\', + \'name\'=>\'specialpage_member_list\', \'urlname\'=>\'Memberlist\', \'namespace\'=>\'Special\', \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', )); + + $paths->add_page(Array( + \'name\'=>\'specialpage_language_export\', + \'urlname\'=>\'LangExportJSON\', + \'namespace\'=>\'Special\', + \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', + )); + '); // function names are IMPORTANT!!! The name pattern is: page__ @@ -100,21 +108,84 @@ { global $db, $session, $paths, $template, $plugins; // Common objects global $__login_status; + global $lang; $pubkey = $session->rijndael_genkey(); $challenge = $session->dss_rand(); + $locked_out = false; + // are we locked out? + $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5; + $duration = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15; + // convert to minutes + $duration = $duration * 60; + $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout'; + if ( $policy != 'disable' ) + { + $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']); + $timestamp_cutoff = time() - $duration; + $q = $session->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;'); + $fails = $db->numrows(); + if ( $fails >= $threshold ) + { + $row = $db->fetchrow(); + $locked_out = true; + $lockdata = array( + 'locked_out' => true, + 'lockout_threshold' => $threshold, + 'lockout_duration' => ( $duration / 60 ), + 'lockout_fails' => $fails, + 'lockout_policy' => $policy, + 'lockout_last_time' => $row['timestamp'], + 'time_rem' => ( $duration / 60 ) - round( ( time() - $row['timestamp'] ) / 60 ), + 'captcha' => '' + ); + if ( $policy == 'captcha' ) + { + $lockdata['captcha'] = $session->make_captcha(); + } + } + $db->free_result(); + } + if ( isset($_GET['act']) && $_GET['act'] == 'getkey' ) { - header('Content-type: application/json'); + header('Content-type: text/javascript'); $username = ( $session->user_logged_in ) ? $session->username : false; $response = Array( 'username' => $username, 'key' => $pubkey, - 'challenge' => $challenge + 'challenge' => $challenge, + 'locked_out' => false ); - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - $response = $json->encode($response); + + if ( $locked_out ) + { + foreach ( $lockdata as $x => $y ) + { + $response[$x] = $y; + } + unset($x, $y); + } + + // 1.1.3: generate diffie hellman key + global $dh_supported, $_math; + + $response['dh_supported'] = $dh_supported; + if ( $dh_supported ) + { + $dh_key_priv = dh_gen_private(); + $dh_key_pub = dh_gen_public($dh_key_priv); + $dh_key_priv = $_math->str($dh_key_priv); + $dh_key_pub = $_math->str($dh_key_pub); + $response['dh_public_key'] = $dh_key_pub; + // store the keys in the DB + $q = $db->sql_query('INSERT INTO ' . table_prefix . "diffiehellman( public_key, private_key ) VALUES ( '$dh_key_pub', '$dh_key_priv' );"); + if ( !$q ) + $db->die_json(); + } + + $response = enano_json_encode($response); echo $response; return null; } @@ -136,10 +207,53 @@ $paths->main_page(); $template->header(); echo '
'; - $header = ( $level > USER_LEVEL_MEMBER ) ? 'Please re-enter your login details' : 'Please enter your username and password to log in.'; + $header = ( $level > USER_LEVEL_MEMBER ) ? $lang->get('user_login_message_short_elev') : $lang->get('user_login_message_short'); if ( isset($_POST['login']) ) { - echo '

'.$__login_status.'

'; + $errstring = $__login_status['error']; + switch($__login_status['error']) + { + case 'key_not_found': + $errstring = $lang->get('user_err_key_not_found'); + break; + case 'key_wrong_length': + $errstring = $lang->get('user_err_key_wrong_length'); + break; + case 'too_big_for_britches': + $errstring = $lang->get('user_err_too_big_for_britches'); + break; + case 'invalid_credentials': + $errstring = $lang->get('user_err_invalid_credentials'); + if ( $__login_status['lockout_policy'] == 'lockout' ) + { + $errstring .= $lang->get('err_invalid_credentials_lockout', array('lockout_fails' => $__login_status['lockout_fails'])); + } + else if ( $__login_status['lockout_policy'] == 'captcha' ) + { + $errstring .= $lang->get('user_err_invalid_credentials_lockout_captcha', array('lockout_fails' => $__login_status['lockout_fails'])); + } + break; + case 'backend_fail': + $errstring = $lang->get('user_err_backend_fail'); + break; + case 'locked_out': + $attempts = intval($__login_status['lockout_fails']); + if ( $attempts > $__login_status['lockout_threshold']) + $attempts = $__login_status['lockout_threshold']; + + $server_time = time(); + $time_rem = ( $__login_status['lockout_last_time'] == time() ) ? $__login_status['lockout_duration'] : $__login_status['lockout_duration'] - round( ( $server_time - $__login_status['lockout_last_time'] ) / 60 ); + if ( $time_rem < 1 ) + $time_rem = $__login_status['lockout_duration']; + + $s = ( $time_rem == 1 ) ? '' : $lang->get('meta_plural'); + + $captcha_string = ( $__login_status['lockout_policy'] == 'captcha' ) ? $lang->get('err_locked_out_captcha_blurb') : ''; + $errstring = $lang->get('user_err_locked_out', array('plural' => $s, 'captcha_blurb' => $captcha_string, 'time_rem' => $time_rem)); + + break; + } + echo '
'.$errstring.'
'; } if ( $p = $paths->getAllParams() ) { @@ -160,18 +274,18 @@ Logging in enables you to use your preferences and access member information. If you don\'t have a username and password here, you can create an account.

'; + echo '

' . $lang->get('user_login_body', array('reg_link' => makeUrlNS('Special', 'Register'))) . '

'; } else { - echo '

You are requesting that a sensitive operation be performed. To continue, please re-enter your password to confirm your identity.

'; + echo '

' . $lang->get('user_login_body_elev') . '

'; } ?> - Username: + get('user_login_field_username'); ?>: /> - - Forgot your password? No problem.
- Maybe you need to create an account.
+ + get('user_login_forgotpass_blurb', array('forgotpass_link' => makeUrlNS('Special', 'PasswordReset'))); ?>
+ get('user_login_createaccount_blurb', array('reg_link' => makeUrlNS('Special', 'Register'))); ?>
- Password:
+ + get('user_login_field_password'); ?>: + - + + + get('user_login_field_captcha'); ?>:
+ + + + + + + -

Important note regarding cryptography: Some countries do not allow the import or use of cryptographic technology. If you live in one of the countries listed below, you should log in without using encryption.

-

This restriction applies to the following countries: Belarus, China, India, Israel, Kazakhstan, Mongolia, Pakistan, Russia, Saudi Arabia, Singapore, Tunisia, Venezuela, and Vietnam.

+ getAllParams() ) ? '/' . $return : ''; + $nocrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=0", true); + echo '

' . $lang->get('user_login_nocrypt_title') . ' ' . $lang->get('user_login_nocrypt_body', array('nocrypt_link' => $nocrypt_link)) . '

'; + echo '

' . $lang->get('user_login_nocrypt_countrylist') . '

'; + } + else if ( $level <= USER_LEVEL_MEMBER && ( isset($_GET['use_crypt']) && $_GET['use_crypt']=='0' ) ) + { + $returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : ''; + $usecrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=1", true); + echo '

' . $lang->get('user_login_usecrypt_title') . ' ' . $lang->get('user_login_usecrypt_body', array('usecrypt_link' => $usecrypt_link)) . '

'; + echo '

' . $lang->get('user_login_usecrypt_countrylist') . '

'; + } + ?> - - - -

Encrypted logon has been disabled. Unless you live in a country where encryption technology is illegal, you should use encryption when you log on to help protect against password sniffing.

- - - @@ -244,17 +381,98 @@ { global $db, $session, $paths, $template, $plugins; // Common objects global $__login_status; + global $lang; + if ( $paths->getParam(0) === 'action.json' ) + { + if ( !isset($_POST['r']) ) + die('No request.'); + + $request = $_POST['r']; + try + { + $request = enano_json_decode($request); + } + catch ( Exception $e ) + { + die(enano_json_encode(array( + 'mode' => 'error', + 'error' => 'ERR_JSON_PARSE_FAILED' + ))); + } + + echo enano_json_encode($session->process_login_request($request)); + + $db->close(); + exit; + } if ( isset($_GET['act']) && $_GET['act'] == 'ajaxlogin' ) { $plugins->attachHook('login_password_reset', 'SpecialLogin_SendResponse_PasswordReset($row[\'user_id\'], $row[\'temp_password\']);'); - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - $data = $json->decode($_POST['params']); + $data = enano_json_decode($_POST['params']); + $captcha_hash = ( isset($data['captcha_hash']) ) ? $data['captcha_hash'] : false; + $captcha_code = ( isset($data['captcha_code']) ) ? $data['captcha_code'] : false; $level = ( isset($data['level']) ) ? intval($data['level']) : USER_LEVEL_MEMBER; - $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $data['crypt_key'], $data['challenge'], $level); - $session->start(); - //echo "$result\n$session->sid_super"; - //exit; - if ( $result == 'success' ) + + // 1.1.3: Diffie Hellman + global $dh_supported; + global $_math; + if ( $data['diffiehellman'] && isset($data['publickey_client']) && isset($data['publickey_server']) && isset($data['crypt_key_check']) ) + { + if ( !$dh_supported ) + { + die('Special:Login: Illegal request for Diffie Hellman exchange'); + } + // retrieve our public key + if ( !preg_match('/^[0-9]+$/', $data['publickey_server']) ) + { + die('Special:Login: Illegal request for Diffie Hellman exchange'); + } + $pubkey_server =& $data['publickey_server']; + + // retrieve our private key + $q = $db->sql_query('SELECT private_key, key_id FROM ' . table_prefix . "diffiehellman WHERE public_key = '$pubkey_server';"); + if ( !$q ) + $db->die_json(); + + if ( $db->numrows() < 1 ) + { + die('Special:Login: Couldn\'t lookup Diffie Hellman key: ' . $pubkey_server); + } + list($privkey_server, $key_id) = $db->fetchrow_num(); + $db->free_result(); + + // get shared secret + $dh_secret = dh_gen_shared_secret($privkey_server, $data['publickey_client']); + $dh_secret = $_math->str($dh_secret); + $secret_check = sha1($dh_secret); + if ( $secret_check !== $data['crypt_key_check'] ) + { + die(enano_json_encode(array( + 'mode' => 'error', + 'error' => 'Diffie Hellman redundancy check failed, couldn\'t rebuild the AES key.', + 'debug' => array( + 'server private key' => $privkey_server, + 'client public key' => $data['publickey_client'], + 'expected sha1' => $data['crypt_key_check'], + 'actual sha1' => $secret_check + ) + ))); + } + // we have the secret, now get the sha256 hash + $crypt_key = substr(sha256($dh_secret), 0, ( AES_BITS / 4 )); + } + else if ( !$data['diffiehellman'] && isset($data['crypt_key']) && isset($data['crypt_data']) ) + { + $crypt_key = $data['crypt_key']; + } + else + { + die('Special:Login: Illegal request'); + } + + $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $crypt_key, $data['challenge'], $level, $captcha_hash, $captcha_code, !$dh_supported); + + if ( $result['success'] ) { $response = Array( 'result' => 'success', @@ -263,38 +481,56 @@ } else { + $captcha = ''; + if ( $result['error'] == 'locked_out' && $result['lockout_policy'] == 'captcha' ) + { + $session->kill_captcha(); + $captcha = $session->make_captcha(); + } $response = Array( 'result' => 'error', - 'error' => $result + 'data' => $result, + 'captcha' => $captcha ); } - $response = $json->encode($response); + $response = enano_json_encode($response); echo $response; $db->close(); exit; } if(isset($_POST['login'])) { + $captcha_hash = ( isset($_POST['captcha_hash']) ) ? $_POST['captcha_hash'] : false; + $captcha_code = ( isset($_POST['captcha_code']) ) ? $_POST['captcha_code'] : false; if($_POST['use_crypt'] == 'yes') { - $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level'])); + $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level']), $captcha_hash, $captcha_code); } else { - $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level'])); + $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level']), $captcha_hash, $captcha_code); } - $session->start(); - $paths->init(); - if($result == 'success') + + if($result['success']) { + $session->start(); + $template->load_theme($session->theme, $session->style); if(isset($_POST['return_to'])) { $name = ( isset($paths->pages[$_POST['return_to']]['name']) ) ? $paths->pages[$_POST['return_to']]['name'] : $_POST['return_to']; - redirect( makeUrl($_POST['return_to'], false, true), 'Login successful', 'You have successfully logged into the '.getConfig('site_name').' site as "'.$session->username.'". Redirecting to ' . $name . '...' ); + $subst = array( + 'username' => $session->username, + 'redir_target' => $name + ); + redirect( makeUrl($_POST['return_to'], false, true), $lang->get('user_login_success_title'), $lang->get('user_login_success_body', $subst) ); } else { - redirect( makeUrl(getConfig('main_page'), false, true), 'Login successful', 'You have successfully logged into the '.getConfig('site_name').' site as "'.$session->username.'". Redirecting to the main page...' ); + $subst = array( + 'username' => $session->username, + 'redir_target' => $lang->get('user_login_success_body_mainpage') + ); + redirect( makeUrl(getConfig('main_page'), false, true), $lang->get('user_login_success_title'), $lang->get('user_login_success_body', $subst) ); } } else @@ -306,7 +542,6 @@ function SpecialLogin_SendResponse_PasswordReset($user_id, $passkey) { - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); $response = Array( 'result' => 'success_reset', @@ -314,7 +549,7 @@ 'temppass' => $passkey ); - $response = $json->encode($response); + $response = enano_json_encode($response); echo $response; $db->close(); @@ -324,32 +559,47 @@ function page_Special_Logout() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; if ( !$session->user_logged_in ) $paths->main_page(); $l = $session->logout(); if ( $l == 'success' ) { - redirect(makeUrl(getConfig('main_page'), false, true), 'Logged out', 'You have been successfully logged out, and all cookies have been cleared. You will now be transferred to the main page.', 4); + $url = makeUrl(getConfig('main_page'), false, true); + if ( $pi = $paths->getAllParams() ) + { + list($pid, $ns) = RenderMan::strToPageID($pi); + $perms = $session->fetch_page_acl($pid, $ns); + if ( $perms->get_permissions('read') ) + { + $url = makeUrl($pi, false, true); + } + } + redirect($url, $lang->get('user_logout_success_title'), $lang->get('user_logout_success_body'), 4); } $template->header(); - echo '

An error occurred during the logout process.

'.$l.'

'; + echo '

' . $lang->get('user_logout_err_title') . '

'; + echo '

' . $l . '

'; $template->footer(); } function page_Special_Register() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; // form field trackers $username = ''; $email = ''; $realname = ''; + $terms = getConfig('register_tou'); + if(getConfig('account_activation') == 'disable' && ( ( $session->user_level >= USER_LEVEL_ADMIN && !isset($_GET['IWannaPlayToo']) ) || $session->user_level < USER_LEVEL_ADMIN || !$session->user_logged_in )) { - $s = ($session->user_level >= USER_LEVEL_ADMIN) ? '

Oops...it seems that you are the administrator...hehe...you can also force account registration to work.

' : ''; - die_friendly('Registration disabled', '

The administrator has disabled new user registration on this site.

' . $s); + $s = ($session->user_level >= USER_LEVEL_ADMIN) ? '

' . $lang->get('user_reg_err_disabled_body_adminblurb', array( 'reg_link' => makeUrl($paths->page, 'IWannaPlayToo&coppa=no', true) )) . '

' : ''; + die_friendly($lang->get('user_reg_err_disabled_title'), '

' . $lang->get('user_reg_err_disabled_body') . '

' . $s); } if ( $session->user_level < USER_LEVEL_ADMIN && $session->user_logged_in ) { @@ -361,9 +611,9 @@ $captcharesult = $session->get_captcha($_POST['captchahash']); $session->kill_captcha(); - if(strtolower($captcharesult) != strtolower($_POST['captchacode'])) + if ( strtolower($captcharesult) != strtolower($_POST['captchacode']) ) { - $s = 'The confirmation code you entered was incorrect.'; + $s = $lang->get('user_reg_err_captcha'); } else { @@ -371,6 +621,10 @@ { $s = 'Invalid COPPA input'; } + else if ( !empty($terms) && !isset($_POST['tou_agreed']) ) + { + $s = $lang->get('user_reg_err_accept_tou'); + } else { $coppa = ( isset($_POST['coppa']) && $_POST['coppa'] == 'yes' ); @@ -387,7 +641,7 @@ $crypt_key = $session->fetch_public_key($_POST['crypt_key']); if ( !$crypt_key ) { - $s = 'Couldn\'t look up public encryption key'; + $s = $lang->get('user_reg_err_missing_key'); } else { @@ -414,28 +668,28 @@ { case "none": default: - $str = 'You may now log in with the username and password that you created.'; + $str = $lang->get('user_reg_msg_success_activ_none', array('login_link' => makeUrlNS('Special', 'Login', false, true))); break; case "user": - $str = 'Because this site requires account activation, you have been sent an e-mail with further instructions. Please follow the instructions in that e-mail to continue your registration.'; + $str = $lang->get('user_reg_msg_success_activ_user'); break; case "admin": - $str = 'Because this site requires administrative account activation, you cannot use your account at the moment. A notice has been sent to the site administration team that will alert them that your account has been created.'; + $str = $lang->get('user_reg_msg_success_activ_admin'); break; } - die_friendly('Registration successful', '

Thank you for registering, your user account has been created. '.$str.'

'); + die_friendly($lang->get('user_reg_msg_success_title'), '

' . $lang->get('user_reg_msg_success_body') . ' ' . $str . '

'); } else if ( $s == 'success' && $coppa ) { - $str = 'However, in compliance with the Childrens\' Online Privacy Protection Act, you must have your parent or legal guardian activate your account. Please ask them to check their e-mail for further information.'; - die_friendly('Registration successful', '

Thank you for registering, your user account has been created. '.$str.'

'); + $str = $lang->get('user_reg_msg_success_activ_coppa'); + die_friendly($lang->get('user_reg_msg_success_title'), '

' . $lang->get('user_reg_msg_success_body') . ' ' . $str . '

'); } $username = htmlspecialchars($_POST['username']); $email = htmlspecialchars($_POST['email']); $realname = htmlspecialchars($_POST['real_name']); } $template->header(); - echo 'A user account enables you to have greater control over your browsing experience.'; + echo $lang->get('user_reg_msg_greatercontrol'); if ( getConfig('enable_coppa') != '1' || ( isset($_GET['coppa']) && in_array($_GET['coppa'], array('yes', 'no')) ) ) { @@ -447,49 +701,49 @@ $challenge = $session->dss_rand(); ?> -

Create a user account

- +

get('user_reg_msg_table_title'); ?>

+
- + '; ?> - @@ -507,29 +761,35 @@ + + + + + + + + + + + + + + @@ -605,6 +899,18 @@ var frm = document.forms.regform; if ( frm.password.value.length < 1 ) return true; + pass1 = frm.password.value; + pass2 = frm.password_confirm.value; + if ( pass1 != pass2 ) + { + alert($lang.get('user_reg_err_alert_password_nomatch')); + return false; + } + if ( pass1.length < 6 && pass1.length > 0 ) + { + alert($lang.get('user_reg_err_alert_password_tooshort')); + return false; + } if(aes_testpassed) { frm.use_crypt.value = 'yes'; @@ -617,21 +923,6 @@ len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : ''; alert('The key is messed up\nType: '+typeof(cryptkey)+len); } - } - pass1 = frm.password.value; - pass2 = frm.password_confirm.value; - if ( pass1 != pass2 ) - { - alert('The passwords you entered do not match.'); - return false; - } - if ( pass1.length < 6 && pass1.length > 0 ) - { - alert('The new password must be 6 characters or greater in length.'); - return false; - } - if(aes_testpassed) - { pass = frm.password.value; pass = stringToByteArray(pass); cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB'); @@ -653,24 +944,37 @@ ' : ''; - $pw_blurb = ( getConfig('pw_strength_enable') == '1' && intval(getConfig('pw_strength_minimum')) > -10 ) ? '
Your password needs to have a score of at least '.getConfig('pw_strength_minimum').'.' : ''; + $pw_meter = ( getConfig('pw_strength_enable') == '1' ) ? '' : ''; + $pw_blurb = ( getConfig('pw_strength_enable') == '1' && intval(getConfig('pw_strength_minimum')) > -10 ) ? '
' . $lang->get('userfuncs_passreset_stage2_blurb_strength') . '' : ''; ?>
Please tell us a little bit about yourself.
get('user_reg_msg_table_subtitle'); ?>
'.$s.'
- Preferred username: + get('user_reg_lbl_field_username'); ?> - + - Good/bad icon + + Good/bad icon
- Password: + get('user_reg_lbl_field_password'); ?> -10 ): ?> - It needs to score at least for your registration to be accepted. + get('user_reg_msg_password_score'); ?> - Loading... + Loading... - Good/bad icon + Good/bad icon
- Enter your password again to confirm. + get('user_reg_lbl_field_password_confirm'); ?>
-mail address: + if ( $coppa ) + { + echo $lang->get('user_reg_lbl_field_email_coppa'); + } + else + { + echo $lang->get('user_reg_lbl_field_email'); + } + ?> An e-mail with an account activation key will be sent to this address, so please ensure that it is correct.'; + echo '
' . $lang->get('user_reg_msg_email_activuser') . ''; } ?>
- + - Good/bad icon + Good/bad icon
- Real name:
- Giving your real name is totally optional. If you choose to provide your real name, it will be used to provide attribution for any edits or contributions you may make to this site. + get('user_reg_lbl_field_realname'); ?>
+ get('user_reg_msg_realname_optional'); ?>
@@ -539,11 +799,11 @@
- Visual confirmation
+ get('user_reg_lbl_field_captcha'); ?>
- Please enter the code shown in the image to the right into the text box. This process helps to ensure that this registration is not being performed by an automated bot. If the image to the right is illegible, you can generate a new image.
+ get('user_reg_msg_captcha_pleaseenter', array('regen_flags' => 'href="#" onclick="regenCaptcha(); return false;"')); ?>

- If you are visually impaired or otherwise cannot read the text shown to the right, please contact the site management and they will create an account for you. + get('user_reg_msg_captcha_blind'); ?>
@@ -555,16 +815,50 @@
- Code: + get('user_reg_lbl_field_captcha_code'); ?>
+ get('user_reg_msg_please_read_tou'); + ?> +
+
+ +
+

+ +

+
- +
' . $lang->get('userfuncs_passreset_stage2_lbl_strength') . '
- - - + + + -
Reset password
Password:/>
Confirm:
get('userfuncs_passreset_stage2_th'); ?>
get('userfuncs_passreset_stage2_lbl_password'); ?> />
get('userfuncs_passreset_stage2_lbl_confirm'); ?>
+ - +
@@ -1217,12 +1629,12 @@ pass2 = frm.pass_confirm.value; if ( pass1 != pass2 ) { - alert('The passwords you entered do not match.'); + alert($lang.get('userfuncs_passreset_err_no_match')); return false; } if ( pass1.length < 6 ) { - alert('The new password must be 6 characters or greater in length.'); + alert($lang.get('userfuncs_passreset_err_too_short')); return false; } if(testpassed) @@ -1251,20 +1663,20 @@ { if($session->mail_password_reset($_POST['username'])) { - echo '

An e-mail has been sent to the e-mail address on file for your username with a new password in it. Please check your e-mail for further instructions.

'; + echo '

' . $lang->get('userfuncs_passreset_stage1_success') . '

'; } else { - echo '

Error occured, your new password was not sent.

'; + echo '

' . $lang->get('userfuncs_passreset_stage1_error') . '

'; } $template->footer(); return true; } - echo '

Don\'t worry, it happens to the best of us.

-

To reset your password, just enter your username below, and a new password will be e-mailed to you.

+ echo '

' . $lang->get('userfuncs_passreset_blurb_line1') . '

+

' . $lang->get('userfuncs_passreset_blurb_line2') . '

-

Username: '.$template->username_field('username').'

-

+

' . $lang->get('userfuncs_passreset_lbl_username') . ' '.$template->username_field('username').'

+

'; $template->footer(); } @@ -1272,6 +1684,8 @@ function page_Special_Memberlist() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + $template->header(); $startletters = 'abcdefghijklmnopqrstuvwxyz'; @@ -1362,16 +1776,16 @@ # - Username + ' . $lang->get('userfuncs_ml_column_username') . ' - Title + ' . $lang->get('userfuncs_ml_column_userlevel') . ' - E-mail + ' . $lang->get('userfuncs_ml_column_email') . ' - Registered + ' . $lang->get('userfuncs_ml_column_regtime') . ' '; @@ -1385,8 +1799,16 @@ if ( !empty($finduser_url) ) { - $s = ( $num_rows == 1 ) ? '' : 'es'; - echo "

Search returned $num_rows match$s

"; + switch ( $num_rows ) + { + case 0: + $str = $lang->get('userfuncs_ml_msg_matches_zero'); break; + case 1: + $str = $lang->get('userfuncs_ml_msg_matches_one'); break; + default: + $str = $lang->get('userfuncs_ml_msg_matches', array('matches' => $num_rows)); break; + } + echo "

$str

"; } // main selector @@ -1425,14 +1847,16 @@
' . ( urlSeparator == '&' ? '' : '' ) . ( $session->sid_super ? '' : '') - . '

Find a member: ' . $template->username_field('finduser') . '
You may use the following wildcards: * to match multiple characters, ? to match a single character.

' + . '

' . $lang->get('userfuncs_ml_lbl_finduser') . ' ' . $template->username_field('finduser') . '
+ ' . $lang->get('userfuncs_ml_tip_wildcard') . '

' . '
' // Footer (printed after rows) ); if ( $num_rows < 1 ) { - echo ( isset($_GET['finduser']) ) ? '

Sorry - no users that matched your query could be found. Please try some different search terms.

' : '

Sorry - no users with usernames that start with that letter could be found.

'; + echo ( isset($_GET['finduser']) ) ? '

' . $lang->get('userfuncs_ml_err_nousers_find') . '

' : + '

' . $lang->get('userfuncs_ml_err_nousers') . '

'; } else { @@ -1452,37 +1876,41 @@ function username($username, $row) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + $userpage = $paths->nslist['User'] . sanitize_page_id($username); - $class = ( isPage($userpage) ) ? ' title="Click to view this user\'s userpage"' : ' class="wikilink-nonexistent" title="This user hasn\'t created a userpage yet, but you can still view profile details by clicking this link."'; + $class = ( isPage($userpage) ) ? ' title="' . $lang->get('userfuncs_ml_tip_userpage') . '"' : ' class="wikilink-nonexistent" title="' . $lang->get('userfuncs_ml_tip_nouserpage') . '"'; $anchor = '' . htmlspecialchars($username) . ''; if ( $session->user_level >= USER_LEVEL_ADMIN ) { $anchor .= ' - Administer user'; + onclick="ajaxAdminUser(\'' . addslashes(htmlspecialchars($username)) . '\'); return false;">' . $lang->get('userfuncs_ml_btn_adminuser') . ''; } return $anchor; } function user_level($level, $row) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; switch ( $level ) { case USER_LEVEL_GUEST: - $s_level = 'Guest'; break; + $s_level = $lang->get('userfuncs_ml_level_guest'); break; case USER_LEVEL_MEMBER: case USER_LEVEL_CHPREF: - $s_level = 'Member'; break; + $s_level = $lang->get('userfuncs_ml_level_member'); break; case USER_LEVEL_MOD: - $s_level = 'Moderator'; break; + $s_level = $lang->get('userfuncs_ml_level_mod'); break; case USER_LEVEL_ADMIN: - $s_level = 'Site administrator'; break; + $s_level = $lang->get('userfuncs_ml_level_admin'); break; default: - $s_level = 'Unknown (level ' . $level . ')'; + $s_level = $lang->get('userfuncs_ml_level_unknown', array( 'level' => $level )); } return $s_level; } function email($addy, $row) { + global $lang; if ( $row['email_public'] == '1' ) { global $email; @@ -1491,7 +1919,7 @@ } else { - return '<Non-public>'; + return '<' . $lang->get('userfuncs_ml_email_nonpublic') . '>'; } } /** @@ -1502,35 +1930,36 @@ function format_date($time) { - // Our formattting string to pass to date() + global $lang; + // Our formattting string to pass to enano_date() // This should not include minute/second info, only today's date in whatever format suits your fancy $formatstring = 'F j, Y'; // Today's date - $today = date($formatstring); + $today = enano_date($formatstring); // Yesterday's date - $yesterday = date($formatstring, (time() - (24*60*60))); + $yesterday = enano_date($formatstring, (time() - (24*60*60))); // Date on the input - $then = date($formatstring, $time); + $then = enano_date($formatstring, $time); // "X days ago" logic for ( $i = 2; $i <= 6; $i++ ) { // hours_in_day * minutes_in_hour * seconds_in_minute * num_days $offset = 24 * 60 * 60 * $i; - $days_ago = date($formatstring, (time() - $offset)); + $days_ago = enano_date($formatstring, (time() - $offset)); // so does the input timestamp match the date from $i days ago? if ( $then == $days_ago ) { // yes, return $i - return "$i days ago"; + return $lang->get('userfuncs_ml_date_daysago', array('days_ago' => $i)); } } // either yesterday, today, or before 6 days ago switch($then) { case $today: - return 'Today'; + return $lang->get('userfuncs_ml_date_today'); case $yesterday: - return 'Yesterday'; + return $lang->get('userfuncs_ml_date_yesterday'); default: return $then; } @@ -1549,4 +1978,30 @@ } } +function page_Special_LangExportJSON() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + + $lang_id = ( $x = $paths->getParam(0) ) ? intval($x) : $lang->lang_id; + + if ( $lang->lang_id == $lang_id ) + $lang_local =& $lang; + else + $lang_local = new Language($lang_id); + + + $timestamp = enano_date('D, j M Y H:i:s T', $lang_local->lang_timestamp); + header("Last-Modified: $timestamp"); + header("Date: $timestamp"); + header('Content-type: text/javascript'); + + $lang_local->fetch(); + echo "if ( typeof(enano_lang) != 'object' ) + var enano_lang = new Object(); + +enano_lang[{$lang->lang_id}] = " . enano_json_encode($lang_local->strings) . ";"; + +} + ?> \ No newline at end of file diff -r d823e49e2e4e -r c433348f3628 plugins/SpecialUserPrefs.php --- a/plugins/SpecialUserPrefs.php Fri Feb 22 12:46:51 2008 -0500 +++ b/plugins/SpecialUserPrefs.php Fri Feb 22 12:51:53 2008 -0500 @@ -1,16 +1,16 @@ namespace != 'Special' || $paths->page_id != 'Preferences' ) return false; @@ -54,7 +55,7 @@ $template->toolbar_menu = ''; $button->assign_vars(array( - 'TEXT' => 'list of registered members', + 'TEXT' => $lang->get('usercp_btn_memberlist'), 'FLAGS' => '', 'PARENTFLAGS' => '', 'HREF' => makeUrlNS('Special', 'Memberlist') @@ -67,17 +68,28 @@ { global $userprefs_menu; global $userprefs_menu_links; + global $lang; $html = ''; $quot = '"'; foreach ( $userprefs_menu as $section => $buttons ) { - $html .= ( isset($userprefs_menu_links[$section]) ) ? "{$section}\n " : "{$section}\n "; + $section_name = $section; + if ( preg_match('/^[a-z]+_[a-z_]+$/', $section) ) + { + $section_name = $lang->get($section_name); + } + $html .= ( isset($userprefs_menu_links[$section]) ) ? "{$section_name}\n " : "{$section_name}\n "; $html .= "
    \n "; foreach ( $buttons as $button ) { - $html .= "
  • {$button['text']}
  • \n "; + $buttontext = $button['text']; + if ( preg_match('/^[a-z]+_[a-z_]+$/', $buttontext) ) + { + $buttontext = $lang->get($buttontext); + } + $html .= "
  • {$buttontext}
  • \n "; } $html .= "
\n "; } @@ -100,14 +112,29 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $userprefs_menu_links; - userprefs_menu_add('Profile/membership', 'Edit e-mail address and password', makeUrlNS('Special', 'Preferences/EmailPassword') . '" onclick="ajaxLoginNavTo(\'Special\', \'Preferences/EmailPassword\', '.USER_LEVEL_CHPREF.'); return false;'); - userprefs_menu_add('Profile/membership', 'Edit signature', makeUrlNS('Special', 'Preferences/Signature')); - userprefs_menu_add('Profile/membership', 'Edit public profile', makeUrlNS('Special', 'Preferences/Profile')); - userprefs_menu_add('Private messages', 'Inbox', makeUrlNS('Special', 'PrivateMessages/Folder/Inbox')); - userprefs_menu_add('Private messages', 'Outbox', makeUrlNS('Special', 'PrivateMessages/Folder/Outbox')); - userprefs_menu_add('Private messages', 'Sent items', makeUrlNS('Special', 'PrivateMessages/Folder/Sent')); - userprefs_menu_add('Private messages', 'Drafts', makeUrlNS('Special', 'PrivateMessages/Folder/Drafts')); - userprefs_menu_add('Private messages', 'Archive', makeUrlNS('Special', 'PrivateMessages/Folder/Archive')); + userprefs_menu_add('usercp_sec_profile', 'usercp_sec_profile_emailpassword', makeUrlNS('Special', 'Preferences/EmailPassword') . '" onclick="ajaxLoginNavTo(\'Special\', \'Preferences/EmailPassword\', '.USER_LEVEL_CHPREF.'); return false;'); + userprefs_menu_add('usercp_sec_profile', 'usercp_sec_profile_signature', makeUrlNS('Special', 'Preferences/Signature')); + userprefs_menu_add('usercp_sec_profile', 'usercp_sec_profile_publicinfo', makeUrlNS('Special', 'Preferences/Profile')); + userprefs_menu_add('usercp_sec_profile', 'usercp_sec_profile_usergroups', makeUrlNS('Special', 'Usergroups')); + if ( getConfig('avatar_enable') == '1' ) + { + userprefs_menu_add('usercp_sec_profile', 'usercp_sec_profile_avatar', makeUrlNS('Special', 'Preferences/Avatar')); + } + userprefs_menu_add('usercp_sec_pm', 'usercp_sec_pm_inbox', makeUrlNS('Special', 'PrivateMessages/Folder/Inbox')); + userprefs_menu_add('usercp_sec_pm', 'usercp_sec_pm_outbox', makeUrlNS('Special', 'PrivateMessages/Folder/Outbox')); + userprefs_menu_add('usercp_sec_pm', 'usercp_sec_pm_sent', makeUrlNS('Special', 'PrivateMessages/Folder/Sent')); + userprefs_menu_add('usercp_sec_pm', 'usercp_sec_pm_drafts', makeUrlNS('Special', 'PrivateMessages/Folder/Drafts')); + userprefs_menu_add('usercp_sec_pm', 'usercp_sec_pm_archive', makeUrlNS('Special', 'PrivateMessages/Folder/Archive')); + + /* + // Reserved for Enano's Next Big Innovation.(TM) + userprefs_menu_add('Private messages', 'Inbox', makeUrlNS('Special', 'Private_Messages#folder:inbox')); + userprefs_menu_add('Private messages', 'Starred', makeUrlNS('Special', 'Private_Messages#folder:starred')); + userprefs_menu_add('Private messages', 'Sent items', makeUrlNS('Special', 'Private_Messages#folder:sent')); + userprefs_menu_add('Private messages', 'Drafts', makeUrlNS('Special', 'Private_Messages#folder:drafts')); + userprefs_menu_add('Private messages', 'Archive', makeUrlNS('Special', 'Private_Messages#folder:archive')); + userprefs_menu_add('Private messages', 'Trash', makeUrlNS('Special', 'Private_Messages#folder:trash')); + */ $userprefs_menu_links['Profile/membership'] = makeUrlNS('Special', 'Preferences'); $userprefs_menu_links['Private messages'] = makeUrlNS('Special', 'PrivateMessages'); @@ -119,11 +146,13 @@ } } -$plugins->attachHook('session_started', 'userprefs_menu_init();'); +$plugins->attachHook('common_post', 'userprefs_menu_init();'); function page_Special_Preferences() { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + global $timezone; // We need a login to continue if ( !$session->user_logged_in ) @@ -171,7 +200,7 @@ case 'foo': if ( $_POST['newemail'] != $_POST['newemail_conf'] ) { - $errors .= '
The e-mail addresses you entered did not match.
'; + $errors .= '
' . $lang->get('usercp_emailpassword_err_email_no_match') . '
'; break; } } @@ -187,9 +216,9 @@ $result = $session->update_user($session->user_id, false, $old_pass, false, $new_email); if ( $result != 'success' ) { - $message = '

The following errors were encountered while saving your e-mail address:

'; + $message = '

' . $lang->get('usercp_emailpassword_err_list') . '

'; $message .= '
  • ' . implode("
  • \n
  • ", $result) . '
'; - die_friendly('Error updating e-mail address', $message); + die_friendly($lang->get('usercp_emailpassword_err_title'), $message); } $email_changed = true; } @@ -213,16 +242,15 @@ if ( strlen($newpass) > 0 ) { if ( defined('ENANO_DEMO_MODE') ) - $errors .= '
You can\'t change your password in demo mode.
'; + $errors .= '
' . $lang->get('usercp_emailpassword_err_demo') . '
'; // Perform checks if ( strlen($newpass) < 6 ) - $errors .= '
Password must be at least 6 characters. You hacked my script, darn you!
'; + $errors .= '
' . $lang->get('usercp_emailpassword_err_password_too_short') . '
'; if ( getConfig('pw_strength_enable') == '1' ) { $score_inp = password_score($newpass); - $score_min = intval( getConfig('pw_strength_minimum') ); if ( $score_inp < $score_min ) - $errors .= '
Your password did not meet the complexity score requirement for this site. Your password scored '. $score_inp .', while a score of at least '. $score_min .' is needed.
'; + $errors .= '
' . $lang->get('usercp_emailpassword_err_password_too_weak', array('score' => $score_inp)) . '
'; } // Encrypt new password if ( empty($errors) ) @@ -239,15 +267,15 @@ { if ( getConfig('account_activation') == 'user' ) { - redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your password and e-mail address have been changed. Since e-mail activation is required on this site, you will need to re-activate your account to continue. An e-mail has been sent to the new e-mail address with an activation link. You must click that link in order to log in again.', 19); + redirect(makeUrl(getConfig('main_page')), $lang->get('usercp_emailpassword_msg_profile_success'), $lang->get('usercp_emailpassword_msg_need_activ_user'), 20); } else if ( getConfig('account_activation') == 'admin' ) { - redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your password and e-mail address have been changed. Since administrative activation is requires on this site, a request has been sent to the administrators to activate your account for you. You will not be able to use your account until it is activated by an administrator.', 19); + redirect(makeUrl(getConfig('main_page')), $lang->get('usercp_emailpassword_msg_profile_success'), $lang->get('usercp_emailpassword_msg_need_activ_admin'), 20); } } $session->login_without_crypto($session->username, $newpass); - redirect(makeUrlNS('Special', 'Preferences'), 'Password changed', 'Your password has been changed, and you will now be redirected back to the user control panel.', 4); + redirect(makeUrlNS('Special', 'Preferences'), $lang->get('usercp_emailpassword_msg_pass_success'), $lang->get('usercp_emailpassword_msg_password_changed'), 5); } } } @@ -259,37 +287,39 @@ $pass = $_POST['newpass']; if ( $pass != $_POST['newpass_conf'] ) { - $errors .= '
The passwords you entered did not match
'; + $errors .= '
' . $lang->get('usercp_emailpassword_err_password_no_match') . '
'; break; } + $session->logout(); if ( $email_changed ) { if ( getConfig('account_activation') == 'user' ) { - redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your e-mail address has been changed. Since e-mail activation is required on this site, you will need to re-activate your account to continue. An e-mail has been sent to the new e-mail address with an activation link. You must click that link in order to log in again.', 19); + redirect(makeUrl(getConfig('main_page')), $lang->get('usercp_emailpassword_msg_profile_success'), $lang->get('usercp_emailpassword_msg_need_activ_user'), 20); } else if ( getConfig('account_activation') == 'admin' ) { - redirect(makeUrl(getConfig('main_page')), 'Profile changed', 'Your e-mail address has been changed. Since administrative activation is requires on this site, a request has been sent to the administrators to activate your account for you. You will not be able to use your account until it is activated by an administrator.', 19); + redirect(makeUrl(getConfig('main_page')), $lang->get('usercp_emailpassword_msg_profile_success'), $lang->get('usercp_emailpassword_msg_need_activ_admin'), 20); } - else - { - redirect(makeUrlNS('Special', 'Preferences'), 'Password changed', 'Your e-mail address has been changed, and you will now be redirected back to the user control panel.', 4); - } + } + else + { + $session->login_without_crypto($session->username, $newpass); + redirect(makeUrlNS('Special', 'Preferences'), $lang->get('usercp_emailpassword_msg_pass_success'), $lang->get('usercp_emailpassword_msg_password_changed'), 5); } return; } } } - $template->tpl_strings['PAGE_NAME'] = 'Change E-mail Address or Password'; + $template->tpl_strings['PAGE_NAME'] = $lang->get('usercp_emailpassword_title'); break; case 'Signature': - $template->tpl_strings['PAGE_NAME'] = 'Editing signature'; + $template->tpl_strings['PAGE_NAME'] = $lang->get('usercp_signature_title'); break; case 'Profile': - $template->tpl_strings['PAGE_NAME'] = 'Editing public profile'; + $template->tpl_strings['PAGE_NAME'] = $lang->get('usercp_publicinfo_title'); break; } @@ -306,13 +336,14 @@ global $email; $userpage_id = $paths->nslist['User'] . sanitize_page_id($session->username); $userpage_exists = ( isPage($userpage_id) ) ? '' : ' class="wikilink-nonexistent"'; - $user_page = 'user page (comments)'; - $site_admin = $email->encryptEmail(getConfig('contact_email'), '', '', 'administrator'); - $make_one_now = 'make one now'; - echo "

$session->username, welcome to your control panel

"; - echo "

Here you can make changes to your profile, view statistics on yourself on this site, and set your preferences.

-

Your $user_page is your free writing space. You can use it to tell the other members of this site a little bit about yourself. If you haven't already made a user page, why not $make_one_now?

-

Use the menu at the top to navigate around. If you have any questions, you may contact the $site_admin."; + $user_page = makeUrlNS('User', sanitize_page_id($session->username)); + $site_admin = $email->encryptEmail(getConfig('contact_email'), '', '', $lang->get('usercp_intro_para3_admin_link')); + + echo '

' . $lang->get('usercp_intro_heading_main', array('username' => $session->username)) . '

'; + + echo '

' . $lang->get('usercp_intro_para1') . '

+

' . $lang->get('usercp_intro_para2', array('userpage_link' => $user_page)) . '

+

' . $lang->get('usercp_intro_para3', array('admin_contact_link' => $site_admin)) . '

'; break; case 'EmailPassword': @@ -328,30 +359,30 @@ $pubkey = $session->rijndael_genkey(); echo '
- Change password - Type a new password:
+ ' . $lang->get('usercp_emailpassword_grp_chpasswd') . ' + ' . $lang->get('usercp_emailpassword_field_newpass') . '
' . ( getConfig('pw_strength_enable') == '1' ? ' Loading...' : '' ) . '

- Type the password again to confirm:
+ ' . $lang->get('usercp_emailpassword_field_newpass_confirm') . '
' . ( getConfig('pw_strength_enable') == '1' ? '

- Your password needs to score at least '.getConfig('pw_strength_minimum').' in order to be accepted.' : '' ) . ' + ' . $lang->get('usercp_emailpassword_msg_password_min_score') . '' : '' ) . '

- Change e-mail address - New e-mail address:
+ ' . $lang->get('usercp_emailpassword_grp_chemail') . ' + ' . $lang->get('usercp_emailpassword_field_newemail') . '


- Confirm e-mail address:
+ ' . $lang->get('usercp_emailpassword_field_newemail_confirm') . '

-
'; +
'; echo ''; @@ -386,6 +417,20 @@ var frm = document.forms.empwform; if ( frm.newpass.value.length < 1 ) return true; + + pass1 = frm.newpass.value; + pass2 = frm.newpass_conf.value; + if ( pass1 != pass2 ) + { + alert($lang.get('usercp_emailpassword_err_password_no_match')); + return false; + } + if ( pass1.length < 6 && pass1.length > 0 ) + { + alert($lang.get('usercp_emailpassword_err_password_too_short')); + return false; + } + if(aes_testpassed) { frm.use_crypt.value = 'yes'; @@ -398,21 +443,6 @@ len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : ''; alert('The key is messed up\nType: '+typeof(cryptkey)+len); } - } - pass1 = frm.newpass.value; - pass2 = frm.newpass_conf.value; - if ( pass1 != pass2 ) - { - alert('The passwords you entered do not match.'); - return false; - } - if ( pass1.length < 6 && pass1.length > 0 ) - { - alert('The new password must be 6 characters or greater in length.'); - return false; - } - if(aes_testpassed) - { pass = frm.newpass.value; pass = stringToByteArray(pass); cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB'); @@ -441,11 +471,11 @@ if ( !$q ) $db->_die(); $session->signature = $sig; - echo '
Your signature has been saved.
'; + echo '
' . $lang->get('usercp_signature_msg_saved') . '
'; } echo '
'; echo $template->tinymce_textarea('new_sig', htmlspecialchars($session->signature)); - echo ''; + echo ''; echo '
'; break; case "Profile": @@ -454,6 +484,9 @@ $real_name = htmlspecialchars($_POST['real_name']); $real_name = $db->escape($real_name); + $timezone = intval($_POST['timezone']); + $tz_local = $timezone + 1440; + $imaddr_aim = htmlspecialchars($_POST['imaddr_aim']); $imaddr_aim = $db->escape($imaddr_aim); @@ -507,7 +540,7 @@ $session->user_extra['user_hobbies'] = $hobbies; $session->user_extra['email_public'] = intval($email_public); - $q = $db->sql_query('UPDATE '.table_prefix."users SET real_name='$real_name' WHERE user_id=$session->user_id;"); + $q = $db->sql_query('UPDATE '.table_prefix."users SET real_name='$real_name', user_timezone = $tz_local WHERE user_id=$session->user_id;"); if ( !$q ) $db->_die(); @@ -519,74 +552,144 @@ if ( !$q ) $db->_die(); - echo '
Your profile has been updated.
'; + // verify language id + $lang_id = strval(intval($_POST['lang_id'])); + $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . 'language WHERE lang_id = ' . $lang_id . ';'); + if ( !$q ) + $db->_die(); + + if ( $db->numrows() > 0 ) + { + $db->free_result(); + + // unload / reload $lang, this verifies that the selected language works + unset($GLOBALS['lang']); + unset($lang); + $lang_id = intval($lang_id); + $GLOBALS['lang'] = new Language($lang_id); + global $lang; + + $q = $db->sql_query('UPDATE ' . table_prefix . 'users SET user_lang = ' . $lang_id . " WHERE user_id = {$session->user_id};"); + if ( !$q ) + $db->_die(); + } + else + { + $db->free_result(); + } + + echo '
' . $lang->get('usercp_publicinfo_msg_save_success') . '
'; } + + $lang_box = ''; + + $tz_select = ''; + echo '
'; ?>
- + - + - + - - + + + + + + + + + + - + - + - + - + - + - + - + - + - +
Your public profileget('usercp_publicinfo_heading_main'); ?>
Please note that all of the information you enter here will be publicly viewable. All of the fields on this page are optional and may be left blank if you so desire.get('usercp_publicinfo_note_optional'); ?>
Real name:get('usercp_publicinfo_field_realname'); ?>
Change theme:If you don't like the look of the site, need a visual break, or are just curious, we might have some different themes for you to try out! Change my theme...get('usercp_publicinfo_field_language') . '
' . $lang->get('usercp_publicinfo_field_language_hint') . ''; ?>
get('usercp_publicinfo_field_changetheme_title'); ?>get('usercp_publicinfo_field_changetheme_hint'); ?> get('usercp_publicinfo_field_changetheme'); ?>
get('usercp_publicinfo_field_timezone'); ?>
get('usercp_publicinfo_field_timezone_hint'); ?>
- Instant messenger contact information + get('usercp_publicinfo_th_im'); ?>
AIM handle:get('usercp_publicinfo_field_aim'); ?>
WLM handle:
If you don't specify the domain (@whatever.com), "@hotmail.com" will be assumed.
get('usercp_publicinfo_field_wlm'); ?>
Yahoo! IM handle:get('usercp_publicinfo_field_yim'); ?>
Jabber/XMPP handle:get('usercp_publicinfo_field_xmpp'); ?>
- Extra contact information + get('usercp_publicinfo_th_contact'); ?>
Your homepage:
Please remember the http:// prefix.
get('usercp_publicinfo_field_homepage'); ?>
Your location:get('usercp_publicinfo_field_location'); ?>
Your job:get('usercp_publicinfo_field_job'); ?>
Your hobbies:get('usercp_publicinfo_field_hobbies'); ?>

If this is checked, your e-mail address will be displayed on your user page. To protect your address from spambots, your e-mail address will be encrypted.

get('usercp_publicinfo_field_email_public_hint'); ?>
user_extra['email_public'] == 1) echo 'checked="checked"'; ?> size="30" />
- +
@@ -594,6 +697,276 @@ '; break; + case 'Avatar': + if ( getConfig('avatar_enable') != '1' ) + { + echo '
' . $lang->get('usercp_avatar_err_disabled_title') . '
' . $lang->get('usercp_avatar_err_disabled_body') . '
'; + } + + // Determine current avatar + $q = $db->sql_query('SELECT user_has_avatar, avatar_type FROM ' . table_prefix . 'users WHERE user_id = ' . $session->user_id . ';'); + if ( !$q ) + $db->_die('Avatar CP selecting user\'s avatar data'); + + list($has_avi, $avi_type) = $db->fetchrow_num(); + + if ( isset($_POST['submit']) ) + { + $action = ( isset($_POST['avatar_action']) ) ? $_POST['avatar_action'] : 'keep'; + $avi_path = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $session->user_id . '.' . $avi_type; + switch($action) + { + case 'keep': + default: + break; + case 'remove': + if ( $has_avi ) + { + // First switch the avatar off + $q = $db->sql_query('UPDATE ' . table_prefix . 'users SET user_has_avatar = 0 WHERE user_id = ' . $session->user_id . ';'); + if ( !$q ) + $db->_die('Avatar CP switching user avatar off'); + + if ( @unlink($avi_path) ) + { + echo '
' . $lang->get('usercp_avatar_delete_success') . '
'; + } + $has_avi = 0; + } + break; + case 'set_http': + case 'set_file': + // Hackish way to preserve the UNIX philosophy of reusing as much code as possible + if ( $action == 'set_http' ) + { + // Check if this action is enabled + if ( getConfig('avatar_upload_http') !== '1' ) + { + // non-localized, only appears on hack attempt + echo '
Uploads over HTTP are disabled.
'; + break; + } + // Download the file + require_once( ENANO_ROOT . '/includes/http.php' ); + + if ( !preg_match('/^http:\/\/([a-z0-9-\.]+)(:([0-9]+))?\/(.+)$/', $_POST['avatar_http_url'], $match) ) + { + echo '
' . $lang->get('usercp_avatar_invalid_url') . '
'; + break; + } + + $hostname = $match[1]; + $uri = '/' . $match[4]; + $port = ( $match[3] ) ? intval($match[3]) : 80; + $max_size = intval(getConfig('avatar_max_size')); + + // Get temporary file + $tempfile = tempnam(false, "enanoavatar_{$session->user_id}"); + if ( !$tempfile ) + echo '
Error getting temp file.
'; + + @unlink($tempfile); + $request = new Request_HTTP($hostname, $uri, 'GET', $port); + $result = $request->write_response_to_file($tempfile, 50, $max_size); + if ( !$result || $request->response_code != HTTP_OK ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_bad_write') . '
'; + break; + } + + // Response written. Proceed to validation... + } + else + { + // Check if this action is enabled + if ( getConfig('avatar_upload_file') !== '1' ) + { + // non-localized, only appears on hack attempt + echo '
Uploads from the browser are disabled.
'; + break; + } + + $max_size = intval(getConfig('avatar_max_size')); + + $file =& $_FILES['avatar_file']; + $tempfile =& $file['tmp_name']; + if ( filesize($tempfile) > $max_size ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_file_too_large') . '
'; + break; + } + } + $file_type = get_image_filetype($tempfile); + if ( !$file_type ) + { + unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_bad_filetype') . '
'; + break; + } + + $avi_path_new = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $session->user_id . '.' . $file_type; + + // The file type is good - validate dimensions and animation + switch($file_type) + { + case 'png': + $is_animated = is_png_animated($tempfile); + $dimensions = png_get_dimensions($tempfile); + break; + case 'gif': + $is_animated = is_gif_animated($tempfile); + $dimensions = gif_get_dimensions($tempfile); + break; + case 'jpg': + $is_animated = false; + $dimensions = jpg_get_dimensions($tempfile); + break; + default: + echo '
API mismatch
'; + break 2; + } + // Did we get invalid size data? If so the image is probably corrupt. + if ( !$dimensions ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_corrupt_image') . '
'; + break; + } + // Is the image animated? + if ( $is_animated && getConfig('avatar_enable_anim') !== '1' ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_disallowed_animation') . '
'; + break; + } + // Check image dimensions + list($image_x, $image_y) = $dimensions; + $max_x = intval(getConfig('avatar_max_width')); + $max_y = intval(getConfig('avatar_max_height')); + if ( $image_x > $max_x || $image_y > $max_y ) + { + @unlink($tempfile); + echo '
' . $lang->get('usercp_avatar_too_large') . '
'; + break; + } + // All good! + @unlink($avi_path); + if ( rename($tempfile, $avi_path_new) ) + { + $q = $db->sql_query('UPDATE ' . table_prefix . "users SET user_has_avatar = 1, avatar_type = '$file_type' WHERE user_id = {$session->user_id};"); + if ( !$q ) + $db->_die('Avatar CP updating users table after successful avatar upload'); + $has_avi = 1; + $avi_type = $file_type; + echo '
' . $lang->get('usercp_avatar_upload_success') . '
'; + } + else + { + echo '
' . $lang->get('usercp_avatar_move_failed') . '
'; + } + break; + } + } + + ?> + + fullpage) . '" method="post" enctype="multipart/form-data">'; + echo '
'; + echo ''; + echo ' + + '; + + echo ' + + + '; + + echo ' + + + '; + + echo ' + + '; + + echo '
+ ' . $lang->get('usercp_avatar_table_title') . ' +
+ ' . $lang->get('usercp_avatar_label_current') . ' + '; + + if ( $has_avi == 1 ) + { + echo '' . $lang->get('usercp_avatar_image_alt', array('username' => $session->username)) . ''; + } + else + { + echo $lang->get('usercp_avatar_image_none'); + } + + echo '
+ ' . $lang->get('usercp_avatar_lbl_change') . ' + +
+
'; + if ( getConfig('avatar_upload_http') == '1' ) + { + echo '
+ '; + } + else + { + echo ' '; + } + if ( getConfig('avatar_upload_file') == '1' ) + { + echo ' + '; + } + else + { + echo ' '; + } + echo '
+ +
+
'; + + break; default: $good = false; $code = $plugins->setHook('userprefs_body'); diff -r d823e49e2e4e -r c433348f3628 plugins/admin/GroupManager.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/admin/GroupManager.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,383 @@ +auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; + return; + } + + if(isset($_POST['do_create_stage1'])) + { + if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name'])) + { + echo '

' . $lang->get('acpug_err_group_name_invalid') . '

'; + return; + } + echo ''; + echo '
+ + + + + + + + + +
' . $lang->get('acpug_heading_creating_group') . ' '.htmlspecialchars($_POST['create_group_name']).'
' . $lang->get('acpug_field_group_mod') . '' . $template->username_field('group_mod') . '
' . $lang->get('acpug_field_group_type') . ' +
+
+
+ +
+ + +
+
'; + echo ''; + return; + } + elseif(isset($_POST['do_create_stage2'])) + { + if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['create_group_name'])) + { + echo '

' . $lang->get('acpug_err_group_name_invalid') . '

'; + return; + } + if(!in_array(intval($_POST['group_status']), Array(GROUP_CLOSED, GROUP_OPEN, GROUP_HIDDEN, GROUP_REQUEST))) + { + echo '

Hacking attempt

'; + return; + } + $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';'); + if(!$e) + { + echo $db->get_error(); + return; + } + if($db->numrows() > 0) + { + echo '

' . $lang->get('acpug_err_already_exist') . '

'; + return; + } + $db->free_result(); + $q = $db->sql_query('INSERT INTO '.table_prefix.'groups(group_name,group_type) VALUES( \''.$db->escape($_POST['create_group_name']).'\', ' . intval($_POST['group_status']) . ' )'); + if(!$q) + { + echo $db->get_error(); + return; + } + $e = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['group_mod']).'\';'); + if(!$e) + { + echo $db->get_error(); + return; + } + if($db->numrows() < 1) + { + echo '

' . $lang->get('acpug_err_bad_username') . '

'; + return; + } + $row = $db->fetchrow(); + $id = $row['user_id']; + $db->free_result(); + $e = $db->sql_query('SELECT group_id FROM '.table_prefix.'groups WHERE group_name=\''.$db->escape($_POST['create_group_name']).'\';'); + if(!$e) + { + echo $db->get_error(); + return; + } + if($db->numrows() < 1) + { + echo '

' . $lang->get('acpug_err_bad_insert_id') . '

'; + return; + } + $row = $db->fetchrow(); + $gid = $row['group_id']; + $db->free_result(); + $e = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.$gid.', '.$id.', 1);'); + if(!$e) + { + echo $db->get_error(); + return; + } + $g_name = htmlspecialchars($_POST['create_group_name']); + echo "
+ " . $lang->get('acpug_heading_info') . "
+ " . $lang->get('acpug_msg_create_success', array('g_name' => $g_name)) . " +
"; + } + if(isset($_POST['do_edit']) || isset($_POST['edit_do'])) + { + // Fetch the group name + $q = $db->sql_query('SELECT group_name,system_group FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + if($db->numrows() < 1) + { + echo '

Error: couldn\'t look up group name

'; + } + $row = $db->fetchrow(); + $name = htmlspecialchars($row['group_name']); + $db->free_result(); + if(isset($_POST['edit_do'])) + { + if(isset($_POST['edit_do']['del_group'])) + { + if ( $row['system_group'] == 1 ) + { + echo '
' . $lang->get('acpug_err_nodelete_system_group', array('g_name' => $name)) . '
'; + } + else + { + $q = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + $q = $db->sql_query('DELETE FROM '.table_prefix.'groups WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + echo '
' . $lang->get('acpug_msg_delete_success', array('g_name' => $name, 'a_flags' => 'href="javascript:ajaxPage(\'' . $paths->nslist['Admin'] . 'GroupManager\');"')) . '
'; + return; + } + } + if(isset($_POST['edit_do']['save_name'])) + { + if(!preg_match('/^([A-z0-9 -]+)$/', $_POST['group_name'])) + { + echo '

' . $lang->get('acpug_err_group_name_invalid') . '

'; + return; + } + $q = $db->sql_query('UPDATE '.table_prefix.'groups SET group_name=\''.$db->escape($_POST['group_name']).'\' + WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + else + { + echo '
+ ' . $lang->get('acpug_msg_name_update_success') . ' +
'; + } + $name = htmlspecialchars($_POST['group_name']); + + } + $q = $db->sql_query('SELECT member_id FROM '.table_prefix.'group_members + WHERE group_id='.intval($_POST['group_edit_id']).';'); + if(!$q) + { + echo $db->get_error(); + return; + } + if($db->numrows() > 0) + { + while($row = $db->fetchrow($q)) + { + if(isset($_POST['edit_do']['del_' . $row['member_id']])) + { + $e = $db->sql_query('DELETE FROM '.table_prefix.'group_members WHERE member_id='.$row['member_id']); + if(!$e) + { + echo $db->get_error(); + return; + } + } + } + } + $db->free_result(); + if(isset($_POST['edit_do']['add_member'])) + { + $q = $db->sql_query('SELECT user_id FROM '.table_prefix.'users WHERE username=\''.$db->escape($_POST['edit_add_username']).'\';'); + if(!$q) + { + echo $db->get_error(); + return; + } + if($db->numrows() > 0) + { + $row = $db->fetchrow(); + $user_id = $row['user_id']; + $is_mod = ( isset( $_POST['add_mod'] ) ) ? '1' : '0'; + $q = $db->sql_query('INSERT INTO '.table_prefix.'group_members(group_id,user_id,is_mod) VALUES('.intval($_POST['group_edit_id']).','.$user_id.','.$is_mod.');'); + if(!$q) + { + echo $db->get_error(); + return; + } + else + { + echo '
+ ' . $lang->get('acpug_msg_user_added', array('username' => htmlspecialchars($_POST['edit_add_username']))) . ' +
'; + } + } + else + echo '
' . $lang->get('acpug_err_username_not_exist', array('username' => htmlspecialchars($_POST['edit_add_username']))) . '
'; + } + } + $sg_disabled = ( $row['system_group'] == 1 ) ? + ' value="' . $lang->get('acpug_btn_cant_delete') . '" disabled="disabled" style="color: #FF9773" ' : + ' value="' . $lang->get('acpug_btn_delete_group') . '" style="color: #FF3713" '; + echo '
'; + echo '
+ + + + + + + + +
' . $lang->get('acpug_heading_edit_name') . '
+ ' . $lang->get('acpug_field_group_name') . ' +
+ + +
+
+ '; + echo '
'; + echo '
'; + echo '
+ + '; + $q = $db->sql_query('SELECT m.member_id,m.is_mod,u.username FROM '.table_prefix.'group_members AS m + LEFT JOIN '.table_prefix.'users AS u + ON u.user_id=m.user_id + WHERE m.group_id='.intval($_POST['group_edit_id']).' + ORDER BY m.is_mod DESC, u.username ASC;'); + if(!$q) + { + echo $db->get_error(); + return; + } + if($db->numrows() < 1) + { + echo ''; + } + else + { + $cls = 'row2'; + while($row = $db->fetchrow()) + { + $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; + $mod = ( $row['is_mod'] == 1 ) ? $lang->get('acpug_lbl_member_mod') : ''; + echo ' + + + + '; + } + } + $db->free_result(); + echo '
' . $lang->get('acpug_heading_edit_members') . '
' . $lang->get('acpug_msg_no_members') . '
+ ' . $row['username'] . ' + + '.$mod.' + + +
+
+ '; + echo '
'; + echo '
'; + echo '
+ + + + + + + + + + + + + +
' . $lang->get('acpug_heading_add_member') . '
+ ' . $lang->get('acpug_field_username') . ' ' . $template->username_field('edit_add_username') . ' +
+ + ' . $lang->get('acpug_field_make_mod_hint') . ' +
+ +
+
+ '; + echo '
'; + return; + } + echo '

' . $lang->get('acpug_heading_main') . '

'; + echo '
'; + $q = $db->sql_query('SELECT group_id,group_name FROM '.table_prefix.'groups ORDER BY group_name ASC;'); + if(!$q) + { + echo $db->get_error(); + } + else + { + echo '
+ + + + '; + echo ''; + echo ' +
' . $lang->get('acpug_heading_edit_existing') . '
+
+

'; + } + echo '
'; + echo '
+ + + + '; + echo ''; + echo ' +
' . $lang->get('acpug_heading_create_new') . '
' . $lang->get('acpug_field_group_name') . '
+
'; + echo '
'; +} + +?> diff -r d823e49e2e4e -r c433348f3628 plugins/admin/LangManager.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/admin/LangManager.php Fri Feb 22 12:51:53 2008 -0500 @@ -0,0 +1,630 @@ +auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) + { + $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); + echo '

' . $lang->get('adm_err_not_auth_title') . '

'; + echo '

' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '

'; + return; + } + if ( isset($_POST['action']) ) + { + $action =& $_POST['action']; + // Parse parameters + if ( strpos($action, ';') ) + { + // Parameter section + $parms = substr($action, strpos($action, ';') + 1); + + // Action name section + $action = substr($action, 0, strpos($action, ';')); + + // Match all parameters + preg_match_all('/([a-z0-9_]+)=(.+?)(;|$)/', $parms, $matches); + $parms = array(); + + // For each full parameter, assign $parms an associative value + foreach ( $matches[0] as $i => $_ ) + { + $parm = $matches[2][$i]; + + // Is this parameter in the form of an integer? + // (designed to ease validation later) + if ( preg_match('/^[0-9]+$/', $parm) ) + // Yes, run intval(), this enabling is_int()-ish checks + $parm = intval($parm); + + $parms[$matches[1][$i]] = $parm; + } + } + switch ( $action ) + { + case 'install_language': + + if ( defined('ENANO_DEMO_MODE') ) + { + echo '
' . $lang->get('acplm_err_lang_install_demo') . '
'; + break; + } + + $lang_list = list_available_languages(); + // Verify that we have this language's metadata + if ( isset($lang_list[@$parms['iso639']]) ) + { + // From here it's all downhill :-) + $lang_code =& $parms['iso639']; + $lang_data =& $lang_list[$lang_code]; + + $result = install_language($lang_code, $lang_data['name_eng'], $lang_data['name']); + if ( $result ) + { + // Language installed. Import the language files. + $lang_local = new Language($lang_code); + if ( file_exists(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json") ) + { + $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json"); + } + else + { + foreach ( array('core', 'admin', 'tools', 'user') as $file ) + { + $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/$file.json"); + } + } + unset($lang_local); + + echo '
' . $lang->get('acplm_msg_lang_install_success', array('lang_name' => htmlspecialchars($lang_data['name_eng']))) . '
'; + } + } + break; + case 'modify_language': + + $lang_id =& $parms['lang_id']; + if ( !is_int($lang_id) ) + { + echo 'Hacking attempt'; + break; + } + + if ( isset($parms['finish']) && !empty($_POST['lang_name_native']) && !empty($_POST['lang_name_english']) && !defined('ENANO_DEMO_MODE') ) + { + // We just did validation above, it's safe to save. + $name_native = $db->escape($_POST['lang_name_native']); + $name_english = $db->escape($_POST['lang_name_english']); + + $q = $db->sql_query('UPDATE ' . table_prefix . "language SET lang_name_native = '$name_native', lang_name_default = '$name_english' WHERE lang_id = $lang_id;"); + if ( !$q ) + $db->_die(); + + echo '
' . $lang->get('acplm_msg_basic_save_success') . '
'; + } + else if ( isset($parms['finish']) && defined('ENANO_DEMO_MODE') ) + { + echo '
' . $lang->get('acplm_err_lang_install_demo') . '
'; + } + + // Select language data + $q = $db->sql_query('SELECT lang_name_native, lang_name_default, lang_code FROM ' . table_prefix . "language WHERE lang_id = $lang_id;"); + if ( !$q ) + $db->_die(); + + list($name_native, $name_english, $lang_code) = $db->fetchrow_num(); + + // Output properties table + echo '

' . $lang->get('acplm_heading_modify') . '

'; + + acp_start_form(); + + ?> +
+ + + + + + + + + + + + + + + + + + + +
+ get('acplm_th_lang_basic'); + ?> +
+ get('acplm_field_lang_name_native')); + ?> + + +
+ get('acplm_field_lang_name_english'); + ?> + + +
+ get('acplm_field_lang_code') . '
' + . '' . $lang->get('acplm_field_lang_code_hint') . ''; + ?> +
+ +
+ +
+
+ + + + +

get('acplm_heading_edit_strings_portal'); ?>

+

get('acplm_msg_edit_strings_portal_intro'); ?>

+ +

+ + lang_id == $lang_id ) + { + $lang_local =& $lang; + } + else + { + $lang_local = new Language($lang_id); + $lang_local->fetch(); + } + + $categories_loc = array(); + + // Using the & here ensures that a reference is created, thus avoiding wasting memory + foreach ( $lang_local->strings as $cat => &$_ ) + { + unset($_); + $categories_loc[$cat] = htmlspecialchars($lang->get("meta_$cat")); + } + + asort($categories_loc); + + echo ''; + + ?> + +

+ +

get('acplm_heading_reimport_portal'); ?>

+

get('acplm_msg_reimport_portal_intro'); ?>

+ +

+ +

+ + + + ' . $lang->get('acplm_heading_backup') . '

'; + echo '

' . $lang->get('acplm_backup_intro') . '

'; + + echo '
'; + echo ''; + echo '
'; + + return true; + case 'edit_strings': + + $cat_id = @$_POST['cat_id']; + if ( !preg_match('/^[a-z0-9]+$/', $cat_id) || !is_int(@$parms['lang_id']) ) + break; + + $lang_id =& $parms['lang_id']; + + if ( isset($parms['save']) && !defined('ENANO_DEMO_MODE') ) + { + // Grab a Language object + if ( $lang->lang_id == $lang_id ) + { + $lang_local =& $lang; + } + else + { + $lang_local = new Language($lang_id); + } + // Main save loop + // Trying to minimize queries as much as possible here, but you know how that goes. + $count_upd = 0; + foreach ( $_POST['string'] as $string_id => $user_content ) + { + $curr_content = $lang_local->get_uncensored("{$cat_id}_{$string_id}"); + if ( $curr_content != $user_content ) + { + $count_upd++; + $user_content = $db->escape($user_content); + $string_id = $db->escape($string_id); + $q = $db->sql_query('UPDATE ' . table_prefix . "language_strings SET string_content = '$user_content' WHERE lang_id = $lang_id AND string_category = '$cat_id' AND string_name = '$string_id';"); + if ( !$q ) + $db->_die(); + } + } + if ( $count_upd > 0 ) + { + // Update the cache + $lang_local->regen_caches(); + + // Update modification time + $q = $db->sql_query('UPDATE ' . table_prefix . "language SET last_changed = " . time() . " WHERE lang_id = $lang_id;"); + if ( !$q ) + $db->_die(); + } + + echo '
' . $lang->get('acplm_msg_string_save_success') . '
'; + } + else if ( isset($parms['save']) && defined('ENANO_DEMO_MODE') ) + { + echo '
' . $lang->get('acplm_err_lang_install_demo') . '
'; + } + + acp_start_form(); + + $cat_name = $lang->get("meta_$cat_id"); + echo '

' . $lang->get('acplm_editor_heading', array('cat_name' => $cat_name)) . '

'; + + // Fetch all strings + // This is more efficient than iterating through $lang->strings, I think. + $q = $db->sql_query('SELECT string_id, string_name, string_content FROM ' . table_prefix . "language_strings WHERE string_category = '$cat_id' AND lang_id = $lang_id;"); + if ( !$q ) + $db->_die(); + + ?> +
+ + + + + + fetchrow_num() ) + { + list($string_id, $string_name, $string_content) = $row; + unset($row); + + echo ''; + + if ( strpos($string_content, "\n") ) + { + $editor = '
get('acplm_editor_col_string_name'); ?>get('acplm_editor_col_string_content'); ?>