Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 2.4 #323

Merged
merged 53 commits into from
Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
af23413
Fix HTML.isArray to work across frames.
brucejo75 Dec 11, 2017
e503814
Use HTML.isArray where appropriate.
brucejo75 Dec 21, 2017
e0f4b56
use lodash.isPlainObject technique to determine if object is a plain …
brucejo75 Dec 21, 2017
2acf08c
Added one other case...
brucejo75 Dec 21, 2017
245a586
Add basic HMR integration to Blaze
zodern Jan 14, 2021
5489299
Bumps version to prepare for Blaze HMR release
filipenevola Jan 17, 2021
3d9fe24
Fix cache key
zodern Jan 18, 2021
3433c8b
Bumps version to prepare for Blaze HMR release
filipenevola Jan 18, 2021
1e869e3
Bumps version to prepare for Blaze HMR release - beta.1
filipenevola Jan 20, 2021
63be737
Bumps version to prepare for Blaze HMR release - beta.1
filipenevola Jan 20, 2021
6270bab
Add _applyHmrChanges and _migrateTemplate to reserved names
zodern Feb 26, 2021
3a632ac
Improve simple HMR integration
zodern Feb 26, 2021
6a68baf
Fix replacing body render functions
zodern Feb 26, 2021
dc1f906
Replace the specific views updated by HMR
zodern Feb 26, 2021
cfe8f31
Preserve dom location of root views
zodern Feb 26, 2021
91d9653
Fix updating root views with custom content blocks
zodern Feb 26, 2021
173fe47
Remove unused code
zodern Feb 26, 2021
cd912fc
Update the specific templates that were affected
zodern Mar 4, 2021
9bdddc8
Fix detecting duplicate templates
zodern Mar 4, 2021
e078164
Recover from errors in HMR update
zodern Mar 4, 2021
d96e105
Update after template is removed
zodern Mar 4, 2021
977fbaf
Handle errors while updating template
zodern Mar 4, 2021
c73b59f
Bumps version to prepare for Blaze HMR release - beta.2
filipenevola Mar 15, 2021
ce76ab6
Bumps version to prepare for Blaze HMR release - beta.2
filipenevola Mar 15, 2021
d0d76a3
Merge branch 'master' into hot-module-replacement
filipenevola Mar 18, 2021
043b66f
Merge branch 'master' into hot-module-replacement
filipenevola Mar 18, 2021
35941eb
spacebars: Add test for compilation within block helpers
nathan-muir Feb 9, 2018
ffae1b1
spacebars: Fix compiler optimisation within block tags
nathan-muir Feb 9, 2018
d1895a1
spacebars: Add test for compilation within nested elements
nathan-muir Feb 9, 2018
81f3de0
spacebars: Fix compiler optimisation within nested elements
nathan-muir Feb 9, 2018
b0cffc6
spacebars: Add test for compilation within tables
nathan-muir Feb 9, 2018
940c73e
spacebars: Allow partial optimisation within table's
nathan-muir Feb 9, 2018
1835f39
Merge branch 'master' into HTML_isArray_cross_frame
brucejo75 Mar 19, 2021
4ce1f30
Merge pull request #276 from brucejo75/HTML_isArray_cross_frame
filipenevola Mar 19, 2021
283665b
Merge branch 'master' into release-2.4
filipenevola Mar 19, 2021
735f525
Merge pull request #319 from 3stack-software/spacebars-compiler-optim…
filipenevola Mar 19, 2021
0dd78c9
Add missing dependency
zodern Mar 19, 2021
080f327
Merge branch 'master' into hot-module-replacement
filipenevola Mar 20, 2021
c66364f
Merge branch 'release-2.4' into hot-module-replacement
filipenevola Mar 20, 2021
08a8e16
Merge pull request #313 from meteor/hot-module-replacement
filipenevola Mar 20, 2021
ed9299e
modernize htmljs, html-tools, blaze-tools, spacebars-compiler & templ…
nathan-muir Mar 22, 2021
a0dde2c
add directive to extra whitespace from templates
nathan-muir Mar 22, 2021
5fa8383
Merge pull request #321 from 3stack-software/nm-modernize
filipenevola Mar 22, 2021
f89a52d
Merge pull request #324 from 3stack-software/spacebars-strip-whitespace
filipenevola Mar 22, 2021
0a4b0f7
History comment on PR #276
brucejo75 Mar 22, 2021
13f10d0
Merge branch 'master' into history-276
filipenevola Mar 24, 2021
12dfc18
Merge pull request #325 from brucejo75/history-276
filipenevola Mar 24, 2021
f9a033b
Update History
filipenevola Mar 24, 2021
9fd2769
Remove deprecated ui package
filipenevola Mar 24, 2021
540437a
Remove deprecated ui package - update history
filipenevola Mar 24, 2021
e8e2fe2
Merge pull request #326 from meteor/remove-deprecated-ui-package
filipenevola Mar 24, 2021
05ee63f
Bumps version to prepare for Blaze HMR release - beta.3
filipenevola Mar 24, 2021
80fbd1d
Update HISTORY.md
filipenevola Mar 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
140 changes: 140 additions & 0 deletions packages/blaze-hot/hot.js
Original file line number Diff line number Diff line change
@@ -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
}
});
}
20 changes: 20 additions & 0 deletions packages/blaze-hot/package.js
Original file line number Diff line number Diff line change
@@ -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');
});
164 changes: 164 additions & 0 deletions packages/blaze-hot/update-templates.js
Original file line number Diff line number Diff line change
@@ -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);
}
}
});
});
}
Loading