
fitnesse.resources.bootstrap-plus.js.codemirror.wysiwyg.js Maven / Gradle / Ivy
Show all versions of fitnesse-bootstrap-plus-theme
'use strict';
/*jslint devel: true, undef: true, browser: true, continue: true, sloppy: true, stupid: true, vars: true, plusplus: true, regexp: true, maxerr: 50, indent: 4 */
/****
vim:sw=4:et:ai
Wysiwyg editor for FitNesse, based on the Trac Wysiwyg editor written by
OpenGroove and Ciklone, BSD licensed.
General rules are:
- text is rendered to a Fragment node
- div elements separate nested blocks e.g. collapsible sections
****/
var Wysiwyg = function (textarea, options) {
CodeMirror.commands.autocomplete = function (cm) {
cm.showHint({hint: CodeMirror.hint.fitnesse_anyword, closeCharacters: /[()\|\[\]{};:>,]/ });
};
CodeMirror.commands.comment = function (cm) {
$(this).removeClass('cm-variable-3');
$(this).addClass('cm-comment');
let doc = cm.getDoc();
// Get array of lines
let beginLine = (doc.listSelections()[0].head.line < doc.listSelections()[0].anchor.line) ? doc.listSelections()[0].head.line + 1 : doc.listSelections()[0].anchor.line + 1;
let endLine = (doc.listSelections()[0].head.line > doc.listSelections()[0].anchor.line) ? doc.listSelections()[0].head.line + 1 : doc.listSelections()[0].anchor.line + 1;
let selectionRange = doc.getSelection().toString();
let cursor = doc.getCursor();
let lineArray = [];
if (selectionRange !== "") {
// Multi line
for (let i = beginLine; i <= endLine ; i++) {
let line = doc.getLine(i - 1);
lineArray.push({index: i, lineText: line});
}
}
else if(cursor.line) {
// Single line
lineArray.push({index: cursor.line+1, lineText: doc.getLine(cursor.line)});
}
// Add of remove comment
if(lineArray.length !== 0){
// Find commented lines
let amountLines = (endLine - beginLine) + 1;
let amountHashes = 0;
lineArray.forEach(object => {
if(object.lineText.match('#')){
amountHashes++;
}
});
if(amountHashes === amountLines){
// Remove comment
lineArray.forEach(object => {
const newLine = object.lineText.substring(0, object.lineText.length).replace('#','');
doc.replaceRange(newLine, createPosition("from", (object.index-1), 0, null), createPosition("to", (object.index-1), null, newLine.length));
});
}
else {
// Add comment
lineArray.forEach(object => {
//const placement = object.lineText.substring(0, 1) === '|' ? 1 : 0;
const newLine = '#' + object.lineText.substring(0, object.lineText.length);
doc.replaceRange(newLine, createPosition("from", (object.index-1),0, null), createPosition("to", (object.index-1), null, newLine.length));
});
}
}
function createPosition(direction, iteration, beginPlacement, endPlacement) {
return {
line: iteration,
ch: (direction === "from") ? beginPlacement : endPlacement+2
};
}
};
//pre.CodeMirrorLine
CodeMirror.commands.save = function (cm) {
$(document.f).submit();
return false;
};
this.codeMirrorEditor = CodeMirror.fromTextArea(textarea, {
mode: 'fitnesse',
lineNumbers: true,
foldGutter: true,
showCursorWhenSelecting: true,
viewportMargin: Infinity,
gutters: ['CodeMirror-lint-markers', 'CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
extraKeys: {
'Ctrl-Space': 'autocomplete',
'Ctrl-/': 'comment'
}
});
var self = this;
this.textarea = textarea;
this.options = options || {};
this.frame = this.createEditable(document, textarea);
this.contentWindow = window;
this.contentDocument = this.contentWindow.document;
this.textareaToolbar = this.createTextareaToolbar(document);
this.setupTextareaMenuEvents();
this.savedWysiwygHTML = null;
// Hide both editors, so the current one gets properly shown:
this.codeMirrorEditor.getWrapperElement().style.display = this.frame.style.display = 'none';
textarea.parentNode.insertBefore(this.textareaToolbar, textarea);
this.listenerToggleEditor()({initializing: true});
// disable firefox table resizing
try {
this.contentDocument.execCommand('enableObjectResizing', false, false);
} catch (e) {
}
try {
this.contentDocument.execCommand('enableInlineTableEditing', false, false);
} catch (e) {
}
try {
self.execCommand('useCSS', false);
} catch (e1) {
}
try {
self.execCommand('styleWithCSS', false);
} catch (e2) {
}
self.setupEditorEvents();
self.setupFormEvent();
//remember the original content to revert to on cancel
document.originalContent = document.querySelector('.CodeMirror').CodeMirror.doc.getValue();
};
Wysiwyg.getBooleanFromCookie = function (fieldName, defaultValue) {
var result = defaultValue;
var cookies = (document.cookie || '').split(';');
var length = cookies.length;
var i;
for (i = 0; i < length; i++) {
var regex = new RegExp('^\\s*' + fieldName + '=(\\S*)');
var match = regex.exec(cookies[i]);
if (match) {
return (match[1] === 'true');
}
}
return result;
};
Wysiwyg.getWrapOn = function () {
return Wysiwyg.getBooleanFromCookie('textwrapon', false);
};
Wysiwyg.getAutoformat = function () {
return Wysiwyg.getBooleanFromCookie('textautoformat', false);
};
Wysiwyg.getValidateOnSave = function () {
return Wysiwyg.getBooleanFromCookie('validateOnSave', false);
};
Wysiwyg.prototype.listenerToggleEditor = function () {
var self = this;
return function (event) {
var wrappedElement = self.codeMirrorEditor.getWrapperElement();
if (wrappedElement.style.display === 'none') {
if (event && !event.initializing) {
self.loadWikiText();
}
wrappedElement.style.display = '';
wrappedElement.setAttribute('tabIndex', '');
self.syncTextAreaHeight();
self.frame.setAttribute('tabIndex', '-1');
self.textareaToolbar.style.display = '';
self.codeMirrorEditor.refresh();
}
self.focusTextarea();
};
};
Wysiwyg.prototype.setupFormEvent = function () {
var self = this;
$(this.textarea.form).submit(function (event) {
try {
if (Wysiwyg.getAutoformat()) {
var formatter = new WikiFormatter();
self.codeMirrorEditor.setValue(formatter.format(self.codeMirrorEditor.getValue()));
self.codeMirrorEditor.save();
}
if (Wysiwyg.getValidateOnSave()) {
if ($('.toggle-bar').attr('populated') === undefined && $('#collapseCHelpText').attr('populated') === undefined) {
populateContext();
}
var validationMessages = validateTestPage();
if (validationMessages > 0) {
if (!confirm('There are ' + validationMessages + ' validation messages. Save anyway?')) {
return false;
}
}
self.codeMirrorEditor.save();
}
} catch (e) {
Wysiwyg.stopEvent(event);
}
});
};
Wysiwyg.prototype.createEditable = function (d, textarea) {
var frame = d.createElement('div');
frame.setAttribute('class', 'wysiwyg');
frame.setAttribute('contenteditable', 'true');
textarea.parentNode.insertBefore(frame, textarea.nextSibling);
return frame;
};
Wysiwyg.prototype.createTextareaToolbar = function (d) {
var html = [
'',
'',
'',
'',
'',
'',
'',
''];
var div = d.createElement('div');
div.className = 'textarea-toolbar';
div.innerHTML = html.join(' ');
return div;
};
Wysiwyg.prototype.setupTextareaMenuEvents = function () {
var codeMirror = this.codeMirrorEditor;
var container = this.textareaToolbar;
$('#tt-spreadsheet-to-wiki', container).click(function () {
var translator = new SpreadsheetTranslator();
translator.parseExcelTable(codeMirror.getValue());
codeMirror.setValue(translator.getFitNesseTables());
codeMirror.focus();
});
$('#tt-wiki-to-spreadsheet', container).click(function () {
var selection = codeMirror.getValue();
selection = selection.replace(/\r\n/g, '\n');
selection = selection.replace(/\r/g, '\n');
// remove the last | at the end of the line
selection = selection.replace(/\|\n/g, '\n');
// replace all remaining | with \t
selection = selection.replace(/\|/g, '\t');
codeMirror.setValue(selection);
codeMirror.focus();
});
$('#tt-format-wiki', container).click(function () {
var formatter = new WikiFormatter();
var scrollInfo = codeMirror.getScrollInfo();
var cursorInfo = codeMirror.getDoc().getCursor();
codeMirror.setValue(formatter.format(codeMirror.getValue()));
codeMirror.scrollTo(scrollInfo.left, scrollInfo.top);
codeMirror.getDoc().setCursor(cursorInfo.line, cursorInfo.ch);
codeMirror.focus();
});
$('#tt-insert-template', container).click(function () {
var selectedValue = $('#tt-template-map').val();
var inserter = new TemplateInserter();
inserter.insertInto(selectedValue, codeMirror);
codeMirror.focus();
});
function setWrap(wrap) {
if (wrap) {
codeMirror.setOption('lineWrapping', true);
Wysiwyg.setCookie('textwrapon', 'true');
} else {
codeMirror.setOption('lineWrapping', false);
Wysiwyg.setCookie('textwrapon', 'false');
}
}
function setAutoformat(autoformat) {
if (autoformat) {
Wysiwyg.setCookie('textautoformat', 'true');
} else {
Wysiwyg.setCookie('textautoformat', 'false');
}
}
function setValidateOnSave(validateOnSave) {
if (validateOnSave) {
Wysiwyg.setCookie('validateOnSave', 'true');
} else {
Wysiwyg.setCookie('validateOnSave', 'false');
}
}
$('#tt-wrap-text', container)
.change(function () {
setWrap($(this).is(':checked'));
})
.prop('checked', Wysiwyg.getWrapOn())
.change();
$('#tt-autoformat', container)
.change(function () {
setAutoformat($(this).is(':checked'));
})
.prop('checked', Wysiwyg.getAutoformat())
.change();
$('#tt-autovalidate', container)
.change(function () {
setValidateOnSave($(this).is(':checked'));
})
.prop('checked', Wysiwyg.getValidateOnSave())
.change();
};
Wysiwyg.prototype.hideAllMenus = function (except) {
var menus = this.menus;
var length = menus.length;
var i;
for (i = 0; i < length; i++) {
if (menus[i] !== except) {
Wysiwyg.setStyle(menus[i], {display: 'none'});
}
}
};
Wysiwyg.prototype.execDecorate = function (name) {
if (this.selectionContainsTagName('pre')) {
return;
}
var getSelfOrAncestor = Wysiwyg.getSelfOrAncestor;
var position = this.getSelectionPosition();
var ancestor = {};
ancestor.start = getSelfOrAncestor(position.start, /^(?:a|tt)$/);
ancestor.end = getSelfOrAncestor(position.end, /^(?:a|tt)$/);
this.expandSelectionToElement(ancestor);
if (name !== 'escape') {
this.execCommand(name);
} else {
this.execDecorateMonospace();
}
this.selectionChanged();
};
Wysiwyg.prototype.execDecorateMonospace = function () {
var html = this.getSelectionHTML();
if (/^/i.test(html) && /<\/tt>$/i.test(html)) {
html = html.replace(/|<\/tt>/gi, '');
} else {
html = '' + html.replace(/<[a-z]+.*?>|<\/[a-z]+>/gi, '') + '';
}
this.insertHTML(html);
var node = this.contentDocument.getElementById(id);
if (node) {
this.selectNode(node);
}
};
Wysiwyg.prototype.execCommand = function (name, arg, selectionRange) {
this.frame.focus();
if (selectionRange) {
this.selectRange(selectionRange.startContainer, selectionRange.startOffset, selectionRange.endContainer, selectionRange.endOffset);
this.selectionChanged();
}
return this.contentDocument.execCommand(name, false, arg);
};
Wysiwyg.prototype.isHashTable = function (node) {
return node.tagName === 'TABLE' && /hashtable/.test(node.className);
};
Wysiwyg.prototype.setupEditorEvents = function () {
var getSelfOrAncestor = Wysiwyg.getSelfOrAncestor;
var self = this;
var frame = this.frame;
var ime = false;
var inPasteAction = false;
$(frame).keydown(function (event) {
var method = null;
var args = null;
var keyCode = event.keyCode;
switch (keyCode) {
case 0x09: // TAB
var range = self.getSelectionRange();
var stop = false;
var element = getSelfOrAncestor(range.startContainer, /^(?:li|pre|table)$/);
if (element) {
switch (element.tagName.toLowerCase()) {
case 'li':
self.execCommand(event.shiftKey ? 'outdent' : 'indent');
self.selectionChanged();
stop = true;
break;
case 'pre':
self.insertHTML('\t');
stop = true;
break;
case 'table':
if (getSelfOrAncestor(range.endContainer, 'table') === element) {
self.moveFocusInTable(!event.shiftKey);
self.selectionChanged();
stop = true;
}
break;
}
}
if (stop) {
Wysiwyg.stopEvent(event);
}
return;
case 0xe5:
ime = true;
break;
}
switch ((keyCode & 0x00fffff) | (event.ctrlKey ? 0x40000000 : 0)
| (event.shiftKey ? 0x20000000 : 0) | (event.altKey ? 0x10000000 : 0)) {
case 0x40000042: // C-b
method = self.execDecorate;
args = ['bold'];
break;
case 0x40000049: // C-i
method = self.execDecorate;
args = ['italic'];
break;
case 0x40000055: // C-u
method = self.execDecorate;
args = ['underline'];
break;
case 0x40000059: // C-y
method = self.execCommand;
args = ['redo'];
break;
case 0x4000005a: // C-z
method = self.execCommand;
args = ['undo'];
break;
}
if (method !== null) {
Wysiwyg.stopEvent(event);
method.apply(self, args);
self.selectionChanged();
} else if (keyCode && !inPasteAction) {
var focus = self.getFocusNode();
if (!getSelfOrAncestor(focus, /^(?:p|li|h[1-6]|t[dh]|d[td]|pre|blockquote)$/)) {
self.execCommand('formatblock', '');
}
}
});
//noinspection JSUnresolvedFunction
$(frame).keypress(function (event) {
var modifier = (event.ctrlKey ? 0x40000000 : 0)
| (event.shiftKey ? 0x20000000 : 0) | (event.altKey ? 0x10000000 : 0);
switch (event.charCode || event.keyCode) {
case 0x20: // SPACE
self.detectLink(event);
return;
case 0x3e: // ">"
self.detectLink(event);
return;
case 0x0d: // ENTER
self.detectLink(event);
switch (modifier) {
case 0:
var focus = self._getFocusForTable();
if (focus.table && focus.cell) {
self.insertTableRow(true);
Wysiwyg.stopEvent(event);
} else if (self.insertParagraphOnEnter) {
self.insertParagraphOnEnter(event);
}
break;
case 0x20000000: // Shift
if (self.insertLineBreakOnShiftEnter) {
self.insertLineBreakOnShiftEnter(event);
}
break;
}
return;
case 0x7c: // "|"
case 28: // ctrl-"|"
var range = self.getSelectionRange();
var element = getSelfOrAncestor(range.startContainer, 'table');
if (element && !self.isHashTable(element) &&
getSelfOrAncestor(range.endContainer, 'table') === element &&
!getSelfOrAncestor(range.endContainer, /^(?:tt)/)) {
if (event.ctrlKey) {
self.deleteTableCell();
} else {
self.ui_insertTableCell(true);
}
Wysiwyg.stopEvent(event);
}
return;
}
});
//noinspection JSUnresolvedFunction
$(frame).keyup(function (event) {
var keyCode = event.keyCode;
if (ime) {
switch (keyCode) {
case 0x20: // SPACE
self.detectLink(event);
break;
}
ime = false;
}
if (self.getSelectionRange()) {
self.updateElementClassName(self.getSelectionRange().startContainer);
}
self.selectionChanged();
});
//noinspection JSUnresolvedFunction
$(frame).mouseup(function () {
self.selectionChanged();
});
$(frame).click(function () {
self.hideAllMenus();
self.selectionChanged();
});
$(frame).on('touchstart click', 'div.collapsible > p.title', function (event) {
var x = event.pageX - $(this).offset().left;
if (x < parseInt($(this).css('padding-left'))) {
var e = $(this.parentNode);
if (e.hasClass('closed')) {
e.removeClass('closed').addClass('hidden');
} else if (e.hasClass('hidden')) {
e.removeClass('hidden');
} else {
e.addClass('closed');
}
}
// Avoid default open/close handling from being called
event.stopPropagation();
});
$(frame).on('click', 'a', function () {
return false;
});
/* Pasting data is forced in a specific div: pasteddata. In there, the
* raw data is collected and fed to the wikiToDom parser.
*/
$(frame).on('paste', 'body', function () {
function tagNode(node) {
while (node.nodeType === 3 /* TextNode */) {
node = node.parentNode;
}
return node;
}
// Clone state is change in Firefox, need to extract the fields
var range = self.getSelectionRange();
var position = {
startContainer: range.startContainer,
endContainer: range.startContainer === range.endContainer ? range.startContainer.nextSibling : range.endContainer,
sameContainer: range.startContainer === range.endContainer,
atStart: range.startOffset === 0,
atEnd: range.endOffset === range.endContainer.length
};
inPasteAction = true;
// Move tables up to the table they're pasted in
function flattenTable(td) {
var nestedRows = $('tr', td);
if (nestedRows.length) {
var parentTr = getSelfOrAncestor(td, 'tr');
nestedRows.each(function (j, elem) {
$(parentTr).after(elem);
parentTr = $(parentTr).next();
});
self.spanTableColumns(getSelfOrAncestor(parentTr, 'table'));
}
}
function wikitextToOnelinerFragment(wikitext, contentDocument) {
var source = this.wikitextToFragment(wikitext, contentDocument);
var fragment = contentDocument.createDocumentFragment();
this.collectChildNodes(fragment, source.firstChild);
return fragment;
}
// Post processing:
setTimeout(function () {
inPasteAction = false;
var parentTd = getSelfOrAncestor(position.startContainer, 'td');
var wikiText, fragment;
if (parentTd) {
flattenTable(parentTd);
// Make a one-liner for the content pasted in the table cell
wikiText = self.domToWikitext(parentTd, self.options);
fragment = wikitextToOnelinerFragment(wikiText.replace('\n', ' '), self.contentDocument, self.options);
while (parentTd.firstChild) {
parentTd.removeChild(parentTd.firstChild);
}
parentTd.appendChild(fragment);
flattenTable(parentTd);
} else if (position.sameContainer) {
var c = tagNode(position.startContainer);
wikiText = self.domToWikitext(c, {retainNewLines: true});
fragment = self.wikitextToFragment(wikiText, self.contentDocument);
c.parentNode.insertBefore(fragment, c);
c.parentNode.removeChild(c);
// NOTE: At this point the position object is invalid/not useful.
}
}, 20);
});
};
Wysiwyg.prototype.loadWikiText = function () {
this.codeMirrorEditor.setValue(this.domToWikitext(this.frame, this.options));
this.codeMirrorEditor.save();
this.savedWysiwygHTML = null;
};
Wysiwyg.prototype.focusTextarea = function () {
this.codeMirrorEditor.focus();
$(window).resize();
};
Wysiwyg.prototype.syncTextAreaHeight = function () {
var height = this.textarea.offsetHeight;
var frame = this.frame;
if (height > 0 && frame.height !== height) {
frame.height = height;
}
};
Wysiwyg.prototype.normalizeLink = function (link) {
if (/^[\/.#]/.test(link)) {
link = encodeURIComponent(link);
}
if (/^[^"']/.test(link) && /\s/.test(link)) {
if (link.indexOf('"') === -1) {
link = '"' + link + '"';
} else if (link.indexOf('\'') === -1) {
link = '\'' + link + '\'';
} else {
link = '"' + link.replace(/"/g, '%22') + '"';
}
}
return link;
};
Wysiwyg.prototype.detectLink = function (event) {
var range = this.getSelectionRange();
var node = range.startContainer;
if (!node || !range.collapsed) {
return;
}
var getSelfOrAncestor = Wysiwyg.getSelfOrAncestor;
if (getSelfOrAncestor(node, /^(?:a|tt|pre)$/)) {
return;
}
var offset = range.startOffset;
if (node.nodeType !== 3) {
node = node.childNodes[offset];
while (node && node.nodeType !== 3) {
node = node.lastChild;
}
if (!node) {
return;
}
offset = node.nodeValue.length;
} else if (offset === 0) {
node = node.previousSibling;
if (!node || node.nodeType === 1) {
return;
}
offset = node.nodeValue.length;
}
//noinspection JSUnusedAssignment
var startContainer = node;
var endContainer = node;
var text = [node.nodeValue.substring(0, offset)];
while (true) {
if (/[ \t\r\n\f\v]/.test(text[text.length - 1])) {
break;
}
node = node.previousSibling;
if (!node || node.nodeType === 1) {
break;
}
text.push(node.nodeValue);
startContainer = node;
}
text.reverse();
var linkText = text.join('');
if (!linkText) {
return;
}
var pattern = this.wikiDetectLinkPattern;
pattern.lastIndex = /[^ \t\r\n\f\v]*$/.exec(linkText).index;
var match, tmp;
for (tmp = pattern.exec(linkText); tmp; tmp = pattern.exec(linkText)) {
match = tmp;
}
if (!match) {
return;
}
var label = match[0];
var link = this.normalizeLink(label);
var id = this.generateDomId();
var anchor = this.createAnchor(link, label, {id: id, 'data-wysiwyg-autolink': 'true'});
var anonymous = this.contentDocument.createElement('div');
anonymous.appendChild(anchor);
var html = anonymous.innerHTML;
node = endContainer;
var startOffset = match.index;
while (startContainer !== node && startOffset >= startContainer.nodeValue.length) {
startOffset -= startContainer.nodeValue.length;
startContainer = startContainer.nextSibling;
}
var endOffset = startOffset + label.length;
endContainer = startContainer;
while (endContainer !== node && endOffset >= endContainer.nodeValue.length) {
endOffset -= endContainer.nodeValue.length;
endContainer = endContainer.nextSibling;
}
this.selectRange(startContainer, startOffset, endContainer, endOffset);
offset = linkText.length - match.index - label.length;
if (offset === 0) {
switch (event.keyCode) {
case 0x20: // SPACE
this.insertHTML(html + '\u00a0');
Wysiwyg.stopEvent(event);
return;
case 0x0d: // ENTER
if (event.shiftKey) {
if (window.opera || !anonymous.addEventListener) {
this.insertHTML(html + '
');
if (window.opera) {
anchor = this.contentDocument.getElementById(id);
node = anchor.parentNode;
offset = node.childNodes.length;
this.selectRange(node, offset, node, offset);
}
Wysiwyg.stopEvent(event);
return;
}
}
this.insertHTML(html);
anchor = this.contentDocument.getElementById(id);
node = event.shiftKey ? anchor.parentNode : anchor;
offset = node.childNodes.length;
this.selectRange(node, offset, node, offset);
return;
}
}
this.insertHTML(html);
anchor = this.contentDocument.getElementById(id);
node = anchor.nextSibling;
if (!node) {
node = anchor.parentNode;
offset = node.childNodes.length;
}
this.selectRange(node, offset, node, offset);
};
Wysiwyg.prototype.outdent = function () {
if (this.selectionContainsTagName('table') || this.selectionContainsTagName('pre')) {
return;
}
this.execCommand('outdent');
};
Wysiwyg.prototype.indent = function () {
if (this.selectionContainsTagName('table') || this.selectionContainsTagName('pre')) {
return;
}
this.execCommand('indent');
};
Wysiwyg.prototype.formatParagraph = function () {
if (this.selectionContainsTagName('table')) {
return;
}
this.execCommand('formatblock', '
');
this.selectionChanged();
};
Wysiwyg.prototype.formatHeaderBlock = function (name) {
if (this.selectionContainsTagName('table')) {
return;
}
this.execCommand('formatblock', '<' + name + '>');
this.selectionChanged();
};
Wysiwyg.prototype.insertOrderedList = function () {
if (this.selectionContainsTagName('table') || this.selectionContainsTagName('pre')) {
return;
}
this.execCommand('insertorderedlist');
this.selectionChanged();
};
Wysiwyg.prototype.insertUnorderedList = function () {
if (this.selectionContainsTagName('table') || this.selectionContainsTagName('pre')) {
return;
}
this.execCommand('insertunorderedlist');
this.selectionChanged();
};
Wysiwyg.prototype.insertImage = function () {
var self = this;
var insertImage = 'insert-image';
var path = ['files'];
var filesList = $('#' + insertImage + ' ul');
var pathName = $('#' + insertImage + ' pre');
var selectionRange = self.getSelectionRange();
loadFiles();
var insertImageBox = $('#' + insertImage + ' > div');
insertImageBox
.on('click', 'span', function () {
path = Array.prototype.slice.call($(this).data());
loadFiles();
})
.on('click', 'li.directory', function () {
path.push($(this).data().name);
loadFiles();
})
.on('click', 'li.file', function () {
window.location.hash = '';
insertImageBox.off();
self.execCommand('insertimage', pathStr() + $(this).data().name, selectionRange);
})
.on('click', 'button', function () {
var url = $('#' + insertImage + ' input').val();
window.location.hash = '';
insertImageBox.off();
self.execCommand('insertimage', url, selectionRange);
});
window.location.hash = insertImage;
function loadFiles() {
$.getJSON(pathStr(), {responder: 'files', format: 'json'}, function (data) {
breadcrumbHtml();
filesList.empty();
$(data).each(function (i, e) {
var h = $('
' + e.name + (e.directory ? '/' : '') + ' ').attr('class', e.directory ? 'directory' : 'file').data(e);
filesList.append(h);
});
});
}
function pathStr() {
var s = '';
for (var i in path) {
s = s + path[i] + '/';
}
return s;
}
function breadcrumbHtml() {
var s = [];
pathName.empty();
for (var i in path) {
s.push(path[i]);
var d = $.extend({}, s);
d.length = s.length;
pathName.append(' / ');
pathName.append($('' + path[i] + '').data(d));
}
}
};
Wysiwyg.prototype.insertTable = function () {
if (this.selectionContainsTagName('pre')) {
return;
}
var self = this;
function nest(html) {
if (self.selectionContainsTagName('table')) {
return '' + html + '';
}
return html;
}
var id = this.generateDomId();
this.insertHTML(nest(this.tableHTML(id, 2, 2, 'wiki')));
var element = this.contentDocument.getElementById(id);
if (element) {
this.selectNodeContents(element);
}
this.selectionChanged();
};
Wysiwyg.prototype.insertHashTable = function () {
if (this.selectionContainsTagName('pre')) {
return;
}
var id = this.generateDomId();
this.insertHTML(this.tableHTML(id, 2, 2, 'hashtable'));
var element = this.contentDocument.getElementById(id);
if (element) {
element.setAttribute('class', 'hashtable');
this.selectNodeContents(element);
}
this.selectionChanged();
};
Wysiwyg.prototype._tableHTML = function (row, col, className) {
var tr = '' + ((1 << col) - 1).toString(2).replace(/1/g, ' ') + ' ';
var html = [
'', '',
((1 << row) - 1).toString(2).replace(/1/g, tr),
'', '
'];
return html.join('');
};
Wysiwyg.prototype._getFocusForTable = function () {
var hash = {node: null, cell: null, row: null, table: null};
hash.node = this.getFocusNode();
hash.cell = hash.node ? Wysiwyg.getSelfOrAncestor(hash.node, /^t[dh]$/) : null;
hash.row = hash.cell ? Wysiwyg.getSelfOrAncestor(hash.cell, 'tr') : null;
hash.table = hash.row ? Wysiwyg.getSelfOrAncestor(hash.row, 'table') : null;
return hash;
};
Wysiwyg.prototype.ui_insertTableCell = function (after) {
var focus = this._getFocusForTable();
if (focus.table && focus.cell) {
var row = focus.table.rows[focus.row.rowIndex];
var cellIndex = focus.cell.cellIndex + (after ? 1 : 0);
$(focus.cell).removeAttr('colspan');
var cell = this.insertTableCell(row, Math.min(cellIndex, row.cells.length));
this.spanTableColumns(focus.table);
this.selectNodeContents(cell);
this.selectionChanged();
cell.focus();
}
};
Wysiwyg.prototype.insertTableRow = function (after) {
var focus = this._getFocusForTable();
if (focus.table && focus.row) {
var cells = focus.row.getElementsByTagName('td');
var row = focus.table.insertRow(focus.row.rowIndex + (after ? 1 : 0));
var cell;
var j;
for (j = 0; j < cells.length; j++) {
cell = this.insertTableCell(row, 0);
}
this.spanTableColumns(focus.table);
this.selectNodeContents(cell);
this.selectionChanged();
cell.focus();
return row;
}
};
Wysiwyg.prototype.insertTableColumn = function (after) {
var focus = this._getFocusForTable();
if (focus.table && focus.cell) {
var rows = focus.table.rows;
var length = rows.length;
var cellIndex = focus.cell.cellIndex + (after ? 1 : 0);
var i;
for (i = 1; i < length; i++) {
var row = rows[i];
this.insertTableCell(row, Math.min(cellIndex, row.cells.length));
}
this.spanTableColumns(focus.table);
}
};
Wysiwyg.prototype.deleteTableCell = function () {
var focus = this._getFocusForTable();
if (focus.table && focus.cell) {
var row = focus.table.rows[focus.row.rowIndex];
var cellIndex = focus.cell.cellIndex;
if (cellIndex < row.cells.length) {
row.deleteCell(cellIndex);
}
this.spanTableColumns(focus.table);
//this.selectNode(row.cells[cellIndex < row.cells.length ? cellIndex : row.cells.length - 1].firstChild);
this.moveFocusInTable(false);
}
};
Wysiwyg.prototype.deleteTableRow = function () {
var focus = this._getFocusForTable();
if (focus.table && focus.row) {
focus.table.deleteRow(focus.row.rowIndex);
this.spanTableColumns(focus.table);
}
};
Wysiwyg.prototype.deleteTableColumn = function () {
var focus = this._getFocusForTable();
if (focus.table && focus.cell) {
var rows = focus.table.rows;
var length = rows.length;
var cellIndex = focus.cell.cellIndex;
var i;
for (i = 1; i < length; i++) {
var row = rows[i];
if (cellIndex < row.cells.length) {
row.deleteCell(cellIndex);
}
}
this.spanTableColumns(focus.table);
}
};
Wysiwyg.prototype.deleteTable = function () {
var focus = this._getFocusForTable();
if (focus.table) {
$(focus.table).remove();
}
};
Wysiwyg.prototype.spanTableColumns = function (table) {
// Spanning columns fitnesse style.
var rows = $('> tbody > tr', table);
var maxCells = Math.max.apply(Math, $.map(rows, function (e) {
var tds = $('> td', e);
tds.removeAttr('colspan');
return tds.size();
}));
rows.each(function () {
var s = $('> td', this).size();
if (s < maxCells) {
$('td:last', this).attr('colspan', maxCells - s + 1);
}
});
};
Wysiwyg.prototype.moveFocusInTable = function (forward) {
var getSelfOrAncestor = Wysiwyg.getSelfOrAncestor;
var focus = this.getFocusNode();
var element = getSelfOrAncestor(focus, /^(?:t[dhr]|table)$/);
var target, table, rows, cells;
switch (element.tagName.toLowerCase()) {
case 'td':
case 'th':
focus = element;
var row = getSelfOrAncestor(element, 'tr');
cells = row.cells;
if (forward) {
if (focus.cellIndex + 1 < cells.length) {
target = cells[focus.cellIndex + 1];
} else {
table = getSelfOrAncestor(row, /^(?:tbody|table)$/);
rows = table.rows;
target = row.rowIndex + 1 < rows.length ? rows[row.rowIndex + 1].cells[0] : null;
}
} else {
if (focus.cellIndex > 0) {
target = cells[focus.cellIndex - 1];
} else {
table = getSelfOrAncestor(row, /^(?:tbody|table)$/);
rows = table.rows;
if (row.rowIndex > 0) {
cells = rows[row.rowIndex - 1].cells;
target = cells[cells.length - 1];
} else {
target = null;
}
}
}
break;
case 'tr':
cells = element.cells;
target = cells[forward ? 0 : cells.length - 1];
break;
case 'tbody':
case 'table':
rows = element.rows;
cells = rows[forward ? 0 : rows.length - 1].cells;
target = cells[forward ? 0 : cells.length - 1];
break;
}
if (target) {
this.selectNodeContents(target);
} else if (table) {
table = getSelfOrAncestor(table, 'table');
var parent = table.parentNode;
var elements = parent.childNodes;
var length = elements.length;
var offset;
for (offset = 0; offset < length; offset++) {
if (table === elements[offset]) {
if (forward) {
offset++;
}
this.selectRange(parent, offset, parent, offset);
}
}
}
};
Wysiwyg.prototype.formatCodeBlock = function () {
if (this.selectionContainsTagName('table') || this.selectionContainsTagName('pre')) {
return;
}
if (!this.getSelectionText()) {
var node = this.getFocusNode();
while (node.nodeType === 3) {
node = node.parentNode;
}
this.selectNode(node);
}
var fragment = this.getSelectionFragment();
var text = this.domToWikitext(fragment, this.options).replace(/\s+$/, '');
var d = this.contentDocument;
var anonymous = d.createElement('div');
var pre = d.createElement('pre');
pre.className = 'wiki';
anonymous.appendChild(pre);
if (text) {
pre.appendChild(d.createTextNode(text));
}
this.insertHTML(anonymous.innerHTML);
this.selectionChanged();
};
Wysiwyg.prototype.insertHorizontalRule = function () {
if (this.selectionContainsTagName('table') || this.selectionContainsTagName('pre')) {
return;
}
if (!this.execCommand('inserthorizontalrule')) {
this.insertHTML('
');
}
this.selectionChanged();
};
Wysiwyg.prototype.insertCollapsibleSection = function (mode) {
var self = this;
var range = this.getSelectionRange();
var d = this.contentDocument;
function topNode(node) {
while (node.parentNode && node.parentNode !== self.frame) {
node = node.parentNode;
}
return node;
}
var nodes, node;
var start = topNode(range.startContainer);
if (range.startContainer === range.endContainer) {
nodes = range.startOffset === range.endOffset ? [] : [topNode(range.startContainer)];
} else {
var end = topNode(range.endContainer);
nodes = [];
for (node = start; node !== end; node = node.nextSibling) {
nodes.push(node);
}
nodes.push(end);
}
var classes = (mode) ? ' ' + mode : '';
var collapsible = d.createElement('div');
collapsible.setAttribute('class', 'collapsible' + classes);
start.parentNode.insertBefore(collapsible, start);
var sectionName = d.createElement('p');
sectionName.appendChild(d.createTextNode('section title'));
collapsible.appendChild(sectionName);
for (node in nodes) {
//noinspection JSUnfilteredForInLoop
collapsible.appendChild(nodes[node]);
}
this.selectNode(sectionName);
};
Wysiwyg.prototype.deleteCollapsibleSection = function () {
var pos = this.getSelectionPosition();
var startCol = $(pos.start).parents('div.collapsible')[0];
var endCol = $(pos.end).parents('div.collapsible')[0];
if (startCol === endCol) {
$(startCol).before($(startCol).children());
$(startCol).remove();
}
};
Wysiwyg.prototype.createLink = function () {
if (this.selectionContainsTagName('pre')) {
return;
}
var focus = this.getFocusNode();
var anchor = Wysiwyg.getSelfOrAncestor(focus, 'a');
var expand = anchor || Wysiwyg.getSelfOrAncestor(focus, 'tt');
var currLink;
if (anchor) {
var autolink = anchor.getAttribute('data-wysiwyg-autolink');
if (autolink === 'true') {
var pattern = this.wikiDetectLinkPattern;
pattern.lastIndex = 0;
var label = Wysiwyg.getTextContent(anchor);
var match = pattern.exec(label);
if (match && match.index === 0 && match[0].length === label.length) {
currLink = this.normalizeLink(label);
}
}
if (!currLink) {
currLink = anchor.getAttribute('data-wysiwyg-link') || anchor.href;
}
} else {
currLink = '';
}
if (expand) {
this.selectNodeContents(expand);
}
var text = this.getSelectionText() || '';
var newLink = (prompt(text ? 'Enter link:' : 'Insert link:', currLink) || '').replace(/^\s+|\s+$/g, '');
if (newLink && newLink !== currLink) {
text = text || newLink;
newLink = this.normalizeLink(newLink);
var id = this.generateDomId();
var d = this.contentDocument;
var anonymous = d.createElement('div');
anchor = this.createAnchor(newLink, text, {id: id});
anonymous.appendChild(anchor);
this.insertHTML(anonymous.innerHTML);
anchor = d.getElementById(id);
if (anchor) {
this.selectNodeContents(anchor);
}
}
this.selectionChanged();
};
Wysiwyg.prototype.createAnchor = function (link, label, attrs) {
var d = this.contentDocument;
var anchor = d.createElement('a');
var name;
for (name in attrs) {
if (attrs.hasOwnProperty(name)) {
var value = attrs[name];
anchor.setAttribute(name, value);
}
}
anchor.href = link;
anchor.title = link;
anchor.setAttribute('data-wysiwyg-link', link);
if (label) {
anchor.appendChild(d.createTextNode(label));
}
return anchor;
};
Wysiwyg.prototype.createCollapsibleSection = function () {
var collapsible = this.contentDocument.createElement('div');
$(collapsible).addClass('collapsible');
return collapsible;
};
Wysiwyg.prototype.collectChildNodes = function (dest, source) {
var childNodes = source.childNodes;
var i;
for (i = childNodes.length - 1; i >= 0; i--) {
dest.insertBefore(childNodes[i], dest.firstChild);
}
};
Wysiwyg.prototype.generateDomId = function () {
var d = this.contentDocument;
while (true) {
var id = 'tmp-' + (new Date().valueOf().toString(36));
if (!d.getElementById(id)) {
return id;
}
}
};
Wysiwyg.prototype.selectionChanged = function () {
var status = {
strong: false,
em: false,
underline: false,
strike: false,
sub: false,
sup: false,
escape: false,
paragraph: false,
heading1: false,
heading2: false,
heading3: false,
heading4: false,
heading5: false,
heading6: false,
link: false,
ol: false,
ul: false,
outdent: false,
indent: false,
table: false,
code: false,
quote: false,
hr: false,
br: false
};
var tagNameToKey = {
b: 'strong',
i: 'em',
u: 'underline',
del: 'strike',
tt: 'escape',
p: 'paragraph',
h1: 'heading1',
h2: 'heading2',
h3: 'heading3',
h4: 'heading4',
h5: 'heading5',
h6: 'heading6',
a: 'link',
pre: 'code'
};
var position = this.getSelectionPosition();
var node, toolbarButtons, name;
var hashTable = false;
if (position.start) {
node = position.start === position.end ? position.start.firstChild : position.start.nextSibling;
node = node || position.start;
} else {
node = null;
}
while (node) {
if (node.nodeType === 1) {
name = node.tagName.toLowerCase();
if (tagNameToKey.hasOwnProperty(name)) {
name = tagNameToKey[name];
}
status[name] = true;
hashTable |= this.isHashTable(node);
}
node = node.parentNode;
}
toolbarButtons = this.toolbarButtons;
for (name in status) {
if (status.hasOwnProperty(name)) {
var button = toolbarButtons[name];
if (button) {
var parent = button.parentNode;
parent.className = (parent.className || '').replace(/ *\bselected\b|$/, status[name] ? ' selected' : '');
}
}
}
if (hashTable) {
$('.wysiwyg-toolbar .non-table').hide();
$('.wysiwyg-toolbar .in-table').hide();
$('.wysiwyg-toolbar .in-hash-table').show();
} else if (status['table']) {
$('.wysiwyg-toolbar .non-table').hide();
$('.wysiwyg-toolbar .in-table').show();
$('.wysiwyg-toolbar .in-hash-table').hide();
} else {
$('.wysiwyg-toolbar .non-table').show();
$('.wysiwyg-toolbar .in-table').hide();
$('.wysiwyg-toolbar .in-hash-table').hide();
}
$(window).resize();
var styles = ['quote', 'paragraph', 'code', 'heading1',
'heading2', 'heading3', 'heading4', 'heading5', 'heading6'];
var styleButton = toolbarButtons.style;
var styleButtonClass = 'wysiwyg-menu-style';
var i;
for (i = 0; i < styles.length; i++) {
name = styles[i];
if (status[name]) {
styleButtonClass = 'wysiwyg-menu-' + name;
break;
}
}
styleButton.parentNode.className = styleButtonClass;
};
if (window.getSelection) {
Wysiwyg.prototype.insertParagraphOnEnter = function (event) {
var range = this.getSelectionRange();
var node = range.endContainer;
var header = null;
if (node && node.nodeType === 3 && range.endOffset === node.nodeValue.length) {
var nextSibling = node.nextSibling;
if (!nextSibling || nextSibling.tagName.toLowerCase() === 'br') {
while (node) {
if (node.nodeType === 1 && /^h[1-6]$/i.exec(node.tagName)) {
header = node;
break;
}
node = node.parentNode;
}
if (header) {
var parent = header.parentNode;
var childNodes = parent.childNodes;
var length = childNodes.length;
var offset;
for (offset = 0; offset < length; offset++) {
if (childNodes[offset] === header) {
offset++;
break;
}
}
this.selectRange(parent, offset, parent, offset);
this.insertHTML('
');
Wysiwyg.stopEvent(event);
}
}
}
};
Wysiwyg.prototype.tableHTML = function (id, row, col, className) {
var html = this._tableHTML(row, col, className);
return html.replace(/<\/td>/g, '
').replace(//, ' ');
};
Wysiwyg.prototype.insertTableCell = function (row, index) {
var cell = row.insertCell(index);
this.appendBogusLineBreak(cell);
return cell;
};
Wysiwyg.prototype.getFocusNode = function () {
return this.contentWindow.getSelection().focusNode;
};
if (window.opera) {
Wysiwyg.prototype.insertLineBreak = function () {
this.execCommand('inserthtml', '
');
};
Wysiwyg.prototype.insertLineBreakOnShiftEnter = null;
} else if (window.getSelection().setBaseAndExtent) { // Safari 2+
Wysiwyg.prototype.insertLineBreak = function () {
this.execCommand('insertlinebreak');
};
Wysiwyg.prototype.insertLineBreakOnShiftEnter = function (event) {
this.insertLineBreak();
Wysiwyg.stopEvent(event);
};
} else { // Firefox 2+
Wysiwyg.prototype.insertLineBreak = function () {
var event = this.contentDocument.createEvent('KeyboardEvent');
event.initKeyEvent('keypress', true, true, null, false, false, true, false, 0x000d, 0);
this.frame.dispatchEvent(event);
};
Wysiwyg.prototype.insertLineBreakOnShiftEnter = null;
}
if (window.getSelection().removeAllRanges) {
Wysiwyg.prototype.selectNode = function (node) {
var selection = this.contentWindow.getSelection();
selection.removeAllRanges();
var range = this.contentDocument.createRange();
range.selectNode(node);
selection.addRange(range);
};
Wysiwyg.prototype.selectNodeContents = function (node) {
var selection = this.contentWindow.getSelection();
selection.removeAllRanges();
var range = this.contentDocument.createRange();
range.selectNodeContents(node);
selection.addRange(range);
};
Wysiwyg.prototype.selectRange = function (start, startOffset, end, endOffset) {
var selection = this.contentWindow.getSelection();
selection.removeAllRanges();
var range = this.contentDocument.createRange();
range.setStart(start, startOffset);
range.setEnd(end, endOffset);
selection.addRange(range);
};
Wysiwyg.prototype.getNativeSelectionRange = function () {
var selection = this.contentWindow.getSelection();
return selection.rangeCount > 0 ? selection.getRangeAt(0) : null;
};
Wysiwyg.prototype.expandSelectionToElement = function (arg) {
if (arg.start || arg.end) {
var selection = this.contentWindow.getSelection();
var range = this.getNativeSelectionRange() || this.contentDocument.createRange();
selection.removeAllRanges();
if (arg.start) {
range.setStartBefore(arg.start);
}
if (arg.end) {
range.setEndAfter(arg.end);
}
selection.addRange(range);
}
};
Wysiwyg.prototype.insertHTML = function (html) {
this.execCommand('inserthtml', html);
};
} else { // Safari 2
Wysiwyg.prototype.selectNode = function (node) {
var selection = this.contentWindow.getSelection();
var range = this.contentDocument.createRange();
range.selectNode(node);
selection.setBaseAndExtent(range.startContainer, range.startOffset, range.endContainer, range.endOffset);
range.detach();
};
Wysiwyg.prototype.selectNodeContents = function (node) {
this.selectRange(node, 0, node, node.childNodes.length);
};
Wysiwyg.prototype.selectRange = function (start, startOffset, end, endOffset) {
var selection = this.contentWindow.getSelection();
selection.setBaseAndExtent(start, startOffset, end, endOffset);
};
Wysiwyg.prototype.getNativeSelectionRange = function () {
var selection = this.contentWindow.getSelection();
if (selection.anchorNode) {
var range = this.contentDocument.createRange();
range.setStart(selection.baseNode, selection.baseOffset);
range.setEnd(selection.extentNode, selection.extentOffset);
if (range.collapsed && !selection.isCollapsed) {
range.setStart(selection.extentNode, selection.extentOffset);
range.setEnd(selection.baseNode, selection.baseOffset);
}
return range;
}
return null;
};
Wysiwyg.prototype.expandSelectionToElement = function (arg) {
if (arg.start || arg.end) {
var selection = this.contentWindow.getSelection();
var range = this.getNativeSelectionRange();
if (arg.start) {
range.setStartBefore(arg.start);
}
if (arg.end) {
range.setEndAfter(arg.end);
}
selection.setBaseAndExtent(range.startContainer, range.startOffset, range.endContainer, range.endOffset);
range.detach();
}
};
Wysiwyg.prototype.insertHTML = function (html) {
var range = this.getNativeSelectionRange();
if (range) {
var d = this.contentDocument;
var tmp = d.createRange();
tmp.setStart(this.frame, 0);
tmp.setEnd(this.frame, 0);
var fragment = tmp.createContextualFragment(html);
range.deleteContents();
range.insertNode(fragment);
range.detach();
tmp.detach();
}
};
}
Wysiwyg.prototype.getSelectionRange = Wysiwyg.prototype.getNativeSelectionRange;
Wysiwyg.prototype.getSelectionText = function () {
var range = this.getNativeSelectionRange();
return range ? range.toString() : null;
};
Wysiwyg.prototype.getSelectionHTML = function () {
var fragment = this.getSelectionFragment();
var anonymous = this.contentDocument.createElement('div');
anonymous.appendChild(fragment);
return anonymous.innerHTML;
};
Wysiwyg.prototype.getSelectionFragment = function () {
var range = this.getNativeSelectionRange();
return range ? range.cloneContents() : this.contentDocument.createDocumentFragment();
};
Wysiwyg.prototype.getSelectionPosition = function () {
var range = this.getNativeSelectionRange();
var position = {start: null, end: null};
if (range) {
position.start = range.startContainer;
position.end = range.endContainer;
}
return position;
};
Wysiwyg.prototype.selectionContainsTagName = function (name) {
var selection = this.contentWindow.getSelection();
var range = this.getNativeSelectionRange();
if (!range) {
return false;
}
var ancestor = range.commonAncestorContainer;
if (!ancestor) {
return false;
}
if (Wysiwyg.getSelfOrAncestor(ancestor, name)) {
return true;
}
if (ancestor.nodeType !== 1) {
return false;
}
var elements = ancestor.getElementsByTagName(name);
var length = elements.length;
var i;
for (i = 0; i < length; i++) {
if (selection.containsNode(elements[i], true)) {
return true;
}
}
return false;
};
} else if (document.selection) {
// For IE <= 8
Wysiwyg.prototype.insertParagraphOnEnter = null;
Wysiwyg.prototype.insertLineBreak = function () {
this.insertHTML('
');
};
Wysiwyg.prototype.insertLineBreakOnShiftEnter = null;
Wysiwyg.prototype.tableHTML = function (id, row, col, className) {
var html = this._tableHTML(row, col, className);
return html.replace(/ /, ' ');
};
Wysiwyg.prototype.insertTableCell = function (row, index) {
return row.insertCell(index);
};
Wysiwyg.prototype.getFocusNode = function () {
this.frame.focus();
var d = this.contentDocument;
var range = d.selection.createRange();
var node = range.item ? range.item(0) : range.parentElement();
return node.ownerDocument === d ? node : null;
};
Wysiwyg.prototype.selectNode = function (node) {
var d = this.contentDocument;
var body = this.frame;
var range;
d.selection.empty();
try {
range = body.createControlRange();
range.addElement(node);
} catch (e) {
range = body.createTextRange();
range.moveToElementText(node);
}
range.select();
};
Wysiwyg.prototype.selectNodeContents = function (node) {
var d = this.contentDocument;
d.selection.empty();
var range = this.frame.createTextRange();
range.moveToElementText(node);
range.select();
};
Wysiwyg.prototype.selectRange = function (start, startOffset, end, endOffset) {
var d = this.contentDocument;
var body = this.frame;
d.selection.empty();
var range = endPoint(start, startOffset);
if (start !== end || startOffset !== endOffset) {
range.setEndPoint('EndToEnd', endPoint(end, endOffset));
}
range.select();
function endPoint(node, offset) {
var range;
if (node.nodeType === 1) {
var childNodes = node.childNodes;
if (offset >= childNodes.length) {
range = body.createTextRange();
range.moveToElementText(node);
range.collapse(false);
return range;
}
node = childNodes[offset];
if (node.nodeType === 1) {
range = body.createTextRange();
range.moveToElementText(node);
range.collapse(true);
switch (node.tagName.toLowerCase()) {
case 'table':
range.move('character', -1);
break;
}
return range;
}
return endPoint(node, 0);
}
if (node.nodeType !== 3) {
throw 'selectRange: nodeType != @'.replace(/@/, node.nodeType);
}
range = body.createTextRange();
var element = node.previousSibling;
while (element) {
var nodeType = element.nodeType;
if (nodeType === 1) {
range.moveToElementText(element);
range.collapse(false);
break;
}
if (nodeType === 3) {
offset += element.nodeValue.length;
}
element = element.previousSibling;
}
if (!element) {
range.moveToElementText(node.parentNode);
range.collapse(true);
}
if (offset !== 0) {
range.move('character', offset);
}
return range;
}
};
Wysiwyg.prototype.getSelectionRange = function () {
var body = this.frame;
var pseudo = {};
var start = this.getNativeSelectionRange();
if (start.item) {
var element = start.item(0);
var parent = element.parentNode;
var childNodes = parent.childNodes;
var length = childNodes.length;
var i;
for (i = 0; i < length; i++) {
if (childNodes[i] === element) {
pseudo.startOffset = i;
pseudo.endOffset = i + 1;
break;
}
}
pseudo.collapsed = false;
pseudo.startContainer = pseudo.endContainer = parent;
return pseudo;
}
var end = start.duplicate();
pseudo.collapsed = start.compareEndPoints('StartToEnd', end) === 0;
start.collapse(true);
end.collapse(false);
function nextElement(range) {
var parent = range.parentElement();
var childNodes = parent.childNodes;
var length = childNodes.length;
var i;
for (i = 0; i < length; i++) {
var node = childNodes[i];
if (node.nodeType === 1) {
var tmp = body.createTextRange();
tmp.moveToElementText(node);
if (range.compareEndPoints('EndToStart', tmp) <= 0) {
return node;
}
}
}
return null;
}
function nodeOffset(range, parent, element, index, length) {
var tmp = body.createTextRange();
var len;
tmp.moveToElementText(element || parent);
tmp.collapse(!!element);
tmp.move('character', -index);
if (!element) {
length++;
}
for (len = length; len >= 0; len--) {
if (tmp.compareEndPoints('EndToStart', range) === 0) {
return len;
}
tmp.move('character', -1);
}
return null;
}
function setContainerOffset(range, containerKey, offsetKey) {
var parent = range.parentElement();
var element = nextElement(range);
var index = 0;
var node = element ? element.previousSibling : parent.lastChild;
var offset, length;
while (node && node.nodeType === 3) {
length = node.nodeValue.length;
offset = nodeOffset(range, parent, element, index, length);
if (offset !== null) {
pseudo[containerKey] = node;
pseudo[offsetKey] = offset;
return;
}
index += length;
node = node.previousSibling;
}
var childNodes = parent.childNodes;
length = childNodes.length;
if (length > 0) {
pseudo[containerKey] = parent;
pseudo[offsetKey] = containerKey === 'startContainer' ? 0 : length - 1;
return;
}
element = parent;
parent = element.parentNode;
childNodes = parent.childNodes;
length = childNodes.length;
for (offset = 0; offset < length; offset++) {
if (element === childNodes[offset]) {
pseudo[containerKey] = parent;
pseudo[offsetKey] = offset;
return;
}
}
}
setContainerOffset(start, 'startContainer', 'startOffset');
setContainerOffset(end, 'endContainer', 'endOffset');
return pseudo;
};
Wysiwyg.prototype.getNativeSelectionRange = function () {
this.contentWindow.focus();
return this.contentDocument.selection.createRange();
};
Wysiwyg.prototype.getSelectionText = function () {
var range = this.getNativeSelectionRange();
if (range) {
return range.item ? range.item(0).innerText : range.text;
}
return null;
};
Wysiwyg.prototype.getSelectionHTML = function () {
var range = this.getNativeSelectionRange();
if (range) {
return range.item ? range.item(0).innerHTML : range.htmlText;
}
return null;
};
Wysiwyg.prototype.getSelectionFragment = function () {
var d = this.contentDocument;
var fragment = d.createDocumentFragment();
var anonymous = d.createElement('div');
anonymous.innerHTML = this.getSelectionHTML();
this.collectChildNodes(fragment, anonymous);
return fragment;
};
Wysiwyg.prototype.getSelectionPosition = function () {
this.frame.focus();
var d = this.contentDocument;
var range = d.selection.createRange();
var startNode = null;
var endNode = null;
if (range.item) {
if (range.item(0).ownerDocument === d) {
startNode = range.item(0);
endNode = range.item(range.length - 1);
}
} else {
if (range.parentElement().ownerDocument === d) {
var startRange = range.duplicate();
startRange.collapse(true);
startNode = startRange.parentElement();
var endRange = range.duplicate();
endRange.collapse(false);
endNode = endRange.parentElement();
}
}
return {start: startNode, end: endNode};
};
Wysiwyg.prototype.expandSelectionToElement = function (arg) {
this.frame.focus();
var d = this.contentDocument;
var body = this.frame;
var range = d.selection.createRange();
var tmp;
if (arg.start) {
tmp = body.createTextRange();
tmp.moveToElementText(arg.start);
range.setEndPoint('StartToStart', tmp);
}
if (arg.end) {
tmp = body.createTextRange();
tmp.moveToElementText(arg.end);
range.setEndPoint('EndToEnd', tmp);
}
if (tmp) {
range.select();
}
};
Wysiwyg.prototype.selectionContainsTagName = function (name) {
this.frame.focus();
var d = this.contentDocument;
var selection = d.selection;
var range = selection.createRange();
var parent = range.item ? range.item(0) : range.parentElement();
if (!parent) {
return false;
}
if (Wysiwyg.getSelfOrAncestor(parent, name)) {
return true;
}
var elements = parent.getElementsByTagName(name);
var length = elements.length;
var i;
for (i = 0; i < length; i++) {
var testRange = selection.createRange();
testRange.moveToElementText(elements[i]);
if (range.compareEndPoints('StartToEnd', testRange) <= 0
&& range.compareEndPoints('EndToStart', testRange) >= 0) {
return true;
}
}
return false;
};
Wysiwyg.prototype.insertHTML = function (html) {
this.frame.focus();
var selection = this.contentDocument.selection;
var range = selection.createRange();
range.pasteHTML(html.replace(/\t/g, ' '));
range.collapse(false);
range.select();
range = this.contentDocument.selection.createRange();
};
} else {
Wysiwyg.prototype.insertParagraphOnEnter = null;
Wysiwyg.prototype.insertLineBreak = function () {
};
Wysiwyg.prototype.insertTableCell = function () {
return null;
};
Wysiwyg.prototype.getFocusNode = function () {
return null;
};
Wysiwyg.prototype.selectNode = function (node) {
};
Wysiwyg.prototype.selectNodeContents = function () {
return null;
};
Wysiwyg.prototype.selectRange = function (start, startOffset, end, endOffset) {
};
Wysiwyg.prototype.getSelectionRange = function () {
return null;
};
Wysiwyg.prototype.getNativeSelectionRange = function () {
return null;
};
Wysiwyg.prototype.getSelectionText = function () {
return null;
};
Wysiwyg.prototype.getSelectionHTML = function () {
return null;
};
Wysiwyg.prototype.getSelectionFragment = function () {
return null;
};
Wysiwyg.prototype.getSelectionPosition = function () {
return null;
};
Wysiwyg.prototype.expandSelectionToElement = function () {
};
Wysiwyg.prototype.selectionContainsTagName = function () {
return false;
};
Wysiwyg.prototype.insertHTML = function (html) {
};
}
Wysiwyg.prototype._treeWalkEmulation = function (root, iterator) {
if (!root.firstChild) {
iterator(null);
return;
}
var element = root;
while (element) {
if (element.firstChild) {
element = element.firstChild;
} else if (element.nextSibling) {
element = element.nextSibling;
} else {
while (true) {
element = element.parentNode;
if (element === root || !element) {
iterator(null);
return;
}
if (element.nextSibling) {
element = element.nextSibling;
break;
}
}
}
iterator(element);
}
};
if (document.createTreeWalker) {
Wysiwyg.prototype.treeWalk = function (root, iterator) {
var walker = root.ownerDocument.createTreeWalker(
root,
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
null,
true
);
while (walker.nextNode()) {
iterator(walker.currentNode);
}
iterator(null);
};
} else {
Wysiwyg.prototype.treeWalk = Wysiwyg.prototype._treeWalkEmulation;
}
Wysiwyg.count = 0;
Wysiwyg.newInstance = function (textarea, options) {
return new Wysiwyg(textarea, options);
};
Wysiwyg.getOptions = function () {
var options = {};
//noinspection JSUnresolvedVariable
if (window._wysiwyg) {
options = window._wysiwyg;
}
return options;
};
Wysiwyg.getEditorMode = function () {
if (Wysiwyg.editorMode) {
return Wysiwyg.editorMode;
}
var mode = null;
var cookies = (document.cookie || '').split(';');
var length = cookies.length;
var i;
for (i = 0; i < length; i++) {
var match = /^\s*wysiwyg=(\S*)/.exec(cookies[i]);
if (match) {
switch (match[1]) {
case 'wysiwyg':
mode = match[1];
break;
default: // "textarea"
mode = null;
break;
}
break;
}
}
Wysiwyg.editorMode = mode || 'textarea';
return Wysiwyg.editorMode;
};
Wysiwyg.setCookie = function (key, val) {
var now = new Date();
var expires = new Date(now.getTime() + 365 * 86400 * 1000);
var pieces = [key + '=' + val,
'expires=' + expires.toUTCString()];
document.cookie = pieces.join(';');
};
Wysiwyg.removeEvent = function (element, type, func) {
jQuery(element).unbind(type, func);
};
Wysiwyg.stopEvent = function (event) {
if (event.preventDefault) {
event.preventDefault();
event.stopPropagation();
} else {
event.returnValue = false;
event.cancelBubble = true;
}
};
Wysiwyg.setStyle = function (element, object) {
var style = element.style;
var name;
for (name in object) {
if (object.hasOwnProperty(name)) {
style[name] = object[name];
}
}
};
if (document.defaultView) {
Wysiwyg.getStyle = function (element, name) {
var value = element.style[name];
if (!value) {
var style = element.ownerDocument.defaultView.getComputedStyle(element, null);
value = style ? style[name] : null;
}
return value;
};
} else {
Wysiwyg.getStyle = function (element, name) {
return element.style[name] || element.currentStyle[name];
};
}
// Find parent element of type 'name', stop if an element of type 'notName' is found.
Wysiwyg.getSelfOrAncestor = function (element, name, notName) {
var target = element;
var d = element.ownerDocument;
if (name instanceof RegExp) {
while (target && target !== d) {
switch (target.nodeType) {
case 1: // element
if (name.test(target.tagName.toLowerCase())) {
return target;
}
break;
case 11: // fragment
return null;
}
target = target.parentNode;
}
} else {
name = name.toLowerCase();
while (target && target !== d) {
switch (target.nodeType) {
case 1: // element
if (target.tagName.toLowerCase() === name) {
return target;
} else if (target.tagName.toLowerCase() === notName || target.tagName.toLowerCase() === 'div') {
return null;
}
break;
case 11: // fragment
return null;
}
target = target.parentNode;
}
}
return null;
};
Wysiwyg.getTextContent = (function () {
var anonymous = document.createElement('div');
if (typeof anonymous.textContent !== undefined) {
return function (element) {
return element.textContent;
};
} else if (typeof anonymous.innerText !== undefined) {
return function (element) {
return element.innerText;
};
} else {
return function () {
return null;
};
}
})();
Wysiwyg.initialize = function (textArea) {
if ('replace'.replace(/[a-e]/g, function () {
return '*';
}) !== 'r*pl***') {
return;
}
if (typeof document.designMode === undefined) {
return;
}
var options = Wysiwyg.getOptions();
return Wysiwyg.newInstance(textArea, options);
};
// vim:et:ai:ts=4
© 2015 - 2025 Weber Informatics LLC | Privacy Policy