2018-06-17 16:07:19 +00:00
|
|
|
/**
|
|
|
|
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
|
|
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
2014-04-11 20:07:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* @fileOverview Defines the {@link CKEDITOR.dom.document} class which
|
2014-04-11 20:07:18 +00:00
|
|
|
* represents a DOM document.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents a DOM document.
|
|
|
|
*
|
|
|
|
* var document = new CKEDITOR.dom.document( document );
|
|
|
|
*
|
|
|
|
* @class
|
|
|
|
* @extends CKEDITOR.dom.domObject
|
|
|
|
* @constructor Creates a document class instance.
|
|
|
|
* @param {Object} domDocument A native DOM document.
|
|
|
|
*/
|
|
|
|
CKEDITOR.dom.document = function( domDocument ) {
|
|
|
|
CKEDITOR.dom.domObject.call( this, domDocument );
|
|
|
|
};
|
|
|
|
|
|
|
|
// PACKAGER_RENAME( CKEDITOR.dom.document )
|
|
|
|
|
|
|
|
CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject();
|
|
|
|
|
|
|
|
CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype, {
|
|
|
|
/**
|
|
|
|
* The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT}.
|
|
|
|
*
|
|
|
|
* @readonly
|
|
|
|
* @property {Number} [=CKEDITOR.NODE_DOCUMENT]
|
|
|
|
*/
|
|
|
|
type: CKEDITOR.NODE_DOCUMENT,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Appends a CSS file to the document.
|
|
|
|
*
|
|
|
|
* CKEDITOR.document.appendStyleSheet( '/mystyles.css' );
|
|
|
|
*
|
|
|
|
* @param {String} cssFileUrl The CSS file URL.
|
|
|
|
*/
|
|
|
|
appendStyleSheet: function( cssFileUrl ) {
|
|
|
|
if ( this.$.createStyleSheet )
|
|
|
|
this.$.createStyleSheet( cssFileUrl );
|
|
|
|
else {
|
|
|
|
var link = new CKEDITOR.dom.element( 'link' );
|
|
|
|
link.setAttributes( {
|
|
|
|
rel: 'stylesheet',
|
|
|
|
type: 'text/css',
|
|
|
|
href: cssFileUrl
|
|
|
|
} );
|
|
|
|
|
|
|
|
this.getHead().append( link );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Creates a CSS stylesheet and inserts it into the document.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* @param cssStyleText {String} CSS style text.
|
2018-06-17 16:07:19 +00:00
|
|
|
* @returns {Object} The created DOM native stylesheet object.
|
2014-04-11 20:07:18 +00:00
|
|
|
*/
|
|
|
|
appendStyleText: function( cssStyleText ) {
|
|
|
|
if ( this.$.createStyleSheet ) {
|
2018-06-17 16:07:19 +00:00
|
|
|
var styleSheet = this.$.createStyleSheet( '' );
|
2014-04-11 20:07:18 +00:00
|
|
|
styleSheet.cssText = cssStyleText;
|
|
|
|
} else {
|
|
|
|
var style = new CKEDITOR.dom.element( 'style', this );
|
|
|
|
style.append( new CKEDITOR.dom.text( cssStyleText, this ) );
|
|
|
|
this.getHead().append( style );
|
|
|
|
}
|
|
|
|
|
|
|
|
return styleSheet || style.$.sheet;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Creates a {@link CKEDITOR.dom.element} instance in this document.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* @param {String} name The name of the element.
|
|
|
|
* @param {Object} [attributesAndStyles]
|
|
|
|
* @param {Object} [attributesAndStyles.attributes] Attributes that will be set.
|
|
|
|
* @param {Object} [attributesAndStyles.styles] Styles that will be set.
|
2014-04-11 20:07:18 +00:00
|
|
|
* @returns {CKEDITOR.dom.element}
|
|
|
|
*/
|
|
|
|
createElement: function( name, attribsAndStyles ) {
|
|
|
|
var element = new CKEDITOR.dom.element( name, this );
|
|
|
|
|
|
|
|
if ( attribsAndStyles ) {
|
|
|
|
if ( attribsAndStyles.attributes )
|
|
|
|
element.setAttributes( attribsAndStyles.attributes );
|
|
|
|
|
|
|
|
if ( attribsAndStyles.styles )
|
|
|
|
element.setStyles( attribsAndStyles.styles );
|
|
|
|
}
|
|
|
|
|
|
|
|
return element;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Creates a {@link CKEDITOR.dom.text} instance in this document.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* @param {String} text Value of the text node.
|
|
|
|
* @returns {CKEDITOR.dom.element}
|
|
|
|
*/
|
|
|
|
createText: function( text ) {
|
|
|
|
return new CKEDITOR.dom.text( text, this );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Moves the selection focus to this document's window.
|
|
|
|
*/
|
|
|
|
focus: function() {
|
|
|
|
this.getWindow().focus();
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the element that is currently designated as the active element in the document.
|
|
|
|
*
|
|
|
|
* **Note:** Only one element can be active at a time in a document.
|
|
|
|
* An active element does not necessarily have focus,
|
|
|
|
* but an element with focus is always the active element in a document.
|
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* @returns {CKEDITOR.dom.element} Active element or `null` if an IE8-9 bug is encountered.
|
|
|
|
* See [#10030](https://dev.ckeditor.com/ticket/10030).
|
2014-04-11 20:07:18 +00:00
|
|
|
*/
|
|
|
|
getActive: function() {
|
2018-06-17 16:07:19 +00:00
|
|
|
var $active;
|
|
|
|
try {
|
|
|
|
$active = this.$.activeElement;
|
|
|
|
} catch ( e ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return new CKEDITOR.dom.element( $active );
|
2014-04-11 20:07:18 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Gets an element based on its ID.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* var element = CKEDITOR.document.getById( 'myElement' );
|
|
|
|
* alert( element.getId() ); // 'myElement'
|
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* @param {String} elementId The element ID.
|
|
|
|
* @returns {CKEDITOR.dom.element} The element instance, or `null` if not found.
|
2014-04-11 20:07:18 +00:00
|
|
|
*/
|
|
|
|
getById: function( elementId ) {
|
|
|
|
var $ = this.$.getElementById( elementId );
|
|
|
|
return $ ? new CKEDITOR.dom.element( $ ) : null;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets a node based on its address. See {@link CKEDITOR.dom.node#getAddress}.
|
|
|
|
*
|
|
|
|
* @param {Array} address
|
|
|
|
* @param {Boolean} [normalized=false]
|
|
|
|
*/
|
|
|
|
getByAddress: function( address, normalized ) {
|
|
|
|
var $ = this.$.documentElement;
|
|
|
|
|
|
|
|
for ( var i = 0; $ && i < address.length; i++ ) {
|
|
|
|
var target = address[ i ];
|
|
|
|
|
|
|
|
if ( !normalized ) {
|
|
|
|
$ = $.childNodes[ target ];
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
var currentIndex = -1;
|
|
|
|
|
|
|
|
for ( var j = 0; j < $.childNodes.length; j++ ) {
|
|
|
|
var candidate = $.childNodes[ j ];
|
|
|
|
|
|
|
|
if ( normalized === true && candidate.nodeType == 3 && candidate.previousSibling && candidate.previousSibling.nodeType == 3 )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
currentIndex++;
|
|
|
|
|
|
|
|
if ( currentIndex == target ) {
|
|
|
|
$ = candidate;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $ ? new CKEDITOR.dom.node( $ ) : null;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Gets elements list based on a given tag name.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* @param {String} tagName The element tag name.
|
|
|
|
* @returns {CKEDITOR.dom.nodeList} The nodes list.
|
|
|
|
*/
|
|
|
|
getElementsByTag: function( tagName, namespace ) {
|
2018-06-17 16:07:19 +00:00
|
|
|
if ( !( CKEDITOR.env.ie && ( document.documentMode <= 8 ) ) && namespace )
|
2014-04-11 20:07:18 +00:00
|
|
|
tagName = namespace + ':' + tagName;
|
|
|
|
return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the `<head>` element for this document.
|
|
|
|
*
|
|
|
|
* var element = CKEDITOR.document.getHead();
|
|
|
|
* alert( element.getName() ); // 'head'
|
|
|
|
*
|
|
|
|
* @returns {CKEDITOR.dom.element} The `<head>` element.
|
|
|
|
*/
|
|
|
|
getHead: function() {
|
|
|
|
var head = this.$.getElementsByTagName( 'head' )[ 0 ];
|
|
|
|
if ( !head )
|
|
|
|
head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true );
|
|
|
|
else
|
|
|
|
head = new CKEDITOR.dom.element( head );
|
|
|
|
|
|
|
|
return head;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the `<body>` element for this document.
|
|
|
|
*
|
|
|
|
* var element = CKEDITOR.document.getBody();
|
|
|
|
* alert( element.getName() ); // 'body'
|
|
|
|
*
|
|
|
|
* @returns {CKEDITOR.dom.element} The `<body>` element.
|
|
|
|
*/
|
|
|
|
getBody: function() {
|
|
|
|
return new CKEDITOR.dom.element( this.$.body );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the DOM document element for this document.
|
|
|
|
*
|
|
|
|
* @returns {CKEDITOR.dom.element} The DOM document element.
|
|
|
|
*/
|
|
|
|
getDocumentElement: function() {
|
|
|
|
return new CKEDITOR.dom.element( this.$.documentElement );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Gets the window object that stores this document.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* @returns {CKEDITOR.dom.window} The window object.
|
|
|
|
*/
|
|
|
|
getWindow: function() {
|
|
|
|
return new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Defines the document content through `document.write`. Note that the
|
|
|
|
* previous document content will be lost (cleaned).
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* document.write(
|
|
|
|
* '<html>' +
|
2018-06-17 16:07:19 +00:00
|
|
|
* '<head><title>Sample Document</title></head>' +
|
|
|
|
* '<body>Document content created by code.</body>' +
|
2014-04-11 20:07:18 +00:00
|
|
|
* '</html>'
|
|
|
|
* );
|
|
|
|
*
|
|
|
|
* @since 3.5
|
2018-06-17 16:07:19 +00:00
|
|
|
* @param {String} html The HTML defining the document content.
|
2014-04-11 20:07:18 +00:00
|
|
|
*/
|
|
|
|
write: function( html ) {
|
2018-06-17 16:07:19 +00:00
|
|
|
// Don't leave any history log in IE. (https://dev.ckeditor.com/ticket/5657)
|
2014-04-11 20:07:18 +00:00
|
|
|
this.$.open( 'text/html', 'replace' );
|
|
|
|
|
|
|
|
// Support for custom document.domain in IE.
|
|
|
|
//
|
|
|
|
// 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();
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper for `querySelectorAll`. Returns a list of elements within this document that match
|
2018-06-17 16:07:19 +00:00
|
|
|
* the specified `selector`.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* **Note:** The returned list is not a live collection (like the result of native `querySelectorAll`).
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* @since 4.3
|
|
|
|
* @param {String} selector
|
|
|
|
* @returns {CKEDITOR.dom.nodeList}
|
|
|
|
*/
|
|
|
|
find: function( selector ) {
|
|
|
|
return new CKEDITOR.dom.nodeList( this.$.querySelectorAll( selector ) );
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Wrapper for `querySelector`. Returns the first element within this document that matches
|
|
|
|
* the specified `selector`.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* @since 4.3
|
|
|
|
* @param {String} selector
|
|
|
|
* @returns {CKEDITOR.dom.element}
|
|
|
|
*/
|
|
|
|
findOne: function( selector ) {
|
|
|
|
var el = this.$.querySelector( selector );
|
|
|
|
|
|
|
|
return el ? new CKEDITOR.dom.element( el ) : null;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Internet Explorer 8 only method. It returns a document fragment which has all HTML5 elements enabled.
|
2014-04-11 20:07:18 +00:00
|
|
|
*
|
|
|
|
* @since 4.3
|
|
|
|
* @private
|
|
|
|
* @returns DocumentFragment
|
|
|
|
*/
|
|
|
|
_getHtml5ShivFrag: function() {
|
|
|
|
var $frag = this.getCustomData( 'html5ShivFrag' );
|
|
|
|
|
|
|
|
if ( !$frag ) {
|
|
|
|
$frag = this.$.createDocumentFragment();
|
|
|
|
CKEDITOR.tools.enableHtml5Elements( $frag, true );
|
|
|
|
this.setCustomData( 'html5ShivFrag', $frag );
|
|
|
|
}
|
|
|
|
|
|
|
|
return $frag;
|
|
|
|
}
|
|
|
|
} );
|