1<?php 2/** 3 * swfObject Plugin 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author i-net software <tools@inetsoftware.de> 7 * @author Gerry Weissbach <gweissbach@inetsoftware.de> 8 */ 9 10 11// must be run within Dokuwiki 12if(!defined('DOKU_INC')) die(); 13 14if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 15require_once(DOKU_PLUGIN.'syntax.php'); 16 17/** 18 * All DokuWiki plugins to extend the parser/rendering mechanism 19 * need to inherit from this class 20 */ 21class syntax_plugin_swfobject extends DokuWiki_Syntax_Plugin { 22 23 var $saveData = array(); 24 var $swfID = array(); 25 26 function getInfo(){ 27 return array( 28 'author' => 'i-net software', 29 'email' => 'tools@inetsoftware.de', 30 'date' => '2010-03-18', 31 'name' => 'swfObject', 32 'desc' => 'The Plugin wraps the SWFObject which can display an alternative if Flash is not present.', 33 ); 34 } 35 36 function getType(){ return 'protected';} 37 function getAllowedTypes() { return array('container','substition','protected','disabled','formatting','paragraphs'); } 38 function getPType(){ return 'block';} 39 40 function getSort(){ return 194; } 41 function connectTo($mode) { 42 $this->Lexer->addEntryPattern('<swfobject\s[^\r\n\|]*?>(?=.*?</swfobject.*?>)',$mode,'plugin_swfobject'); 43 } 44 45 function postConnect() { 46 $this->Lexer->addExitPattern('</swfobject.*?>', 'plugin_swfobject'); 47 } 48 49 /** 50 * Handle the match 51 */ 52 function handle($match, $state, $pos, &$handler){ 53 54 switch ($state) { 55 case DOKU_LEXER_ENTER: 56 if( preg_match('%<swfobject\s([^\r\n\|]*?)>%', $match, $matches) ) { 57 58 $conf = split('\?', $matches[1], 2); 59 60 $return = array( 'swffile' => $conf[0], 61 'width' => $this->getConf('width'), 62 'height' => $this->getConf('height'), 63 'minfla' => $this->getConf('minfla'), 64 'skiplinux' => $this->getConf('skiplinux'), 65 'autowidth' => $this->getConf('autowidth'), 66 'param' => array( 67 'play' => 'true', 68 'loop' => 'false', 69 'menu' => 'false', 70 'quality' => 'autohigh', 71 'scale' => 'default', 72 'salign' => '', 73 'wmode' => 'transparent', 74 'bgcolor' => '', 75 'base' => '', 76 'swliveconnect' => 'false', 77 'flashvars' => '', 78 'devicefont' => 'true', 79 'allowscriptaccess' => 'false', 80 'seamlesstabbing' => 'false', 81 'allowfullscreen' => 'false', 82 'allownetworking' => 'true' 83 ) 84 ); 85 86 $conf = explode('&', $conf[1]); 87 foreach ( $conf AS $keyValue ) { 88 list ($key, $value) = explode('=', $keyValue); 89 if (empty($key)) { continue; } 90 91 if ( substr($value, 0, 1) == ':' ) 92 $value = ml(cleanID($value)); 93 94 if ( in_array(strtolower($key), array_keys($return['param'])) ) { 95 $return['param'][strtolower($key)] = strtolower($value); 96 } else if ( in_array(strtolower($key), array_keys($return)) ) { 97 $return[strtolower($key)] = $value; 98 } else { 99 if ( !empty($return['param']['flashvars']) ) 100 $return['param']['flashvars'] .= '&'; 101 $return['param']['flashvars'] .= "$key=$value"; 102 } 103 } 104 105 return array('SWFOBJECT__ENTER', $return); 106 } 107 108 break; 109 110 case DOKU_LEXER_UNMATCHED: 111 return array('SWFOBJECT__UNMATCHED', $match); 112 break; 113 114 case DOKU_LEXER_EXIT: 115 return array('SWFOBJECT__EXIT', $match); 116 break; 117 } 118 return false; 119 } 120 121 /** 122 * Create output 123 */ 124 function render($mode, &$renderer, $inputData) { 125 global $conf; 126 127 if($mode == 'xhtml'){ 128 129 list( $state, $data) = $inputData; 130 switch ( $state ) { 131 case 'SWFOBJECT__ENTER' : 132 $this->saveData[] = $data; 133 //Alternative Content 134 $swfID = "SWFObject__Alternative" . rand(0, 1000000); 135 $this->swfID[] = $swfID; 136 137 $renderer->doc .= <<<OUTPUT 138 <div id="$swfID" class="swfobject alternate show"> 139 <!-- DEFAULT CONTENT --> 140OUTPUT; 141 return true; 142 break; 143 144 case 'SWFOBJECT__UNMATCHED' : 145 $renderer->doc .= $renderer->_xmlEntities($data); 146 147 return true; 148 break; 149 150 case 'SWFOBJECT__EXIT' : 151 152 $data = array_pop($this->saveData); 153 $swfID = array_pop($this->swfID); 154 155 $skipLinux = $data['skiplinux'] ? " && clientPC.indexOf('linux') == -1 ": ''; 156 157 $file = ml($data['swffile'], null, true, '&'); 158 159 $flashvars = ""; 160 $params = ""; 161 if ( is_array($data['param']) ) { 162 foreach( array_keys($data['param']) AS $paramKeys ) { 163 if ( empty( $paramKeys ) || empty($data['param'][$paramKeys]) ) { continue; } 164 if ( !empty($params) ) { $params.= ','; } 165 $params .= $paramKeys .':\''. $data['param'][$paramKeys] . '\''; 166 } 167 } 168 169 $attributes = "styleclass: 'swfobject'"; 170 $autoWidth = ''; 171 if ( $data['autowidth'] ) { 172 $autoWidth = "$('$swfID').style.width = \"100%\";"; 173 } 174 175 $DOKU_BASE = DOKU_BASE; 176 $XI = ( $this->getConf("useExpressInstall") ) ? "\"{$DOKU_BASE}lib/plugins/swfobject/expressinstall.swf\"" : "null"; 177 $JS = <<<JSOUTPUT 178 179 var counter$swfID = 10; 180 var addSWF$swfID = function () { 181 182 if ( counter$swfID <= 0 ) { if ( $('$swfID') ) $('$swfID').className += ' show'; return; } 183 if ( typeof addInitEvent == "undefined" ) { counter$swfID--; window.setTimeout("addSWF$swfID", 100); return; } 184 185 addInitEvent( function() { 186 if ( typeof swfobject != "undefined" $skipLinux) { 187 swfobject.embedSWF("$file", "$swfID", "{$data['width']}", "{$data['height']}", "{$data['minfla']}", $XI, { $flashvars }, { $params }, { $attributes }, null ); 188 $autoWidth 189 } else { 190 if ( $('$swfID') ) $('$swfID').className += ' show'; 191 } 192 }); 193 }; 194 195 if ( document.getElementById('$swfID') ) document.getElementById('$swfID').className = document.getElementById('$swfID').className.substr( 0, document.getElementById('$swfID').className.lastIndexOf("show")-1 ); 196 addSWF$swfID(); 197 198JSOUTPUT; 199 if ( $conf['compress'] ) $JS = $this->js_compress($JS); 200 $renderer->doc .= <<<OUTPUT 201 202 </div> 203 204 <script type="text/javascript">{$JS}</script> 205OUTPUT; 206 break; 207 return true; 208 } 209 } 210 return false; 211 } 212 213 /** 214 * Strip comments and whitespaces from given JavaScript Code 215 * 216 * This is a port of Nick Galbreath's python tool jsstrip.py which is 217 * released under BSD license. See link for original code. 218 * 219 * This was taken from the Core. 220 * 221 * @author Nick Galbreath <nickg@modp.com> 222 * @author Andreas Gohr <andi@splitbrain.org> 223 * @link http://code.google.com/p/jsstrip/ 224 */ 225 function js_compress($s){ 226 227 $s = ltrim($s); // strip all initial whitespace 228 $s .= "\n"; 229 $i = 0; // char index for input string 230 $j = 0; // char forward index for input string 231 $line = 0; // line number of file (close to it anyways) 232 $slen = strlen($s); // size of input string 233 $lch = ''; // last char added 234 $result = ''; // we store the final result here 235 236 // items that don't need spaces next to them 237 $chars = "^&|!+\-*\/%=\?:;,{}()<>% \t\n\r'\"[]"; 238 239 while($i < $slen){ 240 // skip all "boring" characters. This is either 241 // reserved word (e.g. "for", "else", "if") or a 242 // variable/object/method (e.g. "foo.color") 243 while ($i < $slen && (strpos($chars,$s[$i]) === false) ){ 244 $result .= $s{$i}; 245 $i = $i + 1; 246 } 247 248 $ch = $s{$i}; 249 // multiline comments (keeping IE conditionals) 250 if($ch == '/' && $s{$i+1} == '*' && $s{$i+2} != '@'){ 251 $endC = strpos($s,'*/',$i+2); 252 if($endC === false) trigger_error('Found invalid /*..*/ comment', E_USER_ERROR); 253 $i = $endC + 2; 254 continue; 255 } 256 257 // singleline 258 if($ch == '/' && $s{$i+1} == '/'){ 259 $endC = strpos($s,"\n",$i+2); 260 if($endC === false) trigger_error('Invalid comment', E_USER_ERROR); 261 $i = $endC; 262 continue; 263 } 264 265 // tricky. might be an RE 266 if($ch == '/'){ 267 // rewind, skip white space 268 $j = 1; 269 while($s{$i-$j} == ' '){ 270 $j = $j + 1; 271 } 272 if( ($s{$i-$j} == '=') || ($s{$i-$j} == '(') ){ 273 // yes, this is an re 274 // now move forward and find the end of it 275 $j = 1; 276 while($s{$i+$j} != '/'){ 277 while( ($s{$i+$j} != '\\') && ($s{$i+$j} != '/')){ 278 $j = $j + 1; 279 } 280 if($s{$i+$j} == '\\') $j = $j + 2; 281 } 282 $result .= substr($s,$i,$j+1); 283 $i = $i + $j + 1; 284 continue; 285 } 286 } 287 288 // double quote strings 289 if($ch == '"'){ 290 $j = 1; 291 while( $s{$i+$j} != '"' && ($i+$j < $slen)){ 292 if( $s{$i+$j} == '\\' && ($s{$i+$j+1} == '"' || $s{$i+$j+1} == '\\') ){ 293 $j += 2; 294 }else{ 295 $j += 1; 296 } 297 } 298 $result .= substr($s,$i,$j+1); 299 $i = $i + $j + 1; 300 continue; 301 } 302 303 // single quote strings 304 if($ch == "'"){ 305 $j = 1; 306 while( $s{$i+$j} != "'" && ($i+$j < $slen)){ 307 if( $s{$i+$j} == '\\' && ($s{$i+$j+1} == "'" || $s{$i+$j+1} == '\\') ){ 308 $j += 2; 309 }else{ 310 $j += 1; 311 } 312 } 313 $result .= substr($s,$i,$j+1); 314 $i = $i + $j + 1; 315 continue; 316 } 317 318 // whitespaces 319 if( $ch == ' ' || $ch == "\r" || $ch == "\n" || $ch == "\t" ){ 320 // leading spaces 321 if($i+1 < $slen && (strpos($chars,$s[$i+1]) !== false)){ 322 $i = $i + 1; 323 continue; 324 } 325 // trailing spaces 326 // if this ch is space AND the last char processed 327 // is special, then skip the space 328 $lch = substr($result,-1); 329 if($lch && (strpos($chars,$lch) !== false)){ 330 $i = $i + 1; 331 continue; 332 } 333 // else after all of this convert the "whitespace" to 334 // a single space. It will get appended below 335 $ch = ' '; 336 } 337 338 // other chars 339 $result .= $ch; 340 $i = $i + 1; 341 } 342 343 return trim($result); 344 } 345} 346 347//Setup VIM: ex: et ts=4 enc=utf-8 :