| Index: Source/core/dom/ProcessingInstruction.js
|
| diff --git a/Source/core/dom/ProcessingInstruction.js b/Source/core/dom/ProcessingInstruction.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..23d529b0a031061f8c1bfc045feb2ede72571328
|
| --- /dev/null
|
| +++ b/Source/core/dom/ProcessingInstruction.js
|
| @@ -0,0 +1,167 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +"use strict";
|
| +
|
| +installClass("ProcessingInstruction", function(ProcessingInstructionPrototype) {
|
| +
|
| + // Should be implemented as HTMLSerializer / XMLSerializer.
|
| + function serializeAttributes(node) {
|
| + var attributes = node.attributes;
|
| + if (!attributes)
|
| + return '';
|
| + var sink = '';
|
| + var attrs = [];
|
| + for (var index = 0; index < attributes.length; ++index) {
|
| + attrs.push(attributes[index]);
|
| + }
|
| +
|
| + attrs.sort(function(a, b) {
|
| + return a.name <= b.name ? -1 : 0;
|
| + }).forEach(function(attr) {
|
| + var attrName = attr.name;
|
| + if (attrName.indexOf('_moz') == 0)
|
| + return;
|
| + var attrValue = attr.value;
|
| + if (attrValue){
|
| + attrValue = String(attrValue).replace(/&/g, '&')
|
| + .replace(/\u0022/g, '"')
|
| + sink += ' ' + attrName + '="' + attrValue + '"';
|
| + } else {
|
| + sink += ' ' + attrName;
|
| + }
|
| + });
|
| + return sink;
|
| + }
|
| +
|
| + function serializeChildren(node, isXML) {
|
| + var sink = '';
|
| + var child = node.firstChild;
|
| + while (child) {
|
| + sink += serialize(child, isXML);
|
| + var nextSibling = child.nextSibling;
|
| + if (child.nodeType == Node.TEXT_NODE && nextSibling &&
|
| + nextSibling.nodeType == Node.TEXT_NODE) {
|
| + sink += '_';
|
| + }
|
| + child = nextSibling;
|
| + }
|
| + return sink;
|
| + }
|
| +
|
| + var _END_TAG_MISSIBLE = {'area':true,'base':true,'br':true,'col':true,'command':true,'embed':true,'frame':true,
|
| + 'hr':true,'img':true,'input':true,'keygen':true,'link':true,'meta':true,'param':true,
|
| + 'source':true,'track':true,'wbr':true};
|
| +
|
| + // FIXME: should implement this as HTMLSerializer to share the code with editing?
|
| + function serialize(node, isXML) {
|
| + if (node.nodeType == Node.TEXT_NODE) {
|
| + if (node.parentNode && node.parentNode.nodeType == Node.ELEMENT_NODE && node.parentNode.nodeName.toLowerCase() == 'script')
|
| + return node.nodeValue;
|
| + // Need to escape: &, <
|
| + return node.nodeValue.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
| + }
|
| + if (node.nodeType == Node.DOCUMENT_TYPE_NODE) {
|
| + var sink = '<!DOCTYPE ' + node.name;
|
| + if (node.publicId) {
|
| + sink += ' PUBLIC "' + node.publicId + '"';
|
| + if (node.systemId)
|
| + sink += ' "' + node.systemId + '"';
|
| + }
|
| + sink += '>';
|
| + return sink;
|
| + }
|
| + if (node.nodeType == Node.PROCESSING_INSTRUCTION_NODE) {
|
| + var sink = '<?' + node.target;
|
| + if (node.nodeValue)
|
| + sink += ' ' + node.nodeValue;
|
| + sink += '?>';
|
| + return sink;
|
| + }
|
| + if (node.nodeType == Node.COMMENT_NODE) {
|
| + return '<!-- ' + node.nodeValue + ' -->';
|
| + }
|
| + if (node.nodeType != Node.ELEMENT_NODE) {
|
| + // To support |Document| node, we iterate over child nodes.
|
| + var sink = '';
|
| + for (var child = node.firstChild; child; child = child.nextSibling) {
|
| + sink += serialize(child, isXML);
|
| + }
|
| + return sink.length ? sink : node.nodeValue;
|
| + }
|
| +
|
| + var tagName = node.nodeName.toLowerCase();
|
| + var sink = '<' + node.nodeName + serializeAttributes(node) + '>';
|
| +
|
| + if (tagName == 'template') {
|
| + sink += serializeChildren(node.content, node.content instanceof XMLDocument);
|
| + } else if (tagName == 'iframe') {
|
| + sink += serialize(node.contentDocument, node.contentDocument instanceof XMLDocument);
|
| + } else {
|
| + sink += serializeChildren(node, isXML);
|
| + }
|
| +
|
| + if (!_END_TAG_MISSIBLE[tagName] || isXML)
|
| + sink += '</' + node.nodeName + '>';
|
| + return sink;
|
| + }
|
| +
|
| + function applyXSLTransformToCurrentDocument(pi) {
|
| + var processor = new XSLTProcessor;
|
| + processor.importStylesheet(pi.styleSheetRootNode_);
|
| + var transformedDocument = processor.transformToDocument(window.document);
|
| + if (!transformedDocument)
|
| + return;
|
| + var content = serialize(transformedDocument, transformedDocument instanceof XMLDocument);
|
| + window.replaceDocument(content, transformedDocument.contentType, transformedDocument.characterSet);
|
| + }
|
| +
|
| + function findFirstStyleSheet() {
|
| + for (var child = document.firstChild; child; child = child.nextSibling) {
|
| + if (child.nodeName == 'xml-stylesheet')
|
| + return child.styleSheetRootNode_ ? child : null;
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + function initializeForXSLT(parsing) {
|
| + window.document.parsing_ = parsing;
|
| + window.document.addEventListener('DOMContentLoaded', function() {
|
| + window.document.parsing_ = false;
|
| + if (window.document.transformSourceDocument_)
|
| + return;
|
| + var pi = findFirstStyleSheet();
|
| + if (!pi)
|
| + return;
|
| + applyXSLTransformToCurrentDocument(pi);
|
| + }, false);
|
| + }
|
| +
|
| + ProcessingInstructionPrototype.onProcessingInstructionAvailable = function(href, parsing) {
|
| + if (!window.document.xslStyleSheetInitialized_)
|
| + initializeForXSLT(parsing);
|
| +
|
| + var request = new XMLHttpRequest();
|
| + request.pi_ = this;
|
| + request.onload = function() {
|
| + var xmldoc = request.responseXML;
|
| + if (!xmldoc)
|
| + xmldoc = new DOMParser().parseFromString(request.responseText, 'text/xml');
|
| + var regex = new RegExp('#[^/#?]+$');
|
| + var match = regex.exec(href);
|
| + if (match && xmldoc) {
|
| + this.pi_.styleSheetRootNode_ = xmldoc.getElementById(match[0].substring(1));
|
| + } else {
|
| + this.pi_.styleSheetRootNode_ = xmldoc;
|
| + }
|
| + if (window.document.transformSourceDocument_ || window.document.parsing_)
|
| + return;
|
| + if (findFirstStyleSheet() == this.pi_)
|
| + applyXSLTransformToCurrentDocument(this.pi_);
|
| + };
|
| + request.open("GET", href, true);
|
| + request.send();
|
| + }
|
| +});
|
| +
|
|
|