そのため、setDataを使用して、ユーザーが入力した内容と一緒に送信される情報をCKeditorコンテンツ領域に事前入力しています。
CKEDITOR.on( 'instanceReady', function( ev ) {
CKEDITOR.instances.ckeditor99.setData( messageTemplate1, function() {
this.checkDirty(); // true
});
});
「mesageTemplate1」のコンテンツがCKeditorコンテンツ領域に設定される前に、JavaScriptを適用してクリーンアップします。この後、JSを再度使用して、CKeditorコンテンツ領域に挿入したばかりの情報を含むdivを削除します。削除後、カスタムCKeditorプラグインを起動して、CKeditorでそのコンテンツを処理したいと思います。プラグインはIDをターゲットにし、両方のdivが(ページのどこかとckeditorに)存在する場合、プラグインは最初にCKeditorコンテンツ領域にないものをターゲットにするため、使用済みのdivを削除した後にこのプラグインを起動することが重要です。 ckエリアでは手つかずです。
これは、前の質問でスタックのメンバーから取得したプラグインです(特定のコンテンツ領域への編集をブロックします) 。
/*
Plugin that prevents editing of elements with the "non-editable" class as well as elements outside of blocks with "editable" class.
*/
//* ************************** NOTES *************************** NOTES ****************************
/*
The "lastSelectedElement" variable is used to store the last element selected.
This plugin uses the "elementspath" plugin which shows all elements in the DOM
parent tree relative to the current selection in the editing area.
When the selection changes, "elementsPathUpdate" is fired,
we key on this and loop through the elements in the tree checking the classes assigned to each element.
Three outcomes are possible.
1) The non-editable class is found:
Looping stops, the current action is cancelled and the cursor is moved to the previous selection.
The "selectionChange" hook is fired to set the reverted selection throughout the instance.
2) The editable class is found during looping, the "in_editable_area" flag is set to true.
3) Neither the editable or the non-editable classes are found (user clicked outside your main container).
The "in_editable_area" flag remains set to false.
If the "in_editable_area" flag is false, the current action is cancelled and the cursor is moved to the previous location.
The "selectionChange" hook is fired to set the reverted selection throughout the instance.
If the "in_editable_area" flag is true,
the "lastSelectedElement" is updated to the currently selected element and the plugin returns true.
---------------
If you don't want the elements path to be displayed at the bottom of the editor window,
you can hide it with CSS rather than disabling the "elementspath" plugin.
The elementspath plugin creates and is left active because we are keying on changes to the path in our plugin.
#cke_path_content
{
visibility: hidden !important;
}
---------------
CSS Classes and ID that the plugin keys on. Use defaults or update variables to use your preferred classes and ID:
var starting_element_id = ID of known editable element that always occurs in the instance.
Don't use elements like <table>, <tr>, <br /> that don't contain HTML text.
Default value = cwjdsjcs_editable_id
var editable_class = class of editable containers.
Should be applied to all top level elements that contain editable elements.
Default = cwjdsjcs_editable
var non_editable_class = class of non-editable elements within editable containers
Apply to elements where all child elements are non-editable.
Default = cwjdsjcs_not_editable
*/
//* ************************** END NOTES *************************** END NOTES ****************************
// Register the plugin with the editor.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.plugins.html
CKEDITOR.plugins.add( 'cwjdsjcsconfineselection',
{
requires : [ 'elementspath' ],
// The plugin initialization logic goes inside this method.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.pluginDefinition.html#init
init: function( editor )
{
editor.on( 'instanceReady', function( instance_ready_data )
{
// Create variable that will hold the last allowed selection (for use when a non-editable selection is made)
var lastSelectedElement;
editor.cwjdsjcs_just_updated = false;
// This section starts things off right by selecting a known editable element.
// *** Enter the ID of the element that should have initial focus *** IMPORTANT *** IMPORTANT ***
var starting_element_id = "cwjdsjcs_editable_id";
var resInitialRange = new CKEDITOR.dom.range( editor.document );
resInitialRange.selectNodeContents( editor.document.getById( starting_element_id ) );
resInitialRange.collapse();
var selectionObject = new CKEDITOR.dom.selection( editor.document );
editor.document.focus();
selectionObject.selectRanges( [ resInitialRange ] );
var sel = editor.getSelection();
var firstElement = sel.getStartElement();
var currentPath = new CKEDITOR.dom.elementPath( firstElement );
// Set path for known editable element, fire "selectionChange" hook to update selection throughout instance.
editor._.selectionPreviousPath = currentPath;
editor.fire( 'selectionChange', { selection : sel, path : currentPath, element : firstElement } );
}); // *** END - editor.on( 'instanceReady', function( e )
// When a new element is selected by the user, check if it's ok for them to edit it,
// if not move cursor back to last know editable selection
editor.on( 'elementsPathUpdate', function( resPath )
{
// When we fire the "selectionChange" hook at the end of this code block, the "elementsPathUpdate" hook fires.
// No need to check because we just updated the selection, so bypass processing.
if( editor.cwjdsjcs_just_updated == true )
{
editor.cwjdsjcs_just_updated = false;
return true;
}
var elementsList = editor._.elementsPath.list;
var in_editable_area = false;
var non_editable_class = "cwjdsjcs_not_editable";
var editable_class = "cwjdsjcs_editable";
for(var w=0;w<elementsList.length;w++){
var currentElement = elementsList[w];
// Sometimes a non content element is selected, catch them and return selection to editable area.
if(w == 0)
{
// Could change to switch.
if( currentElement.getName() == "tbody" )
{
in_editable_area = false;
break;
}
if( currentElement.getName() == "tr" )
{
in_editable_area = false;
break;
}
}
// If selection is inside a non-editable element, break from loop and reset selection.
if( currentElement.hasClass(non_editable_class) )
{
in_editable_area = false;
break;
}
if( currentElement.hasClass(editable_class) ) {
in_editable_area = true;
}
console.log(currentElement);
console.log(currentElement.getName());
}
// if selection is within an editable element, exit the plugin, otherwise reset selection.
if( in_editable_area ) {
lastSelectedElement = elementsList[0];
return true;
}
var resRange = new CKEDITOR.dom.range( editor.document );
resRange.selectNodeContents( lastSelectedElement );
resRange.collapse();
editor.getSelection().selectRanges( [ resRange ] );
//resRange.endContainer.$.scrollIntoView();
// Open dialog window:
// It tells user they selected a non-editable area and cursor has been returned to previous selection
currentEditorName = editor.name;
openResDefaultDialog(currentEditorName);
try
{
var sel = editor.getSelection();
var firstElement = sel.getStartElement();
var currentPath = new CKEDITOR.dom.elementPath( firstElement );
editor.cwjdsjcs_just_updated = true;
editor._.selectionPreviousPath = currentPath;
editor.fire( 'selectionChange', { selection : sel, path : currentPath, element : firstElement } );
}
catch (e)
{}
});
} // *** END - init: function( editor )
}); // ************************************************************************************* END - CKEDITOR.plugins.add
これは、CKeditorコンテンツ領域に設定されているdivです。
<table id="messageTemplate1" class="message cwjdsjcs_editable">
<tbody>
<tr>
<td class="cwjdsjcs_not_editable" contenteditable="false">
</td>
<td id="cwjdsjcs_editable_id">
</td>
</tr>
<tr class="cwjdsjcs_not_editable" contenteditable="false">
<td colspan="2">
<!-- Begin Original Content -->
<table class="hide" style="font-size: 12px; display:none;">
<tbody>
<tr class="hide">
<td>
Application sent by <strong><a href="http://www.globalcastingcenter.com/talent/jack-bolton">Matt Faro</a></strong> for Audition: <a href="http://www.globalcastingcenter.com:80/CustomContentRetrieve.aspx?ID=4185493">Actors Needed</a>
</td>
</tr>
<tr class="hide">
<td>
Reply to applicant directly: mantas@mantas.co or visit full profile: http://www.globalcastingcenter.com/talent/jack-bolton
</td>
</tr>
</tbody>
</table>
<table class="hide" style="font-size: 12px; display:none;">
<tbody>
<tr class="hide">
<td><strong>Short Profile Summary:</strong></td>
</tr>
</tbody>
</table>
<table class="hide" style="font-size: 12px; display:none;">
<tbody>
<tr class="hide">
<td>
<a href="http://www.globalcastingcenter.com/talent/jack-bolton"><img alt="" src="http://globalcastingcenter.com/talent_images/4164035_258551_foto.png?Action=thumbnail&Width=144&Height=215" /></a>
</td>
</tr>
</tbody>
</table>
<table style="font-size: 12px; display:none;" class="hide">
<tbody>
<tr class="hide">
<td><strong>Areas:</strong></td>
<td>Actor,Extra</td>
</tr>
<tr class="hide">
<td><strong>Country:</strong></td>
<td>WORLDWIDE,Any</td>
</tr>
<tr class="hide">
<td><strong>Age:</strong></td>
<td>26</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
私はここにたくさんのものを貼り付けましたが、それはすべて、手動で、または削除イベントが完了した後にckeditorプラグインを起動できるかどうか、そしてどのように起動できるかという問題に要約されます。私はまた、私の問題に対してもっと合理的な解決策があるかどうか尋ねます。プラグインの起動タイミングはそうではないかもしれません。
ありがとう
編集:
setDataの後にcwjdsjcsconfineselectionを起動するプラグインスクリプト:
//JavaScriptドキュメント
CKEDITOR.plugins.add('cwjdsjcsconfineselection',
{
requires : [ 'elementspath' ],
init: function(editor)
{
/* editor.on( 'confineselection', function( confineselection_data )
{
alert ("Blocker is on!");
}); // editor on END
*/
editor.on( 'confineselection', function( confineselection_data )
{
alert ("Plugin fired!");
// Create variable that will hold the last allowed selection (for use when a non-editable selection is made)
var lastSelectedElement;
editor.cwjdsjcs_just_updated = false;
// This section starts things off right by selecting a known editable element.
// *** Enter the ID of the element that should have initial focus *** IMPORTANT *** IMPORTANT ***
var starting_element_id = "cwjdsjcs_editable_id";
var resInitialRange = new CKEDITOR.dom.range( editor.document );
resInitialRange.selectNodeContents( editor.document.getById( starting_element_id ) );
resInitialRange.collapse();
var selectionObject = new CKEDITOR.dom.selection( editor.document );
editor.document.focus();
selectionObject.selectRanges( [ resInitialRange ] );
var sel = editor.getSelection();
var firstElement = sel.getStartElement();
var currentPath = new CKEDITOR.dom.elementPath( firstElement );
// Set path for known editable element, fire "selectionChange" hook to update selection throughout instance.
editor._.selectionPreviousPath = currentPath;
editor.fire( 'selectionChange', { selection : sel, path : currentPath, element : firstElement } );
}); // *** END - editor.on( 'instanceReady', function( e )
// When a new element is selected by the user, check if it's ok for them to edit it,
// if not move cursor back to last know editable selection
editor.on( 'elementsPathUpdate', function( resPath )
{
// When we fire the "selectionChange" hook at the end of this code block, the "elementsPathUpdate" hook fires.
// No need to check because we just updated the selection, so bypass processing.
if( editor.cwjdsjcs_just_updated == true )
{
editor.cwjdsjcs_just_updated = false;
return true;
}
var elementsList = editor._.elementsPath.list;
var in_editable_area = false;
var non_editable_class = "cwjdsjcs_not_editable";
var editable_class = "cwjdsjcs_editable";
for(var w=0;w<elementsList.length;w++){
var currentElement = elementsList[w];
// Sometimes a non content element is selected, catch them and return selection to editable area.
if(w == 0)
{
// Could change to switch.
if( currentElement.getName() == "tbody" )
{
in_editable_area = false;
break;
}
if( currentElement.getName() == "tr" )
{
in_editable_area = false;
break;
}
}
// If selection is inside a non-editable element, break from loop and reset selection.
if( currentElement.hasClass(non_editable_class) )
{
in_editable_area = false;
break;
}
if( currentElement.hasClass(editable_class) ) {
in_editable_area = true;
}
console.log(currentElement);
console.log(currentElement.getName());
}
// if selection is within an editable element, exit the plugin, otherwise reset selection.
if( in_editable_area ) {
lastSelectedElement = elementsList[0];
return true;
}
var resRange = new CKEDITOR.dom.range( editor.document );
resRange.selectNodeContents( lastSelectedElement );
resRange.collapse();
editor.getSelection().selectRanges( [ resRange ] );
//resRange.endContainer.$.scrollIntoView();
// Open dialog window:
// It tells user they selected a non-editable area and cursor has been returned to previous selection
currentEditorName = editor.name;
openResDefaultDialog(currentEditorName);
try
{
var sel = editor.getSelection();
var firstElement = sel.getStartElement();
var currentPath = new CKEDITOR.dom.elementPath( firstElement );
editor.cwjdsjcs_just_updated = true;
editor._.selectionPreviousPath = currentPath;
editor.fire( 'selectionChange', { selection : sel, path : currentPath, element : firstElement } );
}
catch (e)
{}
}); // Blocker source END
editor.on( 'instanceReady', function( ev )
{
var messageTemplate1 = $("#messageTemplate1").html();
CKEDITOR.instances.ckeditor99.setData( messageTemplate1, function()
{
alert ("setData done!");
this.checkDirty(); // true
});
CKEDITOR.instances.ckeditor99.fire( 'confineselection' );
});
} // init END
}); // Plugin add END
テーブルの周りに表示される変換ハンドルにはまだ問題があります。これはFirefoxでのみ発生します。これはビデオです:http : //screencast.com/t/lxKJWb6NIこのボックスは、更新後に消えることもあれば、消えないこともあります。ログインの詳細は、ライブでテストしたい場合は私のコメントにあります。
これは私の設定です:
CKEDITOR.editorConfig = function( config )
{
config.toolbar = 'MyToolbar';
config.toolbar_MyToolbar =
[
{ name: 'clipboard', items : [ 'Undo','Redo' ] },
{ name: 'styles', items : ['FontSize' ] },
{ name: 'basicstyles', items : [ 'Bold','Italic'] },
{ name: 'paragraph', items : ['Outdent','Indent' ] },
];
config.startupShowBorders = false;
config.disableObjectResizing = true;
config.removePlugins = 'contextmenu';
config.forcePasteAsPlainText = true;
config.pasteFromWordRemoveFontStyles = true;
config.pasteFromWordRemoveStyles = true;
config.extraPlugins = 'cwjdsjcsconfineselection';
};