add support for class, id, style selector wiki templates, improve wiki in general, a=chris

Chris Pollett [2014-06-13 05:Jun:th]
add support for class, id, style selector wiki templates, improve wiki in general, a=chris
Filename
configs/createdb.php
controllers/components/social_component.php
data/default.db
lib/wiki_parser.php
models/group_model.php
scripts/basic.js
views/elements/wiki_element.php
diff --git a/configs/createdb.php b/configs/createdb.php
index 39a9b1dea..6700eb9c0 100755
--- a/configs/createdb.php
+++ b/configs/createdb.php
@@ -278,7 +278,7 @@ Yioop also supports several html tags such as:

 ===Spacing within Paragraphs===
 The HTML entity
-<nowiki> </nowiki>
+<nowiki>&nbsp;</nowiki>
 can be used to create a non-breaking space. The tag
 <nowiki><br></nowiki>
 can be used to produce a line break.
@@ -443,6 +443,8 @@ EOD;
 $group_model = new GroupModel(DB_NAME, false);
 $group_model->db = $db;
 foreach($public_pages as $page_name => $page_content) {
+    $page_content = str_replace("&amp;", "&", $page_content);
+    $page_content = @htmlentities($page_content, ENT_QUOTES, "UTF-8");
     $group_model->setPageName(ROOT_ID, PUBLIC_USER_ID, $page_name,
         $page_content, "en-US", "Creating Default Pages",
         "$page_name Wiki Page Created!", "Discuss the page in this thread!");
diff --git a/controllers/components/social_component.php b/controllers/components/social_component.php
index d824d94b8..cf5389b48 100644
--- a/controllers/components/social_component.php
+++ b/controllers/components/social_component.php
@@ -993,7 +993,20 @@ class SocialComponent extends Component implements CrawlConstants
                         $data['SCRIPT'] .=
                             "doMessage('<h1 class=\"red\" >".
                             tl("group_controller_page_saved").
-                            "</h1>')";
+                            "</h1>');";
+                        if(isset($_REQUEST['caret']) &&
+                           isset($_REQUEST['scroll_top'])) {
+                            $caret = $parent->clean($_REQUEST['caret'],
+                                'int');
+                            $scroll_top= $parent->clean($_REQUEST['scroll_top'],
+                                'int');
+                            $data['SCRIPT'] .= "wiki = elt('wiki-page');".
+                                "if (wiki.setSelectionRange) { " .
+                                "   wiki.focus();" .
+                                "   wiki.setSelectionRange($caret, $caret);".
+                                "} ".
+                                "wiki.scrollTop = $scroll_top;";
+                        }
                     }
                 break;
                 case "history":
diff --git a/data/default.db b/data/default.db
index cd0da75e8..aae20a67f 100644
Binary files a/data/default.db and b/data/default.db differ
diff --git a/lib/wiki_parser.php b/lib/wiki_parser.php
index 87d5ce54d..86333b17c 100644
--- a/lib/wiki_parser.php
+++ b/lib/wiki_parser.php
@@ -47,6 +47,12 @@ require_once BASE_DIR."/lib/processors/text_processor.php";

 class WikiParser implements CrawlConstants
 {
+    /**
+     * Escape string to prevent inccoreect nesting of div for some of the
+     * substitutions;
+     * @var string
+     */
+    var $esc=",[}";
     /**
      * Used to initialize the arrays of match/replacements used to format
      * wikimedia syntax into HTML (not perfectly since we are only doing
@@ -56,6 +62,7 @@ class WikiParser implements CrawlConstants
      */
     function __construct($base_address = "", $add_substitutions = array())
     {
+        $esc = $this->esc;
         //assume substitutions are applied after htmlentities called on string
         $substitutions = array(
             array('/(\A|\n)=\s*([^=]+)\s*=/',
@@ -70,18 +77,18 @@ class WikiParser implements CrawlConstants
                 "\n<h5 id='$2'>$2</h5>"),
             array('/(\A|\n)======\s*([^=]+)\s*======/',
                 "\n<h6 id='$2'>$2</h6>"),
-            array("/{{Main\s*\|(.+?)(\|.+)?}}/i",
-                "<div class='indent'>(<a href=\"".
-                $base_address."$1\">$1</a>)</div>"),
-            array("/{{See also\s*\|(.+?)(\|.+)?}}/i",
-                "<div class='indent'>(<a href=\"".
-                $base_address."$1\">$1</a>)</div>"),
-            array("/{{See\s*\|(.+?)(\|.+)?}}/i",
-                "<div class='indent'>(<a href=\"".
-                $base_address."$1\">$1</a>)</div>"),
-            array("/{{\s*Related articles\s*\|(.+?)\|(.+?)}}/si",
-                "<div class='indent'>(<a href=\"".
-                $base_address . "$1\">$1?</a>)</div>"),
+            array("/\n*?{{Main\s*\|(.+?)(\|.+)?}}/i",
+                "$esc<div class='indent'>\n\n(<a href=\"".
+                $base_address."$1\">$1</a>)\n\n$esc</div>"),
+            array("/\n*?{{See also\s*\|(.+?)(\|.+)?}}/i",
+                "$esc<div class='indent'>\n\n(<a href=\"".
+                $base_address."$1\">$1</a>)\n\n$esc</div>"),
+            array("/\n*?{{See\s*\|(.+?)(\|.+)?}}/i",
+                "$esc<div class='indent'>\n\n(<a href=\"".
+                $base_address."$1\">$1</a>)\n\n$esc</div>"),
+            array("/\n*?{{\s*Related articles\s*\|(.+?)\|(.+?)}}/si",
+                "$esc<div class='indent'>\n\n(<a href=\"".
+                $base_address . "$1\">$1?</a>)\n\n$esc</div>"),
             array('/\[\[(http[^\s\|\]]+)\|([^\[\]]+?)\]\]/s',
                 "<a href=\"$1\">$2</a>"),
             array('/\[\[([^\[\]]+?)\|([^\[\]]+?)\]\]/s',
@@ -95,9 +102,39 @@ class WikiParser implements CrawlConstants
                 "&#039;&#039;&#039;&#039;&#039;/s", "<b><i>$1</i></b>"),
             array("/&#039;&#039;&#039;(.+?)&#039;&#039;&#039;/s", "<b>$1</b>"),
             array("/&#039;&#039;(.+?)&#039;&#039;/s", "<i>$1</i>"),
-            array('/{{center\|(.+?)}}/s', "<div class='center'>$1</div>"),
-            array('/{{left\|(.+?)}}/s', "<div class='align-left'>$1</div>"),
-            array('/{{right\|(.+?)}}/s', "<div class='align-right'>$1</div>"),
+            array('/\n*?{{center\|(.+?)}}/s',
+                "$esc<div class='center'>\n\n$1\n\n$esc</div>"),
+            array('/\n*?{{\s*class\s*\=\s*'.
+                '&quot;([a-zA-Z\_\-\s]+)&quot;\s+(.+)}}/',
+                "$esc<span class=\"$1\">$2$esc</span>"),
+            array('/\n*?{{\s*class\s*\=\s*'.
+                '&quot;([a-zA-Z\_\-\s]+)&quot;\s+(.+)}}/s',
+                "$esc<div class=\"$1\">\n\n$2\n\n$esc</div>"),
+            array('/\n*?{{\s*class\s*\=\s*'.
+                '&#039;([a-zA-Z\_\-\s]+)&#039;\s+(.+)}}/s',
+                "$esc<div class='$1'>\n\n$2\n\n$esc</div>"),
+            array('/\n*?{{\s*id\s*\=\s*&quot;([a-zA-Z\_\-]+)&quot;\s+(.+)}}/',
+                "$esc<span id=\"$1\">$2$esc</span>"),
+            array('/\n*?{{\s*id\s*\=\s*&quot;([a-zA-Z\_\-]+)&quot;\s+(.+)}}/s',
+                "$esc<div id=\"$1\">\n\n$2\n\n$esc</div>"),
+            array('/\n*?{{\s*id\s*\=\s*&#039;([a-zA-Z\_\-]+)&#039;\s+(.+)}}/s',
+                "$esc<div id='$1'>\n\n$2\n\n$esc</div>"),
+            array('/\n*?{{\s*style\s*\=\s*'.
+                '&quot;([0-9a-zA-Z\/\#\_\-\.\;\:\s\n]+)&quot;\s+(.+)}}/',
+                "$esc<span style=\"$1\">$2$esc</span>"),
+            array('/\n*?{{\s*style\s*\=\s*'.
+                '&quot;([0-9a-zA-Z\/\#\_\-\.\;\:\s\n]+)&quot;\s+(.+)}}/s',
+                "$esc<div style=\"$1\">\n\n$2\n\n$esc</div>"),
+            array('/\n*?{{\s*style\s*\=\s*'.
+                '&#039;([0-9a-zA-Z\_\-\.\;\:\s\n]+)&#039;\s+(.+)}}/',
+                "$esc<span style='$1'>$2$esc</span>"),
+            array('/\n*?{{\s*style\s*\=\s*'.
+                '&#039;([0-9a-zA-Z\_\-\.\;\:\s\n]+)&#039;\s+(.+)}}/s',
+                "$esc<div style='$1'>\n\n$2\n\n$esc</div>"),
+            array('/\n*?{{left\s*\|(.+?)}}/s',
+                "$esc<div class='align-left'>\n\n$1\n\n$esc</div>"),
+            array('/\n*?{{right\s*\|(.+?)}}/s',
+                "$esc<div class='align-right'>\n\n$1\n\n$esc</div>"),
             array('/{{smallcaps\|(.+?)}}/s', "<small>$1</small>"),
             array('/{{Hatnote\|(.+?)}}/si', "($1)"),
             array("/{{fraction\|(.+?)\|(.+?)}}/si", "<small>$1/$2</small>"),
@@ -106,8 +143,9 @@ class WikiParser implements CrawlConstants
             array("/{{IPA-(.+?)\|(.+?)}}/si", "(IPA $2)"),
             array("/{{dablink\|(.+?)}}/si", "($1)"),
             array("/&lt;blockquote&gt;(.+?)&lt;\/blockquote&gt;/s",
-                "<blockquote>$1</blockquote>"),
-            array("/&lt;pre&gt;(.+?)&lt;\/pre&gt;/s", "<pre>$1</pre>"),
+                "$esc<blockquote>\n\n$1\n\n$esc</blockquote>"),
+            array("/&lt;pre&gt;(.+?)&lt;\/pre&gt;/s",
+                "$esc<pre>\n\n$1\n\n$esc</pre>"),
             array("/&lt;tt&gt;(.+?)&lt;\/tt&gt;/s", "<tt>$1</tt>"),
             array("/&lt;u&gt;(.+?)&lt;\/u&gt;/s", "<u>$1</u>"),
             array("/&lt;strike&gt;(.+?)&lt;\/strike&gt;/s",
@@ -188,6 +226,7 @@ class WikiParser implements CrawlConstants
     function parse($document, $parse_head_vars = true,
         $handle_big_files = false)
     {
+        $esc = $this->esc;
         $head = "";
         if($parse_head_vars) {
         $document_parts = explode("END_HEAD_VARS", $document);
@@ -231,13 +270,18 @@ class WikiParser implements CrawlConstants
             if(trim($part) == "") {
                 continue;
             }
-            $start = substr($part, 0, 2);
+            $start = substr($part, 0, 3);
             if(in_array($start[0], $space_like)) {
                 $document .= "\n<pre>\n".ltrim($part)."\n</pre>\n";
             } else {
-                $document .= "\n<div>\n".$part. "\n</div>\n";
+                if($start != $esc) {
+                    $document .= "\n<div>\n".$part. "\n</div>\n";
+                } else {
+                    $document .= $part;
+                }
             }
         }
+        $document = str_replace(",[}", "", $document);
         $document = $this->insertReferences($document, $references);
         $document = $this->insertTableOfContents($document, $toc);
         $document = preg_replace_callback(
diff --git a/models/group_model.php b/models/group_model.php
index c6bf0fdfc..f918b40f2 100644
--- a/models/group_model.php
+++ b/models/group_model.php
@@ -970,7 +970,7 @@ class GroupModel extends Model
         }
         $pages = array();
         if($total > 0) {
-            $sql = "SELECT TITLE, SUBSTR(PAGE,0, 100) AS DESCRIPTION
+            $sql = "SELECT TITLE, PAGE AS DESCRIPTION
                 FROM GROUP_PAGE WHERE GROUP_ID = ? AND
                 LOCALE_TAG= ? AND LENGTH(PAGE) > 0
                 $like ORDER BY UPPER(TITLE) ASC ".
@@ -979,6 +979,8 @@ class GroupModel extends Model
             $i = 0;
             if($result) {
                 while($pages[$i] = $db->fetchArray($result)) {
+                    $pages[$i]['DESCRIPTION'] = substr(
+                        $pages[$i]['DESCRIPTION'], 0, 100);
                     $i++;
                 }
                 unset($pages[$i]); //last one will be null
diff --git a/scripts/basic.js b/scripts/basic.js
index f61a226f4..73dd7f0e8 100755
--- a/scripts/basic.js
+++ b/scripts/basic.js
@@ -92,18 +92,43 @@ function getPage(tag, url)
             }
         }
         request.open("GET", url, true);
-
         request.send();
     }
 }
 /*
- *  Shorthand for document.createElement()
+ *  Returns the position of the caret within anode
  *
  *  @param String input type element
  */
-function ce(input)
+function caret(node)
+{
+    if (node.selectionStart) {
+        return node.selectionStart;
+    } else if (!document.selection) {
+        return false;
+    }
+    // old ie hack
+    var insert_char = "\001",
+    sel = document.selection.createRange(),
+    dul = sel.duplicate(),
+    len = 0;
+
+    dul.moveToElementText(node);
+    sel.text = insert_char;
+    len = dul.text.indexOf(insert_char);
+    sel.moveStart('character',-1);
+    sel.text = "";
+    return len;
+}
+/*
+ *  Shorthand for document.createElement()
+ *
+ *  @param String name tag name of element desired
+ *  @return Element the create element
+ */
+function ce(name)
 {
-    return document.createElement(input);
+    return document.createElement(name);
 }
 /*
  *  Shorthand for document.getElementById()
diff --git a/views/elements/wiki_element.php b/views/elements/wiki_element.php
index 94dc7fb09..bad3dd92c 100644
--- a/views/elements/wiki_element.php
+++ b/views/elements/wiki_element.php
@@ -66,7 +66,7 @@ class WikiElement extends Element implements CrawlConstants
         $other_base_query = "?c=$other_controller&amp;".CSRF_TOKEN."=".
             $data[CSRF_TOKEN]."&amp;a=wiki&amp;group_id=".
             $data["GROUP"]["GROUP_ID"]."&amp;arg=".$data['MODE']."&amp;".
-            "page_name=".$data['GROUP']['GROUP_NAME'];
+            "page_name=".$data['PAGE_NAME'];
         if($is_admin || $logged_in) { ?>
             <div class="float-same admin-collapse">[<a
             href="<?php e($other_base_query) ?>" ><?php
@@ -204,7 +204,11 @@ class WikiElement extends Element implements CrawlConstants
             '&amp;just_thread='.$data['DISCUSS_THREAD']);?>" ><?php
             e(tl('wiki_element_discuss'))?></a>]
         </div>
-        <form id="editpageForm" method="post" action='#'>
+        <form id="editpageForm" method="post" action='#'
+            onsubmit="elt('caret-pos').value =
+            (elt('wiki-page').selectionStart) ?
+            elt('wiki-page').selectionStart : 0;
+            elt('scroll-top').value=elt('wiki-page').scrollTop;" >
             <input type="hidden" name="c" value="<?php e($data['CONTROLLER']);
             ?>" />
             <input type="hidden" name="<?php e(CSRF_TOKEN); ?>" value="<?php
@@ -215,6 +219,8 @@ class WikiElement extends Element implements CrawlConstants
                 e($data['GROUP']['GROUP_ID']); ?>" />
             <input type="hidden" name="page_name" value="<?php
                 e($data['PAGE_NAME']); ?>" />
+            <input type="hidden" name="caret" id="caret-pos"/>
+            <input type="hidden" name="scroll_top" id="scroll-top"/>
             <div class="top-margin">
                 <b><?php
                 e(tl('wiki_element_locale_name',
ViewGit