You are here

pwa.apple.inc in Progressive Web App 7.2

File

includes/pwa.apple.inc
View source
<?php

/**
 * @file
 */
function _pwa_apple_drusplash_list() {
  $cid = 'pwa:apple';
  if ($data = cache_get($cid, 'cache')) {
    $data = $data->data;
  }
  else {
    $manifest = pwa_file_data('manifest');
    $data = _pwa_apple_splash_screens_meta($manifest);
    cache_set($cid, $data, 'cache');
  }
  return $data;
}
function _pwa_apple_splash_screens_meta($manifest) {
  $metas = [];
  $devices = array_filter((array) variable_get('pwa_apple_startup-image_devices'));

  // Take the largest icon to generate the splashscreens.
  foreach (_pwa_apple_devices() as $device) {

    // Generate meta for selected devices only.
    if (!in_array($device->device, $devices)) {
      continue;
    }
    $scale = $device->scaleFactor;
    $media = [
      'width' => '(device-width: ' . $device->portrait->width / $scale . 'px)',
      'height' => '(device-height: ' . $device->portrait->height / $scale . 'px)',
      'pixel' => '(-webkit-device-pixel-ratio: ' . $scale . ')',
    ];
    foreach ([
      'landscape',
      'portrait',
    ] as $orientation) {
      if ($href = _pwa_apple_get_spalsh_screen_href((array) $device->{$orientation})) {
        $metas[$device->device . '-' . $orientation] = [
          'media' => implode(' and ', $media + [
            'orientation' => '(orientation: ' . $orientation . ')',
          ]),
          'href' => $href,
          'data-device' => $device->device,
        ];
      }
    }
  }
  return $metas;
}
function _pwa_apple_create_folder($directory = 'public://pwa/apple') {

  // Get the folder for the final location of this style.
  // Build the destination folder tree if it doesn't already exist.
  if (!file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
    watchdog('image', 'Failed to create style directory: %directory', array(
      '%directory' => $directory,
    ), WATCHDOG_ERROR);
    return FALSE;
  }
  return drupal_realpath($directory);
}
function _pwa_apple_create_image_base() {
  $manifest = pwa_file_data('manifest');
  $base_folder = 'public://pwa/apple';
  if ($icon_src = array_search('512x512', array_column($manifest['icons'], 'sizes', 'src'))) {
    $src = DRUPAL_ROOT . parse_url($icon_src, PHP_URL_PATH);
    $image = image_load($src);
    $target = imagecreatetruecolor(2732, 2732);

    // Get background color from the icon, take from the edge in case there
    // is a gradient going on.
    $color_index = imagecolorat($image->resource, 1, 1);
    $color = imagecolorsforindex($image->resource, $color_index);
    $background = imagecolorallocate($target, $color['red'], $color['green'], $color['blue']);
    imagefill($target, 0, 0, $background);

    // Because we know all the sizes, possible to hardcode the values here.
    imagecopymerge($target, $image->resource, 1110, 1110, 0, 0, 512, 512, 100);
    if ($directory = _pwa_apple_create_folder($base_folder)) {
      imagepng($target, $directory . '/drusplash.png');
    }
    imagedestroy($target);
  }
}
function _pwa_apple_get_spalsh_screen_href($data) {
  $base_folder = 'public://pwa/apple';
  $directory = _pwa_apple_create_folder($base_folder);
  if (!file_exists($directory . '/drusplash.png')) {
    _pwa_apple_create_image_base();
  }
  $base_image = $base_folder . '/drusplash.png';
  $image_path = $base_folder . '/' . pathinfo($base_image, PATHINFO_FILENAME) . '-' . $data['width'] . 'x' . $data['height'] . '.' . pathinfo($base_image, PATHINFO_EXTENSION);
  if (file_exists($image_path)) {
    return file_create_url($image_path);
  }
  if (!($image = image_load($base_image))) {
    return FALSE;
  }

  // Get the folder for the final location of this style.
  // Build the destination folder tree if it doesn't already exist.
  module_load_include('inc', 'image', 'image.effects');
  image_scale_and_crop_effect($image, $data);
  if (!image_save($image, $image_path)) {
    return FALSE;
  }
  return file_create_url($image_path);
}

/**
 * Add apple specific variables.
 */
function _pwa_apple_html_head_alter(&$head_elements) {
  $manifest = pwa_file_data('manifest');

  // Icon used by Safari when the tab is pinned.
  if ($mask_src = array_search('monochrome', array_column($manifest['icons'], 'purpose', 'src'))) {

    // Add mask-icon
    $head_elements['apple-mask-icon'] = [
      '#type' => 'html_tag',
      '#tag' => 'link',
      '#attributes' => [
        'rel' => 'mask-icon',
        'href' => $mask_src,
        'color' => $manifest['theme_color'],
      ],
      '#weight' => 90,
    ];
  }

  // If the display does not give an 'app' feel, do not add apple metadata.
  if (!in_array($manifest['display'], [
    'standalone',
    'fullscreen',
    'minimal-ui',
  ])) {
    return;
  }
  $head_elements['apple-mobile-web-app-capable'] = [
    '#type' => 'html_tag',
    '#tag' => 'meta',
    '#attributes' => [
      'name' => 'apple-mobile-web-app-capable',
      'content' => 'yes',
    ],
    '#weight' => 90,
  ];
  $head_elements['apple-mobile-web-app-status-bar-style'] = [
    '#type' => 'html_tag',
    '#tag' => 'meta',
    '#attributes' => [
      'name' => 'apple-mobile-web-app-status-bar-style',
      'content' => variable_get('pwa_apple_status-bar-style', 'black_translucent'),
    ],
    '#weight' => 90,
  ];

  // Many many images for the apple-touch-startup-image.
  if (!variable_get('pwa_apple_startup-image', TRUE)) {
    return;
  }
  foreach (_pwa_apple_drusplash_list() as $device => $icon) {
    $head_elements['apple-touch-startup-image_' . $device] = [
      '#type' => 'html_tag',
      '#tag' => 'link',
      '#attributes' => [
        'rel' => 'apple-touch-startup-image',
      ] + $icon,
      // Keep this lower in the HTML Source than the other meta tags.
      '#weight' => 100,
    ];
  }
}

/**
 * List all devices to be supported from apple.
 * @see https://github.com/onderceylan/pwa-asset-generator/blob/master/src/config/apple-fallback-data.json
 */
function _pwa_apple_devices() {
  $specs = <<<SPECS
[
{
  "device": "12.9\\" iPad Pro",
  "portrait": {
    "width": 2048,
    "height": 2732
  },
  "landscape": {
    "width": 2732,
    "height": 2048
  },
  "scaleFactor": 2
},
{
  "device": "11\\" iPad Pro",
  "portrait": {
    "width": 1668,
    "height": 2388
  },
  "landscape": {
    "width": 2388,
    "height": 1668
  },
  "scaleFactor": 2
},
{
  "device": "10.5\\" iPad Pro",
  "portrait": {
    "width": 1668,
    "height": 2388
  },
  "landscape": {
    "width": 2388,
    "height": 1668
  },
  "scaleFactor": 2
},
{
  "device": "9.7\\" iPad Pro",
  "portrait": {
    "width": 1536,
    "height": 2048
  },
  "landscape": {
    "width": 2048,
    "height": 1536
  },
  "scaleFactor": 2
},
{
  "device": "7.9\\" iPad mini",
  "portrait": {
    "width": 1536,
    "height": 2048
  },
  "landscape": {
    "width": 2048,
    "height": 1536
  },
  "scaleFactor": 2
},
{
  "device": "10.5\\" iPad Air",
  "portrait": {
    "width": 1668,
    "height": 2224
  },
  "landscape": {
    "width": 2224,
    "height": 1668
  },
  "scaleFactor": 2
},
{
  "device": "9.7\\" iPad Air",
  "portrait": {
    "width": 1536,
    "height": 2048
  },
  "landscape": {
    "width": 2048,
    "height": 1536
  },
  "scaleFactor": 2
},
{
  "device": "10.2\\" iPad",
  "portrait": {
    "width": 1620,
    "height": 2160
  },
  "landscape": {
    "width": 2160,
    "height": 1620
  },
  "scaleFactor": 2
},
{
  "device": "9.7\\" iPad",
  "portrait": {
    "width": 1536,
    "height": 2048
  },
  "landscape": {
    "width": 2048,
    "height": 1536
  },
  "scaleFactor": 2
},
{
  "device": "iPhone 11 Pro Max",
  "portrait": {
    "width": 1242,
    "height": 2688
  },
  "landscape": {
    "width": 2688,
    "height": 1242
  },
  "scaleFactor": 3
},
{
  "device": "iPhone 11 Pro",
  "portrait": {
    "width": 1125,
    "height": 2436
  },
  "landscape": {
    "width": 2436,
    "height": 1125
  },
  "scaleFactor": 3
},
{
  "device": "iPhone 11",
  "portrait": {
    "width": 828,
    "height": 1792
  },
  "landscape": {
    "width": 1792,
    "height": 828
  },
  "scaleFactor": 2
},
{
  "device": "iPhone XS Max",
  "portrait": {
    "width": 1242,
    "height": 2688
  },
  "landscape": {
    "width": 2688,
    "height": 1242
  },
  "scaleFactor": 3
},
{
  "device": "iPhone XS",
  "portrait": {
    "width": 1125,
    "height": 2436
  },
  "landscape": {
    "width": 2436,
    "height": 1125
  },
  "scaleFactor": 3
},
{
  "device": "iPhone XR",
  "portrait": {
    "width": 828,
    "height": 1792
  },
  "landscape": {
    "width": 1792,
    "height": 828
  },
  "scaleFactor": 2
},
{
  "device": "iPhone X",
  "portrait": {
    "width": 1125,
    "height": 2436
  },
  "landscape": {
    "width": 2436,
    "height": 1125
  },
  "scaleFactor": 3
},
{
  "device": "iPhone 8 Plus",
  "portrait": {
    "width": 1080,
    "height": 1920
  },
  "landscape": {
    "width": 1920,
    "height": 1080
  },
  "scaleFactor": 3
},
{
  "device": "iPhone 8",
  "portrait": {
    "width": 750,
    "height": 1334
  },
  "landscape": {
    "width": 1334,
    "height": 750
  },
  "scaleFactor": 2
},
{
  "device": "iPhone 7 Plus",
  "portrait": {
    "width": 1080,
    "height": 1920
  },
  "landscape": {
    "width": 1920,
    "height": 1080
  },
  "scaleFactor": 3
},
{
  "device": "iPhone 7",
  "portrait": {
    "width": 750,
    "height": 1334
  },
  "landscape": {
    "width": 1334,
    "height": 750
  },
  "scaleFactor": 2
},
{
  "device": "iPhone 6s Plus",
  "portrait": {
    "width": 1080,
    "height": 1920
  },
  "landscape": {
    "width": 1920,
    "height": 1080
  },
  "scaleFactor": 3
},
{
  "device": "iPhone 6s",
  "portrait": {
    "width": 750,
    "height": 1334
  },
  "landscape": {
    "width": 1334,
    "height": 750
  },
  "scaleFactor": 2
},
{
  "device": "iPhone 6 Plus",
  "portrait": {
    "width": 1080,
    "height": 1920
  },
  "landscape": {
    "width": 1920,
    "height": 1080
  },
  "scaleFactor": 3
},
{
  "device": "iPhone 6",
  "portrait": {
    "width": 750,
    "height": 1334
  },
  "landscape": {
    "width": 1334,
    "height": 750
  },
  "scaleFactor": 2
},
{
  "device": "4.7\\" iPhone SE",
  "portrait": {
    "width": 750,
    "height": 1334
  },
  "landscape": {
    "width": 1334,
    "height": 750
  },
  "scaleFactor": 2
},
{
  "device": "4\\" iPhone SE",
  "portrait": {
    "width": 640,
    "height": 1136
  },
  "landscape": {
    "width": 1136,
    "height": 640
  },
  "scaleFactor": 2
}
]
SPECS;
  return json_decode($specs);
}