diff --git a/HISTORY.md b/HISTORY.md index 5fd888ddd..6d323f422 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,19 @@ ## vNEXT +## v.2.4.0, 2021-March-26? + +* [#313](https://github.com/meteor/blaze/pull/313) Implemented HMR for Blaze + +* [#319](https://github.com/meteor/blaze/pull/319) Fixed a few situations where the template compiler wouldn't optimise it's output javascript. Should make rendering faster (if the initial optimisation reasoning holds true) + +* [#321](https://github.com/meteor/blaze/pull/321) Just source code modernisation, making it easier to read. Shouldn't change any API's; except may need explicit import if other packages are using directly. + +* [#324](https://github.com/meteor/blaze/pull/324) Add a whitespace="strip" option to templates, which removes any whitespace that crosses newlines. + +* [#276](https://github.com/meteor/blaze/pull/276) [HTML.isArray](https://github.com/brucejo75/blaze/blob/release-2.4/packages/htmljs/README.md#htmlisarrayx) works across iFrames. This supports running blaze in sandboxed iFrames. + +* [#326](https://github.com/meteor/blaze/pull/326) Remove old ui package code from this repository. + ## v2.3.4, 2019-Dec-13 * jquery 3 support diff --git a/packages/blaze-hot/hot.js b/packages/blaze-hot/hot.js new file mode 100644 index 000000000..5035e73ce --- /dev/null +++ b/packages/blaze-hot/hot.js @@ -0,0 +1,140 @@ +import { Blaze } from 'meteor/blaze'; +import { Template as Templates} from 'meteor/templating-runtime'; +import { UpdateAll } from './update-templates.js'; + +let importedTemplating = new WeakMap(); +let currentModule = {id: null}; +const SourceModule = Symbol(); + +function patchTemplate(Template) { + const oldRegisterHelper = Template.registerHelper; + Template.registerHelper = function (name, func) { + func[SourceModule] = currentModule.id; + oldRegisterHelper(name, func); + } + + const oldOnCreated = Template.prototype.onCreated; + Template.prototype.onCreated = function (cb) { + if (cb) { + cb[SourceModule] = currentModule.id; + } + + return oldOnCreated.call(this, cb); + } + + const oldOnRendered = Template.prototype.onRendered; + Template.prototype.onRendered = function (cb) { + if (cb) { + cb[SourceModule] = currentModule.id; + } + + return oldOnRendered.call(this, cb); + } + + const oldOnDestroyed = Template.prototype.onDestroyed; + Template.prototype.onDestroyed = function (cb) { + if (cb) { + cb[SourceModule] = currentModule.id; + } + + return oldOnDestroyed.call(this, cb); + } + + const oldHelpers = Template.prototype.helpers; + Template.prototype.helpers = function (dict) { + if (typeof dict === 'object') { + for (var k in dict) { + if (dict[k]) { + dict[k][SourceModule] = currentModule.id; + } + } + } + + return oldHelpers.call(this, dict); + } + + const oldEvents = Template.prototype.events; + Template.prototype.events = function (eventMap) { + const result = oldEvents.call(this, eventMap); + this.__eventMaps[this.__eventMaps.length - 1][SourceModule] = currentModule.id; + return result; + } +} + +function cleanTemplate(template, moduleId) { + let usedModule = false + if (!template || !Blaze.isTemplate(template)) { + return usedModule; + } + + function cleanArray(array) { + for (let i = array.length - 1; i >= 0; i--) { + let item = array[i]; + if (item && item[SourceModule] === moduleId) { + usedModule = true + array.splice(i, 1); + } + } + } + + cleanArray(template._callbacks.created); + cleanArray(template._callbacks.rendered); + cleanArray(template._callbacks.destroyed); + cleanArray(template.__eventMaps); + + Object.keys(template.__helpers).forEach(key => { + if (template.__helpers[key] && template.__helpers[key][SourceModule] === moduleId) { + usedModule = true + delete template.__helpers[key]; + } + }); + + return usedModule +} + +function shouldAccept(module) { + if (!importedTemplating.get(module)) { + return false; + } + if (!module.exports) { + return true; + } + + return Object.keys(module.exports).filter(key => key !== '__esModule').length === 0; +} + +if (module.hot) { + patchTemplate(Blaze.Template); + module.hot.onRequire({ + before(module) { + if (module.id === '/node_modules/meteor/blaze.js' || module.id === '/node_modules/meteor/templating.js') { + importedTemplating.set(currentModule, true); + } + + let previousModule = currentModule; + currentModule = module; + return previousModule; + }, + after(module, previousModule) { + if (shouldAccept(module)) { + module.hot.accept(); + module.hot.dispose(() => { + Object.keys(Templates).forEach(templateName => { + let template = Templates[templateName] + let usedByModule = cleanTemplate(template, module.id); + if (usedByModule) { + Template._applyHmrChanges(templateName); + } + }); + + Object.values(Blaze._globalHelpers).forEach(helper => { + if (helper && helper[SourceModule] === module.id) { + Template._applyHmrChanges(UpdateAll); + } + }); + }); + } + currentModule = previousModule + } + }); +} diff --git a/packages/blaze-hot/package.js b/packages/blaze-hot/package.js new file mode 100644 index 000000000..1a5d5e8bb --- /dev/null +++ b/packages/blaze-hot/package.js @@ -0,0 +1,20 @@ +Package.describe({ + name: 'blaze-hot', + summary: "Update files using Blaze's API with HMR", + version: '1.0.0-beta.3', + git: 'https://github.com/meteor/blaze.git', + documentation: null, + debugOnly: true +}); + +Package.onUse(function (api) { + api.use('modules@0.15.0'); + api.use('ecmascript@0.14.4'); + api.use('blaze@2.4.0-beta.3'); + api.use('underscore@1.0.9'); + api.use('templating-runtime@1.4.0-beta.3'); + api.use('hot-module-replacement@0.2.0', { weak: true }); + + api.addFiles('hot.js', 'client'); + api.addFiles('update-templates.js', 'client'); +}); diff --git a/packages/blaze-hot/update-templates.js b/packages/blaze-hot/update-templates.js new file mode 100644 index 000000000..caef9fb02 --- /dev/null +++ b/packages/blaze-hot/update-templates.js @@ -0,0 +1,164 @@ +export const UpdateAll = Symbol('update all templates') + +let renderedTemplates = {}; +let overrideTemplateContentBlock = null; +let overrideTemplateElseBlock = null; + +const oldConstructView = Template.prototype.constructView; + +Template.prototype.constructView = function () { + let view = oldConstructView.apply(this, arguments); + let templateName = this.viewName; + + view.onViewCreated(function () { + renderedTemplates[templateName] = renderedTemplates[templateName] || []; + renderedTemplates[templateName].push(view); + }); + + view.onViewDestroyed(function () { + const index = renderedTemplates[templateName].indexOf(view); + if (index > -1) { + renderedTemplates[templateName].splice(index, 1); + } + }); + + if (overrideTemplateContentBlock) { + view.templateContentBlock = overrideTemplateContentBlock; + overrideTemplateContentBlock = null; + } + + if (overrideTemplateElseBlock) { + view.templateElseBlock = overrideTemplateElseBlock; + overrideTemplateElseBlock = null; + } + + return view; +} + +let updateRootViews = Template._applyHmrChanges; + +let timeout = null; +let lastUpdateFailed = false; +let modifiedTemplates = new Set(); +let templateViewPrefix = 'Template.'; + +// Overrides the default _applyHmrChanges with one that updates the specific +// views for modified templates instead of updating everything. +Template._applyHmrChanges = function (templateName = UpdateAll) { + if (templateName === UpdateAll || lastUpdateFailed) { + lastUpdateFailed = false; + clearTimeout(timeout); + updateRootViews(); + return; + } else { + modifiedTemplates.add(templateName); + } + + if (timeout) { + return; + } + + timeout = setTimeout(() => { + for (var i = 0; i < Template.__pendingReplacement.length; i++) { + delete Template[Template.__pendingReplacement[i]] + } + + Template.__pendingReplacement = []; + + timeout = null; + modifiedTemplates.forEach(templateName => { + modifiedTemplates.delete(templateName); + let viewName = templateName; + + if (!(viewName in renderedTemplates)) { + viewName = templateViewPrefix + viewName; + } else { + console.error('[Blaze HMR] Error: view name does not start with Template'); + return; + } + + if (!(viewName in renderedTemplates)) { + return; + } + + let views = renderedTemplates[viewName]; + renderedTemplates[viewName] = []; + while (views.length > 0) { + let view = views.pop(); + + // find first parent template that isn't a content block + while (!view.template || view.templateContentBlock || view.templateElseBlock) { + if (!view.parentView) { + console.log('[Blaze HMR] Unable to update template', viewName); + return; + } + + view = view.parentView; + } + + if (!view.isRendered) { + continue; + } + + // TODO: this can be removed if we don't update a view, and then update + // one of its children (we only need to update the parent). + Package.tracker.Tracker.flush(); + + let parent = view.parentView; + let parentElement = view._domrange.parentElement; + let next = view._domrange.lastNode().nextSibling; + let nextComment = null; + + if (!next) { + // percolate:momentum requires a next node to show the new nodes + next = nextComment = document.createComment('Blaze HMR Placeholder'); + parentElement.insertBefore(nextComment, null); + } + + if (!parent) { + // TODO: we only need to update a single root view + return updateRootViews(); + } + + if (view.templateContentBlock) { + overrideTemplateContentBlock = view.templateContentBlock; + } + if (view.templateElseBlock) { + overrideTemplateElseBlock = view.templateElseBlock; + } + + // Since there is a parent range, Blaze will not automatically + // detach the dom range. + view._domrange.detach(); + view._domrange.destroy(); + let newView; + + try { + newView = Blaze.render( + Template[view.template.viewName.slice('Template.'.length)], + parentElement, + next, + parent + ); + } catch (error) { + console.log('[Blaze HMR] Error re-rending template:'); + console.error(error); + lastUpdateFailed = true; + } + + let index = parent._domrange.members.findIndex(member => { + return member && member.view === view; + }); + if (newView) { + parent._domrange.members.splice(index, 1, newView._domrange); + } else { + parent._domrange.members.splice(index, 1); + } + + if (nextComment) { + parentElement.removeChild(nextComment); + } + } + }); + }); +} diff --git a/packages/blaze-html-templates/.versions b/packages/blaze-html-templates/.versions index 30b46fabb..d293b1807 100644 --- a/packages/blaze-html-templates/.versions +++ b/packages/blaze-html-templates/.versions @@ -1,35 +1,41 @@ -babel-compiler@6.14.1 -babel-runtime@1.0.1 -base64@1.0.10 -blaze@2.3.2 -blaze-html-templates@1.1.2 -blaze-tools@1.0.10 -caching-compiler@1.1.9 -caching-html-compiler@1.1.2 -check@1.2.5 -diff-sequence@1.0.7 -ecmascript@0.6.3 -ecmascript-runtime@0.3.15 -ejson@1.0.13 -html-tools@1.0.11 -htmljs@1.0.11 -id-map@1.0.9 -jquery@1.11.10 -meteor@1.6.1 -modules@0.7.9 -modules-runtime@0.7.9 -mongo-id@1.0.6 +babel-compiler@7.6.0 +babel-runtime@1.5.0 +base64@1.0.12 +blaze@2.4.0-beta.3 +blaze-html-templates@1.2.0-beta.3 +blaze-tools@1.1.0-beta.3 +caching-compiler@1.2.2 +caching-html-compiler@1.2.0-beta.3 +check@1.3.1 +diff-sequence@1.1.1 +dynamic-import@0.6.0 +ecmascript@0.15.0 +ecmascript-runtime@0.7.0 +ecmascript-runtime-client@0.11.0 +ecmascript-runtime-server@0.10.0 +ejson@1.1.1 +fetch@0.1.1 +html-tools@1.1.0-beta.3 +htmljs@1.1.0-beta.3 +id-map@1.1.0 +inter-process-messaging@0.1.1 +meteor@1.9.3 +modern-browsers@0.1.5 +modules@0.16.0 +modules-runtime@0.12.0 +mongo-id@1.0.7 observe-sequence@1.0.16 -ordered-dict@1.0.9 -promise@0.8.8 -random@1.0.10 +ordered-dict@1.1.0 +promise@0.11.2 +random@1.2.0 +react-fast-refresh@0.1.0 reactive-var@1.0.11 -spacebars@1.0.15 -spacebars-compiler@1.1.2 -templating@1.3.2 -templating-compiler@1.3.2 -templating-runtime@1.3.2 -templating-tools@1.1.2 -tracker@1.1.2 -ui@1.0.12 +spacebars@1.1.0-beta.3 +spacebars-compiler@1.2.0-beta.3 +templating@1.4.0-beta.3 +templating-compiler@1.4.0-beta.3 +templating-runtime@1.4.0-beta.3 +templating-tools@1.2.0-beta.3 +tracker@1.2.0 +ui@1.0.13 underscore@1.0.10 diff --git a/packages/blaze-html-templates/package.js b/packages/blaze-html-templates/package.js index 10a0091a2..27188c2ce 100644 --- a/packages/blaze-html-templates/package.js +++ b/packages/blaze-html-templates/package.js @@ -1,22 +1,22 @@ Package.describe({ name: 'blaze-html-templates', summary: "Compile HTML templates into reactive UI with Meteor Blaze", - version: '1.1.2', + version: '1.2.0-beta.3', git: 'https://github.com/meteor/blaze.git' }); Package.onUse(function(api) { api.imply([ // A library for reactive user interfaces - 'blaze@2.3.2', + 'blaze@2.4.0-beta.3', // The following packages are basically empty shells that just exist to // satisfy code checking for the existence of a package. Rest assured that // they are not adding any bloat to your bundle. - 'ui@1.0.12', // XXX COMPAT WITH PACKAGES BUILT FOR 0.9.0. - 'spacebars@1.0.15', // XXX COMPAT WITH PACKAGES BUILT FOR 0.9.0 + 'ui@1.0.13', // XXX COMPAT WITH PACKAGES BUILT FOR 0.9.0. + 'spacebars@1.1.0-beta.3', // XXX COMPAT WITH PACKAGES BUILT FOR 0.9.0 // Compile .html files into Blaze reactive views - 'templating@1.3.2' + 'templating@1.4.0-beta.3' ]); }); diff --git a/packages/blaze-tools/.versions b/packages/blaze-tools/.versions index ea0b17337..48f9fced0 100644 --- a/packages/blaze-tools/.versions +++ b/packages/blaze-tools/.versions @@ -1,47 +1,51 @@ -allow-deny@1.0.5 -babel-compiler@6.14.1 -babel-runtime@1.0.1 -base64@1.0.10 -binary-heap@1.0.10 -blaze@2.3.2 -blaze-tools@1.0.10 -boilerplate-generator@1.0.11 -callback-hook@1.0.10 -check@1.2.5 -ddp@1.2.5 -ddp-client@1.3.3 -ddp-common@1.2.8 -ddp-server@1.3.13 -diff-sequence@1.0.7 -ecmascript@0.6.3 -ecmascript-runtime@0.3.15 -ejson@1.0.13 +allow-deny@1.1.0 +babel-compiler@7.6.0 +babel-runtime@1.5.0 +base64@1.0.12 +binary-heap@1.0.11 +blaze-tools@1.1.0-beta.3 +boilerplate-generator@1.7.1 +callback-hook@1.3.0 +check@1.3.1 +ddp@1.4.0 +ddp-client@2.4.0 +ddp-common@1.4.0 +ddp-server@2.3.2 +diff-sequence@1.1.1 +dynamic-import@0.6.0 +ecmascript@0.15.0 +ecmascript-runtime@0.7.0 +ecmascript-runtime-client@0.11.0 +ecmascript-runtime-server@0.10.0 +ejson@1.1.1 +fetch@0.1.1 geojson-utils@1.0.10 -html-tools@1.0.11 -htmljs@1.0.11 -id-map@1.0.9 -jquery@1.11.10 -local-test:blaze-tools@1.0.10 -logging@1.1.17 -meteor@1.6.1 -minimongo@1.0.21 -modules@0.7.9 -modules-runtime@0.7.9 -mongo@1.1.16 -mongo-id@1.0.6 -npm-mongo@2.2.24 -observe-sequence@1.0.16 -ordered-dict@1.0.9 -promise@0.8.8 -random@1.0.10 -reactive-var@1.0.11 -retry@1.0.9 -routepolicy@1.0.12 -spacebars@1.0.15 -spacebars-compiler@1.1.2 -tinytest@1.0.12 -tracker@1.1.2 -ui@1.0.12 +html-tools@1.1.0-beta.3 +htmljs@1.1.0-beta.3 +id-map@1.1.0 +inter-process-messaging@0.1.1 +local-test:blaze-tools@1.1.0-beta.3 +logging@1.2.0 +meteor@1.9.3 +minimongo@1.6.1 +modern-browsers@0.1.5 +modules@0.16.0 +modules-runtime@0.12.0 +mongo@1.10.1 +mongo-decimal@0.1.2 +mongo-dev-server@1.1.0 +mongo-id@1.0.7 +npm-mongo@3.8.1 +ordered-dict@1.1.0 +promise@0.11.2 +random@1.2.0 +react-fast-refresh@0.1.0 +reload@1.3.1 +retry@1.1.0 +routepolicy@1.1.0 +socket-stream-client@0.3.1 +tinytest@1.1.0 +tracker@1.2.0 underscore@1.0.10 -webapp@1.3.14 -webapp-hashing@1.0.9 +webapp@1.10.0 +webapp-hashing@1.1.0 diff --git a/packages/blaze-tools/package.js b/packages/blaze-tools/package.js index 77503f8e7..bca22bfcf 100644 --- a/packages/blaze-tools/package.js +++ b/packages/blaze-tools/package.js @@ -1,30 +1,23 @@ Package.describe({ name: 'blaze-tools', summary: "Compile-time tools for Blaze", - version: '1.0.10', + version: '1.1.0-beta.3', git: 'https://github.com/meteor/blaze.git' }); Package.onUse(function (api) { - api.use('underscore@1.0.9'); + api.use('ecmascript@0.14.4'); + api.use('htmljs@1.1.0-beta.3'); - api.export('BlazeTools'); - - api.use('htmljs@1.0.11'); - - api.addFiles([ - 'preamble.js', - 'tokens.js', - 'tojs.js' - ]); + api.mainModule('preamble.js'); }); Package.onTest(function (api) { api.use('tinytest@1.0.11'); - api.use('underscore@1.0.9'); + api.use('ecmascript'); api.use('blaze-tools'); - api.use('html-tools@1.0.11'); + api.use('html-tools@1.1.0-beta.3'); api.addFiles([ 'token_tests.js' diff --git a/packages/blaze-tools/preamble.js b/packages/blaze-tools/preamble.js index 2211e646a..0ea86ee21 100644 --- a/packages/blaze-tools/preamble.js +++ b/packages/blaze-tools/preamble.js @@ -1 +1,27 @@ -BlazeTools = {}; + +import { + EmitCode, + toJSLiteral, + toObjectLiteralKey, + ToJSVisitor, + toJS +} from './tojs'; + +import { + parseNumber, + parseIdentifierName, + parseExtendedIdentifierName, + parseStringLiteral +} from './tokens'; + +export const BlazeTools = { + EmitCode, + toJSLiteral, + toObjectLiteralKey, + ToJSVisitor, + toJS, + parseNumber, + parseIdentifierName, + parseExtendedIdentifierName, + parseStringLiteral +}; diff --git a/packages/blaze-tools/tojs.js b/packages/blaze-tools/tojs.js index 730dc24d5..d50bce98c 100644 --- a/packages/blaze-tools/tojs.js +++ b/packages/blaze-tools/tojs.js @@ -1,50 +1,51 @@ +import { HTML } from 'meteor/htmljs'; -BlazeTools.EmitCode = function (value) { - if (! (this instanceof BlazeTools.EmitCode)) + +export function EmitCode (value) { + if (! (this instanceof EmitCode)) // called without `new` - return new BlazeTools.EmitCode(value); + return new EmitCode(value); if (typeof value !== 'string') - throw new Error('BlazeTools.EmitCode must be constructed with a string'); + throw new Error('EmitCode must be constructed with a string'); this.value = value; -}; -BlazeTools.EmitCode.prototype.toJS = function (visitor) { +} + +EmitCode.prototype.toJS = function (visitor) { return this.value; }; // Turns any JSONable value into a JavaScript literal. -toJSLiteral = function (obj) { +export function toJSLiteral (obj) { // See for `\u2028\u2029`. // Also escape Unicode surrogates. return (JSON.stringify(obj) .replace(/[\u2028\u2029\ud800-\udfff]/g, function (c) { return '\\u' + ('000' + c.charCodeAt(0).toString(16)).slice(-4); })); -}; -BlazeTools.toJSLiteral = toJSLiteral; +} var jsReservedWordSet = (function (set) { - _.each("abstract else instanceof super boolean enum int switch break export interface synchronized byte extends let this case false long throw catch final native throws char finally new transient class float null true const for package try continue function private typeof debugger goto protected var default if public void delete implements return volatile do import short while double in static with".split(' '), function (w) { + "abstract else instanceof super boolean enum int switch break export interface synchronized byte extends let this case false long throw catch final native throws char finally new transient class float null true const for package try continue function private typeof debugger goto protected var default if public void delete implements return volatile do import short while double in static with".split(' ').forEach(function (w) { set[w] = 1; }); return set; })({}); -toObjectLiteralKey = function (k) { +export function toObjectLiteralKey (k) { if (/^[a-zA-Z$_][a-zA-Z$0-9_]*$/.test(k) && jsReservedWordSet[k] !== 1) return k; return toJSLiteral(k); -}; -BlazeTools.toObjectLiteralKey = toObjectLiteralKey; +} var hasToJS = function (x) { return x.toJS && (typeof (x.toJS) === 'function'); }; -ToJSVisitor = HTML.Visitor.extend(); +export const ToJSVisitor = HTML.Visitor.extend(); ToJSVisitor.def({ visitNull: function (nullOrUndefined) { return 'null'; @@ -149,8 +150,7 @@ ToJSVisitor.def({ return null; } }); -BlazeTools.ToJSVisitor = ToJSVisitor; -BlazeTools.toJS = function (content) { +export function toJS (content) { return (new ToJSVisitor).visit(content); -}; +} diff --git a/packages/blaze-tools/token_tests.js b/packages/blaze-tools/token_tests.js index 91aa8bd36..530be1dd3 100644 --- a/packages/blaze-tools/token_tests.js +++ b/packages/blaze-tools/token_tests.js @@ -1,3 +1,6 @@ +import { BlazeTools } from 'meteor/blaze-tools'; +import { HTMLTools } from 'meteor/html-tools'; + Tinytest.add("blaze-tools - token parsers", function (test) { var run = function (func, input, expected) { @@ -40,7 +43,7 @@ Tinytest.add("blaze-tools - token parsers", function (test) { runValue(parseNumber, "-0xa", -10); runValue(parseNumber, "1e+1", 10); - _.each([parseIdentifierName, parseExtendedIdentifierName], function (f) { + [parseIdentifierName, parseExtendedIdentifierName].forEach(function (f) { run(f, "a", "a"); run(f, "true", "true"); run(f, "null", "null"); diff --git a/packages/blaze-tools/tokens.js b/packages/blaze-tools/tokens.js index 441d070fb..3f13d6793 100644 --- a/packages/blaze-tools/tokens.js +++ b/packages/blaze-tools/tokens.js @@ -52,7 +52,7 @@ var rLineContinuation = /^\\(\r\n|[\u000A\u000D\u2028\u2029])/; -BlazeTools.parseNumber = function (scanner) { +export function parseNumber (scanner) { var startPos = scanner.pos; var isNegative = false; @@ -75,9 +75,9 @@ BlazeTools.parseNumber = function (scanner) { var value = Number(matchText); value = (isNegative ? -value : value); return { text: text, value: value }; -}; +} -BlazeTools.parseIdentifierName = function (scanner) { +export function parseIdentifierName (scanner) { var startPos = scanner.pos; var rest = scanner.rest(); var match = rIdentifierPrefix.exec(rest); @@ -106,13 +106,13 @@ BlazeTools.parseIdentifierName = function (scanner) { } return scanner.input.substring(startPos, scanner.pos); -}; +} -BlazeTools.parseExtendedIdentifierName = function (scanner) { +export function parseExtendedIdentifierName (scanner) { // parse an identifier name optionally preceded by '@' if (scanner.peek() === '@') { scanner.pos++; - var afterAt = BlazeTools.parseIdentifierName(scanner); + var afterAt = parseIdentifierName(scanner); if (afterAt) { return '@' + afterAt; } else { @@ -120,11 +120,11 @@ BlazeTools.parseExtendedIdentifierName = function (scanner) { return null; } } else { - return BlazeTools.parseIdentifierName(scanner); + return parseIdentifierName(scanner); } -}; +} -BlazeTools.parseStringLiteral = function (scanner) { +export function parseStringLiteral (scanner) { var startPos = scanner.pos; var rest = scanner.rest(); var match = rStringQuote.exec(rest); @@ -190,4 +190,4 @@ BlazeTools.parseStringLiteral = function (scanner) { var text = scanner.input.substring(startPos, scanner.pos); var value = JSON.parse(jsonLiteral); return { text: text, value: value }; -}; +} diff --git a/packages/blaze/.versions b/packages/blaze/.versions index 43143a22c..9c858935c 100644 --- a/packages/blaze/.versions +++ b/packages/blaze/.versions @@ -1,64 +1,64 @@ allow-deny@1.1.0 -babel-compiler@7.4.1 -babel-runtime@1.4.0 +babel-compiler@7.6.0 +babel-runtime@1.5.0 base64@1.0.12 binary-heap@1.0.11 -blaze@2.3.4 -blaze-tools@1.0.10 -boilerplate-generator@1.6.0 -caching-compiler@1.2.1 +blaze@2.4.0-beta.3 +blaze-tools@1.1.0-beta.3 +boilerplate-generator@1.7.1 +caching-compiler@1.2.2 caching-html-compiler@1.1.2 -callback-hook@1.2.0 +callback-hook@1.3.0 check@1.3.1 ddp@1.4.0 -ddp-client@2.3.3 +ddp-client@2.4.0 ddp-common@1.4.0 -ddp-server@2.3.0 -deps@1.0.12 +ddp-server@2.3.2 diff-sequence@1.1.1 -dynamic-import@0.5.1 -ecmascript@0.13.0 +dynamic-import@0.6.0 +ecmascript@0.15.0 ecmascript-runtime@0.7.0 -ecmascript-runtime-client@0.9.0 -ecmascript-runtime-server@0.8.0 -ejson@1.1.0 +ecmascript-runtime-client@0.11.0 +ecmascript-runtime-server@0.10.0 +ejson@1.1.1 fetch@0.1.1 geojson-utils@1.0.10 -html-tools@1.0.11 -htmljs@1.0.11 +html-tools@1.1.0-beta.3 +htmljs@1.1.0-beta.3 id-map@1.1.0 -inter-process-messaging@0.1.0 +inter-process-messaging@0.1.1 jquery@1.11.10 -local-test:blaze@2.3.4 -logging@1.1.20 +local-test:blaze@2.4.0-beta.3 +logging@1.2.0 meteor@1.9.3 -minimongo@1.4.5 -modern-browsers@0.1.4 -modules@0.14.0 -modules-runtime@0.11.0 -mongo@1.7.0 -mongo-decimal@0.1.1 +minimongo@1.6.1 +modern-browsers@0.1.5 +modules@0.16.0 +modules-runtime@0.12.0 +mongo@1.10.1 +mongo-decimal@0.1.2 mongo-dev-server@1.1.0 mongo-id@1.0.7 -npm-mongo@3.2.0 +npm-mongo@3.8.1 observe-sequence@1.0.16 ordered-dict@1.1.0 promise@0.11.2 -random@1.1.0 +random@1.2.0 +react-fast-refresh@0.1.0 reactive-var@1.0.11 -reload@1.3.0 +reload@1.3.1 retry@1.1.0 routepolicy@1.1.0 -socket-stream-client@0.2.2 +socket-stream-client@0.3.1 spacebars@1.0.15 spacebars-compiler@1.1.2 templating@1.3.2 templating-compiler@1.3.2 templating-runtime@1.3.2 templating-tools@1.1.2 -test-helpers@1.1.0 +test-helpers@1.2.0 tinytest@1.1.0 tracker@1.2.0 underscore@1.0.10 -webapp@1.7.5 -webapp-hashing@1.0.9 +webapp@1.10.0 +webapp-hashing@1.1.0 diff --git a/packages/blaze/builtins.js b/packages/blaze/builtins.js index 18e165c09..21fcd21eb 100644 --- a/packages/blaze/builtins.js +++ b/packages/blaze/builtins.js @@ -1,5 +1,5 @@ Blaze._calculateCondition = function (cond) { - if (cond instanceof Array && cond.length === 0) + if (HTML.isArray(cond) && cond.length === 0) cond = false; return !! cond; }; diff --git a/packages/blaze/package.js b/packages/blaze/package.js index 7c5d4be2f..39bfc6e35 100644 --- a/packages/blaze/package.js +++ b/packages/blaze/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'blaze', summary: "Meteor Reactive Templating library", - version: '2.3.4', + version: '2.4.0-beta.3', git: 'https://github.com/meteor/blaze.git' }); @@ -13,7 +13,7 @@ Package.onUse(function (api) { api.use('observe-sequence@1.0.12'); api.use('reactive-var@1.0.10'); api.use('ordered-dict@1.0.9'); - api.use('ecmascript@0.12.7'); + api.use('ecmascript@0.14.4'); api.export([ 'Blaze', @@ -21,8 +21,8 @@ Package.onUse(function (api) { 'Handlebars' ]); - api.use('htmljs@1.0.11'); - api.imply('htmljs@1.0.11'); + api.use('htmljs@1.1.0-beta.3'); + api.imply('htmljs@1.1.0-beta.3'); api.addFiles([ 'preamble.js' @@ -49,6 +49,7 @@ Package.onUse(function (api) { }); Package.onTest(function (api) { + api.use('ecmascript@0.14.4') api.use('tinytest@1.0.11'); api.use('test-helpers@1.0.10'); api.use('jquery@1.11.9 || 3.0.0'); // strong dependency, for testing jQuery backend @@ -57,9 +58,9 @@ Package.onTest(function (api) { api.use('tracker@1.1.0'); api.use('blaze'); - api.use('blaze-tools@1.0.10'); // for BlazeTools.toJS - api.use('html-tools@1.0.11'); - api.use('templating@1.3.2'); + api.use('blaze-tools@1.1.0-beta.3'); // for BlazeTools.toJS + api.use('html-tools@1.1.0-beta.3'); + api.use('templating'); api.addFiles('view_tests.js'); api.addFiles('render_tests.js', 'client'); diff --git a/packages/blaze/render_tests.js b/packages/blaze/render_tests.js index b23bb06eb..0802d8e4d 100644 --- a/packages/blaze/render_tests.js +++ b/packages/blaze/render_tests.js @@ -1,3 +1,5 @@ +import { BlazeTools } from 'meteor/blaze-tools'; + var toCode = BlazeTools.toJS; var P = HTML.P; diff --git a/packages/blaze/view.js b/packages/blaze/view.js index 50d7712ce..4cbdea531 100644 --- a/packages/blaze/view.js +++ b/packages/blaze/view.js @@ -598,6 +598,8 @@ var contentAsFunc = function (content) { } }; +Blaze.__rootViews = []; + /** * @summary Renders a template or View to DOM nodes and inserts it into the DOM, returning a rendered [View](#Blaze-View) which can be passed to [`Blaze.remove`](#Blaze-remove). * @locus Client @@ -629,8 +631,22 @@ Blaze.render = function (content, parentElement, nextNode, parentView) { parentView = parentView || currentViewIfRendering(); var view = contentAsView(content); - Blaze._materializeView(view, parentView); + // TODO: this is only needed in development + if (!parentView) { + view.onViewCreated(function () { + Blaze.__rootViews.push(view); + }); + + view.onViewDestroyed(function () { + var index = Blaze.__rootViews.indexOf(view); + if (index > -1) { + Blaze.__rootViews.splice(index, 1); + } + }); + } + + Blaze._materializeView(view, parentView); if (parentElement) { view._domrange.attach(parentElement, nextNode); } diff --git a/packages/caching-html-compiler/.versions b/packages/caching-html-compiler/.versions index 0df18c817..392f1632d 100644 --- a/packages/caching-html-compiler/.versions +++ b/packages/caching-html-compiler/.versions @@ -1,18 +1,24 @@ -babel-compiler@6.14.1 -babel-runtime@1.0.1 -blaze-tools@1.0.10 -caching-compiler@1.1.9 -caching-html-compiler@1.1.2 -ecmascript@0.6.3 -ecmascript-runtime@0.3.15 -html-tools@1.0.11 -htmljs@1.0.11 -meteor@1.6.1 -modules@0.7.9 -modules-runtime@0.7.9 -promise@0.8.8 -random@1.0.10 -spacebars-compiler@1.1.2 -templating-tools@1.1.2 -tracker@1.1.2 +babel-compiler@7.6.0 +babel-runtime@1.5.0 +blaze-tools@1.1.0-beta.3 +caching-compiler@1.2.2 +caching-html-compiler@1.2.0-beta.3 +dynamic-import@0.6.0 +ecmascript@0.15.0 +ecmascript-runtime@0.7.0 +ecmascript-runtime-client@0.11.0 +ecmascript-runtime-server@0.10.0 +fetch@0.1.1 +html-tools@1.1.0-beta.3 +htmljs@1.1.0-beta.3 +inter-process-messaging@0.1.1 +meteor@1.9.3 +modern-browsers@0.1.5 +modules@0.16.0 +modules-runtime@0.12.0 +promise@0.11.2 +random@1.2.0 +react-fast-refresh@0.1.0 +spacebars-compiler@1.2.0-beta.3 +templating-tools@1.2.0-beta.3 underscore@1.0.10 diff --git a/packages/caching-html-compiler/caching-html-compiler.js b/packages/caching-html-compiler/caching-html-compiler.js index f4819b324..e6e25c0a5 100644 --- a/packages/caching-html-compiler/caching-html-compiler.js +++ b/packages/caching-html-compiler/caching-html-compiler.js @@ -47,6 +47,7 @@ CachingHtmlCompiler = class CachingHtmlCompiler extends CachingCompiler { return [ inputFile.getArch(), inputFile.getSourceHash(), + inputFile.hmrAvailable && inputFile.hmrAvailable() ]; } @@ -61,7 +62,7 @@ CachingHtmlCompiler = class CachingHtmlCompiler extends CachingCompiler { tagNames: ["body", "head", "template"] }); - return this.tagHandlerFunc(tags); + return this.tagHandlerFunc(tags, inputFile.hmrAvailable && inputFile.hmrAvailable()); } catch (e) { if (e instanceof TemplatingTools.CompileError) { inputFile.error({ diff --git a/packages/caching-html-compiler/package.js b/packages/caching-html-compiler/package.js index 850a81def..583477dad 100644 --- a/packages/caching-html-compiler/package.js +++ b/packages/caching-html-compiler/package.js @@ -1,7 +1,7 @@ Package.describe({ name: 'caching-html-compiler', summary: "Pluggable class for compiling HTML into templates", - version: '1.1.3', + version: '1.2.0-beta.3', git: 'https://github.com/meteor/blaze.git' }); @@ -9,13 +9,13 @@ Package.onUse(function(api) { api.use([ 'underscore@1.0.9', 'caching-compiler@1.1.7', - 'ecmascript@0.5.8' + 'ecmascript@0.14.4' ]); api.export('CachingHtmlCompiler', 'server'); api.use([ - 'templating-tools@1.1.2' + 'templating-tools@1.2.0-beta.3' ]); api.addFiles([ diff --git a/packages/html-tools/.versions b/packages/html-tools/.versions index a9238181e..c7b70b1c2 100644 --- a/packages/html-tools/.versions +++ b/packages/html-tools/.versions @@ -1,47 +1,51 @@ -allow-deny@1.0.5 -babel-compiler@6.14.1 -babel-runtime@1.0.1 -base64@1.0.10 -binary-heap@1.0.10 -blaze@2.3.2 +allow-deny@1.1.0 +babel-compiler@7.6.0 +babel-runtime@1.5.0 +base64@1.0.12 +binary-heap@1.0.11 blaze-tools@1.0.10 -boilerplate-generator@1.0.11 -callback-hook@1.0.10 -check@1.2.5 -ddp@1.2.5 -ddp-client@1.3.3 -ddp-common@1.2.8 -ddp-server@1.3.13 -diff-sequence@1.0.7 -ecmascript@0.6.3 -ecmascript-runtime@0.3.15 -ejson@1.0.13 +boilerplate-generator@1.7.1 +callback-hook@1.3.0 +check@1.3.1 +ddp@1.4.0 +ddp-client@2.4.0 +ddp-common@1.4.0 +ddp-server@2.3.2 +diff-sequence@1.1.1 +dynamic-import@0.6.0 +ecmascript@0.15.0 +ecmascript-runtime@0.7.0 +ecmascript-runtime-client@0.11.0 +ecmascript-runtime-server@0.10.0 +ejson@1.1.1 +fetch@0.1.1 geojson-utils@1.0.10 -html-tools@1.0.11 -htmljs@1.0.11 -id-map@1.0.9 -jquery@1.11.10 -local-test:html-tools@1.0.11 -logging@1.1.17 -meteor@1.6.1 -minimongo@1.0.21 -modules@0.7.9 -modules-runtime@0.7.9 -mongo@1.1.16 -mongo-id@1.0.6 -npm-mongo@2.2.24 -observe-sequence@1.0.16 -ordered-dict@1.0.9 -promise@0.8.8 -random@1.0.10 -reactive-var@1.0.11 -retry@1.0.9 -routepolicy@1.0.12 -spacebars@1.0.15 -spacebars-compiler@1.1.2 -tinytest@1.0.12 -tracker@1.1.2 -ui@1.0.12 +html-tools@1.1.0-beta.3 +htmljs@1.1.0-beta.3 +id-map@1.1.0 +inter-process-messaging@0.1.1 +local-test:html-tools@1.1.0-beta.3 +logging@1.2.0 +meteor@1.9.3 +minimongo@1.6.1 +modern-browsers@0.1.5 +modules@0.16.0 +modules-runtime@0.12.0 +mongo@1.10.1 +mongo-decimal@0.1.2 +mongo-dev-server@1.1.0 +mongo-id@1.0.7 +npm-mongo@3.8.1 +ordered-dict@1.1.0 +promise@0.11.2 +random@1.2.0 +react-fast-refresh@0.1.0 +reload@1.3.1 +retry@1.1.0 +routepolicy@1.1.0 +socket-stream-client@0.3.1 +tinytest@1.1.0 +tracker@1.2.0 underscore@1.0.10 -webapp@1.3.14 -webapp-hashing@1.0.9 +webapp@1.10.0 +webapp-hashing@1.1.0 diff --git a/packages/html-tools/charref.js b/packages/html-tools/charref.js index ff437ee8b..c0725abb0 100644 --- a/packages/html-tools/charref.js +++ b/packages/html-tools/charref.js @@ -1,3 +1,4 @@ +import { makeRegexMatcher } from './scanner'; // http://www.whatwg.org/specs/web-apps/current-work/multipage/entities.json @@ -2360,7 +2361,7 @@ var isLegalCodepoint = function (cp) { // either `"`, `'`, or `>` and is supplied when parsing attribute values. NOTE: In the current spec, the // value of `allowedChar` doesn't actually seem to end up mattering, but there is still some debate about // the right approach to ampersands. -getCharacterReference = HTMLTools.Parse.getCharacterReference = function (scanner, inAttribute, allowedChar) { +export function getCharacterReference (scanner, inAttribute, allowedChar) { if (scanner.peek() !== '&') // no ampersand return null; @@ -2411,4 +2412,4 @@ getCharacterReference = HTMLTools.Parse.getCharacterReference = function (scanne return null; } } -}; +} diff --git a/packages/html-tools/charref_tests.js b/packages/html-tools/charref_tests.js index 35a991aeb..2c7d555ad 100644 --- a/packages/html-tools/charref_tests.js +++ b/packages/html-tools/charref_tests.js @@ -1,3 +1,5 @@ +import { HTMLTools } from 'meteor/html-tools'; + var Scanner = HTMLTools.Scanner; var getCharacterReference = HTMLTools.Parse.getCharacterReference; @@ -19,7 +21,7 @@ Tinytest.add("html-tools - entities", function (test) { test.equal(result, { t: 'CharRef', v: match, - cp: _.map(codepoints, + cp: codepoints.map( function (x) { return (typeof x === 'string' ? x.charCodeAt(0) : x); }) }); diff --git a/packages/html-tools/main.js b/packages/html-tools/main.js new file mode 100644 index 000000000..1221313c2 --- /dev/null +++ b/packages/html-tools/main.js @@ -0,0 +1,27 @@ + +import { getCharacterReference } from './charref'; +import { asciiLowerCase, properCaseTagName, properCaseAttributeName} from "./utils"; +import { TemplateTag } from './templatetag' +import { Scanner } from './scanner'; +import { parseFragment, codePointToString, getContent, getRCData } from './parse'; +import { getComment, getDoctype, getHTMLToken, getTagToken, TEMPLATE_TAG_POSITION } from './tokenize'; + +export const HTMLTools = { + asciiLowerCase, + properCaseTagName, + properCaseAttributeName, + TemplateTag, + Scanner, + parseFragment, + codePointToString, + TEMPLATE_TAG_POSITION, + Parse: { + getCharacterReference, + getContent, + getRCData, + getComment, + getDoctype, + getHTMLToken, + getTagToken, + } +}; diff --git a/packages/html-tools/package.js b/packages/html-tools/package.js index 75f84bc1b..39565221f 100644 --- a/packages/html-tools/package.js +++ b/packages/html-tools/package.js @@ -1,33 +1,25 @@ Package.describe({ name: 'html-tools', summary: "Standards-compliant HTML tools", - version: '1.0.11', + version: '1.1.0-beta.3', git: 'https://github.com/meteor/blaze.git' }); Package.onUse(function (api) { - api.export('HTMLTools'); + api.use('ecmascript@0.14.4'); + api.use('htmljs@1.1.0-beta.3'); + api.imply('htmljs@1.1.0-beta.3'); - api.use('htmljs@1.0.11'); - api.imply('htmljs@1.0.11'); - - api.addFiles([ - 'utils.js', - 'scanner.js', - 'charref.js', - 'tokenize.js', - 'templatetag.js', - 'parse.js' - ]); + api.mainModule('main.js'); }); Package.onTest(function (api) { + api.use('ecmascript'); api.use('tinytest@1.0.11'); - api.use('underscore@1.0.9'); api.use('html-tools'); - api.use('htmljs@1.0.11'); - api.use('blaze-tools@1.0.10'); // for `toJS` + api.use('htmljs@1.1.0-beta.3'); + api.use('blaze-tools'); // for `toJS` api.addFiles([ 'charref_tests.js', diff --git a/packages/html-tools/parse.js b/packages/html-tools/parse.js index 109e9fa2f..248b1ab3c 100644 --- a/packages/html-tools/parse.js +++ b/packages/html-tools/parse.js @@ -1,7 +1,11 @@ +import { HTML } from 'meteor/htmljs'; +import { Scanner } from './scanner'; +import { properCaseAttributeName } from './utils'; +import { getHTMLToken, isLookingAtEndTag } from './tokenize'; // Parse a "fragment" of HTML, up to the end of the input or a particular // template tag (using the "shouldStop" option). -HTMLTools.parseFragment = function (input, options) { +export function parseFragment(input, options) { var scanner; if (typeof input === 'string') scanner = new Scanner(input); @@ -69,14 +73,14 @@ HTMLTools.parseFragment = function (input, options) { } return result; -}; +} // Take a numeric Unicode code point, which may be larger than 16 bits, // and encode it as a JavaScript UTF-16 string. // // Adapted from // http://stackoverflow.com/questions/7126384/expressing-utf-16-unicode-characters-in-javascript/7126661. -codePointToString = HTMLTools.codePointToString = function(cp) { +export function codePointToString(cp) { if (cp >= 0 && cp <= 0xD7FF || cp >= 0xE000 && cp <= 0xFFFF) { return String.fromCharCode(cp); } else if (cp >= 0x10000 && cp <= 0x10FFFF) { @@ -97,9 +101,9 @@ codePointToString = HTMLTools.codePointToString = function(cp) { } else { return ''; } -}; +} -getContent = HTMLTools.Parse.getContent = function (scanner, shouldStopFunc) { +export function getContent (scanner, shouldStopFunc) { var items = []; while (! scanner.isEOF()) { @@ -187,7 +191,7 @@ getContent = HTMLTools.Parse.getContent = function (scanner, shouldStopFunc) { // as in `FOO.apply(null, content)`. if (content == null) content = []; - else if (! (content instanceof Array)) + else if (! HTML.isArray(content)) content = [content]; items.push(HTML.getTag(tagName).apply( @@ -204,7 +208,7 @@ getContent = HTMLTools.Parse.getContent = function (scanner, shouldStopFunc) { return items[0]; else return items; -}; +} var pushOrAppendString = function (items, string) { if (items.length && @@ -215,7 +219,7 @@ var pushOrAppendString = function (items, string) { }; // get RCDATA to go in the lowercase (or camel case) tagName (e.g. "textarea") -getRCData = HTMLTools.Parse.getRCData = function (scanner, tagName, shouldStopFunc) { +export function getRCData(scanner, tagName, shouldStopFunc) { var items = []; while (! scanner.isEOF()) { @@ -250,7 +254,7 @@ getRCData = HTMLTools.Parse.getRCData = function (scanner, tagName, shouldStopFu return items[0]; else return items; -}; +} var getRawText = function (scanner, tagName, shouldStopFunc) { var items = []; @@ -350,7 +354,7 @@ var parseAttrs = function (attrs) { var outValue = (inValue.length === 0 ? '' : (outParts.length === 1 ? outParts[0] : outParts)); - var properKey = HTMLTools.properCaseAttributeName(k); + var properKey = properCaseAttributeName(k); result[properKey] = outValue; } diff --git a/packages/html-tools/parse_tests.js b/packages/html-tools/parse_tests.js index 3bc69be8c..5029b6714 100644 --- a/packages/html-tools/parse_tests.js +++ b/packages/html-tools/parse_tests.js @@ -1,3 +1,7 @@ +import { HTML } from 'meteor/htmljs'; +import { HTMLTools } from 'meteor/html-tools'; +import { BlazeTools} from 'meteor/blaze-tools'; + var Scanner = HTMLTools.Scanner; var getContent = HTMLTools.Parse.getContent; @@ -190,8 +194,8 @@ Tinytest.add("html-tools - parseFragment", function (test) { test.equal(BlazeTools.toJS(HTMLTools.parseFragment("

Hello

")), BlazeTools.toJS(DIV(P({id:'foo'}, 'Hello')))); - _.each(['asdf
', '{{!foo}}
', '{{!foo}}
', - 'asdf', '{{!foo}}', '{{!foo}} '], function (badFrag) { + ['asdf
', '{{!foo}}
', '{{!foo}}
', + 'asdf', '{{!foo}}', '{{!foo}} '].forEach(function (badFrag) { test.throws(function() { HTMLTools.parseFragment(badFrag); }, /Unexpected HTML close tag/); diff --git a/packages/html-tools/scanner.js b/packages/html-tools/scanner.js index d110a8a81..6f1b51726 100644 --- a/packages/html-tools/scanner.js +++ b/packages/html-tools/scanner.js @@ -9,10 +9,10 @@ // * `scanner.isEOF()` - true if `pos` is at or beyond the end of `input` // * `scanner.fatal(msg)` - throw an error indicating a problem at `pos` -Scanner = HTMLTools.Scanner = function (input) { +export function Scanner (input) { this.input = input; // public, read-only this.pos = 0; // public, read-write -}; +} Scanner.prototype.rest = function () { // Slicing a string is O(1) in modern JavaScript VMs (including old IE). @@ -69,7 +69,7 @@ Scanner.prototype.peek = function () { // the current position of the scanner is advanced. If it fails, the // current position is not advanced and a falsy value (typically null) // is returned. -makeRegexMatcher = function (regex) { +export function makeRegexMatcher(regex) { return function (scanner) { var match = regex.exec(scanner.rest()); @@ -79,4 +79,4 @@ makeRegexMatcher = function (regex) { scanner.pos += match[0].length; return match[1] || match[0]; }; -}; +} diff --git a/packages/html-tools/templatetag.js b/packages/html-tools/templatetag.js index f94f9fd21..3bc952db7 100644 --- a/packages/html-tools/templatetag.js +++ b/packages/html-tools/templatetag.js @@ -11,17 +11,17 @@ var _assign = function (tgt, src) { }; -HTMLTools.TemplateTag = function (props) { - if (! (this instanceof HTMLTools.TemplateTag)) +export function TemplateTag (props) { + if (! (this instanceof TemplateTag)) // called without `new` - return new HTMLTools.TemplateTag; + return new TemplateTag; if (props) _assign(this, props); -}; +} -_assign(HTMLTools.TemplateTag.prototype, { - constructorName: 'HTMLTools.TemplateTag', +_assign(TemplateTag.prototype, { + constructorName: 'TemplateTag', toJS: function (visitor) { return visitor.generateCall(this.constructorName, _assign({}, this)); diff --git a/packages/html-tools/tokenize.js b/packages/html-tools/tokenize.js index de0b9c066..55cbd3ecf 100644 --- a/packages/html-tools/tokenize.js +++ b/packages/html-tools/tokenize.js @@ -1,3 +1,8 @@ +import { asciiLowerCase, properCaseTagName, properCaseAttributeName } from './utils'; +import { TemplateTag } from './templatetag'; +import { getCharacterReference } from './charref'; +import { makeRegexMatcher } from './scanner'; + // Token types: // // { t: 'Doctype', @@ -54,7 +59,7 @@ var convertCRLF = function (str) { return str.replace(/\r\n?/g, '\n'); }; -getComment = HTMLTools.Parse.getComment = function (scanner) { +export function getComment (scanner) { if (scanner.rest().slice(0, 4) !== '