From 1e12de8b00d75875a61077653e919c47297a0fbe Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Mon, 27 Nov 2023 18:36:24 +0100 Subject: [PATCH 1/3] Update blaze package to es6 --- packages/blaze/attrs.js | 93 +++++++------- packages/blaze/builtins.js | 47 ++++---- packages/blaze/dombackend.js | 34 +++--- packages/blaze/domrange.js | 90 +++++++------- packages/blaze/events.js | 58 +++++---- packages/blaze/exceptions.js | 4 +- packages/blaze/lookup.js | 54 ++++----- packages/blaze/materializer.js | 46 +++---- packages/blaze/package.js | 18 +-- packages/blaze/preamble.js | 16 +-- packages/blaze/render_tests.js | 214 ++++++++++++++++----------------- packages/blaze/template.js | 75 ++++++------ packages/blaze/view.js | 117 +++++++++--------- packages/blaze/view_tests.js | 16 +-- 14 files changed, 441 insertions(+), 441 deletions(-) diff --git a/packages/blaze/attrs.js b/packages/blaze/attrs.js index cbc112cea..50b5162ae 100644 --- a/packages/blaze/attrs.js +++ b/packages/blaze/attrs.js @@ -1,6 +1,7 @@ import has from 'lodash.has'; +import { OrderedDict } from 'meteor/ordered-dict'; -var jsUrlsAllowed = false; +let jsUrlsAllowed = false; Blaze._allowJavascriptUrls = function () { jsUrlsAllowed = true; }; @@ -47,8 +48,8 @@ AttributeHandler.prototype.update = function (element, oldValue, value) { }; AttributeHandler.extend = function (options) { - var curType = this; - var subType = function AttributeHandlerSubtype(/*arguments*/) { + const curType = this; + const subType = function AttributeHandlerSubtype(/*arguments*/) { AttributeHandler.apply(this, arguments); }; subType.prototype = new curType; @@ -73,13 +74,13 @@ Blaze._DiffingAttributeHandler = AttributeHandler.extend({ if (!this.getCurrentValue || !this.setValue || !this.parseValue || !this.joinValues) throw new Error("Missing methods in subclass of 'DiffingAttributeHandler'"); - var oldAttrsMap = oldValue ? this.parseValue(oldValue) : new OrderedDict(); - var attrsMap = value ? this.parseValue(value) : new OrderedDict(); + const oldAttrsMap = oldValue ? this.parseValue(oldValue) : new OrderedDict(); + const attrsMap = value ? this.parseValue(value) : new OrderedDict(); // the current attributes on the element, which we will mutate. - var currentAttrString = this.getCurrentValue(element); - var currentAttrsMap = currentAttrString ? this.parseValue(currentAttrString) : new OrderedDict(); + const currentAttrString = this.getCurrentValue(element); + const currentAttrsMap = currentAttrString ? this.parseValue(currentAttrString) : new OrderedDict(); // Any outside changes to attributes we add at the end. currentAttrsMap.forEach(function (value, key, i) { @@ -97,7 +98,7 @@ Blaze._DiffingAttributeHandler = AttributeHandler.extend({ attrsMap.append(key, value); }); - var values = []; + const values = []; attrsMap.forEach(function (value, key, i) { values.push(value); }); @@ -106,7 +107,7 @@ Blaze._DiffingAttributeHandler = AttributeHandler.extend({ } }); -var ClassHandler = Blaze._DiffingAttributeHandler.extend({ +const ClassHandler = Blaze._DiffingAttributeHandler.extend({ // @param rawValue {String} getCurrentValue: function (element) { return element.className; @@ -115,7 +116,7 @@ var ClassHandler = Blaze._DiffingAttributeHandler.extend({ element.className = className; }, parseValue: function (attrString) { - var tokens = new OrderedDict(); + const tokens = new OrderedDict(); attrString.split(' ').forEach(function (token) { if (token) { @@ -132,7 +133,7 @@ var ClassHandler = Blaze._DiffingAttributeHandler.extend({ } }); -var SVGClassHandler = ClassHandler.extend({ +const SVGClassHandler = ClassHandler.extend({ getCurrentValue: function (element) { return element.className.baseVal; }, @@ -141,7 +142,7 @@ var SVGClassHandler = ClassHandler.extend({ } }); -var StyleHandler = Blaze._DiffingAttributeHandler.extend({ +const StyleHandler = Blaze._DiffingAttributeHandler.extend({ getCurrentValue: function (element) { return element.getAttribute('style'); }, @@ -158,12 +159,12 @@ var StyleHandler = Blaze._DiffingAttributeHandler.extend({ // Example: // "color:red; foo:12px" produces a token {color: "color:red", foo:"foo:12px"} parseValue: function (attrString) { - var tokens = new OrderedDict(); + const tokens = new OrderedDict(); // Regex for parsing a css attribute declaration, taken from css-parse: // https://github.com/reworkcss/css-parse/blob/7cef3658d0bba872cde05a85339034b187cb3397/index.js#L219 - var regex = /(\*?[-#\/\*\\\w]+(?:\[[0-9a-z_-]+\])?)\s*:\s*(?:\'(?:\\\'|.)*?\'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+[;\s]*/g; - var match = regex.exec(attrString); + const regex = /(\*?[-#\/\*\\\w]+(?:\[[0-9a-z_-]+\])?)\s*:\s*(?:\'(?:\\\'|.)*?\'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+[;\s]*/g; + let match = regex.exec(attrString); while (match) { // match[0] = entire matching string // match[1] = css property @@ -188,9 +189,9 @@ var StyleHandler = Blaze._DiffingAttributeHandler.extend({ } }); -var BooleanHandler = AttributeHandler.extend({ +const BooleanHandler = AttributeHandler.extend({ update: function (element, oldValue, value) { - var name = this.name; + const name = this.name; if (value == null) { if (oldValue != null) element[name] = false; @@ -200,9 +201,9 @@ var BooleanHandler = AttributeHandler.extend({ } }); -var DOMPropertyHandler = AttributeHandler.extend({ +const DOMPropertyHandler = AttributeHandler.extend({ update: function (element, oldValue, value) { - var name = this.name; + const name = this.name; if (value !== element[name]) element[name] = value; } @@ -210,9 +211,9 @@ var DOMPropertyHandler = AttributeHandler.extend({ // attributes of the type 'xlink:something' should be set using // the correct namespace in order to work -var XlinkHandler = AttributeHandler.extend({ +const XlinkHandler = AttributeHandler.extend({ update: function(element, oldValue, value) { - var NS = 'http://www.w3.org/1999/xlink'; + const NS = 'http://www.w3.org/1999/xlink'; if (value === null) { if (oldValue !== null) element.removeAttributeNS(NS, this.name); @@ -223,15 +224,15 @@ var XlinkHandler = AttributeHandler.extend({ }); // cross-browser version of `instanceof SVGElement` -var isSVGElement = function (elem) { +const isSVGElement = function (elem) { return 'ownerSVGElement' in elem; }; -var isUrlAttribute = function (tagName, attrName) { +const isUrlAttribute = function (tagName, attrName) { // Compiled from http://www.w3.org/TR/REC-html40/index/attributes.html // and // http://www.w3.org/html/wg/drafts/html/master/index.html#attributes-1 - var urlAttrs = { + const urlAttrs = { FORM: ['action'], BODY: ['background'], BLOCKQUOTE: ['cite'], @@ -260,18 +261,19 @@ var isUrlAttribute = function (tagName, attrName) { return true; } - var urlAttrNames = urlAttrs[tagName] || []; + const urlAttrNames = urlAttrs[tagName] || []; return urlAttrNames.includes(attrName); }; // To get the protocol for a URL, we let the browser normalize it for // us, by setting it as the href for an anchor tag and then reading out // the 'protocol' property. +let anchorForNormalization if (Meteor.isClient) { - var anchorForNormalization = document.createElement('A'); + anchorForNormalization = document.createElement('A'); } -var getUrlProtocol = function (url) { +const getUrlProtocol = function (url) { if (Meteor.isClient) { anchorForNormalization.href = url; return (anchorForNormalization.protocol || "").toLowerCase(); @@ -285,17 +287,17 @@ var getUrlProtocol = function (url) { // Blaze._allowJavascriptUrls() has been called. To detect javascript: // urls, we set the attribute on a dummy anchor element and then read // out the 'protocol' property of the attribute. -var origUpdate = AttributeHandler.prototype.update; -var UrlHandler = AttributeHandler.extend({ +const origUpdate = AttributeHandler.prototype.update; +const UrlHandler = AttributeHandler.extend({ update: function (element, oldValue, value) { - var self = this; - var args = arguments; + const self = this; + const args = arguments; if (Blaze._javascriptUrlsAllowed()) { origUpdate.apply(self, args); } else { - var isJavascriptProtocol = (getUrlProtocol(value) === "javascript:"); - var isVBScriptProtocol = (getUrlProtocol(value) === "vbscript:"); + const isJavascriptProtocol = (getUrlProtocol(value) === "javascript:"); + const isVBScriptProtocol = (getUrlProtocol(value) === "vbscript:"); if (isJavascriptProtocol || isVBScriptProtocol) { Blaze._warn("URLs that use the 'javascript:' or 'vbscript:' protocol are not " + "allowed in URL attribute values. " + @@ -337,9 +339,6 @@ Blaze._makeAttributeHandler = function (elem, name, value) { } else { return new AttributeHandler(name, value); } - - // XXX will need one for 'style' on IE, though modern browsers - // seem to handle setAttribute ok. }; ElementAttributesUpdater = function (elem) { @@ -350,28 +349,28 @@ ElementAttributesUpdater = function (elem) { // Update attributes on `elem` to the dictionary `attrs`, whose // values are strings. ElementAttributesUpdater.prototype.update = function(newAttrs) { - var elem = this.elem; - var handlers = this.handlers; + const elem = this.elem; + const handlers = this.handlers; - for (var k in handlers) { + Object.getOwnPropertyNames(handlers).forEach((k) => { if (!has(newAttrs, k)) { // remove attributes (and handlers) for attribute names // that don't exist as keys of `newAttrs` and so won't // be visited when traversing it. (Attributes that // exist in the `newAttrs` object but are `null` // are handled later.) - var handler = handlers[k]; - var oldValue = handler.value; + const handler = handlers[k]; + const oldValue = handler.value; handler.value = null; handler.update(elem, oldValue, null); delete handlers[k]; } - } + }) - for (var k in newAttrs) { - var handler = null; - var oldValue = null; - var value = newAttrs[k]; + Object.getOwnPropertyNames(newAttrs).forEach((k) => { + let handler = null; + let oldValue = null; + const value = newAttrs[k]; if (!has(handlers, k)) { if (value !== null) { // make new handler @@ -388,5 +387,5 @@ ElementAttributesUpdater.prototype.update = function(newAttrs) { if (value === null) delete handlers[k]; } - } + }) }; diff --git a/packages/blaze/builtins.js b/packages/blaze/builtins.js index 06d68fec7..1a53d2593 100644 --- a/packages/blaze/builtins.js +++ b/packages/blaze/builtins.js @@ -2,9 +2,8 @@ import has from 'lodash.has'; import isObject from 'lodash.isobject'; Blaze._calculateCondition = function (cond) { - if (HTML.isArray(cond) && cond.length === 0) - cond = false; - return !! cond; + if (HTML.isArray(cond) && cond.length === 0) return false; + return !!cond; }; /** @@ -15,9 +14,9 @@ Blaze._calculateCondition = function (cond) { * @param {Function} contentFunc A Function that returns [*renderable content*](#Renderable-Content). */ Blaze.With = function (data, contentFunc) { - var view = Blaze.View('with', contentFunc); + const view = Blaze.View('with', contentFunc); - view.dataVar = new ReactiveVar; + view.dataVar = new ReactiveVar(); view.onViewCreated(function () { if (typeof data === 'function') { @@ -194,8 +193,8 @@ Blaze.Unless = function (conditionFunc, contentFunc, elseFunc) { * in the sequence. */ Blaze.Each = function (argFunc, contentFunc, elseFunc) { - var eachView = Blaze.View('each', function () { - var subviews = this.initialSubviews; + const eachView = Blaze.View('each', function () { + const subviews = this.initialSubviews; this.initialSubviews = null; if (this._isCreatedForExpansion) { this.expandedValueDep = new Tracker.Dependency; @@ -213,13 +212,13 @@ Blaze.Each = function (argFunc, contentFunc, elseFunc) { eachView.variableName = null; // update the @index value in the scope of all subviews in the range - var updateIndices = function (from, to) { + const updateIndices = function (from, to) { if (to === undefined) { to = eachView.numItems - 1; } - for (var i = from; i <= to; i++) { - var view = eachView._domrange.members[i].view; + for (let i = from; i <= to; i++) { + const view = eachView._domrange.members[i].view; view._scopeBindings['@index'].set({ value: i }); } }; @@ -246,7 +245,7 @@ Blaze.Each = function (argFunc, contentFunc, elseFunc) { }, { addedAt: function (id, item, index) { Tracker.nonreactive(function () { - var newItemView; + let newItemView; if (eachView.variableName) { // new-style #each (as in {{#each item in items}}) // doesn't create a new data context @@ -257,7 +256,7 @@ Blaze.Each = function (argFunc, contentFunc, elseFunc) { eachView.numItems++; - var bindings = {}; + const bindings = {}; bindings['@index'] = index; if (eachView.variableName) { bindings[eachView.variableName] = item; @@ -272,7 +271,7 @@ Blaze.Each = function (argFunc, contentFunc, elseFunc) { eachView.inElseMode = false; } - var range = Blaze._materializeView(newItemView, eachView); + const range = Blaze._materializeView(newItemView, eachView); eachView._domrange.addMember(range, index); updateIndices(index); } else { @@ -305,7 +304,7 @@ Blaze.Each = function (argFunc, contentFunc, elseFunc) { if (eachView.expandedValueDep) { eachView.expandedValueDep.changed(); } else { - var itemView; + let itemView; if (eachView._domrange) { itemView = eachView._domrange.getMember(index).view; } else { @@ -328,8 +327,8 @@ Blaze.Each = function (argFunc, contentFunc, elseFunc) { updateIndices( Math.min(fromIndex, toIndex), Math.max(fromIndex, toIndex)); } else { - var subviews = eachView.initialSubviews; - var itemView = subviews[fromIndex]; + const subviews = eachView.initialSubviews; + const itemView = subviews[fromIndex]; subviews.splice(fromIndex, 1); subviews.splice(toIndex, 0, itemView); } @@ -366,9 +365,9 @@ Blaze._AwaitContent = function () { }; Blaze._TemplateWith = function (arg, contentFunc) { - var w; + let w; - var argFunc = arg; + let argFunc = arg; if (typeof arg !== 'function') { argFunc = function () { return arg; @@ -386,8 +385,8 @@ Blaze._TemplateWith = function (arg, contentFunc) { // // To make this better, reconsider _InOuterTemplateScope as a primitive. // Longer term, evaluate expressions in the proper lexical scope. - var wrappedArgFunc = function () { - var viewToEvaluateArg = null; + const wrappedArgFunc = function () { + let viewToEvaluateArg = null; if (w.parentView && w.parentView.name === 'InOuterTemplateScope') { viewToEvaluateArg = w.parentView.originalParentView; } @@ -398,8 +397,8 @@ Blaze._TemplateWith = function (arg, contentFunc) { } }; - var wrappedContentFunc = function () { - var content = contentFunc.call(this); + const wrappedContentFunc = function () { + let content = contentFunc.call(this); // Since we are generating the Blaze._TemplateWith view for the // user, set the flag on the child view. If `content` is a template, @@ -420,8 +419,8 @@ Blaze._TemplateWith = function (arg, contentFunc) { }; Blaze._InOuterTemplateScope = function (templateView, contentFunc) { - var view = Blaze.View('InOuterTemplateScope', contentFunc); - var parentView = templateView.parentView; + const view = Blaze.View('InOuterTemplateScope', contentFunc); + let parentView = templateView.parentView; // Hack so that if you call `{{> foo bar}}` and it expands into // `{{#with bar}}{{> foo}}{{/with}}`, and then `foo` is a template diff --git a/packages/blaze/dombackend.js b/packages/blaze/dombackend.js index 361e37ae5..9c5c45e84 100644 --- a/packages/blaze/dombackend.js +++ b/packages/blaze/dombackend.js @@ -1,7 +1,7 @@ -var DOMBackend = {}; +const DOMBackend = {}; Blaze._DOMBackend = DOMBackend; -var $jq = (typeof jQuery !== 'undefined' ? jQuery : +const $jq = (typeof jQuery !== 'undefined' ? jQuery : (typeof Package !== 'undefined' ? Package.jquery && Package.jquery.jQuery : null)); if (! $jq) @@ -31,9 +31,9 @@ DOMBackend.Events = { }, bindEventCapturer: function (elem, type, selector, handler) { - var $elem = $jq(elem); + const $elem = $jq(elem); - var wrapper = function (event) { + const wrapper = function (event) { event = $jq.event.fix(event); event.currentTarget = event.target; @@ -43,7 +43,7 @@ DOMBackend.Events = { // since jQuery can't bind capturing handlers, it's not clear // where we would hook in. Internal jQuery functions like `dispatch` // are too high-level. - var $target = $jq(event.currentTarget); + const $target = $jq(event.currentTarget); if ($target.is($elem.find(selector))) handler.call(elem, event); }; @@ -62,7 +62,7 @@ DOMBackend.Events = { parseEventType: function (type) { // strip off namespaces - var dotLoc = type.indexOf('.'); + const dotLoc = type.indexOf('.'); if (dotLoc >= 0) return type.slice(0, dotLoc); return type; @@ -80,10 +80,10 @@ DOMBackend.Events = { // which we can detect using a custom event with a teardown // hook. -var NOOP = function () {}; +const NOOP = function () {}; // Circular doubly-linked list -var TeardownCallback = function (func) { +const TeardownCallback = function (func) { this.next = this; this.prev = this; this.func = func; @@ -103,7 +103,7 @@ TeardownCallback.prototype.unlink = function () { }; TeardownCallback.prototype.go = function () { - var func = this.func; + const func = this.func; func && func(); }; @@ -117,9 +117,9 @@ DOMBackend.Teardown = { // The callback function is called at most once, and it receives the element // in question as an argument. onElementTeardown: function (elem, func) { - var elt = new TeardownCallback(func); + const elt = new TeardownCallback(func); - var propName = DOMBackend.Teardown._CB_PROP; + const propName = DOMBackend.Teardown._CB_PROP; if (! elem[propName]) { // create an empty node that is never unlinked elem[propName] = new TeardownCallback; @@ -135,11 +135,11 @@ DOMBackend.Teardown = { // Recursively call all teardown hooks, in the backend and registered // through DOMBackend.onElementTeardown. tearDownElement: function (elem) { - var elems = []; + const elems = []; // Array.prototype.slice.call doesn't work when given a NodeList in // IE8 ("JScript object expected"). - var nodeList = elem.getElementsByTagName('*'); - for (var i = 0; i < nodeList.length; i++) { + const nodeList = elem.getElementsByTagName('*'); + for (let i = 0; i < nodeList.length; i++) { elems.push(nodeList[i]); } elems.push(elem); @@ -155,10 +155,10 @@ $jq.event.special[DOMBackend.Teardown._JQUERY_EVENT_NAME] = { // feature enabled. }, teardown: function() { - var elem = this; - var callbacks = elem[DOMBackend.Teardown._CB_PROP]; + const elem = this; + const callbacks = elem[DOMBackend.Teardown._CB_PROP]; if (callbacks) { - var elt = callbacks.next; + let elt = callbacks.next; while (elt !== callbacks) { elt.go(); elt = elt.next; diff --git a/packages/blaze/domrange.js b/packages/blaze/domrange.js index f9baa465f..1efb1b118 100644 --- a/packages/blaze/domrange.js +++ b/packages/blaze/domrange.js @@ -1,6 +1,6 @@ // A constant empty array (frozen if the JS engine supports it). -var _emptyArray = Object.freeze ? Object.freeze([]) : []; +const _emptyArray = Object.freeze ? Object.freeze([]) : []; // `[new] Blaze._DOMRange([nodeAndRangeArray])` // @@ -13,11 +13,11 @@ Blaze._DOMRange = function (nodeAndRangeArray) { // called without `new` return new DOMRange(nodeAndRangeArray); - var members = (nodeAndRangeArray || _emptyArray); + const members = (nodeAndRangeArray || _emptyArray); if (! (members && (typeof members.length) === 'number')) throw new Error("Expected array"); - for (var i = 0; i < members.length; i++) + for (let i = 0; i < members.length; i++) this._memberIn(members[i]); this.members = members; @@ -27,7 +27,7 @@ Blaze._DOMRange = function (nodeAndRangeArray) { this.parentRange = null; this.attachedCallbacks = _emptyArray; }; -var DOMRange = Blaze._DOMRange; +const DOMRange = Blaze._DOMRange; // In IE 8, don't use empty text nodes as placeholders // in empty DOMRanges, use comment nodes instead. Using @@ -40,8 +40,8 @@ var DOMRange = Blaze._DOMRange; // even though we don't need to set properties on the // placeholder anymore. DOMRange._USE_COMMENT_PLACEHOLDERS = (function () { - var result = false; - var textNode = document.createTextNode(""); + let result = false; + const textNode = document.createTextNode(""); try { textNode.someProp = true; } catch (e) { @@ -53,7 +53,7 @@ DOMRange._USE_COMMENT_PLACEHOLDERS = (function () { // static methods DOMRange._insert = function (rangeOrNode, parentElement, nextNode, _isMove) { - var m = rangeOrNode; + const m = rangeOrNode; if (m instanceof DOMRange) { m.attach(parentElement, nextNode, _isMove); } else { @@ -65,7 +65,7 @@ DOMRange._insert = function (rangeOrNode, parentElement, nextNode, _isMove) { }; DOMRange._remove = function (rangeOrNode) { - var m = rangeOrNode; + const m = rangeOrNode; if (m instanceof DOMRange) { m.detach(); } else { @@ -111,7 +111,7 @@ DOMRange._moveNodeWithHooks = function (n, parent, next) { DOMRange.forElement = function (elem) { if (elem.nodeType !== 1) throw new Error("Expected element, found: " + elem); - var range = null; + let range = null; while (elem && ! range) { range = (elem.$blaze_range || null); if (! range) @@ -133,14 +133,14 @@ DOMRange.prototype.attach = function (parentElement, nextNode, _isMove, _isRepla throw new Error("Can only move or replace an attached DOMRange, and only under the same parent element"); } - var members = this.members; + const members = this.members; if (members.length) { this.emptyRangePlaceholder = null; - for (var i = 0; i < members.length; i++) { + for (let i = 0; i < members.length; i++) { DOMRange._insert(members[i], parentElement, nextNode, _isMove); } } else { - var placeholder = ( + const placeholder = ( DOMRange._USE_COMMENT_PLACEHOLDERS ? document.createComment("") : document.createTextNode("")); @@ -151,23 +151,23 @@ DOMRange.prototype.attach = function (parentElement, nextNode, _isMove, _isRepla this.parentElement = parentElement; if (! (_isMove || _isReplace)) { - for(var i = 0; i < this.attachedCallbacks.length; i++) { - var obj = this.attachedCallbacks[i]; + for(let i = 0; i < this.attachedCallbacks.length; i++) { + const obj = this.attachedCallbacks[i]; obj.attached && obj.attached(this, parentElement); } } }; DOMRange.prototype.setMembers = function (newNodeAndRangeArray) { - var newMembers = newNodeAndRangeArray; + const newMembers = newNodeAndRangeArray; if (! (newMembers && (typeof newMembers.length) === 'number')) throw new Error("Expected array"); - var oldMembers = this.members; + const oldMembers = this.members; - for (var i = 0; i < oldMembers.length; i++) + for (let i = 0; i < oldMembers.length; i++) this._memberOut(oldMembers[i]); - for (var i = 0; i < newMembers.length; i++) + for (let i = 0; i < newMembers.length; i++) this._memberIn(newMembers[i]); if (! this.attached) { @@ -176,8 +176,8 @@ DOMRange.prototype.setMembers = function (newNodeAndRangeArray) { // don't do anything if we're going from empty to empty if (newMembers.length || oldMembers.length) { // detach the old members and insert the new members - var nextNode = this.lastNode().nextSibling; - var parentElement = this.parentElement; + const nextNode = this.lastNode().nextSibling; + const parentElement = this.parentElement; // Use detach/attach, but don't fire attached/detached hooks this.detach(true /*_isReplace*/); this.members = newMembers; @@ -193,7 +193,7 @@ DOMRange.prototype.firstNode = function () { if (! this.members.length) return this.emptyRangePlaceholder; - var m = this.members[0]; + const m = this.members[0]; return (m instanceof DOMRange) ? m.firstNode() : m; }; @@ -204,7 +204,7 @@ DOMRange.prototype.lastNode = function () { if (! this.members.length) return this.emptyRangePlaceholder; - var m = this.members[this.members.length - 1]; + const m = this.members[this.members.length - 1]; return (m instanceof DOMRange) ? m.lastNode() : m; }; @@ -212,14 +212,14 @@ DOMRange.prototype.detach = function (_isReplace) { if (! this.attached) throw new Error("Must be attached"); - var oldParentElement = this.parentElement; - var members = this.members; + const oldParentElement = this.parentElement; + const members = this.members; if (members.length) { - for (var i = 0; i < members.length; i++) { + for (let i = 0; i < members.length; i++) { DOMRange._remove(members[i]); } } else { - var placeholder = this.emptyRangePlaceholder; + const placeholder = this.emptyRangePlaceholder; this.parentElement.removeChild(placeholder); this.emptyRangePlaceholder = null; } @@ -228,15 +228,15 @@ DOMRange.prototype.detach = function (_isReplace) { this.attached = false; this.parentElement = null; - for(var i = 0; i < this.attachedCallbacks.length; i++) { - var obj = this.attachedCallbacks[i]; + for(let i = 0; i < this.attachedCallbacks.length; i++) { + const obj = this.attachedCallbacks[i]; obj.detached && obj.detached(this, oldParentElement); } } }; DOMRange.prototype.addMember = function (newMember, atIndex, _isMove) { - var members = this.members; + const members = this.members; if (! (atIndex >= 0 && atIndex <= members.length)) throw new Error("Bad index in range.addMember: " + atIndex); @@ -250,12 +250,12 @@ DOMRange.prototype.addMember = function (newMember, atIndex, _isMove) { // empty; use the empty-to-nonempty handling of setMembers this.setMembers([newMember]); } else { - var nextNode; + let nextNode; if (atIndex === members.length) { // insert at end nextNode = this.lastNode().nextSibling; } else { - var m = members[atIndex]; + const m = members[atIndex]; nextNode = (m instanceof DOMRange) ? m.firstNode() : m; } members.splice(atIndex, 0, newMember); @@ -264,14 +264,14 @@ DOMRange.prototype.addMember = function (newMember, atIndex, _isMove) { }; DOMRange.prototype.removeMember = function (atIndex, _isMove) { - var members = this.members; + const members = this.members; if (! (atIndex >= 0 && atIndex < members.length)) throw new Error("Bad index in range.removeMember: " + atIndex); if (_isMove) { members.splice(atIndex, 1); } else { - var oldMember = members[atIndex]; + const oldMember = members[atIndex]; this._memberOut(oldMember); if (members.length === 1) { @@ -286,13 +286,13 @@ DOMRange.prototype.removeMember = function (atIndex, _isMove) { }; DOMRange.prototype.moveMember = function (oldIndex, newIndex) { - var member = this.members[oldIndex]; + const member = this.members[oldIndex]; this.removeMember(oldIndex, true /*_isMove*/); this.addMember(member, newIndex, true /*_isMove*/); }; DOMRange.prototype.getMember = function (atIndex) { - var members = this.members; + const members = this.members; if (! (atIndex >= 0 && atIndex < members.length)) throw new Error("Bad index in range.getMember: " + atIndex); return this.members[atIndex]; @@ -323,8 +323,8 @@ DOMRange.prototype._memberOut = DOMRange._destroy; // Tear down, but don't remove, the members. Used when chunks // of DOM are being torn down or replaced. DOMRange.prototype.destroyMembers = function (_skipNodes) { - var members = this.members; - for (var i = 0; i < members.length; i++) + const members = this.members; + for (let i = 0; i < members.length; i++) this._memberOut(members[i], _skipNodes); }; @@ -357,7 +357,7 @@ DOMRange.prototype.containsElement = function (elem, selector, event) { while (elem.parentNode !== this.parentElement) elem = elem.parentNode; - var range = elem.$blaze_range; + let range = elem.$blaze_range; while (range && range !== this) range = range.parentRange; @@ -405,9 +405,9 @@ DOMRange.prototype.onAttachedDetached = function (callbacks) { }; DOMRange.prototype.$ = function (selector) { - var self = this; + const self = this; - var parentNode = this.parentElement; + const parentNode = this.parentElement; if (! parentNode) throw new Error("Can't select in removed DomRange"); @@ -424,7 +424,7 @@ DOMRange.prototype.$ = function (selector) { if (parentNode.nodeType === 11 /* DocumentFragment */) throw new Error("Can't use $ on an offscreen range"); - var results = Blaze._DOMBackend.findBySelector(selector, parentNode); + let results = Blaze._DOMBackend.findBySelector(selector, parentNode); // We don't assume `results` has jQuery API; a plain array // should do just as well. However, if we do have a jQuery @@ -434,7 +434,7 @@ DOMRange.prototype.$ = function (selector) { // Function that selects only elements that are actually // in this DomRange, rather than simply descending from // `parentNode`. - var filterFunc = function (elem) { + const filterFunc = function (elem) { // handle jQuery's arguments to filter, where the node // is in `this` and the index is the first argument. if (typeof elem === 'number') @@ -446,9 +446,9 @@ DOMRange.prototype.$ = function (selector) { if (! results.filter) { // not a jQuery array, and not a browser with // Array.prototype.filter (e.g. IE <9) - var newResults = []; - for (var i = 0; i < results.length; i++) { - var x = results[i]; + const newResults = []; + for (let i = 0; i < results.length; i++) { + const x = results[i]; if (filterFunc(x)) newResults.push(x); } diff --git a/packages/blaze/events.js b/packages/blaze/events.js index 4dfaa4dc0..e1051d4c4 100644 --- a/packages/blaze/events.js +++ b/packages/blaze/events.js @@ -1,8 +1,8 @@ import has from 'lodash.has'; -var EventSupport = Blaze._EventSupport = {}; +const EventSupport = Blaze._EventSupport = {}; -var DOMBackend = Blaze._DOMBackend; +const DOMBackend = Blaze._DOMBackend; // List of events to always delegate, never capture. // Since jQuery fakes bubbling for certain events in @@ -12,20 +12,26 @@ var DOMBackend = Blaze._DOMBackend; // We could list all known bubbling // events here to avoid creating speculative capturers // for them, but it would only be an optimization. -var eventsToDelegate = EventSupport.eventsToDelegate = { - blur: 1, change: 1, click: 1, focus: 1, focusin: 1, - focusout: 1, reset: 1, submit: 1 +const eventsToDelegate = EventSupport.eventsToDelegate = { + blur: 1, + change: 1, + click: 1, + focus: 1, + focusin: 1, + focusout: 1, + reset: 1, + submit: 1 }; -var EVENT_MODE = EventSupport.EVENT_MODE = { +const EVENT_MODE = EventSupport.EVENT_MODE = { TBD: 0, BUBBLING: 1, CAPTURING: 2 }; -var NEXT_HANDLERREC_ID = 1; +let NEXT_HANDLERREC_ID = 1; -var HandlerRec = function (elem, type, selector, handler, recipient) { +const HandlerRec = function (elem, type, selector, handler, recipient) { this.elem = elem; this.type = type; this.selector = selector; @@ -58,7 +64,7 @@ var HandlerRec = function (elem, type, selector, handler, recipient) { // events using capture in all browsers except IE 8. // IE 8 doesn't support these events anyway. - var tryCapturing = elem.addEventListener && + const tryCapturing = elem.addEventListener && (!has(eventsToDelegate, DOMBackend.Events.parseEventType(type))); @@ -129,26 +135,26 @@ EventSupport.listen = function (element, events, selector, handler, recipient, g // Repro: https://github.com/dgreensp/public/tree/master/safari-crash try { element = element; } finally {} - var eventTypes = []; + const eventTypes = []; events.replace(/[^ /]+/g, function (e) { eventTypes.push(e); }); - var newHandlerRecs = []; - for (var i = 0, N = eventTypes.length; i < N; i++) { - var type = eventTypes[i]; + const newHandlerRecs = []; + for (let i = 0, N = eventTypes.length; i < N; i++) { + const type = eventTypes[i]; - var eventDict = element.$blaze_events; + let eventDict = element.$blaze_events; if (! eventDict) eventDict = (element.$blaze_events = {}); - var info = eventDict[type]; + let info = eventDict[type]; if (! info) { info = eventDict[type] = {}; info.handlers = []; } - var handlerList = info.handlers; - var handlerRec = new HandlerRec( + const handlerList = info.handlers; + const handlerRec = new HandlerRec( element, type, selector, handler, recipient); newHandlerRecs.push(handlerRec); handlerRec.bind(); @@ -157,12 +163,12 @@ EventSupport.listen = function (element, events, selector, handler, recipient, g // them. In jQuery (or other DOMBackend) this causes them to fire // later when the backend dispatches event handlers. if (getParentRecipient) { - for (var r = getParentRecipient(recipient); r; + for (let r = getParentRecipient(recipient); r; r = getParentRecipient(r)) { // r is an enclosing range (recipient) - for (var j = 0, Nj = handlerList.length; + for (let j = 0, Nj = handlerList.length; j < Nj; j++) { - var h = handlerList[j]; + const h = handlerList[j]; if (h.recipient === r) { h.unbind(); h.bind(); @@ -179,7 +185,7 @@ EventSupport.listen = function (element, events, selector, handler, recipient, g return { // closes over just `element` and `newHandlerRecs` stop: function () { - var eventDict = element.$blaze_events; + const eventDict = element.$blaze_events; if (! eventDict) return; // newHandlerRecs has only one item unless you specify multiple @@ -187,13 +193,13 @@ EventSupport.listen = function (element, events, selector, handler, recipient, g // iterate over handlerList here. Clearing a whole handlerList // via stop() methods is O(N^2) in the number of handlers on // an element. - for (var i = 0; i < newHandlerRecs.length; i++) { - var handlerToRemove = newHandlerRecs[i]; - var info = eventDict[handlerToRemove.type]; + for (let i = 0; i < newHandlerRecs.length; i++) { + const handlerToRemove = newHandlerRecs[i]; + const info = eventDict[handlerToRemove.type]; if (! info) continue; - var handlerList = info.handlers; - for (var j = handlerList.length - 1; j >= 0; j--) { + const handlerList = info.handlers; + for (let j = handlerList.length - 1; j >= 0; j--) { if (handlerList[j] === handlerToRemove) { handlerToRemove.unbind(); handlerList.splice(j, 1); // remove handlerList[j] diff --git a/packages/blaze/exceptions.js b/packages/blaze/exceptions.js index 429ac82f7..2e62a8e67 100644 --- a/packages/blaze/exceptions.js +++ b/packages/blaze/exceptions.js @@ -1,4 +1,4 @@ -var debugFunc; +let debugFunc; // We call into user code in many places, and it's nice to catch exceptions // propagated from user code immediately so that the whole system doesn't just @@ -46,7 +46,7 @@ Blaze._wrapCatchingExceptions = function (f, where) { if (typeof f !== 'function') return f; - return function () { + return function (...arguments) { try { return f.apply(this, arguments); } catch (e) { diff --git a/packages/blaze/lookup.js b/packages/blaze/lookup.js index 9111cd120..5fc748230 100644 --- a/packages/blaze/lookup.js +++ b/packages/blaze/lookup.js @@ -44,7 +44,7 @@ Blaze.deregisterHelper = function(name) { delete Blaze._globalHelpers[name]; }; -var bindIfIsFunction = function (x, target) { +const bindIfIsFunction = function (x, target) { if (typeof x !== 'function') return x; return Blaze._bind(x, target); @@ -52,13 +52,13 @@ var bindIfIsFunction = function (x, target) { // If `x` is a function, binds the value of `this` for that function // to the current data context. -var bindDataContext = function (x) { +const bindDataContext = function (x) { if (typeof x === 'function') { - return function () { - var data = Blaze.getData(); + return function (...args) { + let data = Blaze.getData(); if (data == null) data = {}; - return x.apply(data, arguments); + return x.apply(data, args); }; } return x; @@ -68,10 +68,10 @@ Blaze._OLDSTYLE_HELPER = {}; Blaze._getTemplateHelper = function (template, name, tmplInstanceFunc) { // XXX COMPAT WITH 0.9.3 - var isKnownOldStyleHelper = false; + let isKnownOldStyleHelper = false; if (template.__helpers.has(name)) { - var helper = template.__helpers.get(name); + const helper = template.__helpers.get(name); if (helper === Blaze._OLDSTYLE_HELPER) { isKnownOldStyleHelper = true; } else if (helper != null) { @@ -100,14 +100,13 @@ Blaze._getTemplateHelper = function (template, name, tmplInstanceFunc) { return null; }; -var wrapHelper = function (f, templateFunc) { +const wrapHelper = function (f, templateFunc) { if (typeof f !== "function") { return f; } - return function () { - var self = this; - var args = arguments; + return function (...args) { + const self = this; return Blaze.Template._withTemplateInstanceFunc(templateFunc, function () { return Blaze._wrapCatchingExceptions(f, 'template helper').apply(self, args); @@ -125,7 +124,7 @@ function _lexicalKeepGoing(currentView) { if (currentView.parentView.__childDoesntStartNewLexicalScope) { return currentView.parentView; } - + // in the case of {{> Template.contentBlock data}} the contentBlock loses the lexical scope of it's parent, wheras {{> Template.contentBlock}} it does not // this is because a #with sits between the include InOuterTemplateScope if (currentView.parentView.name === "with" && currentView.parentView.parentView && currentView.parentView.parentView.__childDoesntStartNewLexicalScope) { @@ -135,7 +134,7 @@ function _lexicalKeepGoing(currentView) { } function _lexicalBindingLookup(view, name) { - var currentView = view; + let currentView = view; // walk up the views stopping at a Spacebars.include or Template view that // doesn't have an InOuterTemplateScope view as a parent @@ -186,12 +185,12 @@ Blaze._getGlobalHelper = function (name, templateInstance) { // dependencies itself. If there is any reactivity in the // value, lookup should return a function. Blaze.View.prototype.lookup = function (name, _options) { - var template = this.template; - var lookupTemplate = _options && _options.template; - var helper; - var binding; - var boundTmplInstance; - var foundTemplate; + const template = this.template; + const lookupTemplate = _options && _options.template; + let helper; + let binding; + let boundTmplInstance; + let foundTemplate; if (this.templateInstance) { boundTmplInstance = Blaze._bind(this.templateInstance, this); @@ -225,15 +224,16 @@ Blaze.View.prototype.lookup = function (name, _options) { } // 4. look up a global helper - if ((helper = Blaze._getGlobalHelper(name, boundTmplInstance)) != null) { + helper = Blaze._getGlobalHelper(name, boundTmplInstance); + if (helper != null) { return helper; } // 5. look up in a data context - return function () { - var isCalledAsFunction = (arguments.length > 0); - var data = Blaze.getData(); - var x = data && data[name]; + return function (...args) { + const isCalledAsFunction = (args?.length > 0); + const data = Blaze.getData(); + const x = data && data[name]; if (! x) { if (lookupTemplate) { throw new Error("No such template: " + name); @@ -259,7 +259,7 @@ Blaze.View.prototype.lookup = function (name, _options) { } return x; } - return x.apply(data, arguments); + return x.apply(data, args); }; }; @@ -270,8 +270,8 @@ Blaze._parentData = function (height, _functionWrapped) { if (height == null) { height = 1; } - var theWith = Blaze.getView('with'); - for (var i = 0; (i < height) && theWith; i++) { + let theWith = Blaze.getView('with'); + for (let i = 0; (i < height) && theWith; i++) { theWith = Blaze.getView(theWith, 'with'); } diff --git a/packages/blaze/materializer.js b/packages/blaze/materializer.js index 0a05ea85a..b1f2182b2 100644 --- a/packages/blaze/materializer.js +++ b/packages/blaze/materializer.js @@ -21,7 +21,7 @@ Blaze._materializeDOM = function (htmljs, intoArray, parentView, // and run, last first, after materializeDOMInner returns. The // reason we use a stack instead of a queue is so that we recurse // depth-first, doing newer tasks first. - var workStack = (_existingWorkStack || []); + const workStack = (_existingWorkStack || []); materializeDOMInner(htmljs, intoArray, parentView, workStack); if (! _existingWorkStack) { @@ -30,7 +30,7 @@ Blaze._materializeDOM = function (htmljs, intoArray, parentView, // of the stack. while (workStack.length) { // Note that running task() may push new items onto workStack. - var task = workStack.pop(); + const task = workStack.pop(); task(); } } @@ -38,7 +38,7 @@ Blaze._materializeDOM = function (htmljs, intoArray, parentView, return intoArray; }; -var materializeDOMInner = function (htmljs, intoArray, parentView, workStack) { +const materializeDOMInner = function (htmljs, intoArray, parentView, workStack) { if (htmljs == null) { // null or undefined return; @@ -63,13 +63,13 @@ var materializeDOMInner = function (htmljs, intoArray, parentView, workStack) { case HTML.Raw.htmljsType: // Get an array of DOM nodes by using the browser's HTML parser // (like innerHTML). - var nodes = Blaze._DOMBackend.parseHTML(htmljs.value); - for (var i = 0; i < nodes.length; i++) + const nodes = Blaze._DOMBackend.parseHTML(htmljs.value); + for (let i = 0; i < nodes.length; i++) intoArray.push(nodes[i]); return; } } else if (HTML.isArray(htmljs)) { - for (var i = htmljs.length-1; i >= 0; i--) { + for (let i = htmljs.length-1; i >= 0; i--) { workStack.push(Blaze._bind(Blaze._materializeDOM, null, htmljs[i], intoArray, parentView, workStack)); } @@ -120,9 +120,9 @@ function waitForAllAttributesAndContinue(attrs, fn) { } } -var materializeTag = function (tag, parentView, workStack) { - var tagName = tag.tagName; - var elem; +const materializeTag = function (tag, parentView, workStack) { + const tagName = tag.tagName; + let elem; if ((HTML.isKnownSVGElement(tagName) || isSVGAnchor(tag)) && document.createElementNS) { // inline SVG @@ -132,8 +132,8 @@ var materializeTag = function (tag, parentView, workStack) { elem = document.createElement(tagName); } - var rawAttrs = tag.attrs; - var children = tag.children; + let rawAttrs = tag.attrs; + let children = tag.children; if (tagName === 'textarea' && tag.children.length && ! (rawAttrs && ('value' in rawAttrs))) { // Provide very limited support for TEXTAREA tags with children @@ -153,13 +153,13 @@ var materializeTag = function (tag, parentView, workStack) { } if (rawAttrs) { - var attrUpdater = new ElementAttributesUpdater(elem); - var updateAttributes = function () { - var expandedAttrs = Blaze._expandAttributes(rawAttrs, parentView); + const attrUpdater = new ElementAttributesUpdater(elem); + const updateAttributes = function () { + const expandedAttrs = Blaze._expandAttributes(rawAttrs, parentView); waitForAllAttributesAndContinue(expandedAttrs, () => { - var flattenedAttrs = HTML.flattenAttributes(expandedAttrs); - var stringAttrs = {}; - for (var attrName in flattenedAttrs) { + const flattenedAttrs = HTML.flattenAttributes(expandedAttrs); + const stringAttrs = {}; + Object.keys(flattenedAttrs).forEach((attrName) => { // map `null`, `undefined`, and `false` to null, which is important // so that attributes with nully values are considered absent. // stringify anything else (e.g. strings, booleans, numbers including 0). @@ -169,11 +169,11 @@ var materializeTag = function (tag, parentView, workStack) { stringAttrs[attrName] = Blaze._toText(flattenedAttrs[attrName], parentView, HTML.TEXTMODE.STRING); - } + }); attrUpdater.update(stringAttrs); }); }; - var updaterComputation; + let updaterComputation; if (parentView) { updaterComputation = parentView.autorun(updateAttributes, undefined, 'updater'); @@ -190,11 +190,11 @@ var materializeTag = function (tag, parentView, workStack) { } if (children.length) { - var childNodesAndRanges = []; + const childNodesAndRanges = []; // push this function first so that it's done last workStack.push(function () { - for (var i = 0; i < childNodesAndRanges.length; i++) { - var x = childNodesAndRanges[i]; + for (let i = 0; i < childNodesAndRanges.length; i++) { + const x = childNodesAndRanges[i]; if (x instanceof Blaze._DOMRange) x.attach(elem); else @@ -211,7 +211,7 @@ var materializeTag = function (tag, parentView, workStack) { }; -var isSVGAnchor = function (node) { +const isSVGAnchor = function (node) { // We generally aren't able to detect SVG elements because // if "A" were in our list of known svg element names, then all // nodes would be created using diff --git a/packages/blaze/package.js b/packages/blaze/package.js index 922a88128..1b968bb57 100644 --- a/packages/blaze/package.js +++ b/packages/blaze/package.js @@ -14,12 +14,12 @@ Npm.depends({ Package.onUse(function (api) { api.use('jquery@1.11.9 || 3.0.0', { weak: true }); // should be a weak dep, by having multiple "DOM backends" - api.use('tracker@1.3.0'); - api.use('check@1.3.1'); - api.use('observe-sequence@1.0.16'); - api.use('reactive-var@1.0.11'); + api.use('tracker@1.3.2'); + api.use('check@1.3.2'); + api.use('observe-sequence@1.0.21'); + api.use('reactive-var@1.0.12'); api.use('ordered-dict@1.1.0'); - api.use('ecmascript@0.15.1'); + api.use('ecmascript@0.16.7'); api.export([ 'Blaze', @@ -57,12 +57,12 @@ Package.onUse(function (api) { }); Package.onTest(function (api) { - api.use('ecmascript@0.15.1'); + api.use('ecmascript@0.16.7'); api.use('tinytest@1.1.0'); - api.use('test-helpers@1.2.0'); + api.use('test-helpers@1.3.1'); api.use('jquery@1.11.9 || 3.0.0'); // strong dependency, for testing jQuery backend - api.use('reactive-var@1.0.11'); - api.use('tracker@1.3.0'); + api.use('reactive-var@1.0.12'); + api.use('tracker@1.3.2'); api.use('blaze'); api.use('blaze-tools@1.1.3'); // for BlazeTools.toJS diff --git a/packages/blaze/preamble.js b/packages/blaze/preamble.js index 8d1291b8e..33b2a6083 100644 --- a/packages/blaze/preamble.js +++ b/packages/blaze/preamble.js @@ -8,7 +8,7 @@ Blaze = {}; // TODO: Should be replaced with _.escape once underscore is upgraded to a newer // version which escapes ` (backtick) as well. Underscore 1.5.2 does not. Blaze._escape = (function() { - var escape_map = { + const escape_map = { "<": "<", ">": ">", '"': """, @@ -17,7 +17,7 @@ Blaze._escape = (function() { "`": "`", /* IE allows backtick-delimited attributes?? */ "&": "&" }; - var escape_one = function(c) { + const escape_one = function(c) { return escape_map[c]; }; @@ -34,23 +34,19 @@ Blaze._warn = function (msg) { } }; -var nativeBind = Function.prototype.bind; +const nativeBind = Function.prototype.bind; // An implementation of _.bind which allows better optimization. // See: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments if (nativeBind) { - Blaze._bind = function (func, obj) { + Blaze._bind = function (func, obj, ...rest) { if (arguments.length === 2) { return nativeBind.call(func, obj); } - // Copy the arguments so this function can be optimized. - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } + const args = [obj, ...rest]; - return nativeBind.apply(func, args.slice(1)); + return nativeBind.apply(func, args); }; } else { diff --git a/packages/blaze/render_tests.js b/packages/blaze/render_tests.js index 3b916d783..67df25b72 100644 --- a/packages/blaze/render_tests.js +++ b/packages/blaze/render_tests.js @@ -1,22 +1,22 @@ import { BlazeTools } from 'meteor/blaze-tools'; -var toCode = BlazeTools.toJS; - -var P = HTML.P; -var CharRef = HTML.CharRef; -var DIV = HTML.DIV; -var Comment = HTML.Comment; -var BR = HTML.BR; -var A = HTML.A; -var UL = HTML.UL; -var LI = HTML.LI; -var SPAN = HTML.SPAN; -var HR = HTML.HR; -var TEXTAREA = HTML.TEXTAREA; -var INPUT = HTML.INPUT; - -var materialize = function (content, parent) { - var func = content; +const toCode = BlazeTools.toJS; + +const P = HTML.P; +const CharRef = HTML.CharRef; +const DIV = HTML.DIV; +const Comment = HTML.Comment; +const BR = HTML.BR; +const A = HTML.A; +const UL = HTML.UL; +const LI = HTML.LI; +const SPAN = HTML.SPAN; +const HR = HTML.HR; +const TEXTAREA = HTML.TEXTAREA; +const INPUT = HTML.INPUT; + +const materialize = function (content, parent) { + let func = content; if (typeof content !== 'function') { func = function () { return content; @@ -25,11 +25,11 @@ var materialize = function (content, parent) { Blaze.render(func, parent); }; -var toHTML = Blaze.toHTML; +const toHTML = Blaze.toHTML; Tinytest.add("blaze - render - basic", function (test) { - var run = function (input, expectedInnerHTML, expectedHTML, expectedCode) { - var div = document.createElement("DIV"); + const run = function (input, expectedInnerHTML, expectedHTML, expectedCode) { + const div = document.createElement("DIV"); materialize(input, div); test.equal(canonicalizeHtml(div.innerHTML), expectedInnerHTML); test.equal(toHTML(input), expectedHTML); @@ -105,10 +105,10 @@ Tinytest.add("blaze - render - basic", function (test) { // rather than the 'value' attribute. the 'value' attribute only sets // the initial value. Tinytest.add("blaze - render - input - value", function (test) { - var R = ReactiveVar("hello"); - var div = document.createElement("DIV"); + const R = ReactiveVar("hello"); + const div = document.createElement("DIV"); materialize(INPUT({value: function () { return R.get(); }}), div); - var inputEl = div.querySelector('input'); + const inputEl = div.querySelector('input'); test.equal(inputEl.value, "hello"); inputEl.value = "goodbye"; R.set("hola"); @@ -120,10 +120,10 @@ Tinytest.add("blaze - render - input - value", function (test) { // the 'checked' attribute on input fields of type 'checkbox'. the // 'checked' attribute only sets the initial value. Tinytest.add("blaze - render - input - checked", function (test) { - var R = ReactiveVar(null); - var div = document.createElement("DIV"); + const R = ReactiveVar(null); + const div = document.createElement("DIV"); materialize(INPUT({type: "checkbox", checked: function () { return R.get(); }}), div); - var inputEl = div.querySelector('input'); + const inputEl = div.querySelector('input'); test.equal(inputEl.checked, false); inputEl.checked = true; @@ -135,7 +135,7 @@ Tinytest.add("blaze - render - input - checked", function (test) { }); Tinytest.add("blaze - render - textarea", function (test) { - var run = function (optNode, text, html, code) { + const run = function (optNode, text, html, code) { if (typeof optNode === 'string') { // called with args (text, html, code) code = html; @@ -143,11 +143,11 @@ Tinytest.add("blaze - render - textarea", function (test) { text = optNode; optNode = null; } - var div = document.createElement("DIV"); - var node = TEXTAREA({value: optNode || text}); + const div = document.createElement("DIV"); + const node = TEXTAREA({value: optNode || text}); materialize(node, div); - var value = div.querySelector('textarea').value; + let value = div.querySelector('textarea').value; value = value.replace(/\r\n/g, "\n"); // IE8 substitutes \n with \r\n test.equal(value, text); @@ -181,15 +181,15 @@ Tinytest.add("blaze - render - textarea", function (test) { // test that reactivity of textarea "value" attribute works... (function () { - var R = ReactiveVar('one'); - var div = document.createElement("DIV"); - var node = TEXTAREA({value: function () { + const R = ReactiveVar('one'); + const div = document.createElement("DIV"); + const node = TEXTAREA({value: function () { return Blaze.View(function () { return R.get(); }); }}); materialize(node, div); - var textarea = div.querySelector('textarea'); + const textarea = div.querySelector('textarea'); test.equal(textarea.value, 'one'); R.set('two'); Tracker.flush(); @@ -199,13 +199,13 @@ Tinytest.add("blaze - render - textarea", function (test) { // ... while "content" reactivity simply doesn't update // (but doesn't throw either) (function () { - var R = ReactiveVar('one'); - var div = document.createElement("DIV"); - var node = TEXTAREA([Blaze.View(function () { + const R = ReactiveVar('one'); + const div = document.createElement("DIV"); + const node = TEXTAREA([Blaze.View(function () { return R.get(); })]); materialize(node, div); - var textarea = div.querySelector('textarea'); + const textarea = div.querySelector('textarea'); test.equal(textarea.value, 'one'); R.set('two'); Tracker.flush({_throwFirstError: true}); @@ -217,14 +217,14 @@ Tinytest.add("blaze - render - view isolation", function (test) { // Reactively change a text node (function () { - var R = ReactiveVar('Hello'); - var test1 = function () { + const R = ReactiveVar('Hello'); + const test1 = function () { return P(Blaze.View(function () { return R.get(); })); }; test.equal(toHTML(test1()), '

Hello

'); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); materialize(test1, div); test.equal(canonicalizeHtml(div.innerHTML), "

Hello

"); @@ -235,14 +235,14 @@ Tinytest.add("blaze - render - view isolation", function (test) { // Reactively change an array of text nodes (function () { - var R = ReactiveVar(['Hello', ' World']); - var test1 = function () { + const R = ReactiveVar(['Hello', ' World']); + const test1 = function () { return P(Blaze.View(function () { return R.get(); })); }; test.equal(toHTML(test1()), '

Hello World

'); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); materialize(test1, div); test.equal(canonicalizeHtml(div.innerHTML), "

Hello World

"); @@ -256,8 +256,8 @@ Tinytest.add("blaze - render - view isolation", function (test) { // 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"); +const malformedStylesAllowed = function () { + const div = document.createElement("div"); div.setAttribute("style", "bar::d;"); return (div.getAttribute("style") === "bar::d;"); }; @@ -265,10 +265,10 @@ var malformedStylesAllowed = function () { 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(); })); + const R = ReactiveVar('Hello'); + const test1 = P(Blaze.View(function () { return R.get(); })); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); materialize(test1, div); test.equal(canonicalizeHtml(div.innerHTML), "

Hello

"); @@ -292,10 +292,10 @@ Tinytest.add("blaze - render - view GC", function (test) { Tinytest.add("blaze - render - reactive attributes", function (test) { (function () { - var R = ReactiveVar({'class': ['david gre', CharRef({html: 'ë', str: '\u00eb'}), 'nspan'], + const R = ReactiveVar({'class': ['david gre', CharRef({html: 'ë', str: '\u00eb'}), 'nspan'], id: 'foo'}); - var spanFunc = function () { + const spanFunc = function () { return SPAN(HTML.Attrs( function () { return R.get(); })); }; @@ -305,13 +305,13 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { test.equal(R._numListeners(), 0); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); Blaze.render(spanFunc, div); test.equal(canonicalizeHtml(div.innerHTML), ''); test.equal(R._numListeners(), 1); - var span = div.firstChild; + const 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 @@ -331,11 +331,11 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { })(); (function () { - var style = ReactiveVar(false); + const style = ReactiveVar(false); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); - var divFunc = function () { + const divFunc = function () { return DIV({ style: function () { return [Blaze.If(function () { @@ -362,10 +362,10 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { // Test styles. (function () { // Test the case where there is a semicolon in the css attribute. - var R = ReactiveVar({'style': 'foo: "a;aa"; bar: b;', + const R = ReactiveVar({'style': 'foo: "a;aa"; bar: b;', id: 'foo'}); - var spanFunc = function () { + const spanFunc = function () { return SPAN(HTML.Attrs(function () { return R.get(); })); }; @@ -373,12 +373,12 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { test.equal(R._numListeners(), 0); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); Blaze.render(spanFunc, div); test.equal(canonicalizeHtml(div.innerHTML), ''); test.equal(R._numListeners(), 1); - var span = div.firstChild; + const span = div.firstChild; test.equal(span.nodeName, 'SPAN'); span.setAttribute('style', span.getAttribute('style') + '; jquery-style: hidden'); @@ -401,18 +401,18 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { // Test that identical styles are successfully overwritten. (function () { - var R = ReactiveVar({'style': 'foo: a;'}); + const R = ReactiveVar({'style': 'foo: a;'}); - var spanFunc = function () { + const spanFunc = function () { return SPAN(HTML.Attrs(function () { return R.get(); })); }; - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); document.body.appendChild(div); Blaze.render(spanFunc, div); test.equal(canonicalizeHtml(div.innerHTML), ''); - var span = div.firstChild; + const span = div.firstChild; test.equal(span.nodeName, 'SPAN'); span.setAttribute("style", 'foo: b;'); test.equal(canonicalizeHtml(div.innerHTML), ''); @@ -446,7 +446,7 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { // Test `null`, `undefined`, and `[]` attributes (function () { - var R = ReactiveVar({id: 'foo', + const R = ReactiveVar({id: 'foo', aaa: null, bbb: undefined, ccc: [], @@ -455,7 +455,7 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { fff: [[]], ggg: ['x', ['y', ['z']]]}); - var spanFunc = function () { + const spanFunc = function () { return SPAN(HTML.Attrs( function () { return R.get(); })); }; @@ -464,9 +464,9 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { test.equal(toCode(SPAN(R.get())), 'HTML.SPAN({id: "foo", ggg: ["x", ["y", ["z"]]]})'); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); Blaze.render(spanFunc, div); - var span = div.firstChild; + const span = div.firstChild; test.equal(span.nodeName, 'SPAN'); test.equal(canonicalizeHtml(div.innerHTML), ''); @@ -490,10 +490,10 @@ Tinytest.add("blaze - render - reactive attributes", function (test) { Tinytest.add("blaze - render - templates and views", function (test) { (function () { - var counter = 1; - var buf = []; + let counter = 1; + const buf = []; - var myTemplate = Blaze.Template( + const myTemplate = Blaze.Template( 'myTemplate', function () { return [String(this.number), @@ -501,15 +501,15 @@ Tinytest.add("blaze - render - templates and views", function (test) { }); myTemplate.constructView = function (number) { - var view = Template.prototype.constructView.call(this); + const 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'); + const view = this.view; + const parent = Blaze.getView(view, 'myTemplate'); if (parent) { buf.push('parent of ' + view.number + ' is ' + parent.number); @@ -520,7 +520,7 @@ Tinytest.add("blaze - render - templates and views", function (test) { myTemplate.onRendered(function () { test.isFalse(Tracker.active); - var nodeDescr = function (node) { + const nodeDescr = function (node) { if (node.nodeType === 8) // comment return ''; if (node.nodeType === 3) // text @@ -529,9 +529,9 @@ Tinytest.add("blaze - render - templates and views", function (test) { return node.nodeName; }; - var view = this.view; - var start = view.firstNode(); - var end = view.lastNode(); + const view = this.view; + let start = view.firstNode(); + let end = view.lastNode(); // skip marker nodes while (start !== end && ! nodeDescr(start)) start = start.nextSibling; @@ -548,14 +548,14 @@ Tinytest.add("blaze - render - templates and views", function (test) { buf.push('destroyed ' + Template.currentData()); }); - var makeView = function () { - var number = counter++; + const makeView = function () { + let number = counter++; return Blaze.With(number, function () { return myTemplate.constructView(number); }); }; - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); Blaze.render(makeView, div); buf.push('---flush---'); @@ -583,7 +583,7 @@ Tinytest.add("blaze - render - templates and views", function (test) { buf.length = 0; counter = 1; - var html = Blaze.toHTML(makeView()); + const html = Blaze.toHTML(makeView()); test.equal(buf, ['created 1', 'parent of 2 is 1', @@ -599,10 +599,10 @@ Tinytest.add("blaze - render - templates and views", function (test) { }); Tinytest.add("blaze - render - findAll", function (test) { - var found = null; - var $found = null; + let found = null; + let $found = null; - var myTemplate = new Template( + const myTemplate = new Template( 'findAllTest', function() { return DIV([P('first'), P('second')]); @@ -612,7 +612,7 @@ Tinytest.add("blaze - render - findAll", function (test) { $found = this.$('p'); }; - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); Blaze.render(myTemplate, div); Tracker.flush(); @@ -624,18 +624,18 @@ Tinytest.add("blaze - render - findAll", function (test) { }); Tinytest.add("blaze - render - reactive attributes 2", function (test) { - var R1 = ReactiveVar(['foo']); - var R2 = ReactiveVar(['bar']); + const R1 = ReactiveVar(['foo']); + const R2 = ReactiveVar(['bar']); - var spanFunc = function () { + const spanFunc = function () { return SPAN(HTML.Attrs( { blah: function () { return R1.get(); } }, function () { return { blah: R2.get() }; })); }; - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); Blaze.render(spanFunc, div); - var check = function (expected) { + const check = function (expected) { test.equal(Blaze.toHTML(spanFunc()), expected); test.equal(canonicalizeHtml(div.innerHTML), expected); }; @@ -682,20 +682,20 @@ Tinytest.add("blaze - render - SVG", function (test) { return; } - var fillColor = ReactiveVar('red'); - var classes = ReactiveVar('one two'); + const fillColor = ReactiveVar('red'); + const classes = ReactiveVar('one two'); - var content = DIV({'class': 'container'}, HTML.SVG( + const content = DIV({'class': 'container'}, HTML.SVG( {width: 100, height: 100}, HTML.CIRCLE({cx: 50, cy: 50, r: 40, stroke: 'black', 'stroke-width': 3, 'class': function () { return classes.get(); }, fill: function () { return fillColor.get(); }}))); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); materialize(content, div); - var circle = div.querySelector('.container > svg > circle'); + const circle = div.querySelector('.container > svg > circle'); test.equal(circle.getAttribute('fill'), 'red'); test.equal(circle.className.baseVal, 'one two'); @@ -711,8 +711,8 @@ Tinytest.add("blaze - render - SVG", function (test) { }); Tinytest.add("ui - attributes", function (test) { - var SPAN = HTML.SPAN; - var amp = HTML.CharRef({html: '&', str: '&'}); + const SPAN = HTML.SPAN; + const amp = HTML.CharRef({html: '&', str: '&'}); test.equal(HTML.toHTML(SPAN({title: ['M', amp, 'Ms']}, 'M', amp, 'M candies')), 'M&M candies'); @@ -722,22 +722,22 @@ if (typeof MutationObserver !== 'undefined') { // This test is not really able to test that Blaze._materializeDOM is called only when // not Blaze._isContentEqual(lastHtmljs, htmljs), which is what we would in fact want to test. Tinytest.addAsync("blaze - render - optimization", function (test, onComplete) { - var R = ReactiveVar('aa'); - var view = Blaze.View(function () { return R.get().substr(0, 1); }); + const R = ReactiveVar('aa'); + const view = Blaze.View(function () { return R.get().substr(0, 1); }); - var renderedCount = 0; + let renderedCount = 0; test.equal(view.renderCount, 0); view._onViewRendered(function () { renderedCount++; }); - var test1 = P(view); + const test1 = P(view); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); - var observedMutations = []; - var observer = new MutationObserver(function (mutations) { + const observedMutations = []; + const observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { observedMutations.push(mutation); }); @@ -745,8 +745,8 @@ if (typeof MutationObserver !== 'undefined') { observer.observe(div, {childList: true, subtree: true}); - var materializeCount = 0; - var originalMaterializeDOM = Blaze._materializeDOM; + let materializeCount = 0; + const originalMaterializeDOM = Blaze._materializeDOM; Blaze._materializeDOM = function (htmljs, intoArray, parentView, _existingWorkStack) { if (parentView === view) { materializeCount++; diff --git a/packages/blaze/template.js b/packages/blaze/template.js index f084ece82..d95624d08 100644 --- a/packages/blaze/template.js +++ b/packages/blaze/template.js @@ -45,9 +45,9 @@ Blaze.Template = function (viewName, renderFunction) { destroyed: [] }; }; -var Template = Blaze.Template; +const Template = Blaze.Template; -var HelperMap = function () {}; +const HelperMap = function () {}; HelperMap.prototype.get = function (name) { return this[' '+name]; }; @@ -107,8 +107,8 @@ Template.prototype.onDestroyed = function (cb) { }; Template.prototype._getCallbacks = function (which) { - var self = this; - var callbacks = self[which] ? [self[which]] : []; + const self = this; + let callbacks = self[which] ? [self[which]] : []; // Fire all callbacks added with the new API (Template.onRendered()) // as well as the old-style callback (e.g. Template.rendered) for // backwards-compatibility. @@ -116,19 +116,19 @@ Template.prototype._getCallbacks = function (which) { return callbacks; }; -var fireCallbacks = function (callbacks, template) { +const fireCallbacks = function (callbacks, template) { Template._withTemplateInstanceFunc( function () { return template; }, function () { - for (var i = 0, N = callbacks.length; i < N; i++) { + for (let i = 0, N = callbacks.length; i < N; i++) { callbacks[i].call(template); } }); }; Template.prototype.constructView = function (contentFunc, elseFunc) { - var self = this; - var view = Blaze.View(self.viewName, self.renderFunction); + const self = this; + const view = Blaze.View(self.viewName, self.renderFunction); view.template = self; view.templateContentBlock = ( @@ -161,7 +161,7 @@ Template.prototype.constructView = function (contentFunc, elseFunc) { view.templateInstance = function () { // Update data, firstNode, and lastNode, and return the TemplateInstance // object. - var inst = view._templateInstance; + const inst = view._templateInstance; /** * @instance @@ -195,7 +195,7 @@ Template.prototype.constructView = function (contentFunc, elseFunc) { // To avoid situations when new callbacks are added in between view // instantiation and event being fired, decide on all callbacks to fire // immediately and then fire them on the event. - var createdCallbacks = self._getCallbacks('created'); + const createdCallbacks = self._getCallbacks('created'); view.onViewCreated(function () { fireCallbacks(createdCallbacks, view.templateInstance()); }); @@ -208,7 +208,7 @@ Template.prototype.constructView = function (contentFunc, elseFunc) { * @locus Client * @deprecated in 1.1 */ - var renderedCallbacks = self._getCallbacks('rendered'); + const renderedCallbacks = self._getCallbacks('rendered'); view.onViewReady(function () { fireCallbacks(renderedCallbacks, view.templateInstance()); }); @@ -221,7 +221,7 @@ Template.prototype.constructView = function (contentFunc, elseFunc) { * @locus Client * @deprecated in 1.1 */ - var destroyedCallbacks = self._getCallbacks('destroyed'); + const destroyedCallbacks = self._getCallbacks('destroyed'); view.onViewDestroyed(function () { fireCallbacks(destroyedCallbacks, view.templateInstance()); }); @@ -294,7 +294,7 @@ Blaze.TemplateInstance = function (view) { * @returns {DOMNode[]} */ Blaze.TemplateInstance.prototype.$ = function (selector) { - var view = this.view; + const view = this.view; if (! view._domrange) throw new Error("Can't use $ on template instance with no DOM"); return view._domrange.$(selector); @@ -317,7 +317,7 @@ Blaze.TemplateInstance.prototype.findAll = function (selector) { * @returns {DOMElement} */ Blaze.TemplateInstance.prototype.find = function (selector) { - var result = this.$(selector); + const result = this.$(selector); return result[0] || null; }; @@ -350,17 +350,17 @@ Blaze.TemplateInstance.prototype.autorun = function (f) { * subscription. */ Blaze.TemplateInstance.prototype.subscribe = function (...args) { - var self = this; + const self = this; - var subHandles = self._subscriptionHandles; + const subHandles = self._subscriptionHandles; // Duplicate logic from Meteor.subscribe - var options = {}; + let options = {}; if (args.length) { - var lastParam = args[args.length - 1]; + const lastParam = args[args.length - 1]; // Match pattern to check if the last arg is an options argument - var lastParamOptionsPattern = { + const lastParamOptionsPattern = { onReady: Match.Optional(Function), // XXX COMPAT WITH 1.0.3.1 onError used to exist, but now we use // onStop with an error callback instead. @@ -376,8 +376,8 @@ Blaze.TemplateInstance.prototype.subscribe = function (...args) { } } - var subHandle; - var oldStopped = options.onStop; + let subHandle; + const oldStopped = options.onStop; options.onStop = function (error) { // When the subscription is stopped, remove it from the set of tracked // subscriptions to avoid this list growing without bound @@ -395,9 +395,8 @@ Blaze.TemplateInstance.prototype.subscribe = function (...args) { } }; - var connection = options.connection; - const { onReady, onError, onStop } = options; - var callbacks = { onReady, onError, onStop }; + const { onReady, onError, onStop, connection } = options; + const callbacks = { onReady, onError, onStop }; // The callbacks are passed as the last item in the arguments array passed to // View#subscribe @@ -431,7 +430,7 @@ Blaze.TemplateInstance.prototype.subscribe = function (...args) { */ Blaze.TemplateInstance.prototype.subscriptionsReady = function () { this._allSubsReadyDep.depend(); - this._allSubsReady = Object.values(this._subscriptionHandles).every((handle) => { + this._allSubsReady = Object.values(this._subscriptionHandles).every((handle) => { return handle.ready(); }); @@ -449,12 +448,12 @@ Template.prototype.helpers = function (dict) { throw new Error("Helpers dictionary has to be an object"); } - for (var k in dict) this.__helpers.set(k, dict[k]); + for (let k in dict) this.__helpers.set(k, dict[k]); }; -var canUseGetters = (function () { +const canUseGetters = (function () { if (Object.defineProperty) { - var obj = {}; + let obj = {}; try { Object.defineProperty(obj, "self", { get: function () { return obj; } @@ -472,7 +471,7 @@ if (canUseGetters) { // rather than a value so that not all helpers are implicitly dependent // on the current template instance's `data` property, which would make // them dependent on the data context of the template inclusion. - var currentTemplateInstanceFunc = null; + let currentTemplateInstanceFunc = null; // If getters are supported, define this property with a getter function // to make it effectively read-only, and to work around this bizarre JSC @@ -487,7 +486,7 @@ if (canUseGetters) { if (typeof func !== 'function') { throw new Error("Expected function, got: " + func); } - var oldTmplInstanceFunc = currentTemplateInstanceFunc; + const oldTmplInstanceFunc = currentTemplateInstanceFunc; try { currentTemplateInstanceFunc = templateInstanceFunc; return func(); @@ -503,7 +502,7 @@ if (canUseGetters) { if (typeof func !== 'function') { throw new Error("Expected function, got: " + func); } - var oldTmplInstanceFunc = Template._currentTemplateInstanceFunc; + const oldTmplInstanceFunc = Template._currentTemplateInstanceFunc; try { Template._currentTemplateInstanceFunc = templateInstanceFunc; return func(); @@ -524,20 +523,20 @@ Template.prototype.events = function (eventMap) { throw new Error("Event map has to be an object"); } - var template = this; - var eventMap2 = {}; - for (var k in eventMap) { + const template = this; + let eventMap2 = {}; + for (let k in eventMap) { eventMap2[k] = (function (k, v) { return function (event /*, ...*/) { - var view = this; // passed by EventAugmenter - var args = Array.prototype.slice.call(arguments); + const view = this; // passed by EventAugmenter + const args = Array.prototype.slice.call(arguments); // Exiting the current computation to avoid creating unnecessary // and unexpected reactive dependencies with Templates data // or any other reactive dependencies defined in event handlers return Tracker.nonreactive(function () { - var data = Blaze.getData(event.currentTarget); + let data = Blaze.getData(event.currentTarget); if (data == null) data = {}; - var tmplInstanceFunc = Blaze._bind(view.templateInstance, view); + const tmplInstanceFunc = Blaze._bind(view.templateInstance, view); args.splice(1, 0, tmplInstanceFunc()); return Template._withTemplateInstanceFunc(tmplInstanceFunc, function () { return v.apply(data, args); diff --git a/packages/blaze/view.js b/packages/blaze/view.js index aa3e95dd4..7550c1898 100644 --- a/packages/blaze/view.js +++ b/packages/blaze/view.js @@ -32,6 +32,7 @@ /// of name "with". Names are also useful when debugging, so in /// general it's good for functions that create Views to set the name. /// Views associated with templates have names of the form "Template.foo". +import { HTML } from 'meteor/htmljs'; /** * A binding is either `undefined` (pending), `{ error }` (rejected), or @@ -108,8 +109,8 @@ Blaze.View.prototype._onViewRendered = function (cb) { }; Blaze.View.prototype.onViewReady = function (cb) { - var self = this; - var fire = function () { + const self = this; + const fire = function () { Tracker.afterFlush(function () { if (! self.isDestroyed) { Blaze._withCurrentView(self, function () { @@ -133,10 +134,10 @@ Blaze.View.prototype.onViewDestroyed = function (cb) { this._callbacks.destroyed.push(cb); }; Blaze.View.prototype.removeViewDestroyedListener = function (cb) { - var destroyed = this._callbacks.destroyed; + const destroyed = this._callbacks.destroyed; if (! destroyed) return; - var index = destroyed.lastIndexOf(cb); + const index = destroyed.lastIndexOf(cb); if (index !== -1) { // XXX You'd think the right thing to do would be splice, but _fireCallbacks // gets sad if you remove callbacks while iterating over the list. Should @@ -166,7 +167,7 @@ Blaze.View.prototype.removeViewDestroyedListener = function (cb) { /// from either onViewCreated (guarded against the absence of /// view._domrange), or onViewReady. Blaze.View.prototype.autorun = function (f, _inViewScope, displayName) { - var self = this; + const self = this; // The restrictions on when View#autorun can be called are in order // to avoid bad patterns, like creating a Blaze.View and immediately @@ -196,9 +197,9 @@ Blaze.View.prototype.autorun = function (f, _inViewScope, displayName) { throw new Error("Can't call View#autorun from inside render(); try calling it from the created or rendered callback"); } - var templateInstanceFunc = Blaze.Template._currentTemplateInstanceFunc; + const templateInstanceFunc = Blaze.Template._currentTemplateInstanceFunc; - var func = function viewAutorun(c) { + const func = function viewAutorun(c) { return Blaze._withCurrentView(_inViewScope || self, function () { return Blaze.Template._withTemplateInstanceFunc( templateInstanceFunc, function () { @@ -212,9 +213,9 @@ Blaze.View.prototype.autorun = function (f, _inViewScope, displayName) { // and Firefox prefer it in debuggers over the name function was declared by. func.displayName = (self.name || 'anonymous') + ':' + (displayName || 'anonymous'); - var comp = Tracker.autorun(func); + const comp = Tracker.autorun(func); - var stopComputation = function () { comp.stop(); }; + const stopComputation = function () { comp.stop(); }; self.onViewDestroyed(stopComputation); comp.onStop(function () { self.removeViewDestroyedListener(stopComputation); @@ -224,7 +225,7 @@ Blaze.View.prototype.autorun = function (f, _inViewScope, displayName) { }; Blaze.View.prototype._errorIfShouldntCallSubscribe = function () { - var self = this; + const self = this; if (! self.isCreated) { throw new Error("View#subscribe must be called from the created callback at the earliest"); @@ -244,12 +245,12 @@ Blaze.View.prototype._errorIfShouldntCallSubscribe = function () { * see if it is ready, or stop it manually */ Blaze.View.prototype.subscribe = function (args, options) { - var self = this; + const self = this; options = options || {}; self._errorIfShouldntCallSubscribe(); - var subHandle; + let subHandle; if (options.connection) { subHandle = options.connection.subscribe.apply(options.connection, args); } else { @@ -280,8 +281,8 @@ Blaze.View.prototype.lastNode = function () { Blaze._fireCallbacks = function (view, which) { Blaze._withCurrentView(view, function () { Tracker.nonreactive(function fireCallbacks() { - var cbs = view._callbacks[which]; - for (var i = 0, N = (cbs && cbs.length); i < N; i++) + const cbs = view._callbacks[which]; + for (let i = 0, N = (cbs && cbs.length); i < N; i++) cbs[i] && cbs[i].call(view); }); }); @@ -299,17 +300,17 @@ Blaze._createView = function (view, parentView, forExpansion) { Blaze._fireCallbacks(view, 'created'); }; -var doFirstRender = function (view, initialContent) { - var domrange = new Blaze._DOMRange(initialContent); - view._domrange = domrange; +const doFirstRender = function (view, initialContent) { + const domrange = new Blaze._DOMRange(initialContent); + view.setAttribute('_domrange', domrange) domrange.view = view; - view.isRendered = true; + view.setAttribute('isRendered', true) Blaze._fireCallbacks(view, 'rendered'); - var teardownHook = null; + let teardownHook = null; domrange.onAttached(function attached(range, element) { - view._isAttached = true; + view.setAttribute('_isAttached', true) teardownHook = Blaze._DOMBackend.Teardown.onElementTeardown( element, function teardown() { @@ -319,7 +320,7 @@ var doFirstRender = function (view, initialContent) { // tear down the teardown hook view.onViewDestroyed(function () { - teardownHook && teardownHook.stop(); + if (teardownHook) teardownHook.stop(); teardownHook = null; }); @@ -343,24 +344,24 @@ var doFirstRender = function (view, initialContent) { Blaze._materializeView = function (view, parentView, _workStack, _intoArray) { Blaze._createView(view, parentView); - var domrange; - var lastHtmljs; + let domrange; + let lastHtmljs; // We don't expect to be called in a Computation, but just in case, // wrap in Tracker.nonreactive. Tracker.nonreactive(function () { view.autorun(function doRender(c) { // `view.autorun` sets the current view. - view.renderCount++; - view._isInRender = true; + view.setAttribute('renderCount', view.renderCount + 1); + view.setAttribute('_isInRender', true); // Any dependencies that should invalidate this Computation come // from this line: - var htmljs = view._render(); - view._isInRender = false; + const htmljs = view._render(); + view.setAttribute('_isInRender', false); if (! c.firstRun && ! Blaze._isContentEqual(lastHtmljs, htmljs)) { Tracker.nonreactive(function doMaterialize() { // re-render - var rangesAndNodes = Blaze._materializeDOM(htmljs, [], view); + const rangesAndNodes = Blaze._materializeDOM(htmljs, [], view); domrange.setMembers(rangesAndNodes); Blaze._fireCallbacks(view, 'rendered'); }); @@ -379,7 +380,7 @@ Blaze._materializeView = function (view, parentView, _workStack, _intoArray) { }, undefined, 'materialize'); // first render. lastHtmljs is the first htmljs. - var initialContents; + let initialContents; if (! _workStack) { initialContents = Blaze._materializeDOM(lastHtmljs, [], view); domrange = doFirstRender(view, initialContents); @@ -424,13 +425,13 @@ Blaze._materializeView = function (view, parentView, _workStack, _intoArray) { Blaze._expandView = function (view, parentView) { Blaze._createView(view, parentView, true /*forExpansion*/); - view._isInRender = true; - var htmljs = Blaze._withCurrentView(view, function () { + view.setAttribute('_isInRender', true); + const htmljs = Blaze._withCurrentView(view, function () { return view._render(); }); - view._isInRender = false; + view.setAttribute('_isInRender', false); - var result = Blaze._expand(htmljs, view); + const result = Blaze._expand(htmljs, view); if (Tracker.active) { Tracker.onInvalidate(function () { @@ -476,8 +477,8 @@ Blaze._HTMLJSExpander.def({ // Return Blaze.currentView, but only if it is being rendered // (i.e. we are in its render() method). -var currentViewIfRendering = function () { - var view = Blaze.currentView; +const currentViewIfRendering = function () { + const view = Blaze.currentView; return (view && view._isInRender) ? view : null; }; @@ -509,7 +510,7 @@ Blaze._destroyView = function (view, _skipNodes) { // otherwise it's tracker.flush will cause the above line will // not be called and their views won't be destroyed // Involved issues: DOMRange "Must be attached" error, mem leak - + Blaze._fireCallbacks(view, 'destroyed'); }; @@ -547,7 +548,7 @@ Blaze.currentView = null; * @returns {T} */ Blaze._withCurrentView = function (view, func) { - var oldView = Blaze.currentView; + const oldView = Blaze.currentView; try { Blaze.currentView = view; return func(); @@ -560,7 +561,7 @@ Blaze._withCurrentView = function (view, func) { // Privately, it takes any HTMLJS (extended with Views and Templates) // except null or undefined, or a function that returns any extended // HTMLJS. -var checkRenderContent = function (content) { +const checkRenderContent = function (content) { if (content === null) throw new Error("Can't render null"); if (typeof content === 'undefined') @@ -585,7 +586,7 @@ var checkRenderContent = function (content) { // For Blaze.render and Blaze.toHTML, take content and // wrap it in a View, unless it's a single View or // Template already. -var contentAsView = function (content) { +const contentAsView = function (content) { checkRenderContent(content); if (content instanceof Blaze.Template) { @@ -593,7 +594,7 @@ var contentAsView = function (content) { } else if (content instanceof Blaze.View) { return content; } else { - var func = content; + let func = content; if (typeof func !== 'function') { func = function () { return content; @@ -606,7 +607,7 @@ var contentAsView = function (content) { // For Blaze.renderWithData and Blaze.toHTMLWithData, wrap content // in a function, if necessary, so it can be a content arg to // a Blaze.With. -var contentAsFunc = function (content) { +const contentAsFunc = function (content) { checkRenderContent(content); if (typeof content !== 'function') { @@ -650,7 +651,7 @@ Blaze.render = function (content, parentElement, nextNode, parentView) { parentView = parentView || currentViewIfRendering(); - var view = contentAsView(content); + const view = contentAsView(content); // TODO: this is only needed in development if (!parentView) { @@ -659,7 +660,7 @@ Blaze.render = function (content, parentElement, nextNode, parentView) { }); view.onViewDestroyed(function () { - var index = Blaze.__rootViews.indexOf(view); + let index = Blaze.__rootViews.indexOf(view); if (index > -1) { Blaze.__rootViews.splice(index, 1); } @@ -711,7 +712,7 @@ Blaze.remove = function (view) { while (view) { if (! view.isDestroyed) { - var range = view._domrange; + const range = view._domrange; range.destroy(); if (range.attached && ! range.parentRange) { @@ -774,12 +775,12 @@ Blaze._toText = function (htmljs, parentView, textMode) { * @param {DOMElement|Blaze.View} [elementOrView] Optional. An element that was rendered by a Meteor, or a View. */ Blaze.getData = function (elementOrView) { - var theWith; + let theWith; if (! elementOrView) { theWith = Blaze.getView('with'); } else if (elementOrView instanceof Blaze.View) { - var view = elementOrView; + const view = elementOrView; theWith = (view.name === 'with' ? view : Blaze.getView(view, 'with')); } else if (typeof elementOrView.nodeType === 'number') { @@ -812,7 +813,7 @@ Blaze.getElementData = function (element) { * @param {DOMElement} [element] Optional. If specified, the View enclosing `element` is returned. */ Blaze.getView = function (elementOrView, _viewName) { - var viewName = _viewName; + let viewName = _viewName; if ((typeof elementOrView) === 'string') { // omitted elementOrView; viewName present @@ -836,7 +837,7 @@ Blaze.getView = function (elementOrView, _viewName) { // Gets the current view or its nearest ancestor of name // `name`. Blaze._getCurrentView = function (name) { - var view = Blaze.currentView; + let view = Blaze.currentView; // Better to fail in cases where it doesn't make sense // to use Blaze._getCurrentView(). There will be a current // view anywhere it does. You can check Blaze.currentView @@ -856,7 +857,7 @@ Blaze._getCurrentView = function (name) { }; Blaze._getParentView = function (view, name) { - var v = view.parentView; + let v = view.parentView; if (name) { while (v && v.name !== name) @@ -867,8 +868,8 @@ Blaze._getParentView = function (view, name) { }; Blaze._getElementView = function (elem, name) { - var range = Blaze._DOMRange.forElement(elem); - var view = null; + let range = Blaze._DOMRange.forElement(elem); + let view = null; while (range && ! view) { view = (range.view || null); if (! view) { @@ -890,7 +891,7 @@ Blaze._getElementView = function (elem, name) { Blaze._addEventMap = function (view, eventMap, thisInHandler) { thisInHandler = (thisInHandler || null); - var handles = []; + const handles = []; if (! view._domrange) throw new Error("View must have a DOMRange"); @@ -898,22 +899,22 @@ Blaze._addEventMap = function (view, eventMap, thisInHandler) { view._domrange.onAttached(function attached_eventMaps(range, element) { Object.keys(eventMap).forEach(function (spec) { let handler = eventMap[spec]; - var clauses = spec.split(/,\s+/); + const clauses = spec.split(/,\s+/); // iterate over clauses of spec, e.g. ['click .foo', 'click .bar'] clauses.forEach(function (clause) { - var parts = clause.split(/\s+/); + const parts = clause.split(/\s+/); if (parts.length === 0) return; - var newEvents = parts.shift(); - var selector = parts.join(' '); + const newEvents = parts.shift(); + const selector = parts.join(' '); handles.push(Blaze._EventSupport.listen( element, newEvents, selector, function (evt) { if (! range.containsElement(evt.currentTarget, selector, newEvents)) return null; - var handlerThis = thisInHandler || this; - var handlerArgs = arguments; + const handlerThis = thisInHandler || this; + const handlerArgs = arguments; return Blaze._withCurrentView(view, function () { return handler.apply(handlerThis, handlerArgs); }); diff --git a/packages/blaze/view_tests.js b/packages/blaze/view_tests.js index 2e49b4240..9f7e188f2 100644 --- a/packages/blaze/view_tests.js +++ b/packages/blaze/view_tests.js @@ -1,11 +1,11 @@ if (Meteor.isClient) { Tinytest.add("blaze - view - callbacks", function (test) { - var R = ReactiveVar('foo'); + const R = ReactiveVar('foo'); - var buf = ''; + let buf = ''; - var v = Blaze.View(function () { + const v = Blaze.View(function () { return R.get(); }); @@ -24,7 +24,7 @@ if (Meteor.isClient) { test.equal(buf, ''); - var div = document.createElement("DIV"); + const div = document.createElement("DIV"); test.isFalse(v.isRendered); test.isFalse(v._isAttached); test.equal(canonicalizeHtml(div.innerHTML), ""); @@ -57,10 +57,10 @@ if (Meteor.isClient) { }); // this checks, whether a DOMRange is correctly marked as - // desroyed after Blaze.remove has destroyed + // desroyed after Blaze.remove has destroyed // the corresponding view Tinytest.add("blaze - view - destroy", function (test) { - var v = { + const v = { _domrange: Blaze._DOMRange([]) }; v._domrange.view = Blaze.View(); @@ -68,11 +68,11 @@ if (Meteor.isClient) { Blaze.remove(v); test.equal(v._domrange.view.isDestroyed, true); }); - + // this checks, whether an unattached DOMRange notifies // correctly about it's root cause, when throwing due to an event Tinytest.add("blaze - view - attached", function (test) { - test.throws(() => Blaze._DOMRange.prototype.containsElement.call({attached: false, view: {name: 'Template.foo'}}, undefined, '.class', 'click'), + test.throws(() => Blaze._DOMRange.prototype.containsElement.call({attached: false, view: {name: 'Template.foo'}}, undefined, '.class', 'click'), `click event triggerd with .class on foo but associated view is not be found. Make sure the event doesn't destroy the view.`); }); From a851cccd6a41e0ce3d5d26e1b5ceaece175cf013 Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Tue, 28 Nov 2023 14:42:41 +0100 Subject: [PATCH 2/3] Revert use of view.setAttribute --- packages/blaze/view.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/blaze/view.js b/packages/blaze/view.js index 7550c1898..625bcc288 100644 --- a/packages/blaze/view.js +++ b/packages/blaze/view.js @@ -302,15 +302,15 @@ Blaze._createView = function (view, parentView, forExpansion) { const doFirstRender = function (view, initialContent) { const domrange = new Blaze._DOMRange(initialContent); - view.setAttribute('_domrange', domrange) + view._domrange = domrange; domrange.view = view; - view.setAttribute('isRendered', true) + view.isRendered = true; Blaze._fireCallbacks(view, 'rendered'); let teardownHook = null; domrange.onAttached(function attached(range, element) { - view.setAttribute('_isAttached', true) + view._isAttached = true; teardownHook = Blaze._DOMBackend.Teardown.onElementTeardown( element, function teardown() { @@ -351,12 +351,12 @@ Blaze._materializeView = function (view, parentView, _workStack, _intoArray) { Tracker.nonreactive(function () { view.autorun(function doRender(c) { // `view.autorun` sets the current view. - view.setAttribute('renderCount', view.renderCount + 1); - view.setAttribute('_isInRender', true); + view.renderCount = view.renderCount + 1; + view._isInRender = true; // Any dependencies that should invalidate this Computation come // from this line: const htmljs = view._render(); - view.setAttribute('_isInRender', false); + view._isInRender = false; if (! c.firstRun && ! Blaze._isContentEqual(lastHtmljs, htmljs)) { Tracker.nonreactive(function doMaterialize() { @@ -425,11 +425,11 @@ Blaze._materializeView = function (view, parentView, _workStack, _intoArray) { Blaze._expandView = function (view, parentView) { Blaze._createView(view, parentView, true /*forExpansion*/); - view.setAttribute('_isInRender', true); + view._isInRender = true; const htmljs = Blaze._withCurrentView(view, function () { return view._render(); }); - view.setAttribute('_isInRender', false); + view._isInRender = false; const result = Blaze._expand(htmljs, view); From 8141b41e87e8cc15273ade859c1316ac78121a85 Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Tue, 28 Nov 2023 22:50:46 +0100 Subject: [PATCH 3/3] Remove conditional chaining in lookup.js --- packages/blaze/lookup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/blaze/lookup.js b/packages/blaze/lookup.js index 5fc748230..903c88efa 100644 --- a/packages/blaze/lookup.js +++ b/packages/blaze/lookup.js @@ -231,7 +231,7 @@ Blaze.View.prototype.lookup = function (name, _options) { // 5. look up in a data context return function (...args) { - const isCalledAsFunction = (args?.length > 0); + const isCalledAsFunction = (args.length > 0); const data = Blaze.getData(); const x = data && data[name]; if (! x) {