diff --git a/WebContent/public/js/css-filters-polyfill.js b/WebContent/public/js/css-filters-polyfill.js index 91b2514..a079c4a 100644 --- a/WebContent/public/js/css-filters-polyfill.js +++ b/WebContent/public/js/css-filters-polyfill.js @@ -11,291 +11,362 @@ * */ ;(function(window){ + // 定义一个名为polyfilter的对象,用于存储各种方法和属性 var polyfilter = { - // Detect if we are dealing with IE <= 9 - // http://james.padolsey.com/javascript/detect-_ie-in-js-using-conditional-comments/ - _ie: (function(){ - var undef, - v = 3, - div = document.createElement('div'), - all = div.getElementsByTagName('i'); - - while( + // 检测是否为IE <= 9版本 + _ie: (function () { + // 定义未定义变量和初始值v为3 + var undef, v = 3, + // 创建一个div元素 + div = document.createElement('div'), + // 获取div中的所有i元素 + all = div.getElementsByTagName('i'); + + // 循环判断IE版本 + while ( div.innerHTML = '', - all[0] - ); - + all[0] + ) ; + + // 如果v大于4,返回v,否则返回未定义 return v > 4 ? v : undef; }()), - - _svg_cache: {}, - - _create_svg_element: function(tagname,attributes){ + + // 缓存SVG元素 + _svg_cache: {}, + + // 创建SVG元素的方法 + _create_svg_element: function (tagname, attributes) { + // 定义SVG命名空间 var xmlns = 'http://www.w3.org/2000/svg'; - var elem = document.createElementNS(xmlns,tagname); - for(key in attributes){ - elem.setAttributeNS(null,key,attributes[key]); + // 使用命名空间创建SVG元素 + var elem = document.createElementNS(xmlns, tagname); + // 遍历属性并设置到元素上 + for (key in attributes) { + elem.setAttributeNS(null, key, attributes[key]); } - + + // 返回创建的SVG元素 return elem; }, - - _create_svg: function(id,filterelements){ + + // 创建SVG容器的方法 + _create_svg: function (id, filterelements) { + // 定义SVG命名空间 var xmlns = 'http://www.w3.org/2000/svg'; - var svg = document.createElementNS(xmlns,'svg'); - svg.setAttributeNS(null,'width','0'); - svg.setAttributeNS(null,'height','0'); - svg.setAttributeNS(null,'style','position:absolute'); - - var svg_filter = document.createElementNS(xmlns,'filter'); - svg_filter.setAttributeNS(null,'id',id); + // 使用命名空间创建SVG元素 + var svg = document.createElementNS(xmlns, 'svg'); + // 设置SVG元素的宽度和高度为0 + svg.setAttributeNS(null, 'width', '0'); + svg.setAttributeNS(null, 'height', '0'); + // 设置SVG元素的样式为绝对定位 + svg.setAttributeNS(null, 'style', 'position:absolute'); + + // 创建SVG滤镜元素并添加到SVG容器中 + var svg_filter = document.createElementNS(xmlns, 'filter'); + svg_filter.setAttributeNS(null, 'id', id); svg.appendChild(svg_filter); - - for(var i = 0; i < filterelements.length; i++){ + + // 将滤镜元素添加到SVG滤镜中 + for (var i = 0; i < filterelements.length; i++) { svg_filter.appendChild(filterelements[i]); } - + + // 返回创建的SVG容器 return svg; }, - + + // 记录待处理的样式表数量 _pending_stylesheets: 0, - - _stylesheets: [], - - _development_mode: (function(){ - if(location.hostname === 'localhost' || location.hostname.search(/.local$/) !== -1 || location.hostname.search(/\d+\.\d+\.\d+\.\d+/) !== -1){ - if(window.console) console.log('Detected localhost or IP address. Assuming you are a developer. Caching of stylesheets is disabled.'); + // 存储样式表内容的数组 + _stylesheets: [], + // 开发模式标志,根据主机名或IP地址判断是否为开发环境 + _development_mode: (function () { + // 检查主机名是否为localhost或IP地址,如果是则启用开发模式 + if (location.hostname === 'localhost' || location.hostname.search(/.local$/) !== -1 || location.hostname.search(/\d+\.\d+\.\d+\.\d+/) !== -1) { + if (window.console) console.log('Detected localhost or IP address. Assuming you are a developer. Caching of stylesheets is disabled.'); return true; } - if(window.console) console.log('Caching of stylesheets is enabled. You need to refresh twice to see any changes.'); + // 如果不是开发环境,则启用缓存模式 + if (window.console) console.log('Caching of stylesheets is enabled. You need to refresh twice to see any changes.'); return false; - })(), - - process_stylesheets: function(){ - var xmlHttp = []; - - // Check if path to library is correct, do that 2 secs. after this to not disturb initial processing - window.setTimeout(function(){ + }()), + // 处理样式表的方法 + process_stylesheets: function () { + // 延迟2秒执行,避免干扰页面加载 + window.setTimeout(function () { + // 检查XMLHttpRequest对象是否存在,如果不存在则使用ActiveXObject if (window.XMLHttpRequest) { var xmlHttpCheck = new XMLHttpRequest(); - } else if (window.ActiveXObject) { + } else { var xmlHttpCheck = new ActiveXObject("Microsoft.XMLHTTP"); } + // 打开GET请求,检查路径是否正确 xmlHttpCheck.open('GET', window.polyfilter_scriptpath + 'htc/sepia.htc', true); - xmlHttpCheck.onreadystatechange = function(){ - if(xmlHttp.readyState == 4 && xmlHttp.status != 200){ - alert('The configured path \r\rvar polyfilter_scriptpath = "' + window.polyfilter_scriptpath + '"\r\rseems wrong!\r\rConfigure the polyfill\'s correct absolute(!) script path before referencing the css-filters-polyfill.js, like so:\r\rvar polyfilter_scriptpath = "/js/css-filters-polyfill/";\r\rLeaving IE dead in the water is no option. You damn Mac user... ;)'); + xmlHttpCheck.onreadystatechange = function () { + // 如果请求完成且状态码不为200,则输出错误信息 + if (xmlHttpCheck.readyState == 4 && xmlHttpCheck.status != 200) { + ('The configured path seems wrong!\r\rvar polyfilter_scriptpath = "' + window.polyfilter_scriptpath + '\r\rConfigure the polyfilter\'s absolute(!) scriptpath before referencing the css-filters-polyfill.js, like so:\r\rvar polyfilter_scriptpath = "/js/css-filters-polyfill/";\r\rLeaving IE dead in the water is no option... ;)'); } }; - try{ + try { + // 发送请求 xmlHttpCheck.send(null); - } catch(e){} - },2000); - - + } catch (e) { + } + }, 2000); + + // 获取所有样式表和链接标签 var stylesheets = document.querySelectorAll ? document.querySelectorAll('style,link[rel="stylesheet"]') : document.getElementsByTagName('*'); - - for(var i = 0; i < stylesheets.length; i++){ - (function(i){ - switch(stylesheets[i].nodeName){ + + // 遍历所有样式表和链接标签 + for (var i = 0; i < stylesheets.length; i++) { + (function (i) { + switch (stylesheets[i].nodeName) { default: - break; - + break; case 'STYLE': + // 如果是样式表,将其内容和媒体类型保存到_stylesheets数组中 polyfilter._stylesheets.push({ - media: stylesheets[i].media || 'all', - content: stylesheets[i].innerHTML + media: stylesheets[i].media || 'all', + content: stylesheets[i].innerHTML }); - break; - + break; case 'LINK': - if(stylesheets[i].rel === 'stylesheet'){ + // 如果是链接标签且rel属性为stylesheet,则处理外部样式表 + if (stylesheets[i].rel === 'stylesheet') { var index = polyfilter._stylesheets.length; - + // 将外部样式表的信息保存到_stylesheets数组中 polyfilter._stylesheets.push({ - media: stylesheets[i].media || 'all' + media: stylesheets[i].media || 'all' }); - + // 增加待处理的样式表数量 polyfilter._pending_stylesheets++; - - // Fetch external stylesheet + // 获取外部样式表的href属性 var href = stylesheets[i].href; - - // Use localStorage as cache for stylesheets, if available - if(!polyfilter._development_mode && window.localStorage && window.localStorage.getItem('polyfilter_' + href)){ + // 如果本地存储可用,则使用本地存储作为样式表缓存 + if (!polyfilter._development_mode && window.localStorage && window.localStorage.getItem('polyfilter_' + href)) { + // 减少待处理的样式表数量 polyfilter._pending_stylesheets--; + // 从本地存储中获取样式表内容并保存到_stylesheets数组中 polyfilter._stylesheets[index].content = localStorage.getItem('polyfilter_' + href); - if(polyfilter._pending_stylesheets === 0){ + // 如果所有样式表都已处理完毕,则调用process方法进行处理 + if (polyfilter._pending_stylesheets === 0) { polyfilter.process(); + } } - - // Always fetch stylesheets to reflect possible changes - try{ - if(window.XMLHttpRequest) { - var xmlHttp = new XMLHttpRequest(); - } else if(window.ActiveXObject) { - var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); + +// Always fetch stylesheets to reflect possible changes + try { + // 检查浏览器是否支持XMLHttpRequest对象 + if (window.XMLHttpRequest) { + var xmlHttp = new XMLHttpRequest(); // 创建一个新的XMLHttpRequest对象 + } else if (window.ActiveXObject) { + var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); // 对于较旧的IE浏览器,使用ActiveXObject } + // 初始化一个GET请求,异步方式 xmlHttp.open('GET', href, true); - xmlHttp.onreadystatechange = function(){ - if(xmlHttp.readyState === 4){ - if(xmlHttp.status === 0){ - if(window.console) console.log('Could not fetch external CSS via HTTP-Request ' + href + '. Probably because of cross origin.'); - if(!polyfilter._stylesheets[index].content){ - polyfilter._pending_stylesheets--; - polyfilter._stylesheets[index].content = xmlHttp.responseText; - if(polyfilter._pending_stylesheets === 0){ - polyfilter.process(); + // 定义当readyState属性改变时触发的函数 + xmlHttp.onreadystatechange = function () { + // 检查请求是否完成 + if (xmlHttp.readyState === 4) { + // 检查HTTP状态码是否为0(通常表示跨域问题) + if (xmlHttp.status === 0) { + if (window.console) console.log('Could not fetch external CSS via HTTP-Request ' + href + '. Probably because of cross origin.'); // 输出错误信息到控制台 + // 如果当前样式表内容为空 + if (!polyfilter._stylesheets[index].content) { + polyfilter._pending_stylesheets--; // 减少待处理样式表计数 + polyfilter._stylesheets[index].content = xmlHttp.responseText; // 将响应文本保存到样式表内容中 + // 如果所有样式表都已加载完毕 + if (polyfilter._pending_stylesheets === 0) { + polyfilter.process(); // 调用处理函数 } } } else { - if(!polyfilter._stylesheets[index].content){ - polyfilter._pending_stylesheets--; - polyfilter._stylesheets[index].content = xmlHttp.responseText; - if(polyfilter._pending_stylesheets === 0){ - polyfilter.process(); + // 如果HTTP状态码不为0且当前样式表内容为空 + if (!polyfilter._stylesheets[index].content) { + polyfilter._pending_stylesheets--; // 减少待处理样式表计数 + polyfilter._stylesheets[index].content = xmlHttp.responseText; // 将响应文本保存到样式表内容中 + // 如果所有样式表都已加载完毕 + if (polyfilter._pending_stylesheets === 0) { + polyfilter.process(); // 调用处理函数 } } + // Cache stylesheet in localStorage, if available - if(!polyfilter._development_mode && window.localStorage){ - try{ - window.localStorage.setItem('polyfilter_' + href,polyfilter._stylesheets[index].content) - } - catch(e){ - if(window.console) console.log('Local storage quota have been exceeded. Caching of stylesheet ' + href + ' is not possible'); + // 检查是否不在开发模式且浏览器支持localStorage + if (!polyfilter._development_mode && window.localStorage) { + try { + // 尝试将样式表内容存储到localStorage中,键名为'polyfilter_'加上href + window.localStorage.setItem('polyfilter_' + href, polyfilter._stylesheets[index].content + ); + } catch + (e) { + // 如果存储失败(例如超出配额),在控制台输出错误信息 + if (window.console) console.log('Local storage quota have been exceeded. Caching of stylesheet ' + href + ' is not possible'); } } } } }; - try{ + try {// 发送HTTP请求以获取外部CSS文件 xmlHttp.send(null); - } catch(e){ - if(window.console) console.log('Could not fetch external CSS via HTTP-Request ' + href + '. Are you maybe testing using the file://-protocol?'); - if(!polyfilter._stylesheets[index].content){ + } catch (e) { + // 如果控制台可用,则在控制台中记录错误信息 + if (window.console) console.log('Could not fetch external CSS via HTTP-Request ' + href + '. Are you maybe testing using the file://-protocol?'); + // 检查当前样式表是否没有内容 + if (!polyfilter._stylesheets[index].content) { + // 减少待处理的样式表计数 polyfilter._pending_stylesheets--; - if(polyfilter._pending_stylesheets === 0){ + // 如果所有样式表都已处理完毕,则调用process方法 + if (polyfilter._pending_stylesheets === 0) { polyfilter.process(); } } } - } catch(e){} + } catch (e) { + } } - break; + break; } })(i); } - if(this._pending_stylesheets === 0){ + if (this._pending_stylesheets === 0) { // 如果所有样式表都已处理完毕,则调用process方法 this.process(); } }, - - _processDeclarations: function(rule){ - var newstyles = ''; - for(var k in rule.declarations){ - var declaration = rule.declarations[k]; - - if(declaration.property === 'filter'){ - - if(document.querySelectorAll){ - var elems = document.querySelectorAll(rule.mSelectorText); - for(var k = 0; k < elems.length; k++){ + + _processDeclarations: function (rule) { + var newstyles = ''; // 初始化新样式字符串 + for (var k in rule.declarations) { + var declaration = rule.declarations[k]; // 获取当前声明 + + if (declaration.property === 'filter') { + // 如果document支持querySelectorAll方法 + if (document.querySelectorAll) { + var elems = document.querySelectorAll(rule.mSelectorText); // 根据选择器文本获取元素列表 + for (var k = 0; k < elems.length; k++) { + // 为每个元素设置自定义属性polyfilterStore,存储过滤器值 elems[k].style.polyfilterStore = declaration.valueText; } } - + + // 将声明的值文本赋值给变量gluedvalues var gluedvalues = declaration.valueText; + +// 使用正则表达式分割字符串,以匹配右括号后跟一个或多个空白字符的模式 var values = gluedvalues.split(/\)\s+/), + // 初始化一个对象properties,用于存储不同类型的过滤器和行为 properties = { - filtersW3C: [], - filtersWebKit: [], - filtersSVG: [], - filtersIE: [], - behaviorsIE: [] + filtersW3C: [], // W3C标准的过滤器数组 + filtersWebKit: [], // WebKit浏览器的过滤器数组 + filtersSVG: [], // SVG格式的过滤器数组 + filtersIE: [], // IE浏览器的过滤器数组 + behaviorsIE: [] // IE浏览器的行为数组 }; - - for(idx in values){ + + // 遍历分割后的values数组 + for (idx in values) { + // 为每个值添加右括号,因为之前被分割掉了 var value = values[idx] + ')'; - + + // 调用polyfilter.convert函数转换当前值,返回一个包含不同类型过滤器的对象 currentproperties = polyfilter.convert(value); - - for(key in currentproperties){ - if(typeof properties[key] !== 'undefined'){ + + // 遍历currentproperties对象的键 + for (key in currentproperties) { + // 如果properties对象中存在对应的键 + if (typeof properties[key] !== 'undefined') { + // 将currentproperties中的值合并到properties对应的数组中 properties[key] = properties[key].concat(currentproperties[key]); } } } - + + // 将选择器文本和左大括号添加到newstyles字符串中,开始定义新的CSS规则 newstyles += rule.mSelectorText + '{'; - if(properties['filtersW3C'].length > 0){ - var filter = - webkitFilter = - mozFilter = - oFilter = - msFilter = - properties['filtersW3C'].join(' '); - - if(properties['filtersWebKit'] && properties['filtersWebKit'].length > 0){ + +// 如果W3C标准的过滤器数组不为空 + if (properties['filtersW3C'].length > 0) { + // 将所有W3C标准过滤器连接成一个字符串,并赋值给多个变量 + var filter = + webkitFilter = + mozFilter = + oFilter = + msFilter = + properties['filtersW3C'].join(' '); + + // 如果WebKit的过滤器数组存在且不为空,则将其连接成字符串并赋值给webkitFilter变量 + if (properties['filtersWebKit'] && properties['filtersWebKit'].length > 0) { webkitFilter = properties['filtersWebKit'].join(' '); } - if(typeof this._ie === 'undefined'){ + // 如果_ie属性未定义(即不在IE浏览器中) + if (typeof this._ie === 'undefined') { + // 添加-ms-filter样式到newstyles字符串中 newstyles += '-ms-filter:' + msFilter + ';'; } - + + // 添加-webkit-filter样式到newstyles字符串中 newstyles += '-webkit-filter:' + webkitFilter + ';'; + // 添加-moz-filter样式到newstyles字符串中 newstyles += '-moz-filter:' + mozFilter + ';'; + // 添加-o-filter样式到newstyles字符串中 newstyles += '-o-filter:' + oFilter + ';'; } - if(properties['filtersSVG'].length > 0){ - if(properties['filtersSVG'][0] != 'none'){ - var id = gluedvalues.replace(/[^a-z0-9]/g,''); - if(typeof this._svg_cache[id] === 'undefined'){ - this._svg_cache[id] = this._create_svg(id,properties['filtersSVG']); +// 如果SVG过滤器数组不为空 + if (properties['filtersSVG'].length > 0) { + // 如果第一个SVG过滤器不是'none' + if (properties['filtersSVG'][0] != 'none') { + // 使用正则表达式从gluedvalues中提取字母和数字字符,生成一个ID + var id = gluedvalues.replace(/[^a-z0-9]/g, ''); - if(typeof XMLSerializer === 'undefined'){ + // 如果_svg_cache对象中没有这个ID对应的缓存项 + if (typeof this._svg_cache[id] === 'undefined') { + // 调用_create_svg方法创建一个新的SVG元素,并将其存储在_svg_cache中 + this._svg_cache[id] = this._create_svg(id, properties['filtersSVG']); + + // 如果XMLSerializer类不存在(可能在某些旧版浏览器中) + if (typeof XMLSerializer === 'undefined') { + // 直接将SVG元素添加到文档的body中 document.body.appendChild(this._svg_cache[id]); - } - else { + } else { + // 使用XMLSerializer将SVG元素序列化为字符串 var s = new XMLSerializer(); var svgString = s.serializeToString(this._svg_cache[id]); - if(svgString.search('SourceGraphic') != -1){ + // 如果序列化后的字符串包含'SourceGraphic',则将SVG元素添加到文档的body中 + if (svgString.search('SourceGraphic') != -1) { document.body.appendChild(this._svg_cache[id]); } } } - - if(typeof XMLSerializer === 'undefined'){ - newstyles += 'filter: url(#' + id + ')'; - } - else { - var s = new XMLSerializer(); - var svgString = s.serializeToString(this._svg_cache[id]); - - if(svgString.search('SourceGraphic') != -1){ - newstyles += 'filter: url(#' + id + ')'; - } - else { - newstyles += 'filter: url(\'data:image/svg+xml;utf8,' + svgString + '#' + id + '\')'; + + if (typeof XMLSerializer === 'undefined') { // 检查浏览器是否支持XMLSerializer类 + newstyles += 'filter: url(#' + id + ')'; // 如果不支持,使用旧的IE方式添加滤镜URL + } else { + var s = new XMLSerializer(); // 创建一个新的XMLSerializer实例 + var svgString = s.serializeToString(this._svg_cache[id]); // 将SVG元素序列化为字符串 + + if (svgString.search('SourceGraphic') != -1) { // 检查序列化后的字符串中是否包含'SourceGraphic' + newstyles += 'filter: url(#' + id + ')'; // 如果包含,使用旧的IE方式添加滤镜URL + } else { + newstyles += 'filter: url(\'data:image/svg+xml;utf8,' + svgString + '#' + id + '\')'; // 如果不包含,使用数据URI的方式添加滤镜 } } - } - else { - newstyles += 'filter: none;'; + } else { + newstyles += 'filter: none;'; // 如果所有条件都不满足,设置滤镜为none } } - if(typeof this._ie !== 'undefined'){ - if(properties['filtersIE'].length > 0){ - var filtersIE = properties['filtersIE'].join(' '); - - newstyles += 'filter:' + filtersIE + ';'; + if (typeof this._ie !== 'undefined') { // 检查是否是IE浏览器 + if (properties['filtersIE'].length > 0) { // 检查是否有IE特定的滤镜 + var filtersIE = properties['filtersIE'].join(' '); // 将所有IE滤镜连接成一个字符串 + newstyles += 'filter:' + filtersIE + ';'; // 添加IE滤镜到样式中 } - if(properties['behaviorsIE'].length > 0){ - var behaviorsIE = properties['behaviorsIE'].join(' '); - - newstyles += 'behavior:' + behaviorsIE + ';'; + if (properties['behaviorsIE'].length > 0) { // 检查是否有IE特定的行为 + var behaviorsIE = properties['behaviorsIE'].join(' '); // 将所有IE行为连接成一个字符串 + newstyles += 'behavior:' + behaviorsIE + ';'; // 添加IE行为到样式中 } } newstyles += '}\r\n'; @@ -303,484 +374,523 @@ } return newstyles; }, - + // Absolute path to the .htc-files - scriptpath: - window.polyfilter_scriptpath ? window.polyfilter_scriptpath : (function(){ + scriptpath: + window.polyfilter_scriptpath ? window.polyfilter_scriptpath : (function () { alert('Please configure the polyfill\'s absolute(!) script path before referencing the css-filters-polyfill.js, like so:\r\nvar polyfilter_scriptpath = "/js/css-filters-polyfill/";'); return './' })(), - + // process stylesheets - process: function(){ + // 处理样式表的函数 + process: function () { + // 创建一个新的CSSParser实例 var parser = new CSSParser(); - - for(var i = 0; i < this._stylesheets.length; i++){ - var newstyles = ''; + + // 遍历所有样式表 + for (var i = 0; i < this._stylesheets.length; i++) { + var newstyles = ''; // 初始化新的样式字符串 + // 解析当前样式表的内容 var sheet = parser.parse(this._stylesheets[i].content, false, true); - if(sheet !== null) for(var j in sheet.cssRules){ - var rule = sheet.cssRules[j]; - - switch(rule.type){ + if (sheet !== null) for (var j in sheet.cssRules) { + var rule = sheet.cssRules[j]; // 获取当前规则 + + switch (rule.type) { default: - break; - + break; + case 1: - newstyles += this._processDeclarations(rule); - break; - + newstyles += this._processDeclarations(rule); // 处理普通规则 + break; + case 4: - newstyles += '@media ' + rule.media.join(',') + '{'; - for(var k in rule.cssRules){ - var mediarule = rule.cssRules[k]; - - newstyles += this._processDeclarations(mediarule); + newstyles += '@media ' + rule.media.join(',') + '{'; // 处理媒体查询规则 + for (var k in rule.cssRules) { + var mediarule = rule.cssRules[k]; // 获取媒体查询中的规则 + + newstyles += this._processDeclarations(mediarule); // 处理媒体查询中的规则 } newstyles += '}'; - break; + break; } } + // 创建一个新的