From ec57f1190eb6df5ddeba76bb2c35b46d65d31561 Mon Sep 17 00:00:00 2001 From: LarsDW223 <lars_paulsen@web.de> Date: Thu, 4 Jan 2018 14:38:01 +0100 Subject: [PATCH] Refactored section edit The data for the section edit button is now passed as an assoziative array which is encoded in the '#<!-- EDIT(.*) -->#' placeholder as an JSON array. --- _test/tests/inc/html_secedit_pattern.test.php | 15 ++--- inc/html.php | 22 +++---- inc/parser/xhtml.php | 63 +++++++++++++------ 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/_test/tests/inc/html_secedit_pattern.test.php b/_test/tests/inc/html_secedit_pattern.test.php index 1c0107801..ca1615885 100644 --- a/_test/tests/inc/html_secedit_pattern.test.php +++ b/_test/tests/inc/html_secedit_pattern.test.php @@ -6,9 +6,9 @@ class html_scedit_pattern_test extends DokuWikiTest { public function dataProviderForTestSecEditPattern() { return [ [ - '<!-- EDIT5 SECTION "Plugins" "plugins" [1406-] -->', + '<!-- EDIT{"target":"SECTION","name":"Plugins","hid":"plugins","codeblockOffset":0,"secid":5,"range":"1406-"} -->', [ - 'secid' => '5', + 'secid' => 5, 'target' => 'SECTION', 'name' => 'Plugins', 'hid' => 'plugins', @@ -17,9 +17,9 @@ class html_scedit_pattern_test extends DokuWikiTest { 'basic section edit', ], [ - '<!-- EDIT10 TABLE "" "table4" [11908-14014] -->', + '<!-- EDIT{"target":"TABLE","name":"","hid":"table4","codeblockOffset":0,"secid":10,"range":"11908-14014"} -->', [ - 'secid' => '10', + 'secid' => 10, 'target' => 'TABLE', 'name' => '', 'hid' => 'table4', @@ -28,9 +28,9 @@ class html_scedit_pattern_test extends DokuWikiTest { 'table edit' ], [ - '<!-- EDIT2 PLUGIN_DATA [27-432] -->', + '<!-- EDIT{"target":"PLUGIN_DATA","name":"","hid":"","codeblockOffset":0,"secid":2,"range":"27-432"} -->', [ - 'secid' => '2', + 'secid' => 2, 'target' => 'PLUGIN_DATA', 'name' => '', 'hid' => '', @@ -50,8 +50,9 @@ class html_scedit_pattern_test extends DokuWikiTest { */ public function testSecEditPattern($text, $expectedMatches, $msg) { preg_match(SEC_EDIT_PATTERN, $text, $matches); + $data = json_decode($matches[1], true); foreach ($expectedMatches as $key => $expected_value) { - $this->assertSame($expected_value, $matches[$key], $msg); + $this->assertSame($expected_value, $data[$key], $msg); } } diff --git a/inc/html.php b/inc/html.php index b8465a641..7cb1063b9 100644 --- a/inc/html.php +++ b/inc/html.php @@ -9,7 +9,7 @@ if(!defined('DOKU_INC')) die('meh.'); if(!defined('NL')) define('NL',"\n"); if (!defined('SEC_EDIT_PATTERN')) { - define('SEC_EDIT_PATTERN', '#<!-- EDIT(?<secid>\d+) (?<target>[A-Z_]+) (?:"(?<name>[^"]*)" )?(?:"(?<hid>[^"]*)" )?\[(?<range>\d+-\d*)\] -->#'); + define('SEC_EDIT_PATTERN', '#<!-- EDIT({.*}) -->#'); } @@ -114,17 +114,12 @@ function html_secedit($text,$show=true){ * @triggers HTML_SECEDIT_BUTTON */ function html_secedit_button($matches){ - $data = array('secid' => $matches['secid'], - 'target' => strtolower($matches['target']), - 'range' => $matches['range']); - - if (!empty($matches['hid'])) { - $data['hid'] = strtolower($matches['hid']); - } - - if (!empty($matches['name'])) { - $data['name'] = $matches['name']; + $data = json_decode($matches[1], true); + if ($data == NULL) { + return; } + $data ['target'] = strtolower($data['target']); + $data ['hid'] = strtolower($data['hid']); return trigger_event('HTML_SECEDIT_BUTTON', $data, 'html_secedit_get_button'); @@ -1860,6 +1855,9 @@ function html_edit(){ if ($INPUT->has('hid')) { $form->addHidden('hid', $INPUT->str('hid')); } + if ($INPUT->has('codeblockOffset')) { + $form->addHidden('codeblockOffset', $INPUT->str('codeblockOffset')); + } $form->addElement(form_makeOpenTag('div', array('id'=>'wiki__editbar', 'class'=>'editBar'))); $form->addElement(form_makeOpenTag('div', array('id'=>'size__ctl'))); $form->addElement(form_makeCloseTag('div')); @@ -2314,4 +2312,4 @@ function html_sizechange($sizechange, Doku_Form $form) { $form->addElement($value); $form->addElement(form_makeCloseTag('span')); } -} \ No newline at end of file +} diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php index 393ec8d10..df436e0e6 100644 --- a/inc/parser/xhtml.php +++ b/inc/parser/xhtml.php @@ -59,16 +59,31 @@ class Doku_Renderer_xhtml extends Doku_Renderer { /** * Register a new edit section range * - * @param string $type The section type identifier - * @param string $title The section title * @param int $start The byte position for the edit start + * @param array $data Associative array with section data: + * Key 'name': the section name/title + * Key 'target': the target for the section edit, + * e.g. 'section' or 'table' + * Key 'hid': header id + * Key 'codeblockOffset': actual code block index + * Key 'start': set in startSectionEdit(), + * do not set yourself + * Key 'range': calculated from 'start' and + * $key in finishSectionEdit(), + * do not set yourself * @return string A marker class for the starting HTML element * * @author Adrian Lang <lang@cosmocode.de> */ - public function startSectionEdit($start, $type, $title = null, $hid = null) { - $this->sectionedits[] = array(++$this->lastsecid, $start, $type, $title, $hid); - return 'sectionedit'.$this->lastsecid; + public function startSectionEdit($start, $data) { + if (!is_array($data)) { + msg('startSectionEdit: $data is NOT an array!', -1); + return ''; + } + $data['secid'] = ++$this->lastsecid; + $data['start'] = $start; + $this->sectionedits[] = $data; + return 'sectionedit'.$data['secid']; } /** @@ -79,18 +94,16 @@ class Doku_Renderer_xhtml extends Doku_Renderer { * @author Adrian Lang <lang@cosmocode.de> */ public function finishSectionEdit($end = null, $hid = null) { - list($id, $start, $type, $title, $hid) = array_pop($this->sectionedits); - if(!is_null($end) && $end <= $start) { + $data = array_pop($this->sectionedits); + if(!is_null($end) && $end <= $data['start']) { return; } - $this->doc .= "<!-- EDIT$id ".strtoupper($type).' '; - if(!is_null($title)) { - $this->doc .= '"'.str_replace('"', '', $title).'" '; - } if(!is_null($hid)) { - $this->doc .= '"'.$hid.'" '; + $data['hid'] .= $hid; } - $this->doc .= "[$start-".(is_null($end) ? '' : $end).'] -->'; + $data['range'] = $data['start'].'-'.(is_null($end) ? '' : $end); + unset($data['start']); + $this->doc .= '<!-- EDIT'.json_encode ($data).' -->'; } /** @@ -117,7 +130,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { function document_end() { // Finish open section edits. while(count($this->sectionedits) > 0) { - if($this->sectionedits[count($this->sectionedits) - 1][1] <= 1) { + if($this->sectionedits[count($this->sectionedits) - 1]['start'] <= 1) { // If there is only one section, do not write a section edit // marker. array_pop($this->sectionedits); @@ -212,7 +225,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { if($level <= $conf['maxseclevel'] && count($this->sectionedits) > 0 && - $this->sectionedits[count($this->sectionedits) - 1][2] === 'section' + $this->sectionedits[count($this->sectionedits) - 1]['target'] === 'section' ) { $this->finishSectionEdit($pos - 1); } @@ -220,7 +233,12 @@ class Doku_Renderer_xhtml extends Doku_Renderer { // write the header $this->doc .= DOKU_LF.'<h'.$level; if($level <= $conf['maxseclevel']) { - $this->doc .= ' class="'.$this->startSectionEdit($pos, 'section', $text, $hid).'"'; + $data = array(); + $data['target'] = 'section'; + $data['name'] = $text; + $data['hid'] = $hid; + $data['codeblockOffset'] = $this->_codeblock; + $this->doc .= ' class="'.$this->startSectionEdit($pos, $data).'"'; } $this->doc .= ' id="'.$hid.'">'; $this->doc .= $this->_xmlEntities($text); @@ -632,6 +650,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer { function _highlight($type, $text, $language = null, $filename = null) { global $ID; global $lang; + global $INPUT; $language = preg_replace(PREG_PATTERN_VALID_LANGUAGE, '', $language); @@ -641,8 +660,12 @@ class Doku_Renderer_xhtml extends Doku_Renderer { $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); $class = 'mediafile mf_'.$class; + $offset = 0; + if ($INPUT->has('codeblockOffset')) { + $offset = $INPUT->str('codeblockOffset'); + } $this->doc .= '<dl class="'.$type.'">'.DOKU_LF; - $this->doc .= '<dt><a href="'.exportlink($ID, 'code', array('codeblock' => $this->_codeblock)).'" title="'.$lang['download'].'" class="'.$class.'">'; + $this->doc .= '<dt><a href="'.exportlink($ID, 'code', array('codeblock' => $offset+$this->_codeblock)).'" title="'.$lang['download'].'" class="'.$class.'">'; $this->doc .= hsc($filename); $this->doc .= '</a></dt>'.DOKU_LF.'<dd>'; } @@ -1340,7 +1363,11 @@ class Doku_Renderer_xhtml extends Doku_Renderer { } if($pos !== null) { $hid = $this->_headerToLink($class, true); - $class .= ' '.$this->startSectionEdit($pos, 'table', '', $hid); + $data = array(); + $data['target'] = 'table'; + $data['name'] = ''; + $data['hid'] = $hid; + $class .= ' '.$this->startSectionEdit($pos, $data); } $this->doc .= '<div class="'.$class.'"><table class="inline">'. DOKU_LF; -- GitLab