mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-08-28 17:57:38 +00:00
HTML composition, take 2
Monotone-Parent: dbd490c81ea6cac4c12b2e17661e2fef43219e68 Monotone-Revision: 0801dc9f1e4fdc49ea44fc0450fb025c2639ed26 Monotone-Author: crobert@inverse.ca Monotone-Date: 2009-06-25T19:18:02 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
|
||||
CKEDITOR.dialog.add( 'paste', function( editor )
|
||||
{
|
||||
var isCustomDomain = CKEDITOR.env.ie && document.domain != window.location.hostname;
|
||||
|
||||
return {
|
||||
title : editor.lang.clipboard.title,
|
||||
|
||||
minWidth : CKEDITOR.env.ie && CKEDITOR.env.quirks ? 370 : 350,
|
||||
minHeight : CKEDITOR.env.ie && CKEDITOR.env.quirks ? 250 : 240,
|
||||
htmlToLoad : '<!doctype html><script type="text/javascript">'
|
||||
+ 'window.onload = function()'
|
||||
+ '{'
|
||||
+ 'if ( ' + CKEDITOR.env.ie + ' ) '
|
||||
+ 'document.body.contentEditable = "true";'
|
||||
+ 'else '
|
||||
+ 'document.designMode = "on";'
|
||||
+ 'var iframe = new window.parent.CKEDITOR.dom.element( frameElement );'
|
||||
+ 'var dialog = iframe.getCustomData( "dialog" );'
|
||||
+ 'dialog.fire( "iframeAdded", { iframe : iframe } );'
|
||||
+ '};'
|
||||
+ '</script><style>body { margin: 3px; height: 95%; } </style><body></body>',
|
||||
|
||||
onShow : function()
|
||||
{
|
||||
if ( CKEDITOR.env.ie )
|
||||
this.getParentEditor().document.getBody().$.contentEditable = 'false';
|
||||
|
||||
// FIREFOX BUG: Force the browser to render the dialog to make the to-be-
|
||||
// inserted iframe editable. (#3366)
|
||||
this.parts.dialog.$.offsetHeight;
|
||||
|
||||
var container = this.getContentElement( 'general', 'editing_area' ).getElement(),
|
||||
iframe = CKEDITOR.dom.element.createFromHtml( '<iframe src="javascript:void(0)" frameborder="0" allowtransparency="1"></iframe>' );
|
||||
|
||||
var lang = this.getParentEditor().lang;
|
||||
|
||||
iframe.setStyles(
|
||||
{
|
||||
width : '346px',
|
||||
height : '130px',
|
||||
'background-color' : 'white',
|
||||
border : '1px solid black'
|
||||
} );
|
||||
iframe.setCustomData( 'dialog', this );
|
||||
|
||||
var accTitle = lang.editorTitle.replace( '%1', lang.clipboard.title );
|
||||
|
||||
if ( CKEDITOR.env.ie )
|
||||
container.setHtml( '<legend style="position:absolute;top:-1000000px;left:-1000000px;">'
|
||||
+ CKEDITOR.tools.htmlEncode( accTitle )
|
||||
+ '</legend>' );
|
||||
else
|
||||
{
|
||||
container.setHtml( '' );
|
||||
container.setAttributes(
|
||||
{
|
||||
role : 'region',
|
||||
title : accTitle
|
||||
} );
|
||||
iframe.setAttributes(
|
||||
{
|
||||
role : 'region',
|
||||
title : ' '
|
||||
} );
|
||||
}
|
||||
container.append( iframe );
|
||||
if ( CKEDITOR.env.ie )
|
||||
container.setStyle( 'height', ( iframe.$.offsetHeight + 2 ) + 'px' );
|
||||
|
||||
if ( isCustomDomain )
|
||||
{
|
||||
CKEDITOR._cke_htmlToLoad = this.definition.htmlToLoad;
|
||||
iframe.setAttribute( 'src',
|
||||
'javascript:void( (function(){' +
|
||||
'document.open();' +
|
||||
'document.domain="' + document.domain + '";' +
|
||||
'document.write( window.parent.CKEDITOR._cke_htmlToLoad );' +
|
||||
'delete window.parent.CKEDITOR._cke_htmlToLoad;' +
|
||||
'document.close();' +
|
||||
'})() )' );
|
||||
}
|
||||
else
|
||||
{
|
||||
var doc = iframe.$.contentWindow.document;
|
||||
doc.open();
|
||||
doc.write( this.definition.htmlToLoad );
|
||||
doc.close();
|
||||
}
|
||||
},
|
||||
|
||||
onHide : function()
|
||||
{
|
||||
if ( CKEDITOR.env.ie )
|
||||
this.getParentEditor().document.getBody().$.contentEditable = 'true';
|
||||
},
|
||||
|
||||
onOk : function()
|
||||
{
|
||||
var container = this.getContentElement( 'general', 'editing_area' ).getElement(),
|
||||
iframe = container.getElementsByTag( 'iframe' ).getItem( 0 ),
|
||||
editor = this.getParentEditor(),
|
||||
html = iframe.$.contentWindow.document.body.innerHTML;
|
||||
|
||||
editor.insertHtml( html );
|
||||
|
||||
},
|
||||
|
||||
contents : [
|
||||
{
|
||||
id : 'general',
|
||||
label : editor.lang.common.generalTab,
|
||||
elements : [
|
||||
{
|
||||
type : 'html',
|
||||
id : 'securityMsg',
|
||||
html : '<div style="white-space:normal;width:340px;">' + editor.lang.clipboard.securityMsg + '</div>'
|
||||
},
|
||||
{
|
||||
type : 'html',
|
||||
id : 'pasteMsg',
|
||||
html : '<div style="white-space:normal;width:340px;">'+editor.lang.clipboard.pasteMsg +'</div>'
|
||||
},
|
||||
{
|
||||
type : 'html',
|
||||
id : 'editing_area',
|
||||
style : 'width: 100%; height: 100%;',
|
||||
html : '<fieldset></fieldset>',
|
||||
focus : function()
|
||||
{
|
||||
var div = this.getElement();
|
||||
var iframe = div.getElementsByTag( 'iframe' );
|
||||
if ( iframe.count() < 1 )
|
||||
return;
|
||||
iframe = iframe.getItem( 0 );
|
||||
|
||||
// #3291 : JAWS needs the 500ms delay to detect that the editor iframe
|
||||
// iframe is no longer editable. So that it will put the focus into the
|
||||
// Paste from Word dialog's editable area instead.
|
||||
setTimeout( function()
|
||||
{
|
||||
iframe.$.contentWindow.focus();
|
||||
}, 500 );
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Clipboard support
|
||||
*/
|
||||
|
||||
(function()
|
||||
{
|
||||
// Tries to execute any of the paste, cut or copy commands in IE. Returns a
|
||||
// boolean indicating that the operation succeeded.
|
||||
var execIECommand = function( editor, command )
|
||||
{
|
||||
var doc = editor.document,
|
||||
body = doc.getBody();
|
||||
|
||||
var enabled = false;
|
||||
var onExec = function()
|
||||
{
|
||||
enabled = true;
|
||||
};
|
||||
|
||||
// The following seems to be the only reliable way to detect that
|
||||
// clipboard commands are enabled in IE. It will fire the
|
||||
// onpaste/oncut/oncopy events only if the security settings allowed
|
||||
// the command to execute.
|
||||
body.on( command, onExec );
|
||||
|
||||
doc.$.execCommand( command );
|
||||
|
||||
body.removeListener( command, onExec );
|
||||
|
||||
return enabled;
|
||||
};
|
||||
|
||||
// Attempts to execute the Cut and Copy operations.
|
||||
var tryToCutCopy =
|
||||
CKEDITOR.env.ie ?
|
||||
function( editor, type )
|
||||
{
|
||||
return execIECommand( editor, type );
|
||||
}
|
||||
: // !IE.
|
||||
function( editor, type )
|
||||
{
|
||||
try
|
||||
{
|
||||
// Other browsers throw an error if the command is disabled.
|
||||
return editor.document.$.execCommand( type );
|
||||
}
|
||||
catch( e )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// A class that represents one of the cut or copy commands.
|
||||
var cutCopyCmd = function( type )
|
||||
{
|
||||
this.type = type;
|
||||
this.canUndo = ( this.type == 'cut' ); // We can't undo copy to clipboard.
|
||||
};
|
||||
|
||||
cutCopyCmd.prototype =
|
||||
{
|
||||
exec : function( editor, data )
|
||||
{
|
||||
var success = tryToCutCopy( editor, this.type );
|
||||
|
||||
if ( !success )
|
||||
alert( editor.lang.clipboard[ this.type + 'Error' ] ); // Show cutError or copyError.
|
||||
|
||||
return success;
|
||||
}
|
||||
};
|
||||
|
||||
// Paste command.
|
||||
var pasteCmd =
|
||||
CKEDITOR.env.ie ?
|
||||
{
|
||||
exec : function( editor, data )
|
||||
{
|
||||
// Prevent IE from pasting at the begining of the document.
|
||||
editor.focus();
|
||||
|
||||
if ( !editor.fire( 'beforePaste' )
|
||||
&& !execIECommand( editor, 'paste' ) )
|
||||
{
|
||||
editor.openDialog( 'paste' );
|
||||
}
|
||||
}
|
||||
}
|
||||
:
|
||||
{
|
||||
exec : function( editor )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( !editor.fire( 'beforePaste' )
|
||||
&& !editor.document.$.execCommand( 'Paste', false, null ) )
|
||||
{
|
||||
throw 0;
|
||||
}
|
||||
}
|
||||
catch ( e )
|
||||
{
|
||||
// Open the paste dialog.
|
||||
editor.openDialog( 'paste' );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Listens for some clipboard related keystrokes, so they get customized.
|
||||
var onKey = function( event )
|
||||
{
|
||||
switch ( event.data.keyCode )
|
||||
{
|
||||
// Paste
|
||||
case CKEDITOR.CTRL + 86 : // CTRL+V
|
||||
case CKEDITOR.SHIFT + 45 : // SHIFT+INS
|
||||
|
||||
var editor = this;
|
||||
editor.fire( 'saveSnapshot' ); // Save before paste
|
||||
|
||||
if ( editor.fire( 'beforePaste' ) )
|
||||
event.cancel();
|
||||
|
||||
setTimeout( function()
|
||||
{
|
||||
editor.fire( 'saveSnapshot' ); // Save after paste
|
||||
}, 0 );
|
||||
return;
|
||||
|
||||
// Cut
|
||||
case CKEDITOR.CTRL + 88 : // CTRL+X
|
||||
case CKEDITOR.SHIFT + 46 : // SHIFT+DEL
|
||||
|
||||
// Save Undo snapshot.
|
||||
editor = this;
|
||||
editor.fire( 'saveSnapshot' ); // Save before paste
|
||||
setTimeout( function()
|
||||
{
|
||||
editor.fire( 'saveSnapshot' ); // Save after paste
|
||||
}, 0 );
|
||||
}
|
||||
};
|
||||
|
||||
// Register the plugin.
|
||||
CKEDITOR.plugins.add( 'clipboard',
|
||||
{
|
||||
init : function( editor )
|
||||
{
|
||||
function addButtonCommand( buttonName, commandName, command, ctxMenuOrder )
|
||||
{
|
||||
var lang = editor.lang[ commandName ];
|
||||
|
||||
editor.addCommand( commandName, command );
|
||||
editor.ui.addButton( buttonName,
|
||||
{
|
||||
label : lang,
|
||||
command : commandName
|
||||
});
|
||||
|
||||
// If the "menu" plugin is loaded, register the menu item.
|
||||
if ( editor.addMenuItems )
|
||||
{
|
||||
editor.addMenuItem( commandName,
|
||||
{
|
||||
label : lang,
|
||||
command : commandName,
|
||||
group : 'clipboard',
|
||||
order : ctxMenuOrder
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addButtonCommand( 'Cut', 'cut', new cutCopyCmd( 'cut' ), 1 );
|
||||
addButtonCommand( 'Copy', 'copy', new cutCopyCmd( 'copy' ), 4 );
|
||||
addButtonCommand( 'Paste', 'paste', pasteCmd, 8 );
|
||||
|
||||
CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) );
|
||||
|
||||
editor.on( 'key', onKey, editor );
|
||||
|
||||
// If the "contextmenu" plugin is loaded, register the listeners.
|
||||
if ( editor.contextMenu )
|
||||
{
|
||||
function stateFromNamedCommand( command )
|
||||
{
|
||||
return editor.document.$.queryCommandEnabled( command ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
|
||||
}
|
||||
|
||||
editor.contextMenu.addListener( function()
|
||||
{
|
||||
return {
|
||||
cut : stateFromNamedCommand( 'Cut' ),
|
||||
|
||||
// Browser bug: 'Cut' has the correct states for both Copy and Cut.
|
||||
copy : stateFromNamedCommand( 'Cut' ),
|
||||
paste : CKEDITOR.env.webkit ? CKEDITOR.TRISTATE_OFF : stateFromNamedCommand( 'Paste' )
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user