/**
* @license wysihtml5 v0.4.0pre
* https://github.com/xing/wysihtml5
*
* Author: Christopher Blum (https://github.com/tiff)
*
* Copyright (C) 2012 XING AG
* Licensed under the MIT license (MIT)
*
*/
var wysihtml5 = {
version: "0.4.0pre",
// namespaces
commands: {},
dom: {},
quirks: {},
toolbar: {},
lang: {},
selection: {},
views: {},
INVISIBLE_SPACE: "\uFEFF",
EMPTY_FUNCTION: function() {},
ELEMENT_NODE: 1,
TEXT_NODE: 3,
BACKSPACE_KEY: 8,
ENTER_KEY: 13,
ESCAPE_KEY: 27,
SPACE_KEY: 32,
DELETE_KEY: 46
};/**
* @license Rangy, a cross-browser JavaScript range and selection library
* http://code.google.com/p/rangy/
*
* Copyright 2011, Tim Down
* Licensed under the MIT license.
* Version: 1.2.2
* Build date: 13 November 2011
*/
window['rangy'] = (function() {
var OBJECT = "object", FUNCTION = "function", UNDEFINED = "undefined";
var domRangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed",
"commonAncestorContainer", "START_TO_START", "START_TO_END", "END_TO_START", "END_TO_END"];
var domRangeMethods = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore",
"setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents",
"extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"];
var textRangeProperties = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"];
// Subset of TextRange's full set of methods that we're interested in
var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "getBookmark", "moveToBookmark",
"moveToElementText", "parentElement", "pasteHTML", "select", "setEndPoint", "getBoundingClientRect"];
/*----------------------------------------------------------------------------------------------------------------*/
// Trio of functions taken from Peter Michaux's article:
// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
function isHostMethod(o, p) {
var t = typeof o[p];
return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == "unknown";
}
function isHostObject(o, p) {
return !!(typeof o[p] == OBJECT && o[p]);
}
function isHostProperty(o, p) {
return typeof o[p] != UNDEFINED;
}
// Creates a convenience function to save verbose repeated calls to tests functions
function createMultiplePropertyTest(testFunc) {
return function(o, props) {
var i = props.length;
while (i--) {
if (!testFunc(o, props[i])) {
return false;
}
}
return true;
};
}
// Next trio of functions are a convenience to save verbose repeated calls to previous two functions
var areHostMethods = createMultiplePropertyTest(isHostMethod);
var areHostObjects = createMultiplePropertyTest(isHostObject);
var areHostProperties = createMultiplePropertyTest(isHostProperty);
function isTextRange(range) {
return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties);
}
var api = {
version: "1.2.2",
initialized: false,
supported: true,
util: {
isHostMethod: isHostMethod,
isHostObject: isHostObject,
isHostProperty: isHostProperty,
areHostMethods: areHostMethods,
areHostObjects: areHostObjects,
areHostProperties: areHostProperties,
isTextRange: isTextRange
},
features: {},
modules: {},
config: {
alertOnWarn: false,
preferTextRange: false
}
};
function fail(reason) {
window.alert("Rangy not supported in your browser. Reason: " + reason);
api.initialized = true;
api.supported = false;
}
api.fail = fail;
function warn(msg) {
var warningMessage = "Rangy warning: " + msg;
if (api.config.alertOnWarn) {
window.alert(warningMessage);
} else if (typeof window.console != UNDEFINED && typeof window.console.log != UNDEFINED) {
window.console.log(warningMessage);
}
}
api.warn = warn;
if ({}.hasOwnProperty) {
api.util.extend = function(o, props) {
for (var i in props) {
if (props.hasOwnProperty(i)) {
o[i] = props[i];
}
}
};
} else {
fail("hasOwnProperty not supported");
}
var initListeners = [];
var moduleInitializers = [];
// Initialization
function init() {
if (api.initialized) {
return;
}
var testRange;
var implementsDomRange = false, implementsTextRange = false;
// First, perform basic feature tests
if (isHostMethod(document, "createRange")) {
testRange = document.createRange();
if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) {
implementsDomRange = true;
}
testRange.detach();
}
var body = isHostObject(document, "body") ? document.body : document.getElementsByTagName("body")[0];
if (body && isHostMethod(body, "createTextRange")) {
testRange = body.createTextRange();
if (isTextRange(testRange)) {
implementsTextRange = true;
}
}
if (!implementsDomRange && !implementsTextRange) {
fail("Neither Range nor TextRange are implemented");
}
api.initialized = true;
api.features = {
implementsDomRange: implementsDomRange,
implementsTextRange: implementsTextRange
};
// Initialize modules and call init listeners
var allListeners = moduleInitializers.concat(initListeners);
for (var i = 0, len = allListeners.length; i < len; ++i) {
try {
allListeners[i](api);
} catch (ex) {
if (isHostObject(window, "console") && isHostMethod(window.console, "log")) {
window.console.log("Init listener threw an exception. Continuing.", ex);
}
}
}
}
// Allow external scripts to initialize this library in case it's loaded after the document has loaded
api.init = init;
// Execute listener immediately if already initialized
api.addInitListener = function(listener) {
if (api.initialized) {
listener(api);
} else {
initListeners.push(listener);
}
};
var createMissingNativeApiListeners = [];
api.addCreateMissingNativeApiListener = function(listener) {
createMissingNativeApiListeners.push(listener);
};
function createMissingNativeApi(win) {
win = win || window;
init();
// Notify listeners
for (var i = 0, len = createMissingNativeApiListeners.length; i < len; ++i) {
createMissingNativeApiListeners[i](win);
}
}
api.createMissingNativeApi = createMissingNativeApi;
/**
* @constructor
*/
function Module(name) {
this.name = name;
this.initialized = false;
this.supported = false;
}
Module.prototype.fail = function(reason) {
this.initialized = true;
this.supported = false;
throw new Error("Module '" + this.name + "' failed to load: " + reason);
};
Module.prototype.warn = function(msg) {
api.warn("Module " + this.name + ": " + msg);
};
Module.prototype.createError = function(msg) {
return new Error("Error in Rangy " + thi