Plugin Directory

Changeset 3414250


Ignore:
Timestamp:
12/08/2025 11:59:21 AM (2 months ago)
Author:
kasuga16
Message:

Update to 1.4.0 from 1.2.0

Location:
stick-copy-button-codeblock
Files:
17 added
6 edited

Legend:

Unmodified
Added
Removed
  • stick-copy-button-codeblock/trunk/languages/stick-copy-button-codeblock-ja.po

    r3402170 r3414250  
    11msgid ""
    22msgstr ""
    3 "Project-Id-Version: Sticky Copy Button for Code Blocks 1.2.0\n"
     3"Project-Id-Version: Sticky Copy Button for Code Blocks 1.4.0\n"
    44"Report-Msgid-Bugs-To: \n"
    5 "POT-Creation-Date: 2025-11-25 02:57:38+0000\n"
    6 "PO-Revision-Date: 2025-11-25 03:01:12+0000\n"
     5"POT-Creation-Date: 2025-12-08 11:33:05+0000\n"
     6"PO-Revision-Date: 2025-12-08 11:33:10+0000\n"
    77"Last-Translator: Kasuga\n"
    88"Language-Team: \n"
     
    1717msgstr "Sticky Copy Button for Code Blocks"
    1818
    19 msgid "This plugin adds a convenient copy button to every code block on your blog posts. Customize the button's position, labels, size, and colors from a dedicated settings page to match your site's design."
    20 msgstr "このプラグインは、ブログ記事内のすべてのコードブロックに便利なコピーボタンを追加します。専用の設定ページから、ボタンの位置やラベル、サイズ、色などをカスタマイズして、サイトのデザインに合わせることができます。"
     19msgid "This plugin adds a convenient copy button to every code block on your blog posts. Customize the button's position, labels, size, and colors from a dedicated settings page to match your site's design. Optional line numbers can be displayed."
     20msgstr "このプラグインは、ブログ記事内のすべてのコードブロックに便利なコピーボタンを追加します。専用の設定ページから、ボタンの位置、ラベル、サイズ、色をカスタマイズして、サイトのデザインに合わせることができます。オプションで行番号も表示できます。"
    2121
    2222msgid "Kasuga"
     
    2929msgstr "Sticky Copy Button"
    3030
    31 msgid "Enter any custom CSS to further style the copy button or code blocks. This CSS will be loaded on the frontend.\n\n* Usable Selectors:\n\n.copy-code-btn          → The copy button\n.copy-code-btn.copied   → The button after copying\n.code-block-wrapper     → Wrapper of the code block (position: relative)\n.code-block-wrapper pre → Inner code text area (the <pre> element)\n\nExample:\n\n.copy-code-btn {\n    font-family: \"Comic Sans MS\", cursive;\n    font-weight: 700;\n}"
    32 msgstr "コピー用ボタンやコードブロックのスタイルをさらにカスタマイズするための任意のCSSを入力してください。このCSSはフロントエンドで読み込まれます。\n\n使用可能なセレクタ:\n\n.copy-code-btn          → コピー用ボタン\n.copy-code-btn.copied   → コピー後のボタン\n.code-block-wrapper     → コードブロックのラッパー(position: relative)\n.code-block-wrapper pre → 内部のコード表示領域(<pre> 要素)\n\n例:\n\n.copy-code-btn {\n    font-family: \"Comic Sans MS\", cursive;\n    font-weight: 700;\n}"
     31msgid "Enter any custom CSS to further style the copy button or code blocks. This CSS will be loaded on the frontend.\n\n* Usable Selectors:\n\n.copy-code-btn          → The copy button\n.copy-code-btn.copied   → The button after copying\n.code-block-wrapper     → Wrapper of the code block (flex container)\n.code-block-wrapper pre → Inner code text area (the <pre> element)\n\nExample:\n\n.copy-code-btn {\n    font-family: \"Comic Sans MS\", cursive;\n    font-weight: 700;\n}"
     32msgstr "カスタムCSSを入力すると、コピー ボタンやコードブロックのデザインを自由に調整できます。入力した CSS はフロントエンドで読み込まれます。\n\n使用できるセレクタ:\n\n.copy-code-btn          → コピー ボタン\n.copy-code-btn.copied   → コピー後のボタン\n.code-block-wrapper     → コードブロックのラッパー (flexコンテナ)\n.code-block-wrapper pre → コード本文 (<pre> 要素)\n\n例:\n\n.copy-code-btn {\n    font-family: \"Comic Sans MS\", cursive;\n    font-weight: 700;\n}"
    3333
    3434msgid "Adjust button top position (px)"
     
    5959msgstr "ボタンの背景色"
    6060
    61 msgid "* The label after copying (for 2 seconds), the text and background colors are swapped."
    62 msgstr "* コピー後のラベル (2秒間)は、文字色と背景色が入れ替わって表示されます。"
     61msgid "Always transparent background"
     62msgstr "常に背景を透明にする"
    6363
    64 msgid "Make background transparent"
    65 msgstr "背景を透明にする"
     64msgid "The label after copying swaps text/background for 2 seconds;<br>however, when the background is transparent, only the text color is swapped."
     65msgstr "コピー後は2秒間、文字色と背景色が反転します。<br>ただし背景が透明の場合は、文字色のみ反転します。"
     66
     67msgid "*** Other settings"
     68msgstr "*** ボタン以外の設定"
     69
     70msgid "Code block max height (px)"
     71msgstr "コードブロックの高さ上限 (px)"
    6672
    6773msgid "Enable"
    6874msgstr "有効にする"
    6975
    70 msgid "*** Other settings"
    71 msgstr "*** ボタン以外の設定"
     76msgid "Minimum value is 100px. If \"Enable\" is unchecked, this value is ignored."
     77msgstr "最小値は100pxです。「有効化」のチェックが外れている場合、この値は無視されます。"
    7278
    73 msgid "Code block max lines (lines)"
    74 msgstr "コードブロック最大行数(行)"
    75 
    76 msgid "Set max height in lines. Enter 0 or leave empty for no limit."
    77 msgstr "最大行数を設定します。制限なしにする場合は 0 を入力するか空欄のままにしてください。"
     79msgid "Display Line Numbers"
     80msgstr "行番号の表示"
    7881
    7982msgid "Custom Styles (CSS)"
    80 msgstr "カスタムスタイル(CSS)"
     83msgstr "カスタムスタイル (CSS)"
    8184
    8285msgid "Save Changes"
    8386msgstr "変更を保存"
    8487
    85 msgid "Failed to copy: "
    86 msgstr "コピーに失敗しました: "
    87 
    88 msgid "Copy error"
    89 msgstr "コピーエラー"
    90 
    9188msgid "Settings"
    9289msgstr "設定"
  • stick-copy-button-codeblock/trunk/languages/stick-copy-button-codeblock.pot

    r3402170 r3414250  
    11msgid ""
    22msgstr ""
    3 "Project-Id-Version: Sticky Copy Button for Code Blocks 1.2.0\n"
     3"Project-Id-Version: Sticky Copy Button for Code Blocks 1.4.0\n"
    44"Report-Msgid-Bugs-To: \n"
    5 "POT-Creation-Date: 2025-11-25 02:57:38+0000\n"
     5"POT-Creation-Date: 2025-12-08 11:33:05+0000\n"
    66"PO-Revision-Date: \n"
    77"Last-Translator: \n"
     
    1717msgstr ""
    1818
    19 msgid "This plugin adds a convenient copy button to every code block on your blog posts. Customize the button's position, labels, size, and colors from a dedicated settings page to match your site's design."
     19msgid "This plugin adds a convenient copy button to every code block on your blog posts. Customize the button's position, labels, size, and colors from a dedicated settings page to match your site's design. Optional line numbers can be displayed."
    2020msgstr ""
    2121
     
    2929msgstr ""
    3030
    31 msgid "Enter any custom CSS to further style the copy button or code blocks. This CSS will be loaded on the frontend.\n\n* Usable Selectors:\n\n.copy-code-btn          → The copy button\n.copy-code-btn.copied   → The button after copying\n.code-block-wrapper     → Wrapper of the code block (position: relative)\n.code-block-wrapper pre → Inner code text area (the <pre> element)\n\nExample:\n\n.copy-code-btn {\n    font-family: \"Comic Sans MS\", cursive;\n    font-weight: 700;\n}"
     31msgid "Enter any custom CSS to further style the copy button or code blocks. This CSS will be loaded on the frontend.\n\n* Usable Selectors:\n\n.copy-code-btn          → The copy button\n.copy-code-btn.copied   → The button after copying\n.code-block-wrapper     → Wrapper of the code block (flex container)\n.code-block-wrapper pre → Inner code text area (the <pre> element)\n\nExample:\n\n.copy-code-btn {\n    font-family: \"Comic Sans MS\", cursive;\n    font-weight: 700;\n}"
    3232msgstr ""
    3333
     
    5959msgstr ""
    6060
    61 msgid "* The label after copying (for 2 seconds), the text and background colors are swapped."
     61msgid "Always transparent background"
    6262msgstr ""
    6363
    64 msgid "Make background transparent"
     64msgid "The label after copying swaps text/background for 2 seconds;<br>however, when the background is transparent, only the text color is swapped."
     65msgstr ""
     66
     67msgid "*** Other settings"
     68msgstr ""
     69
     70msgid "Code block max height (px)"
    6571msgstr ""
    6672
     
    6874msgstr ""
    6975
    70 msgid "*** Other settings"
     76msgid "Minimum value is 100px. If \"Enable\" is unchecked, this value is ignored."
    7177msgstr ""
    7278
    73 msgid "Code block max lines (lines)"
    74 msgstr ""
    75 
    76 msgid "Set max height in lines. Enter 0 or leave empty for no limit."
     79msgid "Display Line Numbers"
    7780msgstr ""
    7881
     
    8386msgstr ""
    8487
    85 msgid "Failed to copy: "
    86 msgstr ""
    87 
    88 msgid "Copy error"
    89 msgstr ""
    90 
    9188msgid "Settings"
    9289msgstr ""
  • stick-copy-button-codeblock/trunk/readme.txt

    r3402170 r3414250  
    11=== Sticky Copy Button for Code Blocks ===
    22Contributors: Kasuga16
    3 Tags: code, copy, button, utility, easy
     3Tags: code, copy, button, line-numbers, easy
    44Requires at least: 5.0
    55Requires PHP: 7.4
    6 Tested up to: 6.8
    7 Stable tag: 1.2.0
     6Tested up to: 6.9
     7Stable tag: 1.4.0
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    1111Domain Path: /languages
    1212
    13 Adds a customizable copy button to code blocks, making it easy for users to copy code with a single click.
     13Adds a floating "Copy" button to every code block, with extensive styling options, optional line numbers, max-height control, and custom CSS support.
    1414
    1515== Description ==
    16 This plugin adds a convenient copy button to every code block on your blog posts, allowing users to copy code with a single click.
    1716
    18 Highlights:
     17**Sticky Copy Button for Code Blocks** automatically adds a floating copy button to each `<pre><code>` block on your website. 
     18It provides convenient front-end copying for developers, readers, and tutorial users.
    1919
    20 - Easy One-Click Copying: Your blog visitors can instantly copy code to their clipboard by simply clicking a button on any code block.
     20== Features ==
    2121
    22 - Flexible Customization: From a dedicated settings page, you can freely adjust the button's position, size, color, and labels (for both before and after copying) to perfectly match your site's design.
     22This plugin is light, fast, and highly customizable:
    2323
    24 - Lightweight and Fast: The plugin only loads the necessary CSS and JavaScript, ensuring it won't impact your site's performance.
     24- Adjustable button position (up/down and left/right)
     25- Customizable labels (“Copy” / “Copied”)
     26- Adjustable font size
     27- Background color, text color, or transparent mode
     28- Max-height option for large code blocks (with scroll support)
     29- **Optional line numbers** (simple native implementation)
     30- Custom CSS that is safely sanitized
    2531
    26 This plugin makes it super easy for your blog visitors to grab code snippets. By adding a simple copy button to every code block, it boosts convenience and makes your code content much more user-friendly.
     32No dependencies such as Prism or Highlight.js are required.
    2733
    2834== Installation ==
     
    4248    – (Optional) Go to 'Settings' → 'Stick Copy Button' to configure options.
    4349
    44 == Frequently Asked Questions ==
    45 = Which code blocks does this plugin support? =
    46 It supports code blocks marked up in the `pre > code` format.
     50== Detailed Settings Guide ==
    4751
    48 = Can I control the height of the code blocks? =
    49 Yes, you can set a **maximum height by specifying the number of lines** in the plugin settings. If the content exceeds this height, a **vertical scroll bar** will automatically appear.
     52The following explains **every option** in the plugin settings page.
    5053
    51 = Can I add custom styles? =
    52 Yes, you can enter custom CSS to further style the copy button or code blocks in the **Custom Styles (CSS)** section of the settings menu.
    53 Any CSS added here will be applied on the frontend.
     54---
    5455
    55 - Usable Selectors:
    56 **.copy-code-btn** → The copy button
    57 **.copy-code-btn.copied**  → The button after Copying
    58 **.code-block-wrapper**  → Wrapper of the code block (position: relative)
    59 **.code-block-wrapper pre** → Inner code text area (the &lt;pre&gt; element)
     56### 1. **Button Position**
     57**Adjust vertical position (top offset in px)** 
     58Moves the button up or down relative to the top of the code block. 
     59Use positive or negative values to fine-tune vertical alignment.
     60
     61**Adjust horizontal position (right offset in px)** 
     62Moves the button left or right by adjusting how far it sits from the right edge of the code block. 
     63Use positive or negative values to fine-tune horizontal alignment.
     64
     65These values help fine-tune button alignment to avoid overlapping with theme elements.
     66
     67---
     68
     69### 2. **Button Text and Behavior**
     70
     71**Copy button label** 
     72The label shown normally (default: “Copy”).
     73
     74**Label after copying (2 seconds)** 
     75Once the text is copied, the button temporarily displays this label. 
     76Default: “Copied”.
     77
     78---
     79
     80### 3. **Button Size**
     81
     82**Button size (8–36 px)** 
     83Controls the font size of the button. 
     84Padding is automatically adjusted based on this value.
     85
     86---
     87
     88### 4. **Button Colors**
     89
     90**Button text color** 
     91Hex color of button text.
     92
     93**Button background color** 
     94Hex background color. 
     95When copying, the plugin automatically swaps the text and background colors for visual feedback.
     96However, if the background is transparent, only the text color is swapped.
     97
     98**Always transparent background** 
     99If enabled:
     100- The button background always becomes transparent.
     101- Only text + border remain visible
     102
     103---
     104
     105### 5. **Code Block Max Height**
     106
     107**Code block max height (px)** 
     108Sets a maximum height (minimum: 100px). 
     109Content taller than this becomes scrollable.
     110
     111**Enable** 
     112Must be checked for the value to apply.
     113
     114This prevents long code blocks from stretching your page layout.
     115
     116---
     117
     118### 6. **Display Line Numbers**
     119
     120**Display Line Numbers (Enable)** 
     121Shows simple line numbers next to each line. 
     122Notes:
     123- Line height is unified for consistency.
     124- Theme-specific code styling is preserved.
     125- Line wrapping is forcibly disabled.
     126
     127This is a built-in lightweight alternative to syntax-highlighter libraries.
     128
     129---
     130
     131### 7. **Custom Styles (CSS)**
     132
     133You can add any custom CSS to adjust:
     134
     135- Button design 
     136- Wrapper layout 
     137- Code spacing 
     138- Line number appearance 
     139
     140Usable Selectors (CSS) :
     141
     142- **.copy-code-btn** → The copy button
     143- **.copy-code-btn.copied**  → The button after Copying
     144-  **.code-block-wrapper**  → Wrapper of the code block (position: relative)
     145- **.code-block-wrapper pre** → Inner code text area (the `<pre>` element)
     146- **.line-numbers**  → The container holding the line numbers
    60147
    61148- Example:
     
    63150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`font-family: "Comic Sans MS", cursive;`
    64151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`font-weight: 700;`
     152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`border: none;`
    65153&nbsp;`}`
     154Note: Do not include any comments.
     155
     156== Frequently Asked Questions ==
     157= Which code blocks does this plugin support? =
     158It supports only code blocks marked up in the `pre > code` format.
    66159
    67160== Screenshots ==
    681611. Plugin settings screen
    691622. Button display in an actual blog post
     1633. Line numbers displayed on a code block.
    70164
    71165== Changelog ==
     166= 1.4.0 =
     167* Added an option to display line numbers.
     168* Minor bug fixes.
     169* Updated readme.txt.
     170
     171= 1.3.0 =
     172* Changed the method for limiting code block height from line count to pixel-based sizing.
     173* Minor bug fixes.
     174
    72175= 1.2.0 =
    73176* Added support for limiting code block height by line count.
    74 * Added a Custom CSS option, allowing users to apply their own CSS to further style the copy button or code blocks.
     177* Added a Custom CSS option, allowing users to apply their own CSS to style the copy button or code blocks.
    75178
    76179= 1.1.0 =
    77 * Changed button size adjustment from size selector to numeric input.
     180* Changed button size settings from a size selector to a numeric input field.
     181* Minor improvements and cleanup.
    78182
    79183= 1.0.1 =
  • stick-copy-button-codeblock/trunk/stick-copy-button-codeblock.php

    r3402170 r3414250  
    22/**
    33 * Plugin Name: Sticky Copy Button for Code Blocks
    4  * Description: This plugin adds a convenient copy button to every code block on your blog posts. Customize the button's position, labels, size, and colors from a dedicated settings page to match your site's design.
    5  * Version: 1.2.0
     4 * Description: This plugin adds a convenient copy button to every code block on your blog posts. Customize the button's position, labels, size, and colors from a dedicated settings page to match your site's design. Optional line numbers can be displayed.
     5 * Version: 1.4.0
    66 * Author: Kasuga
    77 * License: GPLv2 or later
    8  * License URI: http://www.gnu.gnu.org/licenses/gpl-2.0.html
     8 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
    99 * Text Domain: stick-copy-button-codeblock
    1010 * Domain Path: /languages
     
    1818
    1919/**
    20  * Adds the plugin settings page to the admin menu.
    21  *
     20 * Add settings page to admin menu.
     21 *
     22 * This function registers the plugin's settings page under the 'Settings' menu
     23 * in the WordPress admin dashboard.
     24 *
     25 * @since 1.0.0
    2226 * @return void
    2327 */
     
    3438
    3539/**
    36  * Registers plugin settings.
    37  *
     40 * Register plugin settings.
     41 *
     42 * Registers all the individual settings fields used by the plugin for
     43 * configuration on the admin settings page.
     44 *
     45 * @since 1.0.0
    3846 * @return void
    3947 */
     
    4755    register_setting( 'kasuga_scbc-settings-group', 'kasuga_scbc_button_text_color', 'kasuga_scbc_sanitize_hex_color' );
    4856    register_setting( 'kasuga_scbc-settings-group', 'kasuga_scbc_button_bg_transparent', 'kasuga_scbc_sanitize_checkbox' );
     57    register_setting( 'kasuga_scbc-settings-group', 'kasuga_scbc_enable_max_height', 'kasuga_scbc_sanitize_checkbox' );
    4958    register_setting( 'kasuga_scbc-settings-group', 'kasuga_scbc_max_height', 'intval' );
    5059    register_setting( 'kasuga_scbc-settings-group', 'kasuga_scbc_custom_styles', 'kasuga_scbc_sanitize_custom_styles' );
     60    register_setting( 'kasuga_scbc-settings-group', 'kasuga_scbc_enable_linenumbers', 'kasuga_scbc_sanitize_checkbox' );
    5161}
    5262add_action( 'admin_init', 'kasuga_scbc_register_settings' );
    5363
    5464/**
    55  * Sanitizes a hex color input.
    56  *
    57  * @param string $input Hex color code.
    58  * @return string Valid hex color or default #ffffff.
     65 * Sanitize hex color.
     66 *
     67 * Ensures the input is a valid 6-digit or 3-digit hex color code,
     68 * prepended with '#'. Returns a default color if invalid.
     69 *
     70 * @since 1.0.0
     71 * @param string $input The color string to sanitize.
     72 * @return string The sanitized hex color string or a default value.
    5973 */
    6074function kasuga_scbc_sanitize_hex_color( $input ) {
    61     return preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})$/i', $input ) ? $input : '#ffffff';
    62 }
    63 
    64 /**
    65  * Sanitizes a checkbox input.
    66  *
    67  * @param mixed $input Checkbox value.
    68  * @return string '1' if checked, empty string otherwise.
     75    return preg_match( '/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/', $input ) ? $input : '#ffffff';
     76}
     77
     78/**
     79 * Sanitize checkbox.
     80 *
     81 * Ensures the input is either '1' (checked) or an empty string (unchecked).
     82 *
     83 * @since 1.0.0
     84 * @param string $input The checkbox input value.
     85 * @return string '1' if checked, otherwise ''.
    6986 */
    7087function kasuga_scbc_sanitize_checkbox( $input ) {
     
    7390
    7491/**
    75  * Sanitizes custom CSS styles input.
    76  *
    77  * This function is designed to sanitize raw CSS input, allowing
    78  * CSS properties and simple class definitions. It attempts to remove
    79  * potentially dangerous scripts or HTML that might be injected.
    80  *
    81  * @param string $input Raw CSS string.
    82  * @return string Sanitized CSS string.
     92 * Sanitize custom CSS.
     93 *
     94 * Strips all HTML tags and then sanitizes the content using wp_kses_post
     95 * to allow basic HTML-like syntax often found in CSS comments, while being safe.
     96 *
     97 * @since 1.2.0
     98 * @param string $input The custom CSS string.
     99 * @return string The sanitized custom CSS.
    83100 */
    84101function kasuga_scbc_sanitize_custom_styles( $input ) {
    85102    $input         = wp_strip_all_tags( $input );
    86103    $sanitized_css = wp_kses_post( $input );
    87 
    88104    return $sanitized_css;
    89105}
    90106
    91107/**
    92  * Outputs the plugin settings page HTML.
    93  *
     108 * Settings Page HTML
     109 *
     110 * Displays the HTML content for the plugin's administration settings page,
     111 * including options for button style, position, and other features.
     112 *
     113 * @since 1.0.0
    94114 * @return void
    95115 */
    96116function kasuga_scbc_settings_page() {
    97     $button_size    = get_option( 'kasuga_scbc_button_size', 12 );
    98     $bg_transparent = get_option( 'kasuga_scbc_button_bg_transparent', false );
    99     $max_lines      = get_option( 'kasuga_scbc_max_height', 0 );
    100     $custom_styles  = get_option( 'kasuga_scbc_custom_styles', '' );
    101 
    102     $css_sample_placeholder = __( "Enter any custom CSS to further style the copy button or code blocks. This CSS will be loaded on the frontend.\n\n* Usable Selectors:\n\n.copy-code-btn          → The copy button\n.copy-code-btn.copied   → The button after copying\n.code-block-wrapper     → Wrapper of the code block (position: relative)\n.code-block-wrapper pre → Inner code text area (the <pre> element)\n\nExample:\n\n.copy-code-btn {\n    font-family: \"Comic Sans MS\", cursive;\n    font-weight: 700;\n}", 'stick-copy-button-codeblock' );
    103 
     117    $button_size       = get_option( 'kasuga_scbc_button_size', 12 );
     118    $bg_transparent    = get_option( 'kasuga_scbc_button_bg_transparent', '' );
     119    $enable_max_height = get_option( 'kasuga_scbc_enable_max_height', '' );
     120    $max_height_px     = get_option( 'kasuga_scbc_max_height', 100 );
     121    $custom_styles     = get_option( 'kasuga_scbc_custom_styles', '' );
     122    $enable_linenums   = get_option( 'kasuga_scbc_enable_linenumbers', '' );
     123
     124    $css_sample_placeholder = __( "Enter any custom CSS to further style the copy button or code blocks. This CSS will be loaded on the frontend.\n\n* Usable Selectors:\n\n.copy-code-btn          → The copy button\n.copy-code-btn.copied   → The button after copying\n.code-block-wrapper     → Wrapper of the code block (flex container)\n.code-block-wrapper pre → Inner code text area (the <pre> element)\n\nExample:\n\n.copy-code-btn {\n    font-family: \"Comic Sans MS\", cursive;\n    font-weight: 700;\n}", 'stick-copy-button-codeblock' );
    104125    ?>
    105126    <div class="wrap">
    106127        <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
     128
    107129        <form method="post" action="options.php">
    108130            <?php
     
    110132            do_settings_sections( 'kasuga_scbc-settings-group' );
    111133            ?>
     134
    112135            <table class="form-table">
    113136                <tr>
     
    115138                    <td><input type="number" name="kasuga_scbc_button_top" value="<?php echo esc_attr( get_option( 'kasuga_scbc_button_top', 0 ) ); ?>" /></td>
    116139                </tr>
     140
    117141                <tr>
    118142                    <th scope="row"><?php esc_html_e( 'Adjust button right position (px)', 'stick-copy-button-codeblock' ); ?></th>
    119143                    <td><input type="number" name="kasuga_scbc_button_right" value="<?php echo esc_attr( get_option( 'kasuga_scbc_button_right', 0 ) ); ?>" /></td>
    120144                </tr>
     145
    121146                <tr>
    122147                    <th scope="row"><?php esc_html_e( 'Copy button label', 'stick-copy-button-codeblock' ); ?></th>
    123148                    <td><input type="text" name="kasuga_scbc_label_copy" value="<?php echo esc_attr( get_option( 'kasuga_scbc_label_copy', __( 'Copy', 'stick-copy-button-codeblock' ) ) ); ?>" /></td>
    124149                </tr>
     150
    125151                <tr>
    126152                    <th scope="row"><?php esc_html_e( 'Label after copying (2 seconds)', 'stick-copy-button-codeblock' ); ?></th>
    127153                    <td><input type="text" name="kasuga_scbc_label_copied" value="<?php echo esc_attr( get_option( 'kasuga_scbc_label_copied', __( 'Copied', 'stick-copy-button-codeblock' ) ) ); ?>" /></td>
    128154                </tr>
     155
    129156                <tr>
    130157                    <th scope="row"><?php esc_html_e( 'Button size (8–36 px)', 'stick-copy-button-codeblock' ); ?></th>
     
    133160                    </td>
    134161                </tr>
     162
    135163                <tr>
    136164                    <th scope="row"><?php esc_html_e( 'Button text color', 'stick-copy-button-codeblock' ); ?></th>
    137165                    <td><input type="color" name="kasuga_scbc_button_text_color" value="<?php echo esc_attr( get_option( 'kasuga_scbc_button_text_color', '#4caf50' ) ); ?>" /></td>
    138166                </tr>
     167
    139168                <tr>
    140169                    <th scope="row"><?php esc_html_e( 'Button background color', 'stick-copy-button-codeblock' ); ?></th>
    141170                    <td>
    142                         <input type="color" name="kasuga_scbc_button_bg_color" value="<?php echo esc_attr( get_option( 'kasuga_scbc_button_bg_color', '#ffffff' ) ); ?>" />
    143                         <p class="description"><?php esc_html_e( '* The label after copying (for 2 seconds), the text and background colors are swapped.', 'stick-copy-button-codeblock' ); ?></p>
    144                     </td>
    145                 </tr>
    146                 <tr>
    147                     <th scope="row"><?php esc_html_e( 'Make background transparent', 'stick-copy-button-codeblock' ); ?></th>
    148                     <td>
    149171                        <label>
    150                             <input type="checkbox" name="kasuga_scbc_button_bg_transparent" value="1" <?php checked( 1, $bg_transparent ); ?> />
     172                            <input type="color" name="kasuga_scbc_button_bg_color" value="<?php echo esc_attr( get_option( 'kasuga_scbc_button_bg_color', '#ffffff' ) ); ?>" />
     173                            <input type="checkbox" name="kasuga_scbc_button_bg_transparent" value="1" <?php checked( '1', $bg_transparent ); ?> />
     174                            <?php esc_html_e( 'Always transparent background', 'stick-copy-button-codeblock' ); ?>
     175                            <p class="description">
     176                                <?php
     177                                echo wp_kses_post(
     178                                    __( 'The label after copying swaps text/background for 2 seconds;<br>however, when the background is transparent, only the text color is swapped.', 'stick-copy-button-codeblock' )
     179                                );
     180                                ?>
     181                            </p>
     182                        </label>
     183                    </td>
     184                </tr>
     185
     186                <tr>
     187                    <th><h3><?php esc_html_e( '*** Other settings', 'stick-copy-button-codeblock' ); ?></h3></th>
     188                </tr>
     189
     190                <tr>
     191                    <th scope="row"><?php esc_html_e( 'Code block max height (px)', 'stick-copy-button-codeblock' ); ?></th>
     192                    <td>
     193                        <label>
     194                            <input type="number" name="kasuga_scbc_max_height" value="<?php echo esc_attr( $max_height_px ); ?>" min="100" step="1" />
     195                            <input type="checkbox" name="kasuga_scbc_enable_max_height" value="1" <?php checked( '1', $enable_max_height ); ?> />
     196                            <?php esc_html_e( 'Enable', 'stick-copy-button-codeblock' ); ?>
     197                            <p class="description"><?php esc_html_e( 'Minimum value is 100px. If "Enable" is unchecked, this value is ignored.', 'stick-copy-button-codeblock' ); ?></p>
     198                        </label>
     199                    </td>
     200                </tr>
     201
     202                <tr>
     203                    <th scope="row"><?php esc_html_e( 'Display Line Numbers', 'stick-copy-button-codeblock' ); ?></th>
     204                    <td>
     205                        <label>
     206                            <input type="checkbox" name="kasuga_scbc_enable_linenumbers" value="1" <?php checked( '1', $enable_linenums ); ?> />
    151207                            <?php esc_html_e( 'Enable', 'stick-copy-button-codeblock' ); ?>
    152208                        </label>
    153209                    </td>
    154210                </tr>
    155                 <tr>
    156                     <th>
    157                         <h3><?php esc_html_e( '*** Other settings', 'stick-copy-button-codeblock' ); ?></h3>
    158                     </th>
    159                 </tr>
    160                 <tr>
    161                     <th scope="row"><?php esc_html_e( 'Code block max lines (lines)', 'stick-copy-button-codeblock' ); ?></th>
    162                     <td>
    163                         <input type="number" name="kasuga_scbc_max_height" value="<?php echo esc_attr( $max_lines ); ?>" min="0" step="1" />
    164                         <p class="description"><?php esc_html_e( 'Set max height in lines. Enter 0 or leave empty for no limit.', 'stick-copy-button-codeblock' ); ?></p>
    165                     </td>
    166                 </tr>
     211
    167212                <tr>
    168213                    <th scope="row"><?php esc_html_e( 'Custom Styles (CSS)', 'stick-copy-button-codeblock' ); ?></th>
    169214                    <td>
    170                         <textarea name="kasuga_scbc_custom_styles" rows="2" class="large-text code" placeholder="<?php echo esc_attr( $css_sample_placeholder ); ?>"><?php echo esc_textarea( $custom_styles ); ?></textarea>
     215                        <textarea name="kasuga_scbc_custom_styles" rows="4" class="large-text code" placeholder="<?php echo esc_attr( $css_sample_placeholder ); ?>"><?php echo esc_textarea( $custom_styles ); ?></textarea>
    171216                    </td>
    172217                </tr>
    173218            </table>
     219
    174220            <?php submit_button( esc_html__( 'Save Changes', 'stick-copy-button-codeblock' ) ); ?>
    175221        </form>
     
    179225
    180226/**
    181  * Enqueues frontend styles and scripts.
    182  *
     227 * Enqueue styles and scripts.
     228 *
     229 * Loads the necessary external CSS and JavaScript files for the frontend,
     230 * and adds dynamic CSS based on user settings using inline styles.
     231 * Localizes settings variables for JavaScript use.
     232 *
     233 * @since 1.0.0
    183234 * @return void
    184235 */
    185236function kasuga_scbc_enqueue_assets() {
     237
    186238    $settings = array(
    187         'top'            => intval( get_option( 'kasuga_scbc_button_top', 0 ) ),
    188         'right'          => intval( get_option( 'kasuga_scbc_button_right', 0 ) ),
    189         'label_copy'     => esc_js( get_option( 'kasuga_scbc_label_copy', __( 'Copy', 'stick-copy-button-codeblock' ) ) ),
    190         'label_copied'   => esc_js( get_option( 'kasuga_scbc_label_copied', __( 'Copied', 'stick-copy-button-codeblock' ) ) ),
    191         'button_size'    => intval( get_option( 'kasuga_scbc_button_size', 12 ) ),
    192         'bg_color'       => esc_js( get_option( 'kasuga_scbc_button_bg_color', '#ffffff' ) ),
    193         'text_color'     => esc_js( get_option( 'kasuga_scbc_button_text_color', '#4caf50' ) ),
    194         'bg_transparent' => ( '1' === get_option( 'kasuga_scbc_button_bg_transparent', false ) ),
    195         'max_lines'      => intval( get_option( 'kasuga_scbc_max_height', 0 ) ),
     239        'top'               => intval( get_option( 'kasuga_scbc_button_top', 0 ) ),
     240        'right'             => intval( get_option( 'kasuga_scbc_button_right', 0 ) ),
     241        'label_copy'        => esc_js( get_option( 'kasuga_scbc_label_copy', __( 'Copy', 'stick-copy-button-codeblock' ) ) ),
     242        'label_copied'      => esc_js( get_option( 'kasuga_scbc_label_copied', __( 'Copied', 'stick-copy-button-codeblock' ) ) ),
     243        'button_size'       => intval( get_option( 'kasuga_scbc_button_size', 12 ) ),
     244        'bg_color'          => esc_js( get_option( 'kasuga_scbc_button_bg_color', '#ffffff' ) ),
     245        'text_color'        => esc_js( get_option( 'kasuga_scbc_button_text_color', '#4caf50' ) ),
     246        'bg_transparent'    => ( '1' === get_option( 'kasuga_scbc_button_bg_transparent', '' ) ),
     247        'enable_max_height' => ( '1' === get_option( 'kasuga_scbc_enable_max_height', '' ) ),
     248        'max_height_px'     => intval( get_option( 'kasuga_scbc_max_height', 100 ) ),
     249        'show_linenumbers'  => ( '1' === get_option( 'kasuga_scbc_enable_linenumbers', '' ) ),
    196250    );
    197251
    198     $final_bg = $settings['bg_transparent'] ? 'transparent' : $settings['bg_color'];
    199 
    200     $max_height_css = '';
    201     if ( $settings['max_lines'] > 0 ) {
    202         $line_height_em  = 1.5;
    203         $max_height_calc = $line_height_em * intval( $settings['max_lines'] );
    204 
    205         $max_height_css = '
     252    $swap_bg   = $settings['bg_transparent'] ? 'transparent' : $settings['bg_color'];
     253    $swap_text = $settings['bg_transparent'] ? 'transparent' : $settings['text_color'];
     254
     255    $line_number_css     = '';
     256    $code_whitespace_css = '';
     257
     258    if ( $settings['show_linenumbers'] ) {
     259        $line_number_css     = '
     260        .code-block-wrapper .line-numbers span {
     261            display: block !important;
     262            height: 1.5em !important;
     263            line-height: 1.5 !important;
     264            width: 100%;
     265        }
    206266        .code-block-wrapper pre {
    207             max-height: ' . esc_html( $max_height_calc ) . 'em !important;
    208             overflow-y: auto !important;
    209         }';
    210     }
    211 
    212     $css = '
    213     /* CSS for copy button */
    214     .code-block-wrapper { position: relative; padding-right: 50px; margin-bottom: 1em; }
    215     .code-block-wrapper pre { position: static; padding-top: 0; margin-bottom: 0; }
    216     ' . $max_height_css . '
     267            line-height: 1.5 !important;
     268            letter-spacing: 0 !important;
     269        }
     270        ';
     271        $code_whitespace_css = '
     272        .code-block-wrapper pre code {
     273            white-space: pre !important;
     274        }
     275        ';
     276    }
     277
     278    $dynamic_css = '
    217279    .copy-code-btn {
    218         position: absolute;
    219280        top: calc(0px - ' . intval( $settings['top'] ) . 'px);
    220281        right: calc(50px - ' . intval( $settings['right'] ) . 'px);
    221         background-color: ' . esc_html( $final_bg ) . ';
     282        background-color: ' . esc_html( $swap_bg ) . ';
    222283        color: ' . esc_html( $settings['text_color'] ) . ';
    223284        border: 1px solid ' . esc_html( $settings['text_color'] ) . ';
    224         border-radius: 4px;
    225         cursor: pointer;
    226         opacity: 0.8;
    227285        font-size: ' . intval( $settings['button_size'] ) . 'px;
    228286        padding: ' . intval( $settings['button_size'] * 0.2 ) . 'px ' . intval( $settings['button_size'] * 0.5 ) . 'px;
    229         transition: opacity 0.2s, background-color 0.2s, color 0.2s;
    230         z-index: 10;
    231         outline: none !important;
    232         box-shadow: none !important;
    233     }
    234     .copy-code-btn:hover { opacity: 1; }
    235     @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.15); } 100% { transform: scale(1); } }
     287    }
    236288    .copy-code-btn.copied {
    237         animation: pulse 0.4s ease;
    238         background-color: ' . esc_html( $settings['text_color'] ) . ' !important;
    239         color: ' . esc_html( $settings['bg_color'] ) . ' !important;
    240         border: 1px solid ' . esc_html( $settings['text_color'] ) . ' !important;
    241         outline: none !important;
    242         box-shadow: none !important;
    243     }';
    244 
    245     wp_register_style( 'kasuga_scbc-style', false, array(), '1.3.0' );
    246     wp_enqueue_style( 'kasuga_scbc-style' );
    247     wp_add_inline_style( 'kasuga_scbc-style', $css );
    248 
    249     $custom_styles_from_options = get_option( 'kasuga_scbc_custom_styles', '' );
    250     if ( ! empty( $custom_styles_from_options ) ) {
    251         wp_add_inline_style( 'kasuga_scbc-style', $custom_styles_from_options );
    252     }
    253 
    254     $js_script = '
    255     document.addEventListener("DOMContentLoaded", () => {
    256         const settings = kasuga_scbc_vars;
    257         document.querySelectorAll("pre code, pre.wp-block-code code").forEach(codeBlock => {
    258             const preElement = codeBlock.parentNode;
    259             if (preElement.closest(".code-block-wrapper")) {
    260                 return;
    261             }
    262 
    263             const wrapper = document.createElement("div");
    264             wrapper.className = "code-block-wrapper";
    265 
    266             preElement.parentNode.insertBefore(wrapper, preElement);
    267             wrapper.appendChild(preElement);
    268 
    269             const copyButton = document.createElement("button");
    270             copyButton.textContent = settings.label_copy;
    271             copyButton.className = "copy-code-btn";
    272 
    273             copyButton.onclick = async () => {
    274                 try {
    275                     await navigator.clipboard.writeText(codeBlock.textContent);
    276                     copyButton.textContent = settings.label_copied;
    277                     copyButton.classList.add("copied");
    278                     setTimeout(() => {
    279                         copyButton.textContent = settings.label_copy;
    280                         copyButton.classList.remove("copied");
    281                     }, 2000);
    282                 } catch (err) {
    283                     console.error("' . esc_js( __( 'Failed to copy: ', 'stick-copy-button-codeblock' ) ) . '", err);
    284                     copyButton.textContent = "' . esc_js( __( 'Copy error', 'stick-copy-button-codeblock' ) ) . '";
    285                     setTimeout(() => copyButton.textContent = settings.label_copy, 2000);
    286                 }
    287             };
    288             wrapper.appendChild(copyButton);
    289         });
    290     });';
    291 
    292     wp_register_script( 'kasuga_scbc-script', false, array(), '1.3.0', true );
     289        background-color: ' . esc_html( $swap_text ) . ';
     290        color: ' . esc_html( $settings['bg_color'] ) . ';
     291        border: 1px solid ' . esc_html( $settings['text_color'] ) . ';
     292    }
     293    ' . $line_number_css . '
     294    ' . $code_whitespace_css . '
     295    ';
     296
     297    wp_enqueue_style( 'kasuga_scbc-style', plugin_dir_url( __FILE__ ) . 'assets/scbc-style.css', array(), '1.3.8' );
     298
     299    wp_add_inline_style( 'kasuga_scbc-style', $dynamic_css );
     300
     301    /* Add user custom CSS */
     302    $custom_css = get_option( 'kasuga_scbc_custom_styles', '' );
     303    if ( ! empty( $custom_css ) ) {
     304        wp_add_inline_style( 'kasuga_scbc-style', $custom_css );
     305    }
     306
     307    wp_enqueue_script( 'kasuga_scbc-script', plugin_dir_url( __FILE__ ) . 'assets/scbc-script.js', array( 'jquery' ), '1.3.8', true );
     308
    293309    wp_localize_script( 'kasuga_scbc-script', 'kasuga_scbc_vars', $settings );
    294     wp_add_inline_script( 'kasuga_scbc-script', $js_script );
    295     wp_enqueue_script( 'kasuga_scbc-script' );
    296310}
    297311add_action( 'wp_enqueue_scripts', 'kasuga_scbc_enqueue_assets' );
    298312
    299313/**
    300  * Adds a settings link to the plugin action links.
    301  *
    302  * @param array $links Plugin action links.
    303  * @return array Modified links.
     314 * Settings link on plugin list
     315 *
     316 * Adds a "Settings" link directly to the plugin entry on the WordPress
     317 * plugins administration page.
     318 *
     319 * @since 1.0.0
     320 * @param array $links Array of existing action links.
     321 * @return array Array of action links with the new 'Settings' link prepended.
    304322 */
    305323function kasuga_scbc_action_links( $links ) {
     
    311329
    312330/**
    313  * Runs on plugin uninstall to delete saved options.
    314  *
     331 * Uninstall hook
     332 *
     333 * Cleans up all plugin options from the WordPress database upon uninstallation.
     334 *
     335 * @since 1.0.0
    315336 * @return void
    316337 */
    317338function kasuga_scbc_uninstall() {
    318     $options_to_delete = array(
     339    $opts = array(
    319340        'kasuga_scbc_button_top',
    320341        'kasuga_scbc_button_right',
     
    325346        'kasuga_scbc_button_text_color',
    326347        'kasuga_scbc_button_bg_transparent',
     348        'kasuga_scbc_enable_max_height',
    327349        'kasuga_scbc_max_height',
    328350        'kasuga_scbc_custom_styles',
     351        'kasuga_scbc_enable_linenumbers',
    329352    );
    330 
    331     foreach ( $options_to_delete as $option ) {
    332         delete_option( $option );
     353    foreach ( $opts as $o ) {
     354        delete_option( $o );
    333355    }
    334356}
Note: See TracChangeset for help on using the changeset viewer.