diff --git a/compiler/ast/HtmlAttribute/html/generateCode.js b/compiler/ast/HtmlAttribute/html/generateCode.js
index e65ea7a44..66a018bd5 100644
--- a/compiler/ast/HtmlAttribute/html/generateCode.js
+++ b/compiler/ast/HtmlAttribute/html/generateCode.js
@@ -1,7 +1,8 @@
'use strict';
-var attr = require('../../../../runtime/html/attr');
-var escapeXmlAttr = require('../../../../runtime/html/escapeXml').attr;
+var runtimeHtmlHelpers = require('../../../../runtime/html/helpers');
+var attr = runtimeHtmlHelpers.a;
+var escapeXmlAttr = runtimeHtmlHelpers.xa;
function isStringLiteral(node) {
return node.type === 'Literal' && typeof node.value === 'string';
@@ -76,12 +77,11 @@ function generateCodeForExpressionAttr(name, value, escape, codegen) {
if (isStringLiteral(part)) {
part.value = escapeXmlAttr(part.value);
} else if (part.type === 'Literal') {
-
} else if (isNoEscapeXml(part)) {
part = codegen.builder.functionCall(context.helper('str'), [part]);
} else {
if (escape !== false) {
- part = codegen.builder.functionCall(context.helper('escapeXmlAttr'), [part]);
+ part = builder.functionCall(context.helper('escapeXmlAttr'), [part]);
}
}
addHtml(part);
diff --git a/compiler/ast/Text/html/generateCode.js b/compiler/ast/Text/html/generateCode.js
index c179f70e3..9feb57a5e 100644
--- a/compiler/ast/Text/html/generateCode.js
+++ b/compiler/ast/Text/html/generateCode.js
@@ -1,6 +1,6 @@
'use strict';
-var escapeXml = require('../../../../runtime/html/escapeXml');
+var escapeXml = require('../../../../runtime/html/helpers').x;
var Literal = require('../..//Literal');
module.exports = function(node, codegen) {
diff --git a/compiler/ast/Text/vdom/TextVDOM.js b/compiler/ast/Text/vdom/TextVDOM.js
index 9d63715f0..781fa2945 100644
--- a/compiler/ast/Text/vdom/TextVDOM.js
+++ b/compiler/ast/Text/vdom/TextVDOM.js
@@ -21,16 +21,6 @@ class TextVDOM extends Node {
vdomUtil.registerOptimizer(context);
- var args = this.arguments;
-
- for (var i=0, len=args.length; i 'a b'
- *
- */
- cl: function() {
- return classList(arguments);
- },
-
- /**
- * Loads a template (__helpers.l --> marko_loadTemplate(path))
- */
- l: load,
-
- i: require('./include')
+ };
+ } else {
+ return renderer;
+ }
};
+
+/**
+ * Merges object properties
+ * @param {[type]} object [description]
+ * @param {[type]} source [description]
+ * @return {[type]} [description]
+ */
+exports.m = function mergeHelper(into, source) {
+ for (var k in source) {
+ if (source.hasOwnProperty(k) && !into.hasOwnProperty(k)) {
+ into[k] = source[k];
+ }
+ }
+ return into;
+};
+
+/**
+ * classList(a, b, c, ...)
+ * Joines a list of class names with spaces. Empty class names are omitted.
+ *
+ * classList('a', undefined, 'b') --> 'a b'
+ *
+ */
+exports.cl = function classListHelper() {
+ return classList(arguments);
+};
+
+/**
+ * Loads a template (__helpers.l --> marko_loadTemplate(path))
+ */
+exports.l = require('./loader');
+exports.i = require('./include');
\ No newline at end of file
diff --git a/runtime/html/AsyncStream.js b/runtime/html/AsyncStream.js
index 0c89296d4..7a3f58d67 100644
--- a/runtime/html/AsyncStream.js
+++ b/runtime/html/AsyncStream.js
@@ -2,11 +2,9 @@
var EventEmitter = require('events').EventEmitter;
var StringWriter = require('./StringWriter');
var BufferedWriter = require('./BufferedWriter');
-var attr = require('./attr');
-var escapeXml = require('./escapeXml');
var extend = require('raptor-util/extend');
-
-var defaultDocument = typeof document != 'undefined' && document;
+var documentProvider = require('../document-provider');
+var helpers;
var voidWriter = { write:function(){} };
@@ -412,12 +410,10 @@ var proto = AsyncStream.prototype = {
return new AsyncStream(this.global);
},
- beginElement: function(name, attrs) {
+ beginElement: function(name, elementAttrs) {
var str = '<' + name;
- for (var attrName in attrs) {
- str += attr(attrName, attrs[attrName]);
- }
+ helpers.as(elementAttrs);
str += '>';
@@ -436,7 +432,7 @@ var proto = AsyncStream.prototype = {
},
text: function(str) {
- this.write(escapeXml(str));
+ this.write(helpers.x(str));
},
getNode: function(doc) {
@@ -446,7 +442,7 @@ var proto = AsyncStream.prototype = {
var html = this.getOutput();
if (!doc) {
- doc = this.document || defaultDocument;
+ doc = documentProvider.document;
}
if (!node) {
@@ -504,4 +500,6 @@ proto.w = proto.write;
extend(proto, require('../OutMixins'));
-module.exports = AsyncStream;
\ No newline at end of file
+module.exports = AsyncStream;
+
+helpers = require('./helpers');
\ No newline at end of file
diff --git a/runtime/html/attr.js b/runtime/html/attr.js
deleted file mode 100644
index d038d1ce9..000000000
--- a/runtime/html/attr.js
+++ /dev/null
@@ -1,13 +0,0 @@
-var escapeXmlAttr = require('./escapeXml').attr;
-
-module.exports = function(name, value, shouldEscape) {
- if (typeof value === 'string') {
- return ' ' + name + '="' + (shouldEscape !== false ? escapeXmlAttr(value) : value) + '"';
- } else if (value === true) {
- return ' ' + name;
- } else if (value == null || value === false) {
- return '';
- } else {
- return ' ' + name + '="' + value.toString() + '"';
- }
-};
diff --git a/runtime/html/escapeXml.js b/runtime/html/escapeXml.js
deleted file mode 100644
index 8a43dec41..000000000
--- a/runtime/html/escapeXml.js
+++ /dev/null
@@ -1,35 +0,0 @@
-var elTest = /[&<]/;
-var elTestReplace = /[&<]/g;
-var attrTest = /[&<\"\n]/;
-var attrReplace = /[&<\"\n]/g;
-var replacements = {
- '<': '<',
- '&': '&',
- '"': '"',
- '\n': '
' //Preserve new lines so that they don't get normalized as space
-};
-
-function replaceChar(match) {
- return replacements[match];
-}
-
-function escapeXml(str) {
- // check for most common case first
- if (typeof str === 'string') {
- return elTest.test(str) ? str.replace(elTestReplace, replaceChar) : str;
- }
-
- return (str == null) ? '' : str.toString();
-}
-
-function escapeXmlAttr(str) {
- if (typeof str === 'string') {
- return attrTest.test(str) ? str.replace(attrReplace, replaceChar) : str;
- }
-
- return (str == null) ? '' : str.toString();
-}
-
-
-module.exports = escapeXml;
-escapeXml.attr = escapeXmlAttr;
\ No newline at end of file
diff --git a/runtime/html/helpers.js b/runtime/html/helpers.js
index 6a920a618..4443bc139 100644
--- a/runtime/html/helpers.js
+++ b/runtime/html/helpers.js
@@ -1,120 +1,193 @@
'use strict';
-var escapeXml = require('./escapeXml');
-var escapeXmlAttr = escapeXml.attr;
-var attr = require('./attr');
+require('raptor-polyfill/string/startsWith');
+
+var warp10 = require('warp10');
var extend = require('raptor-util/extend');
var STYLE_ATTR = 'style';
var CLASS_ATTR = 'class';
var escapeEndingScriptTagRegExp = /<\//g;
-var commonHelpers = require('../helpers');
+var elTest = /[&<]/;
+var elTestReplace = /[&<]/g;
+var attrTest = /[&<\"\n]/;
+var attrReplace = /[&<\"\n]/g;
+var stringifiedAttrTest = /[&\'\n]/;
+var stringifiedAttrReplace = /[&\'\n]/g;
-var classList = commonHelpers.cl;
+var classList;
-module.exports = extend({
- /**
- * Internal method to escape special XML characters
- * @private
- */
- x: escapeXml,
- /**
- * Internal method to escape special XML characters within an attribute
- * @private
- */
- xa: escapeXmlAttr,
+var replacements = {
+ '<': '<',
+ '&': '&',
+ '"': '"',
+ '\'': ''',
+ '\n': '
' //Preserve new lines so that they don't get normalized as space
+};
- /**
- * Escapes the '' sequence in the body of a '
- * };
- *
- *
- *
- * Without escaping the ending '' sequence the opening '
+ * };
+ *
+ *
+ *
+ * Without escaping the ending '' sequence the opening