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 $event->data['script'][] = array( 51 'type' => 'text/javascript', 52 'charset' => 'utf-8', 53 'src' => DOKU_BASE . 'lib/plugins/' . $this->getPluginName() . '/bundle/SketchCanvas.js', 54 '_data' => '', 55 ); 56 $files = array('draw.js', /*'i18next-1.7.2.min.js', 'js-yaml.min.js',*/ ); 57 foreach($files as $file) 58 $event->data['script'][] = array( 59 'type' => 'text/javascript', 60 'charset' => 'utf-8', 61 'src' => DOKU_BASE . 'lib/plugins/' . $this->getPluginName() . '/script/' . $file, 62 '_data' => '', 63 ); 64 $event->data['script'][] = array( 65 'type' => 'text/javascript', 66 'charset' => 'utf-8', 67 '_data' => <<<EOT 68document.addEventListener('DOMContentLoaded', function(){ 69 var canvas; 70 for(var i = 1; (canvas = document.getElementById("__sketchcanvas" + i)); i++) { 71 var text = document.getElementById("__sketchcanvas_text" + i); 72 if(text) { 73 var skcanvas = new SketchCanvas.SketchCanvas(canvas); 74 skcanvas.loadData(text.innerHTML); 75 var form = document.forms['__sketchcanvas_form' + i]; 76 if(form){ 77 var input = document.createElement('input'); 78 input.type = 'hidden'; 79 input.name = "data"; 80 input.value = text.innerHTML; 81 form.appendChild(input); 82 } 83 } 84 } 85}); 86EOT 87 ); 88 } 89 90 public function editButton(Doku_Event $event, $param){ 91 if($event->data['target'] !== 'plugin_sketchcanvas') 92 return; 93 94 $event->data['name'] = /*$this->getLang*/('Edit Figure'); 95 } 96 97 public function editForm(Doku_Event $event, $param){ 98 global $TEXT; 99 if($event->data['target'] !== 'plugin_sketchcanvas') 100 return; 101 $event->preventDefault(); 102 103 $event->data['media_manager'] = false; 104 105 $escText = '"' . str_replace(array("\r", "\n"), array('\r', '\n'), addslashes($TEXT)) . '"'; 106 107 $form =& $event->data['form']; 108 $canvasText = <<<EOT 109<canvas id="editcanvas"></canvas> 110<script type="text/javascript"><!-- 111var skcanvas; 112document.addEventListener('DOMContentLoaded', function(){ 113 skcanvas = new SketchCanvas.SketchCanvas(document.getElementById('editcanvas'), {editmode: true}); 114 skcanvas.loadData($escText); 115 skcanvas.onUpdateData = function(data){ 116 var wikitext = document.getElementById('wiki__text'); 117 wikitext.value = data; 118 } 119}); 120--></script> 121<input type="button" value="Load data from text" onclick="skcanvas.loadData(document.getElementById('wiki__text').value)"> 122<textarea name="wikitext" id="wiki__text" class="edit" cols="80" rows="10">$TEXT</textarea> 123EOT; 124 $form->addElement($canvasText); 125 126 // Pass wikitext through POSTs for previewing and saving 127 if(isset($_POST['editfigure__new'])) { 128 foreach($_POST['editfigure__new'] as $k => $v) { 129 $form->addHidden("editfigure__new[$k]", $v); 130 } 131 } 132 } 133 134 /** 135 * An event handler for newer versions of DokuWiki, starting from Igor. 136 * 137 * @param Doku_Event $event 138 */ 139 public function editFormNew(Doku_Event $event, $param){ 140 global $TEXT; 141 if($event->data['target'] !== 'plugin_sketchcanvas') 142 return; 143 $event->preventDefault(); 144 145 $event->data['media_manager'] = false; 146 147 $form =& $event->data['form']; 148 $canvasElem = new CanvasElement(); 149 $canvasElem->val($TEXT); 150 $form->addElement($canvasElem); 151 152 // Pass wikitext through POSTs for previewing and saving 153 if(isset($_POST['editfigure__new'])) { 154 foreach($_POST['editfigure__new'] as $k => $v) { 155 $form->setHiddenField("editfigure__new[$k]", $v); 156 } 157 } 158 } 159 160 /** 161 * Add a toolbar button to add a new figure 162 * 163 * @param Doku_Event $event 164 */ 165 public function toolbarDefine(Doku_Event $event, $param){ 166 $event->data[] = array( 167 'type' => 'NewFigure', 168 'title' => 'New Figure', 169 'icon' => '../../plugins/' . $this->getPluginName() . '/images/figure.png', 170 'block' => true); 171 } 172 173 /** 174 * Handle the click on the new figure button in the toolbar 175 * 176 * @param Doku_Event $event 177 */ 178 function handle_newfigure($event) { 179 global $INPUT; 180 global $TEXT; 181 global $ACT; 182 183 if(!$INPUT->post->has('editfigure__new')) return; 184 185 /* 186 * $fields['pre'] has all data before the selection when the "Insert table" button was clicked 187 * $fields['text'] has all data inside the selection when the "Insert table" button was clicked 188 * $fields['suf'] has all data after the selection when the "Insert table" button was clicked 189 * $TEXT has the table created by the editor (from action_plugin_edittable_editor::handle_table_post()) 190 */ 191 $fields = $INPUT->post->arr('editfigure__new'); 192 193 // clean the fields (undos formText()) and update the post and request arrays 194 $fields['pre'] = cleanText($fields['pre']); 195 $fields['text'] = cleanText($fields['text']); 196 $fields['suf'] = cleanText($fields['suf']); 197 $INPUT->post->set('editfigure__new', $fields); 198 199 200 $ACT = act_clean($ACT); 201 switch($ACT){ 202 case 'preview': 203 // preview view of a table edit 204 $INPUT->post->set('target', 'plugin_sketchcanvas'); 205 break; 206 case 'edit': 207 // edit view of a table (first edit) 208 $INPUT->post->set('target', 'plugin_sketchcanvas'); 209 $TEXT = ""; 210 $lines = explode("\n", $fields['text']); 211 212 // Delete opening and closing <skcanvas> tags from the input because they're not part of 213 // the figure source and the tags will be added on the save button anyway 214 if(preg_match('/^<skcanvas.*?>/', $lines[0])) 215 array_shift($lines); 216 if(preg_match('/^<\/skcanvas>/', end($lines))) 217 array_pop($lines); 218 219 foreach($lines as $line) { 220 $TEXT .= "$line\n"; 221 } 222 break; 223 case 'draftdel': 224 // not sure if/how this would happen, we restore all data and hand over to section edit 225 $INPUT->post->set('target', 'section'); 226 $TEXT = $fields['pre'].$fields['text'].$fields['suf']; 227 $INPUT->post->set('wikitext', $TEXT); 228 $event->data = 'edit'; 229 break; 230 case 'save': 231 // return to edit page 232 $INPUT->post->set('target', 'section'); 233 $TEXT = $fields['pre']."<skcanvas>\n".$TEXT."</skcanvas>".$fields['suf']; 234 $INPUT->post->set('wikitext', $TEXT); 235 $ACT = 'edit'; 236 break; 237 } 238 } 239} 240