Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions _test/renderer_plugin_edittable_json.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ function test_table() {
);

$renderer = $this->render($input);
$json = new JSON(JSON_LOOSE_TYPE);

$this->assertEquals($data, $json->decode($renderer->getDataJSON()));
$this->assertEquals($meta, $json->decode($renderer->getMetaJSON()));
$this->assertEquals($data, json_decode($renderer->getDataJSON(), true));
$this->assertEquals($meta, json_decode($renderer->getMetaJSON(), true));
}


Expand Down
135 changes: 91 additions & 44 deletions action/editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@
* @author Andreas Gohr <[email protected]>
*/

if(!defined('DOKU_INC')) die();
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
use dokuwiki\Form\Form;
use dokuwiki\Utf8;

/**
* handles all the editor related things
*
* like displaying the editor and adding custom edit buttons
*/
class action_plugin_edittable_editor extends DokuWiki_Action_Plugin {

class action_plugin_edittable_editor extends DokuWiki_Action_Plugin
{
/**
* Register its handlers with the DokuWiki's event controller
*/
function register(Doku_Event_Handler $controller) {
public function register(Doku_Event_Handler $controller)
{
// register custom edit buttons
$controller->register_hook('HTML_SECEDIT_BUTTON', 'BEFORE', $this, 'secedit_button');

// register our editor
$controller->register_hook('EDIT_FORM_ADDTEXTAREA', 'BEFORE', $this, 'editform');
$controller->register_hook('HTML_EDIT_FORMSELECTION', 'BEFORE', $this, 'editform');

// register preprocessing for accepting editor data
Expand All @@ -38,10 +40,10 @@ function register(Doku_Event_Handler $controller) {
*
* @param Doku_Event $event
*/
function secedit_button(Doku_Event $event) {
if($event->data['target'] !== 'table') {
return;
}
public function secedit_button(Doku_Event $event)
{
if ($event->data['target'] !== 'table') return;

$event->data['name'] = $this->getLang('secedit_name');
}

Expand All @@ -50,12 +52,14 @@ function secedit_button(Doku_Event $event) {
*
* @param Doku_Event $event
*/
function editform(Doku_Event $event) {
public function editform(Doku_Event $event)
{
global $TEXT;
global $RANGE;
global $INPUT;

if($event->data['target'] !== 'table') return;
if(!$RANGE){
if ($event->data['target'] !== 'table') return;
if (!$RANGE){
// section editing failed, use default editor instead
$event->data['target'] = 'section';
return;
Expand All @@ -69,7 +73,7 @@ function editform(Doku_Event $event) {
$instructions = p_get_instructions($TEXT);

// Loop through the instructions
foreach($instructions as $instruction) {
foreach ($instructions as $instruction) {
// Execute the callback against the Renderer
call_user_func_array(array(&$Renderer, $instruction[0]), $instruction[1]);
}
Expand All @@ -79,21 +83,36 @@ function editform(Doku_Event $event) {
/** @var Doku_Form $form */
$form =& $event->data['form'];

// data for handsontable
$form->addHidden('edittable_data', $Renderer->getDataJSON());
$form->addHidden('edittable_meta', $Renderer->getMetaJSON());
$form->addElement('<div id="edittable__editor"></div>');
if (is_a($form, Form::class)) { // $event->name is EDIT_FORM_ADDTEXTAREA
// data for handsontable
$form->setHiddenField('edittable_data', $Renderer->getDataJSON());
$form->setHiddenField('edittable_meta', $Renderer->getMetaJSON());
$form->addHTML('<div id="edittable__editor"></div>');

// set data from action asigned to "New Table" button in the toolbar
foreach ($INPUT->post->arr('edittable__new', []) as $k => $v) {
$form->setHiddenField("edittable__new[$k]", $v);
}

// set target and range to keep track during previews
$form->setHiddenField('target', 'table');
$form->setHiddenField('range', $RANGE);

} else { // $event->name is HTML_EDIT_FORMSELECTION
// data for handsontable
$form->addHidden('edittable_data', $Renderer->getDataJSON());
$form->addHidden('edittable_meta', $Renderer->getMetaJSON());
$form->addElement('<div id="edittable__editor"></div>');

// FIXME add explanation here
if(isset($_POST['edittable__new'])) {
foreach($_POST['edittable__new'] as $k => $v) {
// set data from action asigned to "New Table" button in the toolbar
foreach ($INPUT->post->arr('edittable__new', []) as $k => $v) {
$form->addHidden("edittable__new[$k]", $v);
}
}

// set target and range to keep track during previews
$form->addHidden('target', 'table');
$form->addHidden('range', $RANGE);
// set target and range to keep track during previews
$form->addHidden('target', 'table');
$form->addHidden('range', $RANGE);
}
}

/**
Expand All @@ -103,14 +122,14 @@ function editform(Doku_Event $event) {
*
* @author Andreas Gohr <gohr@cosmocode,de>
*/
public function handle_table_post($event) {
public function handle_table_post(Doku_Event $event)
{
global $TEXT;
global $INPUT;
if(!$INPUT->post->has('edittable_data')) return;
if (!$INPUT->post->has('edittable_data')) return;

$json = new JSON(JSON_LOOSE_TYPE);
$data = $json->decode($INPUT->post->str('edittable_data'));
$meta = $json->decode($INPUT->post->str('edittable_meta'));
$data = json_decode($INPUT->post->str('edittable_data'), true);
$meta = json_decode($INPUT->post->str('edittable_meta'), true);

$TEXT = $this->build_table($data, $meta);
}
Expand All @@ -124,20 +143,21 @@ public function handle_table_post($event) {
* @param array $meta meta data for each cell
* @return string
*/
public function build_table($data, $meta) {
public function build_table($data, $meta)
{
$table = '';
$rows = count($data);
$cols = $rows ? count($data[0]) : 0;

$colmax = $cols ? array_fill(0, $cols, 0) : array();

// find maximum column widths
for($row = 0; $row < $rows; $row++) {
for($col = 0; $col < $cols; $col++) {
$len = utf8_strlen($data[$row][$col]);
for ($row = 0; $row < $rows; $row++) {
for ($col = 0; $col < $cols; $col++) {
$len = $this->strWidth($data[$row][$col]);

// alignment adds padding
if($meta[$row][$col]['align'] == 'center') {
if ($meta[$row][$col]['align'] == 'center') {
$len += 4;
} else {
$len += 3;
Expand All @@ -146,19 +166,19 @@ public function build_table($data, $meta) {
// remember lenght
$meta[$row][$col]['length'] = $len;

if($len > $colmax[$col]) $colmax[$col] = $len;
if ($len > $colmax[$col]) $colmax[$col] = $len;
}
}

$last = '|'; // used to close the last cell
for($row = 0; $row < $rows; $row++) {
for($col = 0; $col < $cols; $col++) {
for ($row = 0; $row < $rows; $row++) {
for ($col = 0; $col < $cols; $col++) {

// minimum padding according to alignment
if($meta[$row][$col]['align'] == 'center') {
if ($meta[$row][$col]['align'] == 'center') {
$lpad = 2;
$rpad = 2;
} elseif($meta[$row][$col]['align'] == 'right') {
} elseif ($meta[$row][$col]['align'] == 'right') {
$lpad = 2;
$rpad = 1;
} else {
Expand All @@ -170,13 +190,13 @@ public function build_table($data, $meta) {
$target = $colmax[$col];

// colspanned columns span all the cells
for($i = 1; $i < $meta[$row][$col]['colspan']; $i++) {
for ($i = 1; $i < $meta[$row][$col]['colspan']; $i++) {
$target += $colmax[$col + $i];
}

// copy colspans to rowspans below if any
if($meta[$row][$col]['colspan'] > 1){
for($i = 1; $i < $meta[$row][$col]['rowspan']; $i++) {
if ($meta[$row][$col]['colspan'] > 1) {
for ($i = 1; $i < $meta[$row][$col]['rowspan']; $i++) {
$meta[$row + $i][$col]['colspan'] = $meta[$row][$col]['colspan'];
}
}
Expand All @@ -186,15 +206,15 @@ public function build_table($data, $meta) {
$addpad = $target - $length;

// decide which side needs padding
if($meta[$row][$col]['align'] == 'right') {
if ($meta[$row][$col]['align'] == 'right') {
$lpad += $addpad;
} else {
$rpad += $addpad;
}

// add the padding
$cdata = $data[$row][$col];
if(!$meta[$row][$col]['hide'] || $cdata) {
if (!$meta[$row][$col]['hide'] || $cdata) {
$cdata = str_pad('', $lpad).$cdata.str_pad('', $rpad);
}

Expand All @@ -212,4 +232,31 @@ public function build_table($data, $meta) {
return $table;
}

/**
* Return width of string
*
* @param string $str
* @return int
*/
public function strWidth($str)
{
static $callable;

if (isset($callable)) {
return $callable($str);
} else {
if (UTF8_MBSTRING) {
// count fullwidth characters as 2, halfwidth characters as 1
$callable = 'mb_strwidth';
} elseif (method_exists(Utf8\PhpString::class, 'strlen')) {
// count any characters as 1
$callable = [Utf8\PhpString::class, 'strlen'];
} else {
// fallback deprecated utf8_strlen since 2019-06-09
$callable = 'utf8_strlen';
}
return $this->strWidth($str);
}
}

}
12 changes: 6 additions & 6 deletions action/jsinfo.php
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
<?php

if(!defined('DOKU_INC')) die();

/**
* handles the data that has to be written into jsinfo
*
* like displaying the editor and adding custom edit buttons
*/
class action_plugin_edittable_jsinfo extends DokuWiki_Action_Plugin {

class action_plugin_edittable_jsinfo extends DokuWiki_Action_Plugin
{
/**
* Register its handlers with the DokuWiki's event controller
*/
function register(Doku_Event_Handler $controller) {
public function register(Doku_Event_Handler $controller)
{
// register custom edit buttons
$controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'fill_jsinfo');
}

function fill_jsinfo() {
public function fill_jsinfo()
{
global $JSINFO;
$JSINFO['plugins']['edittable']['default columnwidth'] = $this->getConf('default colwidth');
}
Expand Down
22 changes: 11 additions & 11 deletions action/newtable.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@
* @author Adrian Lang <[email protected]>
*/

if(!defined('DOKU_INC')) die();
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');

/**
* Handles the inserting of a new table in a running edit session
*/
class action_plugin_edittable_newtable extends DokuWiki_Action_Plugin {

class action_plugin_edittable_newtable extends DokuWiki_Action_Plugin
{
/**
* Register its handlers with the DokuWiki's event controller
*/
function register(Doku_Event_Handler $controller) {
function register(Doku_Event_Handler $controller)
{
$controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'toolbar');

//$controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_newtable');
Expand All @@ -28,7 +26,8 @@ function register(Doku_Event_Handler $controller) {
*
* @param Doku_Event $event
*/
function toolbar($event) {
public function toolbar(Doku_Event $event)
{
$event->data[] = array(
'title' => $this->getLang('add_table'),
'type' => 'NewTable',
Expand All @@ -42,11 +41,12 @@ function toolbar($event) {
*
* @param Doku_Event $event
*/
function handle_newtable($event) {
public function handle_newtable(Doku_Event $event)
{
global $INPUT;
global $TEXT;

if(!$INPUT->post->has('edittable__new')) return;
if (!$INPUT->post->has('edittable__new')) return;

/*
* $fields['pre'] has all data before the selection when the "Insert table" button was clicked
Expand All @@ -64,7 +64,7 @@ function handle_newtable($event) {


$event->data = act_clean($event->data);
switch($event->data){
switch ($event->data) {
case 'preview':
// preview view of a table edit
$INPUT->post->set('target', 'table');
Expand All @@ -73,7 +73,7 @@ function handle_newtable($event) {
// edit view of a table (first edit)
$INPUT->post->set('target', 'table');
$TEXT = "^ ^ ^\n";
foreach(explode("\n", $fields['text']) as $line) {
foreach (explode("\n", $fields['text']) as $line) {
$TEXT .= "| $line | |\n";
}
break;
Expand Down
Loading