Last active
January 31, 2019 13:23
-
-
Save serradura/279ddb7f3aa4a68b5aaf882031f7ffdc to your computer and use it in GitHub Desktop.
jQuery.behavior (Demo: https://jquery-behavior.firebaseapp.com)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>jQuery.behavior</title> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
</head> | |
<body> | |
<a href="01.html">01</a> | <a href="02.html">02</a> | <a href="03.html">03</a> | <a href="04.html">04</a> | <a href="05.html">05</a> | |
<hr> | |
<p> | |
<button data-behavior="greet">Greet</button> | |
</p> | |
<pre class="prettyprint"> | |
<button data-behavior="greet">Greet</button> | |
</pre> | |
<pre class="prettyprint"> | |
var greet = function() { alert('Hello!') }; | |
$.behavior( 'greet' ).on( 'click', greet ); | |
</pre> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.js"></script> --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.js"></script> | |
<script src="./jquery.behavior.js"></script> | |
<script> | |
$(function() { | |
var greet = function() { alert('Hello!') } | |
$.behavior( 'greet' ).on( 'click', greet ); | |
}); | |
</script> | |
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>jQuery.behavior</title> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
</head> | |
<body> | |
<a href="01.html">01</a> | <a href="02.html">02</a> | <a href="03.html">03</a> | <a href="04.html">04</a> | <a href="05.html">05</a> | |
<hr> | |
<p> | |
<button data-behavior="greet-with-name">Greet with Name</button> | |
</p> | |
<pre class="prettyprint"> | |
<button data-behavior="greet-with-name">Greet with Name</button> | |
</pre> | |
<pre class="prettyprint"> | |
var greetWithName = function( event ) { | |
alert( 'Hello ' + event.data + '!' ) | |
}; | |
$.behavior( 'greet-with-name' ) | |
.on( 'click', 'Serradura', greetWithName ); | |
</pre> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.js"></script> --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.js"></script> | |
<script src="./jquery.behavior.js"></script> | |
<script> | |
$(function() { | |
var greetWithName = function( event ) { | |
alert( 'Hello ' + event.data + '!' ) | |
}; | |
$.behavior( 'greet-with-name' ) | |
.on( 'click', 'Serradura', greetWithName ); | |
}); | |
</script> | |
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>jQuery.behavior</title> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
</head> | |
<body> | |
<a href="01.html">01</a> | <a href="02.html">02</a> | <a href="03.html">03</a> (<a href="03a.html">a</a>, <a href="03b.html">b</a>) | <a href="04.html">04</a> | <a href="05.html">05</a> | |
<hr> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
<pre class="prettyprint"> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
</pre> | |
<pre class="prettyprint"> | |
$.behavior( 'counter' ).ifPresent(function( root ) { | |
var state = 0; | |
var updateNumber = function(number) { | |
root.directTarget( 'number' ).text( number ); | |
}; | |
var handleIncrement = function() { | |
updateNumber( state = state + 1 ); | |
}; | |
var handleDecrement = function() { | |
updateNumber( state = state - 1 ); | |
}; | |
root.child( 'increment' ).on( 'click', handleIncrement ); | |
root.child( 'decrement' ).on( 'click', handleDecrement ); | |
}); | |
</pre> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.js"></script> --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.js"></script> | |
<script src="./jquery.behavior.js"></script> | |
<script> | |
$(function() { | |
$.behavior( 'counter' ).ifPresent(function( root ) { | |
var state = 0; | |
var updateNumber = function(number) { | |
root.directTarget( 'number' ).text( number ); | |
}; | |
var handleIncrement = function() { | |
updateNumber( state = state + 1 ); | |
}; | |
var handleDecrement = function() { | |
updateNumber( state = state - 1 ); | |
}; | |
root.child( 'increment' ).on( 'click', handleIncrement ); | |
root.child( 'decrement' ).on( 'click', handleDecrement ); | |
}); | |
}); | |
</script> | |
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>jQuery.behavior</title> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
</head> | |
<body> | |
<a href="01.html">01</a> | <a href="02.html">02</a> | <a href="03.html">03</a> (<a href="03a.html">a</a>, <a href="03b.html">b</a>) | <a href="04.html">04</a> | <a href="05.html">05</a> | |
<hr> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
<pre class="prettyprint"> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
</pre> | |
<pre class="prettyprint"> | |
$.behavior( 'counter' ).ifPresent(function( root ) { | |
var state = 0; | |
var updateNumber = function(number) { | |
root.directTarget( 'number' ).text( number ); | |
}; | |
var handleIncrement = function() { | |
updateNumber( state = state + 1 ); | |
}; | |
var handleDecrement = function() { | |
updateNumber( state = state - 1 ); | |
}; | |
root.child( 'increment' ).on( 'click', handleIncrement ); | |
root.child( 'decrement' ).on( 'click', handleDecrement ); | |
}); | |
</pre> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.js"></script> --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.js"></script> | |
<script src="./jquery.behavior.js"></script> | |
<script> | |
$(function() { | |
$.behavior( 'counter' ).ifPresent(function( root ) { | |
var state = 0; | |
var updateNumber = function(number) { | |
root.directTarget( 'number' ).text( number ); | |
}; | |
var handleIncrement = function() { | |
updateNumber( state = state + 1 ); | |
}; | |
var handleDecrement = function() { | |
updateNumber( state = state - 1 ); | |
}; | |
root.child( 'increment' ).on( 'click', handleIncrement ); | |
root.child( 'decrement' ).on( 'click', handleDecrement ); | |
}); | |
}); | |
</script> | |
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>jQuery.behavior</title> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
</head> | |
<body> | |
<a href="01.html">01</a> | <a href="02.html">02</a> | <a href="03.html">03</a> (<a href="03a.html">a</a>, <a href="03b.html">b</a>) | <a href="04.html">04</a> | <a href="05.html">05</a> | |
<hr> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
<pre class="prettyprint"> | |
<p data-behavior="counter"> | |
<button data-behavior="increment">+</button> | |
<span data-behavior-target="number">0</span> | |
<button data-behavior="decrement">-</button> | |
</p> | |
</pre> | |
<pre class="prettyprint"> | |
$.behavior( 'counter' ).ifPresent(function( root, $root ) { | |
$root.on( 'updateNumber', function(_, number) { | |
root.target( 'number' ).text( number ); | |
}); | |
var setState = function(value) { this.data( 'state', value ) }; | |
var getState = function() { return this.data( 'state' ) || 0 }; | |
var updateNumberWith = function(value) { | |
return function() { | |
var number = getState.call( $root ) + value; | |
setState.call( $root, number ); | |
$root.trigger( 'updateNumber', number ); | |
}; | |
}; | |
var handleClickAndAdd = function(value) { | |
return function() { | |
this.on( 'click', updateNumberWith( value ) ); | |
} | |
}; | |
root.child( 'increment' ).ifPresent( handleClickAndAdd( 1 ) ); | |
root.child( 'decrement' ).ifPresent( handleClickAndAdd( -1 ) ); | |
}); | |
</pre> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.js"></script> --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.js"></script> | |
<script src="./jquery.behavior.js"></script> | |
<script> | |
$(function() { | |
$.behavior( 'counter' ).ifPresent(function( root, $root ) { | |
$root.on( 'updateNumber', function(_, number) { | |
root.target( 'number' ).text( number ); | |
}); | |
var setState = function(value) { this.data( 'state', value ) }; | |
var getState = function() { return this.data( 'state' ) || 0 }; | |
var updateNumberWith = function(value) { | |
return function() { | |
var number = getState.call( $root ) + value; | |
setState.call( $root, number ); | |
$root.trigger( 'updateNumber', number ); | |
}; | |
}; | |
var handleClickAndAdd = function(value) { | |
return function() { | |
this.on( 'click', updateNumberWith( value ) ); | |
} | |
}; | |
root.child( 'increment' ).ifPresent( handleClickAndAdd( 1 ) ); | |
root.child( 'decrement' ).ifPresent( handleClickAndAdd( -1 ) ); | |
}); | |
}); | |
</script> | |
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>jQuery.behavior</title> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<style> | |
.text-red { color: red; } | |
.text-blue { color: blue; } | |
</style> | |
</head> | |
<body> | |
<a href="01.html">01</a> | <a href="02.html">02</a> | <a href="03.html">03</a> | <a href="04.html">04</a> | <a href="05.html">05</a> | |
<hr> | |
<div data-behavior="filters"> | |
<p data-behavior="event-toggler"> | |
Filters: | |
<button data-behavior="enable" class="text-blue" style="display: none;"> | |
Turn on Events | |
</button> | |
<button data-behavior="disable" class="text-red"> | |
Turn off Events | |
</button> | |
</p> | |
<p> | |
<select data-behavior="numbers-filter"> | |
<option value="">Select any number</option> | |
<option value="1">1</option> | |
<option value="2">2</option> | |
</select> | |
</p> | |
<p data-behavior="query-filter"> | |
<input type="text" data-behavior-target="query"> | |
<button type="button" data-behavior="submit-query">Search</button> | |
</p> | |
</div> | |
<pre class="prettyprint"> | |
<div data-behavior="filters"> | |
<p data-behavior="event-toggler"> | |
Filters: | |
<button data-behavior="enable" class="text-blue" style="display: none;"> | |
Turn on Events | |
</button> | |
<button data-behavior="disable" class="text-red"> | |
Turn off Events | |
</button> | |
</p> | |
<p> | |
<select data-behavior="numbers-filter"> | |
<option value="">Select any number</option> | |
<option value="1">1</option> | |
<option value="2">2</option> | |
</select> | |
</p> | |
<p data-behavior="query-filter"> | |
<input type="text" data-behavior-target="query"> | |
<button type="button" data-behavior="submit-query">Search</button> | |
</p> | |
</div> | |
</pre> | |
<pre class="prettyprint"> | |
var NumbersFilter = function( $root ) { | |
var find = function( $root ) { | |
return $.behavior.child( 'numbers-filter' ).of( $root ); | |
}; | |
var mount = function( root ) { | |
find( $root ).on( 'change', function() { | |
var value = $( this ).val(); | |
root.trigger( 'alert', [ 'number', value ] ); | |
}); | |
}; | |
var unmount = function() { find( $root ).off( 'change' ); }; | |
return { mount: mount, unmount: unmount }; | |
}; | |
var QueryFilter = function( root ) { | |
var submitQuery = root.child( 'submit-query' ); | |
var mount = function( filters ) { | |
submitQuery.on( 'click', function( e ) { | |
e.preventDefault(); | |
var value = root.target( 'query' ).val(); | |
filters.trigger( 'alert', [ 'query', value ] ) | |
}) | |
}; | |
var unmount = function() { submitQuery.off( 'click' ) }; | |
return { mount: mount, unmount: unmount }; | |
}; | |
var FiltersComponent = (function() { | |
var filters = $.behavior( 'filters' ); | |
var queryFilter = filters.child( 'query-filter' ); | |
filters.on( 'alert', function( _event, filter, value ) { | |
var filterLabel = 'Filter: ' + filter; | |
if ( value ) return alert( filterLabel + ' | value: ' + value ); | |
console.log( filterLabel + ' | There is nothing to alert. :(' ); | |
}); | |
var mountChildrenComponents = function( filters ) { | |
NumbersFilter( this ).mount( filters ); | |
QueryFilter( queryFilter ).mount( filters ); | |
}; | |
var unmountChildrenComponents = function() { | |
NumbersFilter( this ).unmount(); | |
QueryFilter( queryFilter ).unmount(); | |
}; | |
var mountEventToggler = function( filters ) { | |
filters.child( 'event-toggler' ).ifPresent(function( buttons ) { | |
var disableButton = buttons.child( 'disable' ); | |
var enableButton = buttons.child( 'enable' ); | |
var show = function() { this.show() }; | |
disableButton.on( 'click', function() { | |
if ( confirm( 'Are you sure?' ) ) { | |
$( this ).hide(); | |
filters.ifPresent( unmountChildrenComponents ); | |
enableButton.ifPresent( show ); | |
} | |
}); | |
enableButton.on( 'click', function() { | |
$( this ).hide(); | |
filters.ifPresent( mountChildrenComponents ); | |
disableButton.ifPresent( show ); | |
}); | |
}) | |
}; | |
return { | |
mount: function() { | |
filters.ifPresent( mountChildrenComponents ); | |
filters.ifPresent( mountEventToggler ); | |
} | |
} | |
}()); | |
FiltersComponent.mount(); | |
</pre> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.js"></script> --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.js"></script> | |
<script src="./jquery.behavior.js"></script> | |
<script> | |
$(function() { | |
var NumbersFilter = function( $root ) { | |
var find = function( $root ) { | |
return $.behavior.child( 'numbers-filter' ).of( $root ); | |
}; | |
var mount = function( root ) { | |
find( $root ).on( 'change', function() { | |
var value = $( this ).val(); | |
root.trigger( 'alert', [ 'number', value ] ); | |
}); | |
}; | |
var unmount = function() { find( $root ).off( 'change' ); }; | |
return { mount: mount, unmount: unmount }; | |
}; | |
var QueryFilter = function( root ) { | |
var submitQuery = root.child( 'submit-query' ); | |
var mount = function( filters ) { | |
submitQuery.on( 'click', function( e ) { | |
e.preventDefault(); | |
var value = root.target( 'query' ).val(); | |
filters.trigger( 'alert', [ 'query', value ] ) | |
}) | |
}; | |
var unmount = function() { submitQuery.off( 'click' ) }; | |
return { mount: mount, unmount: unmount }; | |
}; | |
var FiltersComponent = (function() { | |
var filters = $.behavior( 'filters' ); | |
var queryFilter = filters.child( 'query-filter' ); | |
filters.on( 'alert', function( _event, filter, value ) { | |
var filterLabel = 'Filter: ' + filter; | |
if ( value ) return alert( filterLabel + ' | value: ' + value ); | |
console.log( filterLabel + ' | There is nothing to alert. :(' ); | |
}); | |
var mountChildrenComponents = function( filters ) { | |
NumbersFilter( this ).mount( filters ); | |
QueryFilter( queryFilter ).mount( filters ); | |
}; | |
var unmountChildrenComponents = function() { | |
NumbersFilter( this ).unmount(); | |
QueryFilter( queryFilter ).unmount(); | |
}; | |
var mountEventToggler = function( filters ) { | |
filters.child( 'event-toggler' ).ifPresent(function( buttons ) { | |
var disableButton = buttons.child( 'disable' ); | |
var enableButton = buttons.child( 'enable' ); | |
var show = function() { this.show() }; | |
disableButton.on( 'click', function() { | |
if ( confirm( 'Are you sure?' ) ) { | |
$( this ).hide(); | |
filters.ifPresent( unmountChildrenComponents ); | |
enableButton.ifPresent( show ); | |
} | |
}); | |
enableButton.on( 'click', function() { | |
$( this ).hide(); | |
filters.ifPresent( mountChildrenComponents ); | |
disableButton.ifPresent( show ); | |
}); | |
}) | |
}; | |
return { | |
mount: function() { | |
filters.ifPresent( mountChildrenComponents ); | |
filters.ifPresent( mountEventToggler ); | |
} | |
} | |
}()); | |
FiltersComponent.mount(); | |
}); | |
</script> | |
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>jQuery.behavior</title> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
</head> | |
<body class="index"> | |
<a href="01.html">01</a> | <a href="02.html">02</a> | <a href="03.html">03</a> | <a href="04.html">04</a> | <a href="05.html">05</a> | |
<hr> | |
<pre class="prettyprint"> | |
<body class="index"> | |
<!--...--> | |
</body> | |
</pre> | |
<pre class="prettyprint"> | |
var MESSAGE = 'Added after document be ready and because \'.index\' selector was found!'; | |
var awaitAndAppendContent = function() { | |
var $content = $( '<h2>' ).text( MESSAGE ); | |
var appendContent = function() { $( 'body' ).append( $content ) } | |
setTimeout( appendContent, 700 ); | |
} | |
$.behavior.to( '.index' ).ifPresent( awaitAndAppendContent ); | |
</pre> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> --> | |
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.js"></script> --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.js"></script> | |
<script src="./jquery.behavior.js"></script> | |
<script> | |
$(function() { | |
var MESSAGE = 'Added after document be ready and because \'.index\' selector was found!'; | |
var awaitAndAppendContent = function() { | |
var $content = $( '<h2>' ).text( MESSAGE ); | |
var appendContent = function() { $( 'body' ).append( $content ) } | |
setTimeout( appendContent, 700 ); | |
} | |
$.behavior.to( '.index' ).ifPresent( awaitAndAppendContent ); | |
}); | |
</script> | |
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
var buildBehaviorEventHandlers = (function($DELEGATOR) { | |
var EVENT_HANDLERS = ['on', 'one', 'off']; | |
var argumentsToAttachEventHandler = function( behaviorSelector, _arguments ) { | |
var event = _arguments[0]; | |
var tail = $.makeArray( _arguments ).slice( 1 ); | |
// Performs a flatMap because of tail data; | |
return $.map( | |
[ event, behaviorSelector, tail ], function(arg) { return arg } | |
); | |
}; | |
var delegateEventHandling = function( eventHandler, args ) { | |
$DELEGATOR[ eventHandler ].apply( $DELEGATOR, args ); | |
}; | |
// returns a behavior event handler (on, one, off) function. e.g: | |
// behavior('foo').on('event', function() {}) will be equivalent to | |
// $( document ).on( 'event', '[data-bevahior="foo"]', function() {}); | |
var buildEventHandler = function( event, behaviorSelector ) { | |
return function() { | |
var args = argumentsToAttachEventHandler( behaviorSelector, arguments ); | |
delegateEventHandling( event, args ); | |
return this; | |
} | |
}; | |
return function(behaviorSelector) { | |
var behaviorEventHandlers = {}; | |
$.each( EVENT_HANDLERS, function( _, name ) { | |
behaviorEventHandlers[name] = buildEventHandler( name, behaviorSelector ) | |
} ); | |
return behaviorEventHandlers; | |
}; | |
}( $(document) )); | |
var buildBehaviorEventTrigger = function ( $el ) { | |
return { | |
trigger: function() { | |
$el.trigger.apply( $el, arguments ); | |
return this; | |
} | |
}; | |
}; | |
var buildBehaviorSelector = function(name) { | |
return '[data-behavior="' + name + '"]'; | |
}; | |
var mapBehaviors = function( key, $el, strategy, dataAttr, dataKey, result ) { | |
var selectorBase = '[' + dataAttr; | |
var selector = key ? selectorBase + '="' + key + '"]' : selectorBase + ']'; | |
var rel = $el[strategy](selector).map(function(_, target) { | |
var data = {}, $this = $( target ), dataVal = $this.data( dataKey ); | |
data[dataVal] = result( $this, dataAttr, dataVal ); | |
return data; | |
}); | |
var result = $.extend.apply( null, [ {} ].concat( rel.get() ) ); | |
return result && result !== window ? result : {}; | |
}; | |
var mapBehaviorsWith = function( strategy ) { | |
return function( $el , key ) { | |
return mapBehaviors( | |
key, $el, strategy, 'data-behavior', 'behavior', | |
function( $el, dataAttr, dataVal ) { | |
return createBehavior( '[' + dataAttr + '="' + dataVal + '"]', $el, true ) | |
} | |
) | |
} | |
}; | |
var mapBehaviorTargetsWith = function( strategy ) { | |
return function( $el, key ) { | |
return mapBehaviors( | |
key, $el, strategy, 'data-behavior-target', 'behaviorTarget', | |
function( $el ) { return $el } | |
) | |
} | |
}; | |
var fetchBehaviorElements = function( mapper, $el ) { | |
return function( key ) { | |
var data = mapper( $el, key ); | |
return key ? data[key] : data; | |
} | |
}; | |
var buildBehaviorElementFetchers = function( $el ) { | |
return { | |
child: fetchBehaviorElements( mapBehaviorsWith('find'), $el ), | |
target: fetchBehaviorElements( mapBehaviorTargetsWith('find'), $el ), | |
directChild: fetchBehaviorElements( mapBehaviorsWith('children'), $el ), | |
directTarget: fetchBehaviorElements( mapBehaviorTargetsWith('children'), $el ), | |
children: function() { return this.child() }, | |
targets: function() { return this.target() }, | |
directChildren: function() { return this.directChild() }, | |
directTargets: function() { return this.directTarget() } | |
} | |
}; | |
var buildBehavior = function( $el, selector ) { | |
var eventHandlers = buildBehaviorEventHandlers( selector ); | |
var eventTrigger = buildBehaviorEventTrigger( $el ); | |
var fetchers = buildBehaviorElementFetchers( $el ); | |
var base = { | |
selector: selector, | |
isPresent: function() { return $el.length > 0 }, | |
ifPresent: function( fn ) { | |
if ( this.isPresent() ) { | |
$el.each(function(index) { | |
var $matched = $( this ); | |
var newBehavior = buildBehavior( $matched, selector ); | |
var args = [ newBehavior, $matched, index ]; | |
fn.apply( $matched, args); | |
}) | |
} | |
} | |
}; | |
return $.extend( base, fetchers, eventTrigger, eventHandlers ); | |
}; | |
var createBehavior = function(selector, $behavior) { | |
var $el = $behavior || $( selector ); | |
return buildBehavior( $el, selector ); | |
}; | |
var behaviorNodeFinder = function( nodeFinder ) { | |
return function( name ) { | |
var findBehaviorNode = function( el ) { | |
var $el = $( el ); | |
var selector = buildBehaviorSelector( name ); | |
var $node = nodeFinder.call( $el, selector ); | |
if ( $node.length ) { | |
var behavior = createBehavior( selector, $node ); | |
return $.extend( behavior, buildBehaviorEventTrigger( $node ) ); | |
} | |
}; | |
return { of: findBehaviorNode }; | |
} | |
}; | |
$.behavior = function( name ) { | |
return createBehavior( buildBehaviorSelector( name ) ) | |
}; | |
$.behavior.to = createBehavior; | |
$.behavior.child = behaviorNodeFinder( function(selector) { | |
return this.find(selector) | |
} ); | |
$.behavior.parent = behaviorNodeFinder( function(selector) { | |
return this.parents(selector) | |
} ); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment