Skip to content

Commit

Permalink
Merge 92fedd2 into c300e6a
Browse files Browse the repository at this point in the history
  • Loading branch information
pencilcheck committed May 6, 2015
2 parents c300e6a + 92fedd2 commit 7d0d823
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 2 deletions.
215 changes: 215 additions & 0 deletions app/volt/assets/js/volt_watch.js
@@ -0,0 +1,215 @@
/*
* Watch Event Listener
*
* @author Darcy Clarke
* Modified by Penn Su
*
* Copyright (c) 2014 Darcy Clarke
* Dual licensed under the MIT and GPL licenses.
*
* Usage:
* watch(element, 'width height', function(){
* console.log(this.style.width, this.style.height);
* });
*/

(function (window) {

var toArray;
var eqlArrays;

// http://jsfiddle.net/moagrius/YxzfV/
Array.prototype.multisplice = function(){
var args = Array.apply(null, arguments);
args.sort(function(a,b){
return a - b;
});
for(var i = 0; i < args.length; i++){
var index = args[i] - i;
this.splice(index, 1);
}
}

// Object to Array
toArray = function (obj) {

var arr = [];

for (var i = obj.length >>> 0; i--;) {
arr[i] = obj[i];
}

return arr;

};

eqlArrays = function (a, b) {
a.length == b.length && a.every(function (e, i) { e === b[i] });
}

var _watch = function (elements, props, options, callback){

// Setup
var self = this;
var check;

// Check if we should fire callback
check = function (e) {

var self = this;

for (var i = 0; i < self.watching.length; i++) {

var data = self.watching[i];
var changed = true;
var temp;

// Iterate through properties
for (var j = 0; j < data.props.length; j++) {
temp = self.attributes[data.props[j]] || self.style[data.props[j]];
if (data.vals[j] != temp) {
data.vals[j] = temp;
data.changed[j] = true;
}
}

// Check changed attributes
for (var k = 0; k < data.props.length; k++) {
if (!data.changed[k]) {
changed = false;
break;
}
}

// Run callback if property has changed
if (changed && data.callback) {
data.callback.apply(self, e);
}

};

};

// Elements from node list to array
elements = toArray(elements);

// Type check options
if (typeof(options) == 'function') {
callback = options;
options = {};
}

// Type check callback
if (typeof(callback) != 'function') {
callback = function(){};
}

// Set throttle
options.throttle = options.throttle || 10;

// Iterate over elements
for (var i = 0; i < elements.length; i++) {

var element = elements[i];
var data = {
props: props.split(' '),
vals: [],
changed: [],
callback: callback
};

// Grab each property's initial value
for (var j = 0; j < data.props.length; j++) {
data.vals[j] = element.attributes[data.props[j]] || element.style[data.props[j]];
data.changed[j] = false;
}

// Set watch array
if (!element.watching) {
element.watching = [];
}

// Store data in watch array
element.watching.push(data);

// Create new Mutation Observer
var observer = new MutationObserver(function (mutations) {
console.log(mutations);
for (var k = 0; k < mutations.length; k++) {
check.call(mutations[k].target, mutations[k]);
}
});

// Set observer array
if (!element.observers) {
element.observers = [];
}

// Store element observer
element.observers.push(observer);

// Start observing
observer.observe(element, { subtree: false, attributes: true });

}

// Return elements to enable chaining
return self;

};

var _unwatch = function (elements, props){

// Setup
var self = this;

// Elements from node list to array
elements = toArray(elements);

// Iterate over elements
for (var i = 0; i < elements.length; i++) {

var element = elements[i];
var indexes = []

for (var j = 0; j < element.watching.length; j++) {

var data = element.watching[j];
if (eqlArrays(data.props, props.split(' '))) {
indexes.push(j);
}

}

element.watching.multisplice.apply(element.watching, indexes);

}

// Return elements to enable chaining
return self;

};

// Expose watch to window
window.watch = function () {
return _watch.apply(arguments[0], arguments);
};

window.unwatch = function () {
return _unwatch.apply(arguments[0], arguments);
};

// Expose watch to jQuery
(function ($) {
$.fn.watch = function () {
Array.prototype.unshift.call(arguments, this);
return _watch.apply(this, arguments);
};

$.fn.unwatch = function () {
Array.prototype.unshift.call(arguments, this);
return _unwatch.apply(this, arguments);
};
})(jQuery);

})(window);
12 changes: 11 additions & 1 deletion lib/volt/page/bindings/attribute_binding.rb
Expand Up @@ -26,6 +26,8 @@ def setup
update(result)
end

@is_check = `#{element}.is('select')`
@is_hidden = `#{element}.is('[type=hidden]')`
@is_radio = `#{element}.is('[type=radio]')`
if @is_radio
@selected_value = `#{element}.attr('value') || ''`
Expand All @@ -35,7 +37,13 @@ def setup
case @attribute_name
when 'value'
changed_event = Proc.new { changed }
`#{element}.on('input.attrbind', #{changed_event})`
if @is_check
`#{element}.on('change', #{changed_event})`
elsif @is_hidden
`#{element}.watch('value', #{changed_event})`
else
`#{element}.on('input.attrbind', #{changed_event})`
end
when 'checked'
changed_event = Proc.new { |event| changed(event) }
`#{element}.on('change.attrbind', #{changed_event})`
Expand Down Expand Up @@ -131,6 +139,8 @@ def remove
case @attribute_name
when 'value'
`#{element}.off('input.attrbind', #{nil})`
`#{element}.off('change')`
`#{element}.unwatch('value')`
when 'checked'
`#{element}.off('change.attrbind', #{nil})`
end
Expand Down
2 changes: 1 addition & 1 deletion spec/server/rack/asset_files_spec.rb
Expand Up @@ -19,7 +19,7 @@
it 'should list all JS files' do
main = Volt::AssetFiles.new('main', @component_paths)

expect(main.javascript_files(nil)).to eq(['/assets/js/jquery-2.0.3.js', '/assets/js/volt_js_polyfills.js', '/assets/js/bootstrap.js', '/assets/js/test2.js', '/assets/js/test3.js', '/assets/js/test1.js', '/assets/volt/page/page.js', '/components/main.js'])
expect(main.javascript_files(nil)).to eq(['/assets/js/jquery-2.0.3.js', '/assets/js/volt_js_polyfills.js', '/assets/js/volt_watch.js', '/assets/js/bootstrap.js', '/assets/js/test2.js', '/assets/js/test3.js', '/assets/js/test1.js', '/assets/volt/page/page.js', '/components/main.js'])
end

it 'should raise an exception for a missing component gem' do
Expand Down

0 comments on commit 7d0d823

Please sign in to comment.