Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(657)

Unified Diff: Source/core/dom/ProcessingInstruction.js

Issue 703193004: XSLT-in-PrivateScript (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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, '&amp;')
+ .replace(/\u0022/g, '&quot;')
+ 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: &amp;, &lt;
+ return node.nodeValue.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+ }
+ 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();
+ }
+});
+

Powered by Google App Engine
This is Rietveld 408576698