var Drupal=Drupal ||{“设置”:{},“行为”:{{}、“区域设置”:}};//允许其他JavaScript库使用$。jQuery.noConflict();(函数($){/***重写jQuery.fn.init以防范XSS攻击。**请参见http://bugs.jquery.com/ticket/9521*/var jquery_init=$.fn.init;$.fn.init=函数(选择器、上下文、根jQuery){//如果字符串在“<”之前包含“#”,请将其视为无效HTML。if(选择器&&typeof选择器===“字符串”){var hash_position=选择器.indexOf('#');如果(hash_position>=0){var bracket_position=选择器.indexOf('<');if(括号位置>散列位置){throw“语法错误,无法识别的表达式:”+选择器;}}}return jquery_init.call(this,selector,context,rootjQuery);};$.fn.init.protype=jquery_init.prototype;/***预先过滤Ajax请求以防范XSS攻击。**请参见https://github.com/jquery/jquery/issues/2432*/if($.ajaxPrefilter){//对于较新版本的jQuery,使用Ajax预过滤器来防止//自动执行来自不受信任域的脚本标记。这与//修复了jQuery 3.0及更高版本中内置的问题。$.ajaxPrefilter(函数){if(s.crossDomain){s.contents.script=假;}});}else if($.httpData){//对于Drupal核心附带的jQuery版本,请重写//jQuery.httpData防止自动检测来自//不受信任的域。var jquery_httpData=$.httpData;$.httpData=函数(xhr,type,s){//@todo考虑从更新的jQuery版本反向移植代码以检查//这里是跨域请求,而不是使用Drupal.urlIsLocal()//阻止来自不在同一站点上的所有URL的脚本。if(!键入&&!Drupal.urlIsLocal(s.url)){var content_type=xhr.getResponseHeader('content-type')||'';if(content_type.indexOf('javascript')>=0){//默认为安全数据类型。type=“文本”;}}return jquery_httpData.call(this,xhr,type,s);};$.httpData.protype=jquery_httpData.prototype;}/***将所有注册的行为附加到页面元素。**行为是附加到页面元素的事件触发操作,增强了*默认非JavaScript UI。行为在Drupal.Behaviors中注册*对象使用方法“attach”和可选的“detach”,如下所示:*@代码*Drupal.behaviors.behavior名称={*附加:函数(上下文,设置){* ...* },*分离:函数(上下文、设置、触发器){* ...* }* };*@endcode(结束代码)**Drupal.attachBehaviors被添加到下面的jQuery就绪事件中,因此*在初始页面加载时运行。开发人员在他们的*解决方案还应在新页面内容完成后调用此函数*加载,在要处理的元素中馈送,以便附加所有*新内容的行为。**行为应该使用*@代码*$(选择器).once('行为名称',函数(){* ...* });*@endcode(结束代码)*以确保行为只附加到给定元素一次。(这样做*允许重新处理给定元素,有时可能需要*尽管能够限制特定元素的行为附加。)**@param上下文*要附加行为的元素。如果未给定任何元素,则为文档元素*使用。*@param设置*包含当前上下文设置的对象。如果没有给出*使用全局Drupal.settings对象。*/Drupal.attachBehaviors=函数(上下文、设置){context=context||document;settings=设置||Drupal.settings;//全部执行。$.each(Drupal.behaviors,函数(){if($.isFunction(this.attach)){this.attach(上下文、设置);}});};/***从页面元素分离已注册的行为。**在解决方案中实现AHAH/Ajax的开发人员应该称之为*函数在即将删除页面内容之前,在元素中馈送*以允许特殊行为从*内容。**这样的实现应该查找在其*相应的Drupal.behaviors.behavior Name.attach实现,即。*处理behaviorName,以确保行为仅与*以前处理过的元素。**@param上下文*要从中分离行为的元素。如果没有给出,文档元素*使用。*@param设置*包含当前上下文设置的对象。如果没有给出*使用全局Drupal.settings对象。*@param触发器*包含导致行为分离的原因的字符串。这个*可能的触发因素包括:*-unload:(默认)正在从DOM中删除上下文元素。*-move:元素即将在DOM中移动(例如,*在表格拖动行交换期间)。移动完成后,*调用Drupal.attachBehaviors(),以便行为可以撤消*不管它是怎么回应这一举动的。许多行为都不需要*只需对移动的元素做出响应即可,但因为*IFRAME元素在DOM中移动时重新加载其“src”,*绑定到IFRAME元素的行为(如所见即所得编辑器)可能需要*采取一些行动。*-serialize:当提交Ajax表单时,使用*形式作为上下文。这提供了表单中的每个行为*确保字段元素具有正确内容的机会*在对表单进行序列化之前。标准用法是这样的*所见即所得编辑器可以更新其所在的隐藏文本区域*绑定。**@参见Drupal.attachBehaviors*/Drupal.detachBehaviors=函数(上下文、设置、触发器){context=context||document;settings=设置||Drupal.settings;trigger=trigger | |'unload';//全部执行。$.each(Drupal.behaviors,函数(){if($.isFunction(this.detach)){this.detach(上下文、设置、触发器);}});};/***将特殊字符编码为纯文本字符串以显示为HTML。**@ingroup消毒*/Drupal.checkPlain=函数(str){var字符、正则表达式、,replace={'&':'&',“'”:“'”,“”:“”,“<':'<','>':'>'};str=字符串(str);for(替换中的字符){if(replace.hasOwnProperty(字符)){regex=新RegExp(字符,'g');str=str.replace(regex,replace[字符]);}}返回str;};/***将占位符替换为字符串中经过清理的值。**@param字符串*包含占位符的字符串。*@param参数*要生成的替换对对象。此中任何键的事件*数组被替换为相应的值。基于第一个*键的字符,值被转义和/或主题化:* - !变量:按原样插入*-@variable:将纯文本转义为HTML(Drupal.checkPlain)*-%variable:将文本和主题转义为用户提交的占位符*内容(checkPlain+Drupal.theme(“placeholder”))**@请参阅Drupal.t()*@ingroup消毒*/Drupal.formatString=函数(str,args){//在插入参数之前对其进行转换。for(参数中的var键){if(args.hasOwnProperty(key)){开关(key.charAt(0)){//仅逃逸。案例“@”:args[key]=Drupal.checkPlain(args[key]);断裂;//直通式。案例“!”:断裂;//转义和占位符。违约:args[key]=Drupal.theme('placeholder',args[key]);断裂;}}}return Drupal.stringReplace(str,args,null);};/***替换子字符串。**将首先尝试最长的键。一旦替换了子串,*它的新值将不再被搜索。**@param{String}字符串*包含占位符的字符串。*@param{Object}参数*键值对。*@param{Array | null}键*“args”中的键数组。仅供内部使用。**@return{String}*返回替换的字符串。*/Drupal.stringReplace=函数(str、args、keys){如果(str.length====0){返回str;}//如果未传递密钥数组,则从参数中收集密钥。if(!$.isArray(keys)){键=[];for(参数中的var k){if(args.hasOwnProperty(k)){按键(k);}}//按字符长度排序键。最短的是第一个。keys.sort(函数(a,b){return a.length-b.length;});}if(键长度===0){返回str;}//从末端取下一个最长的。var键=keys.pop();var片段=str.split(键);if(键长度){for(var i=0;i<片段长度;i++){//使用剩余密钥的副本处理每个片段。fragments[i]=Drupal.stringReplace(fragments[i],args,keys.slice(0));}}return fragments.join(args[key]);};/***将字符串翻译为页面语言或给定语言。**有关更多详细信息,请参阅服务器端t()函数的文档。**@param字符串*包含要翻译的英语字符串的字符串。*@param参数*翻译后要生成的替换对对象。事件*将用相应的值替换此数组中任何键的。*请参阅Drupal.formatString()。**@param选项*-“context”(默认为空上下文):上下文源字符串*属于。**@返回*翻译后的字符串。*/Drupal.t=函数(str、args、options){options=options|{};options.context=选项.context | |“”;//获取字符串的本地化版本。if(Drupal.locale.strings和Drupal.locale.string[options.context]和Drupall.locale.strings[options.context][str]){str=Drupal.locale.strings[options.context][str];}if(参数){str=Drupal.formatString(str,args);}返回str;};/***设置包含项目计数的字符串的格式。**此函数可确保字符串正确复数。因为Drupal.t()是*被此函数调用时,请确保不要将已经本地化的字符串传递给它。**有关更多详细信息,请参阅服务器端format_plural()函数的文档。**@param计数*要显示的项目计数。*@param单数*奇异情况的字符串。请确保清楚这是*单数,以便于翻译(例如,使用“1个新评论”而不是“1个新建评论”)。*不要在单数字符串中使用@count。*@param复数*复数大小写的字符串。请确保这是复数,*以便于翻译。使用@count代替项目计数,如“@count*新评论”。*@param参数*翻译后要生成的替换对对象。事件*将用相应的值替换此数组中任何键的。*请参阅Drupal.formatString()。*请注意,您不需要在此数组中包含@count。*对于复数形式的情况,此替换将自动完成。*@param选项*传递给Drupal-t()函数的选项。*@返回*翻译后的字符串。*/Drupal.formatPural=函数(计数、单数、复数、参数、选项){args=args |{};args[“@count”]=计数;//确定复数形式的索引。var index=Drupal.locale.pluralFormula?Drupal.locale.pluralFormula(args['@count']):((args['@count']==1)?0 : 1);if(索引==0){return Drupal.t(单数,args,options);}else if(索引==1){return Drupal.t(复数,args,options);}其他{args['@count['+index+']']=args['@count'];删除参数[“@count”];return Drupal.t(复数.replace('@count','@coount['+index+']'),args,options);}};/***以绝对URL的形式返回传入的URL。**@param url*要规范化为绝对URL的URL字符串。**@返回*标准化的绝对URL。**@参见https://github.com/angular/angular.js/blob/v1.4.4/src/ng/urlUtils.js*@参见https://grack.com/blog/2009/11/17/absolutizing-url-in-javascript*@参见https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L53*/Drupal.absoluteUrl=函数(url){var urlParsingNode=文档.createElement('a');//首先解码URL;这是IE<=6所要求的。解码非UTF-8//字符串可能会引发异常。尝试{url=解码URI组件(url);}捕获(e){}urlParsingNode.setAttribute('href',url);//IE<=7在分配给锚节点时规范化URL,类似于//其他浏览器。return urlParsingNode.cloneNode(false).href;};/***如果URL位于Drupal的基本路径内,则返回true。**@param url*要测试的URL字符串。**@返回*如果是局部的,则为布尔true。**@参见https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L58*/Drupal.urlIsLocal=函数(url){//在比较中始终使用浏览器派生的绝对URL,以避免//尝试使用目录遍历中断基本路径。var absoluteUrl=Drupal.absoluteUrl(url);var协议=location.protocol;//考虑与此网站的基本URL匹配但使用HTTPS而不是HTTP的URL//也是本地的。if(协议===“http:”&&absoluteUrl.indexOf(“https:”)===0){协议=“https:”;}var baseUrl=protocol+“//”+location.host+Drupal.settings.basePath.slice(0,-1);//解码非UTF-8字符串可能会引发异常。尝试{absoluteUrl=解码URIComponent(absoluteUrl);}捕获(e){}尝试{baseUrl=解码URI组件(baseUrl);}捕获(e){}//给定的URL与站点的基本URL匹配,或在站点的//基本URL。return absoluteUrl===baseUrl||absoluteUrl.indexOf(baseUrl+'/')===0;};/***清理URL以便与jQuery.ajax()一起使用。**@param url*要清除的URL字符串。**@返回*已清理的URL。*/Drupal.sanitizeAjaxUrl=函数(url){var正则表达式=/\=\?(&|$)/;while(url.match(正则表达式)){url=url.replace(regex,'');}返回url;}/***生成Drupal对象的主题表示。**所有主题输出请求都必须通过此函数。它检查*请求并将其路由到适当的主题函数。如果电流*主题不提供覆盖函数,通用主题函数为*已调用。**例如,检索应该强调的文本的HTML*在句子中显示为占位符,调用*Drupal主题(“占位符”,文本)。**@param函数*要调用的主题函数的名称。*@param。。。*传递给主题函数的其他参数。*@返回*主题函数返回的任何数据。这可以是一个普通的HTML字符串,*也是一个复杂的对象。*/Drupal.theme=函数(func){var args=Array.prototype.slice.apply(参数,[1]);return(Drupal.theme[func]||Drupal.dheme.troptotype[func]).apply(this,args);};/***冻结当前车身高度(作为最小高度)。用于防止*进行DOM操作时不必要的向上滚动。*/Drupal.freezeHeight=函数(){Drupal.unfreezeHeight();$('
').css({position:'绝对',顶部:“0px”,左:“0px”,宽度:'1px',高度:$('body').css('height')}).appendTo(“正文”);};/***解冻车身高度。*/Drupal.unfreezeHeight=函数(){$(“#冻结高度”).remove();};/***对Drupal路径进行编码,以便在URL中使用。**出于美学原因,斜线是不可避免的。*/Drupal.encodePath=函数(item,uri){uri=uri||location.href;return encodeURIComponent(item).replace(/%2F/g,'/');};/***获取文本区域中的文本选择。*/Drupal.getSelection=函数(元素){if(元素类型.selectionStart!=“数字”&&document.selection){//当前选择。var range1=document.selection.createRange();var range2=range1.duplicate();//选择所有文本。range2.moveToElementText(元素);//现在将“虚拟”端点移动到原始范围的端点。range2.设置端点('EndToEnd',range1);//现在我们可以计算起点和终点了。var开始=范围2.text.length-范围1.text.lenth;var结束=开始+范围1.text.length;return{“start”:开始,“end”:结束};}return{“开始”:element.selectionStart,“结束”:element.selectionEnd};};/***添加一个全局变量,用于确定是否正在卸载窗口。**这主要由Drupal.displayAjaxError()使用。*/Drupal.beforeUnloadCalled=false;$(window).bind('加载前页面隐藏',函数(){Drupal.beforeUnloadCalled=true;});/***在适当的时候显示Ajax响应中的JavaScript错误。*/Drupal.displayAjaxError=函数(消息){//如果用户故意中止(例如,//通过重新加载页面或导航到其他页面)//请求仍在进行中。例如,请参阅// http://stackoverflow.com/questions/699941/handle-ajax-error-when-a-user-clicks-refresh。if(!Drupal.beforeUnloadCalled){警报(消息);}};/***从Ajax响应构建错误消息。*/Drupal.ajaxError=函数(xmlhttp,uri,customMessage){var statusCode、statusText、pathText、responseText、readyStateText、message;if(xmlhttp.status){statusCode=“\n”+Drupal.t(“发生AJAX HTTP错误。”)+“\n”+Drupal.t(“HTTP结果代码:!status”,{'!status':xmlhttp.status});}其他{statusCode=“\n”+Drupal.t(“AJAX HTTP请求异常终止。”);}statusCode+=“\n”+Drupal.t(“调试信息如下。”);pathText=“\n”+Drupal.t(“路径:!uri”,{'!uri':uri});statusText=“”;//在某些情况下,当statusCode==0时,可能不会定义xmlhttp.statusText。//不幸的是,用typeof等进行测试似乎并没有抓住这一点//测试会导致异常。所以我们需要在这里捕获异常。尝试{statusText=“\n”+Drupal.t(“statusText:!statusText”,{'!statusText':$.trim(xmlhttp.statusText)});}捕获(e){}responseText=“”;//同样,我们无法确定是否访问//xmlhttp.responseText将引发异常。所以我们会抓住它。尝试{responseText=“\n”+Drupal.t(“响应文本:!response文本”,{'!respondseText':$.trim(xmlhttp.response文本)});}捕获(e){}//通过剥离HTML标记和换行符,使responseText更具可读性。responseText=response Text.replace(/<(“[^”]*“|'[^']*'|[^'“>])*>/gi,”“);responseText=response Text.replace(/[\n]+\s+/g,“\n”);//除了status==0之外,我们不需要readyState。readyStateText=xmlhttp.status==0?(“\n”+Drupal.t(“ReadyState:!ReadyState”,{'!ReadyState':xmlhttp.ReadyState}):“”;//除了xmlhttp对象提供的内容之外,还有其他消息。customMessage=customMessage?(“\n”+Drupal.t(“自定义消息:!CustomMessage”,{'!CustomMessage':CustomMessage}):“”;消息=statusCode+pathText+statusText+customMessage+responseText+readyStateText;返回消息;};//指示启用JS的类;用于造型目的。$('html).addClass('js');$(函数(){if(Drupal.settings.setHasJsCookie===1){//“启用js”cookie。document.cookie=‘has_js=1;路径=/;同一场地=Lax';}});/***添加到jQuery.support。*/$(函数(){/***布尔值,指示是否支持位置:fixed。*/if(jQuery.support.positionFixed===未定义){var el=$('
').appendTo(document.body);jQuery.support.positionFixed=el[0].offsetTop===10;el.remove();}});//附加所有行为。$(函数(){Drupal.attachBehaviors(文档、Drupal.settings);});/***默认主题。*/Drupal.theme.prototype={/***设置文本格式,以便在句子内的占位符中强调显示。**@param字符串*要格式化的文本(纯文本)。*@返回*格式化文本(html)。*/占位符:函数(str){返回''+Drupal.checkPlain(str)+'';}};})(jQuery);