<?php if (!defined('PmWiki')) exit(); /* ****************************************************************************************** * * * Live Edit 2.2 - Edit parts/blocks/sections of a wiki page separately and from the * * wiki's view page without the need of going to the edit form. * * Copyright (C) Dec 16, 2011 Subhrajit Bhattacharya * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details <http://www.gnu.org/licenses/>. * * * * * * Contact: subhrajit@gmail.com, http://www.subhrajit.net/ * * * * * ****************************************************************************************** */ SDV($LiveEdit->isActive, true); // Set this to false in config.php to disable LiveEdit SDV($LiveEdit->DefaultEnabled, false); // Whether LiveEdit will be enabled when user logs in. SDV($LiveEdit->DefaultStyle, "Phantom_Backdrop"); SDV($LiveEdit->Markup_OpenBracket, "[:"); SDV($LiveEdit->Markup_CloseBracket, ":]"); SDV($LiveEdit->EmptyBlockContent, "Add new content here. Please change the name of the block as well."); SDV($LiveEdit->AutoDetectStyles['BorderColor'], "cccccc"); SDV($LiveEdit->AutoDetectStyles['BorderColorHover'], "4444aa"); SDV($LiveEdit->AutoDetectStyles['Opacity'], "99"); SDV($LiveEdit->AutoDetectStyles['TitleForeColor'], "ffffff"); SDV($LiveEdit->AutoDetectStyles['DisabledTitleForeColor'], "999999"); SDV($LiveEdit->AutoDetectStyles['TitleBackColor'], "666688"); SDV($LiveEdit->AutoDetectStyles['TitleOpacity'], "80"); SDV($LiveEdit->AutoDetectStyles['SelectedBorderColor'], "ff6666"); SDV($LiveEdit->AutoDetectStyles['SelectedOpacity'], "100"); SDV($LiveEdit->MenuStyle['BackgroundColor'], "888888"); SDV($LiveEdit->MenuStyle['Opacity'], "80"); SDV($LiveEdit->MenuStyle['MenuWidth'], "250"); SDV($LiveEdit->MenuStyle['MainButtonStyle'], "font-weight:bold;color:#ffffff; cursor:pointer; cursor:hand;"); SDV($LiveEdit->MenuStyle['MenuItemsStyle'], "display:block; color:#ffffff; padding:2px 15px 2px 0px; border-top: solid 2px #aaaaaa; text-decoration:none;"); SDV($LiveEdit->MenuStyle['ShowMenuTime'], "10"); SDV($LiveEdit->MenuStyle['HideMenuTime'], "15"); $LiveEdit->OptionsEncodeChars = array( array("\"" ,"&" ,"<" ,">" ,"%" ,"]" ,"\n" ,"\r" ), array("\quot/","\amp/","\lt/","\gt/","\perc/","\sqnd/","\\n/","\\r/" ) ); /* ========================================================================= */ // The LiveEdit menu $LiveEdit->MenuHTML = ""; $page = RetrieveAuthPage($pagename, 'edit', false, READPAGE_CURRENT); if (!(!$page || !$LiveEdit->isActive)) { global $LiveEdit; $LiveEdit->MenuHTML = "<div style='position:fixed;top:0px;right:0px; background-color:#".$LiveEdit->MenuStyle['BackgroundColor'].";padding:0px 3px; height:17px; opacity:0.".$LiveEdit->MenuStyle['Opacity']."; filter:alpha(opacity=".$LiveEdit->MenuStyle['Opacity'].")''> <script type=\"text/javascript\"> document.LiveEditMenuShow = false; function ShowLiveEditMenu () { var RightPos = parseInt(document.getElementById('LiveEditMenu').style.right); if (RightPos<-10 && document.LiveEditMenuShow) { document.getElementById('LiveEditMenu').style.right = (4+RightPos)+'px'; setTimeout('ShowLiveEditMenu();', ".$LiveEdit->MenuStyle['ShowMenuTime']."); } } function HideLiveEditMenu () { var RightPos = parseInt(document.getElementById('LiveEditMenu').style.right); if (RightPos>-".$LiveEdit->MenuStyle['MenuWidth']." && !document.LiveEditMenuShow) { document.getElementById('LiveEditMenu').style.right = (RightPos-4)+'px'; setTimeout('HideLiveEditMenu();', ".$LiveEdit->MenuStyle['HideMenuTime']."); } } </script> <div onmouseover=\"javascript: document.LiveEditMenuShow=true; ShowLiveEditMenu(); \" onmouseout=\"javascript: document.LiveEditMenuShow=false; HideLiveEditMenu();\"><span style='".$LiveEdit->MenuStyle['MainButtonStyle']."'>LiveEdit</span> <div id='LiveEditMenu' style='position:fixed;top:17px;right:-".$LiveEdit->MenuStyle['MenuWidth']."px; background-color:#".$LiveEdit->MenuStyle['BackgroundColor'].";padding:0; width:".($LiveEdit->MenuStyle['MenuWidth']-10)."px; text-align:right;'>"; if (!array_key_exists('LiveEdit', $_COOKIE)) $_COOKIE['LiveEdit'] = (($LiveEdit->DefaultEnabled)?"true":"false"); if ($_COOKIE['LiveEdit']=="true") { if ($_GET['action']!=="liveeditAutodetect") $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "<a href='?n=".$pagename."&action=liveeditAutodetect' style='".$LiveEdit->MenuStyle['MenuItemsStyle']."'>AutoDetect blocks in this page</a>"; else $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "<a href='?n=".$pagename."' style='".$LiveEdit->MenuStyle['MenuItemsStyle']."'>Exit AutoDetect mode</a>"; $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "<a href='?n=".$pagename."&LiveEdit=ShowStyle' style='".$LiveEdit->MenuStyle['MenuItemsStyle']."'>View available styles & parameters</a> <a href='?n=".$pagename."&LiveEdit=false' style='".$LiveEdit->MenuStyle['MenuItemsStyle']."'>Turn Off LiveEdit!</a>"; } else { $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "<a href='?n=".$pagename."&LiveEdit=true' style='".$LiveEdit->MenuStyle['MenuItemsStyle']."'>Turn On LiveEdit!</a>"; } $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "</div> </div> </div>"; SDV($HandleBrowseFmt, array(&$PageStartFmt, &$PageRedirectFmt, '$PageText', $LiveEdit->MenuHTML, &$PageEndFmt)); } else setcookie('LiveEdit', (($LiveEdit->DefaultEnabled)?"true":"false")); /* ========================================================================= */ /* This section adds an action called 'liveeditAutodetect' that helps in identifying and generating LiveEdit blocks automatically in a Wiki-page */ /* Each element of $LiveEdit->AutoDetectBrackets is an array with the following elements: 0 => Regular expression of the pattern defining the bracket 1 => Backreference index of the bracket body (the portion to start another recursive search. -1 for no resursive search) 2 => Backreference index of the bracket block (the one that is to be included inside the LiveEdit bracket) 3 => Backreference index of the blanket (the portion to be blanketed before starting next cycle) 4 => What kind of block: 'span' or 'div' 5 => Backreference index of pre-padding content (the relevant content that comes before bracket starts - for duplication: set -1 to skip) 6 => Backreference index of post-padding content (the relevant content that comes after bracket ends - for duplication: set -1 to skip) If the regular expression contains ^ or $, it needs to be separate from the main pattern and the pattern name should start with 'Last_' or 'First_' respectively. The order in which the patterns are defined matters. The first patterns are given more preference in case of conflicts. */ $LiveEdit->AutoDetectBrackets['TableCell'] = array( "/((\\(:(cell|head).*?:\\))(.*?))(\\n)\\(:(cell.*?|head.*?|tableend):\\)/es" , 4 , 4 , 1 , 'div', 2, 5); $LiveEdit->AutoDetectBrackets['MarkupBlock'] = array( "/\\(:([\w]+).*?:\\)(.*?)\\(:\\1\\s*?end:\\)/es" , 2 , 0 , 0 , 'div', -1, -1); $LiveEdit->AutoDetectBrackets['DivBlock'] = array( "/((\\n>>.+?<<)(.*?))(>>.*?<<|$)/es" , 3 , 3 , 1, 'div', 2, -1); $LiveEdit->AutoDetectBrackets['FormattingBlocks'] = array( "/\\[(=|@)(.*?)\\1\\]/es" , 2 , 0 , 0 , 'span', -1, -1); // markup inside $LiveEdit->AutoDetectBrackets['SingleLineMarkup'] = array( "/\\(:[\w]+.*?:\\)/e" , -1 , 0 , 0 , 'span', -1, -1); // markup inside $LiveEdit->AutoDetectBrackets['SimpleTableCell'] = array( "/(\\|\\|(.+?))(\\|\\|)/e" , 2 , 2 , 1 , 'span', -1, 3); $LiveEdit->AutoDetectBrackets['ListsAndIndents'] = array( "/\\n((\\*|\\*\\*|#|##|Q:|A:|->|-<|:[\w]+:)(.*?))(\\n|\\r)/es" , 3 , 3 , 1 , 'span', 2, 4); $LiveEdit->AutoDetectBrackets['SpanBlock'] = array( "/(^|[^%])((%[^\\n%]+?%)(.*?))(%.*?%|\\|\\||\\n|$)/es" , 4 , 4 , 2 , 'span', 3, -1); $LiveEdit->AutoDetectBrackets['Hyperlinks'] = array( "/\\[\\[([^<].*?)\\]\\]/e" , 1 , 0 , 0 , 'span', -1, -1); // markup inside $LiveEdit->AutoDetectBrackets['Heading'] = array( "/(\\n|^)(!+(.*))/e" , 3 , 2 , 2 , 'div', -1, -1); // markup inside $LiveEdit->AutoDetectBrackets['Paragraph'] = array( "/(\\n(\\n)(.*?))(\\n)\\n/es" , 3 , 3 , 1 , 'div', 2, 4); $LiveEdit->AutoDetectBrackets['Last_Paragraph'] = array( "/(\\n(\\n)(.*?))\\n?$/es" , 3 , 3 , 1 , 'div', 2, 2); // --------------------- $LiveEdit->BlanketChar = "\235"; $LiveEdit->BlockPadding = array( 'div'=>"\n" , 'span'=>"" ); $LiveEdit->BraPosEncode = "%09d-2-%09d-%09d"; $LiveEdit->KetPosEncode = "%09d-1-%09d-%09d"; $LiveEdit->BracketPosEncode = "%09d-%01d-%09d-%09d"; $LiveEdit->PaddingEncode = "%09d+%09d"; $LiveEdit->BracketsInfo = array(); function LiveEdit_findBrackets($WikiText, $StartOffset, $Level) { global $LiveEdit; $thisBraketInfos = array(); $BlanketedWikiText = $WikiText; foreach ($LiveEdit->AutoDetectBrackets as $k=>$v) { $thisRegex = $v[0]; $thisBodyBackref = $v[1]; $thisBlockBackref = $v[2]; $thisBlanketBackref = $v[3]; $thisBracketType = $v[4]; if (count($v)>5) { $thisPrepadBackref = $v[5]; $thisPostpadBackref = $v[6]; } if ($Level > 0 && ( (preg_match("/[^\\\\]\\$/es",$thisRegex)!==0 && substr($k,0,5)==="Last_") || (preg_match("/[^\\\\]\\^/es",$thisRegex)!==0 && substr($k,0,6)==="First_") ) ) continue; $found = true; while ($found) { $found = false; $matchCount = preg_match($thisRegex, $BlanketedWikiText, $match, PREG_OFFSET_CAPTURE ); if ($matchCount === 1) { $vv = $match; // Recursive capture inside this brackets if ($thisBodyBackref >= 0) LiveEdit_findBrackets($vv[$thisBodyBackref][0], $StartOffset+$vv[$thisBodyBackref][1], $Level+1); $BlanketLength = strlen($vv[$thisBlanketBackref][0]); $BlanketedWikiText = substr_replace($BlanketedWikiText, str_repeat($LiveEdit->BlanketChar, $BlanketLength), $vv[$thisBlanketBackref][1], $BlanketLength); $thisBracketInfo->start = $StartOffset + $vv[$thisBlockBackref][1]; $thisBracketInfo->end = $StartOffset + $vv[$thisBlockBackref][1] + strlen($vv[$thisBlockBackref][0]); $thisBracketInfo->blocktype = $thisBracketType; $thisBracketInfo->brackettype = $k; $thisBracketInfo->level = $Level; $thisBracketInfo->content = $vv[$thisBlockBackref][0]; if ($thisPrepadBackref>=0) $thisBracketInfo->prepad = array($StartOffset+$vv[$thisPrepadBackref][1], strlen($vv[$thisPrepadBackref][0])); else $thisBracketInfo->prepad = false; if ($thisPostpadBackref>=0) $thisBracketInfo->postpad = array($StartOffset+$vv[$thisPostpadBackref][1], strlen($vv[$thisPostpadBackref][0])); else $thisBracketInfo->postpad = false; $LiveEdit->BracketsInfo[] = clone $thisBracketInfo; $found = true; } } } } # add "?action=liveeditAutodetect" SDV($HandleActions['liveeditAutodetect'], 'HandleLiveeditAutodetect'); SDV($HandleAuth['liveeditAutodetect'], 'edit'); SDV($AuthCascade['liveeditAutodetect'], 'edit'); function HandleLiveeditAutodetect($pagename, $auth='edit') { global $LiveEdit, $WikiDir, $LastModFile; $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT); if (!$page || $_COOKIE['LiveEdit']=="false" || !$LiveEdit->isActive) { Abort("Cannot edit $pagename<br>Possible cause: You are not logged in as an authenticated user with edit permission, or you have LiveEdit turned off. Try passing &<b>LiveEdit=true</b>."); return; } LiveEdit_findBrackets($page['text'], 0, 0); $PageLength = strlen($page['text']); $BraKets = array(); foreach ($LiveEdit->BracketsInfo as $k=>$v) { $id = $k; $thisBracketInfo = $v; $thisBracketInfo->enabled = true; if ( preg_match("/^\\s*$/es", $v->content) !== 0 ) continue; elseif ( preg_match("/^\\s*\\Q".$LiveEdit->Markup_OpenBracket."\\E([\\w]*).*?\\Q".$LiveEdit->Markup_CloseBracket."\\E(.*?)\\Q".$LiveEdit->Markup_OpenBracket."\\E\\/\\1\\Q".$LiveEdit->Markup_CloseBracket."\\E\\s*$/es", $v->content) !== 0 ) $thisBracketInfo->enabled = false; else // test for pre-brackets - may be expensive, and may not be very useful { $matches = array(); if ($id==55) { echo substr($page['text'], 0, $thisBracketInfo->start)."------\n".substr($page['text'], $thisBracketInfo->end)."+++++\n"; if( preg_match( "/\\Q".$LiveEdit->Markup_OpenBracket."\\E([\\w]*)[^\\]]*?\\Q".$LiveEdit->Markup_CloseBracket."\\E\\s*$/es", substr($page['text'], 0, $thisBracketInfo->start), $matches ) !== 0 ) { echo("matched1 ".$matches[1]."----"); if( preg_match( "/^\\s*\\Q".$LiveEdit->Markup_OpenBracket."\\E\\/".$matches[1]."\\Q".$LiveEdit->Markup_CloseBracket."\\E/", substr($page['text'], $thisBracketInfo->end) ) !== 0 ) { echo("matched2----"); $thisBracketInfo->enabled = false; } } } } $thisBracketInfo->id = $id; $thisPadding = $LiveEdit->BlockPadding[$v->blocktype]; $thisBracketInfo->StartPosString = sprintf($LiveEdit->BraPosEncode, $v->start, $PageLength-$v->end, $id); $thisBracketInfo->EndPosString = sprintf($LiveEdit->KetPosEncode, $v->end, $PageLength-$v->start, $id); $thisBracketInfo->PrepadInfo = ($thisBracketInfo->prepad)?sprintf($LiveEdit->PaddingEncode, $thisBracketInfo->prepad[0], $thisBracketInfo->prepad[1]):""; $thisBracketInfo->PostpadInfo = ($thisBracketInfo->postpad)?sprintf($LiveEdit->PaddingEncode, $thisBracketInfo->postpad[0], $thisBracketInfo->postpad[1]):""; $BraKets[$thisBracketInfo->StartPosString] = $thisPadding.Keep(LiveEdit_GenerateBra($thisBracketInfo)).$thisPadding; $BraKets[$thisBracketInfo->EndPosString] = $thisPadding.Keep(LiveEdit_GenerateKet($thisBracketInfo)).$thisPadding; } ksort($BraKets); //echo(implode("\n",array_keys($BraKets))); $TheWikiText = ""; $startPos = 0; foreach ($BraKets as $k=>$v) { list($endPos, $dummy, $dummy, $dummy) = sscanf($k, $LiveEdit->BracketPosEncode); $TheWikiText = $TheWikiText . substr($page['text'], $startPos, $endPos-$startPos) . $BraKets[$k]; //echo ($k." (".$endPos."): ".MarkupToHTML($pagename, $BraKets[$k])."\n"); //echo (substr($page['text'], $startPos, $endPos-$startPos) . " [".$k."] "); $startPos = $endPos; } $TheWikiText = $TheWikiText . substr($page['text'], $startPos); $MainBracketInfo->id = 'main'; $MainBracketInfo->blocktype = 'div'; $MainBracketInfo->brackettype = 'FullPage'; $MainBracketInfo->enabled = true; if ( preg_match("/^\\s*\\Q".$LiveEdit->Markup_OpenBracket."\\E([\\w]*).*?\\Q".$LiveEdit->Markup_CloseBracket."\\E(.*?)\\Q".$LiveEdit->Markup_OpenBracket."\\E\\/\\1\\Q".$LiveEdit->Markup_CloseBracket."\\E\\s*$/es", $TheWikiText) ) $MainBracketInfo->enabled = false; $TheWikiText = "\n".Keep(LiveEdit_GenerateBra($MainBracketInfo))."\n" . $TheWikiText . "\n".Keep(LiveEdit_GenerateKet($MainBracketInfo))."\n"; //echo $TheWikiText; $TheWikiText = Keep("<form method=POST action=\"?n=".$pagename."&action=liveeditCreateblocks\" >"). $TheWikiText . Keep( "<input type='hidden' name='LiveEditPageHash' value='".md5($page['text'])."' />". "<input type='hidden' name='basetime' value='".time()."'>". "<input type='submit' value='Create Selected Blocks' />". "</form>"); $TheHTML = MarkupToHTML($pagename, $TheWikiText); global $HandleBrowseFmt, $PageStartFmt, $PageRedirectFmt, $PageEndFmt; $HandleBrowseFmt = array(&$PageStartFmt, &$PageRedirectFmt, $TheHTML, $LiveEdit->MenuHTML, &$PageEndFmt); PrintFmt($pagename,$HandleBrowseFmt); } function LiveEdit_GenerateBra($info) { global $LiveEdit; $tagName = $info->blocktype; $id = $info->id; $OutHTML = "<".$tagName." id=\"LiveEditAutoBlock_".$id."\" style='border: solid 1px #".$LiveEdit->AutoDetectStyles['BorderColor']."; margin:5px;padding:0; position:relative; opacity:0.".$LiveEdit->AutoDetectStyles['Opacity']."; filter:alpha(opacity=".$LiveEdit->AutoDetectStyles['Opacity'].")' ". " onmouseover = \"javascript: document.getElementById('LiveEditAutoBlockForm_".$id."').style.display = 'block'; if (!document.getElementById('LiveEditAutoBlockCheckbox_".$id."').checked) document.getElementById('LiveEditAutoBlock_".$id."').style.borderColor='#".$LiveEdit->AutoDetectStyles['BorderColorHover']."'; \" ". " onmouseout = \"javascript: document.getElementById('LiveEditAutoBlockForm_".$id."').style.display = 'none'; if (!document.getElementById('LiveEditAutoBlockCheckbox_".$id."').checked) document.getElementById('LiveEditAutoBlock_".$id."').style.borderColor='#".$LiveEdit->AutoDetectStyles['BorderColor']."'; \" ". ">". "<span id=\"LiveEditAutoBlockForm_".$id."\" style='width:20em; background-color:#".$LiveEdit->AutoDetectStyles['TitleBackColor']."; padding-right:0; margin:0;". " display:none; position:absolute; left:0; top:0; z-index:99997; opacity:0.".$LiveEdit->AutoDetectStyles['TitleOpacity']."; filter:alpha(opacity=".$LiveEdit->AutoDetectStyles['TitleOpacity'].")'>". "<input type='checkbox' id=\"LiveEditAutoBlockCheckbox_".$id."\" name='LiveEditAutoBlock[]' ". ($info->enabled?"":"checked disabled"). " value='".sprintf("%d,%d,%d,%s,%s,%s,%s,%s",$id,$info->start,$info->end,$info->StartPosString,$info->EndPosString,$info->blocktype,$info->PrepadInfo,$info->PostpadInfo)."'". " onClick=\"javascript: if (this.checked) ". " { document.getElementById('LiveEditAutoBlock_".$id."').style.borderColor='#".$LiveEdit->AutoDetectStyles['SelectedBorderColor']."'; ". " document.getElementById('LiveEditAutoBlock_".$id."').style.opacity=".$LiveEdit->AutoDetectStyles['SelectedOpacity']."/100; ". " document.getElementById('LiveEditAutoBlock_".$id."').style.filter='alpha(opacity=".$LiveEdit->AutoDetectStyles['SelectedOpacity'].")'; } ". " else { document.getElementById('LiveEditAutoBlock_".$id."').style.borderColor='#".$LiveEdit->AutoDetectStyles['BorderColor']."'; ". " document.getElementById('LiveEditAutoBlock_".$id."').style.opacity=".$LiveEdit->AutoDetectStyles['Opacity']."/100; ". " document.getElementById('LiveEditAutoBlock_".$id."').style.filter='alpha(opacity=".$LiveEdit->AutoDetectStyles['Opacity'].")'; } \" ". "/>". "<span style='color:#".($info->enabled?$LiveEdit->AutoDetectStyles['TitleForeColor']:$LiveEdit->AutoDetectStyles['DisabledTitleForeColor']).";'> Select (".$info->brackettype.")</span>". "</span>"; return $OutHTML; } function LiveEdit_GenerateKet($info) { $tagName = $info->blocktype; return "</".$tagName.">"; //."-".$info->id."-"; } // ---------------------------------------------- /* This section adds an action called 'liveeditCreateblocks' to processes the request submitted by liveeditAutodetect */ # add "?action=liveeditCreateblocks" SDV($HandleActions['liveeditCreateblocks'], 'HandleLiveeditCreateblocks'); SDV($HandleAuth['liveeditCreateblocks'], 'edit'); SDV($AuthCascade['liveeditCreateblocks'], 'edit'); function HandleLiveeditCreateblocks($pagename, $auth='edit') { global $LiveEdit, $SaveProperties, $EnablePost; $page = RetrieveAuthPage($pagename, $auth, true, 0); if (!$page || $_COOKIE['LiveEdit']=="false" || !$LiveEdit->isActive) { Abort("Cannot edit $pagename"); return; } if (md5($page['text']) !== $_POST['LiveEditPageHash']) { Abort("Edit conflict! The content of $pagename has been changed. Please try again!"); return; } $newpage = $page; if (!empty($_POST['LiveEditAutoBlock'])) { foreach ($_POST['LiveEditAutoBlock'] as $k=>$v) { $infos = explode(",",$v); $id = $infos[0]; $start = $infos[1]; $end = $infos[2]; $StartPosString = $infos[3]; $EndPosString = $infos[4]; $blocktype = $infos[5]; switch ($blocktype) { case "div": $optstr = " ".$LiveEdit->DefaultStyle; break; case "span": $optstr = " ".$LiveEdit->DefaultStyle."_Inline"; break; } $prepadinfo = $infos[6]; if (!empty($prepadinfo)) { $prepadsubstr = explode("+",$prepadinfo); $optstr .= " LEABprepad=\"" . LiveEditOptionValueEncode(substr($page['text'], intval($prepadsubstr[0]), intval($prepadsubstr[1])))."\""; } $postpadinfo = $infos[7]; if (!empty($postpadinfo)) { $postpadsubstr = explode("+",$postpadinfo); $optstr .= " LEABpostpad=\"" . LiveEditOptionValueEncode(substr($page['text'], intval($postpadsubstr[0]), intval($postpadsubstr[1])))."\""; } $blockname = "LEAB_".$k."_".$id."_".$start."_".$end; // LiveEdit Auto Block $inserts[$StartPosString] = $LiveEdit->Markup_OpenBracket.$blockname.$optstr.$LiveEdit->Markup_CloseBracket; $inserts[$EndPosString] = $LiveEdit->Markup_OpenBracket."/".$blockname.$LiveEdit->Markup_CloseBracket; } ksort($inserts); $TheWikiText = ""; $startPos = 0; foreach ($inserts as $k=>$v) { list($endPos, $dummy, $dummy, $dummy) = sscanf($k, $LiveEdit->BracketPosEncode); $TheWikiText = $TheWikiText . substr($page['text'], $startPos, $endPos-$startPos) . $inserts[$k]; $startPos = $endPos; } $TheWikiText = $TheWikiText . substr($page['text'], $startPos); $newpage['text'] = $TheWikiText; $newpage['csum'] = "Created LiveEdit block $blockname using Autodetect"; $newpage['action'] = "edit"; $newpage['n'] = $pagename; $newpage['time'] = time(); $newpage['basetime'] = $_POST['basetime']; $EnablePost = true; foreach((array)$SaveProperties as $k) SetProperty($pagename, $k, $page[$k]); PCache($pagename, $newpage); UpdatePage($pagename, $page, $newpage); } Redirect($pagename); exit; } /* ========================================================================= */ /* ========================================================================= */ /* This section adds an action called 'liveeditSave' and processes the submitted form */ # add "?action=liveeditSave" SDV($HandleActions['liveeditSave'], 'HandleLiveeditSave'); SDV($HandleAuth['liveeditSave'], 'edit'); SDV($AuthCascade['liveeditSave'], 'edit'); function HandleLiveeditSave($pagename, $auth='edit') { global $WikiDir, $LastModFile, $LiveEdit, $EnablePost, $SaveProperties; $page = RetrieveAuthPage($pagename, $auth, true, 0); if (!$page) { Abort("Cannot edit $pagename"); return; } $newpage = $page; $blockname = $_GET['liveeditBlock']; $newBlockName = $blockname; if ( !$_POST['cancel'] ) { // Extract the values from the mandetory (hidden) fields $OriginalFullBlockHash = rawurldecode($_POST['LiveEditOriginalHash_'.$blockname]); $OriginalStart = rawurldecode($_POST['LiveEditOriginalStart_'.$blockname]); $OriginalEnd = rawurldecode($_POST['LiveEditOriginalEnd_'.$blockname]); // Find/extract the content $startPos = strpos($page['text'], $OriginalStart); $startPosPos = $startPos+strlen($OriginalStart); $startPos2 = strpos($page['text'], $OriginalStart, $startPosPos); if ($startPos2 !== false) { Abort("!!! Cannot edit block <b>$blockname</b>. Possible cause: Multiple blocks with same name."); return; } $endPos = strpos($page['text'], $OriginalEnd, $startPosPos); $endPosPos = $endPos+strlen($OriginalEnd); $rawWikitext = substr($page['text'], $startPosPos, $endPos-$startPosPos); $OriginalFullBlock = substr($page['text'], $startPos, $endPosPos-$startPos); if ($OriginalFullBlockHash != md5($OriginalFullBlock) || @strpos( $page['text'], $OriginalFullBlock, strpos($page['text'],$OriginalFullBlock)+strlen($OriginalFullBlock) ) != false ) { Abort("!!! Cannot edit block <b>$blockname</b>. Possible cause: Ambiguous block."); return; } // Extract options if ( array_key_exists('LiveEditOptions_'.$blockname,$_POST) ) $optstr = $_POST['LiveEditOptions_'.$blockname]; else $optstr = ""; list($StyleName, $params) = ParseLiveEditOptionString($optstr); $newoptstr = $StyleName; foreach ($params as $pp=>$vv) $newoptstr .= " ".$pp."=\"".LiveEditOptionValueEncode($vv)."\""; // The changed wiki-text if ($_POST['LiveEdit_'.$blockname]) $ChangedWikiText = $_POST['LiveEdit_'.$blockname]; else $ChangedWikiText = $rawWikitext; // The changed start and end strings if ($_POST['remove'] || $_POST['delete']) { $ChangedStart = ""; $ChangedEnd = ""; if ($_POST['delete']) $ChangedWikiText = ""; } elseif (array_key_exists('LiveEditBlockName_'.$blockname,$_POST)) { $newBlockName = $_POST['LiveEditBlockName_'.$blockname]; $ChangedStart = $LiveEdit->Markup_OpenBracket . $newBlockName . " " . $newoptstr . $LiveEdit->Markup_CloseBracket; $ChangedEnd = $LiveEdit->Markup_OpenBracket."/".$newBlockName.$LiveEdit->Markup_CloseBracket; } else { $ChangedStart = $OriginalStart; $ChangedEnd = $OriginalEnd; } $ChangedFullBlock = $ChangedStart.$ChangedWikiText.$ChangedEnd; if ($_POST['addbefore'] || $_POST['addafter']) { $NewNewBlockname = $newBlockName . "_".time()."x".rand(1,999); $ChangedStartNew = $LiveEdit->Markup_OpenBracket . $NewNewBlockname . " " . $newoptstr . $LiveEdit->Markup_CloseBracket; $ChangedEndNew = $LiveEdit->Markup_OpenBracket."/".$NewNewBlockname.$LiveEdit->Markup_CloseBracket; $prepad = ""; if (array_key_exists('LEABprepad',$params)) $prepad = LiveEditOptionValueDecode($params['LEABprepad']); $postpad = ""; if (array_key_exists('LEABpostpad',$params)) $postpad = LiveEditOptionValueDecode($params['LEABpostpad']); if ($_POST['addbefore']) $ChangedFullBlock = $ChangedStartNew . $LiveEdit->EmptyBlockContent . $ChangedEndNew .$postpad.$prepad. $ChangedFullBlock; elseif ($_POST['addafter']) $ChangedFullBlock = $ChangedFullBlock .$postpad.$prepad. $ChangedStartNew . $LiveEdit->EmptyBlockContent . $ChangedEndNew; } if ($_POST['copybefore'] || $_POST['copyafter']) { $NewNewBlockname = $newBlockName . "_".time()."x".rand(1,999); $ChangedStartNew = $LiveEdit->Markup_OpenBracket . $NewNewBlockname . " " . $newoptstr . $LiveEdit->Markup_CloseBracket; $ChangedEndNew = $LiveEdit->Markup_OpenBracket."/".$NewNewBlockname.$LiveEdit->Markup_CloseBracket; $prepad = ""; if (array_key_exists('LEABprepad',$params)) $prepad = LiveEditOptionValueDecode($params['LEABprepad']); $postpad = ""; if (array_key_exists('LEABpostpad',$params)) $postpad = LiveEditOptionValueDecode($params['LEABpostpad']); if ($_POST['copybefore']) $ChangedFullBlock = $ChangedStartNew . $ChangedWikiText . $ChangedEndNew .$postpad.$prepad. $ChangedFullBlock; elseif ($_POST['copyafter']) $ChangedFullBlock = $ChangedFullBlock .$postpad.$prepad. $ChangedStartNew . $ChangedWikiText . $ChangedEndNew; } $newpage['text'] = str_replace($OriginalFullBlock, $ChangedFullBlock, $newpage['text']); $newpage['text'] = str_replace("\r", '', stripmagic($newpage['text'])); // This removes the unwanted \r added in textarea $newpage['csum'] = "Updated LiveEdit block $blockname"; $newpage['action'] = "edit"; $newpage['n'] = $pagename; $newpage['time'] = time(); $newpage['basetime'] = $_POST['basetime']; $EnablePost = true; foreach((array)$SaveProperties as $k) SetProperty($pagename, $k, $page[$k]); PCache($pagename, $newpage); UpdatePage($pagename, $page, $newpage); } Redirect($pagename."#".$newBlockName."_anchor"); exit; } /* ========================================================================= */ /* This section generates the main LiveEdit form, and corresponding HTML+Javascripts */ // Start of the markup: // [:BlockName:] ... // [:BlockName StyleName:] ... // [:BlockName StyleGroup.StylePage:] ... // [:... ... param1="..." param2="..." ...:] ... (NOTE: param value needs to be in double quote and cannot contain the characters '"' and ':]' ) // End of the markup: // ... [:/BlockName:] // [:BlockName:] ... [:/BlockName:] Markup('liveeditblock', '<_begin', "/(\\Q".$LiveEdit->Markup_OpenBracket."\\E([\\w]*)\\Q".$LiveEdit->Markup_CloseBracket."\\E)(.*?)(\\Q".$LiveEdit->Markup_OpenBracket."\\E\\/\\2\\Q".$LiveEdit->Markup_CloseBracket."\\E)/es", "GenerateLiveEditBlock(\$pagename,PSS('\$2'),PSS('\$3'),PSS(''),PSS('\$1'),PSS('\$4'))"); // [:BlockName options:] ... [:/BlockName:] Markup('liveeditblock2', '<_begin', "/(\\Q".$LiveEdit->Markup_OpenBracket."\\E([\\w]*)\\s+(.*?)\\Q".$LiveEdit->Markup_CloseBracket."\\E)(.*?)(\\Q".$LiveEdit->Markup_OpenBracket."\\E\\/\\2\\Q".$LiveEdit->Markup_CloseBracket."\\E)/es", "GenerateLiveEditBlock(\$pagename,PSS('\$2'),PSS('\$4'),PSS('\$3'),PSS('\$1'),PSS('\$5'))"); // Support for older version (TODO: remove this in future version) // [#-BlockName] ... [-#] Markup('liveeditblock_old', '<_begin', "/(\\[#-([\\w]*)\\])(.*?)(\\[-#\\])/es", "GenerateLiveEditBlock(\$pagename,PSS('\$2'),PSS('\$3'),PSS(''),PSS('\$1'),PSS('\$4'))"); // [#-BlockName options] ... [-#] Markup('liveeditblock_old2', '<_begin', "/(\\[#-([\\w]*)\\s+(.*?)\\])(.*?)(\\[-#\\])/es", "GenerateLiveEditBlock(\$pagename,PSS('\$2'),PSS('\$4'),PSS('\$3'),PSS('\$1'),PSS('\$5'))"); function ParseLiveEditOptionString($optstr) { // Get StyleName preg_match("/^([-\\w.]*)(\\s+[^=\\s]+|\\s*$)/", $optstr, $StyleNameMatch); if (!empty($StyleNameMatch)) $StyleName = $StyleNameMatch[1]; else $StyleName = $LiveEdit->DefaultStyle; // Get Parameters preg_match_all("/([\\w]+)\\s*=\\s*\"(.*?)\"/", $optstr, $ParamsMatch, PREG_SET_ORDER); $params = array(); foreach ($ParamsMatch as $ParamsJoint) $params[$ParamsJoint[1]] = LiveEditOptionValueDecode($ParamsJoint[2]); return array($StyleName, $params); } function GenerateLiveEditBlock($pagename, $blockname, $wikitext, $options, $start, $end) { global $LiveEdit; $page = RetrieveAuthPage($pagename, 'edit', false, READPAGE_CURRENT); if ( !$page || $_COOKIE['LiveEdit']=="false" || !$LiveEdit->isActive || $_GET['action']=="liveeditAutodetect" ) { PRR(); return $wikitext; } $retHTML = ""; $startPos = strpos($page['text'], $start); $startPosPos = $startPos+strlen($start); $startPos2 = strpos($page['text'], $start, $startPosPos); if ($startPos2 !== false) return $wikitext; $endPos = strpos($page['text'], $end, $startPosPos); $endPosPos = $endPos+strlen($end); $rawWikitext = substr($page['text'], $startPosPos, $endPos-$startPosPos); $rawBlockContent = substr($page['text'], $startPos, $endPosPos-$startPos); list($StyleName, $params) = ParseLiveEditOptionString($options); $HTMLarray = LiveEditHTMLfromTemplate($StyleName, $pagename, $blockname, $rawWikitext, $params, $options, md5($rawBlockContent), $start, $end); if (preg_match("/Inline$/es", $StyleName) || preg_match("/_inline$/esi", $StyleName)) $sep = ""; else $sep = "\n"; if (count($HTMLarray)==2) { PRR(); return $sep.Keep($HTMLarray[0]).$sep.$wikitext.$sep.Keep($HTMLarray[1]).$sep; } else return Keep($HTMLarray[0]); } /* ========================================================================= */ /* LiveEdit template functions */ $LiveEdit->TemplatePlaceholders["FormAction"] = "?n={\$pagename}&action=liveeditSave&liveeditBlock={\$blockname}"; $LiveEdit->TemplatePlaceholders["FormElements"] = "<span style=\"visibility:hidden; display:none; \">". "<input type='hidden' name='LiveEditOriginalHash_{\$blockname}' value=\"{\$LiveEdit->BlockHash}\">". "<input type='hidden' name='LiveEditOriginalStart_{\$blockname}' value=\"{\$LiveEdit->BlockStart}\">". "<input type='hidden' name='LiveEditOriginalEnd_{\$blockname}' value=\"{\$LiveEdit->BlockEnd}\">". "<input type='hidden' name='basetime' value='".time()."'>". "</span>"; $LiveEdit->TemplatePlaceholders["FormSaveButtonName"] = "save"; $LiveEdit->TemplatePlaceholders["FormCancelButtonName"] = "cancel"; $LiveEdit->TemplatePlaceholders["FormRemoveButtonName"] = "remove"; $LiveEdit->TemplatePlaceholders["FormDeleteButtonName"] = "delete"; $LiveEdit->TemplatePlaceholders["FormAddBeforeButtonName"] = "addbefore"; $LiveEdit->TemplatePlaceholders["FormAddAfterButtonName"] = "addafter"; $LiveEdit->TemplatePlaceholders["FormCopyBeforeButtonName"] = "copybefore"; $LiveEdit->TemplatePlaceholders["FormCopyAfterButtonName"] = "copyafter"; function LiveEditHTMLfromTemplate($StyleName, $pagename, $blockname, $wikitext, $inParams, $optionString, $FullBlockHash, $BlockStart, $BlockEnd) { global $LiveEdit; if (!empty($StyleName) && ($stylepage=RetrieveAuthPage($StyleName, 'read', false, READPAGE_CURRENT)) && !empty($stylepage['text'])) $HTML = $stylepage['text']; else $HTML = GetLiveEditStyleHTML($StyleName); // Substitute the paramater values (parameter values themselves can contain the standard placeholders) if (!empty($inParams)) // First substitute the input parameters foreach ($inParams as $k=>$v) $HTML = preg_replace("/{\\\$params:".$k."=?[^}]*?}/", $v, $HTML); $HTML = preg_replace("/{\\\$params:[\w]+=\\s*\"([^}\"]*?)\"\\s*}/", "\$1", $HTML); // Among the remaining, use default values // Substitute the mandetory placeholders foreach ($LiveEdit->TemplatePlaceholders as $k=>$v) { $HTML = str_replace("{\$LiveEdit->".$k."}", $v, $HTML, $count); if ($count==0) return array("<pre> <b>LiveEdit:</b> Error in template ".$StyleName. ": placeholder <b>{\$LiveEdit->".$k."}</b> not found.\n\n $HTML</pre>", ""); } // Substitute the standard variables $HTML = str_replace("{\$pagename}", $pagename, $HTML); $HTML = str_replace("{\$blockname}", $blockname, $HTML); // Form elements: Complete block content, start and end pos of wiki text $HTML = str_replace("{\$LiveEdit->BlockHash}", rawurlencode($FullBlockHash), $HTML); $HTML = str_replace("{\$LiveEdit->BlockStart}", rawurlencode($BlockStart), $HTML); $HTML = str_replace("{\$LiveEdit->BlockEnd}", rawurlencode($BlockEnd), $HTML); // Wiki text for displaying inside textarea // HTML text area does not display the first linebreak, if there is one. So fix that! $firstChar = substr($wikitext, 0, 1); if( $firstChar == "\n" || $firstChar == "\r" ) $wikitext = $firstChar.$wikitext; $HTML = str_replace("{\$LiveEdit->WikiTextExtract}", htmlspecialchars($wikitext), $HTML); $HTML = str_replace("{\$LiveEdit->OptionsString}", htmlspecialchars($optionString), $HTML); // Split at the DisplayTextPlaceholder $HTML = explode("{\$LiveEdit->DisplayTextPlaceholder}", $HTML); return $HTML; } /* ========================================================================= */ // TODO: Edit and add to the following /* ========================================================================= */ /* ------------------ LiveEdit templates and styles ------------------------ */ /* ========================================================================= */ /* Note: If you create your own template at Group.TemplatePage you will need to include the following placeholders Mandetory placeholders: {$LiveEdit->FormAction} {$LiveEdit->FormElements} {$LiveEdit->FormSaveButtonName} {$LiveEdit->FormCancelButtonName} {$LiveEdit->FormRemoveButtonName} {$LiveEdit->FormDeleteButtonName} {$LiveEdit->FormAddBeforeButtonName} {$LiveEdit->FormAddAfterButtonName} Optional Placeholders: {$LiveEdit->DisplayTextPlaceholder} {$LiveEdit->WikiTextExtract} {$LiveEdit->OptionsString} Optional variables: {$blockname} {$pagename} {$params:<ParamName>=<ParamDefaultValue>} Suggested parameters: {$params:DisplayType=<block|inline-block>} HTML items (all optional) {$blockname}_anchor Input field names (all optional): LiveEdit_{$blockname} LiveEditOptions_{$blockname} LiveEditBlockName_{$blockname} */ /* ========================================================================= */ // The sub-templates // Format: // $LiveEdit->SubTemplates['Groupname']['Templatename'] // Note: 'Templatename' must // i. be unique, even across different Groupnames, // ii. start with an upper-case letter, and rest be lower case // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // Form sub-templates $LiveEdit->SubTemplates['Form']['Popup'] = "<div class='LiveEdit-formdiv' id=\"{\$blockname}_divblock\" style=\"{\$params:FormDivStyle=\"border:solid 1px #888888; left:-1px; top:1.5em; background-color:#eeeeee; width:600px; margin:0px; padding:0px;\"} position:absolute; display:none; z-index:99998; \">". // Beginning of form "<form method=POST action=\"{\$LiveEdit->FormAction}\" onsubmit='return validateLiveEditForm(this);' >". "{\$LiveEdit->FormElements}". // Form title "<div class='LiveEdit-formtitle' style=\"{\$params:FormTitleStyle=\"margin:10px;\"}\">". // The close button "<a href='javascript:void(0);' style='display:inline; {\$params:FormCloseButtonStyle=\"background-color:#888888;border:solid 1px #222222;font-size:1.5em;font-weight:bold;padding:3px 5px;margin:2px;color:#880000;\"} float:right;' onclick=\"javascript: ". " document.getElementById('{\$blockname}_divblock').style.display = 'none'; " . " document.LiveEdit_FormOpened = false; " . " if (document.getElementById('{\$blockname}_editlink')) { document.getElementById('{\$blockname}_editlink').innerHTML = 'edit';} ". " \">X</a> ". // The heading "Editing block <input value=\"{\$blockname}\" style=\"{\$params:FormBlocknameInputStyle=\"border:solid 1px #888888;background-color:#eeeeee;font-weight:bold;\"}\" name='LiveEditBlockName_{\$blockname}' /> ". "</div>". // The options inputbox "<span style='margin-left:10px;margin-top:0px;'>options <a id='{\$blockname}_optionslink' href='javascript:void(0);' onclick=\"javascript: ". " if (document.getElementById('{\$blockname}_optionsblock').style.display == 'none') { " . " document.getElementById('{\$blockname}_optionsblock').style.display = 'block'; document.getElementById('{\$blockname}_optionsquickref').style.display = 'inline'; " . " document.getElementById('{\$blockname}_optionslink').innerHTML = '[ - ]'; " . " } else { " . " document.getElementById('{\$blockname}_optionsblock').style.display = 'none'; document.getElementById('{\$blockname}_optionsquickref').style.display = 'none'; " . " document.getElementById('{\$blockname}_optionslink').innerHTML = '[+]'; } ". "\" >[+]</a></span> <span id='{\$blockname}_optionsquickref' style='margin-left:10px;margin-top:0px;display:none;'>[ <a target='_blank' href='?LiveEdit=ShowStyle'>View available styles and parameters</a> ]</span>". "<div class='LiveEdit-optionsareadiv' id=\"{\$blockname}_optionsblock\" style=\"display:none; {\$params:FormOptionareaStyle=\"margin:10px;\"}\" ><textarea class='LiveEdit-optionsarea' name='LiveEditOptions_{\$blockname}' rows='2'>{\$LiveEdit->OptionsString}</textarea></div>". // The main textarea "<div class='LiveEdit-textareadiv' style=\"{\$params:FormTextareaStyle=\"margin:10px;\"}\"><textarea class='LiveEdit-textarea' name='LiveEdit_{\$blockname}' rows='{\$params:FormTextBoxRowCount=\"15\"} '>{\$LiveEdit->WikiTextExtract}</textarea></div>". // The buttons "<div class='LiveEdit-buttondiv' style=\"{\$params:FormButtonsStyle=\"margin:10px;\"}\">". "<input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormSaveButtonName}' value='Save this block'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormCancelButtonName}' value='Cancel'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormDeleteButtonName}' value='Delete block'>". " [<a href='?n=Site.EditQuickReference' target='_blank'>Quick Reference</a>]". "<hr style='height:1px;border:none;background-color:#666;margin:5px;'/>". "<table border=0 cellpadding=0 cellspacing=0><tr><td><span style='font-weight:bold;font-size:1.1em;'>Save and... </span></td><td>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormAddBeforeButtonName}' value='Add block before'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormAddAfterButtonName}' value='Add block after'><br/>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormCopyBeforeButtonName}' value='Copy block before'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormCopyAfterButtonName}' value='Copy block after'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormRemoveButtonName}' value='Remove block brackets'>". "</td></tr></table></div>". // End of form "</form></div>"; // ----------------------------------------------------------------- $LiveEdit->SubTemplates['Form']['Backdrop'] = "<center><div id=\"{\$blockname}_divblock\" style='position:fixed;z-index=99999;top:0;left:0;margin:0;padding:0; display:none;'>". // Start of form "<form method=POST action=\"{\$LiveEdit->FormAction}\" onsubmit='return validateLiveEditForm(this);'>". "{\$LiveEdit->FormElements}". // the backdrop "<div style='position:fixed; left:0px; top:0px; z-index:100000; width:80000px;height:80000px; {\$params:FormBackdropStyle=\"background-color:#444444; opacity:0.75; filter:'alpha(opacity=75)';\"}'></div>". // Form content and title "<div style='position:fixed; left:0px; top:0px; width:100%; height:100%;'>". "<div class='LiveEdit-formdiv' style=\"position:relative; {\$params:FormDivStyle=\"border:solid 1px #888888; background-color:#222222; width:600px; padding:10px;\"} margin-top:{\$params:FormTopSpace=\"100px\"}; margin-left:auto; margin-right:auto; z-index:100001;\">". "<div class='LiveEdit-formtitle' style=\"{\$params:FormTitleStyle=\"margin:10px; color:#ffffff;\"}\">". // The close button "<a href='javascript:void(0);' style='display:inline;position:absolute; {\$params:FormClosebuttonStyle=\"background-color:#bbbbbb;color:#aa0022;border:solid 2px #888888;font-size:1.5em;font-weight:bold;padding:1px 2px;margin:2px; left:25px;top:15px;\"}' onclick=\"javascript: ". " document.getElementById('{\$blockname}_divblock').style.display = 'none'; " . " setTimeout('document.LiveEdit_FormOpened = false;', 500); " . " if (document.getElementById('{\$blockname}_editlink')) { document.getElementById('{\$blockname}_editlink').innerHTML = 'edit';} ". " \">X</a> ". // The heading "Editing block <input value=\"{\$blockname}\" style=\"{\$params:FormBlocknameInputStyle=\"border:solid 1px #aaaaaa;background-color:#222222;font-weight:bold;color:#ffffff;\"}\" name='LiveEditBlockName_{\$blockname}' /> ". "</div>". // The main textarea "<div class='LiveEdit-textareadiv' style=\"{\$params:FormTextareaStyle=\"margin:10px;\"}\"><textarea class='LiveEdit-textarea' name='LiveEdit_{\$blockname}' rows='{\$params:FormTextBoxRowCount=\"15\"} ' style='background-color:#dddddd;'>{\$LiveEdit->WikiTextExtract}</textarea></div>". // The options textbox "<span style='margin-left:10px;margin-top:0px;color:#ffffff;position:relative;left:-260px;'>options <a id='{\$blockname}_optionslink' href='javascript:void(0);' onclick=\"javascript: ". " if (document.getElementById('{\$blockname}_optionsblock').style.display == 'none') { " . " document.getElementById('{\$blockname}_optionsblock').style.display = 'block'; document.getElementById('{\$blockname}_optionsquickref').style.display = 'inline'; " . " document.getElementById('{\$blockname}_optionslink').innerHTML = '[ - ]'; " . " } else { " . " document.getElementById('{\$blockname}_optionsblock').style.display = 'none'; document.getElementById('{\$blockname}_optionsquickref').style.display = 'none'; " . " document.getElementById('{\$blockname}_optionslink').innerHTML = '[+]'; } ". "\" >[+]</a> <span id='{\$blockname}_optionsquickref' style='margin-left:10px;margin-top:0px;display:none;position:absolute; left:70px;top:0px; white-space:nowrap;'>[ <a target='_blank' href='?LiveEdit=ShowStyle'>View available styles and parameters</a> ]</span></span>". "<div class='LiveEdit-optionsareadiv' id=\"{\$blockname}_optionsblock\" style=\"display:none; {\$params:FormOptionareaStyle=\"margin:10px;\"}\" ><textarea class='LiveEdit-optionsarea' name='LiveEditOptions_{\$blockname}' rows='2' style='{\$params:FormOptionsInputStyle=\"background-color:#dddddd;\"}'>{\$LiveEdit->OptionsString}</textarea></div>". // The buttons "<div class='LiveEdit-buttondiv' style=\"{\$params:FormButtonsStyle=\"margin:10px 40px;\"}\">". "<input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormSaveButtonName}' value='Save this block'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormCancelButtonName}' value='Cancel'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormDeleteButtonName}' value='Delete block'>". " <font color='#ffffff'>[<a href='?n=Site.EditQuickReference' target='_blank'>Quick Reference</a>]</font>". "<hr style='height:1px;border:none;background-color:#666;margin:5px;'/>". "<table border=0 cellpadding=0 cellspacing=0><tr><td><span style='font-weight:bold;color:#ffffff;font-size:1.1em;'>Save and... </span></td><td>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormAddBeforeButtonName}' value='Add block before'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormAddAfterButtonName}' value='Add block after'><br/>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormCopyBeforeButtonName}' value='Copy block before'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormCopyAfterButtonName}' value='Copy block after'>". " <input class='LiveEdit-button' type='submit' name='{\$LiveEdit->FormRemoveButtonName}' value='Remove block brackets'>". "</td></tr></table></div>". // End of form "</div></form></div></div></center>"; // For version compatibility: $LiveEdit->SubTemplates['Form']['CoolForm'] = $LiveEdit->SubTemplates['Form']['Backdrop']; // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // Form validation sub-template $LiveEdit->SubTemplates['ValidationJS']['Confirmdelete'] = "<script language='javascript' type='text/javascript'> function validateLiveEditForm(theform) { //alert('hello'); return true; } </script> "; // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // Display block type sub-templates $LiveEdit->SubTemplates['DisplayType']["Block"] = "block"; $LiveEdit->SubTemplates['DisplayType']["Inline"] = "inline-block"; // ----------------------------------------------------------------- // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // Shortcut menu sub-templates // ----------------------------------------------------------------- // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| /* ========================================================================= */ // The templates (these include the sub-templates) // The template names should be different from the names of the sub-templates // Template: standard $LiveEdit->Templates['Standard'] = // The main div block container "<div class='LiveEdit-border1' style=\"border:solid 1px #{\$params:BorderColors_0=\"cccccc\"}; margin:0px 5px; padding:0; display:{\$subtemplate:DisplayType=\"Block\"}; \" id=\"{\$blockname}_maindivblock\" >". "<script type=\"text/javascript\"> if (\"{\$subtemplate:DisplayType=\"Block\"}\" == \"inline-block\") { var node = document.getElementById('{\$blockname}_maindivblock').parentNode; for(var i=0;i<node.childNodes.length;i++) if (node.childNodes[i].id == '{\$blockname}_maindivblock' && i>0) node.childNodes[i-1].style.display = 'inline-block'; } </script>". "<div class='LiveEdit-border2' style=\"border:solid 1px #{\$params:BorderColors_1=\"888888\"}; margin:0; padding:0; position:relative; \">". // The top bar "<div class='LiveEdit-topbar' style=\"{\$params:TopBarStyle=\"height:1.5em; width: 100%; background-color:#cccccc;\"}\"> <a name=\"{\$blockname}_anchor\"></a>". " [<a class='LiveEdit-link' id=\"{\$blockname}_editlink\" href=\"javascript:void(0);\" onclick=\"javascript: ". // Javascript to show-hide the form " if (document.getElementById('{\$blockname}_divblock').style.display == 'none' && !document.LiveEdit_FormOpened) { " . " document.LiveEdit_FormOpened = true; ". " document.getElementById('{\$blockname}_divblock').style.display = 'block'; " . " document.getElementById('{\$blockname}_editlink').innerHTML = 'close'; " . " } else { " . " document.LiveEdit_FormOpened = false; ". " document.getElementById('{\$blockname}_divblock').style.display = 'none'; " . " document.getElementById('{\$blockname}_editlink').innerHTML = 'edit'; } ". " \">edit</a>] ". " </div> ". // The edit form "{\$subtemplate:ValidationJS=\"Confirmdelete\"}". "{\$subtemplate:Form=\"Popup\"}". // The Wiki text to be displayed here "<div style=\"margin:5px;\">". "{\$LiveEdit->DisplayTextPlaceholder}". // End of the block "</div></div></div>"; // ----------------------------------------------------------------- // Template: phantom $LiveEdit->Templates['Phantom'] = // The main div block container "<div class='LiveEdit-border1' style=\"display:{\$subtemplate:DisplayType=\"Block\"}; border:solid 1px #{\$params:BorderColors=\"cccccc\"}; margin:0px 5px; padding:0; position:relative; \" id=\"{\$blockname}_maindivblock\" >". "<script type=\"text/javascript\"> if (\"{\$subtemplate:DisplayType=\"Block\"}\" == \"inline-block\") { var node = document.getElementById('{\$blockname}_maindivblock').parentNode; for(var i=0;i<node.childNodes.length;i++) if (node.childNodes[i].id == '{\$blockname}_maindivblock' && i>0) node.childNodes[i-1].style.display = 'inline-block'; } </script>". "<a name=\"{\$blockname}_anchor\" style=\"margin:0;padding:0;\"></a>". // The edit form "{\$subtemplate:ValidationJS=\"Confirmdelete\"}". "{\$subtemplate:Form=\"Backdrop\"}". // The Wiki text to be displayed here "<div class='LiveEdit-linkphantom' id=\"{\$blockname}_editlinkbox\" href=\"javascript:void(0);\" ". " onclick=\"javascript: if(!document.LiveEdit_FormOpened) { document.getElementById('{\$blockname}_divblock').style.display = 'block'; document.LiveEdit_FormOpened = true; } this.style.opacity='1.0'; this.style.filter='alpha(opacity=100)'; \" " . " style=\"{\$params:PhantomStyle=\"margin:0; padding:0; cursor:pointer; cursor:hand;\"}\" ". " onmouseover=\"if(!document.LiveEdit_FormOpened) { {\$params:PhantomMouseOver=\"this.style.opacity='0.4'; this.style.filter='alpha(opacity=40)';\"} }\" ". " onmouseout=\"{\$params:PhantomMouseOut=\"this.style.opacity='1.0'; this.style.filter='alpha(opacity=100)';\"}\">". "{\$LiveEdit->DisplayTextPlaceholder}". // End of the block "</div></div>"; /* ========================================================================= */ /* ========================================================================= */ // Styles (derived from templates) // ------------------------------------------------------------------------- // function GetLiveEditStyleHTML($stylename) { global $LiveEdit; // Choose template if ( !($templatename = IsArrayitemInString( array_keys($LiveEdit->Templates), $stylename) ) ) $templatename = IsArrayitemInString( array_keys($LiveEdit->Templates), $LiveEdit->DefaultStyle); $TheHTML = $LiveEdit->Templates[ $templatename ]; // Replace sub-templates $ct = 0; $count = 1; while ($ct++<100 && $count>0) $TheHTML = preg_replace("/{\\\$subtemplate:([\w]+)=\\s*\"([^}\"]*?)\"\\s*}/es", "GetLiveEditSubtemplateHTML('\$1', '".$stylename."', '\$2')", $TheHTML, -1 , $count); return($TheHTML); } function IsArrayitemInString($arrk, $str, $falsereturn=null) { // Checks if any of items of $arr is in the $str - case sensitive (unless preceded by "_") foreach ($arrk as $k) if ( preg_match("/".$k."/", $str) || preg_match("/_".$k."/i", $str) ) return($k); return($falsereturn); } function GetLiveEditSubtemplateHTML($groupname, $stylename, $defaultsubtemplate) { global $LiveEdit; return ( $LiveEdit->SubTemplates[$groupname][ IsArrayitemInString(array_keys($LiveEdit->SubTemplates[$groupname]), $stylename, $defaultsubtemplate) ] ); } // -------------- // Listing styles // Items not to list $LiveEdit->StyleNoDisplay = array(); $LiveEdit->StyleNoDisplay['Form']['CoolForm'] = true; $LiveEdit->StyleNoDisplay['ValidationJS'] = true; function GetLiveEditAllStyles ($styles=null, $subtemplategroupct=0) { global $LiveEdit; if (!$styles) $styles = array_keys($LiveEdit->Templates); if ( $subtemplategroupct >= count($LiveEdit->SubTemplates) ) return($styles); $allgroups = array_keys( $LiveEdit->SubTemplates ); $thisgroup = $allgroups[$subtemplategroupct]; if ( isset($LiveEdit->StyleNoDisplay[$thisgroup]) && $LiveEdit->StyleNoDisplay[$thisgroup]===true ) return( GetLiveEditAllStyles( $styles, ++$subtemplategroupct) ); $nextstyles = array(); foreach( $styles as $s ) foreach ( array_keys($LiveEdit->SubTemplates[$thisgroup]) as $ss ) if( !isset($LiveEdit->StyleNoDisplay[$thisgroup][$ss]) ) $nextstyles[] = $s."_".$ss; return( GetLiveEditAllStyles($nextstyles, ++$subtemplategroupct) ); } /* ========================================================================= */ /* ========================================================================= */ /* Enable/Disable LiveEdit view + View LiveEdit Styles */ // LiveEdit=true|false|toggle // LiveEdit=ShowStyle:StyleName|StyleGroup.StylePage if ($_GET['LiveEdit']) { $page = RetrieveAuthPage($pagename, 'edit', true, READPAGE_CURRENT); if (!$page) { setcookie('LiveEdit', "false"); Redirect($pagename); } if ($_GET['LiveEdit']=="toggle") { if ($_COOKIE['LiveEdit']=="true") setcookie('LiveEdit', "false"); else setcookie('LiveEdit', "true"); Redirect($pagename); exit; } if ($_GET['LiveEdit']=="true" || $_GET['LiveEdit']=="false") { setcookie('LiveEdit', $_GET['LiveEdit']); Redirect($pagename); exit; } if ($_GET['LiveEdit']==="ShowStyle") { global $LiveEdit; $HTML = "<html>". "<style type='text/css' media='all'> table { border:solid 1px #888; } td { border:solid 1px #aaa; padding: 4px; margin: 0; } </style>". "<body style='margin:10px 40px; font-family: courier, courier new, monospace;'>"; $HTML .= "An option string can have one of the folling formats: <ul> <li><b>Style_Name</b></li> <li><b>StyleGroup.StylePage</b></li> <li><b>Style_Name ParamName1=\"ParamValue1\" ParamName2=\"ParamValue2\" . . . </b></li> <li><b>StyleGroup.StylePage ParamName1=\"ParamValue1\" ParamName2=\"ParamValue2\" . . . </b></li> </ul>". "Use the following character encodings for the contents of <b>ParamValue</b><i>n</i>". "<table border=0 cellspacing=0><tr><td><b>character</b></td><td><b>encoding</b></td></tr>"; for ($a=0; $a<count($LiveEdit->OptionsEncodeChars[0]); $a++) $HTML .= "<tr><td>". str_replace(array("\n","\r"),array("<i>newline</i>","<i>carriage return</i>"),htmlspecialchars($LiveEdit->OptionsEncodeChars[0][$a])). "</td><td>".htmlspecialchars($LiveEdit->OptionsEncodeChars[1][$a])."</td></tr>"; $HTML .= "</table> <br />Click one of the available <b>Style_Name</b> to view its parameters and their default values</b><br /><br /><b>"; foreach ( GetLiveEditAllStyles() as $s) { if ($s==$LiveEdit->DefaultStyle) $HTML .= "[ <a href='?n=".$pagename."&LiveEdit=ShowStyle:".$s."'>".$s."</a> ] (default)<br />"; else $HTML .= "[ <a href='?n=".$pagename."&LiveEdit=ShowStyle:".$s."'>".$s."</a> ]<br />"; } $HTML .= "</b><br />Or, type in the <b>StyleGroup.StylePage</b>: <br /> <input type='text' id='StyleNameBox' style='margin-top:10px;'/> <input type='button' onclick=\"window.location='?n=".$pagename."&LiveEdit=ShowStyle:'+getElementById('StyleNameBox').value;\" value='Submit' style='margin-top:10px;' /><br /> <br /> "; $HTML .= "<hr><input type='button' onclick=\"window.location='?n=".$pagename."';\" value='Exit!' style='width:150px;font-weight:bold;font-size:1.2em;'>"; $HTML .= "</body></html>"; print($HTML); exit; } if (preg_match("/^ShowStyle:(.*)/e",$_GET['LiveEdit'],$match)===1) { global $LiveEdit; $StyleName = $match[1]; if (!empty($StyleName) && ($stylepage=RetrieveAuthPage($StyleName, 'read', false, READPAGE_CURRENT)) && !empty($stylepage['text'])) $HTML = $stylepage['text']; else $HTML = GetLiveEditStyleHTML($StyleName); if (!empty($paramsST)) foreach ($paramsST as $k=>$v) $HTML = str_replace("{\$paramsST:".$k."}", $v, $HTML); $HTML = preg_replace("/[\\n\\r]+/", "", $HTML); $HTML = preg_replace("/[\\t\\s]+/", " ", $HTML); $newLineTags = "div|p|script|span|form|textarea"; $HTML = preg_replace("/[\\s]*(<\\/?(".$newLineTags.")*\\b[^>]*>)/i", "\n\\1", $HTML, -1, $count); $HTMLarray = explode("\n", $HTML); $HTMLfinal = "<html><body style='margin:10px 20px;'> Below is the code for style <b>".$StyleName."</b>. Parameters are displayed in the format <b><pre> <span style='background-color:#ccccff; color:#0000ff;'>ParamName</span>=\"<font color='#0000ff'>ParamDefaultValue</font>\"</pre></b> <table border=0 cellpadding=2>"; $rowbgcolors = array ("ffeeee", "eeeeff"); $tabdepth = 0; foreach ($HTMLarray as $l=>$line) { if (empty($line)) continue; if (preg_match("/^<\\/(".$newLineTags.").*/i",$line) === 1) { $tabdepth--; } $HTMLfinal = $HTMLfinal . "<tr style='background-color:#".$rowbgcolors[$l%2].";'>". "<td valign='top' style='width:50px;'><font size=1 color='#cccccc'>".str_repeat(" ",2*$tabdepth)."</font></td>". "<td valign='top' style='padding-left:". (20*$tabdepth) ."px'>" . str_repeat(" ",0*$tabdepth) . "<font face='Courier, Courier New, Monospace' size=1>" . htmlspecialchars($line) . "</font></td></tr>\n"; if (preg_match("/^<(".$newLineTags.").*/i",$line) === 1) { $tabdepth++; } } $HTMLfinal = $HTMLfinal . "</table>"; $HTMLfinal = $HTMLfinal . "<hr><input type='button' onclick=\"window.location='?n=".$pagename. "';\" value='Exit!' style='width:150px;font-weight:bold;font-size:1.2em;'>". "</body></html>"; $HTMLfinal = preg_replace("/{\\\$(.*?)}/", "<b>{\$\\1}</b>",$HTMLfinal); $HTMLfinal = preg_replace("/{\\\$LiveEdit->(.*?)}/", "{<font color='#880000'>\$LiveEdit-></font>\\1}",$HTMLfinal); $HTMLfinal = preg_replace("/{\\\$params:([\w]*)="(.*?)"}/", "{<font color='#ff0000'>\$params:</font><span style='background-color:#ccccff; color:#0000ff;'>\\1</span>=\"<font color='#0000ff'>\\2</font>\"}",$HTMLfinal); print($HTMLfinal); exit; } Redirect($pagename); exit; } // ============================================== // helper functions function LiveEditOptionValueEncode($str) { global $LiveEdit; $out = str_replace($LiveEdit->OptionsEncodeChars[0], $LiveEdit->OptionsEncodeChars[1], $str); return( $out ); } function LiveEditOptionValueDecode($str) { global $LiveEdit; $out = str_replace($LiveEdit->OptionsEncodeChars[1], $LiveEdit->OptionsEncodeChars[0], $str); return( $out ); } ?>