diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..a0767ce460 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "packages/non-core/blaze"] + path = packages/non-core/blaze + url = https://github.com/meteor/blaze.git diff --git a/.travis.yml b/.travis.yml index 5ec40272b9..e943bf20c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,8 @@ node_js: - "4.0" cache: directories: - - "dev_bundle" - ".meteor" - ".babel-cache" -install: ./meteor --get-ready script: TEST_PACKAGES_EXCLUDE="less" ./packages/test-in-console/run.sh sudo: false env: diff --git a/Contributing.md b/Contributing.md index 547278dc69..38fa0880ad 100644 --- a/Contributing.md +++ b/Contributing.md @@ -1,10 +1,84 @@ # Contributing to Meteor -Thank you for contributing to the Meteor project! Please read the guidelines below or it might be -hard for the community to help you with your issue or pull request. +We are excited to have your help building Meteor — both the platform and the community behind it. Please read the project overview and guidelines for contributing bug reports and new code, or it might be hard for the community to help you with your issue or pull request. -We are excited to have your help building Meteor — both the platform and the -community behind it. Here's how you can help with bug reports and new code. +
Hello
', - 'Hello
', - 'HTML.P("Hello")'); - - run([], '', '', '[]'); - run([null, null], '', '', '[null, null]'); - - // Test crazy character references - - // `𝕫` is "Mathematical double-struck small z" a.k.a. "open-face z" - run(P(CharRef({html: '𝕫', str: '\ud835\udd6b'})), - '\ud835\udd6b
', - '𝕫
', - 'HTML.P(HTML.CharRef({html: "𝕫", str: "\\ud835\\udd6b"}))'); - - run(P({id: CharRef({html: '𝕫', str: '\ud835\udd6b'})}, 'Hello'), - 'Hello
', - 'Hello
', - 'HTML.P({id: HTML.CharRef({html: "𝕫", str: "\\ud835\\udd6b"})}, "Hello")'); - - run(P({id: [CharRef({html: '𝕫', str: '\ud835\udd6b'}), '!']}, 'Hello'), - 'Hello
', - 'Hello
', - 'HTML.P({id: [HTML.CharRef({html: "𝕫", str: "\\ud835\\udd6b"}), "!"]}, "Hello")'); - - // Test comments - - run(DIV(Comment('Test')), - '', // our innerHTML-canonicalization function kills comment contents - '', - 'HTML.DIV(HTML.Comment("Test"))'); - - // Test arrays - - run([P('Hello'), P('World')], - 'Hello
World
', - 'Hello
World
', - '[HTML.P("Hello"), HTML.P("World")]'); - - // Test slightly more complicated structure - - run(DIV({'class': 'foo'}, UL(LI(P(A({href: '#one'}, 'One'))), - LI(P('Two', BR(), 'Three')))), - 'Two
Three
Two
Three
Hello
'); - - var div = document.createElement("DIV"); - materialize(test1, div); - test.equal(canonicalizeHtml(div.innerHTML), "Hello
"); - - R.set('World'); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), "World
"); - })(); - - // Reactively change an array of text nodes - (function () { - var R = ReactiveVar(['Hello', ' World']); - var test1 = function () { - return P(Blaze.View(function () { return R.get(); })); - }; - - test.equal(toHTML(test1()), 'Hello World
'); - - var div = document.createElement("DIV"); - materialize(test1, div); - test.equal(canonicalizeHtml(div.innerHTML), "Hello World
"); - - R.set(['Goodbye', ' World']); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), "Goodbye World
"); - })(); - -}); - -// IE strips malformed styles like "bar::d" from the `style` -// attribute. We detect this to adjust expectations for the StyleHandler -// test below. -var malformedStylesAllowed = function () { - var div = document.createElement("div"); - div.setAttribute("style", "bar::d;"); - return (div.getAttribute("style") === "bar::d;"); -}; - -Tinytest.add("blaze - render - view GC", function (test) { - // test that removing parent element removes listeners and stops autoruns. - (function () { - var R = ReactiveVar('Hello'); - var test1 = P(Blaze.View(function () { return R.get(); })); - - var div = document.createElement("DIV"); - materialize(test1, div); - test.equal(canonicalizeHtml(div.innerHTML), "Hello
"); - - R.set('World'); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), "World
"); - - test.equal(R._numListeners(), 1); - - $(div).remove(); - - test.equal(R._numListeners(), 0); - - R.set('Steve'); - Tracker.flush(); - // should not have changed: - test.equal(canonicalizeHtml(div.innerHTML), "World
"); - })(); - -}); - -Tinytest.add("blaze - render - reactive attributes", function (test) { - (function () { - var R = ReactiveVar({'class': ['david gre', CharRef({html: 'ë', str: '\u00eb'}), 'nspan'], - id: 'foo'}); - - var spanFunc = function () { - return SPAN(HTML.Attrs( - function () { return R.get(); })); - }; - - test.equal(Blaze.toHTML(spanFunc()), - ''); - - test.equal(R._numListeners(), 0); - - var div = document.createElement("DIV"); - Blaze.render(spanFunc, div); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - test.equal(R._numListeners(), 1); - - var span = div.firstChild; - test.equal(span.nodeName, 'SPAN'); - span.className += ' blah'; // change the element's class outside of Blaze. this simulates what a jQuery could do - - R.set({'class': 'david smith', id: 'bar'}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - test.equal(R._numListeners(), 1); - - R.set({}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - test.equal(R._numListeners(), 1); - - $(div).remove(); - - test.equal(R._numListeners(), 0); - })(); - - // Test styles. - (function () { - // Test the case where there is a semicolon in the css attribute. - var R = ReactiveVar({'style': 'foo: "a;aa"; bar: b;', - id: 'foo'}); - - var spanFunc = function () { - return SPAN(HTML.Attrs(function () { return R.get(); })); - }; - - test.equal(Blaze.toHTML(spanFunc()), ''); - - test.equal(R._numListeners(), 0); - - var div = document.createElement("DIV"); - Blaze.render(spanFunc, div); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - test.equal(R._numListeners(), 1); - var span = div.firstChild; - test.equal(span.nodeName, 'SPAN'); - - span.setAttribute('style', span.getAttribute('style') + '; jquery-style: hidden'); - - R.set({'style': 'foo: "a;zz;aa";', id: 'bar'}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML, true), ''); - test.equal(R._numListeners(), 1); - - R.set({}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - test.equal(R._numListeners(), 1); - - $(div).remove(); - - test.equal(R._numListeners(), 0); - })(); - - // Test that identical styles are successfully overwritten. - (function () { - - var R = ReactiveVar({'style': 'foo: a;'}); - - var spanFunc = function () { - return SPAN(HTML.Attrs(function () { return R.get(); })); - }; - - var div = document.createElement("DIV"); - document.body.appendChild(div); - Blaze.render(spanFunc, div); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - var span = div.firstChild; - test.equal(span.nodeName, 'SPAN'); - span.setAttribute("style", 'foo: b;'); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - R.set({'style': 'foo: c;'}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - // test malformed styles - different expectations in IE (which - // strips malformed styles) from other browsers - R.set({'style': 'foo: a; bar::d;:e; baz: c;'}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), - malformedStylesAllowed() ? - '' : - ''); - - // Test strange styles - R.set({'style': ' foo: c; constructor: a; __proto__: b;'}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - R.set({}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - R.set({'style': 'foo: bar;'}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - })(); - - // Test `null`, `undefined`, and `[]` attributes - (function () { - var R = ReactiveVar({id: 'foo', - aaa: null, - bbb: undefined, - ccc: [], - ddd: [null], - eee: [undefined], - fff: [[]], - ggg: ['x', ['y', ['z']]]}); - - var spanFunc = function () { - return SPAN(HTML.Attrs( - function () { return R.get(); })); - }; - - test.equal(Blaze.toHTML(spanFunc()), ''); - test.equal(toCode(SPAN(R.get())), - 'HTML.SPAN({id: "foo", ggg: ["x", ["y", ["z"]]]})'); - - var div = document.createElement("DIV"); - Blaze.render(spanFunc, div); - var span = div.firstChild; - test.equal(span.nodeName, 'SPAN'); - - test.equal(canonicalizeHtml(div.innerHTML), ''); - R.set({id: 'foo', ggg: [[], [], []]}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - R.set({id: 'foo', ggg: null}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - R.set({id: 'foo', ggg: ''}); - Tracker.flush(); - test.equal(canonicalizeHtml(div.innerHTML), ''); - - $(div).remove(); - - test.equal(R._numListeners(), 0); - })(); -}); - -Tinytest.add("blaze - render - templates and views", function (test) { - (function () { - var counter = 1; - var buf = []; - - var myTemplate = Blaze.Template( - 'myTemplate', - function () { - return [String(this.number), - (this.number < 3 ? makeView() : HR())]; - }); - - myTemplate.constructView = function (number) { - var view = Template.prototype.constructView.call(this); - view.number = number; - return view; - }; - - myTemplate.created = function () { - test.isFalse(Tracker.active); - var view = this.view; - var parent = Blaze.getView(view, 'myTemplate'); - if (parent) { - buf.push('parent of ' + view.number + ' is ' + - parent.number); - } - - buf.push('created ' + Template.currentData()); - }; - - myTemplate.onRendered(function () { - test.isFalse(Tracker.active); - var nodeDescr = function (node) { - if (node.nodeType === 8) // comment - return ''; - if (node.nodeType === 3) // text - return node.nodeValue; - - return node.nodeName; - }; - - var view = this.view; - var start = view.firstNode(); - var end = view.lastNode(); - // skip marker nodes - while (start !== end && ! nodeDescr(start)) - start = start.nextSibling; - while (end !== start && ! nodeDescr(end)) - end = end.previousSibling; - - buf.push('dom-' + Template.currentData() + - ' is ' + nodeDescr(start) +'..' + - nodeDescr(end)); - }); - - myTemplate.onDestroyed(function () { - test.isFalse(Tracker.active); - buf.push('destroyed ' + Template.currentData()); - }); - - var makeView = function () { - var number = counter++; - return Blaze.With(number, function () { - return myTemplate.constructView(number); - }); - }; - - var div = document.createElement("DIV"); - - Blaze.render(makeView, div); - buf.push('---flush---'); - Tracker.flush(); - test.equal(buf, ['created 1', - 'parent of 2 is 1', - 'created 2', - 'parent of 3 is 2', - 'created 3', - '---flush---', - // (proper order for these has not be thought out:) - 'dom-3 is 3..HR', - 'dom-2 is 2..HR', - 'dom-1 is 1..HR']); - - test.equal(canonicalizeHtml(div.innerHTML), '123origin include
"http://example.com" and "https://foo.example.com". This value of
the X-Frame-Options header is not yet supported in Chrome or Safari
-and will be ignored in those browsers.
+and will be ignored in those browsers. If you need Chrome and/or Safari
+support, or need to allow multiple domains to frame your application,
+you can use the frame-ancestors CSP option via the
+BrowserPolicy.content.allowFrameAncestorsOrigin() function
@@ -124,7 +129,7 @@ Disallows inline CSS.
Finally, you can configure a whitelist of allowed requests that various types of
content can make. The following functions are defined for the content types
-script, object, image, media, font, frame, style, and connect.
+script, object, image, media, font, frame, frame-ancestors, style, and connect.