Passed
Push — master ( b893da...e7ac93 )
by Andreas
03:30 queued 15s
created

action_plugin_prosemirror_editor::addJSINFO()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * DokuWiki Plugin prosemirror (Action Component)
4
 *
5
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6
 * @author  Andreas Gohr <[email protected]>
7
 */
8
9
// must be run within Dokuwiki
10
if (!defined('DOKU_INC')) {
11
    die();
12
}
13
14
class action_plugin_prosemirror_editor extends DokuWiki_Action_Plugin
15
{
16
    /**
17
     * Registers a callback function for a given event
18
     *
19
     * @param Doku_Event_Handler $controller DokuWiki's event controller object
20
     *
21
     * @return void
22
     */
23
    public function register(Doku_Event_Handler $controller)
24
    {
25
        $controller->register_hook('ACTION_HEADERS_SEND', 'BEFORE', $this, 'forceWYSIWYG');
26
        $controller->register_hook('ACTION_HEADERS_SEND', 'AFTER', $this, 'addJSINFO');
27
        $controller->register_hook('HTML_EDITFORM_OUTPUT', 'BEFORE', $this, 'addDataAndToggleButton');
28
        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, 'addAddtionalForms');
29
    }
30
31
    /**
32
     * If the current user is forced to use the WYSIWYG editor, set the cookie accordingly
33
     *
34
     * Triggered by event: ACTION_HEADERS_SEND
35
     *
36
     * @param Doku_Event $event
37
     * @param            $param
38
     */
39
    public function forceWYSIWYG(Doku_Event $event, $param)
40
    {
41
        if ($this->isForceWYSIWYG()) {
42
            set_doku_pref('plugin_prosemirror_useWYSIWYG', true);
43
        }
44
    }
45
46
    /**
47
     * Add the editor toggle button and, if using the WYSIWYG editor, the instructions rendered to json
48
     *
49
     * Triggered by event: HTML_EDITFORM_OUTPUT
50
     *
51
     * @param Doku_Event $event  event object
52
     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
53
     *                           handler was registered]
54
     *
55
     * @return void
56
     */
57
    public function addDataAndToggleButton(Doku_Event $event, $param)
58
    {
59
        if (!$this->allowWYSIWYG()) {
60
            return;
61
        }
62
63
        /** @var Doku_Form $form */
64
        $form =& $event->data;
65
        $useWYSIWYG = get_doku_pref('plugin_prosemirror_useWYSIWYG', false);
66
67
        $prosemirrorJSON = '';
68
        if ($useWYSIWYG) {
69
            global $TEXT;
70
            $instructions = p_get_instructions($TEXT);
71
            try {
72
                $prosemirrorJSON = p_render('prosemirror', $instructions, $info);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $info seems to be never defined.
Loading history...
73
            } catch (Throwable $e) {
74
                $errorMsg = 'Rendering the page\'s syntax for the WYSIWYG editor failed: ' . $e->getMessage();
75
76
                /** @var \helper_plugin_prosemirror $helper */
77
                $helper = plugin_load('helper', 'prosemirror');
78
                if ($helper->tryToLogErrorToSentry($e, ['text' => $TEXT])) {
79
                    $errorMsg .= ' -- The error has been logged to Sentry.';
80
                }
81
82
                msg($errorMsg, -1);
83
                return;
84
            }
85
        }
86
87
        $form->addElement($this->buildToggleButton());
88
89
        // output data and editor field
90
        $form->addHidden('prosemirror_json',$prosemirrorJSON);
91
        $form->insertElement(1, '<div class="prosemirror_wrapper" id="prosemirror__editor"></div>');
92
    }
93
94
    /**
95
     * Create the button to toggle the WYSIWYG editor
96
     *
97
     * Creates it as hidden if forcing WYSIWYG
98
     *
99
     * @return array the pseudo-tag expected by \Doku_Form::addElement
100
     */
101
    protected function buildToggleButton()
102
    {
103
        $attr = [
104
            'class' => 'button plugin_prosemirror_useWYSIWYG'
105
        ];
106
        if ($this->isForceWYSIWYG()) {
107
            $attr['style'] = 'display: none;';
108
        }
109
        return form_makeButton('button', '', $this->getLang('switch_editors'), $attr);
110
    }
111
112
    /**
113
     * Determine if the current user is forced to use the WYSIWYG editor
114
     *
115
     * @return bool
116
     */
117
    protected function isForceWYSIWYG()
118
    {
119
        return $this->getConf('forceWYSIWYG') && !auth_ismanager();
120
    }
121
122
    /**
123
     * Forbid using WYSIWYG editor when editing anything else then sections or the entire page
124
     *
125
     * This would be the case for the edittable editor or the editor of the data plugin
126
     *
127
     * @return bool
128
     */
129
    protected function allowWYSIWYG()
130
    {
131
        global $INPUT;
132
        return !$INPUT->has('target') || $INPUT->str('target') === 'section';
133
    }
134
135
    public function addAddtionalForms(Doku_Event $event)
136
    {
137
        if (!$this->allowWYSIWYG()) {
138
            return;
139
        }
140
141
        if (!in_array($event->data, ['edit', 'preview'])) {
142
            return;
143
        }
144
145
        $linkForm = new dokuwiki\Form\Form([
146
            'class' => 'plugin_prosemirror_linkform',
147
            'id' => 'prosemirror-linkform',
148
            'style' => 'display: none;',
149
        ]);
150
        $linkForm->addFieldsetOpen('Links')->addClass('js-link-fieldset');;
151
        $iwOptions = array_keys(getInterwiki());
152
        $linkForm->addDropdown('iwshortcut', $iwOptions, 'InterWiki')->attr('required', 'required');
153
154
        $linkForm->addButtonHTML('linkwiz', inlineSVG(DOKU_PLUGIN . 'prosemirror/images/link.svg'))->attrs([
0 ignored issues
show
Bug introduced by
The constant DOKU_PLUGIN was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
155
            'type' => 'button',
156
            'class' => 'js-open-linkwiz linkform_linkwiz'
157
        ]);
158
        $linkForm->addTextInput('linktarget', $this->getLang('link target'))->attrs(
159
            [
160
            'required'=> 'required',
161
            'autofocus' => 'autofocus',
162
            ]
163
        );
164
165
        $linkForm->addTagOpen('div')->addClass('radio-wrapper');
166
        $linkForm->addTagOpen('fieldset');
167
        $linkForm->addTagOpen('legend');
168
        $linkForm->addHTML('Link Type');
169
        $linkForm->addTagClose('legend');
170
        $linkForm->addRadioButton('linktype', $this->getLang('type:wiki page'))->val('internallink');
171
        $linkForm->addRadioButton('linktype', $this->getLang('type:interwiki'))->val('interwikilink');
172
        $linkForm->addRadioButton('linktype', $this->getLang('type:email'))->val('emaillink');
173
        $linkForm->addRadioButton('linktype', $this->getLang('type:external'))->val('externallink')->attr('checked', 'checked');
174
        $linkForm->addRadioButton('linktype', $this->getLang('type:other'))->val('other');
175
        $linkForm->addTagClose('fieldset');
176
        $linkForm->addTagClose('div');
177
178
        $linkForm->addTagOpen('div')->addClass('radio-wrapper');
179
        $linkForm->addTagOpen('fieldset');
180
        $linkForm->addTagOpen('legend');
181
        $linkForm->addHTML('Link Name Type');
182
        $linkForm->addTagClose('legend');
183
        $linkForm->addRadioButton('nametype', $this->getLang('type:automatic title'))->val('automatic')->attr('checked', 'checked');
184
        $linkForm->addRadioButton('nametype', $this->getLang('type:custom title'))->val('custom');
185
        $linkForm->addRadioButton('nametype', $this->getLang('type:image'))->val('image');
186
        $linkForm->addTextInput('linkname', 'Link name')->attr('placeholder', $this->getLang('placeholder:link name'));
187
        $linkForm->addTagOpen('div')->addClass('js-media-wrapper');
188
        $linkForm->addTagClose('div');
189
        $linkForm->addTagClose('fieldset');
190
        $linkForm->addTagClose('div');
191
192
193
        $linkForm->addFieldsetClose();
194
        $linkForm->addButton('ok-button', 'OK')->attr('type', 'submit');
195
        $linkForm->addButton('cancel-button', $this->getLang('cancel'))->attr('type', 'button');
196
197
        echo $linkForm->toHTML();
198
199
        $mediaForm = new dokuwiki\Form\Form([
200
            'class' => 'plugin_prosemirror_mediaform',
201
            'id' => 'prosemirror-mediaform',
202
            'style' => 'display: none;',
203
        ]);
204
        $mediaForm->addFieldsetOpen($this->getLang('legend:media'))->addClass('js-media-fieldset');
205
        $mediaForm->addButtonHTML('mediamanager', inlineSVG(DOKU_PLUGIN . 'prosemirror/images/image.svg'))->attrs([
206
            'type' => 'button',
207
            'class' => 'js-open-mediamanager mediaform_mediamanager'
208
        ]);
209
        $mediaForm->addTextInput('mediatarget', $this->getLang('media target'))->attrs(
210
            [
211
                'required'=> 'required',
212
                'autofocus' => 'autofocus',
213
            ]
214
        );
215
        $mediaForm->addTextInput('mediacaption', $this->getLang('label:caption'));
216
        $mediaForm->addTextInput('width', $this->getLang('label:width'))->attr('type', 'number');
217
        $mediaForm->addTextInput('height', $this->getLang('label:height'))->attr('type', 'number');
218
219
        $mediaForm->addTagOpen('div')->addClass('radio-wrapper');
220
        $mediaForm->addTagOpen('fieldset');
221
        $mediaForm->addTagOpen('legend');
222
        $mediaForm->addHTML($this->getLang('legend:alignment'));
223
        $mediaForm->addTagClose('legend');
224
        $mediaForm->addRadioButton('alignment', $this->getLang('label:default alignment'))->val('')->attr('checked', 'checked');
225
        $mediaForm->addRadioButton('alignment', $this->getLang('label:float left'))->val('left');
226
        $mediaForm->addRadioButton('alignment', $this->getLang('label:center alignment'))->val('center');
227
        $mediaForm->addRadioButton('alignment', $this->getLang('label:float right'))->val('right');
228
        $mediaForm->addTagClose('fieldset');
229
        $mediaForm->addTagClose('div');
230
231
        $mediaForm->addTagOpen('div')->addClass('radio-wrapper');
232
        $mediaForm->addTagOpen('fieldset');
233
        $mediaForm->addTagOpen('legend');
234
        $mediaForm->addHTML($this->getLang('legend:linking'));
235
        $mediaForm->addTagClose('legend');
236
        $mediaForm->addRadioButton('linking', $this->getLang('label:default linking'))->val('details')->attr('checked', 'checked');
237
        $mediaForm->addRadioButton('linking', $this->getLang('label:direct linking'))->val('direct');
238
        $mediaForm->addRadioButton('linking', $this->getLang('label:nolink'))->val('nolink');
239
        $mediaForm->addRadioButton('linking', $this->getLang('label:linkonly'))->val('linkonly');
240
        $mediaForm->addTagClose('fieldset');
241
        $mediaForm->addTagClose('div');
242
243
        $mediaForm->addTagOpen('div')->addClass('radio-wrapper');
244
        $mediaForm->addTagOpen('fieldset');
245
        $mediaForm->addTagOpen('legend');
246
        $mediaForm->addHTML($this->getLang('legend:caching'));
247
        $mediaForm->addTagClose('legend');
248
        $mediaForm->addRadioButton('caching', $this->getLang('label:default caching'))->val('')->attr('checked', 'checked');
249
        $mediaForm->addRadioButton('caching', $this->getLang('label:recache'))->val('recache');
250
        $mediaForm->addRadioButton('caching', $this->getLang('label:nocache'))->val('nocache');
251
        $mediaForm->addTagClose('fieldset');
252
        $mediaForm->addTagClose('div');
253
254
        $mediaForm->addFieldsetClose();
255
        $mediaForm->addButton('ok-button', 'OK')->attr('type', 'submit');
256
        $mediaForm->addButton('cancel-button', $this->getLang('cancel'))->attr('type', 'button');
257
258
        // dynamic image hack? https://www.dokuwiki.org/images#dynamic_images
259
260
        echo $mediaForm->toHTML();
261
262
        // phpcs:disable
263
        $languages = explode(' ', '4cs 6502acme 6502kickass 6502tasm 68000devpac abap actionscript3 actionscript ada aimms algol68 apache applescript apt_sources arm asm asp asymptote autoconf autohotkey autoit avisynth awk bascomavr bash basic4gl batch bf biblatex bibtex blitzbasic bnf boo caddcl cadlisp ceylon cfdg cfm chaiscript chapel cil c_loadrunner clojure c_mac cmake cobol coffeescript c cpp cpp-qt cpp-winapi csharp css cuesheet c_winapi dart dcl dcpu16 dcs delphi diff div dos dot d ecmascript eiffel email epc e erlang euphoria ezt f1 falcon fo fortran freebasic freeswitch fsharp gambas gdb genero genie gettext glsl gml gnuplot go groovy gwbasic haskell haxe hicest hq9plus html html4strict html5 icon idl ini inno intercal io ispfpanel java5 java javascript jcl j jquery julia kixtart klonec klonecpp kotlin latex lb ldif lisp llvm locobasic logtalk lolcode lotusformulas lotusscript lscript lsl2 lua m68k magiksf make mapbasic mathematica matlab mercury metapost mirc mk-61 mmix modula2 modula3 mpasm mxml mysql nagios netrexx newlisp nginx nimrod nsis oberon2 objc objeck ocaml-brief ocaml octave oobas oorexx oracle11 oracle8 oxygene oz parasail parigp pascal pcre perl6 perl per pf phix php-brief php pic16 pike pixelbender pli plsql postgresql postscript povray powerbuilder powershell proftpd progress prolog properties providex purebasic pycon pys60 python qbasic qml q racket rails rbs rebol reg rexx robots rpmspec rsplus ruby rust sas sass scala scheme scilab scl sdlbasic smalltalk smarty spark sparql sql standardml stonescript swift systemverilog tclegg tcl teraterm texgraph text thinbasic tsql twig typoscript unicon upc urbi uscript vala vbnet vb vbscript vedit verilog vhdl vim visualfoxpro visualprolog whitespace whois winbatch xbasic xml xojo xorg_conf xpp yaml z80 zxbasic');
264
        // phpcs:enable
265
        $datalistHTML = '<datalist id="codelanguages">';
266
        foreach ($languages as $language) {
267
            $datalistHTML .= "<option value=\"$language\">";
268
        }
269
        $datalistHTML .= '</datalist>';
270
        echo $datalistHTML;
271
    }
272
273
    /**
274
     * Provide the current smiley configuration to Javascript
275
     */
276
    public function addJSINFO()
277
    {
278
        global $JSINFO;
279
        $JSINFO['SMILEY_CONF'] = getSmileys();
280
    }
281
}
282
283
// vim:ts=4:sw=4:et:
284