Diff
checker
文本
文本
圖像
文檔
Excel
文件夾
Legal
Enterprise
桌面版
定價
登入
下載 Diffchecker 桌面版
比較文本
尋找兩個文字檔案之間的差異
工具
歷史
即時編輯器
隱藏空白變更
摺疊未變更行
關閉換行
檢視
拆分
統一
比對精度
智能
單詞
字符
文字樣式
變更外觀
語法突出顯示
選擇語法
忽略
文字轉換
前往第一個差異
編輯輸入
Diffchecker Desktop
執行Diffchecker最安全的方式。取得Diffchecker桌面應用程式:您的差異永遠不會離開您的電腦!
取得桌面版
Untitled diff
建立於
11 年前
差異永不過期
清除
匯出
分享
解釋
13 刪除
行
總計
刪除
字符
總計
刪除
要繼續使用此功能,請升級到
Diff
checker
Pro
查看價格
332 行
全部複製
47 新增
行
總計
新增
字符
總計
新增
要繼續使用此功能,請升級到
Diff
checker
Pro
查看價格
348 行
全部複製
/* @fileoverview
/* @fileoverview
* Provides full Bootstrap based, multi-instance WYSIWYG editor.
* Provides full Bootstrap based, multi-instance WYSIWYG editor.
*
*
* "Name" = 'bootstrap-wysiwyg'
* "Name" = 'bootstrap-wysiwyg'
複製
已複製
複製
已複製
* "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.'
*/
*/
複製
已複製
複製
已複製
(function ($) {
(function ($) {
'use strict';
'use strict';
/** underscoreThrottle()
/** underscoreThrottle()
* From underscore http://underscorejs.org/docs/underscore.html
* From underscore http://underscorejs.org/docs/underscore.html
*/
*/
複製
已複製
複製
已複製
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;
複製
已複製
複製
已複製
if (!options) {
options = {};
}
var later = function() {
var later = function() {
複製
已複製
複製
已複製
previous =
new Date
();
previous =
options.leading === false ? 0 : $.now
();
timeout = null;
timeout = null;
result = func.apply(context, args);
result = func.apply(context, args);
複製
已複製
複製
已複製
if (!timeout) {
context = args = null;
}
};
};
return function() {
return function() {
複製
已複製
複製
已複製
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;
複製
已複製
複製
已複製
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);
複製
已複製
複製
已複製
}
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,
複製
已複製
複製
已複製
wrapper = $(editor).parent(),
selectedRange,
selectedRange,
options,
options,
toolbarBtnSelector,
toolbarBtnSelector,
updateToolbar = function () {
updateToolbar = function () {
if (options.activeToolbarClass) {
if (options.activeToolbarClass) {
複製
已複製
複製
已複製
$(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);
}
}
複製
已複製
複製
已複製
}
, 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 ) {
複製
已複製
複製
已複製
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 ) {
複製
已複製
複製
已複製
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();
複製
已複製
複製
已複製
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) {
複製
已複製
複製
已複製
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')) {
複製
已複製
複製
已複製
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) {
複製
已複製
複製
已複製
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 {
複製
已複製
複製
已複製
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();
複製
已複製
複製
已複製
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));
已保存差異
原始文本
開啟檔案
/* @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));
更改後文本
開啟檔案
/* @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));
尋找差異