_binary From aa3912fcc721838bbd0bf7e6df8b660dd82007f9 Mon Sep 17 00:00:00 2001
From: Eswar Rajesh Pinapala <epinapala@live.com>
Date: Sun, 4 May 2014 21:13:04 -0700
Subject: [PATCH] Added wikify.js to /Scripts Added editor.css to /css (for
 editor styles) Added button images to resources directory Edited
 web_layout.php to include css and js files., a=epinapala optimized CSS and JS

---
 configs/config.php                 |   4 +-
 css/editor.css                     | 108 +++++++
 resources/wikiedit/Bold.png        | Bin 0 -> 23068 bytes
 resources/wikiedit/Hyperlink.png   | Bin 0 -> 23980 bytes
 resources/wikiedit/Italic.png      | Bin 0 -> 22773 bytes
 resources/wikiedit/No-Wiki.png     | Bin 0 -> 23588 bytes
 resources/wikiedit/Strike.png      | Bin 0 -> 23717 bytes
 resources/wikiedit/Underline.png   | Bin 0 -> 23171 bytes
 resources/wikiedit/bullets.png     | Bin 0 -> 23394 bytes
 resources/wikiedit/button.psd      | Bin 0 -> 89306 bytes
 resources/wikiedit/empty.png       | Bin 0 -> 21979 bytes
 resources/wikiedit/heading.png     | Bin 0 -> 22663 bytes
 resources/wikiedit/hr.png          | Bin 0 -> 22174 bytes
 resources/wikiedit/numbers.png     | Bin 0 -> 23336 bytes
 resources/wikiedit/table.png       | Bin 0 -> 23545 bytes
 resources/wikiedit/yioopSearch.png | Bin 0 -> 23742 bytes
 scripts/wikify.js                  | 607 +++++++++++++++++++++++++++++++++++++
 views/layouts/web_layout.php       |   3 +
 18 files changed, 720 insertions(+), 2 deletions(-)
 create mode 100755 css/editor.css
 create mode 100644 resources/wikiedit/Bold.png
 create mode 100644 resources/wikiedit/Hyperlink.png
 create mode 100644 resources/wikiedit/Italic.png
 create mode 100644 resources/wikiedit/No-Wiki.png
 create mode 100644 resources/wikiedit/Strike.png
 create mode 100644 resources/wikiedit/Underline.png
 create mode 100644 resources/wikiedit/bullets.png
 create mode 100755 resources/wikiedit/button.psd
 create mode 100644 resources/wikiedit/empty.png
 create mode 100644 resources/wikiedit/heading.png
 create mode 100644 resources/wikiedit/hr.png
 create mode 100644 resources/wikiedit/numbers.png
 create mode 100644 resources/wikiedit/table.png
 create mode 100755 resources/wikiedit/yioopSearch.png
 create mode 100755 scripts/wikify.js

diff --git a/configs/config.php b/configs/config.php
index 222c0d5..70393da 100755
--- a/configs/config.php
+++ b/configs/config.php
@@ -104,9 +104,9 @@ if(MAINTENANCE_MODE && $_SERVER["SERVER_ADDR"] != $_SERVER["REMOTE_ADDR"]) {
 }
 
 if(!defined('WORK_DIRECTORY')) {
-/*+++ The next block of code is machine edited, change at
+/*+++ The next block of code is machine edited, change at 
 your own risk, please use configure web page instead +++*/
-define('WORK_DIRECTORY', '');
+define('WORK_DIRECTORY', '/Applications/XAMPP/htdocs/yioop_data');
 /*++++++*/
 // end machine edited code
 }
diff --git a/css/editor.css b/css/editor.css
new file mode 100755
index 0000000..1040dd7
--- /dev/null
+++ b/css/editor.css
@@ -0,0 +1,108 @@
+#wikiEditor
+{
+    text-align: center;
+    display: table;
+    margin: 0 auto;
+}
+
+#wikiEditor div
+{
+    float: left;
+    padding: 5px;
+}
+
+div.wikiEditor input
+{
+    cursor: pointer;
+    width: 46px;
+    height: 50px;
+    display: inline-block;
+    vertical-align: top;
+    border-style: solid;
+}
+div.wikiEditor select
+{
+    cursor: pointer;
+    width: 46px;
+    height: 50px;
+    border: 1px;
+}
+
+#bold
+{
+    background: url(../images/Bold.png) no-repeat;
+}
+
+
+#underline
+{
+    background: url(../images/Underline.png) no-repeat;
+}
+
+#bullets
+{
+    background: url(../images/bullets.png) no-repeat;
+}
+
+#heading
+{
+    height: 50px;
+    background: url(../images/heading.png) no-repeat;
+}
+
+#hr
+{
+    background: url(../images/hr.png) no-repeat;
+}
+
+#hyperlink
+{
+    background: url(../images/Hyperlink.png) no-repeat;
+}
+
+
+#italic
+{
+    background: url(../images/Italic.png) no-repeat;
+}
+
+#nowiki
+{
+    background: url(../images/No-Wiki.png) no-repeat;
+}
+
+#numbers
+{
+    background:url(../images/numbers.png) no-repeat;
+}
+
+#strike
+{
+    background: url(../images/Strike.png) no-repeat;
+}
+
+#table
+{
+    background: url(../images/table.png) no-repeat;
+}
+
+#yioopSearch
+{
+    background: url(../images/yioopSearch.png) no-repeat;
+}
+
+#bold:hover,
+#bullets:hover,
+#heading:hover,
+#hr:hover,
+#hyperlink:hover,
+#italic:hover,
+#nowiki:hover,
+#numbers:hover,
+#strike:hover,
+#table:hover,
+#underline:hover,
+#yioopSearch:hover
+{
+    background-position: 0 -50px;
+}
\ No newline at end of file
diff --git a/resources/wikiedit/Bold.png b/resources/wikiedit/Bold.png
new file mode 100644
index 0000000000000000000000000000000000000000..c77f5d7395f95837dad94de87d22c50cb6df50ce
GIT binary patch
diff --git a/resources/wikiedit/Hyperlink.png b/resources/wikiedit/Hyperlink.png
new file mode 100644
index 0000000000000000000000000000000000000000..b703fae35ccd0e1fbfefd7308cbd61d9cfd20e8d
GIT binary patch
diff --git a/resources/wikiedit/Italic.png b/resources/wikiedit/Italic.png
new file mode 100644
index 0000000000000000000000000000000000000000..b8e92c0db0f9393fcff495a4c981949ff6e29485
GIT binary patch
diff --git a/resources/wikiedit/No-Wiki.png b/resources/wikiedit/No-Wiki.png
new file mode 100644
index 0000000000000000000000000000000000000000..e96c6137da344ed109f903519a65d09500a1237a
GIT binary patch
diff --git a/resources/wikiedit/Strike.png b/resources/wikiedit/Strike.png
new file mode 100644
index 0000000000000000000000000000000000000000..7a5159b280ff29d7e4170ee1450c353ee9d7ef06
GIT binary patch
diff --git a/resources/wikiedit/Underline.png b/resources/wikiedit/Underline.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa5f509edf020d2ee655cf278f6984ddcf7fa56a
GIT binary patch
diff --git a/resources/wikiedit/bullets.png b/resources/wikiedit/bullets.png
new file mode 100644
index 0000000000000000000000000000000000000000..79bc7fd5d07459e7ba9509eddca5df81d9ac150d
GIT binary patch
diff --git a/resources/wikiedit/button.psd b/resources/wikiedit/button.psd
new file mode 100755
index 0000000000000000000000000000000000000000..0ee1deacd8c0495c7af904733aba4ade3c3758af
GIT binary patch
diff --git a/resources/wikiedit/empty.png b/resources/wikiedit/empty.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0a72bc4b5a697f1b49a8736570e519083d0056f
GIT binary patch
diff --git a/resources/wikiedit/heading.png b/resources/wikiedit/heading.png
new file mode 100644
index 0000000000000000000000000000000000000000..8b2c5be4ae2269704cce671acd593348ffea06fd
GIT binary patch
diff --git a/resources/wikiedit/hr.png b/resources/wikiedit/hr.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f72892893450b8f0994ee91f915e37ff0c33166
GIT binary patch
diff --git a/resources/wikiedit/numbers.png b/resources/wikiedit/numbers.png
new file mode 100644
index 0000000000000000000000000000000000000000..2de3b1790757c8bc6fe83902ab67ff75baf7fa39
GIT binary patch
diff --git a/resources/wikiedit/table.png b/resources/wikiedit/table.png
new file mode 100644
index 0000000000000000000000000000000000000000..c5719cf93998cf854274a9f2547c478a25b7e9db
GIT binary patch
diff --git a/resources/wikiedit/yioopSearch.png b/resources/wikiedit/yioopSearch.png
new file mode 100755
index 0000000000000000000000000000000000000000..1664f842b979d2e7b723cf07a3319fb9875fc57e
GIT binary patch
diff --git a/scripts/wikify.js b/scripts/wikify.js
new file mode 100755
index 0000000..3643cf5
--- /dev/null
+++ b/scripts/wikify.js
@@ -0,0 +1,607 @@
+/**
+ * @author: epinapala
+ * @url: http://pinapala.com
+ */
+
+
+/**
+ * Buttons is where all the buttons are
+ * added as params to the buttons object.
+ * The editor automatically renders the 
+ * editor buttons using this object as 
+ * configuration data.
+ * 
+ * @type {Object}
+ */
+var buttons = {
+    'bold': ['---', '---'],
+    'italic': ['--', '--'],
+    'underline': ['<u>', '</u>'],
+    'strike': ['<s>', '</s>'],
+    'nowiki': ['<nowiki>', '</nowiki>'],
+    'hyperlink': ['[', ']'],
+    'bullets': ['* Bulleted list item \n'],
+    'numbers': ['# Numbered list item \n'],
+    'hr': ['---- \n']
+};
+
+//global flag variable to check if browser is Older MSIE.
+var isMSIE = false;
+//global flag variable that holds the wikiTextName. defults to wikiText if data-wikiText is not set.
+var wikiTextName = "wikiText";
+
+
+/**
+ * On window load , Render the editor
+ * and buttons.
+ * 
+ * @returns {void}
+ */
+window.onload = function() {
+    //check if the editor div exists.
+    var node = document.getElementById("wikiEditor");
+
+    if (node === null) {
+        //If the div to render Wikieditor is not found, do nothing.
+        //alert("Please create a Div with id=wikiEdit to insert the Wikieditor");
+        return false;
+    }
+
+    if (document.selection) {
+
+        isMSIE = true;
+        var buttonString = "" ;
+        
+        for (var prop in buttons) {
+            if (buttons.hasOwnProperty(prop)) {
+                buttonString += '<input type="button" class="button" id="'+prop+'" onmousedown="wikifySelection(\''+prop+'\');">';
+            }
+        }
+        
+        node.innerHTML =
+                buttonString +
+                '<select class="heading" id="heading" value="heading" onchange="setHeading();">\n\
+                <option selected="" disabled="">Heading\n\
+                </option><option value="1">H1</option>\n\
+                <option value="2">H2</option>\n\
+                <option value="3">H3</option>\n\
+                <option value="4">H4</option>\n\
+                </select>\n\
+                <input type="button" class="button" id="table" onmousedown="insertTable();">'+
+                '<input type="button" class="button" id="yioopSearch" onmousedown="insertYioopSearch();">'+
+                '<form action="" method="POST" name="">' +
+                '<textarea id="wikiText" class="wikiText" style="width: 550px; height: 300px; resize: none;"></textarea><p>'+
+                '<input type=SUBMIT value="submit" />\n\
+                </p></form>';
+
+        return;
+    }
+
+    renderWikiEditor(node);
+
+};
+
+/**
+ * This is a function for rendering the
+ * wiki editor using DOM manipulation.
+ * This is the core function that leverages
+ * teh cofigurations buttons object and builds
+ * the wiki editor buttons, textarea etc.
+ * 
+ * @param {Element} wikiEditor
+ * @returns {void}
+ */
+function renderWikiEditor(wikiEditor) {
+
+    //Insert Heading
+    wikiEditor.appendChild(createDropDown(
+            "heading",
+            "setHeading",
+            {
+                "H1": "1",
+                "H2": "2",
+                "H3": "3",
+                "H4": "4"
+            }
+    ));
+
+    //Using the buttons JSON, populate the buttons.
+    for (var property in buttons) {
+        if (buttons.hasOwnProperty(property)) {
+            createButton(wikiEditor, property);
+        }
+    }
+
+    //Insert button for insertTable
+    wikiEditor.appendChild(createElement("input", {
+        "type": "button",
+        "class": 'button',
+        "id": 'table',
+        //"value": 'table',
+        "onmousedown": "insertTable();"
+    }));
+
+    //Insert button for insertTable
+    wikiEditor.appendChild(createElement("input", {
+        "type": "button",
+        "class": 'button',
+        "id": 'yioopSearch',
+        //"value": 'table',
+        "onmousedown": "insertYioopSearch();"
+    }));
+
+    //Insert a couple of line breaks
+    //wikiEditor.appendChild(document.createElement('br'));
+    wikiEditor.appendChild(document.createElement('br'));
+
+    //retreive data-* attributes for the wikiEditor.
+    var wikiTextDiv = document.getElementById("wikiEditor");
+    var wikiFormName = wikiTextDiv.getAttribute("data-formName");
+    var wikiFormAction = wikiTextDiv.getAttribute("data-formAction");
+    var wikiFormMethod = wikiTextDiv.getAttribute("data-formMethod");
+
+    //Check if the data-* attributes are set.
+    if (wikiFormName && wikiFormAction && wikiFormMethod) {
+
+        wikiTextName = wikiFormName;
+        //Create a FOrmElement 
+        var formElement = createElement("form", {
+            "name": wikiTextName,
+            "action": wikiFormAction,
+            "method": wikiFormMethod
+        });
+
+        //Insert a text area
+        formElement.appendChild(createElement("textarea", {
+            "id": wikiTextName,
+            "class": wikiFormName,
+            "style": 'width: 550px; height: 300px; resize: none;'
+        }));
+        var pElement = createElement("p", {});
+        pElement.appendChild(createElement("input", {
+            "type": "SUBMIT",
+            "id": "Submit",
+            "value": "Submit"
+        }));
+
+        formElement.appendChild(pElement);
+
+        wikiEditor.appendChild(formElement);
+
+    } else {
+        //Insert a text area
+        wikiEditor.appendChild(createElement("textarea", {
+            "id": wikiTextName,
+            "class": wikiTextName,
+            "style": 'width: 550px; height: 300px; resize: none;'
+        }));
+
+    }
+    //Finally another line break.
+    wikiEditor.appendChild(document.createElement('br'));
+}
+
+/**
+ * Util function to create a Dom element,
+ * given an element name and an object with
+ * attributes as key value pairs.
+ * 
+ * @param {String} elementName
+ * @param {Object} attributes
+ * @returns {createElement.elementx|Element}
+ */
+function createElement(elementName, attributes) {
+    var elementx = document.createElement(elementName);
+
+    for (var property in attributes) {
+        if (attributes.hasOwnProperty(property)) {
+            //alert(property + buttons[property]);
+            elementx.setAttribute(property, attributes[property]);
+        }
+    }
+
+    return elementx;
+}
+
+/**
+ * Given the parent element and
+ * name of the button, This util function
+ * created an editor button.
+ * 
+ * @param {Element} context
+ * @param {String} name
+ * @returns {undefined}
+ */
+function createButton(context, name) {
+    context.appendChild(createElement("input", {
+        "type": "button",
+        "class": 'button',
+        "id": name,
+        //"value": name,
+        "onmousedown": "wikifySelection('" + name + "');"
+    }));
+}
+
+/**
+ * This is a util function to
+ * create a dropdown element.
+ * 
+ * @param {String} dropDownName
+ * @param {String} action
+ * @param {Object} options
+ * @returns {createElement.elementx|Element|createDropDown.select|Node}
+ */
+function createDropDown(dropDownName, action, options) {
+    var select = createElement("select", {
+        "class": dropDownName,
+        "id": dropDownName,
+        "value": dropDownName,
+        "onchange": action + "();"
+    });
+
+
+
+    var option = document.createElement("option");
+    //option.text = dropDownName;
+    option.setAttribute("selected", "");
+    option.setAttribute("disabled", "");
+    select.add(option);
+
+
+    for (optionObj in options) {
+        if (options.hasOwnProperty(optionObj)) {
+            var option = document.createElement("option");
+            option.text = optionObj;
+            option.value = options[optionObj];
+            select.add(option);
+        }
+    }
+
+
+
+    return select;
+}
+
+
+/**
+ * This function returns the selection(from Textarea)
+ * information in an object. The obejct contains 
+ * selected text, entre prefix and entire suffix strings to the
+ * selected text.
+ * @returns {getSelection.obj}
+ */
+function getSelection() {
+    //Select the DOM element - wikiText
+    var textArea = document.getElementById(wikiTextName);
+
+    // IE?
+    if (document.selection) {
+        //console.log("IE");
+
+        /**
+         * MSIE docs referred to make things work in IE.
+         * createTextRange - //http://msdn.microsoft.com/en-us/library/ms536401(v=vs.85).aspx
+         * moveToBookMark - //http://msdn.microsoft.com/en-us/library/ms536628(v=vs.85).aspx
+         * setEndPoint - http://msdn.microsoft.com/en-us/library/ms536745(v=vs.85).aspx
+         * collapse - http://msdn.microsoft.com/en-us/library/ff975439(v=vs.85).aspx
+         */
+
+        var selectionBookmark = document.selection.createRange().getBookmark();
+        var sel = textArea.createTextRange();
+        sel.moveToBookmark(selectionBookmark);
+
+        var sleft = textArea.createTextRange();
+        sleft.collapse(true);
+        sleft.setEndPoint("EndToStart", sel);
+
+        textArea.selectionStart = sleft.text.length;
+        textArea.selectionEnd = sleft.text.length + sel.text.length;
+        textArea.selectedText = sel.text;
+
+        var selectedTextPrefix = textArea.value.substring(0, textArea.selectionStart);
+        var selection = sel.text;
+        var selectedTextSuffix = textArea.value.substring(textArea.selectionEnd, textArea.textLength);
+    }
+    // Mozilla?
+    else if (typeof (textArea.selectionStart) !== "undefined") {
+        /** 
+         * Things are pretty straight forward in Mozilla based browsers & IE > 10. 
+         * We can get the selectionStart & selectionEnd character position directly.
+         * Then compute the prefix and suffix using substr method.
+         */
+
+        console.log("Mozilla");
+        var selectedTextPrefix = textArea.value.substr(0, textArea.selectionStart);
+        var selection = textArea.value.substr(textArea.selectionStart, textArea.selectionEnd - textArea.selectionStart);
+        var selectedTextSuffix = textArea.value.substr(textArea.selectionEnd);
+}
+
+    var obj = {};
+    obj.selection = selection;
+    obj.selectedTextPrefix = selectedTextPrefix;
+    obj.selectedTextSuffix = selectedTextSuffix;
+    setCaretPosition(textArea, textArea.selectionEnd);
+
+    return obj;
+}
+
+/**
+ * MSIE has a problem displaying \n as libe breaks
+ * we use this fucntions to normalise all the libebreaks
+ * to be backward compatible with MSIE.
+ * 
+ * @param {type} text
+ * @returns {unresolved}
+ */
+function normalizeNewlinesForMSIE(text)
+{
+    return text.replace(/(\r\n|\r|\n)/g, '\n\r');
+}
+
+
+/**
+ * This function can be used to set 
+ * the caret position in the ctrl object.
+ * 
+ * @param {type} ctrl 
+ * @param {type} pos
+ * @returns {void}
+ */
+function setCaretPosition(ctrl, pos) {
+    if (ctrl.setSelectionRange)
+    {
+        ctrl.focus();
+        ctrl.setSelectionRange(pos, pos);
+    }
+    else if (ctrl.createTextRange) {
+        var range = ctrl.createTextRange();
+        range.collapse(true);
+        range.moveEnd('character', pos);
+        range.moveStart('character', pos);
+        range.select();
+    }
+}
+
+/**
+ * 
+ * @param {String} name
+ * @returns {void}
+ */
+function wikifySelection(name) {
+    var length = 0;
+    if (isMSIE) {
+        for (var prop in buttons) {
+            if (buttons.hasOwnProperty(prop)) {
+                if (prop === name) {
+                    length = buttons[prop].length;
+                }
+            }
+        }
+    } else {
+        length = buttons[name].length;
+    }
+
+    if (length === 2) {
+        wikify(
+                buttons[name][0].replace(new RegExp('-', 'g'), "\'"),
+                buttons[name][1].replace(new RegExp('-', 'g'), "\'")
+                );
+    } else if (length === 1) {
+        insertTextAtCursor(buttons[name][0]);
+    } else {
+        return;
+    }
+}
+
+/**
+ * This is the main function that takes
+ * prefix and suffix characters for wikifying 
+ * selected text. Selected text will be obtained using
+ * the function-getSelection();
+ * 
+ * @param {type} wikiPrefix
+ * @param {type} wikiSuffix
+ * @returns {void}
+ */
+function wikify(wikiPrefix, wikiSuffix) {
+    //Select the DOM element - wikiText
+    var textArea = document.getElementById(wikiTextName);
+
+    var obj = getSelection();
+
+    var selection = obj.selection;
+    var selectedTextPrefix = obj.selectedTextPrefix;
+    var selectedTextSuffix = obj.selectedTextSuffix;
+
+    if (!selection && wikiPrefix === '[') {
+        var title = prompt("Link Title", "Enter Link title");
+        var link = prompt("Link", "Enter link startng with http:// or https://");
+
+        if (!title || !link) {
+            return;
+        }
+
+        selection = link + " " + title;
+    } else if (!selection && wikiPrefix === '<nowiki>') {
+        selection = "Insert non-formatted text here";
+    }
+
+    //Now Add the wrap the selected text between the wiki stuff, and then wrap the 
+    //selected text between actual selected text's prefix and suffix.
+    //Replace the textArea contents with the result.
+    textArea.value = selectedTextPrefix + wikiPrefix + selection + wikiSuffix + selectedTextSuffix;
+
+}
+
+
+/**
+ * This function takes in number of rows, columns and
+ * headerText(if desired) and constructs a table in wiki markup.
+ * 
+ * @param {type} rows
+ * @param {type} cols
+ * @param {type} exampleText
+ * @param {type} headerText
+ * @returns {createWikiTable.br|String}
+ */
+function createWikiTable(rows, cols, exampleText, headerText) {
+    var br = "\n";
+    var table = "{|" + br;
+    for (i = 0; i < rows; i++) {
+        if (headerText && i === 0) {
+            table = table + "|- " + br;
+            table = table + "! ";
+            for (j = 0; j < cols; j++) {
+                table = table + headerText + " ";
+                if (j < (cols - 1)) {
+                    table = table + "!!" + " ";
+                } else {
+                    table = table + br;
+                }
+            }
+        }
+
+        table = table + "|- " + br;
+        table = table + "| ";
+
+        for (j = 0; j < cols; j++) {
+            table = table + exampleText + " ";
+            if (j < (cols - 1)) {
+                table = table + "||" + " ";
+            } else {
+                table = table + br;
+            }
+        }
+
+    }
+
+    table = table + "|}";
+
+    return table;
+}
+
+/**
+ * function to insert
+ * yioop search widget.
+ * @returns {void}
+ */
+function insertYioopSearch() {
+
+    var width = prompt("Enter the width of the widget");
+    var height = prompt("Enter the height of the widget");
+
+    var widgetObj = {};
+    var yioopObj = {};
+
+    yioopObj.width = width;
+    yioopObj.height = height;
+    widgetObj.yioop_search = objToString(yioopObj);
+    
+    insertTextAtCursor("[" + objToString(widgetObj) + "]");
+}
+
+/**
+ * Util function to Stringify an
+ * Object
+ * @param {type} jsObject
+ * @returns {String}
+ */
+function objToString(jsObject) {
+    var jsonString = [];
+    for (var property in jsObject) {
+        if (jsObject.hasOwnProperty(property)) {
+            jsonString.push('"' + property + '"' + ':' + jsObject[property]);
+        }
+    }
+    
+    jsonString.push();
+    
+    return '{' + jsonString.join(',') + '}';
+}
+
+/**
+ * This function is the main function that
+ * is invoked by the editor to insert a wiki table.
+ * This functions takes care okf the user input for rows/columns/etc
+ * and leverages createWikiTable function to construct the table.
+ * 
+ * @returns {void}
+ */
+function insertTable() {
+    var cols = prompt("Enter the number of columns");
+    var rows = prompt("Enter the number of rows");
+
+
+    if (!cols || !rows) {
+        return;
+    }
+
+    var retVal = confirm("Insert heading too?");
+
+    if (retVal) {
+        var table = createWikiTable(rows, cols, "Example", "Title");
+    } else {
+        table = createWikiTable(rows, cols, "Example");
+    }
+    insertTextAtCursor(table);
+}
+
+/**
+ * 
+ * @param {type} text
+ * @returns {void}
+ */
+function insertTextAtCursor(text) {
+    var field = document.getElementById(wikiTextName);
+
+    if (document.selection) {
+        var range = document.selection.createRange();
+
+        if (!range || range.parentElement() !== field) {
+            field.focus();
+            range = field.createTextRange();
+            range.collapse(false);
+        }
+        range.text = text;
+        range.collapse(false);
+        range.select();
+    } else {
+        field.focus();
+        var val = field.value;
+        var selStart = field.selectionStart;
+        var caretPos = selStart + text.length;
+        field.value = val.slice(0, selStart) + text + val.slice(field.selectionEnd);
+        field.setSelectionRange(caretPos, caretPos);
+    }
+}
+
+/**
+ * This function is used to set the headings
+ * for selected text.
+ * 
+ * @returns {void}
+ */
+function setHeading() {
+    var markUpText = fillChars("=", document.getElementById("heading").value);
+    document.getElementById("heading").selectedIndex = 0;
+    wikify(markUpText, markUpText);
+}
+
+/**
+ * This is a simple util
+ * function to fill a character 
+ * array and return as a string,
+ * given a character and array count.
+ * 
+ * @param {char} c
+ * @param {int} n
+ * @returns {String|fillChars.e}
+ */
+function fillChars(c, n) {
+    for (var e = ""; e.length < n; )
+    {
+        e += c;
+    }
+    //console.log(e);
+    return e;
+}
\ No newline at end of file
diff --git a/views/layouts/web_layout.php b/views/layouts/web_layout.php
index 74d79e3..370c977 100755
--- a/views/layouts/web_layout.php
+++ b/views/layouts/web_layout.php
@@ -91,6 +91,8 @@ class WebLayout extends Layout
             href="<?php e($path_info); ?>favicon.ico" />
         <link rel="stylesheet" type="text/css"
             href="<?php e($path_info); ?>/css/search.css" />
+        <link rel="stylesheet" type="text/css"
+            href="<?php e($path_info); ?>/css/editor.css" />
         <link rel="search" type="application/opensearchdescription+xml"
             href="<?php e(NAME_SERVER."yioopbar.xml");?>"
             title="Content search" />
@@ -128,6 +130,7 @@ class WebLayout extends Layout
         } ?>
 
         <script type="text/javascript" src="./scripts/basic.js" ></script>
+        <script type="text/javascript" src="./scripts/wikify.js" ></script>
         <?php
         if(isset($data['INCLUDE_SCRIPTS'])) {
             foreach($data['INCLUDE_SCRIPTS'] as $script_name) {
-- 
1.8.5.2 (Apple Git-48)

