@automattic/newspack-blocks 4.29.2 → 4.30.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -253,9 +253,9 @@ class Newspack_Blocks_Caching {
253
253
  }
254
254
 
255
255
  if ( 'newspack-blocks/homepage-articles' === $block_data['blockName'] ) {
256
- Newspack_Blocks::enqueue_view_assets( 'homepage-articles' );
256
+ Newspack_Blocks::enqueue_view_assets( 'homepage-articles', 'defer' );
257
257
  } elseif ( 'newspack-blocks/carousel' === $block_data['blockName'] ) {
258
- Newspack_Blocks::enqueue_view_assets( 'carousel' );
258
+ Newspack_Blocks::enqueue_view_assets( 'carousel', 'defer' );
259
259
  }
260
260
 
261
261
  return $cached_data['cached_content'];
@@ -25,6 +25,7 @@ class Newspack_Blocks {
25
25
  */
26
26
  public static function init() {
27
27
  add_action( 'after_setup_theme', [ __CLASS__, 'add_image_sizes' ] );
28
+ add_filter( 'intermediate_image_sizes_advanced', [ __CLASS__, 'maybe_skip_article_block_image_subsizes' ] );
28
29
  add_post_type_support( 'post', 'newspack_blocks' );
29
30
  add_post_type_support( 'page', 'newspack_blocks' );
30
31
  add_action( 'jetpack_register_gutenberg_extensions', [ __CLASS__, 'disable_jetpack_donate' ], 99 );
@@ -340,9 +341,13 @@ class Newspack_Blocks {
340
341
  /**
341
342
  * Enqueue view scripts and styles for a single block.
342
343
  *
343
- * @param string $type The block's type.
344
+ * @param string $type The block's type.
345
+ * @param string|null $strategy Optional. Script loading strategy to apply to the
346
+ * view script ('defer' or 'async'). First write wins:
347
+ * ignored if a strategy is already set on the handle.
348
+ * Default null (no strategy).
344
349
  */
345
- public static function enqueue_view_assets( $type ) {
350
+ public static function enqueue_view_assets( $type, $strategy = null ) {
346
351
  $style_path = apply_filters(
347
352
  'newspack_blocks_enqueue_view_assets',
348
353
  NEWSPACK_BLOCKS__BLOCKS_DIRECTORY . $type . '/view.css',
@@ -362,13 +367,17 @@ class Newspack_Blocks {
362
367
  }
363
368
  $script_data = static::script_enqueue_helper( NEWSPACK_BLOCKS__BLOCKS_DIRECTORY . $type . '/view.js' );
364
369
  if ( $script_data ) {
370
+ $handle = "newspack-blocks-{$type}";
365
371
  wp_enqueue_script(
366
- "newspack-blocks-{$type}",
372
+ $handle,
367
373
  $script_data['script_path'],
368
374
  $script_data['dependencies'],
369
375
  $script_data['version'],
370
376
  true
371
377
  );
378
+ if ( $strategy && ! wp_scripts()->get_data( $handle, 'strategy' ) ) {
379
+ wp_script_add_data( $handle, 'strategy', $strategy );
380
+ }
372
381
  }
373
382
  }
374
383
 
@@ -543,6 +552,70 @@ class Newspack_Blocks {
543
552
  add_image_size( 'newspack-article-block-uncropped', 1200, 9999, false );
544
553
  }
545
554
 
555
+ /**
556
+ * Skip generating the physical `newspack-article-block-*` sub-size files on upload.
557
+ *
558
+ * The sizes stay registered, so blocks still resolve correctly-cropped URLs;
559
+ * we only skip writing the files where an on-the-fly image CDN can reproduce them
560
+ * from the registered sizes. The prefix match removes every `newspack-article-block-*`
561
+ * sub-size, including `newspack-article-block-uncropped` (registered with
562
+ * `crop => false` — a plain downscale, not a crop); the CDN resizes as well as
563
+ * crops, so none of them need a physical file. This also makes the Image block
564
+ * (REST) and Media Library upload paths behave the same on wpcom, where they
565
+ * otherwise differ.
566
+ *
567
+ * @param array $sizes Image sub-sizes to generate, keyed by size name.
568
+ * @return array Filtered sizes.
569
+ */
570
+ public static function maybe_skip_article_block_image_subsizes( array $sizes ): array {
571
+ /**
572
+ * Filters whether to skip physical `newspack-article-block-*` sub-size generation.
573
+ * Defaults to true where an on-the-fly image CDN reproduces the sizes: WordPress.com
574
+ * Simple (always) and Atomic (only when the Jetpack Image CDN is active). Self-hosted
575
+ * sites can opt in, e.g. when fronting uploads with the Jetpack Image CDN.
576
+ *
577
+ * @param bool $skip Whether to skip physical sub-size generation.
578
+ */
579
+ $skip = apply_filters( 'newspack_blocks_skip_article_image_subsizes', self::is_wpcom_image_cdn_active() );
580
+ if ( ! $skip ) {
581
+ return $sizes;
582
+ }
583
+
584
+ foreach ( array_keys( $sizes ) as $size_name ) {
585
+ if ( is_string( $size_name ) && str_starts_with( $size_name, 'newspack-article-block-' ) ) {
586
+ unset( $sizes[ $size_name ] );
587
+ }
588
+ }
589
+ return $sizes;
590
+ }
591
+
592
+ /**
593
+ * Whether this site serves images through an on-the-fly image CDN that crops and
594
+ * resizes from the registered sizes, making the physical `newspack-article-block-*`
595
+ * files redundant.
596
+ *
597
+ * WordPress.com Simple always serves images through the platform image CDN. On
598
+ * Atomic the Jetpack Image CDN (Photon) can be toggled off, so it counts only when
599
+ * the module is active — otherwise the crops must still be generated. Self-hosted
600
+ * sites are not auto-detected here; they opt in via the filter above.
601
+ *
602
+ * @return bool
603
+ */
604
+ private static function is_wpcom_image_cdn_active(): bool {
605
+ if ( ! class_exists( '\Automattic\Jetpack\Status\Host' ) ) {
606
+ return false;
607
+ }
608
+ $host = new \Automattic\Jetpack\Status\Host();
609
+ if ( $host->is_wpcom_simple() ) {
610
+ return true;
611
+ }
612
+ if ( $host->is_wpcom_platform() ) {
613
+ // Atomic: only skip when the Image CDN (Photon) is actually active to crop on the fly.
614
+ return class_exists( 'Jetpack' ) && \Jetpack::is_module_active( 'photon' );
615
+ }
616
+ return false;
617
+ }
618
+
546
619
  /**
547
620
  * Whether the block should be included in the deduplication logic.
548
621
  *
@@ -1387,44 +1460,84 @@ class Newspack_Blocks {
1387
1460
  }
1388
1461
 
1389
1462
  /**
1390
- * Pick either white or black, whatever has sufficient contrast with the color being passed to it.
1391
- * From Newspack Theme functions.
1463
+ * Pick either black or white text, whichever reads better on the given background.
1392
1464
  *
1393
- * @param string $hex Hexidecimal value of the color to adjust.
1394
- * @return string Either black or white hexidecimal values.
1465
+ * Scores pure black and pure white as text against the background and returns
1466
+ * whichever produces the greater APCA lightness contrast (Lc); ties fall to
1467
+ * black. The constants are the SA98G set from apca-w3 0.1.9.
1395
1468
  *
1396
- * @ref https://stackoverflow.com/questions/1331591/given-a-background-color-black-or-white-text
1469
+ * Keep in sync with getColorForContrast() in src/blocks/donate/utils.ts.
1470
+ *
1471
+ * @param string $hex Hexadecimal background color (#RGB, #RRGGBB or #RRGGBBAA, with or without #).
1472
+ * @return string Either 'black' or 'white' (literal CSS color keywords).
1397
1473
  */
1398
1474
  public static function get_color_for_contrast( $hex ) {
1399
- // Hex RGB.
1400
- $r1 = hexdec( substr( $hex, 1, 2 ) );
1401
- $g1 = hexdec( substr( $hex, 3, 2 ) );
1402
- $b1 = hexdec( substr( $hex, 5, 2 ) );
1403
- // Black RGB.
1404
- $black_color = '#000';
1405
- $r2_black_color = hexdec( substr( $black_color, 1, 2 ) );
1406
- $g2_black_color = hexdec( substr( $black_color, 3, 2 ) );
1407
- $b2_black_color = hexdec( substr( $black_color, 5, 2 ) );
1408
- // Calc contrast ratio.
1409
- $l1 = 0.2126 * pow( $r1 / 255, 2.2 ) +
1410
- 0.7152 * pow( $g1 / 255, 2.2 ) +
1411
- 0.0722 * pow( $b1 / 255, 2.2 );
1412
- $l2 = 0.2126 * pow( $r2_black_color / 255, 2.2 ) +
1413
- 0.7152 * pow( $g2_black_color / 255, 2.2 ) +
1414
- 0.0722 * pow( $b2_black_color / 255, 2.2 );
1415
- $contrast_ratio = 0;
1416
- if ( $l1 > $l2 ) {
1417
- $contrast_ratio = (int) ( ( $l1 + 0.05 ) / ( $l2 + 0.05 ) );
1418
- } else {
1419
- $contrast_ratio = (int) ( ( $l2 + 0.05 ) / ( $l1 + 0.05 ) );
1475
+ $background_y = self::get_apca_luminance( $hex );
1476
+ $black_lc = self::get_apca_contrast( $background_y, self::get_apca_luminance( '#000000' ) );
1477
+ $white_lc = self::get_apca_contrast( $background_y, self::get_apca_luminance( '#ffffff' ) );
1478
+
1479
+ return abs( $white_lc ) > abs( $black_lc ) ? 'white' : 'black';
1480
+ }
1481
+
1482
+ /**
1483
+ * Compute the soft-clamped APCA screen luminance (Y) of a hex color.
1484
+ *
1485
+ * Accepts #RGB, #RRGGBB and #RRGGBBAA (the alpha pair is stripped), with or
1486
+ * without the leading #, case-insensitively. Unparseable input is treated as
1487
+ * white (luminance 1.0) so callers fall back to black text.
1488
+ *
1489
+ * @param string $hex Hexadecimal color.
1490
+ * @return float Soft-clamped luminance in the 0..1 range.
1491
+ */
1492
+ private static function get_apca_luminance( $hex ) {
1493
+ $hex = ltrim( trim( (string) $hex ), '#' );
1494
+ if ( 3 === strlen( $hex ) ) {
1495
+ $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
1496
+ } elseif ( 8 === strlen( $hex ) ) {
1497
+ // Drop the alpha pair from #RRGGBBAA.
1498
+ $hex = substr( $hex, 0, 6 );
1420
1499
  }
1421
- if ( $contrast_ratio > 5 ) {
1422
- // If contrast is more than 5, return black color.
1423
- return 'black';
1424
- } else {
1425
- // if not, return white color.
1426
- return 'white';
1500
+ if ( 6 !== strlen( $hex ) || ! ctype_xdigit( $hex ) ) {
1501
+ return 1.0;
1427
1502
  }
1503
+
1504
+ $r = hexdec( substr( $hex, 0, 2 ) ) / 255;
1505
+ $g = hexdec( substr( $hex, 2, 2 ) ) / 255;
1506
+ $b = hexdec( substr( $hex, 4, 2 ) ) / 255;
1507
+
1508
+ $y = 0.2126729 * pow( $r, 2.4 ) + 0.7151522 * pow( $g, 2.4 ) + 0.0721750 * pow( $b, 2.4 );
1509
+
1510
+ // APCA soft-clamp of near-black luminance.
1511
+ if ( $y <= 0.022 ) {
1512
+ $y += pow( 0.022 - $y, 1.414 );
1513
+ }
1514
+
1515
+ return $y;
1516
+ }
1517
+
1518
+ /**
1519
+ * Compute the APCA lightness contrast (Lc) of text on a background.
1520
+ *
1521
+ * Positive values are dark text on a lighter background; negative values are
1522
+ * light text on a darker background. Both luminances must already be
1523
+ * soft-clamped.
1524
+ *
1525
+ * @param float $background_y Soft-clamped background luminance.
1526
+ * @param float $text_y Soft-clamped text luminance.
1527
+ * @return float The Lc value.
1528
+ */
1529
+ private static function get_apca_contrast( $background_y, $text_y ) {
1530
+ if ( abs( $background_y - $text_y ) < 0.0005 ) {
1531
+ return 0.0;
1532
+ }
1533
+
1534
+ if ( $background_y > $text_y ) {
1535
+ $sapc = ( pow( $background_y, 0.56 ) - pow( $text_y, 0.57 ) ) * 1.14;
1536
+ return $sapc < 0.1 ? 0.0 : ( $sapc - 0.027 ) * 100;
1537
+ }
1538
+
1539
+ $sapc = ( pow( $background_y, 0.65 ) - pow( $text_y, 0.62 ) ) * 1.14;
1540
+ return $sapc > -0.1 ? 0.0 : ( $sapc + 0.027 ) * 100;
1428
1541
  }
1429
1542
 
1430
1543
  /**
@@ -7,7 +7,7 @@
7
7
  * Author URI: https://newspack.com/
8
8
  * Text Domain: newspack-blocks
9
9
  * Domain Path: /languages
10
- * Version: 4.29.2
10
+ * Version: 4.30.0-alpha.2
11
11
  *
12
12
  * @package Newspack_Blocks
13
13
  */
@@ -15,7 +15,7 @@
15
15
  define( 'NEWSPACK_BLOCKS__PLUGIN_FILE', __FILE__ );
16
16
  define( 'NEWSPACK_BLOCKS__BLOCKS_DIRECTORY', 'dist/' );
17
17
  define( 'NEWSPACK_BLOCKS__PLUGIN_DIR', plugin_dir_path( NEWSPACK_BLOCKS__PLUGIN_FILE ) );
18
- define( 'NEWSPACK_BLOCKS__VERSION', '4.29.2' );
18
+ define( 'NEWSPACK_BLOCKS__VERSION', '4.30.0-alpha.2' );
19
19
 
20
20
  require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'includes/class-newspack-blocks.php';
21
21
  require_once NEWSPACK_BLOCKS__PLUGIN_DIR . 'includes/class-newspack-blocks-api.php';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/newspack-blocks",
3
- "version": "4.29.2",
3
+ "version": "4.30.0-alpha.2",
4
4
  "author": "Automattic",
5
5
  "description": "=== Newspack Blocks === Contributors: (this should be a list of wordpress.org userid's) Donate link: https://example.com/ Tags: comments, spam Requires at least: 4.5 Tested up to: 5.1.1 Stable tag: 0.1.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html",
6
6
  "repository": {
@@ -46,8 +46,8 @@
46
46
  "dependencies": {
47
47
  "classnames": "^2.5.1",
48
48
  "lodash": "^4.17.21",
49
- "newspack-colors": "1.1.1",
50
- "newspack-icons": "1.1.0",
49
+ "newspack-colors": "1.1.2-alpha.1",
50
+ "newspack-icons": "1.1.1-alpha.1",
51
51
  "redux": "^5.0.0",
52
52
  "redux-saga": "^1.5.0",
53
53
  "regenerator-runtime": "^0.14.1",
@@ -55,8 +55,8 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/lodash": "^4.17.23",
58
- "newspack-components": "4.6.0",
59
- "newspack-scripts": "5.10.0"
58
+ "newspack-components": "4.6.1-alpha.1",
59
+ "newspack-scripts": "5.11.0-alpha.1"
60
60
  },
61
61
  "overrides": {
62
62
  "path-to-regexp": "1.7.0"
@@ -78,8 +78,8 @@ function newspack_blocks_render_block_author_list( $attributes ) {
78
78
  }
79
79
 
80
80
  // Enqueue required front-end assets.
81
- Newspack_Blocks::enqueue_view_assets( 'author-list' );
82
- Newspack_Blocks::enqueue_view_assets( 'author-profile' );
81
+ Newspack_Blocks::enqueue_view_assets( 'author-list', 'defer' );
82
+ Newspack_Blocks::enqueue_view_assets( 'author-profile', 'defer' );
83
83
 
84
84
  // Class names for the list container.
85
85
  $container_classes = [ 'newspack-blocks__author-list-container' ];
@@ -320,7 +320,7 @@ function newspack_blocks_render_block_author_profile( $attributes, $content, $bl
320
320
  return '';
321
321
  }
322
322
 
323
- Newspack_Blocks::enqueue_view_assets( 'author-profile' );
323
+ Newspack_Blocks::enqueue_view_assets( 'author-profile', 'defer' );
324
324
 
325
325
  // NESTED MODE: Determined by layoutVersion attribute, not theme type.
326
326
  // Once a block is created in nested mode (layoutVersion 2), it stays nested.
@@ -269,7 +269,7 @@ function newspack_blocks_render_block_carousel( $attributes ) {
269
269
  $data_attributes[] = 'data-autoplay=1';
270
270
  $data_attributes[] = sprintf( 'data-autoplay_delay=%s', esc_attr( $delay ) );
271
271
  }
272
- Newspack_Blocks::enqueue_view_assets( 'carousel' );
272
+ Newspack_Blocks::enqueue_view_assets( 'carousel', 'defer' );
273
273
  if ( 1 === $counter ) {
274
274
  $selector = '';
275
275
  }
@@ -81,7 +81,7 @@ function render_callback( $attributes ) {
81
81
  ? $attributes['product']
82
82
  : $product_id;
83
83
  \Newspack_Blocks\Modal_Checkout::enqueue_modal( $modal_product_id );
84
- \Newspack_Blocks::enqueue_view_assets( 'checkout-button' );
84
+ \Newspack_Blocks::enqueue_view_assets( 'checkout-button', 'defer' );
85
85
 
86
86
  $background_color = $attributes['backgroundColor'] ?? '';
87
87
  $text_color = $attributes['textColor'] ?? '';
@@ -0,0 +1,37 @@
1
+ import { getColorForContrast } from './utils';
2
+
3
+ describe( 'getColorForContrast', () => {
4
+ // Must stay in parity with Newspack_Blocks::get_color_for_contrast(), which
5
+ // runs the same APCA math (see tests/test-color-contrast.php).
6
+ it.each( [
7
+ [ '#000000', '#ffffff' ],
8
+ [ '#ffffff', '#000000' ],
9
+ [ '#f0f0f0', '#000000' ],
10
+ [ '#ffcc00', '#000000' ],
11
+ // APCA flip zone: WCAG2 said black, APCA says white decisively.
12
+ [ '#178f15', '#ffffff' ],
13
+ [ '#3366cc', '#ffffff' ],
14
+ [ '#dd3333', '#ffffff' ],
15
+ [ '#fff', '#000000' ],
16
+ [ '#36c', '#ffffff' ],
17
+ [ 'not-a-color', '#000000' ],
18
+ // Parity cases shared with the PHP fixture table.
19
+ [ '3366cc', '#ffffff' ],
20
+ [ '178f15', '#ffffff' ],
21
+ [ '', '#000000' ],
22
+ [ '#33333380', '#ffffff' ],
23
+ [ '#FFCC00', '#000000' ],
24
+ [ ' #178f15 ', '#ffffff' ],
25
+ ] )( 'picks readable text for %s', ( background, expected ) => {
26
+ expect( getColorForContrast( background ) ).toBe( expected );
27
+ } );
28
+
29
+ it( 'falls back to black when no color is provided', () => {
30
+ expect( getColorForContrast( undefined ) ).toBe( '#000000' );
31
+ } );
32
+
33
+ it( 'expands 3-digit hex the same as 6-digit hex', () => {
34
+ expect( getColorForContrast( '#36c' ) ).toBe( getColorForContrast( '#3366cc' ) );
35
+ expect( getColorForContrast( '#fff' ) ).toBe( getColorForContrast( '#ffffff' ) );
36
+ } );
37
+ } );
@@ -1,17 +1,74 @@
1
1
  import { __, _x, sprintf } from '@wordpress/i18n';
2
2
  import type { DonationFrequencySlug } from './types';
3
3
 
4
+ // Normalize a hex color to exactly six lowercase hex digits (no leading #).
5
+ // Accepts #RGB, #RRGGBB and #RRGGBBAA (the alpha pair is stripped), with or
6
+ // without the leading #, case-insensitively; returns null when unparseable.
7
+ // Keep in sync with Newspack_Blocks::get_apca_luminance() in
8
+ // includes/class-newspack-blocks.php.
9
+ const normalizeHex = ( color: string ): string | null => {
10
+ let hex = color.trim().replace( /^#/, '' ).toLowerCase();
11
+ if ( hex.length === 3 ) {
12
+ hex = hex[ 0 ] + hex[ 0 ] + hex[ 1 ] + hex[ 1 ] + hex[ 2 ] + hex[ 2 ];
13
+ } else if ( hex.length === 8 ) {
14
+ hex = hex.substring( 0, 6 );
15
+ }
16
+ return /^[a-f\d]{6}$/.test( hex ) ? hex : null;
17
+ };
18
+
4
19
  const hexToRGB = ( hex: string ): number[] => {
5
- const parts = hex
6
- .replace( /^#?([a-f\d])([a-f\d])([a-f\d])$/i, ( m, r, g, b ) => '#' + r + r + g + g + b + b )
7
- .substring( 1 )
8
- .match( /.{2}/g );
20
+ const parts = hex.match( /.{2}/g );
9
21
  if ( parts === null ) {
10
22
  return [ 0, 0, 0 ];
11
23
  }
12
24
  return parts.map( x => parseInt( x, 16 ) );
13
25
  };
14
26
 
27
+ // APCA soft-clamps near-black luminance and treats unparseable input as white
28
+ // (luminance 1) so callers fall back to black text.
29
+ const apcaLuminance = ( color: string ): number => {
30
+ const hex = normalizeHex( color );
31
+ if ( hex === null ) {
32
+ return 1;
33
+ }
34
+
35
+ const [ r, g, b ] = hexToRGB( hex );
36
+
37
+ let y = 0.2126729 * Math.pow( r / 255, 2.4 ) + 0.7151522 * Math.pow( g / 255, 2.4 ) + 0.072175 * Math.pow( b / 255, 2.4 );
38
+
39
+ if ( y <= 0.022 ) {
40
+ y += Math.pow( 0.022 - y, 1.414 );
41
+ }
42
+
43
+ return y;
44
+ };
45
+
46
+ // APCA lightness contrast (Lc): positive is dark text on a lighter background,
47
+ // negative is light text on a darker background. Both luminances are clamped.
48
+ const apcaContrast = ( backgroundY: number, textY: number ): number => {
49
+ if ( Math.abs( backgroundY - textY ) < 0.0005 ) {
50
+ return 0;
51
+ }
52
+
53
+ if ( backgroundY > textY ) {
54
+ const sapc = ( Math.pow( backgroundY, 0.56 ) - Math.pow( textY, 0.57 ) ) * 1.14;
55
+ return sapc < 0.1 ? 0 : ( sapc - 0.027 ) * 100;
56
+ }
57
+
58
+ const sapc = ( Math.pow( backgroundY, 0.65 ) - Math.pow( textY, 0.62 ) ) * 1.14;
59
+ return sapc > -0.1 ? 0 : ( sapc + 0.027 ) * 100;
60
+ };
61
+
62
+ /**
63
+ * Pick either black or white text, whichever reads better on the given background.
64
+ *
65
+ * Scores pure black and pure white as text against the background and returns
66
+ * whichever produces the greater APCA lightness contrast (Lc); ties fall to
67
+ * black. The constants are the SA98G set from apca-w3 0.1.9.
68
+ *
69
+ * Keep in sync with Newspack_Blocks::get_color_for_contrast() in
70
+ * includes/class-newspack-blocks.php.
71
+ */
15
72
  export const getColorForContrast = ( color?: string ): string => {
16
73
  const blackColor = '#000000';
17
74
  const whiteColor = '#ffffff';
@@ -19,19 +76,11 @@ export const getColorForContrast = ( color?: string ): string => {
19
76
  return blackColor;
20
77
  }
21
78
 
22
- const backgroundColorRGB = hexToRGB( color );
23
- const blackRGB = hexToRGB( blackColor );
24
-
25
- const l1 =
26
- 0.2126 * Math.pow( backgroundColorRGB[ 0 ] / 255, 2.2 ) +
27
- 0.7152 * Math.pow( backgroundColorRGB[ 1 ] / 255, 2.2 ) +
28
- 0.0722 * Math.pow( backgroundColorRGB[ 2 ] / 255, 2.2 );
29
- const l2 =
30
- 0.2126 * Math.pow( blackRGB[ 0 ] / 255, 2.2 ) + 0.7152 * Math.pow( blackRGB[ 1 ] / 255, 2.2 ) + 0.0722 * Math.pow( blackRGB[ 2 ] / 255, 2.2 );
31
-
32
- const contrastRatio = l1 > l2 ? ( l1 + 0.05 ) / ( l2 + 0.05 ) : ( l2 + 0.05 ) / ( l1 + 0.05 );
79
+ const backgroundY = apcaLuminance( color );
80
+ const blackLc = apcaContrast( backgroundY, apcaLuminance( blackColor ) );
81
+ const whiteLc = apcaContrast( backgroundY, apcaLuminance( whiteColor ) );
33
82
 
34
- return contrastRatio > 5 ? blackColor : whiteColor;
83
+ return Math.abs( whiteLc ) > Math.abs( blackLc ) ? whiteColor : blackColor;
35
84
  };
36
85
 
37
86
  export const getMigratedAmount = (
@@ -422,7 +422,7 @@ function newspack_blocks_render_block_homepage_articles( $attributes ) {
422
422
  <?php
423
423
 
424
424
  $content = ob_get_clean();
425
- Newspack_Blocks::enqueue_view_assets( 'homepage-articles' );
425
+ Newspack_Blocks::enqueue_view_assets( 'homepage-articles', 'defer' );
426
426
 
427
427
  return $content;
428
428
  }
@@ -13,7 +13,7 @@
13
13
  * @return string
14
14
  */
15
15
  function newspack_blocks_render_block_iframe( $attributes ) {
16
- Newspack_Blocks::enqueue_view_assets( 'iframe' );
16
+ Newspack_Blocks::enqueue_view_assets( 'iframe', 'defer' );
17
17
 
18
18
  return newspack_blocks_get_iframe( $attributes );
19
19
  }
@@ -3,7 +3,7 @@
3
3
  'name' => 'automattic/newspack-blocks',
4
4
  'pretty_version' => 'dev-main',
5
5
  'version' => 'dev-main',
6
- 'reference' => '6f5c479147b99356531e175bffe5b1846d2bfa71',
6
+ 'reference' => '676b21e16de65c4c31fba7e48dcf23dd93dfcd1c',
7
7
  'type' => 'wordpress-plugin',
8
8
  'install_path' => __DIR__ . '/../../',
9
9
  'aliases' => array(),
@@ -13,7 +13,7 @@
13
13
  'automattic/newspack-blocks' => array(
14
14
  'pretty_version' => 'dev-main',
15
15
  'version' => 'dev-main',
16
- 'reference' => '6f5c479147b99356531e175bffe5b1846d2bfa71',
16
+ 'reference' => '676b21e16de65c4c31fba7e48dcf23dd93dfcd1c',
17
17
  'type' => 'wordpress-plugin',
18
18
  'install_path' => __DIR__ . '/../../',
19
19
  'aliases' => array(),