Your IP : 216.73.216.50


Current Path : /proc/1908984/root/proc/self/root/proc/self/root/proc/2411249/cwd/
Upload File :
Current File : //proc/1908984/root/proc/self/root/proc/self/root/proc/2411249/cwd/Renderable.tar

AbstractRenderable.php000064400000010033152356645660011023 0ustar00<?php

namespace Nextend\SmartSlider3\Renderable;

use Nextend\Framework\Font\FontParser;
use Nextend\Framework\Font\FontRenderer;
use Nextend\Framework\Style\StyleParser;
use Nextend\Framework\Style\StyleRenderer;
use Nextend\SmartSlider3\Slider\FeatureManager;

abstract class AbstractRenderable {

    public $isAdmin = false;

    public $less = array();
    public $css = array();

    public $cssDevice = array(
        'all'              => array(),
        'desktoplandscape' => array(),
        'desktopportrait'  => array(),
        'tabletlandscape'  => array(),
        'tabletportrait'   => array(),
        'mobilelandscape'  => array(),
        'mobileportrait'   => array(),

    );

    public $elementId = '';

    public $fontSize = 16;

    protected $images = array();

    private $fontCache = array();

    private $styleCache = array();

    public $initCallbacks = array();
    public $addedScriptResources = array();

    /**
     * @var FeatureManager
     */
    public $features;

    public function addLess($file, $context) {
        $this->less[$file] = $context;
    }

    public function addCSS($css) {
        $this->css[] = $css;
    }

    public function addDeviceCSS($device, $css) {
        $this->cssDevice[$device][] = $css;
    }

    public function getSelector() {

        return 'div#' . $this->elementId . ' ';
    }

    private function _addFontCache($font, $mode, $pre, $fontSize) {
        $cacheKey = md5($font . $mode . $pre . $fontSize);
        if (!isset($this->fontCache[$cacheKey])) {
            $fontData = FontRenderer::render($font, $mode, $pre, $fontSize);
            if ($fontData) {
                $this->addCSS($fontData[1]);

                $this->fontCache[$cacheKey] = $fontData[0];
            } else {
                $this->fontCache[$cacheKey] = '';
            }
        }

        return $this->fontCache[$cacheKey];
    }

    public function addFont($font, $mode, $pre = null) {

        $font = FontParser::parse($font);

        if ($this->isAdmin) {
            $fontData = FontRenderer::render($font, $mode, $pre == null ? $this->getSelector() : $pre, $this->fontSize);
            if ($fontData) {
                $this->addCSS($fontData[1]);

                return $fontData[0];
            }

            return '';
        }

        return $this->_addFontCache($font, $mode, $pre == null ? $this->getSelector() : $pre, $this->fontSize);
    }


    private function _addStyleCache($style, $mode, $pre) {
        $cacheKey = md5($style . $mode . $pre);
        if (!isset($this->styleCache[$cacheKey])) {
            $styleData = StyleRenderer::render($style, $mode, $pre);
            if ($styleData) {
                $this->addCSS($styleData[1]);

                $this->styleCache[$cacheKey] = $styleData[0];
            } else {
                $this->styleCache[$cacheKey] = '';
            }
        }

        return $this->styleCache[$cacheKey];
    }

    public function addStyle($style, $mode, $pre = null) {

        $style = StyleParser::parse($style);

        if ($this->isAdmin) {
            $styleData = StyleRenderer::render($style, $mode, $pre == null ? $this->getSelector() : $pre);
            if ($styleData) {
                $this->addCSS($styleData[1]);

                return $styleData[0];
            }

            return '';
        }

        return $this->_addStyleCache($style, $mode, $pre == null ? $this->getSelector() : $pre);
    }

    public function addScript($script, $name = false) {
        if ($name !== false) {
            $this->addedScriptResources[] = $name;
        }
        $this->initCallbacks[] = $script;

    }

    public function isScriptAdded($name) {
        return in_array($name, $this->addedScriptResources);
    }

    public function addImage($imageUrl) {
        $this->images[] = $imageUrl;
    }

    public function getImages() {
        return $this->images;
    }

    public abstract function render();
}AbstractRenderableOwner.php000064400000006122152356645660012042 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable;


use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Component\ComponentCol;
use Nextend\SmartSlider3\Renderable\Component\ComponentContent;
use Nextend\SmartSlider3\Renderable\Component\ComponentLayer;
use Nextend\SmartSlider3\Renderable\Component\ComponentRow;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

abstract class AbstractRenderableOwner {

    public $underEdit = false;

    /**
     * @var AbstractRenderable
     */
    protected $renderable;

    /** @var string Used for generators when multiple slides might contain the same unique class */
    public $unique = '';

    /**
     * @return AbstractRenderable
     */
    public function getRenderable() {
        return $this->renderable;
    }

    public abstract function getElementID();

    public function isComponentVisible($generatorVisibleVariable) {
        return true;
    }

    public function fill($value) {
        return $value;
    }

    public function fillLayers(&$layers) {
        for ($i = 0; $i < count($layers); $i++) {
            if (isset($layers[$i]['type'])) {
                switch ($layers[$i]['type']) {
                    case 'slide':
                        $this->fillLayers($layers[$i]['layers']);
                        break;
                    case 'content':
                        ComponentContent::getFilled($this, $layers[$i]);
                        break;
                    case 'row':
                        ComponentRow::getFilled($this, $layers[$i]);
                        break;
                    case 'col':
                        ComponentCol::getFilled($this, $layers[$i]);
                        break;
                    case 'group':
                        $this->fillLayers($layers[$i]['layers']);
                        break;
                    default:
                        ComponentLayer::getFilled($this, $layers[$i]);
                }
            } else {
                ComponentLayer::getFilled($this, $layers[$i]);
            }
        }
    }

    public function isLazyLoadingEnabled() {
        return false;
    }

    /**
     * @param AbstractItemFrontend $item
     * @param                      $src
     * @param array                $attributes
     *
     * @return string
     */
    public function renderImage($item, $src, $attributes = array(), $pictureAttributes = array()) {

        return Html::image($src, $attributes);
    }

    public abstract function addScript($script, $name = false);

    public abstract function isScriptAdded($name);

    public abstract function addLess($file, $context);

    public abstract function addCSS($css);

    public abstract function addDeviceCSS($device, $css);

    public abstract function addFont($font, $mode, $pre = null);

    public abstract function addStyle($style, $mode, $pre = null);

    public abstract function addImage($imageUrl);

    public abstract function isAdmin();

    public abstract function getAvailableDevices();
}ComponentContainer.php000064400000010706152356645660011110 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable;


use Exception;
use Nextend\Framework\Notification\Notification;
use Nextend\SmartSlider3\Renderable\Component\AbstractComponent;
use Nextend\SmartSlider3\Renderable\Component\ComponentCol;
use Nextend\SmartSlider3\Renderable\Component\ComponentContent;
use Nextend\SmartSlider3\Renderable\Component\ComponentLayer;
use Nextend\SmartSlider3\Renderable\Component\ComponentRow;
use Nextend\SmartSlider3\Slider\Slide;

class ComponentContainer {

    /** @var AbstractComponent[] */
    protected $layers = array();

    protected $index = 0;

    /** @var Slide */
    protected $slide;

    /** @var AbstractComponent */
    protected $component;

    /**
     *
     * @param Slide             $slide
     * @param AbstractComponent $component
     * @param array             $componentsData
     */
    public function __construct($slide, $component, $componentsData) {
        $this->slide     = $slide;
        $this->component = $component;

        if (is_array($componentsData)) {

            if ($component->getType() == 'slide') {
                $componentsData = array_reverse($componentsData);
            }

            foreach ($componentsData as $componentData) {
                $this->addComponent($componentData);
            }
        }
    }

    private function addComponent($componentData) {
        $this->index++;
        if (!isset($componentData['type'])) {
            $componentData['type'] = 'layer';
        }
        switch ($componentData['type']) {
            case 'content':
                $this->layers[] = new ComponentContent($this->index, $this->slide, $this->component, $componentData);
                break;
            case 'row':
                $this->layers[] = new ComponentRow($this->index, $this->slide, $this->component, $componentData);
                break;
            case 'col':
                $this->layers[] = new ComponentCol($this->index, $this->slide, $this->component, $componentData);
                break;
            case 'layer':
                try {
                    if (empty($componentData['item'])) {
                        if (empty($componentData['items'])) {
                            $this->index--;
                            break;
                        }
                        $componentData['item'] = $componentData['items'][0];
                    }

                    $layer          = new ComponentLayer($this->index, $this->slide, $this->component, $componentData);
                    $this->layers[] = $layer;

                } catch (Exception $e) {
                    $this->index--;
                    Notification::error($e->getMessage());
                }
                break;
            case 'group':
                $componentData['layers'] = array_reverse($componentData['layers']);
                foreach ($componentData['layers'] as $subComponentData) {
                    $this->addComponent($subComponentData);
                }
                break;

        }
    }

    public function addContentLayer($slide, $component) {
        $content    = false;
        $layerCount = count($this->layers);
        for ($i = 0; $i < $layerCount; $i++) {
            if ($this->layers[$i] instanceof ComponentContent) {
                $content = $this->layers[$i];
                break;
            }
        }

        if ($content === false) {
            array_unshift($this->layers, new ComponentContent($layerCount + 1, $slide, $component, array(
                'bgimage'                   => '',
                'bgimagex'                  => 50,
                'bgimagey'                  => 50,
                'bgcolor'                   => '00000000',
                'bgcolorgradient'           => 'off',
                'verticalalign'             => 'center',
                'desktopportraitinneralign' => 'inherit',
                'desktopportraitpadding'    => '10|*|10|*|10|*|10|*|px',
                'layers'                    => array()
            ), 'absolute'));
        }

        return $content;
    }

    /**
     * @return AbstractComponent[]
     */
    public function getLayers() {
        return $this->layers;
    }

    public function render($isAdmin) {
        $html = '';
        foreach ($this->layers as $layer) {
            $html .= $layer->render($isAdmin);
        }

        return $html;
    }
}Placement/AbstractPlacement.php000064400000001440152356645660012602 0ustar00<?php

namespace Nextend\SmartSlider3\Renderable\Placement;

use Nextend\SmartSlider3\Renderable\Component\AbstractComponent;

abstract class AbstractPlacement {

    /** @var  AbstractComponent */
    protected $component;

    protected $index = 1;

    protected $style = '';
    protected $attributes = '';

    /**
     *
     * @param AbstractComponent $component
     * @param int               $index
     */
    public function __construct($component, $index) {
        $this->component = $component;
        $this->index     = $index;
    }

    /**
     * @param array $attributes
     */
    public function attributes(&$attributes) {

    }

    /**
     * @param array $attributes
     */
    public function adminAttributes(&$attributes) {
    }
}Placement/PlacementAbsolute.php000064400000002657152356645660012630 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Placement;


class PlacementAbsolute extends AbstractPlacement {

    public function attributes(&$attributes) {
        $data = $this->component->data;

        $attributes['data-pm'] = 'absolute';

        $this->component->createProperty('responsiveposition', 1);

        $this->component->createDeviceProperty('left', 0);
        $this->component->createDeviceProperty('top', 0);

        $this->component->createProperty('responsivesize', 1);

        $this->component->createDeviceProperty('width');
        $this->component->createDeviceProperty('height');

        $this->component->createDeviceProperty('align');
        $this->component->createDeviceProperty('valign');

        // Chain
        $attributes['data-parentid'] = $data->get('parentid');
        $this->component->createDeviceProperty('parentalign');
        $this->component->createDeviceProperty('parentvalign');

        $isLegacyFontScale = $this->component->getOwner()
                                             ->getSlider()
                                             ->isLegacyFontScale();
        if ($isLegacyFontScale) {
            $adaptiveFont = intval($data->get('adaptivefont', 1));
            if ($adaptiveFont === 0) {
                $attributes['data-adaptivefont'] = 0;
            }
        }
    }

    public function adminAttributes(&$attributes) {

    }
}Placement/PlacementDefault.php000064400000000342152356645660012423 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Placement;


class PlacementDefault extends AbstractPlacement {

    public function attributes(&$attributes) {

        $attributes['data-pm'] = 'default';
    }
}Placement/PlacementNormal.php000064400000007622152356645660012277 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Placement;


use Nextend\SmartSlider3\Renderable\Component\AbstractComponent;

class PlacementNormal extends AbstractPlacement {

    public function attributes(&$attributes) {
        $data = $this->component->data;

        $attributes['data-pm'] = 'normal';


        $devices = $this->component->getOwner()
                                   ->getAvailableDevices();

        $desktopPortraitSelfAlign = $data->get('desktopportraitselfalign', 'inherit');
        $desktopPortraitMaxWidth  = intval($data->get('desktopportraitmaxwidth', 0));
        $desktopPortraitHeight    = $data->get('desktopportraitheight', 0);
        $desktopPortraitMargin    = $data->get('desktopportraitmargin');
        if (!empty($desktopPortraitMargin)) {
            $desktopPortraitMargin = $this->component->spacingToPxValue($desktopPortraitMargin);
        } else {
            $desktopPortraitMargin = array(
                0,
                0,
                0,
                0
            );
        }

        foreach ($devices as $device) {
            $margin = $data->get($device . 'margin');
            if (!empty($margin)) {
                $marginValues = $this->component->spacingToPxValue($margin);

                $cssText = array();
                if (($marginValues[0] == 0 && $desktopPortraitMargin[0] != 0) || $marginValues[0] != 0) {
                    $cssText[] = '--margin-top:' . $marginValues[0] . 'px';
                }
                if (($marginValues[1] == 0 && $desktopPortraitMargin[1] != 0) || $marginValues[1] != 0) {
                    $cssText[] = '--margin-right:' . $marginValues[1] . 'px';
                }
                if (($marginValues[2] == 0 && $desktopPortraitMargin[2] != 0) || $marginValues[2] != 0) {
                    $cssText[] = '--margin-bottom:' . $marginValues[2] . 'px';
                }
                if (($marginValues[3] == 0 && $desktopPortraitMargin[3] != 0) || $marginValues[3] != 0) {
                    $cssText[] = '--margin-left:' . $marginValues[3] . 'px';
                }

                $this->component->style->add($device, '', implode(';', $cssText));
            }

            $height = $data->get($device . 'height');
            if ($height === 0 || !empty($height)) {
                if ($height == 0) {
                    if ($desktopPortraitHeight > 0) {
                        $this->component->style->add($device, '', 'height:auto');
                    }
                } else {
                    $this->component->style->add($device, '', 'height:' . $height . 'px');
                }
            }

            $maxWidth = intval($data->get($device . 'maxwidth', -1));
            if ($maxWidth > 0) {
                $this->component->style->add($device, '', 'max-width:' . $maxWidth . 'px');
            } else if ($maxWidth === 0 && $device != 'desktopportrait' && $maxWidth != $desktopPortraitMaxWidth) {
                $this->component->style->add($device, '', 'max-width:none');
            }


            $selfAlign = $data->get($device . 'selfalign', '');

            if ($device == 'desktopportrait') {
                if ($desktopPortraitSelfAlign != 'inherit') {
                    $this->component->style->add($device, '', AbstractComponent::selfAlignToStyle($selfAlign));
                }
            } else if ($desktopPortraitSelfAlign != $selfAlign) {
                $this->component->style->add($device, '', AbstractComponent::selfAlignToStyle($selfAlign));
            }
        }

    }

    public function adminAttributes(&$attributes) {

        $this->component->createDeviceProperty('maxwidth', 0);
        $this->component->createDeviceProperty('margin', '0|*|0|*|0|*|0');
        $this->component->createDeviceProperty('height', 0);
        $this->component->createDeviceProperty('selfalign', 'inherit');
    }
}Item/AbstractItem.php000064400000012507152356645660010564 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Font\FontParser;
use Nextend\Framework\Form\ContainerInterface;
use Nextend\Framework\Model\Section;
use Nextend\Framework\Pattern\GetAssetsPathTrait;
use Nextend\Framework\Pattern\OrderableTrait;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\Style\StyleParser;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;
use Nextend\SmartSlider3\BackupSlider\ImportSlider;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Slider\Admin\AdminSlider;

abstract class AbstractItem {

    use GetAssetsPathTrait, OrderableTrait;

    protected $layerProperties = array();

    protected $fonts = array();

    protected $styles = array();

    /**
     * AbstractItem constructor.
     *
     * @param ItemFactory $factory
     */
    public function __construct($factory) {

        $this->initDefault();

        $factory->addItem($this);
    }

    private function initDefault() {

        foreach ($this->fonts as &$fontData) {
            $this->loadDefaultFont($fontData['defaultName'], $fontData['value']);
        }

        foreach ($this->styles as &$styleData) {
            $this->loadDefaultStyle($styleData['defaultName'], $styleData['value']);
        }
    }

    protected function loadDefaultFont($name, &$value) {

        $res = Section::get('smartslider', 'default', $name);
        if (is_array($res)) {
            $value = $res['value'];
        }

        $value = FontParser::parse($value);
    }

    protected function loadDefaultStyle($name, &$value) {

        $res = Section::get('smartslider', 'default', $name);
        if (is_array($res)) {
            $value = $res['value'];
        }

        $value = StyleParser::parse($value);
    }

    /**
     * @param $id
     * @param $itemData
     * @param $layer
     *
     * @return AbstractItemFrontend
     */
    public abstract function createFrontend($id, $itemData, $layer);

    /**
     * @return string
     */
    public abstract function getTitle();

    /**
     * @return string
     */
    public abstract function getIcon();

    /**
     * @return string
     */
    public function getGroup() {
        return n2_x('Basic', 'Layer group');
    }

    public function getLayerProperties() {
        return $this->layerProperties;
    }

    public function isLegacy() {
        return false;
    }

    public function getValues() {
        $values = array();

        foreach ($this->fonts as $name => $fontData) {
            $values[$name] = $fontData['value'];
        }

        foreach ($this->styles as $name => $styleData) {
            $values[$name] = $styleData['value'];
        }

        return $values;
    }

    /**
     * @param $slide AbstractRenderableOwner
     * @param $data  Data
     *
     * @return Data
     */
    public function getFilled($slide, $data) {
        $this->upgradeData($data);

        return $data;
    }

    /**
     * @param Data $data
     */
    public function upgradeData($data) {

    }

    /**
     * Fix linked fonts/styles for the editor
     *
     * @param Data $data
     */
    public function adminNormalizeFontsStyles($data) {

        foreach ($this->fonts as $name => $fontData) {
            $data->set($name, FontParser::parse($data->get($name)));
        }

        foreach ($this->styles as $name => $styleData) {
            $data->set($name, StyleParser::parse($data->get($name)));
        }
    }

    /**
     * @param ExportSlider $export
     * @param Data         $data
     */
    public function prepareExport($export, $data) {
        $this->upgradeData($data);
    }

    /**
     * @param ImportSlider $import
     * @param Data         $data
     *
     * @return Data
     */
    public function prepareImport($import, $data) {
        $this->upgradeData($data);

        return $data;
    }

    /**
     * @param Data $data
     *
     * @return Data
     */
    public function prepareSample($data) {
        $this->upgradeData($data);

        return $data;
    }

    public function fixImage($image) {
        return ResourceTranslator::toUrl($image);
    }

    public function fixLightbox($url) {
        preg_match('/^([a-zA-Z]+)\[(.*)](.*)/', $url, $matches);
        if (!empty($matches) && $matches[1] == 'lightbox') {
            $images    = explode(',', $matches[2]);
            $newImages = array();
            foreach ($images as $image) {
                $newImages[] = ResourceTranslator::toUrl($image);
            }
            $url = 'lightbox[' . implode(',', $newImages) . ']' . $matches[3];
        }

        return $url;
    }

    /**
     * @param AdminSlider $renderable
     */
    public function loadResources($renderable) {
    }

    /**
     * @return string
     */
    public abstract function getType();

    protected function isBuiltIn() {
        return false;
    }

    /**
     * @param ContainerInterface $container
     */
    public abstract function renderFields($container);

    /**
     * @param ContainerInterface $container
     */
    public function globalDefaultItemFontAndStyle($container) {
    }
}Item/AbstractItemFrontend.php000064400000006052152356645660012262 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Parser\Link;
use Nextend\Framework\Pattern\GetAssetsPathTrait;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Component\ComponentLayer;

abstract class AbstractItemFrontend {

    use GetAssetsPathTrait;

    /** @var AbstractItem */
    protected $item;

    protected $id;

    /** @var ComponentLayer */
    protected $layer;

    /** @var Data */
    public $data;

    protected $isEditor = false;

    /**
     *
     * @param AbstractItem   $item
     * @param string         $id
     * @param array          $itemData
     * @param ComponentLayer $layer
     */
    public function __construct($item, $id, $itemData, $layer) {
        $this->item  = $item;
        $this->id    = $id;
        $this->data  = new Data($itemData);
        $this->layer = $layer;

        $this->fillDefault($item->getValues());
    }

    private function fillDefault($defaults) {

        $this->item->upgradeData($this->data);

        $this->data->fillDefault($defaults);
    }

    public abstract function render();

    public function renderAdmin() {
        $this->isEditor = true;

        /**
         * Fix linked fonts/styles for the editor
         */
        $this->item->adminNormalizeFontsStyles($this->data);

        $rendered = $this->renderAdminTemplate();

        $json = $this->data->toJson();

        return Html::tag("div", array(
            "class"           => "n2-ss-item n2-ss-item-" . $this->item->getType(),
            "data-item"       => $this->item->getType(),
            "data-itemvalues" => $json
        ), $rendered);
    }

    protected abstract function renderAdminTemplate();

    public function needHeight() {
        return false;
    }

    public function isAuto() {
        return false;
    }

    protected function hasLink() {
        $link = $this->data->get('href', '#');
        if (($link != '#' && !empty($link))) {
            return true;
        }

        return false;
    }

    protected function getLink($content, $attributes = array(), $renderEmpty = false) {

        $link   = $this->data->get('href', '#');
        $target = $this->data->get('href-target', '#');
        $rel    = $this->data->get('href-rel', '#');
        $class  = $this->data->get('href-class', '');

        if (($link != '#' && !empty($link)) || $renderEmpty === true) {

            $link = Link::parse($this->layer->getOwner()
                                            ->fill($link), $attributes, $this->isEditor);
            if (!empty($target) && $target != '_self') {
                $attributes['target'] = $target;
            }
            if (!empty($rel)) {
                $attributes['rel'] = $rel;
            }
            if (!empty($class)) {
                $attributes['class'] = $class;
            }

            return Html::link($content, $link, $attributes);
        }

        return $content;
    }
}Item/ItemFactory.php000064400000012610152356645660010423 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item;


use Exception;
use Nextend\Framework\Data\Data;
use Nextend\Framework\Pattern\OrderableTrait;
use Nextend\Framework\Pattern\PluggableTrait;
use Nextend\Framework\Pattern\SingletonTrait;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;
use Nextend\SmartSlider3\BackupSlider\ImportSlider;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Component\ComponentLayer;
use Nextend\SmartSlider3\Renderable\Item\Button\ItemButton;
use Nextend\SmartSlider3\Renderable\Item\Heading\ItemHeading;
use Nextend\SmartSlider3\Renderable\Item\Image\ItemImage;
use Nextend\SmartSlider3\Renderable\Item\Missing\ItemMissing;
use Nextend\SmartSlider3\Renderable\Item\Text\ItemText;
use Nextend\SmartSlider3\Renderable\Item\Vimeo\ItemVimeo;
use Nextend\SmartSlider3\Renderable\Item\YouTube\ItemYouTube;

class ItemFactory {

    use SingletonTrait, PluggableTrait, OrderableTrait;

    public static $i = array();
    /** @var AbstractItem[][] */
    private static $itemGroups = array();
    /**
     * @var AbstractItem[]
     */
    private static $items = array();

    /**
     * @return AbstractItem[]
     */
    public static function getItems() {

        return self::$items;
    }

    /**
     * @param $type
     *
     * @return AbstractItem
     */
    public static function getItem($type) {

        return self::$items[$type];
    }

    /**
     * @return AbstractItem[][]
     */
    public static function getItemGroups() {

        return self::$itemGroups;
    }

    /**
     * @param ComponentLayer $layer
     * @param array          $itemData
     *
     * @return AbstractItemFrontend
     * @throws Exception
     */
    public static function create($layer, $itemData) {

        if (!isset($itemData['type'])) {
            throw new Exception('Error with itemData: ' . $itemData);
        }

        $type = $itemData['type'];

        if ($type == 'missing') {
            $type = $itemData['values']['type'];
        }

        if (!isset(self::$items[$type])) {
            $itemData['values']['type'] = $type;

            $type = 'missing';
        }

        /** @var AbstractItem $factory */
        $factory = self::$items[$type];

        $elementID = $layer->getOwner()
                           ->getElementID();

        if (!isset(self::$i[$elementID])) {
            self::$i[$elementID] = 0;
        }

        self::$i[$elementID]++;
        $id = $elementID . 'item' . self::$i[$elementID];

        return $factory->createFrontend($id, $itemData['values'], $layer);
    }

    /**
     * @param AbstractRenderableOwner $slide
     * @param array                   $item
     */
    public static function getFilled($slide, &$item) {

        $type = $item['type'];
        if (isset(self::$items[$type])) {
            $item['values'] = self::$items[$type]->getFilled($slide, new Data($item['values']))
                                                 ->toArray();
        }
    }

    /**
     * @param ExportSlider                                    $export
     * @param                                                 $item
     */
    public static function prepareExport($export, $item) {

        $type = $item['type'];
        if (isset(self::$items[$type])) {
            self::$items[$type]->prepareExport($export, new Data($item['values']));
        }
    }

    /**
     * @param ImportSlider                                    $import
     * @param                                                 $item
     *
     * @return mixed
     */
    public static function prepareImport($import, $item) {

        $type = $item['type'];
        if (isset(self::$items[$type])) {
            $item['values'] = self::$items[$type]->prepareImport($import, new Data($item['values']))
                                                 ->toArray();
        }

        return $item;
    }

    public static function prepareSample($item) {

        $type = $item['type'];
        if (isset(self::$items[$type])) {
            $item['values'] = self::$items[$type]->prepareSample(new Data($item['values']))
                                                 ->toArray();
        }

        return $item;
    }

    /**
     * @param AbstractItem $item
     */
    public function addItem($item) {

        self::$items[$item->getType()] = $item;
    }

    protected function init() {

        new ItemHeading($this);
        new ItemButton($this);
        new ItemImage($this);
        new ItemText($this);
        new ItemVimeo($this);
        new ItemYouTube($this);

        $this->makePluggable('RenderableItem');

        self::uasort(self::$items);

        self::$itemGroups[n2_x('Basic', 'Layer group')] = array();
        self::$itemGroups[n2_x('Special', 'Layer group')] = array();
    
        self::$itemGroups[n2_x('Media', 'Layer group')] = array();
        self::$itemGroups[n2_x('Advanced', 'Layer group')] = array();
    

        foreach (self::$items as $type => $item) {
            $group = $item->getGroup();
            if (!isset(self::$itemGroups[$group])) {
                self::$itemGroups[$group] = array();
            }
            self::$itemGroups[$group][$type] = $item;
        }

        new ItemMissing($this);
    }
}

ItemFactory::getInstance();Item/YouTube/ItemYouTube.php000064400000023273152356645660012013 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\YouTube;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemYouTube extends AbstractItem {

    protected $ordering = 20;

    protected $layerProperties = array(
        "desktopportraitwidth"  => 300,
        "desktopportraitheight" => 'auto'
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'youtube';
    }

    public function getTitle() {
        return 'YouTube';
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--youtube';
    }

    public function getGroup() {
        return n2_x('Media', 'Layer group');
    }

    /**
     * @param Data $data
     */
    public function upgradeData($data) {
        if (!$data->has('aspect-ratio')) {
            $data->set('aspect-ratio', 'fill');
        }
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemYouTubeFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {
        return parent::getValues() + array(
                'code'             => 'qesNtYIBDfs',
                'aspect-ratio'     => '16:9',
                'youtubeurl'       => 'https://www.youtube.com/watch?v=3PPtkRU7D74',
                'image'            => '$ss3-frontend$/images/placeholder/video.png',
                'autoplay'         => 0,
                'ended'            => '',
                'controls'         => 1,
                'defaultimage'     => 'hqdefault',
                'related'          => '1',
                'center'           => 0,
                'loop'             => 0,
                'modestbranding'   => 1,
                'reset'            => 0,
                'start'            => '0',
                'playbutton'       => 1,
                'playbuttonwidth'  => 48,
                'playbuttonheight' => 48,
                'playbuttonimage'  => '',
                'scroll-pause'     => 'partly-visible',
            );
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('image', $slide->fill($data->get('image', '')));
        $data->set('youtubeurl', $slide->fill($data->get('youtubeurl', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('image'));
        $export->addImage($data->get('playbuttonimage'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('image', $import->fixImage($data->get('image')));
        $data->set('playbuttonimage', $import->fixImage($data->get('playbuttonimage')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('image', ResourceTranslator::toUrl($data->get('image')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-youtube', n2_('General'));
        new Text($settings, 'youtubeurl', n2_('YouTube URL or Video ID'), '', array(
            'style' => 'width:302px;'
        ));
        new FieldImage($settings, 'image', n2_('Cover image'), '', array(
            'width' => 220
        ));

        new Select($settings, 'aspect-ratio', n2_('Aspect ratio'), '16:9', array(
            'options'            => array(
                '16:9'   => '16:9',
                '16:10'  => '16:10',
                '4:3'    => '4:3',
                'custom' => n2_('Custom'),
                'fill'   => n2_('Fill layer height')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'custom'
                    ),
                    'field'  => array(
                        'item_youtubeaspect-ratio-width',
                        'item_youtubeaspect-ratio-height'
                    )
                ),
                array(
                    'values' => array(
                        'fill'
                    ),
                    'field'  => array(
                        'item_youtubeaspect-ratio-notice'
                    )
                )
            )
        ));

        new Text\Number($settings, 'aspect-ratio-width', n2_('Width'), '16', array(
            'wide' => 4,
            'min'  => 1
        ));

        new Text\Number($settings, 'aspect-ratio-height', n2_('Height'), '9', array(
            'wide' => 4,
            'min'  => 1
        ));

        new Notice($settings, 'aspect-ratio-notice', n2_('Fill layer height'), n2_('Set on Style tab.'));


        $misc = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-youtube-misc', n2_('Video settings'));

        new Warning($misc, 'slide-background-notice', sprintf(n2_('Video autoplaying has a lot of limitations made by browsers. %1$sLearn about them.%2$s'), '<a href="https://smartslider.helpscoutdocs.com/article/1919-video-autoplay-handling" target="_blank">', '</a>'));

        new OnOff($misc, 'autoplay', n2_('Autoplay'), 0, array(
            'relatedFieldsOn' => array(
                'item_youtubeautoplay-notice'
            )
        ));

        new Select($misc, 'ended', n2_('When ended'), '', array(
            'options' => array(
                ''     => n2_('Do nothing'),
                'next' => n2_('Go to next slide')
            )
        ));

        new Number($misc, 'start', n2_('Start time'), 0, array(
            'min'  => 0,
            'unit' => 'sec',
            'wide' => 5
        ));
        new Number($misc, 'end', n2_('End time'), 0, array(
            'min'  => 0,
            'unit' => 'sec',
            'wide' => 5
        ));
        new Select($misc, 'volume', n2_('Volume'), 1, array(
            'options' => array(
                '0'    => n2_('Mute'),
                '0.25' => '25%',
                '0.5'  => '50%',
                '0.75' => '75%',
                '1'    => '100%',
                '-1'   => n2_('Default')
            )
        ));

        new Select($misc, 'scroll-pause', n2_('Pause on scroll'), 'partly-visible', array(
            'options'        => array(
                ''               => n2_('Never'),
                'partly-visible' => n2_('When partly visible'),
                'not-visible'    => n2_('When not visible'),
            ),
            'tipLabel'       => n2_('Pause on scroll'),
            'tipDescription' => n2_('You can pause the video when the visitor scrolls away from the slider')
        ));

        new OnOff($misc, 'loop', n2_x('Loop', 'Video/Audio play'), 0, array(
            'relatedFieldsOff' => array(
                'item_youtubeended'
            )
        ));

        new OnOff($misc, 'reset', n2_('Restart on slide change'), 0, array(
            'tipLabel'       => n2_('Restart on slide change'),
            'tipDescription' => n2_('Starts the video from the beginning when the slide is viewed again.')
        ));

        $display = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-youtube-display', n2_('Display'));
        new OnOff($display, 'controls', n2_('Controls'), 1);
        new OnOff($display, 'modestbranding', n2_('Hide YouTube logo'), 1);
    
        new OnOff($display, 'center', n2_('Centered'), 0, array(
            'tipLabel'       => n2_('Centered'),
            'tipDescription' => n2_('Scales up and crops the video to cover the whole layer.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1846-youtube-layer#centered'
        ));

        new Select($display, 'related', n2_('Show related videos'), 1, array(
            'options'        => array(
                '0' => n2_('Anywhere'),
                '1' => n2_('Same channel')
            ),
            'tipLabel'       => n2_('Show related videos'),
            'tipDescription' => n2_('YouTube no longer allows hiding the related videos at the end of the video. This setting defines whether the videos should come from the same channel as the video that was just played or from any other channel.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1846-youtube-layer#show-related-videos',
        ));
        $playButton = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-youtube-playbutton', n2_('Play button'));
        new OnOff($playButton, 'playbutton', n2_('Play button'), 1, array(
            'relatedFieldsOn' => array(
                'item_youtubeplaybuttonwidth',
                'item_youtubeplaybuttonheight',
                'item_youtubeplaybuttonimage',
            )
        ));
        new Number($playButton, 'playbuttonwidth', n2_('Width'), 48, array(
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($playButton, 'playbuttonheight', n2_('Height'), 48, array(
            'unit' => 'px',
            'wide' => 4
        ));

        new FieldImage($playButton, 'playbuttonimage', n2_('Image'), '', array(
            'width' => 220
        ));
    
    }
}Item/YouTube/ItemYouTubeFrontend.php000064400000016447152356645660013520 0ustar00<?php

namespace Nextend\SmartSlider3\Renderable\Item\YouTube;

use Nextend\Framework\Data\Data;
use Nextend\Framework\FastImageSize\FastImageSize;
use Nextend\Framework\Image\Image;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;
use Nextend\SmartSlider3\Settings;

class ItemYouTubeFrontend extends AbstractItemFrontend {

    public function render() {
        $owner = $this->layer->getOwner();
        /**
         * @var Data
         */
        $this->data->fillDefault(array(
            'image'        => '',
            'aspect-ratio' => '16:9',
            'start'        => 0,
            'volume'       => -1,
            'autoplay'     => 0,
            'ended'        => '',
            'controls'     => 1,
            'center'       => 0,
            'loop'         => 0,
            'reset'        => 0,
            'related'      => 1,
        ));

        $aspectRatio = $this->data->get('aspect-ratio', '16:9');
        if ($aspectRatio != 'fill') {
            $this->data->set('center', 0);
        }

        $rawYTUrl = $owner->fill($this->data->get('youtubeurl', ''));

        $url_parts = parse_url($rawYTUrl);
        if (!empty($url_parts['query'])) {
            parse_str($url_parts['query'], $query);
            if (isset($query['v'])) {
                unset($query['v']);
            }
            $this->data->set("query", $query);
        }

        $youTubeUrl = $this->parseYoutubeUrl($rawYTUrl);

        $start = $owner->fill($this->data->get('start', ''));
        $this->data->set("youtubecode", $youTubeUrl);
        $this->data->set("start", $start);

        $end = $owner->fill($this->data->get('end', ''));
        $this->data->set("youtubecode", $youTubeUrl);
        $this->data->set("end", $end);

        $hasImage      = 0;
        $coverImageUrl = $owner->fill($this->data->get('image'));

        $coverImage = '';
        if (!empty($coverImageUrl)) {

            $coverImageElement = $owner->renderImage($this, $coverImageUrl, array(
                'class' => 'n2_ss_video_cover',
                'alt'   => n2_('Play')
            ), array(
                'class' => 'n2-ow-all'
            ));

            $hasImage  = 1;
            $playImage = '';

            if ($this->data->get('playbutton', 1) == 1) {

                $playWidth  = intval($this->data->get('playbuttonwidth', '48'));
                $playHeight = intval($this->data->get('playbuttonheight', '48'));
                if ($playWidth > 0 && $playHeight > 0) {

                    $attributes = Html::addExcludeLazyLoadAttributes(array(
                        'style' => '',
                        'class' => 'n2_ss_video_play_btn'
                    ));

                    if ($playWidth != 48) {
                        $attributes['style'] .= 'width:' . $playWidth . 'px;';
                    }
                    if ($playHeight != 48) {
                        $attributes['style'] .= 'height:' . $playHeight . 'px;';
                    }

                    $playButtonImage = $this->data->get('playbuttonimage', '');
                    if (!empty($playButtonImage)) {
                        $image = $this->data->get('playbuttonimage', '');
                        FastImageSize::initAttributes($image, $attributes);
                        $src = ResourceTranslator::toUrl($image);
                    } else {
                        $image = '$ss3-frontend$/images/play.svg';
                        FastImageSize::initAttributes($image, $attributes);
                        $src = Image::SVGToBase64($image);
                    }

                    $playImage = Html::image($src, 'Play', $attributes);
                }
            }

            $coverImage = Html::tag('div', array(
                'class'              => 'n2_ss_video_player__cover',
                'data-force-pointer' => ''
            ), $coverImageElement . $playImage);
        }

        $this->data->set('privacy-enhanced', intval(Settings::get('youtube-privacy-enhanced', 0)));

        $owner->addScript('new _N2.FrontendItemYouTube(this, "' . $this->id . '", ' . $this->data->toJSON() . ', ' . $hasImage . ');');

        $style = '';
        if ($aspectRatio == 'custom') {
            $style = 'style="padding-top:' . ($this->data->get('aspect-ratio-height', '9') / $this->data->get('aspect-ratio-width', '16') * 100) . '%"';
        }

        return Html::tag('div', array(
            'id'                => $this->id,
            'class'             => 'n2_ss_video_player n2-ss-item-content n2-ow-all',
            'data-aspect-ratio' => $aspectRatio
        ), '<div class="n2_ss_video_player__placeholder" ' . $style . '></div>' . Html::tag('div', array(
                'id' => $this->id . '-frame',
            ), '') . $coverImage);
    }

    public function renderAdminTemplate() {

        $aspectRatio = $this->data->get('aspect-ratio', '16:9');

        $style = '';
        if ($aspectRatio == 'custom') {
            $style = 'style="padding-top:' . ($this->data->get('aspect-ratio-height', '9') / $this->data->get('aspect-ratio-width', '16') * 100) . '%"';
        }

        $image = $this->layer->getOwner()
                             ->fill($this->data->get('image'));
        $this->data->set('image', $image);

        $playButtonImage = $this->data->get('playbuttonimage', '');
        if (!empty($playButtonImage)) {
            $playButtonImage = ResourceTranslator::toUrl($playButtonImage);
        } else {
            $playButtonImage = Image::SVGToBase64('$ss3-frontend$/images/play.svg');
        }

        $playButtonStyle  = '';
        $playButtonWidth  = intval($this->data->get('playbuttonwidth', '48'));
        $playButtonHeight = intval($this->data->get('playbuttonheight', '48'));

        if ($playButtonWidth > 0) {
            $playButtonStyle .= 'width:' . $playButtonWidth . 'px;';
        }
        if ($playButtonHeight > 0) {
            $playButtonStyle .= 'height:' . $playButtonWidth . 'px;';
        }

        $playButton = Html::image($playButtonImage, n2_('Play'), Html::addExcludeLazyLoadAttributes(array(
            'class' => 'n2_ss_video_play_btn',
            'style' => $playButtonStyle
        )));

        return Html::tag('div', array(
            'class'             => 'n2_ss_video_player n2-ow-all',
            'data-aspect-ratio' => $aspectRatio,
            "style"             => 'background: URL(' . ResourceTranslator::toUrl($this->data->getIfEmpty('image', '$ss3-frontend$/images/placeholder/video.png')) . ') no-repeat 50% 50%; background-size: cover;'
        ), '<div class="n2_ss_video_player__placeholder" ' . $style . '></div>' . ($this->data->get('playbutton', 1) ? '<div class="n2_ss_video_player__cover">' . $playButton . '</div>' : ''));

    }

    private function parseYoutubeUrl($youTubeUrl) {
        preg_match('#^(?:https?://)?(?:www\.)?(?:youtu\.be/|youtube(?:-nocookie)?\.com(?:/embed/|/shorts/|/v/|/watch\?v=|/watch\?.+&v=))([\w-]{11})(?:.+)?$#x', $youTubeUrl, $matches);

        if ($matches && isset($matches[1]) && strlen($matches[1]) == 11) {
            return $matches[1];
        }

        return $youTubeUrl;
    }
}Item/Vimeo/ItemVimeo.php000064400000023362152356645660011160 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Vimeo;


use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemVimeo extends AbstractItem {

    protected $ordering = 20;

    protected $layerProperties = array(
        "desktopportraitwidth"  => 300,
        "desktopportraitheight" => 'auto'
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'vimeo';
    }

    public function getTitle() {
        return 'Vimeo';
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--vimeo';
    }

    public function getGroup() {
        return n2_x('Media', 'Layer group');
    }

    /**
     * @param Data $data
     */
    public function upgradeData($data) {
        if (!$data->has('aspect-ratio')) {
            $data->set('aspect-ratio', 'fill');
        }
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemVimeoFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {
        return parent::getValues() + array(
                'vimeourl'         => '75251217',
                'privateid'        => '',
                'image'            => '$ss3-frontend$/images/placeholder/video.png',
                'aspect-ratio'     => '16:9',
                'autoplay'         => 0,
                'ended'            => '',
                'title'            => 1,
                'byline'           => 1,
                'portrait'         => 0,
                'color'            => '00adef',
                'loop'             => 0,
                'start'            => 0,
                'playbutton'       => 1,
                'playbuttonwidth'  => 48,
                'playbuttonheight' => 48,
                'playbuttonimage'  => '',
                'scroll-pause'     => 'partly-visible',
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('image', $slide->fill($data->get('image', '')));
        $data->set('vimeourl', $slide->fill($data->get('vimeourl', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('image'));
        $export->addImage($data->get('playbuttonimage'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('image', $import->fixImage($data->get('image')));
        $data->set('playbuttonimage', $import->fixImage($data->get('playbuttonimage')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('image', ResourceTranslator::toUrl($data->get('image')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-vimeo', n2_('General'));

        new Text($settings, 'vimeourl', n2_('Vimeo url or Video ID'), '', array(
            'style' => 'width:302px;'
        ));

        new FieldImage($settings, 'image', n2_('Cover image'), '', array(
            'width' => 220
        ));

        new Select($settings, 'aspect-ratio', n2_('Aspect ratio'), '16:9', array(
            'options'            => array(
                '16:9'   => '16:9',
                '16:10'  => '16:10',
                '4:3'    => '4:3',
                'custom' => n2_('Custom'),
                'fill'   => n2_('Fill layer height')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'custom'
                    ),
                    'field'  => array(
                        'item_vimeoaspect-ratio-width',
                        'item_vimeoaspect-ratio-height'
                    )
                ),
                array(
                    'values' => array(
                        'fill'
                    ),
                    'field'  => array(
                        'item_vimeoaspect-ratio-notice'
                    )
                )
            )
        ));

        new Text\Number($settings, 'aspect-ratio-width', n2_('Width'), '16', array(
            'wide' => 4,
            'min'  => 1
        ));

        new Text\Number($settings, 'aspect-ratio-height', n2_('Height'), '9', array(
            'wide' => 4,
            'min'  => 1
        ));

        new Notice($settings, 'aspect-ratio-notice', n2_('Fill layer height'), n2_('Set on Style tab.'));

        $misc = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-vimeo-misc', n2_('Video settings'));

        new Warning($misc, 'slide-background-notice', sprintf(n2_('Video autoplaying has a lot of limitations made by browsers. %1$sLearn about them.%2$s'), '<a href="https://smartslider.helpscoutdocs.com/article/1919-video-autoplay-handling" target="_blank">', '</a>'));

        new OnOff($misc, 'autoplay', n2_('Autoplay'), 0, array(
            'relatedFieldsOn' => array(
                'item_vimeoautoplay-notice'
            )
        ));

        new Select($misc, 'ended', n2_('When ended'), '', array(
            'options' => array(
                ''     => n2_('Do nothing'),
                'next' => n2_('Go to next slide')
            )
        ));

        new Number($misc, 'start', n2_('Start time'), 0, array(
            'min'  => 0,
            'unit' => 'sec',
            'wide' => 5
        ));

        new Select($misc, 'volume', n2_('Volume'), 1, array(
            'options' => array(
                '0'    => n2_('Mute'),
                '0.25' => '25%',
                '0.5'  => '50%',
                '0.75' => '75%',
                '1'    => '100%',
                '-1'   => n2_('Default')
            )
        ));

        new Select($misc, 'scroll-pause', n2_('Pause on scroll'), 'partly-visible', array(
            'options'        => array(
                ''               => n2_('Never'),
                'partly-visible' => n2_('When partly visible'),
                'not-visible'    => n2_('When not visible'),
            ),
            'tipLabel'       => n2_('Pause on scroll'),
            'tipDescription' => n2_('You can pause the video when the visitor scrolls away from the slider')
        ));
        new OnOff($misc, 'loop', n2_x('Loop', 'Video/Audio play'), 0, array(
            'relatedFieldsOff' => array(
                'item_vimeoended'
            )
        ));
    

        new OnOff($misc, 'reset', n2_('Restart on slide change'), 0, array(
            'tipLabel'       => n2_('Restart on slide change'),
            'tipDescription' => n2_('Starts the video from the beginning when the slide is viewed again.')
        ));

        $display = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-youtube-display', n2_('Display'));
        new Color($display, 'color', n2_('Color'), 0, array(
            'tipLabel'       => n2_('Color'),
            'tipDescription' => n2_('Only works on videos of Vimeo Pro users.')
        ));

        new OnOff($display, 'background', n2_('Remove controls'), 0, array(
            'tipLabel'       => n2_('Remove controls'),
            'tipDescription' => n2_('Removes the controls of the video, but it only works on videos of Vimeo Pro users.')
        ));

        new OnOff($display, 'title', n2_('Title'), 1, array(
            'tipLabel'       => n2_('Title'),
            'tipDescription' => n2_('Hides the title of the video, but only if video owner allows it.')
        ));
        new OnOff($display, 'byline', n2_('Users byline'), 1, array(
            'tipLabel'       => n2_('Users byline'),
            'tipDescription' => n2_('Hides the user\'s byline of the video, but only if video owner allows it.')
        ));
        new OnOff($display, 'portrait', n2_('Portrait'), 1, array(
            'tipLabel'       => n2_('Portrait'),
            'tipDescription' => n2_('Hides the profile image of the author, but only if video owner allows it. ')
        ));
        new Select($display, 'quality', n2_('Quality'), '-1', array(
            'options'        => array(
                '270p'  => '270p',
                '360p'  => '360p',
                '720p'  => '720p',
                '1080p' => '1080p',
                '-1'    => n2_('Default')
            ),
            'tipLabel'       => n2_('Quality'),
            'tipDescription' => n2_('Only works on videos of Vimeo Pro users.')
        ));

        new Text($display, 'iframe-title', n2_('Iframe title'));
        $playButton = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-vimeo-playbutton', n2_('Play button'));
        new OnOff($playButton, 'playbutton', n2_('Play button'), 1);
        new Number($playButton, 'playbuttonwidth', n2_('Width'), 48, array(
            'unit' => 'px',
            'wide' => 4
        ));
        new Number($playButton, 'playbuttonheight', n2_('Height'), 48, array(
            'unit' => 'px',
            'wide' => 4
        ));

        new FieldImage($playButton, 'playbuttonimage', n2_('Image'), '', array(
            'width' => 220
        ));
    
    }

}Item/Vimeo/ItemVimeoFrontend.php000064400000014547152356645660012665 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Vimeo;


use Nextend\Framework\FastImageSize\FastImageSize;
use Nextend\Framework\Image\Image;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;
use Nextend\SmartSlider3\Settings;

class ItemVimeoFrontend extends AbstractItemFrontend {

    public function render() {
        $owner = $this->layer->getOwner();

        $url = $owner->fill($this->data->get("vimeourl"));

        $urlParts = explode('?', $url);

        $privateID = '';
        if (preg_match('/https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/', $urlParts[0], $matches)) {
            $videoID   = $matches[3];
            $privateID = str_replace($matches, '', $urlParts[0]);
        } else {
            $videoID = preg_replace('/\D/', '', $urlParts[0]);
        }

        $this->data->set("vimeocode", $videoID);

        if (isset($urlParts[1])) {
            $parsedUrl = parse_url('https://player.vimeo.com/video/' . $videoID . '?' . $urlParts[1]);
            parse_str($parsedUrl['query'], $query);
            if (isset($query['h'])) {
                $privateID = $query['h'];
            }
        }

        $this->data->set("privateid", $privateID);

        $hasImage      = 0;
        $coverImageUrl = $owner->fill($this->data->get('image'));

        $coverImage = '';
        if (!empty($coverImageUrl)) {

            $coverImageElement = $owner->renderImage($this, $coverImageUrl, array(
                'class' => 'n2_ss_video_cover',
                'alt'   => n2_('Play')
            ), array(
                'class' => 'n2-ow-all'
            ));

            $hasImage  = 1;
            $playImage = '';

            if ($this->data->get('playbutton', 1) == 1) {

                $playWidth  = intval($this->data->get('playbuttonwidth', '48'));
                $playHeight = intval($this->data->get('playbuttonheight', '48'));
                if ($playWidth > 0 && $playHeight > 0) {

                    $attributes = Html::addExcludeLazyLoadAttributes(array(
                        'style' => '',
                        'class' => 'n2_ss_video_play_btn'
                    ));

                    if ($playWidth != 48) {
                        $attributes['style'] .= 'width:' . $playWidth . 'px;';
                    }
                    if ($playHeight != 48) {
                        $attributes['style'] .= 'height:' . $playHeight . 'px;';
                    }

                    $playButtonImage = $this->data->get('playbuttonimage', '');
                    if (!empty($playButtonImage)) {
                        $image = $this->data->get('playbuttonimage', '');
                        FastImageSize::initAttributes($image, $attributes);
                        $src = ResourceTranslator::toUrl($image);
                    } else {
                        $image = '$ss3-frontend$/images/play.svg';
                        FastImageSize::initAttributes($image, $attributes);
                        $src = Image::SVGToBase64($image);
                    }

                    $playImage = Html::image($src, 'Play', $attributes);
                }
            }

            $coverImage = Html::tag('div', array(
                'class'              => 'n2_ss_video_player__cover',
                'data-force-pointer' => ''
            ), $coverImageElement . $playImage);
        }

        $this->data->set('privacy-enhanced', intval(Settings::get('youtube-privacy-enhanced', 0)));

        $owner->addScript('new _N2.FrontendItemVimeo(this, "' . $this->id . '", "' . $owner->getElementID() . '", ' . $this->data->toJSON() . ', ' . $hasImage . ', ' . $owner->fill($this->data->get('start', '0')) . ');');

        $aspectRatio = $this->data->get('aspect-ratio', '16:9');
        $style       = '';
        if ($aspectRatio == 'custom') {
            $style = 'style="padding-top:' . ($this->data->get('aspect-ratio-height', '9') / $this->data->get('aspect-ratio-width', '16') * 100) . '%"';
        }

        return Html::tag('div', array(
            'id'                => $this->id,
            'class'             => 'n2_ss_video_player n2-ss-item-content n2-ow-all',
            'data-aspect-ratio' => $aspectRatio
        ), '<div class="n2_ss_video_player__placeholder" ' . $style . '></div>' . $coverImage);
    }

    public function renderAdminTemplate() {

        $aspectRatio = $this->data->get('aspect-ratio', '16:9');

        $owner = $this->layer->getOwner();

        $style = '';
        if ($aspectRatio == 'custom') {
            $style = 'style="padding-top:' . ($this->data->get('aspect-ratio-height', '9') / $this->data->get('aspect-ratio-width', '16') * 100) . '%"';
        }

        $playButtonImage = $this->data->get('playbuttonimage', '');
        if (!empty($playButtonImage)) {
            $playButtonImage = ResourceTranslator::toUrl($playButtonImage);
        } else {
            $playButtonImage = Image::SVGToBase64('$ss3-frontend$/images/play.svg');
        }

        $playButtonStyle  = '';
        $playButtonWidth  = intval($this->data->get('playbuttonwidth', '48'));
        $playButtonHeight = intval($this->data->get('playbuttonheight', '48'));

        if ($playButtonWidth > 0) {
            $playButtonStyle .= 'width:' . $playButtonWidth . 'px;';
        }
        if ($playButtonHeight > 0) {
            $playButtonStyle .= 'height:' . $playButtonHeight . 'px;';
        }

        $playButton = Html::image($playButtonImage, n2_('Play'), Html::addExcludeLazyLoadAttributes(array(
            'class' => 'n2_ss_video_play_btn',
            'style' => $playButtonStyle
        )));

        return Html::tag('div', array(
            "class"             => 'n2_ss_video_player n2-ow-all',
            'data-aspect-ratio' => $aspectRatio,
            "style"             => 'background: URL(' . ResourceTranslator::toUrl($owner->fill($this->data->getIfEmpty('image', '$ss3-frontend$/images/placeholder/video.png'))) . ') no-repeat 50% 50%; background-size: cover;'
        ), '<div class="n2_ss_video_player__placeholder" ' . $style . '></div>' . '<div class="n2_ss_video_player__cover">' . $playButton . '</div>');

    }
}Item/Text/ItemText.php000064400000013113152356645660010663 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Text;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\RichTextarea;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemText extends AbstractItem {

    protected $ordering = 2;

    protected $layerProperties = array(
        "desktopportraitleft"   => 0,
        "desktopportraittop"    => 0,
        "desktopportraitwidth"  => 400,
        "desktopportraitalign"  => "left",
        "desktopportraitvalign" => "top"
    );

    protected $fonts = array(
        'font' => array(
            'defaultName' => 'item-text-font',
            'value'       => '{"data":[{"color":"ffffffff","size":"14||px","align":"inherit"},{"color":"1890d7ff"},{"color":"1890d7ff"}]}'
        )
    );

    protected $styles = array(
        'style' => array(
            'defaultName' => 'item-text-style',
            'value'       => ''
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'text';
    }

    public function getTitle() {
        return n2_('Text');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--text';
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemTextFrontend($this, $id, $itemData, $layer);
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-text-font', false, $this->fonts['font']['value'], array(
            'mode' => 'paragraph'
        ));

        new Style($row1, 'item-text-style', false, $this->styles['style']['value'], array(
            'mode' => 'heading'
        ));
    }

    public function getValues() {

        return parent::getValues() + array(
                'content'                => 'Lorem ipsum dolor sit amet, <a href="#">consectetur adipiscing</a> elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
                'content-tablet-enabled' => 0,
                'contenttablet'          => '',
                'content-mobile-enabled' => 0,
                'contentmobile'          => ''
            );
    }

    /**
     * @param Data $data
     */
    public function upgradeData($data) {
        if (!$data->has('content-tablet-enabled')) {
            if ($data->get('contenttablet', '') != '') {
                $data->set('content-tablet-enabled', 1);
            }
        }
        if (!$data->has('content-mobile-enabled')) {
            if ($data->get('contentmobile', '') != '') {
                $data->set('content-mobile-enabled', 1);
            }
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('content', $slide->fill($data->get('content', '')));
        $data->set('contenttablet', $slide->fill($data->get('contenttablet', '')));
        $data->set('contentmobile', $slide->fill($data->get('contentmobile', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('style'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('style', $import->fixSection($data->get('style')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-text', n2_('General'));

        new RichTextarea($settings, 'content', n2_('Text'), '', array(
            'fieldStyle' => 'height: 120px; width: 314px;resize: vertical;'
        ));

        new HiddenFont($settings, 'font', false, '', array(
            'mode' => 'paragraph'
        ));
        new HiddenStyle($settings, 'style', false, '', array(
            'mode' => 'heading'
        ));

        new OnOff($settings, 'content-tablet-enabled', n2_('Tablet'), 0, array(
            'relatedFieldsOn' => array(
                'item_textcontenttablet'
            ),
            'tipLabel'        => n2_('Tablet'),
            'tipDescription'  => n2_('Custom text for tablet')
        ));

        new RichTextarea($settings, 'contenttablet', n2_('Tablet text'), '', array(
            'fieldStyle' => 'height: 120px; width: 314px;resize: vertical;'
        ));

        new OnOff($settings, 'content-mobile-enabled', n2_('Mobile'), 0, array(
            'relatedFieldsOn' => array(
                'item_textcontentmobile'
            ),
            'tipLabel'        => n2_('Mobile'),
            'tipDescription'  => n2_('Custom text for mobile')
        ));

        new RichTextarea($settings, 'contentmobile', n2_('Mobile text'), '', array(
            'fieldStyle' => 'height: 120px; width: 314px;resize: vertical;'
        ));
    }
}Item/Text/ItemTextFrontend.php000064400000040327152356645660012372 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Text;


use Nextend\Framework\Platform\Platform;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;
use function Nextend\Framework\Sanitize;

class ItemTextFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHTML() {
        $owner = $this->layer->getOwner();

        $font = $owner->addFont($this->data->get('font'), 'paragraph');

        $style = $owner->addStyle($this->data->get('style'), 'heading');

        $tagName = 'p';
        if (Platform::needStrongerCSS()) {
            $tagName = 'ss-p';
        }

        $html    = '';
        $content = str_replace(array(
            '<p>',
            '</p>'
        ), array(
            '<' . $tagName . ' class="' . $font . ' ' . $style . ' ">',
            '</' . $tagName . '>'
        ), $this->wpautop(Sanitize::filter_allowed_html($this->closeTags($owner->fill($this->data->get('content', ''))), '<p>')));

        $class = '';

        $hasMobile = false;
        if ($this->data->get('content-mobile-enabled')) {
            $hasMobile = true;
            $html      .= Html::tag('div', array(
                'data-hide-desktoplandscape' => 1,
                'data-hide-desktopportrait'  => 1,
                'data-hide-tabletlandscape'  => 1,
                'data-hide-tabletportrait'   => 1
            ), str_replace(array(
                '<p>',
                '</p>'
            ), array(
                '<' . $tagName . ' class="' . $font . ' ' . $style . ' ">',
                '</' . $tagName . '>'
            ), $this->wpautop(Sanitize::filter_allowed_html($this->closeTags($owner->fill($this->data->get('contentmobile', ''))), '<p>'))));
        }

        $hasTablet = false;
        if ($this->data->get('content-tablet-enabled')) {
            $hasTablet = true;

            $attributes = array(
                'class'                      => $class,
                'data-hide-desktoplandscape' => 1,
                'data-hide-desktopportrait'  => 1,
            );

            if ($hasMobile) {
                $attributes['data-hide-mobilelandscape'] = 1;
                $attributes['data-hide-mobileportrait']  = 1;
            } else {
                $hasMobile = true;
            }

            $html  .= Html::tag('div', $attributes, str_replace(array(
                '<p>',
                '</p>'
            ), array(
                '<' . $tagName . ' class="' . $font . ' ' . $style . '">',
                '</' . $tagName . '>'
            ), $this->wpautop(Sanitize::filter_allowed_html($this->closeTags($owner->fill($this->data->get('contenttablet', '')))), '<p>')));
            $class = '';
        }


        $attributes = array(
            'class' => $class
        );

        if ($hasMobile) {
            $attributes['data-hide-mobilelandscape'] = 1;
            $attributes['data-hide-mobileportrait']  = 1;
        }

        if ($hasTablet) {
            $attributes['data-hide-tabletlandscape'] = 1;
            $attributes['data-hide-tabletportrait']  = 1;
        }
        $html .= Html::tag('div', $attributes, $content);

        return Html::tag('div', array(
            'class' => 'n2-ss-item-content n2-ss-text n2-ow-all'
        ), $html);
    }


    public function closeTags($html) {
        $html = str_replace(array(
            '<>',
            '</>'
        ), array(
            '',
            ''
        ), $html);
        // Put all opened tags into an array
        preg_match_all('#<([a-z]+)(?: .*)?(?<![/| ])>#iU', $html, $result);
        $openedtags = $result[1];   #put all closed tags into an array
        preg_match_all('#</([a-z]+)>#iU', $html, $result);
        $closedtags = $result[1];
        $len_opened = count($openedtags);
        # Check if all tags are closed
        if (count($closedtags) == $len_opened) {
            return $html;
        }
        $openedtags = array_reverse($openedtags);
        # close tags
        for ($i = 0; $i < $len_opened; $i++) {
            if (!in_array($openedtags[$i], $closedtags)) {
                if ($openedtags[$i] != 'br') {
                    // Ignores <br> tags to avoid unnessary spacing
                    // at the end of the string
                    $html .= '</' . $openedtags[$i] . '>';
                }
            } else {
                unset($closedtags[array_search($openedtags[$i], $closedtags)]);
            }
        }

        return $html;
    }

    private function wpautop($pee, $br = true) {
        $pre_tags = array();

        if (trim($pee) === '') {
            return '';
        }

        // Just to make things a little easier, pad the end.
        $pee = $pee . "\n";

        /*
         * Pre tags shouldn't be touched by autop.
         * Replace pre tags with placeholders and bring them back after autop.
         */
        if (strpos($pee, '<pre') !== false) {
            $pee_parts = explode('</pre>', $pee);
            $last_pee  = array_pop($pee_parts);
            $pee       = '';
            $i         = 0;

            foreach ($pee_parts as $pee_part) {
                $start = strpos($pee_part, '<pre');

                // Malformed HTML?
                if (false === $start) {
                    $pee .= $pee_part;
                    continue;
                }

                $name            = "<pre wp-pre-tag-$i></pre>";
                $pre_tags[$name] = substr($pee_part, $start) . '</pre>';

                $pee .= substr($pee_part, 0, $start) . $name;
                $i++;
            }

            $pee .= $last_pee;
        }
        // Change multiple <br>'s into two line breaks, which will turn into paragraphs.
        $pee = preg_replace('|<br\s*/?>\s*<br\s*/?>|', "\n\n", $pee);

        $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)';

        // Add a double line break above block-level opening tags.
        $pee = preg_replace('!(<' . $allblocks . '[\s/>])!', "\n\n$1", $pee);

        // Add a double line break below block-level closing tags.
        $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);

        // Add a double line break after hr tags, which are self closing.
        $pee = preg_replace('!(<hr\s*?/?>)!', "$1\n\n", $pee);

        // Standardize newline characters to "\n".
        $pee = str_replace(array(
            "\r\n",
            "\r"
        ), "\n", $pee);

        // Find newlines in all elements and add placeholders.
        $pee = self::wp_replace_in_html_tags($pee, array("\n" => ' <!-- wpnl --> '));

        // Collapse line breaks before and after <option> elements so they don't get autop'd.
        if (strpos($pee, '<option') !== false) {
            $pee = preg_replace('|\s*<option|', '<option', $pee);
            $pee = preg_replace('|</option>\s*|', '</option>', $pee);
        }

        /*
         * Collapse line breaks inside <object> elements, before <param> and <embed> elements
         * so they don't get autop'd.
         */
        if (strpos($pee, '</object>') !== false) {
            $pee = preg_replace('|(<object[^>]*>)\s*|', '$1', $pee);
            $pee = preg_replace('|\s*</object>|', '</object>', $pee);
            $pee = preg_replace('%\s*(</?(?:param|embed)[^>]*>)\s*%', '$1', $pee);
        }

        /*
         * Collapse line breaks inside <audio> and <video> elements,
         * before and after <source> and <track> elements.
         */
        if (strpos($pee, '<source') !== false || strpos($pee, '<track') !== false) {
            $pee = preg_replace('%([<\[](?:audio|video)[^>\]]*[>\]])\s*%', '$1', $pee);
            $pee = preg_replace('%\s*([<\[]/(?:audio|video)[>\]])%', '$1', $pee);
            $pee = preg_replace('%\s*(<(?:source|track)[^>]*>)\s*%', '$1', $pee);
        }

        // Collapse line breaks before and after <figcaption> elements.
        if (strpos($pee, '<figcaption') !== false) {
            $pee = preg_replace('|\s*(<figcaption[^>]*>)|', '$1', $pee);
            $pee = preg_replace('|</figcaption>\s*|', '</figcaption>', $pee);
        }

        // Remove more than two contiguous line breaks.
        $pee = preg_replace("/\n\n+/", "\n\n", $pee);

        // Split up the contents into an array of strings, separated by double line breaks.
        $pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);

        // Reset $pee prior to rebuilding.
        $pee = '';

        // Rebuild the content as a string, wrapping every bit with a <p>.
        foreach ($pees as $tinkle) {
            $pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
        }

        // Under certain strange conditions it could create a P of entirely whitespace.
        $pee = preg_replace('|<p>\s*</p>|', '', $pee);

        // Add a closing <p> inside <div>, <address>, or <form> tag if missing.
        $pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', '<p>$1</p></$2>', $pee);

        // If an opening or closing block element tag is wrapped in a <p>, unwrap it.
        $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $pee);

        // In some cases <li> may get wrapped in <p>, fix them.
        $pee = preg_replace('|<p>(<li.+?)</p>|', '$1', $pee);

        // If a <blockquote> is wrapped with a <p>, move it inside the <blockquote>.
        $pee = preg_replace('|<p><blockquote([^>]*)>|i', '<blockquote$1><p>', $pee);
        $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);

        // If an opening or closing block element tag is preceded by an opening <p> tag, remove it.
        $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', '$1', $pee);

        // If an opening or closing block element tag is followed by a closing <p> tag, remove it.
        $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', '$1', $pee);

        // Optionally insert line breaks.
        if ($br) {
            // Replace newlines that shouldn't be touched with a placeholder.
            $pee = preg_replace_callback('/<(script|style|svg).*?<\/\\1>/s', array(
                $this,
                '_autop_newline_preservation_helper'
            ), $pee);

            // Normalize <br>
            $pee = str_replace(array(
                '<br>',
                '<br/>'
            ), '<br />', $pee);

            // Replace any new line characters that aren't preceded by a <br /> with a <br />.
            $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee);

            // Replace newline placeholders with newlines.
            $pee = str_replace('<WPPreserveNewline />', "\n", $pee);
        }

        // If a <br /> tag is after an opening or closing block tag, remove it.
        $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', '$1', $pee);

        // If a <br /> tag is before a subset of opening or closing block tags, remove it.
        $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
        $pee = preg_replace("|\n</p>$|", '</p>', $pee);

        // Replace placeholder <pre> tags with their original content.
        if (!empty($pre_tags)) {
            $pee = str_replace(array_keys($pre_tags), array_values($pre_tags), $pee);
        }

        // Restore newlines in all elements.
        if (false !== strpos($pee, '<!-- wpnl -->')) {
            $pee = str_replace(array(
                ' <!-- wpnl --> ',
                '<!-- wpnl -->'
            ), "\n", $pee);
        }

        return $pee;
    }

    /**
     * Replace characters or phrases within HTML elements only.
     *
     * @param string $haystack      The text which has to be formatted.
     * @param array  $replace_pairs In the form array('from' => 'to', ...).
     *
     * @return string The formatted text.
     * @since 4.2.3
     *
     */
    private function wp_replace_in_html_tags($haystack, $replace_pairs) {
        // Find all elements.
        $textarr = self::wp_html_split($haystack);
        $changed = false;

        // Optimize when searching for one item.
        if (1 === count($replace_pairs)) {
            // Extract $needle and $replace.
            foreach ($replace_pairs as $needle => $replace) {
            }

            // Loop through delimiters (elements) only.
            for ($i = 1, $c = count($textarr); $i < $c; $i += 2) {
                if (false !== strpos($textarr[$i], $needle)) {
                    $textarr[$i] = str_replace($needle, $replace, $textarr[$i]);
                    $changed     = true;
                }
            }
        } else {
            // Extract all $needles.
            $needles = array_keys($replace_pairs);

            // Loop through delimiters (elements) only.
            for ($i = 1, $c = count($textarr); $i < $c; $i += 2) {
                foreach ($needles as $needle) {
                    if (false !== strpos($textarr[$i], $needle)) {
                        $textarr[$i] = strtr($textarr[$i], $replace_pairs);
                        $changed     = true;
                        // After one strtr() break out of the foreach loop and look at next element.
                        break;
                    }
                }
            }
        }

        if ($changed) {
            $haystack = implode($textarr);
        }

        return $haystack;
    }

    /**
     * Separate HTML elements and comments from the text.
     *
     * @param string $input The text which has to be formatted.
     *
     * @return string[] Array of the formatted text.
     * @since 4.2.4
     *
     */
    private function wp_html_split($input) {
        return preg_split(self::get_html_split_regex(), $input, -1, PREG_SPLIT_DELIM_CAPTURE);
    }

    /**
     * Retrieve the regular expression for an HTML element.
     *
     * @return string The regular expression
     * @since 4.4.0
     *
     */
    private function get_html_split_regex() {
        static $regex;

        if (!isset($regex)) {
            // phpcs:disable Squiz.Strings.ConcatenationSpacing.PaddingFound -- don't remove regex indentation
            $comments = '!'             // Start of comment, after the <.
                . '(?:'         // Unroll the loop: Consume everything until --> is found.
                . '-(?!->)' // Dash not followed by end of comment.
                . '[^\-]*+' // Consume non-dashes.
                . ')*+'         // Loop possessively.
                . '(?:-->)?';   // End of comment. If not found, match all input.

            $cdata = '!\[CDATA\['    // Start of comment, after the <.
                . '[^\]]*+'     // Consume non-].
                . '(?:'         // Unroll the loop: Consume everything until ]]> is found.
                . '](?!]>)' // One ] not followed by end of comment.
                . '[^\]]*+' // Consume non-].
                . ')*+'         // Loop possessively.
                . '(?:]]>)?';   // End of comment. If not found, match all input.

            $escaped = '(?='             // Is the element escaped?
                . '!--' . '|' . '!\[CDATA\[' . ')' . '(?(?=!-)'      // If yes, which type?
                . $comments . '|' . $cdata . ')';

            $regex = '/('                // Capture the entire match.
                . '<'           // Find start of element.
                . '(?'          // Conditional expression follows.
                . $escaped  // Find end of escaped element.
                . '|'           // ...else...
                . '[^>]*>?' // Find end of normal element.
                . ')' . ')/';
            // phpcs:enable
        }

        return $regex;
    }

    public function _autop_newline_preservation_helper($matches) {
        return str_replace("\n", '<WPPreserveNewline />', $matches[0]);
    }
}Item/Missing/ItemMissingFrontend.php000064400000000636152356645660013543 0ustar00<?php

namespace Nextend\SmartSlider3\Renderable\Item\Missing;

use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemMissingFrontend extends AbstractItemFrontend {

    public function render() {
        return '';
    }

    protected function renderAdminTemplate() {
        return '<div>' . sprintf(n2_('Missing layer type: %s'), $this->data->get('type')) . '</div>';
    }
}Item/Missing/ItemMissing.php000064400000001113152356645660012032 0ustar00<?php

namespace Nextend\SmartSlider3\Renderable\Item\Missing;

use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemMissing extends AbstractItem {

    public function createFrontend($id, $itemData, $layer) {
        return new ItemMissingFrontend($this, $id, $itemData, $layer);
    }

    public function getTitle() {
        return n2_x('Missing', 'Layer');
    }

    public function getIcon() {
        return '';
    }

    public function getType() {
        return 'missing';
    }

    public function renderFields($container) {
    }

}Item/Heading/ItemHeading.php000064400000024666152356645660011730 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Heading;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;
use Nextend\SmartSlider3Pro\Form\Element\SplitTextAnimation;

class ItemHeading extends AbstractItem {

    protected $ordering = 1;

    protected $fonts = array(
        'font' => array(
            'defaultName' => 'item-heading-font',
            'value'       => '{"data":[{"color":"ffffffff","size":"36||px","align":"inherit"},{"extra":""}]}'
        )
    );

    protected $styles = array(
        'style' => array(
            'defaultName' => 'item-heading-style',
            'value'       => ''
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'heading';
    }

    public function getTitle() {
        return n2_('Heading');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--heading';
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemHeadingFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {

        return parent::getValues() + array(
                'priority'    => 'div',
                'fullwidth'   => 1,
                'nowrap'      => 0,
                'heading'     => n2_('Heading layer'),
                'title'       => '',
                'href'        => '#',
                'href-target' => '_self',
                'href-rel'    => '',

                'split-text-transform-origin'    => '50|*|50|*|0',
                'split-text-backface-visibility' => 1,

                'split-text-animation-in' => '',
                'split-text-delay-in'     => 0,

                'split-text-animation-out' => '',
                'split-text-delay-out'     => 0,

                'class' => ''
            );
    }

    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            if (is_array($link)) {
                $data->set('href', implode('', $link));
            } else {
                $data->set('href', $link);
            }
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('heading', $slide->fill($data->get('heading', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('style'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('style', $import->fixSection($data->get('style')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-heading-font', false, $this->fonts['font']['value'], array(
            'mode' => 'hover'
        ));

        new Style($row1, 'item-heading-style', false, $this->styles['style']['value'], array(
            'mode' => 'heading'
        ));
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-heading', n2_('General'));

        new Textarea($settings, 'heading', n2_('Text'), n2_('Heading'), array(
            'width' => 314
        ));

        new Select($settings, 'priority', 'Tag', 'div', array(
            'options' => array(
                'div' => 'div',
                '1'   => 'H1',
                '2'   => 'H2',
                '3'   => 'H3',
                '4'   => 'H4',
                '5'   => 'H5',
                '6'   => 'H6'
            )
        ));

        new OnOff($settings, 'fullwidth', n2_('Full width'), 1);
        new OnOff($settings, 'nowrap', n2_('No wrap'), 0, array(
            'tipLabel'       => n2_('No wrap'),
            'tipDescription' => n2_('Prevents the text from breaking into more lines')
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-heading-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'width'         => 248,
            'relatedFields' => array(
                'item_headinghref-target',
                'item_headinghref-rel'
            )
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));

        new HiddenFont($settings, 'font', false, '', array(
            'mode' => 'hover'
        ));
        new HiddenStyle($settings, 'style', false, '', array(
            'mode' => 'heading'
        ));
        $splitText = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-heading-split-text', n2_('Text animation'));
        new SplitTextAnimation($splitText, 'split-text-animation-in', n2_('Incoming'), '', array(
            'group'               => 'in',
            'relatedFont'         => 'item_headingfont',
            'relatedStyle'        => 'item_headingstyle',
            'transformOrigin'     => 'item_headingsplit-text-transform-origin',
            'preview'             => '<div class="{styleClassName}" style="width:{width}px;"><span class="{fontClassName}">{text}</span></div>',
            'linkedRelatedFields' => array(
                'linkedFields'  => array(
                    'item_headingsplit-text-animation-out'
                ),
                'relatedFields' => array(
                    'item_headingsplit-text-backface-visibility',
                    'item_headingsplit-text-transform-origin'
                )
            ),
            'relatedFields'       => array(
                'item_headingsplit-text-delay-in'
            ),
            'width'               => 136
        ));
        new Number($splitText, 'split-text-delay-in', n2_('Delay'), 0, array(
            'unit'  => 'ms',
            'min'   => 0,
            'style' => 'width:40px;'
        ));

        new SplitTextAnimation($splitText, 'split-text-animation-out', n2_('Outgoing'), '', array(
            'group'               => 'out',
            'relatedFont'         => 'item_headingfont',
            'relatedStyle'        => 'item_headingstyle',
            'transformOrigin'     => 'item_headingsplit-text-transform-origin',
            'preview'             => '<div class="{styleClassName}" style="width:{width}px;"><span class="{fontClassName}">{text}</span></div>',
            'linkedRelatedFields' => array(
                'linkedFields'  => array(
                    'item_headingsplit-text-animation-in'
                ),
                'relatedFields' => array(
                    'item_headingsplit-text-backface-visibility',
                    'item_headingsplit-text-transform-origin'
                )
            ),
            'relatedFields'       => array(
                'item_headingsplit-text-delay-out'
            ),
            'width'               => 136
        ));
        new Number($splitText, 'split-text-delay-out', n2_('Delay'), 0, array(
            'unit'  => 'ms',
            'min'   => 0,
            'style' => 'width:40px;'
        ));

        $transformOrigin = new MixedField($splitText, 'split-text-transform-origin', n2_('Transform origin'), '50|*|50|*|0');
        new NumberAutoComplete($transformOrigin, 'split-text-transform-origin-x', false, '', array(
            'sublabel' => 'X',
            'values'   => array(
                0,
                50,
                100
            ),
            'unit'     => '%',
            'wide'     => 4
        ));
        new NumberAutoComplete($transformOrigin, 'split-text-transform-origin-y', false, '', array(
            'sublabel' => 'Y',
            'values'   => array(
                0,
                50,
                100
            ),
            'unit'     => '%',
            'wide'     => 4
        ));
        new Number($transformOrigin, 'split-text-transform-origin-z', false, '', array(
            'sublabel' => 'Z',
            'unit'     => 'px',
            'wide'     => 4
        ));

        new OnOff($splitText, 'split-text-backface-visibility', n2_('Backface visibility'), 1);

        $advanced = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-heading-advanced', n2_('Advanced'));

        new Text($advanced, 'title', n2_('Title'), '', array(
            'style' => 'width:133px;'
        ));

        new Text($advanced, 'class', n2_('CSS Class'), '', array(
            'style' => 'width:133px;'
        ));
    

    }
}Item/Heading/ItemHeadingFrontend.php000064400000007445152356645660013424 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Heading;


use Nextend\Framework\Misc\Base64;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemHeadingFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $attributes = array();
        $inDelay  = max(0, intval($this->data->get('split-text-delay-in', 0))) / 1000;
        $outDelay = max(0, intval($this->data->get('split-text-delay-out', 0))) / 1000;

        $in  = $this->data->get('split-text-animation-in', '');
        $out = $this->data->get('split-text-animation-out', '');

        $transformOrigin    = implode('% ', explode('|*|', $this->data->get('split-text-transform-origin', '50|*|50|*|0'))) . 'px';
        $backfaceVisibility = $this->data->get('split-text-backface-visibility', 1) ? 'visible' : 'hidden';

        if (!empty($in) || !empty($out)) {
            if ($this->isEditor && $owner->underEdit) {
                $owner->addScript('new _N2.HeadingItemSplitTextAdmin(this, "' . $this->id . '", "' . $transformOrigin . '", "' . $backfaceVisibility . '",  "' . $in . '",' . $inDelay . ', "' . $out . '", ' . $outDelay . ');');
            } else {

                if (!empty($in)) {
                    $in = Base64::decode($in);
                } else {
                    $in = 'false';
                }
                if (!empty($out)) {
                    $out = Base64::decode($out);
                } else {
                    $out = 'false';
                }

                $owner->addScript('new _N2.FrontendItemHeadingSplitText(this, "' . $this->id . '", "' . $transformOrigin . '", "' . $backfaceVisibility . '",  ' . $in . ',' . $inDelay . ', ' . $out . ', ' . $outDelay . ');');
            }
        }
    
        $font = $owner->addFont($this->data->get('font'), 'hover');

        $style = $owner->addStyle($this->data->get('style'), 'heading');

        $linkAttributes = array(
            'class' => 'n2-ow'
        );
        if ($this->isEditor) {
            $linkAttributes['onclick'] = 'return false;';
        }

        $title = $this->data->get('title', '');
        if (!empty($title)) {
            $attributes['title'] = $title;
        }

        $href = $this->data->get('href', '');
        if (!empty($href) && $href != '#') {
            $linkAttributes['class'] .= ' ' . $font . $style;

            $font  = '';
            $style = '';
        }

        $linkAttributes['style'] = "display:" . ($this->data->get('fullwidth', 1) ? 'block' : 'inline-block') . ";";

        $strippedHtml = Sanitize::filter_allowed_html($owner->fill($this->data->get('heading', '')));

        return $this->heading($this->data->get('priority', 'div'), $attributes + array(
                "id"    => $this->id,
                "class" => $font . $style . " " . $owner->fill($this->data->get('class', '')) . ' n2-ss-item-content n2-ss-text n2-ow',
                "style" => "display:" . ($this->data->get('fullwidth', 1) ? 'block' : 'inline-block') . ";" . ($this->data->get('nowrap', 0) ? 'white-space:nowrap;' : '')
            ), $this->getLink(str_replace("\n", '<br>', $strippedHtml), $linkAttributes));
    }

    private function heading($type, $attributes, $content) {
        if (is_numeric($type) && $type > 0) {
            return Html::tag("h{$type}", $attributes, $content);
        }

        return Html::tag("div", $attributes, $content);
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    public function isAuto() {
        return !$this->data->get('fullwidth', 1);
    }
}Item/Image/ItemImageFrontend.php000064400000004777152356645660012577 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Image;


use Nextend\Framework\Parser\Common;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemImageFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $styles     = array();
        $linkStyles = array();

        $size = (array)Common::parse($this->data->get('size', ''));
        for ($i = 0; $i < 2; $i++) {
            if (is_numeric($size[$i])) {
                $size[$i] = $size[$i] . 'px';
            }
        }

        if (!empty($size[0]) && $size[0] != 'auto') {
            $styles[] = 'width:' . $size[0];
            if ($this->hasLink() && substr($size[0], -1) == '%') {
                $linkStyles[] = 'width:100%';
            }
            if (empty($size[1]) || $size[1] == 'auto') {
                $styles[] = 'height:auto';
            }
        }
        if (!empty($size[1]) && $size[1] != 'auto') {
            if (empty($size[0]) || $size[0] == 'auto') {
                $styles[] = 'width:auto';
            }
            $styles[] = 'height:' . $size[1];
        }

        $imageUrl = $this->data->get('image', '');

        if (empty($imageUrl)) {

            return '';
        }

        $image = $owner->fill($this->data->get('image', ''));

        $imageAttributes = array(
            "id"    => $this->id,
            "alt"   => $owner->fill($this->data->get('alt', '')),
            "class" => $owner->fill($this->data->get('cssclass', ''))
        );

        if (!empty($styles)) {
            $imageAttributes['style'] = implode(';', $styles);
        }

        $linkAttributes = array();
        if (!empty($linkStyles)) {
            $linkAttributes['style'] = implode(';', $linkStyles);
        }

        $title = $owner->fill($this->data->get('title', ''));
        if (!empty($title)) {
            $imageAttributes['title'] = $title;
        }

        $html = $owner->renderImage($this, $image, $imageAttributes);

        $style = $owner->addStyle($this->data->get('style'), 'heading');

        return Html::tag("div", array(
            "class" => $style . ' n2-ss-item-image-content n2-ss-item-content n2-ow-all'
        ), $this->getLink($html, $linkAttributes));
    }
}Item/Image/ItemImage.php000064400000017257152356645660011074 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Image;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Hidden;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemImage extends AbstractItem {

    protected $ordering = 3;

    protected $layerProperties = array("desktopportraitwidth" => "300");

    protected $styles = array(
        'style' => array(
            'defaultName' => 'item-image-style',
            'value'       => ''
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'image';
    }

    public function getTitle() {
        return n2_('Image');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--image';
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemImageFrontend($this, $id, $itemData, $layer);
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Style($row1, 'item-image-style', false, $this->styles['style']['value'], array(
            'mode' => 'box'
        ));
    }

    public function getValues() {

        return parent::getValues() + array(
                'image'          => '$ss3-frontend$/images/placeholder/image.png',
                'alt'            => '',
                'title'          => '',
                'href'           => '#',
                'href-target'    => '_self',
                'href-rel'       => '',
                'href-class'     => '',
                'size'           => 'auto|*|auto',
                'cssclass'       => '',
                'image-optimize' => 1
            );
    }

    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('image', $slide->fill($data->get('image', '')));
        $data->set('alt', $slide->fill($data->get('alt', '')));
        $data->set('title', $slide->fill($data->get('title', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('image'));
        $export->addVisual($data->get('style'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('image', $import->fixImage($data->get('image')));
        $data->set('style', $import->fixSection($data->get('style')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('image', ResourceTranslator::toUrl($data->get('image')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-image', n2_('General'));

        new FieldImage($settings, 'image', n2_('Image'), '', array(
            'relatedAlt' => 'item_imagealt',
            'width'      => 220
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-image-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'style'         => 'width:236px;',
            'relatedFields' => array(
                'item_imagehref-target',
                'item_imagehref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));

        $size = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-image-misc', n2_('Size'));
        $misc = new MixedField($size, 'size', false, 'auto|*|auto');
        new Text($misc, 'size-1', n2_('Width'), '', array(
            'style'          => 'width:60px;',
            'tipLabel'       => n2_('Width'),
            'tipDescription' => sprintf(n2_('Fix width for the %1$s.'), $this->getTitle())
        ));
        new Text($misc, 'size-2', n2_('Height'), '', array(
            'style'          => 'width:60px;',
            'tipLabel'       => n2_('Height'),
            'tipDescription' => sprintf(n2_('Fix height for the %1$s.'), $this->getTitle())
        ));

        $seo = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-image-seo', n2_('SEO'));
        new Text($seo, 'alt', 'SEO - ' . n2_('Alt tag'), '', array(
            'style' => 'width:133px;'
        ));
        new Text($seo, 'title', 'SEO - ' . n2_('Title'), '', array(
            'style' => 'width:133px;'
        ));
        $optimize = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-image-optimize', n2_('Optimize'));
        new OnOff($optimize, 'image-optimize', n2_('Optimize image'), 1, array(
            'tipLabel'       => n2_('Optimize image'),
            'tipDescription' => n2_('You can turn off the Layer image optimization for this image, to resize it for tablet and mobile.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1833-image-layer#optimize'
        ));
    

        $dev = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-image-dev', n2_('Advanced'));
        new Text($dev, 'href-class', n2_('CSS Class') . ' - ' . n2_('Link'), '', array(
            'tipLabel'       => n2_('CSS Class'),
            'tipDescription' => sprintf(n2_('Class on the %s element.'), '&lt;a&gt;'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1833-image-layer#advanced',
            'style'          => 'width:133px;'
        ));
        new Text($dev, 'cssclass', n2_('CSS Class') . ' - ' . n2_('Image'), '', array(
            'tipLabel'       => n2_('CSS Class'),
            'tipDescription' => sprintf(n2_('Class on the %s element.'), '&lt;img&gt;'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1833-image-layer#advanced',
            'style'          => 'width:133px;'
        ));

        new Hidden\HiddenStyle($settings, 'style', false, '', array(
            'mode' => 'box'
        ));
    
    }
}Item/Button/ItemButton.php000064400000017107152356645660011550 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Button;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\Icon;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemButton extends AbstractItem {

    protected $ordering = 4;

    protected $fonts = array(
        'font' => array(
            'defaultName' => 'item-button-font',
            'value'       => '{"data":[{"color":"ffffffff","size":"14||px","align":"center"}, {"extra":""}]}'
        )
    );

    protected $styles = array(
        'style' => array(
            'defaultName' => 'item-button-style',
            'value'       => '{"data":[{"backgroundcolor":"5cba3cff","padding":"10|*|30|*|10|*|30|*|px"}, {"extra":""}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'button';
    }

    public function getTitle() {
        return n2_('Button');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--button';
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemButtonFrontend($this, $id, $itemData, $layer);
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-button-font', false, $this->fonts['font']['value'], array(
            'mode' => 'link'
        ));

        new Style($row1, 'item-button-style', false, $this->styles['style']['value'], array(
            'mode' => 'button'
        ));
    }

    public function getValues() {

        return parent::getValues() + array(
                'content'       => n2_x('MORE', 'Button layer default text'),
                'nowrap'        => 1,
                'fullwidth'     => 0,
                'href'          => '#',
                'href-target'   => '_self',
                'href-rel'      => '',
                'class'         => '',
                'icon'          => '',
                'iconsize'      => '100',
                'iconspacing'   => '30',
                'iconplacement' => 'left',
            );
    }

    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('content', $slide->fill($data->get('content', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('style'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('style', $import->fixSection($data->get('style')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/button.n2less", array(
            "sliderid" => $renderable->elementId
        ));
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-button', n2_('General'));

        new Text($settings, 'content', n2_('Label'), n2_('Button'), array(
            'style' => 'width:302px;'
        ));
        new HiddenFont($settings, 'font', false, '', array(
            'mode' => 'link'
        ));
        new HiddenStyle($settings, 'style', false, '', array(
            'mode' => 'button'
        ));

        new OnOff($settings, 'fullwidth', n2_('Full width'), 1);
        new OnOff($settings, 'nowrap', n2_('No wrap'), 1, array(
            'tipLabel'       => n2_('No wrap'),
            'tipDescription' => n2_('Prevents the text from breaking into more lines')
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-button-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'relatedFields' => array(
                'item_buttonhref-target',
                'item_buttonhref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));
        $icon = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-button-icon', n2_('Icon'));
        new Icon($icon, 'icon', n2_('Icon'), '', array(
            'hasClear'      => true,
            'relatedFields' => array(
                'item_buttoniconsize',
                'item_buttoniconspacing',
                'item_buttoniconplacement'
            )
        ));
        new NumberSlider($icon, 'iconsize', n2_('Size'), 100, array(
            'min'       => 5,
            'max'       => 1000,
            'sliderMax' => 300,
            'step'      => 5,
            'wide'      => 4,
            'unit'      => 'px'
        ));
        new NumberSlider($icon, 'iconspacing', n2_('Spacing'), 30, array(
            'min'  => 0,
            'max'  => 300,
            'step' => 1,
            'wide' => 4,
            'unit' => '%'
        ));
        new Select($icon, 'iconplacement', n2_('Placement'), '', array(
            'options' => array(
                'left'  => n2_('Left'),
                'right' => n2_('Right')
            )
        ));

        $dev = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-button-dev', n2_('Advanced'));
        new Text($dev, 'class', n2_('CSS Class'), '', array(
            'style'          => 'width: 302px;',
            'tipLabel'       => n2_('CSS Class'),
            'tipDescription' => sprintf(n2_('Class on the %s element.'), '&lt;a&gt;'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1834-button-layer#advanced'
        ));

    
    }
}Item/Button/ItemButtonFrontend.php000064400000005457152356645660013255 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Item\Button;


use Nextend\Framework\Icon\Icon;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemButtonFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $this->loadResources($owner);

        $font = $owner->addFont($this->data->get('font'), 'link');

        $html = Html::openTag("div", array(
            "class" => "n2-ss-button-container n2-ss-item-content n2-ow " . $font . ($this->data->get('nowrap', 1) ? ' n2-ss-nowrap' : '') . ($this->isAuto() ? ' n2-ss-button-container--non-full-width' : '')
        ));

        $content = '<div>' . Sanitize::filter_allowed_html($owner->fill($this->data->get("content"))) . '</div>';

        $attrs = array();
        $icon = $this->data->get('icon');
        if ($icon) {
            $iconPlacement = $this->data->get('iconplacement', 'left');
            $iconData      = Icon::render($icon);
            if ($iconData) {
                $iconStyle = 'font-size:' . $this->data->get('iconsize') . '%;';
                if ($iconPlacement == 'right') {
                    $iconStyle .= 'margin-left:' . ($this->data->get('iconspacing') / 100) . 'em;';
                } else {
                    $iconStyle .= 'margin-right:' . ($this->data->get('iconspacing') / 100) . 'em;';
                }
                $iconHTML = '<span class="n2i ' . $iconData['class'] . '" style="' . $iconStyle . '">' . $iconData['ligature'] . '</span>';
                if ($iconPlacement == 'right') {
                    $content = $content . $iconHTML;
                } else {
                    $content = $iconHTML . $content;
                }

                $attrs['data-iconplacement'] = $iconPlacement;
            }
        }
    

        $style = $owner->addStyle($this->data->get('style'), 'heading');

        $html .= $this->getLink('<div>' . $content . '</div>', $attrs + array(
                "class" => "{$style} n2-ow " . $owner->fill($this->data->get('class', ''))
            ), true);

        $html .= Html::closeTag("div");

        return $html;
    }

    /**
     * @param AbstractRenderableOwner $owner
     */
    public function loadResources($owner) {
        $owner->addLess(self::getAssetsPath() . "/button.n2less", array(
            "sliderid" => $owner->getElementID()
        ));
    }

    public function isAuto() {
        return !$this->data->get('fullwidth', 0);
    }
}Component/AbstractComponent.php000064400000100407152356645660012671 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Component;

use Nextend\Framework\Data\Data;
use Nextend\Framework\Parser\Color;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;
use Nextend\SmartSlider3\BackupSlider\ImportSlider;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\ComponentContainer;
use Nextend\SmartSlider3\Renderable\Placement\AbstractPlacement;
use Nextend\SmartSlider3\Renderable\Placement\PlacementAbsolute;
use Nextend\SmartSlider3\Renderable\Placement\PlacementDefault;
use Nextend\SmartSlider3\Renderable\Placement\PlacementNormal;
use Nextend\SmartSlider3\Slider\Slide;

abstract class AbstractComponent {

    public static $isAdmin = false;

    /**
     * @var Slide
     */
    protected $owner;

    /**
     * @var Style
     */
    public $style;

    protected $type = '';

    protected $name = '';
    /**
     * @var AbstractComponent|bool
     */
    protected $group;

    /**
     * @var AbstractPlacement
     */
    protected $placement;

    /**
     * @var ComponentContainer
     */
    protected $container = false;

    protected $fontSizeModifier = 100;

    protected $attributes = array(
        'class' => 'n2-ss-layer n2-ow',
        'style' => ''
    );

    public $data;

    protected $localStyle = array();

    protected $localRawStyles = array();

    protected $hasBackground = false;

    /**
     * AbstractBuilderComponent constructor.
     *
     * @param int                                 $index
     * @param AbstractRenderableOwner             $owner
     * @param AbstractComponent|bool              $group
     * @param                                     $data
     */
    public function __construct($index, $owner, $group, $data) {
        $this->owner = $owner;
        $this->group = $group;

        $this->style = new Style($this);

        $this->data = new Data($data);

        $this->fontSizeModifier = $this->data->get('desktopportraitfontsize', 100);
        if (!is_numeric($this->fontSizeModifier)) {
            $this->fontSizeModifier = 100;
        }

        switch ($this->getPlacement()) {
            case 'normal':
                $this->placement = new PlacementNormal($this, $index);
                break;
            case 'default':
                $this->placement = new PlacementDefault($this, $index);
                break;
            case 'absolute':
            default:
                $this->placement = new PlacementAbsolute($this, $index);
                break;
        }
    }

    public function getPlacement() {

        if ($this->data->has('pm')) {
            return $this->data->get('pm');
        }

        if ($this->group->getType() == 'slide') {
            return 'absolute';
        }

        return 'normal';
    }

    /**
     * @return Slide
     */
    public function getOwner() {
        return $this->owner;
    }

    public function isRenderAllowed() {
        $generatorVisible = $this->data->get('generatorvisible', '');
        if ($this->owner->isComponentVisible($generatorVisible) && !self::$isAdmin) {
            $filled = $this->owner->fill($generatorVisible);
            if (empty($filled)) {
                return false;
            }
        }

        return true;
    }

    public abstract function render($isAdmin);

    protected function renderContainer($isAdmin) {

        if ($this->container) {
            return $this->container->render($isAdmin);
        }

        return '';
    }

    protected function admin() {

        $this->createProperty('id', '');
        $this->createProperty('uniqueclass', '');
        $this->createProperty('zindex', 2);
        $this->createProperty('class', '');
        $this->createProperty('name', $this->name);
        $this->createProperty('namesynced', 1);
        $this->createProperty('status');
        $this->createProperty('generatorvisible', '');

        $this->placement->adminAttributes($this->attributes);
    }

    public function spacingToPxValue($value) {
        $values = explode('|*|', $value);
        unset($values[4]);

        return array_map('intval', $values) + array(
                0,
                0,
                0,
                0
            );
    }

    protected function prepareHTML() {
        $this->attributes['data-sstype'] = $this->type;

        $id = $this->data->get('id', '');
        if (!empty($id)) {
            $this->attributes['id'] = $id;
        }

        $class = $this->data->get('class', '');
        if (!empty($class)) {
            $this->attributes['class'] .= ' ' . $this->getOwner()
                                                     ->fill($class);
        }

        $uniqueClass = $this->data->get('uniqueclass', '');
        if (!empty($uniqueClass)) {
            $this->addUniqueClass($uniqueClass . $this->owner->unique);
        }

        $zIndex = intval($this->data->get('zindex', 2));
        if ($zIndex != 2) {
            $this->attributes['style'] .= 'z-index:' . $zIndex . ';';
        }

    }

    protected function addUniqueClass($class) {
        $this->attributes['class'] .= ' ' . $class;
    }

    protected function runPlugins() {
        $this->pluginRotation();
        $this->pluginAnimations();
    
        $this->pluginShowOn();
        $this->pluginFontSize();
        $this->pluginParallax();
    }

    protected function renderPlugins($html) {

        return $this->pluginCrop($html);
    }

    private function pluginRotation() {

        $rotation = $this->data->get('rotation', 0);
        if ($rotation) {
            $this->createProperty('rotation', 0);
            $this->attributes['style'] .= 'transform:rotate(' . $rotation . 'deg);';
        }
    }

    private function pluginCrop($html) {

        $cropStyle = $this->data->get('crop', 'visible');

        if (self::$isAdmin) {
            if ($cropStyle == 'auto') {
                $cropStyle = 'hidden';
            }
        } else {
            if ($cropStyle == 'auto') {
                $this->attributes['class'] .= ' n2_container_scrollable';
            }
        }

        if ($cropStyle == 'mask') {
            $cropStyle = 'hidden';
            $html      = Html::tag('div', array('class' => 'n2-ss-layer-mask n2-ss-layer-wrapper'), $html);

            $this->attributes['data-animatableselector'] = '.n2-ss-layer-mask';
        }

        if (!empty($cropStyle) && $cropStyle != 'visible') {
            $this->attributes['style'] .= 'overflow:' . $cropStyle . ';';
        }

        if (self::$isAdmin) {
            $crop = $this->data->get('crop', 'visible');
            if (empty($crop)) {
                $crop = 'visible';
            }
            $this->attributes['data-crop'] = $crop;
        }

        return $html;
    }

    /**
     * Transform V1 animations to V2
     *
     * @param $data
     *
     * @return array
     */
    private function pluginAnimationsConvertV1ToV2($data) {
        if (empty($data)) {
            return array();
        }

        if (isset($data['in'])) {
            if (!isset($data['basic'])) {
                $data['basic'] = array(
                    'in' => array()
                );
            } else if (!isset($data['basic']['in'])) {
                $data['basic']['in'] = array();
            }
            $this->pluginAnimationsConvertV1ToV2RemoveName($data['in']);
            if (isset($data['in'][0]['delay']) && isset($data['repeatable']) && $data['repeatable'] == 1) {
                if ($data['in'][0]['delay'] > 0) {
                    $data['startDelay'] = $data['in'][0]['delay'];
                }
                unset($data['in'][0]['delay']);
            }
            $data['basic']['in']['keyFrames'] = $data['in'];
            unset($data['in']);
        }

        if (isset($data['specialZeroIn'])) {
            if (isset($data['basic']['in'])) {
                $data['basic']['in']['specialZero'] = $data['specialZeroIn'];
            }
            unset($data['specialZeroIn']);
        }

        if (isset($data['transformOriginIn'])) {
            if (isset($data['basic']['in'])) {
                $data['basic']['in']['transformOrigin'] = $data['transformOriginIn'];
            }
            unset($data['transformOriginIn']);
        }

        if (isset($data['loop'])) {
            if (!isset($data['basic'])) {
                $data['basic'] = array(
                    'loop' => array()
                );
            } else if (!isset($data['basic']['loop'])) {
                $data['basic']['loop'] = array();
            }
            $this->pluginAnimationsConvertV1ToV2RemoveName($data['loop']);
            $data['basic']['loop']['keyFrames'] = $data['loop'];
            unset($data['loop']);
        }

        if (isset($data['repeatCount'])) {
            if (isset($data['basic']['loop'])) {
                $data['basic']['loop']['repeatCount'] = $data['repeatCount'];
            }
            unset($data['repeatCount']);
        }

        if (isset($data['repeatStartDelay'])) {
            if (isset($data['basic']['loop'])) {
                $data['basic']['loop']['repeatStartDelay'] = $data['repeatStartDelay'];
            }
            unset($data['repeatStartDelay']);
        }

        if (isset($data['transformOriginLoop'])) {
            if (isset($data['basic']['loop'])) {
                $data['basic']['loop']['transformOrigin'] = $data['transformOriginLoop'];
            }
            unset($data['transformOriginLoop']);
        }

        if (isset($data['out'])) {
            if (!isset($data['basic'])) {
                $data['basic'] = array(
                    'out' => array()
                );
            } else if (!isset($data['basic']['out'])) {
                $data['basic']['out'] = array();
            }
            $this->pluginAnimationsConvertV1ToV2RemoveName($data['out']);
            $data['basic']['out']['keyFrames'] = $data['out'];
            unset($data['out']);
        }

        if (isset($data['transformOriginOut'])) {
            if (isset($data['basic']['out'])) {
                $data['basic']['out']['transformOrigin'] = $data['transformOriginOut'];
            }
            unset($data['transformOriginOut']);
        }

        if (!isset($data['instantOut']) || $data['instantOut'] == '1') {
            if (empty($data['outPlayEvent']) && $this->owner->getSlider()->params->get('layer-animation-play-mode') === 'forced') {
                $data['outPlayEvent'] = 'InstantOut';
            }
        }

        if (isset($data['instantOut'])) {
            unset($data['instantOut']);
        }

        return $data;
    }

    private function pluginAnimationsConvertV1ToV2RemoveName(&$keyFrames) {
        for ($i = 0; $i < count($keyFrames); $i++) {
            if (isset($keyFrames[$i]['name'])) {
                unset($keyFrames[$i]['name']);
            }
        }

    }


    private function pluginAnimations() {
        $animations = $this->data->get('animv2', -1);
        if ($animations === -1) {
            $animationsV1 = $this->data->get('animations', -1);
            if ($animationsV1 !== -1) {
                $animations = $this->pluginAnimationsConvertV1ToV2($animationsV1);
            }
        }

        if ($animations === -1) {
            $animations = '';
        }

        if (!empty($animations)) {

            if (isset($animations['basic'])) {
                /**
                 * Empty keyFrame gets encoded as array instead of object and arrays might have extra property
                 * which can mess up animations.
                 */
                if (isset($animations['basic']['in'])) {
                    if (empty($animations['basic']['in'])) {
                        unset($animations['basic']['in']);
                    } else {
                        self::fixAnimationArray($animations['basic']['in'], 'keyFrames');
                    }
                }
                if (isset($animations['basic']['loop'])) {
                    if (empty($animations['basic']['loop'])) {
                        unset($animations['basic']['loop']);
                    } else {
                        self::fixAnimationArray($animations['basic']['loop'], 'keyFrames');
                    }
                }
                if (isset($animations['basic']['out'])) {
                    if (empty($animations['basic']['out'])) {
                        unset($animations['basic']['out']);
                    } else {
                        self::fixAnimationArray($animations['basic']['out'], 'keyFrames');
                    }
                }
            }

            if (isset($animations['reveal'])) {
                if (isset($animations['reveal']['in'])) {
                    $animations['reveal']['in'] = (object)$animations['reveal']['in'];
                }
                if (isset($animations['reveal']['out'])) {
                    $animations['reveal']['out'] = (object)$animations['reveal']['out'];
                }
            }

            $this->attributes['data-animv2'] = json_encode($animations);
        }

        $this->pluginAnimationGetEventAttributes();
    
    }

    private static function fixAnimationArray(&$array, $key) {
        if (isset($array[$key]) && is_array($array[$key])) {
            for ($i = 0; $i < count($array[$key]); $i++) {
                $array[$key][$i] = (object)$array[$key][$i];
            }
        }
    }


    private function pluginAnimationGetEventAttributes() {

        if (!self::$isAdmin) {
            $elementID = $this->owner->getElementID();

            $click = $this->data->get('click');
            if (!empty($click)) {
                $this->attributes['data-click'] = $this->pluginAnimationParseEventCode($click, $elementID);
            }
            $mouseenter = $this->data->get('mouseenter');
            if (!empty($mouseenter)) {
                $this->attributes['data-mouseenter'] = $this->pluginAnimationParseEventCode($mouseenter, $elementID);
            }
            $mouseleave = $this->data->get('mouseleave');
            if (!empty($mouseleave)) {
                $this->attributes['data-mouseleave'] = $this->pluginAnimationParseEventCode($mouseleave, $elementID);
            }
            $play = $this->data->get('play');
            if (!empty($play)) {
                $this->attributes['data-play'] = $this->pluginAnimationParseEventCode($play, $elementID);
            }
            $pause = $this->data->get('pause');
            if (!empty($pause)) {
                $this->attributes['data-pause'] = $this->pluginAnimationParseEventCode($pause, $elementID);
            }
            $stop = $this->data->get('stop');
            if (!empty($stop)) {
                $this->attributes['data-stop'] = $this->pluginAnimationParseEventCode($stop, $elementID);
            }
        } else {

            $click = $this->data->get('click');
            if (!empty($click)) {
                $this->attributes['data-click'] = $click;
            }
            $mouseenter = $this->data->get('mouseenter');
            if (!empty($mouseenter)) {
                $this->attributes['data-mouseenter'] = $mouseenter;
            }
            $mouseleave = $this->data->get('mouseleave');
            if (!empty($mouseleave)) {
                $this->attributes['data-mouseleave'] = $mouseleave;
            }
            $play = $this->data->get('play');
            if (!empty($play)) {
                $this->attributes['data-play'] = $play;
            }
            $pause = $this->data->get('pause');
            if (!empty($pause)) {
                $this->attributes['data-pause'] = $pause;
            }
            $stop = $this->data->get('stop');
            if (!empty($stop)) {
                $this->attributes['data-stop'] = $stop;
            }
        }
    }

    private function pluginAnimationParseEventCode($code, $elementId) {
        if (preg_match('/^[a-zA-Z0-9_\-,]+$/', $code)) {
            if (is_numeric($code)) {
                $code = "window['" . $elementId . "'].changeTo(" . ($code - 1) . ");";
            } else if ($code == 'next') {
                $code = "window['" . $elementId . "'].next();";
            } else if ($code == 'previous') {
                $code = "window['" . $elementId . "'].previous();";
            } else {
                $code = "n2ss.trigger(e.currentTarget, '" . $code . "');";
            }
        }

        return $code;
    }


    private function pluginShowOn() {

        if (self::$isAdmin) {
            $this->createDeviceProperty('', 1);
        }

        $devices = $this->owner->getAvailableDevices();

        foreach ($devices as $device) {
            if (!$this->isShown($device)) {
                $this->attributes['data-hide' . $device] = 1;
                $this->style->addOnly($device, '', 'display:none');
            }
        }
    }

    public function isShown($device) {

        return intval($this->data->get($device, 1)) === 1;
    }

    protected function pluginFontSize() {

        if (self::$isAdmin) {
            $this->createDeviceProperty('fontsize', 100);
        }

        $devices         = $this->owner->getAvailableDevices();
        $desktopFontSize = $this->data->get('desktopportraitfontsize');
        foreach ($devices as $device) {
            $fontSize = $this->data->get($device . 'fontsize');
            if ($fontSize !== '') {
                if ($device === 'desktopportrait') {
                    if ($fontSize != 100) {
                        $this->style->add($device, '', '--ssfont-scale:' . $fontSize / 100 . '');
                    }
                } else if ($fontSize != $desktopFontSize) {
                    $this->style->add($device, '', '--ssfont-scale:' . $fontSize / 100 . '');
                }
            }
        }
    }

    public function pluginParallax() {

        $parallax = intval($this->data->get('parallax', 0));
        if (self::$isAdmin) {
            $this->attributes['data-parallax'] = $parallax;
        } else if ($parallax >= 1) {
            /**
             * FlatSome theme use data-parallax and we are conflicting with it.
             *
             * @see SSDEV-2769
             */
            $this->attributes['data-ssparallax'] = $parallax;
        }

    }

    public function createProperty($name, $default = null) {
        $this->attributes['data-' . $name] = $this->data->get($name, $default);
    }

    public function createColorProperty($name, $allowVariable, $default = null) {
        $value = $this->data->get($name, $default);

        if (!$allowVariable || ($value !== NULL && substr($value, 0, 1) != '{')) {
            $l = strlen($value);
            if (($l != 6 && $l != 8) || !preg_match('/^[0-9A-Fa-f]+$/', $value)) {
                $value = $default;
            }
        }
        $this->attributes['data-' . $name] = $value;
    }

    public function createDeviceProperty($name, $default = null) {
        $device = 'desktopportrait';

        $this->attributes['data-' . $device . $name] = $this->data->get($device . $name, $default);

        $devices = array(
            'desktoplandscape',
            'tabletportrait',
            'tabletlandscape',
            'mobileportrait',
            'mobilelandscape'
        );
        foreach ($devices as $device) {
            $this->attributes['data-' . $device . $name] = $this->data->get($device . $name, null);
        }
    }

    protected function renderBackground() {

        $backgroundStyle = '';
        $image           = $this->owner->fill($this->data->get('bgimage', ''));
        if ($image != '') {
            $x = intval($this->data->get('bgimagex', 50));
            $y = intval($this->data->get('bgimagey', 50));

            $backgroundStyle     .= '--n2bgimage:URL("' . esc_url(ResourceTranslator::toUrl($image)) . '");';
            $backgroundStyle     .= 'background-position:50% 50%,' . $x . '% ' . $y . '%;';
            $this->hasBackground = true;

            $optimizedData = $this->owner->optimizeImageWebP($image);

            if (isset($optimizedData['normal'])) {
                $this->owner->addImage($optimizedData['normal']['src']);

                $this->localRawStyles[] = '.n2webp @rule-inner{--n2bgimage: URL(' . $optimizedData['normal']['src'] . ')}';
            }

            if (isset($optimizedData['medium'])) {
                $this->owner->addImage($optimizedData['medium']['src']);

                $this->localRawStyles[] = '@media (max-width: ' . $optimizedData['medium']['width'] . 'px) {.n2webp @rule-inner{--n2bgimage: URL(' . $optimizedData['medium']['src'] . ')}}';
            }

            if (isset($optimizedData['small'])) {
                $this->owner->addImage($optimizedData['small']['src']);

                $this->localRawStyles[] = '@media (max-width: ' . $optimizedData['small']['width'] . 'px) {.n2webp @rule-inner{--n2bgimage: URL(' . $optimizedData['small']['src'] . ')}}';

            }
        }

        $color = $this->owner->fill($this->data->get('bgcolor', '00000000'));
        if (empty($color)) {
            $color = '00000000';
        }
        $gradient = $this->data->get('bgcolorgradient', 'off');
        $colorEnd = $this->owner->fill($this->data->get('bgcolorgradientend', '00000000'));
        if (empty($colorEnd)) {
            $colorEnd = '00000000';
        }
        $this->addLocalStyle('normal', 'background', $this->getBackgroundCSS($color, $gradient, $colorEnd, $backgroundStyle) . $backgroundStyle);


        $colorHover       = $this->owner->fill($this->data->get('bgcolor-hover'));
        $gradientHover    = $this->data->get('bgcolorgradient-hover');
        $colorEndHover    = $this->owner->fill($this->data->get('bgcolorgradientend-hover'));
        $isHoverDifferent = false;
        if (!empty($colorHover) && $colorHover != $color) {
            $isHoverDifferent = true;
        }
        if (!empty($gradientHover) && $gradientHover != $gradient) {
            $isHoverDifferent = true;
        }
        if (!empty($colorEndHover) && $colorEndHover != $colorEnd) {
            $isHoverDifferent = true;
        }
        if ($isHoverDifferent) {
            if (empty($colorHover)) $colorHover = $color;
            if (empty($gradientHover)) $gradientHover = $gradient;
            if (empty($colorEndHover)) $colorEndHover = $colorEnd;

            $this->addLocalStyle('hover', 'background', $this->getBackgroundCSS($colorHover, $gradientHover, $colorEndHover, $backgroundStyle, true));
        }
    }

    protected function getBackgroundCSS($color, $gradient, $colorend, $backgroundStyle, $isHover = false) {
        if (Color::hex2alpha($color) != 0 || ($gradient != 'off' && Color::hex2alpha($colorend) != 0) || $isHover) {
            $this->hasBackground = true;
            switch ($gradient) {
                case 'horizontal':
                    return '--n2bggradient:linear-gradient(to right, ' . Color::colorToRGBA($color) . ' 0%,' . Color::colorToRGBA($colorend) . ' 100%);';
                case 'vertical':
                    return '--n2bggradient:linear-gradient(to bottom, ' . Color::colorToRGBA($color) . ' 0%,' . Color::colorToRGBA($colorend) . ' 100%);';
                case 'diagonal1':
                    return '--n2bggradient:linear-gradient(45deg, ' . Color::colorToRGBA($color) . ' 0%,' . Color::colorToRGBA($colorend) . ' 100%);';
                case 'diagonal2':
                    return '--n2bggradient:linear-gradient(135deg, ' . Color::colorToRGBA($color) . ' 0%,' . Color::colorToRGBA($colorend) . ' 100%);';
                case 'off':
                default:
                    if (!empty($backgroundStyle)) {
                        return "--n2bggradient:linear-gradient(" . Color::colorToRGBA($color) . ", " . Color::colorToRGBA($color) . ");";
                    } else {
                        return "background-color:" . Color::colorToRGBA($color) . ';';
                    }

                    break;
            }
        }

        return '';
    }

    /**
     * @param AbstractRenderableOwner $slide
     * @param array                   $layer
     */
    public static function getFilled($slide, &$layer) {
        if (!empty($layer['uniqueclass'])) {
            $layer['uniqueclass'] .= $slide->unique;
        }
        if (!empty($layer['class'])) {
            $layer['class'] = $slide->fill($layer['class']);
        }
    }

    /**
     * @param ExportSlider $export
     * @param array        $layer
     */
    public static function prepareExport($export, $layer) {

    }

    /**
     * @param ImportSlider $import
     * @param array        $layer
     */
    public static function prepareImport($import, &$layer) {

    }

    /**
     * @param array $layer
     */
    public static function prepareSample(&$layer) {

    }

    public function getAttribute($key) {
        if (isset($this->attributes[$key])) {
            return $this->attributes[$key];
        }

        return null;
    }

    public function setAttribute($key, $value) {
        $this->attributes[$key] = $value;
    }

    protected function addLocalStyle($group, $name, $style) {
        if (!empty($style)) {
            for ($i = 0; $i < count($this->localStyle); $i++) {
                if ($this->localStyle[$i]['group'] == $group) {
                    $this->localStyle[$i]['css'][$name] = $style;
                    break;
                }
            }
        }
    }

    protected function serveLocalStyle() {

        $uniqueClassSelector = $this->getUniqueClassSelector();

        $css = '';
        for ($i = 0; $i < count($this->localStyle); $i++) {
            $style = '';
            foreach ($this->localStyle[$i]['css'] as $_css) {
                $style .= $_css;
            }
            if (!empty($style)) {
                $css .= '@rule' . $this->localStyle[$i]['selector'] . '{' . $style . '}';
            }
        }
        if (!empty($css)) {
            $this->getOwner()
                 ->addCSS(str_replace('@rule', $uniqueClassSelector, $css));
        }

        if (!empty($this->localRawStyles)) {
            foreach ($this->localRawStyles as $localRawStyle) {
                $this->getOwner()
                     ->addCSS(str_replace('@rule', $uniqueClassSelector, $localRawStyle));
            }
        }

        foreach ($this->style->styles as $device => $styles) {
            foreach ($styles as $selector => $stylesData) {
                $this->getOwner()
                     ->addDeviceCSS($device, $uniqueClassSelector . $selector . '{' . implode(';', $stylesData) . '}');
            }
        }
    }

    public function getUniqueClassSelector() {

        $uniqueClass = $this->data->get('uniqueclass', '');
        if (empty($uniqueClass)) {
            $uniqueClass = self::generateUniqueIdentifier('n-uc-');
            $this->data->set('uniqueclass', $uniqueClass);
        }

        $uniqueClass .= $this->owner->unique;

        return 'div#' . $this->owner->getElementID() . ' .' . $uniqueClass;
    }

    protected static function generateUniqueIdentifier($prefix = 'n', $length = 12) {
        $characters       = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString     = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[mt_rand(0, $charactersLength - 1)];
        }

        return $prefix . $randomString;
    }


    public static function translateUniqueIdentifier($layers, $isAction = true) {
        $idTranslation = array();

        self::translateUniqueIdentifierID($idTranslation, $layers);

        self::translateUniqueIdentifierParentID($idTranslation, $layers);

        if ($isAction) {
            self::translateUniqueIdentifierClass($layers);
        }

        return $layers;
    }

    private static function translateUniqueIdentifierID(&$idTranslation, &$layers) {
        if (is_array($layers)) {
            for ($i = 0; $i < count($layers); $i++) {
                if (!empty($layers[$i]['id'])) {
                    $newId                            = self::generateUniqueIdentifier();
                    $idTranslation[$layers[$i]['id']] = $newId;
                    $layers[$i]['id']                 = $newId;
                }
                if (isset($layers[$i]['type'])) {
                    switch ($layers[$i]['type']) {
                        case 'row':
                            self::translateUniqueIdentifierID($idTranslation, $layers[$i]['cols']);
                            break;
                        case 'col':
                        case 'content':
                            self::translateUniqueIdentifierID($idTranslation, $layers[$i]['layers']);
                            break;
                    }
                }
            }
        }
    }

    private static function translateUniqueIdentifierParentID(&$idTranslation, &$layers) {
        if (is_array($layers)) {
            for ($i = 0; $i < count($layers); $i++) {
                if (!empty($layers[$i]['parentid'])) {
                    if (isset($idTranslation[$layers[$i]['parentid']])) {
                        $layers[$i]['parentid'] = $idTranslation[$layers[$i]['parentid']];
                    } else {
                        $layers[$i]['parentid'] = '';
                    }
                }
                if (isset($layers[$i]['type'])) {
                    switch ($layers[$i]['type']) {
                        case 'row':
                            self::translateUniqueIdentifierParentID($idTranslation, $layers[$i]['cols']);
                            break;
                        case 'col':
                        case 'content':
                            self::translateUniqueIdentifierParentID($idTranslation, $layers[$i]['layers']);
                            break;
                    }
                }
            }
        }
    }

    private static function translateUniqueIdentifierClass(&$layers) {
        if (is_array($layers)) {
            for ($i = 0; $i < count($layers); $i++) {
                if (!empty($layers[$i]['uniqueclass'])) {
                    $layers[$i]['uniqueclass'] = self::generateUniqueIdentifier('n-uc-');
                }
                if (isset($layers[$i]['type'])) {
                    switch ($layers[$i]['type']) {
                        case 'row':
                            self::translateUniqueIdentifierClass($layers[$i]['cols']);
                            break;
                        case 'col':
                        case 'content':
                            self::translateUniqueIdentifierClass($layers[$i]['layers']);
                            break;
                    }
                }
            }
        }
    }

    /**
     * @return string
     */
    public function getType() {
        return $this->type;
    }

    public static function innerAlignToStyle($innerAlign) {

        if ($innerAlign == 'left') {
            return 'text-align:left;--ssselfalign:var(--ss-fs);';
        } else if ($innerAlign == 'center') {
            return 'text-align:center;--ssselfalign:center;';
        } else if ($innerAlign == 'right') {
            return 'text-align:right;--ssselfalign:var(--ss-fe);';
        } else if ($innerAlign == '') {
            return '';
        }

        return 'text-align:inherit;--ssselfalign:inherit;';
    }

    public static function selfAlignToStyle($innerAlign) {

        if ($innerAlign == 'left') {
            return 'align-self:var(--ss-fs);';
        } else if ($innerAlign == 'center') {
            return 'align-self:center;';
        } else if ($innerAlign == 'right') {
            return 'align-self:var(--ss-fe);';
        } else if ($innerAlign == '') {
            return '';
        }

        return 'align-self:var(--ssselfalign);';
    }
}Component/ComponentCol.php000064400000034771152356645660011655 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Component;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\Parser\Link;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\ComponentContainer;

class ComponentCol extends AbstractComponent {

    protected $type = 'col';

    protected $colAttributes = array(
        'class' => 'n2-ss-layer-col n2-ss-layer-with-background n2-ss-layer-content',
        'style' => ''
    );

    protected $localStyle = array(
        array(
            "group"    => "normal",
            "selector" => '-inner',
            "css"      => array()
        ),
        array(
            "group"    => "hover",
            "selector" => '-inner:HOVER',
            "css"      => array()
        ),
    );

    protected $width;

    public function __construct($index, $owner, $group, $data) {
        parent::__construct($index, $owner, $group, $data);

        $this->container = new ComponentContainer($owner, $this, $data['layers']);
        $this->data->un_set('layers');

        $this->upgradeData();

        $this->attributes['style'] = '';

        $devices = $this->owner->getAvailableDevices();

        $desktopportraitInnerAlign = $this->data->get('desktopportraitinneralign', 'inherit');
        $desktopPortraitMaxWidth   = intval($this->data->get('desktopportraitmaxwidth'));

        foreach ($devices as $device) {

            if ($this->data->has($device . 'padding')) {
                $padding = $this->data->get($device . 'padding');
                if (!empty($padding)) {
                    $paddingValues = $this->spacingToPxValue($padding);

                    $this->style->add($device, '-inner', 'padding:' . implode('px ', $paddingValues) . 'px');
                }
            }

            if ($this->data->has($device . 'maxwidth')) {
                $maxWidth = intval($this->data->get($device . 'maxwidth'));
                if ($maxWidth > 0) {
                    $this->style->add($device, '', 'max-width: ' . $maxWidth . 'px');
                } else if ($device != 'desktopportrait' && $maxWidth != $desktopPortraitMaxWidth) {
                    $this->style->add($device, '', 'max-width: none');
                }
            }

            $innerAlign = $this->data->get($device . 'inneralign', '');

            if ($device == 'desktopportrait') {
                if ($desktopportraitInnerAlign != 'inherit') {
                    $this->style->add($device, '-inner', AbstractComponent::innerAlignToStyle($innerAlign));
                }
            } else if ($desktopportraitInnerAlign != $innerAlign) {
                $this->style->add($device, '-inner', AbstractComponent::innerAlignToStyle($innerAlign));
            }


            $verticalAlign = $this->data->get($device . 'verticalalign');
            if (!empty($verticalAlign)) {
                $this->style->add($device, '-inner', 'justify-content:' . $verticalAlign);
            }


            if ($this->data->has($device . 'order')) {
                $order = intval($this->data->get($device . 'order'));
                if ($order > 0) {
                    $this->style->add($device, '', 'order: ' . $order);
                }
            }
        }

        $this->renderBackground();

        $borderRadius = intval($this->data->get('borderradius', '0'));
        $this->addLocalStyle('normal', 'borderradius', $this->getBorderRadiusCSS($borderRadius));

        $borderRadiusHover = intval($this->data->get('borderradius-hover'));
        if (!empty($borderRadiusHover) && $borderRadiusHover != $borderRadius) {
            $this->addLocalStyle('hover', 'borderradius', $this->getBorderRadiusCSS($borderRadiusHover));
        }


        $boxShadow = $this->data->get('boxshadow', '0|*|0|*|0|*|0|*|00000080');
        $this->addLocalStyle('normal', 'boxshadow', $this->getBoxShadowCSS($boxShadow));

        $boxShadowHover = $this->data->get('boxshadow-hover');
        if (!empty($boxShadowHover) && $boxShadowHover != $boxShadow) {
            $this->addLocalStyle('hover', 'boxshadow', $this->getBoxShadowCSS($boxShadowHover));
        }


        $borderWidth = $this->data->get('borderwidth', '1|*|1|*|1|*|1');
        $borderStyle = $this->data->get('borderstyle', 'none');
        $borderColor = $this->data->get('bordercolor', 'ffffffff');

        if ($borderStyle != 'none') {
            $this->addLocalStyle('normal', 'border', $this->getBorderCSS($borderWidth, $borderStyle, $borderColor));
        }

        $borderWidthHover = $this->data->get('borderwidth-hover');
        $borderStyleHover = $this->data->get('borderstyle-hover');
        $borderColorHover = $this->data->get('bordercolor-hover');
        $isHoverDifferent = false;
        if (!empty($borderWidthHover) || $borderWidthHover != $borderWidth) {
            $isHoverDifferent = true;
        }
        if (!empty($borderStyleHover) || $borderStyleHover != $borderStyle) {
            $isHoverDifferent = true;
        }
        if (!empty($borderColorHover) || $borderColorHover != $borderColor) {
            $isHoverDifferent = true;
        }
        if ($isHoverDifferent) {
            if (empty($borderWidthHover)) $borderWidthHover = $borderWidth;
            if (empty($borderStyleHover)) $borderStyleHover = $borderStyle;
            if (empty($borderColorHover)) $borderColorHover = $borderColor;

            $this->addLocalStyle('hover', 'border', $this->getBorderCSS($borderWidthHover, $borderStyleHover, $borderColorHover));
        }

        $this->placement->attributes($this->attributes);


        $width = explode('/', $this->data->get('colwidth', 1));
        if (count($width) == 2) {
            if ($width[0] == 0 || $width[1] == 0) {
                $width[0] = 1;
                $width[1] = 2;
                $this->data->set('colwidth', '1/2');
            }
            $width = floor($width[0] / $width[1] * 1000) / 10;
        } else {
            $width = 100;
        }

        $this->width = $width;

        if (!AbstractComponent::$isAdmin) {
            $this->makeLink();
        }
    }

    public function setWidth($device) {
        $this->style->add($device, '', 'width:' . $this->width . '%');
    }

    public function setWidthAuto($device) {
        $this->style->add($device, '', 'width:auto');
    }

    public function setWrapAfterWidth($device, $width, $gutter) {
        $this->style->add($device, '', 'width:calc(' . $width . '% - ' . $gutter . 'px)');

    }

    protected function upgradeData() {

        if ($this->data->has('verticalalign')) {
            /**
             * Upgrade data to device specific
             */
            $this->data->set('desktopportraitverticalalign', $this->data->get('verticalalign'));
            $this->data->un_set('verticalalign');
        }
    }

    public function getPlacement() {
        return 'default';
    }

    private function getBorderRadiusCSS($borderRadius) {
        if ($borderRadius > 0) {
            return 'border-radius:' . $borderRadius . 'px;';
        }

        return '';
    }

    private function getBoxShadowCSS($boxShadow) {
        $boxShadowArray = explode('|*|', $boxShadow);
        if (count($boxShadowArray) == 5 && ($boxShadowArray[0] != 0 || $boxShadowArray[1] != 0 || $boxShadowArray[2] != 0 || $boxShadowArray[3] != 0) && Color::hex2alpha($boxShadowArray[4]) != 0) {
            return 'box-shadow:' . $boxShadowArray[0] . 'px ' . $boxShadowArray[1] . 'px ' . $boxShadowArray[2] . 'px ' . $boxShadowArray[3] . 'px ' . Color::colorToRGBA($boxShadowArray[4]) . ';';
        }

        return '';
    }

    private function getBorderCSS($width, $style, $color) {
        if ($style != 'none') {

            $values    = explode('|*|', $width);
            $unit      = 'px';
            $values[4] = '';
            $css       = 'border-width:' . implode($unit . ' ', $values) . ';';

            $css .= 'border-style:' . $style . ';';
            $css .= 'border-color:' . Color::colorToRGBA($color) . ';';

            return $css;
        }

        return '';
    }

    private function makeLink() {

        $linkV1 = $this->data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target) = array_pad((array)Common::parse($linkV1), 2, '');
            $this->data->un_set('link');
            $this->data->set('href', $link);
            $this->data->set('href-target', $target);
        }

        $link = $this->data->get('href');

        if (($link != '#' && !empty($link))) {
            $target = $this->data->get('href-target');

            $link                          = Link::parse($this->owner->fill($link), $this->attributes);
            $this->attributes['data-href'] = $link;
            $this->attributes['tabindex']  = 0;
            $this->attributes['role']      = 'button';

            $ariaLabel = $this->data->get('aria-label');
            if (!empty($ariaLabel)) {
                $this->attributes['aria-label'] = $this->owner->fill($ariaLabel);
            }

            if (!isset($this->attributes['onclick']) && !isset($this->attributes['data-n2-lightbox'])) {
                if (!empty($target) && $target != '_self') {
                    $this->attributes['data-target'] = $target;
                }
                $this->attributes['data-n2click'] = "url";
            }

            $this->attributes['data-force-pointer'] = "";
        }
    }

    public function render($isAdmin) {
        if ($this->isRenderAllowed()) {

            $this->runPlugins();

            $this->serveLocalStyle();
            if ($isAdmin) {
                $this->admin();
            }
            $this->prepareHTML();

            $html = Html::tag('div', $this->colAttributes, parent::renderContainer($isAdmin));
            $html = $this->renderPlugins($html);

            return Html::tag('div', $this->attributes, $html);
        }

        return '';
    }

    protected function addUniqueClass($class) {
        $this->attributes['class']    .= ' ' . $class;
        $this->colAttributes['class'] .= ' ' . $class . '-inner';
    }

    protected function admin() {

        $linkV1 = $this->data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target) = array_pad((array)Common::parse($linkV1), 2, '');
            $this->data->un_set('link');
            $this->data->set('href', $link);
            $this->data->set('href-target', $target);
        }

        $this->createProperty('href', '');
        $this->createProperty('href-target', '_self');
        $this->createProperty('aria-label', '');

        $this->createProperty('colwidth');

        $this->createProperty('bgimage', '');
        $this->createProperty('bgimagex', 50);
        $this->createProperty('bgimagey', 50);
        $this->createColorProperty('bgcolor', true, '00000000');
        $this->createProperty('bgcolorgradient', 'off');
        $this->createColorProperty('bgcolorgradientend', true, '00000000');
        $this->createColorProperty('bgcolor-hover', true);
        $this->createProperty('bgcolorgradient-hover');
        $this->createColorProperty('bgcolorgradientend-hover', true);

        $this->createProperty('borderradius', '0');
        $this->createProperty('borderradius-hover');

        $this->createProperty('boxshadow', '0|*|0|*|0|*|0|*|00000080');
        $this->createProperty('boxshadow-hover');

        $this->createProperty('borderwidth', '1|*|1|*|1|*|1');
        $this->createProperty('borderstyle', 'none');
        $this->createProperty('bordercolor', 'FFFFFFFF');
        $this->createProperty('borderwidth-hover');
        $this->createProperty('borderstyle-hover');
        $this->createProperty('bordercolor-hover');

        $this->createProperty('opened', 1);

        $this->createDeviceProperty('maxwidth', '0');
        $this->createDeviceProperty('padding', '10|*|10|*|10|*|10');
        $this->createDeviceProperty('verticalalign', 'flex-start');
        $this->createDeviceProperty('inneralign', 'inherit');
        $this->createDeviceProperty('order');

        parent::admin();
    }


    /**
     * @param ExportSlider $export
     * @param array        $layer
     */
    public static function prepareExport($export, $layer) {
        if (!empty($layer['bgimage'])) {
            $export->addImage($layer['bgimage']);
        }

        $export->prepareLayer($layer['layers']);
    }

    public static function prepareImport($import, &$layer) {
        if (!empty($layer['bgimage'])) {
            $layer['bgimage'] = $import->fixImage($layer['bgimage']);
        }

        $import->prepareLayers($layer['layers']);
    }

    public static function prepareSample(&$layer) {
        if (!empty($layer['bgimage'])) {
            $layer['bgimage'] = ResourceTranslator::toUrl($layer['bgimage']);
        }

        ModelSlides::prepareSample($layer['layers']);
    }

    /**
     * @param AbstractRenderableOwner $slide
     * @param array                   $layer
     */
    public static function getFilled($slide, &$layer) {
        AbstractComponent::getFilled($slide, $layer);

        $fields = array(
            'bgimage',
            'href'
        );

        foreach ($fields as $field) {
            if (!empty($layer[$field])) {
                $layer[$field] = $slide->fill($layer[$field]);
            }
        }

        $slide->fillLayers($layer['layers']);
    }

    public function getOrder($device) {

        $order = intval($this->data->get($device . 'order'));
        if ($order > 0) {
            return $order;
        }

        return 10;
    }

    public function getWidth() {

        return $this->width;
    }

    public static $compareOrderDevice;

    /**
     * @param ComponentCol $column1
     * @param ComponentCol $column2
     *
     * @return int
     */
    public static function compareOrder($column1, $column2) {

        $order1 = $column1->getOrder(self::$compareOrderDevice);
        $order2 = $column2->getOrder(self::$compareOrderDevice);

        if ($order1 == $order2) {
            return 0;
        }

        return ($order1 < $order2) ? -1 : 1;
    }
}Component/ComponentContent.php000064400000016242152356645660012543 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Component;


use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\ComponentContainer;

class ComponentContent extends AbstractComponent {

    protected $type = 'content';

    protected $name = 'Content';

    protected $colAttributes = array(
        'class' => 'n2-ss-section-main-content n2-ss-layer-with-background n2-ss-layer-content n2-ow',
        'style' => ''
    );

    protected $localStyle = array(
        array(
            "group"    => "normal",
            "selector" => '-inner',
            "css"      => array()
        ),
        array(
            "group"    => "hover",
            "selector" => '-inner:HOVER',
            "css"      => array()
        ),
    );

    public function getPlacement() {
        return 'default';
    }

    public function __construct($index, $owner, $group, $data) {
        parent::__construct($index, $owner, $group, $data);
        $this->container = new ComponentContainer($owner, $this, $data['layers']);
        $this->data->un_set('layers');

        $this->upgradeData();

        $this->attributes['style'] = '';


        $devices = $this->owner->getAvailableDevices();

        $desktopPortraitSelfAlign = $this->data->get('desktopportraitselfalign', 'inherit');

        $desktopportraitInnerAlign = $this->data->get('desktopportraitinneralign', 'inherit');

        foreach ($devices as $device) {
            $padding = $this->data->get($device . 'padding');
            if (!empty($padding)) {
                $paddingValues = $this->spacingToPxValue($padding);

                $this->style->add($device, '-inner', 'padding:' . implode('px ', $paddingValues) . 'px');
            }

            $maxWidth = intval($this->data->get($device . 'maxwidth', 0));
            if ($maxWidth > 0) {
                $this->style->add($device, '', 'max-width: ' . $maxWidth . 'px');
            }

            $innerAlign = $this->data->get($device . 'inneralign', '');

            if ($device == 'desktopportrait') {
                if ($desktopportraitInnerAlign != 'inherit') {
                    $this->style->add($device, '-inner', AbstractComponent::innerAlignToStyle($innerAlign));
                }
            } else if ($desktopportraitInnerAlign != $innerAlign) {
                $this->style->add($device, '-inner', AbstractComponent::innerAlignToStyle($innerAlign));
            }


            $selfAlign = $this->data->get($device . 'selfalign', '');

            if ($device == 'desktopportrait') {
                if ($desktopPortraitSelfAlign != 'inherit') {
                    $this->style->add($device, '', AbstractComponent::selfAlignToStyle($selfAlign));
                }
            } else if ($desktopPortraitSelfAlign != $selfAlign) {
                $this->style->add($device, '', AbstractComponent::selfAlignToStyle($selfAlign));
            }


            $verticalAlign = $this->data->get($device . 'verticalalign');
            if (!empty($verticalAlign)) {
                $this->style->add($device, '-inner', 'justify-content:' . $verticalAlign);
            }
        }

        $this->renderBackground();

        $this->placement->attributes($this->attributes);

    }

    protected function upgradeData() {

        if ($this->data->has('verticalalign')) {
            /**
             * Upgrade data to device specific
             */
            $this->data->set('desktopportraitverticalalign', $this->data->get('verticalalign'));
            $this->data->un_set('verticalalign');
        }
    }

    public function render($isAdmin) {
        if ($this->isRenderAllowed()) {
            if ($isAdmin || $this->hasBackground || count($this->container->getLayers())) {

                $this->runPlugins();

                $this->serveLocalStyle();
                if ($isAdmin) {
                    $this->admin();
                }

                $this->prepareHTML();

                $this->attributes['data-hasbackground'] = $this->hasBackground ? '1' : '0';

                $html = Html::tag('div', $this->colAttributes, parent::renderContainer($isAdmin));
                $html = $this->renderPlugins($html);

                return Html::tag('div', $this->attributes, $html);
            }
        }

        return '';
    }

    protected function addUniqueClass($class) {
        $this->attributes['class']    .= ' ' . $class;
        $this->colAttributes['class'] .= ' ' . $class . '-inner';
    }

    protected function admin() {


        $this->createDeviceProperty('verticalalign', 'center');
        $this->createDeviceProperty('inneralign', 'inherit');
        $this->createDeviceProperty('selfalign', 'center');
        $this->createDeviceProperty('maxwidth', '0');
        $this->createDeviceProperty('padding', '10|*|10|*|10|*|10');

        $this->createProperty('bgimage', '');
        $this->createProperty('bgimagex', 50);
        $this->createProperty('bgimagey', 50);

        $this->createColorProperty('bgcolor', true, '00000000');
        $this->createProperty('bgcolorgradient', 'off');
        $this->createColorProperty('bgcolorgradientend', true, '00000000');
        $this->createColorProperty('bgcolor-hover', true);
        $this->createProperty('bgcolorgradient-hover');
        $this->createColorProperty('bgcolorgradientend-hover', true);

        $this->createProperty('opened', 1);


        $this->createProperty('id', '');
        $this->createProperty('uniqueclass', '');
        $this->createProperty('class', '');
        $this->createProperty('status');
        $this->createProperty('generatorvisible', '');

        $this->placement->adminAttributes($this->attributes);
    }


    /**
     * @param ExportSlider $export
     * @param array        $layer
     */
    public static function prepareExport($export, $layer) {
        if (!empty($layer['bgimage'])) {
            $export->addImage($layer['bgimage']);
        }

        $export->prepareLayer($layer['layers']);
    }

    public static function prepareImport($import, &$layer) {
        if (!empty($layer['bgimage'])) {
            $layer['bgimage'] = $import->fixImage($layer['bgimage']);
        }

        $import->prepareLayers($layer['layers']);
    }

    public static function prepareSample(&$layer) {
        if (!empty($layer['bgimage'])) {
            $layer['bgimage'] = ResourceTranslator::toUrl($layer['bgimage']);
        }

        ModelSlides::prepareSample($layer['layers']);
    }

    /**
     * @param AbstractRenderableOwner $slide
     * @param array                   $layer
     */
    public static function getFilled($slide, &$layer) {
        AbstractComponent::getFilled($slide, $layer);

        if (!empty($layer['bgimage'])) {
            $layer['bgimage'] = $slide->fill($layer['bgimage']);
        }

        $slide->fillLayers($layer['layers']);
    }
}Component/ComponentLayer.php000064400000006101152356645660012176 0ustar00<?php

namespace Nextend\SmartSlider3\Renderable\Component;

use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;
use Nextend\SmartSlider3\Renderable\Item\ItemFactory;

class ComponentLayer extends AbstractComponent {

    protected $type = 'layer';

    /** @var AbstractItemFrontend */
    private $item;

    public function __construct($index, $owner, $group, $data) {

        parent::__construct($index, $owner, $group, $data);


        $this->attributes['style'] = '';

        $item = $this->data->get('item');
        if (empty($item)) {
            $items = $this->data->get('items');
            $item  = $items[0];
        }

        $this->item = ItemFactory::create($this, $item);

        $this->placement->attributes($this->attributes);
    }

    public function render($isAdmin) {
        if ($this->isRenderAllowed()) {

            $this->runPlugins();

            $this->serveLocalStyle();

            $this->prepareHTML();

            if ($isAdmin) {
                $renderedItem = $this->item->renderAdmin();
            } else {
                $renderedItem = $this->item->render();
            }

            if ($renderedItem === false) {
                return '';
            }

            if ($this->item->needHeight()) {
                $this->attributes['class'] .= ' n2-ss-layer--need-height';
            }

            if ($this->item->isAuto()) {
                $this->attributes['class'] .= ' n2-ss-layer--auto';
            }

            $html = $this->renderPlugins($renderedItem);

            if ($isAdmin) {
                $this->admin();
            }

            return Html::tag('div', $this->attributes, $html);
        }

        return '';
    }

    /**
     * @param AbstractRenderableOwner $slide
     * @param array                   $layer
     */
    public static function getFilled($slide, &$layer) {
        AbstractComponent::getFilled($slide, $layer);

        if (empty($layer['item'])) {
            $layer['item'] = $layer['items'][0];
            unset($layer['items']);
        }
        ItemFactory::getFilled($slide, $layer['item']);
    }

    public static function prepareExport($export, $layer) {
        if (empty($layer['item'])) {
            $layer['item'] = $layer['items'][0];
            unset($layer['items']);
        }

        ItemFactory::prepareExport($export, $layer['item']);

    }

    public static function prepareImport($import, &$layer) {
        if (empty($layer['item'])) {
            $layer['item'] = $layer['items'][0];
            unset($layer['items']);
        }

        $layer['item'] = ItemFactory::prepareImport($import, $layer['item']);
    }

    public static function prepareSample(&$layer) {
        if (empty($layer['item'])) {
            $layer['item'] = $layer['items'][0];
            unset($layer['items']);
        }

        $layer['item'] = ItemFactory::prepareSample($layer['item']);
    }
}Component/ComponentRow.php000064400000037274152356645660011710 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Component;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\Parser\Link;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Application\Model\ModelSlides;
use Nextend\SmartSlider3\BackupSlider\ExportSlider;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\ComponentContainer;

class ComponentRow extends AbstractComponent {

    protected $type = 'row';

    protected $rowAttributes = array(
        'class' => 'n2-ss-layer-row n2-ss-layer-with-background',
        'style' => ''
    );

    protected $rowAttributesInner = array(
        'class' => 'n2-ss-layer-row-inner '
    );

    protected $localStyle = array(
        array(
            "group"    => "normal",
            "selector" => '-inner',
            "css"      => array()
        ),
        array(
            "group"    => "hover",
            "selector" => '-inner:HOVER',
            "css"      => array()
        ),
    );

    protected $html = '';

    public function __construct($index, $owner, $group, $data) {
        parent::__construct($index, $owner, $group, $data);
        $this->container = new ComponentContainer($owner, $this, $data['cols']);
        $this->data->un_set('cols');
        $this->data->un_set('inneralign');

        $fullWidth = $this->data->get('fullwidth', 1);
        if ($fullWidth) {
            $this->attributes['class'] .= ' n2-ss-layer--block';
        } else {
            $this->attributes['class'] .= ' n2-ss-layer--auto';
        }

        $devices = $this->owner->getAvailableDevices();

        $desktopportraitInnerAlign = $this->data->get('desktopportraitinneralign', 'inherit');

        $desktopportraitGutter = $this->getGutter('desktopportrait');
        if (empty($desktopportraitGutter)) {
            $desktopportraitGutter = 0;
        }

        $desktopportraitWrapAfter = $this->data->get('desktopportraitwrapafter', 0);
        if (empty($desktopportraitWrapAfter)) {
            $desktopportraitWrapAfter = 0;
        }


        foreach ($devices as $device) {
            $padding = $this->data->get($device . 'padding');
            if (!empty($padding)) {
                $paddingValues = $this->spacingToPxValue($padding);

                $this->style->add($device, '-inner', 'padding:' . implode('px ', $paddingValues) . 'px');
            }


            $innerAlign = $this->data->get($device . 'inneralign', '');

            if ($device == 'desktopportrait') {
                if ($desktopportraitInnerAlign != 'inherit') {
                    $this->style->add($device, '-inner', AbstractComponent::innerAlignToStyle($innerAlign));
                }
            } else if ($desktopportraitInnerAlign != $innerAlign) {
                $this->style->add($device, '-inner', AbstractComponent::innerAlignToStyle($innerAlign));
            }


            $gutter    = $this->getGutter($device);
            $wrapAfter = $this->data->get($device . 'wrapafter', '');
            if ($wrapAfter === '') {
                $wrapAfter = $desktopportraitWrapAfter; // inherit desktop value
            }

            if ($gutter !== null) {
                $sideGutter = $gutter / 2;
                /**
                 * +1 to fix Safari line break
                 *
                 * @see https://bugs.webkit.org/show_bug.cgi?id=225962
                 * @see SSDEV-2980
                 */
                $this->style->add($device, '-inner > .n2-ss-layer-row-inner', 'width:calc(100% + ' . ($gutter + 1) . 'px);margin:-' . $sideGutter . 'px');
                $this->style->add($device, '-inner > .n2-ss-layer-row-inner > .n2-ss-layer[data-sstype="col"]', 'margin:' . $sideGutter . 'px');
            } else {
                $gutter = $desktopportraitGutter;
            }


            $columns      = $this->getSortedColumns($device);
            $columnsCount = count($columns);

            if ($wrapAfter > 0 || !$fullWidth) {

                $this->style->add($device, '-inner > .n2-ss-layer-row-inner', 'flex-wrap:wrap;');
                if ($fullWidth && $wrapAfter <= $columnsCount) {
                    $rows = array_fill(0, ceil($columnsCount / $wrapAfter), 0);
                    for ($i = 0; $i < $columnsCount; $i++) {
                        $rowIndex        = floor($i / $wrapAfter);
                        $rows[$rowIndex] += $columns[$i]->getWidth();
                    }

                    for ($i = 0; $i < $columnsCount; $i++) {
                        $rowIndex = floor($i / $wrapAfter);
                        $columns[$i]->setWrapAfterWidth($device, floor($columns[$i]->getWidth() / $rows[$rowIndex] * 100), $gutter);
                    }
                } else {
                    foreach ($columns as $column) {
                        $column->setWidthAuto($device);
                    }
                }

            } else {
                $this->style->add($device, '-inner > .n2-ss-layer-row-inner', 'flex-wrap:nowrap;');
                if ($fullWidth) {
                    foreach ($columns as $column) {
                        $column->setWidth($device);
                    }
                } else {
                    foreach ($columns as $column) {
                        $column->setWidthAuto($device);
                    }
                }
            }
        }

        $this->renderBackground();

        $this->attributes['class'] .= ' n2-ss-has-self-align';

        $stretch = $this->data->get('stretch', 0);
        if ($stretch) {
            $this->attributes['class'] .= ' n2-ss-stretch-layer';
        }

        $borderWidth = $this->data->get('borderwidth', '1|*|1|*|1|*|1');
        $borderStyle = $this->data->get('borderstyle', 'none');
        $borderColor = $this->data->get('bordercolor', 'ffffffff');

        if ($borderStyle != 'none') {
            $this->addLocalStyle('normal', 'border', $this->getBorderCSS($borderWidth, $borderStyle, $borderColor));
        }

        $borderWidthHover = $this->data->get('borderwidth-hover');
        $borderStyleHover = $this->data->get('borderstyle-hover');
        $borderColorHover = $this->data->get('bordercolor-hover');
        $isHoverDifferent = false;
        if (!empty($borderWidthHover) || $borderWidthHover != $borderWidth) {
            $isHoverDifferent = true;
        }
        if (!empty($borderStyleHover) || $borderStyleHover != $borderStyle) {
            $isHoverDifferent = true;
        }
        if (!empty($borderColorHover) || $borderColorHover != $borderColor) {
            $isHoverDifferent = true;
        }
        if ($isHoverDifferent) {
            if (empty($borderWidthHover)) $borderWidthHover = $borderWidth;
            if (empty($borderStyleHover)) $borderStyleHover = $borderStyle;
            if (empty($borderColorHover)) $borderColorHover = $borderColor;

            $this->addLocalStyle('hover', 'border', $this->getBorderCSS($borderWidthHover, $borderStyleHover, $borderColorHover));
        }

        $borderRadius = intval($this->data->get('borderradius', 0));
        $this->addLocalStyle('normal', 'borderradius', $this->getBorderRadiusCSS($borderRadius));

        $borderRadiusHover = intval($this->data->get('borderradius-hover'));
        if (!empty($borderRadiusHover) && $borderRadiusHover != $borderRadius) {
            $this->addLocalStyle('hover', 'borderradius', $this->getBorderRadiusCSS($borderRadiusHover));
        }

        $boxShadow = $this->data->get('boxshadow', '0|*|0|*|0|*|0|*|00000080');
        $this->addLocalStyle('normal', 'boxshadow', $this->getBoxShadowCSS($boxShadow));

        $boxShadowHover = $this->data->get('boxshadow-hover');
        if (!empty($boxShadowHover) && $boxShadowHover != $boxShadow) {
            $this->addLocalStyle('hover', 'boxshadow', $this->getBoxShadowCSS($boxShadowHover));
        }

        $this->placement->attributes($this->attributes);


        if (!AbstractComponent::$isAdmin) {
            $this->makeLink();
        }
    }

    public function getGutter($device) {
        return $this->data->get($device . 'gutter', null);
    }

    public function render($isAdmin) {
        if ($this->isRenderAllowed()) {

            $this->runPlugins();

            $this->serveLocalStyle();
            if ($isAdmin) {
                $this->admin();
            }
            $this->prepareHTML();

            $html = Html::tag('div', $this->rowAttributes, Html::tag('div', $this->rowAttributesInner, parent::renderContainer($isAdmin)));
            $html = $this->renderPlugins($html);

            return Html::tag('div', $this->attributes, $html);
        }

        return '';
    }

    /**
     * @return ComponentCol[]
     */
    protected function getColumns() {
        $layers  = $this->container->getLayers();
        $columns = array();
        for ($i = 0; $i < count($layers); $i++) {
            if ($layers[$i] instanceof ComponentCol) {
                $columns[] = $layers[$i];
            }
        }

        return $columns;
    }

    protected function getSortedColumns($device) {

        $columns = $this->getColumns();
        for ($i = count($columns) - 1; $i >= 0; $i--) {
            if (!$columns[$i]->isShown($device)) {
                array_splice($columns, $i, 1);
            }
        }
        ComponentCol::$compareOrderDevice = $device;
        usort($columns, array(
            ComponentCol::class,
            'compareOrder'
        ));

        return $columns;
    }

    protected function addUniqueClass($class) {
        $this->attributes['class']    .= ' ' . $class;
        $this->rowAttributes['class'] .= ' ' . $class . '-inner';
    }

    private function makeLink() {

        $linkV1 = $this->data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target) = array_pad((array)Common::parse($linkV1), 2, '');
            $this->data->un_set('link');
            $this->data->set('href', $link);
            $this->data->set('href-target', $target);
        }

        $link = $this->data->get('href');

        if (($link != '#' && !empty($link))) {
            $target = $this->data->get('href-target');

            $link                          = Link::parse($this->owner->fill($link), $this->attributes);
            $this->attributes['data-href'] = $link;
            $this->attributes['tabindex']  = 0;
            $this->attributes['role']      = 'button';

            $ariaLabel = $this->data->get('aria-label');
            if (!empty($ariaLabel)) {
                $this->attributes['aria-label'] = $this->owner->fill($ariaLabel);
            }

            if (!isset($this->attributes['onclick']) && !isset($this->attributes['data-n2-lightbox'])) {
                if (!empty($target) && $target != '_self') {
                    $this->attributes['data-target'] = $target;
                }
                $this->attributes['data-n2click'] = "url";
            }

            $this->attributes['data-force-pointer'] = "";
        }
    }

    protected function admin() {

        $linkV1 = $this->data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target) = array_pad((array)Common::parse($linkV1), 2, '');
            $this->data->un_set('link');
            $this->data->set('href', $link);
            $this->data->set('href-target', $target);
        }

        $this->createProperty('href', '');
        $this->createProperty('href-target', '_self');
        $this->createProperty('aria-label', '');

        $this->createProperty('bgimage', '');
        $this->createProperty('bgimagex', 50);
        $this->createProperty('bgimagey', 50);

        $this->createColorProperty('bgcolor', true, '00000000');
        $this->createProperty('bgcolorgradient', 'off');
        $this->createColorProperty('bgcolorgradientend', true, '00000000');
        $this->createColorProperty('bgcolor-hover', true);
        $this->createProperty('bgcolorgradient-hover');
        $this->createColorProperty('bgcolorgradientend-hover', true);

        $this->createProperty('borderwidth', '1|*|1|*|1|*|1');
        $this->createProperty('borderstyle', 'none');
        $this->createProperty('bordercolor', 'FFFFFFFF');
        $this->createProperty('borderwidth-hover');
        $this->createProperty('borderstyle-hover');
        $this->createProperty('bordercolor-hover');

        $this->createProperty('borderradius', 0);
        $this->createProperty('borderradius-hover');

        $this->createProperty('boxshadow', '0|*|0|*|0|*|0|*|00000080');
        $this->createProperty('boxshadow-hover');

        $this->createProperty('fullwidth', '1');
        $this->createProperty('stretch', '0');

        $this->createProperty('opened', 1);

        $this->createDeviceProperty('padding', '10|*|10|*|10|*|10');

        $this->createDeviceProperty('gutter', 20);
        $this->createDeviceProperty('wrapafter', 0);
        $this->createDeviceProperty('inneralign', 'inherit');

        parent::admin();
    }


    /**
     * @param ExportSlider $export
     * @param array        $layer
     */
    public static function prepareExport($export, $layer) {
        if (!empty($layer['bgimage'])) {
            $export->addImage($layer['bgimage']);
        }

        $export->prepareLayer($layer['cols']);
    }

    public static function prepareImport($import, &$layer) {
        if (!empty($layer['bgimage'])) {
            $layer['bgimage'] = $import->fixImage($layer['bgimage']);
        }

        $import->prepareLayers($layer['cols']);
    }

    public static function prepareSample(&$layer) {
        if (!empty($layer['bgimage'])) {
            $layer['bgimage'] = ResourceTranslator::toUrl($layer['bgimage']);
        }

        ModelSlides::prepareSample($layer['cols']);
    }

    /**
     * @param AbstractRenderableOwner $slide
     * @param array                   $layer
     */
    public static function getFilled($slide, &$layer) {
        AbstractComponent::getFilled($slide, $layer);

        $fields = array(
            'bgimage',
            'href'
        );

        foreach ($fields as $field) {
            if (!empty($layer[$field])) {
                $layer[$field] = $slide->fill($layer[$field]);
            }
        }

        $slide->fillLayers($layer['cols']);
    }

    private function getBorderCSS($width, $style, $color) {
        if ($style != 'none') {

            $values    = explode('|*|', $width);
            $unit      = 'px';
            $values[4] = '';
            $css       = 'border-width:' . implode($unit . ' ', $values) . ';';

            $css .= 'border-style:' . $style . ';';
            $css .= 'border-color:' . Color::colorToRGBA($color) . ';';

            return $css;
        }

        return '';
    }

    private function getBorderRadiusCSS($borderRadius) {
        if ($borderRadius > 0) {
            return 'border-radius:' . $borderRadius . 'px;';
        }

        return '';
    }

    private function getBoxShadowCSS($boxShadow) {
        $boxShadowArray = explode('|*|', $boxShadow);
        if (count($boxShadowArray) == 5 && ($boxShadowArray[0] != 0 || $boxShadowArray[1] != 0 || $boxShadowArray[2] != 0 || $boxShadowArray[3] != 0) && Color::hex2alpha($boxShadowArray[4]) != 0) {
            return 'box-shadow:' . $boxShadowArray[0] . 'px ' . $boxShadowArray[1] . 'px ' . $boxShadowArray[2] . 'px ' . $boxShadowArray[3] . 'px ' . Color::colorToRGBA($boxShadowArray[4]) . ';';
        }

        return '';
    }
}Component/ComponentSlide.php000064400000013025152356645660012165 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Component;


use Nextend\Framework\Parser\Common;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\ComponentContainer;
use Nextend\SmartSlider3\Slider\Slide;
use Nextend\SmartSlider3\Slider\SliderType\SliderTypeFactory;

class ComponentSlide extends AbstractComponent {

    protected $type = 'slide';

    /**
     * @var Slide
     */
    protected $owner;

    /**
     * ComponentSlide constructor.
     *
     * @param Slide $owner
     * @param       $data
     */
    public function __construct($owner, $data) {
        if (!$owner->underEdit) {
            $data['layers'] = AbstractComponent::translateUniqueIdentifier($data['layers'], false);
        }

        parent::__construct(0, $owner, false, $data);

        $this->container = new ComponentContainer($owner, $this, $data['layers']);
        $this->data->un_set('layers');

        $this->container->addContentLayer($owner, $this);

        $this->upgradeData();

        $devices = $this->owner->getAvailableDevices();

        foreach ($devices as $device) {
            $padding = $this->data->get($device . 'padding');
            if (!empty($padding)) {
                $this->style->add($device, '', 'padding:' . implode('px ', explode('|*|', $padding)) . 'px');
            }
        }
    }

    protected function upgradeData() {

        if ($this->data->get('background-type') == '') {
            $this->data->set('background-type', 'color');
            if ($this->data->get('backgroundVideoMp4')) {
                $this->data->set('background-type', 'video');
            } else if ($this->data->get('backgroundImage')) {
                $this->data->set('background-type', 'image');
            }
        }

        $linkV1 = $this->data->getIfEmpty('link', '');
        if (!empty($linkV1)) {
            list($link, $target) = array_pad((array)Common::parse($linkV1), 2, '');
            $this->data->un_set('link');
            $this->data->set('href', $link);
            $this->data->set('href-target', $target);
        }
        $backgroundMode = $this->data->get('backgroundMode');
        if ($backgroundMode == 'fixed' || $backgroundMode == 'tile') {
            $this->data->set('backgroundMode', 'fill');
        }
    
        if ($this->data->get('publish_up') == '1970-01-01 00:00:00') {
            $this->data->set('publish_up', '0000-00-00 00:00:00');
        }

        if ($this->data->get('publish_down') == '1970-01-01 00:00:00') {
            $this->data->set('publish_down', '0000-00-00 00:00:00');
        }
    
    }

    public function getPlacement() {
        return 'default';
    }

    protected function admin() {
        /**
         * Hide on properties
         */
        $this->createDeviceProperty('', 1);

        $this->createProperty('title', '');
        $this->createProperty('publish_up', '0000-00-00 00:00:00');
        $this->createProperty('publish_down', '0000-00-00 00:00:00');
        $this->createProperty('published', 1);
        $this->createProperty('description', '');
        $this->createProperty('thumbnail', '');
        $this->createProperty('thumbnailAlt', '');
        $this->createProperty('thumbnailType', 'default');

        $this->createProperty('static-slide', 0);
        $this->createProperty('slide-duration', 0);
        $this->createProperty('ligthboxImage', '');

        $this->createProperty('record-slides', 0);

        SliderTypeFactory::getType($this->owner->getSlider()->data->get('type'))
                         ->createAdmin()
                         ->registerSlideAdminProperties($this);

        $this->createProperty('href', '');
        $this->createProperty('href-target', '');
        $this->createProperty('aria-label', '');


        $this->createProperty('background-type', 'color');

        $this->createProperty('backgroundColor', 'ffffff00');
        $this->createProperty('backgroundGradient', 'off');
        $this->createProperty('backgroundColorEnd', 'ffffff00');
        $this->createProperty('backgroundColorOverlay', 0);

        $this->createProperty('backgroundImage', '');
        $this->createProperty('backgroundFocusX', 50);
        $this->createProperty('backgroundFocusY', 50);
        $this->createProperty('backgroundImageOpacity', 100);
        $this->createProperty('backgroundImageBlur', 0);
        $this->createProperty('backgroundAlt', '');
        $this->createProperty('backgroundTitle', '');
        $this->createProperty('backgroundMode', 'default');
        $this->createProperty('backgroundBlurFit', 7);


        $this->createProperty('backgroundVideoMp4', '');
        $this->createProperty('backgroundVideoOpacity', 100);
        $this->createProperty('backgroundVideoLoop', 1);
        $this->createProperty('backgroundVideoReset', 1);
        $this->createProperty('backgroundVideoMode', 'fill');

        $this->createDeviceProperty('padding', '10|*|10|*|10|*|10');
    }

    public function render($isAdmin) {
        $this->attributes['data-sstype'] = $this->type;

        $this->placement->attributes($this->attributes);

        $this->serveLocalStyle();

        if ($isAdmin) {
            $this->admin();
        }

        $uniqueClass = $this->data->get('uniqueclass', '');
        if (!empty($uniqueClass)) {
            $this->addUniqueClass($uniqueClass . $this->owner->unique);
        }

        return Html::tag('div', $this->attributes, parent::renderContainer($isAdmin));
    }
}Component/Style.php000064400000002270152356645660010342 0ustar00<?php


namespace Nextend\SmartSlider3\Renderable\Component;


class Style {

    public $styles = array(
        'all'              => array(),
        'desktoplandscape' => array(),
        'tabletlandscape'  => array(),
        'tabletportrait'   => array(),
        'mobilelandscape'  => array(),
        'mobileportrait'   => array(),

    );

    /**
     * @var AbstractComponent
     */
    protected $component;

    /**
     * Style constructor.
     *
     * @param AbstractComponent $component
     */
    public function __construct($component) {
        $this->component = $component;
    }

    public function add($device, $selector, $css) {

        if (!empty($css)) {

            if ($device == 'desktopportrait') {
                $device = 'all';
            }

            $this->addOnly($device, $selector, $css);
        }
    }

    public function addOnly($device, $selector, $css) {

        if (!empty($css)) {

            if (!isset($this->styles[$device][$selector])) {
                $this->styles[$device][$selector] = array();
            }

            $this->styles[$device][$selector][] = $css;
        }
    }

}Joomla/Item/JoomlaModule/ItemJoomlaModule.php000064400000004647152426504100015203 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Joomla\Item\JoomlaModule;


use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemJoomlaModule extends AbstractItem {

    protected $ordering = 101;

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'joomlamodule';
    }

    public function getTitle() {
        return n2_('Joomla module');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--joomla';
    }

    public function getGroup() {
        return n2_x('Advanced', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemJoomlaModuleFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {
        return parent::getValues() + array(
                'positiontype'  => 'loadposition',
                'positionvalue' => ''
            );
    }


    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-joomlamodule', n2_('General'));

        new Warning($settings, '', sprintf(n2_('Please note, that %1$swe do not support%2$s the Joomla module layer!%3$sThe loaded module often needs code customizations what you have to do yourself, so we only suggest using this layer if you are a developer!'), '<b>', '</b>', '<br>'));

        new Select($settings, 'positiontype', n2_('Type'), 'loadposition', array(
            'options' => array(
                'loadposition' => 'Loadposition - Content plugin',
                'loadmoduleid' => 'Loadmoduleid - Content plugin',
                'module'       => 'Module - Modules Anywhere',
                'modulepos'    => 'Modulepos - Modules Anywhere'
            )
        ));

        new Text($settings, 'positionvalue', n2_('Value'), '', array(
            'style'          => 'width:302px;',
            'tipLabel'       => n2_('Position name or module ID'),
            'tipDescription' => n2_('The position name of your module (for Loadposition and Modulepos) or the module\'s ID (Module).'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1853-joomla-module-layer'
        ));
    }
}Joomla/Item/JoomlaModule/ItemJoomlaModuleFrontend.php000064400000000771152426504150016702 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Joomla\Item\JoomlaModule;


use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemJoomlaModuleFrontend extends AbstractItemFrontend {

    public function render() {

        return '<div class="n2-ss-item-content n2-ow">{' . $this->data->get('positiontype', '') . ' ' . $this->data->get('positionvalue', '') . '}</div>';
    }

    public function renderAdminTemplate() {

        return $this->render();
    }
}Item/ItemLoader.php000064400000005245152426504270010215 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item;


use Nextend\Framework\Plugin;
use Nextend\SmartSlider3\Platform\Joomla\JoomlaShim;
use Nextend\SmartSlider3\Renderable\Item\ItemFactory;
use Nextend\SmartSlider3Pro\Renderable\Item\AnimatedHeading\ItemAnimatedHeading;
use Nextend\SmartSlider3Pro\Renderable\Item\Area\ItemArea;
use Nextend\SmartSlider3Pro\Renderable\Item\Audio\ItemAudio;
use Nextend\SmartSlider3Pro\Renderable\Item\BeforeAfter\ItemBeforeAfter;
use Nextend\SmartSlider3Pro\Renderable\Item\Caption\ItemCaption;
use Nextend\SmartSlider3Pro\Renderable\Item\CircleCounter\ItemCircleCounter;
use Nextend\SmartSlider3Pro\Renderable\Item\Counter\ItemCounter;
use Nextend\SmartSlider3Pro\Renderable\Item\Countdown\ItemCountdown;
use Nextend\SmartSlider3Pro\Renderable\Item\HighlightedHeading\ItemHighlightedHeading;
use Nextend\SmartSlider3Pro\Renderable\Item\Html\ItemHtml;
use Nextend\SmartSlider3Pro\Renderable\Item\HtmlList\ItemHtmlList;
use Nextend\SmartSlider3Pro\Renderable\Item\Icon\ItemIcon;
use Nextend\SmartSlider3Pro\Renderable\Item\Iframe\ItemIframe;
use Nextend\SmartSlider3Pro\Renderable\Item\ImageArea\ItemImageArea;
use Nextend\SmartSlider3Pro\Renderable\Item\ImageBox\ItemImageBox;
use Nextend\SmartSlider3Pro\Renderable\Item\Input\ItemInput;
use Nextend\SmartSlider3Pro\Renderable\Item\ProgressBar\ItemProgressBar;
use Nextend\SmartSlider3Pro\Renderable\Item\Transition\ItemTransition;
use Nextend\SmartSlider3Pro\Renderable\Item\Video\ItemVideo;
use Nextend\SmartSlider3Pro\Renderable\Joomla\Item\JoomlaModule\ItemJoomlaModule;

class ItemLoader {

    public function __construct() {

        Plugin::addAction('PluggableFactoryRenderableItem', array(
            $this,
            'renderableItems'
        ));
    }

    /**
     * @param ItemFactory $factory
     */
    public function renderableItems($factory) {

        new ItemAnimatedHeading($factory);
        new ItemArea($factory);
        new ItemAudio($factory);
        new ItemCaption($factory);
        new ItemCircleCounter($factory);
        new ItemCounter($factory);
        new ItemCountdown($factory);
        new ItemHighlightedHeading($factory);
        new ItemHtml($factory);
        new ItemIcon($factory);
        new ItemIframe($factory);
        new ItemImageArea($factory);
        new ItemImageBox($factory);
        new ItemInput($factory);
        new ItemHtmlList($factory);
        new ItemProgressBar($factory);
        new ItemTransition($factory);
        new ItemVideo($factory);
        new ItemBeforeAfter($factory);
        if (!JoomlaShim::$isJoomla4) {
            new ItemJoomlaModule($factory);
        }
    
    }
}Item/Video/ItemVideo.php000064400000021610152426504340011113 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Video;


use Nextend\Framework\Data\Data;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\Video;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemVideo extends AbstractItem {

    protected $ordering = 20;

    protected $layerProperties = array(
        "desktopportraitwidth"  => 300,
        "desktopportraitheight" => 'auto'
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'video';
    }

    public function getTitle() {
        return n2_('Video');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--video';
    }

    public function getGroup() {
        return n2_x('Media', 'Layer group');
    }

    /**
     * @param Data $data
     */
    public function upgradeData($data) {
        if (!$data->has('aspect-ratio')) {
            $data->set('aspect-ratio', 'fill');
        }
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemVideoFrontend($this, $id, $itemData, $layer);
    }

    /**
     * @return array
     */
    public function getValues() {
        return parent::getValues() + array(
                'autoplay'         => 0,
                'video_mp4'        => '',
                'aspect-ratio'     => '16:9',
                'scroll-pause'     => 'partly-visible',
                'showcontrols'     => 1,
                'volume'           => 1,
                'loop'             => 0,
                'reset'            => 0,
                'videoplay'        => '',
                'videopause'       => '',
                'videoend'         => '',
                'ended'            => '',
                'playbutton'       => 1,
                'playbuttonwidth'  => 48,
                'playbuttonheight' => 48,
                'playbuttonimage'  => '',
                'poster'           => ''
            );
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('poster', $slide->fill($data->get('poster', '')));
        $data->set('video_mp4', $slide->fill($data->get('video_mp4', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('poster'));
        $export->addImage($data->get('video_mp4'));
        $export->addImage($data->get('playbuttonimage'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('poster', $import->fixImage($data->get('poster')));
        $data->set('video_mp4', $import->fixImage($data->get('video_mp4')));
        $data->set('playbuttonimage', $import->fixImage($data->get('playbuttonimage')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('poster', ResourceTranslator::toUrl($data->get('poster')));
        $data->set('video_mp4', ResourceTranslator::toUrl($data->get('video_mp4')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-video', n2_('General'));

        new Video($settings, 'video_mp4', n2_('MP4 video'), '', array(
            'width' => 220
        ));

        new FieldImage($settings, 'poster', n2_('Cover image'), '', array(
            'width' => 220
        ));

        new Select($settings, 'aspect-ratio', n2_('Aspect ratio'), '16:9', array(
            'options'            => array(
                '16:9'   => '16:9',
                '16:10'  => '16:10',
                '4:3'    => '4:3',
                'custom' => n2_('Custom'),
                'fill'   => n2_('Fill layer height')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'custom'
                    ),
                    'field'  => array(
                        'item_videoaspect-ratio-width',
                        'item_videoaspect-ratio-height'
                    )
                ),
                array(
                    'values' => array(
                        'fill'
                    ),
                    'field'  => array(
                        'item_videoaspect-ratio-notice'
                    )
                )
            )
        ));

        new Text\Number($settings, 'aspect-ratio-width', n2_('Width'), '16', array(
            'wide' => 4,
            'min'  => 1
        ));

        new Text\Number($settings, 'aspect-ratio-height', n2_('Height'), '9', array(
            'wide' => 4,
            'min'  => 1
        ));

        new Notice($settings, 'aspect-ratio-notice', n2_('Fill layer height'), n2_('Set on Style tab.'));

        $misc = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-video-misc', n2_('Video settings'));

        new Warning($misc, 'slide-background-notice', sprintf(n2_('Video autoplaying has a lot of limitations made by browsers. %1$sLearn about them.%2$s'), '<a href="https://smartslider.helpscoutdocs.com/article/1919-video-autoplay-handling" target="_blank">', '</a>'));

        new OnOff($misc, 'autoplay', n2_('Autoplay'), 0, array(
            'relatedFieldsOn' => array(
                'item_videoautoplay-notice'
            )
        ));

        new Select($misc, 'ended', n2_('When ended'), '', array(
            'options' => array(
                ''     => n2_('Do nothing'),
                'next' => n2_('Go to next slide')
            )
        ));

        new OnOff($misc, 'loop', n2_x('Loop', 'Video/Audio play'), 0, array(
            'relatedFieldsOff' => array(
                'item_videoended'
            )
        ));

        new Select($misc, 'volume', n2_('Volume'), 1, array(
            'options' => array(
                '0'    => n2_('Mute'),
                '0.25' => '25%',
                '0.5'  => '50%',
                '0.75' => '75%',
                '1'    => '100%'
            )
        ));

        new OnOff($misc, 'reset', n2_('Restart on slide change'), 0, array(
            'tipLabel'       => n2_('Restart on slide change'),
            'tipDescription' => n2_('Starts the video from the beginning when the slide is viewed again.')
        ));

        $display = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-video-display', n2_('Display'));

        new Select($display, 'fill-mode', n2_('Fill mode'), 'cover', array(
            'options' => array(
                'cover'   => n2_('Fill'),
                'contain' => n2_('Fit')
            )
        ));

        new OnOff($display, 'showcontrols', n2_('Controls'), 0);

        $load = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-video-dev', n2_('Loading'));

        new Select($load, 'preload', n2_('Preload'), 'metadata', array(
            'options' => array(
                'auto'     => 'Auto',
                'metadata' => 'metadata',
                'none'     => n2_('None')
            )
        ));

        new Select($load, 'scroll-pause', n2_('Pause on scroll'), 'partly-visible', array(
            'options'        => array(
                ''               => n2_('Never'),
                'partly-visible' => n2_('When partly visible'),
                'not-visible'    => n2_('When not visible'),
            ),
            'tipLabel'       => n2_('Pause on scroll'),
            'tipDescription' => n2_('You can pause the video when the visitor scrolls away from the slider')
        ));

        $playButton = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-video-playbutton', n2_('Play button'));
        new OnOff($playButton, 'playbutton', n2_('Play button'), 1, array(
            'relatedFieldsOn' => array(
                'item_videoplaybuttonwidth',
                'item_videoplaybuttonheight',
                'item_videoplaybuttonimage',
            )
        ));
        new Text\Number($playButton, 'playbuttonwidth', n2_('Width'), 48, array(
            'unit' => 'px',
            'wide' => 4
        ));
        new Text\Number($playButton, 'playbuttonheight', n2_('Height'), 48, array(
            'unit' => 'px',
            'wide' => 4
        ));

        new FieldImage($playButton, 'playbuttonimage', n2_('Image'), '', array(
            'width' => 220
        ));
    }
}Item/Video/ItemVideoFrontend.php000064400000015753152426504420012625 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Video;


use Nextend\Framework\Data\Data;
use Nextend\Framework\FastImageSize\FastImageSize;
use Nextend\Framework\Image\Image;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemVideoFrontend extends AbstractItemFrontend {

    public function render() {
        $owner = $this->layer->getOwner();

        $aspectRatio = $this->data->get('aspect-ratio', '16:9');

        $hasImage = 0;
        $poster   = $owner->fill($this->data->get('poster'));

        $coverImage = '';
        if (!empty($poster)) {

            $coverImage = $owner->renderImage($this, $poster, array(
                'class' => 'n2_ss_video_cover',
                'alt'   => n2_('Play')
            ), array(
                'class' => 'n2-ow-all'
            ));

            $hasImage  = 1;
            $playImage = '';

            if ($this->data->get('playbutton', 1) == 1) {

                $playWidth  = intval($this->data->get('playbuttonwidth', '48'));
                $playHeight = intval($this->data->get('playbuttonheight', '48'));
                if ($playWidth > 0 && $playHeight > 0) {

                    $attributes = Html::addExcludeLazyLoadAttributes(array(
                        'style' => '',
                        'class' => 'n2_ss_video_play_btn'
                    ));

                    if ($playWidth != 48) {
                        $attributes['style'] .= 'width:' . $playWidth . 'px;';
                    }
                    if ($playHeight != 48) {
                        $attributes['style'] .= 'height:' . $playHeight . 'px;';
                    }

                    $playButtonImage = $this->data->get('playbuttonimage', '');
                    if (!empty($playButtonImage)) {
                        $image = $this->data->get('playbuttonimage', '');
                        FastImageSize::initAttributes($image, $attributes);
                        $src = ResourceTranslator::toUrl($image);
                    } else {
                        $image = '$ss3-frontend$/images/play.svg';
                        FastImageSize::initAttributes($image, $attributes);
                        $src = Image::SVGToBase64($image);
                    }

                    $playImage = Html::image($src, 'Play', $attributes);
                }
            }

            $coverImage = Html::tag('div', array(
                'class'              => 'n2_ss_video_player__cover',
                'data-force-pointer' => ''
            ), $coverImage . $playImage);
        }

        $owner->addScript('new _N2.FrontendItemVideo(this, "' . $this->id . '", ' . $this->data->toJSON() . ', ' . $hasImage . ');');

        $style = '';
        if ($aspectRatio == 'custom') {
            $style = 'style="padding-top:' . ($this->data->get('aspect-ratio-height', '9') / $this->data->get('aspect-ratio-width', '16') * 100) . '%"';
        }

        return Html::tag("div", array(
            'class'             => 'n2_ss_video_player n2-ss-item-content n2-ss-item-video-container n2-ow-all',
            'data-aspect-ratio' => $aspectRatio
        ), '<div class="n2_ss_video_player__placeholder" ' . $style . '></div>' . Html::tag("video", $this->setOptions($this->data, $this->id), $this->setContent($owner, $this->data)) . $coverImage);
    }

    public function renderAdminTemplate() {
        $aspectRatio = $this->data->get('aspect-ratio', '16:9');

        $style = '';
        if ($aspectRatio == 'custom') {
            $style = 'style="padding-top:' . ($this->data->get('aspect-ratio-height', '9') / $this->data->get('aspect-ratio-width', '16') * 100) . '%"';
        }

        $playButtonImage = $this->data->get('playbuttonimage', '');
        if (!empty($playButtonImage)) {
            $playButtonImage = ResourceTranslator::toUrl($playButtonImage);
        } else {
            $playButtonImage = Image::SVGToBase64('$ss3-frontend$/images/play.svg');
        }

        $playButtonStyle  = '';
        $playButtonWidth  = intval($this->data->get('playbuttonwidth', '48'));
        $playButtonHeight = intval($this->data->get('playbuttonheight', '48'));

        if ($playButtonWidth > 0) {
            $playButtonStyle .= 'width:' . $playButtonWidth . 'px;';
        }
        if ($playButtonHeight > 0) {
            $playButtonStyle .= 'height:' . $playButtonHeight . 'px;';
        }

        $playButton = Html::image($playButtonImage, n2_('Play'), Html::addExcludeLazyLoadAttributes(array(
            'class' => 'n2_ss_video_play_btn',
            'style' => $playButtonStyle
        )));

        return Html::tag('div', array(
            'class'             => 'n2_ss_video_player n2-ss-item-content n2-ss-item-video-container n2-ow-all',
            'data-aspect-ratio' => $aspectRatio,
            "style"             => 'background: URL(' . ResourceTranslator::toUrl($this->data->getIfEmpty('poster', '$ss3-frontend$/images/placeholder/video.png')) . ') no-repeat 50% 50%; background-size: cover;'
        ), '<div class="n2_ss_video_player__placeholder" ' . $style . '></div>' . ($this->data->get('playbutton', 1) ? '<div class="n2_ss_video_player__cover">' . $playButton . '</div>' : ''));
    }

    /**
     * @param $data Data
     * @param $id
     *
     * @return array
     */
    private function setOptions($data, $id) {
        $videoOptions = array(
            'style'        => '',
            'class'        => 'n2-ow intrinsic-ignore data-tf-not-load n2-' . $data->get("fill-mode", 'cover'),
            'encode'       => false,
            'controlsList' => 'nodownload'
        );

        $videoOptions["data-volume"] = $data->get("volume", 1);
        if ($videoOptions["data-volume"] == 0) {
            $videoOptions['muted'] = 'muted';
        }

        $videoOptions['playsinline']        = 1;
        $videoOptions['webkit-playsinline'] = 1;

        if ($data->get('loop')) {
            $videoOptions['loop'] = 'loop';
        }


        $videoOptions["id"] = $id;

        if ($data->get("showcontrols")) {
            $videoOptions["controls"] = "yes";
        } else {
            $videoOptions["style"] .= "pointer-events:none;";
        }

        $videoOptions["preload"] = $data->get("preload", "auto");

        return $videoOptions;
    }

    /**
     * @param $owner AbstractRenderableOwner
     * @param $data  Data
     *
     * @return string
     */
    private function setContent($owner, $data) {
        $videoContent = "";

        if ($data->get("video_mp4", false)) {
            $videoContent .= Html::tag("source", array(
                "src"  => ResourceTranslator::toUrl($owner->fill($data->get("video_mp4"))),
                "type" => "video/mp4"
            ), '', false);
        }

        return $videoContent;
    }
}Item/Transition/ItemTransition.php000064400000014365152426504470013300 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Transition;


use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemTransition extends AbstractItem {

    protected $ordering = 5;

    protected $layerProperties = array("desktopportraitwidth" => 200);

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'transition';
    }

    public function getTitle() {
        return n2_('Transition');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--transition';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemTransitionFrontend($this, $id, $itemData, $layer);
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/transition.n2less", array(
            "sliderid" => $renderable->elementId
        ));
    }

    public function getValues() {
        return parent::getValues() + array(
                'animation'      => 'Fade',
                'image'          => '$ss3-frontend$/images/placeholder/image.png',
                'image2'         => '$ss3-frontend$/images/placeholder/video.png',
                'alt'            => '',
                'alt2'           => '',
                'href'           => '#',
                'href-target'    => '_self',
                'href-rel'       => '',
                'image-optimize' => 1
            );
    }


    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('image', $slide->fill($data->get('image', '')));
        $data->set('image2', $slide->fill($data->get('image2', '')));
        $data->set('alt', $slide->fill($data->get('alt', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('image'));
        $export->addImage($data->get('image2'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('image', $import->fixImage($data->get('image', '')));
        $data->set('image2', $import->fixImage($data->get('image2', '')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('image', ResourceTranslator::toUrl($data->get('image')));
        $data->set('image2', ResourceTranslator::toUrl($data->get('image2')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-transition', n2_('General'));
        new FieldImage($settings, 'image', n2_('Front image'), '', array(
            'relatedAlt' => 'item_transitionalt',
            'width'      => 220
        ));
        new FieldImage($settings, 'image2', n2_('Back image'), '', array(
            'relatedAlt' => 'item_transitionalt2',
            'width'      => 220

        ));

        new Select($settings, 'animation', n2_('Animation'), '', array(
            'options' => array(
                'Fade'           => n2_('Fade'),
                'VerticalFlip'   => n2_('Vertical flip'),
                'HorizontalFlip' => n2_('Horizontal flip')
            )
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-transition-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'relatedFields' => array(
                'item_transitionhref-target',
                'item_transitionhref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));

        $seo = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-transition-seo', n2_('SEO'));
        new Text($seo, 'alt', n2_('Front image alt tag'), '', array(
            'style' => 'width:133px;'
        ));
        new Text($seo, 'alt2', n2_('Back image alt tag'), '', array(
            'style' => 'width:133px;'
        ));

        $optimize = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-transition-optimize', n2_('Optimize'));
        new OnOff($optimize, 'image-optimize', n2_('Optimize image'), 1, array(
            'tipLabel'       => n2_('Optimize image'),
            'tipDescription' => n2_('You can turn off the Layer image optimization for this image, to resize it for tablet and mobile.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1839-caption-layer#optimize'
        ));
    }

}Item/Transition/ItemTransitionFrontend.php000064400000004523152426504540014771 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Transition;


use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemTransitionFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {

        $image  = $this->data->get('image', '');
        $image2 = $this->data->get('image2', '');
        if (empty($image) && empty($image2)) {
            return '';
        }

        $owner = $this->layer->getOwner();

        $image  = $owner->fill($image);
        $image2 = $owner->fill($image2);

        if (empty($image) && empty($image2)) {
            return '';
        }

        $this->loadResources($owner);
        $owner->addScript('new _N2.FrontendItemTransition(this, "' . $this->id . '", "' . $this->data->get('animation', 'Fade') . '");');

        $html = Html::openTag("div", array(
            "class" => "n2-ss-item-transition-inner"
        ));

        $imageAttributes = array(
            'alt'   => htmlspecialchars($owner->fill($this->data->get('alt', ''))),
            'class' => 'n2-ss-item-transition-image1'
        );

        $html .= $owner->renderImage($this, $image, $imageAttributes);

        $imageAttributes2 = array(
            'alt'   => htmlspecialchars($owner->fill($this->data->get('alt2', ''))),
            'class' => 'n2-ss-item-transition-image2'
        );

        $html .= $owner->renderImage($this, $image2, $imageAttributes2);


        $html .= Html::closeTag('div');

        $linkAttributes = array();
        if ($this->isEditor) {
            $linkAttributes['onclick'] = 'return false;';
        }

        return Html::tag("div", array(
            "id"    => $this->id,
            "class" => "n2-ss-item-transition n2-ss-item-content n2-ow-all"
        ), $this->getLink($html, $linkAttributes));
    }

    /**
     * @param $owner AbstractRenderableOwner
     */
    public function loadResources($owner) {

        $owner->addLess(self::getAssetsPath() . "/transition.n2less", array(
            "sliderid" => $owner->getElementID()
        ));
    }
}Item/ProgressBar/ItemProgressBar.php000064400000014456152426504610013473 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\ProgressBar;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemProgressBar extends AbstractItem {

    protected $ordering = 10;

    protected $layerProperties = array(
        "desktopportraitwidth" => 300
    );

    protected $fonts = array(
        'font'      => array(
            'defaultName' => 'item-progressbar-font',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"14||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"right","letterspacing":"normal","wordspacing":"normal","texttransform":"none"}]}'
        ),
        'fontlabel' => array(
            'defaultName' => 'item-progressbar-fontlabel',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"14||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"left","letterspacing":"normal","wordspacing":"normal","texttransform":"none"}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'progressbar';
    }

    public function getTitle() {
        return n2_('Progress bar');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--progressbar';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemProgressBarFrontend($this, $id, $itemData, $layer);
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/progressbar.n2less", array(
            "sliderid" => $renderable->elementId
        ));
    }

    public function getValues() {

        return parent::getValues() + array(
                'value'             => 50,
                'startvalue'        => 0,
                'total'             => 100,
                'color'             => '00000080',
                'color2'            => '64c133ff',
                'pre'               => '',
                'post'              => '%',
                'label'             => n2_('Progress'),
                'labelplacement'    => 'before',
                'animationduration' => 1000,
                'animationdelay'    => 0
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('label', $slide->fill($data->get('label', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('fontlabel'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('fontlabel', $import->fixSection($data->get('fontlabel')));

        return $data;
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-progressbar-font', n2_('Progress bar'), $this->fonts['font']['value'], array(
            'mode' => 'simple'
        ));

        new Font($row1, 'item-progressbar-fontlabel', n2_('Label'), $this->fonts['fontlabel']['value'], array(
            'mode' => 'simple'
        ));

    }

    public function renderFields($container) {
        $counter = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-progressbar-counter', n2_('Counter'));
        new Number($counter, 'value', n2_('Value'), '', array(
            'wide' => 5
        ));
        new Number($counter, 'startvalue', n2_('Start from'), '', array(
            'wide' => 5
        ));
        new Number($counter, 'total', n2_('Total'), '', array(
            'wide' => 5
        ));

        $display = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-progressbar-display', n2_('Display'));
        new Color($display, 'color', n2_('Color'), '', array(
            'alpha' => true
        ));
        new Color($display, 'color2', n2_('Active color'), '', array(
            'alpha' => true
        ));

        $labels = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-progressbar-labels', n2_('Labels'));
        new Text($labels, 'label', n2_('Label'), '', array(
            'style' => 'width:150px;'
        ));
        new Select($labels, 'labelplacement', n2_('Placement'), '', array(
            'options' => array(
                'before' => n2_('Before'),
                'over'   => n2_('Over'),
                'after'  => n2_('After')
            )
        ));
        new Text($labels, 'pre', n2_('Pre'), '', array(
            'style' => 'width:40px;'
        ));
        new Text($labels, 'post', n2_('Post'), '', array(
            'style' => 'width:40px;'
        ));

        $animation = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-progressbar-animation', n2_('Animation'));
        new Number($animation, 'animationduration', n2_('Animation duration'), 1, array(
            'min'  => 0,
            'wide' => 5,
            'unit' => 'ms'
        ));
        new Number($animation, 'animationdelay', n2_('Delay'), 0, array(
            'min'  => 0,
            'wide' => 5,
            'unit' => 'ms'
        ));

        new HiddenFont($counter, 'font', n2_('Font') . ' - ' . n2_('Counter'), '', array(
            'mode' => 'simple'
        ));

        new HiddenFont($counter, 'fontlabel', n2_('Font') . ' - ' . n2_('Label'), '', array(
            'mode' => 'simple'
        ));
    }
}Item/ProgressBar/ItemProgressBarFrontend.php000064400000010634152426504660015172 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\ProgressBar;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemProgressBarFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $this->loadResources($owner);

        $value      = intval($this->data->get('value'));
        $min        = min(0, $value);
        $startvalue = max(intval($this->data->get('startvalue')), $min);
        $total      = max(max(intval($this->data->get('total')), $startvalue), $value);
        $duration   = max(0, intval($this->data->get('animationduration')));

        if ($total != $min) {
            $toPercent = (min($value, $total) - $min) / ($total - $min);

            if ($duration == 0) {
                // We do not have animation
                $fromPercent = $toPercent;
            } else {
                $fromPercent = (min($startvalue, $total) - $min) / ($total - $min);
            }
        } else {
            $duration    = 0;
            $fromPercent = $toPercent = 0;
        }


        $labelHTML = '';
        $label     = Sanitize::filter_allowed_html($owner->fill($this->data->get('label')));
        $placement = '';
        if (!empty($label)) {
            $fontLabel = $owner->addFont($this->data->get('fontlabel'), 'simple');

            $labelHTML = Html::tag('div', array(
                'class' => 'n2-ss-item-progressbar-label n2-ow ' . $fontLabel
            ), $label);
            $placement = $this->data->get('labelplacement');
        }

        $html = '';

        if ($placement == 'before') {
            $html .= $labelHTML;
        }

        $html .= Html::openTag('div', array(
            'id'    => $this->id,
            'class' => 'n2-ow n2-ss-item-progressbar',
            'style' => 'background-color: ' . Color::colorToRGBA($this->data->get('color')) . ';'
        ));

        $html .= Html::openTag('div', array(
            'class' => 'n2-ow n2-ss-item-progressbar-inner',
            'style' => 'width:' . $fromPercent * 100 . '%;background-color: ' . Color::colorToRGBA($this->data->get('color2')) . ';'
        ));

        if ($placement == 'over') {
            $html .= $labelHTML;
        }


        $font = $owner->addFont($this->data->get('font'), 'simple');

        $pre  = Sanitize::filter_allowed_html($this->data->get('pre'));
        $post = Sanitize::filter_allowed_html($this->data->get('post'));

        $html .= Html::tag('div', array(
            'class' => 'n2-ss-item-progressbar-counting n2-ow ' . $font
        ), $pre . round($min + $fromPercent * ($total - $min)) . $post);


        $html .= '</div>';

        $html .= '</div>';

        if ($placement == 'after') {
            $html .= $labelHTML;
        }

        $jsData = array(
            'name'        => 'progressbar',
            'pre'         => $pre,
            'post'        => $post,
            'fromPercent' => $fromPercent,
            'toPercent'   => $toPercent,
            'duration'    => $duration,
            'delay'       => $this->data->get('animationdelay'),
            'min'         => $min,
            'total'       => $total,
            'counting'    => '.n2-ss-item-progressbar-counting',
            'display'     => '.n2-ss-item-progressbar-inner',
            'displayMode' => 'width'
        );

        if ($this->isEditor && $owner->underEdit) {
            $owner->addScript('new _N2.CounterItemAdmin(this, "' . $this->id . '", ' . json_encode($jsData) . ');');
        } else {
            $owner->addScript('new _N2.FrontendItemCounter(this, "' . $this->id . '", ' . json_encode($jsData) . ');');
        }

        return Html::tag('div', array(
            'class' => 'n2-ss-item-content n2-ow'
        ), $html);
    }

    /**
     * @param $owner AbstractRenderableOwner
     */
    public function loadResources($owner) {
        $owner->addLess(self::getAssetsPath() . "/progressbar.n2less", array(
            "sliderid" => $owner->getElementID()
        ));
    }
}Item/Input/ItemInput.php000064400000020771152426504730011207 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Input;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemInput extends AbstractItem {

    protected $ordering = 100;

    protected $fonts = array(
        'inputfont'  => array(
            'defaultName' => 'item-input-font',
            'value'       => '{"data":[{"color":"000000ff","size":"15||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Montserrat,Arial","lineheight":"44px","bold":0,"italic":0,"underline":0,"align":"left","letterspacing":"normal","wordspacing":"normal","texttransform":"none","extra":"height:44px;"},{},{}]}'
        ),
        'buttonfont' => array(
            'defaultName' => 'item-input-button-font',
            'value'       => '{"data":[{"color":"ffffffff","size":"14||px","tshadow":"0|*|0|*|0|*|000000ff","afont":"Montserrat,Arial","lineheight":"44px","bold":0,"italic":0,"underline":0,"align":"left","letterspacing":"normal","wordspacing":"normal","texttransform":"none","extra":""},{},{}]}'
        )
    );

    protected $styles = array(
        'style'       => array(
            'defaultName' => 'item-input-container-style',
            'value'       => ''
        ),
        'inputstyle'  => array(
            'defaultName' => 'item-input-style',
            'value'       => '{"data":[{"backgroundcolor":"ffffffff","padding":"0|*|20|*|0|*|20|*|px","boxshadow":"0|*|0|*|0|*|0|*|000000ff","border":"0|*|solid|*|000000ff","borderradius":"0","extra":""},{}]}'
        ),
        'buttonstyle' => array(
            'defaultName' => 'item-input-button-style',
            'value'       => '{"data":[{"backgroundcolor":"04bc8fff","padding":"0|*|35|*|0|*|35|*|px","boxshadow":"0|*|0|*|0|*|0|*|000000ff","border":"0|*|solid|*|000000ff","borderradius":"0","extra":""},{}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'input';
    }

    public function getTitle() {
        return n2_('Input');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--input';
    }

    public function getGroup() {
        return n2_x('Advanced', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemInputFrontend($this, $id, $itemData, $layer);
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Style($row1, 'item-input-container-style', n2_('Container'), $this->styles['style']['value'], array(
            'mode' => 'heading'
        ));

        new Font($row1, 'item-input-font', n2_('Input'), $this->fonts['inputfont']['value'], array(
            'mode' => 'input'
        ));

        new Style($row1, 'item-input-style', n2_('Input'), $this->styles['inputstyle']['value'], array(
            'mode' => 'heading'
        ));

        new Font($row1, 'item-input-button-font', n2_('Button'), $this->fonts['buttonfont']['value'], array(
            'mode' => 'hover'
        ));

        new Style($row1, 'item-input-button-style', n2_('Button'), $this->styles['buttonstyle']['value'], array(
            'mode' => 'button'
        ));
    }


    public function getValues() {

        return parent::getValues() + array(
                'placeholder' => n2_('What are you looking for?'),
                'action'      => 'https://www.google.com/search',
                'method'      => 'GET',
                'target'      => '_self',
                'parameters'  => 'ie=utf-8&oe=utf-8',
                'name'        => 'q',
                'buttonlabel' => n2_('Search'),
                'submit'      => '',
                'class'       => '',
                'onsubmit'    => '',
                'onkeyup'     => ''
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('parameters', $slide->fill($data->get('parameters')));
        $data->set('buttonlabel', $slide->fill($data->get('buttonlabel')));
        $data->set('action', $slide->fill($data->get('action')));
        $data->set('name', $slide->fill($data->get('name')));
        $data->set('placeholder', $slide->fill($data->get('placeholder')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('style'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('style', $import->fixSection($data->get('style')));

        return $data;
    }

    public function renderFields($container) {

        $text = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-input', n2_('Text'));

        new Warning($text, 'item-input-notice', n2_('We only suggest using this layer if you are a developer, since the Input layer requires deep understanding how HTML form works.'));

        new Text($text, 'placeholder', n2_('Placeholder text'), n2_('What are you looking for?'), array(
            'style' => 'width:170px;'
        ));

        new Text($text, 'buttonlabel', n2_('Label'), n2_('Button'), array(
            'style' => 'width:96px;'
        ));

        $developer = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-input-developer', n2_('Form'));
        new Text($developer, 'name', n2_('Input name'), 'q', array(
            'style' => 'width:80px;'
        ));
        new Select($developer, 'method', n2_('Method'), 'GET', array(
            'options' => array(
                'GET'  => 'GET',
                'POST' => 'POST'
            )
        ));
        new LinkTarget($developer, 'target', n2_('Target window'));
        new Text($developer, 'action', n2_('Form action'), 'https://www.google.com/search', array(
            'style' => 'width:302px;'
        ));
        new Textarea($developer, 'parameters', n2_('Parameters'), 'ie=utf-8&oe=utf-8', array(
            'width' => 314
        ));
        new Select($developer, 'submit', n2_('Slide action to submit'), '', array(
            'options' => array(
                ''           => n2_('Off'),
                'click'      => n2_('Click'),
                'mouseenter' => n2_('Mouse enter'),
                'mouseleave' => n2_('Mouse leave')
            )
        ));

        $js = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-input-js', n2_('JavaScript'));
        new Text($js, 'onsubmit', 'OnSubmit', '', array(
            'style' => 'width:133px;'
        ));
        new Text($js, 'onkeyup', 'OnKeyUp', '', array(
            'style' => 'width:133px;'
        ));

        $html = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-input-html', n2_('Advanced'));
        new Text($html, 'class', n2_('CSS Class'), '', array(
            'style'          => 'width:302px;',
            'tipLabel'       => n2_('CSS Class'),
            'tipDescription' => sprintf(n2_('Class on the %s element.'), '<form>'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1812-layer-style#advanced'
        ));


        new HiddenFont($text, 'inputfont', n2_('Input'), '', array(
            'mode' => 'paragraph'
        ));

        new HiddenStyle($text, 'inputstyle', n2_('Input'), '', array(
            'mode' => 'heading'
        ));

        new HiddenStyle($text, 'style', n2_('Container'), '', array(
            'mode' => 'heading'
        ));

        new HiddenFont($text, 'buttonfont', n2_('Button'), '', array(
            'mode' => 'hover'
        ));

        new HiddenStyle($text, 'buttonstyle', n2_('Button'), '', array(
            'mode' => 'heading'
        ));
    }
}Item/Input/ItemInputFrontend.php000064400000010520152426505000012665 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Input;


use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemInputFrontend extends AbstractItemFrontend {

    public function render() {
        $owner = $this->layer->getOwner();

        $style = $owner->addStyle($this->data->get('style'), 'heading');

        $inputFont  = $owner->addFont($this->data->get('inputfont'), 'paragraph');
        $inputStyle = $owner->addStyle($this->data->get('inputstyle'), 'heading');

        $slideSubmitAction = $this->data->get('submit');
        if (!empty($slideSubmitAction)) {
            $owner->addScript('(function(){var form=document.getElementById("' . $this->id . '");form.closest(".n2-ss-slide").addEventListener("' . $this->data->get('submit') . '",function(){form.submit()})})();');
        }

        $parameters     = explode('&', $owner->fill($this->data->get('parameters')));
        $parametersHTML = '';
        foreach ($parameters as $parameter) {
            $parameter = explode('=', $parameter);
            if (count($parameter) == 2) {
                $parametersHTML .= Html::tag('input', array(
                    'type'  => 'hidden',
                    'name'  => $parameter[0],
                    'value' => $parameter[1],
                    'class' => 'n2-ow'
                ), false, false);
            }
        }


        $button      = '';
        $buttonLabel = strip_tags($owner->fill($this->data->get('buttonlabel')));
        if (!empty($buttonLabel)) {

            $buttonFont  = $owner->addFont($this->data->get('buttonfont'), 'hover');
            $buttonStyle = $owner->addStyle($this->data->get('buttonstyle'), 'heading');

            $button = Html::tag('input', array(
                'encode' => false,
                'style'  => 'white-space:nowrap;',
                'type'   => 'submit',
                'value'  => $buttonLabel,
                'class'  => 'n2-form-button ' . $buttonFont . ' ' . $buttonStyle . ' n2-ow'
            ), false, false);
        }

        return Html::tag('form', array(
            'class'    => 'n2-ss-item-input-form ' . $style . ' n2-ss-item-content n2-ow ' . $owner->fill($this->data->get('class', '')),
            'id'       => $this->id,
            'action'   => $owner->fill($this->data->get('action')),
            'method'   => $this->data->get('method'),
            'target'   => $this->data->get('target'),
            'onsubmit' => $this->data->get('onsubmit')
        ), Html::tag('input', array(
                'encode'      => false,
                'name'        => $owner->fill($this->data->get('name', '')),
                'type'        => 'text',
                'placeholder' => strip_tags($owner->fill($this->data->get('placeholder', ''))),
                'class'       => 'n2-input n2-ow ' . $inputFont . $inputStyle,
                'style'       => 'display: block; width: 100%;white-space:nowrap;',
                'onkeyup'     => $this->data->get('onkeyup')
            ), false, false) . $parametersHTML . $button);
    }

    public function renderAdminTemplate() {
        $owner = $this->layer->getOwner();

        $style = $owner->addStyle($this->data->get('style'), 'heading');


        $inputFont  = $owner->addFont($this->data->get('inputfont'), 'paragraph');
        $inputStyle = $owner->addStyle($this->data->get('inputstyle'), 'heading');

        $button      = '';
        $buttonLabel = strip_tags($owner->fill($this->data->get('buttonlabel')));
        if (!empty($buttonLabel)) {
            $buttonFont  = $owner->addFont($this->data->get('buttonfont'), 'hover');
            $buttonStyle = $owner->addStyle($this->data->get('buttonstyle'), 'heading');

            $button = Html::tag('div', array(
                'style' => 'white-space:nowrap;',
                'class' => 'n2-form-button ' . $buttonFont . ' ' . $buttonStyle . ' n2-ow'
            ), $buttonLabel);
        }


        return Html::tag('div', array(
            'class' => 'n2-ss-item-input-form ' . $style . ' ' . $this->data->get('class', '') . ' n2-ow'
        ), "<div class='n2-input n2-ow " . $inputFont . " " . $inputStyle . "' style='white-space:nowrap;'>" . strip_tags($owner->fill($this->data->get('placeholder', ''))) . "</div>" . $button);

    }
}Item/ImageBox/ItemImageBox.php000064400000033444152426505050012174 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\ImageBox;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\Icon;
use Nextend\Framework\Form\Element\IconTab;
use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\RichTextarea;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Form\Element\Radio\InnerAlign;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemImageBox extends AbstractItem {

    protected $ordering = 1;

    protected $layerProperties = array("desktopportraitwidth" => "300");

    protected $fonts = array(
        'fonttitle'       => array(
            'defaultName' => 'item-imagebox-fonttitle',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"32||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""}]}'
        ),
        'fontdescription' => array(
            'defaultName' => 'item-imagebox-fontdescription',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"16||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"2","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{"extra":""},{"extra":""}]}'
        )
    );

    protected $styles = array(
        'style' => array(
            'defaultName' => 'item-imagebox-style',
            'value'       => ''
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'imagebox';
    }

    public function getTitle() {
        return n2_('Image box');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--imagebox';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemImageBoxFrontend($this, $id, $itemData, $layer);
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/imagebox.n2less", array(
            "sliderid" => $renderable->elementId
        ));
    }

    public function getValues() {

        return parent::getValues() + array(
                'layout'          => 'top',
                'padding'         => '10|*|10|*|10|*|10',
                'inneralign'      => 'center',
                'verticalalign'   => 'flex-start',
                'image'           => '$ss3-frontend$/images/placeholder/image.png',
                'imagewidth'      => 100,
                'alt'             => '',
                'icon'            => '',
                'iconsize'        => 64,
                'iconcolor'       => 'ffffffff',
                'heading'         => n2_('Heading'),
                'headingpriority' => 'div',
                'description'     => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
                'href'            => '#',
                'href-target'     => '_self',
                'href-rel'        => '',
                'href-aria-label' => '',
                'fullwidth'       => 0,
                'image-optimize'  => 1
            );
    }


    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('heading', $slide->fill($data->get('heading', '')));
        $data->set('description', $slide->fill($data->get('description', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));
        $data->set('image', $slide->fill($data->get('image', '')));
        $data->set('alt', $slide->fill($data->get('alt', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('image'));
        $export->addVisual($data->get('fonttitle'));
        $export->addVisual($data->get('fontdescription'));
        $export->addVisual($data->get('style'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('image', $import->fixImage($data->get('image')));
        $data->set('fonttitle', $import->fixSection($data->get('fonttitle')));
        $data->set('fontdescription', $import->fixSection($data->get('fontdescription')));
        $data->set('style', $import->fixSection($data->get('style')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('image', ResourceTranslator::toUrl($data->get('image')));

        return $data;
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-imagebox-fonttitle', n2_('Title'), $this->fonts['fonttitle']['value'], array(
            'mode' => 'hover'
        ));

        new Font($row1, 'item-imagebox-fontdescription', n2_('Description'), $this->fonts['fontdescription']['value'], array(
            'mode' => 'paragraph'
        ));

        new Style($row1, 'item-imagebox-style', n2_('Image box'), $this->styles['style']['value'], array(
            'mode' => 'heading'
        ));
    }

    public function renderFields($container) {
        $imageSettings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'image-settings', n2_('General'));

        new IconTab($imageSettings, 'imagetype', n2_('Type'), 'image', array(
            'options'            => array(
                'image' => 'ssi_16 ssi_16--image',
                'icon'  => 'ssi_16 ssi_16--star'
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'image'
                    ),
                    'field'  => array(
                        'item_imageboximage',
                        'item_imageboximagewidth',
                        'item_imageboxalt'
                    )
                ),
                array(
                    'values' => array(
                        'icon'
                    ),
                    'field'  => array(
                        'item_imageboxicon',
                        'item_imageboxiconsize',
                        'item_imageboxiconcolor',
                        'item_imageboxhref-aria-label'
                    )
                )
            ),
            'tooltips'           => array(
                'image' => n2_('Image'),
                'icon'  => n2_('Icon'),
            )
        ));

        new FieldImage($imageSettings, 'image', n2_('Image'), '', array(
            'relatedAlt' => 'item_imageboxalt',
            'width'      => 140
        ));

        new NumberSlider($imageSettings, 'imagewidth', n2_('Width'), '', array(
            'max'  => 100,
            'unit' => '%',
            'wide' => 3
        ));
        new Text($imageSettings, 'alt', 'SEO - ' . n2_('Alt tag'), '', array(
            'style' => 'width:218px;'
        ));


        new Icon($imageSettings, 'icon', n2_('Icon'), '', array(
            'hasClear' => true
        ));
        new NumberSlider($imageSettings, 'iconsize', n2_('Size'), 100, array(
            'min'       => 8,
            'max'       => 400,
            'sliderMax' => 200,
            'step'      => 4,
            'wide'      => 3,
            'unit'      => 'px'
        ));
        new Color($imageSettings, 'iconcolor', n2_('Color'), '', array(
            'alpha' => true
        ));

        new OnOff($imageSettings, 'fullwidth', n2_('Full width'), 1);

        $text = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'text-settings', n2_('Text'));
        new Text($text, 'heading', n2_('Heading'), n2_('Heading'), array(
            'style' => 'width:226px;'
        ));
        new Select($text, 'headingpriority', n2_('Tag'), 'div', array(
            'options' => array(
                'div' => 'div',
                '1'   => 'H1',
                '2'   => 'H2',
                '3'   => 'H3',
                '4'   => 'H4',
                '5'   => 'H5',
                '6'   => 'H6'
            )
        ));

        new HiddenFont($text, 'fonttitle', n2_('Heading'), '', array(
            'mode' => 'hover'
        ));

        new RichTextarea($text, 'description', n2_('Description'), '', array(
            'fieldStyle' => 'height: 120px; width: 314px;resize: vertical;'
        ));

        new HiddenFont($text, 'fontdescription', n2_('Description'), '', array(
            'mode' => 'paragraph'
        ));

        new HiddenStyle($text, 'style', false, '', array(
            'mode' => 'box'
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-imagebox-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'relatedFields' => array(
                'item_imageboxhref-target',
                'item_imageboxhref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));
        new Text($link, 'href-aria-label', n2_('Aria label'), '', array(
            'tipLabel'       => n2_('Aria label'),
            'tipDescription' => sprintf(n2_('Enter an %1$s aria-label attribute %2$s that describes the link.'), '<a href="https://www.w3.org/TR/WCAG20-TECHS/ARIA14.html" target="_blank">', '</a>')
        ));

        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-imagebox', n2_('Display'));

        new Select($settings, 'layout', n2_('Layout'), '', array(
            'options'            => array(
                'top'    => n2_('Top'),
                'left'   => n2_('Left'),
                'right'  => n2_('Right'),
                'bottom' => n2_('Bottom')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'left',
                        'right'
                    ),
                    'field'  => array(
                        'item_imageboxverticalalign'
                    )
                )
            )
        ));

        $padding = new MarginPadding($settings, 'padding', n2_('Padding'), '10|*|10|*|10|*|10', array(
            'unit' => 'px'
        ));
        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($padding, 'padding-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'wide'   => 3
            ));
        }

        new InnerAlign($settings, 'inneralign', n2_('Inner align'));
        new Select($settings, 'verticalalign', n2_('Vertical align'), '', array(
            'options'        => array(
                'flex-start' => n2_('Top'),
                'center'     => n2_('Center'),
                'flex-end'   => n2_('Bottom')
            ),
            'tipLabel'       => n2_('Vertical align'),
            'tipDescription' => n2_('Positions the text inside the layer. Only works with left and right layout.')
        ));


        $optimize = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-caption-optimize', n2_('Optimize'));
        new OnOff($optimize, 'image-optimize', n2_('Optimize image'), 1, array(
            'tipLabel'       => n2_('Optimize image'),
            'tipDescription' => n2_('You can turn off the Layer image optimization for this image, to resize it for tablet and mobile.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1839-caption-layer#optimize'
        ));
    }
}Item/ImageBox/ItemImageBoxFrontend.php000064400000011230152426505200013656 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\ImageBox;


use Nextend\Framework\Icon\Icon;
use Nextend\Framework\Parser\Color;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Component\AbstractComponent;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemImageBoxFrontend extends AbstractItemFrontend {

    public function isAuto() {
        return !$this->data->get('fullwidth', 1);
    }

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $this->loadResources($owner);

        $style = $owner->addStyle($this->data->get('style'), 'heading');

        $layout = $this->data->get('layout');

        $attr = array(
            'class'       => 'n2-ss-item-imagebox-container n2-ss-item-content n2-ow-all ' . $style,
            'data-layout' => $layout,
            'style'       => AbstractComponent::innerAlignToStyle($this->data->get('inneralign'))
        );

        if ($layout == 'left' || $layout == 'right') {
            $attr['style'] .= 'align-items:' . $this->data->get('verticalalign') . ';';
        }

        $html = Html::openTag('div', $attr);

        // START IMAGE SECTION
        $imageHTML           = '';
        $imageContainerStyle = '';
        $imageInnerStyle     = '';
        $icon                = $this->data->get('icon');
        $image               = $this->data->get('image');
        $imageType           = $this->data->get('imagetype', 'icon');
        $linkAttributes      = array();
        if (!empty($icon) && $imageType == 'icon') {
            $iconData  = Icon::render($icon);
            $imageHTML .= Html::tag('i', array(
                'class' => 'n2i ' . $iconData['class'],
                'style' => 'color: ' . Color::colorToRGBA($this->data->get('iconcolor')) . ';font-size:' . ($this->data->get('iconsize') / 16 * 100) . '%'
            ), $iconData['ligature']);

            $ariaLabel = $this->data->get('href-aria-label', '');
            if (!empty($ariaLabel)) {
                $linkAttributes['aria-label'] = $ariaLabel;
            }
        } else if (!empty($image)) {

            if ($layout == 'top' || $layout == 'bottom') {
                $imageInnerStyle .= 'max-width:' . $this->data->get('imagewidth') . '%;';
            } else {
                $imageContainerStyle .= 'max-width:' . $this->data->get('imagewidth') . '%;';
            }

            $image = $owner->fill($this->data->get('image'));

            $imageAttributes = array(
                'alt'   => $owner->fill($this->data->get('alt')),
                'style' => $imageInnerStyle,
                'class' => ''
            );

            $imageHTML = $owner->renderImage($this, $image, $imageAttributes);
        }

        if (!empty($imageHTML)) {
            $html .= Html::tag('div', array(
                'class' => 'n2-ss-item-imagebox-image',
                'style' => $imageContainerStyle
            ), $this->getLink($imageHTML, $linkAttributes));
        }
        // END IMAGE SECTION


        // START CONTENT SECTION
        $html .= Html::openTag('div', array(
            'class' => 'n2-ss-item-imagebox-content',
            'style' => 'padding:' . implode('px ', explode('|*|', $this->data->get('padding'))) . 'px'
        ));

        $heading = Sanitize::filter_allowed_html($this->data->get('heading'));
        if (!empty($heading)) {
            $font = $owner->addFont($this->data->get('fonttitle'), 'hover');

            $priority = $this->data->get('headingpriority');
            $html     .= $this->getLink(Html::tag($priority > 0 ? 'h' . $priority : $priority, array('class' => $font), $owner->fill($heading)));
        }

        $description = Sanitize::filter_allowed_html($this->data->get('description'));
        if (!empty($description)) {
            $font = $owner->addFont($this->data->get('fontdescription'), 'paragraph');

            $html .= Html::tag('div', array('class' => $font), $owner->fill($description));
        }

        $html .= '</div>';
        // END CONTENT SECTION


        $html .= '</div>';

        return $html;
    }

    /**
     * @param AbstractRenderableOwner $owner
     */
    public function loadResources($owner) {
        $owner->addLess(self::getAssetsPath() . "/imagebox.n2less", array(
            "sliderid" => $owner->getElementID()
        ));
    }
}Item/ImageArea/ItemImageArea.php000064400000012675152426505250012441 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\ImageArea;


use Nextend\Framework\Form\Element\LayerWindowFocus;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\HiddenText;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemImageArea extends AbstractItem {

    protected $ordering = 6;

    protected $layerProperties = array(
        "desktopportraitwidth"  => 150,
        "desktopportraitheight" => 150
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'imagearea';
    }

    public function getTitle() {
        return n2_('Image area');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--imagearea';
    }

    public function getGroup() {
        return n2_x('Advanced', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemImageAreaFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {
        return parent::getValues() + array(
                'image'       => '$ss3-frontend$/images/placeholder/image.png',
                'alt'         => '',
                'href'        => '#',
                'href-target' => '_self',
                'href-rel'    => '',
                'fillmode'    => 'cover',
                'positionx'   => 50,
                'positiony'   => 50
            );
    }


    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('image', $slide->fill($data->get('image', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));
        $data->set('alt', $slide->fill($data->get('alt', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('image'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('image', $import->fixImage($data->get('image')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('image', ResourceTranslator::toUrl($data->get('image')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-imagearea', n2_('General'));

        $fieldImage = new FieldImage($settings, 'image', n2_('Image'), '', array(
            'relatedAlt'    => 'item_imageareaalt',
            'width'         => 220,
            'relatedFields' => array(
                'item_imageareaitem-imagearea-focus'
            )
        ));

        $fieldFocusX = new HiddenText($settings, 'positionx', 50);
        $fieldFocusY = new HiddenText($settings, 'positiony', 50);

        $focusField = new LayerWindowFocus($settings, 'item-imagearea-focus', n2_('Focus'), array(
            'tipLabel'       => n2_('Focus'),
            'tipDescription' => n2_('You can set the starting position of a background image. This makes sure that the selected part will always remain visible, so you should pick the most important part.')
        ));

        $focusField->setFields($fieldImage, $fieldFocusX, $fieldFocusY);

        new Select($settings, 'fillmode', n2_('Fill mode'), 'cover', array(
            'options' => array(
                'cover'   => n2_('Fill'),
                'contain' => n2_('Fit')
            )
        ));
        new Text($settings, 'alt', 'SEO - ' . n2_('Alt tag'), '', array(
            'style' => 'width:133px;'
        ));


        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-imagearea-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'relatedFields' => array(
                'item_imageareahref-target',
                'item_imageareahref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));

    }
}Item/ImageArea/ItemImageAreaFrontend.php000064400000003165152426505320014131 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\ImageArea;


use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemImageAreaFrontend extends AbstractItemFrontend {

    public function render() {

        if ($this->hasLink()) {
            return $this->getLink($this->getHtml(false), array(
                'style' => 'display: block; width:100%;height:100%;',
                'class' => 'n2-ss-item-content n2-ow'
            ));
        }

        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml($isContent = true) {
        $owner = $this->layer->getOwner();

        $image = $this->data->get('image', '');
        if (empty($image)) {
            return '';
        }

        $image = $owner->fill($image);

        $imageUrl = ResourceTranslator::toUrl($image);

        $owner->addImage($imageUrl);

        $imageAttributes = array(
            "alt"   => htmlspecialchars($owner->fill($this->data->get('alt', ''))),
            'class' => ($isContent ? 'n2-ss-item-content ' : '') . ' n2-ss-item-image-area',
            'style' => 'object-fit:' . $this->data->get('fillmode', 'cover') . ';object-position:' . $this->data->get('positionx', 50) . '% ' . $this->data->get('positiony', 50) . '%;'
        );

        return $owner->renderImage($this, $image, $imageAttributes, array(
            'class' => 'n2-ow-all'
        ));
    }

    public function needHeight() {
        return true;
    }
}Item/Iframe/ItemIframe.php000064400000006114152426505370011413 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Iframe;


use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemIframe extends AbstractItem {

    protected $ordering = 100;

    protected $layerProperties = array(
        "desktopportraitwidth"  => 300,
        "desktopportraitheight" => 300
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'iframe';
    }

    public function getTitle() {
        return n2_('Iframe');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--iframe';
    }

    public function getGroup() {
        return n2_x('Advanced', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemIframeFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {
        return parent::getValues() + array(
                'url'    => 'https://smartslider3.com/',
                'size'   => '100%|*|100%',
                'scroll' => 'yes'
            );
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('url', $slide->fill($data->get('url', '')));

        return $data;
    }

    public function renderFields($container) {
        $general = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-iframe', n2_('General'));
        new Warning($general, '', sprintf(n2_('Please note, that %1$swe do not support%2$s customized coding! The iframe layer often needs code customizations what you have to do yourself, so we only suggest using this layer if you are a developer!'), '<b>', '</b>'));

        new Text($general, 'url', n2_('Iframe url'), '', array(
            'style' => 'width:302px;'
        ));

        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-iframe-settings', n2_('Display'));
        new Select($settings, 'scroll', n2_('Scroll'), 'auto', array(
            'options'        => array(
                'yes'  => n2_('Yes'),
                'no'   => n2_('No'),
                'auto' => n2_('Auto')
            ),
            'tipLabel'       => n2_('Scroll'),
            'tipDescription' => n2_('You can disable the scroll on the iframe content.')
        ));
        $size = new MixedField($settings, 'size', false, '100%|*|100%');
        new Text($size, 'size-1', n2_('Width'), '', array(
            'style' => 'width:40px;'
        ));
        new Text($size, 'size-2', n2_('Height'), '', array(
            'style' => 'width:40px;'
        ));

        $advanced = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-iframe-advanced', n2_('Advanced'));

        new Text($advanced, 'title', n2_('Iframe title'), '', array(
            'style' => 'width:302px;'
        ));
    }
}Item/Iframe/ItemIframeFrontend.php000064400000003060152426505440013106 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Iframe;


use Nextend\Framework\Parser\Common;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemIframeFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $size = (array)Common::parse($this->data->get('size', ''));
        if (!isset($size[0])) $size[0] = '100%';
        if (!isset($size[1])) $size[1] = '100%';

        $attributes = array(
            "encode"      => false,
            "frameborder" => 0,
            "class"       => "n2-ow intrinsic-ignore",
            "width"       => $size[0],
            "height"      => $size[1],
            "scrolling"   => $this->data->get("scroll"),
            "sandbox"     => 'allow-modals allow-forms allow-popups allow-scripts allow-same-origin'
        );

        $title = strip_tags($this->data->get('title', ''));
        if (!empty($title)) {
            $attributes['title'] = $title;
        }

        $attributes[$owner->isLazyLoadingEnabled() ? 'data-lazysrc' : 'src'] = $owner->fill($this->data->get("url"));

        return Html::tag('div', array('class' => 'n2-ss-item-iframe-wrapper n2-ss-item-content n2-ow'), Html::tag("iframe", $attributes, ""));
    }

    public function needHeight() {
        return true;
    }
}Item/HtmlList/ItemHtmlList.php000064400000014326152426505560012312 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\HtmlList;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemHtmlList extends AbstractItem {

    protected $ordering = 6;

    protected $layerProperties = array(
        "desktopportraitleft"   => 0,
        "desktopportraittop"    => 0,
        "desktopportraitwidth"  => 400,
        "desktopportraitalign"  => "left",
        "desktopportraitvalign" => "top"
    );

    protected $fonts = array(
        'font' => array(
            'defaultName' => 'item-list-font',
            'value'       => '{"data":[{"color":"ffffffff","size":"14||px","align":"left"},{"color":"1890d7ff"},{"extra":""}]}'
        )
    );

    protected $styles = array(
        'liststyle' => array(
            'defaultName' => 'item-list-liststyle',
            'value'       => '{"data":[{"extra":"margin-top:0;\nmargin-bottom:0;"}, {"extra":""}]}'
        ),
        'itemstyle' => array(
            'defaultName' => 'item-list-itemstyle',
            'value'       => '{"name":"List","data":[{"padding":"10|*|20|*|10|*|20|*|px","extra":"margin:0;"},{"extra":""}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'list';
    }

    public function getTitle() {
        return n2_('List');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--list';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemHtmlListFrontend($this, $id, $itemData, $layer);
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-list-font', n2_('List'), $this->fonts['font']['value'], array(
            'mode' => 'list'
        ));

        new Style($row1, 'item-list-liststyle', n2_('List'), $this->styles['liststyle']['value'], array(
            'mode' => 'heading'
        ));

        new Style($row1, 'item-list-itemstyle', n2_('Item'), $this->styles['itemstyle']['value'], array(
            'mode' => 'heading'
        ));
    }

    public function getValues() {

        return parent::getValues() + array(
                'content' => n2_("Item 1\nItem 2\nItem 3"),
                'type'    => 'disc'
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('content', $slide->fill($data->get('content', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('liststyle'));
        $export->addVisual($data->get('itemstyle'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('liststyle', $import->fixSection($data->get('liststyle')));
        $data->set('itemstyle', $import->fixSection($data->get('itemstyle')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-list', n2_('General'));

        new Textarea($settings, 'content', n2_('Items'), '', array(
            'width'  => 314,
            'height' => 120
        ));

        new Select($settings, 'type', n2_('List type'), '', array(
            'options' => array(
                'none'                 => n2_x('None', 'List layer type'),
                'disc'                 => n2_x('Disc', 'List layer type'),
                'square'               => n2_x('Square', 'List layer type'),
                'circle'               => n2_x('Circle', 'List layer type'),
                'decimal'              => n2_x('Decimal', 'List layer type'),
                'armenian'             => n2_x('Armenian', 'List layer type'),
                'cjk-ideographic'      => n2_x('Cjk-ideographic', 'List layer type'),
                'decimal-leading-zero' => n2_x('Decimal-leading-zero', 'List layer type'),
                'georgian'             => n2_x('Georgian', 'List layer type'),
                'hebrew'               => n2_x('Hebrew', 'List layer type'),
                'hiragana'             => n2_x('Hiragana', 'List layer type'),
                'hiragana-iroha'       => n2_x('Hiragana-iroha', 'List layer type'),
                'katakana'             => n2_x('Katakana', 'List layer type'),
                'katakana-iroha'       => n2_x('Katakana-iroha', 'List layer type'),
                'lower-alpha'          => n2_x('Lower-alpha', 'List layer type'),
                'lower-greek'          => n2_x('Lower-greek', 'List layer type'),
                'lower-latin'          => n2_x('Lower-latin', 'List layer type'),
                'lower-roman'          => n2_x('Lower-roman', 'List layer type'),
                'upper-alpha'          => n2_x('Upper-alpha', 'List layer type'),
                'upper-latin'          => n2_x('Upper-latin', 'List layer type'),
                'upper-roman'          => n2_x('Upper-roman', 'List layer type')
            )
        ));
        new HiddenFont($settings, 'font', false, '', array(
            'mode' => 'list',
        ));
        new HiddenStyle($settings, 'liststyle', n2_('Style') . ' - ' . n2_('List'), '', array(
            'mode' => 'heading'
        ));
        new HiddenStyle($settings, 'itemstyle', n2_('Style') . ' - ' . n2_('Item'), '', array(
            'mode' => 'heading'
        ));
    }
}Item/HtmlList/ItemHtmlListFrontend.php000064400000002355152426505640014010 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\HtmlList;


use Nextend\Framework\View\Html;
use Nextend\Framework\Sanitize;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemHtmlListFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }


    private function getHTML() {
        $owner = $this->layer->getOwner();

        $font      = $owner->addFont($this->data->get('font'), 'list');
        $listStyle = $owner->addStyle($this->data->get('liststyle'), 'heading');
        $itemStyle = $owner->addStyle($this->data->get('itemstyle'), 'heading');


        $html = '';
        $lis  = explode("\n", Sanitize::filter_allowed_html($owner->fill($this->data->get('content', ''))));
        foreach ($lis as $li) {
            $html .= '<li class="' . $itemStyle . ' n2-ow" style="list-style-type:inherit;">' . $li . '</li>';
        }

        return Html::tag('ol', array(
            'class' => $font . '' . $listStyle . ' n2-ss-item-content n2-ow',
            'style' => "list-style-type:" . $this->data->get('type')
        ), $html);
    }
}Item/Icon/ItemIcon.php000064400000011513152426505710010562 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Icon;


use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\Icon;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemIcon extends AbstractItem {

    protected $ordering = 5;

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'icon2';
    }

    public function getTitle() {
        return n2_('Icon');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--icon';
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemIconFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {
        return parent::getValues() + array(
                'icon'            => 'fa:smile-o',
                'color'           => 'ffffffff',
                'colorhover'      => 'ffffff00',
                'size'            => 100,
                'href'            => '#',
                'href-target'     => '_self',
                'href-rel'        => '',
                'href-aria-label' => '',
                'style'           => ''
            );
    }

    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('icon', $slide->fill($data->get('icon', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('style'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('style', $import->fixSection($data->get('style')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-icon2-icon', n2_('General'));
        new Icon($settings, 'icon', n2_('Icon'));
        new Color($settings, 'color', n2_('Color'), '00000080', array(
            'alpha' => true
        ));
        new Color($settings, 'colorhover', n2_('Hover color'), '00000000', array(
            'alpha' => true
        ));

        new NumberSlider($settings, 'size', n2_('Size'), 24, array(
            'min'       => 4,
            'max'       => 10000,
            'sliderMax' => 200,
            'step'      => 4,
            'wide'      => 3,
            'unit'      => 'px'
        ));

        new HiddenStyle($settings, 'style', false, '', array(
            'mode' => 'box'
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-icon2-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'style'         => 'width:236px;',
            'relatedFields' => array(
                'item_icon2href-target',
                'item_icon2href-rel',
                'item_icon2href-aria-label'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));
        new Text($link, 'href-aria-label', n2_('ARIA label'), '', array(
            'tipLabel'       => n2_('ARIA label'),
            'tipDescription' => sprintf(n2_('Enter an %1$s aria-label attribute %2$s that describes the link.'), '<a href="https://www.w3.org/TR/WCAG20-TECHS/ARIA14.html" target="_blank">', '</a>')
        ));
    }
}Item/Icon/ItemIconFrontend.php000064400000004031152426505760012264 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Icon;


use Nextend\Framework\Icon\Icon;
use Nextend\Framework\Parser\Color;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemIconFrontend extends AbstractItemFrontend {

    public function isAuto() {
        return true;
    }

    public function render() {

        if ($this->hasLink()) {
            $attributes = array(
                'style' => 'display:inline-block;',
                'class' => 'n2-ss-item-content n2-ow'
            );

            $ariaLabel = $this->data->get('href-aria-label', '');
            if (!empty($ariaLabel)) {
                $attributes['aria-label'] = $ariaLabel;
            }

            return $this->getLink($this->getHtml(false), $attributes);
        }

        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml($isContent = true) {
        $owner = $this->layer->getOwner();

        $iconData = Icon::render($this->data->get('icon'));
        if (!$iconData) {
            return '';
        }

        $styleClass = $owner->addStyle($this->data->get('style'), 'heading');

        $selector = 'div#' . $owner->getElementID() . ' .' . $this->id;
        $color    = Color::colorToRGBA($this->data->get('color', '00000080'));
        $style    = $selector . '{color:' . $color . '}';
        if (substr($this->data->get('colorhover', '00000000'), 6, 2) != '00') {
            $colorHover = Color::colorToRGBA($this->data->get('colorhover', '00000000'));
            $style      .= $selector . ':HOVER,' . $selector . ':FOCUS,' . $selector . ':VISITED{color:' . $colorHover . '}';
        }

        $owner->addCSS($style);


        return '<span class="n2i ' . $styleClass . ' ' . $this->id . ' ' . $iconData['class'] . ($isContent ? ' n2-ss-item-content' : '') . '" style="font-size:' . ($this->data->get('size') / 16 * 100) . '%;">' . $iconData['ligature'] . '</span>';
    }
}Item/Html/ItemHtml.php000064400000004765152426506030010621 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Html;


use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Radio\TextAlign;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemHtml extends AbstractItem {

    protected $ordering = 102;

    protected $layerProperties = array("desktopportraitwidth" => 200);

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'html';
    }

    public function getTitle() {
        return n2_('HTML');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--html';
    }

    public function getGroup() {
        return n2_x('Advanced', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemHtmlFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {
        return parent::getValues() + array(
                'html'      => '<div>' . n2_('Empty element') . '</div>',
                'css'       => ".selector{\n\n}",
                'textalign' => 'inherit'
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('html', $slide->fill($data->get('html', '')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-html', n2_('General'));
        new Warning($settings, 'item-html-notice', sprintf(n2_('Please note that %1$swe do not support%2$s the HTML layer and the 3rd party codes loaded by it. We only suggest using this layer if you are a developer. %3$sAlso, make sure your HTML code is valid! Invalid HTML codes can mess up the entire slide and the only way resolving this problem is deleting the slide.'), '<b>', '</b>', '<br>'));

        new Textarea($settings, 'html', 'HTML', '', array(
            'height' => 130,
            'width'  => 314
        ));
        new TextAlign($settings, 'textalign', n2_('Text align'), 'inherit');

        if (class_exists('tidy', false)) {
            new OnOff($settings, 'tidy', n2_('Repair HTML errors'), 1);
        }

        new Textarea($settings, 'css', 'CSS', '', array(
            'height' => 130,
            'width'  => 314
        ));
    }
}Item/Html/ItemHtmlFrontend.php000064400000004046152426506100012307 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Html;


use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;
use tidy;

class ItemHtmlFrontend extends AbstractItemFrontend {

    private $scripts = array();

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $css = '';
        if ($cssCode = $this->data->get('css', '')) {
            $css = Html::style($cssCode);
        }

        return Html::tag("div", array(), $this->closeTags('<div style="text-align:' . $this->data->get("textalign") . ';">' . $owner->fill($this->data->get("html")) . '</div>') . $css);
    }

    private function closeTags($html) {

        $html = Html::tag('div', array(
            'class' => 'n2-ss-item-content n2-ow'
        ), $html);

        if (class_exists('tidy', false) && $this->data->get('tidy', 1)) {
            $tidy_config = array(
                'show-body-only'      => true,
                'wrap'                => 0,
                'new-blocklevel-tags' => 'menu,mytag,article,header,footer,section,nav,svg,path,g,a,lottie-player',
                'new-inline-tags'     => 'video,audio,canvas,ruby,rt,rp',
                'doctype'             => '<!DOCTYPE HTML>',
                'preserve-entities'   => true,
                'drop-empty-elements' => false,
                'drop-empty-paras'    => false
            );
            $tidy        = new tidy();

            $html = preg_replace_callback('/<script.*?>.*?<\/script>/ism', array(
                $this,
                'matchScript'
            ), $html);

            return $tidy->repairString($html, $tidy_config, 'UTF8') . implode('', $this->scripts);
        }

        return $html;
    }

    public function matchScript($matches) {
        $this->scripts[] = $matches[0];

        return '';
    }
}Item/HighlightedHeading/ItemHighlightedHeading.php000064400000030175152426506150016206 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\HighlightedHeading;


use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemHighlightedHeading extends AbstractItem {

    protected $ordering = 3;

    protected $fonts = array(
        'font' => array(
            'defaultName' => 'item-highlighted-heading-font',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{},{}]}'
        )
    );

    protected $styles = array(
        'style' => array(
            'defaultName' => 'item-highlighted-heading-style',
            'value'       => '{"data":[{},{"padding":"0|*|0|*|0|*|0|*|px"},{"padding":"0|*|0|*|0|*|0|*|px"}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'highlightedHeading';
    }

    public function getTitle() {
        return n2_('Highlighted heading');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--highlightheading';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemHighlightedHeadingFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {

        return parent::getValues() + array(
                'type'  => 'circle1',
                'color' => '5CBA3CFF',
                'width' => 10,
                'front' => 0,

                'before-text'      => n2_('This page is'),
                'highlighted-text' => n2_('Amazing'),
                'after-text'       => '',

                'animate'    => 1,
                'delay'      => 0,
                'duration'   => 1500,
                'loop'       => 0,
                'loop-delay' => 2000,

                'href'        => '#',
                'href-target' => '_self',
                'href-rel'    => '',

                'priority' => 'div',

                'class' => ''
            );
    }

    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/highlightedHeading.n2less", array(
            "sliderid" => $renderable->elementId
        ));

        $renderable->addScript('_N2.ItemHighlightedHeading.svg=' . json_encode($this->getTypes()) . ';');
    }

    private function getTypes() {
        static $types = null;
        if ($types === null) {
            $types     = array();
            $extension = 'svg';
            $folder    = self::getAssetsPath() . '/svg/';
            $files     = Filesystem::files($folder);
            for ($i = 0; $i < count($files); $i++) {
                $pathInfo = pathinfo($files[$i]);
                if (isset($pathInfo['extension']) && $pathInfo['extension'] == $extension) {
                    $types[$pathInfo['filename']] = file_get_contents($folder . $files[$i]);
                }
            }
        }

        return $types;
    }

    private function getTypeOptions() {
        return array(
            ''                  => n2_('None'),
            'circle1'           => sprintf(n2_('Circle %d'), '1'),
            'circle2'           => sprintf(n2_('Circle %d'), '2'),
            'circle3'           => sprintf(n2_('Circle %d'), '3'),
            'curly1'            => sprintf(n2_('Curly %d'), '1'),
            'curly2'            => sprintf(n2_('Curly %d'), '2'),
            'highlight1'        => sprintf(n2_('Highlight %d'), '1'),
            'highlight2'        => sprintf(n2_('Highlight %d'), '2'),
            'highlight3'        => sprintf(n2_('Highlight %d'), '3'),
            'line_through1'     => sprintf(n2_('Line Through %d'), '1'),
            'line_through2'     => sprintf(n2_('Line Through %d'), '2'),
            'line_through3'     => sprintf(n2_('Line Through %d'), '3'),
            'rectangle1'        => sprintf(n2_('Rectangle %d'), '1'),
            'rectangle2'        => sprintf(n2_('Rectangle %d'), '2'),
            'underline1'        => sprintf(n2_('Underline %d'), '1'),
            'underline2'        => sprintf(n2_('Underline %d'), '2'),
            'underline3'        => sprintf(n2_('Underline %d'), '3'),
            'underline_double1' => sprintf(n2_('Underline double %d'), '1'),
            'underline_double2' => sprintf(n2_('Underline double %d'), '2'),
            'zigzag1'           => sprintf(n2_('ZigZag %d'), '1'),
            'zigzag2'           => sprintf(n2_('ZigZag %d'), '2'),
            'zigzag3'           => sprintf(n2_('ZigZag %d'), '3'),
        );
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('heading', $slide->fill($data->get('heading', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('style'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('style', $import->fixSection($data->get('style')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-highlighted-heading-font', false, $this->fonts['font']['value'], array(
            'mode' => 'hover'
        ));

        new Style($row1, 'item-highlighted-heading-style', false, $this->styles['style']['value'], array(
            'mode' => 'heading'
        ));
    }

    public function renderFields($container) {
        $text = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-highlighted-heading-text', n2_('General'));

        new Text($text, 'before-text', n2_('Before text'), '', array(
            'style' => 'width: 302px;'
        ));

        new Text($text, 'highlighted-text', n2_('Highlighted text'), '', array(
            'style' => 'width: 302px;'
        ));

        new Text($text, 'after-text', n2_('After text'), '', array(
            'style' => 'width: 302px;'
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-highlightheading-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'style'         => 'width:236px;',
            'relatedFields' => array(
                'item_highlightedHeadinghref-target',
                'item_highlightedHeadinghref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));

        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-highlighted-heading', n2_('Highlight'));

        new Select($settings, 'type', n2_('Type'), '', array(
            'options'       => $this->getTypeOptions(),
            'relatedFields' => array(
                'item_highlightedHeadingcolor',
                'item_highlightedHeadingwidth',
                'item_highlightedHeadingfront',
                'fieldset-layer-window-item-highlightheading-animation'
            )
        ));
        new Color($settings, 'color', n2_('Color'), '', array(
            'alpha' => true
        ));
        new NumberSlider($settings, 'width', n2_('Width'), '', array(
            'max'  => 100,
            'min'  => 1,
            'unit' => 'px',
            'wide' => 3
        ));
        new OnOff($settings, 'front', n2_('Bring front'), 0, array(
            'tipLabel'       => n2_('Bring front'),
            'tipDescription' => n2_('Puts the shape on top of the text.')
        ));

        $animation = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-highlightheading-animation', n2_('Animation'));
        new OnOff($animation, 'animate', n2_('Animate'), 1, array(
            'relatedFieldsOn' => array(
                'item_highlightedHeadingdelay',
                'item_highlightedHeadingduration',
                'item_highlightedHeadingloop-group'
            )
        ));
        new Number($animation, 'delay', n2_('Delay'), 0, array(
            'unit' => 'ms',
            'wide' => 5
        ));
        new Number($animation, 'duration', n2_('Duration'), 1500, array(
            'unit' => 'ms',
            'wide' => 5,
            'post' => 'break'
        ));

        $groupingLoop = new Grouping($animation, 'loop-group');

        new OnOff($groupingLoop, 'loop', n2_x('Loop', 'Effect'), 1, array(
            'relatedFieldsOn' => array(
                'item_highlightedHeadingloop-delay'
            )
        ));
        new Number($groupingLoop, 'loop-delay', n2_('Loop delay'), 0, array(
            'unit' => 'ms',
            'wide' => 5
        ));

        $dev = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-highlightheading-dev', n2_('Advanced'));
        new Select($dev, 'priority', 'Tag', 'div', array(
            'options' => array(
                'div' => 'div',
                '1'   => 'H1',
                '2'   => 'H2',
                '3'   => 'H3',
                '4'   => 'H4',
                '5'   => 'H5',
                '6'   => 'H6'
            )
        ));

        new HiddenFont($settings, 'font', n2_('Font') . ' - ' . n2_('Heading'), '', array(
            'mode' => 'highlight'
        ));

        new HiddenStyle($settings, 'style', n2_('Style') . ' - ' . n2_('Heading'), '', array(
            'mode' => 'highlight'
        ));


        new Text($dev, 'class', n2_('CSS Class'), '', array(
            'style'          => 'width:226px;',
            'tipLabel'       => n2_('CSS Class'),
            'tipDescription' => n2_('Class on the selected tag element.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1812-layer-style#advanced'
        ));

    }
}Item/HighlightedHeading/ItemHighlightedHeadingFrontend.php000064400000012623152426506270017707 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\HighlightedHeading;


use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Parser\Color;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemHighlightedHeadingFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $this->loadResources($owner);

        $heading = array();

        $beforeText = Sanitize::filter_allowed_html($owner->fill($this->data->get('before-text', '')));
        if (!empty($beforeText)) {
            $heading[] = Html::tag('div', array(
                'class' => 'n2-ss-highlighted-heading-before'
            ), $beforeText);
        }

        $highlightedText = Sanitize::filter_allowed_html($owner->fill($this->data->get('highlighted-text', '')));
        if (!empty($highlightedText)) {

            $svg           = '';
            $highlightType = $this->data->get('type', '');
            if (!empty($highlightType)) {
                $svgPath = self::getAssetsPath() . '/svg/' . $highlightType . '.svg';
                if (Filesystem::fileexists($svgPath)) {
                    $svg = Filesystem::readFile($svgPath);

                    $highlightColor = $this->data->get('color', '');
                    $css            = array(
                        'stroke:#' . substr($highlightColor, 0, 6) . ';',
                        'stroke-opacity:' . Color::hex2opacity($highlightColor) . ';',
                        'stroke-width:' . $this->data->get('width', 10) . 'px;'
                    );
                    $owner->addCSS('div #' . $owner->getElementID() . ' #' . $this->id . ' svg path{' . implode('', $css) . '}');
                }
            }

            $attributes = array(
                'class'          => 'n2-highlighted n2-ss-highlighted-heading-highlighted n2-ow',
                'data-highlight' => $highlightType
            );

            if ($this->data->get('animate', 1)) {
                $attributes['data-animate'] = 1;
            }

            $delay = $this->data->get('delay', 0);
            if ($delay > 0) {
                $attributes['data-delay'] = $delay;
            }

            $duration = $this->data->get('duration', 1500);
            if ($duration != 1500) {
                $attributes['data-duration'] = $duration;
            }

            if ($this->data->get('loop', 0)) {
                $attributes['data-loop'] = 1;
            }

            $loopDelay = $this->data->get('loop-delay', 0);
            if ($loopDelay >= 0) {
                $attributes['data-loop-delay'] = $loopDelay;
            }

            if ($this->data->get('front', 0)) {
                $attributes['data-front'] = 1;
            }

            $highlightedInner = Html::tag('div', array(
                    'class' => 'n2-ss-highlighted-heading-highlighted-text'
                ), $highlightedText) . $svg;


            $href = $this->data->get('href', '');
            if (!empty($href) && $href != '#') {
                $heading[] = $this->getLink($highlightedInner, $attributes);
            } else {
                $heading[] = Html::tag('div', $attributes, $highlightedInner);
            }
        }

        $afterText = Sanitize::filter_allowed_html($owner->fill($this->data->get('after-text', '')));
        if (!empty($afterText)) {
            $heading[] = Html::tag('div', array(
                'class' => 'n2-ss-highlighted-heading-after'
            ), $afterText);
        }


        $font = $owner->addFont($this->data->get('font'), 'highlight');


        $style = $owner->addStyle($this->data->get('style'), 'highlight');

        return $this->heading($this->data->get('priority', 'div'), array(
            "id"    => $this->id,
            "class" => 'n2-ss-highlighted-heading-wrapper ' . $font . ' ' . $style . ' n2-ss-item-content n2-ss-text n2-ow'
        ), implode('', $heading));
    }

    private function heading($type, $attributes, $content) {
        if (is_numeric($type) && $type > 0) {
            return Html::tag("h{$type}", $attributes, $content);
        }

        return Html::tag("div", $attributes, $content);
    }

    /**
     * @param AbstractRenderableOwner $owner
     */
    public function loadResources($owner) {
        $owner->addLess(self::getAssetsPath() . "/highlightedHeading.n2less", array(
            "sliderid" => $owner->getElementID()
        ));

        if (!$owner->isScriptAdded('highlighted-heading')) {
            if ($this->isEditor) {
                $owner->addScript('this.sliderElement.querySelectorAll(\'.n2-ss-currently-edited-slide .n2-ss-highlighted-heading-highlighted\').forEach((function(el){new _N2.HighlightedHeadingItemAdmin(el, this)}).bind(this));', 'highlighted-heading');
            } else {
                $owner->addScript('this.sliderElement.querySelectorAll(\'.n2-ss-highlighted-heading-highlighted\').forEach((function(el){new _N2.FrontendItemHighlightedHeading(el, this)}).bind(this));', 'highlighted-heading');
            }
        }
    }
}Item/Counter/ItemCounter.php000064400000012557152426506340012051 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Counter;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemCounter extends AbstractItem {

    protected $ordering = 11;

    protected $fonts = array(
        'font'      => array(
            'defaultName' => 'item-counter-font',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"40||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"}]}'
        ),
        'fontlabel' => array(
            'defaultName' => 'item-counter-fontlabel',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"16||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"2","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'counter';
    }

    public function getTitle() {
        return n2_('Counter');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--counter';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemCounterFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {

        return parent::getValues() + array(
                'value'             => 50,
                'startvalue'        => 0,
                'pre'               => '',
                'post'              => '%',
                'label'             => '',
                'labelplacement'    => 'after',
                'animationduration' => 1000,
                'animationdelay'    => 0
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('label', $slide->fill($data->get('label', '')));
        $data->set('value', $slide->fill($data->get('value', '')));
        $data->set('startvalue', $slide->fill($data->get('startvalue', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('fontlabel'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('fontlabel', $import->fixSection($data->get('fontlabel')));

        return $data;
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-counter-font', n2_('Counter'), $this->fonts['font']['value'], array(
            'mode' => 'simple'
        ));

        new Font($row1, 'item-counter-fontlabel', n2_('Label'), $this->fonts['fontlabel']['value'], array(
            'mode' => 'simple'
        ));
    }

    public function renderFields($container) {
        $counter = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-counter', n2_('Counter'));
        new Number($counter, 'value', n2_('Value'), '', array(
            'wide' => 5
        ));
        new Number($counter, 'startvalue', n2_('Start from'), '', array(
            'wide' => 5
        ));

        $labels = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-counter-labels', n2_('Labels'));
        new Text($labels, 'pre', n2_('Pre'), '', array(
            'style' => 'width:50px;'
        ));
        new Text($labels, 'post', n2_('Post'), '', array(
            'style' => 'width:50px;'
        ));
        new Text($labels, 'label', n2_('Label'), '', array(
            'style' => 'width:150px;'
        ));
        new Select($labels, 'labelplacement', n2_('Placement'), '', array(
            'options' => array(
                'before' => n2_('Before'),
                'after'  => n2_('After')
            )
        ));

        $animation = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-counter-animation', n2_('Animation'));
        new Number($animation, 'animationduration', n2_('Animation duration'), 1, array(
            'min'  => 0,
            'wide' => 5,
            'unit' => 'ms'
        ));
        new Number($animation, 'animationdelay', n2_('Delay'), 0, array(
            'min'  => 0,
            'wide' => 5,
            'unit' => 'ms'
        ));

        new HiddenFont($counter, 'font', n2_('Font') . ' - ' . n2_('Counter'), '', array(
            'mode' => 'simple'
        ));
        new HiddenFont($counter, 'fontlabel', n2_('Font') . ' - ' . n2_('Label'), '', array(
            'mode' => 'simple'
        ));
    }

}Item/Counter/ItemCounterFrontend.php000064400000006714152426506420013546 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Counter;


use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemCounterFrontend extends AbstractItemFrontend {

    public function isAuto() {
        return true;
    }

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $value      = intval($owner->fill($this->data->get('value')));
        $min        = min(0, $value);
        $startvalue = max(intval($owner->fill($this->data->get('startvalue'))), $min);
        $total      = max($startvalue, $value);
        $duration   = max(0, intval($this->data->get('animationduration')));

        if ($total != $min) {
            $toPercent = (min($value, $total) - $min) / ($total - $min);
            if ($duration == 0) {
                // We do not have animation
                $fromPercent = $toPercent;
            } else {
                $fromPercent = (min($startvalue, $total) - $min) / ($total - $min);
            }
        } else {
            $duration    = 0;
            $fromPercent = $toPercent = 0;
        }

        $label     = Sanitize::filter_allowed_html($owner->fill($this->data->get('label')));
        $placement = '';
        if (!empty($label)) {

            $fontLabel = $owner->addFont($this->data->get('fontlabel'), 'simple');

            $labelHTML = Html::tag('div', array(
                'class' => $fontLabel
            ), $label);
            $placement = $this->data->get('labelplacement');
        }

        $html = '';

        if ($placement == 'before') {
            $html .= $labelHTML;
        }

        $font = $owner->addFont($this->data->get('font'), 'simple');

        $pre             = Sanitize::filter_allowed_html($this->data->get('pre'));
        $post            = Sanitize::filter_allowed_html($this->data->get('post'));
        $countingDivHTML = Html::tag('div', array(
            'class' => 'n2-ss-item-counter-counting-div n2-ow ' . $font
        ), $pre . round($min + $fromPercent * ($total - $min)) . $post);

        $html .= Html::tag('div', array(
            'id'    => $this->id,
            'class' => 'n2-ow'
        ), $countingDivHTML);


        if ($placement == 'after') {
            $html .= $labelHTML;
        }

        $jsData = array(
            'name'        => 'counter',
            'pre'         => $pre,
            'post'        => $post,
            'fromPercent' => $fromPercent,
            'toPercent'   => $toPercent,
            'duration'    => $duration,
            'delay'       => $this->data->get('animationdelay'),
            'min'         => $min,
            'total'       => $total,
            'counting'    => '.n2-ss-item-counter-counting-div',
            'displayMode' => false
        );

        if ($this->isEditor && $owner->underEdit) {
            $owner->addScript('new _N2.CounterItemAdmin(this, "' . $this->id . '", ' . json_encode($jsData) . ');');
        } else {
            $owner->addScript('new _N2.FrontendItemCounter(this, "' . $this->id . '", ' . json_encode($jsData) . ');');
        }

        return Html::tag('div', array(
            'class' => 'n2-ss-item-content n2-ow'
        ), $html);
    }
}Item/Countdown/ItemCountdown.php000064400000026176152426506470012761 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Countdown;


use Nextend\Framework\Asset\Js\Js;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Gap;
use Nextend\Framework\Form\Element\Grouping;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\Message\Notice;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Platform\Platform;
use Nextend\SmartSlider3\Form\Element\DatePicker;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemCountdown extends AbstractItem {

    protected $ordering = 11;

    protected $fonts = array(
        'font'      => array(
            'defaultName' => 'item-countdown-font',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"40||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"}]}'
        ),
        'fontlabel' => array(
            'defaultName' => 'item-countdown-fontlabel',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"16||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"capitalize"}]}'
        )
    );

    protected $styles = array(
        'style' => array(
            'defaultName' => 'item-countdown-style',
            'value'       => ''
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'countdown';
    }

    public function getTitle() {
        return n2_('Countdown');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--countdown';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemCountdownFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {

        return parent::getValues() + array(
                'slide-schedule' => 0,
                'date'           => date('Y-m-d H:i:s'),

                'gap'            => '10|*|10',
                'columns'        => 4,
                'label'          => 1,
                'tablet-style'   => 0,
                'tablet-gap'     => '10|*|10',
                'tablet-columns' => 4,

                'mobile-style'   => 0,
                'mobile-gap'     => '10|*|10',
                'mobile-columns' => 1,

                'action'       => '',
                'redirect-url' => ''
            );
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('style'));
        $export->addVisual($data->get('fontlabel'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('style', $import->fixSection($data->get('style')));
        $data->set('fontlabel', $import->fixSection($data->get('fontlabel')));

        return $data;
    }

    public function globalDefaultItemFontAndStyle($container) {
        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-countdown-font', n2_('Countdown'), $this->fonts['font']['value'], array(
            'mode' => 'simple'
        ));

        new Font($row1, 'item-countdown-fontlabel', n2_('Label'), $this->fonts['fontlabel']['value'], array(
            'mode' => 'simple'
        ));

        new Style($row1, 'item-countdown-style', n2_('Countdown'), $this->styles['style']['value'], array(
            'mode' => 'heading'
        ));
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . '/countdown.n2less', array(
            'sliderid' => $renderable->elementId
        ));
    }

    public function renderFields($container) {

        $offset  = (Platform::getTimestamp() - gmdate('U', time() - date('Z'))) / 60;
        $minutes = $offset % 60;
        $hours   = (int)($offset / 60);

        Js::addGlobalInline('window.ssTimezoneOffset=' . json_encode(sprintf('%+03d:%02d', $hours, $minutes)) . ';');

        $dateFieldset = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-countdown', n2_('Date'));

        new OnOff($dateFieldset, 'slide-schedule', n2_('Use slide schedule'), 0, array(
            'relatedFieldsOff' => array(
                'item_countdowndate'
            ),
            'relatedFieldsOn'  => array(
                'item_countdownschedule-notice'
            ),
            'tipLabel'         => n2_('Use slide schedule'),
            'tipDescription'   => n2_('You can use the "Unpublished on" date of the slide itself.'),
            'tipLink'          => 'https://smartslider.helpscoutdocs.com/article/2047-countdown-layer#use-slide-schedule'
        ));

        new Notice($dateFieldset, 'schedule-notice', n2_('Use Slide Schedule'), n2_('Go to Slide → Content tab and set the Unpublish on date for the slide.'));


        $dateGroup = new Grouping($dateFieldset, 'date-group');

        new DatePicker($dateGroup, 'date', 'Date', date('Y-m-d H:i:s'), array(
            'onOff' => false
        ));

        new HiddenFont($dateFieldset, 'font', n2_('Font') . ' - ' . n2_('Countdown'), '', array(
            'mode' => 'simple'
        ));

        new HiddenFont($dateFieldset, 'fontlabel', n2_('Font') . ' - ' . n2_('Label'), '', array(
            'mode' => 'simple'
        ));

        new HiddenStyle($dateFieldset, 'style', false, '', array(
            'mode' => 'heading'
        ));

        $style = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-countdown-style', n2_('Style'));

        new OnOff($style, 'label', n2_('Show label'), 1, array(
            'tipLabel'       => n2_('Show label'),
            'tipDescription' => n2_('Displays the days, hours, minutes and seconds texts under the counter numbers. To display the labels in your own language, translate the texts in the language files.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1938-translation#translation'
        ));

        $gap = new Gap($style, 'gap', n2_('Gap'), '10|*|10', array(
            'tipLabel'       => n2_('Gap'),
            'tipDescription' => n2_('Creates vertical and horizontal distance between the counter elements.')
        ));
        $gap->setUnit('px');

        for ($i = 1; $i < 3; $i++) {
            new NumberAutoComplete($gap, 'gap-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'wide'   => 3
            ));
        }

        new Select($style, 'columns', n2_('Columns'), '4', array(
            'options' => array(
                '1' => '1',
                '2' => '2',
                '4' => '4'
            )
        ));

        $tabletStyleGroup = new Grouping($style, 'tablet-style-group');

        new OnOff($tabletStyleGroup, 'tablet-style', n2_('Tablet style'), 0, array(
            'relatedFieldsOn' => array(
                'item_countdowntablet-gap',
                'item_countdowntablet-columns'
            ),
            'tipLabel'        => n2_('Tablet style'),
            'tipDescription'  => n2_('Set custom Gap and Column for tablet.')
        ));

        $gap = new Gap($tabletStyleGroup, 'tablet-gap', n2_('Gap'), '10|*|10');
        $gap->setUnit('px');

        for ($i = 1; $i < 3; $i++) {
            new NumberAutoComplete($gap, 'tablet-gap-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'wide'   => 3
            ));
        }

        new Select($tabletStyleGroup, 'tablet-columns', n2_('Columns'), '4', array(
            'options' => array(
                '1' => '1',
                '2' => '2',
                '4' => '4'
            )
        ));

        $mobileStyleGroup = new Grouping($style, 'mobile-style-group');
        new OnOff($mobileStyleGroup, 'mobile-style', n2_('Mobile style'), 0, array(
            'relatedFieldsOn' => array(
                'item_countdownmobile-gap',
                'item_countdownmobile-columns'
            ),
            'tipLabel'        => n2_('Mobile style'),
            'tipDescription'  => n2_('Set custom Gap and Column for mobile.')
        ));

        $gap = new Gap($mobileStyleGroup, 'mobile-gap', n2_('Gap'), '10|*|10');
        $gap->setUnit('px');

        for ($i = 1; $i < 3; $i++) {
            new NumberAutoComplete($gap, 'mobile-gap-' . $i, false, '', array(
                'values' => array(
                    0,
                    5,
                    10,
                    20,
                    30
                ),
                'wide'   => 3
            ));
        }

        new Select($mobileStyleGroup, 'mobile-columns', n2_('Columns'), '4', array(
            'options' => array(
                '1' => '1',
                '2' => '2',
                '4' => '4'
            )
        ));

        $general = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-countdown-general', n2_('General'));

        new Select($general, 'action', n2_('Action when ends'), '4', array(
            'options'            => array(
                ''          => n2_('No action'),
                'hideLayer' => n2_('Hide layer'),
                'redirect'  => n2_('Redirect to URL'),
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'redirect',
                    ),
                    'field'  => array(
                        'item_countdownredirect-url'
                    )
                )
            ),
            'tipLabel'           => n2_('Action when ends'),
            'tipDescription'     => n2_('Choose what happens after the counter reached zero.'),
            'tipLink'            => 'https://smartslider.helpscoutdocs.com/article/2047-countdown-layer#action-when-ends'
        ));

        new Text($general, 'redirect-url', n2_('Redirect to URL'), '', array(
            'style' => 'width: 140px;'
        ));
    }

}Item/Countdown/ItemCountdownFrontend.php000064400000013133152426506540014444 0ustar00<?php

namespace Nextend\SmartSlider3Pro\Renderable\Item\Countdown;

use Nextend\Framework\Platform\Platform;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemCountdownFrontend extends AbstractItemFrontend {

    private $font, $style, $fontLabel;

    public function isAuto() {
        return true;
    }

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();
        $this->loadResources($owner);

        if ($this->data->get('slide-schedule')) {
            $date = $this->layer->getOwner()->publish_down;
        } else {
            $date = $this->data->get('date');
        }

        if (empty($date)) {
            $date = date('Y-m-d H:i:s', time() + 86400);
        }

        $currentTimestampUtc = gmdate('U');

        $timezoneOffset = Platform::getTimestamp() - $currentTimestampUtc;
        /**
         * Adjust date to GMT
         */
        $timestampUTC = strtotime($date) - $timezoneOffset;


        $diff = $timestampUTC - $currentTimestampUtc;

        $days    = 0;
        $hours   = 0;
        $minutes = 0;
        $seconds = 0;

        if ($diff > 0) {
            $days    = floor($diff / 86400);
            $diff    -= $days * 86400;
            $hours   = floor($diff / 3600);
            $diff    -= $hours * 3600;
            $minutes = floor($diff / 60);
            $diff    -= $minutes * 60;
            $seconds = $diff;
        }

        $this->font      = $owner->addFont($this->data->get('font'), 'simple');
        $this->fontLabel = $owner->addFont($this->data->get('fontlabel'), 'simple');
        $this->style     = $owner->addStyle($this->data->get('style'), 'heading');


        $columns = $this->data->get('columns', 4);
        $gap     = explode('|*|', $this->data->get('gap', '10|*|10'));

        $cssVariables = array(
            '--ss-counter-columns:' . $columns,
            '--ss-counter-gap-v:' . $gap[0] . 'px',
            '--ss-counter-gap-h:' . $gap[1] . 'px'
        );

        if ($this->data->get('tablet-style')) {
            $tabletColumns = $this->data->get('tablet-columns', 4);
            if ($columns !== $tabletColumns) {
                $cssVariables[] = '--ss-counter-tablet-columns:' . $tabletColumns;
            }
            $tabletGap = explode('|*|', $this->data->get('tablet-gap', '10|*|10'));
            if ($gap[0] !== $tabletGap[0]) {
                $cssVariables[] = '--ss-counter-tablet-gap-v:' . $tabletGap[0] . 'px';
            }
            if ($gap[1] !== $tabletGap[1]) {
                $cssVariables[] = '--ss-counter-tablet-gap-h:' . $tabletGap[1] . 'px';
            }
        }

        if ($this->data->get('mobile-style')) {
            $mobileColumns = $this->data->get('mobile-columns', 4);
            if ($columns !== $mobileColumns) {
                $cssVariables[] = '--ss-counter-mobile-columns:' . $mobileColumns;
            }
            $mobileGap = explode('|*|', $this->data->get('mobile-gap', '10|*|10'));
            if ($gap[0] !== $mobileGap[0]) {
                $cssVariables[] = '--ss-counter-mobile-gap-v:' . $mobileGap[0] . 'px';
            }
            if ($gap[1] !== $mobileGap[1]) {
                $cssVariables[] = '--ss-counter-mobile-gap-h:' . $mobileGap[1] . 'px';
            }
        }

        return Html::tag('div', array(
            'class'             => 'n2-ss-item-countdown_container n2-ss-item-content n2-ow-all',
            'style'             => implode(';', $cssVariables),
            'data-timestamp'    => $timestampUTC,
            'data-action'       => $this->data->get('action'),
            'data-redirect-url' => $this->data->get('redirect-url')
        ), implode(array(
            $this->createCard('day', $days, n2_('Days')),
            $this->createCard('hour', $hours, n2_('Hours')),
            $this->createCard('minute', $minutes, n2_('Minutes')),
            $this->createCard('second', $seconds, n2_('Seconds'))
        )));
    }

    private function createCard($element, $value, $label) {

        $labelHTML = '';
        if ($this->data->get('label', 1)) {
            $labelHTML = Html::tag('div', array(
                'class' => 'n2-ss-item-countdown_label ' . $this->fontLabel
            ), $label);
        }

        return Html::tag('div', array(
            'class' => 'n2-ss-item-countdown_element n2-ss-item-countdown_' . $element . ' ' . $this->style
        ), Html::tag('div', array(
                'class' => 'n2-ss-item-countdown_number ' . $this->font
            ), $this->formatNumber($value)) . $labelHTML);
    }

    private function formatNumber($number) {
        if ($number < 10) {
            return '0' . $number;
        } else {
            return $number;
        }
    }

    /**
     * @param AbstractRenderableOwner $owner
     */
    public function loadResources($owner) {
        $owner->addLess(self::getAssetsPath() . "/countdown.n2less", array(
            "sliderid" => $owner->getElementID()
        ));

        if (!$this->layer->getOwner()
                         ->isAdmin() && !$owner->isScriptAdded('countdown')) {
            $owner->addScript('this.sliderElement.querySelectorAll(\'.n2-ss-item-countdown_container\').forEach((function(el){new _N2.FrontendItemCountdown(el, this)}).bind(this));', 'countdown');
        }
    }
}Item/CircleCounter/ItemCircleCounter.php000064400000015745152426506610014317 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\CircleCounter;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Fieldset;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemCircleCounter extends AbstractItem {

    protected $ordering = 11;

    protected $fonts = array(
        'font'      => array(
            'defaultName' => 'item-circlecounter-font',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"40||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1","bold":0,"italic":0,"underline":0,"align":"center","letterspacing":"normal","wordspacing":"normal","texttransform":"none"}]}'
        ),
        'fontlabel' => array(
            'defaultName' => 'item-circlecounter-fontlabel',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"16||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"2","bold":0,"italic":0,"underline":0,"align":"center","letterspacing":"normal","wordspacing":"normal","texttransform":"none"}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'circlecounter';
    }

    public function getTitle() {
        return n2_('Circle counter');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--circlecounter';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemCircleCounterFrontend($this, $id, $itemData, $layer);
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/circlecounter.n2less", array(
            "sliderid" => $renderable->elementId
        ));
    }

    public function getValues() {

        return parent::getValues() + array(
                'value'             => 50,
                'startvalue'        => 0,
                'total'             => 100,
                'size'              => 200,
                'strokewidth'       => 10,
                'color'             => '00000033',
                'color2'            => '64c133ff',
                'pre'               => '',
                'post'              => '%',
                'label'             => '',
                'labelplacement'    => 'after',
                'animationduration' => 1000,
                'animationdelay'    => 0
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('label', $slide->fill($data->get('label', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('fontlabel'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('fontlabel', $import->fixSection($data->get('fontlabel')));

        return $data;
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-circlecounter-font', n2_('Counter'), $this->fonts['font']['value'], array(
            'mode' => 'simple'
        ));

        new Font($row1, 'item-circlecounter-fontlabel', n2_('Label'), $this->fonts['fontlabel']['value'], array(
            'mode' => 'simple'
        ));

    }

    public function renderFields($container) {
        $counter = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-circlecounter', n2_('Counter'));
        new Number($counter, 'value', n2_('Value'), '', array(
            'wide' => 5
        ));
        new Number($counter, 'startvalue', n2_('Start from'), '', array(
            'wide' => 5
        ));
        new Number($counter, 'total', n2_('Total'), '', array(
            'wide' => 5
        ));

        $display = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-circlecounter-display', n2_('Display'));
        new Color($display, 'color', n2_('Color'), '', array(
            'alpha' => true
        ));
        new Color($display, 'color2', n2_('Active color'), '', array(
            'alpha' => true
        ));
        new NumberSlider($display, 'size', n2_('Size'), '', array(
            'min'       => 20,
            'max'       => 1000,
            'sliderMax' => 500,
            'step'      => 10,
            'unit'      => 'px',
            'wide'      => 4
        ));
        new NumberSlider($display, 'strokewidth', n2_('Stroke width'), '', array(
            'min'       => 1,
            'max'       => 300,
            'sliderMax' => 100,
            'step'      => 1,
            'unit'      => 'px',
            'wide'      => 3
        ));

        $labels = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-circlecounter-labels', n2_('Labels'));
        new Text($labels, 'label', n2_('Label'), '', array(
            'style' => 'width:150px;'
        ));
        new Select($labels, 'labelplacement', n2_('Placement'), '', array(
            'options' => array(
                'before'      => n2_('Before'),
                'innerbefore' => n2_('Inner before'),
                'innerafter'  => n2_('Inner after'),
                'after'       => n2_('After')
            )
        ));
        new Text($labels, 'pre', n2_('Pre'), '', array(
            'style' => 'width:40px;'
        ));
        new Text($labels, 'post', n2_('Post'), '', array(
            'style' => 'width:40px;'
        ));

        $animation = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-circlecounter-animation', n2_('Animation'));
        new Number($animation, 'animationduration', n2_('Animation duration'), 1, array(
            'min'  => 0,
            'wide' => 5,
            'unit' => 'ms'
        ));
        new Number($animation, 'animationdelay', n2_('Delay'), 0, array(
            'min'  => 0,
            'wide' => 5,
            'unit' => 'ms'
        ));

        new HiddenFont($counter, 'font', n2_('Font') . ' - ' . n2_('Counter'), '', array(
            'mode' => 'simple'
        ));
        new HiddenFont($counter, 'fontlabel', n2_('Font') . ' - ' . n2_('Label'), '', array(
            'mode' => 'simple'
        ));
    }
}Item/CircleCounter/ItemCircleCounterFrontend.php000064400000013407152426506660016015 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\CircleCounter;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemCircleCounterFrontend extends AbstractItemFrontend {

    public function isAuto() {
        return true;
    }

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $this->loadResources($owner);

        $value       = intval($this->data->get('value'));
        $min         = min(0, $value);
        $strokeWidth = intval($this->data->get('strokewidth'));
        $size        = max(intval($this->data->get('size')), $strokeWidth + 1);
        $startValue  = max(intval($this->data->get('startvalue')), $min);
        $total       = max(max(intval($this->data->get('total')), $startValue), $value);
        $duration    = max(0, intval($this->data->get('animationduration')));

        $center = $size / 2;
        $r      = ($size - $strokeWidth) / 2;
        $c      = pi() * $r * 2;

        if ($total != $min) {
            $toPercent = (min($value, $total) - $min) / ($total - $min);

            if ($duration == 0) {
                // We do not have animation
                $fromPercent = $toPercent;
            } else {
                $fromPercent = (min($startValue, $total) - $min) / ($total - $min);
            }
        } else {
            $duration    = 0;
            $fromPercent = $toPercent = 0;
        }

        $pct = (1 - $fromPercent) * $c;

        $labelHTML = '';
        $label     = Sanitize::filter_allowed_html($owner->fill($this->data->get('label')));
        $placement = '';
        if (!empty($label)) {
            $fontLabel = $owner->addFont($this->data->get('fontlabel'), 'simple');

            $labelHTML = Html::tag('div', array(
                'class' => $fontLabel
            ), $label);
            $placement = $this->data->get('labelplacement');
        }


        $html = '';

        if ($placement == 'before') {
            $html .= $labelHTML;
        }

        $font = $owner->addFont($this->data->get('font'), 'simple');

        $pre             = Sanitize::filter_allowed_html($this->data->get('pre'));
        $post            = Sanitize::filter_allowed_html($this->data->get('post'));
        $countingDivHTML = Html::tag('div', array(
            'class' => 'n2-ss-item-circlecounter-counting-div n2-ow ' . $font
        ), $pre . round($min + $fromPercent * ($total - $min)) . $post);

        $html .= Html::openTag('div', array(
            'id'    => $this->id,
            'class' => 'n2-ow n2-ss-item-circlecounter-svg-container',
            'style' => 'width:' . $size . 'px;'
        ));

        $color  = $this->data->get('color');
        $color2 = $this->data->get('color2');
        $html   .= '<svg class="svg" viewBox="0 0 ' . $size . ' ' . $size . '" version="1.1" style="width:' . $size . 'px;height:' . $size . 'px;" preserveAspectRatio="xMinYMin meet">';
        $html   .= '<circle class="fl-bar-bg" r="' . $r . '" cx="' . $center . '" cy="' . $center . '" stroke="#' . substr($color, 0, 6) . '" stroke-opacity="' . Color::hex2alpha($color) / 127 . '" stroke-width="' . $strokeWidth . '" stroke-dashoffset="0" stroke-dasharray="' . $c . '" fill="transparent"></circle>';
        $html   .= '<circle class="fl-bar" r="' . $r . '" cx="' . $center . '" cy="' . $center . '" stroke="#' . substr($color2, 0, 6) . '" stroke-opacity="' . Color::hex2alpha($color2) / 127 . '" stroke-width="' . $strokeWidth . '" stroke-dasharray="' . $c . '" stroke-dashoffset="' . $pct . '" transform="rotate(-90 ' . $center . ' ' . $center . ')" fill="transparent"></circle>';
        $html   .= '</svg>';

        $html .= Html::openTag('div', array(
            'class' => 'n2-ow n2-ss-item-circlecounter-svg-overlay'
        ));

        if ($placement == 'innerbefore') {
            $html .= $labelHTML;
        }

        $html .= $countingDivHTML;


        if ($placement == 'innerafter') {
            $html .= $labelHTML;
        }

        $html .= '</div>';
        $html .= '</div>';


        if ($placement == 'after') {
            $html .= $labelHTML;
        }

        $jsData = array(
            'name'        => 'circlecounter',
            'pre'         => $pre,
            'post'        => $post,
            'fromPercent' => $fromPercent,
            'toPercent'   => $toPercent,
            'duration'    => $duration,
            'delay'       => $this->data->get('animationdelay'),
            'min'         => $min,
            'total'       => $total,
            'c'           => $c,
            'counting'    => '.n2-ss-item-circlecounter-counting-div',
            'displayMode' => 'circle',
            'display'     => 'circle + circle'
        );

        if ($this->isEditor && $owner->underEdit) {
            $owner->addScript('new _N2.CounterItemAdmin(this, "' . $this->id . '", ' . json_encode($jsData) . ');');
        } else {
            $owner->addScript('new _N2.FrontendItemCounter(this, "' . $this->id . '", ' . json_encode($jsData) . ');');
        }

        return Html::tag('div', array(
            'class' => 'n2-ss-item-content n2-ow'
        ), $html);
    }

    /**
     * @param AbstractRenderableOwner $owner
     */
    public function loadResources($owner) {
        $owner->addLess(self::getAssetsPath() . "/circlecounter.n2less", array(
            "sliderid" => $owner->getElementID()
        ));
    }
}Item/Caption/ItemCaption.php000064400000023756152426506730012013 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Caption;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\MixedField;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemCaption extends AbstractItem {

    protected $ordering = 4;

    protected $layerProperties = array(
        "desktopportraitleft"  => 0,
        "desktopportraittop"   => 0,
        "desktopportraitwidth" => 200
    );

    protected $fonts = array(
        'fonttitle' => array(
            'defaultName' => 'item-caption-font-title',
            'value'       => '{"data":[{"color":"ffffffff","size":"14||px","align":"inherit"},{"extra":""},{"extra":""}]}'
        ),
        'font'      => array(
            'defaultName' => 'item-caption-font',
            'value'       => '{"data":[{"color":"ffffffff","size":"14||px","align":"inherit"},{"extra":""},{"extra":""}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'caption';
    }

    public function getTitle() {
        return n2_('Caption');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--imagecaption';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemCaptionFrontend($this, $id, $itemData, $layer);
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-caption-font-title', n2_('Title'), $this->fonts['fonttitle']['value'], array(
            'mode' => 'paragraph'
        ));

        new Font($row1, 'item-caption-font', n2_('Description'), $this->fonts['font']['value'], array(
            'mode' => 'paragraph'
        ));
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/caption.n2less", array(
            "sliderid" => $renderable->elementId
        ));
    }

    public function getValues() {

        return parent::getValues() + array(
                'animation'      => 'Simple|*|left|*|0',
                'image'          => '$ss3-frontend$/images/placeholder/image.png',
                'alt'            => '',
                'href'           => '#',
                'href-target'    => '_self',
                'href-rel'       => '',
                'verticalalign'  => 'center',
                'content'        => n2_('Caption'),
                'description'    => '',
                'color'          => '00000080',
                'image-optimize' => 1
            );
    }


    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('image', $slide->fill($data->get('image', '')));
        $data->set('alt', $slide->fill($data->get('alt', '')));
        $data->set('content', $slide->fill($data->get('content', '')));
        $data->set('description', $slide->fill($data->get('description', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('image'));
        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('fonttitle'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('image', $import->fixImage($data->get('image')));
        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('fonttitle', $import->fixSection($data->get('fonttitle')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('image', ResourceTranslator::toUrl($data->get('image')));

        return $data;
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-caption', n2_('General'));

        new FieldImage($settings, 'image', n2_('Image'), '', array(
            'relatedAlt' => 'item_captionalt',
            'width'      => 220
        ));

        new Text($settings, 'content', n2_('Title'), '', array(
            'style' => 'width:302px;'
        ));
        new HiddenFont($settings, 'fonttitle', n2_('Font') . ' - ' . n2_('Title'), '', array(
            'mode' => 'paragraph'
        ));

        new Textarea($settings, 'description', n2_('Description'), '', array(
            'width' => 314
        ));
        new HiddenFont($settings, 'font', n2_('Font') . ' - ' . n2_('Description'), '', array(
            'mode' => 'paragraph'
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-caption-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'relatedFields' => array(
                'item_captionhref-target',
                'item_captionhref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));

        $animationFieldset = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-caption-animation', n2_('Animation'));
        $animation         = new MixedField($animationFieldset, 'animation', false, 'Simple|*|left|*|0');
        new Select($animation, 'animation-1', n2_('Animation'), '', array(
            'options'            => array(
                'Full'   => n2_('Full'),
                'Simple' => n2_('Simple'),
                'Fade'   => n2_('Fade')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'Full',
                        'Simple'
                    ),
                    'field'  => array(
                        'animationitem_captionanimation-2'
                    )
                ),
                array(
                    'values' => array(
                        'Full',
                        'Fade'
                    ),
                    'field'  => array(
                        'item_captionverticalalign'
                    )
                )
            )
        ));
        new Select($animation, 'animation-2', n2_('Direction'), '', array(
            'options' => array(
                'top'    => n2_('Top'),
                'right'  => n2_('Right'),
                'bottom' => n2_('Bottom'),
                'left'   => n2_('Left')
            )
        ));
        new OnOff($animation, 'animation-3', n2_('Scale'), 0, array(
            'tipLabel'       => n2_('Scale'),
            'tipDescription' => n2_('Scales up the image on hover')
        ));

        $overlay = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-caption-overlay', n2_('Display'));
        new Color($overlay, 'color', n2_('Overlay background'), '00000080', array(
            'alpha' => true
        ));
        new Select($overlay, 'verticalalign', n2_('Vertical align'), '', array(
            'options'        => array(
                'flex-start' => n2_('Top'),
                'center'     => n2_('Center'),
                'flex-end'   => n2_('Bottom')
            ),
            'tipLabel'       => n2_('Vertical align'),
            'tipDescription' => n2_('Positions the text inside the overlay.')
        ));

        $seo = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-caption-seo', n2_('SEO'));
        new Text($seo, 'alt', 'SEO - ' . n2_('Alt tag'), '', array(
            'style' => 'width:302px;'
        ));

        $optimize = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-caption-optimize', n2_('Optimize'));
        new OnOff($optimize, 'image-optimize', n2_('Optimize image'), 1, array(
            'tipLabel'       => n2_('Optimize image'),
            'tipDescription' => n2_('You can turn off the Layer image optimization for this image, to resize it for tablet and mobile.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1839-caption-layer#optimize'
        ));

    }
}Item/Caption/ItemCaptionFrontend.php000064400000006543152426507050013502 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Caption;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemCaptionFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $this->loadResources($owner);

        list($mode, $direction, $scale) = Common::parse($this->data->get('animation', 'Simple|*|left|*|0'));
        switch ($direction) {
            case 'top':
                $axis  = 'yP';
                $ratio = -1;
                break;
            case 'right':
                $axis  = 'xP';
                $ratio = 1;
                break;
            case 'bottom':
                $axis  = 'yP';
                $ratio = 1;
                break;
            case 'left':
                $axis  = 'xP';
                $ratio = -1;
                break;
        }
        $owner->addScript('new _N2.FrontendItemCaption(this, "' . $this->id . '", "' . $mode . '",' . json_encode($axis) . ',' . json_encode($ratio) . ', ' . intval($scale) . ');');

        $image = $owner->fill($this->data->get('image', ''));

        $imageAttributes = array(
            'alt' => htmlspecialchars($owner->fill($this->data->get('alt', '')))
        );

        $html = $owner->renderImage($this, $image, $imageAttributes);

        $rgba = Color::colorToRGBA($this->data->get('color', '00000080'));
        $html .= Html::openTag("div", array(
            "class" => "n2-ss-item-caption-content",
            "style" => "background: {$rgba};" . 'justify-content:' . $this->data->get('verticalalign', 'center') . ';'
        ));

        $title = Sanitize::filter_allowed_html($owner->fill($this->data->get('content', '')));
        if ($title != '') {
            $fontTitle = $owner->addFont($this->data->get('fonttitle'), 'paragraph');
            $html      .= Html::tag("div", array("class" => 'n2-div-h4 ' . $fontTitle), $title);
        }

        $description = Sanitize::filter_allowed_html($owner->fill($this->data->get('description', '')));
        if ($description != '') {
            $font = $owner->addFont($this->data->get('font'), 'paragraph');
            $html .= Html::tag("p", array("class" => $font), $description);
        }

        $html .= Html::closeTag("div");

        $linkAttributes = array();
        if ($this->isEditor) {
            $linkAttributes['onclick'] = 'return false;';
        }

        return Html::tag("div", array(
            "id"             => $this->id,
            "class"          => "n2-ss-item-caption n2-ss-item-content n2-ow-all n2-ss-item-caption-" . $mode,
            "data-direction" => $direction
        ), $this->getLink($html, $linkAttributes));
    }

    /**
     * @param AbstractRenderableOwner $owner
     */
    public function loadResources($owner) {

        $owner->addLess(self::getAssetsPath() . "/caption.n2less", array(
            "sliderid" => $owner->getElementID()
        ));
    }
}Item/BeforeAfter/ItemBeforeAfter.php000064400000033522152426507130013354 0ustar00<?php

namespace Nextend\SmartSlider3Pro\Renderable\Item\BeforeAfter;


use Nextend\Framework\Filesystem\Filesystem;
use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\FieldImage;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemBeforeAfter extends AbstractItem {


    protected $fonts = array(
        'fontlabel'   => array(
            'defaultName' => 'item-beforeafter-fontlabel',
            'value'       => '{"data":[{"extra":"","color":"000000FF","size":"14||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1.2","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{},{}]}'
        ),
        'fontcaption' => array(
            'defaultName' => 'item-beforeafter-fontcaption',
            'value'       => '{"data":[{"extra":"","color":"000000FF","size":"14||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1.2","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{},{}]}'
        )
    );


    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'beforeafter';
    }

    public function getTitle() {
        return n2_('Before After');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--beforeafter';
    }

    public function getGroup() {
        return n2_x('Special', 'Layer group');
    }


    public function createFrontend($id, $itemData, $layer) {
        return new ItemBeforeAfterFrontend($this, $id, $itemData, $layer);
    }


    public function loadResources($renderable) {
        parent::loadResources($renderable);
        $renderable->addLess(self::getAssetsPath() . "/beforeAfter.n2less", array(
            "sliderid" => $renderable->elementId
        ));


        $renderable->addScript('_N2.ItemBeforeafter.svgUrlList=' . json_encode($this->getArrowUrlList()) . ';');
        $renderable->addScript('_N2.ItemBeforeafter.svgTypeList=' . json_encode($this->getArrowTypeList()) . ';');


    }


    public function getValues() {
        return parent::getValues() + array(
                'imagebefore'       => '$ss3-frontend$/images/placeholder/image.png',
                'imageafter'        => '$ss3-frontend$/images/placeholder/video.png',
                'textbefore'        => n2_('Before'),
                'textafter'         => n2_('After'),
                'labelposition'     => 'center',
                'labelbackground'   => 'FFFFFFFF',
                'showlabel'         => 1,
                'labeltype'         => 'normal',
                'showcaption'       => 0,
                'captiontext'       => n2_('Caption'),
                'captiontype'       => 'normal',
                'captionposition'   => '3-2',
                'captionbackground' => 'FFFFFFFF',
                'direction'         => 'horizontal',
                'interaction'       => 'drag',
                'dividerstyle'      => 'arrow',
                'dividercolor'      => 'FFFFFFFF',
                'dividerwidth'      => '4',
                'width'             => '4',
                'startposition'     => '50',
                'image-optimize'  => 1
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('imagebefore', $slide->fill($data->get('imagebefore', '')));
        $data->set('imageafter', $slide->fill($data->get('imageafter', '')));
        $data->set('textbefore', $slide->fill($data->get('textbefore', '')));
        $data->set('textafter', $slide->fill($data->get('textafter', '')));
        $data->set('captiontext', $slide->fill($data->get('captiontext', '')));
        $data->set('altbefore', $slide->fill($data->get('altbefore', '')));
        $data->set('altafter', $slide->fill($data->get('altafter', '')));

        return $data;

    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('fontlabel'));
        $export->addVisual($data->get('fontcaption'));

        $export->addImage($data->get('imagebefore', ''));
        $export->addImage($data->get('imageafter', ''));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('fontlabel', $import->fixSection($data->get('fontlabel')));
        $data->set('fontcaption', $import->fixSection($data->get('fontcaption')));

        $data->set('imagebefore', $import->fixImage($data->get('imagebefore')));
        $data->set('imageafter', $import->fixImage($data->get('imageafter')));



        return $data;
    }

    public function prepareSample($data) {
        $data->set('imagebefore', ResourceTranslator::toUrl($data->get('imagebefore', '')));
        $data->set('imageafter', ResourceTranslator::toUrl($data->get('imageafter', '')));

        return $data;
    }



    private function getArrowTypeList() {
        return array(
            'arrow' => 'default',
            'circle'    => 'custom',
            'rectangle' => 'custom'
        );
    }

    private function getArrowUrlList() {
        static $types = null;
        if ($types === null) {
            $types     = array();
            $extension = 'svg';
            $folder    = self::getAssetsPath() . '/svg/';
            $files     = Filesystem::files($folder);
            foreach ($files as $file) {
                $pathInfo = pathinfo($file);
                if (isset($pathInfo['extension']) && $pathInfo['extension'] == $extension) {
                    $types[$pathInfo['filename']] = Filesystem::readFile($folder . $file);;
                }
            }
        }

        return $types;
    }

    public function getArrowSvg($type) {
        $arrowList = $this->getArrowUrlList();

        if (isset($this->getArrowTypeList()[$type])) {
            $arrow = $arrowList["arrow_" . $this->getArrowTypeList()[$type]];
            return $arrow;
        }

        return false;
    }

    private function getCaptionTypes() {
        return array(
            '1-1' => n2_('Left top'),
            '1-2' => n2_('Center top'),
            '1-3' => n2_('Right top'),
            '2-1' => n2_('Left center'),
            '2-2' => n2_('Center'),
            '2-3' => n2_('Right Center'),
            '3-1' => n2_('Left bottom'),
            '3-2' => n2_('Center bottom'),
            '3-3' => n2_('Right bottom')
        );
    }




    public function globalDefaultItemFontAndStyle($container) {
        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-beforeafter-fontlabel', false, $this->fonts['fontlabel']['value'], array(
            'mode' => 'simple'
        ));
        new Font($row1, 'item-beforeafter-captionlabel', false, $this->fonts['fontcaption']['value'], array(
            'mode' => 'simple'
        ));

    }

    public function renderFields($container) {

        $general = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-beforeafter', n2_('General'));
        new FieldImage($general, 'imagebefore', n2_('Before Image'), '', array(
            'width'         => 220,
            'relatedFields' => array(
                'item_beforeafteraltbefore'
            )
        ));
        new FieldImage($general, 'imageafter', n2_('After Image'), '', array(
            'width'         => 220,
            'relatedFields' => array(
                'item_beforeafteraltafter'
            )
        ));

        $label = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-beforeafter-label', n2_('Label'));
        new OnOff($label, 'showlabel', n2_('Labels'), 1, array(
            'relatedFieldsOn' => array(
                'item_beforeaftertextbefore',
                'item_beforeaftertextafter',
                'item_beforeafterlabelposition',
                'item_beforeafterlabeltype',
                'item_beforeafterlabelbackground',
            )
        ));
        new Select($label, 'labeltype', n2_('Show Label'), '', array(
            'options' => array(
                'normal' => n2_('Normal'),
                'hover'  => n2_('Hover'),
                'always' => n2_('Always')
            )
        ));
        new Select($label, 'labelposition', n2_('Position'), '', array(
            'options' => array(
                'start'  => n2_('Start'),
                'center' => n2_('Center'),
                'end'    => n2_('End')
            )
        ));
        new Text($label, 'textbefore', n2_('Before label'), '', array(
            'style' => 'width:132px;',
        ));
        new Text($label, 'textafter', n2_('After label'), '', array(
            'style' => 'width:132px;',
        ));


        new Color($label, 'labelbackground', n2_('Background'), 'FFFFFFFF', array(
            'alpha' => true,
            'style' => "width:75px"

        ));

        new HiddenFont($label, 'fontlabel', n2_('Font') . ' - ' . n2_('Label'), '', array(
            'mode' => 'simple'
        ));

        $behavior = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-beforeafter-behavior', n2_('Behavior'));
        new Select($behavior, 'direction', n2_('Direction'), '', array(
            'options' => array(
                'horizontal' => n2_('Horizontal'),
                'vertical'   => n2_('Vertical'),
            )
        ));

        new Select($behavior, 'interaction', n2_('Interaction'), 'drag', array(
            'options' => array(
                'drag'  => n2_('Drag'),
                'hover' => n2_('Hover'),
            )
        ));

        $divider = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-beforeafter-divider', n2_('Divider'));

        new Select($divider, 'dividerstyle', n2_('Type'), 'arrow', array(
            'options' => array(
                'line'      => n2_('Line'),
                'arrow'     => n2_('Arrow'),
                'circle'    => n2_('Circle'),
                'rectangle' => n2_('Rectangle'),
            )
        ));

        new Color($divider, 'dividercolor', n2_('Color'), 'FFFFFFFF', array(
            'alpha' => true,
            'style' => "width:65px"

        ));

        $caption = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-beforeafter-caption', n2_('Caption'));
        new OnOff($caption, 'showcaption', n2_('Caption'), 0, array(
            'relatedFieldsOn' => array(
                'item_beforeaftercaptiontype',
                'item_beforeaftercaptionposition',
                'item_beforeaftercaptiontext',
                'item_beforeaftercaptionbackground',
            )
        ));

        new Select($caption, 'captiontype', n2_('Show Caption'), 'normal', array(
            'options' => array(
                'normal' => n2_('Normal'),
                'hover'  => n2_('Hover'),
                'always' => n2_('Always')
            )
        ));

        new Select($caption, 'captionposition', n2_('Position'), '', array(
            'options' => $this->getCaptionTypes()
        ));

        new Text($caption, 'captiontext', n2_('Caption text'), 'Caption', array(
            'style' => 'width:132px;',
        ));

        new Color($caption, 'captionbackground', n2_('Background'), 'FFFFFFFF', array(
            'alpha' => true,
            'style' => "width:75px"

        ));

        new HiddenFont($caption, 'fontcaption', n2_('Font') . ' - ' . n2_('Caption'), '', array(
            'mode' => 'simple'
        ));


        new NumberSlider($divider, 'startposition', n2_('Position'), 50, array(
            'min'       => 0,
            'max'       => 100,
            'unit'      => '%',
            'style'     => "width:15px;",
            'sliderMax' => 100,
            'step'      => 5,
            'wide'      => 4
        ));

        new Select($divider, 'dividerwidth', n2_('Width'), 4, array(
            'options' => array(
                '2'  => '2',
                '4'  => '4',
                '6'  => '6',
                '8'  => '8',
                '10' => '10'
            )
        ));



        $seo = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-beforeafter-seo', n2_('SEO'));
        new Text($seo, 'altbefore', n2_('Before image alt tag'), '', array(
            'style' => 'width:132px;'
        ));
        new Text($seo, 'altafter', n2_('After image alt tag'), '', array(
            'style' => 'width:132px;'
        ));

        $optimize = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-caption-optimize', n2_('Optimize'));
        new OnOff($optimize, 'image-optimize', n2_('Optimize images'), 1, array(
            'tipLabel'       => n2_('Optimize image'),
            'tipDescription' => n2_('You can turn off the Layer image optimization for this image, to resize it for tablet and mobile.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1839-caption-layer#optimize'
        ));

    }
}Item/BeforeAfter/ItemBeforeAfterFrontend.php000064400000021523152426507250015055 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\BeforeAfter;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemBeforeAfterFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }


    private function getHtml() {
        $image  = $this->data->get('imagebefore', '');
        $image2 = $this->data->get('imageafter', '');

        if (empty($image) && empty($image2)) {
            return '';
        }

        $owner = $this->layer->getOwner();
        $this->loadResources($owner);

        $image  = $owner->fill($image);
        $image2 = $owner->fill($image2);

        if (empty($image) && empty($image2)) {
            return '';
        }


        $attributes = [
            'direction'         => $this->data->get('direction', 'horizontal'),
            'startposition'     => $this->data->get('startposition', '50'),
            'interaction'       => $this->data->get('interaction', 'drag'),
            'dividerstyle'      => $this->data->get('dividerstyle', 'line'),
            'dividercolor'      => $this->data->get('dividercolor', '00000080'),
            'dividerwidth'      => $this->data->get('dividerwidth', '4'),
            'labelpositon'      => $this->data->get('labelposition', 'end'),
            'labelfront'        => $this->data->get('labelfront', '0'),
            'labeltype'         => $this->data->get('labeltype', 'normal'),
            'showlabel'         => $this->data->get('showlabel', 1),
            'labelbackground'   => $this->data->get('labelbackground', 'FFFFFF80'),
            'fontlabel'         => $owner->addFont($this->data->get('fontlabel'), 'simple'),
            'fontcaption'       => $owner->addFont($this->data->get('fontcaption'), 'simple'),
            'showcaption'       => $this->data->get('showcaption', ""),
            'captiontype'       => $this->data->get('captiontype', ""),
            'captionbackground' => $this->data->get('captionbackground', "00000080"),
            'captionpos'        => $this->data->get('captionposition', "2-3"),
            'captionrow'        => '2',
            'captioncol'        => '3',
        ];


        //need here because style
        $gridValues               = explode('-', $attributes['captionpos']);
        $attributes['captionrow'] = $gridValues[0];
        $attributes['captioncol'] = $gridValues[1];

        //Container
        $styles = "
       --dividerColor : " . Color::colorToRGBA($attributes['dividercolor'], '00000080') . " ;
       --dividerPos : " . $attributes['startposition'] . "%;
       --imagePos : " . $attributes['startposition'] . "%;
       --labelBackground : " . Color::colorToRGBA($attributes['labelbackground'], '00000080') . ";
       --captionBackground : " . Color::colorToRGBA($attributes['captionbackground'], '00000080') . ";
       --dividerWidth : " . $attributes['dividerwidth'] . "px;";

        $containerInEditor = $this->isEditor ? "n2-ss-item-ba-container--ineditor" : "";

        $html = Html::openTag("div", array(
            'style' => $styles,
            "class" => "n2-ss-item-ba-container n2-ss-item-ba-container--{$attributes['direction']} n2_container_scrollable $containerInEditor n2-ss-item-ba-container--interaction-{$attributes['interaction']}"
        ));


        $labelBefore = $textBefore = "";
        $labelAfter  = $textAfter = "";
        if ($attributes['showlabel']) {
            $textBefore = Sanitize::filter_allowed_html($owner->fill($this->data->get('textbefore', "")));
            $textAfter  = Sanitize::filter_allowed_html($owner->fill($this->data->get('textafter', "")));
            $show       = $attributes['interaction'] === 'hover' && $attributes['labeltype'] === 'hover' ? 'normal' : $attributes['labeltype'];

            $labelClass = $this->isEditor ? "" : "n2-ss-item-ba-label--show-$show n2-ss-text n2-ow ";
            $labelClass .= $attributes['fontlabel'];

            if ($textBefore) $labelBefore = "<div class='n2-ss-item-ba-label n2-ss-item-ba-label--before $labelClass'> $textBefore</div>";
            if ($textAfter) $labelAfter = "<div class='n2-ss-item-ba-label n2-ss-item-ba-label--after $labelClass'> $textAfter</div>";

        }

        //Caption
        if ($attributes['showcaption']) {
            $captionText = Sanitize::filter_allowed_html($owner->fill($this->data->get('captiontext', "")));
            if ($captionText != "") {
                $show           = $attributes['interaction'] === 'hover' && $attributes['captiontype'] === 'hover' ? 'normal' : $attributes['captiontype'];
                $labelClass     = $this->isEditor ? "" : "n2-ss-item-ba-caption--show-$show n2-ss-text n2-ow";
                $caption        = "<div class='n2-ss-item-ba-caption $labelClass {$attributes['fontcaption']}'> $captionText</div>";
                $labelContainer = Html::tag('div', array(
                    "data-position" => $attributes['captionpos'],
                    "class"         => "n2-ss-item-ba-caption-container"
                ), $caption);
                $html           .= $labelContainer;
            }
        }

        //Images

        $imageAttributes = array(
            'alt'       => htmlspecialchars($owner->fill($this->data->getIfEmpty('altbefore', $textBefore))),
            'class'     => 'n2-ow-all n2-ss-item-ba-image n2-ss-item-ba-image--before',
            'draggable' => 'false'
        );

        $imageBefore = Html::tag("div", array(
            "class" => "n2-ss-item-ba-image-container n2-ss-item-ba-image-container--bottom n2-ss-item-ba-label-container--{$attributes['labelpositon']}"
        ), $labelBefore . $owner->renderImage($this, $image, $imageAttributes));


        $imageAttributes2 = array(
            'alt'       => htmlspecialchars($owner->fill($this->data->getIfEmpty('altafter', $textAfter))),
            'class'     => 'n2-ow-all n2-ss-item-ba-image n2-ss-item-ba-image--after',
            'draggable' => 'false'
        );

        $imageAfter = Html::tag("div", array(
            "class" => "n2-ss-item-ba-image-container n2-ss-item-ba-image-container--top n2-ss-item-ba-label-container--{$attributes['labelpositon']}"
        ), $labelAfter . $owner->renderImage($this, $image2, $imageAttributes2));


        $html .= $imageBefore;
        $html .= $imageAfter;

        //Divider
        $dividerClass = ($attributes['dividerstyle'] === 'line' || $attributes['dividerstyle'] === 'arrow') ? '' : 'n2-ss-item-ba-divider--gap';
        $divider      = Html::openTag("div", array(
            "class" => "n2-ss-item-ba-divider $dividerClass"
        ));
        //Divider-part-top
        $divider .= "<div class='n2-ss-item-ba-divider-part n2-ss-item-ba-divider-part--top'></div>";

        //Svg arrows
        $svg = $this->item->getArrowSvg($attributes['dividerstyle']);
        //arrowContainer
        if ($svg) {
            $arrowContainer = Html::tag("div", array(
                "class" => "n2-ss-item-ba-arrow-container n2-ss-item-ba-arrow-container--{$attributes['dividerstyle']}"
            ), $svg . $svg);

            $divider .= $arrowContainer;
        }

        //Divider-part-bottom
        $divider .= "<div class='n2-ss-item-ba-divider-part n2-ss-item-ba-divider-part--bottom'></div>";

        //Divider Close
        $divider .= Html::closeTag('div');


        //Dividercontainer
        $dividerContainer = Html::tag("div", array(
            "class" => "n2-ss-item-ba-divider-container"
        ), $divider);

        $html .= $dividerContainer;

        //Close Container
        $html .= Html::closeTag('div');


        $jsData = array(
            'startPos'    => $attributes['startposition'],
            'interaction' => $attributes['interaction'],
            'direction'   => $attributes['direction'],
            'labeltype'   => $attributes['labeltype'],
            'captiontype' => $attributes['captiontype'],

        );

        if (!$this->isEditor && !$owner->underEdit) {
            $owner->addScript('new _N2.FrontendItemBeforeAfter(this, "' . $this->id . '", ' . json_encode($jsData) . ');');
        }


        return Html::tag("div", array(
            "id"    => $this->id,
            "class" => "n2-ss-item-ba-wrapper n2-ss-item-content n2-ow-all"
        ), $html);
    }


    /**
     * @param $owner AbstractRenderableOwner
     */
    public function loadResources($owner) {


        $owner->addLess(self::getAssetsPath() . "/beforeAfter.n2less", array(
            "sliderid" => $owner->getElementID()
        ));


    }


}Item/Audio/ItemAudio.php000064400000012552152426507370011114 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Audio;


use Nextend\Framework\Form\Element\Message\Warning;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Video;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemAudio extends AbstractItem {

    protected $ordering = 21;

    protected $layerProperties = array(
        "desktopportraitwidth" => 300
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'audio';
    }

    public function getTitle() {
        return n2_('Audio');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--audio';
    }

    public function getGroup() {
        return n2_x('Media', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemAudioFrontend($this, $id, $itemData, $layer);
    }

    /**
     * @return array
     */
    public function getValues() {
        return parent::getValues() + array(
                'audio_mp3'     => '',
                'volume'        => 1,
                'autoplay'      => 0,
                'loop'          => 0,
                'reset'         => 0,
                'color'         => '000000B2',
                'color2'        => 'ffffff',
                'videoplay'     => '',
                'videopause'    => '',
                'videoend'      => '',
                'fullwidth'     => 1,
                'show'          => 1,
                'show-progress' => 1,
                'show-time'     => 1,
                'show-volume'   => 1,
                'iconsize'      => 'small',
            );
    }


    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('audio_mp3', $slide->fill($data->get('audio_mp3', '')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addImage($data->get('audio_mp3'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('audio_mp3', $import->fixImage($data->get('audio_mp3')));

        return $data;
    }

    public function prepareSample($data) {
        $data->set('audio_mp3', ResourceTranslator::toUrl($data->get('audio_mp3')));

        return $data;
    }

    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/audio.n2less", array(
            "sliderid" => $renderable->elementId
        ));
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-audio', n2_('General'));

        new Video($settings, 'audio_mp3', n2_('MP3 audio'), '', array(
            'width' => 220
        ));

        new Color($settings, 'color', n2_('Main color'), '', array(
            'alpha' => true
        ));
        new Color($settings, 'color2', n2_('Secondary color'));

        $audioSettings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-audio-settings', n2_('Audio settings'));
        new Warning($audioSettings, 'autoplay-notice', sprintf(n2_('Audio autoplaying has a lot of limitations made by browsers. You can read about them %1$shere%2$s.'), '<a href="https://smartslider.helpscoutdocs.com/article/1919-video-autoplay-handling" target="_blank">', '</a>'));

        new OnOff($audioSettings, 'autoplay', n2_('Autoplay'), 0, array(
            'relatedFieldsOn' => array(
                'item_audioautoplay-notice'
            )
        ));
        new OnOff($audioSettings, 'loop', n2_x('Loop', 'Video/Audio play'), 0);
        new Select($audioSettings, 'volume', n2_('Volume'), 1, array(
            'options' => array(
                '0'    => n2_('Mute'),
                '0.25' => '25%',
                '0.5'  => '50%',
                '0.75' => '75%',
                '1'    => '100%'
            )
        ));
        new OnOff($audioSettings, 'reset', n2_('Restart on slide change'), 0, array(
            'tipLabel'       => n2_('Restart on slide change'),
            'tipDescription' => n2_('Starts the audio from the beginning when the slide is viewed again.')
        ));

        $display = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-audio-display', n2_('Display'));
        new OnOff($display, 'fullwidth', n2_('Full width'), 0);
        new OnOff($display, 'show', n2_('Controls'), 0, array(
            'relatedFieldsOn' => array(
                'item_audioiconsize'
            )
        ));
        new OnOff($display, 'show-progress', n2_('Progress'), 0);
        new OnOff($display, 'show-time', n2_('Time'), 0);
        new OnOff($display, 'show-volume', n2_('Volume'), 0);
        new Select($display, 'iconsize', n2_('Icon Size'), 'small', array(
            'options' => array(
                'small'  => 'Small',
                'medium' => 'Medium',
                'large'  => 'Large'
            )
        ));
    }
}Item/Audio/ItemAudioFrontend.php000064400000013477152426507440012621 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Audio;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\ResourceTranslator\ResourceTranslator;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemAudioFrontend extends AbstractItemFrontend {

    public function render() {
        $owner = $this->layer->getOwner();

        $owner->addScript('new _N2.FrontendItemAudio(this, "' . $this->id . '", ' . $this->data->toJSON() . ');');

        return $this->getHTML();
    }

    public function renderAdminTemplate() {
        return $this->getHTML();
    }

    public function getHTML() {
        $owner = $this->layer->getOwner();

        $this->loadResources($owner);
        $attributes['iconsize'] = $this->data->get('iconsize');

        $attributes = array(
            'class' => 'n2-ss-item-audio-bar n2-ss-item-audio-bar--' . $attributes['iconsize'] . ' n2-ow n2-ss-item-content n2-ow-all',
            'id'    => $this->id
        );

        $controls = array();

        if ($this->data->get('show')) {
            $attributes['data-state']  = 'paused';
            $attributes['data-volume'] = '1';
            $attributes['style']       = 'background-color:' . Color::colorToRGBA($this->data->get('color')) . ';';
            if (!$this->data->get('fullwidth')) {
                $attributes['style'] .= 'display:inline-flex;vertical-align:top;';
            }

            $controls[] = '<div class="n2-ss-item-audio-play"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="{color2}" d="M20 15.99c0 .41-.21.772-.52.967l-6.867 4.87c-.003 0-.006.002-.01.004l-.003.004c-.158.1-.342.156-.54.156-.585 0-1.06-.504-1.06-1.125v-9.752c0-.622.475-1.126 1.06-1.126.198 0 .382.058.54.157l.004.002.01.006 6.865 4.868c.31.196.52.556.52.97z"></path></svg></div>';
            $controls[] = '<div class="n2-ss-item-audio-pause"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="{color2}" d="M17 22V10h4v12h-4zm-6-12h4v12h-4V10z"></path></svg></div>';

            if ($this->data->get('show-progress')) {
                $controls[] = '<div class="n2-ss-item-audio-progress-container n2_container_scrollable"><div class="n2-ss-item-audio-progress" style="background:{bar};"><div style="background:{color2};" class="n2-ss-item-audio-progress-playhead"></div></div></div>';
            }
            if ($this->data->get('show-time')) {
                $controls[] = '<div class="n2-ss-item-audio-time" style="color:{color2};">00:00 / 00:00</div>';
            }
            if ($this->data->get('show-volume')) {
                $controls[] = '<div class="n2-ss-item-audio-unmute"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="{color2}" d="M15 22h-1l-4-4H9c-.45 0-1-.527-1-1v-3c0-.474.55-1 1-1h1l4-4h1v13z"/></svg></div>';
                $controls[] = '<div class="n2-ss-item-audio-mute"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="{color2}" d="M15 22h-1l-4-4H9c-.45 0-1-.527-1-1v-3c0-.474.55-1 1-1h1l4-4h1v13zm3.147-1.954l-.06.002c-.215 0-.423-.09-.577-.25l-.11-.116c-.286-.3-.32-.776-.078-1.117.612-.865.935-1.892.935-2.968 0-1.158-.367-2.244-1.06-3.14-.266-.342-.24-.837.055-1.148l.11-.115c.162-.172.38-.265.618-.25.23.012.446.126.592.313.963 1.236 1.472 2.737 1.472 4.34 0 1.49-.45 2.912-1.3 4.106-.143.2-.36.324-.597.342zm3.38 2.65c-.15.183-.363.293-.59.303H20.9c-.215 0-.423-.09-.577-.25l-.107-.114c-.3-.314-.32-.817-.048-1.158 1.32-1.644 2.045-3.733 2.045-5.88 0-2.236-.778-4.387-2.19-6.058-.285-.34-.27-.853.034-1.174l.107-.112c.16-.168.365-.26.603-.252.225.006.438.11.587.287C23.06 10.303 24 12.9 24 15.596c0 2.595-.878 5.116-2.474 7.1z"></path></svg></div>';
                $controls[] = '<div class="n2-ss-item-audio-volume-container n2_container_scrollable"><div class="n2-ss-item-audio-volume" style="background:{bar};"><div style="background:{color2};" class="n2-ss-item-audio-volumehead"></div></div></div>';
            }
        } else if ($owner->isAdmin()) {
            $controls[]          = 'Audio';
            $attributes['style'] = 'color:#' . $this->data->get('color2') . ';';
        }

        return Html::tag('div', $attributes, $this->getAudioHTML($owner) . str_replace(array(
                '{bar}',
                '{color2}'
            ), array(
                Color::colorToRGBA($this->data->get('color2') . '33'),
                '#' . $this->data->get('color2')
            ), implode('', $controls)));
    }

    /**
     * @param AbstractRenderableOwner $slide
     *
     * @return string
     */
    private function getAudioHTML($slide) {
        $attributes = array();

        if ($this->data->get("volume", 1) == 0) {
            $attributes['muted'] = true;
        }

        return Html::tag("audio", $attributes, $this->setContent($slide));
    }


    /**
     * @param AbstractRenderableOwner $slide
     *
     * @return string
     */
    private function setContent($slide) {
        $videoContent = "";

        if ($this->data->get("audio_mp3", false)) {

            $audioUrl = ResourceTranslator::toUrl($slide->fill($this->data->get("audio_mp3")));
            $type     = "audio/mpeg";

            if (strpos($audioUrl, '.m4a')) {
                $type = "audio/mp4";
            }

            $videoContent .= Html::tag("source", array(
                "src"  => $audioUrl,
                "type" => $type
            ), '', false);
        }

        return $videoContent;
    }

    /**
     * @param AbstractRenderableOwner $owner
     */
    public function loadResources($owner) {
        $owner->addLess(self::getAssetsPath() . "/audio.n2less", array(
            "sliderid" => $owner->getElementID()
        ));
    }
}Item/Area/ItemArea.php000064400000016356152426507510010534 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Area;


use Nextend\Framework\Form\Element\MarginPadding;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\Gradient;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberAutoComplete;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemArea extends AbstractItem {

    protected $ordering = 100;

    protected $layerProperties = array(
        "desktopportraitwidth"  => 150,
        "desktopportraitheight" => 150
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'area';
    }

    public function getTitle() {
        return n2_('Area');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--area';
    }

    public function getGroup() {
        return n2_x('Advanced', 'Layer group');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemAreaFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {
        return parent::getValues() + array(
                'width'        => '',
                'height'       => '',
                'color'        => '000000ff',
                'gradient'     => 'off',
                'color2'       => '000000ff',
                'css'          => '',
                'borderWidth'  => '0|*|0|*|0|*|0',
                'borderStyle'  => 'solid',
                'borderColor'  => 'ffffff1f',
                'borderRadius' => 0,
                'href'         => '#',
                'href-target'  => '_self',
                'href-rel'     => '',
            );
    }

    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }

        $borderWidthV1 = $data->get('borderWidth', 0);
        if (is_numeric($borderWidthV1)) {
            $data->set('borderWidth', $borderWidthV1 . '|*|' . $borderWidthV1 . '|*|' . $borderWidthV1 . '|*|' . $borderWidthV1 . '');
        }

    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function renderFields($container) {
        $color = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-area', n2_('Color'));
        new Color($color, 'color', n2_('Background color'), '00000000', array(
            'alpha' => true
        ));
        new Gradient($color, 'gradient', n2_('Gradient'), 'off', array(
            'relatedFields' => array(
                'item_areacolor2'
            )
        ));
        new Color($color, 'color2', n2_('Color end'), 'ffffff00', array(
            'alpha' => true
        ));

        $border = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-area-border', n2_('Border'));

        $borderWidth = new MarginPadding($border, 'borderWidth', n2_('Border'), '0|*|0|*|0|*|0', array(
            'unit'          => 'px',
            'relatedFields' => array(
                'item_areaborderStyle',
                'item_areaborderColor',
            )
        ));

        for ($i = 1; $i < 5; $i++) {
            new NumberAutoComplete($borderWidth, 'borderWidth-' . $i, false, '', array(
                'values' => array(
                    0,
                    1,
                    2,
                    3,
                    5
                ),
                'min'    => 0,
                'wide'   => 3
            ));
        }

        new Select($border, 'borderStyle', n2_('Style'), 'solid', array(
            'options' => array(
                'none'   => n2_('None'),
                'solid'  => n2_('Solid'),
                'dashed' => n2_('Dashed'),
                'dotted' => n2_('Dotted'),
            )
        ));

        new Color($border, 'borderColor', n2_('Color'), '00000000', array(
            'alpha' => true
        ));

        new NumberAutoComplete($border, 'borderRadius', n2_('Border radius'), 0, array(
            'values' => array(
                0,
                3,
                5,
                10,
                99
            ),
            'wide'   => 3,
            'unit'   => 'px'
        ));

        $size = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-area-size', n2_('Size'));
        new Number($size, 'width', n2_('Width'), '', array(
            'wide'           => 4,
            'unit'           => 'px',
            'tipLabel'       => n2_('Width'),
            'tipDescription' => sprintf(n2_('Fix width for the %1$s.'), $this->getTitle())
        ));
        new Number($size, 'height', n2_('Height'), '', array(
            'wide'           => 4,
            'unit'           => 'px',
            'tipLabel'       => n2_('Height'),
            'tipDescription' => sprintf(n2_('Fix height for the %1$s.'), $this->getTitle())
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-area-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'relatedFields' => array(
                'item_areahref-target',
                'item_areahref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));

        $developer = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-area-developer', n2_('Advanced'));
        new Textarea($developer, 'css', 'CSS', '', array(
            'width'          => 314,
            'tipLabel'       => 'CSS',
            'tipDescription' => n2_('Write custom CSS codes here without selectors.')
        ));
    }
}Item/Area/ItemAreaFrontend.php000064400000007463152426507640012237 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\Area;


use Nextend\Framework\Parser\Color;
use Nextend\Framework\Parser\Common;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemAreaFrontend extends AbstractItemFrontend {

    public function render() {

        if ($this->hasLink()) {
            return $this->getLink($this->getHtml(false), array(
                'style' => 'display: block; width:100%;height:100%;',
                'class' => 'n2-ss-item-content n2-ow'
            ));
        }

        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml($isContent = true) {
        $style = '';

        $color    = $this->data->get('color');
        $gradient = $this->data->get('gradient', 'off');

        if ($gradient != 'off') {
            $colorEnd = $this->data->get('color2');
            switch ($gradient) {
                case 'horizontal':
                    $style .= 'background:linear-gradient(to right, ' . Color::colorToRGBA($color) . ' 0%,' . Color::colorToRGBA($colorEnd) . ' 100%);';
                    break;
                case 'vertical':
                    $style .= 'background:linear-gradient(to bottom, ' . Color::colorToRGBA($color) . ' 0%,' . Color::colorToRGBA($colorEnd) . ' 100%);';
                    break;
                case 'diagonal1':
                    $style .= 'background:linear-gradient(45deg, ' . Color::colorToRGBA($color) . ' 0%,' . Color::colorToRGBA($colorEnd) . ' 100%);';
                    break;
                case 'diagonal2':
                    $style .= 'background:linear-gradient(135deg, ' . Color::colorToRGBA($color) . ' 0%,' . Color::colorToRGBA($colorEnd) . ' 100%);';
                    break;
            }
        } else {
            if (strlen($color) == 8 && substr($color, 6, 2) != '00') {
                $style = 'background-color: #' . substr($color, 0, 6) . ';';
                $style .= "background-color: " . Color::colorToRGBA($color) . ";";
            }
        }

        $_width = intval($this->data->get('width'));
        if ($_width > 0) {
            $style .= 'width:' . $_width . 'px;';
        }


        $height = '100%';

        $_height = intval($this->data->get('height'));
        if ($_height > 0) {
            $height = $_height . 'px';
        }

        $style .= 'height:' . $height . ';';


        $borderWidths = array();
        list($borderWidths[0], $borderWidths[1], $borderWidths[2], $borderWidths[3]) = (array)Common::parse($this->data->getIfEmpty('borderWidth', '0|*|0|*|0|*|0'));

        $hasBorder = false;
        for ($i = 0; $i < 4; $i++) {
            $borderWidths[$i] = max(0, intval($borderWidths[$i]));
            if ($borderWidths[$i] > 0) {
                $hasBorder = true;
            }
        }


        if ($hasBorder) {
            $borderRgba = Color::colorToRGBA($this->data->get('borderColor'));
            $style      .= 'border-width:' . implode('px ', explode('|*|', $this->data->get('borderWidth'))) . 'px;';
            $style      .= 'border-style: ' . $this->data->get('borderStyle') . ';';
            $style      .= 'border-color: ' . $borderRgba . ';';
            $style      .= 'box-sizing: border-box;';
        }
        $borderRadius = max(0, intval($this->data->get('borderRadius')));
        if ($borderRadius > 0) {
            $style .= 'border-radius:' . $borderRadius . 'px;';
        }

        return Html::tag('div', array(
            'class' => ($isContent ? 'n2-ss-item-content ' : '') . 'n2-ow',
            'style' => $style . $this->data->get('css')
        ));
    }

    public function needHeight() {
        return true;
    }
}Item/AnimatedHeading/ItemAnimatedHeading.php000064400000023555152426507710015021 0ustar00<?php


namespace Nextend\SmartSlider3Pro\Renderable\Item\AnimatedHeading;


use Nextend\Framework\Form\Container\ContainerTable;
use Nextend\Framework\Form\Element\Font;
use Nextend\Framework\Form\Element\Hidden\HiddenFont;
use Nextend\Framework\Form\Element\Hidden\HiddenStyle;
use Nextend\Framework\Form\Element\OnOff;
use Nextend\Framework\Form\Element\Select;
use Nextend\Framework\Form\Element\Select\LinkTarget;
use Nextend\Framework\Form\Element\Style;
use Nextend\Framework\Form\Element\Text;
use Nextend\Framework\Form\Element\Text\Color;
use Nextend\Framework\Form\Element\Text\Number;
use Nextend\Framework\Form\Element\Text\NumberSlider;
use Nextend\Framework\Form\Element\Text\Url;
use Nextend\Framework\Form\Element\Textarea;
use Nextend\Framework\Form\Fieldset;
use Nextend\Framework\Parser\Common;
use Nextend\SmartSlider3\Renderable\Item\AbstractItem;

class ItemAnimatedHeading extends AbstractItem {

    protected $ordering = 2;

    protected $fonts = array(
        'font' => array(
            'defaultName' => 'item-animated-heading-font',
            'value'       => '{"data":[{"extra":"","color":"ffffffff","size":"36||px","tshadow":"0|*|0|*|0|*|000000ff","lineheight":"1.5","bold":0,"italic":0,"underline":0,"align":"inherit","letterspacing":"normal","wordspacing":"normal","texttransform":"none"},{},{}]}'
        )
    );

    protected $styles = array(
        'style' => array(
            'defaultName' => 'item-animated-heading-style',
            'value'       => '{"data":[{},{"padding":"0|*|0|*|0|*|0|*|px"},{}]}'
        )
    );

    protected function isBuiltIn() {
        return true;
    }

    public function getType() {
        return 'animatedHeading';
    }

    public function getTitle() {
        return n2_('Animated heading');
    }

    public function getIcon() {
        return 'ssi_32 ssi_32--animatedheading';
    }

    public function getGroup() {
        return n2_('Special');
    }

    public function createFrontend($id, $itemData, $layer) {
        return new ItemAnimatedHeadingFrontend($this, $id, $itemData, $layer);
    }

    public function getValues() {

        return parent::getValues() + array(
                'type'          => 'slide',
                'color'         => 'ffffffff',
                'loop'          => 0,
                'delay'         => 0,
                'speed'         => 100,
                'show-duration' => 1500,
                'animate-width' => 1,

                'priority'      => 'div',
                'before-text'   => n2_('We are Passionate About'),
                'animated-text' => n2_("Amazing Food\nGreat Hospitality"),
                'href'          => '#',
                'href-target'   => '_self',
                'href-rel'      => '',
                'after-text'    => '',
                'title'         => '',

                'class' => ''
            );
    }

    public function upgradeData($data) {
        $linkV1 = $data->get('link', '');
        if (!empty($linkV1)) {
            list($link, $target, $rel) = array_pad((array)Common::parse($linkV1), 3, '');
            $data->un_set('link');
            $data->set('href', $link);
            $data->set('href-target', $target);
            $data->set('href-rel', $rel);
        }
    }


    public function loadResources($renderable) {
        parent::loadResources($renderable);

        $renderable->addLess(self::getAssetsPath() . "/animatedHeading.n2less", array(
            "sliderid" => $renderable->elementId
        ));
    }

    public function getFilled($slide, $data) {
        $data = parent::getFilled($slide, $data);

        $data->set('heading', $slide->fill($data->get('heading', '')));
        $data->set('href', $slide->fill($data->get('href', '#|*|')));

        return $data;
    }

    public function prepareExport($export, $data) {
        parent::prepareExport($export, $data);

        $export->addVisual($data->get('font'));
        $export->addVisual($data->get('style'));
        $export->addLightbox($data->get('href'));
    }

    public function prepareImport($import, $data) {
        $data = parent::prepareImport($import, $data);

        $data->set('font', $import->fixSection($data->get('font')));
        $data->set('style', $import->fixSection($data->get('style')));
        $data->set('href', $import->fixLightbox($data->get('href')));

        return $data;
    }

    public function globalDefaultItemFontAndStyle($container) {

        $table = new ContainerTable($container, $this->getType(), $this->getTitle());
        $row1  = $table->createRow($this->getType() . '-1');

        new Font($row1, 'item-animated-heading-font', false, $this->fonts['font']['value'], array(
            'mode' => 'hover'
        ));

        new Style($row1, 'item-animated-heading-style', false, $this->styles['style']['value'], array(
            'mode' => 'heading'
        ));
    }

    public function renderFields($container) {
        $settings = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-animated-heading-text', n2_('General'));

        new Text($settings, 'before-text', n2_('Before text'), '', array(
            'style' => 'width: 302px;'
        ));

        new Textarea($settings, 'animated-text', n2_('Animated text'), '', array(
            'height' => 70,
            'width'  => 314
        ));

        new Text($settings, 'after-text', n2_('After text'), '', array(
            'style' => 'width: 302px;'
        ));

        $link = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-animated-heading-link', n2_('Link'));
        new Url($link, 'href', n2_('Link'), '', array(
            'style'         => 'width:236px;',
            'relatedFields' => array(
                'item_animatedHeadinghref-target',
                'item_animatedHeadinghref-rel'
            ),
            'width'         => 248
        ));
        new LinkTarget($link, 'href-target', n2_('Target window'));
        new Text($link, 'href-rel', n2_('Rel'), '', array(
            'style'          => 'width:195px;',
            'tipLabel'       => n2_('Rel'),
            'tipDescription' => sprintf(n2_('Enter the %1$s rel attribute %2$s that represents the relationship between the current document and the linked document. Multiple rel attributes can be separated with space. E.g. nofollow noopener noreferrer'), '<a href="https://www.w3schools.com/TAGS/att_a_rel.asp" target="_blank">', '</a>')
        ));

        $animation = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-animated-heading-animation', n2_('Animation'));

        new Select($animation, 'type', n2_('Type'), '', array(
            'options'            => array(
                'fade'        => n2_('Fade'),
                'rotating'    => n2_('Rotating'),
                'drop-in'     => n2_('Drop-in'),
                'slide'       => n2_x('Slide', 'Animation'),
                'slide-down'  => n2_('Slide down'),
                'typewriter1' => n2_('Typewriter'),
                'chars'       => n2_('Chars'),
                'chars2'      => n2_('Chars 2')
            ),
            'relatedValueFields' => array(
                array(
                    'values' => array(
                        'fade',
                        'rotating',
                        'drop-in',
                        'slide',
                        'slide-down',
                        'chars',
                        'chars2'
                    ),
                    'field'  => array(
                        'item_animatedHeadinganimate-width'
                    )
                ),
                array(
                    'values' => array(
                        'typewriter1',
                    ),
                    'field'  => array(
                        'item_animatedHeadingcolor'
                    )
                )
            )
        ));
        new OnOff($animation, 'animate-width', n2_('Auto width'), 1);
        new Color($animation, 'color', n2_('Cursor color'), '', array(
            'alpha' => true
        ));

        new OnOff($animation, 'loop', n2_x('Loop', 'Effect'), 1);

        new Number($animation, 'delay', n2_('Delay'), 0, array(
            'unit' => 'ms',
            'wide' => 5,
            'min'  => 0
        ));
        new NumberSlider($animation, 'speed', n2_('Speed'), 100, array(
            'style'     => 'width:35px;',
            'unit'      => '%',
            'min'       => 10,
            'max'       => 400,
            'step'      => 1,
            'sliderMax' => 150
        ));
        new Number($animation, 'show-duration', n2_('Show duration'), 1500, array(
            'unit' => 'ms',
            'wide' => 5,
            'min'  => 0
        ));

        $dev = new Fieldset\LayerWindow\FieldsetLayerWindow($container, 'item-animated-heading-developer', n2_('Advanced'));
        new Select($dev, 'priority', 'Tag', 'div', array(
            'options' => array(
                'div' => 'div',
                '1'   => 'H1',
                '2'   => 'H2',
                '3'   => 'H3',
                '4'   => 'H4',
                '5'   => 'H5',
                '6'   => 'H6'
            )
        ));

        new HiddenFont($settings, 'font', false, '', array(
            'mode' => 'highlight'
        ));

        new HiddenStyle($settings, 'style', false, '', array(
            'mode' => 'highlight'
        ));


        new Text($dev, 'class', n2_('CSS Class'), '', array(
            'style'          => 'width:226px;',
            'tipLabel'       => n2_('CSS Class'),
            'tipDescription' => n2_('Class on the selected tag element.'),
            'tipLink'        => 'https://smartslider.helpscoutdocs.com/article/1812-layer-style#advanced'
        ));

    }
}Item/AnimatedHeading/ItemAnimatedHeadingFrontend.php000064400000012051152426507760016513 0ustar00<?php

namespace Nextend\SmartSlider3Pro\Renderable\Item\AnimatedHeading;

use Nextend\Framework\Parser\Color;
use Nextend\Framework\Sanitize;
use Nextend\Framework\View\Html;
use Nextend\SmartSlider3\Renderable\AbstractRenderableOwner;
use Nextend\SmartSlider3\Renderable\Item\AbstractItemFrontend;

class ItemAnimatedHeadingFrontend extends AbstractItemFrontend {

    public function render() {
        return $this->getHtml();
    }

    public function renderAdminTemplate() {
        return $this->getHtml();
    }

    private function getHtml() {
        $owner = $this->layer->getOwner();

        $this->loadResources($owner);

        $heading = array();

        $beforeText = Sanitize::filter_allowed_html($owner->fill($this->data->get('before-text', '')));
        if (!empty($beforeText)) {
            $heading[] = Html::tag('ss-text', array(
                    'class' => 'n2-ss-animated-heading-before'
                ), $beforeText) . ' ';
        }

        $animatedText = preg_split('/\r\n|\r|\n/', Sanitize::filter_allowed_html($owner->fill($this->data->get('animated-text', ''))));
        if (!empty($animatedText)) {


            $attributes = array(
                'class' => 'n2-highlighted n2-ss-animated-heading-i'
            );
            $type       = $this->data->get('type', 'slide');
            if ($type != 'slide') {
                $attributes['data-animation-type'] = $type;
            }

            $color = $this->data->get('color', 'ffffffff');
            if ($color != 'ffffffff') {
                $attributes['data-color'] = Color::colorToRGBA($color);
            }

            $animateWidth = $this->data->get('animate-width', '1');
            if ($animateWidth != 1) {
                $attributes['data-animate-width'] = $animateWidth;
            }


            $delay = $this->data->get('delay', 0);
            if ($delay > 0) {
                $attributes['data-delay'] = $delay;
            }

            $showDuration = max(0, $this->data->get('show-duration', 1500));
            if ($showDuration != 1500) {
                $attributes['data-show-duration'] = $showDuration;
            }

            $speed = max(0, $this->data->get('speed', 100));
            if ($speed != 100) {
                $attributes['data-speed'] = $speed;
            }

            if ($this->data->get('loop', 0)) {
                $attributes['data-loop'] = 1;
            }

            $animatedInner = '';

            foreach ($animatedText as $text) {
                $text = trim($text);
                if (!empty($text)) {
                    $animatedInner .= Html::tag('div', array(
                        'class' => 'n2-ss-animated-heading-i-text'
                    ), $text);
                }
            }
            $animatedInner = Html::tag('div', array(
                'class' => 'n2-ss-animated-heading-i2'
            ), $animatedInner);

            $href = $this->data->get('href', '');
            if (!empty($href) && $href != '#') {
                $heading[] = $this->getLink($animatedInner, $attributes);
            } else {
                $heading[] = Html::tag('ss-text', $attributes, $animatedInner);
            }
        }

        $afterText = Sanitize::filter_allowed_html($owner->fill($this->data->get('after-text', '')));
        if (!empty($afterText)) {
            $heading[] = ' ' . Html::tag('ss-text', array(
                    'class' => 'n2-ss-animated-heading-after'
                ), $afterText);
        }


        $font  = $owner->addFont($this->data->get('font'), 'highlight');
        $style = $owner->addStyle($this->data->get('style'), 'highlight');

        return $this->heading($this->data->get('priority', 'div'), array(
            "id"    => $this->id,
            "class" => 'n2-ss-animated-heading-wrapper ' . $font . ' ' . $style . ' n2-ss-item-content n2-ss-text n2-ow-all'
        ), implode('', $heading));
    }

    private function heading($type, $attributes, $content) {
        if (is_numeric($type) && $type > 0) {
            return Html::tag("h{$type}", $attributes, $content);
        }

        return Html::tag("div", $attributes, $content);
    }

    /**
     * @param AbstractRenderableOwner $owner
     */
    public function loadResources($owner) {
        $owner->addLess(self::getAssetsPath() . "/animatedHeading.n2less", array(
            "sliderid" => $owner->getElementID()
        ));

        if (!$owner->isScriptAdded('animated-heading')) {
            if ($this->isEditor) {
                $owner->addScript('this.sliderElement.querySelectorAll(\'.n2-ss-currently-edited-slide .n2-ss-animated-heading-i\').forEach((function(el){new _N2.AnimatedHeadingItemAdmin(el, this)}).bind(this));', 'animated-heading');
            } else {
                $owner->addScript("this.sliderElement.querySelectorAll('.n2-ss-animated-heading-i').forEach((function(el){new _N2.FrontendItemAnimatedHeading(el, this)}).bind(this));", 'animated-heading');
            }
        }
    }
}