Skip to content

Commit

Permalink
Merge branch 't/10165'
Browse files Browse the repository at this point in the history
  • Loading branch information
oleq committed May 29, 2013
2 parents 929f6ab + d3afa90 commit 70fbb8d
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 77 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -12,6 +12,7 @@ CKEditor 4 Changelog
* [#6504](http://dev.ckeditor.com/ticket/6504): Resolved race condition while loading several customConfig files.
* [#10298](http://dev.ckeditor.com/ticket/10298): Data processor breaks attributes containing protected parts.
* [#9945](http://dev.ckeditor.com/ticket/9945): [iOS] Scrolling not possible on iPad.
* [#10165](http://dev.ckeditor.com/ticket/10165): [IE] Access denied error if document.domain has been altered.

## CKEditor 4.1.1

Expand Down
7 changes: 6 additions & 1 deletion core/dom/document.js
Expand Up @@ -261,7 +261,12 @@ CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype, {
this.$.open( 'text/html', 'replace' );

// Support for custom document.domain in IE.
CKEDITOR.env.isCustomDomain() && ( this.$.domain = document.domain );
//
// The script must be appended because if placed before the
// doctype, IE will go into quirks mode and mess with
// the editable, e.g. by changing its default height.
if ( CKEDITOR.env.ie )
html = html.replace( /(?:^\s*<!DOCTYPE[^>]*?>)|^/i, '$&\n<script data-cke-temp="1">(' + CKEDITOR.tools.fixDomain + ')();</script>' );

this.$.write( html );
this.$.close();
Expand Down
1 change: 1 addition & 0 deletions core/env.js
Expand Up @@ -109,6 +109,7 @@ if ( !CKEDITOR.env ) {
* alert( 'I\'m in a custom domain!' );
*
* @returns {Boolean} `true` if a custom domain is enabled.
* @deprecated
*/
isCustomDomain: function() {
if ( !this.ie )
Expand Down
39 changes: 39 additions & 0 deletions core/tools.js
Expand Up @@ -971,6 +971,45 @@
obj[ arr[ i ] ] = fillWith;

return obj;
},

/**
* Tries to fix the document.domain of the current document to match the
* parent window domain, avoiding "Same Origin" policy issues.
* This is a IE only requirement.
*
* @since 4.1.2
* @returns {boolean} True if the current domain is already good or if
* it has been fixed successfully.
*/
fixDomain: function() {
var domain;

while( 1 ) {
try {
// Try to access the parent document. It throws
// "access denied" if restricted by the "Same Origin" policy.
domain = parent.document.domain;
return true;
} catch ( e ) {
// Calculate the value to set to document.domain.
domain = domain ?

// If it is not the first pass, strip one part of the
// name. E.g. "test.example.com" => "example.com"
domain.replace( /.+?(?:\.|$)/, '' ) :

// In the first pass, we'll handle the
// "document.domain = document.domain" case.
document.domain;

// Stop here if there is no more domain parts available.
if ( !domain )
return false;

document.domain = domain;
}
}
}
};
})();
Expand Down
17 changes: 10 additions & 7 deletions plugins/clipboard/dialogs/paste.js
Expand Up @@ -5,7 +5,6 @@

CKEDITOR.dialog.add( 'paste', function( editor ) {
var lang = editor.lang.clipboard;
var isCustomDomain = CKEDITOR.env.isCustomDomain();

function onPasteFrameLoad( win ) {
var doc = new CKEDITOR.dom.document( win.document ),
Expand Down Expand Up @@ -130,12 +129,12 @@ CKEDITOR.dialog.add( 'paste', function( editor ) {
var src =
CKEDITOR.env.air ?
'javascript:void(0)' :
isCustomDomain ?
'javascript:void((function(){' +
CKEDITOR.env.ie ?
'javascript:void((function(){' + encodeURIComponent(
'document.open();' +
'document.domain=\'' + document.domain + '\';' +
'document.close();' +
'})())"'
'(' + CKEDITOR.tools.fixDomain + ')();' +
'document.close();'
) + '})())"'
: '';

var iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' +
Expand Down Expand Up @@ -172,7 +171,11 @@ CKEDITOR.dialog.add( 'paste', function( editor ) {
if ( CKEDITOR.env.ie ) {
var focusGrabber = CKEDITOR.dom.element.createFromHtml( '<span tabindex="-1" style="position:absolute" role="presentation"></span>' );
focusGrabber.on( 'focus', function() {
iframe.$.contentWindow.focus();
// Since fixDomain is called in src attribute,
// IE needs some slight delay to correctly move focus.
setTimeout( function() {
iframe.$.contentWindow.focus();
});
});
container.append( focusGrabber );

Expand Down
15 changes: 7 additions & 8 deletions plugins/dialog/plugin.js
Expand Up @@ -161,8 +161,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;

// IFrame shim for dialog that masks activeX in IE. (#7619)
if ( CKEDITOR.env.ie && !CKEDITOR.env.ie6Compat ) {
var isCustomDomain = CKEDITOR.env.isCustomDomain(),
src = 'javascript:void(function(){' + encodeURIComponent( 'document.open();' + ( isCustomDomain ? ( 'document.domain="' + document.domain + '";' ) : '' ) + 'document.close();' ) + '}())',
var src = 'javascript:void(function(){' + encodeURIComponent( 'document.open();(' + CKEDITOR.tools.fixDomain + ')();document.close();' ) + '}())',
iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' +
' frameBorder="0"' +
' class="cke_iframe_shim"' +
Expand Down Expand Up @@ -1976,21 +1975,21 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3;

if ( CKEDITOR.env.ie6Compat ) {
// Support for custom document.domain in IE.
var isCustomDomain = CKEDITOR.env.isCustomDomain(),
iframeHtml = '<html><body style=\\\'background-color:' + backgroundColorStyle + ';\\\'></body></html>';
var iframeHtml = '<html><body style=\\\'background-color:' + backgroundColorStyle + ';\\\'></body></html>';

html.push( '<iframe' +
' hidefocus="true"' +
' frameborder="0"' +
' id="cke_dialog_background_iframe"' +
' src="javascript:' );

html.push( 'void((function(){' +
html.push( 'void((function(){' + encodeURIComponent(
'document.open();' +
( isCustomDomain ? 'document.domain=\'' + document.domain + '\';' : '' ) +
// Support for custom document.domain in IE.
'(' + CKEDITOR.tools.fixDomain + ')();' +
'document.write( \'' + iframeHtml + '\' );' +
'document.close();' +
'})())' );
'document.close();'
) + '})())' );

html.push( '"' +
' style="' +
Expand Down
64 changes: 33 additions & 31 deletions plugins/dialogui/plugin.js
Expand Up @@ -592,9 +592,6 @@ CKEDITOR.plugins.add( 'dialogui', {
var innerHTML = function() {
_.frameId = CKEDITOR.tools.getNextId() + '_fileInput';

// Support for custom document.domain in IE.
var isCustomDomain = CKEDITOR.env.isCustomDomain();

var html = [
'<iframe' +
' frameborder="0"' +
Expand All @@ -605,11 +602,13 @@ CKEDITOR.plugins.add( 'dialogui', {
' title="', elementDefinition.label, '"' +
' src="javascript:void(' ];

html.push( isCustomDomain ? '(function(){' +
'document.open();' +
'document.domain=\'' + document.domain + '\';' +
'document.close();' +
'})()'
// Support for custom document.domain on IE. (#10165)
html.push( CKEDITOR.env.ie ?
'(function(){' + encodeURIComponent(
'document.open();' +
'(' + CKEDITOR.tools.fixDomain + ')();' +
'document.close();'
) + '})()'
:
'0' );

Expand Down Expand Up @@ -1256,33 +1255,36 @@ CKEDITOR.plugins.add( 'dialogui', {
function generateFormField() {
frameDocument.$.open();

// Support for custom document.domain in IE.
if ( CKEDITOR.env.isCustomDomain() )
frameDocument.$.domain = document.domain;

var size = '';
if ( elementDefinition.size )
size = elementDefinition.size - ( CKEDITOR.env.ie ? 7 : 0 ); // "Browse" button is bigger in IE.

var inputId = _.frameId + '_input';

frameDocument.$.write( [ '<html dir="' + langDir + '" lang="' + langCode + '"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">',
'<form enctype="multipart/form-data" method="POST" dir="' + langDir + '" lang="' + langCode + '" action="',
CKEDITOR.tools.htmlEncode( elementDefinition.action ),
'">',
// Replicate the field label inside of iframe.
'<label id="', _.labelId, '" for="', inputId, '" style="display:none">',
CKEDITOR.tools.htmlEncode( elementDefinition.label ),
'</label>',
'<input id="', inputId, '" aria-labelledby="', _.labelId, '" type="file" name="',
CKEDITOR.tools.htmlEncode( elementDefinition.id || 'cke_upload' ),
'" size="',
CKEDITOR.tools.htmlEncode( size > 0 ? size : "" ),
'" />',
'</form>',
'</body></html>',
'<script>window.parent.CKEDITOR.tools.callFunction(' + callNumber + ');',
'window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(' + unloadNumber + ')}</script>' ].join( '' ) );
var inputId = _.frameId + '_input';

frameDocument.$.write( [
'<html dir="' + langDir + '" lang="' + langCode + '"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">',
'<form enctype="multipart/form-data" method="POST" dir="' + langDir + '" lang="' + langCode + '" action="',
CKEDITOR.tools.htmlEncode( elementDefinition.action ),
'">',
// Replicate the field label inside of iframe.
'<label id="', _.labelId, '" for="', inputId, '" style="display:none">',
CKEDITOR.tools.htmlEncode( elementDefinition.label ),
'</label>',
'<input id="', inputId, '" aria-labelledby="', _.labelId, '" type="file" name="',
CKEDITOR.tools.htmlEncode( elementDefinition.id || 'cke_upload' ),
'" size="',
CKEDITOR.tools.htmlEncode( size > 0 ? size : "" ),
'" />',
'</form>',
'</body></html>',
'<script>',
// Support for custom document.domain in IE.
CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '',

'window.parent.CKEDITOR.tools.callFunction(' + callNumber + ');',
'window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(' + unloadNumber + ')}',
'</script>'
].join( '' ) );

frameDocument.$.close();

Expand Down
13 changes: 6 additions & 7 deletions plugins/docprops/dialogs/docprops.js
Expand Up @@ -146,13 +146,12 @@ CKEDITOR.dialog.add( 'docProps', function( editor ) {
};
};
var previewSrc = 'javascript:' +
'void((function(){' +
encodeURIComponent( 'document.open();' +
( CKEDITOR.env.isCustomDomain() ? 'document.domain=\'' + document.domain + '\';' : '' ) +
'document.write( \'<html style="background-color: #ffffff; height: 100%"><head></head><body style="width: 100%; height: 100%; margin: 0px">' + lang.previewHtml + '</body></html>\' );' +
'document.close();'
) +
'})())';
'void((function(){' + encodeURIComponent(
'document.open();' +
( CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '' ) +
'document.write( \'<html style="background-color: #ffffff; height: 100%"><head></head><body style="width: 100%; height: 100%; margin: 0px">' + lang.previewHtml + '</body></html>\' );' +
'document.close();'
) + '})())';

return {
title: lang.title,
Expand Down
16 changes: 14 additions & 2 deletions plugins/panel/plugin.js
Expand Up @@ -163,10 +163,22 @@
};

if ( this.isFramed ) {
// With IE, the custom domain has to be taken care at first,
// for other browers, the 'src' attribute should be left empty to
// trigger iframe's 'load' event.
var src =
CKEDITOR.env.air ? 'javascript:void(0)' :
CKEDITOR.env.ie ? 'javascript:void(function(){' + encodeURIComponent(
'document.open();' +
// In IE, the document domain must be set any time we call document.open().
'(' + CKEDITOR.tools.fixDomain + ')();' +
'document.close();'
) + '}())' :
'';

data.frame = frameTpl.output({
id: this.id + '_frame',
src: 'javascript:void(document.open(),' + ( CKEDITOR.env.isCustomDomain() ? 'document.domain=\'' + document.domain + '\',' : '' )
+ 'document.close())">'
src: src
});
}

Expand Down
11 changes: 6 additions & 5 deletions plugins/preview/plugin.js
Expand Up @@ -17,7 +17,6 @@
var sHTML,
config = editor.config,
baseTag = config.baseHref ? '<base href="' + config.baseHref + '"/>' : '',
isCustomDomain = CKEDITOR.env.isCustomDomain(),
eventData;

if ( config.fullPage ) {
Expand Down Expand Up @@ -63,15 +62,17 @@
return false;

var sOpenUrl = '';
if ( isCustomDomain ) {
if ( CKEDITOR.env.ie ) {
window._cke_htmlToLoad = eventData.dataValue;
sOpenUrl = 'javascript:void( (function(){' +
'document.open();' +
'document.domain="' + document.domain + '";' +
// Support for custom document.domain.
// Strip comments and replace parent with window.opener in the function body.
( '(' + CKEDITOR.tools.fixDomain + ')();' ).replace( /\/\/.*?\n/g, '' ).replace( /parent\./g, 'window.opener.' ) +
'document.write( window.opener._cke_htmlToLoad );' +
'document.close();' +
'window.opener._cke_htmlToLoad = null;' +
'})() )';
'})() )';
}

// With Firefox only, we need to open a special preview page, so
Expand All @@ -84,7 +85,7 @@
var oWindow = window.open( sOpenUrl, null, 'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width=' +
iWidth + ',height=' + iHeight + ',left=' + iLeft );

if ( !isCustomDomain && !CKEDITOR.env.gecko ) {
if ( !CKEDITOR.env.ie && !CKEDITOR.env.gecko ) {
var doc = oWindow.document;
doc.open();
doc.write( eventData.dataValue );
Expand Down
26 changes: 10 additions & 16 deletions plugins/wysiwygarea/plugin.js
Expand Up @@ -19,17 +19,9 @@
}

editor.addMode( 'wysiwyg', function( callback ) {
var iframe = CKEDITOR.document.createElement( 'iframe' );
iframe.setStyles({ width: '100%', height: '100%' } );
iframe.addClass( 'cke_wysiwyg_frame cke_reset' );

var contentSpace = editor.ui.space( 'contents' );
contentSpace.append( iframe );

var src = 'document.open();' +
// The document domain must be set any time we
// call document.open().
( isCustomDomain ? ( 'document.domain="' + document.domain + '";' ) : '' ) +
// In IE, the document domain must be set any time we call document.open().
( CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '' ) +
'document.close();';

// With IE, the custom domain has to be taken care at first,
Expand All @@ -39,6 +31,14 @@
:
'';

var iframe = CKEDITOR.dom.element.createFromHtml( '<iframe src="' + src + '" frameBorder="0"></iframe>' );
iframe.setStyles({ width: '100%', height: '100%' } );
iframe.addClass( 'cke_wysiwyg_frame cke_reset' );

var contentSpace = editor.ui.space( 'contents' );
contentSpace.append( iframe );


// Asynchronous iframe loading is only required in IE>8 and Gecko (other reasons probably).
// Do not use it on WebKit as it'll break the browser-back navigation.
var useOnloadEvent = CKEDITOR.env.ie || CKEDITOR.env.gecko;
Expand All @@ -63,10 +63,8 @@
});

iframe.setAttributes({
frameBorder: 0,
'aria-describedby' : labelId,
title: frameLabel,
src: src,
tabIndex: editor.tabIndex,
allowTransparency: 'true'
});
Expand Down Expand Up @@ -102,9 +100,6 @@
}
});

// Support for custom document.domain in IE.
var isCustomDomain = CKEDITOR.env.isCustomDomain();

function onDomReady( win ) {
var editor = this.editor,
doc = win.document,
Expand Down Expand Up @@ -412,7 +407,6 @@
// is fully editable even before the editing iframe is fully loaded (#4455).
var bootstrapCode =
'<script id="cke_actscrpt" type="text/javascript"' + ( CKEDITOR.env.ie ? ' defer="defer" ' : '' ) + '>' +
( isCustomDomain ? ( 'document.domain="' + document.domain + '";' ) : '' ) +
'var wasLoaded=0;' + // It must be always set to 0 as it remains as a window property.
'function onload(){' +
'if(!wasLoaded)' + // FF3.6 calls onload twice when editor.setData. Stop that.
Expand Down

0 comments on commit 70fbb8d

Please sign in to comment.