Remove 2-way binding from objects
This commit is contained in:
@@ -1,51 +0,0 @@
|
|||||||
---
|
|
||||||
template: example.html
|
|
||||||
title: Bind HTML input example
|
|
||||||
shortdesc: Demonstrates two-way binding of HTML input elements to OpenLayers objects.
|
|
||||||
docs: >
|
|
||||||
<p id="has-webgl" style="display: none">With the <a href="?renderer=webgl">WebGL renderer</a>, <strong>hue</strong>, <strong>saturation</strong>, <strong>contrast</strong> and <strong>brightness</strong> can also be controlled.</p>
|
|
||||||
<div id="no-webgl" class="alert alert-warning" style="display: none">
|
|
||||||
<h4>Warning!</h4>
|
|
||||||
A browser that supports <a href="http://get.webgl.org/">WebGL</a> is required to change the
|
|
||||||
<strong>hue</strong>, <strong>saturation</strong>, <strong>contrast</strong> and <strong>brightness</strong>.
|
|
||||||
</div>
|
|
||||||
tags: "custom, control"
|
|
||||||
---
|
|
||||||
<div class="row-fluid">
|
|
||||||
<div class="span12">
|
|
||||||
<div id="map" class="map"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="span4">
|
|
||||||
<form class="">
|
|
||||||
<fieldset>
|
|
||||||
<legend>Layer</legend>
|
|
||||||
<label class="checkbox" for="visible">
|
|
||||||
<input id="visible" type="checkbox"/>visibility
|
|
||||||
</label>
|
|
||||||
<label>opacity</label>
|
|
||||||
<input id="opacity" type="range" min="0" max="1" step="0.01"/>
|
|
||||||
</fieldset>
|
|
||||||
<fieldset id="webgl" style="display: none">
|
|
||||||
<label>hue</label>
|
|
||||||
<input id="hue" type="range" min="-3.141592653589793" max="3.141592653589793" step="0.01"/>
|
|
||||||
<label>saturation</label>
|
|
||||||
<input id="saturation" type="range" min="0" max="5" step="0.01"/>
|
|
||||||
<label>contrast</label>
|
|
||||||
<input id="contrast" type="range" min="0" max="2" step="0.01"/>
|
|
||||||
<label>brightness</label>
|
|
||||||
<input id="brightness" type="range" min="-1" max="1" step="0.01"/>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="span4">
|
|
||||||
<form class="">
|
|
||||||
<fieldset>
|
|
||||||
<legend>View</legend>
|
|
||||||
<label>rotation</label>
|
|
||||||
<input id="rotation" type="range" min="-3.141592653589793" max="3.141592653589793" step="0.01"/>
|
|
||||||
<label>resolution</label>
|
|
||||||
<input id="resolution" type="number" min="0" step="250"/>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
goog.require('ol.Map');
|
|
||||||
goog.require('ol.View');
|
|
||||||
goog.require('ol.control');
|
|
||||||
goog.require('ol.dom.Input');
|
|
||||||
goog.require('ol.has');
|
|
||||||
goog.require('ol.layer.Tile');
|
|
||||||
goog.require('ol.source.OSM');
|
|
||||||
|
|
||||||
|
|
||||||
function checkWebGL(evt) {
|
|
||||||
document.getElementById('no-webgl').style.display =
|
|
||||||
ol.has.WEBGL ? 'none' : '';
|
|
||||||
document.getElementById('has-webgl').style.display =
|
|
||||||
ol.has.WEBGL && !evt.glContext ? '' : 'none';
|
|
||||||
document.getElementById('webgl').style.display =
|
|
||||||
evt.glContext ? '' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
var layer = new ol.layer.Tile({
|
|
||||||
source: new ol.source.OSM()
|
|
||||||
});
|
|
||||||
layer.once('precompose', checkWebGL);
|
|
||||||
|
|
||||||
var view = new ol.View({
|
|
||||||
center: [0, 0],
|
|
||||||
zoom: 2
|
|
||||||
});
|
|
||||||
|
|
||||||
var map = new ol.Map({
|
|
||||||
layers: [layer],
|
|
||||||
renderer: exampleNS.getRendererFromQueryString(),
|
|
||||||
target: 'map',
|
|
||||||
controls: ol.control.defaults({
|
|
||||||
attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
|
|
||||||
collapsible: false
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
view: view
|
|
||||||
});
|
|
||||||
|
|
||||||
var visible = new ol.dom.Input(document.getElementById('visible'));
|
|
||||||
visible.bindTo('checked', layer, 'visible');
|
|
||||||
|
|
||||||
var opacity = new ol.dom.Input(document.getElementById('opacity'));
|
|
||||||
opacity.bindTo('value', layer, 'opacity')
|
|
||||||
.transform(parseFloat, String);
|
|
||||||
|
|
||||||
var hue = new ol.dom.Input(document.getElementById('hue'));
|
|
||||||
hue.bindTo('value', layer, 'hue')
|
|
||||||
.transform(parseFloat, String);
|
|
||||||
|
|
||||||
var saturation = new ol.dom.Input(document.getElementById('saturation'));
|
|
||||||
saturation.bindTo('value', layer, 'saturation')
|
|
||||||
.transform(parseFloat, String);
|
|
||||||
|
|
||||||
var contrast = new ol.dom.Input(document.getElementById('contrast'));
|
|
||||||
contrast.bindTo('value', layer, 'contrast')
|
|
||||||
.transform(parseFloat, String);
|
|
||||||
|
|
||||||
var brightness = new ol.dom.Input(document.getElementById('brightness'));
|
|
||||||
brightness.bindTo('value', layer, 'brightness')
|
|
||||||
.transform(parseFloat, String);
|
|
||||||
|
|
||||||
|
|
||||||
var rotation = new ol.dom.Input(document.getElementById('rotation'));
|
|
||||||
rotation.bindTo('value', view, 'rotation').transform(parseFloat, String);
|
|
||||||
|
|
||||||
var resolution = new ol.dom.Input(document.getElementById('resolution'));
|
|
||||||
resolution.bindTo('value', view, 'resolution').transform(parseFloat, String);
|
|
||||||
@@ -170,7 +170,7 @@ ol.control.OverviewMap.prototype.setMap = function(map) {
|
|||||||
// if no layers were set for the overviewmap map, then bind with
|
// if no layers were set for the overviewmap map, then bind with
|
||||||
// those in the main map
|
// those in the main map
|
||||||
if (this.ovmap_.getLayers().getLength() === 0) {
|
if (this.ovmap_.getLayers().getLength() === 0) {
|
||||||
this.ovmap_.bindTo(ol.MapProperty.LAYERGROUP, map);
|
this.ovmap_.setLayerGroup(map.getLayerGroup());
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind current map view, or any new one
|
// bind current map view, or any new one
|
||||||
@@ -202,7 +202,7 @@ ol.control.OverviewMap.prototype.bindView_ = function() {
|
|||||||
// FIXME - the overviewmap view rotation currently follows the one used
|
// FIXME - the overviewmap view rotation currently follows the one used
|
||||||
// by the main map view. We could support box rotation instead. The choice
|
// by the main map view. We could support box rotation instead. The choice
|
||||||
// between the 2 modes would be made in a single option
|
// between the 2 modes would be made in a single option
|
||||||
this.ovmap_.getView().bindTo(ol.ViewProperty.ROTATION, view);
|
// this.ovmap_.getView().bindTo(ol.ViewProperty.ROTATION, view);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
goog.provide('ol.dom.Input');
|
|
||||||
goog.provide('ol.dom.InputProperty');
|
|
||||||
|
|
||||||
goog.require('goog.asserts');
|
|
||||||
goog.require('goog.events');
|
|
||||||
goog.require('goog.events.EventType');
|
|
||||||
goog.require('ol.Object');
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum {string}
|
|
||||||
*/
|
|
||||||
ol.dom.InputProperty = {
|
|
||||||
VALUE: 'value',
|
|
||||||
CHECKED: 'checked'
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @classdesc
|
|
||||||
* Helper class for binding HTML input to an {@link ol.Object}.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
*
|
|
||||||
* // bind a checkbox with id 'visible' to a layer's visibility
|
|
||||||
* var visible = new ol.dom.Input(document.getElementById('visible'));
|
|
||||||
* visible.bindTo('checked', layer, 'visible');
|
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
* @extends {ol.Object}
|
|
||||||
* @param {Element} target Target element.
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.dom.Input = function(target) {
|
|
||||||
goog.base(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {HTMLInputElement}
|
|
||||||
*/
|
|
||||||
this.target_ = /** @type {HTMLInputElement} */ (target);
|
|
||||||
|
|
||||||
goog.events.listen(this.target_,
|
|
||||||
[goog.events.EventType.CHANGE, goog.events.EventType.INPUT],
|
|
||||||
this.handleInputChanged_, false, this);
|
|
||||||
|
|
||||||
goog.events.listen(this,
|
|
||||||
ol.Object.getChangeEventType(ol.dom.InputProperty.VALUE),
|
|
||||||
this.handleValueChanged_, false, this);
|
|
||||||
goog.events.listen(this,
|
|
||||||
ol.Object.getChangeEventType(ol.dom.InputProperty.CHECKED),
|
|
||||||
this.handleCheckedChanged_, false, this);
|
|
||||||
};
|
|
||||||
goog.inherits(ol.dom.Input, ol.Object);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the input is a checkbox, return whether or not the checkbox is checked.
|
|
||||||
* @return {boolean|undefined} The checked state of the Input.
|
|
||||||
* @observable
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.dom.Input.prototype.getChecked = function() {
|
|
||||||
return /** @type {boolean} */ (this.get(ol.dom.InputProperty.CHECKED));
|
|
||||||
};
|
|
||||||
goog.exportProperty(
|
|
||||||
ol.dom.Input.prototype,
|
|
||||||
'getChecked',
|
|
||||||
ol.dom.Input.prototype.getChecked);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of the input.
|
|
||||||
* @return {string|undefined} The value of the Input.
|
|
||||||
* @observable
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.dom.Input.prototype.getValue = function() {
|
|
||||||
return /** @type {string} */ (this.get(ol.dom.InputProperty.VALUE));
|
|
||||||
};
|
|
||||||
goog.exportProperty(
|
|
||||||
ol.dom.Input.prototype,
|
|
||||||
'getValue',
|
|
||||||
ol.dom.Input.prototype.getValue);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of the input.
|
|
||||||
* @param {string} value The value of the Input.
|
|
||||||
* @observable
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.dom.Input.prototype.setValue = function(value) {
|
|
||||||
this.set(ol.dom.InputProperty.VALUE, value);
|
|
||||||
};
|
|
||||||
goog.exportProperty(
|
|
||||||
ol.dom.Input.prototype,
|
|
||||||
'setValue',
|
|
||||||
ol.dom.Input.prototype.setValue);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set whether or not a checkbox is checked.
|
|
||||||
* @param {boolean} checked The checked state of the Input.
|
|
||||||
* @observable
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.dom.Input.prototype.setChecked = function(checked) {
|
|
||||||
this.set(ol.dom.InputProperty.CHECKED, checked);
|
|
||||||
};
|
|
||||||
goog.exportProperty(
|
|
||||||
ol.dom.Input.prototype,
|
|
||||||
'setChecked',
|
|
||||||
ol.dom.Input.prototype.setChecked);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {goog.events.BrowserEvent} browserEvent Browser event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.dom.Input.prototype.handleInputChanged_ = function(browserEvent) {
|
|
||||||
goog.asserts.assert(browserEvent.currentTarget == this.target_,
|
|
||||||
'currentTarget should be the same as this.target_');
|
|
||||||
var target = this.target_;
|
|
||||||
if (target.type === 'checkbox' || target.type === 'radio') {
|
|
||||||
this.setChecked(target.checked);
|
|
||||||
} else {
|
|
||||||
this.setValue(target.value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {goog.events.Event} event Change event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.dom.Input.prototype.handleCheckedChanged_ = function(event) {
|
|
||||||
this.target_.checked = /** @type {boolean} */ (this.getChecked());
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {goog.events.Event} event Change event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.dom.Input.prototype.handleValueChanged_ = function(event) {
|
|
||||||
this.target_.value = /** @type {string} */ (this.getValue());
|
|
||||||
};
|
|
||||||
278
src/ol/object.js
278
src/ol/object.js
@@ -10,9 +10,7 @@ goog.provide('ol.ObjectEventType');
|
|||||||
|
|
||||||
goog.require('goog.events');
|
goog.require('goog.events');
|
||||||
goog.require('goog.events.Event');
|
goog.require('goog.events.Event');
|
||||||
goog.require('goog.functions');
|
|
||||||
goog.require('goog.object');
|
goog.require('goog.object');
|
||||||
goog.require('goog.string');
|
|
||||||
goog.require('ol.Observable');
|
goog.require('ol.Observable');
|
||||||
|
|
||||||
|
|
||||||
@@ -64,63 +62,6 @@ goog.inherits(ol.ObjectEvent, goog.events.Event);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {ol.Object} source Source object.
|
|
||||||
* @param {ol.Object} target Target object.
|
|
||||||
* @param {string} sourceKey Source key.
|
|
||||||
* @param {string} targetKey Target key.
|
|
||||||
*/
|
|
||||||
ol.ObjectAccessor = function(source, target, sourceKey, targetKey) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {ol.Object}
|
|
||||||
*/
|
|
||||||
this.source = source;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {ol.Object}
|
|
||||||
*/
|
|
||||||
this.target = target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.sourceKey = sourceKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.targetKey = targetKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {function(?): ?}
|
|
||||||
*/
|
|
||||||
this.from = goog.functions.identity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {function(?): ?}
|
|
||||||
*/
|
|
||||||
this.to = goog.functions.identity;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {function(?): ?} from A function that transforms the source value
|
|
||||||
* before it is set to the target.
|
|
||||||
* @param {function(?): ?} to A function that transforms the target value
|
|
||||||
* before it is set to the source.
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.ObjectAccessor.prototype.transform = function(from, to) {
|
|
||||||
var oldValue = ol.Object.getKeyValue_(this.source, this.sourceKey);
|
|
||||||
this.from = from;
|
|
||||||
this.to = to;
|
|
||||||
this.source.notify(this.sourceKey, oldValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @classdesc
|
* @classdesc
|
||||||
* Abstract base class; normally only used for creating subclasses and not
|
* Abstract base class; normally only used for creating subclasses and not
|
||||||
@@ -157,12 +98,6 @@ ol.ObjectAccessor.prototype.transform = function(from, to) {
|
|||||||
* first will be a `hasOwnProperty`; the second will appear in
|
* first will be a `hasOwnProperty`; the second will appear in
|
||||||
* `getProperties()`. Only the second is observable.
|
* `getProperties()`. Only the second is observable.
|
||||||
*
|
*
|
||||||
* The observable properties also implement a form of Key Value Observing.
|
|
||||||
* Two objects can be bound together such that a change in one will
|
|
||||||
* automatically be reflected in the other. See `bindTo` method for more
|
|
||||||
* details, and see {@link ol.dom.Input} for the specific case of binding an
|
|
||||||
* object with an HTML element.
|
|
||||||
*
|
|
||||||
* Properties can be deleted by using the unset method. E.g.
|
* Properties can be deleted by using the unset method. E.g.
|
||||||
* object.unset('foo').
|
* object.unset('foo').
|
||||||
*
|
*
|
||||||
@@ -187,18 +122,6 @@ ol.Object = function(opt_values) {
|
|||||||
*/
|
*/
|
||||||
this.values_ = {};
|
this.values_ = {};
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, ol.ObjectAccessor>}
|
|
||||||
*/
|
|
||||||
this.accessors_ = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, goog.events.Key>}
|
|
||||||
*/
|
|
||||||
this.listeners_ = {};
|
|
||||||
|
|
||||||
if (goog.isDef(opt_values)) {
|
if (goog.isDef(opt_values)) {
|
||||||
this.setProperties(opt_values);
|
this.setProperties(opt_values);
|
||||||
}
|
}
|
||||||
@@ -213,20 +136,6 @@ goog.inherits(ol.Object, ol.Observable);
|
|||||||
ol.Object.changeEventTypeCache_ = {};
|
ol.Object.changeEventTypeCache_ = {};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, string>}
|
|
||||||
*/
|
|
||||||
ol.Object.getterNameCache_ = {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, string>}
|
|
||||||
*/
|
|
||||||
ol.Object.setterNameCache_ = {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} key Key name.
|
* @param {string} key Key name.
|
||||||
* @return {string} Change name.
|
* @return {string} Change name.
|
||||||
@@ -238,116 +147,6 @@ ol.Object.getChangeEventType = function(key) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} key String.
|
|
||||||
* @return {string} Getter name.
|
|
||||||
*/
|
|
||||||
ol.Object.getGetterName = function(key) {
|
|
||||||
return ol.Object.getterNameCache_.hasOwnProperty(key) ?
|
|
||||||
ol.Object.getterNameCache_[key] :
|
|
||||||
(ol.Object.getterNameCache_[key] = 'get' + goog.string.capitalize(key));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} key String.
|
|
||||||
* @return {string} Setter name.
|
|
||||||
*/
|
|
||||||
ol.Object.getSetterName = function(key) {
|
|
||||||
return ol.Object.setterNameCache_.hasOwnProperty(key) ?
|
|
||||||
ol.Object.setterNameCache_[key] :
|
|
||||||
(ol.Object.setterNameCache_[key] = 'set' + goog.string.capitalize(key));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value for an object and a key. Use the getter (`getX`) if it exists,
|
|
||||||
* otherwise use the generic `get` function.
|
|
||||||
* @param {ol.Object} obj Object.
|
|
||||||
* @param {string} key Key;
|
|
||||||
* @return {*} Value;
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.Object.getKeyValue_ = function(obj, key) {
|
|
||||||
var getterName = ol.Object.getGetterName(key);
|
|
||||||
var getter = /** @type {function(): *|undefined} */
|
|
||||||
(/** @type {Object} */ (obj)[getterName]);
|
|
||||||
return goog.isDef(getter) ? getter.call(obj) : obj.get(key);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the value for an object and a key. Use the setter (`setX`) if it exists,
|
|
||||||
* otherwise use the generic `set` function.
|
|
||||||
* @param {ol.Object} obj Object.
|
|
||||||
* @param {string} key Key.
|
|
||||||
* @param {*} value Value.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.Object.setKeyValue_ = function(obj, key, value) {
|
|
||||||
var setterName = ol.Object.getSetterName(key);
|
|
||||||
var setter = /** @type {function(*)|undefined} */
|
|
||||||
(/** @type {Object} */ (obj)[setterName]);
|
|
||||||
if (goog.isDef(setter)) {
|
|
||||||
setter.call(obj, value);
|
|
||||||
} else {
|
|
||||||
obj.set(key, value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The bindTo method allows you to set up a two-way binding between a
|
|
||||||
* `source` and `target` object. The method returns an object with a
|
|
||||||
* `transform` method that you can use to provide `from` and `to`
|
|
||||||
* functions to transform values on the way from the source to the
|
|
||||||
* target and on the way back.
|
|
||||||
*
|
|
||||||
* For example, if you had two map views (sourceView and targetView)
|
|
||||||
* and you wanted the target view to have double the resolution of the
|
|
||||||
* source view, you could transform the resolution on the way to and
|
|
||||||
* from the target with the following:
|
|
||||||
*
|
|
||||||
* sourceView.bindTo('resolution', targetView)
|
|
||||||
* .transform(
|
|
||||||
* function(sourceResolution) {
|
|
||||||
* // from sourceView.resolution to targetView.resolution
|
|
||||||
* return 2 * sourceResolution;
|
|
||||||
* },
|
|
||||||
* function(targetResolution) {
|
|
||||||
* // from targetView.resolution to sourceView.resolution
|
|
||||||
* return targetResolution / 2;
|
|
||||||
* }
|
|
||||||
* );
|
|
||||||
*
|
|
||||||
* @param {string} key Key name.
|
|
||||||
* @param {ol.Object} target Target.
|
|
||||||
* @param {string=} opt_targetKey Target key.
|
|
||||||
* @return {ol.ObjectAccessor}
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
|
|
||||||
var targetKey = opt_targetKey || key;
|
|
||||||
this.unbind(key);
|
|
||||||
|
|
||||||
// listen for change:targetkey events
|
|
||||||
var eventType = ol.Object.getChangeEventType(targetKey);
|
|
||||||
this.listeners_[key] = goog.events.listen(target, eventType,
|
|
||||||
/**
|
|
||||||
* @param {ol.ObjectEvent} e Event.
|
|
||||||
* @this {ol.Object}
|
|
||||||
*/
|
|
||||||
function(e) {
|
|
||||||
this.notify(key, e.oldValue);
|
|
||||||
}, undefined, this);
|
|
||||||
|
|
||||||
var accessor = new ol.ObjectAccessor(this, target, key, targetKey);
|
|
||||||
this.accessors_[key] = accessor;
|
|
||||||
this.notify(key, this.values_[key]);
|
|
||||||
return accessor;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a value.
|
* Gets a value.
|
||||||
* @param {string} key Key name.
|
* @param {string} key Key name.
|
||||||
@@ -356,12 +155,7 @@ ol.Object.prototype.bindTo = function(key, target, opt_targetKey) {
|
|||||||
*/
|
*/
|
||||||
ol.Object.prototype.get = function(key) {
|
ol.Object.prototype.get = function(key) {
|
||||||
var value;
|
var value;
|
||||||
var accessors = this.accessors_;
|
if (this.values_.hasOwnProperty(key)) {
|
||||||
if (accessors.hasOwnProperty(key)) {
|
|
||||||
var accessor = accessors[key];
|
|
||||||
value = ol.Object.getKeyValue_(accessor.target, accessor.targetKey);
|
|
||||||
value = accessor.to(value);
|
|
||||||
} else if (this.values_.hasOwnProperty(key)) {
|
|
||||||
value = this.values_[key];
|
value = this.values_[key];
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@@ -374,29 +168,7 @@ ol.Object.prototype.get = function(key) {
|
|||||||
* @api stable
|
* @api stable
|
||||||
*/
|
*/
|
||||||
ol.Object.prototype.getKeys = function() {
|
ol.Object.prototype.getKeys = function() {
|
||||||
var accessors = this.accessors_;
|
return goog.object.getKeys(this.values_);
|
||||||
var keysObject;
|
|
||||||
if (goog.object.isEmpty(this.values_)) {
|
|
||||||
if (goog.object.isEmpty(accessors)) {
|
|
||||||
return [];
|
|
||||||
} else {
|
|
||||||
keysObject = accessors;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (goog.object.isEmpty(accessors)) {
|
|
||||||
keysObject = this.values_;
|
|
||||||
} else {
|
|
||||||
keysObject = {};
|
|
||||||
var key;
|
|
||||||
for (key in this.values_) {
|
|
||||||
keysObject[key] = true;
|
|
||||||
}
|
|
||||||
for (key in accessors) {
|
|
||||||
keysObject[key] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return goog.object.getKeys(keysObject);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -411,9 +183,6 @@ ol.Object.prototype.getProperties = function() {
|
|||||||
for (key in this.values_) {
|
for (key in this.values_) {
|
||||||
properties[key] = this.values_[key];
|
properties[key] = this.values_[key];
|
||||||
}
|
}
|
||||||
for (key in this.accessors_) {
|
|
||||||
properties[key] = this.get(key);
|
|
||||||
}
|
|
||||||
return properties;
|
return properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -438,16 +207,9 @@ ol.Object.prototype.notify = function(key, oldValue) {
|
|||||||
* @api stable
|
* @api stable
|
||||||
*/
|
*/
|
||||||
ol.Object.prototype.set = function(key, value) {
|
ol.Object.prototype.set = function(key, value) {
|
||||||
var accessors = this.accessors_;
|
var oldValue = this.values_[key];
|
||||||
if (accessors.hasOwnProperty(key)) {
|
this.values_[key] = value;
|
||||||
var accessor = accessors[key];
|
this.notify(key, oldValue);
|
||||||
value = accessor.from(value);
|
|
||||||
ol.Object.setKeyValue_(accessor.target, accessor.targetKey, value);
|
|
||||||
} else {
|
|
||||||
var oldValue = this.values_[key];
|
|
||||||
this.values_[key] = value;
|
|
||||||
this.notify(key, oldValue);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -465,36 +227,6 @@ ol.Object.prototype.setProperties = function(values) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a binding. Unbinding will set the unbound property to the current
|
|
||||||
* value. The object will not be notified, as the value has not changed.
|
|
||||||
* @param {string} key Key name.
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.Object.prototype.unbind = function(key) {
|
|
||||||
var listeners = this.listeners_;
|
|
||||||
var listener = listeners[key];
|
|
||||||
if (listener) {
|
|
||||||
delete listeners[key];
|
|
||||||
goog.events.unlistenByKey(listener);
|
|
||||||
var value = this.get(key);
|
|
||||||
delete this.accessors_[key];
|
|
||||||
this.values_[key] = value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all bindings.
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.Object.prototype.unbindAll = function() {
|
|
||||||
for (var key in this.listeners_) {
|
|
||||||
this.unbind(key);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsets a property.
|
* Unsets a property.
|
||||||
* @param {string} key Key name.
|
* @param {string} key Key name.
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ describe('ol.Object', function() {
|
|||||||
|
|
||||||
describe('notify', function() {
|
describe('notify', function() {
|
||||||
|
|
||||||
var listener1, listener2, listener3;
|
var listener1, listener2;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
listener1 = sinon.spy();
|
listener1 = sinon.spy();
|
||||||
@@ -117,11 +117,6 @@ describe('ol.Object', function() {
|
|||||||
|
|
||||||
listener2 = sinon.spy();
|
listener2 = sinon.spy();
|
||||||
goog.events.listen(o, ol.ObjectEventType.PROPERTYCHANGE, listener2);
|
goog.events.listen(o, ol.ObjectEventType.PROPERTYCHANGE, listener2);
|
||||||
|
|
||||||
var o2 = new ol.Object();
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
listener3 = sinon.spy();
|
|
||||||
goog.events.listen(o2, 'change:k', listener3);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches events', function() {
|
it('dispatches events', function() {
|
||||||
@@ -143,21 +138,11 @@ describe('ol.Object', function() {
|
|||||||
expect(event.key).to.be('k');
|
expect(event.key).to.be('k');
|
||||||
expect(event.oldValue).to.be(1);
|
expect(event.oldValue).to.be(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches events to bound objects', function() {
|
|
||||||
o.notify('k', 1);
|
|
||||||
expect(listener3.calledOnce).to.be(true);
|
|
||||||
var args = listener3.firstCall.args;
|
|
||||||
expect(args).to.have.length(1);
|
|
||||||
var event = args[0];
|
|
||||||
expect(event.key).to.be('k');
|
|
||||||
expect(event.oldValue).to.be(1);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('set', function() {
|
describe('set', function() {
|
||||||
|
|
||||||
var listener1, o2, listener2, listener3;
|
var listener1, listener2;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
listener1 = sinon.spy();
|
listener1 = sinon.spy();
|
||||||
@@ -165,11 +150,6 @@ describe('ol.Object', function() {
|
|||||||
|
|
||||||
listener2 = sinon.spy();
|
listener2 = sinon.spy();
|
||||||
goog.events.listen(o, ol.ObjectEventType.PROPERTYCHANGE, listener2);
|
goog.events.listen(o, ol.ObjectEventType.PROPERTYCHANGE, listener2);
|
||||||
|
|
||||||
o2 = new ol.Object();
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
listener3 = sinon.spy();
|
|
||||||
goog.events.listen(o2, 'change:k', listener3);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches events to object', function() {
|
it('dispatches events to object', function() {
|
||||||
@@ -177,7 +157,6 @@ describe('ol.Object', function() {
|
|||||||
expect(listener1).to.be.called();
|
expect(listener1).to.be.called();
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['k']);
|
expect(o.getKeys()).to.eql(['k']);
|
||||||
expect(o2.getKeys()).to.eql(['k']);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches generic change events to object', function() {
|
it('dispatches generic change events to object', function() {
|
||||||
@@ -189,259 +168,6 @@ describe('ol.Object', function() {
|
|||||||
expect(event.key).to.be('k');
|
expect(event.key).to.be('k');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches events to bound object', function() {
|
|
||||||
o.set('k', 1);
|
|
||||||
expect(listener3).to.be.called();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('dispatches events to object bound to', function() {
|
|
||||||
o2.set('k', 2);
|
|
||||||
expect(listener1).to.be.called();
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['k']);
|
|
||||||
expect(o2.getKeys()).to.eql(['k']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('dispatches generic change events to object bound to', function() {
|
|
||||||
o2.set('k', 2);
|
|
||||||
expect(listener2.calledOnce).to.be(true);
|
|
||||||
var args = listener2.firstCall.args;
|
|
||||||
expect(args).to.have.length(1);
|
|
||||||
var event = args[0];
|
|
||||||
expect(event.key).to.be('k');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('bind', function() {
|
|
||||||
|
|
||||||
var o2;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
o2 = new ol.Object();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('bindTo after set', function() {
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
o.set('k', 1);
|
|
||||||
o2.set('k', 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('gets expected value', function() {
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(1);
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['k']);
|
|
||||||
expect(o2.getKeys()).to.eql(['k']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('dispatches a change: event', function() {
|
|
||||||
var listener = sinon.spy();
|
|
||||||
o2.on('change:k', listener);
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
expect(listener.calledOnce).to.be(true);
|
|
||||||
var call = listener.firstCall;
|
|
||||||
expect(call.args).to.have.length(1);
|
|
||||||
expect(call.args[0].key).to.be('k');
|
|
||||||
expect(call.args[0].oldValue).to.be(0);
|
|
||||||
expect(o2.get('k')).to.be(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('dispatches a propertychange event', function() {
|
|
||||||
var listener = sinon.spy();
|
|
||||||
o2.on('propertychange', listener);
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
expect(listener.calledOnce).to.be(true);
|
|
||||||
var call = listener.firstCall;
|
|
||||||
expect(call.args).to.have.length(1);
|
|
||||||
expect(call.args[0].key).to.be('k');
|
|
||||||
expect(call.args[0].oldValue).to.be(0);
|
|
||||||
expect(o2.get('k')).to.be(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('bindTo before set', function() {
|
|
||||||
|
|
||||||
it('gets expected value', function() {
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
o.set('k', 1);
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(1);
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['k']);
|
|
||||||
expect(o2.getKeys()).to.eql(['k']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('backwards', function() {
|
|
||||||
describe('bindTo after set', function() {
|
|
||||||
|
|
||||||
it('gets expected value', function() {
|
|
||||||
o2.set('k', 1);
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
expect(o.get('k')).to.be(undefined);
|
|
||||||
expect(o2.get('k')).to.be(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('bindTo before set', function() {
|
|
||||||
|
|
||||||
it('gets expected value', function() {
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
o2.set('k', 1);
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('unbind', function() {
|
|
||||||
var o2;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
o2 = new ol.Object();
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
o2.set('k', 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('makes changes to unbound object invisible to other object', function() {
|
|
||||||
// initial state
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(1);
|
|
||||||
o2.unbind('k');
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(1);
|
|
||||||
o2.set('k', 2);
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('unbindAll', function() {
|
|
||||||
var o2;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
o2 = new ol.Object();
|
|
||||||
o2.bindTo('k', o);
|
|
||||||
o2.set('k', 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('makes changes to unbound object invisible to other object', function() {
|
|
||||||
// initial state
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(1);
|
|
||||||
o2.unbindAll();
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(1);
|
|
||||||
o2.set('k', 2);
|
|
||||||
expect(o.get('k')).to.eql(1);
|
|
||||||
expect(o2.get('k')).to.eql(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('bind rename', function() {
|
|
||||||
var listener1, o2, listener2;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
o2 = new ol.Object();
|
|
||||||
o2.bindTo('k2', o, 'k1');
|
|
||||||
|
|
||||||
listener1 = sinon.spy();
|
|
||||||
goog.events.listen(o, 'change:k1', listener1);
|
|
||||||
|
|
||||||
listener2 = sinon.spy();
|
|
||||||
goog.events.listen(o2, 'change:k2', listener2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sets the expected properties', function() {
|
|
||||||
o.set('k1', 1);
|
|
||||||
expect(o.get('k1')).to.eql(1);
|
|
||||||
expect(o.get('k2')).to.be(undefined);
|
|
||||||
expect(o2.get('k2')).to.eql(1);
|
|
||||||
expect(o2.get('k1')).to.be(undefined);
|
|
||||||
expect(listener1).to.be.called();
|
|
||||||
expect(listener2).to.be.called();
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['k1']);
|
|
||||||
expect(o2.getKeys()).to.eql(['k2']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('transitive bind', function() {
|
|
||||||
var o2, o3;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
o2 = new ol.Object();
|
|
||||||
o3 = new ol.Object();
|
|
||||||
o2.bindTo('k2', o, 'k1');
|
|
||||||
o3.bindTo('k3', o2, 'k2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sets the expected properties', function() {
|
|
||||||
o.set('k1', 1);
|
|
||||||
expect(o.get('k1')).to.eql(1);
|
|
||||||
expect(o2.get('k2')).to.eql(1);
|
|
||||||
expect(o3.get('k3')).to.eql(1);
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['k1']);
|
|
||||||
expect(o2.getKeys()).to.eql(['k2']);
|
|
||||||
expect(o3.getKeys()).to.eql(['k3']);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('backward', function() {
|
|
||||||
|
|
||||||
it('sets the expected properties', function() {
|
|
||||||
o3.set('k3', 1);
|
|
||||||
expect(o.get('k1')).to.eql(1);
|
|
||||||
expect(o2.get('k2')).to.eql(1);
|
|
||||||
expect(o3.get('k3')).to.eql(1);
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['k1']);
|
|
||||||
expect(o2.getKeys()).to.eql(['k2']);
|
|
||||||
expect(o3.getKeys()).to.eql(['k3']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('circular bind', function() {
|
|
||||||
var o2;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
o2 = new ol.Object();
|
|
||||||
o.bindTo('k', o2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws an error', function() {
|
|
||||||
expect(function() { o2.bindTo('k', o); }).to.throwException();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('priority', function() {
|
|
||||||
var o2;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
o2 = new ol.Object();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('respects set order', function() {
|
|
||||||
o.set('k', 1);
|
|
||||||
o2.set('k', 2);
|
|
||||||
o.bindTo('k', o2);
|
|
||||||
expect(o.get('k')).to.eql(2);
|
|
||||||
expect(o2.get('k')).to.eql(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('respects set order (undefined)', function() {
|
|
||||||
o.set('k', 1);
|
|
||||||
o.bindTo('k', o2);
|
|
||||||
expect(o.get('k')).to.be(undefined);
|
|
||||||
expect(o2.get('k')).to.be(undefined);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setter', function() {
|
describe('setter', function() {
|
||||||
@@ -452,27 +178,12 @@ describe('ol.Object', function() {
|
|||||||
sinon.spy(o, 'setX');
|
sinon.spy(o, 'setX');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('without bind', function() {
|
it('does not call the setter', function() {
|
||||||
it('does not call the setter', function() {
|
o.set('x', 1);
|
||||||
o.set('x', 1);
|
expect(o.get('x')).to.eql(1);
|
||||||
expect(o.get('x')).to.eql(1);
|
expect(o.setX).to.not.be.called();
|
||||||
expect(o.setX).to.not.be.called();
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['x']);
|
expect(o.getKeys()).to.eql(['x']);
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with bind', function() {
|
|
||||||
it('does call the setter', function() {
|
|
||||||
var o2 = new ol.Object();
|
|
||||||
o2.bindTo('x', o);
|
|
||||||
o2.set('x', 1);
|
|
||||||
expect(o.setX).to.be.called();
|
|
||||||
expect(o.get('x')).to.eql(1);
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql(['x']);
|
|
||||||
expect(o2.getKeys()).to.eql(['x']);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -484,29 +195,9 @@ describe('ol.Object', function() {
|
|||||||
sinon.spy(o, 'getX');
|
sinon.spy(o, 'getX');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('without bind', function() {
|
it('does not call the getter', function() {
|
||||||
it('does not call the getter', function() {
|
expect(o.get('x')).to.be(undefined);
|
||||||
expect(o.get('x')).to.be(undefined);
|
expect(o.getX).to.not.be.called();
|
||||||
expect(o.getX).to.not.be.called();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with bind', function() {
|
|
||||||
it('does call the getter', function() {
|
|
||||||
var o2 = new ol.Object();
|
|
||||||
o2.bindTo('x', o);
|
|
||||||
expect(o2.get('x')).to.eql(1);
|
|
||||||
expect(o.getX).to.be.called();
|
|
||||||
|
|
||||||
expect(o.getKeys()).to.eql([]);
|
|
||||||
expect(o2.getKeys()).to.eql(['x']);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('bind self', function() {
|
|
||||||
it('throws an error', function() {
|
|
||||||
expect(function() { o.bindTo('k', o); }).to.throwException();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -538,130 +229,6 @@ describe('ol.Object', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('transforms', function() {
|
|
||||||
|
|
||||||
describe('original states and events', function() {
|
|
||||||
it('bindTo and transform emit propertychange events', function() {
|
|
||||||
var source = new ol.Object();
|
|
||||||
var target = new ol.Object();
|
|
||||||
source.set('x', 1);
|
|
||||||
target.set('x', 2);
|
|
||||||
var sourceSpy = sinon.spy();
|
|
||||||
var targetSpy = sinon.spy();
|
|
||||||
source.on('propertychange', sourceSpy);
|
|
||||||
target.on('propertychange', targetSpy);
|
|
||||||
var accessor = source.bindTo('x', target);
|
|
||||||
expect(sourceSpy.callCount).to.be(1);
|
|
||||||
expect(targetSpy.callCount).to.be(0);
|
|
||||||
expect(source.get('x')).to.be(2);
|
|
||||||
expect(target.get('x')).to.be(2);
|
|
||||||
accessor.transform(function(v) {
|
|
||||||
return v * 2;
|
|
||||||
}, function(v) {
|
|
||||||
return v / 2;
|
|
||||||
});
|
|
||||||
var call, args;
|
|
||||||
expect(sourceSpy.calledTwice).to.be(true);
|
|
||||||
call = sourceSpy.firstCall;
|
|
||||||
expect(call.args).to.have.length(1);
|
|
||||||
expect(call.args[0].key).to.be('x');
|
|
||||||
expect(call.args[0].oldValue).to.be(1);
|
|
||||||
call = sourceSpy.secondCall;
|
|
||||||
expect(call.args).to.have.length(1);
|
|
||||||
expect(call.args[0].key).to.be('x');
|
|
||||||
expect(call.args[0].oldValue).to.be(2);
|
|
||||||
expect(targetSpy.called).to.be(false);
|
|
||||||
expect(source.get('x')).to.be(1);
|
|
||||||
expect(target.get('x')).to.be(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with multiple binds to a single property', function() {
|
|
||||||
|
|
||||||
var original, plusOne, asString;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
original = new ol.Object();
|
|
||||||
original.set('x', 1);
|
|
||||||
plusOne = new ol.Object();
|
|
||||||
plusOne.bindTo('x', original).transform(
|
|
||||||
function(x) { return x - 1; },
|
|
||||||
function(x) { return x + 1; }
|
|
||||||
);
|
|
||||||
asString = new ol.Object();
|
|
||||||
asString.bindTo('x', original).transform(
|
|
||||||
function(x) { return +x; },
|
|
||||||
function(x) { return x + ''; }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the expected value', function() {
|
|
||||||
expect(original.get('x')).to.be(1);
|
|
||||||
expect(plusOne.get('x')).to.be(2);
|
|
||||||
expect(asString.get('x')).to.be('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('allows the original value to be set correctly', function() {
|
|
||||||
original.set('x', 2);
|
|
||||||
expect(plusOne.get('x')).to.be(3);
|
|
||||||
expect(asString.get('x')).to.be('2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('allows the transformed values to be set correctly', function() {
|
|
||||||
plusOne.set('x', 3);
|
|
||||||
expect(original.get('x')).to.be(2);
|
|
||||||
expect(asString.get('x')).to.be('2');
|
|
||||||
asString.set('x', '3');
|
|
||||||
expect(original.get('x')).to.be(3);
|
|
||||||
expect(plusOne.get('x')).to.be(4);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with transitive binds', function() {
|
|
||||||
|
|
||||||
var original, plusOne, plusOneAsString;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
original = new ol.Object();
|
|
||||||
original.set('x', 1);
|
|
||||||
plusOne = new ol.Object();
|
|
||||||
plusOne.bindTo('x', original).transform(
|
|
||||||
function(x) { return x - 1; },
|
|
||||||
function(x) { return x + 1; }
|
|
||||||
);
|
|
||||||
plusOneAsString = new ol.Object();
|
|
||||||
plusOneAsString.bindTo('x', plusOne).transform(
|
|
||||||
parseFloat,
|
|
||||||
function(x) { return x + ''; }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns the expected value', function() {
|
|
||||||
expect(original.get('x')).to.be(1);
|
|
||||||
expect(plusOne.get('x')).to.be(2);
|
|
||||||
expect(plusOneAsString.get('x')).to.be('2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('allows the original value to be set correctly', function() {
|
|
||||||
original.set('x', 2);
|
|
||||||
expect(plusOne.get('x')).to.be(3);
|
|
||||||
expect(plusOneAsString.get('x')).to.be('3');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('allows the transformed values to be set correctly', function() {
|
|
||||||
plusOne.set('x', 3);
|
|
||||||
expect(original.get('x')).to.be(2);
|
|
||||||
expect(plusOneAsString.get('x')).to.be('3');
|
|
||||||
plusOneAsString.set('x', '4');
|
|
||||||
expect(original.get('x')).to.be(3);
|
|
||||||
expect(plusOne.get('x')).to.be(4);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user