Completed
Push — master ( 0708bc...621f78 )
by Alberto
37s queued 31s
created

WebComponentsHelper::props()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 16
c 1
b 0
f 0
nc 7
nop 1
dl 0
loc 27
rs 9.1111
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * BEdita, API-first content management framework
6
 * Copyright 2020 ChannelWeb Srl, Chialab Srl
7
 *
8
 * This file is part of BEdita: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published
10
 * by the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
14
 */
15
16
namespace BEdita\WebTools\View\Helper;
17
18
use Cake\View\Helper;
19
20
/**
21
 * Helper to handle Web Components initialization with properties.
22
 */
23
class WebComponentsHelper extends Helper
24
{
25
    /**
26
     * {@inheritDoc}
27
     **/
28
    public $helpers = ['Html'];
29
30
    /**
31
     * A list of used identifiers.
32
     *
33
     * @var array
34
     **/
35
    private $ids = [];
36
37
    /**
38
     * Pass properties to an HTMLElement using attributes for plain values and inline scripts for array.
39
     *
40
     * @param array $properties A list of properties to set.
41
     * @return array An array of attributes.
42
     */
43
    public function props(array $properties): array
44
    {
45
        if (empty($properties)) {
46
            return [];
47
        }
48
49
        $id = count($this->ids);
50
        $this->ids[] = $id;
51
52
        $attributes = [
53
            'data-wc' => $id,
54
        ];
55
        $statements = [];
56
        foreach ($properties as $key => $value) {
57
            if (is_string($value) || is_numeric($value)) {
58
                $attributes[$key] = $value;
59
            } else {
60
                $statements[] = sprintf('elem[\'%s\'] = %s;', $key, json_encode($value));
61
            }
62
        }
63
64
        if (!empty($statements)) {
65
            $content = sprintf('(function(){var elem = document.querySelector(\'[data-wc="%s"]\');%s}());if(document.currentScript)document.currentScript.parentNode.removeChild(document.currentScript);', $id, join('', $statements));
66
            $this->Html->scriptBlock($content, [ 'block' => 'scriptsComponents' ]);
67
        }
68
69
        return $attributes;
70
    }
71
72
    /**
73
     * Initialize a Custom Element which extends a native node.
74
     *
75
     * @param string $tagName The defined Custom Element name to set as `is` attribute.
76
     * @param array $properties A list of properties to set.
77
     * @param string $scriptPath The path of the definition script to import.
78
     * @return string An attributes string list like `is="my-element" data-wc="0"`.
79
     */
80
    public function is(string $tagName, array $properties = [], string $scriptPath = ''): string
81
    {
82
        if (!empty($scriptPath)) {
83
            $this->Html->script($scriptPath, [ 'block' => 'scriptsComponents' ]);
84
        }
85
86
        $options = ['is' => $tagName] + $this->props($properties);
87
88
        return trim($this->Html->templater()->formatAttributes($options));
89
    }
90
91
    /**
92
     * Initialize a Custom Element.
93
     *
94
     * @param string $tagName The defined Custom Element name to use as tag name.
95
     * @param array $properties A list of properties to set.
96
     * @param string $scriptPath The path of the definition script to import.
97
     * @return string An HTML node string like `<my-element data-wc="0"></my-element>`.
98
     */
99
    public function element(string $tagName, array $properties = [], $scriptPath = ''): string
100
    {
101
        if (!empty($scriptPath)) {
102
            $this->Html->script($scriptPath, [ 'block' => 'scriptsComponents' ]);
103
        }
104
105
        return $this->Html->tag($tagName, '', $this->props($properties));
106
    }
107
}
108