Skip to content

Commit

Permalink
Merge pull request #106 from canjs/major
Browse files Browse the repository at this point in the history
Merge into master for 4.0 release
  • Loading branch information
matthewp authored Jan 29, 2018
2 parents e838aed + b0b8053 commit 25b0e61
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 200 deletions.
3 changes: 2 additions & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"start": true,
"stop": true,
"global": true,
"Promise": true
"Promise": true,
"WeakMap": true
},
"strict": false,
"curly": true,
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
21 changes: 0 additions & 21 deletions build.js

This file was deleted.

149 changes: 91 additions & 58 deletions can-control.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,30 @@
// ## helpers

var Construct = require("can-construct");

var namespace = require("can-namespace");
var assign = require("can-assign");
var observeReader = require("can-stache-key");
var canReflect = require("can-reflect");
var Observation = require("can-observation");
var canEvent = require("can-event-queue/map/map");
var dev = require('can-log/dev/dev');

var string = require("can-util/js/string/string");
var assign = require("can-util/js/assign/assign");
var isFunction = require("can-util/js/is-function/is-function");
var each = require("can-util/js/each/each");
var dev = require("can-util/js/dev/dev");
var types = require("can-types");
var get = require("can-util/js/get/get");
var domData = require("can-util/dom/data/data");
var className = require("can-util/dom/class-name/class-name");
var domEvents = require("can-util/dom/events/events");
var canEvent = require("can-event");
var canCompute = require("can-compute");
var observeReader = require("can-stache-key");
var canReflect = require("can-reflect");
var processors;
var domMutate = require('can-dom-mutate');

require("can-util/dom/dispatch/dispatch");
require("can-util/dom/events/delegate/delegate");
var processors;
var controlData = new WeakMap();

// ### bind
// this helper binds to one element and returns a function that unbinds from that element.
var bind = function (el, ev, callback) {
var bind = function (el, ev, callback, queue) {

canEvent.on.call(el, ev, callback);
canEvent.on.call(el, ev, callback, queue);

return function () {
canEvent.off.call(el, ev, callback);
canEvent.off.call(el, ev, callback, queue);
};
},
slice = [].slice,
Expand Down Expand Up @@ -63,7 +58,7 @@ var bind = function (el, ev, callback) {

basicProcessor;

var Control = Construct.extend(
var Control = Construct.extend("Control",
// ## *static functions*
/**
* @static
Expand Down Expand Up @@ -97,15 +92,21 @@ var Control = Construct.extend(
_shifter: function (context, name) {
var method = typeof name === "string" ? context[name] : name;

if (!isFunction(method)) {
if (typeof method !== "function") {
method = context[method];
}

return function () {
var wrapped = types.wrapElement(this);
var Control = this;
function controlMethod() {
var wrapped = Control.wrapElement(this);
context.called = name;
return method.apply(context, [wrapped].concat(slice.call(arguments, 0)));
};
}
//!steal-remove-start
Object.defineProperty(controlMethod, "name", {
value: canReflect.getName(this) + "["+name+"]",
});
//!steal-remove-end
return controlMethod;
},

// ## can.Control._isAction
Expand All @@ -118,7 +119,7 @@ var Control = Construct.extend(
type = typeof val;

return (methodName !== 'constructor') &&
(type === "function" || (type === "string" && isFunction(this.prototype[val]))) &&
(type === "function" || (type === "string" && (typeof this.prototype[val] === "function") )) &&
!! (Control.isSpecial(methodName) || processors[methodName] || /[^\w]/.test(methodName));
},
// ## can.Control._action
Expand All @@ -130,16 +131,16 @@ var Control = Construct.extend(
// * It's called when the Control class is created. for templated method names (e.g., `{window} foo`), it returns null. For non-templated method names it returns the event binding data. That data is added to `this.actions`.
// * It is called wehn a control instance is created, but only for templated actions.
_action: function(methodName, options, controlInstance) {
var readyCompute;
var readyCompute,
unableToBind;

// If we don't have options (a `control` instance), we'll run this later. If we have
// options, run `can.sub` to replace the action template `{}` with values from the `options`
// or `window`. If a `{}` template resolves to an object, `convertedName` will be an array.
// In that case, the event name we want will be the last item in that array.
paramReplacer.lastIndex = 0;
if (options || !paramReplacer.test(methodName)) {

readyCompute = canCompute(function() {
var controlActionData = function() {
var delegate;

// Set the delegate target and get the name of the event we're listening to.
Expand All @@ -164,17 +165,15 @@ var Control = Construct.extend(
readCompute: false
}).value;

// If `value` is undefined use `string.getObject` to get the value.
// If `value` is undefined try to get the value from the window.
if (value === undefined && typeof window !== 'undefined') {
value = get(window, key);
}

// if the parent is not an observable and we don't have a value, show a warning
// in this situation, it is not possible for the event handler to be triggered
if (!parent || !(canReflect.isObservableLike(parent) && canReflect.isMapLike(parent)) && !value) {
//!steal-remove-start
dev.log('can/control/control.js: No property found for handling ' + methodName);
//!steal-remove-end
unableToBind = true;
return null;
}

Expand All @@ -201,28 +200,49 @@ var Control = Construct.extend(
parts: [name, parts.join(" "), event],
delegate: delegate || undefined
};
}, this);
};

//!steal-remove-start
Object.defineProperty(controlActionData, "name", {
value: canReflect.getName(controlInstance || this.prototype) + "["+methodName+"].actionData",
});
//!steal-remove-end

readyCompute = new Observation(controlActionData, this);


if (controlInstance) {
// Create a handler function that we'll use to handle the `change` event on the `readyCompute`.
var handler = function(ev, ready) {
var handler = function(actionData) {
// unbinds the old binding
controlInstance._bindings.control[methodName](controlInstance.element);
// binds the new
controlInstance._bindings.control[methodName] = ready.processor(
ready.delegate || controlInstance.element,
ready.parts[2], ready.parts[1], methodName, controlInstance);
controlInstance._bindings.control[methodName] = actionData.processor(
actionData.delegate || controlInstance.element,
actionData.parts[2], actionData.parts[1], methodName, controlInstance);
};

readyCompute.bind("change", handler);
//!steal-remove-start
Object.defineProperty(handler, "name", {
value: canReflect.getName(controlInstance) + "["+methodName+"].handler",
});
//!steal-remove-end


canReflect.onValue(readyCompute, handler, "mutate");
//!steal-remove-start
if(unableToBind) {
dev.log('can-control: No property found for handling ' + methodName);
}
//!steal-remove-end

controlInstance._bindings.readyComputes[methodName] = {
compute: readyCompute,
handler: handler
};
}

return readyCompute();
return readyCompute.get();
}
},
// the lookup path - where templated keys will be looked up
Expand Down Expand Up @@ -254,7 +274,13 @@ var Control = Construct.extend(
element = typeof element === "string" ?
document.querySelector(element) : element;

return types.wrapElement(element);
return this.wrapElement(element);
},
wrapElement: function(el){
return el;
},
unwrapElement: function(el){
return el;
},
// should be overwritten to look in jquery special events
isSpecial: function(eventName){
Expand Down Expand Up @@ -284,18 +310,18 @@ var Control = Construct.extend(
throw new Error('Creating an instance of a named control without passing an element');
}
// Retrieve the raw element, then set the plugin name as a class there.
this.element = cls.convertElement(element);
this.element = cls.convertElement(element);

if (pluginname && pluginname !== 'can_control') {
if (pluginname && pluginname !== 'Control') {
className.add.call(this.element, pluginname);
}

// Set up the 'controls' data on the element. If it does not exist, initialize
// it to an empty array.
arr = domData.get.call(this.element, 'controls');
arr = controlData.get(this.element);
if (!arr) {
arr = [];
domData.set.call(this.element, 'controls', arr);
controlData.set(this.element, arr);
}
arr.push(this);

Expand Down Expand Up @@ -333,7 +359,7 @@ var Control = Construct.extend(
var cls = this.constructor,
bindings = this._bindings,
actions = cls.actions,
element = types.unwrapElement(this.element),
element = this.constructor.unwrapElement(this.element),
destroyCB = Control._shifter(this, "destroy"),
funcName, ready;

Expand All @@ -349,9 +375,16 @@ var Control = Construct.extend(
}

// Set up the ability to `destroy` the control later.
domEvents.addEventListener.call(element, "removed", destroyCB);
bindings.user.push(function (el) {
domEvents.removeEventListener.call(el, "removed", destroyCB);
var removalDisposal = domMutate.onNodeRemoval(element, function () {
if (!element.ownerDocument.contains(element)) {
destroyCB();
}
});
bindings.user.push(function () {
if (removalDisposal) {
removalDisposal();
removalDisposal = undefined;
}
});
return bindings.user.length;
}
Expand Down Expand Up @@ -384,17 +417,17 @@ var Control = Construct.extend(
// Unbinds all event handlers on the controller.
// This should _only_ be called in combination with .on()
off: function () {
var el = types.unwrapElement(this.element),
var el = this.constructor.unwrapElement(this.element),
bindings = this._bindings;
if( bindings ) {
each(bindings.user || [], function (value) {
(bindings.user || []).forEach(function (value) {
value(el);
});
each(bindings.control || {}, function (value) {
canReflect.eachKey(bindings.control || {}, function (value) {
value(el);
});
each(bindings.readyComputes || {}, function(value) {
value.compute.unbind("change", value.handler);
canReflect.eachKey(bindings.readyComputes || {}, function(value) {
canReflect.offValue(value.compute, value.handler, "mutate");
});
}
// Adds bindings.
Expand All @@ -408,7 +441,7 @@ var Control = Construct.extend(
destroy: function () {
if (this.element === null) {
//!steal-remove-start
dev.warn("can/control/control.js: Control already destroyed");
dev.warn("can-control: Control already destroyed");
//!steal-remove-end
return;
}
Expand All @@ -422,12 +455,12 @@ var Control = Construct.extend(
className.remove.call(this.element, pluginName);
}

controls = domData.get.call(this.element, "controls");
controls = controlData.get(this.element);
if (controls) {
controls.splice(controls.indexOf(this), 1);
}

canEvent.dispatch.call(this, "destroyed");
//canEvent.dispatch.call(this, "destroyed");

this.element = null;
}
Expand All @@ -443,14 +476,14 @@ basicProcessor = function (el, event, selector, methodName, control) {
};

// Set common events to be processed as a `basicProcessor`
each(["beforeremove", "change", "click", "contextmenu", "dblclick", "keydown", "keyup",
["beforeremove", "change", "click", "contextmenu", "dblclick", "keydown", "keyup",
"keypress", "mousedown", "mousemove", "mouseout", "mouseover",
"mouseup", "reset", "resize", "scroll", "select", "submit", "focusin",
"focusout", "mouseenter", "mouseleave",
"touchstart", "touchmove", "touchcancel", "touchend", "touchleave",
"inserted","removed",
"dragstart", "dragenter", "dragover", "dragleave", "drag", "drop", "dragend"
], function (v) {
].forEach(function (v) {
processors[v] = basicProcessor;
});

Expand Down
Loading

0 comments on commit 25b0e61

Please sign in to comment.