Diff
checker
Text
Text
Bilder
Dokumente
Excel
Ordner
Legal
Enterprise
Desktop-App
Preise
Einloggen
Diffchecker Desktop herunterladen
Texte vergleichen
Finde den Unterschied zwischen zwei Textdateien
Werkzeuge
Verlauf
Live-Editor
Leerzeichen ausblenden
Gleiches ausblenden
Zeilenumbruch aus
Ansicht
Zweispaltig
Einspaltig
Vergleichsgenauigkeit
Intelligent
Wort
Zeichen
Textstile
Darstellung ändern
Syntaxhervorhebung
Syntax auswählen
Ignorieren
Text umwandeln
Zur ersten Änderung
Eingabe bearbeiten
Diffchecker Desktop
Der sicherste Weg, Diffchecker zu nutzen. Hol dir die Desktop-App: Deine Diffs verlassen nie deinen Computer!
Desktop holen
Untitled diff
Erstellt
vor 11 Jahren
Diff läuft nie ab
Löschen
Exportieren
Teilen
Erklären
13 Entfernungen
Zeilen
Gesamt
Entfernt
Zeichen
Gesamt
Entfernt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
332 Zeilen
Kopieren
47 Hinzufügungen
Zeilen
Gesamt
Hinzugefügt
Zeichen
Gesamt
Hinzugefügt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
348 Zeilen
Kopieren
/* @fileoverview
/* @fileoverview
* Provides full Bootstrap based, multi-instance WYSIWYG editor.
* Provides full Bootstrap based, multi-instance WYSIWYG editor.
*
*
* "Name" = 'bootstrap-wysiwyg'
* "Name" = 'bootstrap-wysiwyg'
Kopieren
Kopiert
Kopieren
Kopiert
* "Author" = 'Various, see LICEN
C
E'
* "Author" = 'Various, see LICEN
S
E'
* "Version" = '1.0.
3-rc
'
* "Version" = '1.0.
4
'
* "About" = 'A tiny Bootstrap and jQuery based WYSIWYG rich text editor based on the browser function execCommand.'
* "About" = 'A tiny Bootstrap and jQuery based WYSIWYG rich text editor based on the browser function execCommand.'
*/
*/
Kopieren
Kopiert
Kopieren
Kopiert
(function ($) {
(function ($) {
'use strict';
'use strict';
/** underscoreThrottle()
/** underscoreThrottle()
* From underscore http://underscorejs.org/docs/underscore.html
* From underscore http://underscorejs.org/docs/underscore.html
*/
*/
Kopieren
Kopiert
Kopieren
Kopiert
var underscoreThrottle = function(func, wait
) {
var underscoreThrottle = function(func, wait
, options
) {
var context, args,
timeout
, result
;
var context, args,
result;
var
timeout
= null
;
var previous = 0;
var previous = 0;
Kopieren
Kopiert
Kopieren
Kopiert
if (!options) {
options = {};
}
var later = function() {
var later = function() {
Kopieren
Kopiert
Kopieren
Kopiert
previous =
new Date
();
previous =
options.leading === false ? 0 : $.now
();
timeout = null;
timeout = null;
result = func.apply(context, args);
result = func.apply(context, args);
Kopieren
Kopiert
Kopieren
Kopiert
if (!timeout) {
context = args = null;
}
};
};
return function() {
return function() {
Kopieren
Kopiert
Kopieren
Kopiert
var now =
new Date
();
var now =
$.now
();
if (!previous && options.leading === false) {
previous = now;
}
var remaining = wait - (now - previous);
var remaining = wait - (now - previous);
context = this;
context = this;
args = arguments;
args = arguments;
Kopieren
Kopiert
Kopieren
Kopiert
if (remaining <= 0
) {
if (remaining <= 0
|| remaining > wait) {
clearTimeout(timeout);
if (timeout
) {
timeout = null;
clearTimeout(timeout);
timeout = null;
}
previous = now;
previous = now;
result = func.apply(context, args);
result = func.apply(context, args);
Kopieren
Kopiert
Kopieren
Kopiert
}
else if (!timeout
) {
if (!timeout) {
context = args = null;
}
}
else if (!timeout
&& options.trailing !== false
) {
timeout = setTimeout(later, remaining);
timeout = setTimeout(later, remaining);
}
}
return result;
return result;
};
};
};
};
var readFileIntoDataUrl = function (fileInfo) {
var readFileIntoDataUrl = function (fileInfo) {
var loader = $.Deferred(),
var loader = $.Deferred(),
fReader = new FileReader();
fReader = new FileReader();
fReader.onload = function (e) {
fReader.onload = function (e) {
loader.resolve(e.target.result);
loader.resolve(e.target.result);
};
};
fReader.onerror = loader.reject;
fReader.onerror = loader.reject;
fReader.onprogress = loader.notify;
fReader.onprogress = loader.notify;
fReader.readAsDataURL(fileInfo);
fReader.readAsDataURL(fileInfo);
return loader.promise();
return loader.promise();
};
};
$.fn.cleanHtml = function (o) {
$.fn.cleanHtml = function (o) {
if ( $(this).data("wysiwyg-html-mode") === true ) {
if ( $(this).data("wysiwyg-html-mode") === true ) {
$(this).html($(this).text());
$(this).html($(this).text());
$(this).attr('contenteditable',true);
$(this).attr('contenteditable',true);
$(this).data('wysiwyg-html-mode',false);
$(this).data('wysiwyg-html-mode',false);
}
}
// Strip the images with src="data:image/.." out;
// Strip the images with src="data:image/.." out;
if ( o === true && $(this).parent().is("form") ) {
if ( o === true && $(this).parent().is("form") ) {
var gGal = $(this).html;
var gGal = $(this).html;
if ( $(gGal).has( "img" ).length ) {
if ( $(gGal).has( "img" ).length ) {
var gImages = $( "img", $(gGal));
var gImages = $( "img", $(gGal));
var gResults = [];
var gResults = [];
var gEditor = $(this).parent();
var gEditor = $(this).parent();
$.each(gImages, function(i,v) {
$.each(gImages, function(i,v) {
if ( $(v).attr('src').match(/^data:image\/.*$/) ) {
if ( $(v).attr('src').match(/^data:image\/.*$/) ) {
gResults.push(gImages[i]);
gResults.push(gImages[i]);
$(gEditor).prepend("<input value='"+$(v).attr('src')+"' type='hidden' name='postedimage/"+i+"' />");
$(gEditor).prepend("<input value='"+$(v).attr('src')+"' type='hidden' name='postedimage/"+i+"' />");
$(v).attr('src', 'postedimage/'+i);
$(v).attr('src', 'postedimage/'+i);
}});
}});
}
}
}
}
var html = $(this).html();
var html = $(this).html();
return html && html.replace(/(<br>|\s|<div><br><\/div>| )*$/, '');
return html && html.replace(/(<br>|\s|<div><br><\/div>| )*$/, '');
};
};
$.fn.wysiwyg = function (userOptions) {
$.fn.wysiwyg = function (userOptions) {
var editor = this,
var editor = this,
Kopieren
Kopiert
Kopieren
Kopiert
wrapper = $(editor).parent(),
selectedRange,
selectedRange,
options,
options,
toolbarBtnSelector,
toolbarBtnSelector,
updateToolbar = function () {
updateToolbar = function () {
if (options.activeToolbarClass) {
if (options.activeToolbarClass) {
Kopieren
Kopiert
Kopieren
Kopiert
$(options.toolbarSelector
,wrapper
).find(toolbarBtnSelector).each(
underscoreThrottle(
function () {
$(options.toolbarSelector
).find(toolbarBtnSelector).each(
function () {
var commandArr = $(this).data(options.commandRole).split(' '),
var commandArr = $(this).data(options.commandRole).split(' '),
command = commandArr[0];
command = commandArr[0];
// If the command has an argument and its value matches this button. == used for string/number comparison
// If the command has an argument and its value matches this button. == used for string/number comparison
if (commandArr.length > 1 && document.queryCommandEnabled(command) && document.queryCommandValue(command) === commandArr[1]) {
if (commandArr.length > 1 && document.queryCommandEnabled(command) && document.queryCommandValue(command) === commandArr[1]) {
$(this).addClass(options.activeToolbarClass);
$(this).addClass(options.activeToolbarClass);
// Else if the command has no arguments and it is active
// Else if the command has no arguments and it is active
} else if (commandArr.length === 1 && document.queryCommandEnabled(command) && document.queryCommandState(command)) {
} else if (commandArr.length === 1 && document.queryCommandEnabled(command) && document.queryCommandState(command)) {
$(this).addClass(options.activeToolbarClass);
$(this).addClass(options.activeToolbarClass);
// Else the command is not active
// Else the command is not active
} else {
} else {
$(this).removeClass(options.activeToolbarClass);
$(this).removeClass(options.activeToolbarClass);
}
}
Kopieren
Kopiert
Kopieren
Kopiert
}
, options.keypressTimeout)
);
}
);
}
}
},
},
execCommand = function (commandWithArgs, valueArg) {
execCommand = function (commandWithArgs, valueArg) {
var commandArr = commandWithArgs.split(' '),
var commandArr = commandWithArgs.split(' '),
command = commandArr.shift(),
command = commandArr.shift(),
args = commandArr.join(' ') + (valueArg || '');
args = commandArr.join(' ') + (valueArg || '');
var parts = commandWithArgs.split('-');
var parts = commandWithArgs.split('-');
if ( parts.length === 1 ) {
if ( parts.length === 1 ) {
Kopieren
Kopiert
Kopieren
Kopiert
document.execCommand(command,
0
, args)
;
underscoreThrottle(
document.execCommand(command,
false
, args)
, options.keypressTimeout)
;
}
}
else if ( parts[0] === 'format' && parts.length === 2 ) {
else if ( parts[0] === 'format' && parts.length === 2 ) {
Kopieren
Kopiert
Kopieren
Kopiert
document.execCommand('formatBlock', false, parts[1] )
;
underscoreThrottle(
document.execCommand('formatBlock', false, parts[1] )
, options.keypressTimeout)
;
}
}
editor.trigger('change');
editor.trigger('change');
updateToolbar();
updateToolbar();
},
},
bindHotkeys = function (hotKeys) {
bindHotkeys = function (hotKeys) {
$.each(hotKeys, function (hotkey, command) {
$.each(hotKeys, function (hotkey, command) {
editor.keydown(hotkey, function (e) {
editor.keydown(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.preventDefault();
e.stopPropagation();
e.stopPropagation();
Kopieren
Kopiert
Kopieren
Kopiert
execCommand(command)
;
underscoreThrottle(
execCommand(command)
, options.keypressTimeout)
;
}
}
}).keyup(hotkey, function (e) {
}).keyup(hotkey, function (e) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
if (editor.attr('contenteditable') && editor.is(':visible')) {
e.preventDefault();
e.preventDefault();
e.stopPropagation();
e.stopPropagation();
}
}
});
});
});
});
editor.keyup(function(){ editor.trigger('change'); });
editor.keyup(function(){ editor.trigger('change'); });
},
},
getCurrentRange = function () {
getCurrentRange = function () {
var sel, range;
var sel, range;
if (window.getSelection) {
if (window.getSelection) {
sel = window.getSelection();
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range = sel.getRangeAt(0);
}
}
} else if (document.selection) {
} else if (document.selection) {
range = document.selection.createRange();
range = document.selection.createRange();
} return range;
} return range;
},
},
saveSelection = function () {
saveSelection = function () {
selectedRange = getCurrentRange();
selectedRange = getCurrentRange();
},
},
restoreSelection = function () {
restoreSelection = function () {
var selection;
var selection;
if (window.getSelection || document.createRange) {
if (window.getSelection || document.createRange) {
selection = window.getSelection();
selection = window.getSelection();
if (selectedRange) {
if (selectedRange) {
try {
try {
selection.removeAllRanges();
selection.removeAllRanges();
} catch (ex) {
} catch (ex) {
document.body.createTextRange().select();
document.body.createTextRange().select();
document.selection.empty();
document.selection.empty();
}
}
selection.addRange(selectedRange);
selection.addRange(selectedRange);
}
}
}
}
else if (document.selection && selectedRange) {
else if (document.selection && selectedRange) {
selectedRange.select();
selectedRange.select();
}
}
},
},
// Adding Toggle HTML based on the work by @jd0000, but cleaned up a little to work in this context.
// Adding Toggle HTML based on the work by @jd0000, but cleaned up a little to work in this context.
toggleHtmlEdit = function() {
toggleHtmlEdit = function() {
if ( $(editor).data("wysiwyg-html-mode") !== true ) {
if ( $(editor).data("wysiwyg-html-mode") !== true ) {
var oContent = $(editor).html();
var oContent = $(editor).html();
var editorPre = $( "<pre />" );
var editorPre = $( "<pre />" );
$(editorPre).append( document.createTextNode( oContent ) );
$(editorPre).append( document.createTextNode( oContent ) );
$(editorPre).attr('contenteditable',true);
$(editorPre).attr('contenteditable',true);
$(editor).html(' ');
$(editor).html(' ');
$(editor).append($(editorPre));
$(editor).append($(editorPre));
$(editor).attr('contenteditable', false);
$(editor).attr('contenteditable', false);
$(editor).data("wysiwyg-html-mode", true);
$(editor).data("wysiwyg-html-mode", true);
$(editorPre).focus();
$(editorPre).focus();
}
}
else {
else {
$(editor).html($(editor).text());
$(editor).html($(editor).text());
$(editor).attr('contenteditable',true);
$(editor).attr('contenteditable',true);
$(editor).data('wysiwyg-html-mode',false);
$(editor).data('wysiwyg-html-mode',false);
$(editor).focus();
$(editor).focus();
}
}
},
},
insertFiles = function (files) {
insertFiles = function (files) {
editor.focus();
editor.focus();
$.each(files, function (idx, fileInfo) {
$.each(files, function (idx, fileInfo) {
if (/^image\//.test(fileInfo.type)) {
if (/^image\//.test(fileInfo.type)) {
$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
$.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) {
Kopieren
Kopiert
Kopieren
Kopiert
execCommand('insertimage', dataUrl)
;
underscoreThrottle(
execCommand('insertimage', dataUrl)
, options.keypressTimeout)
;
editor.trigger('image-inserted');
editor.trigger('image-inserted');
}).fail(function (e) {
}).fail(function (e) {
options.fileUploadError("file-reader", e);
options.fileUploadError("file-reader", e);
});
});
} else {
} else {
options.fileUploadError("unsupported-file-type", fileInfo.type);
options.fileUploadError("unsupported-file-type", fileInfo.type);
}
}
});
});
},
},
markSelection = function (input, color) {
markSelection = function (input, color) {
restoreSelection();
restoreSelection();
if (document.queryCommandSupported('hiliteColor')) {
if (document.queryCommandSupported('hiliteColor')) {
Kopieren
Kopiert
Kopieren
Kopiert
document.execCommand('hiliteColor',
0
, color || 'transparent')
;
underscoreThrottle(
document.execCommand('hiliteColor',
false
, color || 'transparent')
, options.keypressTimeout)
;
}
}
saveSelection();
saveSelection();
input.data(options.selectionMarker, color);
input.data(options.selectionMarker, color);
},
},
bindToolbar = function (toolbar, options) {
bindToolbar = function (toolbar, options) {
Kopieren
Kopiert
Kopieren
Kopiert
toolbar.find(toolbarBtnSelector
, wrapper
).click(function () {
toolbar.find(toolbarBtnSelector
).click(function () {
restoreSelection();
restoreSelection();
editor.focus();
editor.focus();
if ($(this).data(options.commandRole) === 'html') {
if ($(this).data(options.commandRole) === 'html') {
toggleHtmlEdit();
toggleHtmlEdit();
}
}
else {
else {
Kopieren
Kopiert
Kopieren
Kopiert
execCommand($(this).data(options.commandRole))
;
underscoreThrottle(
execCommand($(this).data(options.commandRole))
, options.keypressTimeout)
;
}
}
saveSelection();
saveSelection();
});
});
toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
toolbar.find('[data-toggle=dropdown]').click(restoreSelection);
toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () {
var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */
this.value = '';
this.value = '';
restoreSelection();
restoreSelection();
if (newValue) {
if (newValue) {
editor.focus();
editor.focus();
Kopieren
Kopiert
Kopieren
Kopiert
execCommand($(this).data(options.commandRole), newValue)
;
underscoreThrottle(
execCommand($(this).data(options.commandRole), newValue)
, options.keypressTimeout)
;
}
}
saveSelection();
saveSelection();
}).on('focus', function () {
}).on('focus', function () {
var input = $(this);
var input = $(this);
if (!input.data(options.selectionMarker)) {
if (!input.data(options.selectionMarker)) {
markSelection(input, options.selectionColor);
markSelection(input, options.selectionColor);
input.focus();
input.focus();
}
}
}).on('blur', function () {
}).on('blur', function () {
var input = $(this);
var input = $(this);
if (input.data(options.selectionMarker)) {
if (input.data(options.selectionMarker)) {
markSelection(input, false);
markSelection(input, false);
}
}
});
});
toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () {
restoreSelection();
restoreSelection();
if (this.type === 'file' && this.files && this.files.length > 0) {
if (this.type === 'file' && this.files && this.files.length > 0) {
insertFiles(this.files);
insertFiles(this.files);
}
}
saveSelection();
saveSelection();
this.value = '';
this.value = '';
});
});
},
},
initFileDrops = function () {
initFileDrops = function () {
editor.on('dragenter dragover', false)
editor.on('dragenter dragover', false)
.on('drop', function (e) {
.on('drop', function (e) {
var dataTransfer = e.originalEvent.dataTransfer;
var dataTransfer = e.originalEvent.dataTransfer;
e.stopPropagation();
e.stopPropagation();
e.preventDefault();
e.preventDefault();
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) {
insertFiles(dataTransfer.files);
insertFiles(dataTransfer.files);
}
}
});
});
};
};
options = $.extend(true, {}, $.fn.wysiwyg.defaults, userOptions);
options = $.extend(true, {}, $.fn.wysiwyg.defaults, userOptions);
toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']';
bindHotkeys(options.hotKeys);
bindHotkeys(options.hotKeys);
// Support placeholder attribute on the DIV
// Support placeholder attribute on the DIV
if ($(this).attr('placeholder') !== '') {
if ($(this).attr('placeholder') !== '') {
$(this).addClass('placeholderText');
$(this).addClass('placeholderText');
$(this).html($(this).attr('placeholder'));
$(this).html($(this).attr('placeholder'));
$(this).bind('focus',function() {
$(this).bind('focus',function() {
if ( $(this).attr('placeholder') !== '' && $(this).text() === $(this).attr('placeholder') ) {
if ( $(this).attr('placeholder') !== '' && $(this).text() === $(this).attr('placeholder') ) {
$(this).removeClass('placeholderText');
$(this).removeClass('placeholderText');
$(this).html('');
$(this).html('');
}
}
});
});
$(this).bind('blur',function() {
$(this).bind('blur',function() {
if ( $(this).attr('placeholder') !== '' && $(this).text() === '' ) {
if ( $(this).attr('placeholder') !== '' && $(this).text() === '' ) {
$(this).addClass('placeholderText');
$(this).addClass('placeholderText');
$(this).html($(this).attr('placeholder'));
$(this).html($(this).attr('placeholder'));
}
}
});
});
}
}
if (options.dragAndDropImages) {
if (options.dragAndDropImages) {
initFileDrops();
initFileDrops();
}
}
bindToolbar($(options.toolbarSelector), options);
bindToolbar($(options.toolbarSelector), options);
editor.attr('contenteditable', true)
editor.attr('contenteditable', true)
.on('mouseup keyup mouseout', function () {
.on('mouseup keyup mouseout', function () {
saveSelection();
saveSelection();
updateToolbar();
updateToolbar();
});
});
$(window).bind('touchend', function (e) {
$(window).bind('touchend', function (e) {
var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
var isInside = (editor.is(e.target) || editor.has(e.target).length > 0),
currentRange = getCurrentRange(),
currentRange = getCurrentRange(),
clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset);
if (!clear || isInside) {
if (!clear || isInside) {
saveSelection();
saveSelection();
updateToolbar();
updateToolbar();
}
}
});
});
return this;
return this;
};
};
$.fn.wysiwyg.defaults = {
$.fn.wysiwyg.defaults = {
hotKeys: {
hotKeys: {
'Ctrl+b meta+b': 'bold',
'Ctrl+b meta+b': 'bold',
'Ctrl+i meta+i': 'italic',
'Ctrl+i meta+i': 'italic',
'Ctrl+u meta+u': 'underline',
'Ctrl+u meta+u': 'underline',
'Ctrl+z': 'undo',
'Ctrl+z': 'undo',
'Ctrl+y meta+y meta+shift+z': 'redo',
'Ctrl+y meta+y meta+shift+z': 'redo',
'Ctrl+l meta+l': 'justifyleft',
'Ctrl+l meta+l': 'justifyleft',
'Ctrl+r meta+r': 'justifyright',
'Ctrl+r meta+r': 'justifyright',
'Ctrl+e meta+e': 'justifycenter',
'Ctrl+e meta+e': 'justifycenter',
'Ctrl+j meta+j': 'justifyfull',
'Ctrl+j meta+j': 'justifyfull',
'Shift+tab': 'outdent',
'Shift+tab': 'outdent',
'tab': 'indent'
'tab': 'indent'
},
},
toolbarSelector: '[data-role=editor-toolbar]',
toolbarSelector: '[data-role=editor-toolbar]',
commandRole: 'edit',
commandRole: 'edit',
activeToolbarClass: 'btn-info',
activeToolbarClass: 'btn-info',
selectionMarker: 'edit-focus-marker',
selectionMarker: 'edit-focus-marker',
selectionColor: 'darkgrey',
selectionColor: 'darkgrey',
dragAndDropImages: true,
dragAndDropImages: true,
keypressTimeout: 200,
keypressTimeout: 200,
fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); }
};
};
}(window.jQuery));
}(window.jQuery));
Gespeicherte Diffs
Originaltext
Datei öffnen
/* @fileoverview * Provides full Bootstrap based, multi-instance WYSIWYG editor. * * "Name" = 'bootstrap-wysiwyg' * "Author" = 'Various, see LICENCE' * "Version" = '1.0.3-rc' * "About" = 'A tiny Bootstrap and jQuery based WYSIWYG rich text editor based on the browser function execCommand.' */ (function ($) { 'use strict'; /** underscoreThrottle() * From underscore http://underscorejs.org/docs/underscore.html */ var underscoreThrottle = function(func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var readFileIntoDataUrl = function (fileInfo) { var loader = $.Deferred(), fReader = new FileReader(); fReader.onload = function (e) { loader.resolve(e.target.result); }; fReader.onerror = loader.reject; fReader.onprogress = loader.notify; fReader.readAsDataURL(fileInfo); return loader.promise(); }; $.fn.cleanHtml = function (o) { if ( $(this).data("wysiwyg-html-mode") === true ) { $(this).html($(this).text()); $(this).attr('contenteditable',true); $(this).data('wysiwyg-html-mode',false); } // Strip the images with src="data:image/.." out; if ( o === true && $(this).parent().is("form") ) { var gGal = $(this).html; if ( $(gGal).has( "img" ).length ) { var gImages = $( "img", $(gGal)); var gResults = []; var gEditor = $(this).parent(); $.each(gImages, function(i,v) { if ( $(v).attr('src').match(/^data:image\/.*$/) ) { gResults.push(gImages[i]); $(gEditor).prepend("<input value='"+$(v).attr('src')+"' type='hidden' name='postedimage/"+i+"' />"); $(v).attr('src', 'postedimage/'+i); }}); } } var html = $(this).html(); return html && html.replace(/(<br>|\s|<div><br><\/div>| )*$/, ''); }; $.fn.wysiwyg = function (userOptions) { var editor = this, wrapper = $(editor).parent(), selectedRange, options, toolbarBtnSelector, updateToolbar = function () { if (options.activeToolbarClass) { $(options.toolbarSelector,wrapper).find(toolbarBtnSelector).each(underscoreThrottle(function () { var commandArr = $(this).data(options.commandRole).split(' '), command = commandArr[0]; // If the command has an argument and its value matches this button. == used for string/number comparison if (commandArr.length > 1 && document.queryCommandEnabled(command) && document.queryCommandValue(command) === commandArr[1]) { $(this).addClass(options.activeToolbarClass); // Else if the command has no arguments and it is active } else if (commandArr.length === 1 && document.queryCommandEnabled(command) && document.queryCommandState(command)) { $(this).addClass(options.activeToolbarClass); // Else the command is not active } else { $(this).removeClass(options.activeToolbarClass); } }, options.keypressTimeout)); } }, execCommand = function (commandWithArgs, valueArg) { var commandArr = commandWithArgs.split(' '), command = commandArr.shift(), args = commandArr.join(' ') + (valueArg || ''); var parts = commandWithArgs.split('-'); if ( parts.length === 1 ) { document.execCommand(command, 0, args); } else if ( parts[0] === 'format' && parts.length === 2 ) { document.execCommand('formatBlock', false, parts[1] ); } editor.trigger('change'); updateToolbar(); }, bindHotkeys = function (hotKeys) { $.each(hotKeys, function (hotkey, command) { editor.keydown(hotkey, function (e) { if (editor.attr('contenteditable') && editor.is(':visible')) { e.preventDefault(); e.stopPropagation(); execCommand(command); } }).keyup(hotkey, function (e) { if (editor.attr('contenteditable') && editor.is(':visible')) { e.preventDefault(); e.stopPropagation(); } }); }); editor.keyup(function(){ editor.trigger('change'); }); }, getCurrentRange = function () { var sel, range; if (window.getSelection) { sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); } } else if (document.selection) { range = document.selection.createRange(); } return range; }, saveSelection = function () { selectedRange = getCurrentRange(); }, restoreSelection = function () { var selection; if (window.getSelection || document.createRange) { selection = window.getSelection(); if (selectedRange) { try { selection.removeAllRanges(); } catch (ex) { document.body.createTextRange().select(); document.selection.empty(); } selection.addRange(selectedRange); } } else if (document.selection && selectedRange) { selectedRange.select(); } }, // Adding Toggle HTML based on the work by @jd0000, but cleaned up a little to work in this context. toggleHtmlEdit = function() { if ( $(editor).data("wysiwyg-html-mode") !== true ) { var oContent = $(editor).html(); var editorPre = $( "<pre />" ); $(editorPre).append( document.createTextNode( oContent ) ); $(editorPre).attr('contenteditable',true); $(editor).html(' '); $(editor).append($(editorPre)); $(editor).attr('contenteditable', false); $(editor).data("wysiwyg-html-mode", true); $(editorPre).focus(); } else { $(editor).html($(editor).text()); $(editor).attr('contenteditable',true); $(editor).data('wysiwyg-html-mode',false); $(editor).focus(); } }, insertFiles = function (files) { editor.focus(); $.each(files, function (idx, fileInfo) { if (/^image\//.test(fileInfo.type)) { $.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) { execCommand('insertimage', dataUrl); editor.trigger('image-inserted'); }).fail(function (e) { options.fileUploadError("file-reader", e); }); } else { options.fileUploadError("unsupported-file-type", fileInfo.type); } }); }, markSelection = function (input, color) { restoreSelection(); if (document.queryCommandSupported('hiliteColor')) { document.execCommand('hiliteColor', 0, color || 'transparent'); } saveSelection(); input.data(options.selectionMarker, color); }, bindToolbar = function (toolbar, options) { toolbar.find(toolbarBtnSelector, wrapper).click(function () { restoreSelection(); editor.focus(); if ($(this).data(options.commandRole) === 'html') { toggleHtmlEdit(); } else { execCommand($(this).data(options.commandRole)); } saveSelection(); }); toolbar.find('[data-toggle=dropdown]').click(restoreSelection); toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () { var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */ this.value = ''; restoreSelection(); if (newValue) { editor.focus(); execCommand($(this).data(options.commandRole), newValue); } saveSelection(); }).on('focus', function () { var input = $(this); if (!input.data(options.selectionMarker)) { markSelection(input, options.selectionColor); input.focus(); } }).on('blur', function () { var input = $(this); if (input.data(options.selectionMarker)) { markSelection(input, false); } }); toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () { restoreSelection(); if (this.type === 'file' && this.files && this.files.length > 0) { insertFiles(this.files); } saveSelection(); this.value = ''; }); }, initFileDrops = function () { editor.on('dragenter dragover', false) .on('drop', function (e) { var dataTransfer = e.originalEvent.dataTransfer; e.stopPropagation(); e.preventDefault(); if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) { insertFiles(dataTransfer.files); } }); }; options = $.extend(true, {}, $.fn.wysiwyg.defaults, userOptions); toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']'; bindHotkeys(options.hotKeys); // Support placeholder attribute on the DIV if ($(this).attr('placeholder') !== '') { $(this).addClass('placeholderText'); $(this).html($(this).attr('placeholder')); $(this).bind('focus',function() { if ( $(this).attr('placeholder') !== '' && $(this).text() === $(this).attr('placeholder') ) { $(this).removeClass('placeholderText'); $(this).html(''); } }); $(this).bind('blur',function() { if ( $(this).attr('placeholder') !== '' && $(this).text() === '' ) { $(this).addClass('placeholderText'); $(this).html($(this).attr('placeholder')); } }); } if (options.dragAndDropImages) { initFileDrops(); } bindToolbar($(options.toolbarSelector), options); editor.attr('contenteditable', true) .on('mouseup keyup mouseout', function () { saveSelection(); updateToolbar(); }); $(window).bind('touchend', function (e) { var isInside = (editor.is(e.target) || editor.has(e.target).length > 0), currentRange = getCurrentRange(), clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset); if (!clear || isInside) { saveSelection(); updateToolbar(); } }); return this; }; $.fn.wysiwyg.defaults = { hotKeys: { 'Ctrl+b meta+b': 'bold', 'Ctrl+i meta+i': 'italic', 'Ctrl+u meta+u': 'underline', 'Ctrl+z': 'undo', 'Ctrl+y meta+y meta+shift+z': 'redo', 'Ctrl+l meta+l': 'justifyleft', 'Ctrl+r meta+r': 'justifyright', 'Ctrl+e meta+e': 'justifycenter', 'Ctrl+j meta+j': 'justifyfull', 'Shift+tab': 'outdent', 'tab': 'indent' }, toolbarSelector: '[data-role=editor-toolbar]', commandRole: 'edit', activeToolbarClass: 'btn-info', selectionMarker: 'edit-focus-marker', selectionColor: 'darkgrey', dragAndDropImages: true, keypressTimeout: 200, fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); } }; }(window.jQuery));
Bearbeitung
Datei öffnen
/* @fileoverview * Provides full Bootstrap based, multi-instance WYSIWYG editor. * * "Name" = 'bootstrap-wysiwyg' * "Author" = 'Various, see LICENSE' * "Version" = '1.0.4' * "About" = 'A tiny Bootstrap and jQuery based WYSIWYG rich text editor based on the browser function execCommand.' */ (function ($) { 'use strict'; /** underscoreThrottle() * From underscore http://underscorejs.org/docs/underscore.html */ var underscoreThrottle = function(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; if (!options) { options = {}; } var later = function() { previous = options.leading === false ? 0 : $.now(); timeout = null; result = func.apply(context, args); if (!timeout) { context = args = null; } }; return function() { var now = $.now(); if (!previous && options.leading === false) { previous = now; } var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; result = func.apply(context, args); if (!timeout) { context = args = null; } } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; }; var readFileIntoDataUrl = function (fileInfo) { var loader = $.Deferred(), fReader = new FileReader(); fReader.onload = function (e) { loader.resolve(e.target.result); }; fReader.onerror = loader.reject; fReader.onprogress = loader.notify; fReader.readAsDataURL(fileInfo); return loader.promise(); }; $.fn.cleanHtml = function (o) { if ( $(this).data("wysiwyg-html-mode") === true ) { $(this).html($(this).text()); $(this).attr('contenteditable',true); $(this).data('wysiwyg-html-mode',false); } // Strip the images with src="data:image/.." out; if ( o === true && $(this).parent().is("form") ) { var gGal = $(this).html; if ( $(gGal).has( "img" ).length ) { var gImages = $( "img", $(gGal)); var gResults = []; var gEditor = $(this).parent(); $.each(gImages, function(i,v) { if ( $(v).attr('src').match(/^data:image\/.*$/) ) { gResults.push(gImages[i]); $(gEditor).prepend("<input value='"+$(v).attr('src')+"' type='hidden' name='postedimage/"+i+"' />"); $(v).attr('src', 'postedimage/'+i); }}); } } var html = $(this).html(); return html && html.replace(/(<br>|\s|<div><br><\/div>| )*$/, ''); }; $.fn.wysiwyg = function (userOptions) { var editor = this, selectedRange, options, toolbarBtnSelector, updateToolbar = function () { if (options.activeToolbarClass) { $(options.toolbarSelector).find(toolbarBtnSelector).each(function () { var commandArr = $(this).data(options.commandRole).split(' '), command = commandArr[0]; // If the command has an argument and its value matches this button. == used for string/number comparison if (commandArr.length > 1 && document.queryCommandEnabled(command) && document.queryCommandValue(command) === commandArr[1]) { $(this).addClass(options.activeToolbarClass); // Else if the command has no arguments and it is active } else if (commandArr.length === 1 && document.queryCommandEnabled(command) && document.queryCommandState(command)) { $(this).addClass(options.activeToolbarClass); // Else the command is not active } else { $(this).removeClass(options.activeToolbarClass); } }); } }, execCommand = function (commandWithArgs, valueArg) { var commandArr = commandWithArgs.split(' '), command = commandArr.shift(), args = commandArr.join(' ') + (valueArg || ''); var parts = commandWithArgs.split('-'); if ( parts.length === 1 ) { underscoreThrottle(document.execCommand(command, false, args), options.keypressTimeout); } else if ( parts[0] === 'format' && parts.length === 2 ) { underscoreThrottle(document.execCommand('formatBlock', false, parts[1] ), options.keypressTimeout); } editor.trigger('change'); updateToolbar(); }, bindHotkeys = function (hotKeys) { $.each(hotKeys, function (hotkey, command) { editor.keydown(hotkey, function (e) { if (editor.attr('contenteditable') && editor.is(':visible')) { e.preventDefault(); e.stopPropagation(); underscoreThrottle(execCommand(command), options.keypressTimeout); } }).keyup(hotkey, function (e) { if (editor.attr('contenteditable') && editor.is(':visible')) { e.preventDefault(); e.stopPropagation(); } }); }); editor.keyup(function(){ editor.trigger('change'); }); }, getCurrentRange = function () { var sel, range; if (window.getSelection) { sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { range = sel.getRangeAt(0); } } else if (document.selection) { range = document.selection.createRange(); } return range; }, saveSelection = function () { selectedRange = getCurrentRange(); }, restoreSelection = function () { var selection; if (window.getSelection || document.createRange) { selection = window.getSelection(); if (selectedRange) { try { selection.removeAllRanges(); } catch (ex) { document.body.createTextRange().select(); document.selection.empty(); } selection.addRange(selectedRange); } } else if (document.selection && selectedRange) { selectedRange.select(); } }, // Adding Toggle HTML based on the work by @jd0000, but cleaned up a little to work in this context. toggleHtmlEdit = function() { if ( $(editor).data("wysiwyg-html-mode") !== true ) { var oContent = $(editor).html(); var editorPre = $( "<pre />" ); $(editorPre).append( document.createTextNode( oContent ) ); $(editorPre).attr('contenteditable',true); $(editor).html(' '); $(editor).append($(editorPre)); $(editor).attr('contenteditable', false); $(editor).data("wysiwyg-html-mode", true); $(editorPre).focus(); } else { $(editor).html($(editor).text()); $(editor).attr('contenteditable',true); $(editor).data('wysiwyg-html-mode',false); $(editor).focus(); } }, insertFiles = function (files) { editor.focus(); $.each(files, function (idx, fileInfo) { if (/^image\//.test(fileInfo.type)) { $.when(readFileIntoDataUrl(fileInfo)).done(function (dataUrl) { underscoreThrottle(execCommand('insertimage', dataUrl), options.keypressTimeout); editor.trigger('image-inserted'); }).fail(function (e) { options.fileUploadError("file-reader", e); }); } else { options.fileUploadError("unsupported-file-type", fileInfo.type); } }); }, markSelection = function (input, color) { restoreSelection(); if (document.queryCommandSupported('hiliteColor')) { underscoreThrottle(document.execCommand('hiliteColor', false, color || 'transparent'), options.keypressTimeout); } saveSelection(); input.data(options.selectionMarker, color); }, bindToolbar = function (toolbar, options) { toolbar.find(toolbarBtnSelector).click(function () { restoreSelection(); editor.focus(); if ($(this).data(options.commandRole) === 'html') { toggleHtmlEdit(); } else { underscoreThrottle(execCommand($(this).data(options.commandRole)), options.keypressTimeout); } saveSelection(); }); toolbar.find('[data-toggle=dropdown]').click(restoreSelection); toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () { var newValue = this.value; /* ugly but prevents fake double-calls due to selection restoration */ this.value = ''; restoreSelection(); if (newValue) { editor.focus(); underscoreThrottle(execCommand($(this).data(options.commandRole), newValue), options.keypressTimeout); } saveSelection(); }).on('focus', function () { var input = $(this); if (!input.data(options.selectionMarker)) { markSelection(input, options.selectionColor); input.focus(); } }).on('blur', function () { var input = $(this); if (input.data(options.selectionMarker)) { markSelection(input, false); } }); toolbar.find('input[type=file][data-' + options.commandRole + ']').change(function () { restoreSelection(); if (this.type === 'file' && this.files && this.files.length > 0) { insertFiles(this.files); } saveSelection(); this.value = ''; }); }, initFileDrops = function () { editor.on('dragenter dragover', false) .on('drop', function (e) { var dataTransfer = e.originalEvent.dataTransfer; e.stopPropagation(); e.preventDefault(); if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) { insertFiles(dataTransfer.files); } }); }; options = $.extend(true, {}, $.fn.wysiwyg.defaults, userOptions); toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']'; bindHotkeys(options.hotKeys); // Support placeholder attribute on the DIV if ($(this).attr('placeholder') !== '') { $(this).addClass('placeholderText'); $(this).html($(this).attr('placeholder')); $(this).bind('focus',function() { if ( $(this).attr('placeholder') !== '' && $(this).text() === $(this).attr('placeholder') ) { $(this).removeClass('placeholderText'); $(this).html(''); } }); $(this).bind('blur',function() { if ( $(this).attr('placeholder') !== '' && $(this).text() === '' ) { $(this).addClass('placeholderText'); $(this).html($(this).attr('placeholder')); } }); } if (options.dragAndDropImages) { initFileDrops(); } bindToolbar($(options.toolbarSelector), options); editor.attr('contenteditable', true) .on('mouseup keyup mouseout', function () { saveSelection(); updateToolbar(); }); $(window).bind('touchend', function (e) { var isInside = (editor.is(e.target) || editor.has(e.target).length > 0), currentRange = getCurrentRange(), clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset); if (!clear || isInside) { saveSelection(); updateToolbar(); } }); return this; }; $.fn.wysiwyg.defaults = { hotKeys: { 'Ctrl+b meta+b': 'bold', 'Ctrl+i meta+i': 'italic', 'Ctrl+u meta+u': 'underline', 'Ctrl+z': 'undo', 'Ctrl+y meta+y meta+shift+z': 'redo', 'Ctrl+l meta+l': 'justifyleft', 'Ctrl+r meta+r': 'justifyright', 'Ctrl+e meta+e': 'justifycenter', 'Ctrl+j meta+j': 'justifyfull', 'Shift+tab': 'outdent', 'tab': 'indent' }, toolbarSelector: '[data-role=editor-toolbar]', commandRole: 'edit', activeToolbarClass: 'btn-info', selectionMarker: 'edit-focus-marker', selectionColor: 'darkgrey', dragAndDropImages: true, keypressTimeout: 200, fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); } }; }(window.jQuery));
Unterschied finden