From 5385732fb132224cd111ecb2c3c0de27ead3b27d Mon Sep 17 00:00:00 2001 From: MichaelC Date: Mon, 29 Dec 2014 15:59:00 +0000 Subject: [PATCH 1/2] Add migration --- migrations/v10x/m1_inital_data.php | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 migrations/v10x/m1_inital_data.php diff --git a/migrations/v10x/m1_inital_data.php b/migrations/v10x/m1_inital_data.php new file mode 100644 index 0000000..acf7f10 --- /dev/null +++ b/migrations/v10x/m1_inital_data.php @@ -0,0 +1,38 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +*/ + +namespace phpbb\userprofilerules\migrations\v10x; + +/** +* Migration stage 1: Inital data +*/ +class m1_inital_data extends \phpbb\db\migration\migration +{ + /** + * Add inital config data to the database + * + * @return array Array of table data + * @access public + */ + public function update_data() + { + return array( + array('config_text.add', array('signature_rules_text', '')), + array('config_text.add', array('signature_rules_uid', '')), + array('config_text.add', array('signature_rules_bitfield', '')), + array('config_text.add', array('signature_rules_options', OPTION_FLAG_BBCODE + OPTION_FLAG_SMILIES + OPTION_FLAG_LINKS)), + + array('config_text.add', array('avatar_rules_text', '')), + array('config_text.add', array('avatar_rules_uid', '')), + array('config_text.add', array('avatar_rules_bitfield', '')), + array('config_text.add', array('avatar_rules_options', OPTION_FLAG_BBCODE + OPTION_FLAG_SMILIES + OPTION_FLAG_LINKS)), + ); + } +} From 6e164d45c3e8c7c40ee957586cc356413b49dd6e Mon Sep 17 00:00:00 2001 From: MichaelC Date: Mon, 29 Dec 2014 16:55:54 +0000 Subject: [PATCH 2/2] Add ACP module (excluding the main template). Most of this is copied/adapted from board announcements to save time but there is a lot of code duplication between signatures and avatars which i'd like to resolve at some point. --- acp/user_profile_rules_avatar_info.php | 29 + acp/user_profile_rules_avatar_module.php | 183 ++++++ acp/user_profile_rules_signature_info.php | 29 + acp/user_profile_rules_signature_module.php | 183 ++++++ adm/style/colpick.css | 420 ++++++++++++++ adm/style/colpick.js | 520 ++++++++++++++++++ adm/style/event/acp_overall_footer_after.html | 36 ++ .../event/acp_overall_header_head_append.html | 3 + language/en/info_acp_user_profile_rules.php | 48 ++ language/en/userprofilerules_acp.php | 51 ++ 10 files changed, 1502 insertions(+) create mode 100644 acp/user_profile_rules_avatar_info.php create mode 100644 acp/user_profile_rules_avatar_module.php create mode 100644 acp/user_profile_rules_signature_info.php create mode 100644 acp/user_profile_rules_signature_module.php create mode 100644 adm/style/colpick.css create mode 100644 adm/style/colpick.js create mode 100644 adm/style/event/acp_overall_footer_after.html create mode 100644 adm/style/event/acp_overall_header_head_append.html create mode 100644 language/en/info_acp_user_profile_rules.php create mode 100644 language/en/userprofilerules_acp.php diff --git a/acp/user_profile_rules_avatar_info.php b/acp/user_profile_rules_avatar_info.php new file mode 100644 index 0000000..633e605 --- /dev/null +++ b/acp/user_profile_rules_avatar_info.php @@ -0,0 +1,29 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +*/ + +namespace phpbb\userprofilerules\acp; + +class user_profile_rules_avatar_info +{ + function module() + { + return array( + 'filename' => '\phpbb\userprofilerules\acp\user_profile_rules_avatar_module', + 'title' => 'ACP_USER_PROFILE_RULES_AVATAR', + 'modes' => array( + 'settings' => array( + 'title' => 'ACP_USER_PROFILE_RULES_AVATAR', + 'auth' => 'ext_phpbb/userprofilerules && acl_a_board', + 'cat' => array('ACP_USER_PROFILE_RULES') + ), + ), + ); + } +} diff --git a/acp/user_profile_rules_avatar_module.php b/acp/user_profile_rules_avatar_module.php new file mode 100644 index 0000000..322a9fa --- /dev/null +++ b/acp/user_profile_rules_avatar_module.php @@ -0,0 +1,183 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +*/ + +namespace phpbb\userprofilerules\acp; + +class user_profile_rules_avatar_module +{ + /** @var \phpbb\config\db_text */ + protected $config_text; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\log\log */ + protected $log; + + /** @var \phpbb\request\request */ + protected $request; + + /** @var \phpbb\template\template */ + protected $template; + + /** @var \phpbb\user */ + protected $user; + + /** @var ContainerInterface */ + protected $phpbb_container; + + /** @var string */ + protected $phpbb_root_path; + + /** @var string */ + protected $php_ext; + + /** @var string */ + public $u_action; + + public function main($id, $mode) + { + // This is really ugly, we need to do something about this as soon as phpBB enables us to + global $db, $request, $template, $user, $phpbb_root_path, $phpEx, $phpbb_container; + + $this->config_text = $phpbb_container->get('config_text'); + $this->db = $db; + $this->log = $phpbb_container->get('log'); + $this->request = $request; + $this->template = $template; + $this->user = $user; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $phpEx; + + // BBcodes stuff has some custom language vars so we need to load those + $this->user->add_lang(array('posting')); + + // As we use custom set language variables we need to load the language file + $this->user->add_lang_ext('phpbb/userprofilerules', 'userprofilerules_acp'); + + // Set the template, we share a template for avatar/signature rules changes + $this->tpl_name = 'user_profile_rules'; + + // Set the page for our ACP page as a language variable + $this->page_title = 'ACP_USER_PROFILE_RULES_AVATAR_SETTINGS'; + + // We need to set a form key for CRSF protection + $form_name = 'acp_user_profile_rules'; + add_form_key($form_name); + + // Set an empty error string so it's ready if we have an error later on + $error = ''; + + // We use a number of bbcode functions for getting text ready for storage/display + // which are kept inside this functions file + if (!function_exists('display_custom_bbcodes')) + { + include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext); + } + + // We need the avatar rules data to manipulate on the acp page so we get it from the db/cache + // via the config_text abstraction layer + $data = $this->config_text->get_array(array( + 'avatar_rules_text', + 'avatar_rules_uid', + 'avatar_rules_bitfield', + 'avatar_rules_options', + )); + + // We need to process submitted data if we are previewing or saving + if ($this->request->is_set_post('submit') || $this->request->is_set_post('preview')) + { + // Test if form key is valid for CRSF protection + if (!check_form_key($form_name)) + { + $error = $this->user->lang('FORM_INVALID'); + } + + // We obviously need to get the new announcement text from the submitted + // form for saving/generating a new preview + $data['avatar_rules_text'] = $this->request->variable('user_profile_rules_text', '', true); + + // We need to specially prepare the submitted data for storage with some + // special bbcode processing and sanitization + generate_text_for_storage( + $data['avatar_rules_text'], + $data['avatar_rules_uid'], + $data['avatar_rules_bitfield'], + $data['avatar_rules_options'], + !$this->request->variable('disable_bbcode', false), + !$this->request->variable('disable_magic_url', false), + !$this->request->variable('disable_smilies', false) + ); + + // If all is okay then we have to persist the submitted data to the database + if (empty($error) && $this->request->is_set_post('submit')) + { + // Here we persist the submitted datas to the db/cache via the config_text + // abstraction layer + $this->config_text->set_array(array( + 'avatar_rules_text' => $data['avatar_rules_text'], + 'avatar_rules_uid' => $data['avatar_rules_uid'], + 'avatar_rules_bitfield' => $data['avatar_rules_bitfield'], + 'avatar_rules_options' => $data['avatar_rules_options'], + )); + + // Log the rules update to the ACP logs + $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'USER_PROFILE_RULES_UPDATED_LOG'); + + // Finally we need to inform the user this process has completed so we output + // an auto-generated message with a link back where they were before + trigger_error($this->user->lang('USER_PROFILE_RULES_UPDATED') . adm_back_link($this->u_action)); + } + } + + // Prepare a fresh announcement preview + $avatar_rules_text_preview = ''; + if ($this->request->is_set_post('preview')) + { + // We need to parse the message stored in the db as it's not stored in a raw format + $avatar_rules_text_preview = generate_text_for_display($data['avatar_rules_text'], $data['avatar_rules_uid'], $data['avatar_rules_bitfield'], $data['avatar_rules_options']); + } + + // We also then need to be able to get the message in a format that is the one we can edit it in + $avatar_rules_text_edit = generate_text_for_edit($data['avatar_rules_text'], $data['avatar_rules_uid'], $data['avatar_rules_options']); + + // Output data to the template + $this->template->assign_vars(array( + 'ERRORS' => $error, + 'USER_PROFILE_RULES_TEXT' => $avatar_rules_text_edit['text'], + 'USER_PROFILE_RULES_PREVIEW' => $avatar_rules_text_preview, + + 'S_BBCODE_DISABLE_CHECKED' => !$avatar_rules_text_edit['allow_bbcode'], + 'S_SMILIES_DISABLE_CHECKED' => !$avatar_rules_text_edit['allow_smilies'], + 'S_MAGIC_URL_DISABLE_CHECKED' => !$avatar_rules_text_edit['allow_urls'], + + 'BBCODE_STATUS' => $this->user->lang('BBCODE_IS_ON', '<a href="' . append_sid("{$this->phpbb_root_path}faq.{$this->php_ext}", 'mode=bbcode') . '">', '</a>'), + 'SMILIES_STATUS' => $this->user->lang('SMILIES_ARE_ON'), + 'IMG_STATUS' => $this->user->lang('IMAGES_ARE_ON'), + 'FLASH_STATUS' => $this->user->lang('FLASH_IS_ON'), + 'URL_STATUS' => $this->user->lang('URL_IS_ON'), + + 'S_BBCODE_ALLOWED' => true, + 'S_SMILIES_ALLOWED' => true, + 'S_BBCODE_IMG' => true, + 'S_BBCODE_FLASH' => true, + 'S_LINKS_ALLOWED' => true, + + 'USER_PROFILE_RULES_AVATAR' => true, + + 'S_USER_PROFILE_RULES' => true, + + 'U_ACTION' => $this->u_action, + )); + + // Assigning custom bbcodes + display_custom_bbcodes(); + } +} diff --git a/acp/user_profile_rules_signature_info.php b/acp/user_profile_rules_signature_info.php new file mode 100644 index 0000000..db09350 --- /dev/null +++ b/acp/user_profile_rules_signature_info.php @@ -0,0 +1,29 @@ +<?php +/** +* +* User Profile Rules extension for the phpBB Forum Software package. +* +* @copyright (c) 2015 phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +*/ + +namespace phpbb\userprofilerules\acp; + +class user_profile_rules_signature_info +{ + function module() + { + return array( + 'filename' => '\phpbb\userprofilerules\acp\user_profile_rules_signature_module', + 'title' => 'ACP_USER_PROFILE_RULES_SIGNATURE', + 'modes' => array( + 'settings' => array( + 'title' => 'ACP_USER_PROFILE_RULES_SIGNATURE', + 'auth' => 'ext_phpbb/userprofilerules && acl_a_board', + 'cat' => array('ACP_USER_PROFILE_RULES') + ), + ), + ); + } +} diff --git a/acp/user_profile_rules_signature_module.php b/acp/user_profile_rules_signature_module.php new file mode 100644 index 0000000..ce89de2 --- /dev/null +++ b/acp/user_profile_rules_signature_module.php @@ -0,0 +1,183 @@ +<?php +/** +* +* User Profile Rules extension for the phpBB Forum Software package. +* +* @copyright (c) 2015 phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +*/ + +namespace phpbb\userprofilerules\acp; + +class user_profile_rules_signature_module +{ + /** @var \phpbb\config\db_text */ + protected $config_text; + + /** @var \phpbb\db\driver\driver_interface */ + protected $db; + + /** @var \phpbb\log\log */ + protected $log; + + /** @var \phpbb\request\request */ + protected $request; + + /** @var \phpbb\template\template */ + protected $template; + + /** @var \phpbb\user */ + protected $user; + + /** @var ContainerInterface */ + protected $phpbb_container; + + /** @var string */ + protected $phpbb_root_path; + + /** @var string */ + protected $php_ext; + + /** @var string */ + public $u_action; + + public function main($id, $mode) + { + // This is really ugly, we need to do something about this as soon as phpBB enables us to + global $db, $request, $template, $user, $phpbb_root_path, $phpEx, $phpbb_container; + + $this->config_text = $phpbb_container->get('config_text'); + $this->db = $db; + $this->log = $phpbb_container->get('log'); + $this->request = $request; + $this->template = $template; + $this->user = $user; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $phpEx; + + // BBcodes stuff has some custom language vars so we need to load those + $this->user->add_lang(array('posting')); + + // As we use custom set language variables we need to load the language file + $this->user->add_lang_ext('phpbb/userprofilerules', 'userprofilerules_acp'); + + // Set the template, we share a template for avatar/signature rules changes + $this->tpl_name = 'user_profile_rules'; + + // Set the page <title> for our ACP page as a language variable + $this->page_title = 'ACP_USER_PROFILE_RULES_SIGNATURE_SETTINGS'; + + // We need to set a form key for CRSF protection + $form_name = 'acp_user_profile_rules'; + add_form_key($form_name); + + // Set an empty error string so it's ready if we have an error later on + $error = ''; + + // We use a number of bbcode functions for getting text ready for storage/display + // which are kept inside this functions file + if (!function_exists('display_custom_bbcodes')) + { + include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext); + } + + // We need the avatar rules data to manipulate on the acp page so we get it from the db/cache + // via the config_text abstraction layer + $data = $this->config_text->get_array(array( + 'signature_rules_text', + 'signature_rules_uid', + 'signature_rules_bitfield', + 'signature_rules_options', + )); + + // We need to process submitted data if we are previewing or saving + if ($this->request->is_set_post('submit') || $this->request->is_set_post('preview')) + { + // Test if form key is valid for CRSF protection + if (!check_form_key($form_name)) + { + $error = $this->user->lang('FORM_INVALID'); + } + + // We obviously need to get the new announcement text from the submitted + // form for saving/generating a new preview + $data['signature_rules_text'] = $this->request->variable('user_profile_rules_text', '', true); + + // We need to specially prepare the submitted data for storage with some + // special bbcode processing and sanitization + generate_text_for_storage( + $data['signature_rules_text'], + $data['signature_rules_uid'], + $data['signature_rules_bitfield'], + $data['signature_rules_options'], + !$this->request->variable('disable_bbcode', false), + !$this->request->variable('disable_magic_url', false), + !$this->request->variable('disable_smilies', false) + ); + + // If all is okay then we have to persist the submitted data to the database + if (empty($error) && $this->request->is_set_post('submit')) + { + // Here we persist the submitted datas to the db/cache via the config_text + // abstraction layer + $this->config_text->set_array(array( + 'signature_rules_text' => $data['signature_rules_text'], + 'signature_rules_uid' => $data['signature_rules_uid'], + 'signature_rules_bitfield' => $data['signature_rules_bitfield'], + 'signature_rules_options' => $data['signature_rules_options'], + )); + + // Log the rules update to the ACP logs + $this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'USER_PROFILE_RULES_UPDATED_LOG'); + + // Finally we need to inform the user this process has completed so we output + // an auto-generated message with a link back where they were before + trigger_error($this->user->lang('USER_PROFILE_RULES_UPDATED') . adm_back_link($this->u_action)); + } + } + + // Prepare a fresh announcement preview + $signature_rules_text_preview = ''; + if ($this->request->is_set_post('preview')) + { + // We need to parse the message stored in the db as it's not stored in a raw format + $signature_rules_text_preview = generate_text_for_display($data['signature_rules_text'], $data['signature_rules_uid'], $data['signature_rules_bitfield'], $data['signature_rules_options']); + } + + // We also then need to be able to get the message in a format that is the one we can edit it in + $signature_rules_text_edit = generate_text_for_edit($data['signature_rules_text'], $data['signature_rules_uid'], $data['signature_rules_options']); + + // Output data to the template + $this->template->assign_vars(array( + 'ERRORS' => $error, + 'USER_PROFILE_RULES_TEXT' => $signature_rules_text_edit['text'], + 'USER_PROFILE_RULES_PREVIEW' => $signature_rules_text_preview, + + 'S_BBCODE_DISABLE_CHECKED' => !$signature_rules_text_edit['allow_bbcode'], + 'S_SMILIES_DISABLE_CHECKED' => !$signature_rules_text_edit['allow_smilies'], + 'S_MAGIC_URL_DISABLE_CHECKED' => !$signature_rules_text_edit['allow_urls'], + + 'BBCODE_STATUS' => $this->user->lang('BBCODE_IS_ON', '<a href="' . append_sid("{$this->phpbb_root_path}faq.{$this->php_ext}", 'mode=bbcode') . '">', '</a>'), + 'SMILIES_STATUS' => $this->user->lang('SMILIES_ARE_ON'), + 'IMG_STATUS' => $this->user->lang('IMAGES_ARE_ON'), + 'FLASH_STATUS' => $this->user->lang('FLASH_IS_ON'), + 'URL_STATUS' => $this->user->lang('URL_IS_ON'), + + 'S_BBCODE_ALLOWED' => true, + 'S_SMILIES_ALLOWED' => true, + 'S_BBCODE_IMG' => true, + 'S_BBCODE_FLASH' => true, + 'S_LINKS_ALLOWED' => true, + + 'USER_PROFILE_RULES_AVATAR' => false, + + 'S_USER_PROFILE_RULES' => true, + + 'U_ACTION' => $this->u_action, + )); + + // Assigning custom bbcodes + display_custom_bbcodes(); + } +} diff --git a/adm/style/colpick.css b/adm/style/colpick.css new file mode 100644 index 0000000..564f60c --- /dev/null +++ b/adm/style/colpick.css @@ -0,0 +1,420 @@ +/* +colpick Color Picker / colpick.com +*/ + +/*Main container*/ +.colpick { + position: absolute; + width: 346px; + height: 170px; + overflow: hidden; + display: none; + font-family: Arial, Helvetica, sans-serif; + background:#ebebeb; + border: 1px solid #bbb; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + + /*Prevents selecting text when dragging the selectors*/ + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +/*Color selection box with gradients*/ +.colpick_color { + position: absolute; + left: 7px; + top: 7px; + width: 156px; + height: 156px; + overflow: hidden; + outline: 1px solid #aaa; + cursor: crosshair; +} +.colpick_color_overlay1 { + position: absolute; + left:0; + top:0; + width: 156px; + height: 156px; + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffffff', endColorstr='#00ffffff')"; /* IE8 */ + background: -moz-linear-gradient(left, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* IE10+ */ + background: linear-gradient(to right, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffffff', endColorstr='#00ffffff'); /* IE6 & IE7 */ +} +.colpick_color_overlay2 { + position: absolute; + left:0; + top:0; + width: 156px; + height: 156px; + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00000000', endColorstr='#000000')"; /* IE8 */ + background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,1))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* IE10+ */ + background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#000000',GradientType=0 ); /* IE6-9 */ +} +/*Circular color selector*/ +.colpick_selector_outer { + background:none; + position: absolute; + width: 11px; + height: 11px; + margin: -6px 0 0 -6px; + border: 1px solid black; + border-radius: 50%; +} +.colpick_selector_inner{ + position: absolute; + width: 9px; + height: 9px; + border: 1px solid white; + border-radius: 50%; +} +/*Vertical hue bar*/ +.colpick_hue { + position: absolute; + top: 6px; + left: 175px; + width: 19px; + height: 156px; + border: 1px solid #aaa; + cursor: n-resize; +} +/*Hue bar sliding indicator*/ +.colpick_hue_arrs { + position: absolute; + left: -8px; + width: 35px; + height: 7px; + margin: -7px 0 0 0; +} +.colpick_hue_larr { + position:absolute; + width: 0; + height: 0; + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + border-left: 7px solid #858585; +} +.colpick_hue_rarr { + position:absolute; + right:0; + width: 0; + height: 0; + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + border-right: 7px solid #858585; +} +/*New color box*/ +.colpick_new_color { + position: absolute; + left: 207px; + top: 6px; + width: 60px; + height: 27px; + background: #f00; + border: 1px solid #8f8f8f; +} +/*Current color box*/ +.colpick_current_color { + position: absolute; + left: 277px; + top: 6px; + width: 60px; + height: 27px; + background: #f00; + border: 1px solid #8f8f8f; +} +/*Input field containers*/ +.colpick_field, .colpick_hex_field { + position: absolute; + height: 20px; + width: 60px; + overflow:hidden; + background:#f3f3f3; + color:#b8b8b8; + font-size:12px; + border:1px solid #bdbdbd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.colpick_rgb_r { + top: 40px; + left: 207px; +} +.colpick_rgb_g { + top: 67px; + left: 207px; +} +.colpick_rgb_b { + top: 94px; + left: 207px; +} +.colpick_hsb_h { + top: 40px; + left: 277px; +} +.colpick_hsb_s { + top: 67px; + left: 277px; +} +.colpick_hsb_b { + top: 94px; + left: 277px; +} +.colpick_hex_field { + width: 68px; + left: 207px; + top: 121px; +} +/*Text field container on focus*/ +.colpick_focus { + border-color: #999; +} +/*Field label container*/ +.colpick_field_letter { + position: absolute; + width: 12px; + height: 20px; + line-height: 20px; + padding-left: 4px; + background: #efefef; + border-right: 1px solid #bdbdbd; + font-weight: bold; + color:#777; +} +/*Text inputs*/ +.colpick_field input, .colpick_hex_field input { + position: absolute; + right: 11px; + margin: 0; + padding: 0; + height: 20px; + line-height: 20px; + background: transparent; + border: none; + font-size: 12px; + font-family: Arial, Helvetica, sans-serif; + color: #555; + text-align: right; + outline: none; +} +.colpick_hex_field input { + right: 4px; +} +/*Field up/down arrows*/ +.colpick_field_arrs { + position: absolute; + top: 0; + right: 0; + width: 9px; + height: 21px; + cursor: n-resize; +} +.colpick_field_uarr { + position: absolute; + top: 5px; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-bottom: 4px solid #959595; +} +.colpick_field_darr { + position: absolute; + bottom:5px; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #959595; +} +/*Submit/Select button*/ +.colpick_submit { + position: absolute; + left: 207px; + top: 149px; + width: 130px; + height: 22px; + line-height:22px; + background: #efefef; + text-align: center; + color: #555; + font-size: 12px; + font-weight:bold; + border: 1px solid #bdbdbd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.colpick_submit:hover { + background:#f3f3f3; + border-color:#999; + cursor: pointer; +} + +/*full layout with no submit button*/ +.colpick_full_ns .colpick_submit, .colpick_full_ns .colpick_current_color{ + display:none; +} +.colpick_full_ns .colpick_new_color { + width: 130px; + height: 25px; +} +.colpick_full_ns .colpick_rgb_r, .colpick_full_ns .colpick_hsb_h { + top: 42px; +} +.colpick_full_ns .colpick_rgb_g, .colpick_full_ns .colpick_hsb_s { + top: 73px; +} +.colpick_full_ns .colpick_rgb_b, .colpick_full_ns .colpick_hsb_b { + top: 104px; +} +.colpick_full_ns .colpick_hex_field { + top: 135px; +} + +/*rgbhex layout*/ +.colpick_rgbhex .colpick_hsb_h, .colpick_rgbhex .colpick_hsb_s, .colpick_rgbhex .colpick_hsb_b { + display:none; +} +.colpick_rgbhex { + width:282px; +} +.colpick_rgbhex .colpick_field, .colpick_rgbhex .colpick_submit { + width:68px; +} +.colpick_rgbhex .colpick_new_color { + width:34px; + border-right:none; +} +.colpick_rgbhex .colpick_current_color { + width:34px; + left:240px; + border-left:none; +} + +/*rgbhex layout, no submit button*/ +.colpick_rgbhex_ns .colpick_submit, .colpick_rgbhex_ns .colpick_current_color{ + display:none; +} +.colpick_rgbhex_ns .colpick_new_color{ + width:68px; + border: 1px solid #8f8f8f; +} +.colpick_rgbhex_ns .colpick_rgb_r { + top: 42px; +} +.colpick_rgbhex_ns .colpick_rgb_g { + top: 73px; +} +.colpick_rgbhex_ns .colpick_rgb_b { + top: 104px; +} +.colpick_rgbhex_ns .colpick_hex_field { + top: 135px; +} + +/*hex layout*/ +.colpick_hex .colpick_hsb_h, .colpick_hex .colpick_hsb_s, .colpick_hex .colpick_hsb_b, .colpick_hex .colpick_rgb_r, .colpick_hex .colpick_rgb_g, .colpick_hex .colpick_rgb_b { + display:none; +} +.colpick_hex { + width:206px; + height:201px; +} +.colpick_hex .colpick_hex_field { + width:72px; + height:25px; + top:168px; + left:80px; +} +.colpick_hex .colpick_hex_field div, .colpick_hex .colpick_hex_field input { + height: 25px; + line-height: 25px; +} +.colpick_hex .colpick_new_color { + left:9px; + top:168px; + width:30px; + border-right:none; +} +.colpick_hex .colpick_current_color { + left:39px; + top:168px; + width:30px; + border-left:none; +} +.colpick_hex .colpick_submit { + left:164px; + top: 168px; + width:30px; + height:25px; + line-height: 25px; +} + +/*hex layout, no submit button*/ +.colpick_hex_ns .colpick_submit, .colpick_hex_ns .colpick_current_color { + display:none; +} +.colpick_hex_ns .colpick_hex_field { + width:80px; +} +.colpick_hex_ns .colpick_new_color{ + width:60px; + border: 1px solid #8f8f8f; +} + +/*Dark color scheme*/ +.colpick_dark { + background: #161616; + border-color: #2a2a2a; +} +.colpick_dark .colpick_color { + outline-color: #333; +} +.colpick_dark .colpick_hue { + border-color: #555; +} +.colpick_dark .colpick_field, .colpick_dark .colpick_hex_field { + background: #101010; + border-color: #2d2d2d; +} +.colpick_dark .colpick_field_letter { + background: #131313; + border-color: #2d2d2d; + color: #696969; +} +.colpick_dark .colpick_field input, .colpick_dark .colpick_hex_field input { + color: #7a7a7a; +} +.colpick_dark .colpick_field_uarr { + border-bottom-color:#696969; +} +.colpick_dark .colpick_field_darr { + border-top-color:#696969; +} +.colpick_dark .colpick_focus { + border-color:#444; +} +.colpick_dark .colpick_submit { + background: #131313; + border-color:#2d2d2d; + color:#7a7a7a; +} +.colpick_dark .colpick_submit:hover { + background-color:#101010; + border-color:#444; +} \ No newline at end of file diff --git a/adm/style/colpick.js b/adm/style/colpick.js new file mode 100644 index 0000000..d77432a --- /dev/null +++ b/adm/style/colpick.js @@ -0,0 +1,520 @@ +/* +colpick Color Picker +Copyright 2013 Jose Vargas. Licensed under GPL license. Based on Stefan Petre's Color Picker www.eyecon.ro, dual licensed under the MIT and GPL licenses + +For usage and examples: colpick.com/plugin + */ + +(function ($) { + var colpick = function () { + var + tpl = '<div class="colpick"><div class="colpick_color"><div class="colpick_color_overlay1"><div class="colpick_color_overlay2"><div class="colpick_selector_outer"><div class="colpick_selector_inner"></div></div></div></div></div><div class="colpick_hue"><div class="colpick_hue_arrs"><div class="colpick_hue_larr"></div><div class="colpick_hue_rarr"></div></div></div><div class="colpick_new_color"></div><div class="colpick_current_color"></div><div class="colpick_hex_field"><div class="colpick_field_letter">#</div><input type="text" maxlength="6" size="6" /></div><div class="colpick_rgb_r colpick_field"><div class="colpick_field_letter">R</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_rgb_g colpick_field"><div class="colpick_field_letter">G</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_rgb_b colpick_field"><div class="colpick_field_letter">B</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsb_h colpick_field"><div class="colpick_field_letter">H</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsb_s colpick_field"><div class="colpick_field_letter">S</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsb_b colpick_field"><div class="colpick_field_letter">B</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_submit"></div></div>', + defaults = { + showEvent: 'click', + onShow: function () {}, + onBeforeShow: function(){}, + onHide: function () {}, + onChange: function () {}, + onSubmit: function () {}, + colorScheme: 'light', + color: '3289c7', + livePreview: true, + flat: false, + layout: 'full', + submit: 1, + submitText: 'OK', + height: 156 + }, + //Fill the inputs of the plugin + fillRGBFields = function (hsb, cal) { + var rgb = hsbToRgb(hsb); + $(cal).data('colpick').fields + .eq(1).val(rgb.r).end() + .eq(2).val(rgb.g).end() + .eq(3).val(rgb.b).end(); + }, + fillHSBFields = function (hsb, cal) { + $(cal).data('colpick').fields + .eq(4).val(Math.round(hsb.h)).end() + .eq(5).val(Math.round(hsb.s)).end() + .eq(6).val(Math.round(hsb.b)).end(); + }, + fillHexFields = function (hsb, cal) { + $(cal).data('colpick').fields.eq(0).val(hsbToHex(hsb)); + }, + //Set the round selector position + setSelector = function (hsb, cal) { + $(cal).data('colpick').selector.css('backgroundColor', '#' + hsbToHex({h: hsb.h, s: 100, b: 100})); + $(cal).data('colpick').selectorIndic.css({ + left: parseInt($(cal).data('colpick').height * hsb.s/100, 10), + top: parseInt($(cal).data('colpick').height * (100-hsb.b)/100, 10) + }); + }, + //Set the hue selector position + setHue = function (hsb, cal) { + $(cal).data('colpick').hue.css('top', parseInt($(cal).data('colpick').height - $(cal).data('colpick').height * hsb.h/360, 10)); + }, + //Set current and new colors + setCurrentColor = function (hsb, cal) { + $(cal).data('colpick').currentColor.css('backgroundColor', '#' + hsbToHex(hsb)); + }, + setNewColor = function (hsb, cal) { + $(cal).data('colpick').newColor.css('backgroundColor', '#' + hsbToHex(hsb)); + }, + //Called when the new color is changed + change = function (ev) { + var cal = $(this).parent().parent(), col; + if (this.parentNode.className.indexOf('_hex') > 0) { + cal.data('colpick').color = col = hexToHsb(fixHex(this.value)); + fillRGBFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + } else if (this.parentNode.className.indexOf('_hsb') > 0) { + cal.data('colpick').color = col = fixHSB({ + h: parseInt(cal.data('colpick').fields.eq(4).val(), 10), + s: parseInt(cal.data('colpick').fields.eq(5).val(), 10), + b: parseInt(cal.data('colpick').fields.eq(6).val(), 10) + }); + fillRGBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + } else { + cal.data('colpick').color = col = rgbToHsb(fixRGB({ + r: parseInt(cal.data('colpick').fields.eq(1).val(), 10), + g: parseInt(cal.data('colpick').fields.eq(2).val(), 10), + b: parseInt(cal.data('colpick').fields.eq(3).val(), 10) + })); + fillHexFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + } + setSelector(col, cal.get(0)); + setHue(col, cal.get(0)); + setNewColor(col, cal.get(0)); + cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 0]); + }, + //Change style on blur and on focus of inputs + blur = function (ev) { + $(this).parent().removeClass('colpick_focus'); + }, + focus = function () { + $(this).parent().parent().data('colpick').fields.parent().removeClass('colpick_focus'); + $(this).parent().addClass('colpick_focus'); + }, + //Increment/decrement arrows functions + downIncrement = function (ev) { + ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; + var field = $(this).parent().find('input').focus(); + var current = { + el: $(this).parent().addClass('colpick_slider'), + max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255), + y: ev.pageY, + field: field, + val: parseInt(field.val(), 10), + preview: $(this).parent().parent().data('colpick').livePreview + }; + $(document).mouseup(current, upIncrement); + $(document).mousemove(current, moveIncrement); + }, + moveIncrement = function (ev) { + ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val - ev.pageY + ev.data.y, 10)))); + if (ev.data.preview) { + change.apply(ev.data.field.get(0), [true]); + } + return false; + }, + upIncrement = function (ev) { + change.apply(ev.data.field.get(0), [true]); + ev.data.el.removeClass('colpick_slider').find('input').focus(); + $(document).off('mouseup', upIncrement); + $(document).off('mousemove', moveIncrement); + return false; + }, + //Hue slider functions + downHue = function (ev) { + ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; + var current = { + cal: $(this).parent(), + y: $(this).offset().top + }; + $(document).on('mouseup touchend',current,upHue); + $(document).on('mousemove touchmove',current,moveHue); + + var pageY = ((ev.type == 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); + change.apply( + current.cal.data('colpick') + .fields.eq(4).val(parseInt(360*(current.cal.data('colpick').height - (pageY - current.y))/current.cal.data('colpick').height, 10)) + .get(0), + [current.cal.data('colpick').livePreview] + ); + return false; + }, + moveHue = function (ev) { + var pageY = ((ev.type == 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); + change.apply( + ev.data.cal.data('colpick') + .fields.eq(4).val(parseInt(360*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.y))))/ev.data.cal.data('colpick').height, 10)) + .get(0), + [ev.data.preview] + ); + return false; + }, + upHue = function (ev) { + fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); + fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); + $(document).off('mouseup touchend',upHue); + $(document).off('mousemove touchmove',moveHue); + return false; + }, + //Color selector functions + downSelector = function (ev) { + ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; + var current = { + cal: $(this).parent(), + pos: $(this).offset() + }; + current.preview = current.cal.data('colpick').livePreview; + + $(document).on('mouseup touchend',current,upSelector); + $(document).on('mousemove touchmove',current,moveSelector); + + var payeX,pageY; + if(ev.type == 'touchstart') { + pageX = ev.originalEvent.changedTouches[0].pageX, + pageY = ev.originalEvent.changedTouches[0].pageY; + } else { + pageX = ev.pageX; + pageY = ev.pageY; + } + + change.apply( + current.cal.data('colpick').fields + .eq(6).val(parseInt(100*(current.cal.data('colpick').height - (pageY - current.pos.top))/current.cal.data('colpick').height, 10)).end() + .eq(5).val(parseInt(100*(pageX - current.pos.left)/current.cal.data('colpick').height, 10)) + .get(0), + [current.preview] + ); + return false; + }, + moveSelector = function (ev) { + var payeX,pageY; + if(ev.type == 'touchmove') { + pageX = ev.originalEvent.changedTouches[0].pageX, + pageY = ev.originalEvent.changedTouches[0].pageY; + } else { + pageX = ev.pageX; + pageY = ev.pageY; + } + + change.apply( + ev.data.cal.data('colpick').fields + .eq(6).val(parseInt(100*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.pos.top))))/ev.data.cal.data('colpick').height, 10)).end() + .eq(5).val(parseInt(100*(Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageX - ev.data.pos.left))))/ev.data.cal.data('colpick').height, 10)) + .get(0), + [ev.data.preview] + ); + return false; + }, + upSelector = function (ev) { + fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); + fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); + $(document).off('mouseup touchend',upSelector); + $(document).off('mousemove touchmove',moveSelector); + return false; + }, + //Submit button + clickSubmit = function (ev) { + var cal = $(this).parent(); + var col = cal.data('colpick').color; + cal.data('colpick').origColor = col; + setCurrentColor(col, cal.get(0)); + cal.data('colpick').onSubmit(col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el); + }, + //Show/hide the color picker + show = function (ev) { + // Prevent the trigger of any direct parent + ev.stopPropagation(); + var cal = $('#' + $(this).data('colpickId')); + cal.data('colpick').onBeforeShow.apply(this, [cal.get(0)]); + var pos = $(this).offset(); + var top = pos.top + this.offsetHeight; + var left = pos.left; + var viewPort = getViewport(); + var calW = cal.width(); + if (left + calW > viewPort.l + viewPort.w) { + left -= calW; + } + cal.css({left: left + 'px', top: top + 'px'}); + if (cal.data('colpick').onShow.apply(this, [cal.get(0)]) != false) { + cal.show(); + } + //Hide when user clicks outside + $('html').mousedown({cal:cal}, hide); + cal.mousedown(function(ev){ev.stopPropagation();}) + }, + hide = function (ev) { + if (ev.data.cal.data('colpick').onHide.apply(this, [ev.data.cal.get(0)]) != false) { + ev.data.cal.hide(); + } + $('html').off('mousedown', hide); + }, + getViewport = function () { + var m = document.compatMode == 'CSS1Compat'; + return { + l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), + w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth) + }; + }, + //Fix the values if the user enters a negative or high value + fixHSB = function (hsb) { + return { + h: Math.min(360, Math.max(0, hsb.h)), + s: Math.min(100, Math.max(0, hsb.s)), + b: Math.min(100, Math.max(0, hsb.b)) + }; + }, + fixRGB = function (rgb) { + return { + r: Math.min(255, Math.max(0, rgb.r)), + g: Math.min(255, Math.max(0, rgb.g)), + b: Math.min(255, Math.max(0, rgb.b)) + }; + }, + fixHex = function (hex) { + var len = 6 - hex.length; + if (len > 0) { + var o = []; + for (var i=0; i<len; i++) { + o.push('0'); + } + o.push(hex); + hex = o.join(''); + } + return hex; + }, + restoreOriginal = function () { + var cal = $(this).parent(); + var col = cal.data('colpick').origColor; + cal.data('colpick').color = col; + fillRGBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + setSelector(col, cal.get(0)); + setHue(col, cal.get(0)); + setNewColor(col, cal.get(0)); + }; + return { + init: function (opt) { + opt = $.extend({}, defaults, opt||{}); + //Set color + if (typeof opt.color == 'string') { + opt.color = hexToHsb(opt.color); + } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) { + opt.color = rgbToHsb(opt.color); + } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) { + opt.color = fixHSB(opt.color); + } else { + return this; + } + + //For each selected DOM element + return this.each(function () { + //If the element does not have an ID + if (!$(this).data('colpickId')) { + var options = $.extend({}, opt); + options.origColor = opt.color; + //Generate and assign a random ID + var id = 'collorpicker_' + parseInt(Math.random() * 1000); + $(this).data('colpickId', id); + //Set the tpl's ID and get the HTML + var cal = $(tpl).attr('id', id); + //Add class according to layout + cal.addClass('colpick_'+options.layout+(options.submit?'':' colpick_'+options.layout+'_ns')); + //Add class if the color scheme is not default + if(options.colorScheme != 'light') { + cal.addClass('colpick_'+options.colorScheme); + } + //Setup submit button + cal.find('div.colpick_submit').html(options.submitText).click(clickSubmit); + //Setup input fields + options.fields = cal.find('input').change(change).blur(blur).focus(focus); + cal.find('div.colpick_field_arrs').mousedown(downIncrement).end().find('div.colpick_current_color').click(restoreOriginal); + //Setup hue selector + options.selector = cal.find('div.colpick_color').on('mousedown touchstart',downSelector); + options.selectorIndic = options.selector.find('div.colpick_selector_outer'); + //Store parts of the plugin + options.el = this; + options.hue = cal.find('div.colpick_hue_arrs'); + huebar = options.hue.parent(); + //Paint the hue bar + var UA = navigator.userAgent.toLowerCase(); + var isIE = navigator.appName === 'Microsoft Internet Explorer'; + var IEver = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[\.0-9]{0,})/ )[1] ) : 0; + var ngIE = ( isIE && IEver < 10 ); + var stops = ['#ff0000','#ff0080','#ff00ff','#8000ff','#0000ff','#0080ff','#00ffff','#00ff80','#00ff00','#80ff00','#ffff00','#ff8000','#ff0000']; + if(ngIE) { + var i, div; + for(i=0; i<=11; i++) { + div = $('<div></div>').attr('style','height:8.333333%; filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+'); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+')";'); + huebar.append(div); + } + } else { + stopList = stops.join(','); + huebar.attr('style','background:-webkit-linear-gradient(top,'+stopList+'); background: -o-linear-gradient(top,'+stopList+'); background: -ms-linear-gradient(top,'+stopList+'); background:-moz-linear-gradient(top,'+stopList+'); -webkit-linear-gradient(top,'+stopList+'); background:linear-gradient(to bottom,'+stopList+'); '); + } + cal.find('div.colpick_hue').on('mousedown touchstart',downHue); + options.newColor = cal.find('div.colpick_new_color'); + options.currentColor = cal.find('div.colpick_current_color'); + //Store options and fill with default color + cal.data('colpick', options); + fillRGBFields(options.color, cal.get(0)); + fillHSBFields(options.color, cal.get(0)); + fillHexFields(options.color, cal.get(0)); + setHue(options.color, cal.get(0)); + setSelector(options.color, cal.get(0)); + setCurrentColor(options.color, cal.get(0)); + setNewColor(options.color, cal.get(0)); + //Append to body if flat=false, else show in place + if (options.flat) { + cal.appendTo(this).show(); + cal.css({ + position: 'relative', + display: 'block' + }); + } else { + cal.appendTo(document.body); + $(this).on(options.showEvent, show); + cal.css({ + position:'absolute' + }); + } + } + }); + }, + //Shows the picker + showPicker: function() { + return this.each( function () { + if ($(this).data('colpickId')) { + show.apply(this); + } + }); + }, + //Hides the picker + hidePicker: function() { + return this.each( function () { + if ($(this).data('colpickId')) { + $('#' + $(this).data('colpickId')).hide(); + } + }); + }, + //Sets a color as new and current (default) + setColor: function(col, setCurrent) { + setCurrent = (typeof setCurrent === "undefined") ? 1 : setCurrent; + if (typeof col == 'string') { + col = hexToHsb(col); + } else if (col.r != undefined && col.g != undefined && col.b != undefined) { + col = rgbToHsb(col); + } else if (col.h != undefined && col.s != undefined && col.b != undefined) { + col = fixHSB(col); + } else { + return this; + } + return this.each(function(){ + if ($(this).data('colpickId')) { + var cal = $('#' + $(this).data('colpickId')); + cal.data('colpick').color = col; + cal.data('colpick').origColor = col; + fillRGBFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + setHue(col, cal.get(0)); + setSelector(col, cal.get(0)); + + setNewColor(col, cal.get(0)); + cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 1]); + if(setCurrent) { + setCurrentColor(col, cal.get(0)); + } + } + }); + } + }; + }(); + //Color space convertions + var hexToRgb = function (hex) { + var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16); + return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)}; + }; + var hexToHsb = function (hex) { + return rgbToHsb(hexToRgb(hex)); + }; + var rgbToHsb = function (rgb) { + var hsb = {h: 0, s: 0, b: 0}; + var min = Math.min(rgb.r, rgb.g, rgb.b); + var max = Math.max(rgb.r, rgb.g, rgb.b); + var delta = max - min; + hsb.b = max; + hsb.s = max != 0 ? 255 * delta / max : 0; + if (hsb.s != 0) { + if (rgb.r == max) hsb.h = (rgb.g - rgb.b) / delta; + else if (rgb.g == max) hsb.h = 2 + (rgb.b - rgb.r) / delta; + else hsb.h = 4 + (rgb.r - rgb.g) / delta; + } else hsb.h = -1; + hsb.h *= 60; + if (hsb.h < 0) hsb.h += 360; + hsb.s *= 100/255; + hsb.b *= 100/255; + return hsb; + }; + var hsbToRgb = function (hsb) { + var rgb = {}; + var h = hsb.h; + var s = hsb.s*255/100; + var v = hsb.b*255/100; + if(s == 0) { + rgb.r = rgb.g = rgb.b = v; + } else { + var t1 = v; + var t2 = (255-s)*v/255; + var t3 = (t1-t2)*(h%60)/60; + if(h==360) h = 0; + if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3} + else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3} + else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3} + else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3} + else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3} + else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3} + else {rgb.r=0; rgb.g=0; rgb.b=0} + } + return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)}; + }; + var rgbToHex = function (rgb) { + var hex = [ + rgb.r.toString(16), + rgb.g.toString(16), + rgb.b.toString(16) + ]; + $.each(hex, function (nr, val) { + if (val.length == 1) { + hex[nr] = '0' + val; + } + }); + return hex.join(''); + }; + var hsbToHex = function (hsb) { + return rgbToHex(hsbToRgb(hsb)); + }; + $.fn.extend({ + colpick: colpick.init, + colpickHide: colpick.hidePicker, + colpickShow: colpick.showPicker, + colpickSetColor: colpick.setColor + }); + $.extend({ + colpick:{ + rgbToHex: rgbToHex, + rgbToHsb: rgbToHsb, + hsbToHex: hsbToHex, + hsbToRgb: hsbToRgb, + hexToHsb: hexToHsb, + hexToRgb: hexToRgb + } + }); +})(jQuery); diff --git a/adm/style/event/acp_overall_footer_after.html b/adm/style/event/acp_overall_footer_after.html new file mode 100644 index 0000000..e36e9bc --- /dev/null +++ b/adm/style/event/acp_overall_footer_after.html @@ -0,0 +1,36 @@ +<!-- IF S_USER_PROFILE_RULES --> + +<!-- IF not $INCLUDED_COLPICKJS --> + <!-- INCLUDEJS @phpbb_userprofilerules/colpick.js --> + <!-- DEFINE $INCLUDED_COLPICKJS = true --> +<!-- ENDIF --> + +<script> +jQuery(function($) { + var bgcolor = '{USER_PROFILE_RULES_BGCOLOR}'; + $('#user_profile_rules_bgcolor').colpick({ + layout: 'hex', + submit: 0, + onBeforeShow: function() { + if (bgcolor !== '') { + $(this).colpickSetColor(bgcolor); + bgcolor = ''; + } + }, + onChange: function(hsb, hex, rgb, el, bySetColor) { + $(el).css({ + 'border-right-color': '#' + hex, + 'border-right-width': '20px', + 'border-right-type': 'solid' + }); + if (!bySetColor) { + $(el).val(hex); + } + } + }).keyup(function() { + $(this).colpickSetColor(this.value || 'ffffff'); + }); +}); +</script> + +<!-- ENDIF --> diff --git a/adm/style/event/acp_overall_header_head_append.html b/adm/style/event/acp_overall_header_head_append.html new file mode 100644 index 0000000..c5295a9 --- /dev/null +++ b/adm/style/event/acp_overall_header_head_append.html @@ -0,0 +1,3 @@ +<!-- IF S_USER_PROFILE_RULES --> + <!-- INCLUDECSS colpick.css --> +<!-- ENDIF --> diff --git a/language/en/info_acp_user_profile_rules.php b/language/en/info_acp_user_profile_rules.php new file mode 100644 index 0000000..65b69e2 --- /dev/null +++ b/language/en/info_acp_user_profile_rules.php @@ -0,0 +1,48 @@ +<?php +/** +* +* User Profile Rules extension for the phpBB Forum Software package. +* +* @copyright (c) 2015 phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +*/ + +/** +* DO NOT CHANGE +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +if (empty($lang) || !is_array($lang)) +{ + $lang = array(); +} + +// DEVELOPERS PLEASE NOTE +// +// All language files should use UTF-8 as their encoding and the files must not contain a BOM. +// +// Placeholders can now contain order information, e.g. instead of +// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows +// translators to re-order the output of data while ensuring it remains correct +// +// You do not need this where single placeholders are used, e.g. 'Message %d' is fine +// equally where a string contains only two placeholders which are used to wrap text +// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine +// +// Some characters you may want to copy&paste: +// ’ » “ ” … +// + +$lang = array_merge($lang, array( + // ACP Module + 'ACP_USER_PROFILE_RULES' => 'User profile rules', + 'ACP_USER_PROFILE_RULES_SIGNATURE' => 'Signature rules', + 'ACP_USER_PROFILE_RULES_AVATAR' => 'Avatar rules', + + // ACP Logs + 'USER_PROFILE_RULES_UPDATED_LOG' => '<strong>Altered user profile rules</strong>', +)); diff --git a/language/en/userprofilerules_acp.php b/language/en/userprofilerules_acp.php new file mode 100644 index 0000000..316cb02 --- /dev/null +++ b/language/en/userprofilerules_acp.php @@ -0,0 +1,51 @@ +<?php +/** +* +* User Profile Rules extension for the phpBB Forum Software package. +* +* @copyright (c) 2015 phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +*/ + +/** +* DO NOT CHANGE +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +if (empty($lang) || !is_array($lang)) +{ + $lang = array(); +} + +// DEVELOPERS PLEASE NOTE +// +// All language files should use UTF-8 as their encoding and the files must not contain a BOM. +// +// Placeholders can now contain order information, e.g. instead of +// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows +// translators to re-order the output of data while ensuring it remains correct +// +// You do not need this where single placeholders are used, e.g. 'Message %d' is fine +// equally where a string contains only two placeholders which are used to wrap text +// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine +// +// Some characters you may want to copy&paste: +// ’ » “ ” … +// + +$lang = array_merge($lang, array( + 'USER_PROFILE_RULES_SETTINGS' => 'User profile rules settings', + 'USER_PROFILE_RULES_SETTINGS_EXPLAIN' => 'Here you can change the user profile rules that are displayed on the avatar/signature UCP pages.', + + 'USER_PROFILE_RULES_SIGNATURE_TEXT' => 'Signature rules message', + 'USER_PROFILE_RULES_SIGNATURE_PREVIEW' => 'Signature rules - preview', + 'USER_PROFILE_RULES_SIGNATURE_UPDATED' => 'Signature rules have been updated.', + + 'USER_PROFILE_RULES_AVATAR_TEXT' => 'Avatar rules message', + 'USER_PROFILE_RULES_AVATAR_PREVIEW' => 'Avatar rules - preview', + 'USER_PROFILE_RULES_AVATAR_UPDATED' => 'Avatar rules have been updated.', +));