Plugin Directory

Changeset 2847523


Ignore:
Timestamp:
01/12/2023 04:13:31 PM (2 years ago)
Author:
firmcatalyst
Message:

v 1.3 ready

Location:
fcp-first-screen-css/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • fcp-first-screen-css/trunk/README.md

    r2831743 r2847523  
    11# FCP First Screen CSS
    22
    3 Insert inline CSS to the head of the website, so the first screen renders with no jumps, which might improve the CLS and FCP web vitals. Or for any other reason.
     3Insert the inline CSS to the head of the website, disable existing styles and scripts, defer loading of not-first-screen style, apply to a single post or bulk.
    44
    55## Features
    66
    77* Apply to any single post / page / custom post-type
    8 * Apply to all posts of a particular public post-type
    9 * Apply to the blog or the archive page of a post-type with archive support
     8* Apply to all posts of a particular post-type
     9* Apply to the blog or the archive page of a post-type
    1010* It minifies the css before printing
    11 * Deregister enqueued styles by name
    12 * Apply non-first-screen css separately
     11* Deregister enqueued styles and scripts by name
     12* Apply not-first-screen CSS separately
     13* Defer the not-first-screen CSS loading
    1314
    1415## Usage
    1516
    1617* Install and activate the plugin
    17 * Go to "FirstScreen CSS" menu item in the left sidebar of your wp-admin
     18* Go to the "First Screen CSS" menu item in the left sidebar of your wp-admin
    1819* Add New, insert your CSS
    19 * To apply the CSS, pick where to at the bottom of the page
    20 * To apply to a single post / page - go to that post editor, and select your created FirstScreen CSS in the box in the right sidebar
     20* Pick where to apply and other options
  • fcp-first-screen-css/trunk/changelog.txt

    r2831743 r2847523  
     1= 1.3 =
     2
     3* Added the development mode, visible only to admins
     4* Added the option to deregister existing styles and scripts
     5* Added the option to defer the not-first-screen CSS loading
     6
    17= 1.2 =
    28
  • fcp-first-screen-css/trunk/first-screen.php

    r2845082 r2847523  
    33Plugin Name: FCP First Screen CSS
    44Description: 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.2.1
     5Version: 1.3.0
    66Requires at least: 5.8
    77Tested up to: 6.1
     
    4747        unset( $css_id );
    4848        // get css by post-type
    49         if ( (int) get_option('page_on_front') !== (int) $qo->ID ) { // exclude the front-page, as they are mostly stand out
     49        if ( (int) get_option('page_on_front') !== (int) $qo->ID ) { // exclude the front-page, as they stand out, mostly
    5050            $csss = array_merge( $csss, get_css_ids( FCPFSC_PREF.'post-types', $post_type ) );
    5151        }
     
    6262    if ( empty( $csss ) ) { return; }
    6363
    64     // filter by published & post-type
     64    // filter by post_status, post_type, development-mode
    6565    $csss = filter_csss( $csss );
    6666
     
    8080    // deregister existing styles
    8181    $deregister_styles = function() use ( $csss ) {
    82         foreach ( get_css_to_deregister( $csss ) as $v ) {
     82        list( $styles, $scripts ) = get_to_deregister( $csss );
     83        foreach ( $styles as $v ) {
    8384            wp_deregister_style( $v );
     85        }
     86        foreach ( $scripts as $v ) {
     87            wp_deregister_script( $v );
    8488        }
    8589    };
     
    102106            );
    103107        }
     108
     109        // defer loading
     110        $defer_csss = get_to_defer( $csss );
     111        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 ) ) {
     113                return $tag;
     114            }
     115            return
     116                str_replace( [ 'rel="stylesheet"', "rel='stylesheet'" ], [
     117                    'rel="preload" as="style" onload="this.onload=null;this.rel=\'stylesheet\'"',
     118                    "rel='preload' as='style' onload='this.onload=null;this.rel=\"stylesheet\"'"
     119                ], $tag ).
     120                '<noscript>'.str_replace( // remove doubling id
     121                    [ ' id="'.$handle.'-css"', " id='".$handle."-css'" ],
     122                    [ '', '' ],
     123                    substr( $tag, 0, -1 )
     124                ).'</noscript>' . "\n"
     125            ;
     126        }, 10, 2);
    104127    }, 10 );
    105128
     
    169192    add_meta_box(
    170193        'first-screen-css-bulk',
    171         'Bulk apply the First Screen CSS',
     194        'Bulk apply',
    172195        'FCP\FirstScreenCSS\fcpfsc_meta_bulk_apply',
    173196        FCPFSC_SLUG,
     
    177200    add_meta_box(
    178201        'first-screen-css-disable',
    179         'Disable enqueued styles',
     202        'Disable enqueued',
    180203        'FCP\FirstScreenCSS\fcpfsc_meta_disable_styles',
    181204        FCPFSC_SLUG,
     
    192215    );
    193216
     217    if ( !current_user_can( 'administrator' ) ) { return; }
    194218    list( 'public' => $public_post_types ) = get_all_post_types();
    195219    add_meta_box(
     
    269293    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; }
    270294    if ( !wp_verify_nonce( $_POST[ FCPFSC_PREF.'nounce-name' ], FCPFSC_PREF.'nounce-action' ) ) { return; }
    271     if ( !current_user_can( 'edit_post', $postID ) ) { return; }
     295    //if ( !current_user_can( 'edit_post', $postID ) ) { return; }
     296    if ( !current_user_can( 'administrator' ) ) { return; }
    272297
    273298    $post = get_post( $postID );
     
    276301
    277302    if ( $post->post_type === FCPFSC_SLUG ) {
    278         $fields = [ 'post-types', 'post-archives', 'deregister-style-names', 'rest-css' ];
     303        $fields = [ 'post-types', 'post-archives', 'development-mode', 'deregister-style-names', 'deregister-script-names', 'rest-css', 'rest-css-defer' ];
    279304    } else {
    280305        $fields = [ 'id', 'id-exclude' ];
     
    351376    $field = ( strpos( $field, FCPFSC_PREF ) === 0 ) ? substr( $field, strlen( FCPFSC_PREF ) ) : $field;
    352377
     378    $onoff = function($value) {
     379        return $value[0] === 'on' ? ['on'] : [];
     380    };
     381
    353382    switch( $field ) {
    354         case( 'post-types' ):
     383        case ( 'post-types' ):
    355384            return array_intersect( $value, array_keys( get_all_post_types()['public'] ) );
    356385        break;
    357         case( 'post-archives' ):
     386        case ( 'post-archives' ):
    358387            return array_intersect( $value, array_keys( get_all_post_types()['archive'] ) );
    359388        break;
    360         case( 'deregister-style-names' ):
     389        case ( 'development-mode' ):
     390            return $onoff( $value );
     391        break;
     392        case ( 'deregister-style-names' ):
    361393            return $value; // ++preg_replace not letters ,space-_, lowercase?,
    362394        break;
    363         case( 'rest-css' ):
     395        case ( 'deregister-script-names' ):
     396            return $value; // ++preg_replace not letters ,space-_, lowercase?,
     397        break;
     398        case ( 'rest-css' ):
    364399
    365400            list( $errors, $filtered ) = sanitize_css( wp_unslash( $value ) ); //++ move it all to a separate filter / actions, organize better with errors?
     
    375410            return $value;
    376411        break;
    377         case( 'id' ):
     412        case ( 'rest-css-defer' ):
     413            return $onoff( $value );
     414        break;
     415        case ( 'id' ):
    378416            if ( !is_numeric( $value ) ) { return ''; } // ++to a function
    379417            if ( !( $post = get_post( $value ) ) || $post->post_type !== FCPFSC_SLUG ) { return ''; }
    380418            return $value;
    381419        break;
    382         case( 'id-exclude' ):
     420        case ( 'id-exclude' ):
    383421            if ( !is_numeric( $value ) ) { return ''; }
    384422            if ( !( $post = get_post( $value ) ) || $post->post_type !== FCPFSC_SLUG ) { return ''; }
     
    506544    global $wpdb;
    507545
    508     $metas = $wpdb->get_col( $wpdb->prepare('
     546    // filter by post_status & post_type
     547    $filtered_ids = $wpdb->get_col( $wpdb->prepare('
    509548
    510549        SELECT `ID`
     
    514553    ', array_merge( [ 'publish', FCPFSC_SLUG ], $ids ) ) );
    515554
    516     return $metas;
     555    // filter by development mode
     556    if ( current_user_can( 'administrator' ) ) { return $filtered_ids; }
     557
     558    $dev_mode = $wpdb->get_col( $wpdb->remove_placeholder_escape( $wpdb->prepare('
     559
     560        SELECT `post_id`
     561        FROM `'.$wpdb->postmeta.'`
     562        WHERE `meta_key` = %s AND `meta_value` = %s AND `post_id` IN ( '.implode( ',', array_fill( 0, count( $ids ), '%s' ), ).' )
     563
     564    ', array_merge( [ FCPFSC_PREF.'development-mode', serialize(['on']) ], $ids ) ) ) );
     565
     566
     567    return array_values( array_diff( $filtered_ids, $dev_mode ) );
    517568}
    518569
     
    521572    global $wpdb;
    522573
    523     $metas = $wpdb->get_col( $wpdb->remove_placeholder_escape( $wpdb->prepare('
     574    $ids = $wpdb->get_col( $wpdb->remove_placeholder_escape( $wpdb->prepare('
    524575
    525576        SELECT `post_id`
     
    529580    ', $key, $wpdb->add_placeholder_escape( '%"'.$type.'"%' ) ) ) );
    530581
    531     return $metas;
     582    return $ids;
     583}
     584
     585function get_to_defer( $ids ) {
     586
     587    global $wpdb;
     588
     589    $defer_ids = $wpdb->get_col( $wpdb->remove_placeholder_escape( $wpdb->prepare('
     590
     591        SELECT `post_id`
     592        FROM `'.$wpdb->postmeta.'`
     593        WHERE `meta_key` = %s AND `meta_value` = %s AND `post_id` IN ( '.implode( ',', array_fill( 0, count( $ids ), '%s' ), ).' )
     594
     595    ', array_merge( [ FCPFSC_PREF.'rest-css-defer', serialize(['on']) ], $ids ) ) ) );
     596
     597
     598    return $defer_ids;
    532599}
    533600
     
    549616}
    550617
    551 function get_css_to_deregister( $ids ) {
     618function get_to_deregister( $ids ) {
    552619
    553620    if ( empty( $ids ) ) { return []; }
     
    555622    global $wpdb;
    556623
    557     $metas = $wpdb->get_col( $wpdb->remove_placeholder_escape( $wpdb->prepare('
    558 
    559         SELECT `meta_value`
     624    $wpdb->query( $wpdb->remove_placeholder_escape( $wpdb->prepare('
     625
     626        SELECT
     627            IF ( STRCMP( `meta_key`, %s ) = 0, `meta_value`, "" ) AS "styles",
     628            IF ( STRCMP( `meta_key`, %s ) = 0, `meta_value`, "" ) AS "scripts"
    560629        FROM `'.$wpdb->postmeta.'`
    561         WHERE `meta_key` = %s AND `post_id` IN ( '.implode( ',', array_fill( 0, count( $ids ), '%s' ), ).' )
    562 
    563     ', array_merge( [ FCPFSC_PREF.'deregister-style-names' ], $ids ) ) ) );
    564 
    565     $metas = array_values( array_unique( array_filter( array_map( 'trim', explode( ',', implode( ', ', $metas ) ) ) ) ) );
    566 
    567     return $metas;
     630        WHERE ( `meta_key` = %s OR `meta_key` = %s ) AND `post_id` IN ( '.implode( ',', array_fill( 0, count( $ids ), '%s' ), ).' )
     631
     632    ', array_merge(
     633        [ FCPFSC_PREF.'deregister-style-names', FCPFSC_PREF.'deregister-script-names', FCPFSC_PREF.'deregister-style-names', FCPFSC_PREF.'deregister-script-names' ],
     634        $ids
     635    ) ) ) );
     636
     637    $clear = function($a) { return array_values( array_unique( array_filter( array_map( 'trim', explode( ',', implode( ', ', $a ) ) ) ) ) ); };
     638   
     639    $styles = $clear( $wpdb->get_col( null, 0 ) );
     640    $scripts = $clear( $wpdb->get_col( null, 1 ) );
     641
     642    return [ $styles, $scripts ];
    568643}
    569644
     
    630705
    631706    ?>
    632     <p>You can apply this styling to a separate post. Every public post type now has a special select box in the right sidebar to pick from the list of the first-screen-css posts, like this one.</p>
    633     <p>CSS will be minified before printing.</p>
     707    <p>You can apply this styling to a separate post. Every public post type has a special select box in the right sidebar to pick this or any other first-screen-css.</p>
    634708    <p>You can grab the first screen css of a page with the script: <a href="https://github.com/VVolkov833/first-screen-css-grabber" target="_blank" rel="noopener">github.com/VVolkov833/first-screen-css-grabber</a></p>
    635709    <?php
    636710
     711    checkboxes( (object) [
     712        'name' => 'development-mode',
     713        '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],
     715    ]);
     716
    637717    wp_nonce_field( FCPFSC_PREF.'nounce-action', FCPFSC_PREF.'nounce-name' );
    638718}
     
    641721    global $post;
    642722
    643     ?><p><strong>List the names of styles to deregister, separate by comma</strong></p><?php
     723    ?><p><strong>List the names of STYLES to deregister, separate by comma</strong></p><?php
    644724
    645725    input( (object) [
     
    647727        'placeholder' => 'my-theme-style, some-plugin-style',
    648728        '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
     732
     733    input( (object) [
     734        'name' => 'deregister-script-names',
     735        'placeholder' => 'my-theme-script, some-plugin-script',
     736        'value' => get_post_meta( $post->ID, FCPFSC_PREF.'deregister-script-names' )[0],
    649737    ]);
    650738
     
    664752    ]);
    665753
     754    checkboxes( (object) [
     755        'name' => 'rest-css-defer',
     756        'options' => ['on' => 'Defer the not-first-screen CSS (avoid render-blicking)'],
     757        'value' => get_post_meta( $post->ID, FCPFSC_PREF.'rest-css-defer' )[0],
     758    ]);
    666759}
    667760
     
    709802// svn upload
    710803
     804// ++limit meta boxes to admins too!!!
    711805// ++add formatting button like https://codemirror.net/2/demo/formatting.html
     806// ++add the bigger height button and save it
    712807// ++switch selects to checkboxes or multiples
    713808// ++maybe limit the id-exclude to the fitting post types
     
    715810// ++get the list of css to unload with jQuery.html() && regexp, or ?query in url to print loaded scripts
    716811// ++!!??add small textarea to every public post along with css like for a unique background-image in hero
    717 // ++limit meta boxes to admins too!!!
    718 // ++load in footer - the last argument in enqueue script
     812// ++list of styles to defer like with deregister
  • fcp-first-screen-css/trunk/readme.txt

    r2831794 r2847523  
    11=== FCP First Screen CSS ===
    22Contributors: Firmcatalyst
    3 Tags: inline, css, firstscreen, style, web vitals, cls, fcp
     3Tags: inline, css, firstscreen, style, web vitals, cls, fcp, defer, dequeue, deregister
    44Requires at least: 5.8
    55Tested up to: 6.1
    66Requires PHP: 7.4
    7 Stable tag: 1.2
     7Stable tag: 1.3
    88Author: Firmcatalyst, Vadim Volkov
    99Author URI: https://firmcatalyst.com
     
    1515== Description ==
    1616
    17 Insert inline CSS to the head of the website, so the first screen renders with no jumps, which might improve the CLS and FCP web vitals. Or for any other reason.
     17Insert the inline CSS to the head of the website, disable existing styles and scripts, defer loading of not-first-screen style, apply to a single post or bulk.
    1818
    1919= Features =
    2020
    2121* Apply to any single post / page / custom post-type
    22 * Apply to all posts of a particular public post-type
    23 * Apply to the blog or any archive page of a post-type with archive support
     22* Apply to all posts of a particular post-type
     23* Apply to the blog or the archive page of a post-type
    2424* It minifies the css before printing
    25 * Deregister enqueued styles by name
    26 * Apply non-first-screen css separately
     25* Deregister enqueued styles and scripts by name
     26* Apply not-first-screen CSS separately
     27* Defer the not-first-screen CSS loading
    2728
    2829= Usage =
    2930
    3031* Install and activate the plugin
    31 * Go to "FirstScreen CSS" menu item in the left sidebar of your wp-admin
     32* Go to the "First Screen CSS" menu item in the left sidebar of your wp-admin
    3233* Add New, insert your CSS
    33 * To apply the CSS, pick where to at the bottom of the page
    34 * To apply to a single post / page - go to that post editor, and select your created FirstScreen CSS in the box in the right sidebar
     34* Pick where to apply and other options
    3535
    3636== Installation ==
     
    4949== Upgrade Notice ==
    5050
     51= 1.3 =
     52
     53* Added the development mode, visible only to admins
     54* Added the option to deregister existing styles and scripts
     55* Added the option to defer the not-first-screen CSS loading
     56
    5157= 1.2 =
    5258
Note: See TracChangeset for help on using the changeset viewer.