Changeset 2933528
- Timestamp:
- 07/03/2023 06:03:01 PM (21 months ago)
- Location:
- fcp-first-screen-css/trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
fcp-first-screen-css/trunk/README.md
r2848495 r2933528 1 1 # FCP First Screen CSS 2 2 3 Insert the inline CSS to the head of thewebsite, disable existing styles and scripts, defer loading of not-first-screen style, apply to a single post or bulk.3 Insert the inline CSS to the head tag of a website, disable existing styles and scripts, defer loading of not-first-screen style, apply to a single post or bulk. 4 4 5 5 ## Features … … 7 7 * Apply to any single post / page / custom post-type 8 8 * Apply to all posts of a particular post-type 9 * Apply to the blog or the archive page of a post-type10 * It minifies the cssbefore printing11 * Deregister enqueued styles and scriptsby name12 * Apply not-first-screen CSS separately9 * Apply to the blog or any post-type archive 10 * It minifies the CSS before printing 11 * Deregister styles and scripts: all or by name 12 * Apply the not-first-screen CSS separately 13 13 * Defer the not-first-screen CSS loading 14 14 -
fcp-first-screen-css/trunk/changelog.txt
r2847523 r2933528 1 = 1.4 = 2 3 * Added the Format button to spread new lines and tabs (spaces) 4 * Added the option to deregister all styles or scripts at once 5 * Fixed the CSS minification for bigger content 6 * Removed the Front page from bulk exceptions 7 1 8 = 1.3 = 2 9 -
fcp-first-screen-css/trunk/first-screen.php
r2907688 r2933528 3 3 Plugin Name: FCP First Screen CSS 4 4 Description: Insert inline CSS to the head of the website, so the first screen renders with no jumps, which might improve the CLS web vital. Or for any other reason. 5 Version: 1. 3.05 Version: 1.4.0 6 6 Requires at least: 5.8 7 Tested up to: 6. 27 Tested up to: 6.1 8 8 Requires PHP: 7.4 9 9 Author: Firmcatalyst, Vadim Volkov … … 14 14 15 15 namespace FCP\FirstScreenCSS; 16 17 16 defined( 'ABSPATH' ) || exit; 17 18 define( 'FCPFSC_DEV', false ); 19 define( 'FCPFSC_VER', get_file_data( __FILE__, [ 'ver' => 'Version' ] )[ 'ver' ] . ( FCPFSC_DEV ? time() : '' ) ); 18 20 19 21 define( 'FCPFSC_SLUG', 'fcpfsc' ); 20 22 define( 'FCPFSC_PREF', FCPFSC_SLUG.'-' ); 21 23 define( 'FCPFSC_FRONT_PREF', 'first-screen' ); 24 25 define( 'FCPFSC_CM_VER', '5.65.13' ); 22 26 23 27 // print the styles … … 41 45 if ( is_singular( $post_type ) ) { 42 46 // get css by post id 43 $css_id = get_post_meta( $qo->ID, FCPFSC_PREF.'id' )[0]; 44 if ( isset( $css_id ) ) { 47 if ( $css_id = get_post_meta( $qo->ID, FCPFSC_PREF.'id' )[0] ?? null ) { 45 48 $csss[] = $css_id; 46 49 } 47 unset( $css_id ); 50 48 51 // get css by post-type 49 if ( (int) get_option('page_on_front') !== (int) $qo->ID ) { // exclude the front-page, as they stand out, mostly50 51 }52 //if ( (int) get_option('page_on_front') !== (int) $qo->ID ) { // exclude the front-page, as they stand out, mostly 53 $csss = array_merge( $csss, get_css_ids( FCPFSC_PREF.'post-types', $post_type ) ); 54 //} 52 55 } 53 56 if ( is_home() || is_archive() && ( !$post_type || $post_type === 'page' ) ) { … … 66 69 67 70 // filter by exclude 68 if ( $css_exclude = get_post_meta( $qo->ID, FCPFSC_PREF.'id-exclude' )[0] ) {71 if ( $css_exclude = get_post_meta( $qo->ID, FCPFSC_PREF.'id-exclude' )[0] ?? null ) { 69 72 $csss = array_values( array_diff( $csss, [ $css_exclude ] ) ); 70 73 } … … 73 76 74 77 // print styles 75 wp_register_style( 'first-screen', false );76 wp_enqueue_style( 'first-screen');77 wp_add_inline_style( 'first-screen', get_css_contents_filtered( $csss ) );78 wp_register_style( FCPFSC_FRONT_PREF, false ); 79 wp_enqueue_style( FCPFSC_FRONT_PREF ); 80 wp_add_inline_style( FCPFSC_FRONT_PREF, get_css_contents_filtered( $csss ) ); 78 81 79 82 80 83 // deregister existing styles 81 $deregister _styles= function() use ( $csss ) {84 $deregister = function() use ( $csss ) { 82 85 list( $styles, $scripts ) = get_to_deregister( $csss ); 83 foreach ( $styles as $v ) { 84 wp_deregister_style( $v ); 85 } 86 foreach ( $scripts as $v ) { 87 wp_deregister_script( $v ); 88 } 86 87 $deregister = function($list, $ss) { 88 if ( empty( $list ) ) { return; } 89 90 if ( in_array( '*', $list ) ) { // get all registered 91 $global = 'wp_'.$ss.'s'; 92 global $$global; 93 94 $list = array_map( function( $el ) { 95 $name = $el->handle; 96 if ( strpos( $name, FCPFSC_FRONT_PREF ) === 0 ) { return ''; } 97 return $name ?? ''; 98 }, (array) $$global->registered ?? [] ); 99 } 100 101 $func = 'wp_deregister_'.$ss; 102 foreach ( $list as $v ) { 103 $func( $v ); 104 } 105 }; 106 107 $deregister( $styles, 'style' ); 108 $deregister( $scripts, 'script' ); 89 109 }; 90 add_action( 'wp_enqueue_scripts', $deregister _styles, 100000 );91 add_action( 'wp_footer', $deregister _styles, 1 );92 add_action( 'wp_footer', $deregister _styles, 11 );110 add_action( 'wp_enqueue_scripts', $deregister, 100000 ); 111 add_action( 'wp_footer', $deregister, 1 ); 112 add_action( 'wp_footer', $deregister, 11 ); 93 113 94 114 … … 99 119 if ( !is_file( wp_upload_dir()['basedir'] . $path ) ) { continue; } 100 120 wp_enqueue_style( 101 'first-screen-css-rest-' . $id,121 FCPFSC_FRONT_PREF.'-css-rest-' . $id, 102 122 wp_upload_dir()['baseurl'] . $path, 103 123 [], … … 110 130 $defer_csss = get_to_defer( $csss ); 111 131 add_filter( 'style_loader_tag', function ($tag, $handle) use ($defer_csss) { 112 if ( strpos( $handle, 'first-screen-css-rest-' ) === false || !in_array( str_replace( 'first-screen-css-rest-', '', $handle ), $defer_csss ) ) {132 if ( strpos( $handle, FCPFSC_FRONT_PREF.'-css-rest-' ) === false || !in_array( str_replace( FCPFSC_FRONT_PREF.'-css-rest-', '', $handle ), $defer_csss ) ) { 113 133 return $tag; 114 134 } … … 190 210 // admin controls 191 211 add_action( 'add_meta_boxes', function() { 212 if ( !current_user_can( 'administrator' ) ) { return; } 213 192 214 add_meta_box( 193 'first-screen-css-bulk',215 FCPFSC_FRONT_PREF.'-css-bulk', 194 216 'Bulk apply', 195 217 'FCP\FirstScreenCSS\fcpfsc_meta_bulk_apply', … … 199 221 ); 200 222 add_meta_box( 201 'first-screen-css-disable',223 FCPFSC_FRONT_PREF.'-css-disable', 202 224 'Disable enqueued', 203 225 'FCP\FirstScreenCSS\fcpfsc_meta_disable_styles', … … 207 229 ); 208 230 add_meta_box( 209 'first-screen-css-rest',231 FCPFSC_FRONT_PREF.'-css-rest', 210 232 'The rest of CSS, which is a not-first-screen', 211 233 'FCP\FirstScreenCSS\fcpfsc_meta_rest_css', … … 215 237 ); 216 238 217 if ( !current_user_can( 'administrator' ) ) { return; }218 239 list( 'public' => $public_post_types ) = get_all_post_types(); 219 240 add_meta_box( 220 'first-screen-css',241 FCPFSC_FRONT_PREF.'-css', 221 242 'Select First Screen CSS', 222 243 'FCP\FirstScreenCSS\anypost_meta_select_fsc', … … 231 252 232 253 $screen = get_current_screen(); 233 if ( !isset( $screen ) || !is_object( $screen ) || !in_array( $screen->base, [ 'post' ] ) ) { return; } // ++to inline css & include 254 if ( !isset( $screen ) || !is_object( $screen ) || !in_array( $screen->base, [ 'post' ] ) ) { return; } // ++to inline css & include ++if can admin 234 255 235 256 ?> … … 259 280 }); 260 281 261 // codemirror editor instead of tinymce282 // disable timymce to textarea 262 283 add_filter( 'wp_editor_settings', function($settings, $editor_id) { 263 284 … … 274 295 }, 10, 2 ); 275 296 297 // apply codemirror to the fields for CSS 276 298 add_action( 'admin_enqueue_scripts', function( $hook ) { 277 299 … … 281 303 if ( !isset( $screen ) || !is_object( $screen ) || $screen->post_type !== FCPFSC_SLUG ) { return; } 282 304 283 $cm_settings['codeEditor'] = wp_enqueue_code_editor( ['type' => 'text/css'] ); 284 wp_localize_script( 'jquery', 'cm_settings', $cm_settings ); 285 wp_enqueue_script( 'wp-theme-plugin-editor' ); 286 wp_add_inline_script( 'wp-theme-plugin-editor', file_get_contents( __DIR__ . '/assets/codemirror-init.js') ); 287 wp_enqueue_style( 'wp-codemirror' ); 305 wp_enqueue_script( 'codemirror', plugin_dir_url(__FILE__) . 'assets/codemirror/codemirror.js', ['jquery'], FCPFSC_CM_VER ); 306 wp_enqueue_script( 'codemirror-init', plugin_dir_url(__FILE__) . '/assets/codemirror/init.js', ['jquery'], FCPFSC_VER ); 307 308 wp_enqueue_style( 'codemirror', plugin_dir_url(__FILE__) . 'assets/codemirror/codemirror.css', [], FCPFSC_CM_VER ); 309 wp_enqueue_style( 'codemirror-style', plugin_dir_url(__FILE__) . 'assets/codemirror/style.css', ['codemirror'], FCPFSC_VER ); 310 311 wp_enqueue_script( 'codemirror-mode-css', plugin_dir_url(__FILE__) . 'assets/codemirror/mode/css/css.js', ['codemirror'], FCPFSC_CM_VER ); 312 wp_enqueue_script( 'codemirror-addon-active-line', plugin_dir_url(__FILE__) . 'assets/codemirror/addon/selection/active-line.js', ['codemirror'], FCPFSC_CM_VER ); 313 wp_enqueue_script( 'codemirror-addon-placeholder', plugin_dir_url(__FILE__) . 'assets/codemirror/addon/display/placeholder.js', ['codemirror'], FCPFSC_CM_VER ); 314 wp_enqueue_script( 'codemirror-formatting', plugin_dir_url(__FILE__) . 'assets/codemirror/util/formatting.js', ['codemirror'], '2.38+' ); 288 315 }); 289 316 … … 305 332 $fields = [ 'id', 'id-exclude' ]; 306 333 } 334 335 // exception for the rest-css ++ improve when having different function for processing values 336 $file = wp_upload_dir()['basedir'] . '/' . basename( __DIR__ ) . '/style-'.$postID.'.css'; 337 @unlink( $file ); 307 338 308 339 foreach ( $fields as $f ) { … … 318 349 // filter css 319 350 add_filter( 'wp_insert_post_data', function($data, $postarr) { 320 351 // ++ if can admin? 321 352 if ( $data['post_type'] !== FCPFSC_SLUG ) { return $data; } 322 353 clear_errors( $postarr['ID'] ); … … 352 383 353 384 global $post; 354 if ( empty( $errors = get_post_meta( $post->ID, FCPFSC_PREF.'_post_errors' )[0] ) ) { return; }385 if ( empty( $errors = get_post_meta( $post->ID, FCPFSC_PREF.'_post_errors' )[0] ?? '' ) ) { return; } 355 386 356 387 array_unshift( $errors['errors'], '<strong>This CSS-post can not be published due to the following errors:</strong>' ); … … 398 429 case ( 'rest-css' ): 399 430 400 list( $errors, $filtered ) = sanitize_css( wp_unslash( $value ) ); //++ move it all to a separate filter / actions, organize better with errors ?431 list( $errors, $filtered ) = sanitize_css( wp_unslash( $value ) ); //++ move it all to a separate filter / actions, organize better with errors!! 401 432 $file = wp_upload_dir()['basedir'] . '/' . basename( __DIR__ ) . '/style-'.$postID.'.css'; 433 402 434 // correct 403 435 if ( empty( $errors ) ) { … … 430 462 function sanitize_css($css) { 431 463 464 $errors = []; 465 432 466 // try to escape tags inside svg with url-encoding 433 467 if ( strpos( $css, '<' ) !== false && preg_match( '/<\/?\w+/', $css ) ) { … … 659 693 } 660 694 if ( $type->public ) { 661 if ( $type->name === 'page' ) { $type->label .= ' (except Front Page)'; }695 //if ( $type->name === 'page' ) { $type->label .= ' (except Front Page)'; } 662 696 $public[ $type->name ] = $type->label; 663 697 } … … 669 703 670 704 function css_minify($css) { 671 $css = preg_replace( '/\/\*(?:.*?)*\*\//', '', $css ); // remove comments 672 $css = preg_replace( '/\s+/', ' ', $css ); // one-line & only single speces 673 $css = preg_replace( '/ ?([\{\};:\>\~\+]) ?/', '$1', $css ); // remove spaces 674 $css = preg_replace( '/\+(\d)/', ' + $1', $css ); // restore spaces in functions 675 $css = preg_replace( '/(?:[^\}]*)\{\}/', '', $css ); // remove empty properties 705 $preg_replace = function($regexp, $replace, $string) { // avoid null result so that css still works even though not fully minified 706 return preg_replace( $regexp, $replace, $string ) ?: $string . '/* --- failed '.$regexp.', '.$replace.' */'; 707 }; 708 $css = $preg_replace( '/\s+/', ' ', $css ); // one-line & only single speces 709 $css = $preg_replace( '/ ?\/\*(?:.*?)\*\/ ?/', '', $css ); // remove comments 710 $css = $preg_replace( '/ ?([\{\};:\>\~\+]) ?/', '$1', $css ); // remove spaces 711 $css = $preg_replace( '/\+(\d)/', ' + $1', $css ); // restore spaces in functions 712 $css = $preg_replace( '/(?:[^\}]*)\{\}/', '', $css ); // remove empty properties 676 713 $css = str_replace( [';}', '( ', ' )'], ['}', '(', ')'], $css ); // remove last ; and spaces 677 714 // ++ should also remove 0 from 0.5, but not from svg-s? … … 693 730 'name' => 'post-types', 694 731 'options' => $public_post_types, 695 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'post-types' )[0] ,732 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'post-types' )[0] ?? '', 696 733 ]); 697 734 … … 701 738 'name' => 'post-archives', 702 739 'options' => $archives_post_types, 703 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'post-archives' )[0] ,740 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'post-archives' )[0] ?? '', 704 741 ]); 705 742 … … 712 749 'name' => 'development-mode', 713 750 'options' => ['on' => 'Development mode (apply only if the post is visited as the admin)'], 714 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'development-mode' )[0] ,751 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'development-mode' )[0] ?? '', 715 752 ]); 716 753 … … 721 758 global $post; 722 759 723 ?><p><strong>List the names of STYLES to deregister , separate by comma</strong></p><?php760 ?><p><strong>List the names of STYLES to deregister</strong></p><?php 724 761 725 762 input( (object) [ 726 763 'name' => 'deregister-style-names', 727 764 'placeholder' => 'my-theme-style, some-plugin-style', 728 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'deregister-style-names' )[0], 729 ]); 730 731 ?><p><strong>List the names of SCRIPTS to deregister, separate by comma</strong></p><?php 765 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'deregister-style-names' )[0] ?? '', 766 ]); 767 ?>Separate names by comma. To deregister all styles set *<?php 768 769 ?><p><strong>List the names of SCRIPTS to deregister</strong></p><?php 732 770 733 771 input( (object) [ 734 772 'name' => 'deregister-script-names', 735 773 'placeholder' => 'my-theme-script, some-plugin-script', 736 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'deregister-script-names' )[0], 737 ]); 774 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'deregister-script-names' )[0] ?? '', 775 ]); 776 ?>Separate names by comma. To deregister all scripts set *<?php 738 777 739 778 } … … 744 783 textarea( (object) [ 745 784 'name' => 'rest-css', 746 'placeholder' => '/* enter your css here */ 747 * { 748 border-left: 1px dotted green; 749 box-sizing: border-box; 750 }', 751 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'rest-css' )[0], 785 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'rest-css' )[0] ?? '', 752 786 ]); 753 787 … … 755 789 'name' => 'rest-css-defer', 756 790 'options' => ['on' => 'Defer the not-first-screen CSS (avoid render-blicking)'], 757 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'rest-css-defer' )[0] ,791 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'rest-css-defer' )[0] ?? '', 758 792 ]); 759 793 } … … 779 813 'placeholder' => '------', 780 814 'options' => $css_posts, 781 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'id' )[0] ,815 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'id' )[0] ?? '', 782 816 ]); 783 817 … … 787 821 'placeholder' => '------', 788 822 'options' => $css_posts, 789 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'id-exclude' )[0] ,823 'value' => get_post_meta( $post->ID, FCPFSC_PREF.'id-exclude' )[0] ?? '', 790 824 ]); 791 825 … … 802 836 // svn upload 803 837 804 // ++limit meta boxes to admins too!!! 805 // ++add formatting button like https://codemirror.net/2/demo/formatting.html 838 // ++refactor - split in files 806 839 // ++add the bigger height button and save it 807 840 // ++switch selects to checkboxes or multiples … … 809 842 // ++don't show rest meta box if the storing dir is absent or is not writable or/and the permission error 810 843 // ++get the list of css to unload with jQuery.html() && regexp, or ?query in url to print loaded scripts 811 // ++!!??add small textarea to every public post along with css like for a unique background-image in hero 812 // ++list of styles to defer like with deregister 844 // ++list of styles to defer like with deregister? -
fcp-first-screen-css/trunk/readme.txt
r2907688 r2933528 5 5 Tested up to: 6.2 6 6 Requires PHP: 7.4 7 Stable tag: 1. 37 Stable tag: 1.4 8 8 Author: Firmcatalyst, Vadim Volkov 9 9 Author URI: https://firmcatalyst.com … … 15 15 == Description == 16 16 17 Insert the inline CSS to the head of thewebsite, disable existing styles and scripts, defer loading of not-first-screen style, apply to a single post or bulk.17 Insert the inline CSS to the head tag of a website, disable existing styles and scripts, defer loading of not-first-screen style, apply to a single post or bulk. 18 18 19 19 = Features = … … 21 21 * Apply to any single post / page / custom post-type 22 22 * Apply to all posts of a particular post-type 23 * Apply to the blog or the archive page of a post-type24 * It minifies the cssbefore printing25 * Deregister enqueued styles and scriptsby name26 * Apply not-first-screen CSS separately23 * Apply to the blog or any post-type archive 24 * It minifies the CSS before printing 25 * Deregister styles and scripts: all or by name 26 * Apply the not-first-screen CSS separately 27 27 * Defer the not-first-screen CSS loading 28 28 … … 53 53 == Upgrade Notice == 54 54 55 = 1.4 = 56 57 * Added the Format button to spread new lines and tabs (spaces) 58 * Added the option to deregister all styles or scripts at once 59 * Fixed the CSS minification for bigger content 60 * Removed the Front page from bulk exceptions 61 55 62 = 1.3 = 56 63
Note: See TracChangeset
for help on using the changeset viewer.