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

Avoid domUI queue #144

Open
justinbmeyer opened this issue Jul 17, 2019 · 0 comments
Open

Avoid domUI queue #144

justinbmeyer opened this issue Jul 17, 2019 · 0 comments

Comments

@justinbmeyer
Copy link
Contributor

It should be possible to avoid the domUI queue and only use the dom queue.

Here are versions of the files that are needed to make this work:

text.js

"use strict";
var canReflect = require('can-reflect');
var helpers = require('./helpers');
var queues = require("can-queues");


/**
 * @function can-view-live.text text
 * @parent can-view-live
 * @release 2.0.4
 *
 * @signature `live.text(el, compute, [parentNode], [nodeList])`
 *
 * Replaces one element with some content while keeping [can-view-live.nodeLists nodeLists] data correct.
 */
module.exports = function(el, compute) {
	var handlerName = "";

	//!steal-remove-start
	if(process.env.NODE_ENV !== 'production') {
		if(arguments.length > 2) {
			// TODO: remove
			throw new Error("too many arguments");

		}
		handlerName = "live.text update::"+canReflect.getName(compute);
	}
	//!steal-remove-end

	// TODO: we can remove this at some point
	if (el.nodeType !== Node.TEXT_NODE) {
		var textNode;

		textNode = document.createTextNode("");
		el.parentNode.replaceChild(textNode, el);
		el = textNode;

	}
	function setValue(el, newVal) {

		el.nodeValue = helpers.makeString(newVal);
	}

	var meta = {reasonLog: handlerName, element: el};
	var useQueue = false;
	new helpers.ListenUntilRemovedAndInitialize(compute, function liveTextUpdateTextNode(newVal) {
		
		if(useQueue) {
			queues.domQueue.enqueue(setValue, null, [el, newVal], meta);
		} else {
			el.nodeValue = helpers.makeString(newVal);
			useQueue = true;
		}

	},
	el,
	"notify", // TODO: should this still be domUI?
	handlerName);
};

attr.js

"use strict";
var canReflect = require('can-reflect');
var attr = require("can-attribute-observable/behaviors");
var helpers = require('./helpers');
var queues = require("can-queues");

/**
 * @function can-view-live.attr attr
 * @parent can-view-live
 *
 * @signature `live.attr(el, attributeName, observable)`
 *
 * Keep an attribute live to a [can-reflect]-ed observable.
 *
 * ```js
 * var div = document.createElement('div');
 * var value = new SimpleObservable("foo bar");
 * live.attr(div,"class", value);
 * ```
 *
 * @param {HTMLElement} el The element whos attribute will be kept live.
 * @param {String} attributeName The attribute name.
 * @param {Object} observable An observable value.
 *
 * @body
 *
 * ## How it works
 *
 * This listens for the changes in the observable and uses those changes to
 * set the specified attribute.
 */
module.exports = function(el, attributeName, compute) {
	var handlerName = "";
	//!steal-remove-start
	if(process.env.NODE_ENV !== 'production') {
		// register that the handler changes the parent element
		handlerName = "live.attr update::"+canReflect.getName(compute);
	}
	//!steal-remove-end
	var useQueue = false;
	var meta = {reasonLog: handlerName, element: el};
	new helpers.ListenUntilRemovedAndInitialize(compute,
			function liveUpdateAttr(newVal) {
				if(useQueue) {
					queues.domQueue.enqueue(attr.set, attr, [el,attributeName, newVal], meta);
				} else {
					attr.set(el,attributeName, newVal);
					useQueue = true;
				}

			},
			el,
			"notify",
			handlerName
		);
};

attrs.js

"use strict";
// This provides live binding for stache attributes.
var viewCallbacks = require('can-view-callbacks');
var domMutateNode = require('can-dom-mutate/node');
var canReflect = require('can-reflect');

var helpers = require('./helpers');
var queues = require("can-queues");

function updateAttrs(el, newAttrs, oldAttrs, scope, options){

	var name;
	for (name in newAttrs) {
		var newValue = newAttrs[name],
			// `oldAttrs` was set on the last run of setAttrs in this context
			//  (for this element and compute)
			oldValue = oldAttrs[name];
		// Only fire a callback
		//  if the value of the attribute has changed
		if (newValue !== oldValue) {
			// set on DOM attributes (dispatches an "attributes" event as well)
			domMutateNode.setAttribute.call(el, name, newValue);
			// get registered callback for attribute name and fire
			var callback = viewCallbacks.attr(name);
			if (callback) {
				callback(el, {
					attributeName: name,
					scope: scope,
					options: options
				});
			}
		}
		// remove key found in new attrs from old attrs
		delete oldAttrs[name];
	}
	// any attrs left at this point are not set on the element now,
	// so remove them.
	for (name in oldAttrs) {
		domMutateNode.removeAttribute.call(el, name);
	}

}

module.exports = function(el, compute, scope, options) {
	var handlerName = "";
	if (!canReflect.isObservableLike(compute)) {
		// Non-live case (`compute` was not a compute):
		//  set all attributes on the element and don't
		//  worry about setting up live binding since there
		//  is not compute to bind on.
		var attrs = helpers.getAttributeParts(compute);
		for (var name in attrs) {
			domMutateNode.setAttribute.call(el, name, attrs[name]);
		}
		return;
	}

	//!steal-remove-start
	if(process.env.NODE_ENV !== 'production') {
		handlerName = "live.attrs update::"+canReflect.getName(compute);
	}
	//!steal-remove-end


	// last set of attributes
	var oldAttrs = {};
	var useQueue = false;
	var meta = {reasonLog: handlerName, element: el};
	new helpers.ListenUntilRemovedAndInitialize(compute,
		function canViewLive_updateAttributes(newVal) {
			if(!useQueue) {
				var newAttrs = helpers.getAttributeParts(newVal);
				updateAttrs(el, newAttrs,oldAttrs, scope, options);
				oldAttrs = newAttrs;
			} else {
				queues.domQueue.enqueue(function(){
					var newAttrs = helpers.getAttributeParts(newVal);
					updateAttrs(el, newAttrs,oldAttrs, scope, options);
					oldAttrs = newAttrs;
				}, null, [], meta)
			}
		},
		el,
		"notify",
		handlerName);

};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants