1<?php 2/** 3 * DokuWiki Plugin SketchCanvas (Action Component) 4 * 5 * @license ??? 6 * @author Masahiro Sakuta 7 */ 8 9// must be run within Dokuwiki 10if (!defined('DOKU_INC')) die(); 11 12require_once("CanvasElement.php"); 13 14/** 15 * Add scripts via an event handler 16 */ 17class action_plugin_sketchcanvas extends DokuWiki_Action_Plugin { 18 19 /** 20 * Register handler for the TPL_METAHEADER_OUTPUT event 21 */ 22 public function register(Doku_Event_Handler $controller) { 23 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'metaheader'); 24 25 $controller->register_hook('HTML_SECEDIT_BUTTON', 'BEFORE', $this, 'editButton'); 26 $controller->register_hook('HTML_EDIT_FORMSELECTION', 'BEFORE', $this, 'editForm'); 27 // After Igor 28 $controller->register_hook('EDIT_FORM_ADDTEXTAREA', 'BEFORE', $this, 'editFormNew'); 29 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_newfigure'); 30 31 $controller->register_hook('TOOLBAR_DEFINE', 'AFTER', $this, 'toolbarDefine'); 32 } 33 34 /** 35 * Add <script> blocks to the headers 36 * 37 * Scripts are ought to be included via script.js on the plugin root directory, but 38 * it doesn't work if compress option (discarding whitespaces) is ative, so we have to 39 * include the necessary scripts individually in the header. 40 * 41 * @param Doku_Event $event 42 * @param $param 43 */ 44 public function metaheader(Doku_Event &$event, $param) { 45 $event->data['link'][] = array( 46 'type' => 'text/css', 47 "rel" => "stylesheet", 48 "href" => (is_ssl() ? "https" : "http") . "://fonts.googleapis.com/earlyaccess/notosansjapanese.css", 49 ); 50 $files = array('SketchCanvas.js', 'draw.js', /*'i18next-1.7.2.min.js', 'js-yaml.min.js',*/ 'translation.js'); 51 foreach($files as $file) 52 $event->data['script'][] = array( 53 'type' => 'text/javascript', 54 'charset' => 'utf-8', 55 'src' => DOKU_BASE . 'lib/plugins/' . $this->getPluginName() . '/script/' . $file, 56 '_data' => '', 57 ); 58 $event->data['script'][] = array( 59 'type' => 'text/javascript', 60 'charset' => 'utf-8', 61 '_data' => <<<EOT 62document.addEventListener('DOMContentLoaded', function(){ 63 var canvas; 64 for(var i = 1; (canvas = document.getElementById("__sketchcanvas" + i)); i++) { 65 var text = document.getElementById("__sketchcanvas_text" + i); 66 if(text) { 67 var skcanvas = new SketchCanvas(canvas); 68 skcanvas.loadData(text.innerHTML); 69 var form = document.forms['__sketchcanvas_form' + i]; 70 if(form){ 71 var input = document.createElement('input'); 72 input.type = 'hidden'; 73 input.name = "data"; 74 input.value = text.innerHTML; 75 form.appendChild(input); 76 } 77 } 78 } 79}); 80EOT 81 ); 82 } 83 84 public function editButton(Doku_Event $event, $param){ 85 if($event->data['target'] !== 'plugin_sketchcanvas') 86 return; 87 88 $event->data['name'] = /*$this->getLang*/('Edit Figure'); 89 } 90 91 public function editForm(Doku_Event $event, $param){ 92 global $TEXT; 93 if($event->data['target'] !== 'plugin_sketchcanvas') 94 return; 95 $event->preventDefault(); 96 97 $event->data['media_manager'] = false; 98 99 $escText = '"' . str_replace(array("\r", "\n"), array('\r', '\n'), addslashes($TEXT)) . '"'; 100 101 $form =& $event->data['form']; 102 $canvasText = <<<EOT 103<canvas id="editcanvas"></canvas> 104<script type="text/javascript"><!-- 105var skcanvas; 106document.addEventListener('DOMContentLoaded', function(){ 107 skcanvas = new SketchCanvas(document.getElementById('editcanvas'), {editmode: true}); 108 skcanvas.loadData($escText); 109 skcanvas.onUpdateData = function(data){ 110 var wikitext = document.getElementById('wiki__text'); 111 wikitext.value = data; 112 } 113}); 114--></script> 115<input type="button" value="Load data from text" onclick="skcanvas.loadData(document.getElementById('wiki__text').value)"> 116<textarea name="wikitext" id="wiki__text" class="edit" cols="80" rows="10">$TEXT</textarea> 117EOT; 118 $form->addElement($canvasText); 119 120 // Pass wikitext through POSTs for previewing and saving 121 if(isset($_POST['editfigure__new'])) { 122 foreach($_POST['editfigure__new'] as $k => $v) { 123 $form->addHidden("editfigure__new[$k]", $v); 124 } 125 } 126 } 127 128 /** 129 * An event handler for newer versions of DokuWiki, starting from Igor. 130 * 131 * @param Doku_Event $event 132 */ 133 public function editFormNew(Doku_Event $event, $param){ 134 global $TEXT; 135 if($event->data['target'] !== 'plugin_sketchcanvas') 136 return; 137 $event->preventDefault(); 138 139 $event->data['media_manager'] = false; 140 141 $form =& $event->data['form']; 142 $canvasElem = new CanvasElement(); 143 $canvasElem->val($TEXT); 144 $form->addElement($canvasElem); 145 146 // Pass wikitext through POSTs for previewing and saving 147 if(isset($_POST['editfigure__new'])) { 148 foreach($_POST['editfigure__new'] as $k => $v) { 149 $form->addHidden("editfigure__new[$k]", $v); 150 } 151 } 152 } 153 154 /** 155 * Add a toolbar button to add a new figure 156 * 157 * @param Doku_Event $event 158 */ 159 public function toolbarDefine(Doku_Event $event, $param){ 160 $event->data[] = array( 161 'type' => 'NewFigure', 162 'title' => 'New Figure', 163 'icon' => '../../plugins/' . $this->getPluginName() . '/images/figure.png', 164 'block' => true); 165 } 166 167 /** 168 * Handle the click on the new figure button in the toolbar 169 * 170 * @param Doku_Event $event 171 */ 172 function handle_newfigure($event) { 173 global $INPUT; 174 global $TEXT; 175 global $ACT; 176 177 if(!$INPUT->post->has('editfigure__new')) return; 178 179 /* 180 * $fields['pre'] has all data before the selection when the "Insert table" button was clicked 181 * $fields['text'] has all data inside the selection when the "Insert table" button was clicked 182 * $fields['suf'] has all data after the selection when the "Insert table" button was clicked 183 * $TEXT has the table created by the editor (from action_plugin_edittable_editor::handle_table_post()) 184 */ 185 $fields = $INPUT->post->arr('editfigure__new'); 186 187 // clean the fields (undos formText()) and update the post and request arrays 188 $fields['pre'] = cleanText($fields['pre']); 189 $fields['text'] = cleanText($fields['text']); 190 $fields['suf'] = cleanText($fields['suf']); 191 $INPUT->post->set('editfigure__new', $fields); 192 193 194 $ACT = act_clean($ACT); 195 switch($ACT){ 196 case 'preview': 197 // preview view of a table edit 198 $INPUT->post->set('target', 'plugin_sketchcanvas'); 199 break; 200 case 'edit': 201 // edit view of a table (first edit) 202 $INPUT->post->set('target', 'plugin_sketchcanvas'); 203 $TEXT = ""; 204 $lines = explode("\n", $fields['text']); 205 206 // Delete opening and closing <skcanvas> tags from the input because they're not part of 207 // the figure source and the tags will be added on the save button anyway 208 if(preg_match('/^<skcanvas.*?>/', $lines[0])) 209 array_shift($lines); 210 if(preg_match('/^<\/skcanvas>/', end($lines))) 211 array_pop($lines); 212 213 foreach($lines as $line) { 214 $TEXT .= "$line\n"; 215 } 216 break; 217 case 'draftdel': 218 // not sure if/how this would happen, we restore all data and hand over to section edit 219 $INPUT->post->set('target', 'section'); 220 $TEXT = $fields['pre'].$fields['text'].$fields['suf']; 221 $ACT = 'edit'; 222 break; 223 case 'save': 224 // return to edit page 225 $INPUT->post->set('target', 'section'); 226 $TEXT = $fields['pre']."<skcanvas>\n".$TEXT."</skcanvas>".$fields['suf']; 227 $ACT = 'edit'; 228 break; 229 } 230 } 231} 232