view wiki.js @ 15:c94bd26e0e67

Fixed a bug whereby if the user tried editing an element while already editing a different one, weird things would happen.
author Atul Varma <varmaa@toolness.com>
date Sun, 01 Feb 2009 18:35:33 -0800
parents f8354a940524
children 20b6dbeb6250
line wrap: on
line source

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Ubiquity.
 *
 * The Initial Developer of the Original Code is Mozilla.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Atul Varma <atul@mozilla.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

var App = {
  PART_SEPARATOR: "\n\n",
  creole: null,
  editingElement: null,
  eventHandlers: {}
};

App.eventHandlers.editPart = function editPart(aEvt) {
  if (!aEvt.shiftKey)
    return;

  aEvt.preventDefault();

  App.enterEditMode([this], 1);
};

App.getMarkup = function getMarkup(parts) {
  var partsMarkup = [];
  $(".creole-markup", parts).each(
    function(i) { partsMarkup.push($(this).text()); }
  );

  return partsMarkup.join(App.PART_SEPARATOR);
};

App.enterEditMode = function enterEditMode(parts, level, cursorPos) {
  if (App.editingElement) {
    $(App.editingElement).blur();
    App.editingElement = null;
  }

  var editablePart = $('<textarea class="wiki-edit"></textarea>').get(0);
  $(editablePart).attr("value", App.getMarkup(parts));

  function setScrollHeight() {
    $(this).height(this.scrollHeight);
  }

  function exitEditMode() {
      var markup = $(this).attr("value");
      $(this).replaceWith(App.createParts(markup));
  }

  function editSiblings(aEvt) {
    if (!aEvt.shiftKey || level == 0)
      return;

    aEvt.preventDefault();

    var prevMarkup = App.getMarkup($(this).prevAll());
    var cursorPos = (prevMarkup.length + App.PART_SEPARATOR.length +
                     this.selectionStart);

    var allSiblings = this.parentNode.childNodes;
    exitEditMode.apply(this);

    App.enterEditMode(allSiblings, level-1, cursorPos);
  }

  $(editablePart).blur(exitEditMode);
  $(editablePart).mousedown(editSiblings);
  $(editablePart).keyup(setScrollHeight);
  $(parts).filter(":not(:first)").remove();
  $(parts).replaceWith(editablePart);
  setScrollHeight.apply(editablePart);

  if (typeof(cursorPos) != "undefined") {
    editablePart.selectionStart = cursorPos;
    editablePart.selectionEnd = cursorPos;
  }

  App.editingElement = editablePart;
  $(editablePart).focus();
};

App.createPart = function createPart(markup) {
  var partDiv = $('<div class="part"></div>');
  var markupDiv = $('<div class="creole-markup"></div>');
  markupDiv.text(markup);
  App.creole.parse(partDiv.get(0), markup);
  partDiv.mousedown(App.eventHandlers.editPart);
  partDiv.append(markupDiv);
  return partDiv.get(0);
};

App.createParts = function createParts(text) {
  var parts = [];

  var partsMarkup = text.split(App.PART_SEPARATOR);
  jQuery.each(
    partsMarkup,
    function(i) {
      var partMarkup = this.toString();
      if (partMarkup)
        parts.push(App.createPart(partMarkup));
    }
  );

  return parts;
};

App.eventHandlers.onLoad = function onLoad() {
  App.creole = new Parse.Simple.Creole(
    {interwiki: {
       WikiCreole: 'http://www.wikicreole.org/wiki/',
       Wikipedia: 'http://en.wikipedia.org/wiki/'
     },
     linkFormat: ''
    });

  jQuery.get("wiki.txt",
             {},
             function(text) {
               $("#content").append(App.createParts(text));
             },
             "text");
};

$(window).ready(App.eventHandlers.onLoad);