diff --git a/code-snippets.php b/code-snippets.php index b195bc74..7e5c89cb 100644 --- a/code-snippets.php +++ b/code-snippets.php @@ -2,11 +2,11 @@ /* Plugin Name: Code Snippets - Plugin URI: http://wordpress.org/extend/plugins/code-snippets + Plugin URI: http://bungeshea.wordpress.com/plugins/code-snippets/ Description: Provides an easy-to-manage GUI interface for adding code snippets to your blog. Author: Shea Bunge - Version: 1.1 - Author URI: http://bungeshea.wordpress.com/plugins/code-snippets/ + Version: 1.2 + Author URI: http://bungeshea.wordpress.com/ License: GPLv3 or later Code Snippets - WordPress Plugin @@ -29,60 +29,50 @@ // Exit if accessed directly if ( !defined( 'ABSPATH' ) ) exit; -if( !class_exists('code_snippets') ) : +if( !class_exists('Code_Snippets') ) : -class code_snippets { +class Code_Snippets { - public $table_name = ''; - public $version = '0.1'; - public $current_version = ''; - public $plugin_url = ''; - public $plugin_dir = ''; - public $dirname = ''; - - public $manage_snippets_url = ''; - public $edit_snippets_url = ''; - public $uninstall_plugin_url = ''; + public $table = 'snippets'; + public $version = '1.2'; + + public $file; + public $plugin_dir; + public $plugin_url; + public $basename; - public $manage_snippets_page; - public $edit_snippets_page; - public $uninstall_plugin_page; + var $admin_manage_url = 'snippets'; + var $admin_edit_url = 'snippet'; - public function code_snippets(){ - $this->__construct(); - } - - function __construct() { - $this->setup_vars(); // initialise the varables - $this->setup_actions(); // run the actions and filters - $this->run_snippets(); // execute the snippets + public function Code_Snippets() { + $this->setup(); // initialise the varables and run the hooks + $this->create_table(); // create the snippet tables if they do not exist + $this->upgrade(); // check if we need to change some stuff + $this->run_snippets(); // execute the snippets } - function setup_vars(){ + function setup() { global $wpdb; - $this->table_name = $wpdb->prefix . 'snippets'; - $this->current_version = get_option( 'cs_db_version' ); - $this->file = __FILE__; - $this->basename = plugin_basename( $this->file ); - $this->plugin_dir = plugin_dir_path( $this->file ); - $this->plugin_url = plugin_dir_url ( $this->file ); - $this->dirname = dirname( $this->file ); - $this->manage_snippets_url = admin_url( 'admin.php?page=snippets' ); - $this->edit_snippets_url = admin_url( 'admin.php?page=snippet-new' ); - $this->uninstall_plugin_url = admin_url( 'admin.php?page=uninstall-cs' ); - } + $this->file = __FILE__; + $this->table = $wpdb->prefix . $this->table; + $this->current_version = get_option( 'cs_db_version' ); + + $this->basename = plugin_basename( $this->file ); + $this->plugin_dir = plugin_dir_path( $this->file ); + $this->plugin_url = plugin_dir_url ( $this->file ); - private function setup_actions(){ - add_action( 'activate_' . $this->basename, array( &$this, 'install' ) ); - add_action( 'deactivate_' . $this->basename, array( &$this, 'uninstall' ) ); - add_action( 'admin_menu', array( &$this, 'add_admin_menus' ) ); - add_filter( 'plugin_action_links', array( $this, 'settings_link' ), 10, 2 ); + $this->admin_manage_url = admin_url( 'admin.php?page=' . $this->admin_manage_url ); + $this->admin_edit_url = admin_url( 'admin.php?page=' . $this->admin_edit_url ); + + add_action( 'admin_menu', array( $this, 'add_admin_menus' ) ); + add_filter( 'plugin_action_links_' . $this->basename, array( $this, 'settings_link' ) ); + add_filter( 'plugin_row_meta', array( $this, 'plugin_meta' ), 10, 2 ); } - function install() { + function create_table() { global $wpdb; - if($wpdb->get_var("SHOW TABLES LIKE '$this->table_name'") != $this->table_name) { - $sql = 'CREATE TABLE ' . $this->table_name . ' ( + if( $wpdb->get_var( "SHOW TABLES LIKE '$this->table'" ) != $this->table ) { + $sql = 'CREATE TABLE ' . $this->table . ' ( id mediumint(9) NOT NULL AUTO_INCREMENT, name varchar(36) NOT NULL, description text NOT NULL, @@ -96,42 +86,36 @@ function install() { } } - function uninstall() { - if( get_option( 'cs_complete_uninstall', 0 ) == 1 ) { - global $wpdb; - if( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name ) { - $sql = 'DROP TABLE ' . $table_name; - $wpdb->query( $sql ); - delete_option( 'cs_db_version' ); - delete_option( 'cs_complete_uninstall' ); - } + function upgrade() { + if( $this->current_version < $this->version ) { + delete_option( 'cs_complete_uninstall' ); + update_option( 'cs_db_version', $this->version ); } } function add_admin_menus() { - $this->manage_snippets_page = add_menu_page( 'Snippets', 'Snippets', 'install_plugins', 'snippets', array( &$this, 'manage_snippets' ), $this->plugin_url . 'img/icon16.png', 67 ); - add_submenu_page('snippets', 'Snippets', 'Manage Snippets' , 'install_plugins', 'snippets', array( &$this, 'manage_snippets') ); - $this->edit_snippets_page = add_submenu_page( 'snippets', 'Add New Snippet', 'Add New', 'install_plugins', 'snippet-new', array( &$this, 'edit_snippets' ) ); - $this->uninstall_plugin_page = add_submenu_page( 'snippets', 'Uninstall Code Snippets', 'Uninstall', 'install_plugins', 'uninstall-cs', array( &$this, 'uninstall_plugin' ) ); + $this->admin_manage_page = add_menu_page( __('Snippets'), __('Snippets'), 'install_plugins', 'snippets', array( $this, 'admin_manage_loader' ), $this->plugin_url . 'images/icon16.png', 67 ); + add_submenu_page('snippets', __('Snippets'), __('Manage Snippets') , 'install_plugins', 'snippets', array( $this, 'admin_manage_loader') ); + $this->admin_edit_page = add_submenu_page( 'snippets', __('Add New Snippet'), __('Add New'), 'install_plugins', 'snippet', array( $this, 'admin_edit_loader' ) ); - add_action( 'admin_print_styles-' . $this->manage_snippets_page, array( $this, 'load_stylesheet' ), 5 ); - add_action( 'admin_print_styles-' . $this->edit_snippets_page, array( $this, 'load_stylesheet' ), 5 ); - add_action( 'admin_print_styles-' . $this->uninstall_plugin_page, array( $this, 'load_stylesheet' ), 5 ); - add_action( 'admin_print_scripts-' . $this->edit_snippets_page, array( $this, 'load_tabby' ), 5 ); - add_action( 'load-' . $this->manage_snippets_page, array( $this, 'manage_snippets_help' ), 5 ); - add_action( 'load-' . $this->edit_snippets_page, array( $this, 'edit_snippets_help' ), 5 ); - add_action( 'load-' . $this->uninstall_plugin_page, array( $this, 'uninstall_plugin_help' ), 5 ); + add_action( "admin_print_styles-$this->admin_manage_page", array( $this, 'load_stylesheet' ), 5 ); + add_action( "admin_print_styles-$this->admin_edit_page", array( $this, 'load_stylesheet' ), 5 ); + add_action( "admin_print_scripts-$this->admin_edit_page", array( $this, 'load_editarea' ), 5 ); + add_action( "load-$this->admin_manage_page", array( $this, 'admin_manage_help' ), 5 ); + add_action( "load-$this->admin_edit_page", array( $this, 'admin_edit_help' ), 5 ); } - + function load_stylesheet() { wp_enqueue_style('code-snippets-admin-style', plugins_url( 'css/style.css', $this->file), false, $this->version ); } - - function load_tabby() { - wp_enqueue_script( 'tabby', plugins_url( 'js/jquery.textarea.js', $this->file), array( 'jquery' ), 0.12 ); + + function load_editarea() { + wp_register_script( 'editarea', plugins_url( 'includes/edit_area/edit_area_full.js', $this->file ), array( 'jquery' ), '0.8.2' ); + wp_enqueue_script( 'editarea' ); } - function manage_snippets_help() { + function admin_manage_help() { + $screen = get_current_screen(); $screen->add_help_tab( array( 'id' => 'overview', @@ -144,21 +128,33 @@ function manage_snippets_help() { 'title' => 'Troubleshooting', 'content' => "

Be sure to check your snippets for errors before you activate them as a faulty snippet could bring your whole blog down. If your site starts doing strange things, deactivate all your snippets and activate them one at a time.

" . - "

If something goes wrong with a snippet and you can’t use WordPress, you can use a database manager like phpMyAdmin to access the $this->table_name table in your WordPress database. Locate the offending snippet (if you know which one is the trouble) and change the 1 in the 'active' column into a 0. If this doesn't work try doing this for all snippets.

" + "

If something goes wrong with a snippet and you can’t use WordPress, you can use a database manager like phpMyAdmin to access the $this->table table in your WordPress database. Locate the offending snippet (if you know which one is the trouble) and change the 1 in the 'active' column into a 0. If this doesn't work try doing this for all snippets.
You can also delete or rename the $this->table table and the table will automaticly be reconstructed so you can re-add snippets one at a time.

" + ) ); + + $screen->add_help_tab( array( + 'id' => 'uninstall', + 'title' => 'Uninstall', + 'content' => + "

When you delete Code Snippets through the Plugins menu in WordPress it will clear up the $this->table table and a few other bits of data stored in the database. If you want to keep this data (ie you are only temporally uninstalling Code Snippets) then remove the ".dirname(__FILE__)." folder using FTP." . + "

Even if you're sure that you don't want to use Code Snippets ever again on this WordPress installaion, you may want to use phpMyAdmin to back up the $this->table table in the database. You can later use phpMyAdmin to import it back.

" ) ); $screen->set_help_sidebar( "

For more information:

" . "

WordPress Extend

" . "

Support Forums

" . - "

SheaPress

" + "

SheaPress

" ); } - function edit_snippets_help() { + function admin_edit_title( $title ) { + return str_ireplace( 'Add New Snippet', 'Edit Snippet', $title ); + } + + function admin_edit_help() { if( isset( $_GET['action'] ) && @$_GET['action'] == 'edit' ) - add_filter('admin_title', array( &$this, 'edit_snippets_title' ), 10, 2); + add_filter( 'admin_title', array( $this, 'admin_edit_title' ) ); $screen = get_current_screen(); $screen->add_help_tab( array( @@ -173,12 +169,23 @@ function edit_snippets_help() { 'content' => "

Here are some links to websites which host a large number of snippets that you can add to your site.

- Snippets can be installed through the Add New Snippet page or by addng them to the $this->table_name table in the database (Warning: for advanced users only). Once a snippet has been installed, you can activate it here.

" + And below is a selection of snippets to get you started: + + Snippets can be installed through the Add New Snippet page or by addng them to the $this->table table in the database (Warning: for advanced users only). Once a snippet has been installed, you can activate it here.

" ) ); $screen->add_help_tab( array( 'id' => 'adding', @@ -193,112 +200,69 @@ function edit_snippets_help() { "

For more information:

" . "

WordPress Extend

" . "

Support Forums

" . - "

SheaPress

" - ); - } - - function uninstall_plugin_help() { - $screen = get_current_screen(); - $screen->add_help_tab( array( - 'id' => 'overview', - 'title' => 'Overview', - 'content' => - "

If you are absolutly sure that you will never, ever want to use the Code Snippets plugin ever again in your entire life on this WordPress installation, you can use this page to tell Code Snippets to clear all of its data when deactivated. Simply check the box below and click on the submit button. If you realise what a cool plugin Code Snippets actually is before you get around to deactivating the plugin you can come back here and uncheck the box. If the box is selected when Code Snippets is deactivated it will clear up the $this->table_name table and a few other bits of data stored in the database.

" . - "

Even if you're sure that you don't want to use Code Snippets on this WordPress installaion, you may want to use phpMyAdmin to back up the $this->table_name table in the database. You can later use phpMyAdmin to import it back.

" - ) ); - - $screen->set_help_sidebar( - "

For more information:

" . - "

WordPress Extend

" . - "

Support Forums

" . - "

SheaPress

" + "

SheaPress

" ); } - function manage_snippets() { + function bulk_action( $action, $ids ) { + if( !isset( $action ) && !isset( $ids ) && !is_array( $ids ) ) + return false; global $wpdb; - $msg = ''; - if( isset( $_POST['action'] ) && isset( $_POST['snippets'] ) && is_array( $_POST['snippets'] ) ) { - $count = 0; - switch( $_POST['action'] ) { + $count = 0; + switch( $action ) { - case 'activate': - foreach($_POST['snippets'] as $bd) { - $wpdb->query('update ' . $this->table_name . ' set active=1 where id=' . intval( $bd ) . ' limit 1' ); - $count++; - } - $msg = "Activated $count snippets."; - break; + case 'activate': + foreach( $ids as $id ) { + $wpdb->query('update ' . $this->table . ' set active=1 where id=' . intval( $id ) . ' limit 1' ); + $count++; + } + $msg = "Activated $count snippets."; + break; - case 'deactivate': - foreach($_POST['snippets'] as $bd) { - $wpdb->query('update ' . $this->table_name . ' set active=0 where id=' . intval( $bd ) . ' limit 1' ); - $count++; - } - $msg = "Deactivated $count snippets."; - break; + case 'deactivate': + foreach( $ids as $id ) { + $wpdb->query( 'update ' . $this->table . ' set active=0 where id=' . intval( $id ) . ' limit 1' ); + $count++; + } + $msg = "Deactivated $count snippets."; + break; - case 'delete': - foreach( $_POST['snippets'] as $bd) { - $wpdb->query("delete from ".$wpdb->prefix."snippets where id=".intval($bd)." limit 1"); - $count++; - } - $msg = "Deleted $count snippets."; - break; - } + case 'delete': + foreach( $ids as $id ) { + $wpdb->query( 'delete from ' . $this->table . ' where id=' . intval( $id ) . ' limit 1' ); + $count++; + } + $msg = "Deleted $count snippets."; + break; } + } + + function admin_manage_loader() { + global $wpdb; - if( isset( $_POST['action2'] ) && isset( $_POST['snippets'] ) && is_array( $_POST['snippets'] ) ) { - $count = 0; - switch( $_POST['action2'] ) { - - case 'activate': - foreach($_POST['snippets'] as $bd) { - $wpdb->query('update ' . $this->table_name . ' set active=1 where id=' . intval( $bd ) . ' limit 1' ); - $count++; - } - $msg = "Activated $count snippets."; - break; - - case 'deactivate': - foreach($_POST['snippets'] as $bd) { - $wpdb->query('update ' . $this->table_name . ' set active=0 where id=' . intval( $bd ) . ' limit 1' ); - $count++; - } - $msg = "Deactivated $count snippets."; - break; - - case 'delete': - foreach( $_POST['snippets'] as $bd) { - $wpdb->query("delete from ".$wpdb->prefix."snippets where id=".intval($bd)." limit 1"); - $count++; - } - $msg = "Deleted $count snippets."; - break; - } - } + $this->bulk_action( @$_POST['action'], @$_POST['ids'] ); + $this->bulk_action( @$_POST['action2'], @$_POST['ids'] ); if( isset( $_GET['action'] ) && isset( $_GET['id'] ) ) { if( $_GET['action'] == 'delete') { - $wpdb->query( 'delete from ' . $this->table_name . ' where id=' . intval( $_GET['id'] ) . ' limit 1' ); + $wpdb->query( 'delete from ' . $this->table . ' where id=' . intval( $_GET['id'] ) . ' limit 1' ); $msg = 'Snippet deleted.'; } elseif( $_GET['action'] == 'activate' ) { - $wpdb->query('update ' . $this->table_name . ' set active=1 where id=' . intval( $_GET['id'] ) . ' limit 1' ); + $wpdb->query('update ' . $this->table . ' set active=1 where id=' . intval( $_GET['id'] ) . ' limit 1' ); $msg = 'Snippet activated.'; } elseif( $_GET['action'] == 'deactivate' ) { - $wpdb->query('update ' . $this->table_name . ' set active=0 where id=' . intval( $_GET['id'] ) . ' limit 1' ); + $wpdb->query('update ' . $this->table . ' set active=0 where id=' . intval( $_GET['id'] ) . ' limit 1' ); $msg = 'Snippet deactivated.'; } } - - require_once( $this->dirname . '/inc/manage-snippets.php'); + + require_once $this->plugin_dir . 'includes/admin-manage.php'; } - function edit_snippets() { + function admin_edit_loader() { global $wpdb; - $msg = ''; if( isset( $_POST['save_snippet'] ) ) { $name = mysql_real_escape_string( htmlspecialchars( $_POST['snippet_name' ] ) ); $description = mysql_real_escape_string( htmlspecialchars( $_POST['snippet_description'] ) ); @@ -306,14 +270,14 @@ function edit_snippets() { if( strlen( $name ) && strlen( $code ) ) { if( isset($_POST['edit_id'] ) ) { - $wpdb-> query( "update $this->table_name set name='".$name."', + $wpdb-> query( "update $this->table set name='".$name."', description='".$description."', code='".$code."' where id=" . intval($_POST["edit_id"]." limit 1")); $msg = 'Snippet updated.'; } else { - $wpdb->query( "insert into $this->table_name(name,description,code,active) VALUES ('$name','$description','$code',0)" ); + $wpdb->query( "insert into $this->table(name,description,code,active) VALUES ('$name','$description','$code',0)" ); $msg = 'Snippet added.'; } } @@ -321,62 +285,31 @@ function edit_snippets() { $msg = 'Please provide a name for the snippet and the code.'; } } - require_once( $this->dirname . '/inc/edit-snippets.php'); + require_once $this->plugin_dir . 'includes/admin-edit.php'; } - - function edit_snippets_title( $admin_title, $title ) { - - $title = 'Edit Snippet'; - - if ( is_network_admin() ) - $admin_title = __( 'Network Admin' ); - elseif ( is_user_admin() ) - $admin_title = __( 'Global Dashboard' ); - else - $admin_title = get_bloginfo( 'name' ); - - if ( $admin_title == $title ) - $admin_title = sprintf( __( '%1$s — WordPress' ), $title ); - else - $admin_title = sprintf( __( '%1$s ‹ %2$s — WordPress' ), $title, $admin_title ); - - return $admin_title; + + function settings_link( $links ) { + array_unshift( $links, '' . __('Manage') . '' ); + return $links; } - function uninstall_plugin(){ - $msg = ''; - if( isset( $_POST['uninstall'] ) ) { - if(isset( $_POST['ch_unin']) ) { - update_option('cs_complete_uninstall' , 1); - $msg = 'Option updated. Please deactivate the Code Snippets plugin to clear all data.'; - } - else { - update_option('cs_complete_uninstall', 0); - $msg = 'Option updated. Code Snippets will retain its data when deactivated'; - } - } - require_once( $this->dirname . '/inc/uninstall-plugin.php'); - } - - function settings_link( $links, $file ){ - static $this_plugin; - if ( ! $this_plugin ) { - $this_plugin = plugin_basename( __FILE__ ); - } - if ( $file == $this_plugin ) { - $settings_link = 'Settings'; - array_unshift( $links, $settings_link ); + function plugin_meta( $links, $file ) { + if ( $file == $this->basename ) { + return array_merge( $links, array( + '' . __( 'About' ) . '', + '' . __( 'Support' ) . '' + ) ); } return $links; } - + function run_snippets() { global $wpdb; // grab the active snippets from the database - $active_snippets = $wpdb->get_results( 'select * FROM `' . $this->table_name . '` WHERE `active` = 1;' ); + $active_snippets = $wpdb->get_results( 'select * FROM `' . $this->table . '` WHERE `active` = 1;' ); if( count( $active_snippets ) ) { foreach( $active_snippets as $snippet ) { - // execute the php code + // execute the php code $result = @eval( htmlspecialchars_decode( stripslashes( $snippet->code ) ) ); } } @@ -386,6 +319,12 @@ function run_snippets() { endif; // class exists check global $cs; -$cs = new code_snippets; +$cs = new Code_Snippets; + +register_uninstall_hook( __FILE__, 'cs_uninstall' ); -?> \ No newline at end of file +function cs_uninstall() { + global $wpdb, $cs; + $wpdb->query( "DROP TABLE IF EXISTS `$cs->table`" ); + delete_option( 'cs_db_version' ); +} \ No newline at end of file diff --git a/css/style.css b/css/style.css index 5d828b97..39c20b50 100644 --- a/css/style.css +++ b/css/style.css @@ -1,10 +1,10 @@ -#icon-snippets.icon32{ - background: url('../img/icon32.png') no-repeat scroll transparent; +#icon-snippets.icon32 { + background: url('../images/icon32.png') no-repeat scroll transparent; } /* Snippets > Manage Snippets */ -.inactive a:hover{ +.inactive a:hover { color: #d54e21; } @@ -13,17 +13,17 @@ a.delete:hover { border-bottom-color: #f00; } -a.delete{ +a.delete { color: #21759b; } -tr{ +tr { background-color: #fcfcfc; } .inactive, .inactive th, -.inactive td{ +.inactive td { background-color: #f4f4f4; } diff --git a/img/icon16.png b/images/icon16.png similarity index 100% rename from img/icon16.png rename to images/icon16.png diff --git a/img/icon32.png b/images/icon32.png similarity index 100% rename from img/icon32.png rename to images/icon32.png diff --git a/img/icon-big.png b/img/icon-big.png deleted file mode 100644 index 3889159d..00000000 Binary files a/img/icon-big.png and /dev/null differ diff --git a/img/icon-horiz.png b/img/icon-horiz.png deleted file mode 100644 index 2f383c66..00000000 Binary files a/img/icon-horiz.png and /dev/null differ diff --git a/img/icon-med.png b/img/icon-med.png deleted file mode 100644 index 7f13caaf..00000000 Binary files a/img/icon-med.png and /dev/null differ diff --git a/img/icon-small.png b/img/icon-small.png deleted file mode 100644 index 196cd0d8..00000000 Binary files a/img/icon-small.png and /dev/null differ diff --git a/img/icon.odg b/img/icon.odg deleted file mode 100644 index 23d41ef6..00000000 Binary files a/img/icon.odg and /dev/null differ diff --git a/img/icon.svg b/img/icon.svg deleted file mode 100644 index 37572988..00000000 --- a/img/icon.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - Clipart by Nicu Buculei - book_01 - - - - hash - - education - - - - - Nicu Buculei - - - - - Nicu Buculei - - - - - Nicu Buculei - - - - image/svg+xml - - - en - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/inc/uninstall-plugin.php b/inc/uninstall-plugin.php deleted file mode 100644 index 2a146ed9..00000000 --- a/inc/uninstall-plugin.php +++ /dev/null @@ -1,30 +0,0 @@ -
-

Uninstall Code Snippets

- -

- -

Checking this box will remove all snippets and the table from the database when the plugin is deactivated.

-

Only use if permanently uninstalling the Code Snippets plugin.

-

You can come back here before deactivating the plugin and change your choice.

-
- - style="margin-right: 5px" /> - -
- -
\ No newline at end of file diff --git a/inc/edit-snippets.php b/includes/admin-edit.php similarity index 68% rename from inc/edit-snippets.php rename to includes/admin-edit.php index 9c80ffc7..12b0a38c 100644 --- a/inc/edit-snippets.php +++ b/includes/admin-edit.php @@ -1,23 +1,25 @@

Edit SnippetAdd New

Edit SnippetAdd NewAdd New Snippet - +


- get_row( "SELECT * FROM `$this->table_name` WHERE `id` = '$id';" ); ?> + get_row( "SELECT * FROM `$this->table` WHERE `id` = '$id';" ); ?>

Code

Enter or paste the snippet code without the <?php and ?> tags.
- +

- description ) ), 'description', array( 'textarea_name' => 'snippet_description', 'textarea_rows' => 10 ) ); ?> + description ) ), 'description', array( 'textarea_name' => 'snippet_description', 'textarea_rows' => 10 ) ); ?>

- Cancel + Cancel

\ No newline at end of file diff --git a/inc/manage-snippets.php b/includes/admin-manage.php similarity index 56% rename from inc/manage-snippets.php rename to includes/admin-manage.php index 0381f296..e86feb2e 100644 --- a/inc/manage-snippets.php +++ b/includes/admin-manage.php @@ -1,10 +1,13 @@ - +
-

Snippets Add New

- +

Snippets Add New

+

- get_results( 'select * from ' . $this->table_name ); ?> + get_results( 'select * from ' . $this->table ); ?>
@@ -21,7 +24,7 @@ - Name + Name Description @@ -33,16 +36,16 @@ else echo 'active'; ?>'> - - name);?> + + name );?>
active == 0 ) : ?> - Activate | + Activate | - Deactivate | + Deactivate | - Edit | - Delete + Edit | + Delete
description ) ); ?> @@ -51,16 +54,23 @@   - You do not appear to have any snippets available at this time. + You do not appear to have any snippets available at this time. Add New→ + + + + Name + Description + +
diff --git a/includes/edit_area/autocompletion.js b/includes/edit_area/autocompletion.js new file mode 100644 index 00000000..3f174b2f --- /dev/null +++ b/includes/edit_area/autocompletion.js @@ -0,0 +1,491 @@ +/** + * Autocompletion class + * + * An auto completion box appear while you're writing. It's possible to force it to appear with Ctrl+Space short cut + * + * Loaded as a plugin inside editArea (everything made here could have been made in the plugin directory) + * But is definitly linked to syntax selection (no need to do 2 different files for color and auto complete for each syntax language) + * and add a too important feature that many people would miss if included as a plugin + * + * - init param: autocompletion_start + * - Button name: "autocompletion" + */ + +var EditArea_autocompletion= { + + /** + * Get called once this file is loaded (editArea still not initialized) + * + * @return nothing + */ + init: function(){ + // alert("test init: "+ this._someInternalFunction(2, 3)); + + if(editArea.settings["autocompletion"]) + this.enabled= true; + else + this.enabled= false; + this.current_word = false; + this.shown = false; + this.selectIndex = -1; + this.forceDisplay = false; + this.isInMiddleWord = false; + this.autoSelectIfOneResult = false; + this.delayBeforeDisplay = 100; + this.checkDelayTimer = false; + this.curr_syntax_str = ''; + + this.file_syntax_datas = {}; + } + /** + * Returns the HTML code for a specific control string or false if this plugin doesn't have that control. + * A control can be a button, select list or any other HTML item to present in the EditArea user interface. + * Language variables such as {$lang_somekey} will also be replaced with contents from + * the language packs. + * + * @param {string} ctrl_name: the name of the control to add + * @return HTML code for a specific control or false. + * @type string or boolean + */ + /*,get_control_html: function(ctrl_name){ + switch( ctrl_name ){ + case 'autocompletion': + // Control id, button img, command + return parent.editAreaLoader.get_button_html('autocompletion_but', 'autocompletion.gif', 'toggle_autocompletion', false, this.baseURL); + break; + } + return false; + }*/ + /** + * Get called once EditArea is fully loaded and initialised + * + * @return nothing + */ + ,onload: function(){ + if(this.enabled) + { + var icon= document.getElementById("autocompletion"); + if(icon) + editArea.switchClassSticky(icon, 'editAreaButtonSelected', true); + } + + this.container = document.createElement('div'); + this.container.id = "auto_completion_area"; + editArea.container.insertBefore( this.container, editArea.container.firstChild ); + + // add event detection for hiding suggestion box + parent.editAreaLoader.add_event( document, "click", function(){ editArea.plugins['autocompletion']._hide();} ); + parent.editAreaLoader.add_event( editArea.textarea, "blur", function(){ editArea.plugins['autocompletion']._hide();} ); + + } + + /** + * Is called each time the user touch a keyboard key. + * + * @param (event) e: the keydown event + * @return true - pass to next handler in chain, false - stop chain execution + * @type boolean + */ + ,onkeydown: function(e){ + if(!this.enabled) + return true; + + if (EA_keys[e.keyCode]) + letter=EA_keys[e.keyCode]; + else + letter=String.fromCharCode(e.keyCode); + // shown + if( this._isShown() ) + { + // if escape, hide the box + if(letter=="Esc") + { + this._hide(); + return false; + } + // Enter + else if( letter=="Entrer") + { + var as = this.container.getElementsByTagName('A'); + // select a suggested entry + if( this.selectIndex >= 0 && this.selectIndex < as.length ) + { + as[ this.selectIndex ].onmousedown(); + return false + } + // simply add an enter in the code + else + { + this._hide(); + return true; + } + } + else if( letter=="Tab" || letter=="Down") + { + this._selectNext(); + return false; + } + else if( letter=="Up") + { + this._selectBefore(); + return false; + } + } + // hidden + else + { + + } + + // show current suggestion list and do autoSelect if possible (no matter it's shown or hidden) + if( letter=="Space" && CtrlPressed(e) ) + { + //parent.console.log('SHOW SUGGEST'); + this.forceDisplay = true; + this.autoSelectIfOneResult = true; + this._checkLetter(); + return false; + } + + // wait a short period for check that the cursor isn't moving + setTimeout("editArea.plugins['autocompletion']._checkDelayAndCursorBeforeDisplay();", editArea.check_line_selection_timer +5 ); + this.checkDelayTimer = false; + return true; + } + /** + * Executes a specific command, this function handles plugin commands. + * + * @param {string} cmd: the name of the command being executed + * @param {unknown} param: the parameter of the command + * @return true - pass to next handler in chain, false - stop chain execution + * @type boolean + */ + ,execCommand: function(cmd, param){ + switch( cmd ){ + case 'toggle_autocompletion': + var icon= document.getElementById("autocompletion"); + if(!this.enabled) + { + if(icon != null){ + editArea.restoreClass(icon); + editArea.switchClassSticky(icon, 'editAreaButtonSelected', true); + } + this.enabled= true; + } + else + { + this.enabled= false; + if(icon != null) + editArea.switchClassSticky(icon, 'editAreaButtonNormal', false); + } + return true; + } + return true; + } + ,_checkDelayAndCursorBeforeDisplay: function() + { + this.checkDelayTimer = setTimeout("if(editArea.textarea.selectionStart == "+ editArea.textarea.selectionStart +") EditArea_autocompletion._checkLetter();", this.delayBeforeDisplay - editArea.check_line_selection_timer - 5 ); + } + // hide the suggested box + ,_hide: function(){ + this.container.style.display="none"; + this.selectIndex = -1; + this.shown = false; + this.forceDisplay = false; + this.autoSelectIfOneResult = false; + } + // display the suggested box + ,_show: function(){ + if( !this._isShown() ) + { + this.container.style.display="block"; + this.selectIndex = -1; + this.shown = true; + } + } + // is the suggested box displayed? + ,_isShown: function(){ + return this.shown; + } + // setter and getter + ,_isInMiddleWord: function( new_value ){ + if( typeof( new_value ) == "undefined" ) + return this.isInMiddleWord; + else + this.isInMiddleWord = new_value; + } + // select the next element in the suggested box + ,_selectNext: function() + { + var as = this.container.getElementsByTagName('A'); + + // clean existing elements + for( var i=0; i= as.length || this.selectIndex < 0 ) ? 0 : this.selectIndex; + as[ this.selectIndex ].className += " focus"; + } + // select the previous element in the suggested box + ,_selectBefore: function() + { + var as = this.container.getElementsByTagName('A'); + + // clean existing elements + for( var i=0; i= as.length || this.selectIndex < 0 ) ? as.length-1 : this.selectIndex; + as[ this.selectIndex ].className += " focus"; + } + ,_select: function( content ) + { + cursor_forced_position = content.indexOf( '{@}' ); + content = content.replace(/{@}/g, '' ); + editArea.getIESelection(); + + // retrive the number of matching characters + var start_index = Math.max( 0, editArea.textarea.selectionEnd - content.length ); + + line_string = editArea.textarea.value.substring( start_index, editArea.textarea.selectionEnd + 1); + limit = line_string.length -1; + nbMatch = 0; + for( i =0; i 0 ) + parent.editAreaLoader.setSelectionRange(editArea.id, editArea.textarea.selectionStart - nbMatch , editArea.textarea.selectionEnd); + + parent.editAreaLoader.setSelectedText(editArea.id, content ); + range= parent.editAreaLoader.getSelectionRange(editArea.id); + + if( cursor_forced_position != -1 ) + new_pos = range["end"] - ( content.length-cursor_forced_position ); + else + new_pos = range["end"]; + parent.editAreaLoader.setSelectionRange(editArea.id, new_pos, new_pos); + this._hide(); + } + + + /** + * Parse the AUTO_COMPLETION part of syntax definition files + */ + ,_parseSyntaxAutoCompletionDatas: function(){ + //foreach syntax loaded + for(var lang in parent.editAreaLoader.load_syntax) + { + if(!parent.editAreaLoader.syntax[lang]['autocompletion']) // init the regexp if not already initialized + { + parent.editAreaLoader.syntax[lang]['autocompletion']= {}; + // the file has auto completion datas + if(parent.editAreaLoader.load_syntax[lang]['AUTO_COMPLETION']) + { + // parse them + for(var i in parent.editAreaLoader.load_syntax[lang]['AUTO_COMPLETION']) + { + datas = parent.editAreaLoader.load_syntax[lang]['AUTO_COMPLETION'][i]; + tmp = {}; + if(datas["CASE_SENSITIVE"]!="undefined" && datas["CASE_SENSITIVE"]==false) + tmp["modifiers"]="i"; + else + tmp["modifiers"]=""; + tmp["prefix_separator"]= datas["REGEXP"]["prefix_separator"]; + tmp["match_prefix_separator"]= new RegExp( datas["REGEXP"]["prefix_separator"] +"$", tmp["modifiers"]); + tmp["match_word"]= new RegExp("(?:"+ datas["REGEXP"]["before_word"] +")("+ datas["REGEXP"]["possible_words_letters"] +")$", tmp["modifiers"]); + tmp["match_next_letter"]= new RegExp("^("+ datas["REGEXP"]["letter_after_word_must_match"] +")$", tmp["modifiers"]); + tmp["keywords"]= {}; + //console.log( datas["KEYWORDS"] ); + for( var prefix in datas["KEYWORDS"] ) + { + tmp["keywords"][prefix]= { + prefix: prefix, + prefix_name: prefix, + prefix_reg: new RegExp("(?:"+ parent.editAreaLoader.get_escaped_regexp( prefix ) +")(?:"+ tmp["prefix_separator"] +")$", tmp["modifiers"] ), + datas: [] + }; + for( var j=0; j it's valid + if( !match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length == 0 ) + { + if( ! before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) ) + hasMatch = true; + } + // we still need to check the prefix if there is one + else if( this.curr_syntax[i]["keywords"][prefix]['prefix'].length > 0 ) + { + if( before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) ) + hasMatch = true; + } + + if( hasMatch ) + results[results.length]= [ this.curr_syntax[i]["keywords"][prefix], this.curr_syntax[i]["keywords"][prefix]['datas'][j] ]; + } + } + } + } + // it doesn't match any possible word but we want to display something + // we'll display to list of all available words + else if( this.forceDisplay || match_prefix_separator ) + { + for(var prefix in this.curr_syntax[i]["keywords"]) + { + for(var j=0; j it's valid + if( !match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length == 0 ) + { + hasMatch = true; + } + // we still need to check the prefix if there is one + else if( match_prefix_separator && this.curr_syntax[i]["keywords"][prefix]['prefix'].length > 0 ) + { + var before = last_chars; //.substr( 0, last_chars.length ); + if( before.match( this.curr_syntax[i]["keywords"][prefix]['prefix_reg'] ) ) + hasMatch = true; + } + + if( hasMatch ) + results[results.length]= [ this.curr_syntax[i]["keywords"][prefix], this.curr_syntax[i]["keywords"][prefix]['datas'][j] ]; + } + } + } + } + } + + // there is only one result, and we can select it automatically + if( results.length == 1 && this.autoSelectIfOneResult ) + { + // console.log( results ); + this._select( results[0][1]['replace_with'] ); + } + else if( results.length == 0 ) + { + this._hide(); + } + else + { + // build the suggestion box content + var lines=[]; + for(var i=0; i"+ results[i][1]['comment']; + if(results[i][0]['prefix_name'].length>0) + line+=''+ results[i][0]['prefix_name'] +''; + line+=''; + lines[lines.length]=line; + } + // sort results + this.container.innerHTML = '
    '+ lines.sort().join('') +'
'; + + var cursor = _$("cursor_pos"); + this.container.style.top = ( cursor.cursor_top + editArea.lineHeight ) +"px"; + this.container.style.left = ( cursor.cursor_left + 8 ) +"px"; + this._show(); + } + + this.autoSelectIfOneResult = false; + time=new Date; + t2= time.getTime(); + + //parent.console.log( begin_word +"\n"+ (t2-t1) +"\n"+ html ); + } + } +}; + +// Load as a plugin +editArea.settings['plugins'][ editArea.settings['plugins'].length ] = 'autocompletion'; +editArea.add_plugin('autocompletion', EditArea_autocompletion); \ No newline at end of file diff --git a/includes/edit_area/edit_area.css b/includes/edit_area/edit_area.css new file mode 100644 index 00000000..5022371b --- /dev/null +++ b/includes/edit_area/edit_area.css @@ -0,0 +1,530 @@ +body, html{ + margin: 0; + padding: 0; + height: 100%; + border: none; + overflow: hidden; + background-color: #FFF; +} + +body, html, table, form, textarea{ + font: 12px monospace, sans-serif; +} + +#editor{ + border: solid #888 1px; + overflow: hidden; +} + +#result{ + z-index: 4; + overflow-x: auto; + overflow-y: scroll; + border-top: solid #888 1px; + border-bottom: solid #888 1px; + position: relative; + clear: both; +} + +#result.empty{ + overflow: hidden; +} + +#container{ + overflow: hidden; + border: solid blue 0; + position: relative; + z-index: 10; + padding: 0 5px 0 45px; + /*padding-right: 5px;*/ +} + +#textarea{ + position: relative; + top: 0; + left: 0; + margin: 0; + padding: 0; + width: 100%; + height: 100%; + overflow: hidden; + z-index: 7; + border-width: 0; + background-color: transparent; + resize: none; +} + +#textarea, #textarea:hover{ + outline: none; /* safari outline fix */ +} + +#content_highlight{ + white-space: pre; + margin: 0; + padding: 0; + position : absolute; + z-index: 4; + overflow: visible; +} + + +#selection_field, #selection_field_text{ + margin: 0; + background-color: #E1F2F9; +/* height: 1px; */ + position: absolute; + z-index: 5; + top: -100px; + padding: 0; + white-space: pre; + overflow: hidden; +} + +#selection_field.show_colors { + z-index: 3; + background-color:#EDF9FC; + +} + +#selection_field strong{ + font-weight:normal; +} + +#selection_field.show_colors *, #selection_field_text * { + visibility: hidden; +} + +#selection_field_text{ + background-color:transparent; +} + +#selection_field_text strong{ + font-weight:normal; + background-color:#3399FE; + color: #FFF; + visibility:visible; +} + +#container.word_wrap #content_highlight, +#container.word_wrap #selection_field, +#container.word_wrap #selection_field_text, +#container.word_wrap #test_font_size{ + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ + width: 99%; +} + +#line_number{ + position: absolute; + overflow: hidden; + border-right: solid black 1px; + z-index:8; + width: 38px; + padding: 0 5px 0 0; + margin: 0 0 0 -45px; + text-align: right; + color: #AAAAAA; +} + +#test_font_size{ + padding: 0; + margin: 0; + visibility: hidden; + position: absolute; + white-space: pre; +} + +pre{ + margin: 0; + padding: 0; +} + +.hidden{ + opacity: 0.2; + filter:alpha(opacity=20); +} + +#result .edit_area_cursor{ + position: absolute; + z-index:6; + background-color: #FF6633; + top: -100px; + margin: 0; +} + +#result .edit_area_selection_field .overline{ + background-color: #996600; +} + + +/* area popup */ +.editarea_popup{ + border: solid 1px #888888; + background-color: #ECE9D8; + width: 250px; + padding: 4px; + position: absolute; + visibility: hidden; + z-index: 15; + top: -500px; +} + +.editarea_popup, .editarea_popup table{ + font-family: sans-serif; + font-size: 10pt; +} + +.editarea_popup img{ + border: 0; +} + +.editarea_popup .close_popup{ + float: right; + line-height: 16px; + border: 0; + padding: 0; +} + +.editarea_popup h1,.editarea_popup h2,.editarea_popup h3,.editarea_popup h4,.editarea_popup h5,.editarea_popup h6{ + margin: 0; + padding: 0; +} + +.editarea_popup .copyright{ + text-align: right; +} + +/* Area_search */ +div#area_search_replace{ + /*width: 250px;*/ +} + +div#area_search_replace img{ + border: 0; +} + +div#area_search_replace div.button{ + text-align: center; + line-height: 1.7em; +} + +div#area_search_replace .button a{ + cursor: pointer; + border: solid 1px #888888; + background-color: #DEDEDE; + text-decoration: none; + padding: 0 2px; + color: #000000; + white-space: nowrap; +} + +div#area_search_replace a:hover{ + /*border: solid 1px #888888;*/ + background-color: #EDEDED; +} + +div#area_search_replace #move_area_search_replace{ + cursor: move; + border: solid 1px #888; +} + +div#area_search_replace #close_area_search_replace{ + text-align: right; + vertical-align: top; + white-space: nowrap; +} + +div#area_search_replace #area_search_msg{ + height: 18px; + overflow: hidden; + border-top: solid 1px #888; + margin-top: 3px; +} + +/* area help */ +#edit_area_help{ + width: 350px; +} + +#edit_area_help div.close_popup{ + float: right; +} + +/* area_toolbar */ +.area_toolbar{ + /*font: 11px sans-serif;*/ + width: 100%; + /*height: 21px; */ + margin: 0; + padding: 0; + background-color: #ECE9D8; + text-align: center; +} + +.area_toolbar, .area_toolbar table{ + font: 11px sans-serif; +} + +.area_toolbar img{ + border: 0; + vertical-align: middle; +} + +.area_toolbar input{ + margin: 0; + padding: 0; +} + +.area_toolbar select{ + font-family: 'MS Sans Serif',sans-serif,Verdana,Arial; + font-size: 7pt; + font-weight: normal; + margin: 2px 0 0 0 ; + padding: 0; + vertical-align: top; + background-color: #F0F0EE; +} + +table.statusbar{ + width: 100%; +} + +.area_toolbar td.infos{ + text-align: center; + width: 130px; + border-right: solid 1px #888; + border-width: 0 1px 0 0; + padding: 0; +} + +.area_toolbar td.total{ + text-align: right; + width: 50px; + padding: 0; +} + +.area_toolbar td.resize{ + text-align: right; +} +/* +.area_toolbar span{ + line-height: 1px; + padding: 0; + margin: 0; +}*/ + +.area_toolbar span#resize_area{ + cursor: nw-resize; + visibility: hidden; +} + +/* toolbar buttons */ +.editAreaButtonNormal, .editAreaButtonOver, .editAreaButtonDown, .editAreaSeparator, .editAreaSeparatorLine, .editAreaButtonDisabled, .editAreaButtonSelected { + border: 0; margin: 0; padding: 0; background: transparent; + margin-top: 0; + margin-left: 1px; + padding: 0; +} + +.editAreaButtonNormal { + border: 1px solid #ECE9D8 !important; + cursor: pointer; +} + +.editAreaButtonOver { + border: 1px solid #0A246A !important; + cursor: pointer; + background-color: #B6BDD2; +} + +.editAreaButtonDown { + cursor: pointer; + border: 1px solid #0A246A !important; + background-color: #8592B5; +} + +.editAreaButtonSelected { + border: 1px solid #C0C0BB !important; + cursor: pointer; + background-color: #F4F2E8; +} + +.editAreaButtonDisabled { + filter:progid:DXImageTransform.Microsoft.Alpha(opacity=30); + -moz-opacity:0.3; + opacity: 0.3; + border: 1px solid #F0F0EE !important; + cursor: pointer; +} + +.editAreaSeparatorLine { + margin: 1px 2px; + background-color: #C0C0BB; + width: 2px; + height: 18px; +} + +/* waiting screen */ +#processing{ + display: none; + background-color:#ECE9D8; + border: solid #888 1px; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + text-align: center; +} + +#processing_text{ + position:absolute; + left: 50%; + top: 50%; + width: 200px; + height: 20px; + margin-left: -100px; + margin-top: -10px; + text-align: center; +} +/* end */ + + +/**** tab browsing area ****/ +#tab_browsing_area{ + display: none; + background-color: #CCC9A8; + border-top: 1px solid #888; + text-align: left; + margin: 0; +} + +#tab_browsing_list { + padding: 0; + margin: 0; + list-style-type: none; + white-space: nowrap; +} +#tab_browsing_list li { + float: left; + margin: -1px; +} +#tab_browsing_list a { + position: relative; + display: block; + text-decoration: none; + float: left; + cursor: pointer; + line-height:14px; +} + +#tab_browsing_list a span { + display: block; + color: #000; + background: #ECE9D8; + border: 1px solid #888; + border-width: 1px 1px 0; + text-align: center; + padding: 2px 2px 1px 4px; + position: relative; /*IE 6 hack */ +} + +#tab_browsing_list a b { + display: block; + border-bottom: 2px solid #617994; +} + +#tab_browsing_list a .edited { + display: none; +} + +#tab_browsing_list a.edited .edited { + display: inline; +} + +#tab_browsing_list a img{ + margin-left: 7px; +} + +#tab_browsing_list a.edited img{ + margin-left: 3px; +} + +#tab_browsing_list a:hover span { + background: #F4F2E8; + border-color: #0A246A; +} + +#tab_browsing_list .selected a span{ + background: #046380; + color: #FFF; +} + + +#no_file_selected{ + height: 100%; + width: 150%; /* Opera need more than 100% */ + background: #CCC; + display: none; + z-index: 20; + position: absolute; +} + + +/*** Non-editable mode ***/ +.non_editable #editor +{ + border-width: 0 1px; +} + +.non_editable .area_toolbar +{ + display: none; +} + +/*** Auto completion ***/ +#auto_completion_area +{ + background: #FFF; + border: solid 1px #888; + position: absolute; + z-index: 15; + width: 280px; + height: 180px; + overflow: auto; + display:none; +} + +#auto_completion_area a, #auto_completion_area a:visited +{ + display: block; + padding: 0 2px 1px; + color: #000; + text-decoration:none; +} + +#auto_completion_area a:hover, #auto_completion_area a:focus, #auto_completion_area a.focus +{ + background: #D6E1FE; + text-decoration:none; +} + +#auto_completion_area ul +{ + margin: 0; + padding: 0; + list-style: none inside; +} +#auto_completion_area li +{ + padding: 0; +} +#auto_completion_area .prefix +{ + font-style: italic; + padding: 0 3px; +} \ No newline at end of file diff --git a/includes/edit_area/edit_area.js b/includes/edit_area/edit_area.js new file mode 100644 index 00000000..f288a702 --- /dev/null +++ b/includes/edit_area/edit_area.js @@ -0,0 +1,527 @@ +/****** + * + * EditArea + * Developped by Christophe Dolivet + * Released under LGPL, Apache and BSD licenses (use the one you want) + * +******/ + + function EditArea(){ + var t=this; + t.error= false; // to know if load is interrrupt + + t.inlinePopup= [{popup_id: "area_search_replace", icon_id: "search"}, + {popup_id: "edit_area_help", icon_id: "help"}]; + t.plugins= {}; + + t.line_number=0; + + parent.editAreaLoader.set_browser_infos(t); // navigator identification + // fix IE8 detection as we run in IE7 emulate mode through X-UA tag + if( t.isIE >= 8 ) + t.isIE = 7; + + t.last_selection={}; + t.last_text_to_highlight=""; + t.last_hightlighted_text= ""; + t.syntax_list= []; + t.allready_used_syntax= {}; + t.check_line_selection_timer= 50; // the timer delay for modification and/or selection change detection + + t.textareaFocused= false; + t.highlight_selection_line= null; + t.previous= []; + t.next= []; + t.last_undo=""; + t.files= {}; + t.filesIdAssoc= {}; + t.curr_file= ''; + //t.loaded= false; + t.assocBracket={}; + t.revertAssocBracket= {}; + // bracket selection init + t.assocBracket["("]=")"; + t.assocBracket["{"]="}"; + t.assocBracket["["]="]"; + for(var index in t.assocBracket){ + t.revertAssocBracket[t.assocBracket[index]]=index; + } + t.is_editable= true; + + + /*t.textarea=""; + + t.state="declare"; + t.code = []; // store highlight syntax for languagues*/ + // font datas + t.lineHeight= 16; + /*t.default_font_family= "monospace"; + t.default_font_size= 10;*/ + t.tab_nb_char= 8; //nb of white spaces corresponding to a tabulation + if(t.isOpera) + t.tab_nb_char= 6; + + t.is_tabbing= false; + + t.fullscreen= {'isFull': false}; + + t.isResizing=false; // resize var + + // init with settings and ID (area_id is a global var defined by editAreaLoader on iframe creation + t.id= area_id; + t.settings= editAreas[t.id]["settings"]; + + if((""+t.settings['replace_tab_by_spaces']).match(/^[0-9]+$/)) + { + t.tab_nb_char= t.settings['replace_tab_by_spaces']; + t.tabulation=""; + for(var i=0; i0) + t.syntax_list= t.settings["syntax_selection_allow"].replace(/ /g,"").split(","); + + if(t.settings['syntax']) + t.allready_used_syntax[t.settings['syntax']]=true; + + + }; + EditArea.prototype.init= function(){ + var t=this, a, s=t.settings; + t.textarea = _$("textarea"); + t.container = _$("container"); + t.result = _$("result"); + t.content_highlight = _$("content_highlight"); + t.selection_field = _$("selection_field"); + t.selection_field_text= _$("selection_field_text"); + t.processing_screen = _$("processing"); + t.editor_area = _$("editor"); + t.tab_browsing_area = _$("tab_browsing_area"); + t.test_font_size = _$("test_font_size"); + a = t.textarea; + + if(!s['is_editable']) + t.set_editable(false); + + t.set_show_line_colors( s['show_line_colors'] ); + + if(syntax_selec= _$("syntax_selection")) + { + // set up syntax selection lsit in the toolbar + for(var i=0; i= '3' ) { + t.content_highlight.style.paddingLeft= "1px"; + t.selection_field.style.paddingLeft= "1px"; + t.selection_field_text.style.paddingLeft= "1px"; + } + + if(t.isIE && t.isIE < 8 ){ + a.style.marginTop= "-1px"; + } + /* + if(t.isOpera){ + t.editor_area.style.position= "absolute"; + }*/ + + if( t.isSafari ){ + t.editor_area.style.position = "absolute"; + a.style.marginLeft ="-3px"; + if( t.isSafari < 3.2 ) // Safari 3.0 (3.1?) + a.style.marginTop ="1px"; + } + + // si le textarea n'est pas grand, un click sous le textarea doit provoquer un focus sur le textarea + parent.editAreaLoader.add_event(t.result, "click", function(e){ if((e.target || e.srcElement)==editArea.result) { editArea.area_select(editArea.textarea.value.length, 0);} }); + + if(s['is_multi_files']!=false) + t.open_file({'id': t.curr_file, 'text': ''}); + + t.set_word_wrap( s['word_wrap'] ); + + setTimeout("editArea.focus();editArea.manage_size();editArea.execCommand('EA_load');", 10); + //start checkup routine + t.check_undo(); + t.check_line_selection(true); + t.scroll_to_view(); + + for(var i in t.plugins){ + if(typeof(t.plugins[i].onload)=="function") + t.plugins[i].onload(); + } + if(s['fullscreen']==true) + t.toggle_full_screen(true); + + parent.editAreaLoader.add_event(window, "resize", editArea.update_size); + parent.editAreaLoader.add_event(parent.window, "resize", editArea.update_size); + parent.editAreaLoader.add_event(top.window, "resize", editArea.update_size); + parent.editAreaLoader.add_event(window, "unload", function(){ + // in case where editAreaLoader have been already cleaned + if( parent.editAreaLoader ) + { + parent.editAreaLoader.remove_event(parent.window, "resize", editArea.update_size); + parent.editAreaLoader.remove_event(top.window, "resize", editArea.update_size); + } + if(editAreas[editArea.id] && editAreas[editArea.id]["displayed"]){ + editArea.execCommand("EA_unload"); + } + }); + + + /*date= new Date(); + alert(date.getTime()- parent.editAreaLoader.start_time);*/ + }; + + + + //called by the toggle_on + EditArea.prototype.update_size= function(){ + var d=document,pd=parent.document,height,width,popup,maxLeft,maxTop; + + if( typeof editAreas != 'undefined' && editAreas[editArea.id] && editAreas[editArea.id]["displayed"]==true){ + if(editArea.fullscreen['isFull']){ + pd.getElementById("frame_"+editArea.id).style.width = pd.getElementsByTagName("html")[0].clientWidth + "px"; + pd.getElementById("frame_"+editArea.id).style.height = pd.getElementsByTagName("html")[0].clientHeight + "px"; + } + + if(editArea.tab_browsing_area.style.display=='block' && ( !editArea.isIE || editArea.isIE >= 8 ) ) + { + editArea.tab_browsing_area.style.height = "0px"; + editArea.tab_browsing_area.style.height = (editArea.result.offsetTop - editArea.tab_browsing_area.offsetTop -1)+"px"; + } + + height = d.body.offsetHeight - editArea.get_all_toolbar_height() - 4; + editArea.result.style.height = height +"px"; + + width = d.body.offsetWidth -2; + editArea.result.style.width = width+"px"; + //alert("result h: "+ height+" w: "+width+"\ntoolbar h: "+this.get_all_toolbar_height()+"\nbody_h: "+document.body.offsetHeight); + + // check that the popups don't get out of the screen + for( i=0; i < editArea.inlinePopup.length; i++ ) + { + popup = _$(editArea.inlinePopup[i]["popup_id"]); + maxLeft = d.body.offsetWidth - popup.offsetWidth; + maxTop = d.body.offsetHeight - popup.offsetHeight; + if( popup.offsetTop > maxTop ) + popup.style.top = maxTop+"px"; + if( popup.offsetLeft > maxLeft ) + popup.style.left = maxLeft+"px"; + } + + editArea.manage_size( true ); + editArea.fixLinesHeight( editArea.textarea.value, 0,-1); + } + }; + + + EditArea.prototype.manage_size= function(onlyOneTime){ + if(!editAreas[this.id]) + return false; + + if(editAreas[this.id]["displayed"]==true && this.textareaFocused) + { + var area_height,resized= false; + + //1) Manage display width + //1.1) Calc the new width to use for display + if( !this.settings['word_wrap'] ) + { + var area_width= this.textarea.scrollWidth; + area_height= this.textarea.scrollHeight; + // bug on old opera versions + if(this.isOpera && this.isOpera < 9.6 ){ + area_width=10000; + } + //1.2) the width is not the same, we must resize elements + if(this.textarea.previous_scrollWidth!=area_width) + { + this.container.style.width= area_width+"px"; + this.textarea.style.width= area_width+"px"; + this.content_highlight.style.width= area_width+"px"; + this.textarea.previous_scrollWidth=area_width; + resized=true; + } + } + // manage wrap width + if( this.settings['word_wrap'] ) + { + newW=this.textarea.offsetWidth; + if( this.isFirefox || this.isIE ) + newW-=2; + if( this.isSafari ) + newW-=6; + this.content_highlight.style.width=this.selection_field_text.style.width=this.selection_field.style.width=this.test_font_size.style.width=newW+"px"; + } + + //2) Manage display height + //2.1) Calc the new height to use for display + if( this.isOpera || this.isFirefox || this.isSafari ) { + area_height= this.getLinePosTop( this.last_selection["nb_line"] + 1 ); + } else { + area_height = this.textarea.scrollHeight; + } + //2.2) the width is not the same, we must resize elements + if(this.textarea.previous_scrollHeight!=area_height) + { + this.container.style.height= (area_height+2)+"px"; + this.textarea.style.height= area_height+"px"; + this.content_highlight.style.height= area_height+"px"; + this.textarea.previous_scrollHeight= area_height; + resized=true; + } + + //3) if there is new lines, we add new line numbers in the line numeration area + if(this.last_selection["nb_line"] >= this.line_number) + { + var newLines= '', destDiv=_$("line_number"), start=this.line_number, end=this.last_selection["nb_line"]+100; + for( i = start+1; i < end; i++ ) + { + newLines+='
'+i+"
"; + this.line_number++; + } + destDiv.innerHTML= destDiv.innerHTML + newLines; + if(this.settings['word_wrap']){ + this.fixLinesHeight( this.textarea.value, start, -1 ); + } + } + + //4) be sure the text is well displayed + this.textarea.scrollTop="0px"; + this.textarea.scrollLeft="0px"; + if(resized==true){ + this.scroll_to_view(); + } + } + + if(!onlyOneTime) + setTimeout("editArea.manage_size();", 100); + }; + + EditArea.prototype.execCommand= function(cmd, param){ + + for(var i in this.plugins){ + if(typeof(this.plugins[i].execCommand)=="function"){ + if(!this.plugins[i].execCommand(cmd, param)) + return; + } + } + switch(cmd){ + case "save": + if(this.settings["save_callback"].length>0) + eval("parent."+this.settings["save_callback"]+"('"+ this.id +"', editArea.textarea.value);"); + break; + case "load": + if(this.settings["load_callback"].length>0) + eval("parent."+this.settings["load_callback"]+"('"+ this.id +"');"); + break; + case "onchange": + if(this.settings["change_callback"].length>0) + eval("parent."+this.settings["change_callback"]+"('"+ this.id +"');"); + break; + case "EA_load": + if(this.settings["EA_load_callback"].length>0) + eval("parent."+this.settings["EA_load_callback"]+"('"+ this.id +"');"); + break; + case "EA_unload": + if(this.settings["EA_unload_callback"].length>0) + eval("parent."+this.settings["EA_unload_callback"]+"('"+ this.id +"');"); + break; + case "toggle_on": + if(this.settings["EA_toggle_on_callback"].length>0) + eval("parent."+this.settings["EA_toggle_on_callback"]+"('"+ this.id +"');"); + break; + case "toggle_off": + if(this.settings["EA_toggle_off_callback"].length>0) + eval("parent."+this.settings["EA_toggle_off_callback"]+"('"+ this.id +"');"); + break; + case "re_sync": + if(!this.do_highlight) + break; + case "file_switch_on": + if(this.settings["EA_file_switch_on_callback"].length>0) + eval("parent."+this.settings["EA_file_switch_on_callback"]+"(param);"); + break; + case "file_switch_off": + if(this.settings["EA_file_switch_off_callback"].length>0) + eval("parent."+this.settings["EA_file_switch_off_callback"]+"(param);"); + break; + case "file_close": + if(this.settings["EA_file_close_callback"].length>0) + return eval("parent."+this.settings["EA_file_close_callback"]+"(param);"); + break; + + default: + if(typeof(eval("editArea."+cmd))=="function") + { + if(this.settings["debug"]) + eval("editArea."+ cmd +"(param);"); + else + try{eval("editArea."+ cmd +"(param);");}catch(e){}; + } + } + }; + + EditArea.prototype.get_translation= function(word, mode){ + if(mode=="template") + return parent.editAreaLoader.translate(word, this.settings["language"], mode); + else + return parent.editAreaLoader.get_word_translation(word, this.settings["language"]); + }; + + EditArea.prototype.add_plugin= function(plug_name, plug_obj){ + for(var i=0; i"); + } + }; + + EditArea.prototype.load_script= function(url){ + try{ + script = document.createElement("script"); + script.type = "text/javascript"; + script.src = url; + script.charset= "UTF-8"; + head = document.getElementsByTagName("head"); + head[0].appendChild(script); + }catch(e){ + document.write("\";\n", $sub_scripts); + + + // add the script and use a last compression + if( $this->param['compress'] ) + { + $last_comp = array( 'ร' => 'this', + 'ร‚' => 'textarea', + 'รƒ' => 'function', + 'ร„' => 'prototype', + 'ร…' => 'settings', + 'ร†' => 'length', + 'ร‡' => 'style', + 'รˆ' => 'parent', + 'ร‰' => 'last_selection', + 'รŠ' => 'value', + 'ร‹' => 'true', + 'รŒ' => 'false' + /*, + 'รŽ' => '"', + 'ร' => "\n", + 'ร€' => "\r"*/); + } + else + { + $last_comp = array(); + } + + $js_replace= ''; + foreach( $last_comp as $key => $val ) + $js_replace .= ".replace(/". $key ."/g,'". str_replace( array("\n", "\r"), array('\n','\r'), $val ) ."')"; + + $this->datas.= sprintf("editAreaLoader.iframe_script= \"\"%s;\n", + str_replace( array_values($last_comp), array_keys($last_comp), $sub_scripts ), + $js_replace); + + if($this->load_all_plugins) + $this->datas.="editAreaLoader.all_plugins_loaded=true;\n"; + + + // load the template + $this->datas.= sprintf("editAreaLoader.template= \"%s\";\n", $this->get_html_content("template.html")); + // load the css + $this->datas.= sprintf("editAreaLoader.iframe_css= \"\";\n", $this->get_css_content("edit_area.css")); + + // $this->datas= "function editArea(){};editArea.prototype.loader= function(){alert('bouhbouh');} var a= new editArea();a.loader();"; + + } + + function send_datas() + { + if($this->param['debug']){ + $header=sprintf("/* USE PHP COMPRESSION\n"); + $header.=sprintf("javascript size: based files: %s => PHP COMPRESSION => %s ", $this->file_loaded_size, strlen($this->datas)); + if($this->use_gzip){ + $gzip_datas= gzencode($this->datas, 9, FORCE_GZIP); + $header.=sprintf("=> GZIP COMPRESSION => %s", strlen($gzip_datas)); + $ratio = round(100 - strlen($gzip_datas) / $this->file_loaded_size * 100.0); + }else{ + $ratio = round(100 - strlen($this->datas) / $this->file_loaded_size * 100.0); + } + $header.=sprintf(", reduced by %s%%\n", $ratio); + $header.=sprintf("compression time: %s\n", $this->get_microtime()-$this->start_time); + $header.=sprintf("%s\n", implode("\n", $this->infos)); + $header.=sprintf("*/\n"); + $this->datas= $header.$this->datas; + } + $mtime= time(); // ensure that the 2 disk files will have the same update time + // generate gzip file and cahce it if using disk cache + if($this->use_gzip){ + $this->gzip_datas= gzencode($this->datas, 9, FORCE_GZIP); + if($this->param['use_disk_cache']) + $this->file_put_contents($this->gzip_cache_file, $this->gzip_datas, $mtime); + } + + // generate full js file and cache it if using disk cache + if($this->param['use_disk_cache']) + $this->file_put_contents($this->full_cache_file, $this->datas, $mtime); + + // generate output + if($this->use_gzip) + echo $this->gzip_datas; + else + echo $this->datas; + +// die; + } + + + function get_content($end_uri) + { + $end_uri=preg_replace("/\.\./", "", $end_uri); // Remove any .. (security) + $file= $this->path.$end_uri; + if(file_exists($file)){ + $this->infos[]=sprintf("'%s' loaded", $end_uri); + /*$fd = fopen($file, 'rb'); + $content = fread($fd, filesize($file)); + fclose($fd); + return $content;*/ + return $this->file_get_contents($file); + }else{ + $this->infos[]=sprintf("'%s' not loaded", $end_uri); + return ""; + } + } + + function get_javascript_content($end_uri) + { + $val=$this->get_content($end_uri); + + $this->compress_javascript($val); + $this->prepare_string_for_quotes($val); + return $val; + } + + function compress_javascript(&$code) + { + if($this->param['compress']) + { + // remove all comments + // (\"(?:[^\"\\]*(?:\\\\)*(?:\\\"?)?)*(?:\"|$))|(\'(?:[^\'\\]*(?:\\\\)*(?:\\'?)?)*(?:\'|$))|(?:\/\/(?:.|\r|\t)*?(\n|$))|(?:\/\*(?:.|\n|\r|\t)*?(?:\*\/|$)) + $code= preg_replace("/(\"(?:[^\"\\\\]*(?:\\\\\\\\)*(?:\\\\\"?)?)*(?:\"|$))|(\'(?:[^\'\\\\]*(?:\\\\\\\\)*(?:\\\\\'?)?)*(?:\'|$))|(?:\/\/(?:.|\r|\t)*?(\n|$))|(?:\/\*(?:.|\n|\r|\t)*?(?:\*\/|$))/s", "$1$2$3", $code); + // remove line return, empty line and tabulation + $code= preg_replace('/(( |\t|\r)*\n( |\t)*)+/s', " ", $code); + // add line break before "else" otherwise navigators can't manage to parse the file + $code= preg_replace('/(\b(else)\b)/', "\n$1", $code); + // remove unnecessary spaces + $code= preg_replace('/( |\t|\r)*(;|\{|\}|=|==|\-|\+|,|\(|\)|\|\||&\&|\:)( |\t|\r)*/', "$2", $code); + } + } + + function get_css_content($end_uri){ + $code=$this->get_content($end_uri); + // remove comments + $code= preg_replace("/(?:\/\*(?:.|\n|\r|\t)*?(?:\*\/|$))/s", "", $code); + // remove spaces + $code= preg_replace('/(( |\t|\r)*\n( |\t)*)+/s', "", $code); + // remove spaces + $code= preg_replace('/( |\t|\r)?(\:|,|\{|\})( |\t|\r)+/', "$2", $code); + + $this->prepare_string_for_quotes($code); + return $code; + } + + function get_html_content($end_uri){ + $code=$this->get_content($end_uri); + //$code= preg_replace('/(\"(?:\\\"|[^\"])*(?:\"|$))|' . "(\'(?:\\\'|[^\'])*(?:\'|$))|(?:\/\/(?:.|\r|\t)*?(\n|$))|(?:\/\*(?:.|\n|\r|\t)*?(?:\*\/|$))/s", "$1$2$3", $code); + $code= preg_replace('/(( |\t|\r)*\n( |\t)*)+/s', " ", $code); + $this->prepare_string_for_quotes($code); + return $code; + } + + function prepare_string_for_quotes(&$str){ + // prepare the code to be putted into quotes + /*$pattern= array("/(\\\\)?\"/", '/\\\n/' , '/\\\r/' , "/(\r?\n)/"); + $replace= array('$1$1\\"', '\\\\\\n', '\\\\\\r' , '\\\n"$1+"');*/ + $pattern= array("/(\\\\)?\"/", '/\\\n/' , '/\\\r/' , "/(\r?\n)/"); + if($this->param['compress']) + $replace= array('$1$1\\"', '\\\\\\n', '\\\\\\r' , '\n'); + else + $replace= array('$1$1\\"', '\\\\\\n', '\\\\\\r' , "\\n\"\n+\""); + $str= preg_replace($pattern, $replace, $str); + } + + function replace_scripts($var, $param1, $param2) + { + $this->$var=stripslashes($param2); + return $param1."[];"; + } + + /* for php version that have not thoses functions */ + function file_get_contents($file) + { + $fd = fopen($file, 'rb'); + $content = fread($fd, filesize($file)); + fclose($fd); + $this->file_loaded_size+= strlen($content); + return $content; + } + + function file_put_contents($file, &$content, $mtime=-1) + { + if($mtime==-1) + $mtime=time(); + $fp = @fopen($file, "wb"); + if ($fp) { + fwrite($fp, $content); + fclose($fp); + touch($file, $mtime); + return true; + } + return false; + } + + function get_microtime() + { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } + } +?> diff --git a/includes/edit_area/edit_area_full.gz b/includes/edit_area/edit_area_full.gz new file mode 100644 index 00000000..29bcc50e Binary files /dev/null and b/includes/edit_area/edit_area_full.gz differ diff --git a/includes/edit_area/edit_area_full.js b/includes/edit_area/edit_area_full.js new file mode 100644 index 00000000..267574c3 --- /dev/null +++ b/includes/edit_area/edit_area_full.js @@ -0,0 +1,38 @@ + function EAL(){var t=this;t.version="0.8.2";date=new Date();t.start_time=date.getTime();t.win="loading";t.error=false;t.baseURL="";t.template="";t.lang={};t.load_syntax={};t.syntax={};t.loadedFiles=[];t.waiting_loading={};t.scripts_to_load=[];t.sub_scripts_to_load=[];t.syntax_display_name={'basic':'Basic','brainfuck':'Brainfuck','c':'C','coldfusion':'Coldfusion','cpp':'CPP','css':'CSS','html':'HTML','java':'Java','js':'Javascript','pas':'Pascal','perl':'Perl','php':'Php','python':'Python','robotstxt':'Robots txt','ruby':'Ruby','sql':'SQL','tsql':'T-SQL','vb':'Visual Basic','xml':'XML'};t.resize=[];t.hidden={};t.default_settings={debug:false,smooth_selection:true,font_size:"10",font_family:"monospace",start_highlight:false,toolbar:"search,go_to_line,fullscreen,|,undo,redo,|,select_font,|,change_smooth_selection,highlight,reset_highlight,word_wrap,|,help",begin_toolbar:"",end_toolbar:"",is_multi_files:false,allow_resize:"both",show_line_colors:false,min_width:400,min_height:125,replace_tab_by_spaces:false,allow_toggle:true,language:"en",syntax:"",syntax_selection_allow:"basic,brainfuck,c,coldfusion,cpp,css,html,java,js,pas,perl,php,python,ruby,robotstxt,sql,tsql,vb,xml",display:"onload",max_undo:30,browsers:"known",plugins:"",gecko_spellcheck:false,fullscreen:false,is_editable:true,cursor_position:"begin",word_wrap:false,autocompletion:false,load_callback:"",save_callback:"",change_callback:"",submit_callback:"",EA_init_callback:"",EA_delete_callback:"",EA_load_callback:"",EA_unload_callback:"",EA_toggle_on_callback:"",EA_toggle_off_callback:"",EA_file_switch_on_callback:"",EA_file_switch_off_callback:"",EA_file_close_callback:""};t.advanced_buttons=[ ['new_document','newdocument.gif','new_document',false],['search','search.gif','show_search',false],['go_to_line','go_to_line.gif','go_to_line',false],['undo','undo.gif','undo',true],['redo','redo.gif','redo',true],['change_smooth_selection','smooth_selection.gif','change_smooth_selection_mode',true],['reset_highlight','reset_highlight.gif','resync_highlight',true],['highlight','highlight.gif','change_highlight',true],['help','help.gif','show_help',false],['save','save.gif','save',false],['load','load.gif','load',false],['fullscreen','fullscreen.gif','toggle_full_screen',false],['word_wrap','word_wrap.gif','toggle_word_wrap',true],['autocompletion','autocompletion.gif','toggle_autocompletion',true] ];t.set_browser_infos(t);if(t.isIE>=6||t.isGecko||(t.isWebKit&&!t.isSafari<3)||t.isOpera>=9||t.isCamino)t.isValidBrowser=true; +else t.isValidBrowser=false;t.set_base_url();for(var i=0;i0)s["toolbar"]=s["begin_toolbar"]+","+s["toolbar"];if(s["end_toolbar"].length>0)s["toolbar"]=s["toolbar"]+","+s["end_toolbar"];s["tab_toolbar"]=s["toolbar"].replace(/ /g,"").split(",");s["plugins"]=s["plugins"].replace(/ /g,"").split(",");for(i=0;i0){s["syntax"]=s["syntax"].toLowerCase();t.load_script(t.baseURL+"reg_syntax/"+s["syntax"]+".js");}eAs[s["id"]]={"settings":s};eAs[s["id"]]["displayed"]=false;eAs[s["id"]]["hidden"]=false;t.start(s["id"]);},delete_instance:function(id){var d=document,fs=window.frames,span,iframe;eAL.execCommand(id,"EA_delete");if(fs["frame_"+id]&&fs["frame_"+id].editArea){if(eAs[id]["displayed"])eAL.toggle(id,"off");fs["frame_"+id].editArea.execCommand("EA_unload");}span=d.getElementById("EditAreaArroundInfos_"+id);if(span)span.parentNode.removeChild(span);iframe=d.getElementById("frame_"+id);if(iframe){iframe.parentNode.removeChild(iframe);try{delete fs["frame_"+id];}catch(e){}}delete eAs[id];},start:function(id){var t=this,d=document,f,span,father,next,html='',html_toolbar_content='',template,content,i;if(t.win!="loaded"){setTimeout("eAL.start('"+id+"');",50);return;}for(i in t.waiting_loading){if(t.waiting_loading[i]!="loaded"&&typeof(t.waiting_loading[i])!="function"){setTimeout("eAL.start('"+id+"');",50);return;}}if(!t.lang[eAs[id]["settings"]["language"]]||(eAs[id]["settings"]["syntax"].length>0&&!t.load_syntax[eAs[id]["settings"]["syntax"]])){setTimeout("eAL.start('"+id+"');",50);return;}if(eAs[id]["settings"]["syntax"].length>0)t.init_syntax_regexp();if(!d.getElementById("EditAreaArroundInfos_"+id)&&(eAs[id]["settings"]["debug"]||eAs[id]["settings"]["allow_toggle"])){span=d.createElement("span");span.id="EditAreaArroundInfos_"+id;if(eAs[id]["settings"]["allow_toggle"]){checked=(eAs[id]["settings"]["display"]=="onload")?"checked='checked'":"";html+="
";html+="";html+="
";}if(eAs[id]["settings"]["debug"])html+="
";html=t.translate(html,eAs[id]["settings"]["language"]);span.innerHTML=html;father=d.getElementById(id).parentNode;next=d.getElementById(id).nextSibling;if(next==null)father.appendChild(span); +else father.insertBefore(span,next);}if(!eAs[id]["initialized"]){t.execCommand(id,"EA_init");if(eAs[id]["settings"]["display"]=="later"){eAs[id]["initialized"]=true;return;}}if(t.isIE){t.init_ie_textarea(id);}var area=eAs[id];for(i=0;i';}for(i=0;i';t.iframe_script+='';}if(!t.iframe_css){t.iframe_css="";}template=t.template.replace(/\[__BASEURL__\]/g,t.baseURL);template=template.replace("[__TOOLBAR__]",html_toolbar_content);template=t.translate(template,area["settings"]["language"],"template");template=template.replace("[__CSSRULES__]",t.iframe_css);template=template.replace("[__JSCODE__]",t.iframe_script);template=template.replace("[__EA_VERSION__]",t.version);area.textarea=d.getElementById(area["settings"]["id"]);eAs[area["settings"]["id"]]["textarea"]=area.textarea;if(typeof(window.frames["frame_"+area["settings"]["id"]])!='undefined')delete window.frames["frame_"+area["settings"]["id"]];father=area.textarea.parentNode;content=d.createElement("iframe");content.name="frame_"+area["settings"]["id"];content.id="frame_"+area["settings"]["id"];content.style.borderWidth="0px";setAttribute(content,"frameBorder","0");content.style.overflow="hidden";content.style.display="none";next=area.textarea.nextSibling;if(next==null)father.appendChild(content); +else father.insertBefore(content,next);f=window.frames["frame_"+area["settings"]["id"]];f.document.open();f.eAs=eAs;f.area_id=area["settings"]["id"];f.document.area_id=area["settings"]["id"];f.document.write(template);f.document.close();},toggle:function(id,toggle_to){if(!toggle_to)toggle_to=(eAs[id]["displayed"]==true)?"off":"on";if(eAs[id]["displayed"]==true&&toggle_to=="off"){this.toggle_off(id);} +else if(eAs[id]["displayed"]==false&&toggle_to=="on"){this.toggle_on(id);}return false;},toggle_off:function(id){var fs=window.frames,f,t,parNod,nxtSib,selStart,selEnd,scrollTop,scrollLeft;if(fs["frame_"+id]){f=fs["frame_"+id];t=eAs[id]["textarea"];if(f.editArea.fullscreen['isFull'])f.editArea.toggle_full_screen(false);eAs[id]["displayed"]=false;t.wrap="off";setAttribute(t,"wrap","off");parNod=t.parentNode;nxtSib=t.nextSibling;parNod.removeChild(t);parNod.insertBefore(t,nxtSib);t.value=f.editArea.textarea.value;selStart=f.editArea.last_selection["selectionStart"];selEnd=f.editArea.last_selection["selectionEnd"];scrollTop=f.document.getElementById("result").scrollTop;scrollLeft=f.document.getElementById("result").scrollLeft;document.getElementById("frame_"+id).style.display='none';t.style.display="inline";try{t.focus();}catch(e){};if(this.isIE){t.selectionStart=selStart;t.selectionEnd=selEnd;t.focused=true;set_IE_selection(t);} +else{if(this.isOpera&&this.isOpera < 9.6){t.setSelectionRange(0,0);}try{t.setSelectionRange(selStart,selEnd);}catch(e){};}t.scrollTop=scrollTop;t.scrollLeft=scrollLeft;f.editArea.execCommand("toggle_off");}},toggle_on:function(id){var fs=window.frames,f,t,selStart=0,selEnd=0,scrollTop=0,scrollLeft=0,curPos,elem;if(fs["frame_"+id]){f=fs["frame_"+id];t=eAs[id]["textarea"];area=f.editArea;area.textarea.value=t.value;curPos=eAs[id]["settings"]["cursor_position"];if(t.use_last==true){selStart=t.last_selectionStart;selEnd=t.last_selectionEnd;scrollTop=t.last_scrollTop;scrollLeft=t.last_scrollLeft;t.use_last=false;} +else if(curPos=="auto"){try{selStart=t.selectionStart;selEnd=t.selectionEnd;scrollTop=t.scrollTop;scrollLeft=t.scrollLeft;}catch(ex){}}this.set_editarea_size_from_textarea(id,document.getElementById("frame_"+id));t.style.display="none";document.getElementById("frame_"+id).style.display="inline";area.execCommand("focus");eAs[id]["displayed"]=true;area.execCommand("update_size");f.document.getElementById("result").scrollTop=scrollTop;f.document.getElementById("result").scrollLeft=scrollLeft;area.area_select(selStart,selEnd-selStart);area.execCommand("toggle_on");} +else{elem=document.getElementById(id);elem.last_selectionStart=elem.selectionStart;elem.last_selectionEnd=elem.selectionEnd;elem.last_scrollTop=elem.scrollTop;elem.last_scrollLeft=elem.scrollLeft;elem.use_last=true;eAL.start(id);}},set_editarea_size_from_textarea:function(id,frame){var elem,width,height;elem=document.getElementById(id);width=Math.max(eAs[id]["settings"]["min_width"],elem.offsetWidth)+"px";height=Math.max(eAs[id]["settings"]["min_height"],elem.offsetHeight)+"px";if(elem.style.width.indexOf("%")!=-1)width=elem.style.width;if(elem.style.height.indexOf("%")!=-1)height=elem.style.height;frame.style.width=width;frame.style.height=height;},set_base_url:function(){var t=this,elems,i,docBasePath;if(!this.baseURL){elems=document.getElementsByTagName('script');for(i=0;i';html+='';return html;},get_control_html:function(button_name,lang){var t=this,i,but,html,si;for(i=0;i";case "|":case "separator":return '';case "select_font":html="";return html;case "syntax_selection":html="";return html;}return "["+button_name+"]";},get_template:function(){if(this.template==""){var xhr_object=null;if(window.XMLHttpRequest)xhr_object=new XMLHttpRequest(); +else if(window.ActiveXObject)xhr_object=new ActiveXObject("Microsoft.XMLHTTP"); +else{alert("XMLHTTPRequest not supported. EditArea not loaded");return;}xhr_object.open("GET",this.baseURL+"template.html",false);xhr_object.send(null);if(xhr_object.readyState==4)this.template=xhr_object.responseText; +else this.has_error();}},translate:function(text,lang,mode){if(mode=="word")text=eAL.get_word_translation(text,lang); +else if(mode="template"){eAL.current_language=lang;text=text.replace(/\{\$([^\}]+)\}/gm,eAL.translate_template);}return text;},translate_template:function(){return eAL.get_word_translation(EAL.prototype.translate_template.arguments[1],eAL.current_language);},get_word_translation:function(val,lang){var i;for(i in eAL.lang[lang]){if(i==val)return eAL.lang[lang][i];}return "_"+val;},load_script:function(url){var t=this,d=document,script,head;if(t.loadedFiles[url])return;try{script=d.createElement("script");script.type="text/javascript";script.src=url;script.charset="UTF-8";d.getElementsByTagName("head")[0].appendChild(script);}catch(e){d.write('');}t.loadedFiles[url]=true;},add_event:function(obj,name,handler){try{if(obj.attachEvent){obj.attachEvent("on"+name,handler);} +else{obj.addEventListener(name,handler,false);}}catch(e){}},remove_event:function(obj,name,handler){try{if(obj.detachEvent)obj.detachEvent("on"+name,handler); +else obj.removeEventListener(name,handler,false);}catch(e){}},reset:function(e){var formObj,is_child,i,x;formObj=eAL.isIE ? window.event.srcElement:e.target;if(formObj.tagName!='FORM')formObj=formObj.form;for(i in eAs){is_child=false;for(x=0;x old_sel["start"])this.setSelectionRange(id,new_sel["end"],new_sel["end"]); +else this.setSelectionRange(id,old_sel["start"]+open_tag.length,old_sel["start"]+open_tag.length);},hide:function(id){var fs=window.frames,d=document,t=this,scrollTop,scrollLeft,span;if(d.getElementById(id)&&!t.hidden[id]){t.hidden[id]={};t.hidden[id]["selectionRange"]=t.getSelectionRange(id);if(d.getElementById(id).style.display!="none"){t.hidden[id]["scrollTop"]=d.getElementById(id).scrollTop;t.hidden[id]["scrollLeft"]=d.getElementById(id).scrollLeft;}if(fs["frame_"+id]){t.hidden[id]["toggle"]=eAs[id]["displayed"];if(fs["frame_"+id]&&eAs[id]["displayed"]==true){scrollTop=fs["frame_"+id].document.getElementById("result").scrollTop;scrollLeft=fs["frame_"+id].document.getElementById("result").scrollLeft;} +else{scrollTop=d.getElementById(id).scrollTop;scrollLeft=d.getElementById(id).scrollLeft;}t.hidden[id]["scrollTop"]=scrollTop;t.hidden[id]["scrollLeft"]=scrollLeft;if(eAs[id]["displayed"]==true)eAL.toggle_off(id);}span=d.getElementById("EditAreaArroundInfos_"+id);if(span){span.style.display='none';}d.getElementById(id).style.display="none";}},show:function(id){var fs=window.frames,d=document,t=this,span;if((elem=d.getElementById(id))&&t.hidden[id]){elem.style.display="inline";elem.scrollTop=t.hidden[id]["scrollTop"];elem.scrollLeft=t.hidden[id]["scrollLeft"];span=d.getElementById("EditAreaArroundInfos_"+id);if(span){span.style.display='inline';}if(fs["frame_"+id]){elem.style.display="inline";if(t.hidden[id]["toggle"]==true)eAL.toggle_on(id);scrollTop=t.hidden[id]["scrollTop"];scrollLeft=t.hidden[id]["scrollLeft"];if(fs["frame_"+id]&&eAs[id]["displayed"]==true){fs["frame_"+id].document.getElementById("result").scrollTop=scrollTop;fs["frame_"+id].document.getElementById("result").scrollLeft=scrollLeft;} +else{elem.scrollTop=scrollTop;elem.scrollLeft=scrollLeft;}}sel=t.hidden[id]["selectionRange"];t.setSelectionRange(id,sel["start"],sel["end"]);delete t.hidden[id];}},getCurrentFile:function(id){return this.execCommand(id,'get_file',this.execCommand(id,'curr_file'));},getFile:function(id,file_id){return this.execCommand(id,'get_file',file_id);},getAllFiles:function(id){return this.execCommand(id,'get_all_files()');},openFile:function(id,file_infos){return this.execCommand(id,'open_file',file_infos);},closeFile:function(id,file_id){return this.execCommand(id,'close_file',file_id);},setFileEditedMode:function(id,file_id,to){var reg1,reg2;reg1=new RegExp('\\\\','g');reg2=new RegExp('"','g');return this.execCommand(id,'set_file_edited_mode("'+file_id.replace(reg1,'\\\\').replace(reg2,'\\"')+'",'+to+')');},execCommand:function(id,cmd,fct_param){switch(cmd){case "EA_init":if(eAs[id]['settings']["EA_init_callback"].length>0)eval(eAs[id]['settings']["EA_init_callback"]+"('"+id+"');");break;case "EA_delete":if(eAs[id]['settings']["EA_delete_callback"].length>0)eval(eAs[id]['settings']["EA_delete_callback"]+"('"+id+"');");break;case "EA_submit":if(eAs[id]['settings']["submit_callback"].length>0)eval(eAs[id]['settings']["submit_callback"]+"('"+id+"');");break;}if(window.frames["frame_"+id]&&window.frames["frame_"+id].editArea){if(fct_param!=undefined)return eval('window.frames["frame_'+id+'"].editArea.'+cmd+'(fct_param);'); +else return eval('window.frames["frame_'+id+'"].editArea.'+cmd+';');}return false;}};var eAL=new EAL();var eAs={}; function getAttribute(elm,aName){var aValue,taName,i;try{aValue=elm.getAttribute(aName);}catch(exept){}if(! aValue){for(i=0;i < elm.attributes.length;i++){taName=elm.attributes[i] .name.toLowerCase();if(taName==aName){aValue=elm.attributes[i] .value;return aValue;}}}return aValue;};function setAttribute(elm,attr,val){if(attr=="class"){elm.setAttribute("className",val);elm.setAttribute("class",val);} +else{elm.setAttribute(attr,val);}};function getChildren(elem,elem_type,elem_attribute,elem_attribute_match,option,depth){if(!option)var option="single";if(!depth)var depth=-1;if(elem){var children=elem.childNodes;var result=null;var results=[];for(var x=0;x0){results=results.concat(result);}} +else if(result!=null){return result;}}}}if(option=="all")return results;}return null;};function isChildOf(elem,parent){if(elem){if(elem==parent)return true;while(elem.parentNode !='undefined'){return isChildOf(elem.parentNode,parent);}}return false;};function getMouseX(e){if(e!=null&&typeof(e.pageX)!="undefined"){return e.pageX;} +else{return(e!=null?e.x:event.x)+document.documentElement.scrollLeft;}};function getMouseY(e){if(e!=null&&typeof(e.pageY)!="undefined"){return e.pageY;} +else{return(e!=null?e.y:event.y)+document.documentElement.scrollTop;}};function calculeOffsetLeft(r){return calculeOffset(r,"offsetLeft")};function calculeOffsetTop(r){return calculeOffset(r,"offsetTop")};function calculeOffset(element,attr){var offset=0;while(element){offset+=element[attr];element=element.offsetParent}return offset;};function get_css_property(elem,prop){if(document.defaultView){return document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop);} +else if(elem.currentStyle){var prop=prop.replace(/-\D/gi,function(sMatch){return sMatch.charAt(sMatch.length-1).toUpperCase();});return elem.currentStyle[prop];} +else return null;}var _mCE;function start_move_element(e,id,frame){var elem_id=(e.target||e.srcElement).id;if(id)elem_id=id;if(!frame)frame=window;if(frame.event)e=frame.event;_mCE=frame.document.getElementById(elem_id);_mCE.frame=frame;frame.document.onmousemove=move_element;frame.document.onmouseup=end_move_element;mouse_x=getMouseX(e);mouse_y=getMouseY(e);_mCE.start_pos_x=mouse_x-(_mCE.style.left.replace("px","")||calculeOffsetLeft(_mCE));_mCE.start_pos_y=mouse_y-(_mCE.style.top.replace("px","")||calculeOffsetTop(_mCE));return false;};function end_move_element(e){_mCE.frame.document.onmousemove="";_mCE.frame.document.onmouseup="";_mCE=null;};function move_element(e){var newTop,newLeft,maxLeft;if(_mCE.frame&&_mCE.frame.event)e=_mCE.frame.event;newTop=getMouseY(e)-_mCE.start_pos_y;newLeft=getMouseX(e)-_mCE.start_pos_x;maxLeft=_mCE.frame.document.body.offsetWidth-_mCE.offsetWidth;max_top=_mCE.frame.document.body.offsetHeight-_mCE.offsetHeight;newTop=Math.min(Math.max(0,newTop),max_top);newLeft=Math.min(Math.max(0,newLeft),maxLeft);_mCE.style.top=newTop+"px";_mCE.style.left=newLeft+"px";return false;};var nav=eAL.nav;function getSelectionRange(textarea){return{"start":textarea.selectionStart,"end":textarea.selectionEnd};};function setSelectionRange(t,start,end){t.focus();start=Math.max(0,Math.min(t.value.length,start));end=Math.max(start,Math.min(t.value.length,end));if(nav.isOpera&&nav.isOpera < 9.6){t.selectionEnd=1;t.selectionStart=0;t.selectionEnd=1;t.selectionStart=0;}t.selectionStart=start;t.selectionEnd=end;if(nav.isIE)set_IE_selection(t);};function get_IE_selection(t){var d=document,div,range,stored_range,elem,scrollTop,relative_top,line_start,line_nb,range_start,range_end,tab;if(t&&t.focused){if(!t.ea_line_height){div=d.createElement("div");div.style.fontFamily=get_css_property(t,"font-family");div.style.fontSize=get_css_property(t,"font-size");div.style.visibility="hidden";div.innerHTML="0";d.body.appendChild(div);t.ea_line_height=div.offsetHeight;d.body.removeChild(div);}range=d.selection.createRange();try{stored_range=range.duplicate();stored_range.moveToElementText(t);stored_range.setEndPoint('EndToEnd',range);if(stored_range.parentElement()==t){elem=t;scrollTop=0;while(elem.parentNode){scrollTop+=elem.scrollTop;elem=elem.parentNode;}relative_top=range.offsetTop-calculeOffsetTop(t)+scrollTop;line_start=Math.round((relative_top / t.ea_line_height)+1);line_nb=Math.round(range.boundingHeight / t.ea_line_height);range_start=stored_range.text.length-range.text.length;tab=t.value.substr(0,range_start).split("\n");range_start+=(line_start-tab.length)*2;t.selectionStart=range_start;range_end=t.selectionStart+range.text.length;tab=t.value.substr(0,range_start+range.text.length).split("\n");range_end+=(line_start+line_nb-1-tab.length)*2;t.selectionEnd=range_end;}}catch(e){}}if(t&&t.id){setTimeout("get_IE_selection(document.getElementById('"+t.id+"'));",50);}};function IE_textarea_focus(){event.srcElement.focused=true;}function IE_textarea_blur(){event.srcElement.focused=false;}function set_IE_selection(t){var nbLineStart,nbLineStart,nbLineEnd,range;if(!window.closed){nbLineStart=t.value.substr(0,t.selectionStart).split("\n").length-1;nbLineEnd=t.value.substr(0,t.selectionEnd).split("\n").length-1;try{range=document.selection.createRange();range.moveToElementText(t);range.setEndPoint('EndToStart',range);range.moveStart('character',t.selectionStart-nbLineStart);range.moveEnd('character',t.selectionEnd-nbLineEnd-(t.selectionStart-nbLineStart));range.select();}catch(e){}}};eAL.waiting_loading["elements_functions.js"]="loaded"; + EAL.prototype.start_resize_area=function(){var d=document,a,div,width,height,father;d.onmouseup=eAL.end_resize_area;d.onmousemove=eAL.resize_area;eAL.toggle(eAL.resize["id"]);a=eAs[eAL.resize["id"]]["textarea"];div=d.getElementById("edit_area_resize");if(!div){div=d.createElement("div");div.id="edit_area_resize";div.style.border="dashed #888888 1px";}width=a.offsetWidth-2;height=a.offsetHeight-2;div.style.display="block";div.style.width=width+"px";div.style.height=height+"px";father=a.parentNode;father.insertBefore(div,a);a.style.display="none";eAL.resize["start_top"]=calculeOffsetTop(div);eAL.resize["start_left"]=calculeOffsetLeft(div);};EAL.prototype.end_resize_area=function(e){var d=document,div,a,width,height;d.onmouseup="";d.onmousemove="";div=d.getElementById("edit_area_resize");a=eAs[eAL.resize["id"]]["textarea"];width=Math.max(eAs[eAL.resize["id"]]["settings"]["min_width"],div.offsetWidth-4);height=Math.max(eAs[eAL.resize["id"]]["settings"]["min_height"],div.offsetHeight-4);if(eAL.isIE==6){width-=2;height-=2;}a.style.width=width+"px";a.style.height=height+"px";div.style.display="none";a.style.display="inline";a.selectionStart=eAL.resize["selectionStart"];a.selectionEnd=eAL.resize["selectionEnd"];eAL.toggle(eAL.resize["id"]);return false;};EAL.prototype.resize_area=function(e){var allow,newHeight,newWidth;allow=eAs[eAL.resize["id"]]["settings"]["allow_resize"];if(allow=="both"||allow=="y"){newHeight=Math.max(20,getMouseY(e)-eAL.resize["start_top"]);document.getElementById("edit_area_resize").style.height=newHeight+"px";}if(allow=="both"||allow=="x"){newWidth=Math.max(20,getMouseX(e)-eAL.resize["start_left"]);document.getElementById("edit_area_resize").style.width=newWidth+"px";}return false;};eAL.waiting_loading["resize_area.js"]="loaded"; + EAL.prototype.get_regexp=function(text_array){res="(\\b)(";for(i=0;i0)res+="|";res+=this.get_escaped_regexp(text_array[i]);}res+=")(\\b)";reg=new RegExp(res);return res;};EAL.prototype.get_escaped_regexp=function(str){return str.toString().replace(/(\.|\?|\*|\+|\\|\(|\)|\[|\]|\}|\{|\$|\^|\|)/g,"\\$1");};EAL.prototype.init_syntax_regexp=function(){var lang_style={};for(var lang in this.load_syntax){if(!this.syntax[lang]){this.syntax[lang]={};this.syntax[lang]["keywords_reg_exp"]={};this.keywords_reg_exp_nb=0;if(this.load_syntax[lang]['KEYWORDS']){param="g";if(this.load_syntax[lang]['KEYWORD_CASE_SENSITIVE']===false)param+="i";for(var i in this.load_syntax[lang]['KEYWORDS']){if(typeof(this.load_syntax[lang]['KEYWORDS'][i])=="function")continue;this.syntax[lang]["keywords_reg_exp"][i]=new RegExp(this.get_regexp(this.load_syntax[lang]['KEYWORDS'][i]),param);this.keywords_reg_exp_nb++;}}if(this.load_syntax[lang]['OPERATORS']){var str="";var nb=0;for(var i in this.load_syntax[lang]['OPERATORS']){if(typeof(this.load_syntax[lang]['OPERATORS'][i])=="function")continue;if(nb>0)str+="|";str+=this.get_escaped_regexp(this.load_syntax[lang]['OPERATORS'][i]);nb++;}if(str.length>0)this.syntax[lang]["operators_reg_exp"]=new RegExp("("+str+")","g");}if(this.load_syntax[lang]['DELIMITERS']){var str="";var nb=0;for(var i in this.load_syntax[lang]['DELIMITERS']){if(typeof(this.load_syntax[lang]['DELIMITERS'][i])=="function")continue;if(nb>0)str+="|";str+=this.get_escaped_regexp(this.load_syntax[lang]['DELIMITERS'][i]);nb++;}if(str.length>0)this.syntax[lang]["delimiters_reg_exp"]=new RegExp("("+str+")","g");}var syntax_trace=[];this.syntax[lang]["quotes"]={};var quote_tab=[];if(this.load_syntax[lang]['QUOTEMARKS']){for(var i in this.load_syntax[lang]['QUOTEMARKS']){if(typeof(this.load_syntax[lang]['QUOTEMARKS'][i])=="function")continue;var x=this.get_escaped_regexp(this.load_syntax[lang]['QUOTEMARKS'][i]);this.syntax[lang]["quotes"][x]=x;quote_tab[quote_tab.length]="("+x+"(\\\\.|[^"+x+"])*(?:"+x+"|$))";syntax_trace.push(x);}}this.syntax[lang]["comments"]={};if(this.load_syntax[lang]['COMMENT_SINGLE']){for(var i in this.load_syntax[lang]['COMMENT_SINGLE']){if(typeof(this.load_syntax[lang]['COMMENT_SINGLE'][i])=="function")continue;var x=this.get_escaped_regexp(this.load_syntax[lang]['COMMENT_SINGLE'][i]);quote_tab[quote_tab.length]="("+x+"(.|\\r|\\t)*(\\n|$))";syntax_trace.push(x);this.syntax[lang]["comments"][x]="\n";}}if(this.load_syntax[lang]['COMMENT_MULTI']){for(var i in this.load_syntax[lang]['COMMENT_MULTI']){if(typeof(this.load_syntax[lang]['COMMENT_MULTI'][i])=="function")continue;var start=this.get_escaped_regexp(i);var end=this.get_escaped_regexp(this.load_syntax[lang]['COMMENT_MULTI'][i]);quote_tab[quote_tab.length]="("+start+"(.|\\n|\\r)*?("+end+"|$))";syntax_trace.push(start);syntax_trace.push(end);this.syntax[lang]["comments"][i]=this.load_syntax[lang]['COMMENT_MULTI'][i];}}if(quote_tab.length>0)this.syntax[lang]["comment_or_quote_reg_exp"]=new RegExp("("+quote_tab.join("|")+")","gi");if(syntax_trace.length>0)this.syntax[lang]["syntax_trace_regexp"]=new RegExp("((.|\n)*?)(\\\\*("+syntax_trace.join("|")+"|$))","gmi");if(this.load_syntax[lang]['SCRIPT_DELIMITERS']){this.syntax[lang]["script_delimiters"]={};for(var i in this.load_syntax[lang]['SCRIPT_DELIMITERS']){if(typeof(this.load_syntax[lang]['SCRIPT_DELIMITERS'][i])=="function")continue;this.syntax[lang]["script_delimiters"][i]=this.load_syntax[lang]['SCRIPT_DELIMITERS'];}}this.syntax[lang]["custom_regexp"]={};if(this.load_syntax[lang]['REGEXPS']){for(var i in this.load_syntax[lang]['REGEXPS']){if(typeof(this.load_syntax[lang]['REGEXPS'][i])=="function")continue;var val=this.load_syntax[lang]['REGEXPS'][i];if(!this.syntax[lang]["custom_regexp"][val['execute']])this.syntax[lang]["custom_regexp"][val['execute']]={};this.syntax[lang]["custom_regexp"][val['execute']][i]={'regexp':new RegExp(val['search'],val['modifiers']),'class':val['class']};}}if(this.load_syntax[lang]['STYLES']){lang_style[lang]={};for(var i in this.load_syntax[lang]['STYLES']){if(typeof(this.load_syntax[lang]['STYLES'][i])=="function")continue;if(typeof(this.load_syntax[lang]['STYLES'][i])!="string"){for(var j in this.load_syntax[lang]['STYLES'][i]){lang_style[lang][j]=this.load_syntax[lang]['STYLES'][i][j];}} +else{lang_style[lang][i]=this.load_syntax[lang]['STYLES'][i];}}}var style="";for(var i in lang_style[lang]){if(lang_style[lang][i].length>0){style+="."+lang+" ."+i.toLowerCase()+" span{"+lang_style[lang][i]+"}\n";style+="."+lang+" ."+i.toLowerCase()+"{"+lang_style[lang][i]+"}\n";}}this.syntax[lang]["styles"]=style;}}};eAL.waiting_loading["reg_syntax.js"]="loaded"; +var editAreaLoader= eAL;var editAreas=eAs;EditAreaLoader=EAL;editAreaLoader.iframe_script= "".replace(/ร/g,'this').replace(/ร‚/g,'textarea').replace(/รƒ/g,'function').replace(/ร„/g,'prototype').replace(/ร…/g,'settings').replace(/ร†/g,'length').replace(/ร‡/g,'style').replace(/รˆ/g,'parent').replace(/ร‰/g,'last_selection').replace(/รŠ/g,'value').replace(/ร‹/g,'true').replace(/รŒ/g,'false'); +editAreaLoader.template= " EditArea [__CSSRULES__] [__JSCODE__]
[__TOOLBAR__]
 
 
{$position}: {$line_abbr} 0, {$char_abbr} 0 {$total}: {$line_abbr} 0, {$char_abbr} 0 resize
{$processing}
{$search} {$close_popup}
{$replace} {$move_popup}

{$find_next} {$replace} {$replace_all}
{$close_popup}

Editarea [__EA_VERSION__]


{$shortcuts}:

{$tab}: {$add_tab}
{$shift}+{$tab}: {$remove_tab}
{$ctrl}+f: {$search_command}
{$ctrl}+r: {$replace_command}
{$ctrl}+h: {$highlight}
{$ctrl}+g: {$go_to_line}
{$ctrl}+z: {$undo}
{$ctrl}+y: {$redo}
{$ctrl}+e: {$help}
{$ctrl}+q, {$esc}: {$close_popup}
{$accesskey} E: {$toggle}

{$about_notice}
"; +editAreaLoader.iframe_css= ""; diff --git a/includes/edit_area/edit_area_functions.js b/includes/edit_area/edit_area_functions.js new file mode 100644 index 00000000..cccbe243 --- /dev/null +++ b/includes/edit_area/edit_area_functions.js @@ -0,0 +1,1202 @@ + //replace tabulation by the good number of white spaces + EditArea.prototype.replace_tab= function(text){ + return text.replace(/((\n?)([^\t\n]*)\t)/gi, editArea.smartTab); // slower than simple replace... + }; + + // call by the replace_tab function + EditArea.prototype.smartTab= function(){ + val=" "; + return EditArea.prototype.smartTab.arguments[2] + EditArea.prototype.smartTab.arguments[3] + val.substr(0, editArea.tab_nb_char - (EditArea.prototype.smartTab.arguments[3].length)%editArea.tab_nb_char); + }; + + EditArea.prototype.show_waiting_screen= function(){ + width = this.editor_area.offsetWidth; + height = this.editor_area.offsetHeight; + if( !(this.isIE && this.isIE<6) ) + { + width -= 2; + height -= 2; + } + this.processing_screen.style.display= "block"; + this.processing_screen.style.width = width+"px"; + this.processing_screen.style.height = height+"px"; + this.waiting_screen_displayed = true; + }; + + EditArea.prototype.hide_waiting_screen= function(){ + this.processing_screen.style.display="none"; + this.waiting_screen_displayed= false; + }; + + EditArea.prototype.add_style= function(styles){ + if(styles.length>0){ + newcss = document.createElement("style"); + newcss.type="text/css"; + newcss.media="all"; + if(newcss.styleSheet){ // IE + newcss.styleSheet.cssText = styles; + } else { // W3C + newcss.appendChild(document.createTextNode(styles)); + } + document.getElementsByTagName("head")[0].appendChild(newcss); + } + }; + + EditArea.prototype.set_font= function(family, size){ + var t=this, a=this.textarea, s=this.settings, elem_font, i, elem; + // list all elements concerned by font changes + var elems= ["textarea", "content_highlight", "cursor_pos", "end_bracket", "selection_field", "selection_field_text", "line_number"]; + + if(family && family!="") + s["font_family"]= family; + if(size && size>0) + s["font_size"] = size; + if( t.isOpera && t.isOpera < 9.6 ) // opera<9.6 can't manage non monospace font + s['font_family']="monospace"; + + // update the select tag + if( elem_font = _$("area_font_size") ) + { + for( i = 0; i < elem_font.length; i++ ) + { + if( elem_font.options[i].value && elem_font.options[i].value == s["font_size"] ) + elem_font.options[i].selected=true; + } + } + + /* + * somethimes firefox has rendering mistake with non-monospace font for text width in textarea vs in div for changing font size (eg: verdana change between 11pt to 12pt) + * => looks like a browser internal random bug as text width can change while content_highlight is updated + * we'll check if the font-size produce the same text width inside textarea and div and if not, we'll increment the font-size + * + * This is an ugly fix + */ + if( t.isFirefox ) + { + var nbTry = 3; + do { + var div1 = document.createElement( 'div' ), text1 = document.createElement( 'textarea' ); + var styles = { + width: '40px', + overflow: 'scroll', + zIndex: 50, + visibility: 'hidden', + fontFamily: s["font_family"], + fontSize: s["font_size"]+"pt", + lineHeight: t.lineHeight+"px", + padding: '0', + margin: '0', + border: 'none', + whiteSpace: 'nowrap' + }; + var diff, changed = false; + for( i in styles ) + { + div1.style[ i ] = styles[i]; + text1.style[ i ] = styles[i]; + } + // no wrap for this text + text1.wrap = 'off'; + text1.setAttribute('wrap', 'off'); + t.container.appendChild( div1 ); + t.container.appendChild( text1 ); + // try to make FF to bug + div1.innerHTML = text1.value = 'azertyuiopqsdfghjklm'; + div1.innerHTML = text1.value = text1.value+'wxcvbn^p*รน$!:;,,'; + diff = text1.scrollWidth - div1.scrollWidth; + + // firefox return here a diff of 1 px between equals scrollWidth (can't explain) + if( Math.abs( diff ) >= 2 ) + { + s["font_size"]++; + changed = true; + } + t.container.removeChild( div1 ); + t.container.removeChild( text1 ); + nbTry--; + }while( changed && nbTry > 0 ); + } + + + // calc line height + elem = t.test_font_size; + elem.style.fontFamily = ""+s["font_family"]; + elem.style.fontSize = s["font_size"]+"pt"; + elem.innerHTML = "0"; + t.lineHeight = elem.offsetHeight; + + // update font for all concerned elements + for( i=0; i tags + t.add_style("pre{font-family:"+s["font_family"]+"}"); + + // old opera and IE>=8 doesn't update font changes to the textarea + if( ( t.isOpera && t.isOpera < 9.6 ) || t.isIE >= 8 ) + { + var parNod = a.parentNode, nxtSib = a.nextSibling, start= a.selectionStart, end= a.selectionEnd; + parNod.removeChild(a); + parNod.insertBefore(a, nxtSib); + t.area_select(start, end-start); + } + + // force update of selection field + this.focus(); + this.update_size(); + this.check_line_selection(); + }; + + EditArea.prototype.change_font_size= function(){ + var size=_$("area_font_size").value; + if(size>0) + this.set_font("", size); + }; + + + EditArea.prototype.open_inline_popup= function(popup_id){ + this.close_all_inline_popup(); + var popup= _$(popup_id); + var editor= _$("editor"); + + // search matching icon + for(var i=0; i lines.length) + start= this.textarea.value.length; + else{ + for(var i=0; i0){ + //alert(miss_top); + zone.scrollTop= zone.scrollTop + miss_top; + }else if( zone.scrollTop > cursor_pos_top){ + // when erase all the content -> does'nt scroll back to the top + //alert("else: "+cursor_pos_top); + zone.scrollTop= cursor_pos_top; + } + + // manage left scroll + //var cursor_pos_left= parseInt(_$("cursor_pos").style.left.replace("px","")); + var cursor_pos_left= _$("cursor_pos").cursor_left; + var max_width_visible= zone.clientWidth + zone.scrollLeft; + var miss_left= cursor_pos_left + 10 - max_width_visible; + if(miss_left>0){ + zone.scrollLeft= zone.scrollLeft + miss_left + 50; + }else if( zone.scrollLeft > cursor_pos_left){ + zone.scrollLeft= cursor_pos_left ; + }else if( zone.scrollLeft == 45){ + // show the line numbers if textarea align to it's left + zone.scrollLeft=0; + } + }; + + EditArea.prototype.check_undo= function(only_once){ + if(!editAreas[this.id]) + return false; + if(this.textareaFocused && editAreas[this.id]["displayed"]==true){ + var text=this.textarea.value; + if(this.previous.length<=1) + this.switchClassSticky(_$("undo"), 'editAreaButtonDisabled', true); + + if(!this.previous[this.previous.length-1] || this.previous[this.previous.length-1]["text"] != text){ + this.previous.push({"text": text, "selStart": this.textarea.selectionStart, "selEnd": this.textarea.selectionEnd}); + if(this.previous.length > this.settings["max_undo"]+1) + this.previous.shift(); + + } + if(this.previous.length >= 2) + this.switchClassSticky(_$("undo"), 'editAreaButtonNormal', false); + } + + if(!only_once) + setTimeout("editArea.check_undo()", 3000); + }; + + EditArea.prototype.undo= function(){ + //alert("undo"+this.previous.length); + if(this.previous.length > 0) + { + this.getIESelection(); + // var pos_cursor=this.textarea.selectionStart; + this.next.push( { "text": this.textarea.value, "selStart": this.textarea.selectionStart, "selEnd": this.textarea.selectionEnd } ); + var prev= this.previous.pop(); + if( prev["text"] == this.textarea.value && this.previous.length > 0 ) + prev =this.previous.pop(); + this.textarea.value = prev["text"]; + this.last_undo = prev["text"]; + this.area_select(prev["selStart"], prev["selEnd"]-prev["selStart"]); + this.switchClassSticky(_$("redo"), 'editAreaButtonNormal', false); + this.resync_highlight(true); + //alert("undo"+this.previous.length); + this.check_file_changes(); + } + }; + + EditArea.prototype.redo= function(){ + if(this.next.length > 0) + { + /*this.getIESelection();*/ + //var pos_cursor=this.textarea.selectionStart; + var next= this.next.pop(); + this.previous.push(next); + this.textarea.value= next["text"]; + this.last_undo= next["text"]; + this.area_select(next["selStart"], next["selEnd"]-next["selStart"]); + this.switchClassSticky(_$("undo"), 'editAreaButtonNormal', false); + this.resync_highlight(true); + this.check_file_changes(); + } + if( this.next.length == 0) + this.switchClassSticky(_$("redo"), 'editAreaButtonDisabled', true); + }; + + EditArea.prototype.check_redo= function(){ + if(editArea.next.length == 0 || editArea.textarea.value!=editArea.last_undo){ + editArea.next= []; // undo the ability to use "redo" button + editArea.switchClassSticky(_$("redo"), 'editAreaButtonDisabled', true); + } + else + { + this.switchClassSticky(_$("redo"), 'editAreaButtonNormal', false); + } + }; + + + // functions that manage icons roll over, disabled, etc... + EditArea.prototype.switchClass = function(element, class_name, lock_state) { + var lockChanged = false; + + if (typeof(lock_state) != "undefined" && element != null) { + element.classLock = lock_state; + lockChanged = true; + } + + if (element != null && (lockChanged || !element.classLock)) { + element.oldClassName = element.className; + element.className = class_name; + } + }; + + EditArea.prototype.restoreAndSwitchClass = function(element, class_name) { + if (element != null && !element.classLock) { + this.restoreClass(element); + this.switchClass(element, class_name); + } + }; + + EditArea.prototype.restoreClass = function(element) { + if (element != null && element.oldClassName && !element.classLock) { + element.className = element.oldClassName; + element.oldClassName = null; + } + }; + + EditArea.prototype.setClassLock = function(element, lock_state) { + if (element != null) + element.classLock = lock_state; + }; + + EditArea.prototype.switchClassSticky = function(element, class_name, lock_state) { + var lockChanged = false; + if (typeof(lock_state) != "undefined" && element != null) { + element.classLock = lock_state; + lockChanged = true; + } + + if (element != null && (lockChanged || !element.classLock)) { + element.className = class_name; + element.oldClassName = class_name; + } + }; + + //make the "page up" and "page down" buttons works correctly + EditArea.prototype.scroll_page= function(params){ + var dir= params["dir"], shift_pressed= params["shift"]; + var lines= this.textarea.value.split("\n"); + var new_pos=0, length=0, char_left=0, line_nb=0, curLine=0; + var toScrollAmount = _$("result").clientHeight -30; + var nbLineToScroll = 0, diff= 0; + + if(dir=="up"){ + nbLineToScroll = Math.ceil( toScrollAmount / this.lineHeight ); + + // fix number of line to scroll + for( i = this.last_selection["line_start"]; i - diff > this.last_selection["line_start"] - nbLineToScroll ; i-- ) + { + if( elem = _$('line_'+ i) ) + { + diff += Math.floor( ( elem.offsetHeight - 1 ) / this.lineHeight ); + } + } + nbLineToScroll -= diff; + + if(this.last_selection["selec_direction"]=="up"){ + for(line_nb=0; line_nb< Math.min(this.last_selection["line_start"]-nbLineToScroll, lines.length); line_nb++){ + new_pos+= lines[line_nb].length + 1; + } + char_left=Math.min(lines[Math.min(lines.length-1, line_nb)].length, this.last_selection["curr_pos"]-1); + if(shift_pressed) + length=this.last_selection["selectionEnd"]-new_pos-char_left; + this.area_select(new_pos+char_left, length); + view="top"; + }else{ + view="bottom"; + for(line_nb=0; line_nb< Math.min(this.last_selection["line_start"]+this.last_selection["line_nb"]-1-nbLineToScroll, lines.length); line_nb++){ + new_pos+= lines[line_nb].length + 1; + } + char_left=Math.min(lines[Math.min(lines.length-1, line_nb)].length, this.last_selection["curr_pos"]-1); + if(shift_pressed){ + //length=this.last_selection["selectionEnd"]-new_pos-char_left; + start= Math.min(this.last_selection["selectionStart"], new_pos+char_left); + length= Math.max(new_pos+char_left, this.last_selection["selectionStart"] )- start ; + if(new_pos+char_left < this.last_selection["selectionStart"]) + view="top"; + }else + start=new_pos+char_left; + this.area_select(start, length); + + } + } + else + { + var nbLineToScroll= Math.floor( toScrollAmount / this.lineHeight ); + // fix number of line to scroll + for( i = this.last_selection["line_start"]; i + diff < this.last_selection["line_start"] + nbLineToScroll ; i++ ) + { + if( elem = _$('line_'+ i) ) + { + diff += Math.floor( ( elem.offsetHeight - 1 ) / this.lineHeight ); + } + } + nbLineToScroll -= diff; + + if(this.last_selection["selec_direction"]=="down"){ + view="bottom"; + for(line_nb=0; line_nb< Math.min(this.last_selection["line_start"]+this.last_selection["line_nb"]-2+nbLineToScroll, lines.length); line_nb++){ + if(line_nb==this.last_selection["line_start"]-1) + char_left= this.last_selection["selectionStart"] -new_pos; + new_pos+= lines[line_nb].length + 1; + + } + if(shift_pressed){ + length=Math.abs(this.last_selection["selectionStart"]-new_pos); + length+=Math.min(lines[Math.min(lines.length-1, line_nb)].length, this.last_selection["curr_pos"]); + //length+=Math.min(lines[Math.min(lines.length-1, line_nb)].length, char_left); + this.area_select(Math.min(this.last_selection["selectionStart"], new_pos), length); + }else{ + this.area_select(new_pos+char_left, 0); + } + + }else{ + view="top"; + for(line_nb=0; line_nb< Math.min(this.last_selection["line_start"]+nbLineToScroll-1, lines.length, lines.length); line_nb++){ + if(line_nb==this.last_selection["line_start"]-1) + char_left= this.last_selection["selectionStart"] -new_pos; + new_pos+= lines[line_nb].length + 1; + } + if(shift_pressed){ + length=Math.abs(this.last_selection["selectionEnd"]-new_pos-char_left); + length+=Math.min(lines[Math.min(lines.length-1, line_nb)].length, this.last_selection["curr_pos"])- char_left-1; + //length+=Math.min(lines[Math.min(lines.length-1, line_nb)].length, char_left); + this.area_select(Math.min(this.last_selection["selectionEnd"], new_pos+char_left), length); + if(new_pos+char_left > this.last_selection["selectionEnd"]) + view="bottom"; + }else{ + this.area_select(new_pos+char_left, 0); + } + + } + } + //console.log( new_pos, char_left, length, nbLineToScroll, toScrollAmount, _$("result").clientHeigh ); + this.check_line_selection(); + this.scroll_to_view(view); + }; + + EditArea.prototype.start_resize= function(e){ + parent.editAreaLoader.resize["id"] = editArea.id; + parent.editAreaLoader.resize["start_x"] = (e)? e.pageX : event.x + document.body.scrollLeft; + parent.editAreaLoader.resize["start_y"] = (e)? e.pageY : event.y + document.body.scrollTop; + if(editArea.isIE) + { + editArea.textarea.focus(); + editArea.getIESelection(); + } + parent.editAreaLoader.resize["selectionStart"] = editArea.textarea.selectionStart; + parent.editAreaLoader.resize["selectionEnd"] = editArea.textarea.selectionEnd; + parent.editAreaLoader.start_resize_area(); + }; + + EditArea.prototype.toggle_full_screen= function(to){ + var t=this, p=parent, a=t.textarea, html, frame, selStart, selEnd, old, icon; + if(typeof(to)=="undefined") + to= !t.fullscreen['isFull']; + old = t.fullscreen['isFull']; + t.fullscreen['isFull']= to; + icon = _$("fullscreen"); + selStart = t.textarea.selectionStart; + selEnd = t.textarea.selectionEnd; + html = p.document.getElementsByTagName("html")[0]; + frame = p.document.getElementById("frame_"+t.id); + + if(to && to!=old) + { // toogle on fullscreen + + t.fullscreen['old_overflow'] = p.get_css_property(html, "overflow"); + t.fullscreen['old_height'] = p.get_css_property(html, "height"); + t.fullscreen['old_width'] = p.get_css_property(html, "width"); + t.fullscreen['old_scrollTop'] = html.scrollTop; + t.fullscreen['old_scrollLeft'] = html.scrollLeft; + t.fullscreen['old_zIndex'] = p.get_css_property(frame, "z-index"); + if(t.isOpera){ + html.style.height = "100%"; + html.style.width = "100%"; + } + html.style.overflow = "hidden"; + html.scrollTop = 0; + html.scrollLeft = 0; + + frame.style.position = "absolute"; + frame.style.width = html.clientWidth+"px"; + frame.style.height = html.clientHeight+"px"; + frame.style.display = "block"; + frame.style.zIndex = "999999"; + frame.style.top = "0px"; + frame.style.left = "0px"; + + // if the iframe was in a div with position absolute, the top and left are the one of the div, + // so I fix it by seeing at witch position the iframe start and correcting it + frame.style.top = "-"+p.calculeOffsetTop(frame)+"px"; + frame.style.left = "-"+p.calculeOffsetLeft(frame)+"px"; + + // parent.editAreaLoader.execCommand(t.id, "update_size();"); + // var body=parent.document.getElementsByTagName("body")[0]; + // body.appendChild(frame); + + t.switchClassSticky(icon, 'editAreaButtonSelected', false); + t.fullscreen['allow_resize']= t.resize_allowed; + t.allow_resize(false); + + //t.area_select(selStart, selEnd-selStart); + + + // opera can't manage to do a direct size update + if(t.isFirefox){ + p.editAreaLoader.execCommand(t.id, "update_size();"); + t.area_select(selStart, selEnd-selStart); + t.scroll_to_view(); + t.focus(); + }else{ + setTimeout("parent.editAreaLoader.execCommand('"+ t.id +"', 'update_size();');editArea.focus();", 10); + } + + + } + else if(to!=old) + { // toogle off fullscreen + frame.style.position="static"; + frame.style.zIndex= t.fullscreen['old_zIndex']; + + if(t.isOpera) + { + html.style.height = "auto"; + html.style.width = "auto"; + html.style.overflow = "auto"; + } + else if(t.isIE && p!=top) + { // IE doesn't manage html overflow in frames like in normal page... + html.style.overflow = "auto"; + } + else + { + html.style.overflow = t.fullscreen['old_overflow']; + } + html.scrollTop = t.fullscreen['old_scrollTop']; + html.scrollLeft = t.fullscreen['old_scrollLeft']; + + p.editAreaLoader.hide(t.id); + p.editAreaLoader.show(t.id); + + t.switchClassSticky(icon, 'editAreaButtonNormal', false); + if(t.fullscreen['allow_resize']) + t.allow_resize(t.fullscreen['allow_resize']); + if(t.isFirefox){ + t.area_select(selStart, selEnd-selStart); + setTimeout("editArea.scroll_to_view();", 10); + } + + //p.editAreaLoader.remove_event(p.window, "resize", editArea.update_size); + } + + }; + + EditArea.prototype.allow_resize= function(allow){ + var resize= _$("resize_area"); + if(allow){ + + resize.style.visibility="visible"; + parent.editAreaLoader.add_event(resize, "mouseup", editArea.start_resize); + }else{ + resize.style.visibility="hidden"; + parent.editAreaLoader.remove_event(resize, "mouseup", editArea.start_resize); + } + this.resize_allowed= allow; + }; + + + EditArea.prototype.change_syntax= function(new_syntax, is_waiting){ + // alert("cahnge to "+new_syntax); + // the syntax is the same + if(new_syntax==this.settings['syntax']) + return true; + + // check that the syntax is one allowed + var founded= false; + for(var i=0; i"; + elem.innerHTML= "*"+ this.files[id]['title'] + close +""; + _$('tab_browsing_list').appendChild(elem); + var elem= document.createElement('text'); + this.update_size(); + } + + // open file callback (for plugin) + if(id!="") + this.execCommand('file_open', this.files[id]); + + this.switch_to_file(id, true); + return true; + } + else + return false; + }; + + // close the given file + EditArea.prototype.close_file= function(id){ + if(this.files[id]) + { + this.save_file(id); + + // close file callback + if(this.execCommand('file_close', this.files[id])!==false) + { + // remove the tab in the toolbar + var li= _$(this.files[id]['html_id']); + li.parentNode.removeChild(li); + // select a new file + if(id== this.curr_file) + { + var next_file= ""; + var is_next= false; + for(var i in this.files) + { + if( is_next ) + { + next_file = i; + break; + } + else if( i == id ) + is_next = true; + else + next_file = i; + } + // display the next file + this.switch_to_file(next_file); + } + // clear datas + delete (this.files[id]); + this.update_size(); + } + } + }; + + // backup current file datas + EditArea.prototype.save_file= function(id){ + var t= this, save, a_links, a_selects, save_butt, img, i; + if(t.files[id]) + { + var save= t.files[id]; + save['last_selection'] = t.last_selection; + save['last_text_to_highlight'] = t.last_text_to_highlight; + save['last_hightlighted_text'] = t.last_hightlighted_text; + save['previous'] = t.previous; + save['next'] = t.next; + save['last_undo'] = t.last_undo; + save['smooth_selection'] = t.smooth_selection; + save['do_highlight'] = t.do_highlight; + save['syntax'] = t.settings['syntax']; + save['text'] = t.textarea.value; + save['scroll_top'] = t.result.scrollTop; + save['scroll_left'] = t.result.scrollLeft; + save['selection_start'] = t.last_selection["selectionStart"]; + save['selection_end'] = t.last_selection["selectionEnd"]; + save['font_size'] = t.settings["font_size"]; + save['font_family'] = t.settings["font_family"]; + save['word_wrap'] = t.settings["word_wrap"]; + save['toolbar'] = {'links':{}, 'selects': {}}; + + // save toolbar buttons state for fileSpecific buttons + a_links= _$("toolbar_1").getElementsByTagName("a"); + for( i=0; i