From f3b3648c7bdbe9f690ec56e64008bf53a8808de7 Mon Sep 17 00:00:00 2001 From: srosse <stephane.rosse@frentix.com> Date: Sat, 1 Sep 2018 12:20:09 +0200 Subject: [PATCH] OO-3630: add the possibility to scan wiki content with antisamy --- .../SecurityAdminConfigurationController.java | 12 - .../security/_i18n/LocalStrings_de.properties | 1 - .../security/_i18n/LocalStrings_en.properties | 1 - .../security/_i18n/LocalStrings_fr.properties | 1 - .../security/_i18n/LocalStrings_it.properties | 1 - .../_i18n/LocalStrings_pt_BR.properties | 1 - .../_i18n/LocalStrings_zh_CN.properties | 2 +- .../CollaborationToolsFactory.java | 6 +- .../olat/core/util/filter/FilterFactory.java | 8 +- .../filter/impl/OWASPAntiSamyXSSFilter.java | 54 +- .../filter/impl/_resources/antisamy-wiki.xml | 1372 +++++++++++++++++ .../wiki/WikiCourseNodeConfiguration.java | 4 +- .../run/BusinessGroupMainRunController.java | 6 +- .../modules/wiki/WikiAdminController.java | 91 ++ .../org/olat/modules/wiki/WikiModule.java | 89 ++ .../wiki/_i18n/LocalStrings_de.properties | 6 + .../wiki/_i18n/LocalStrings_en.properties | 6 + .../olat/modules/wiki/_spring/wikiContext.xml | 19 + .../wikiToHtml/WikiMarkupRenderer.java | 27 +- .../olat/repository/handlers/WikiHandler.java | 8 +- src/main/webapp/static/js/functions.js | 11 + src/main/webapp/static/js/js.plugins.min.js | 2 +- .../core/util/filter/impl/XSSFilterTest.java | 5 +- 23 files changed, 1676 insertions(+), 57 deletions(-) create mode 100644 src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-wiki.xml create mode 100644 src/main/java/org/olat/modules/wiki/WikiAdminController.java create mode 100644 src/main/java/org/olat/modules/wiki/WikiModule.java diff --git a/src/main/java/org/olat/admin/security/SecurityAdminConfigurationController.java b/src/main/java/org/olat/admin/security/SecurityAdminConfigurationController.java index 6b802319d29..260ec9d90f3 100644 --- a/src/main/java/org/olat/admin/security/SecurityAdminConfigurationController.java +++ b/src/main/java/org/olat/admin/security/SecurityAdminConfigurationController.java @@ -19,7 +19,6 @@ */ package org.olat.admin.security; -import org.olat.basesecurity.BaseSecurityModule; import org.olat.collaboration.CollaborationToolsFactory; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderModule; @@ -51,7 +50,6 @@ public class SecurityAdminConfigurationController extends FormBasicController { private static final String EXAMPLE = "https://example.com"; - private MultipleSelectionElement wikiEl; private MultipleSelectionElement topFrameEl; private MultipleSelectionElement forceDownloadEl; @@ -78,8 +76,6 @@ public class SecurityAdminConfigurationController extends FormBasicController { private CSPModule cspModule; @Autowired private FolderModule folderModule; - @Autowired - private BaseSecurityModule securityModule; private final HeadersFilter headersProvider; @@ -99,13 +95,6 @@ public class SecurityAdminConfigurationController extends FormBasicController { resourcesCont.setFormTitle(translate("sec.title")); resourcesCont.setFormDescription(translate("sec.description")); resourcesCont.setFormContextHelp("Security"); - - // on: block wiki (more security); off: do not block wiki (less security) - wikiEl = uifactory.addCheckboxesHorizontal("sec.wiki", "sec.wiki", resourcesCont, keys, values); - wikiEl.addActionListener(FormEvent.ONCHANGE); - if(!securityModule.isWikiEnabled()) { - wikiEl.select("on", true); - } // on: force file download in folder component (more security); off: allow execution of content (less security) forceDownloadEl = uifactory.addCheckboxesHorizontal("sec.download", "sec.force.download", resourcesCont, keys, values); @@ -226,7 +215,6 @@ public class SecurityAdminConfigurationController extends FormBasicController { @Override protected void formOK(UserRequest ureq) { cspModule.setForceTopFrame(topFrameEl.isAtLeastSelected(1)); - securityModule.setWikiEnabled(!wikiEl.isAtLeastSelected(1)); cspModule.setXFrameOptionsSameoriginEnabled(xFrameOptionsSameoriginEl.isAtLeastSelected(1)); cspModule.setStrictTransportSecurity(strictTransportSecurityEl.isAtLeastSelected(1)); cspModule.setxContentTypeOptions(xContentTypeOptionsEl.isAtLeastSelected(1)); diff --git a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_de.properties index 64bf5368cae..800fb6f6dd2 100644 --- a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_de.properties @@ -22,7 +22,6 @@ sec.force.download=Dateidownload in Ordner erzwingen sec.title=Sicherheitseinstellungen sec.topframe=Frame Einbettung per JavaScript verhindern sec.strict.transport.sec=Verhindern HTTPS zu HTTP downgrade mit HTTP Header -sec.wiki=Wiki Ressourcen blockieren sec.top.frame.explanation=Aus Kompatibilit\u00e4tsgr\u00fcnden k\u00F6nnen einige Komponenten von OpenOLAT (TinyMCE) nicht in einem Frame dargestellt werden. sec.xframe.sameorigin=Frame Einbettung mit HTTP header X-FRAME-OPTIONS=SAMEDOMAIN verhindern security.configuration=Konfiguration diff --git a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_en.properties index 598b9e64821..13c52a3688a 100644 --- a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_en.properties @@ -23,7 +23,6 @@ sec.strict.transport.sec=Prevent downgrade of HTTPS to HTTP with HTTP header sec.title=Security settings sec.top.frame.explanation=Due to compatibility reasons, the rich text component (TinyMCE) of OpenOLAT cannot be embedded in a frame. sec.topframe=Prevent embedding in frames using JavaScript code -sec.wiki=Block wiki resources sec.xframe.sameorigin=Prevent embedding in frames by sending HTTP header X-FRAME-OPTIONS\=SAMEDOMAIN security.configuration=Configuration security.csp.log=Content security policy log diff --git a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_fr.properties index b9cec41b943..dfa094c4068 100644 --- a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_fr.properties @@ -23,7 +23,6 @@ sec.strict.transport.sec=Emp\u00EAcher le passage d'HTTPS vers HTTP par en-t\u00 sec.title=Param\u00E8tres de s\u00E9curit\u00E9 sec.top.frame.explanation=En raison d'incompatibilit\u00E9s avec certains composants d'OpenOLAT (TinyMCE), il n'est pas possible d'int\u00E9grer OpenOLAT dans une frame. sec.topframe=Emp\u00EAcher l'int\u00E9gration dans les cadres/frames -sec.wiki=Bloquer la resource de type wiki sec.xframe.sameorigin=Interdire l'encadrant dans une frame avec l'en-t\u00EAte "X-FRAME-OPTIONS\=SAMEDOMAIN" security.configuration=Configuration security.csp.log=Log "content security policy" diff --git a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_it.properties index 9f1b152ae10..c56dd2ae1d7 100644 --- a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_it.properties +++ b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_it.properties @@ -6,4 +6,3 @@ sec.force.download=Forzare lo scaricamento dei file nelle cartelle sec.title=Impostazioni di sicurezza sec.top.frame.explanation=Per motivi di compatibilit\u00E0, l'editor di testo (TinyMCE) di OpenOLAT non pu\u00F2 essere incluso in un frame. sec.topframe=Impedire l'inclusione in frame -sec.wiki=Bloccare risorse wiki diff --git a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_pt_BR.properties index 037429c01f1..930e5ad85df 100644 --- a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_pt_BR.properties @@ -23,7 +23,6 @@ sec.strict.transport.sec=Evitar o downgrade de HTTPS para HTTP com cabe\u00E7alh sec.title=Configura\u00E7\u00F5es de seguran\u00E7a sec.top.frame.explanation=Devido a raz\u00F5es de compatibilidade, o componente de texto HTML (TinyMCE) de OpenOLAT n\u00E3o pode ser incorporado em um quadro. sec.topframe=Impedir a incorpora\u00E7\u00E3o em quadros -sec.wiki=Bloquear recursos wiki sec.xframe.sameorigin=Impedir a incorpora\u00E7\u00E3o em quadros enviando o cabe\u00E7alho HTTP X-FRAME-OPTIONS\=SAMEDOMAIN security.configuration=Configura\u00E7\u00E3o security.csp.log=Log de pol\u00EDtica de seguran\u00E7a de conte\u00FAdo diff --git a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_zh_CN.properties index d649413d07d..9c27d65759c 100644 --- a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_zh_CN.properties +++ b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_zh_CN.properties @@ -11,4 +11,4 @@ sec.description=\u8BF7\u60A8\u6839\u636E\u60A8\u673A\u6784\u7684\u8981\u6C42\u67 sec.force.download=\u5F3A\u5236\u5411\u6587\u4EF6\u5939\u4E2D\u4E0B\u8F7D\u6587\u4EF6 sec.title=\u5B89\u5168\u8BBE\u7F6E sec.topframe=\u9632\u6B62\u6846\u67B6\u5D4C\u5165 -sec.wiki=\u5173\u95ED\u7EF4\u57FA\u8D44\u6E90 + diff --git a/src/main/java/org/olat/collaboration/CollaborationToolsFactory.java b/src/main/java/org/olat/collaboration/CollaborationToolsFactory.java index 1064b574c35..51457022d7b 100644 --- a/src/main/java/org/olat/collaboration/CollaborationToolsFactory.java +++ b/src/main/java/org/olat/collaboration/CollaborationToolsFactory.java @@ -27,7 +27,6 @@ package org.olat.collaboration; import java.util.ArrayList; -import org.olat.basesecurity.BaseSecurityModule; import org.olat.commons.calendar.CalendarModule; import org.olat.core.CoreSpringFactory; import org.olat.core.id.OLATResourceable; @@ -41,6 +40,7 @@ import org.olat.group.BusinessGroup; import org.olat.instantMessaging.InstantMessagingModule; import org.olat.modules.openmeetings.OpenMeetingsModule; import org.olat.modules.portfolio.PortfolioV2Module; +import org.olat.modules.wiki.WikiModule; import org.olat.portfolio.PortfolioModule; /** @@ -93,8 +93,8 @@ public class CollaborationToolsFactory { if (CoreSpringFactory.getImpl(InstantMessagingModule.class).isEnabled()) { toolArr.add(CollaborationTools.TOOL_CHAT); } - BaseSecurityModule securityModule = CoreSpringFactory.getImpl(BaseSecurityModule.class); - if (securityModule.isWikiEnabled()) { + WikiModule wikiModule = CoreSpringFactory.getImpl(WikiModule.class); + if (wikiModule.isWikiEnabled()) { toolArr.add(CollaborationTools.TOOL_WIKI); } PortfolioModule portfolioModule = CoreSpringFactory.getImpl(PortfolioModule.class); diff --git a/src/main/java/org/olat/core/util/filter/FilterFactory.java b/src/main/java/org/olat/core/util/filter/FilterFactory.java index e919499b273..d943522aea0 100644 --- a/src/main/java/org/olat/core/util/filter/FilterFactory.java +++ b/src/main/java/org/olat/core/util/filter/FilterFactory.java @@ -28,6 +28,7 @@ import org.olat.core.util.filter.impl.SimpleHTMLTagsFilter; import org.olat.core.util.filter.impl.SmileysCssToDataUriFilter; import org.olat.core.util.filter.impl.XMLValidCharacterFilter; import org.olat.core.util.filter.impl.XMLValidEntityFilter; +import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter.Variant; /** * Description:<br> @@ -108,7 +109,12 @@ public class FilterFactory { */ public static Filter getXSSFilterForTextField(int maxLength) { // currently the XSS filter is statefull - return new OWASPAntiSamyXSSFilter(maxLength, false, false); + return new OWASPAntiSamyXSSFilter(maxLength, false, Variant.tinyMce, false); + } + + public static Filter getXSSFilterForWiki(int maxLength) { + // currently the XSS filter is statefull + return new OWASPAntiSamyXSSFilter(maxLength, false, Variant.wiki, false); } /** diff --git a/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java b/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java index 8d85317e203..bea7128ddae 100644 --- a/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java +++ b/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java @@ -56,29 +56,40 @@ public class OWASPAntiSamyXSSFilter implements Filter { //to be found in /_resources private static final String POLICY_FILE = "antisamy-tinymce.xml"; + private static final String WIKI_POLICY_FILE = "antisamy-wiki.xml"; private static boolean jUnitDebug; private CleanResults cr; private final int maxLength; + private final Variant variant; private final boolean entityEncodeIntlChars; private static Policy tinyMcePolicy; private static Policy internalionalTinyMcePolicy; + private static Policy wikiPolicy; + private static Policy internalionalWikiPolicy; static { - try { - String fPath = VFSManager.sanitizePath(OWASPAntiSamyXSSFilter.class.getPackage().getName()); - fPath = fPath.replace('.', '/'); - fPath = fPath + "/_resources/" + POLICY_FILE; - InputStream inStream = OWASPAntiSamyXSSFilter.class.getResourceAsStream(fPath); + String fPath = VFSManager.sanitizePath(OWASPAntiSamyXSSFilter.class.getPackage().getName()); + fPath = fPath.replace('.', '/'); + String tinyPath = fPath + "/_resources/" + POLICY_FILE; + try(InputStream inStream = OWASPAntiSamyXSSFilter.class.getResourceAsStream(tinyPath)) { tinyMcePolicy = Policy.getInstance(inStream); internalionalTinyMcePolicy = tinyMcePolicy.cloneWithDirective("entityEncodeIntlChars", "false"); } catch (Exception e) { log.error("", e); } + + String wikiPath = fPath + "/_resources/" + WIKI_POLICY_FILE; + try(InputStream inStream = OWASPAntiSamyXSSFilter.class.getResourceAsStream(wikiPath)) { + wikiPolicy = Policy.getInstance(inStream); + internalionalWikiPolicy = wikiPolicy.cloneWithDirective("entityEncodeIntlChars", "false"); + } catch (Exception e) { + log.error("", e); + } } public OWASPAntiSamyXSSFilter(){ - this(-1, true, false); + this(-1, true, Variant.tinyMce, false); } /** @@ -86,18 +97,16 @@ public class OWASPAntiSamyXSSFilter implements Filter { * @param junitDebug */ public OWASPAntiSamyXSSFilter(int maxLength, boolean junitDebug){ - this(maxLength, true, junitDebug); + this(maxLength, true, Variant.tinyMce, junitDebug); } - public OWASPAntiSamyXSSFilter(int maxLength, boolean entityEncodeIntlChars, boolean junitDebug){ + public OWASPAntiSamyXSSFilter(int maxLength, boolean entityEncodeIntlChars, Variant variant, boolean junitDebug){ OWASPAntiSamyXSSFilter.jUnitDebug = junitDebug; + this.variant = variant; this.maxLength = maxLength; this.entityEncodeIntlChars = entityEncodeIntlChars; } - /** - * @see org.olat.core.util.filter.Filter#filter(java.lang.String) - */ @Override public String filter(String original) { if (original == null) { @@ -106,7 +115,7 @@ public class OWASPAntiSamyXSSFilter implements Filter { } String output = getCleanHTML(original); if (original.equals(output)) { -// logInfo(" filter worked correctly!", null); + // works } else { String errMsg = getOrPrintErrorMessages(); if (!errMsg.equals("")) { @@ -130,11 +139,20 @@ public class OWASPAntiSamyXSSFilter implements Filter { private String getCleanHTML(String original) { Policy policy; - if(entityEncodeIntlChars) { - policy = tinyMcePolicy; + if(variant == Variant.wiki) { + if(entityEncodeIntlChars) { + policy = wikiPolicy; + } else { + policy = internalionalWikiPolicy; + } } else { - policy = internalionalTinyMcePolicy; + if(entityEncodeIntlChars) { + policy = tinyMcePolicy; + } else { + policy = internalionalTinyMcePolicy; + } } + if(maxLength > 0) { policy = policy.cloneWithDirective("maxInputSize", Integer.toString(maxLength)); } @@ -186,4 +204,10 @@ public class OWASPAntiSamyXSSFilter implements Filter { } return errors; } + + public enum Variant { + tinyMce, + wiki + + } } diff --git a/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-wiki.xml b/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-wiki.xml new file mode 100644 index 00000000000..91281caaa49 --- /dev/null +++ b/src/main/java/org/olat/core/util/filter/impl/_resources/antisamy-wiki.xml @@ -0,0 +1,1372 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE definition [ + <!ENTITY Agrave "À"> + <!ENTITY Aacute "Á"> + <!ENTITY Acirc "Â"> + <!ENTITY Atilde "Ã"> + <!ENTITY Auml "Ä"> + <!ENTITY Egrave "È"> + <!ENTITY Eacute "É"> + <!ENTITY Ecirc "Ê"> + <!ENTITY Euml "Ë"> + <!ENTITY Igrave "Ì"> + <!ENTITY Iacute "Í"> + <!ENTITY Icirc "Î"> + <!ENTITY Iuml "Ï"> + <!ENTITY Ograve "Ò"> + <!ENTITY Oacute "Ó"> + <!ENTITY Ocirc "Ô"> + <!ENTITY Otilde "Õ"> + <!ENTITY Ouml "Ö"> + <!ENTITY Ugrave "Ù"> + <!ENTITY Uacute "Ú"> + <!ENTITY Ucirc "Û"> + <!ENTITY Uuml "Ü"> + <!ENTITY agrave "à"> + <!ENTITY aacute "á"> + <!ENTITY acirc "â"> + <!ENTITY atilde "ã"> + <!ENTITY auml "ä"> + <!ENTITY egrave "è"> + <!ENTITY eacute "é"> + <!ENTITY ecirc "ê"> + <!ENTITY euml "ë"> + <!ENTITY igrave "ì"> + <!ENTITY iacute "í"> + <!ENTITY icirc "î"> + <!ENTITY iuml "ï"> + <!ENTITY ograve "ò"> + <!ENTITY oacute "ó"> + <!ENTITY ocirc "ô"> + <!ENTITY ouml "ö"> + <!ENTITY ugrave "ù"> + <!ENTITY uacute "ú"> + <!ENTITY ucirc "û"> + <!ENTITY uuml "ü"> +]> +<!-- + TinyMCE policy download from trunk adapted for OLAT + Version found at 30.07.2009, Adaption made by frentix GmbH +--> + +<anti-samy-rules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="antisamy.xsd"> + + <directives> + <directive name="omitXmlDeclaration" value="true" /> + <directive name="omitDoctypeDeclaration" value="true" /> + <directive name="maxInputSize" value="1000000" /> + <directive name="embedStyleSheets" value="false" /> + <directive name="useXHTML" value="true" /> + <directive name="formatOutput" value="false" /> + <directive name="entityEncodeIntlChars" value="true" /> + <directive name="preserveSpace" value="true" /> + </directives> + + <common-regexps> + <regexp name="anything" value=".*" /> + <!-- + From W3C: + This attribute assigns a class name or set of class names to an + element. Any number of elements may be assigned the same class + name or names. Multiple class names must be separated by white + space characters. + --> + <regexp name="htmlTitle" + value="[a-zA-Z0-9\s-_',:\[\]!\./\\\(\)%&;\+#]*" /> + <regexp name="htmlClass" value="[a-zA-Z0-9\s,-_]+" /> + + <!-- force non-empty with a '+' at the end instead of '*' + --> + <regexp name="olatInternalURL" + value="javascript:parent\.gotonode\(\d+\)" /> + <regexp name="onsiteURL" + value="([\p{L}\p{N}\p{Zs}/\.\?=&\-~_#])+" /> + + <!-- + <regexp name="offsiteURL" + value="^(?:(?:http(?:s)?|ftp)://)(?:\\\\S+(?::(?:\\\\S)*)?@)?(?:(?:[a-z0-9\\u00a1-\\uffff](?:-)*)*(?:[a-z0-9\\u00a1-\\uffff])+)(?:\\\\.(?:[a-z0-9\\u00a1-\\uffff](?:-)*)*(?:[a-z0-9\\u00a1-\\uffff])+)*(?:\\\\.(?:[a-z0-9\\u00a1-\\uffff]){2,})(?::(?:\\\\d){2,5})?(?:/(?:\\\\S)*)?$" /> + --> + + <regexp name="offsiteURL" + value="(\s)*(http(s?)://|mailto:)[A-Za-z0-9]+[~a-zA-Z0-9\u00a1-\uffff-_\.@#$% &;À;ÁÂÃÄÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜàáâãäèéêëìíîïòóôöùúûü;:,\?=/\+!]*(\s)*" /> + + <!-- + <regexp name="offsiteURL" + value="(\s)*(http(s?)://|mailto:)[A-Za-z0-9]+[~a-zA-Z0-9-_\.@#$%&;:,\?=/\+!]*(\s)*" /> + --> + <!-- This is for resources referenced from CSS (such as background images and other imported stylesheets) --> + <regexp name="cssOnsiteUri" value="url\(([\p{L}\p{N}\\/\.\?=\#&;\-_~]+|\#(\w)+)\)"/> + <regexp name="cssOffsiteUri" value="url\((\s)*(http(s?)://)[\p{L}\p{N}]+[~\p{L}\p{N}\p{Zs}\-_\.@#$%&;:,\?=/\+!]*(\s)*\)"/> + + <regexp name="paragraph" + value="([\p{L}\p{N},'\.\s\-_\(\)]|&[0-9]{2};)*" /> + + <regexp name="numberOrPercent" value="(\d)+(%{0,1})" /> + <regexp name="number" value="[0-9]+" /> + <regexp name="length" + value="((-|\+)?0|(-|\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))" /> + <regexp name="positiveLength" value="((\+)?0|(\+)?([0-9]+(.[0-9]+)?)(em|ex|px|in|cm|mm|pt|pc))"/> + <regexp name="percentage" value="(-|\+)?([0-9]+(.[0-9]+)?)%" /> + <regexp name="positivePercentage" value="(\+)?([0-9]+(.[0-9]+)?)%"/> + <regexp name="absolute-size" value="(xx-small|x-small|small|medium|large|x-large|xx-large)"/> + <regexp name="relative-size" value="(larger|smaller)"/> + + <!-- The 16 colors defined by the HTML Spec (also used by the CSS Spec) --> + <regexp name="colorName" + value="(aqua|black|blue|fuchsia|gray|grey|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)" /> + <!-- HTML/CSS Spec allows 3 or 6 digit hex to specify color --> + <regexp name="colorCode" + value="(#([0-9a-fA-F]{6}|[0-9a-fA-F]{3}))" /> + <!-- Used for CSS Color specifications (complex regexp expresses integer values of 0-255) --> + <regexp name="rgbCode" + value="rgb\(([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]),([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]),([1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\)" /> + <!-- CSS2 Allowed System Color Values --> + <regexp name="systemColor" + value="(activeborder|activecaption|appworkspace|background|buttonface|buttonhighlight|buttonshadow|buttontext|captiontext|graytext|highlight|highlighttext|inactiveborder|inactivecaption|inactivecaptiontext|infobackground|infotext|menu|menutext|scrollbar|threeddarkshadow|threedface|threedhighlight|threedlightshadow|threedshadow|window|windowframe|windowtext)" /> + + + </common-regexps> + + <!-- + Tag.name = a, b, div, body, etc. + Tag.action = filter: remove tags, but keep content, validate: keep content as long as it passes rules, remove: remove tag and contents + Attribute.name = id, class, href, align, width, etc. + Attribute.onInvalid = what to do when the attribute is invalid, e.g., remove the tag (removeTag), remove the attribute (removeAttribute), filter the tag (filterTag) + Attribute.description = What rules in English you want to tell the users they can have for this attribute. Include helpful things so they'll be able to tune their HTML + --> + + <!-- + Some attributes are common to all (or most) HTML tags. There aren't many that qualify for this. You have to make sure there's no + collisions between any of these attribute names with attribute names of other tags that are for different purposes. + --> + + <common-attributes> + <attribute name="id" description="The 'id' of any HTML attribute should not contain anything besides letters and numbers"> + <regexp-list> + <regexp value="[a-zA-Z0-9_\-\:]+"/> + </regexp-list> + </attribute> + + <attribute name="class" + description="The 'class' of any HTML attribute is usually a single word, but it can also be a list of class names separated by spaces"> + <regexp-list> + <regexp name="htmlClass" /> + </regexp-list> + </attribute> + + <attribute name="lang" + description="The 'lang' attribute tells the browser what language the element's attribute values and content are written in"> + <regexp-list> + <regexp value="[a-zA-Z]{2,20}" /> + </regexp-list> + </attribute> + + <attribute name="title" + description="The 'title' attribute provides text that shows up in a 'tooltip' when a user hovers their mouse over the element"> + <regexp-list> + <regexp name="htmlTitle" /> + </regexp-list> + </attribute> + + <attribute name="href" onInvalid="filterTag"> + + <regexp-list> + <regexp name="onsiteURL" /> + <regexp name="offsiteURL" /> + <regexp name="olatInternalURL" /> + <!-- + --> + </regexp-list> + </attribute> + + <attribute name="align" + description="The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'"> + + <literal-list> + <literal value="center" /> + <literal value="left" /> + <literal value="right" /> + <literal value="justify" /> + <literal value="char" /> + </literal-list> + </attribute> + <attribute name="style" + description="The 'style' attribute provides the ability for users to change many attributes of the tag's contents using a strict syntax" /> + + <attribute name="alt" + description="The 'alt' attribute provides alternative text to users when its visual representation is not available"> + <regexp-list> + <regexp name="paragraph" /> + </regexp-list> + </attribute> + + <!-- Common positioning attributes --> + + <attribute name="width"> + <regexp-list> + <regexp name="numberOrPercent" /> + </regexp-list> + </attribute> + + <attribute name="height"> + <regexp-list> + <regexp name="numberOrPercent" /> + </regexp-list> + </attribute> + + <attribute name="align" + description="The 'align' attribute of an HTML element is a direction word, like 'left', 'right' or 'center'"> + <literal-list> + <literal value="center" /> + <literal value="middle" /> + <literal value="left" /> + <literal value="right" /> + <literal value="justify" /> + <literal value="char" /> + </literal-list> + </attribute> + + <attribute name="valign" + description="The 'valign' attribute of an HTML attribute is a direction word, like 'baseline','bottom','middle' or 'top'"> + <literal-list> + <literal value="baseline" /> + <literal value="bottom" /> + <literal value="middle" /> + <literal value="top" /> + </literal-list> + </attribute> + + <attribute name="border"> + <regexp-list> + <regexp name="number" /> + </regexp-list> + </attribute> + + <attribute name="dir" + description="The 'dir' attribute of an HTML attribute assigns a reading direction, like 'ltr' or 'rtl' "> + <literal-list> + <literal value="ltr" /> + <literal value="rtl" /> + </literal-list> + </attribute> + + <!-- Table attributes --> + <attribute name="rules" description="The 'rules' attribute of a table specifies where to show rules inside table. "> + <literal-list> + <literal value="none" /> + <literal value="rows" /> + <literal value="cols" /> + <literal value="groups" /> + <literal value="all" /> + </literal-list> + </attribute> + + <attribute name="summary" description="The 'summary' attribute of a table holds an abstract of table content mainly for screen readers. "> + <regexp-list> + <regexp name="paragraph" /> + </regexp-list> + </attribute> + + <attribute name="border"> + <regexp-list> + <regexp name="number" /> + </regexp-list> + </attribute> + + <attribute name="cellpadding"> + <regexp-list> + <regexp name="number" /> + </regexp-list> + </attribute> + + <attribute name="cellspacing"> + <regexp-list> + <regexp name="number" /> + </regexp-list> + </attribute> + + <attribute name="colspan"> + <regexp-list> + <regexp name="number" /> + </regexp-list> + </attribute> + + <attribute name="rowspan"> + <regexp-list> + <regexp name="number" /> + </regexp-list> + </attribute> + + <attribute name="background"> + <regexp-list> + <regexp name="onsiteURL" /> + </regexp-list> + </attribute> + + <attribute name="bgcolor"> + <regexp-list> + <regexp name="colorName" /> + <regexp name="colorCode" /> + </regexp-list> + </attribute> + + <attribute name="abbrev"> + <regexp-list> + <regexp name="paragraph" /> + </regexp-list> + </attribute> + + <attribute name="headers" + description="The 'headers' attribute is a space-separated list of cell IDs"> + <regexp-list> + <regexp value="[a-zA-Z0-9\s*]*" /> + </regexp-list> + </attribute> + + <attribute name="charoff"> + <regexp-list> + <regexp value="numberOrPercent" /> + </regexp-list> + </attribute> + + <attribute name="char"> + <regexp-list> + <regexp value=".*{0,1}" /> + </regexp-list> + </attribute> + + <attribute name="axis" + description="The 'headers' attribute is a comma-separated list of related header cells"> + <regexp-list> + <regexp value="[a-zA-Z0-9\s*,]*" /> + </regexp-list> + </attribute> + + <attribute name="nowrap" + description="The 'nowrap' attribute tells the browser not to wrap text that goes over one line"> + <regexp-list> + <regexp name="anything" /> + <!-- <regexp value="(nowrap){0,1}"/> --> + </regexp-list> + </attribute> + + <attribute name="scope" + description="The 'scope' attribute defines what's covered by the header cells"> + <literal-list> + <literal value="row" /> + <literal value="col" /> + <literal value="rowgroup" /> + <literal value="colgroup" /> + </literal-list> + </attribute> + + </common-attributes> + + <!-- + This requires normal updates as browsers continue to diverge from the W3C and each other. As long as the browser wars continue + this is going to continue. I'm not sure war is the right word for what's going on. Doesn't somebody have to win a war after + a while? + + + --> + + <global-tag-attributes> + <attribute name="id" /> + <attribute name="title" /> + <attribute name="lang" /> + <attribute name="style" /> + <attribute name="dir" /> + </global-tag-attributes> + + <tags-to-encode> + <tag>g</tag> + <tag>grin</tag> + </tags-to-encode> + + + + + + + + + + + <tag-rules> + <tag name="h1" action="validate" > + <attribute name="class" /> + </tag> + <tag name="h2" action="validate" > + <attribute name="class" /> + </tag> + <tag name="h3" action="validate" > + <attribute name="class" /> + </tag> + <tag name="h4" action="validate" > + <attribute name="class" /> + </tag> + <tag name="h5" action="validate" > + <attribute name="class" /> + </tag> + <tag name="h6" action="validate" > + <attribute name="class" /> + </tag> + + <!-- Remove --> + + <tag name="script" action="remove" /> + <tag name="noscript" action="remove" /> + <tag name="iframe" action="remove" /> + <tag name="frameset" action="remove" /> + <tag name="frame" action="remove" /> + <tag name="noframes" action="remove" /> + <tag name="head" action="remove" /> + <tag name="title" action="remove" /> + <tag name="base" action="remove" /> + <tag name="style" action="remove" /> + <tag name="link" action="remove" /> + <tag name="input" action="remove" /> + <tag name="textarea" action="remove" /> + + <!-- Truncate --> + <tag name="br" action="truncate" /> + + <!-- Validate --> + <tag name="hr" action="validate"/> + + <tag name="p" action="validate"> + <attribute name="align" /> + </tag> + <tag name="div" action="validate" > + <attribute name="class" /> + </tag> + <tag name="span" action="validate"> + <attribute name="class" /> + </tag> + <!-- necessary for font-awesome icons --> + <tag name="i" action="validate" > + <attribute name="class" /> + </tag> + + <tag name="b" action="validate" /> + <tag name="strong" action="validate" /> + <tag name="s" action="validate" /> + <tag name="strike" action="validate" /> + <tag name="u" action="validate" /> + <tag name="em" action="validate" /> + <tag name="blockquote" action="validate" > + <attribute name="class" /> + </tag> + <tag name="pre" action="validate" /> + <tag name="center" action="validate" /> + <tag name="tt" action="truncate" /> + + <tag name="a" action="validate"> + <attribute name="class" /> + <attribute name="href" onInvalid="filterTag" /> + <attribute name="alt" /> + <attribute name="name"> + <regexp-list> + <regexp value="[a-zA-Z0-9_\-\:]+"/> + </regexp-list> + </attribute> + <attribute name="onclick"> + <literal-list> + <literal value="o_XHRWikiEvent(this);" /> + <literal value="o_XHRWikiEvent(this);return(false);" /> + </literal-list> + </attribute> + <attribute name="target"> + <literal-list> + <literal value="_blank" /> + </literal-list> + </attribute> + <attribute name="nohref"> + <literal-list> + <literal value="nohref" /> + <literal value="" /> + </literal-list> + </attribute> + <attribute name="rel"> + <literal-list> + <literal value="nofollow" /> + </literal-list> + </attribute> + </tag> + + <!-- List tags + --> + <tag name="ul" action="validate" > + <attribute name="class" /> + </tag> + <tag name="ol" action="validate" > + <attribute name="class" /> + </tag> + <tag name="li" action="validate" /> + <tag name="dl" action="validate" /> + <tag name="dt" action="validate" /> + <tag name="dd" action="validate" /> + + <!-- Image & image related tags --> + <tag name="figure" action="validate" > + <attribute name="class" /> + </tag> + <tag name="figcaption" action="validate" > + <attribute name="class" /> + </tag> + + <tag name="img" action="validate"> + <attribute name="src" onInvalid="removeTag"> + <regexp-list> + <regexp name="onsiteURL" /> + <regexp name="offsiteURL" /> + </regexp-list> + </attribute> + <attribute name="class" /> + <attribute name="alt" /> + <attribute name="height" /> + <attribute name="width" /> + <attribute name="border" /> + <attribute name="align" /> + + <attribute name="hspace"> + <regexp-list> + <regexp name="number" /> + </regexp-list> + </attribute> + + <attribute name="vspace"> + <regexp-list> + <regexp name="number" /> + </regexp-list> + </attribute> + </tag> + + + <tag name="sub" action="validate" /> + <tag name="sup" action="validate" /> + <tag name="caption" action="validate" /> + + + <!-- Table tags (tbody, thead, tfoot)--> + + <tag name="thead" action="validate"> + <attribute name="align" /> + <attribute name="char" /> + <attribute name="charoff" /> + <attribute name="valign" /> + </tag> + + <tag name="tbody" action="validate"> + <attribute name="align" /> + <attribute name="char" /> + <attribute name="charoff" /> + <attribute name="valign" /> + </tag> + + <tag name="tfoot" action="validate"> + <attribute name="align" /> + <attribute name="char" /> + <attribute name="charoff" /> + <attribute name="valign" /> + </tag> + + <tag name="table" action="validate"> + <attribute name="class" /> + <attribute name="height" /> + <attribute name="width" /> + <attribute name="border" /> + <attribute name="bgcolor" /> + <attribute name="cellpadding" /> + <attribute name="cellspacing" /> + <attribute name="background" /> + <attribute name="align" /> + <attribute name="rules" /> + <attribute name="summary" /> + <attribute name="noresize"> + <literal-list> + <literal value="noresize" /> + <literal value="" /> + </literal-list> + </attribute> + </tag> + + <tag name="td" action="validate"> + <attribute name="background" /> + <attribute name="bgcolor" /> + <attribute name="abbrev" /> + <attribute name="axis" /> + <attribute name="headers" /> + <attribute name="scope" /> + <attribute name="nowrap" /> + <attribute name="height" /> + <attribute name="width" /> + <attribute name="align" /> + <attribute name="char" /> + <attribute name="charoff" /> + <attribute name="valign" /> + <attribute name="colspan" /> + <attribute name="rowspan" /> + </tag> + + <tag name="th" action="validate"> + <attribute name="abbrev" /> + <attribute name="axis" /> + <attribute name="headers" /> + <attribute name="scope" /> + <attribute name="nowrap" /> + <attribute name="bgcolor" /> + <attribute name="height" /> + <attribute name="width" /> + <attribute name="align" /> + <attribute name="char" /> + <attribute name="charoff" /> + <attribute name="valign" /> + <attribute name="colspan" /> + <attribute name="rowspan" /> + </tag> + + <tag name="tr" action="validate"> + <attribute name="class" /> + <attribute name="height" /> + <attribute name="width" /> + <attribute name="align" /> + <attribute name="valign" /> + <attribute name="char" /> + <attribute name="charoff" /> + <attribute name="background" /> + </tag> + + <tag name="init" action="validate"> + + </tag> + + </tag-rules> + + + + + + + + <css-rules> + + <property name="height" default="auto" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="auto" /> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="length" /> + <regexp name="percentage" /> + </regexp-list> + </property> + <property name="width" default="auto" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="auto" /> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="length" /> + <regexp name="percentage" /> + </regexp-list> + </property> + + <property name="float" default="none" + description=""> + + <category-list> + <category value="visual" /> + </category-list> + + <literal-list> + <literal value="left" /> + <literal value="right" /> + <literal value="none" /> + <literal value="inherit" /> + </literal-list> + </property> + + <property name="text-decoration" default="none" + description=""> + + <category-list> + <category value="visual" /> + </category-list> + + <literal-list> + <literal value="underline" /> + <literal value="overline" /> + <literal value="line-through" /> + </literal-list> + </property> + + <property name="text-align" + description="This property describes how inline content of a block is aligned."> + <category-list> + <category value="visual" /> + </category-list> + <!-- For safety, ignoring string alignment which can be used to line table cells on characters --> + <literal-list> + <literal value="left" /> + <literal value="right" /> + <literal value="center" /> + <literal value="justify" /> + <literal value="inherit" /> + </literal-list> + </property> + + <property name="vertical-align" default="baseline" description=""> + <category-list> + <category value="visual"/> + </category-list> + <literal-list> + <literal value="baseline"/> + <literal value="sub"/> + <literal value="super"/> + <literal value="top"/> + <literal value="text-top"/> + <literal value="middle"/> + <literal value="bottom"/> + <literal value="text-bottom"/> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="percentage"/> + <regexp name="length"/> + </regexp-list> + </property> + + <property name="font-family" + description="This property specifies a prioritized list of font family names and/or generic family names."> + <category-list> + <category value="visual" /> + </category-list> + <!-- allowing only generic font families --> + <literal-list> + <literal value="serif" /> + <literal value="courier" /> + <literal value="courier new" /> + <literal value="arial" /> + <literal value="lucida console" /> + <literal value="sans-serif" /> + <literal value="cursive" /> + <literal value="verdana" /> + <literal value="fantasy" /> + <literal value="monospace" /> + </literal-list> + <!-- FIXME:RH should be removed, after fix of http://code.google.com/p/owaspantisamy/issues/detail?id=49 --> + <regexp-list> + <regexp value="[\w,\-'" ]+"/> + </regexp-list> + </property> + <property name="background" description="The 'background' property is a shorthand property for setting the individual background properties (i.e., 'background-color', 'background-image', 'background-repeat', 'background-attachment' and 'background-position') at the same place in the style sheet."> + <literal-list> + <literal value="inherit"/> + </literal-list> + <shorthand-list> + <shorthand name="background-color"/> + <shorthand name="background-image"/> + <shorthand name="background-repeat"/> + <shorthand name="background-position"/> + </shorthand-list> + </property> + <property name="background-color" + description="This property sets the background color of an element, either a <color> value or the keyword 'transparent', to make the underlying colors shine through."> + <literal-list> + <literal value="transparent" /> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="colorName" /> + <regexp name="colorCode" /> + <regexp name="rgbCode" /> + <regexp name="systemColor" /> + </regexp-list> + </property> + <property name="background-image" description="This property sets the background image of an element."> + <literal-list> + <literal value="none"/> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="cssOffsiteUri"/> + <regexp name="cssOnsiteUri"/> + </regexp-list> + </property> + + <property name="background-position" description="If a background image has been specified, this property specifies its initial position."> + <literal-list> + <literal value="top"/> + <literal value="center"/> + <literal value="bottom"/> + <literal value="left"/> + <literal value="center"/> + <literal value="right"/> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="percentage"/> + <regexp name="length"/> + </regexp-list> + </property> + + <property name="background-repeat" description="If a background image is specified, this property specifies whether the image is repeated (tiled), and how."> + <literal-list> + <literal value="repeat"/> + <literal value="repeat-x"/> + <literal value="repeat-y"/> + <literal value="no-repeat"/> + <literal value="inherit"/> + </literal-list> + </property> + <property name="color" description=""> + <category-list> + <category value="visual"/> + </category-list> + <literal-list> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="colorName"/> + <regexp name="colorCode"/> + <regexp name="rgbCode"/> + <regexp name="systemColor"/> + </regexp-list> + </property> + <property name="font-size" default="medium" description=""> + <category-list> + <category value="visual"/> + </category-list> + <literal-list> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="absolute-size"/> + <regexp name="relative-size"/> + <regexp name="length"/> + <regexp name="percentage"/> + </regexp-list> + </property> + + <property name="border-color" description=""> + <category-list> + <category value="visual"/> + </category-list> + <literal-list> + <literal value="transparent"/> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="colorName"/> + <regexp name="colorCode"/> + <regexp name="rgbCode"/> + <regexp name="systemColor"/> + </regexp-list> + </property> + <property name="border-top-color" description=""> + <category-list> + <category value="visual"/> + </category-list> + <literal-list> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="colorName"/> + <regexp name="colorCode"/> + <regexp name="rgbCode"/> + <regexp name="systemColor"/> + </regexp-list> + </property> + <property name="border-right-color" description=""> + <category-list> + <category value="visual"/> + </category-list> + <literal-list> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="colorName"/> + <regexp name="colorCode"/> + <regexp name="rgbCode"/> + <regexp name="systemColor"/> + </regexp-list> + </property> + <property name="border-bottom-color" description=""> + <category-list> + <category value="visual"/> + </category-list> + <literal-list> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="colorName"/> + <regexp name="colorCode"/> + <regexp name="rgbCode"/> + <regexp name="systemColor"/> + </regexp-list> + </property> + <property name="border-left-color" description=""> + <category-list> + <category value="visual"/> + </category-list> + <literal-list> + <literal value="inherit"/> + </literal-list> + <regexp-list> + <regexp name="colorName"/> + <regexp name="colorCode"/> + <regexp name="rgbCode"/> + <regexp name="systemColor"/> + </regexp-list> + </property> + + + <!-- begin medium properties --> + <property name="border-style" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + <literal value="none" /> + <literal value="hidden" /> + <literal value="dotted" /> + <literal value="dashed" /> + <literal value="solid" /> + <literal value="double" /> + <literal value="groove" /> + <literal value="ridge" /> + <literal value="inset" /> + <literal value="outset" /> + </literal-list> + </property> + <property name="border-top-style" default="none" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + </property> + <property name="border-right-style" default="none" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="border-bottom-style" default="none" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="border-left-style" default="none" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="border-top-width" default="medium" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-width" /> + </shorthand-list> + </property> + <property name="border-right-width" default="medium" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-width" /> + </shorthand-list> + </property> + <property name="border-bottom-width" default="medium" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-width" /> + </shorthand-list> + </property> + <property name="border-left-width" default="medium" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-width" /> + </shorthand-list> + </property> + <property name="border-width" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + <literal value="thin" /> + <literal value="medium" /> + <literal value="thick" /> + </literal-list> + <regexp-list> + <regexp name="length" /> + </regexp-list> + </property> + <property name="margin" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + <literal value="auto" /> + </literal-list> + <regexp-list> + <regexp name="positiveLength" /> + <regexp name="positivePercentage" /> + </regexp-list> + </property> + <property name="margin-top" default="0" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="margin" /> + </shorthand-list> + </property> + <property name="margin-right" default="0" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="margin" /> + </shorthand-list> + </property> + <property name="margin-bottom" default="0" description=""> + <category-list> + <category value="visual" /> + </category-list> + + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="margin" /> + </shorthand-list> + </property> + <property name="margin-left" default="0" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="margin" /> + </shorthand-list> + </property> + <property name="outline-style" default="none" description=""> + <category-list> + <category value="visual" /> + <category value="interactive" /> + </category-list> + + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="outline-width" default="medium" + description=""> + <category-list> + <category value="visual" /> + <category value="interactive" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="border-width" /> + </shorthand-list> + </property> + <property name="padding" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="length" /> + <regexp name="percentage" /> + </regexp-list> + </property> + <property name="padding-top" default="0" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="padding" /> + </shorthand-list> + </property> + <property name="padding-right" default="0" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="padding" /> + </shorthand-list> + </property> + <property name="padding-bottom" default="0" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="padding" /> + </shorthand-list> + </property> + <property name="padding-left" default="0" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="padding" /> + </shorthand-list> + </property> + <!-- end medium properties --> + + <!-- begin hard properties --> + <property name="border" description=""> + <category-list> + <category value="visual" /> + </category-list> + + <literal-list> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="colorName" /> + <regexp name="colorCode" /> + <regexp name="rgbCode" /> + <regexp name="systemColor" /> + </regexp-list> + <shorthand-list> + <shorthand name="border-width" /> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="border-top" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="colorName" /> + <regexp name="colorCode" /> + <regexp name="rgbCode" /> + <regexp name="systemColor" /> + </regexp-list> + <shorthand-list> + <shorthand name="border-top-width" /> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="border-right" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="colorName" /> + <regexp name="colorCode" /> + <regexp name="rgbCode" /> + <regexp name="systemColor" /> + </regexp-list> + <shorthand-list> + <shorthand name="border-top-width" /> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="border-bottom" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="colorName" /> + <regexp name="colorCode" /> + <regexp name="rgbCode" /> + <regexp name="systemColor" /> + </regexp-list> + <shorthand-list> + <shorthand name="border-top-width" /> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="border-left" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="colorName" /> + <regexp name="colorCode" /> + <regexp name="rgbCode" /> + <regexp name="systemColor" /> + </regexp-list> + <shorthand-list> + <shorthand name="border-top-width" /> + <shorthand name="border-style" /> + </shorthand-list> + </property> + <property name="cue" description=""> + <category-list> + <category value="aural" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="cue-before" /> + <shorthand name="cue-after" /> + </shorthand-list> + </property> + <property name="list-style" description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="list-style-type" /> + <shorthand name="list-style-position" /> + <shorthand name="list-style-image" /> + </shorthand-list> + </property> + <property name="marks" default="none" description=""> + <category-list> + <category value="visual" /> + <category value="paged" /> + </category-list> + <literal-list> + <literal value="crop" /> + <literal value="cross" /> + <literal value="none" /> + <literal value="inherit" /> + </literal-list> + </property> + <property name="outline" description=""> + <category-list> + <category value="visual" /> + <category value="interactive" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <shorthand-list> + <shorthand name="outline-color" /> + <shorthand name="outline-style" /> + <shorthand name="outline-width" /> + </shorthand-list> + </property> + <property name="pause" description=""> + <category-list> + <category value="aural" /> + </category-list> + <literal-list> + <literal value="inherit" /> + </literal-list> + <regexp-list> + <regexp name="time" /> + <regexp name="percentage" /> + </regexp-list> + </property> + <property name="text-decoration" default="none" + description=""> + <category-list> + <category value="visual" /> + </category-list> + <literal-list> + <literal value="none" /> + <literal value="underline" /> + <literal value="overline" /> + <literal value="line-through" /> + <literal value="blink" /> + <literal value="inherit" /> + </literal-list> + </property> + <!-- end hard properties --> + + </css-rules> +</anti-samy-rules> \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/wiki/WikiCourseNodeConfiguration.java b/src/main/java/org/olat/course/nodes/wiki/WikiCourseNodeConfiguration.java index bce23030c4e..8202112d56b 100644 --- a/src/main/java/org/olat/course/nodes/wiki/WikiCourseNodeConfiguration.java +++ b/src/main/java/org/olat/course/nodes/wiki/WikiCourseNodeConfiguration.java @@ -27,7 +27,6 @@ package org.olat.course.nodes.wiki; import java.util.Locale; -import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.translator.Translator; import org.olat.core.util.Util; @@ -37,6 +36,7 @@ import org.olat.course.nodes.CourseNodeConfiguration; import org.olat.course.nodes.CourseNodeGroup; import org.olat.course.nodes.WikiCourseNode; import org.olat.modules.wiki.Wiki; +import org.olat.modules.wiki.WikiModule; /** * * Description:<br> @@ -56,7 +56,7 @@ public class WikiCourseNodeConfiguration extends AbstractCourseNodeConfiguration @Override public boolean isEnabled() { - return CoreSpringFactory.getImpl(BaseSecurityModule.class).isWikiEnabled() && super.isEnabled(); + return CoreSpringFactory.getImpl(WikiModule.class).isWikiEnabled() && super.isEnabled(); } @Override diff --git a/src/main/java/org/olat/group/ui/run/BusinessGroupMainRunController.java b/src/main/java/org/olat/group/ui/run/BusinessGroupMainRunController.java index 8dacae65aff..6ee67deae76 100644 --- a/src/main/java/org/olat/group/ui/run/BusinessGroupMainRunController.java +++ b/src/main/java/org/olat/group/ui/run/BusinessGroupMainRunController.java @@ -30,7 +30,6 @@ import java.util.Collections; import java.util.List; import org.olat.NewControllerFactory; -import org.olat.basesecurity.BaseSecurityModule; import org.olat.basesecurity.GroupRoles; import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; @@ -95,6 +94,7 @@ import org.olat.modules.co.ContactFormController; import org.olat.modules.openmeetings.OpenMeetingsModule; import org.olat.modules.portfolio.PortfolioV2Module; import org.olat.modules.wiki.WikiManager; +import org.olat.modules.wiki.WikiModule; import org.olat.portfolio.PortfolioModule; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryService; @@ -1179,8 +1179,8 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im root.addChild(gtnChild); } - BaseSecurityModule securityModule = CoreSpringFactory.getImpl(BaseSecurityModule.class); - if (collabTools.isToolEnabled(CollaborationTools.TOOL_WIKI) && securityModule.isWikiEnabled()) { + WikiModule wikiModule = CoreSpringFactory.getImpl(WikiModule.class); + if (collabTools.isToolEnabled(CollaborationTools.TOOL_WIKI) && wikiModule.isWikiEnabled()) { gtnChild = new GenericTreeNode(nodeIdPrefix.concat("wiki")); gtnChild.setTitle(translate("menutree.wiki")); gtnChild.setUserObject(ACTIVITY_MENUSELECT_WIKI); diff --git a/src/main/java/org/olat/modules/wiki/WikiAdminController.java b/src/main/java/org/olat/modules/wiki/WikiAdminController.java new file mode 100644 index 00000000000..9ea83cccf35 --- /dev/null +++ b/src/main/java/org/olat/modules/wiki/WikiAdminController.java @@ -0,0 +1,91 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.wiki; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 31 août 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class WikiAdminController extends FormBasicController { + + private static final String[] onKeys = new String[] { "on" }; + + private MultipleSelectionElement wikiEl; + private MultipleSelectionElement xssSanEl; + + @Autowired + private WikiModule wikiModule; + + public WikiAdminController(UserRequest ureq, WindowControl wControl) { + super(ureq, wControl); + + initForm(ureq); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + setFormTitle("admin.title"); + + String[] onValues = new String[] { translate("enable") }; + wikiEl = uifactory.addCheckboxesHorizontal("wiki.enable", "wiki.enable", formLayout, onKeys, onValues); + wikiEl.addActionListener(FormEvent.ONCHANGE); + if(wikiModule.isWikiEnabled()) { + wikiEl.select("on", true); + } + + xssSanEl = uifactory.addCheckboxesHorizontal("wiki.xss.scan", "wiki.xss.scan", formLayout, onKeys, onValues); + xssSanEl.addActionListener(FormEvent.ONCHANGE); + if(wikiModule.isXSScanEnabled()) { + xssSanEl.select("on", true); + } + } + + @Override + protected void doDispose() { + // + } + + @Override + protected void formOK(UserRequest ureq) { + // + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(wikiEl == source) { + wikiModule.setWikiEnabled(wikiEl.isAtLeastSelected(1)); + } else if(xssSanEl == source) { + wikiModule.setXSSScanEnabled(xssSanEl.isAtLeastSelected(1)); + } + super.formInnerEvent(ureq, source, event); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/modules/wiki/WikiModule.java b/src/main/java/org/olat/modules/wiki/WikiModule.java new file mode 100644 index 00000000000..a56fc362c2b --- /dev/null +++ b/src/main/java/org/olat/modules/wiki/WikiModule.java @@ -0,0 +1,89 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.wiki; + +import org.olat.basesecurity.BaseSecurityModule; +import org.olat.core.configuration.AbstractSpringModule; +import org.olat.core.util.StringHelper; +import org.olat.core.util.coordinate.CoordinatorManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * + * For historical reason, the wiki.enable property is saved + * in the base security module. + * + * Initial date: 31 août 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Service +public class WikiModule extends AbstractSpringModule { + + private static final String WIKI_XSS_SCAN_ENABLED = "wiki.xss.scan"; + + @Value("${wiki.xss.scan:enabled}") + private String xssScanEnabled; + + @Autowired + private BaseSecurityModule baseSecurityModule; + + @Autowired + public WikiModule(CoordinatorManager coordinatorManager) { + super(coordinatorManager); + } + + @Override + public void init() { + updateProperties(); + } + + @Override + protected void initFromChangedProperties() { + updateProperties(); + } + + private void updateProperties() { + String enabled = getStringPropertyValue(WIKI_XSS_SCAN_ENABLED, true); + if(StringHelper.containsNonWhitespace(enabled)) { + xssScanEnabled = enabled; + } + } + + public boolean isWikiEnabled() { + return baseSecurityModule.isWikiEnabled(); + } + + public void setWikiEnabled(boolean enable) { + baseSecurityModule.setWikiEnabled(enable); + } + + public boolean isXSScanEnabled() { + return "enabled".equals(xssScanEnabled); + } + + public void setXSSScanEnabled(boolean enable) { + String enabled = enable ? "enabled" : "disabled"; + xssScanEnabled = enabled; + setStringProperty(WIKI_XSS_SCAN_ENABLED, enabled, true); + } +} diff --git a/src/main/java/org/olat/modules/wiki/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/wiki/_i18n/LocalStrings_de.properties index 264bf5bb512..d051631720c 100644 --- a/src/main/java/org/olat/modules/wiki/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/wiki/_i18n/LocalStrings_de.properties @@ -5,6 +5,9 @@ INSERT={0} neue Linie(n) eingef\u00FCgt MOVE={0} Linie(n) verschoben O_error=Fehlermeldung WikiPage=Wiki-Seite +admin.menu.title=Wiki +admin.menu.title.alt=Wiki Konfiguration +admin.title=Wikikonfiguration archive.question=M\u00F6chten Sie das gesamte Wiki exportieren? Das Wiki wird als IMS-Content-Package exportiert. Es kann nur als CP-Lernressource importiert (Autoren) oder offline angeschaut werden. Ein Import als Wiki ist nicht m\u00f6glich. Wenn die Datei als Wiki importiert werden soll, m\u00fcssen Sie sie aus den Lernressourcen (Detailansicht) exportieren. archive.wiki=Als CP exportieren archive.wiki.title=Momentaufnahme des gesamten Wiki als CP im pers\u00F6nlichen Ordner archivieren. @@ -33,6 +36,7 @@ disabled=Diese Funktion steht in diesem Kontext nicht zur Verf\u00FCgung. discussion=Diskussion edit=Bearbeiten edit.menu=\u00C4ndern +enable=ein enter.bold=Fetter Text enter.extlink=http\://www.example.ch Linktext enter.headline=\u00DCberschrift Text @@ -100,6 +104,7 @@ table.header.viewcount=Z\u00E4hler to=nach update.comment=Bitte Kommentar f\u00FCr neue Version angeben\! upload.example=Achtung bei Sonderzeichen und Umlauten in Dateinamen\! Erlaubt sind nur . - und _ +wiki.enable=Wikiressource einschalten wiki.error.contains.bad.chars=Das Wiki-Wort enth\u00E4lt nicht erlaubte Sonderzeichen\! wiki.error.file.not.found=Die Datei konnte nicht gefunden werden, evt. wurde sie von einer anderen Person gel\u00F6scht oder der Dateiname enth\u00E4lt ung\u00FCltige Sonderzeichen. Bitte passen Sie den Link und den Dateinamen an\! wiki.error.page.not.found=<br>Der Artikel wurde von einer anderen Person gel\u00F6scht und kann daher nicht angezeigt werden. Bitte passen Sie den Link an\! @@ -108,4 +113,5 @@ wiki.exported.from.group={0} Wiki wiki.exported.from.repository={0} wiki.index=Startseite wiki.deleted=Das Wiki wurde gel\u00f6scht. +wiki.xss.scan=XSS Scanner wikiContentElement={0} diff --git a/src/main/java/org/olat/modules/wiki/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/wiki/_i18n/LocalStrings_en.properties index 33d3312a2b0..a77a91c92f3 100644 --- a/src/main/java/org/olat/modules/wiki/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/wiki/_i18n/LocalStrings_en.properties @@ -5,6 +5,9 @@ INSERT={0} new line(s) inserted MOVE={0} line(s) moved O_error=Error message WikiPage=Wiki page +admin.menu.title=Wiki +admin.menu.title.alt=Configuration of wiki +admin.title=Wiki configuration archive.question=Do you really want to export the entire Wiki? It will be exported as IMS Content Package and can only be imported as CP learning resource (authors) or used offline. It is not possible to import it as Wiki. If you want to import your file as Wiki you have to export it first from learning resources (detailed view). archive.wiki=Export as CP archive.wiki.title=Archive snap-shot of entire Wiki as CP in your personal folder. @@ -33,6 +36,7 @@ disabled=This feature is not at your disposal in this context. discussion=Discussion edit=Edit edit.menu=Modify +enable=on enter.bold=Bold text enter.extlink=http\://www.example.ch link text enter.headline=Headline text @@ -100,6 +104,7 @@ table.header.viewcount=Counter to=to update.comment=Please add a comment regarding the new version\! upload.example=Attention regarding special characters and umlauts in file names\! Only . - and _ is allowed. +wiki.enable=Enable wiki resource wiki.error.contains.bad.chars=This Wiki word contains special characters that are not allowed\! wiki.error.file.not.found=File not found; either it has been deleted or the file name contains invalid characters. Please modify your link as well as your file name\! wiki.error.page.not.found=<br>This article has been deleted and cannot be displayed anymore. Please modify your link\! @@ -108,4 +113,5 @@ wiki.exported.from.group={0} Wiki wiki.exported.from.repository={0} wiki.index=Home page wiki.deleted=The wiki has been deleted. +wiki.xss.scan=XSS scanner wikiContentElement={0} diff --git a/src/main/java/org/olat/modules/wiki/_spring/wikiContext.xml b/src/main/java/org/olat/modules/wiki/_spring/wikiContext.xml index 6f010a27ce7..158c123d39c 100644 --- a/src/main/java/org/olat/modules/wiki/_spring/wikiContext.xml +++ b/src/main/java/org/olat/modules/wiki/_spring/wikiContext.xml @@ -13,5 +13,24 @@ <property name="fileResourceManager" ref="fileresourceManager"></property> <property name="resourceManager" ref="resourceManager"></property> </bean> + + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="7210" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.modules.wiki.WikiAdminController"/> + </bean> + </property> + <property name="navigationKey" value="wiki" /> + <property name="parentTreeNodeIdentifier" value="modulesParent" /> + <property name="i18nActionKey" value="admin.menu.title"/> + <property name="i18nDescriptionKey" value="admin.menu.title.alt"/> + <property name="translationPackage" value="org.olat.modules.wiki"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> </beans> \ No newline at end of file diff --git a/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java b/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java index cdf4682d6d1..38779fa7d6d 100644 --- a/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java +++ b/src/main/java/org/olat/modules/wiki/gui/components/wikiToHtml/WikiMarkupRenderer.java @@ -32,6 +32,7 @@ import java.util.Locale; import org.jamwiki.parser.ParserDocument; import org.jamwiki.parser.ParserInput; import org.jamwiki.parser.jflex.JFlexParser; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.DefaultComponentRenderer; import org.olat.core.gui.control.winmgr.AJAXFlags; @@ -43,6 +44,8 @@ import org.olat.core.gui.translator.Translator; import org.olat.core.helpers.Settings; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.util.Formatter; +import org.olat.core.util.filter.FilterFactory; +import org.olat.modules.wiki.WikiModule; /** * Description:<br> @@ -67,10 +70,8 @@ public class WikiMarkupRenderer extends DefaultComponentRenderer { input.setWikiUser(null); input.setAllowSectionEdit(false); input.setDepth(10); - input.setContext(""); - //input.setTableOfContents(null); + input.setContext(Settings.createServerURI()); input.setLocale(new Locale("en")); - //input.setVirtualWiki(Long.toString(wikiComp.getOres().getResourceableId())); input.setTopicName("dummy"); input.setUserIpAddress("0.0.0.0"); OlatWikiDataHandler dataHandler = new OlatWikiDataHandler(wikiComp.getOres(), wikiComp.getImageBaseUri()); @@ -84,9 +85,10 @@ public class WikiMarkupRenderer extends DefaultComponentRenderer { String uniqueId = "o_wiki".concat(wikiComp.getDispatchID()); try { uri = URLDecoder.decode(uri, "utf-8"); - input.setVirtualWiki(uri.substring(1, uri.length()-1)); + uri = uri.substring(1, uri.length() - 1); + input.setVirtualWiki(uri); if (iframePostEnabled) { - String targetUrl = " onclick=\"o_XHREvent(jQuery(this).attr('href'),false,true); return false;\""; + String targetUrl = " onclick=\"o_XHRWikiEvent(this);return(false);\""; input.setURLTarget(targetUrl); } sb.append("<div style=\"min-height:").append(wikiComp.getMinHeight()).append("px\" id=\"") @@ -100,9 +102,18 @@ public class WikiMarkupRenderer extends DefaultComponentRenderer { } catch (Exception e) { throw new OLATRuntimeException(this.getClass(), "error while rendering wiki page with content:"+ wikiComp.getWikiContent(), e); } - // Use global js math formatter for latex formulas - sb.append(Formatter.formatLatexFormulas(parsedDoc.getContent())) - .append("</div>"); + if(parsedDoc != null) { + // Use global js math formatter for latex formulas + String content = parsedDoc.getContent(); + + boolean xssScan = CoreSpringFactory.getImpl(WikiModule.class).isXSScanEnabled(); + if(xssScan) { + content = FilterFactory.getXSSFilterForWiki(-1).filter(content); + } + sb.append(Formatter.formatLatexFormulas(content)); + } + + sb.append("</div>"); //set targets of media, image and external links to target "_blank" sb.append("<script type=\"text/javascript\">/* <![CDATA[ */ ") .append("changeAnchorTargets('").append(uniqueId).append("','").append(Settings.getServerContextPathURI()).append("');") diff --git a/src/main/java/org/olat/repository/handlers/WikiHandler.java b/src/main/java/org/olat/repository/handlers/WikiHandler.java index b847b1606b5..9b55efd3c18 100644 --- a/src/main/java/org/olat/repository/handlers/WikiHandler.java +++ b/src/main/java/org/olat/repository/handlers/WikiHandler.java @@ -28,7 +28,6 @@ package org.olat.repository.handlers; import java.io.File; import java.util.Locale; -import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.commons.services.notifications.NotificationsManager; @@ -62,6 +61,7 @@ import org.olat.fileresource.types.ResourceEvaluation; import org.olat.fileresource.types.WikiResource; import org.olat.modules.wiki.WikiMainController; import org.olat.modules.wiki.WikiManager; +import org.olat.modules.wiki.WikiModule; import org.olat.modules.wiki.WikiSecurityCallback; import org.olat.modules.wiki.WikiSecurityCallbackImpl; import org.olat.modules.wiki.WikiToZipUtils; @@ -90,7 +90,7 @@ public class WikiHandler implements RepositoryHandler { @Override public boolean isCreate() { - return true; + return CoreSpringFactory.getImpl(WikiModule.class).isWikiEnabled(); } @Override @@ -177,8 +177,8 @@ public class WikiHandler implements RepositoryHandler { @Override public MainLayoutController createLaunchController(RepositoryEntry re, RepositoryEntrySecurity reSecurity, UserRequest ureq, WindowControl wControl) { // first handle special case: disabled wiki for security (XSS Attacks) reasons - BaseSecurityModule securityModule = CoreSpringFactory.getImpl(BaseSecurityModule.class); - if (!securityModule.isWikiEnabled()) { + WikiModule wikiModule = CoreSpringFactory.getImpl(WikiModule.class); + if (!wikiModule.isWikiEnabled()) { return RepositoyUIFactory.createRepoEntryDisabledDueToSecurityMessageController(ureq, wControl); } diff --git a/src/main/webapp/static/js/functions.js b/src/main/webapp/static/js/functions.js index c549631edf3..f07ba951c85 100644 --- a/src/main/webapp/static/js/functions.js +++ b/src/main/webapp/static/js/functions.js @@ -1382,6 +1382,17 @@ function o_ffXHRNFEvent(formNam, dispIdField, dispId, eventIdField, eventInt) { }) } +function o_XHRWikiEvent(link) { + var href = jQuery(link).attr('href'); + console.log(href); + if(href.indexOf(o_info.serverUri) == 0) { + href = href.substring(o_info.serverUri.length, href.length); + } + console.log(href); + o_XHREvent(href, false, true); + return false; +} + function o_XHREvent(targetUrl, dirtyCheck, push) { if(dirtyCheck && o2c==1) { // Copy function arguments and set the dirtyCheck to false for execution in callback. diff --git a/src/main/webapp/static/js/js.plugins.min.js b/src/main/webapp/static/js/js.plugins.min.js index d519377aea4..31e6681be57 100644 --- a/src/main/webapp/static/js/js.plugins.min.js +++ b/src/main/webapp/static/js/js.plugins.min.js @@ -5,7 +5,7 @@ * Dual licensed under the MIT or GPL Version 2 licenses. * */ -jQuery.periodic=function(l,h){if(jQuery.isFunction(l)){h=l;l={}}var c=jQuery.extend({},jQuery.periodic.defaults,{ajax_complete:j,increment:g,reset:f,cancel:i},l);c.cur_period=c.period;c.tid=false;var e="";b();return c;function b(){i();c.tid=setTimeout(function(){h.call(c);g();if(c.tid){b()}},c.cur_period)}function j(n,m){if(m==="success"&&e!==n.responseText){e=n.responseText;f()}}function g(){c.cur_period*=c.decay;if(c.cur_period<c.period){f()}else{if(c.cur_period>c.max_period){c.cur_period=c.max_period;if(c.on_max!==undefined){c.on_max.call(c)}}}}function f(){c.cur_period=c.period;b()}function i(){clearTimeout(c.tid);c.tid=null}function k(){}function a(){}function d(){}};jQuery.periodic.defaults={period:4000,max_period:1800000,decay:1.5,on_max:undefined};var Hashtable=(function(){var p="function";var n=(typeof Array.prototype.splice==p)?function(s,r){s.splice(r,1)}:function(u,t){var s,v,r;if(t===u.length-1){u.length=t}else{s=u.slice(t+1);u.length=t;for(v=0,r=s.length;v<r;++v){u[t+v]=s[v]}}};function a(t){var r;if(typeof t=="string"){return t}else{if(typeof t.hashCode==p){r=t.hashCode();return(typeof r=="string")?r:a(r)}else{if(typeof t.toString==p){return t.toString()}else{try{return String(t)}catch(s){return Object.prototype.toString.call(t)}}}}}function g(r,s){return r.equals(s)}function e(r,s){return(typeof s.equals==p)?s.equals(r):(r===s)}function c(r){return function(s){if(s===null){throw new Error("null is not a valid "+r)}else{if(typeof s=="undefined"){throw new Error(r+" must not be undefined")}}}}var q=c("key"),l=c("value");function d(u,s,t,r){this[0]=u;this.entries=[];this.addEntry(s,t);if(r!==null){this.getEqualityFunction=function(){return r}}}var h=0,j=1,f=2;function o(r){return function(t){var s=this.entries.length,v,u=this.getEqualityFunction(t);while(s--){v=this.entries[s];if(u(t,v[0])){switch(r){case h:return true;case j:return v;case f:return[s,v[1]]}}}return false}}function k(r){return function(u){var v=u.length;for(var t=0,s=this.entries.length;t<s;++t){u[v+t]=this.entries[t][r]}}}d.prototype={getEqualityFunction:function(r){return(typeof r.equals==p)?g:e},getEntryForKey:o(j),getEntryAndIndexForKey:o(f),removeEntryForKey:function(s){var r=this.getEntryAndIndexForKey(s);if(r){n(this.entries,r[0]);return r[1]}return null},addEntry:function(r,s){this.entries[this.entries.length]=[r,s]},keys:k(0),values:k(1),getEntries:function(s){var u=s.length;for(var t=0,r=this.entries.length;t<r;++t){s[u+t]=this.entries[t].slice(0)}},containsKey:o(h),containsValue:function(s){var r=this.entries.length;while(r--){if(s===this.entries[r][1]){return true}}return false}};function m(s,t){var r=s.length,u;while(r--){u=s[r];if(t===u[0]){return r}}return null}function i(r,s){var t=r[s];return(t&&(t instanceof d))?t:null}function b(t,r){var w=this;var v=[];var u={};var x=(typeof t==p)?t:a;var s=(typeof r==p)?r:null;this.put=function(B,C){q(B);l(C);var D=x(B),E,A,z=null;E=i(u,D);if(E){A=E.getEntryForKey(B);if(A){z=A[1];A[1]=C}else{E.addEntry(B,C)}}else{E=new d(D,B,C,s);v[v.length]=E;u[D]=E}return z};this.get=function(A){q(A);var B=x(A);var C=i(u,B);if(C){var z=C.getEntryForKey(A);if(z){return z[1]}}return null};this.containsKey=function(A){q(A);var z=x(A);var B=i(u,z);return B?B.containsKey(A):false};this.containsValue=function(A){l(A);var z=v.length;while(z--){if(v[z].containsValue(A)){return true}}return false};this.clear=function(){v.length=0;u={}};this.isEmpty=function(){return !v.length};var y=function(z){return function(){var A=[],B=v.length;while(B--){v[B][z](A)}return A}};this.keys=y("keys");this.values=y("values");this.entries=y("getEntries");this.remove=function(B){q(B);var C=x(B),z,A=null;var D=i(u,C);if(D){A=D.removeEntryForKey(B);if(A!==null){if(!D.entries.length){z=m(v,C);n(v,z);delete u[C]}}}return A};this.size=function(){var A=0,z=v.length;while(z--){A+=v[z].entries.length}return A};this.each=function(C){var z=w.entries(),A=z.length,B;while(A--){B=z[A];C(B[0],B[1])}};this.putAll=function(H,C){var B=H.entries();var E,F,D,z,A=B.length;var G=(typeof C==p);while(A--){E=B[A];F=E[0];D=E[1];if(G&&(z=w.get(F))){D=C(F,z,D)}w.put(F,D)}};this.clone=function(){var z=new b(t,r);z.putAll(w);return z}}return b})();(function(b){b.fn.ooTranslator=function(){var d=null;b(document).each(function(){d=b(document).data("_ooTranslator");if(d==undefined){d=new a();b(document).data("_ooTranslator",d)}});return d};function a(){return this}a.prototype={mapperUrl:null,translators:null,initialize:function(d){this.mapperUrl=d;this.translators=new Object()},getTranslator:function(d,f){if(this.translators[d]==null){this.translators[d]=new Object()}if(this.translators[d][f]==null){var e=this.mapperUrl+"/"+d+"/"+f+"/translations.js";jQuery.ajax(e,{async:false,dataType:"json",success:function(g,i,h){jQuery(document).ooTranslator()._createTranslator(g,d,f)}})}return this.translators[d][f]},_createTranslator:function(e,d,f){this.translators[d][f]=new c().initialize(e,d,f)}};function c(){return this}c.prototype={localizationData:null,bundle:null,locale:null,initialize:function(f,d,e){this.bundle=e;this.locale=d;this.localizationData=f;return this},translate:function(d){if(this.localizationData[d]){return this.localizationData[d]}else{return this.bundle+":"+d}}}})(jQuery);+function(b){var a=function(){this.addExtraElements();this.state={busy:false,brandW:0,sitesW:0,sitesDirty:false,sites:{collapsed:this.isSitesCollapsed(),extended:this.isSitesExtended},tabsW:0,tabsDirty:false,tabs:{collapsed:this.isTabsCollapsed(),extended:this.isTabsExtended()},toolsW:0,toolsDirty:false,tools:{collapsed:this.isToolsCollapsed(),extended:this.isToolsExtended()},offCanvasWidth:0,moreW:0};var c=b("#o_offcanvas_right").css("width");if(c){this.state.offCanvasWidth=parseInt(c.replace(/[^\d.]/g,""));this.initListners();this.calculateWidth();this.optimize()}};a.prototype.initListners=function(){b(window).resize(b.proxy(this.onResizeCallback,this));b(document).on("oo.nav.sites.modified",b.proxy(function(){this.state.sitesDirty=true},this));b(document).on("oo.nav.tabs.modified",b.proxy(function(){this.state.tabsDirty=true},this));b(document).on("oo.nav.tools.modified",b.proxy(function(){this.state.toolsDirty=true},this));b(document).on("oo.dom.replacement.after",b.proxy(this.onDOMreplacementCallback,this));b(window).on("orientationchange",b.proxy(this.hideRight,this));b("#o_navbar_right-toggle").on("click",b.proxy(this.toggleRight,this));b("#o_offcanvas_right .o_offcanvas_close").on("click",b.proxy(this.hideRight,this));b("#o_navbar_more").on("shown.bs.dropdown",this.onDropdownShown);b("#o_navbar_more").on("hidden.bs.dropdown",this.onDropdownHidden)};a.prototype.onResizeCallback=function(){if(!this.state.busy){this.state.busy=true;this.calculateWidth();this.optimize();this.state.busy=false}};a.prototype.onDOMreplacementCallback=function(){if(!this.state.busy&&(this.state.sitesDirty||this.state.tabsDirty||this.state.toolsDirty)){this.state.busy=true;this.cleanupMoreDropdown();this.calculateWidth();this.optimize();this.state.sitesDirty=false;this.state.tabsDirty=false;this.state.toolsDirty=false;this.state.busy=false}};a.prototype.onDropdownShown=function(c){var f=b("#o_navbar_more .dropdown-menu");if(f.length){var d=f.offset().left;if(d<0){f.removeClass("dropdown-menu-right")}}};a.prototype.onDropdownHidden=function(c){var d=b("#o_navbar_more .dropdown-menu");d.addClass("dropdown-menu-right")};a.prototype.calculateWidth=function(){var c=b("#o_navbar_container .o_navbar-collapse");this.state.navbarW=c.innerWidth();this.state.brandW=b(".o_navbar-brand").outerWidth(true);this.state.sitesW=this.getSites().outerWidth(true);this.state.tabsW=this.getTabs().outerWidth(true);this.state.toolsW=this.getTools().outerWidth(false);this.state.moreW=b("#o_navbar_more:visible").outerWidth(true)};a.prototype.getOverflow=function(c){var d=this.state.navbarW;d-=this.state.sitesW;d-=this.state.tabsW;d-=this.state.toolsW;d-=this.state.brandW;d-=this.state.moreW;d-=25;return -d};a.prototype.optimize=function(h){var c=this.getOverflow();var k=this.getSites();var l=this.getTabs();var g=this.getTools();var n=this.getMoreDropdown();var f=this.getOffcanvasRight();this.updateState();while(c>0&&(!this.state.tabs.collapsed||!this.state.sites.collapsed||!this.state.tools.collapsed)){if(!this.state.tabs.collapsed){this.collapse(l,n,"li","o_dropdown_tab")}else{if(!this.state.sites.collapsed){this.collapse(k,n,"li","o_dropdown_site")}else{if(!this.state.tools.collapsed){this.collapse(g,f,".o_navbar_tool:not(#o_navbar_imclient, #o_navbar_search_opener, #o_navbar_my_menu)","o_tool_right")}}}this.calculateWidth();c=this.getOverflow();this.updateState()}while(c<0&&(!this.state.tabs.extended||!this.state.sites.extended||!this.state.tools.extended)){if(!this.state.tools.extended){var m=this.extend(f,g.children("#o_navbar_imclient, #o_navbar_search_opener, #o_navbar_my_menu").first(),".o_tool_right","o_tool_right",true);if(!m){break}}if(!this.state.sites.extended){var j=this.extend(n,k,"li","o_dropdown_site");if(!j){break}}else{if(!this.state.tabs.extended){var d=this.extend(n,l,"li","o_dropdown_tab");if(!d){break}}}this.calculateWidth();c=this.getOverflow();this.updateState()}if(this.state.sites.extended&&this.state.tabs.extended){var i=b("#o_navbar_more");i.css("display","none")}this.checkToolsOrder()};a.prototype.updateState=function(){this.state.sites.collapsed=this.isSitesCollapsed();this.state.sites.extended=this.isSitesExtended();this.state.tabs.collapsed=this.isTabsCollapsed();this.state.tabs.extended=this.isTabsExtended();this.state.tools.collapsed=this.isToolsCollapsed();this.state.tools.extended=this.isToolsExtended()};a.prototype.collapse=function(g,d,c,f){var e=g.find(c);if(e.length){e=e.last()}if(e.length){f&&e.addClass(f);if(d){e.prependTo(d)}}this.updateDropdownToggle(g)};a.prototype.extend=function(g,d,c,i,f){var e=g.find(c);if(e.length){e=e.first()}var j=false;if(e.length){if(d&&d.length){if(f){d.before(e)}else{e.appendTo(d)}this.updateDropdownToggle(g);this.calculateWidth();var h=this.getOverflow();if(h>0){e.prependTo(g)}else{i&&e.removeClass(i);j=true}}}this.updateDropdownToggle(g);return j};a.prototype.updateDropdownToggle=function(c){var d=c.parents(".o_dropdown_toggle");if(!d.length){return}if(c.children().length){d.css("display","block")}else{d.css("display","none")}};a.prototype.addExtraElements=function(){var d=b("#o_navbar_container .o_navbar-collapse");var c=b("#o_navbar_more");if(c.length==0){c=b('<ul id="o_navbar_more" class="nav o_navbar-nav o_dropdown_toggle"><li><a class="dropdown-toggle" data-toggle="dropdown" href="#"">'+o_info.i18n_topnav_more+' <b class="caret"></b></a><ul class="dropdown-menu dropdown-menu-right"></ul></li></ul>');c.appendTo(d)}this.getSites().append('<li class="divider o_dropdown_site"></li>');b("#o_navbar_help .o_icon, #o_navbar_print .o_icon").addClass("o_icon-fw")};a.prototype.cleanupMoreDropdown=function(){if(!this.state.sitesDirty){var f=this.getSites();var d=this.getMoreDropdown().children(".o_dropdown_site");d.appendTo(f)}else{this.getSites().append('<li class="divider o_dropdown_site"></li>')}if(!this.state.tabsDirty){var e=this.getTabs();var c=this.getMoreDropdown().children(".o_dropdown_tab");c.prependTo(e)}this.getMoreDropdown().empty()};a.prototype.checkToolsOrder=function(){var f=this.getTools();var e=f.find("#o_navbar_help");var d=f.find("#o_navbar_print");var c=f.find("#o_navbar_imclient");if(c&&d){c.after(d)}if(c&&e){c.after(e)}};a.prototype.showRight=function(){if(!this.isOffcanvasVisible()&&!this.offcanvasTransitioning){this.offcanvasTransitioning=true;var d=this;var c=b("#o_offcanvas_right");c.show().transition({x:-d.state.offCanvasWidth},function(){b("body").addClass("o_offcanvas_right_visible");var e=b.proxy(d.hideRightOnClick,d);setTimeout(function(){b("html").on("click",e);d.offcanvasTransitioning=false},10)})}};a.prototype.hideRightOnClick=function(c){if("INPUT"!=c.target.nodeName){this.hideRight()}};a.prototype.hideRight=function(){if(this.isOffcanvasVisible()&&!this.offcanvasTransitioning){this.offcanvasTransitioning=true;b("html").off("click",b.proxy(this.hideRight,this));var d=this;var c=b("#o_offcanvas_right");c.transition({x:d.state.offCanvasWidth},function(){c.hide();b("body").removeClass("o_offcanvas_right_visible");d.offcanvasTransitioning=false})}};a.prototype.toggleRight=function(){if(this.isOffcanvasVisible()){this.hideRight()}else{this.showRight()}};a.prototype.isOffcanvasVisible=function(){return b("#o_offcanvas_right:visible").length};a.prototype.getSites=function(){return b("#o_navbar_container .o_navbar_sites")};a.prototype.getTabs=function(){return b("#o_navbar_container .o_navbar_tabs")};a.prototype.getTools=function(){return b("#o_navbar_container #o_navbar_tools_permanent")};a.prototype.getMoreDropdown=function(){return b("#o_navbar_more .dropdown-menu")};a.prototype.getOffcanvasRight=function(){return b("#o_offcanvas_right_container .o_navbar-right")};a.prototype.isSitesCollapsed=function(){return !this.getSites().children("li").not(".divider").length};a.prototype.isSitesExtended=function(){return !this.getMoreDropdown().children(".o_dropdown_site").not(".divider").length};a.prototype.isTabsCollapsed=function(){return !this.getTabs().children("li").length};a.prototype.isTabsExtended=function(){return !this.getMoreDropdown().children(".o_dropdown_tab").length};a.prototype.isToolsCollapsed=function(){return !this.getTools().children(".o_navbar_tool").not("#o_navbar_imclient, #o_navbar_search_opener, #o_navbar_my_menu").length};a.prototype.isToolsExtended=function(){return !this.getOffcanvasRight().children(".o_tool_right").length};b(document).ready(function(){var d=b("#o_navbar_wrapper");if(d){var c=new a();window.OPOL.navbar=c}})}(jQuery);+function(b){b.fn.ooBgCarrousel=function(){return new a()};var a=function(){};a.prototype.initCarrousel=function(g){this.settings=b.extend({query:null,images:[],shuffle:false,shuffleFirst:false,durationshow:5000,durationout:500,durationin:500,easeout:"ease",easein:"ease"},g);this.pos=null;if(this.settings.query==null||this.settings.images.length==0){return}this.initialImage=this.settings.images[0];if(this.settings.shuffle){var f=this.settings.images;for(var d,c,e=f.length;e;d=parseInt(Math.random()*e),c=f[--e],f[e]=f[d],f[d]=c){}}if(this.settings.shuffleFirst){this._replaceImage()}this.rotate()};a.prototype.rotate=function(){setTimeout(b.proxy(this._hideCurrent,this),this.settings.durationshow)};a.prototype._hideCurrent=function(){var c=b(this.settings.query);if(c&&c.size()>0){c.transition({opacity:0,duration:this.settings.durationout,easing:this.settings.easeout},b.proxy(this._showNext,this))}};a.prototype._replaceImage=function(d){if(!d){d=b(this.settings.query)}if(d&&d.size()>0){this.newImg="";this.oldImg="";if(this.pos==null){this.pos=1;this.oldImg=this.initialImage}else{this.oldImg=this.settings.images[this.pos];this.pos++;if(this.settings.images.length==this.pos){this.pos=0}}this.newImg=this.settings.images[this.pos];var c=d.css("background-image");if(c.indexOf(this.oldImg)==-1){d.transition({opacity:1,duration:0});return}var e=c.replace(this.oldImg,this.newImg);d.css("background-image",e)}};a.prototype._showNext=function(){var c=b(this.settings.query);this._replaceImage(c);c.transition({opacity:1,duration:this.settings.durationin,easing:this.settings.easein},b.proxy(this.rotate,this))}}(jQuery);!function(e){function t(){function t(e){"remove"===e&&this.each(function(e,t){var n=i(t);n&&n.remove()}),this.find("span.mceEditor,div.mceEditor").each(function(e,t){var n=tinymce.get(t.id.replace(/_parent$/,""));n&&n.remove()})}function r(e){var n,r=this;if(null!=e)t.call(r),r.each(function(t,n){var r;(r=tinymce.get(n.id))&&r.setContent(e)});else if(r.length>0&&(n=tinymce.get(r[0].id)))return n.getContent()}function i(e){var t=null;return e&&e.id&&a.tinymce&&(t=tinymce.get(e.id)),t}function o(e){return!!(e&&e.length&&a.tinymce&&e.is(":tinymce"))}var s={};e.each(["text","html","val"],function(t,a){var l=s[a]=e.fn[a],c="text"===a;e.fn[a]=function(t){var a=this;if(!o(a))return l.apply(a,arguments);if(t!==n)return r.call(a.filter(":tinymce"),t),l.apply(a.not(":tinymce"),arguments),a;var s="",u=arguments;return(c?a:a.eq(0)).each(function(t,n){var r=i(n);s+=r?c?r.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):r.getContent({save:!0}):l.apply(e(n),u)}),s}}),e.each(["append","prepend"],function(t,r){var a=s[r]=e.fn[r],l="prepend"===r;e.fn[r]=function(e){var t=this;return o(t)?e!==n?("string"==typeof e&&t.filter(":tinymce").each(function(t,n){var r=i(n);r&&r.setContent(l?e+r.getContent():r.getContent()+e)}),a.apply(t.not(":tinymce"),arguments),t):void 0:a.apply(t,arguments)}}),e.each(["remove","replaceWith","replaceAll","empty"],function(n,r){var i=s[r]=e.fn[r];e.fn[r]=function(){return t.call(this,r),i.apply(this,arguments)}}),s.attr=e.fn.attr,e.fn.attr=function(t,a){var l=this,c=arguments;if(!t||"value"!==t||!o(l))return a!==n?s.attr.apply(l,c):s.attr.apply(l,c);if(a!==n)return r.call(l.filter(":tinymce"),a),s.attr.apply(l.not(":tinymce"),c),l;var u=l[0],d=i(u);return d?d.getContent({save:!0}):s.attr.apply(e(u),c)}}var n,r,i,o=[],a=window;e.fn.tinymce=function(n){function s(){var r=[],o=0;i||(t(),i=!0),d.each(function(e,t){var i,a=t.id,s=n.oninit;a||(t.id=a=tinymce.DOM.uniqueId()),tinymce.get(a)||(i=new tinymce.Editor(a,n,tinymce.EditorManager),r.push(i),i.on("init",function(){var e,t=s;d.css("visibility",""),s&&++o==r.length&&("string"==typeof t&&(e=t.indexOf(".")===-1?null:tinymce.resolve(t.replace(/\.\w+$/,"")),t=tinymce.resolve(t)),t.apply(e||tinymce,r))}))}),e.each(r,function(e,t){t.render()})}var l,c,u,d=this,f="";if(!d.length)return d;if(!n)return window.tinymce?tinymce.get(d[0].id):null;if(d.css("visibility","hidden"),a.tinymce||r||!(l=n.script_url))1===r?o.push(s):s();else{r=1,c=l.substring(0,l.lastIndexOf("/")),l.indexOf(".min")!=-1&&(f=".min"),a.tinymce=a.tinyMCEPreInit||{base:c,suffix:f},l.indexOf("gzip")!=-1&&(u=n.language||"en",l=l+(/\?/.test(l)?"&":"?")+"js=true&core=true&suffix="+escape(f)+"&themes="+escape(n.theme||"modern")+"&plugins="+escape(n.plugins||"")+"&languages="+(u||""),a.tinyMCE_GZ||(a.tinyMCE_GZ={start:function(){function t(e){tinymce.ScriptLoader.markDone(tinymce.baseURI.toAbsolute(e))}t("langs/"+u+".js"),t("themes/"+n.theme+"/theme"+f+".js"),t("themes/"+n.theme+"/langs/"+u+".js"),e.each(n.plugins.split(","),function(e,n){n&&(t("plugins/"+n+"/plugin"+f+".js"),t("plugins/"+n+"/langs/"+u+".js"))})},end:function(){}}));var p=document.createElement("script");p.type="text/javascript",p.onload=p.onreadystatechange=function(t){t=t||window.event,2===r||"load"!=t.type&&!/complete|loaded/.test(p.readyState)||(tinymce.dom.Event.domLoaded=1,r=2,n.script_loaded&&n.script_loaded(),s(),e.each(o,function(e,t){t()}))},p.src=l,document.body.appendChild(p)}return d},e.extend(e.expr[":"],{tinymce:function(e){var t;return!!(e.id&&"tinymce"in window&&(t=tinymce.get(e.id),t&&t.editorManager===tinymce))}})}(jQuery);OPOL={};var o2c=0;var o3c=new Array();o_info.guibusy=false;o_info.linkbusy=false;o_info.scrolling=false;o_info.debug=true;var BLoader={_ajaxLoadedJS:new Array(),_isAlreadyLoadedJS:function(b){var a=true;jQuery("head script[src]").each(function(d,c){if(jQuery(c).attr("src").indexOf(b)!=-1){a=false}});if(jQuery.inArray(b,this._ajaxLoadedJS)!=-1){a=false}return !a},loadJS:function(b,c,a){if(!this._isAlreadyLoadedJS(b)){if(o_info.debug){o_log("BLoader::loadJS: loading ajax::"+a+" url::"+b)}if(a){jQuery.ajax(b,{async:false,dataType:"script",cache:true,success:function(d,f,e){}});this._ajaxLoadedJS.push(b)}else{jQuery.getScript(b)}if(o_info.debug){o_log("BLoader::loadJS: loading DONE url::"+b)}}else{if(o_info.debug){o_log("BLoader::loadJS: already loaded url::"+b)}}},executeGlobalJS:function(jsString,contextDesc){try{if(window.execScript){window.execScript(jsString)}else{window.eval(jsString)}}catch(e){if(window.console){console.log(contextDesc,"cannot execute js",jsString)}if(o_info.debug){o_logerr("BLoader::executeGlobalJS: Error when executing JS code in contextDesc::"+contextDesc+' error::"'+showerror(e)+" for: "+escape(jsString))}if(window.location.href.indexOf("o_winrndo")!=-1){window.location.reload()}else{window.location.href=window.location.href+(window.location.href.indexOf("?")!=-1?"&":"?")+"o_winrndo=1"}}},loadCSS:function(b,p,r){var s=window.document;try{if(s.createStyleSheet){var m=s.styleSheets;var d=0;var q=0;for(i=0;i<m.length;i++){var n=m[i];var g=n.href;if(g==b){d++;if(n.disabled){n.disabled=false;return}else{if(o_info.debug){o_logwarn("BLoader::loadCSS: style: "+b+" already in document and not disabled! (duplicate add)")}return}}if(n.id=="o_theme_css"){q=i}}if(d>1&&o_info.debug){o_logwarn("BLoader::loadCSS: apply styles: num of stylesheets found was not 0 or 1:"+d)}if(r){q=m.length}var f=s.createStyleSheet(b,q)}else{var c=jQuery("#"+p);if(c&&c.size()>0){if(o_info.debug){o_logwarn("BLoader::loadCSS: stylesheet already found in doc when trying to add:"+b+", with id "+p)}return}else{var a=jQuery('<link id="'+p+'" rel="stylesheet" type="text/css" href="'+b+'">');if(r){a.insertBefore(jQuery("#o_fontSize_css"))}else{a.insertBefore(jQuery("#o_theme_css"))}}}}catch(o){if(window.console){console.log(o)}if(o_info.debug){o_logerr("BLoader::loadCSS: Error when loading CSS from URL::"+b)}}},unLoadCSS:function(a,n){var o=window.document;try{if(o.createStyleSheet){var f=o.styleSheets;var d=0;var p=a;var b=window.location.href.substring(0,window.location.href.indexOf("/",8));if(a.indexOf(b)==0){p=a.substring(b.length)}for(i=0;i<f.length;i++){var g=f[i].href;if(g==a||g==p){d++;if(!f[i].disabled){f[i].disabled=true}else{if(o_info.debug){o_logwarn("stylesheet: when removing: matching url, but already disabled! url:"+g)}}}}if(d!=1&&o_info.debug){o_logwarn("stylesheet: when removeing: num of stylesheets found was not 1:"+d)}}else{var c=jQuery("#"+n);if(c){c.href="";c.remove();c=null;return}else{if(o_info.debug){o_logwarn("no link with id found to remove, id:"+n+", url "+a)}}}}catch(m){if(o_info.debug){o_logerr("BLoader::unLoadCSS: Error when unloading CSS from URL::"+a)}}}};var BFormatter={formatLatexFormulas:function(b){try{if(typeof MathJax==="undefined"){o_mathjax()}else{if(MathJax&&MathJax.isReady){jQuery(function(){MathJax.Hub.Queue(function(){if(jQuery("#"+b+" .MathJax").length==0){MathJax.Hub.Typeset(b)}})})}else{setTimeout(function(){BFormatter.formatLatexFormulas(b)},100)}}}catch(a){if(window.console){console.log("error in BFormatter.formatLatexFormulas: ",a)}}},alignTableColumns:function(a){try{var b=new Array();jQuery(a).each(function(){for(j=0;j<jQuery(this)[0].rows[0].cells.length;j++){var d=jQuery(this)[0].rows[0].cells[j];if(!b[j]||b[j]<d.clientWidth){b[j]=d.clientWidth}}});jQuery(a).each(function(){for(j=0;j<jQuery(this)[0].rows[0].cells.length;j++){jQuery(this)[0].rows[0].cells[j].style.width=b[j]+"px"}})}catch(c){if(window.console){console.log("error in BFormatter.alignTableColumns: ",c)}}}};function o_init(){try{o_getMainWin().o_afterserver();if(window.location.href&&window.location.href!=null&&window.location.href.indexOf("%3A")<0){var a=window.location.href;if(a!=null&&!(a.lastIndexOf("http",0)===0)&&!(a.lastIndexOf("https",0)===0)){a=o_info.serverUri+a}o_info.businessPath=a;if(!(typeof o_shareActiveSocialUrl==="undefined")){o_shareActiveSocialUrl()}}}catch(b){if(o_info.debug){o_log("error in o_init: "+showerror(b))}}}function o_initEmPxFactor(){o_info.emPxFactor=jQuery("#o_width_1em").width();if(o_info.emPxFactor==0||o_info.emPxFactor=="undefined"){o_info.emPxFactor=12}}function o_getMainWin(){try{if(window.OPOL){return window}else{if(window.opener&&window.opener.OPOL){return window.opener}}}catch(a){if(o_info.debug){o_logerr('Exception while getting main window. rror::"'+showerror(a))}if(window.console){console.log('Exception while getting main window. rror::"'+showerror(a),"functions.js");console.log(a)}}throw"Can not find main OpenOLAT window"}function o_beforeserver(){o_info.linkbusy=true;showAjaxBusy();if(window.suppressOlatOnUnloadOnce){window.suppressOlatOnUnloadOnce=false}else{if(window.olatonunload){olatonunload()}}}function o_afterserver(){o2c=0;o_info.linkbusy=false;removeAjaxBusy()}function o2cl(){try{if(o_info.linkbusy){return false}else{var b=(o2c==0||confirm(o_info.dirty_form));if(b){o_beforeserver()}return b}}catch(a){if(window.console){console.log(a)}return false}}function o2cl_dirtyCheckOnly(){try{if(o_info.linkbusy){return false}else{return(o2c==0||confirm(o_info.dirty_form))}}catch(a){if(window.console){console.log(a)}return false}}function o2cl_noDirtyCheck(){if(o_info.linkbusy){return false}else{o_beforeserver();return true}}function o3cl(d){if(o_info.linkbusy){return false}else{var b=o3c1.indexOf(d)>-1;var a=(b&&o3c1.length>1)||o3c1.length>0;var c=(!a||confirm(o_info.dirty_form));if(c){o_beforeserver()}return c}}function o_onc(a){var b=a.responseText;BLoader.executeGlobalJS("o_info.last_o_onc="+b+";","o_onc");o_ainvoke(o_info.last_o_onc,false)}function o_allowNextClick(){o_info.linkbusy=false;removeAjaxBusy()}function removeBusyAfterDownload(c,b,a){o2c=0;o_afterserver()}Array.prototype.search=function(c,d){var a=this.length;for(var b=0;b<a;b++){if(this[b].constructor==Array){if(this[b].search(c,d)){return true;break}}else{if(d){if(this[b].indexOf(c)!=-1){return true;break}}else{if(this[b]==c){return true;break}}}}return false};if(!Function.prototype.curry){Function.prototype.curry=function(){if(arguments.length<1){return this}var a=this;var b=Array.prototype.slice.call(arguments);return function(){return a.apply(this,b.concat(Array.prototype.slice.call(arguments)))}}}if(!Array.prototype.indexOf){Array.prototype.indexOf=function(c){if(this==null){throw new TypeError()}var d=Object(this);var a=d.length>>>0;if(a===0){return -1}var e=0;if(arguments.length>1){e=Number(arguments[1]);if(e!=e){e=0}else{if(e!=0&&e!=Infinity&&e!=-Infinity){e=(e>0||-1)*Math.floor(Math.abs(e))}}}if(e>=a){return -1}var b=e>=0?e:Math.max(a-Math.abs(e),0);for(;b<a;b++){if(b in d&&d[b]===c){return b}}return -1}}var b_onDomReplacementFinished_callbacks=new Array();function b_AddOnDomReplacementFinishedCallback(a){b_onDomReplacementFinished_callbacks.push(a)}var b_changedDomEl=new Array();function b_AddOnDomReplacementFinishedUniqueCallback(a){if(a.constructor==Array){if(b_onDomReplacementFinished_callbacks.search(a[0])){return}}b_AddOnDomReplacementFinishedCallback(a)}var o_debug_trid=0;function o_ainvoke(N){if(N==undefined){return}o_info.inainvoke=true;var I=N.cmdcnt;if(I>0){jQuery(document).trigger("oo.dom.replacement.before");b_changedDomEl=new Array();if(o_info.debug){o_debug_trid++}var y=N.cmds;for(var T=0;T<I;T++){var J=y[T];var A=J.cmd;var R=J.cda;var U=J.w;var c=this.window;var K;if(c){switch(A){case 1:var M=R.e;BLoader.executeGlobalJS(M,"o_ainvoker::jsexec");if(o_info.debug){o_log("c1: execute jscode: "+M)}case 2:var u=R.cc;var F=R.cps;for(var Q=0;Q<u;Q++){var m=F[Q];var h=m.cid;var P=m.cidvis;var H=m.cw;var x=m.hfrag;var O=m.jsol;var g=m.hdr;if(o_info.debug){o_log("c2: redraw: "+m.cname+" ("+h+") "+m.hfragsize+" bytes, listener(s): "+m.clisteners)}var W=g+"\n\n"+x;var C="";var S=false;var E="o_c"+h;var B=jQuery("#"+E);if(B==null||B.length==0){E="o_fi"+h;B=jQuery("#"+E);S=true}if(B!=null){var w=jQuery("div.o_richtext_mce textarea",B);for(var L=0;L<w.length;L++){try{var a=jQuery(w.get(L)).attr("id");if(typeof top.tinymce!=undefined){top.tinymce.remove("#"+a)}}catch(Z){if(window.console){console.log(Z)}}}if(P){B.css("display","")}else{B.css("display","none")}if(S||!H){B.replaceWith(W)}else{try{B.empty().html(W);if(W.length>0&&B.get(0).innerHTML==""){B.get(0).innerHTML=W}}catch(Z){if(window.console){console.log(Z)}if(window.console){console.log("Fragment",W)}}b_changedDomEl.push(E)}B=null;if(C!=""){C.each(function(e){BLoader.executeGlobalJS(e,"o_ainvoker::inscripts")})}if(O!=""){BLoader.executeGlobalJS(O,"o_ainvoker::jsol")}}}break;case 3:c.o2c=0;var X=R.rurl;c.o_afterserver();c.document.location.replace(X);break;case 5:c.o2c=0;var X=R.rurl;c.o_afterserver();c.document.location.replace(X);break;case 6:c.o2c=0;c.o_afterserver();break;case 7:var o=c.document.location;var z=o.protocol+"//"+o.hostname;if(o.port!=""){z+=":"+o.port}var v=R.cssrm;for(Q=0;Q<v.length;Q++){var D=v[Q];var G=D.id;var f=z+D.url;BLoader.unLoadCSS(f,G);if(o_info.debug){o_log("c7: rm css: id:"+G+" ,url:'"+f+"'")}}var V=R.cssadd;for(k=0;k<V.length;k++){var D=V[k];var G=D.id;var f=z+D.url;var n=D.pt;BLoader.loadCSS(f,G,n);if(o_info.debug){o_log("c7: add css: id:"+G+" ,url:'"+f+"'")}}var p=R.jsadd;for(l=0;l<p.length;l++){var D=p[l];var Y=D.before;if(jQuery.type(Y)==="string"){BLoader.executeGlobalJS(Y,"o_ainvoker::preJsAdd")}var f=D.url;var q=D.enc;if(jQuery.type(f)==="string"){BLoader.loadJS(f,q,true)}if(o_info.debug){o_log("c7: add js: "+f)}}break;default:if(o_info.debug){o_log("?: unknown command "+A)}break}}else{if(o_info.debug){o_log("could not find window??")}}}var b=b_onDomReplacementFinished_callbacks.length;for(mycounter=0;b>mycounter;mycounter++){if(mycounter>50){break}var s=b_onDomReplacementFinished_callbacks.shift();if(typeof s.length==="number"){if(s[0]=="glosshighlighter"){var d=s[1];s=d}}s()}jQuery(document).trigger("oo.dom.replacement.after")}o_info.inainvoke=false}function clearAfterAjaxIframeCall(){if(o_info.linkbusy){o_afterserver()}}function showAjaxBusy(){setTimeout(function(){if(o_info.linkbusy){try{if(jQuery("#o_ajax_busy_backdrop").length==0){jQuery("#o_body").addClass("o_ajax_busy");jQuery("#o_ajax_busy").modal({show:true,backdrop:"static",keyboard:"false"});jQuery("#o_ajax_busy").after('<div id="o_ajax_busy_backdrop" class="modal-backdrop in"></div>');jQuery("#o_ajax_busy>.modal-backdrop").remove();jQuery("#o_ajax_busy_backdrop").css({"z-index":1200})}}catch(a){if(window.console){console.log(a)}}}},700)}function removeAjaxBusy(){try{jQuery("#o_body").removeClass("o_ajax_busy");jQuery("#o_ajax_busy_backdrop").remove();jQuery("#o_ajax_busy").modal("hide")}catch(a){if(window.console){console.log(a)}}}function setFormDirty(c){o2c=1;var a=document.getElementById(c);if(a!=null){var b=a.olat_fosm_0;if(b==null){b=a.olat_fosm}if(b){b.className="btn o_button_dirty"}}}function contextHelpWindow(a){helpWindow=window.open(a,"HelpWindow","height=760, width=940, left=0, top=0, location=no, menubar=no, resizable=yes, scrollbars=yes, toolbar=no");helpWindow.focus()}function o_openPopUp(b,d,c,a,f){attributes="height="+a+", width="+c+", resizable=yes, scrollbars=yes, left=100, top=100, ";if(f){attributes+="location=yes, menubar=yes, status=yes, toolbar=yes"}else{attributes+="location=no, menubar=no, status=no, toolbar=no"}var h;try{h=window.open(b,d,attributes)}catch(g){h=window.open(b,"OpenOLAT",attributes)}h.focus();if(o_info.linkbusy){o_afterserver()}}function b_handleFileUploadFormChange(e,b,d){var f=e.value;slashPos=f.lastIndexOf("/");if(slashPos!=-1){f=f.substring(slashPos+1)}slashPos=f.lastIndexOf("\\");if(slashPos!=-1){f=f.substring(slashPos+1)}b.value=f;if(d){d.className="o_button_dirty"}var c=e.form.elements;for(i=0;i<c.length;i++){var a=c[i];if(a.name==b.name&&i+1<c.length){c[i+1].focus()}}}function gotonode(a){try{if(typeof o_activateCourseNode!="undefined"){o_activateCourseNode(a)}else{if(opener&&typeof opener.o_activateCourseNode!="undefined"){opener.o_activateCourseNode(a)}}}catch(b){alert("Goto node error:"+b)}}function o_viewportHeight(){var a=jQuery(document).height();if(a>0){return a}else{return 600}}OPOL.getMainColumnsMaxHeight=function(){var m=0,f=0,a=0,c=0,h=0,b,g=jQuery("#o_main_left_content"),e=jQuery("#o_main_right_content"),d=jQuery("#o_main_center_content");if(g!="undefined"&&g!=null){m=g.outerHeight(true)}if(e!="undefined"&&e!=null){f=e.outerHeight(true)}if(d!="undefined"&&d!=null){a=d.outerHeight(true)}c=(m>f?m:f);c=(c>a?c:a);if(c>0){return c}b=jQuery("#o_main");if(b!="undefined"&&b!=null){h=b.height()}if(b>0){return b}return o_viewportHeight()};OPOL.adjustHeight=function(){try{var a=0;col1=jQuery("#o_main_left_content").outerHeight(true);col2=jQuery("#o_main_right_content").outerHeight(true);col3=jQuery("#o_main_center_content").outerHeight(true);a=Math.max(col1,col2,col3);if(col1!=null){jQuery("#o_main_left").css({"min-height":a+"px"})}if(col2!=null){jQuery("#o_main_right").css({"min-height":a+"px"})}if(col3!=null){jQuery("#o_main_center").css({"min-height":a+"px"})}}catch(b){if(window.console){console.log(b)}}};jQuery(window).resize(function(){clearTimeout(o_info.resizeId);o_info.resizeId=setTimeout(function(){jQuery(document).trigger("oo.window.resize.after")},500)});jQuery(document).on("oo.window.resize.after",OPOL.adjustHeight);jQuery(document).on("oo.dom.replacement.after",OPOL.adjustHeight);jQuery().ready(OPOL.adjustHeight);function o_scrollToElement(a){try{o_info.scrolling=true;jQuery("html, body").animate({scrollTop:jQuery(a).offset().top},333,function(d,c){o_info.scrolling=false})}catch(b){}}function o_popover(c,b,a){if(typeof(a)==="undefined"){a="bottom"}jQuery("#"+c).popover({placement:a,html:true,trigger:"click",container:"body",content:function(){return jQuery("#"+b).clone().html()}}).on("shown.bs.popover",function(){var d=function(f){jQuery("#"+c).popover("hide");jQuery("body").unbind("click",d)};setTimeout(function(){jQuery("body").on("click",d)},5)})}function o_popoverWithTitle(d,c,b,a){if(typeof(a)==="undefined"){a="bottom"}return jQuery("#"+d).popover({placement:a,html:true,title:b,trigger:"click",container:"body",content:function(){return jQuery("#"+c).clone().html()}}).on("shown.bs.popover",function(){var e=function(f){jQuery("#"+d).popover("destroy");jQuery("body").unbind("click",e)};setTimeout(function(){jQuery("body").on("click",e)},5)})}function o_shareLinkPopup(d,c,b){if(typeof(b)==="undefined"){b="top"}var a=jQuery("#"+d);a.popover({placement:b,html:true,trigger:"click",container:"body",content:c}).on("shown.bs.popover",function(){var e=function(f){if(jQuery(f.target).data("toggle")!=="popover"&&jQuery(f.target).parents(".popover.in").length===0){jQuery("#"+d).popover("hide");jQuery("body").unbind("click",e)}};setTimeout(function(){jQuery("body").on("click",e)},5)});a.attr("title",a.attr("data-original-title"))}function o_QRCodePopup(d,c,b){if(typeof(b)==="undefined"){b="top"}var a=jQuery("#"+d);a.popover({placement:b,html:true,trigger:"click",container:"body",content:'<div id="'+d+'_pop" class="o_qrcode"></div>'}).on("shown.bs.popover",function(){o_info.qr=o_QRCode(d+"_pop",(jQuery.isFunction(c)?c():c));var e=function(f){if(jQuery(f.target).data("toggle")!=="popover"&&jQuery(f.target).parents(".popover.in").length===0){jQuery("#"+d).popover("hide");jQuery("body").unbind("click",e)}};setTimeout(function(){jQuery("body").on("click",e)},5)}).on("hidden.bs.popover",function(){try{o_info.qr.clear();delete o_info.qr}catch(f){}});a.attr("title",a.attr("data-original-title"))}function o_QRCode(c,b){try{BLoader.loadJS(o_info.o_baseURI+"/js/jquery/qrcodejs/qrcode.min.js","utf8",true);return new QRCode(document.getElementById(c),b)}catch(a){return null}}function b_resizeIframeToMainMaxHeight(f){var d=jQuery("#"+f);if(d!="undefined"&&d!=null){var c=OPOL.getMainColumnsMaxHeight()-110;var b=o_viewportHeight()-100;b=b-d.offset().top;var e=jQuery("#b_footer");if(e!="undefined"&&e!=null){b=b-e.outerHeight(true)}var a=(b>c?b:c);d.height(a)}}var o_debu_oldcn,o_debu_oldtt;function o_debu_show(b,a){if(o_debu_oldcn){o_debu_hide(o_debu_oldcn,o_debu_oldtt)}jQuery(b).addClass("o_dev_m");jQuery(a).show();o_debu_oldtt=a;o_debu_oldcn=b}function o_debu_hide(b,a){jQuery(a).hide();jQuery(b).removeClass("o_dev_m")}function o_dbg_mark(a){var b=jQuery("#"+a);if(b){b.css("background-color","#FCFCB8");b.css("border","3px solid #00F")}}function o_dbg_unmark(a){var b=jQuery("#"+a);if(b){b.css("border","");b.css("background-color","")}}function o_clearConsole(){o_log_all="";o_log(null)}var o_log_all="";function o_log(b){if(b){o_log_all="\n"+o_debug_trid+"> "+b+o_log_all;o_log_all=o_log_all.substr(0,4000)}var a=jQuery("#o_debug_cons");if(a){if(o_log_all.length==4000){o_log_all=o_log_all+"\n... (stripped: to long)... "}a.value=o_log_all}if(!jQuery.type(window.console)==="undefined"){window.console.log(b)}}function o_logerr(a){o_log("ERROR:"+a)}function o_logwarn(a){o_log("WARN:"+a)}function showerror(c){var a="";for(var b in c){a+=b+": "+c[b]+"\n"}return"error detail:\n"+a}function o_ffEvent(f,e,d,n,o){var g,h,b,a;g=document.getElementById(e);h=g.value;g.value=d;b=document.getElementById(n);a=b.value;b.value=o;var c=jQuery("#"+f);var m=c.attr("enctype");if(m&&m.indexOf("multipart")==0){o_XHRSubmitMultipart(f)}else{if(document.forms[f].onsubmit()){document.forms[f].submit()}}g.value=h;b.value=a}function o_IQEvent(a){if(document.forms[a].onsubmit()){document.forms[a].submit()}}function o_TableMultiActionEvent(a,c){var b=jQuery("#o_mai_"+a);b.val(c);if(document.forms[a].onsubmit()){document.forms[a].submit()}b.val("")}function o_XHRSubmit(h){if(o_info.linkbusy){return false}o_beforeserver();var o=true;var a=jQuery("#"+h);var n=a.attr("enctype");if(n&&n.indexOf("multipart")==0){var g="openolat-submit-"+(""+Math.random()).substr(2);var d=o_createIFrame(g);document.body.appendChild(d);a.attr("target",d.name);return true}else{var f=a.serializeArray();if(arguments.length>1){var m=arguments.length;for(var e=1;e<m;e=e+2){if(m>e+1){var c=new Object();c.name=arguments[e];c.value=arguments[e+1];f[f.length]=c}}}var b=a.attr("action");jQuery.ajax(b,{type:"POST",data:f,cache:false,dataType:"json",success:function(s,v,r){try{o_ainvoke(s);if(o){var p=s.businessPath;var q=s.documentTitle;var u=s.historyPointId;if(p){o_pushState(u,q,p)}}}catch(t){if(window.console){console.log(t)}}finally{o_afterserver()}},error:o_onXHRError});return false}}function o_XHRSubmitMultipart(a){var c=jQuery("#"+a);var d="openolat-submit-"+(""+Math.random()).substr(2);var b=o_createIFrame(d);document.body.appendChild(b);c.attr("target",b.name);c.submit();c.attr("target","")}function o_createIFrame(b){var a=jQuery('<iframe name="'+b+'" id="'+b+'" src="about:blank" style="position: absolute; top: -9999px; left: -9999px;"></iframe>');return a[0]}function o_removeIframe(a){jQuery("#"+a).remove()}function o_showFormDirtyDialog(a){o_scrollToElement("#o_top");jQuery("#o_form_dirty_message").modal("show");jQuery("#o_form_dirty_message .o_form_dirty_ignore").on("click",function(){jQuery("#o_form_dirty_message").modal("hide");jQuery("#o_form_dirty_message .o_form_dirty_ignore").off();a()});return false}function o_ffXHREvent(h,e,s,g,p,t,f,m){if(t&&o2c==1){var d=Array.prototype.slice.call(arguments);d[5]=false;var u=function(){o_ffXHREvent.apply(window,d)};return o_showFormDirtyDialog(u)}else{if(!o2cl_noDirtyCheck()){return false}}o_beforeserver();var v=new Object();if(m){var b=jQuery("#"+h);var q=b.serializeArray();var o=q.length;for(var r=0;r<o;r++){var n=q[r];if(n.name!="dispatchuri"&&n.name!="dispatchevent"){v[n.name]=n.value}}}v.dispatchuri=s;v.dispatchevent=p;if(arguments.length>8){var a=arguments.length;for(var r=8;r<a;r=r+2){if(a>r+1){v[arguments[r]]=arguments[r+1]}}}var c=jQuery("#"+h).attr("action");jQuery.ajax(c,{type:"POST",data:v,cache:false,dataType:"json",success:function(z,C,y){try{o_ainvoke(z);if(f){var w=z.businessPath;var x=z.documentTitle;var B=z.historyPointId;if(w){o_pushState(B,x,w)}}}catch(A){if(window.console){console.log(A)}}finally{o_afterserver()}},error:o_onXHRError})}function o_ffXHRNFEvent(f,e,a,h,m){var c=new Object();c.dispatchuri=a;c.dispatchevent=m;if(arguments.length>5){var g=arguments.length;for(var d=5;d<g;d=d+2){if(g>d+1){c[arguments[d]]=arguments[d+1]}}}var b=jQuery("#"+f).attr("action");jQuery.ajax(b,{type:"POST",data:c,cache:false,dataType:"json",success:function(o,p,n){}})}function o_XHREvent(h,f,c){if(f&&o2c==1){var b=Array.prototype.slice.call(arguments);b[1]=false;var a=function(){o_XHREvent.apply(window,b)};return o_showFormDirtyDialog(a)}else{if(!o2cl_noDirtyCheck()){return false}}o_beforeserver();var e=new Object();if(arguments.length>3){var g=arguments.length;for(var d=3;d<g;d=d+2){if(g>d+1){e[arguments[d]]=arguments[d+1]}}}jQuery.ajax(h,{type:"POST",data:e,cache:false,dataType:"json",success:function(p,s,o){try{if(c){try{var m=p.businessPath;var n=p.documentTitle;var r=p.historyPointId;if(m){o_pushState(r,n,m)}}catch(q){if(window.console){console.log(q)}}}o_ainvoke(p)}catch(q){if(window.console){console.log(q)}}finally{o_afterserver()}},error:o_onXHRError});return false}function o_XHRNFEvent(d){var b=new Object();if(arguments.length>1){var c=arguments.length;for(var a=1;a<c;a=a+2){if(c>a+1){b[arguments[a]]=arguments[a+1]}}}jQuery.ajax(d,{type:"POST",data:b,cache:false,dataType:"json",success:function(f,g,e){},error:o_onXHRError})}function o_onXHRError(a,d,b){o_afterserver();if(401==a.status){var c=o_info.oo_noresponse.replace("reload.html",window.document.location.href);showMessageBox("error",o_info.oo_noresponse_title,c,undefined)}else{if(window.console){console.log("Error status 2",d,b,a.responseText);console.log(a)}}}function o_pushState(d,f,a){try{var b=new Object();b.businessPath=a;b.historyPointId=d;if(a!=null&&!(a.lastIndexOf("http",0)===0)&&!(a.lastIndexOf("https",0)===0)){a=o_info.serverUri+a}o_info.businessPath=a;if(!(typeof o_shareActiveSocialUrl==="undefined")){o_shareActiveSocialUrl()}if(window.history&&!(typeof window.history==="undefined")&&window.history.pushState){window.history.pushState(b,f,a)}else{window.location.hash=d}}catch(c){if(window.console){console.log(c,a)}}}function o_toggleMark(a){var b=jQuery("i",a).attr("class");if(b.indexOf("o_icon_bookmark_add")>=0){jQuery("i",a).removeClass("o_icon_bookmark_add").addClass("o_icon_bookmark")}else{jQuery("i",a).removeClass("o_icon_bookmark").addClass("o_icon_bookmark_add")}}function o_normalizeFilename(b){b=b.replace(/\s/g,"_");var f=["/",",",":","(",")"];for(var c=f.length;c-->0;){b=b.split(f[c]).join("_")}var a=["\u00C4","\u00D6","\u00DC","\u00E4","\u00F6","\u00E6","\u00FC","\u00DF","\u00F8","\u2205"],d=["Ae","Oe","Ue","ae","oe","ae","ue","ss","o","o"];for(var c=a.length;c-->0;){b=b.split(a[c]).join(d[c])}try{b=b.normalize("NFKD");b=b.replace("/p{InCombiningDiacriticalMarks}+/g","");b=b.replace("/W+/g","")}catch(g){if(window.console){console.log(g)}}return b}function setFlexiFormDirtyByListener(a){setFlexiFormDirty(a.data.formId,a.data.hideMessage)}function setFlexiFormDirty(b,c){var a=o3c.indexOf(b)>-1;if(!a){o3c.push(b)}jQuery("#"+b).each(function(){var d=jQuery(this).data("FlexiSubmit");if(d!=null){jQuery("#"+d).addClass("btn o_button_dirty");o2c=(c?0:1)}})}function o_ffRegisterSubmit(b,a){jQuery("#"+b).data("FlexiSubmit",a)}function dismissInfoBox(a){javascript:jQuery("#"+a).remove();return true}function showInfoBox(g,d){var c=Math.floor(Math.random()*65536).toString(16);var f='<div id="'+c+'" class="o_alert_info"><div class="alert alert-info clearfix o_sel_info_message"><a class="o_alert_close o_sel_info_close" href="javascript:;" onclick="dismissInfoBox(\''+c+'\')"><i class="o_icon o_icon_close"> </i></a><h3><i class="o_icon o_icon_info"> </i> '+g+"</h3><p>"+d+"</p></div></div>";var a=jQuery("#o_messages").prepend(f);var e=(d.length>150)?8000:((d.length>70)?6000:4000);var b=function(){jQuery("#"+c).transition({top:"-100%"},333,function(){jQuery("#"+c).remove()})};o_info.scrolling=true;jQuery("#"+c).show().transition({top:0},333);jQuery("#"+c).click(function(h){b()});o_scrollToElement("#o_top");g=null;d=null;a=null;setTimeout(function(){try{b()}catch(h){}},e)}function showMessageBox(b,f,d,a){if(b=="info"){showInfoBox(f,d);return null}else{var c='<div id="myFunctionalModal" class="modal fade" role="dialog"><div class="modal-dialog"><div class="modal-content">';c+='<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>';c+='<h4 class="modal-title">'+f+"</h4></div>";c+='<div class="modal-body alert ';if("warn"==b){c+="alert-warning"}else{if("error"==b){c+="alert-danger"}else{c+="alert-info"}}c+='"><p>'+d+"</p></div></div></div></div>";jQuery("#myFunctionalModal").remove();jQuery("body").append(c);var e=jQuery("#myFunctionalModal").modal("show").on("hidden.bs.modal",function(g){jQuery("#myFunctionalModal").remove()});o_scrollToElement("#o_top");return e}}function o_table_toggleCheck(d,c){var a=document.forms[d].elements.tb_ms;len=a.length;if(typeof(len)=="undefined"){a.checked=c}else{var b;for(b=0;b<len;b++){a[b].checked=c}}}function onTreeStartDrag(a,b){jQuery(a.target).addClass("o_dnd_proxy")}function onTreeStopDrag(a,b){jQuery(a.target).removeClass("o_dnd_proxy")}function onTreeDrop(g,h){var a=jQuery(h.draggable[0]);var f=jQuery(this);f.css({position:"",width:""});var c=f.droppable("option","endUrl");if(c.lastIndexOf("/")==(c.length-1)){c=c.substring(0,c.length-1)}var e=a.attr("id");var b=e.substring(2,e.length);c+="%3Atnidle%3A"+b;var d=f.attr("id");if(d.indexOf("ds")==0){c+="%3Asne%3Ayes"}else{if(d.indexOf("dt")==0){c+="%3Asne%3Aend"}}jQuery(".ui-droppable").each(function(m,n){jQuery(n).droppable("disable")});o_XHREvent(c+"/",false,false)}function treeAcceptDrop(a){return true}function treeAcceptDrop_notWithChildren(a){var c=false;var b=jQuery(a);var e=b.attr("id");if(e!=undefined&&(e.indexOf("dd")==0||e.indexOf("ds")==0||e.indexOf("dt")==0||e.indexOf("da")==0||e.indexOf("row")==0)){var g=jQuery(this);var m=g.attr("id");var d=e.substring(2,e.length);var f=m.substring(2,m.length);if(d!=f){var h=jQuery("#dd"+d).parents("li");if(h.length>0&&jQuery(h.get(0)).find("#dd"+f).length==0){c=true}}}return c}function treeAcceptDrop_portfolio(b){var d=false;var c=jQuery(b);var f=c.attr("id");if(treeNode_isDragNode(f)){var h=jQuery(this);var o=h.attr("id");var e=f.substring(2,f.length);var g=o.substring(2,o.length);var n=f.indexOf("ds")==0||f.indexOf("dt")==0;if(e!=g){var m=treeNode_portfolioType(c);var a=treeNode_portfolioType(h);if(m=="artefact"){if(a=="page"||a=="struct"||a=="artefact"){d=true}}else{if(m=="struct"){if(a=="page"||a=="struct"){d=true}}else{if(m=="page"){if(a=="map"||a=="page"){d=true}}}}}}return d}function treeNode_portfolioType(e){var c=jQuery(e.get(0));var d=treeNode_portfolioTypes(c);if(d==null){var a=c.parent("a");if(a.length>0){d=treeNode_portfolioTypes(jQuery(a.get(0)))}else{if(c.attr("id").indexOf("ds")==0){var b=c.prev("div");if(b.length>0){d=treeNode_portfolioTypes(b)}}else{if(c.attr("id").indexOf("dt")==0){var b=c.next("div");if(b.length>0){d=treeNode_portfolioTypes(b)}}}}}return d}function treeNode_portfolioTypes(a){if(a.find===undefined){return null}else{if(a.find(".o_ep_icon_struct").length>0||a.hasClass("o_ep_icon_struct")){return"struct"}else{if(a.find(".o_ep_icon_page").length>0||a.hasClass("o_ep_icon_page")){return"page"}else{if(a.find(".o_ep_icon_map").length>0||a.hasClass("o_ep_icon_map")){return"map"}else{if(a.find(".o_ep_artefact").length>0||a.hasClass("o_ep_artefact")){return"artefact"}}}}}return null}function treeNode_isDragNode(a){if(a!=undefined&&(a.indexOf("dd")==0||a.indexOf("ds")==0||a.indexOf("dt")==0||a.indexOf("da")==0||a.indexOf("row")==0)){return true}return false}function o_choice_toggleCheck(c,b){var d=document.forms[c].elements;len=d.length;if(typeof(len)=="undefined"){d.checked=b}else{var a;for(a=0;a<len;a++){if(d[a].type=="checkbox"&&d[a].getAttribute("class")=="o_checkbox"){d[a].checked=b}}}}function b_briefcase_isChecked(c,e){var b;var a=document.getElementById(c);var d=0;for(b=0;a.elements[b];b++){if(a.elements[b].type=="checkbox"&&a.elements[b].name=="paths"&&a.elements[b].checked){d++}}if(d<1){alert(e);return false}return true}function b_briefcase_toggleCheck(d,c){var a=document.getElementById(d);len=a.elements.length;var b;for(b=0;b<len;b++){if(a.elements[b].name=="paths"){a.elements[b].checked=c}}}function o_doPrint(){var d=jQuery("div.o_iframedisplay iframe");if(d.length>0){try{var a=d[0];frames[a.name].focus();frames[a.name].print();return}catch(c){for(i=0;frames.length>i;i++){a=frames[i];if(a.name=="oaa0"){continue}var b=document.getElementsByName(a.name)[0];if(b&&b.getAttribute("class")=="ext-shim"){continue}if(a.name!=""){try{frames[a.name].focus();frames[a.name].print()}catch(c){window.print()}return}}window.print()}}else{window.print()}}function b_attach_i18n_inline_editing(){jQuery("span.o_translation_i18nitem").hover(function(){jQuery(this.firstChild).show()},function(){jQuery("a.o_translation_i18nitem_launcher").hide()});jQuery("a.o_translation_i18nitem_launcher").hover(function(){var a=jQuery(this).parent("span.o_translation_i18nitem");a.effect("highlight")});b_AddOnDomReplacementFinishedCallback(b_attach_i18n_inline_editing)}function b_hideExtMessageBox(){}var BDebugger={_lastDOMCount:0,_lastObjCount:0,_knownGlobalOLATObjects:["o_afterserver","o_onc","o_getMainWin","o_ainvoke","o_info","o_beforeserver","o_ffEvent","o_openPopUp","o_debu_show","o_logwarn","o_dbg_unmark","o_ffRegisterSubmit","o_clearConsole","o_init","o_log","o_allowNextClick","o_dbg_mark","o_debu_hide","o_logerr","o_debu_oldcn","o_debu_oldtt","o_debug_trid","o_log_all"],_countDOMElements:function(){return document.getElementsByTagName("*").length},_countGlobalObjects:function(){var a=0;for(prop in window){a++}return a},logDOMCount:function(){var b=BDebugger;var a=b._countDOMElements();var c=a-b._lastDOMCount;console.log((c>0?"+":"")+c+" \t"+a+" \tDOM element count after DOM replacement");b._lastDOMCount=a;a=null},logGlobalObjCount:function(){var b=BDebugger;var a=b._countGlobalObjects();var c=a-b._lastObjCount;console.log((c>0?"+":"")+c+" \t"+a+" \tGlobal object count after DOM replacement");b._lastObjCount=a;a=null},logGlobalOLATObjects:function(){var b=BDebugger;var a=new Array();for(prop in window){if(prop.indexOf("o_")==0&&b._knownGlobalOLATObjects.indexOf(prop)==-1){a.push(prop)}}if(a.length>0){console.log(a.length+" global OLAT objects found:");a.each(function(c){console.log("\t"+typeof window[c]+" \t"+c)})}}};/*! +jQuery.periodic=function(l,h){if(jQuery.isFunction(l)){h=l;l={}}var c=jQuery.extend({},jQuery.periodic.defaults,{ajax_complete:j,increment:g,reset:f,cancel:i},l);c.cur_period=c.period;c.tid=false;var e="";b();return c;function b(){i();c.tid=setTimeout(function(){h.call(c);g();if(c.tid){b()}},c.cur_period)}function j(n,m){if(m==="success"&&e!==n.responseText){e=n.responseText;f()}}function g(){c.cur_period*=c.decay;if(c.cur_period<c.period){f()}else{if(c.cur_period>c.max_period){c.cur_period=c.max_period;if(c.on_max!==undefined){c.on_max.call(c)}}}}function f(){c.cur_period=c.period;b()}function i(){clearTimeout(c.tid);c.tid=null}function k(){}function a(){}function d(){}};jQuery.periodic.defaults={period:4000,max_period:1800000,decay:1.5,on_max:undefined};var Hashtable=(function(){var p="function";var n=(typeof Array.prototype.splice==p)?function(s,r){s.splice(r,1)}:function(u,t){var s,v,r;if(t===u.length-1){u.length=t}else{s=u.slice(t+1);u.length=t;for(v=0,r=s.length;v<r;++v){u[t+v]=s[v]}}};function a(t){var r;if(typeof t=="string"){return t}else{if(typeof t.hashCode==p){r=t.hashCode();return(typeof r=="string")?r:a(r)}else{if(typeof t.toString==p){return t.toString()}else{try{return String(t)}catch(s){return Object.prototype.toString.call(t)}}}}}function g(r,s){return r.equals(s)}function e(r,s){return(typeof s.equals==p)?s.equals(r):(r===s)}function c(r){return function(s){if(s===null){throw new Error("null is not a valid "+r)}else{if(typeof s=="undefined"){throw new Error(r+" must not be undefined")}}}}var q=c("key"),l=c("value");function d(u,s,t,r){this[0]=u;this.entries=[];this.addEntry(s,t);if(r!==null){this.getEqualityFunction=function(){return r}}}var h=0,j=1,f=2;function o(r){return function(t){var s=this.entries.length,v,u=this.getEqualityFunction(t);while(s--){v=this.entries[s];if(u(t,v[0])){switch(r){case h:return true;case j:return v;case f:return[s,v[1]]}}}return false}}function k(r){return function(u){var v=u.length;for(var t=0,s=this.entries.length;t<s;++t){u[v+t]=this.entries[t][r]}}}d.prototype={getEqualityFunction:function(r){return(typeof r.equals==p)?g:e},getEntryForKey:o(j),getEntryAndIndexForKey:o(f),removeEntryForKey:function(s){var r=this.getEntryAndIndexForKey(s);if(r){n(this.entries,r[0]);return r[1]}return null},addEntry:function(r,s){this.entries[this.entries.length]=[r,s]},keys:k(0),values:k(1),getEntries:function(s){var u=s.length;for(var t=0,r=this.entries.length;t<r;++t){s[u+t]=this.entries[t].slice(0)}},containsKey:o(h),containsValue:function(s){var r=this.entries.length;while(r--){if(s===this.entries[r][1]){return true}}return false}};function m(s,t){var r=s.length,u;while(r--){u=s[r];if(t===u[0]){return r}}return null}function i(r,s){var t=r[s];return(t&&(t instanceof d))?t:null}function b(t,r){var w=this;var v=[];var u={};var x=(typeof t==p)?t:a;var s=(typeof r==p)?r:null;this.put=function(B,C){q(B);l(C);var D=x(B),E,A,z=null;E=i(u,D);if(E){A=E.getEntryForKey(B);if(A){z=A[1];A[1]=C}else{E.addEntry(B,C)}}else{E=new d(D,B,C,s);v[v.length]=E;u[D]=E}return z};this.get=function(A){q(A);var B=x(A);var C=i(u,B);if(C){var z=C.getEntryForKey(A);if(z){return z[1]}}return null};this.containsKey=function(A){q(A);var z=x(A);var B=i(u,z);return B?B.containsKey(A):false};this.containsValue=function(A){l(A);var z=v.length;while(z--){if(v[z].containsValue(A)){return true}}return false};this.clear=function(){v.length=0;u={}};this.isEmpty=function(){return !v.length};var y=function(z){return function(){var A=[],B=v.length;while(B--){v[B][z](A)}return A}};this.keys=y("keys");this.values=y("values");this.entries=y("getEntries");this.remove=function(B){q(B);var C=x(B),z,A=null;var D=i(u,C);if(D){A=D.removeEntryForKey(B);if(A!==null){if(!D.entries.length){z=m(v,C);n(v,z);delete u[C]}}}return A};this.size=function(){var A=0,z=v.length;while(z--){A+=v[z].entries.length}return A};this.each=function(C){var z=w.entries(),A=z.length,B;while(A--){B=z[A];C(B[0],B[1])}};this.putAll=function(H,C){var B=H.entries();var E,F,D,z,A=B.length;var G=(typeof C==p);while(A--){E=B[A];F=E[0];D=E[1];if(G&&(z=w.get(F))){D=C(F,z,D)}w.put(F,D)}};this.clone=function(){var z=new b(t,r);z.putAll(w);return z}}return b})();(function(b){b.fn.ooTranslator=function(){var d=null;b(document).each(function(){d=b(document).data("_ooTranslator");if(d==undefined){d=new a();b(document).data("_ooTranslator",d)}});return d};function a(){return this}a.prototype={mapperUrl:null,translators:null,initialize:function(d){this.mapperUrl=d;this.translators=new Object()},getTranslator:function(d,f){if(this.translators[d]==null){this.translators[d]=new Object()}if(this.translators[d][f]==null){var e=this.mapperUrl+"/"+d+"/"+f+"/translations.js";jQuery.ajax(e,{async:false,dataType:"json",success:function(g,i,h){jQuery(document).ooTranslator()._createTranslator(g,d,f)}})}return this.translators[d][f]},_createTranslator:function(e,d,f){this.translators[d][f]=new c().initialize(e,d,f)}};function c(){return this}c.prototype={localizationData:null,bundle:null,locale:null,initialize:function(f,d,e){this.bundle=e;this.locale=d;this.localizationData=f;return this},translate:function(d){if(this.localizationData[d]){return this.localizationData[d]}else{return this.bundle+":"+d}}}})(jQuery);+function(b){var a=function(){this.addExtraElements();this.state={busy:false,brandW:0,sitesW:0,sitesDirty:false,sites:{collapsed:this.isSitesCollapsed(),extended:this.isSitesExtended},tabsW:0,tabsDirty:false,tabs:{collapsed:this.isTabsCollapsed(),extended:this.isTabsExtended()},toolsW:0,toolsDirty:false,tools:{collapsed:this.isToolsCollapsed(),extended:this.isToolsExtended()},offCanvasWidth:0,moreW:0};var c=b("#o_offcanvas_right").css("width");if(c){this.state.offCanvasWidth=parseInt(c.replace(/[^\d.]/g,""));this.initListners();this.calculateWidth();this.optimize()}};a.prototype.initListners=function(){b(window).resize(b.proxy(this.onResizeCallback,this));b(document).on("oo.nav.sites.modified",b.proxy(function(){this.state.sitesDirty=true},this));b(document).on("oo.nav.tabs.modified",b.proxy(function(){this.state.tabsDirty=true},this));b(document).on("oo.nav.tools.modified",b.proxy(function(){this.state.toolsDirty=true},this));b(document).on("oo.dom.replacement.after",b.proxy(this.onDOMreplacementCallback,this));b(window).on("orientationchange",b.proxy(this.hideRight,this));b("#o_navbar_right-toggle").on("click",b.proxy(this.toggleRight,this));b("#o_offcanvas_right .o_offcanvas_close").on("click",b.proxy(this.hideRight,this));b("#o_navbar_more").on("shown.bs.dropdown",this.onDropdownShown);b("#o_navbar_more").on("hidden.bs.dropdown",this.onDropdownHidden)};a.prototype.onResizeCallback=function(){if(!this.state.busy){this.state.busy=true;this.calculateWidth();this.optimize();this.state.busy=false}};a.prototype.onDOMreplacementCallback=function(){if(!this.state.busy&&(this.state.sitesDirty||this.state.tabsDirty||this.state.toolsDirty)){this.state.busy=true;this.cleanupMoreDropdown();this.calculateWidth();this.optimize();this.state.sitesDirty=false;this.state.tabsDirty=false;this.state.toolsDirty=false;this.state.busy=false}};a.prototype.onDropdownShown=function(c){var f=b("#o_navbar_more .dropdown-menu");if(f.length){var d=f.offset().left;if(d<0){f.removeClass("dropdown-menu-right")}}};a.prototype.onDropdownHidden=function(c){var d=b("#o_navbar_more .dropdown-menu");d.addClass("dropdown-menu-right")};a.prototype.calculateWidth=function(){var c=b("#o_navbar_container .o_navbar-collapse");this.state.navbarW=c.innerWidth();this.state.brandW=b(".o_navbar-brand").outerWidth(true);this.state.sitesW=this.getSites().outerWidth(true);this.state.tabsW=this.getTabs().outerWidth(true);this.state.toolsW=this.getTools().outerWidth(false);this.state.moreW=b("#o_navbar_more:visible").outerWidth(true)};a.prototype.getOverflow=function(c){var d=this.state.navbarW;d-=this.state.sitesW;d-=this.state.tabsW;d-=this.state.toolsW;d-=this.state.brandW;d-=this.state.moreW;d-=25;return -d};a.prototype.optimize=function(h){var c=this.getOverflow();var k=this.getSites();var l=this.getTabs();var g=this.getTools();var n=this.getMoreDropdown();var f=this.getOffcanvasRight();this.updateState();while(c>0&&(!this.state.tabs.collapsed||!this.state.sites.collapsed||!this.state.tools.collapsed)){if(!this.state.tabs.collapsed){this.collapse(l,n,"li","o_dropdown_tab")}else{if(!this.state.sites.collapsed){this.collapse(k,n,"li","o_dropdown_site")}else{if(!this.state.tools.collapsed){this.collapse(g,f,".o_navbar_tool:not(#o_navbar_imclient, #o_navbar_search_opener, #o_navbar_my_menu)","o_tool_right")}}}this.calculateWidth();c=this.getOverflow();this.updateState()}while(c<0&&(!this.state.tabs.extended||!this.state.sites.extended||!this.state.tools.extended)){if(!this.state.tools.extended){var m=this.extend(f,g.children("#o_navbar_imclient, #o_navbar_search_opener, #o_navbar_my_menu").first(),".o_tool_right","o_tool_right",true);if(!m){break}}if(!this.state.sites.extended){var j=this.extend(n,k,"li","o_dropdown_site");if(!j){break}}else{if(!this.state.tabs.extended){var d=this.extend(n,l,"li","o_dropdown_tab");if(!d){break}}}this.calculateWidth();c=this.getOverflow();this.updateState()}if(this.state.sites.extended&&this.state.tabs.extended){var i=b("#o_navbar_more");i.css("display","none")}this.checkToolsOrder()};a.prototype.updateState=function(){this.state.sites.collapsed=this.isSitesCollapsed();this.state.sites.extended=this.isSitesExtended();this.state.tabs.collapsed=this.isTabsCollapsed();this.state.tabs.extended=this.isTabsExtended();this.state.tools.collapsed=this.isToolsCollapsed();this.state.tools.extended=this.isToolsExtended()};a.prototype.collapse=function(g,d,c,f){var e=g.find(c);if(e.length){e=e.last()}if(e.length){f&&e.addClass(f);if(d){e.prependTo(d)}}this.updateDropdownToggle(g)};a.prototype.extend=function(g,d,c,i,f){var e=g.find(c);if(e.length){e=e.first()}var j=false;if(e.length){if(d&&d.length){if(f){d.before(e)}else{e.appendTo(d)}this.updateDropdownToggle(g);this.calculateWidth();var h=this.getOverflow();if(h>0){e.prependTo(g)}else{i&&e.removeClass(i);j=true}}}this.updateDropdownToggle(g);return j};a.prototype.updateDropdownToggle=function(c){var d=c.parents(".o_dropdown_toggle");if(!d.length){return}if(c.children().length){d.css("display","block")}else{d.css("display","none")}};a.prototype.addExtraElements=function(){var d=b("#o_navbar_container .o_navbar-collapse");var c=b("#o_navbar_more");if(c.length==0){c=b('<ul id="o_navbar_more" class="nav o_navbar-nav o_dropdown_toggle"><li><a class="dropdown-toggle" data-toggle="dropdown" href="#"">'+o_info.i18n_topnav_more+' <b class="caret"></b></a><ul class="dropdown-menu dropdown-menu-right"></ul></li></ul>');c.appendTo(d)}this.getSites().append('<li class="divider o_dropdown_site"></li>');b("#o_navbar_help .o_icon, #o_navbar_print .o_icon").addClass("o_icon-fw")};a.prototype.cleanupMoreDropdown=function(){if(!this.state.sitesDirty){var f=this.getSites();var d=this.getMoreDropdown().children(".o_dropdown_site");d.appendTo(f)}else{this.getSites().append('<li class="divider o_dropdown_site"></li>')}if(!this.state.tabsDirty){var e=this.getTabs();var c=this.getMoreDropdown().children(".o_dropdown_tab");c.prependTo(e)}this.getMoreDropdown().empty()};a.prototype.checkToolsOrder=function(){var f=this.getTools();var e=f.find("#o_navbar_help");var d=f.find("#o_navbar_print");var c=f.find("#o_navbar_imclient");if(c&&d){c.after(d)}if(c&&e){c.after(e)}};a.prototype.showRight=function(){if(!this.isOffcanvasVisible()&&!this.offcanvasTransitioning){this.offcanvasTransitioning=true;var d=this;var c=b("#o_offcanvas_right");c.show().transition({x:-d.state.offCanvasWidth},function(){b("body").addClass("o_offcanvas_right_visible");var e=b.proxy(d.hideRightOnClick,d);setTimeout(function(){b("html").on("click",e);d.offcanvasTransitioning=false},10)})}};a.prototype.hideRightOnClick=function(c){if("INPUT"!=c.target.nodeName){this.hideRight()}};a.prototype.hideRight=function(){if(this.isOffcanvasVisible()&&!this.offcanvasTransitioning){this.offcanvasTransitioning=true;b("html").off("click",b.proxy(this.hideRight,this));var d=this;var c=b("#o_offcanvas_right");c.transition({x:d.state.offCanvasWidth},function(){c.hide();b("body").removeClass("o_offcanvas_right_visible");d.offcanvasTransitioning=false})}};a.prototype.toggleRight=function(){if(this.isOffcanvasVisible()){this.hideRight()}else{this.showRight()}};a.prototype.isOffcanvasVisible=function(){return b("#o_offcanvas_right:visible").length};a.prototype.getSites=function(){return b("#o_navbar_container .o_navbar_sites")};a.prototype.getTabs=function(){return b("#o_navbar_container .o_navbar_tabs")};a.prototype.getTools=function(){return b("#o_navbar_container #o_navbar_tools_permanent")};a.prototype.getMoreDropdown=function(){return b("#o_navbar_more .dropdown-menu")};a.prototype.getOffcanvasRight=function(){return b("#o_offcanvas_right_container .o_navbar-right")};a.prototype.isSitesCollapsed=function(){return !this.getSites().children("li").not(".divider").length};a.prototype.isSitesExtended=function(){return !this.getMoreDropdown().children(".o_dropdown_site").not(".divider").length};a.prototype.isTabsCollapsed=function(){return !this.getTabs().children("li").length};a.prototype.isTabsExtended=function(){return !this.getMoreDropdown().children(".o_dropdown_tab").length};a.prototype.isToolsCollapsed=function(){return !this.getTools().children(".o_navbar_tool").not("#o_navbar_imclient, #o_navbar_search_opener, #o_navbar_my_menu").length};a.prototype.isToolsExtended=function(){return !this.getOffcanvasRight().children(".o_tool_right").length};b(document).ready(function(){var d=b("#o_navbar_wrapper");if(d){var c=new a();window.OPOL.navbar=c}})}(jQuery);+function(b){b.fn.ooBgCarrousel=function(){return new a()};var a=function(){};a.prototype.initCarrousel=function(g){this.settings=b.extend({query:null,images:[],shuffle:false,shuffleFirst:false,durationshow:5000,durationout:500,durationin:500,easeout:"ease",easein:"ease"},g);this.pos=null;if(this.settings.query==null||this.settings.images.length==0){return}this.initialImage=this.settings.images[0];if(this.settings.shuffle){var f=this.settings.images;for(var d,c,e=f.length;e;d=parseInt(Math.random()*e),c=f[--e],f[e]=f[d],f[d]=c){}}if(this.settings.shuffleFirst){this._replaceImage()}this.rotate()};a.prototype.rotate=function(){setTimeout(b.proxy(this._hideCurrent,this),this.settings.durationshow)};a.prototype._hideCurrent=function(){var c=b(this.settings.query);if(c&&c.size()>0){c.transition({opacity:0,duration:this.settings.durationout,easing:this.settings.easeout},b.proxy(this._showNext,this))}};a.prototype._replaceImage=function(d){if(!d){d=b(this.settings.query)}if(d&&d.size()>0){this.newImg="";this.oldImg="";if(this.pos==null){this.pos=1;this.oldImg=this.initialImage}else{this.oldImg=this.settings.images[this.pos];this.pos++;if(this.settings.images.length==this.pos){this.pos=0}}this.newImg=this.settings.images[this.pos];var c=d.css("background-image");if(c.indexOf(this.oldImg)==-1){d.transition({opacity:1,duration:0});return}var e=c.replace(this.oldImg,this.newImg);d.css("background-image",e)}};a.prototype._showNext=function(){var c=b(this.settings.query);this._replaceImage(c);c.transition({opacity:1,duration:this.settings.durationin,easing:this.settings.easein},b.proxy(this.rotate,this))}}(jQuery);!function(e){function t(){function t(e){"remove"===e&&this.each(function(e,t){var n=i(t);n&&n.remove()}),this.find("span.mceEditor,div.mceEditor").each(function(e,t){var n=tinymce.get(t.id.replace(/_parent$/,""));n&&n.remove()})}function r(e){var n,r=this;if(null!=e)t.call(r),r.each(function(t,n){var r;(r=tinymce.get(n.id))&&r.setContent(e)});else if(r.length>0&&(n=tinymce.get(r[0].id)))return n.getContent()}function i(e){var t=null;return e&&e.id&&a.tinymce&&(t=tinymce.get(e.id)),t}function o(e){return!!(e&&e.length&&a.tinymce&&e.is(":tinymce"))}var s={};e.each(["text","html","val"],function(t,a){var l=s[a]=e.fn[a],c="text"===a;e.fn[a]=function(t){var a=this;if(!o(a))return l.apply(a,arguments);if(t!==n)return r.call(a.filter(":tinymce"),t),l.apply(a.not(":tinymce"),arguments),a;var s="",u=arguments;return(c?a:a.eq(0)).each(function(t,n){var r=i(n);s+=r?c?r.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):r.getContent({save:!0}):l.apply(e(n),u)}),s}}),e.each(["append","prepend"],function(t,r){var a=s[r]=e.fn[r],l="prepend"===r;e.fn[r]=function(e){var t=this;return o(t)?e!==n?("string"==typeof e&&t.filter(":tinymce").each(function(t,n){var r=i(n);r&&r.setContent(l?e+r.getContent():r.getContent()+e)}),a.apply(t.not(":tinymce"),arguments),t):void 0:a.apply(t,arguments)}}),e.each(["remove","replaceWith","replaceAll","empty"],function(n,r){var i=s[r]=e.fn[r];e.fn[r]=function(){return t.call(this,r),i.apply(this,arguments)}}),s.attr=e.fn.attr,e.fn.attr=function(t,a){var l=this,c=arguments;if(!t||"value"!==t||!o(l))return a!==n?s.attr.apply(l,c):s.attr.apply(l,c);if(a!==n)return r.call(l.filter(":tinymce"),a),s.attr.apply(l.not(":tinymce"),c),l;var u=l[0],d=i(u);return d?d.getContent({save:!0}):s.attr.apply(e(u),c)}}var n,r,i,o=[],a=window;e.fn.tinymce=function(n){function s(){var r=[],o=0;i||(t(),i=!0),d.each(function(e,t){var i,a=t.id,s=n.oninit;a||(t.id=a=tinymce.DOM.uniqueId()),tinymce.get(a)||(i=new tinymce.Editor(a,n,tinymce.EditorManager),r.push(i),i.on("init",function(){var e,t=s;d.css("visibility",""),s&&++o==r.length&&("string"==typeof t&&(e=t.indexOf(".")===-1?null:tinymce.resolve(t.replace(/\.\w+$/,"")),t=tinymce.resolve(t)),t.apply(e||tinymce,r))}))}),e.each(r,function(e,t){t.render()})}var l,c,u,d=this,f="";if(!d.length)return d;if(!n)return window.tinymce?tinymce.get(d[0].id):null;if(d.css("visibility","hidden"),a.tinymce||r||!(l=n.script_url))1===r?o.push(s):s();else{r=1,c=l.substring(0,l.lastIndexOf("/")),l.indexOf(".min")!=-1&&(f=".min"),a.tinymce=a.tinyMCEPreInit||{base:c,suffix:f},l.indexOf("gzip")!=-1&&(u=n.language||"en",l=l+(/\?/.test(l)?"&":"?")+"js=true&core=true&suffix="+escape(f)+"&themes="+escape(n.theme||"modern")+"&plugins="+escape(n.plugins||"")+"&languages="+(u||""),a.tinyMCE_GZ||(a.tinyMCE_GZ={start:function(){function t(e){tinymce.ScriptLoader.markDone(tinymce.baseURI.toAbsolute(e))}t("langs/"+u+".js"),t("themes/"+n.theme+"/theme"+f+".js"),t("themes/"+n.theme+"/langs/"+u+".js"),e.each(n.plugins.split(","),function(e,n){n&&(t("plugins/"+n+"/plugin"+f+".js"),t("plugins/"+n+"/langs/"+u+".js"))})},end:function(){}}));var p=document.createElement("script");p.type="text/javascript",p.onload=p.onreadystatechange=function(t){t=t||window.event,2===r||"load"!=t.type&&!/complete|loaded/.test(p.readyState)||(tinymce.dom.Event.domLoaded=1,r=2,n.script_loaded&&n.script_loaded(),s(),e.each(o,function(e,t){t()}))},p.src=l,document.body.appendChild(p)}return d},e.extend(e.expr[":"],{tinymce:function(e){var t;return!!(e.id&&"tinymce"in window&&(t=tinymce.get(e.id),t&&t.editorManager===tinymce))}})}(jQuery);OPOL={};var o2c=0;var o3c=new Array();o_info.guibusy=false;o_info.linkbusy=false;o_info.scrolling=false;o_info.debug=true;var BLoader={_ajaxLoadedJS:new Array(),_isAlreadyLoadedJS:function(b){var a=true;jQuery("head script[src]").each(function(d,c){if(jQuery(c).attr("src").indexOf(b)!=-1){a=false}});if(jQuery.inArray(b,this._ajaxLoadedJS)!=-1){a=false}return !a},loadJS:function(b,c,a){if(!this._isAlreadyLoadedJS(b)){if(o_info.debug){o_log("BLoader::loadJS: loading ajax::"+a+" url::"+b)}if(a){jQuery.ajax(b,{async:false,dataType:"script",cache:true,success:function(d,f,e){}});this._ajaxLoadedJS.push(b)}else{jQuery.getScript(b)}if(o_info.debug){o_log("BLoader::loadJS: loading DONE url::"+b)}}else{if(o_info.debug){o_log("BLoader::loadJS: already loaded url::"+b)}}},executeGlobalJS:function(jsString,contextDesc){try{if(window.execScript){window.execScript(jsString)}else{window.eval(jsString)}}catch(e){if(window.console){console.log(contextDesc,"cannot execute js",jsString)}if(o_info.debug){o_logerr("BLoader::executeGlobalJS: Error when executing JS code in contextDesc::"+contextDesc+' error::"'+showerror(e)+" for: "+escape(jsString))}if(window.location.href.indexOf("o_winrndo")!=-1){window.location.reload()}else{window.location.href=window.location.href+(window.location.href.indexOf("?")!=-1?"&":"?")+"o_winrndo=1"}}},loadCSS:function(b,p,r){var s=window.document;try{if(s.createStyleSheet){var m=s.styleSheets;var d=0;var q=0;for(i=0;i<m.length;i++){var n=m[i];var g=n.href;if(g==b){d++;if(n.disabled){n.disabled=false;return}else{if(o_info.debug){o_logwarn("BLoader::loadCSS: style: "+b+" already in document and not disabled! (duplicate add)")}return}}if(n.id=="o_theme_css"){q=i}}if(d>1&&o_info.debug){o_logwarn("BLoader::loadCSS: apply styles: num of stylesheets found was not 0 or 1:"+d)}if(r){q=m.length}var f=s.createStyleSheet(b,q)}else{var c=jQuery("#"+p);if(c&&c.size()>0){if(o_info.debug){o_logwarn("BLoader::loadCSS: stylesheet already found in doc when trying to add:"+b+", with id "+p)}return}else{var a=jQuery('<link id="'+p+'" rel="stylesheet" type="text/css" href="'+b+'">');if(r){a.insertBefore(jQuery("#o_fontSize_css"))}else{a.insertBefore(jQuery("#o_theme_css"))}}}}catch(o){if(window.console){console.log(o)}if(o_info.debug){o_logerr("BLoader::loadCSS: Error when loading CSS from URL::"+b)}}},unLoadCSS:function(a,n){var o=window.document;try{if(o.createStyleSheet){var f=o.styleSheets;var d=0;var p=a;var b=window.location.href.substring(0,window.location.href.indexOf("/",8));if(a.indexOf(b)==0){p=a.substring(b.length)}for(i=0;i<f.length;i++){var g=f[i].href;if(g==a||g==p){d++;if(!f[i].disabled){f[i].disabled=true}else{if(o_info.debug){o_logwarn("stylesheet: when removing: matching url, but already disabled! url:"+g)}}}}if(d!=1&&o_info.debug){o_logwarn("stylesheet: when removeing: num of stylesheets found was not 1:"+d)}}else{var c=jQuery("#"+n);if(c){c.href="";c.remove();c=null;return}else{if(o_info.debug){o_logwarn("no link with id found to remove, id:"+n+", url "+a)}}}}catch(m){if(o_info.debug){o_logerr("BLoader::unLoadCSS: Error when unloading CSS from URL::"+a)}}}};var BFormatter={formatLatexFormulas:function(b){try{if(typeof MathJax==="undefined"){o_mathjax()}else{if(MathJax&&MathJax.isReady){jQuery(function(){MathJax.Hub.Queue(function(){if(jQuery("#"+b+" .MathJax").length==0){MathJax.Hub.Typeset(b)}})})}else{setTimeout(function(){BFormatter.formatLatexFormulas(b)},100)}}}catch(a){if(window.console){console.log("error in BFormatter.formatLatexFormulas: ",a)}}},alignTableColumns:function(a){try{var b=new Array();jQuery(a).each(function(){for(j=0;j<jQuery(this)[0].rows[0].cells.length;j++){var d=jQuery(this)[0].rows[0].cells[j];if(!b[j]||b[j]<d.clientWidth){b[j]=d.clientWidth}}});jQuery(a).each(function(){for(j=0;j<jQuery(this)[0].rows[0].cells.length;j++){jQuery(this)[0].rows[0].cells[j].style.width=b[j]+"px"}})}catch(c){if(window.console){console.log("error in BFormatter.alignTableColumns: ",c)}}}};function o_init(){try{o_getMainWin().o_afterserver();if(window.location.href&&window.location.href!=null&&window.location.href.indexOf("%3A")<0){var a=window.location.href;if(a!=null&&!(a.lastIndexOf("http",0)===0)&&!(a.lastIndexOf("https",0)===0)){a=o_info.serverUri+a}o_info.businessPath=a;if(!(typeof o_shareActiveSocialUrl==="undefined")){o_shareActiveSocialUrl()}}}catch(b){if(o_info.debug){o_log("error in o_init: "+showerror(b))}}}function o_initEmPxFactor(){o_info.emPxFactor=jQuery("#o_width_1em").width();if(o_info.emPxFactor==0||o_info.emPxFactor=="undefined"){o_info.emPxFactor=12}}function o_getMainWin(){try{if(window.OPOL){return window}else{if(window.opener&&window.opener.OPOL){return window.opener}}}catch(a){if(o_info.debug){o_logerr('Exception while getting main window. rror::"'+showerror(a))}if(window.console){console.log('Exception while getting main window. rror::"'+showerror(a),"functions.js");console.log(a)}}throw"Can not find main OpenOLAT window"}function o_beforeserver(){o_info.linkbusy=true;showAjaxBusy();if(window.suppressOlatOnUnloadOnce){window.suppressOlatOnUnloadOnce=false}else{if(window.olatonunload){olatonunload()}}}function o_afterserver(){o2c=0;o_info.linkbusy=false;removeAjaxBusy()}function o2cl(){try{if(o_info.linkbusy){return false}else{var b=(o2c==0||confirm(o_info.dirty_form));if(b){o_beforeserver()}return b}}catch(a){if(window.console){console.log(a)}return false}}function o2cl_dirtyCheckOnly(){try{if(o_info.linkbusy){return false}else{return(o2c==0||confirm(o_info.dirty_form))}}catch(a){if(window.console){console.log(a)}return false}}function o2cl_noDirtyCheck(){if(o_info.linkbusy){return false}else{o_beforeserver();return true}}function o3cl(d){if(o_info.linkbusy){return false}else{var b=o3c1.indexOf(d)>-1;var a=(b&&o3c1.length>1)||o3c1.length>0;var c=(!a||confirm(o_info.dirty_form));if(c){o_beforeserver()}return c}}function o_onc(a){var b=a.responseText;BLoader.executeGlobalJS("o_info.last_o_onc="+b+";","o_onc");o_ainvoke(o_info.last_o_onc,false)}function o_allowNextClick(){o_info.linkbusy=false;removeAjaxBusy()}function removeBusyAfterDownload(c,b,a){o2c=0;o_afterserver()}Array.prototype.search=function(c,d){var a=this.length;for(var b=0;b<a;b++){if(this[b].constructor==Array){if(this[b].search(c,d)){return true;break}}else{if(d){if(this[b].indexOf(c)!=-1){return true;break}}else{if(this[b]==c){return true;break}}}}return false};if(!Function.prototype.curry){Function.prototype.curry=function(){if(arguments.length<1){return this}var a=this;var b=Array.prototype.slice.call(arguments);return function(){return a.apply(this,b.concat(Array.prototype.slice.call(arguments)))}}}if(!Array.prototype.indexOf){Array.prototype.indexOf=function(c){if(this==null){throw new TypeError()}var d=Object(this);var a=d.length>>>0;if(a===0){return -1}var e=0;if(arguments.length>1){e=Number(arguments[1]);if(e!=e){e=0}else{if(e!=0&&e!=Infinity&&e!=-Infinity){e=(e>0||-1)*Math.floor(Math.abs(e))}}}if(e>=a){return -1}var b=e>=0?e:Math.max(a-Math.abs(e),0);for(;b<a;b++){if(b in d&&d[b]===c){return b}}return -1}}var b_onDomReplacementFinished_callbacks=new Array();function b_AddOnDomReplacementFinishedCallback(a){b_onDomReplacementFinished_callbacks.push(a)}var b_changedDomEl=new Array();function b_AddOnDomReplacementFinishedUniqueCallback(a){if(a.constructor==Array){if(b_onDomReplacementFinished_callbacks.search(a[0])){return}}b_AddOnDomReplacementFinishedCallback(a)}var o_debug_trid=0;function o_ainvoke(N){if(N==undefined){return}o_info.inainvoke=true;var I=N.cmdcnt;if(I>0){jQuery(document).trigger("oo.dom.replacement.before");b_changedDomEl=new Array();if(o_info.debug){o_debug_trid++}var y=N.cmds;for(var T=0;T<I;T++){var J=y[T];var A=J.cmd;var R=J.cda;var U=J.w;var c=this.window;var K;if(c){switch(A){case 1:var M=R.e;BLoader.executeGlobalJS(M,"o_ainvoker::jsexec");if(o_info.debug){o_log("c1: execute jscode: "+M)}case 2:var u=R.cc;var F=R.cps;for(var Q=0;Q<u;Q++){var m=F[Q];var h=m.cid;var P=m.cidvis;var H=m.cw;var x=m.hfrag;var O=m.jsol;var g=m.hdr;if(o_info.debug){o_log("c2: redraw: "+m.cname+" ("+h+") "+m.hfragsize+" bytes, listener(s): "+m.clisteners)}var W=g+"\n\n"+x;var C="";var S=false;var E="o_c"+h;var B=jQuery("#"+E);if(B==null||B.length==0){E="o_fi"+h;B=jQuery("#"+E);S=true}if(B!=null){var w=jQuery("div.o_richtext_mce textarea",B);for(var L=0;L<w.length;L++){try{var a=jQuery(w.get(L)).attr("id");if(typeof top.tinymce!=undefined){top.tinymce.remove("#"+a)}}catch(Z){if(window.console){console.log(Z)}}}if(P){B.css("display","")}else{B.css("display","none")}if(S||!H){B.replaceWith(W)}else{try{B.empty().html(W);if(W.length>0&&B.get(0).innerHTML==""){B.get(0).innerHTML=W}}catch(Z){if(window.console){console.log(Z)}if(window.console){console.log("Fragment",W)}}b_changedDomEl.push(E)}B=null;if(C!=""){C.each(function(e){BLoader.executeGlobalJS(e,"o_ainvoker::inscripts")})}if(O!=""){BLoader.executeGlobalJS(O,"o_ainvoker::jsol")}}}break;case 3:c.o2c=0;var X=R.rurl;c.o_afterserver();c.document.location.replace(X);break;case 5:c.o2c=0;var X=R.rurl;c.o_afterserver();c.document.location.replace(X);break;case 6:c.o2c=0;c.o_afterserver();break;case 7:var o=c.document.location;var z=o.protocol+"//"+o.hostname;if(o.port!=""){z+=":"+o.port}var v=R.cssrm;for(Q=0;Q<v.length;Q++){var D=v[Q];var G=D.id;var f=z+D.url;BLoader.unLoadCSS(f,G);if(o_info.debug){o_log("c7: rm css: id:"+G+" ,url:'"+f+"'")}}var V=R.cssadd;for(k=0;k<V.length;k++){var D=V[k];var G=D.id;var f=z+D.url;var n=D.pt;BLoader.loadCSS(f,G,n);if(o_info.debug){o_log("c7: add css: id:"+G+" ,url:'"+f+"'")}}var p=R.jsadd;for(l=0;l<p.length;l++){var D=p[l];var Y=D.before;if(jQuery.type(Y)==="string"){BLoader.executeGlobalJS(Y,"o_ainvoker::preJsAdd")}var f=D.url;var q=D.enc;if(jQuery.type(f)==="string"){BLoader.loadJS(f,q,true)}if(o_info.debug){o_log("c7: add js: "+f)}}break;default:if(o_info.debug){o_log("?: unknown command "+A)}break}}else{if(o_info.debug){o_log("could not find window??")}}}var b=b_onDomReplacementFinished_callbacks.length;for(mycounter=0;b>mycounter;mycounter++){if(mycounter>50){break}var s=b_onDomReplacementFinished_callbacks.shift();if(typeof s.length==="number"){if(s[0]=="glosshighlighter"){var d=s[1];s=d}}s()}jQuery(document).trigger("oo.dom.replacement.after")}o_info.inainvoke=false}function clearAfterAjaxIframeCall(){if(o_info.linkbusy){o_afterserver()}}function showAjaxBusy(){setTimeout(function(){if(o_info.linkbusy){try{if(jQuery("#o_ajax_busy_backdrop").length==0){jQuery("#o_body").addClass("o_ajax_busy");jQuery("#o_ajax_busy").modal({show:true,backdrop:"static",keyboard:"false"});jQuery("#o_ajax_busy").after('<div id="o_ajax_busy_backdrop" class="modal-backdrop in"></div>');jQuery("#o_ajax_busy>.modal-backdrop").remove();jQuery("#o_ajax_busy_backdrop").css({"z-index":1200})}}catch(a){if(window.console){console.log(a)}}}},700)}function removeAjaxBusy(){try{jQuery("#o_body").removeClass("o_ajax_busy");jQuery("#o_ajax_busy_backdrop").remove();jQuery("#o_ajax_busy").modal("hide")}catch(a){if(window.console){console.log(a)}}}function setFormDirty(c){o2c=1;var a=document.getElementById(c);if(a!=null){var b=a.olat_fosm_0;if(b==null){b=a.olat_fosm}if(b){b.className="btn o_button_dirty"}}}function contextHelpWindow(a){helpWindow=window.open(a,"HelpWindow","height=760, width=940, left=0, top=0, location=no, menubar=no, resizable=yes, scrollbars=yes, toolbar=no");helpWindow.focus()}function o_openPopUp(b,d,c,a,f){attributes="height="+a+", width="+c+", resizable=yes, scrollbars=yes, left=100, top=100, ";if(f){attributes+="location=yes, menubar=yes, status=yes, toolbar=yes"}else{attributes+="location=no, menubar=no, status=no, toolbar=no"}var h;try{h=window.open(b,d,attributes)}catch(g){h=window.open(b,"OpenOLAT",attributes)}h.focus();if(o_info.linkbusy){o_afterserver()}}function b_handleFileUploadFormChange(e,b,d){var f=e.value;slashPos=f.lastIndexOf("/");if(slashPos!=-1){f=f.substring(slashPos+1)}slashPos=f.lastIndexOf("\\");if(slashPos!=-1){f=f.substring(slashPos+1)}b.value=f;if(d){d.className="o_button_dirty"}var c=e.form.elements;for(i=0;i<c.length;i++){var a=c[i];if(a.name==b.name&&i+1<c.length){c[i+1].focus()}}}function gotonode(a){try{if(typeof o_activateCourseNode!="undefined"){o_activateCourseNode(a)}else{if(opener&&typeof opener.o_activateCourseNode!="undefined"){opener.o_activateCourseNode(a)}}}catch(b){alert("Goto node error:"+b)}}function o_viewportHeight(){var a=jQuery(document).height();if(a>0){return a}else{return 600}}OPOL.getMainColumnsMaxHeight=function(){var m=0,f=0,a=0,c=0,h=0,b,g=jQuery("#o_main_left_content"),e=jQuery("#o_main_right_content"),d=jQuery("#o_main_center_content");if(g!="undefined"&&g!=null){m=g.outerHeight(true)}if(e!="undefined"&&e!=null){f=e.outerHeight(true)}if(d!="undefined"&&d!=null){a=d.outerHeight(true)}c=(m>f?m:f);c=(c>a?c:a);if(c>0){return c}b=jQuery("#o_main");if(b!="undefined"&&b!=null){h=b.height()}if(b>0){return b}return o_viewportHeight()};OPOL.adjustHeight=function(){try{var a=0;col1=jQuery("#o_main_left_content").outerHeight(true);col2=jQuery("#o_main_right_content").outerHeight(true);col3=jQuery("#o_main_center_content").outerHeight(true);a=Math.max(col1,col2,col3);if(col1!=null){jQuery("#o_main_left").css({"min-height":a+"px"})}if(col2!=null){jQuery("#o_main_right").css({"min-height":a+"px"})}if(col3!=null){jQuery("#o_main_center").css({"min-height":a+"px"})}}catch(b){if(window.console){console.log(b)}}};jQuery(window).resize(function(){clearTimeout(o_info.resizeId);o_info.resizeId=setTimeout(function(){jQuery(document).trigger("oo.window.resize.after")},500)});jQuery(document).on("oo.window.resize.after",OPOL.adjustHeight);jQuery(document).on("oo.dom.replacement.after",OPOL.adjustHeight);jQuery().ready(OPOL.adjustHeight);function o_scrollToElement(a){try{o_info.scrolling=true;jQuery("html, body").animate({scrollTop:jQuery(a).offset().top},333,function(d,c){o_info.scrolling=false})}catch(b){}}function o_popover(c,b,a){if(typeof(a)==="undefined"){a="bottom"}jQuery("#"+c).popover({placement:a,html:true,trigger:"click",container:"body",content:function(){return jQuery("#"+b).clone().html()}}).on("shown.bs.popover",function(){var d=function(f){jQuery("#"+c).popover("hide");jQuery("body").unbind("click",d)};setTimeout(function(){jQuery("body").on("click",d)},5)})}function o_popoverWithTitle(d,c,b,a){if(typeof(a)==="undefined"){a="bottom"}return jQuery("#"+d).popover({placement:a,html:true,title:b,trigger:"click",container:"body",content:function(){return jQuery("#"+c).clone().html()}}).on("shown.bs.popover",function(){var e=function(f){jQuery("#"+d).popover("destroy");jQuery("body").unbind("click",e)};setTimeout(function(){jQuery("body").on("click",e)},5)})}function o_shareLinkPopup(d,c,b){if(typeof(b)==="undefined"){b="top"}var a=jQuery("#"+d);a.popover({placement:b,html:true,trigger:"click",container:"body",content:c}).on("shown.bs.popover",function(){var e=function(f){if(jQuery(f.target).data("toggle")!=="popover"&&jQuery(f.target).parents(".popover.in").length===0){jQuery("#"+d).popover("hide");jQuery("body").unbind("click",e)}};setTimeout(function(){jQuery("body").on("click",e)},5)});a.attr("title",a.attr("data-original-title"))}function o_QRCodePopup(d,c,b){if(typeof(b)==="undefined"){b="top"}var a=jQuery("#"+d);a.popover({placement:b,html:true,trigger:"click",container:"body",content:'<div id="'+d+'_pop" class="o_qrcode"></div>'}).on("shown.bs.popover",function(){o_info.qr=o_QRCode(d+"_pop",(jQuery.isFunction(c)?c():c));var e=function(f){if(jQuery(f.target).data("toggle")!=="popover"&&jQuery(f.target).parents(".popover.in").length===0){jQuery("#"+d).popover("hide");jQuery("body").unbind("click",e)}};setTimeout(function(){jQuery("body").on("click",e)},5)}).on("hidden.bs.popover",function(){try{o_info.qr.clear();delete o_info.qr}catch(f){}});a.attr("title",a.attr("data-original-title"))}function o_QRCode(c,b){try{BLoader.loadJS(o_info.o_baseURI+"/js/jquery/qrcodejs/qrcode.min.js","utf8",true);return new QRCode(document.getElementById(c),b)}catch(a){return null}}function b_resizeIframeToMainMaxHeight(f){var d=jQuery("#"+f);if(d!="undefined"&&d!=null){var c=OPOL.getMainColumnsMaxHeight()-110;var b=o_viewportHeight()-100;b=b-d.offset().top;var e=jQuery("#b_footer");if(e!="undefined"&&e!=null){b=b-e.outerHeight(true)}var a=(b>c?b:c);d.height(a)}}var o_debu_oldcn,o_debu_oldtt;function o_debu_show(b,a){if(o_debu_oldcn){o_debu_hide(o_debu_oldcn,o_debu_oldtt)}jQuery(b).addClass("o_dev_m");jQuery(a).show();o_debu_oldtt=a;o_debu_oldcn=b}function o_debu_hide(b,a){jQuery(a).hide();jQuery(b).removeClass("o_dev_m")}function o_dbg_mark(a){var b=jQuery("#"+a);if(b){b.css("background-color","#FCFCB8");b.css("border","3px solid #00F")}}function o_dbg_unmark(a){var b=jQuery("#"+a);if(b){b.css("border","");b.css("background-color","")}}function o_clearConsole(){o_log_all="";o_log(null)}var o_log_all="";function o_log(b){if(b){o_log_all="\n"+o_debug_trid+"> "+b+o_log_all;o_log_all=o_log_all.substr(0,4000)}var a=jQuery("#o_debug_cons");if(a){if(o_log_all.length==4000){o_log_all=o_log_all+"\n... (stripped: to long)... "}a.value=o_log_all}if(!jQuery.type(window.console)==="undefined"){window.console.log(b)}}function o_logerr(a){o_log("ERROR:"+a)}function o_logwarn(a){o_log("WARN:"+a)}function showerror(c){var a="";for(var b in c){a+=b+": "+c[b]+"\n"}return"error detail:\n"+a}function o_ffEvent(f,e,d,n,o){var g,h,b,a;g=document.getElementById(e);h=g.value;g.value=d;b=document.getElementById(n);a=b.value;b.value=o;var c=jQuery("#"+f);var m=c.attr("enctype");if(m&&m.indexOf("multipart")==0){o_XHRSubmitMultipart(f)}else{if(document.forms[f].onsubmit()){document.forms[f].submit()}}g.value=h;b.value=a}function o_IQEvent(a){if(document.forms[a].onsubmit()){document.forms[a].submit()}}function o_TableMultiActionEvent(a,c){var b=jQuery("#o_mai_"+a);b.val(c);if(document.forms[a].onsubmit()){document.forms[a].submit()}b.val("")}function o_XHRSubmit(h){if(o_info.linkbusy){return false}o_beforeserver();var o=true;var a=jQuery("#"+h);var n=a.attr("enctype");if(n&&n.indexOf("multipart")==0){var g="openolat-submit-"+(""+Math.random()).substr(2);var d=o_createIFrame(g);document.body.appendChild(d);a.attr("target",d.name);return true}else{var f=a.serializeArray();if(arguments.length>1){var m=arguments.length;for(var e=1;e<m;e=e+2){if(m>e+1){var c=new Object();c.name=arguments[e];c.value=arguments[e+1];f[f.length]=c}}}var b=a.attr("action");jQuery.ajax(b,{type:"POST",data:f,cache:false,dataType:"json",success:function(s,v,r){try{o_ainvoke(s);if(o){var p=s.businessPath;var q=s.documentTitle;var u=s.historyPointId;if(p){o_pushState(u,q,p)}}}catch(t){if(window.console){console.log(t)}}finally{o_afterserver()}},error:o_onXHRError});return false}}function o_XHRSubmitMultipart(a){var c=jQuery("#"+a);var d="openolat-submit-"+(""+Math.random()).substr(2);var b=o_createIFrame(d);document.body.appendChild(b);c.attr("target",b.name);c.submit();c.attr("target","")}function o_createIFrame(b){var a=jQuery('<iframe name="'+b+'" id="'+b+'" src="about:blank" style="position: absolute; top: -9999px; left: -9999px;"></iframe>');return a[0]}function o_removeIframe(a){jQuery("#"+a).remove()}function o_showFormDirtyDialog(a){o_scrollToElement("#o_top");jQuery("#o_form_dirty_message").modal("show");jQuery("#o_form_dirty_message .o_form_dirty_ignore").on("click",function(){jQuery("#o_form_dirty_message").modal("hide");jQuery("#o_form_dirty_message .o_form_dirty_ignore").off();a()});return false}function o_ffXHREvent(h,e,s,g,p,t,f,m){if(t&&o2c==1){var d=Array.prototype.slice.call(arguments);d[5]=false;var u=function(){o_ffXHREvent.apply(window,d)};return o_showFormDirtyDialog(u)}else{if(!o2cl_noDirtyCheck()){return false}}o_beforeserver();var v=new Object();if(m){var b=jQuery("#"+h);var q=b.serializeArray();var o=q.length;for(var r=0;r<o;r++){var n=q[r];if(n.name!="dispatchuri"&&n.name!="dispatchevent"){v[n.name]=n.value}}}v.dispatchuri=s;v.dispatchevent=p;if(arguments.length>8){var a=arguments.length;for(var r=8;r<a;r=r+2){if(a>r+1){v[arguments[r]]=arguments[r+1]}}}var c=jQuery("#"+h).attr("action");jQuery.ajax(c,{type:"POST",data:v,cache:false,dataType:"json",success:function(z,C,y){try{o_ainvoke(z);if(f){var w=z.businessPath;var x=z.documentTitle;var B=z.historyPointId;if(w){o_pushState(B,x,w)}}}catch(A){if(window.console){console.log(A)}}finally{o_afterserver()}},error:o_onXHRError})}function o_ffXHRNFEvent(f,e,a,h,m){var c=new Object();c.dispatchuri=a;c.dispatchevent=m;if(arguments.length>5){var g=arguments.length;for(var d=5;d<g;d=d+2){if(g>d+1){c[arguments[d]]=arguments[d+1]}}}var b=jQuery("#"+f).attr("action");jQuery.ajax(b,{type:"POST",data:c,cache:false,dataType:"json",success:function(o,p,n){}})}function o_XHRWikiEvent(b){var a=jQuery(b).attr("href");console.log(a);if(a.indexOf(o_info.serverUri)==0){a=a.substring(o_info.serverUri.length,a.length)}console.log(a);o_XHREvent(a,false,true);return false}function o_XHREvent(h,f,c){if(f&&o2c==1){var b=Array.prototype.slice.call(arguments);b[1]=false;var a=function(){o_XHREvent.apply(window,b)};return o_showFormDirtyDialog(a)}else{if(!o2cl_noDirtyCheck()){return false}}o_beforeserver();var e=new Object();if(arguments.length>3){var g=arguments.length;for(var d=3;d<g;d=d+2){if(g>d+1){e[arguments[d]]=arguments[d+1]}}}jQuery.ajax(h,{type:"POST",data:e,cache:false,dataType:"json",success:function(p,s,o){try{if(c){try{var m=p.businessPath;var n=p.documentTitle;var r=p.historyPointId;if(m){o_pushState(r,n,m)}}catch(q){if(window.console){console.log(q)}}}o_ainvoke(p)}catch(q){if(window.console){console.log(q)}}finally{o_afterserver()}},error:o_onXHRError});return false}function o_XHRNFEvent(d){var b=new Object();if(arguments.length>1){var c=arguments.length;for(var a=1;a<c;a=a+2){if(c>a+1){b[arguments[a]]=arguments[a+1]}}}jQuery.ajax(d,{type:"POST",data:b,cache:false,dataType:"json",success:function(f,g,e){},error:o_onXHRError})}function o_onXHRError(a,d,b){o_afterserver();if(401==a.status){var c=o_info.oo_noresponse.replace("reload.html",window.document.location.href);showMessageBox("error",o_info.oo_noresponse_title,c,undefined)}else{if(window.console){console.log("Error status 2",d,b,a.responseText);console.log(a)}}}function o_pushState(d,f,a){try{var b=new Object();b.businessPath=a;b.historyPointId=d;if(a!=null&&!(a.lastIndexOf("http",0)===0)&&!(a.lastIndexOf("https",0)===0)){a=o_info.serverUri+a}o_info.businessPath=a;if(!(typeof o_shareActiveSocialUrl==="undefined")){o_shareActiveSocialUrl()}if(window.history&&!(typeof window.history==="undefined")&&window.history.pushState){window.history.pushState(b,f,a)}else{window.location.hash=d}}catch(c){if(window.console){console.log(c,a)}}}function o_toggleMark(a){var b=jQuery("i",a).attr("class");if(b.indexOf("o_icon_bookmark_add")>=0){jQuery("i",a).removeClass("o_icon_bookmark_add").addClass("o_icon_bookmark")}else{jQuery("i",a).removeClass("o_icon_bookmark").addClass("o_icon_bookmark_add")}}function o_normalizeFilename(b){b=b.replace(/\s/g,"_");var f=["/",",",":","(",")"];for(var c=f.length;c-->0;){b=b.split(f[c]).join("_")}var a=["\u00C4","\u00D6","\u00DC","\u00E4","\u00F6","\u00E6","\u00FC","\u00DF","\u00F8","\u2205"],d=["Ae","Oe","Ue","ae","oe","ae","ue","ss","o","o"];for(var c=a.length;c-->0;){b=b.split(a[c]).join(d[c])}try{b=b.normalize("NFKD");b=b.replace("/p{InCombiningDiacriticalMarks}+/g","");b=b.replace("/W+/g","")}catch(g){if(window.console){console.log(g)}}return b}function setFlexiFormDirtyByListener(a){setFlexiFormDirty(a.data.formId,a.data.hideMessage)}function setFlexiFormDirty(b,c){var a=o3c.indexOf(b)>-1;if(!a){o3c.push(b)}jQuery("#"+b).each(function(){var d=jQuery(this).data("FlexiSubmit");if(d!=null){jQuery("#"+d).addClass("btn o_button_dirty");o2c=(c?0:1)}})}function o_ffRegisterSubmit(b,a){jQuery("#"+b).data("FlexiSubmit",a)}function dismissInfoBox(a){javascript:jQuery("#"+a).remove();return true}function showInfoBox(g,d){var c=Math.floor(Math.random()*65536).toString(16);var f='<div id="'+c+'" class="o_alert_info"><div class="alert alert-info clearfix o_sel_info_message"><a class="o_alert_close o_sel_info_close" href="javascript:;" onclick="dismissInfoBox(\''+c+'\')"><i class="o_icon o_icon_close"> </i></a><h3><i class="o_icon o_icon_info"> </i> '+g+"</h3><p>"+d+"</p></div></div>";var a=jQuery("#o_messages").prepend(f);var e=(d.length>150)?8000:((d.length>70)?6000:4000);var b=function(){jQuery("#"+c).transition({top:"-100%"},333,function(){jQuery("#"+c).remove()})};o_info.scrolling=true;jQuery("#"+c).show().transition({top:0},333);jQuery("#"+c).click(function(h){b()});o_scrollToElement("#o_top");g=null;d=null;a=null;setTimeout(function(){try{b()}catch(h){}},e)}function showMessageBox(b,f,d,a){if(b=="info"){showInfoBox(f,d);return null}else{var c='<div id="myFunctionalModal" class="modal fade" role="dialog"><div class="modal-dialog"><div class="modal-content">';c+='<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>';c+='<h4 class="modal-title">'+f+"</h4></div>";c+='<div class="modal-body alert ';if("warn"==b){c+="alert-warning"}else{if("error"==b){c+="alert-danger"}else{c+="alert-info"}}c+='"><p>'+d+"</p></div></div></div></div>";jQuery("#myFunctionalModal").remove();jQuery("body").append(c);var e=jQuery("#myFunctionalModal").modal("show").on("hidden.bs.modal",function(g){jQuery("#myFunctionalModal").remove()});o_scrollToElement("#o_top");return e}}function o_table_toggleCheck(d,c){var a=document.forms[d].elements.tb_ms;len=a.length;if(typeof(len)=="undefined"){a.checked=c}else{var b;for(b=0;b<len;b++){a[b].checked=c}}}function onTreeStartDrag(a,b){jQuery(a.target).addClass("o_dnd_proxy")}function onTreeStopDrag(a,b){jQuery(a.target).removeClass("o_dnd_proxy")}function onTreeDrop(g,h){var a=jQuery(h.draggable[0]);var f=jQuery(this);f.css({position:"",width:""});var c=f.droppable("option","endUrl");if(c.lastIndexOf("/")==(c.length-1)){c=c.substring(0,c.length-1)}var e=a.attr("id");var b=e.substring(2,e.length);c+="%3Atnidle%3A"+b;var d=f.attr("id");if(d.indexOf("ds")==0){c+="%3Asne%3Ayes"}else{if(d.indexOf("dt")==0){c+="%3Asne%3Aend"}}jQuery(".ui-droppable").each(function(m,n){jQuery(n).droppable("disable")});o_XHREvent(c+"/",false,false)}function treeAcceptDrop(a){return true}function treeAcceptDrop_notWithChildren(a){var c=false;var b=jQuery(a);var e=b.attr("id");if(e!=undefined&&(e.indexOf("dd")==0||e.indexOf("ds")==0||e.indexOf("dt")==0||e.indexOf("da")==0||e.indexOf("row")==0)){var g=jQuery(this);var m=g.attr("id");var d=e.substring(2,e.length);var f=m.substring(2,m.length);if(d!=f){var h=jQuery("#dd"+d).parents("li");if(h.length>0&&jQuery(h.get(0)).find("#dd"+f).length==0){c=true}}}return c}function treeAcceptDrop_portfolio(b){var d=false;var c=jQuery(b);var f=c.attr("id");if(treeNode_isDragNode(f)){var h=jQuery(this);var o=h.attr("id");var e=f.substring(2,f.length);var g=o.substring(2,o.length);var n=f.indexOf("ds")==0||f.indexOf("dt")==0;if(e!=g){var m=treeNode_portfolioType(c);var a=treeNode_portfolioType(h);if(m=="artefact"){if(a=="page"||a=="struct"||a=="artefact"){d=true}}else{if(m=="struct"){if(a=="page"||a=="struct"){d=true}}else{if(m=="page"){if(a=="map"||a=="page"){d=true}}}}}}return d}function treeNode_portfolioType(e){var c=jQuery(e.get(0));var d=treeNode_portfolioTypes(c);if(d==null){var a=c.parent("a");if(a.length>0){d=treeNode_portfolioTypes(jQuery(a.get(0)))}else{if(c.attr("id").indexOf("ds")==0){var b=c.prev("div");if(b.length>0){d=treeNode_portfolioTypes(b)}}else{if(c.attr("id").indexOf("dt")==0){var b=c.next("div");if(b.length>0){d=treeNode_portfolioTypes(b)}}}}}return d}function treeNode_portfolioTypes(a){if(a.find===undefined){return null}else{if(a.find(".o_ep_icon_struct").length>0||a.hasClass("o_ep_icon_struct")){return"struct"}else{if(a.find(".o_ep_icon_page").length>0||a.hasClass("o_ep_icon_page")){return"page"}else{if(a.find(".o_ep_icon_map").length>0||a.hasClass("o_ep_icon_map")){return"map"}else{if(a.find(".o_ep_artefact").length>0||a.hasClass("o_ep_artefact")){return"artefact"}}}}}return null}function treeNode_isDragNode(a){if(a!=undefined&&(a.indexOf("dd")==0||a.indexOf("ds")==0||a.indexOf("dt")==0||a.indexOf("da")==0||a.indexOf("row")==0)){return true}return false}function o_choice_toggleCheck(c,b){var d=document.forms[c].elements;len=d.length;if(typeof(len)=="undefined"){d.checked=b}else{var a;for(a=0;a<len;a++){if(d[a].type=="checkbox"&&d[a].getAttribute("class")=="o_checkbox"){d[a].checked=b}}}}function b_briefcase_isChecked(c,e){var b;var a=document.getElementById(c);var d=0;for(b=0;a.elements[b];b++){if(a.elements[b].type=="checkbox"&&a.elements[b].name=="paths"&&a.elements[b].checked){d++}}if(d<1){alert(e);return false}return true}function b_briefcase_toggleCheck(d,c){var a=document.getElementById(d);len=a.elements.length;var b;for(b=0;b<len;b++){if(a.elements[b].name=="paths"){a.elements[b].checked=c}}}function o_doPrint(){var d=jQuery("div.o_iframedisplay iframe");if(d.length>0){try{var a=d[0];frames[a.name].focus();frames[a.name].print();return}catch(c){for(i=0;frames.length>i;i++){a=frames[i];if(a.name=="oaa0"){continue}var b=document.getElementsByName(a.name)[0];if(b&&b.getAttribute("class")=="ext-shim"){continue}if(a.name!=""){try{frames[a.name].focus();frames[a.name].print()}catch(c){window.print()}return}}window.print()}}else{window.print()}}function b_attach_i18n_inline_editing(){jQuery("span.o_translation_i18nitem").hover(function(){jQuery(this.firstChild).show()},function(){jQuery("a.o_translation_i18nitem_launcher").hide()});jQuery("a.o_translation_i18nitem_launcher").hover(function(){var a=jQuery(this).parent("span.o_translation_i18nitem");a.effect("highlight")});b_AddOnDomReplacementFinishedCallback(b_attach_i18n_inline_editing)}function b_hideExtMessageBox(){}var BDebugger={_lastDOMCount:0,_lastObjCount:0,_knownGlobalOLATObjects:["o_afterserver","o_onc","o_getMainWin","o_ainvoke","o_info","o_beforeserver","o_ffEvent","o_openPopUp","o_debu_show","o_logwarn","o_dbg_unmark","o_ffRegisterSubmit","o_clearConsole","o_init","o_log","o_allowNextClick","o_dbg_mark","o_debu_hide","o_logerr","o_debu_oldcn","o_debu_oldtt","o_debug_trid","o_log_all"],_countDOMElements:function(){return document.getElementsByTagName("*").length},_countGlobalObjects:function(){var a=0;for(prop in window){a++}return a},logDOMCount:function(){var b=BDebugger;var a=b._countDOMElements();var c=a-b._lastDOMCount;console.log((c>0?"+":"")+c+" \t"+a+" \tDOM element count after DOM replacement");b._lastDOMCount=a;a=null},logGlobalObjCount:function(){var b=BDebugger;var a=b._countGlobalObjects();var c=a-b._lastObjCount;console.log((c>0?"+":"")+c+" \t"+a+" \tGlobal object count after DOM replacement");b._lastObjCount=a;a=null},logGlobalOLATObjects:function(){var b=BDebugger;var a=new Array();for(prop in window){if(prop.indexOf("o_")==0&&b._knownGlobalOLATObjects.indexOf(prop)==-1){a.push(prop)}}if(a.length>0){console.log(a.length+" global OLAT objects found:");a.each(function(c){console.log("\t"+typeof window[c]+" \t"+c)})}}};/*! * jQuery Transit - CSS3 transitions and transformations * (c) 2011-2014 Rico Sta. Cruz * MIT Licensed. diff --git a/src/test/java/org/olat/core/util/filter/impl/XSSFilterTest.java b/src/test/java/org/olat/core/util/filter/impl/XSSFilterTest.java index 80ab437ea01..35930295945 100644 --- a/src/test/java/org/olat/core/util/filter/impl/XSSFilterTest.java +++ b/src/test/java/org/olat/core/util/filter/impl/XSSFilterTest.java @@ -26,6 +26,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.olat.core.util.filter.Filter; +import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter.Variant; /** * Description:<br> @@ -291,13 +292,13 @@ public class XSSFilterTest { @Test public void test_rawText() { - OWASPAntiSamyXSSFilter intlFilter = new OWASPAntiSamyXSSFilter(-1, false, true); + OWASPAntiSamyXSSFilter intlFilter = new OWASPAntiSamyXSSFilter(-1, false, Variant.tinyMce, true); t("Stéphane Rossé", "Stéphane Rossé", intlFilter); } @Test public void test_rawTextAttaqu() { - OWASPAntiSamyXSSFilter intlFilter = new OWASPAntiSamyXSSFilter(-1, false, true); + OWASPAntiSamyXSSFilter intlFilter = new OWASPAntiSamyXSSFilter(-1, false, Variant.tinyMce, true); t("<script>alert('hello');<//script>", "<script>alert('hello');<//script>", intlFilter); } -- GitLab