From 784a41e1d7c039eb908b7ccc61578fc755a9ee10 Mon Sep 17 00:00:00 2001 From: Robin Cornett Date: Tue, 18 Jun 2019 10:26:49 -0400 Subject: [PATCH 01/44] Initial (non-working) add Some kind of REST 404 error but no idea how to resolve. --- ...ass-displayfeaturedimagegenesis-blocks.php | 257 ++++++++++++++++++ .../class-displayfeaturedimagegenesis.php | 10 + includes/js/block.js | 200 ++++++++++++++ 3 files changed, 467 insertions(+) create mode 100644 includes/blocks/class-displayfeaturedimagegenesis-blocks.php create mode 100644 includes/js/block.js diff --git a/includes/blocks/class-displayfeaturedimagegenesis-blocks.php b/includes/blocks/class-displayfeaturedimagegenesis-blocks.php new file mode 100644 index 0000000..5d0b5ac --- /dev/null +++ b/includes/blocks/class-displayfeaturedimagegenesis-blocks.php @@ -0,0 +1,257 @@ +register_script_style(); + foreach ( $this->blocks() as $block => $data ) { + if ( 'term' === $block ) { + continue; + } + register_block_type( + "display-featured-image-genesis/{$block}", + array( + 'editor_script' => 'displayfeaturedimagegenesis-block', + 'attributes' => $this->get_attributes( $block ), + 'render_callback' => array( $this, 'render' ), + ) + ); + } + add_action( 'enqueue_block_editor_assets', array( $this, 'localize' ) ); + } + + /** + * Register the block script and style. + */ + public function register_script_style() { + $version = displayfeaturedimagegenesis_get()->version; + $minify = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : ' . min'; + if ( ! $minify ) { + $version .= current_time( 'gmt' ); + } + wp_register_script( + 'displayfeaturedimagegenesis-block', + plugin_dir_url( dirname( __FILE__ ) ) . "js/block{$minify}.js", + array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-editor' ), + $version, + false + ); + } + + /** + * Get the list of blocks to create. + * @return array + */ + private function blocks() { + return array( + 'term' => array( + 'title' => __( 'Display Featured Term Image', 'display-featured-image-genesis' ), + 'description' => __( 'Display a featured term', 'display-featured-image-genesis' ), + 'keywords' => array( + __( 'Term', 'display-featured-image-genesis' ), + __( 'Featured Image', 'display-featured-image-genesis' ), + ), + ), + 'author' => array( + 'title' => __( 'Display Featured Author Profile', 'display-featured-image-genesis' ), + 'description' => __( 'Display a featured author', 'display-featured-image-genesis' ), + 'keywords' => array( + __( 'Author', 'display-featured-image-genesis' ), + __( 'Featured Image', 'display-featured-image-genesis' ), + ), + ), + 'post-type' => array( + 'title' => __( 'Display Featured Post Type Archive Image', 'display-featured-image-genesis' ), + 'description' => __( 'Display a featured content type', 'display-featured-image-genesis' ), + 'keywords' => array( + __( 'Post Type', 'display-featured-image-genesis' ), + __( 'Featured Image', 'display-featured-image-genesis' ), + ), + ), + ); + } + + /** + * Render the widget in a container div. + * + * @param $attributes + * + * @return string + */ + public function render( $attributes ) { + rgc_error_log( $attributes ); +// $classes = $this->get_block_classes( $attributes ); +// $output = '
'; +//// $output .= $this->register->shortcode( $attributes ); +// $output .= '
'; + + return 'this is the output'; + } + + /** + * Get the block classes. + * + * @param $attributes + * + * @return array + * @since 0.4.0 + */ + private function get_block_classes( $attributes ) { + $classes = array( + 'wp-block-displayfeaturedimagegenesis' . 'term', + ); + if ( ! empty( $attributes['className'] ) ) { + $classes[] = $attributes['className']; + } + if ( ! empty( $attributes['blockAlignment'] ) ) { + $classes[] = 'align' . $attributes['blockAlignment']; + } + + return $classes; + } + + /** + * @param $block + * + * @return array + */ + protected function get_attributes( $block ) { + $attributes = array_merge( + $this->fields(), + $this->get_block_fields( $block ) + ); + foreach ( $attributes as $key => $value ) { + $attributes[ $key ] = $this->get_individual_field_attributes( $value, $key ); + } + + return $attributes; + } + + /** + * + */ + public function localize() { + $args = array(); + foreach ( $this->blocks() as $block => $data ) { + $args['blocks'][ $block ] = $this->get_localization_data( $block, $data ); + } + wp_localize_script( 'displayfeaturedimagegenesis-block', 'DisplayFeaturedImageGenesisBlock', $args ); + } + + /** + * Get the data for localizing everything. + * @return array + */ + protected function get_localization_data( $block, $data ) { + return array( + 'block' => "displayfeaturedimagegenesis/{$block}", + 'title' => $data['title'], + 'description' => $data['description'], + 'keywords' => $data['keywords'], + 'panels' => array( + 'main' => array( + 'title' => __( 'Block Settings', 'display-featured-image-genesis' ), + 'initialOpen' => true, + 'attributes' => $this->get_attributes( $block ), + ), + ), + 'icon' => 'format-image', + 'category' => 'widgets', + ); + } + + /** + * @return array + */ + private function fields() { + return array( + 'blockAlignment' => array( + 'type' => 'string', + 'default' => '', + ), + 'className' => array( + 'type' => 'string', + 'default' => '', + ), + 'title' => array( + 'type' => 'string', + 'default' => '', + 'label' => __( 'Title', 'display-featured-image-genesis' ), + ), + 'show_image' => array( + 'type' => 'boolean', + 'default' => 1, + 'label' => __( 'Show Featured Image', 'display-featured-image-genesis' ), + 'method' => 'checkbox', + ), + 'image_size' => array( + 'type' => 'string', + 'default' => 'medium', + 'label' => __( 'Image Size:', 'display-featured-image-genesis' ), + 'method' => 'select', + 'choices' => $this->get_image_size(), + ), + ); + } + + /** + * Get an array of attributes for an individual field. + * + * @param $field + * @param $id + * + * @return array + */ + protected function get_individual_field_attributes( $field, $id ) { + $field_type = $field['type']; + if ( empty( $field['label'] ) ) { + return $field; + } + $attributes = array( + 'type' => $field['type'], + 'default' => $field['default'], + 'label' => $field['label'], + 'method' => empty( $field['method'] ) ? 'text' : $field['method'], + ); + if ( in_array( 'number', array( $field_type, $attributes['method'] ), true ) ) { + $attributes['min'] = $field['args']['min']; + $attributes['max'] = $field['args']['max']; + } elseif ( 'select' === $attributes['method'] ) { + foreach ( $field['choices'] as $value => $label ) { + $attributes['options'][] = array( + 'value' => $value, + 'label' => $label, + ); + } + } elseif ( 'boolean' === $field_type ) { + $attributes['default'] = 0; + } + + return $attributes; + } + + private function get_image_size() { + $sizes = genesis_get_image_sizes(); + $options = array(); + foreach ( (array) $sizes as $name => $size ) { + $options[ $name ] = sprintf( '%s ( %s x %s )', esc_html( $name ), (int) $size['width'], (int) $size['height'] ); + } + + return $options; + } + + /** + * @param $block + * + * @return array + */ + private function get_block_fields( $block ) { + return array(); + } +} diff --git a/includes/class-displayfeaturedimagegenesis.php b/includes/class-displayfeaturedimagegenesis.php index 1a7c1a5..82fb952 100644 --- a/includes/class-displayfeaturedimagegenesis.php +++ b/includes/class-displayfeaturedimagegenesis.php @@ -125,6 +125,7 @@ class Display_Featured_Image_Genesis { add_action( 'widgets_init', array( $this->widgets, 'register_widgets' ) ); add_action( 'widgets_init', array( $this->widgets, 'register_shortcodes' ) ); add_action( 'admin_enqueue_scripts', array( $this->widgets, 'enqueue_scripts' ) ); + add_action( 'init', array( $this, 'maybe_register_block' ) ); // Taxonomies, Authors add_filter( 'displayfeaturedimagegenesis_get_taxonomies', array( $this->taxonomies, 'remove_post_status_terms' ) ); @@ -249,6 +250,15 @@ class Display_Featured_Image_Genesis { } } + public function maybe_register_block() { + if ( ! function_exists( 'register_block_type' ) ) { + return; + } + include_once 'blocks/class-displayfeaturedimagegenesis-blocks.php'; + $blocks = new DisplayFeaturedImageGenesisBlocks(); + $blocks->init(); + } + /** * Add link to plugin settings page in plugin table * @param $links array link to settings page diff --git a/includes/js/block.js b/includes/js/block.js new file mode 100644 index 0000000..43e2a5c --- /dev/null +++ b/includes/js/block.js @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2019 Robin Cornett + */ + +(function ( wp, undefined ) { + 'use strict'; + const DisplayFeaturedImageBlockObject = { + el: wp.element.createElement, + }; + + /** + * Initialize and register the block. + */ + DisplayFeaturedImageBlockObject.init = function () { + const registerBlockType = wp.blocks.registerBlockType, + ServerSideRender = wp.components.ServerSideRender, + InspectorControls = wp.blockEditor.InspectorControls; + Object.keys( DisplayFeaturedImageBlockObject.params.blocks ).forEach( function ( key, index ) { + if ( DisplayFeaturedImageBlockObject.params.blocks.hasOwnProperty( key ) ) { + const data = DisplayFeaturedImageBlockObject.params.blocks[key]; + registerBlockType( data.block, { + title: data.title, + description: data.description, + keywords: data.keywords, + icon: data.icon, + category: data.category, + supports: { + html: false + }, + + getEditWrapperProps( {blockAlignment} ) { + return {'data-align': blockAlignment}; + }, + + edit: props => { + const { + attributes, + setAttributes + } = props, + Fragment = wp.element.Fragment, + BlockControls = wp.blockEditor.BlockControls, + BlockAlignmentToolbar = wp.blockEditor.BlockAlignmentToolbar; + return [ + DisplayFeaturedImageBlockObject.el( ServerSideRender, { + block: data.block, + attributes: attributes + } ), + DisplayFeaturedImageBlockObject.el( Fragment, null, + DisplayFeaturedImageBlockObject.el( BlockControls, null, + DisplayFeaturedImageBlockObject.el( BlockAlignmentToolbar, { + value: attributes.blockAlignment, + controls: ['wide', 'full'], + onChange: ( value ) => { + setAttributes( {blockAlignment: value} ); + }, + } ) + ), + ), + DisplayFeaturedImageBlockObject.el( InspectorControls, {}, + _getPanels( props ) + ) + ]; + }, + + save: props => { + return null; + }, + } ); + } + } ); + }; + + /** + * Get the panels for the block controls. + * + * @param props + * @return {Array} + * @private + */ + function _getPanels( props ) { + const panels = [], + PanelBody = wp.components.PanelBody; + Object.keys( DisplayFeaturedImageBlockObject.params.blocks ).forEach( function ( block_key, index ) { + if ( DisplayFeaturedImageBlockObject.params.blocks.hasOwnProperty( block_key ) ) { + const data = DisplayFeaturedImageBlockObject.params.blocks[ block_key ]; + Object.keys( data.panels ).forEach( function ( key, index ) { + if ( data.panels.hasOwnProperty( key ) ) { + const IndividualPanel = data.panels[key]; + panels[index] = DisplayFeaturedImageBlockObject.el( PanelBody, { + title: IndividualPanel.title, + initialOpen: IndividualPanel.initialOpen, + className: 'display-featured-image-panel-' + key + }, _getControls( props, IndividualPanel.attributes ) ); + } + } ); + } + } ); + + return panels; + } + + /** + * Get all of the block controls, with defaults and options. + * + * @param props + * @param fields + * @return {Array} + * @private + */ + function _getControls( props, fields ) { + const controls = []; + Object.keys( fields ).forEach( function ( key, index ) { + if ( fields.hasOwnProperty( key ) ) { + var skipped = [ 'blockAlignment', 'className' ]; + if ( -1 !== skipped.indexOf( key ) ) { + return; + } + const IndividualField = fields[key], + control = _getControlType( IndividualField.method, IndividualField.type ); + controls[index] = DisplayFeaturedImageBlockObject.el( control, _getIndividualControl( key, IndividualField, props ) ); + } + } ); + + return controls; + } + + /** + * Get the control type. + * @param method + * @param control_type + * @return {*} + * @private + */ + function _getControlType( method, control_type ) { + const { + TextControl, + SelectControl, + RangeControl, + CheckboxControl, + TextareaControl + } = wp.components; + const control = TextControl; + if ( 'select' === method ) { + return SelectControl; + } else if ( 'number' === method && 'number' === control_type ) { + return RangeControl; + } else if ( 'checkbox' === method ) { + return CheckboxControl; + } else if ( 'textarea' === method ) { + return TextareaControl; + } + + return control; + } + + /** + * Build the individual control object. Sets up standard properties for all + * controls; then adds custom properties as needed. + * + * @param key + * @param field + * @param props + * @return {{label: *, value: *, className: string, onChange: onChange}} + * @private + */ + function _getIndividualControl( key, field, props ) { + const {attributes, setAttributes} = props; + const control = { + heading: field.heading, + label: field.label, + value: attributes[key], + className: 'displayfeaturedimagegenesis-' + key, + onChange: ( value ) => { + setAttributes( {[key]: value} ); + } + }; + + if ( 'select' === field.method ) { + control.options = field.options; + } else if ( 'number' === field.method ) { + control.min = field.min; + control.max = field.max; + if ( 'number' !== field.type ) { + control.type = 'number'; + } else { + control.initialPosition = field.min; + } + } else if ( 'checkbox' === field.method ) { + control.checked = attributes[key]; + } + + return control; + } + + DisplayFeaturedImageBlockObject.params = typeof DisplayFeaturedImageGenesisBlock === 'undefined' ? '' : DisplayFeaturedImageGenesisBlock; + + if ( typeof DisplayFeaturedImageBlockObject.params !== 'undefined' ) { + DisplayFeaturedImageBlockObject.init(); + } +} )( wp ); From 51ae95ce2801621d2858910b3eafc649afc99403 Mon Sep 17 00:00:00 2001 From: Robin Cornett Date: Fri, 21 Jun 2019 08:45:18 -0400 Subject: [PATCH 02/44] Chnage block registration (still REST 404) --- ...ass-displayfeaturedimagegenesis-blocks.php | 6 +- includes/js/block.js | 126 ++++++++---------- includes/js/block.min.js | 1 + 3 files changed, 64 insertions(+), 69 deletions(-) create mode 100644 includes/js/block.min.js diff --git a/includes/blocks/class-displayfeaturedimagegenesis-blocks.php b/includes/blocks/class-displayfeaturedimagegenesis-blocks.php index 5d0b5ac..2de54ca 100644 --- a/includes/blocks/class-displayfeaturedimagegenesis-blocks.php +++ b/includes/blocks/class-displayfeaturedimagegenesis-blocks.php @@ -139,13 +139,17 @@ class DisplayFeaturedImageGenesisBlocks { public function localize() { $args = array(); foreach ( $this->blocks() as $block => $data ) { - $args['blocks'][ $block ] = $this->get_localization_data( $block, $data ); + $args[ $block ] = $this->get_localization_data( $block, $data ); } wp_localize_script( 'displayfeaturedimagegenesis-block', 'DisplayFeaturedImageGenesisBlock', $args ); } /** * Get the data for localizing everything. + * + * @param $block + * @param $data + * * @return array */ protected function get_localization_data( $block, $data ) { diff --git a/includes/js/block.js b/includes/js/block.js index 43e2a5c..1dd7b11 100644 --- a/includes/js/block.js +++ b/includes/js/block.js @@ -8,65 +8,59 @@ el: wp.element.createElement, }; - /** - * Initialize and register the block. - */ - DisplayFeaturedImageBlockObject.init = function () { + DisplayFeaturedImageBlockObject.takeTwo = function ( block ) { const registerBlockType = wp.blocks.registerBlockType, ServerSideRender = wp.components.ServerSideRender, InspectorControls = wp.blockEditor.InspectorControls; - Object.keys( DisplayFeaturedImageBlockObject.params.blocks ).forEach( function ( key, index ) { - if ( DisplayFeaturedImageBlockObject.params.blocks.hasOwnProperty( key ) ) { - const data = DisplayFeaturedImageBlockObject.params.blocks[key]; - registerBlockType( data.block, { - title: data.title, - description: data.description, - keywords: data.keywords, - icon: data.icon, - category: data.category, - supports: { - html: false - }, + const data = DisplayFeaturedImageBlockObject.params[block]; + // console.log( data ); + registerBlockType( data.block, { + title: data.title, + description: data.description, + keywords: data.keywords, + icon: data.icon, + category: data.category, + supports: { + html: false + }, - getEditWrapperProps( {blockAlignment} ) { - return {'data-align': blockAlignment}; - }, + getEditWrapperProps( {blockAlignment} ) { + return {'data-align': blockAlignment}; + }, - edit: props => { - const { - attributes, - setAttributes - } = props, - Fragment = wp.element.Fragment, - BlockControls = wp.blockEditor.BlockControls, - BlockAlignmentToolbar = wp.blockEditor.BlockAlignmentToolbar; - return [ - DisplayFeaturedImageBlockObject.el( ServerSideRender, { - block: data.block, - attributes: attributes - } ), - DisplayFeaturedImageBlockObject.el( Fragment, null, - DisplayFeaturedImageBlockObject.el( BlockControls, null, - DisplayFeaturedImageBlockObject.el( BlockAlignmentToolbar, { - value: attributes.blockAlignment, - controls: ['wide', 'full'], - onChange: ( value ) => { - setAttributes( {blockAlignment: value} ); - }, - } ) - ), - ), - DisplayFeaturedImageBlockObject.el( InspectorControls, {}, - _getPanels( props ) - ) - ]; - }, + edit: props => { + const { + attributes, + setAttributes + } = props, + Fragment = wp.element.Fragment, + BlockControls = wp.blockEditor.BlockControls, + BlockAlignmentToolbar = wp.blockEditor.BlockAlignmentToolbar; + return [ + DisplayFeaturedImageBlockObject.el( ServerSideRender, { + block: data.block, + attributes: data.attributes + } ), + DisplayFeaturedImageBlockObject.el( Fragment, null, + DisplayFeaturedImageBlockObject.el( BlockControls, null, + DisplayFeaturedImageBlockObject.el( BlockAlignmentToolbar, { + value: props.attributes.blockAlignment, + controls: ['wide', 'full'], + onChange: ( value ) => { + setAttributes( {blockAlignment: value} ); + }, + } ) + ), + ), + DisplayFeaturedImageBlockObject.el( InspectorControls, {}, + _getPanels( props, block ) + ) + ]; + }, - save: props => { - return null; - }, - } ); - } + save: props => { + return null; + }, } ); }; @@ -74,25 +68,21 @@ * Get the panels for the block controls. * * @param props + * @param block * @return {Array} * @private */ - function _getPanels( props ) { + function _getPanels( props, block ) { const panels = [], PanelBody = wp.components.PanelBody; - Object.keys( DisplayFeaturedImageBlockObject.params.blocks ).forEach( function ( block_key, index ) { - if ( DisplayFeaturedImageBlockObject.params.blocks.hasOwnProperty( block_key ) ) { - const data = DisplayFeaturedImageBlockObject.params.blocks[ block_key ]; - Object.keys( data.panels ).forEach( function ( key, index ) { - if ( data.panels.hasOwnProperty( key ) ) { - const IndividualPanel = data.panels[key]; - panels[index] = DisplayFeaturedImageBlockObject.el( PanelBody, { - title: IndividualPanel.title, - initialOpen: IndividualPanel.initialOpen, - className: 'display-featured-image-panel-' + key - }, _getControls( props, IndividualPanel.attributes ) ); - } - } ); + const blockData = DisplayFeaturedImageBlockObject.params[block]; + Object.keys( blockData.panels ).forEach( function ( key, index ) { + if ( blockData.panels.hasOwnProperty( key ) ) { + const IndividualPanel = blockData.panels[key]; + panels[index] = DisplayFeaturedImageBlockObject.el( PanelBody, { + title: IndividualPanel.title, + initialOpen: IndividualPanel.initialOpen + }, _getControls( props, IndividualPanel.attributes ) ); } } ); @@ -195,6 +185,6 @@ DisplayFeaturedImageBlockObject.params = typeof DisplayFeaturedImageGenesisBlock === 'undefined' ? '' : DisplayFeaturedImageGenesisBlock; if ( typeof DisplayFeaturedImageBlockObject.params !== 'undefined' ) { - DisplayFeaturedImageBlockObject.init(); + DisplayFeaturedImageBlockObject.takeTwo( 'post-type' ); } } )( wp ); diff --git a/includes/js/block.min.js b/includes/js/block.min.js new file mode 100644 index 0000000..e396e57 --- /dev/null +++ b/includes/js/block.min.js @@ -0,0 +1 @@ +!function(e,t){"use strict";const n={el:e.element.createElement};n.takeTwo=function(t){const o=e.blocks.registerBlockType,l=e.components.ServerSideRender,i=e.blockEditor.InspectorControls,r=n.params[t];o(r.block,{title:r.title,description:r.description,keywords:r.keywords,icon:r.icon,category:r.category,supports:{html:!1},getEditWrapperProps:({blockAlignment:e})=>({"data-align":e}),edit:o=>{const{attributes:s,setAttributes:a}=o,c=e.element.Fragment,u=e.blockEditor.BlockControls,m=e.blockEditor.BlockAlignmentToolbar;return[n.el(l,{block:r.block,attributes:r.attributes}),n.el(c,null,n.el(u,null,n.el(m,{value:o.attributes.blockAlignment,controls:["wide","full"],onChange:e=>{a({blockAlignment:e})}}))),n.el(i,{},function(t,o){const l=[],i=e.components.PanelBody,r=n.params[o];return Object.keys(r.panels).forEach(function(o,s){if(r.panels.hasOwnProperty(o)){const a=r.panels[o];l[s]=n.el(i,{title:a.title,initialOpen:a.initialOpen},function(t,o){const l=[];return Object.keys(o).forEach(function(i,r){if(o.hasOwnProperty(i)){if(-1!==["blockAlignment","className"].indexOf(i))return;const s=o[i],a=function(t,n){const{TextControl:o,SelectControl:l,RangeControl:i,CheckboxControl:r,TextareaControl:s}=e.components,a=o;return"select"===t?l:"number"===t&&"number"===n?i:"checkbox"===t?r:"textarea"===t?s:a}(s.method,s.type);l[r]=n.el(a,function(e,t,n){const{attributes:o,setAttributes:l}=n,i={heading:t.heading,label:t.label,value:o[e],className:"displayfeaturedimagegenesis-"+e,onChange:t=>{l({[e]:t})}};return"select"===t.method?i.options=t.options:"number"===t.method?(i.min=t.min,i.max=t.max,"number"!==t.type?i.type="number":i.initialPosition=t.min):"checkbox"===t.method&&(i.checked=o[e]),i}(i,s,t))}}),l}(t,a.attributes))}}),l}(o,t))]},save:e=>null})},n.params="undefined"==typeof DisplayFeaturedImageGenesisBlock?"":DisplayFeaturedImageGenesisBlock,void 0!==n.params&&n.takeTwo("post-type")}(wp); \ No newline at end of file From f0451a1184f13d1ff844c0aa4a5513f83495aaaf Mon Sep 17 00:00:00 2001 From: Robin Cornett Date: Sun, 23 Jun 2019 16:46:24 -0400 Subject: [PATCH 03/44] Move get_post_types to form class --- ...splayfeaturedimagegenesis-widgets-form.php | 22 +++++++++++++++++++ ...eaturedimagegenesis-cpt-archive-widget.php | 22 ------------------- includes/widgets/fields/cpt-post_type.php | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/includes/widgets/class-displayfeaturedimagegenesis-widgets-form.php b/includes/widgets/class-displayfeaturedimagegenesis-widgets-form.php index 0d62a2b..5eb6898 100644 --- a/includes/widgets/class-displayfeaturedimagegenesis-widgets-form.php +++ b/includes/widgets/class-displayfeaturedimagegenesis-widgets-form.php @@ -26,6 +26,28 @@ class DisplayFeaturedImageGenesisWidgetsForm { $this->instance = $instance; } + /** + * Get the public registered post types on the site. + * + * @return mixed + */ + public function get_post_types() { + $args = array( + 'public' => true, + '_builtin' => false, + 'has_archive' => true, + ); + $output = 'objects'; + $post_types = get_post_types( $args, $output ); + + $options['post'] = __( 'Posts', 'display-featured-image-genesis' ); + foreach ( $post_types as $post_type ) { + $options[ $post_type->name ] = $post_type->label; + } + + return $options; + } + /** * @return array */ diff --git a/includes/widgets/displayfeaturedimagegenesis-cpt-archive-widget.php b/includes/widgets/displayfeaturedimagegenesis-cpt-archive-widget.php index e69da59..c6e2656 100644 --- a/includes/widgets/displayfeaturedimagegenesis-cpt-archive-widget.php +++ b/includes/widgets/displayfeaturedimagegenesis-cpt-archive-widget.php @@ -163,26 +163,4 @@ class Display_Featured_Image_Genesis_Widget_CPT extends WP_Widget { 'archive' => include 'fields/archive.php', ) ); } - - /** - * Get the public registered post types on the site. - * - * @return mixed - */ - protected function get_post_types() { - $args = array( - 'public' => true, - '_builtin' => false, - 'has_archive' => true, - ); - $output = 'objects'; - $post_types = get_post_types( $args, $output ); - - $options['post'] = __( 'Posts', 'display-featured-image-genesis' ); - foreach ( $post_types as $post_type ) { - $options[ $post_type->name ] = $post_type->label; - } - - return $options; - } } diff --git a/includes/widgets/fields/cpt-post_type.php b/includes/widgets/fields/cpt-post_type.php index cf0ab6f..99d567b 100644 --- a/includes/widgets/fields/cpt-post_type.php +++ b/includes/widgets/fields/cpt-post_type.php @@ -10,7 +10,7 @@ return array( 'id' => 'post_type', 'label' => __( 'Post Type:', 'display-featured-image-genesis' ), 'flex' => true, - 'choices' => $this->get_post_types(), + 'choices' => $form->get_post_types(), ), ), ); From 9c0cf4a12fd0ac022d259be75f3b2edbe04b24ab Mon Sep 17 00:00:00 2001 From: Robin Cornett Date: Sun, 23 Jun 2019 16:46:45 -0400 Subject: [PATCH 04/44] Move CPT defaults to new file --- ...playfeaturedimagegenesis-cpt-archive-widget.php | 13 +------------ includes/widgets/fields/cpt-defaults.php | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 includes/widgets/fields/cpt-defaults.php diff --git a/includes/widgets/displayfeaturedimagegenesis-cpt-archive-widget.php b/includes/widgets/displayfeaturedimagegenesis-cpt-archive-widget.php index c6e2656..7baab40 100644 --- a/includes/widgets/displayfeaturedimagegenesis-cpt-archive-widget.php +++ b/includes/widgets/displayfeaturedimagegenesis-cpt-archive-widget.php @@ -46,18 +46,7 @@ class Display_Featured_Image_Genesis_Widget_CPT extends WP_Widget { * @return array */ public function defaults() { - return array( - 'title' => '', - 'post_type' => 'post', - 'show_image' => 0, - 'image_alignment' => 'alignnone', - 'image_size' => 'medium', - 'show_title' => 0, - 'show_content' => 0, - 'custom_content' => '', - 'archive_link' => 0, - 'archive_link_text' => __( 'View Content Type Archive', 'display-featured-image-genesis' ), - ); + return include 'fields/cpt-defaults.php'; } /** diff --git a/includes/widgets/fields/cpt-defaults.php b/includes/widgets/fields/cpt-defaults.php new file mode 100644 index 0000000..9b41376 --- /dev/null +++ b/includes/widgets/fields/cpt-defaults.php @@ -0,0 +1,14 @@ + '', + 'post_type' => 'post', + 'show_image' => 0, + 'image_alignment' => 'alignnone', + 'image_size' => 'medium', + 'show_title' => 0, + 'show_content' => 0, + 'custom_content' => '', + 'archive_link' => 0, + 'archive_link_text' => __( 'View Content Type Archive', 'display-featured-image-genesis' ), +); From fde6e6c565847a2a07e6c99fdc7f37b01cd1da85 Mon Sep 17 00:00:00 2001 From: Robin Cornett Date: Sun, 23 Jun 2019 16:47:07 -0400 Subject: [PATCH 05/44] Create one working block (CPT) --- .../class-displayfeaturedimagegenesis.php | 9 +- includes/js/test-block.js | 190 +++++++++++++ includes/js/test-block.min.js | 1 + ...splayfeaturedimagegenesis-output-block.php | 257 ++++++++++++++++++ 4 files changed, 454 insertions(+), 3 deletions(-) create mode 100644 includes/js/test-block.js create mode 100644 includes/js/test-block.min.js create mode 100644 includes/widgets/class-displayfeaturedimagegenesis-output-block.php diff --git a/includes/class-displayfeaturedimagegenesis.php b/includes/class-displayfeaturedimagegenesis.php index 82fb952..5735ef6 100644 --- a/includes/class-displayfeaturedimagegenesis.php +++ b/includes/class-displayfeaturedimagegenesis.php @@ -254,9 +254,12 @@ class Display_Featured_Image_Genesis { if ( ! function_exists( 'register_block_type' ) ) { return; } - include_once 'blocks/class-displayfeaturedimagegenesis-blocks.php'; - $blocks = new DisplayFeaturedImageGenesisBlocks(); - $blocks->init(); +// include_once 'blocks/class-displayfeaturedimagegenesis-blocks.php'; +// $blocks = new DisplayFeaturedImageGenesisBlocks(); +// $blocks->init(); + include_once 'widgets/class-displayfeaturedimagegenesis-output-block.php'; + $block = new DisplayFeaturedImageGenesisOutputBlock(); + $block->init(); } /** diff --git a/includes/js/test-block.js b/includes/js/test-block.js new file mode 100644 index 0000000..44a97c3 --- /dev/null +++ b/includes/js/test-block.js @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2019 Robin Cornett + */ + +(function ( wp, undefined ) { + 'use strict'; + const DFIGBlockObject = { + el: wp.element.createElement, + }; + + /** + * Initialize and register the block. + */ + DFIGBlockObject.init = function ( params ) { + const registerBlockType = wp.blocks.registerBlockType, + ServerSideRender = wp.components.ServerSideRender, + InspectorControls = wp.editor.InspectorControls; + + registerBlockType( params.block, { + title: params.title, + description: params.description, + keywords: params.keywords, + icon: params.icon, + category: params.category, + supports: { + html: false + }, + + getEditWrapperProps( {blockAlignment} ) { + return {'data-align': blockAlignment}; + }, + + edit: props => { + const { + attributes, + setAttributes + } = props, + Fragment = wp.element.Fragment, + BlockControls = wp.editor.BlockControls, + BlockAlignmentToolbar = wp.editor.BlockAlignmentToolbar; + return [ + DFIGBlockObject.el( ServerSideRender, { + block: DFIGBlockObject.params.block, + attributes: attributes + } ), + DFIGBlockObject.el( Fragment, null, + DFIGBlockObject.el( BlockControls, null, + DFIGBlockObject.el( BlockAlignmentToolbar, { + value: attributes.blockAlignment, + controls: ['wide', 'full'], + onChange: ( value ) => { + setAttributes( {blockAlignment: value} ); + }, + } ) + ), + ), + DFIGBlockObject.el( InspectorControls, {}, + _getPanels( props ) + ) + ]; + }, + + save: props => { + return null; + }, + } ); + }; + + /** + * Get the panels for the block controls. + * + * @param props + * @return {Array} + * @private + */ + function _getPanels( props ) { + const panels = [], + PanelBody = wp.components.PanelBody; + Object.keys( DFIGBlockObject.params.panels ).forEach( function ( key, index ) { + if ( DFIGBlockObject.params.panels.hasOwnProperty( key ) ) { + const IndividualPanel = DFIGBlockObject.params.panels[key]; + panels[index] = DFIGBlockObject.el( PanelBody, { + title: IndividualPanel.title, + initialOpen: IndividualPanel.initialOpen, + className: 'scriptless-panel-' + key + }, _getControls( props, IndividualPanel.attributes ) ); + } + } ); + + return panels; + } + + /** + * Get all of the block controls, with defaults and options. + * + * @param props + * @param fields + * @return {Array} + * @private + */ + function _getControls( props, fields ) { + const controls = []; + Object.keys( fields ).forEach( function ( key, index ) { + if ( fields.hasOwnProperty( key ) ) { + var skipped = [ 'blockAlignment', 'className' ]; + if ( -1 !== skipped.indexOf( key ) ) { + return; + } + const IndividualField = fields[key], + control = _getControlType( IndividualField.method, IndividualField.type ); + controls[index] = DFIGBlockObject.el( control, _getIndividualControl( key, IndividualField, props ) ); + } + } ); + + return controls; + } + + /** + * Get the control type. + * @param method + * @param control_type + * @return {*} + * @private + */ + function _getControlType( method, control_type ) { + const { + TextControl, + SelectControl, + RangeControl, + CheckboxControl, + TextareaControl + } = wp.components; + const control = TextControl; + if ( 'select' === method ) { + return SelectControl; + } else if ( 'number' === method && 'number' === control_type ) { + return RangeControl; + } else if ( 'checkbox' === method ) { + return CheckboxControl; + } else if ( 'textarea' === method ) { + return TextareaControl; + } + + return control; + } + + /** + * Build the individual control object. Sets up standard properties for all + * controls; then adds custom properties as needed. + * + * @param key + * @param field + * @param props + * @return {{label: *, value: *, className: string, onChange: onChange}} + * @private + */ + function _getIndividualControl( key, field, props ) { + const {attributes, setAttributes} = props; + const control = { + label: field.label, + value: attributes[key], + className: 'displayfeaturedimagegenesis-' + key, + onChange: ( value ) => { + setAttributes( {[key]: value} ); + } + }; + + if ( 'select' === field.method ) { + control.options = field.options; + } else if ( 'number' === field.method ) { + control.min = field.min; + control.max = field.max; + if ( 'number' !== field.type ) { + control.type = 'number'; + } else { + control.initialPosition = field.min; + } + } else if ( 'checkbox' === field.method ) { + control.checked = attributes[key]; + } + + return control; + } + + DFIGBlockObject.params = typeof DisplayFeaturedImageTestBlock === 'undefined' ? '' : DisplayFeaturedImageTestBlock; + + if ( typeof DFIGBlockObject.params !== 'undefined' ) { + DFIGBlockObject.init( DFIGBlockObject.params ); + } +} )( wp ); diff --git a/includes/js/test-block.min.js b/includes/js/test-block.min.js new file mode 100644 index 0000000..34bbd44 --- /dev/null +++ b/includes/js/test-block.min.js @@ -0,0 +1 @@ +!function(e,t){"use strict";const n={el:e.element.createElement};n.init=function(t){const o=e.blocks.registerBlockType,l=e.components.ServerSideRender,r=e.editor.InspectorControls;o(t.block,{title:t.title,description:t.description,keywords:t.keywords,icon:t.icon,category:t.category,supports:{html:!1},getEditWrapperProps:({blockAlignment:e})=>({"data-align":e}),edit:t=>{const{attributes:o,setAttributes:i}=t,s=e.element.Fragment,a=e.editor.BlockControls,c=e.editor.BlockAlignmentToolbar;return[n.el(l,{block:n.params.block,attributes:o}),n.el(s,null,n.el(a,null,n.el(c,{value:o.blockAlignment,controls:["wide","full"],onChange:e=>{i({blockAlignment:e})}}))),n.el(r,{},function(t){const o=[],l=e.components.PanelBody;return Object.keys(n.params.panels).forEach(function(r,i){if(n.params.panels.hasOwnProperty(r)){const s=n.params.panels[r];o[i]=n.el(l,{title:s.title,initialOpen:s.initialOpen,className:"scriptless-panel-"+r},function(t,o){const l=[];return Object.keys(o).forEach(function(r,i){if(o.hasOwnProperty(r)){if(-1!==["blockAlignment","className"].indexOf(r))return;const s=o[r],a=function(t,n){const{TextControl:o,SelectControl:l,RangeControl:r,CheckboxControl:i,TextareaControl:s}=e.components,a=o;return"select"===t?l:"number"===t&&"number"===n?r:"checkbox"===t?i:"textarea"===t?s:a}(s.method,s.type);l[i]=n.el(a,function(e,t,n){const{attributes:o,setAttributes:l}=n,r={label:t.label,value:o[e],className:"displayfeaturedimagegenesis-"+e,onChange:t=>{l({[e]:t})}};return"select"===t.method?r.options=t.options:"number"===t.method?(r.min=t.min,r.max=t.max,"number"!==t.type?r.type="number":r.initialPosition=t.min):"checkbox"===t.method&&(r.checked=o[e]),r}(r,s,t))}}),l}(t,s.attributes))}}),o}(t))]},save:e=>null})},n.params="undefined"==typeof DisplayFeaturedImageTestBlock?"":DisplayFeaturedImageTestBlock,void 0!==n.params&&n.init(n.params)}(wp); \ No newline at end of file diff --git a/includes/widgets/class-displayfeaturedimagegenesis-output-block.php b/includes/widgets/class-displayfeaturedimagegenesis-output-block.php new file mode 100644 index 0000000..8139b21 --- /dev/null +++ b/includes/widgets/class-displayfeaturedimagegenesis-output-block.php @@ -0,0 +1,257 @@ +register_script_style(); + register_block_type( + $this->name, + array( + 'editor_script' => $this->block . '-block', + 'attributes' => $this->fields(), + 'render_callback' => array( $this, 'render' ), + ) + ); + add_action( 'enqueue_block_editor_assets', array( $this, 'localize' ) ); + } + + /** + * Render the widget in a container div. + * + * @param $atts + * + * @return string + */ + public function render( $atts ) { + $atts = wp_parse_args( $atts, include 'fields/cpt-defaults.php' ); + $post_type = get_post_type_object( $atts['post_type'] ); + if ( ! $post_type ) { + return ''; + } + + $classes = $this->get_block_classes( $atts ); + include plugin_dir_path( dirname( __FILE__ ) ) . 'output/class-displayfeaturedimagegenesis-output-cpt.php'; + $output = '
'; + ob_start(); + new DisplayFeaturedImageGenesisOutputCPT( $atts, array(), $post_type ); + $output .= ob_get_contents(); + ob_clean(); + $output .= '
'; + + return $output; + } + + /** + * Get the CSS classes for the block. + * @param $atts + * + * @return array + */ + private function get_block_classes( $atts ) { + array( + 'wp-block-' . $this->block, + ); + if ( ! empty( $atts['className'] ) ) { + $classes[] = $atts['className']; + } + if ( ! empty( $atts['blockAlignment'] ) ) { + $classes[] = 'align' . $atts['blockAlignment']; + } + + return $classes; + } + + /** + * Register the block script and style. + */ + public function register_script_style() { + $minify = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : ' . min'; + $version = '3.2.0'; + if ( ! $minify ) { + $version .= current_time( 'gmt' ); + } + wp_register_script( + $this->block . '-block', + plugin_dir_url( dirname( __FILE__ ) ) . "js/test-block{$minify}.js", + array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-editor' ), + $version, + false + ); + } + + /** + * Localize. + */ + public function localize() { + wp_localize_script( $this->block . '-block', 'DisplayFeaturedImageTestBlock', $this->get_localization_data() ); + } + + /** + * Get the data for localizing everything. + * @return array + */ + protected function get_localization_data() { + return array( + 'block' => $this->name, + 'title' => __( 'Display Featured Image Genesis Post Type', 'scriptless-social-sharing' ), + 'description' => __( 'featured image.', 'scriptless-social-sharing' ), + 'keywords' => array( + __( 'image', 'scriptless-social-sharing' ), + __( 'featured', 'scriptless-social-sharing' ), + ), + 'panels' => array( + 'main' => array( + 'title' => __( 'Block Settings', 'scriptless-social-sharing' ), + 'initialOpen' => true, + 'attributes' => $this->fields(), + ), + ), + 'icon' => 'format-image', + 'category' => 'widgets', + ); + } + + /** + * Get the fields for the block. + * @return array + */ + private function fields() { + $output = array(); + foreach ( $this->get_all_fields() as $key => $value ) { + if ( ! empty( $value['args']['id'] ) ) { + $key = $value['args']['id']; + } + $output[ $key ] = $this->get_individual_field_attributes( $value ); + } + + return $output; + } + + private function get_all_fields() { + $form = new DisplayFeaturedImageGenesisWidgetsForm( $this, array() ); + $fields = array_merge( + include 'fields/cpt-post_type.php', + include 'fields/text.php', + include 'fields/image.php', + include 'fields/archive.php' + ); + $attributes = array_merge( + array( + 'blockAlignment' => array( + 'type' => 'string', + 'default' => '', + ), + 'className' => array( + 'type' => 'string', + 'default' => '', + ), + 'title' => array( + 'type' => 'string', + 'default' => '', + 'args' => array( + 'id' => 'title', + 'label' => 'Title', + ), + ), + ), + $fields + ); + + return $attributes; + } + + /** + * Get an array of attributes for an individual field. + * + * @param $field + * + * @return array + */ + protected function get_individual_field_attributes( $field ) { + $method = empty( $field['method'] ) ? 'text' : $field['method']; + $field_type = $this->get_field_type( $method ); + if ( empty( $field['args']['label'] ) ) { + return $field; + } + $defaults = include 'fields/cpt-defaults.php'; + $attributes = array( + 'type' => $field_type, + 'default' => $defaults[ $field['args']['id'] ], + 'label' => $field['args']['label'], + 'method' => $method, + ); + if ( in_array( 'number', array( $field_type, $method ), true ) ) { + $attributes['min'] = $field['args']['min']; + $attributes['max'] = $field['args']['max']; + } elseif ( 'select' === $method ) { + $attributes['options'] = $this->convert_choices_for_select( $field['args']['choices'] ); + } + + return $attributes; + } + + /** + * Define the type of field for our script. + * + * @param $method + * + * @return string + */ + private function get_field_type( $method ) { + $type = 'string'; + if ( 'number' === $method ) { + return $method; + } + if ( 'checkbox' === $method ) { + return 'boolean'; + } + + return $type; + } + + /** + * Convert a standard PHP array to what the block editor needs. + * + * @param $options + * + * @return array + */ + private function convert_choices_for_select( $options ) { + $output = array(); + foreach ( $options as $value => $label ) { + $output[] = array( + 'value' => $value, + 'label' => $label, + ); + } + + return $output; + } +} From cd681a4916f75ce8f4088dd1e9deb8457d934c3b Mon Sep 17 00:00:00 2001 From: Robin Cornett Date: Sun, 23 Jun 2019 16:53:51 -0400 Subject: [PATCH 06/44] Re-minimize backstretch script --- includes/js/backstretch.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/js/backstretch.min.js b/includes/js/backstretch.min.js index e1cbf36..bddc53d 100644 --- a/includes/js/backstretch.min.js +++ b/includes/js/backstretch.min.js @@ -1 +1 @@ -/*! Backstretch - v2.1.15 - 2017-06-22\n* Copyright (c) 2017 Scott Robbin;* Fork of improvements - by Daniel Cohen Gindi (danielgindi@gmail.com) Licensed MIT */!function(a,b,c){"use strict";function d(a){return m.hasOwnProperty(a)?a:"cover"}var e=/^.*(youtu\.be\/|youtube\.com\/v\/|youtube\.com\/embed\/|youtube\.com\/watch\?v=|youtube\.com\/watch\?.*\&v=)([^#\&\?]*).*/i;a.fn.backstretch=function(d,e){var f=arguments;0===a(b).scrollTop()&&b.scrollTo(0,0);var g;return this.each(function(b){var h=a(this),i=h.data("backstretch");if(i){if("string"==typeof f[0]&&"function"==typeof i[f[0]]){var j=i[f[0]].apply(i,Array.prototype.slice.call(f,1));return j===i&&(j=c),void(j!==c&&(g=g||[],g[b]=j))}e=a.extend(i.options,e),i.hasOwnProperty("destroy")&&i.destroy(!0)}if(!d||d&&0===d.length){var k=h.css("background-image");k&&"none"!==k?d=[{url:h.css("backgroundImage").replace(/url\(|\)|"|'/g,"")}]:a.error("No images were supplied for Backstretch, or element must have a CSS-defined background image.")}i=new n(this,d,e||{}),h.data("backstretch",i)}),g?1===g.length?g[0]:g:this},a.backstretch=function(b,c){return a("body").backstretch(b,c).data("backstretch")},a.expr[":"].backstretch=function(b){return a(b).data("backstretch")!==c},a.fn.backstretch.defaults={duration:5e3,transition:"fade",transitionDuration:0,animateFirst:!0,alignX:.5,alignY:.5,paused:!1,start:0,preload:2,preloadSize:1,resolutionRefreshRate:2500,resolutionChangeRatioThreshold:.1};var f={wrap:{left:0,top:0,overflow:"hidden",margin:0,padding:0,height:"100%",width:"100%",zIndex:-999999},itemWrapper:{position:"absolute",display:"none",margin:0,padding:0,border:"none",width:"100%",height:"100%",zIndex:-999999},item:{position:"absolute",margin:0,padding:0,border:"none",width:"100%",height:"100%",maxWidth:"none"}},g=function(){var c=function(a){for(var b=1;bparseInt(c.width,10);)a[d]=a[d-1],--d;a[d]=c}return a},d=function(a,c,d){for(var e,f,g=b.devicePixelRatio||1,h=q(),i=(r(),c>a?"portrait":a>c?"landscape":"square"),j=0,k=0;k=e)));k++);return d[Math.min(k,j)]},e=function(a,b){if("string"==typeof a)a=a.replace(/{{(width|height)}}/g,b);else if(a instanceof Array)for(var c=0;c=c.length&&(d=0,e=0),f<0&&(f=e),f=Math.min(f,e);var k=c.slice(d+f,e-f);if(c=c.slice(d,f),e=c.length,!e)return void j(c,g,!0);for(var l,m=0,n=function(){m++,m===e&&(j(c,g,!k),b(k,0,0,f,g))},o=0;o=this.images.length&&(this.options.start=this.images.length-1),this.options.start<0&&(this.options.start=0),this.isBody=c===document.body;var h=a(b);this.$container=a(c),this.$root=this.isBody?s?h:a(document):this.$container,this.originalImages=this.images,this.images=g(this.options.alwaysTestWindowResolution?h:this.$root,this.originalImages),i(this.images,this.options.start||0,this.options.preload||1);var l=this.$container.children(".backstretch").first();if(this.$wrap=l.length?l:a('
').css(this.options.bypassCss?{}:f.wrap).appendTo(this.$container),!this.options.bypassCss){if(!this.isBody){var m=this.$container.css("position"),n=this.$container.css("zIndex");this.$container.css({position:"static"===m?"relative":m,zIndex:"auto"===n?0:n}),this.$wrap.css({zIndex:-999998})}this.$wrap.css({position:this.isBody&&s?"fixed":"absolute"})}this.index=this.options.start,this.show(this.index),h.on("resize.backstretch",a.proxy(this.resize,this)).on("orientationchange.backstretch",a.proxy(function(){this.isBody&&0===b.pageYOffset&&(b.scrollTo(0,1),this.resize())},this))},o=function(b){var d=b.transition||"fade";"string"==typeof d&&d.indexOf("|")>-1&&(d=d.split("|")),d instanceof Array&&(d=d[Math.round(Math.random()*(d.length-1))]);var e=b.new,f=b.old?b.old:a([]);switch(d.toString().toLowerCase()){default:case"fade":e.fadeIn({duration:b.duration,complete:b.complete,easing:b.easing||c});break;case"fadeinout":case"fade_in_out":var g=function(){e.fadeIn({duration:b.duration/2,complete:b.complete,easing:b.easing||c})};f.length?f.fadeOut({duration:b.duration/2,complete:g,easing:b.easing||c}):g();break;case"pushleft":case"push_left":case"pushright":case"push_right":case"pushup":case"push_up":case"pushdown":case"push_down":case"coverleft":case"cover_left":case"coverright":case"cover_right":case"coverup":case"cover_up":case"coverdown":case"cover_down":var h=d.match(/^(cover|push)_?(.*)$/),i="left"===h[2]?"right":"right"===h[2]?"left":"down"===h[2]?"top":"up"===h[2]?"bottom":"right",j={display:""},k={};if(j[i]="-100%",k[i]=0,e.css(j).animate(k,{duration:b.duration,complete:function(){e.css(i,""),b.complete.apply(this,arguments)},easing:b.easing||c}),"push"===h[1]&&f.length){var l={};l[i]="100%",f.animate(l,{duration:b.duration,complete:function(){f.css("display","none")},easing:b.easing||c})}}};n.prototype={resize:function(){try{var e=this.options.alwaysTestWindowResolution?a(b):this.$root,f=e.width(),h=e.height(),j=f/(this._lastResizeContainerWidth||0),k=h/(this._lastResizeContainerHeight||0),l=this.options.resolutionChangeRatioThreshold||0;if((f!==this._lastResizeContainerWidth||h!==this._lastResizeContainerHeight)&&(Math.abs(j-1)>=l||isNaN(j)||Math.abs(k-1)>=l||isNaN(k))&&(this._lastResizeContainerWidth=f,this._lastResizeContainerHeight=h,this.images=g(e,this.originalImages),this.options.preload&&i(this.images,(this.index+1)%this.images.length,this.options.preload),1===this.images.length&&this._currentImage.url!==this.images[0].url)){var m=this;clearTimeout(m._selectAnotherResolutionTimeout),m._selectAnotherResolutionTimeout=setTimeout(function(){m.show(0)},this.options.resolutionRefreshRate)}var n,o,p={left:0,top:0,right:"auto",bottom:"auto"},q=this.isBody?this.$root.width():this.$root.innerWidth(),r=this.isBody?b.innerHeight?b.innerHeight:this.$root.height():this.$root.innerHeight(),s=this.$itemWrapper.data("width"),t=this.$itemWrapper.data("height"),u=s/t||1,v=this._currentImage.alignX===c?this.options.alignX:this._currentImage.alignX,w=this._currentImage.alignY===c?this.options.alignY:this._currentImage.alignY,x=d(this._currentImage.scale||this.options.scale);if("fit"===x||"fit-smaller"===x){if(n=s,o=t,n>q||o>r||"fit-smaller"===x){var y=q/r;y>u?(n=Math.floor(r*u),o=r):y.backstretch-item").not(".deleteable").each(function(){var b=a(this);b.find("img,video,iframe").css(p)});var z=a.Event("backstretch.resize",{relatedTarget:this.$container[0]});this.$container.trigger(z,this)}catch(a){}return this},show:function(b,d){if(!(Math.abs(b)>this.images.length-1)){var e=this,g=e.$wrap.find(">.backstretch-item").addClass("deleteable"),i=e.videoWrapper,j={relatedTarget:e.$container[0]};e.$container.trigger(a.Event("backstretch.before",j),[e,b]),this.index=b;var k=e.images[b];clearTimeout(e._cycleTimeout),delete e.videoWrapper;var l=h(k);return l?(e.videoWrapper=new p(k),e.$item=e.videoWrapper.$video.css("pointer-events","none")):e.$item=a(""),e.$itemWrapper=a('
').append(e.$item),this.options.bypassCss?e.$itemWrapper.css({display:"none"}):(e.$itemWrapper.css(f.itemWrapper),e.$item.css(f.item)),e.$item.bind(l?"canplay":"load",function(f){var h=a(this),k=h.parent(),m=k.data("options");d&&(m=a.extend({},m,d));var n=this.naturalWidth||this.videoWidth||this.width,p=this.naturalHeight||this.videoHeight||this.height;k.data("width",n).data("height",p);var q=function(a){return m[a]!==c?m[a]:e.options[a]},r=q("transition"),s=q("transitionEasing"),t=q("transitionDuration"),u=function(){i&&(i.stop(),i.destroy()),g.remove(),!e.paused&&e.images.length>1&&e.cycle(),e.options.bypassCss||e.isBody||e.$container.css("background-image","none"),a(["after","show"]).each(function(){e.$container.trigger(a.Event("backstretch."+this,j),[e,b])}),l&&e.videoWrapper.play()};e.firstShow&&!e.options.animateFirst||!t||!r?(k.show(),u()):o({new:k,old:g,transition:r,duration:t,easing:s,complete:u}),e.firstShow=!1,e.resize()}),e.$itemWrapper.appendTo(e.$wrap),e.$item.attr("alt",k.alt||""),e.$itemWrapper.data("options",k),l||e.$item.attr("src",k.url),e._currentImage=k,e}},current:function(){return this.index},next:function(){var a=Array.prototype.slice.call(arguments,0);return a.unshift(this.index1){clearTimeout(this._cycleTimeout);var b=this._currentImage&&this._currentImage.duration||this.options.duration,c=h(this._currentImage),d=function(){this.$item.off(".cycle"),this.paused||this.next()};if(c){if(!this._currentImage.loop){var e=0;this.$item.on("playing.cycle",function(){var b=a(this).data("player");clearTimeout(e),e=setTimeout(function(){b.pause(),b.$video.trigger("ended")},1e3*(b.getDuration()-b.getCurrentTime()))}).on("ended.cycle",function(){clearTimeout(e)})}this.$item.on("error.cycle initerror.cycle",a.proxy(d,this))}c&&!this._currentImage.duration?this.$item.on("ended.cycle",a.proxy(d,this)):this._cycleTimeout=setTimeout(a.proxy(d,this),b)}return this},destroy:function(c){a(b).off("resize.backstretch orientationchange.backstretch"),this.videoWrapper&&this.videoWrapper.destroy(),clearTimeout(this._cycleTimeout),c||this.$wrap.remove(),this.$container.removeData("backstretch")}};var p=function(){this.init.apply(this,arguments)};p.prototype.init=function(d){var f,g=this,h=function(){g.$video=f,g.video=f[0]},i="video";if(d.url instanceof Array||!e.test(d.url)||(i="youtube"),g.type=i,"youtube"===i){p.loadYoutubeAPI(),g.ytId=d.url.match(e)[2];var j="https://www.youtube.com/embed/"+g.ytId+"?rel=0&autoplay=0&showinfo=0&controls=0&modestbranding=1&cc_load_policy=0&disablekb=1&iv_load_policy=3&loop=0&enablejsapi=1&origin="+encodeURIComponent(b.location.origin);g.__ytStartMuted=!!d.mute||d.mute===c,f=a("