Beispiel #1
0
		return function(scope, options){

			var computeValue = compute(function(){
				return renderer(scope, options);
			}, null, false);

			computeValue.computeInstance.addEventListener("change", noop);
			var value = computeValue();
			if( computeValue.computeInstance.hasDependencies ) {
				if(state.textContentOnly) {
					live.text(this, computeValue);
				}
				else if(state.attr) {
					live.attr(this, state.attr, computeValue);
				}
				else {
					live.attrs(this, computeValue, scope, options);
				}
				computeValue.computeInstance.removeEventListener("change", noop);
			} else {
				if(state.textContentOnly) {
					this.nodeValue = value;
				}
				else if(state.attr) {
					attr.set(this, state.attr, value);
				}
				else {
					live.attrs(this, value);
				}
			}
		};
Beispiel #2
0
		attribute: function (el, attributeName, compute) {
			var hook;
			listen(el, compute, function () {
				domAttr.set(el, attributeName, hook.render());
			});
			var hooks;
			// Get the list of hookups or create one for this element.
			// Hooks is a map of attribute names to hookup `data`s.
			// Each hookup data has:
			// `render` - A `function` to render the value of the attribute.
			// `funcs` - A list of hookup `function`s on that attribute.
			// `batchNum` - The last event `batchNum`, used for performance.
			hooks = domData.get.call(el, 'hooks');
			if (!hooks) {
				domData.set.call(el, 'hooks', hooks = {});
			}
			// Get the attribute value.
			// Cast to String. String expected for rendering. Attr may return other types for some attributes.
			var attr = String(domAttr.get(el, attributeName)),
				// Split the attribute value by the template.
				// Only split out the first __!!__ so if we have multiple hookups in the same attribute,
				// they will be put in the right spot on first render
				parts = attr.split(live.attributePlaceholder),
				goodParts = [];

			goodParts.push(parts.shift(), parts.join(live.attributePlaceholder));
			// If we already had a hookup for this attribute...
			if (hooks[attributeName]) {
				// Just add to that attribute's list of `function`s.
				hooks[attributeName].computes.push(compute);
			} else {
				// Create the hookup data.
				hooks[attributeName] = {
					render: function () {
						var i = 0,
							// attr doesn't have a value in IE
							newAttr = attr ? attr.replace(live.attributeReplace, function () {
								return view.contentText(hook.computes[i++]());
							}) : view.contentText(hook.computes[i++]());
						return newAttr;
					},
					computes: [compute],
					batchNum: undefined
				};
			}
			// Save the hook for slightly faster performance.
			hook = hooks[attributeName];
			// Insert the value in parts.
			goodParts.splice(1, 0, compute());

			// Set the attribute.
			domAttr.set(el, attributeName, goodParts.join(''));
		},
Beispiel #3
0
live.attrs = function(el, compute, scope, options) {
	if(!types.isCompute(compute)) {
		var attrs = live.getAttributeParts(compute);
		for(var name in attrs) {
			attr.set(el, name, attrs[name]);
		}
		return;
	}


	var oldAttrs = {};

	var setAttrs = function (newVal) {
		var newAttrs = live.getAttributeParts(newVal),
			name;
		for(name in newAttrs) {
			var newValue = newAttrs[name],
				oldValue = oldAttrs[name];
			if(newValue !== oldValue) {
				attr.set(el, name, newValue);
				var callback = viewCallbacks.attr(name);
				if(callback) {
					callback(el, {
						attributeName: name,
						scope: scope,
						options: options
					});
				}
			}
			delete oldAttrs[name];
		}
		for(name in oldAttrs) {
			attr.remove(el, name);
		}
		oldAttrs = newAttrs;
	};

	var handler = function (ev, newVal) {
		setAttrs(newVal);
	};

	compute.addEventListener('change', handler);
	domEvents.addEventListener.call(el, 'removed', function() {
		compute.removeEventListener('change', handler);
	});

	// current value has been set
	setAttrs(compute());
};
Beispiel #4
0
			var setAttrs = function (newVal) {
				var newAttrs = getAttributeParts(newVal),
					name;
				for( name in newAttrs ) {
					var newValue = newAttrs[name],
						oldValue = oldAttrs[name];
					if(newValue !== oldValue) {
						domAttr.set(el, name, newValue);
					}
					delete oldAttrs[name];
				}
				for( name in oldAttrs ) {
					domAttr.remove(el, name);
				}
				oldAttrs = newAttrs;
			};
Beispiel #5
0
	var setAttrs = function (newVal) {
		var newAttrs = live.getAttributeParts(newVal),
			name;
		for(name in newAttrs) {
			var newValue = newAttrs[name],
				oldValue = oldAttrs[name];
			if(newValue !== oldValue) {
				attr.set(el, name, newValue);
				var callback = viewCallbacks.attr(name);
				if(callback) {
					callback(el, {
						attributeName: name,
						scope: scope,
						options: options
					});
				}
			}
			delete oldAttrs[name];
		}
		for(name in oldAttrs) {
			attr.remove(el, name);
		}
		oldAttrs = newAttrs;
	};
Beispiel #6
0
			listen(el, compute, function (ev, newVal) {
				domAttr.set(el, attributeName, getValue(newVal));
			});
Beispiel #7
0
		specialAttribute: function (el, attributeName, compute) {
			listen(el, compute, function (ev, newVal) {
				domAttr.set(el, attributeName, getValue(newVal));
			});
			domAttr.set(el, attributeName, getValue(compute()));
		},
Beispiel #8
0
			listen(el, compute, function () {
				domAttr.set(el, attributeName, hook.render());
			});
Beispiel #9
0
		setAttributes: function(el, newVal) {
			var attrs = getAttributeParts(newVal);
			for(var name in attrs) {
				domAttr.set(el, name, attrs[name]);
			}
		},
Beispiel #10
0
		return function branchRenderer(scope, options, parentSectionNodeList, truthyRenderer, falseyRenderer){

			var nodeList = [this];
			nodeList.expression = expressionString;
			// register this nodeList.
			// Regsiter it with its parent ONLY if this is directly nested.  Otherwise, it's unencessary.
			nodeLists.register(nodeList, null, parentSectionNodeList || true, state.directlyNested);


			// Get the evaluator. This does not need to be cached (probably) because if there
			// an observable value, it will be handled by `can.view.live`.
			var evaluator = makeEvaluator( scope, options, nodeList, mode, exprData, truthyRenderer, falseyRenderer,
				// If this is within a tag, make sure we only get string values.
				state.tag );

			// Create a compute that can not be observed by other
			// comptues. This is important because this renderer is likely called by
			// parent expresions.  If this value changes, the parent expressions should
			// not re-evaluate. We prevent that by making sure this compute is ignored by
			// everyone else.
			//var compute = can.compute(evaluator, null, false);
			var gotCompute = evaluator.isComputed,
				computeValue;
			if(gotCompute) {
				computeValue = evaluator;
			} else {
				computeValue = compute(evaluator, null, false);
			}

			computeValue.computeInstance.setPrimaryDepth(nodeList.nesting);

			// Bind on the computeValue to set the cached value. This helps performance
			// so live binding can read a cached value instead of re-calculating.
			computeValue.computeInstance.bind("change", k);

			var value = computeValue();

			// If value is a function, it's a helper that returned a function.
			if(typeof value === "function") {

				// A helper function should do it's own binding.  Similar to how
				// we prevented this function's compute from being noticed by parent expressions,
				// we hide any observables read in the function by saving any observables that
				// have been read and then setting them back which overwrites any `can.__observe` calls
				// performed in value.
				ObserveInfo.notObserve(value)(this);

			}
			// If the computeValue has observable dependencies, setup live binding.
			else if(gotCompute || computeValue.computeInstance.hasDependencies ) {

				// Depending on where the template is, setup live-binding differently.
				if(state.attr) {
					live.attr(this, state.attr, computeValue);
				}
				else if( state.tag )  {
					live.attrs( this, computeValue );
				}
				else if(state.text && typeof value !== "object"){
					live.text(this, computeValue, this.parentNode, nodeList);
				}
				else {
					live.html(this, computeValue, this.parentNode, nodeList);
				}
			}
			// If the computeValue has no observable dependencies, just set the value on the element.
			else {

				if(state.attr) {
					attr.set(this, state.attr, value);
				}
				else if(state.tag) {
					live.attrs(this, value);
				}
				else if(state.text && typeof value === "string") {
					this.nodeValue = value;
				}
				else if( value != null ){
					nodeLists.replace([this], frag(value, this.ownerDocument));
				}
			}
			// Unbind the compute.
			computeValue.computeInstance.unbind("change", k);
		};