Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
save per-delegate binding map, to avoid excess parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelw committed Apr 10, 2014
1 parent 9dc4c42 commit 180e4b5
Showing 1 changed file with 40 additions and 11 deletions.
51 changes: 40 additions & 11 deletions src/TemplateBinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,16 +514,7 @@
if (content.firstChild === null)
return emptyInstance;

var map = this.bindingMap_;
if (!map || map.content !== content) {
// TODO(rafaelw): Setup a MutationObserver on content to detect
// when the instanceMap is invalid.
map = createInstanceBindingMap(content,
delegate_ && delegate_.prepareBinding) || [];
map.content = content;
this.bindingMap_ = map;
}

var map = getInstanceBindingMap(content, delegate_);
var stagingDocument = getTemplateStagingDocument(this);
var instance = stagingDocument.createDocumentFragment();
instance.templateCreator_ = this;
Expand Down Expand Up @@ -609,7 +600,7 @@

newDelegate_: function(bindingDelegate) {
if (!bindingDelegate)
return {};
return;

function delegateFn(name) {
var fn = bindingDelegate && bindingDelegate[name];
Expand All @@ -622,6 +613,7 @@
}

return {
bindingMaps: {},
raw: bindingDelegate,
prepareBinding: delegateFn('prepareBinding'),
prepareInstanceModel: delegateFn('prepareInstanceModel'),
Expand Down Expand Up @@ -911,6 +903,43 @@
return map;
}

var contentIdCounter = 1;

// TODO(rafaelw): Setup a MutationObserver on content which clears the id
// so that bindingMaps regenerate when the template.content changes.
function getContentId(content) {
var id = content.id_;
if (!id)
id = content.id_ = contentIdCounter++;
return id;
}

// Each delegate is associated with a set of bindingMaps, one for each
// content which may be used by a template. The intent is that each binding
// delegate gets the opportunity to prepare* the template content once
// across all uses.
// TODO(rafaelw): Separate out the parse map from the binding map. In the
// current implementation, if two delegates need a binding map for the same
// content, the second will have to reparse.
function getInstanceBindingMap(content, delegate_) {
var contentId = getContentId(content);
if (delegate_) {
var map = delegate_.bindingMaps[contentId];
if (!map) {
map = delegate_.bindingMaps[contentId] =
createInstanceBindingMap(content, delegate_.prepareBinding) || [];
}
return map;
}

var map = content.bindingMap_;
if (!map) {
map = content.bindingMap_ =
createInstanceBindingMap(content, undefined) || [];
}
return map;
}

Object.defineProperty(Node.prototype, 'templateInstance', {
get: function() {
var instance = this.templateInstance_;
Expand Down

0 comments on commit 180e4b5

Please sign in to comment.