. * * * * * * 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 = "
MenuStyle['Opacity']."; filter:alpha(opacity=".$LiveEdit->MenuStyle['Opacity'].")''>
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 . "AutoDetect blocks in this page"; else $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "Exit AutoDetect mode"; $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "View available styles & parameters Turn Off LiveEdit!"; } else { $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "Turn On LiveEdit!"; } $LiveEdit->MenuHTML = $LiveEdit->MenuHTML . "
"; 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
Possible cause: You are not logged in as an authenticated user with edit permission, or you have LiveEdit turned off. Try passing &LiveEdit=true."); 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("
"). $TheWikiText . Keep( "". "". "". "
"); $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']."'; \" ". ">". "AutoDetectStyles['TitleOpacity']."; filter:alpha(opacity=".$LiveEdit->AutoDetectStyles['TitleOpacity'].")'>". "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'].")'; } \" ". "/>". "AutoDetectStyles['DisabledTitleForeColor']).";'> Select (".$info->brackettype.")". ""; return $OutHTML; } function LiveEdit_GenerateKet($info) { $tagName = $info->blocktype; return ""; //."-".$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 $blockname. 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 $blockname. 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"] = "". "BlockHash}\">". "BlockStart}\">". "BlockEnd}\">". "". ""; $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("
 LiveEdit: Error in template ".$StyleName.
                         ": placeholder {\$LiveEdit->".$k."} not found.\n\n $HTML
", ""); } // 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:=} Suggested parameters: {$params:DisplayType=} 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'] = "
". // Beginning of form "
FormAction}\" onsubmit='return validateLiveEditForm(this);' >". "{\$LiveEdit->FormElements}". // Form title "
". // The close button "X ". // The heading "Editing block ". "
". // The options inputbox "options [+] ". "
". // The main textarea "
". // The buttons "
". "". "  ". "  ". "    [Quick Reference]". "
". "
Save and...  ". "  ". "  
". "  ". "  ". "  ". "
". // End of form "
"; // ----------------------------------------------------------------- $LiveEdit->SubTemplates['Form']['Backdrop'] = "
"; // For version compatibility: $LiveEdit->SubTemplates['Form']['CoolForm'] = $LiveEdit->SubTemplates['Form']['Backdrop']; // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // Form validation sub-template $LiveEdit->SubTemplates['ValidationJS']['Confirmdelete'] = " "; // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // 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 "
". "". "
". // The top bar "
". " [edit] ". "
". // The edit form "{\$subtemplate:ValidationJS=\"Confirmdelete\"}". "{\$subtemplate:Form=\"Popup\"}". // The Wiki text to be displayed here "
". "{\$LiveEdit->DisplayTextPlaceholder}". // End of the block "
"; // ----------------------------------------------------------------- // Template: phantom $LiveEdit->Templates['Phantom'] = // The main div block container "
". "". "". // The edit form "{\$subtemplate:ValidationJS=\"Confirmdelete\"}". "{\$subtemplate:Form=\"Backdrop\"}". // The Wiki text to be displayed here "
". "{\$LiveEdit->DisplayTextPlaceholder}". // End of the block "
"; /* ========================================================================= */ /* ========================================================================= */ // 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 .= "An option string can have one of the folling formats:
  • Style_Name
  • StyleGroup.StylePage
  • Style_Name ParamName1=\"ParamValue1\" ParamName2=\"ParamValue2\" . . .
  • StyleGroup.StylePage ParamName1=\"ParamValue1\" ParamName2=\"ParamValue2\" . . .
". "Use the following character encodings for the contents of ParamValuen". ""; for ($a=0; $aOptionsEncodeChars[0]); $a++) $HTML .= ""; $HTML .= "
characterencoding
". str_replace(array("\n","\r"),array("newline","carriage return"),htmlspecialchars($LiveEdit->OptionsEncodeChars[0][$a])). "".htmlspecialchars($LiveEdit->OptionsEncodeChars[1][$a])."
 
Click one of the available Style_Name to view its parameters and their default values

"; foreach ( GetLiveEditAllStyles() as $s) { if ($s==$LiveEdit->DefaultStyle) $HTML .= "[ ".$s." ] (default)
"; else $HTML .= "[ ".$s." ]
"; } $HTML .= "

Or, type in the StyleGroup.StylePage:
    
 
 "; $HTML .= "
"; $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 = " Below is the code for style ".$StyleName.". Parameters are displayed in the format
     ParamName=\"ParamDefaultValue\"
"; $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 . "". "". "\n"; if (preg_match("/^<(".$newLineTags.").*/i",$line) === 1) { $tabdepth++; } } $HTMLfinal = $HTMLfinal . "
".str_repeat(" ",2*$tabdepth)."" . str_repeat(" ",0*$tabdepth) . "" . htmlspecialchars($line) . "
"; $HTMLfinal = $HTMLfinal . "
". ""; $HTMLfinal = preg_replace("/{\\\$(.*?)}/", "{\$\\1}",$HTMLfinal); $HTMLfinal = preg_replace("/{\\\$LiveEdit->(.*?)}/", "{\$LiveEdit->\\1}",$HTMLfinal); $HTMLfinal = preg_replace("/{\\\$params:([\w]*)="(.*?)"}/", "{\$params:\\1=\"\\2\"}",$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 ); } ?>