1<?php
2/**
3 * Bootstrap Wrapper Plugin: Affix
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
7 * @copyright  (C) 2015-2020, Giuseppe Di Terlizzi
8 */
9
10class syntax_plugin_bootswrapper_affix extends syntax_plugin_bootswrapper_bootstrap
11{
12    public $p_type         = 'block';
13    public $pattern_start  = '<affix.*?>(?=.*?</affix>)';
14    public $pattern_end    = '</affix>';
15    public $tag_name       = 'affix';
16    public $tag_attributes = array(
17
18        'offset-top'      => array(
19            'type'     => 'integer',
20            'values'   => null,
21            'required' => false,
22            'default'  => null),
23
24        'offset-bottom'   => array(
25            'type'     => 'integer',
26            'values'   => null,
27            'required' => false,
28            'default'  => null),
29
30        'target'          => array(
31            'type'     => 'string',
32            'values'   => null,
33            'required' => false,
34            'default'  => null),
35
36        'position'        => array(
37            'type'     => 'string',
38            'values'   => array('fixed', 'absolute'),
39            'required' => false,
40            'default'  => 'fixed'),
41
42        'position-top'    => array(
43            'type'     => 'string',
44            'values'   => null,
45            'required' => false,
46            'default'  => null),
47
48        'position-bottom' => array(
49            'type'     => 'string',
50            'values'   => null,
51            'required' => false,
52            'default'  => null),
53
54        'position-left'   => array(
55            'type'     => 'string',
56            'values'   => null,
57            'required' => false,
58            'default'  => null),
59
60        'position-right'  => array(
61            'type'     => 'string',
62            'values'   => null,
63            'required' => false,
64            'default'  => null),
65    );
66
67    public function render($mode, Doku_Renderer $renderer, $data)
68    {
69
70        if (empty($data)) {
71            return false;
72        }
73
74        if ($mode !== 'xhtml') {
75            return false;
76        }
77
78        /** @var Doku_Renderer_xhtml $renderer */
79        list($state, $match, $pos, $attributes) = $data;
80
81        if ($state == DOKU_LEXER_ENTER) {
82            $top             = $attributes['offset-top'];
83            $bottom          = $attributes['offset-bottom'];
84            $target          = $attributes['target'];
85            $position        = $attributes['position'];
86            $position_top    = $attributes['position-top'];
87            $position_bottom = $attributes['position-bottom'];
88            $position_right  = $attributes['position-right'];
89            $position_left   = $attributes['position-left'];
90
91            $html5_data = array();
92            $styles     = array();
93
94            if ($position === 'fixed') {
95                $position = null;
96            }
97
98            if ($position_top && (!strstr($position_top, 'px')
99                && !strstr($position_top, 'em')
100                && !strstr($position_top, '%'))) {
101                $position_top = "{$position_top}px";
102            }
103
104            if ($position_bottom && (!strstr($position_bottom, 'px')
105                && !strstr($position_bottom, 'em')
106                && !strstr($position_bottom, '%'))) {
107                $position_bottom = "{$position_bottom}px";
108            }
109
110            if ($position_right && (!strstr($position_right, 'px')
111                && !strstr($position_right, 'em')
112                && !strstr($position_right, '%'))) {
113                $position_right = "{$position_right}px";
114            }
115
116            if ($position_left && (!strstr($position_left, 'px')
117                && !strstr($position_left, 'em')
118                && !strstr($position_left, '%'))) {
119                $position_left = "{$position_left}px";
120            }
121
122            if ($top) {
123                $html5_data[] = "data-offset-top=$top ";
124            }
125
126            if ($bottom) {
127                $html5_data[] = "data-offset-bottom=$bottom ";
128            }
129
130            if ($target) {
131                $html5_data[] = 'data-target="' . $target . '"';
132            }
133
134            if ($position) {
135                $styles[] = "position:$position";
136            }
137
138            if ($position_top) {
139                $styles[] = "top:$position_top";
140            }
141
142            if ($position_bottom) {
143                $styles[] = "bottom:$position_bottom";
144            }
145
146            if ($position_left) {
147                $styles[] = "left:$position_left";
148            }
149
150            if ($position_right) {
151                $styles[] = "right:$position_right";
152            }
153
154            $markup = '<div style="z-index:1024;' . implode(';', $styles) . '" class="bs-wrap bs-wrap-affix" data-spy="affix" ' . implode(' ', $html5_data) . '>';
155
156            $renderer->doc .= $markup;
157            return true;
158        }
159
160        if ($state == DOKU_LEXER_EXIT) {
161            $renderer->doc .= '</div>';
162            return true;
163        }
164
165        return true;
166    }
167}
168