11. Beautiful
Italics are stylized cursive writings –
as if we write by hand. They have
different shapes than roman/regular
● Obliques look like slanted
roman/regular – poor man's italics
●
14. How Can We Use Them? Web Fonts!
<style type="text/css">
@font-face {
font-family: lmr;
src: url(lmrtest-regular.otf);
}
@font-face {
font-family: lmr;
font-style: italic;
src: url(lmrtest-italic.otf);
}
@font-face {
font-family: lmr;
font-style: oblique;
src: url(lmrtest-oblique.otf);
}
</style>
<div style="font-family:lmr">
<p style="font-style:normal">
Roman
</p>
<p style="font-style:italic">
Italic
</p>
<p style="font-style:oblique">
Oblique
</p>
</div>
15. How Can We Find The Bold And The Beautiful?
function isBold(el){
var w = jQuery(el).css('font-weight');
return ('bold' === w) || (400 < (+w));
}
function isSlanted(el){
var s = jQuery(el).css('font-style');
return ('italic' === s) || ('oblique' === s) ;
}
16. Sorry Mario, Our Princess is in Another Castle
●
●
●
We did not find the elements
We can just check whether a particular element is what we are
interested in
So we use it like this and create functions time and again:
jQuery('selector …').filter(function(i){
return isBold(i);
});
17. A Slight Improvement
function bold4jQ(){
var w = jQuery(this).css('font-weight');
return ('bold' === w) || (400 < (+w));
}
jQuery('selector …').filter(bold4jQ);
function slanted4jQ(){
var s = jQuery(this).css('font-style');
return ('italic' === s) || ('oblique' === s);
}
jQuery('selector …').filter(slanted4jQ);
18. (You Gotta) Fight For Your Right (to jQuery)
●
●
●
Why do this imperatively and explicitly call time and agang the
same functions?
jQuery has its own selector engine, why not use it to
accomplish our needs
Let's be declarative – which is more readable?
jQuery('selector …').filter(bold4jQ);
jQuery('selector …').filter(slanted4jQ);
jQuery('selector:bold');
jQuery('selector:slanted');
20. This Is How We Do It
jQuery.extend(jQuery.expr[':'], {
bold: function(el) {
var w = jQuery(el).css('font-weight');
return ('bold' === w) || (400 < (+w));
}
});
jQuery('div:bold');
jQuery.extend(jQuery.expr[':'], {
slanted: function(el) {
var s = jQuery(el).css('font-style');
return ('italic' === s) || ('oblique' === s);
}
});
jQuery('#editor span.usr:slanted');
21. Homework Asignments
●
Find external links
●
Find links that lead to ASPX or JSP pages directly
●
Find divs with sizes above 42px
●
Find spans that are block elements or divs that are inline
●
The sky is the limit
22. Is This All There Is?
●
We are not limited to no args functions. The function we provide
is called with 3 arguments. We can dispatch behaviour based
on all of them
/* returns boolean - whether given DOM
* element matches
matcher(
/* single DOMElement from currenlty
* matched set to check
DOMElement,
/* index of the current element in
* in the matched set
index,
/* array of the split matching
* sequence
matches);
*
*/
*
*/
*
*/
*
*/
23. Positional Parameters Example Usage
jQuery('selector…:font(14,400,italic)');
m = ['font', 'font', '', '14,400,italic'];
24. Positional Parameters Example Usage
jQuery('selector…:font(14,400,italic)');
m = ['font', 'font', '', '14,400,italic'];
m[3] === '14,400,italic';
26. Positional Parameters Example Usage
jQuery.extend(jQuery.expr[':'], {
font: function(el, i, m){
var a = m[3].split(','), // dispatch
l = a.length,
// dispatch
j = jQuery(el),
// cache
p = ['size', 'weight', 'style'],
z = 0;
// index
if(0 === l){return true;}
if(3
< l){throw {name:'Funky', message:'Nuts?'};}
// or return false and fail silently
for(;z<l;++z){if(j.css('font-'+p[z])!=a[z]){return false;}}
return true;
}});
27. Named Parameters Example Usage
jQuery('selector…:font' +
'(size>14,400<=weight,italic!=style,family!=Sans)'
m = ['font', 'font', '',
'size>14,400<=weight,italic!=style,family!=Sans'
28. Named Parameters Example Usage
jQuery('selector…:font' +
'(size>14,400<=weight,italic!=style,family!=Sans)'
m = ['font', 'font', '',
'size>14,400<=weight,italic!=style,family!=Sans'
m[3] === // what to do, what to do?
'size>14,400<=weight,italic!=style,family!=Sans'
33. Named Parameters Example Usage
// split, split, juggle & check
'size>14,400<=weight,italic!=style,family!=Sans'
// split, juggle & check
['size>14','400<=weight','italic!=style','family!=Sans']
[['size','>','14'
],
['400','<=','weight' ],
['italic','!=','style'],
['family','!=','Sans' ]]
[['family','!=','Sans'
['size' ,'>' ,'14'
['style' ,'!=','italic'
['weight','<=','400'
// juggle & check
],
],
],
]]
// check left as an
// excercise for the
// reader
34. Named Parameters Example Usage
Getting Jiggy With It
m[3] === // be creative
'size>14,400<=weight,italic!=style,family!=Sans'
'size>14,400<=weight,italic!=style,family!=Sans'
35. Named Parameters Example Usage
Getting Jiggy With It
m[3] === // be creative
'size>14,400<=weight,italic!=style,family!=Sans'
'size>14,400<=weight,italic!=style,family!=Sans'
'size>14,400<=weight,italic!=style,family!=Sans'.
replace(/,/g,'&&') === ???
36. Named Parameters Example Usage
Getting Jiggy With It
m[3] === // be creative
'size>14,400<=weight,italic!=style,family!=Sans'
'size>14,400<=weight,italic!=style,family!=Sans'
'size>14,400<=weight,italic!=style,family!=Sans'.
replace(/,/g,'&&') === ???
"size>14&&400<=weight&&italic!=style&&family!=Sans"
37. Looks familiar, doesnt' it?
var expression =
"size>14&&400<=weight&&italic!=style&&family!=Sans";
●
But what are size, weight, style, family?
●
What about italic and Sans?
38. But We Already Know That
size:
weight:
style:
family:
j.css('font-size')
j.css('font-weight')
j.css('font-style')
j.css('font-family')
italic: 'italic',
Sans:
'Sans'
39. Why Didn't You Say So?
var scope = {
size:
weight:
style:
family:
j.css('font-size'),
j.css('font-weight'),
j.css('font-style'),
j.css('font-family'),
italic: 'italic',
Sans:
'Sans'};
41. Now That You Know How
●
DON'T!!!
●
Use to explore, you brave explorers.
●
Use in production is misuse – will void your warranty, kill kittens
and cause plague.
42. So What Is The Catch?
●
Quick to implement, experiment, POC;
●
Piggyback on JavaScript as a host for the DSL;
●
●
●
Hard to debug, with weird error messages in strange places – still
we are in control of the scope template and this can be mitigated;
Blocks browser's JS optimization engine (but we are not the only
ones);
Jslint will complain – we are treading in one of the the darkest
places in the language.
43. How Do You Say De-Groovie?
How Do You Say De-Bug?
jQuery('selector…:debug');
jQuery.extend(jQuery.expr[':'], {
debug: function(el, i, m) {
console.log("args: %o", arguments);
console.log("m: %o", m);
return true;
}
});
44. The Power Of Their Source? The Crystal!
https://github.com/jquery/jquery/blob/master/src/selector-sizzle.js
define(["./core", "sizzle"],
function( jQuery, Sizzle ) {
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;
jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
});
46. Sizzle, Who the (BLEEP) is Sizzle?
●
●
Sizzle: A pure-JavaScript CSS selector engine designed to be
easily dropped in to a host library.
Embedded in jQuery, MooTools, Dojo
Version Supported browsers
LOC
Minified API
jQuery 1.10.2
IE6+, FF(Current-1)+, Chrome(Current≈10k
1)+, Safari 5.1+, Opera 12.1x, (Current-1)+
≈93kB
Vast
jQuery 2.0.3
IE9+, FF(Current-1)+, Chrome(Current≈9k
1)+, Safari 5.1+, Opera 12.1x, (Current-1)+
≈84kB
Vast
Sizzle
IE6+, FF3.0+, Chrome 5+, Safari 3+,
Opera 9+
≈18kB
Tiny
1.10.1x
≈2k
47. Sizzle API – part 1
/* returns boolean - whether given DOM
* element matches selector
* If available uses native matchesSelector
Sizzle.matchesSelector(
/* DOMElement to check
DOMElement,
/* String – CSS Selector
selector);
*
*
*/
*/
*/
48. Sizzle API – part 2
/* returns Array of the elements that match
* the selector
Sizzle.matches(
/* String – CSS Selector
selector,
/* Array of DOMElements
elements);
*
*/
*/
*/
49. Sizzle API – part 3
/* Return nodes that match selector
* [starting from the context node]
* as an array [or added to the provided
*
array-like object]
Sizzle(
/* String – CSS Selector
selector,
/* Optional: DOMElement|DOMDocument
* Default: Current document
* Node to start the search from
context,
/* Optional: Array-like object to
*
add elements to
*
eg.: jQuery() obj
* Default: Create new array
results);
*/
*/
*
*
*/
*
*
*
*/
51. Do It Very Slowly (True Lies)
●
●
document.querySelectorAll is very fast and meddles with
our meddling
Get rid of it!
document.querySelectorAll = null; // or any falsy
// why not?
delete document.querySelectorAll;
52. Alien
●
querySelectorAll (as well as querySelector) comes from
elsewhere – from the prototype world
●
Prototype world is wilder that the West!
●
Object.getPrototypeOf() – IE, Chrome, Firefox
●
{}.__proto__ – Firefox, Chome
57. What We Used Thus Far
// Thus far we actually extended
Sizzle.selectors.pseudos;
//jQuery does some magic to ease using
Sizzle.selectors.createPseudo(function(){});
58. Where Next
// Matches parts of selector (as string)
// divides in parts
Sizzle.selectors.match.NAME = new RegExp('...');
Sizzle.selectors.find.NAME = function(
// what was matched above
match,
// element to start search from
context,
// whether doc is XML/HTML
IsXML ) {};
// regex of orders, add |NAME to it
Sizzle.selectors.order;
59. Where Next
// quick prefilter, eg: remove all attributes or
// elements based on a quick decision
Sizzle.selectors.preFilter.NAME =
function( match ) {};
// slow filter invoked after the one above (if ∃)
// real evaluation
Sizzle.selectors.filter.NAME =
function(element, m1, m2, m3 ) {};
60. Sizzle is extensible
●
No extension tests in test harness;
●
Dragons around the corers, YMMV;
●
●
Looooooooooooooooo + ooooooooooooo + oooo + oooooo +
oooooooo + oooooo + ooooooooooooooooooooooooooo +
oooooooo + ooooooooooo + ooooong regular expressions;
Actual regular expressions are longer.