mirror of
https://github.com/boostorg/website.git
synced 2026-01-19 04:42:17 +00:00
Fix .htc line endings.
I'm not sure if they have to be CRLF endings, but they were in subversion.
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -57,6 +57,7 @@ configure eol=lf svneol=LF#text/x-sh
|
||||
*.cmake text svneol=native#text/plain
|
||||
*.css text svneol=native#text/css
|
||||
*.dtd text svneol=native#text/xml
|
||||
*.htc eol=crlf
|
||||
*.htm text svneol=native#text/html
|
||||
*.html text svneol=native#text/html
|
||||
*.ini text svneol=native#text/plain
|
||||
|
||||
@@ -1,262 +1,262 @@
|
||||
<public:attach event="ondocumentready" onevent="CSSHover()" />
|
||||
<script>
|
||||
// <?)|(a([^#.][^ ]+)+)):(hover|active|focus))/i,
|
||||
REG_AFFECTED = /(.*?)\:(hover|active|focus)/i,
|
||||
REG_PSEUDO = /[^:]+:([a-z-]+).*/i,
|
||||
REG_SELECT = /(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi,
|
||||
REG_CLASS = /\.([a-z0-9_-]*on(hover|active|focus))/i,
|
||||
REG_MSIE = /msie (5|6|7)/i,
|
||||
REG_COMPAT = /backcompat/i;
|
||||
|
||||
// css prefix, a leading dash would be nice (spec), but IE6 doesn't like that.
|
||||
var CSSHOVER_PREFIX = 'csh-';
|
||||
|
||||
/**
|
||||
* Local CSSHover object
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
var CSSHover = {
|
||||
|
||||
// array of CSSHoverElements, used to unload created events
|
||||
elements: [],
|
||||
|
||||
// buffer used for checking on duplicate expressions
|
||||
callbacks: {},
|
||||
|
||||
// init, called once ondomcontentready via the exposed window.CSSHover function
|
||||
init:function() {
|
||||
// don't run in IE8 standards; expressions don't work in standards mode anyway,
|
||||
// and the stuff we're trying to fix should already work properly
|
||||
if(!REG_MSIE.test(navigator.userAgent) && !REG_COMPAT.test(window.document.compatMode)) return;
|
||||
|
||||
// start parsing the existing stylesheets
|
||||
var sheets = window.document.styleSheets, l = sheets.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.parseStylesheet(sheets[i]);
|
||||
}
|
||||
},
|
||||
|
||||
// called from init, parses individual stylesheets
|
||||
parseStylesheet:function(sheet) {
|
||||
// check sheet imports and parse those recursively
|
||||
if(sheet.imports) {
|
||||
try {
|
||||
var imports = sheet.imports, l = imports.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.parseStylesheet(sheet.imports[i]);
|
||||
}
|
||||
} catch(securityException){
|
||||
// trycatch for various possible errors,
|
||||
// todo; might need to be placed inside the for loop, since an error
|
||||
// on an import stops following imports from being processed.
|
||||
}
|
||||
}
|
||||
|
||||
// interate the sheet's rules and send them to the parser
|
||||
try {
|
||||
var rules = sheet.rules, l = rules.length;
|
||||
for(var j=0; j<l; j++) {
|
||||
this.parseCSSRule(rules[j], sheet);
|
||||
}
|
||||
} catch(securityException){
|
||||
// trycatch for various errors, most likely accessing the sheet's rules,
|
||||
// don't see how individual rules would throw errors, but you never know.
|
||||
}
|
||||
},
|
||||
|
||||
// magic starts here ...
|
||||
parseCSSRule:function(rule, sheet) {
|
||||
|
||||
// The sheet is used to insert new rules into, this must be the same sheet the rule
|
||||
// came from, to ensure that relative paths keep pointing to the right location.
|
||||
|
||||
// only parse a rule if it contains an interactive pseudo.
|
||||
var select = rule.selectorText;
|
||||
if(REG_INTERACTIVE.test(select)) {
|
||||
var style = rule.style.cssText,
|
||||
|
||||
// affected elements are found by truncating the selector after the interactive pseudo,
|
||||
// eg: "div li:hover" >> "div li"
|
||||
affected = REG_AFFECTED.exec(select)[1],
|
||||
|
||||
// that pseudo is needed for a classname, and defines the type of interaction (focus, hover, active)
|
||||
// eg: "li:hover" >> "onhover"
|
||||
pseudo = select.replace(REG_PSEUDO, 'on$1'),
|
||||
|
||||
// the new selector is going to use that classname in a new css rule,
|
||||
// since IE6 doesn't support multiple classnames, this is merged into one classname
|
||||
// eg: "li:hover" >> "li.onhover", "li.folder:hover" >> "li.folderonhover"
|
||||
newSelect = select.replace(REG_SELECT, '.$2' + pseudo),
|
||||
|
||||
// the classname is needed for the events that are going to be set on affected nodes
|
||||
// eg: "li.folder:hover" >> "folderonhover"
|
||||
className = REG_CLASS.exec(newSelect)[1];
|
||||
|
||||
// no need to set the same callback more than once when the same selector uses the same classname
|
||||
var hash = affected + className;
|
||||
if(!this.callbacks[hash]) {
|
||||
|
||||
// affected elements are given an expression under a fake css property, the classname is used
|
||||
// because a unique name (eg "behavior:") would be overruled (in IE6, not 7) by a following rule
|
||||
// selecting the same element. The expression does a callback to CSSHover.patch, rerouted via the
|
||||
// exposed window.CSSHover function.
|
||||
|
||||
// because the expression is added to the stylesheet, and styles are always applied to html that is
|
||||
// dynamically added to the dom, the expression will also trigger for those new elements (provided
|
||||
// they are selected by the affected selector).
|
||||
|
||||
sheet.addRule(affected, CSSHOVER_PREFIX + className + ':expression(CSSHover(this, "'+pseudo+'", "'+className+'"))');
|
||||
|
||||
// hash it, so an identical selector/class combo does not duplicate the expression
|
||||
this.callbacks[hash] = true;
|
||||
}
|
||||
|
||||
// duplicate expressions need not be set, but the style could differ
|
||||
sheet.addRule(newSelect, style);
|
||||
}
|
||||
},
|
||||
|
||||
// called via the expression, patches individual nodes
|
||||
patch:function(node, type, className) {
|
||||
|
||||
// the patch's type is returned to the expression. That way the expression property
|
||||
// can be found and removed, to stop it from calling patch over and over.
|
||||
// The if will fail the first time, since the expression has not yet received a value.
|
||||
var property = CSSHOVER_PREFIX + className;
|
||||
if(node.style[property]) {
|
||||
node.style[property] = null;
|
||||
}
|
||||
|
||||
// just to make sure, also keep track of patched classnames locally on the node
|
||||
if(!node.csshover) node.csshover = [];
|
||||
|
||||
// and check for it to prevent duplicate events with the same classname from being set
|
||||
if(!node.csshover[className]) {
|
||||
node.csshover[className] = true;
|
||||
|
||||
// create an instance for the given type and class
|
||||
var element = new CSSHoverElement(node, type, className);
|
||||
|
||||
// and store that instance for unloading later on
|
||||
this.elements.push(element);
|
||||
}
|
||||
|
||||
// returns a dummy value to the expression
|
||||
return type;
|
||||
},
|
||||
|
||||
// unload stuff onbeforeunload
|
||||
unload:function() {
|
||||
try {
|
||||
|
||||
// remove events
|
||||
var l = this.elements.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.elements[i].unload();
|
||||
}
|
||||
|
||||
// and set properties to null
|
||||
this.elements = [];
|
||||
this.callbacks = {};
|
||||
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// add the unload to the onbeforeunload event
|
||||
window.attachEvent('onbeforeunload', function(){
|
||||
CSSHover.unload();
|
||||
});
|
||||
|
||||
/**
|
||||
* CSSHoverElement
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
// the event types associated with the interactive pseudos
|
||||
var CSSEvents = {
|
||||
onhover: { activator: 'onmouseenter', deactivator: 'onmouseleave' },
|
||||
onactive: { activator: 'onmousedown', deactivator: 'onmouseup' },
|
||||
onfocus: { activator: 'onfocus', deactivator: 'onblur' }
|
||||
};
|
||||
|
||||
// CSSHoverElement constructor, called via CSSHover.patch
|
||||
function CSSHoverElement(node, type, className) {
|
||||
|
||||
// the CSSHoverElement patches individual nodes by manually applying the events that should
|
||||
// have fired by the css pseudoclasses, eg mouseenter and mouseleave for :hover.
|
||||
|
||||
this.node = node;
|
||||
this.type = type;
|
||||
var replacer = new RegExp('(^|\\s)'+className+'(\\s|$)', 'g');
|
||||
|
||||
// store event handlers for removal onunload
|
||||
this.activator = function(){ node.className += ' ' + className; };
|
||||
this.deactivator = function(){ node.className = node.className.replace(replacer, ' '); };
|
||||
|
||||
// add the events
|
||||
node.attachEvent(CSSEvents[type].activator, this.activator);
|
||||
node.attachEvent(CSSEvents[type].deactivator, this.deactivator);
|
||||
}
|
||||
|
||||
CSSHoverElement.prototype = {
|
||||
// onbeforeunload, called via CSSHover.unload
|
||||
unload:function() {
|
||||
|
||||
// remove events
|
||||
this.node.detachEvent(CSSEvents[this.type].activator, this.activator);
|
||||
this.node.detachEvent(CSSEvents[this.type].deactivator, this.deactivator);
|
||||
|
||||
// and set properties to null
|
||||
this.activator = null;
|
||||
this.deactivator = null;
|
||||
this.node = null;
|
||||
this.type = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Public hook
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
return function(node, type, className) {
|
||||
if(node) {
|
||||
// called via the css expression; patches individual nodes
|
||||
return CSSHover.patch(node, type, className);
|
||||
} else {
|
||||
// called ondomcontentready via the public:attach node
|
||||
CSSHover.init();
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
// ]]>
|
||||
<public:attach event="ondocumentready" onevent="CSSHover()" />
|
||||
<script>
|
||||
// <?)|(a([^#.][^ ]+)+)):(hover|active|focus))/i,
|
||||
REG_AFFECTED = /(.*?)\:(hover|active|focus)/i,
|
||||
REG_PSEUDO = /[^:]+:([a-z-]+).*/i,
|
||||
REG_SELECT = /(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi,
|
||||
REG_CLASS = /\.([a-z0-9_-]*on(hover|active|focus))/i,
|
||||
REG_MSIE = /msie (5|6|7)/i,
|
||||
REG_COMPAT = /backcompat/i;
|
||||
|
||||
// css prefix, a leading dash would be nice (spec), but IE6 doesn't like that.
|
||||
var CSSHOVER_PREFIX = 'csh-';
|
||||
|
||||
/**
|
||||
* Local CSSHover object
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
var CSSHover = {
|
||||
|
||||
// array of CSSHoverElements, used to unload created events
|
||||
elements: [],
|
||||
|
||||
// buffer used for checking on duplicate expressions
|
||||
callbacks: {},
|
||||
|
||||
// init, called once ondomcontentready via the exposed window.CSSHover function
|
||||
init:function() {
|
||||
// don't run in IE8 standards; expressions don't work in standards mode anyway,
|
||||
// and the stuff we're trying to fix should already work properly
|
||||
if(!REG_MSIE.test(navigator.userAgent) && !REG_COMPAT.test(window.document.compatMode)) return;
|
||||
|
||||
// start parsing the existing stylesheets
|
||||
var sheets = window.document.styleSheets, l = sheets.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.parseStylesheet(sheets[i]);
|
||||
}
|
||||
},
|
||||
|
||||
// called from init, parses individual stylesheets
|
||||
parseStylesheet:function(sheet) {
|
||||
// check sheet imports and parse those recursively
|
||||
if(sheet.imports) {
|
||||
try {
|
||||
var imports = sheet.imports, l = imports.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.parseStylesheet(sheet.imports[i]);
|
||||
}
|
||||
} catch(securityException){
|
||||
// trycatch for various possible errors,
|
||||
// todo; might need to be placed inside the for loop, since an error
|
||||
// on an import stops following imports from being processed.
|
||||
}
|
||||
}
|
||||
|
||||
// interate the sheet's rules and send them to the parser
|
||||
try {
|
||||
var rules = sheet.rules, l = rules.length;
|
||||
for(var j=0; j<l; j++) {
|
||||
this.parseCSSRule(rules[j], sheet);
|
||||
}
|
||||
} catch(securityException){
|
||||
// trycatch for various errors, most likely accessing the sheet's rules,
|
||||
// don't see how individual rules would throw errors, but you never know.
|
||||
}
|
||||
},
|
||||
|
||||
// magic starts here ...
|
||||
parseCSSRule:function(rule, sheet) {
|
||||
|
||||
// The sheet is used to insert new rules into, this must be the same sheet the rule
|
||||
// came from, to ensure that relative paths keep pointing to the right location.
|
||||
|
||||
// only parse a rule if it contains an interactive pseudo.
|
||||
var select = rule.selectorText;
|
||||
if(REG_INTERACTIVE.test(select)) {
|
||||
var style = rule.style.cssText,
|
||||
|
||||
// affected elements are found by truncating the selector after the interactive pseudo,
|
||||
// eg: "div li:hover" >> "div li"
|
||||
affected = REG_AFFECTED.exec(select)[1],
|
||||
|
||||
// that pseudo is needed for a classname, and defines the type of interaction (focus, hover, active)
|
||||
// eg: "li:hover" >> "onhover"
|
||||
pseudo = select.replace(REG_PSEUDO, 'on$1'),
|
||||
|
||||
// the new selector is going to use that classname in a new css rule,
|
||||
// since IE6 doesn't support multiple classnames, this is merged into one classname
|
||||
// eg: "li:hover" >> "li.onhover", "li.folder:hover" >> "li.folderonhover"
|
||||
newSelect = select.replace(REG_SELECT, '.$2' + pseudo),
|
||||
|
||||
// the classname is needed for the events that are going to be set on affected nodes
|
||||
// eg: "li.folder:hover" >> "folderonhover"
|
||||
className = REG_CLASS.exec(newSelect)[1];
|
||||
|
||||
// no need to set the same callback more than once when the same selector uses the same classname
|
||||
var hash = affected + className;
|
||||
if(!this.callbacks[hash]) {
|
||||
|
||||
// affected elements are given an expression under a fake css property, the classname is used
|
||||
// because a unique name (eg "behavior:") would be overruled (in IE6, not 7) by a following rule
|
||||
// selecting the same element. The expression does a callback to CSSHover.patch, rerouted via the
|
||||
// exposed window.CSSHover function.
|
||||
|
||||
// because the expression is added to the stylesheet, and styles are always applied to html that is
|
||||
// dynamically added to the dom, the expression will also trigger for those new elements (provided
|
||||
// they are selected by the affected selector).
|
||||
|
||||
sheet.addRule(affected, CSSHOVER_PREFIX + className + ':expression(CSSHover(this, "'+pseudo+'", "'+className+'"))');
|
||||
|
||||
// hash it, so an identical selector/class combo does not duplicate the expression
|
||||
this.callbacks[hash] = true;
|
||||
}
|
||||
|
||||
// duplicate expressions need not be set, but the style could differ
|
||||
sheet.addRule(newSelect, style);
|
||||
}
|
||||
},
|
||||
|
||||
// called via the expression, patches individual nodes
|
||||
patch:function(node, type, className) {
|
||||
|
||||
// the patch's type is returned to the expression. That way the expression property
|
||||
// can be found and removed, to stop it from calling patch over and over.
|
||||
// The if will fail the first time, since the expression has not yet received a value.
|
||||
var property = CSSHOVER_PREFIX + className;
|
||||
if(node.style[property]) {
|
||||
node.style[property] = null;
|
||||
}
|
||||
|
||||
// just to make sure, also keep track of patched classnames locally on the node
|
||||
if(!node.csshover) node.csshover = [];
|
||||
|
||||
// and check for it to prevent duplicate events with the same classname from being set
|
||||
if(!node.csshover[className]) {
|
||||
node.csshover[className] = true;
|
||||
|
||||
// create an instance for the given type and class
|
||||
var element = new CSSHoverElement(node, type, className);
|
||||
|
||||
// and store that instance for unloading later on
|
||||
this.elements.push(element);
|
||||
}
|
||||
|
||||
// returns a dummy value to the expression
|
||||
return type;
|
||||
},
|
||||
|
||||
// unload stuff onbeforeunload
|
||||
unload:function() {
|
||||
try {
|
||||
|
||||
// remove events
|
||||
var l = this.elements.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.elements[i].unload();
|
||||
}
|
||||
|
||||
// and set properties to null
|
||||
this.elements = [];
|
||||
this.callbacks = {};
|
||||
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// add the unload to the onbeforeunload event
|
||||
window.attachEvent('onbeforeunload', function(){
|
||||
CSSHover.unload();
|
||||
});
|
||||
|
||||
/**
|
||||
* CSSHoverElement
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
// the event types associated with the interactive pseudos
|
||||
var CSSEvents = {
|
||||
onhover: { activator: 'onmouseenter', deactivator: 'onmouseleave' },
|
||||
onactive: { activator: 'onmousedown', deactivator: 'onmouseup' },
|
||||
onfocus: { activator: 'onfocus', deactivator: 'onblur' }
|
||||
};
|
||||
|
||||
// CSSHoverElement constructor, called via CSSHover.patch
|
||||
function CSSHoverElement(node, type, className) {
|
||||
|
||||
// the CSSHoverElement patches individual nodes by manually applying the events that should
|
||||
// have fired by the css pseudoclasses, eg mouseenter and mouseleave for :hover.
|
||||
|
||||
this.node = node;
|
||||
this.type = type;
|
||||
var replacer = new RegExp('(^|\\s)'+className+'(\\s|$)', 'g');
|
||||
|
||||
// store event handlers for removal onunload
|
||||
this.activator = function(){ node.className += ' ' + className; };
|
||||
this.deactivator = function(){ node.className = node.className.replace(replacer, ' '); };
|
||||
|
||||
// add the events
|
||||
node.attachEvent(CSSEvents[type].activator, this.activator);
|
||||
node.attachEvent(CSSEvents[type].deactivator, this.deactivator);
|
||||
}
|
||||
|
||||
CSSHoverElement.prototype = {
|
||||
// onbeforeunload, called via CSSHover.unload
|
||||
unload:function() {
|
||||
|
||||
// remove events
|
||||
this.node.detachEvent(CSSEvents[this.type].activator, this.activator);
|
||||
this.node.detachEvent(CSSEvents[this.type].deactivator, this.deactivator);
|
||||
|
||||
// and set properties to null
|
||||
this.activator = null;
|
||||
this.deactivator = null;
|
||||
this.node = null;
|
||||
this.type = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Public hook
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
return function(node, type, className) {
|
||||
if(node) {
|
||||
// called via the css expression; patches individual nodes
|
||||
return CSSHover.patch(node, type, className);
|
||||
} else {
|
||||
// called ondomcontentready via the public:attach node
|
||||
CSSHover.init();
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
@@ -1,262 +1,262 @@
|
||||
<public:attach event="ondocumentready" onevent="CSSHover()" />
|
||||
<script>
|
||||
// <?)|(a([^#.][^ ]+)+)):(hover|active|focus))/i,
|
||||
REG_AFFECTED = /(.*?)\:(hover|active|focus)/i,
|
||||
REG_PSEUDO = /[^:]+:([a-z-]+).*/i,
|
||||
REG_SELECT = /(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi,
|
||||
REG_CLASS = /\.([a-z0-9_-]*on(hover|active|focus))/i,
|
||||
REG_MSIE = /msie (5|6|7)/i,
|
||||
REG_COMPAT = /backcompat/i;
|
||||
|
||||
// css prefix, a leading dash would be nice (spec), but IE6 doesn't like that.
|
||||
var CSSHOVER_PREFIX = 'csh-';
|
||||
|
||||
/**
|
||||
* Local CSSHover object
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
var CSSHover = {
|
||||
|
||||
// array of CSSHoverElements, used to unload created events
|
||||
elements: [],
|
||||
|
||||
// buffer used for checking on duplicate expressions
|
||||
callbacks: {},
|
||||
|
||||
// init, called once ondomcontentready via the exposed window.CSSHover function
|
||||
init:function() {
|
||||
// don't run in IE8 standards; expressions don't work in standards mode anyway,
|
||||
// and the stuff we're trying to fix should already work properly
|
||||
if(!REG_MSIE.test(navigator.userAgent) && !REG_COMPAT.test(window.document.compatMode)) return;
|
||||
|
||||
// start parsing the existing stylesheets
|
||||
var sheets = window.document.styleSheets, l = sheets.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.parseStylesheet(sheets[i]);
|
||||
}
|
||||
},
|
||||
|
||||
// called from init, parses individual stylesheets
|
||||
parseStylesheet:function(sheet) {
|
||||
// check sheet imports and parse those recursively
|
||||
if(sheet.imports) {
|
||||
try {
|
||||
var imports = sheet.imports, l = imports.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.parseStylesheet(sheet.imports[i]);
|
||||
}
|
||||
} catch(securityException){
|
||||
// trycatch for various possible errors,
|
||||
// todo; might need to be placed inside the for loop, since an error
|
||||
// on an import stops following imports from being processed.
|
||||
}
|
||||
}
|
||||
|
||||
// interate the sheet's rules and send them to the parser
|
||||
try {
|
||||
var rules = sheet.rules, l = rules.length;
|
||||
for(var j=0; j<l; j++) {
|
||||
this.parseCSSRule(rules[j], sheet);
|
||||
}
|
||||
} catch(securityException){
|
||||
// trycatch for various errors, most likely accessing the sheet's rules,
|
||||
// don't see how individual rules would throw errors, but you never know.
|
||||
}
|
||||
},
|
||||
|
||||
// magic starts here ...
|
||||
parseCSSRule:function(rule, sheet) {
|
||||
|
||||
// The sheet is used to insert new rules into, this must be the same sheet the rule
|
||||
// came from, to ensure that relative paths keep pointing to the right location.
|
||||
|
||||
// only parse a rule if it contains an interactive pseudo.
|
||||
var select = rule.selectorText;
|
||||
if(REG_INTERACTIVE.test(select)) {
|
||||
var style = rule.style.cssText,
|
||||
|
||||
// affected elements are found by truncating the selector after the interactive pseudo,
|
||||
// eg: "div li:hover" >> "div li"
|
||||
affected = REG_AFFECTED.exec(select)[1],
|
||||
|
||||
// that pseudo is needed for a classname, and defines the type of interaction (focus, hover, active)
|
||||
// eg: "li:hover" >> "onhover"
|
||||
pseudo = select.replace(REG_PSEUDO, 'on$1'),
|
||||
|
||||
// the new selector is going to use that classname in a new css rule,
|
||||
// since IE6 doesn't support multiple classnames, this is merged into one classname
|
||||
// eg: "li:hover" >> "li.onhover", "li.folder:hover" >> "li.folderonhover"
|
||||
newSelect = select.replace(REG_SELECT, '.$2' + pseudo),
|
||||
|
||||
// the classname is needed for the events that are going to be set on affected nodes
|
||||
// eg: "li.folder:hover" >> "folderonhover"
|
||||
className = REG_CLASS.exec(newSelect)[1];
|
||||
|
||||
// no need to set the same callback more than once when the same selector uses the same classname
|
||||
var hash = affected + className;
|
||||
if(!this.callbacks[hash]) {
|
||||
|
||||
// affected elements are given an expression under a fake css property, the classname is used
|
||||
// because a unique name (eg "behavior:") would be overruled (in IE6, not 7) by a following rule
|
||||
// selecting the same element. The expression does a callback to CSSHover.patch, rerouted via the
|
||||
// exposed window.CSSHover function.
|
||||
|
||||
// because the expression is added to the stylesheet, and styles are always applied to html that is
|
||||
// dynamically added to the dom, the expression will also trigger for those new elements (provided
|
||||
// they are selected by the affected selector).
|
||||
|
||||
sheet.addRule(affected, CSSHOVER_PREFIX + className + ':expression(CSSHover(this, "'+pseudo+'", "'+className+'"))');
|
||||
|
||||
// hash it, so an identical selector/class combo does not duplicate the expression
|
||||
this.callbacks[hash] = true;
|
||||
}
|
||||
|
||||
// duplicate expressions need not be set, but the style could differ
|
||||
sheet.addRule(newSelect, style);
|
||||
}
|
||||
},
|
||||
|
||||
// called via the expression, patches individual nodes
|
||||
patch:function(node, type, className) {
|
||||
|
||||
// the patch's type is returned to the expression. That way the expression property
|
||||
// can be found and removed, to stop it from calling patch over and over.
|
||||
// The if will fail the first time, since the expression has not yet received a value.
|
||||
var property = CSSHOVER_PREFIX + className;
|
||||
if(node.style[property]) {
|
||||
node.style[property] = null;
|
||||
}
|
||||
|
||||
// just to make sure, also keep track of patched classnames locally on the node
|
||||
if(!node.csshover) node.csshover = [];
|
||||
|
||||
// and check for it to prevent duplicate events with the same classname from being set
|
||||
if(!node.csshover[className]) {
|
||||
node.csshover[className] = true;
|
||||
|
||||
// create an instance for the given type and class
|
||||
var element = new CSSHoverElement(node, type, className);
|
||||
|
||||
// and store that instance for unloading later on
|
||||
this.elements.push(element);
|
||||
}
|
||||
|
||||
// returns a dummy value to the expression
|
||||
return type;
|
||||
},
|
||||
|
||||
// unload stuff onbeforeunload
|
||||
unload:function() {
|
||||
try {
|
||||
|
||||
// remove events
|
||||
var l = this.elements.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.elements[i].unload();
|
||||
}
|
||||
|
||||
// and set properties to null
|
||||
this.elements = [];
|
||||
this.callbacks = {};
|
||||
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// add the unload to the onbeforeunload event
|
||||
window.attachEvent('onbeforeunload', function(){
|
||||
CSSHover.unload();
|
||||
});
|
||||
|
||||
/**
|
||||
* CSSHoverElement
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
// the event types associated with the interactive pseudos
|
||||
var CSSEvents = {
|
||||
onhover: { activator: 'onmouseenter', deactivator: 'onmouseleave' },
|
||||
onactive: { activator: 'onmousedown', deactivator: 'onmouseup' },
|
||||
onfocus: { activator: 'onfocus', deactivator: 'onblur' }
|
||||
};
|
||||
|
||||
// CSSHoverElement constructor, called via CSSHover.patch
|
||||
function CSSHoverElement(node, type, className) {
|
||||
|
||||
// the CSSHoverElement patches individual nodes by manually applying the events that should
|
||||
// have fired by the css pseudoclasses, eg mouseenter and mouseleave for :hover.
|
||||
|
||||
this.node = node;
|
||||
this.type = type;
|
||||
var replacer = new RegExp('(^|\\s)'+className+'(\\s|$)', 'g');
|
||||
|
||||
// store event handlers for removal onunload
|
||||
this.activator = function(){ node.className += ' ' + className; };
|
||||
this.deactivator = function(){ node.className = node.className.replace(replacer, ' '); };
|
||||
|
||||
// add the events
|
||||
node.attachEvent(CSSEvents[type].activator, this.activator);
|
||||
node.attachEvent(CSSEvents[type].deactivator, this.deactivator);
|
||||
}
|
||||
|
||||
CSSHoverElement.prototype = {
|
||||
// onbeforeunload, called via CSSHover.unload
|
||||
unload:function() {
|
||||
|
||||
// remove events
|
||||
this.node.detachEvent(CSSEvents[this.type].activator, this.activator);
|
||||
this.node.detachEvent(CSSEvents[this.type].deactivator, this.deactivator);
|
||||
|
||||
// and set properties to null
|
||||
this.activator = null;
|
||||
this.deactivator = null;
|
||||
this.node = null;
|
||||
this.type = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Public hook
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
return function(node, type, className) {
|
||||
if(node) {
|
||||
// called via the css expression; patches individual nodes
|
||||
return CSSHover.patch(node, type, className);
|
||||
} else {
|
||||
// called ondomcontentready via the public:attach node
|
||||
CSSHover.init();
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
// ]]>
|
||||
<public:attach event="ondocumentready" onevent="CSSHover()" />
|
||||
<script>
|
||||
// <?)|(a([^#.][^ ]+)+)):(hover|active|focus))/i,
|
||||
REG_AFFECTED = /(.*?)\:(hover|active|focus)/i,
|
||||
REG_PSEUDO = /[^:]+:([a-z-]+).*/i,
|
||||
REG_SELECT = /(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi,
|
||||
REG_CLASS = /\.([a-z0-9_-]*on(hover|active|focus))/i,
|
||||
REG_MSIE = /msie (5|6|7)/i,
|
||||
REG_COMPAT = /backcompat/i;
|
||||
|
||||
// css prefix, a leading dash would be nice (spec), but IE6 doesn't like that.
|
||||
var CSSHOVER_PREFIX = 'csh-';
|
||||
|
||||
/**
|
||||
* Local CSSHover object
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
var CSSHover = {
|
||||
|
||||
// array of CSSHoverElements, used to unload created events
|
||||
elements: [],
|
||||
|
||||
// buffer used for checking on duplicate expressions
|
||||
callbacks: {},
|
||||
|
||||
// init, called once ondomcontentready via the exposed window.CSSHover function
|
||||
init:function() {
|
||||
// don't run in IE8 standards; expressions don't work in standards mode anyway,
|
||||
// and the stuff we're trying to fix should already work properly
|
||||
if(!REG_MSIE.test(navigator.userAgent) && !REG_COMPAT.test(window.document.compatMode)) return;
|
||||
|
||||
// start parsing the existing stylesheets
|
||||
var sheets = window.document.styleSheets, l = sheets.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.parseStylesheet(sheets[i]);
|
||||
}
|
||||
},
|
||||
|
||||
// called from init, parses individual stylesheets
|
||||
parseStylesheet:function(sheet) {
|
||||
// check sheet imports and parse those recursively
|
||||
if(sheet.imports) {
|
||||
try {
|
||||
var imports = sheet.imports, l = imports.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.parseStylesheet(sheet.imports[i]);
|
||||
}
|
||||
} catch(securityException){
|
||||
// trycatch for various possible errors,
|
||||
// todo; might need to be placed inside the for loop, since an error
|
||||
// on an import stops following imports from being processed.
|
||||
}
|
||||
}
|
||||
|
||||
// interate the sheet's rules and send them to the parser
|
||||
try {
|
||||
var rules = sheet.rules, l = rules.length;
|
||||
for(var j=0; j<l; j++) {
|
||||
this.parseCSSRule(rules[j], sheet);
|
||||
}
|
||||
} catch(securityException){
|
||||
// trycatch for various errors, most likely accessing the sheet's rules,
|
||||
// don't see how individual rules would throw errors, but you never know.
|
||||
}
|
||||
},
|
||||
|
||||
// magic starts here ...
|
||||
parseCSSRule:function(rule, sheet) {
|
||||
|
||||
// The sheet is used to insert new rules into, this must be the same sheet the rule
|
||||
// came from, to ensure that relative paths keep pointing to the right location.
|
||||
|
||||
// only parse a rule if it contains an interactive pseudo.
|
||||
var select = rule.selectorText;
|
||||
if(REG_INTERACTIVE.test(select)) {
|
||||
var style = rule.style.cssText,
|
||||
|
||||
// affected elements are found by truncating the selector after the interactive pseudo,
|
||||
// eg: "div li:hover" >> "div li"
|
||||
affected = REG_AFFECTED.exec(select)[1],
|
||||
|
||||
// that pseudo is needed for a classname, and defines the type of interaction (focus, hover, active)
|
||||
// eg: "li:hover" >> "onhover"
|
||||
pseudo = select.replace(REG_PSEUDO, 'on$1'),
|
||||
|
||||
// the new selector is going to use that classname in a new css rule,
|
||||
// since IE6 doesn't support multiple classnames, this is merged into one classname
|
||||
// eg: "li:hover" >> "li.onhover", "li.folder:hover" >> "li.folderonhover"
|
||||
newSelect = select.replace(REG_SELECT, '.$2' + pseudo),
|
||||
|
||||
// the classname is needed for the events that are going to be set on affected nodes
|
||||
// eg: "li.folder:hover" >> "folderonhover"
|
||||
className = REG_CLASS.exec(newSelect)[1];
|
||||
|
||||
// no need to set the same callback more than once when the same selector uses the same classname
|
||||
var hash = affected + className;
|
||||
if(!this.callbacks[hash]) {
|
||||
|
||||
// affected elements are given an expression under a fake css property, the classname is used
|
||||
// because a unique name (eg "behavior:") would be overruled (in IE6, not 7) by a following rule
|
||||
// selecting the same element. The expression does a callback to CSSHover.patch, rerouted via the
|
||||
// exposed window.CSSHover function.
|
||||
|
||||
// because the expression is added to the stylesheet, and styles are always applied to html that is
|
||||
// dynamically added to the dom, the expression will also trigger for those new elements (provided
|
||||
// they are selected by the affected selector).
|
||||
|
||||
sheet.addRule(affected, CSSHOVER_PREFIX + className + ':expression(CSSHover(this, "'+pseudo+'", "'+className+'"))');
|
||||
|
||||
// hash it, so an identical selector/class combo does not duplicate the expression
|
||||
this.callbacks[hash] = true;
|
||||
}
|
||||
|
||||
// duplicate expressions need not be set, but the style could differ
|
||||
sheet.addRule(newSelect, style);
|
||||
}
|
||||
},
|
||||
|
||||
// called via the expression, patches individual nodes
|
||||
patch:function(node, type, className) {
|
||||
|
||||
// the patch's type is returned to the expression. That way the expression property
|
||||
// can be found and removed, to stop it from calling patch over and over.
|
||||
// The if will fail the first time, since the expression has not yet received a value.
|
||||
var property = CSSHOVER_PREFIX + className;
|
||||
if(node.style[property]) {
|
||||
node.style[property] = null;
|
||||
}
|
||||
|
||||
// just to make sure, also keep track of patched classnames locally on the node
|
||||
if(!node.csshover) node.csshover = [];
|
||||
|
||||
// and check for it to prevent duplicate events with the same classname from being set
|
||||
if(!node.csshover[className]) {
|
||||
node.csshover[className] = true;
|
||||
|
||||
// create an instance for the given type and class
|
||||
var element = new CSSHoverElement(node, type, className);
|
||||
|
||||
// and store that instance for unloading later on
|
||||
this.elements.push(element);
|
||||
}
|
||||
|
||||
// returns a dummy value to the expression
|
||||
return type;
|
||||
},
|
||||
|
||||
// unload stuff onbeforeunload
|
||||
unload:function() {
|
||||
try {
|
||||
|
||||
// remove events
|
||||
var l = this.elements.length;
|
||||
for(var i=0; i<l; i++) {
|
||||
this.elements[i].unload();
|
||||
}
|
||||
|
||||
// and set properties to null
|
||||
this.elements = [];
|
||||
this.callbacks = {};
|
||||
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// add the unload to the onbeforeunload event
|
||||
window.attachEvent('onbeforeunload', function(){
|
||||
CSSHover.unload();
|
||||
});
|
||||
|
||||
/**
|
||||
* CSSHoverElement
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
// the event types associated with the interactive pseudos
|
||||
var CSSEvents = {
|
||||
onhover: { activator: 'onmouseenter', deactivator: 'onmouseleave' },
|
||||
onactive: { activator: 'onmousedown', deactivator: 'onmouseup' },
|
||||
onfocus: { activator: 'onfocus', deactivator: 'onblur' }
|
||||
};
|
||||
|
||||
// CSSHoverElement constructor, called via CSSHover.patch
|
||||
function CSSHoverElement(node, type, className) {
|
||||
|
||||
// the CSSHoverElement patches individual nodes by manually applying the events that should
|
||||
// have fired by the css pseudoclasses, eg mouseenter and mouseleave for :hover.
|
||||
|
||||
this.node = node;
|
||||
this.type = type;
|
||||
var replacer = new RegExp('(^|\\s)'+className+'(\\s|$)', 'g');
|
||||
|
||||
// store event handlers for removal onunload
|
||||
this.activator = function(){ node.className += ' ' + className; };
|
||||
this.deactivator = function(){ node.className = node.className.replace(replacer, ' '); };
|
||||
|
||||
// add the events
|
||||
node.attachEvent(CSSEvents[type].activator, this.activator);
|
||||
node.attachEvent(CSSEvents[type].deactivator, this.deactivator);
|
||||
}
|
||||
|
||||
CSSHoverElement.prototype = {
|
||||
// onbeforeunload, called via CSSHover.unload
|
||||
unload:function() {
|
||||
|
||||
// remove events
|
||||
this.node.detachEvent(CSSEvents[this.type].activator, this.activator);
|
||||
this.node.detachEvent(CSSEvents[this.type].deactivator, this.deactivator);
|
||||
|
||||
// and set properties to null
|
||||
this.activator = null;
|
||||
this.deactivator = null;
|
||||
this.node = null;
|
||||
this.type = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Public hook
|
||||
* --------------------------
|
||||
*/
|
||||
|
||||
return function(node, type, className) {
|
||||
if(node) {
|
||||
// called via the css expression; patches individual nodes
|
||||
return CSSHover.patch(node, type, className);
|
||||
} else {
|
||||
// called ondomcontentready via the public:attach node
|
||||
CSSHover.init();
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
// ]]>
|
||||
</script>
|
||||
Reference in New Issue
Block a user