diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java index c2eab752d3cdf0541b0c9aea7269d94486d6c918..652fd6cccf4ba5eeacf33a7e85ddd68645d46ee7 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurity.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java @@ -106,7 +106,7 @@ public interface BaseSecurity { * @param secGroup * @return true if the identity is in the group */ - public boolean isIdentityInSecurityGroup(Identity identity, SecurityGroup secGroup); + public boolean isIdentityInSecurityGroup(IdentityRef identity, SecurityGroup secGroup); /** * Change the last modificaiton date of the membership diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java index 752d043f10b63d30e5a9c4de63a672a4365d1cd4..bb335b3793eb43d5924d1eab0d334d59cfa3df89 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java @@ -501,7 +501,7 @@ public class BaseSecurityManager implements BaseSecurity { * @see org.olat.basesecurity.Manager#isIdentityInSecurityGroup(org.olat.core.id.Identity, org.olat.basesecurity.SecurityGroup) */ @Override - public boolean isIdentityInSecurityGroup(Identity identity, SecurityGroup secGroup) { + public boolean isIdentityInSecurityGroup(IdentityRef identity, SecurityGroup secGroup) { if (secGroup == null || identity == null) return false; String queryString = "select sgmsi.key from org.olat.basesecurity.SecurityGroupMembershipImpl as sgmsi where sgmsi.identity.key=:identitykey and sgmsi.securityGroup.key=:securityGroupKey"; @@ -513,7 +513,7 @@ public class BaseSecurityManager implements BaseSecurity { .setFirstResult(0) .setMaxResults(1) .getResultList(); - return membership != null && membership.size() > 0 && membership.get(0) != null; + return membership != null && !membership.isEmpty() && membership.get(0) != null; } @Override diff --git a/src/main/java/org/olat/core/gui/themes/Theme.java b/src/main/java/org/olat/core/gui/themes/Theme.java index 60131bf91942e3df2f97165cc2f2ee5bdd1e5424..c8b65a4e2b9856bd655da5ee7c7f62bf90fe39fb 100644 --- a/src/main/java/org/olat/core/gui/themes/Theme.java +++ b/src/main/java/org/olat/core/gui/themes/Theme.java @@ -44,6 +44,9 @@ public class Theme { private static final String CUSTOM_FAVICON_PNG32_FILENAME = "meta/favicon32.png"; private static final String CUSTOM_FAVICON_PNG64_FILENAME = "meta/favicon64.png"; private static final String CUSTOM_APPICON_PNG180_FILENAME = "meta/appicon180.png"; + private static final String CUSTOM_TILEICON_PNG70_FILENAME = "meta/tileicon70.png"; + private static final String CUSTOM_TILEICON_PNG150_FILENAME = "meta/tileicon150.png"; + private static final String CUSTOM_TILEICON_PNG310_FILENAME = "meta/tileicon310.png"; private static final String CUSTOM_MANIFEST_FILENAME = "meta/manifest.json"; private static final String CUSTOM_MS_APPLICATION_CONFIG_FILENAM = "meta/msapplication-config.xml"; @@ -168,9 +171,20 @@ public class Theme { if (new File(themeFolder,CUSTOM_MANIFEST_FILENAME).exists()) { sb.append("<link rel='manifest' href='").append(baseURI).append(CUSTOM_MANIFEST_FILENAME).append("' />\n"); } - // Include Microsoft application config file + // Include Microsoft application config file (make sure any referenced image in the file has absolute path configuration if (new File(themeFolder,CUSTOM_MS_APPLICATION_CONFIG_FILENAM).exists()) { sb.append("<meta name='msapplication-config' content='").append(baseURI).append(CUSTOM_MS_APPLICATION_CONFIG_FILENAM).append("' />\n"); + } else { + sb.append("<meta name='msapplication-TileColor' content='").append("#ffffff").append("' />\n"); + if (new File(themeFolder,CUSTOM_TILEICON_PNG70_FILENAME).exists()) { + sb.append("<meta name='msapplication-square70x70logo' content='").append(baseURI).append(CUSTOM_TILEICON_PNG70_FILENAME).append("' />\n"); + } + if (new File(themeFolder,CUSTOM_TILEICON_PNG150_FILENAME).exists()) { + sb.append("<meta name='msapplication-square150x150logo' content='").append(baseURI).append(CUSTOM_TILEICON_PNG150_FILENAME).append("' />\n"); + } + if (new File(themeFolder,CUSTOM_TILEICON_PNG310_FILENAME).exists()) { + sb.append("<meta name='msapplication-square310x310logo' content='").append(baseURI).append(CUSTOM_TILEICON_PNG310_FILENAME).append("' />\n"); + } } return sb.toString(); diff --git a/src/main/java/org/olat/core/util/Formatter.java b/src/main/java/org/olat/core/util/Formatter.java index ab3e7b97f2877a30d651d983062d0ae9be80e350..97e9516a7fe4a5d54c2de1481e5a8c3bc831ba45 100644 --- a/src/main/java/org/olat/core/util/Formatter.java +++ b/src/main/java/org/olat/core/util/Formatter.java @@ -65,7 +65,10 @@ public class Formatter { private static final DateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); private static final DateFormat shortFormatDateFileSystem = new SimpleDateFormat("yyyyMMdd"); - private static final Map<Locale,Formatter> localToFormatterMap = new HashMap<Locale,Formatter>(); + private static final Map<Locale,Formatter> localToFormatterMap = new HashMap<>(); + + // Pattern to find math classes + private static final Pattern classMathPattern = Pattern.compile(".*class[ ]*=[ ]*(math|(['\"])([a-zA-Z0-9_\\- ]* )*math( [a-zA-Z0-9_\\- ]*)*\\2).*"); private final Locale locale; private final DateFormat shortDateFormat; @@ -651,7 +654,7 @@ public class Formatter { public static String formatLatexFormulas(String htmlFragment) { if (htmlFragment == null) return ""; // optimize, reduce jsmath calls on client - if (htmlFragment.contains("<math") || htmlFragment.contains("class='math'") || htmlFragment.contains("class=\"math\"")) { + if (htmlFragment.contains("<math") || htmlFragment.contains("class='math'") || htmlFragment.contains("class=\"math\"") || classMathPattern.matcher(htmlFragment).matches()) { // add math wrapper String domid = "mw_" + CodeHelper.getRAMUniqueID(); String elem = htmlFragment.contains("<div") || htmlFragment.contains("<p") ? "div" : "span"; diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java index 8c1ab501f700500d440d81c0423a3e2e6bf50655..b4a38444a428ea6756e1279e762f0827b812e34a 100644 --- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java +++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java @@ -709,9 +709,9 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent protected final void renderSpan(AssessmentRenderer renderer, StringOutput sb, Span span, AssessmentObjectComponent component, ResolvedAssessmentItem resolvedAssessmentItem, ItemSessionState itemSessionState, URLBuilder ubu, Translator translator) { - Attribute<?> attrClass = span.getAttributes().get("class"); + StringMultipleAttribute attrClass = span.getAttributes().getStringMultipleAttribute("class"); - if(attrClass != null && attrClass.getValue() != null && attrClass.getValue().toString().equals("[math]")) { + if (attrClass != null && attrClass.getValue() != null && attrClass.getValue().contains("math")) { String domid = "mw_" + CodeHelper.getRAMUniqueID(); sb.append("<span id=\"").append(domid).append("\">"); diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties index 208b4a381e48cea1d6a9689c5a9f3f8294caaea4..8fda3810de258c7e331c59ddcb48a35c50b33fa4 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties @@ -17,7 +17,7 @@ create.type=Fragetyp erstellen delete.level=L\u00F6schen delete.level.confirm=Wollen Sie wirklich diese Stufe l\u00F6schen? delete.qustions.without.author=Fragen l\u00F6schen, wenn Autor gel\u00F6scht -delete.qustions.without.author.info=Beim L\u00F6schen eines Benutzers wird er als Autoren von allen Fragen ausgetragen. Wenn diese Option eingeschaltet ist und der Benutzer der einzige Autor einer Frage ist, wird die Frage ebenfalls gel\u00F6scht. +delete.qustions.without.author.info=Beim L\u00F6schen eines Benutzers wird er als Autor von allen Fragen ausgetragen. Wenn diese Option eingeschaltet ist und der Benutzer der einzige Autor einer Frage ist, wird die Frage ebenfalls gel\u00F6scht. delete.taxonomyLevel=L\u00F6schen delete.taxonomyLevel.confirm=Wollen Sie wirklich diese Fachbereich "{0}" l\u00F6schen? delete.type=L\u00F6schen diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/free/ui/FreeAccessConfigurationController.java b/src/main/java/org/olat/resource/accesscontrol/provider/free/ui/FreeAccessConfigurationController.java index ad3238f3167fe5dbdacb207d48884d9340a07e9b..2d6737c5c04c30459c54b42665b94b9d9a37f359 100644 --- a/src/main/java/org/olat/resource/accesscontrol/provider/free/ui/FreeAccessConfigurationController.java +++ b/src/main/java/org/olat/resource/accesscontrol/provider/free/ui/FreeAccessConfigurationController.java @@ -61,14 +61,18 @@ public class FreeAccessConfigurationController extends AbstractConfigurationMeth @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + formLayout.setElementCssClass("o_sel_accesscontrol_free_form"); + String desc = null; if(link.getOffer() != null) { desc = link.getOffer().getDescription(); } descEl = uifactory.addTextAreaElement("offer-desc", "offer.description", 2000, 6, 80, false, desc, formLayout); + descEl.setElementCssClass("o_sel_accesscontrol_description"); String[] autoValues = new String[]{ translate("auto.booking.value") }; autoEl = uifactory.addCheckboxesHorizontal("auto.booking", "auto.booking", formLayout, autoKeys, autoValues); + autoEl.setElementCssClass("o_sel_accesscontrol_auto_booking"); if(link.getOffer() != null && link.getOffer().getKey() != null) { autoEl.select(autoKeys[0], link.getOffer().isAutoBooking()); } else { diff --git a/src/main/webapp/static/themes/light/meta/appicon.png b/src/main/webapp/static/themes/light/meta/appicon.png deleted file mode 100644 index 35d5028af8869c7a65ca8867fddfd1e99a23a2ad..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/light/meta/appicon.png and /dev/null differ diff --git a/src/main/webapp/static/themes/light/meta/appicon150.png b/src/main/webapp/static/themes/light/meta/appicon150.png deleted file mode 100644 index 87e742132f7262c27283f704b8c4e45ae2beb310..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/light/meta/appicon150.png and /dev/null differ diff --git a/src/main/webapp/static/themes/light/meta/appicon180.png b/src/main/webapp/static/themes/light/meta/appicon180.png index daeacdd1ab446e6d16a6f13b4d8aa0575f0f9f9c..198e34500c45bb54faaee5763e1c7b94c7f5d326 100644 Binary files a/src/main/webapp/static/themes/light/meta/appicon180.png and b/src/main/webapp/static/themes/light/meta/appicon180.png differ diff --git a/src/main/webapp/static/themes/light/meta/appicon192.png b/src/main/webapp/static/themes/light/meta/appicon192.png index 4607d733a852dd393c6cc08c234a963f44ee5a90..ec53d0efa46f903cd388481bb4509b22334c2097 100644 Binary files a/src/main/webapp/static/themes/light/meta/appicon192.png and b/src/main/webapp/static/themes/light/meta/appicon192.png differ diff --git a/src/main/webapp/static/themes/light/meta/appicon270.png b/src/main/webapp/static/themes/light/meta/appicon270.png deleted file mode 100644 index 6a5e00c8acbdc3d50f706bf601428cebf4248023..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/light/meta/appicon270.png and /dev/null differ diff --git a/src/main/webapp/static/themes/light/meta/appicon310.png b/src/main/webapp/static/themes/light/meta/appicon310.png deleted file mode 100644 index d34649b21d0751147840fa3a482c7b95ca8afd86..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/light/meta/appicon310.png and /dev/null differ diff --git a/src/main/webapp/static/themes/light/meta/appicon70.png b/src/main/webapp/static/themes/light/meta/appicon70.png deleted file mode 100644 index 0fb545c63688c0d9188a6b52365bb64e2786bcbb..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/light/meta/appicon70.png and /dev/null differ diff --git a/src/main/webapp/static/themes/light/meta/favicon.png b/src/main/webapp/static/themes/light/meta/favicon.png deleted file mode 100644 index b3cc6bfc35306ededf03b46b685b7946fe1b95da..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/light/meta/favicon.png and /dev/null differ diff --git a/src/main/webapp/static/themes/light/meta/favicon16.png b/src/main/webapp/static/themes/light/meta/favicon16.png index 643d96da6c16c256775ef7df38ee802ff156e61d..5a6dbecf1324283d6ccf0cea6d39627643b69044 100644 Binary files a/src/main/webapp/static/themes/light/meta/favicon16.png and b/src/main/webapp/static/themes/light/meta/favicon16.png differ diff --git a/src/main/webapp/static/themes/light/meta/favicon32.png b/src/main/webapp/static/themes/light/meta/favicon32.png index a546d3017baa73fbe16642da834ded57f6a2532e..9725a2aeceddccbb4d3d3b68197d22be5e91d92c 100644 Binary files a/src/main/webapp/static/themes/light/meta/favicon32.png and b/src/main/webapp/static/themes/light/meta/favicon32.png differ diff --git a/src/main/webapp/static/themes/light/meta/favicon64.png b/src/main/webapp/static/themes/light/meta/favicon64.png index 359ae5ef133b5d8be6756334f145d0913052c589..dfa7c180906fc435fb02934d35e7125b8ae67eca 100644 Binary files a/src/main/webapp/static/themes/light/meta/favicon64.png and b/src/main/webapp/static/themes/light/meta/favicon64.png differ diff --git a/src/main/webapp/static/themes/light/meta/manifest.json b/src/main/webapp/static/themes/light/meta/manifest.json index 6c145a783e0a8d02ffc2f5405bf65411224ffba4..9a6aafebe06ce56ca795b908c35b0f73f917c540 100644 --- a/src/main/webapp/static/themes/light/meta/manifest.json +++ b/src/main/webapp/static/themes/light/meta/manifest.json @@ -1,10 +1,10 @@ { - "name":"OpenOLAT - Infinite Learning", + "name":"OpenOLAT eLearning", "icons": [ { "src":"appicon192.png", "sizes":"192x192", "type":"image/png" } ], "theme_color":"#ffffff", - "display":"standalone" + "display":"minimal-ui" } \ No newline at end of file diff --git a/src/main/webapp/static/themes/light/meta/msapplication-config.xml b/src/main/webapp/static/themes/light/meta/msapplication-config.xml deleted file mode 100644 index 588c0ca5ec8ae949f1a6c26394a165800cb4118c..0000000000000000000000000000000000000000 --- a/src/main/webapp/static/themes/light/meta/msapplication-config.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - <browserconfig> - <msapplication> - <tile> - <square70x70logo src="appicon70.png" /> - <square150x150logo src="appicon150.png" /> - <square310x310logo src="appicon310.png" /> - <TileColor>#04283d</TileColor> - </tile> - </msapplication> - </browserconfig> \ No newline at end of file diff --git a/src/main/webapp/static/themes/light/meta/src/appicon.png b/src/main/webapp/static/themes/light/meta/src/appicon.png new file mode 100644 index 0000000000000000000000000000000000000000..350e590e9ea5a5b200167a747148590a8c583a13 Binary files /dev/null and b/src/main/webapp/static/themes/light/meta/src/appicon.png differ diff --git a/src/main/webapp/static/themes/light/meta/src/favicon.png b/src/main/webapp/static/themes/light/meta/src/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..b83c9a419e00197825ada39d9ee974af7099fd29 Binary files /dev/null and b/src/main/webapp/static/themes/light/meta/src/favicon.png differ diff --git a/src/main/webapp/static/themes/light/meta/src/tileicon.png b/src/main/webapp/static/themes/light/meta/src/tileicon.png new file mode 100644 index 0000000000000000000000000000000000000000..4b9fe8935b0bb5759e70b4f4df6d368694c7789a Binary files /dev/null and b/src/main/webapp/static/themes/light/meta/src/tileicon.png differ diff --git a/src/main/webapp/static/themes/light/meta/tileicon150.png b/src/main/webapp/static/themes/light/meta/tileicon150.png new file mode 100644 index 0000000000000000000000000000000000000000..29bafe6cdc5059bd8b98d9821076a9e6586733e1 Binary files /dev/null and b/src/main/webapp/static/themes/light/meta/tileicon150.png differ diff --git a/src/main/webapp/static/themes/light/meta/tileicon310.png b/src/main/webapp/static/themes/light/meta/tileicon310.png new file mode 100644 index 0000000000000000000000000000000000000000..1f832765e7dd664b7531bb84c53b21028d9f3bf3 Binary files /dev/null and b/src/main/webapp/static/themes/light/meta/tileicon310.png differ diff --git a/src/main/webapp/static/themes/light/meta/tileicon70.png b/src/main/webapp/static/themes/light/meta/tileicon70.png new file mode 100644 index 0000000000000000000000000000000000000000..0e49469e7f4521e1c11fc88fe092080e7e9e60c4 Binary files /dev/null and b/src/main/webapp/static/themes/light/meta/tileicon70.png differ diff --git a/src/main/webapp/static/themes/openolat/meta/appicon.png b/src/main/webapp/static/themes/openolat/meta/appicon.png deleted file mode 100644 index 35d5028af8869c7a65ca8867fddfd1e99a23a2ad..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/openolat/meta/appicon.png and /dev/null differ diff --git a/src/main/webapp/static/themes/openolat/meta/appicon150.png b/src/main/webapp/static/themes/openolat/meta/appicon150.png deleted file mode 100644 index 87e742132f7262c27283f704b8c4e45ae2beb310..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/openolat/meta/appicon150.png and /dev/null differ diff --git a/src/main/webapp/static/themes/openolat/meta/appicon180.png b/src/main/webapp/static/themes/openolat/meta/appicon180.png index daeacdd1ab446e6d16a6f13b4d8aa0575f0f9f9c..198e34500c45bb54faaee5763e1c7b94c7f5d326 100644 Binary files a/src/main/webapp/static/themes/openolat/meta/appicon180.png and b/src/main/webapp/static/themes/openolat/meta/appicon180.png differ diff --git a/src/main/webapp/static/themes/openolat/meta/appicon192.png b/src/main/webapp/static/themes/openolat/meta/appicon192.png index 4607d733a852dd393c6cc08c234a963f44ee5a90..ec53d0efa46f903cd388481bb4509b22334c2097 100644 Binary files a/src/main/webapp/static/themes/openolat/meta/appicon192.png and b/src/main/webapp/static/themes/openolat/meta/appicon192.png differ diff --git a/src/main/webapp/static/themes/openolat/meta/appicon270.png b/src/main/webapp/static/themes/openolat/meta/appicon270.png deleted file mode 100644 index 6a5e00c8acbdc3d50f706bf601428cebf4248023..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/openolat/meta/appicon270.png and /dev/null differ diff --git a/src/main/webapp/static/themes/openolat/meta/appicon310.png b/src/main/webapp/static/themes/openolat/meta/appicon310.png deleted file mode 100644 index d34649b21d0751147840fa3a482c7b95ca8afd86..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/openolat/meta/appicon310.png and /dev/null differ diff --git a/src/main/webapp/static/themes/openolat/meta/appicon70.png b/src/main/webapp/static/themes/openolat/meta/appicon70.png deleted file mode 100644 index 0fb545c63688c0d9188a6b52365bb64e2786bcbb..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/openolat/meta/appicon70.png and /dev/null differ diff --git a/src/main/webapp/static/themes/openolat/meta/favicon.png b/src/main/webapp/static/themes/openolat/meta/favicon.png deleted file mode 100644 index b3cc6bfc35306ededf03b46b685b7946fe1b95da..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/openolat/meta/favicon.png and /dev/null differ diff --git a/src/main/webapp/static/themes/openolat/meta/favicon16.png b/src/main/webapp/static/themes/openolat/meta/favicon16.png index 643d96da6c16c256775ef7df38ee802ff156e61d..5a6dbecf1324283d6ccf0cea6d39627643b69044 100644 Binary files a/src/main/webapp/static/themes/openolat/meta/favicon16.png and b/src/main/webapp/static/themes/openolat/meta/favicon16.png differ diff --git a/src/main/webapp/static/themes/openolat/meta/favicon32.png b/src/main/webapp/static/themes/openolat/meta/favicon32.png index a546d3017baa73fbe16642da834ded57f6a2532e..9725a2aeceddccbb4d3d3b68197d22be5e91d92c 100644 Binary files a/src/main/webapp/static/themes/openolat/meta/favicon32.png and b/src/main/webapp/static/themes/openolat/meta/favicon32.png differ diff --git a/src/main/webapp/static/themes/openolat/meta/favicon64.png b/src/main/webapp/static/themes/openolat/meta/favicon64.png index 359ae5ef133b5d8be6756334f145d0913052c589..dfa7c180906fc435fb02934d35e7125b8ae67eca 100644 Binary files a/src/main/webapp/static/themes/openolat/meta/favicon64.png and b/src/main/webapp/static/themes/openolat/meta/favicon64.png differ diff --git a/src/main/webapp/static/themes/openolat/meta/manifest.json b/src/main/webapp/static/themes/openolat/meta/manifest.json index 6c145a783e0a8d02ffc2f5405bf65411224ffba4..9a6aafebe06ce56ca795b908c35b0f73f917c540 100644 --- a/src/main/webapp/static/themes/openolat/meta/manifest.json +++ b/src/main/webapp/static/themes/openolat/meta/manifest.json @@ -1,10 +1,10 @@ { - "name":"OpenOLAT - Infinite Learning", + "name":"OpenOLAT eLearning", "icons": [ { "src":"appicon192.png", "sizes":"192x192", "type":"image/png" } ], "theme_color":"#ffffff", - "display":"standalone" + "display":"minimal-ui" } \ No newline at end of file diff --git a/src/main/webapp/static/themes/openolat/meta/msapplication-config.xml b/src/main/webapp/static/themes/openolat/meta/msapplication-config.xml deleted file mode 100644 index 588c0ca5ec8ae949f1a6c26394a165800cb4118c..0000000000000000000000000000000000000000 --- a/src/main/webapp/static/themes/openolat/meta/msapplication-config.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - <browserconfig> - <msapplication> - <tile> - <square70x70logo src="appicon70.png" /> - <square150x150logo src="appicon150.png" /> - <square310x310logo src="appicon310.png" /> - <TileColor>#04283d</TileColor> - </tile> - </msapplication> - </browserconfig> \ No newline at end of file diff --git a/src/main/webapp/static/themes/openolat/meta/tileicon150.png b/src/main/webapp/static/themes/openolat/meta/tileicon150.png new file mode 100644 index 0000000000000000000000000000000000000000..29bafe6cdc5059bd8b98d9821076a9e6586733e1 Binary files /dev/null and b/src/main/webapp/static/themes/openolat/meta/tileicon150.png differ diff --git a/src/main/webapp/static/themes/openolat/meta/tileicon310.png b/src/main/webapp/static/themes/openolat/meta/tileicon310.png new file mode 100644 index 0000000000000000000000000000000000000000..1f832765e7dd664b7531bb84c53b21028d9f3bf3 Binary files /dev/null and b/src/main/webapp/static/themes/openolat/meta/tileicon310.png differ diff --git a/src/main/webapp/static/themes/openolat/meta/tileicon70.png b/src/main/webapp/static/themes/openolat/meta/tileicon70.png new file mode 100644 index 0000000000000000000000000000000000000000..0e49469e7f4521e1c11fc88fe092080e7e9e60c4 Binary files /dev/null and b/src/main/webapp/static/themes/openolat/meta/tileicon70.png differ diff --git a/src/main/webapp/static/themes/themes.README b/src/main/webapp/static/themes/themes.README index adcf0ef1913a08e56a49f368d65ff3edad6c5c02..296f11aea62ca8817382d7461065f4329b2817a3 100644 --- a/src/main/webapp/static/themes/themes.README +++ b/src/main/webapp/static/themes/themes.README @@ -83,9 +83,18 @@ Optional: mytheme/meta/favicon.16.png -> optional, to add a 16x16 bookmark icon mytheme/meta/favicon.32.png -> optional, to add a 32x32 bookmark icon mytheme/meta/favicon.64.png -> optional, to add a 64x64 bookmark icon +- Place your own application icons for older iOS to mytheme/meta/appicon180.png -> optional, to add iOS homescreen icons - mytheme/meta/manifest.json -> optional, to add Android homescreen icons +- Place your own manifest and application icons for modern Safari and Android to + mytheme/meta/manifest.json -> optional, to add Android homescreen icons (and add the appicons linked from within manifest.json) +- Place your own Windows Tile icons to + mytheme/meta/tileicon70png + mytheme/meta/tileicon150png + mytheme/meta/tileicon310png +- OR alternatively add a browser config file to the location below. mytheme/meta/msapplication-config.xml -> optional, to add Windows tiles icons + Note, when the browser config is there, the tile icons above will not be included. In the browser config the + links to the tile icons must be absolute path to work despite the MS doku tells otherwise - Create a file mytheme/theme.js and add your theme specific JavaScript. Best is to create a JQuery module for it. Make sure you check for necessary changes after each DOM replacement cycle. See the theme.js file diff --git a/src/test/java/org/olat/core/util/FormatterTest.java b/src/test/java/org/olat/core/util/FormatterTest.java index 682e38935e981dfa509494b31bd6683f62279a49..b794f3f8ef0de4b2fa8716faaa7e8cfc181ef115 100644 --- a/src/test/java/org/olat/core/util/FormatterTest.java +++ b/src/test/java/org/olat/core/util/FormatterTest.java @@ -133,5 +133,32 @@ public class FormatterTest { Assert.assertEquals("532:23:45", Formatter.formatTimecode(1916625000l)); } + @Test + public void formatLatexFormulas() { + Assert.assertTrue(Formatter.formatLatexFormulas("<span class='math'></span>").contains("<script")); + Assert.assertTrue(Formatter.formatLatexFormulas("<span class='math inline'></span>").contains("<script")); + Assert.assertTrue(Formatter.formatLatexFormulas("<div class = \"inline math special\"></div>").contains("<script")); + Assert.assertTrue(Formatter.formatLatexFormulas("<span class = math></span>").contains("<script")); + Assert.assertFalse(Formatter.formatLatexFormulas("<span class = \"nomath\"></span>").contains("<script")); + Assert.assertFalse(Formatter.formatLatexFormulas("<span class='test' id='math'></span>").contains("<script")); + Assert.assertFalse(Formatter.formatLatexFormulas("<span class='math\"></span>").contains("<script")); + //wiki + Assert.assertTrue(Formatter.formatLatexFormulas("<DIV CLASS=\"math\"></span>").contains("<script")); + } + + /** + * This case doesn't test the result of the method but if wrong + * formatted HTML code can produce an infinite loop. + * + */ + @Test + public void formatLatexFormulas_edgeCase() { + Assert.assertFalse(Formatter.formatLatexFormulas("<span class='math\"''></span>").contains("<script")); + Assert.assertFalse(Formatter.formatLatexFormulas("<span class='math\"'\"></span>").contains("<script")); + Assert.assertFalse(Formatter.formatLatexFormulas("<span class='math></\"span>").contains("<script")); + Assert.assertFalse(Formatter.formatLatexFormulas("<span class='math></'span>").contains("<script")); + Assert.assertFalse(Formatter.formatLatexFormulas("<span class='math").contains("<script")); + Assert.assertTrue(Formatter.formatLatexFormulas("<span class=math\"").contains("<script")); + } } diff --git a/src/test/java/org/olat/selenium/CourseTest.java b/src/test/java/org/olat/selenium/CourseTest.java index e71458f1ccad566a121107c9b9abc965190328af..ae9b91914b03718c23d3338288389eda0e365611 100644 --- a/src/test/java/org/olat/selenium/CourseTest.java +++ b/src/test/java/org/olat/selenium/CourseTest.java @@ -871,6 +871,91 @@ public class CourseTest extends Deployments { .assertFirstNameInList(ryomou); } + + /** + * An author creates a course, make it visible for + * members and add an access control by free booking + * with the auto booking enabled.<br/> + * The user search for the course and enters it.<br/> + * The author checks in the list of orders if the booking + * of the user is there and after it checks if the user is + * in the member list too. + * + * @param loginPage + * @param userBrowser + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void courseFreeBooking(@InitialPage LoginPage loginPage, + @Drone @User WebDriver userBrowser) + throws IOException, URISyntaxException { + + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + loginPage.loginAs(author.getLogin(), author.getPassword()); + UserVO user = new UserRestClient(deploymentUrl).createRandomUser("Kanu"); + + //go to authoring + AuthoringEnvPage authoringEnv = navBar + .assertOnNavigationPage() + .openAuthoringEnvironment(); + + String title = "AutoBooking-" + UUID.randomUUID(); + //create course + authoringEnv + .openCreateDropDown() + .clickCreate(ResourceType.course) + .fillCreateForm(title) + .assertOnGeneralTab(); + + //open course editor + CoursePageFragment course = new CoursePageFragment(browser); + RepositoryAccessPage courseAccess = course + .openToolsMenu() + .edit() + .createNode("info") + .autoPublish() + .accessConfiguration() + .setUserAccess(UserAccess.registred); + //add booking by secret token + courseAccess + .boooking() + .openAddDropMenu() + .addFreeBooking() + .configureFreeBooking("It's free"); + courseAccess + .clickToolbarBack(); + + //a user search the course + LoginPage userLoginPage = LoginPage.getLoginPage(userBrowser, deploymentUrl); + userLoginPage + .loginAs(user.getLogin(), user.getPassword()) + .resume(); + NavigationPage userNavBar = new NavigationPage(userBrowser); + userNavBar + .openMyCourses() + .openSearch() + .extendedSearch(title) + .book(title);//book the course + //check the course + CoursePageFragment bookedCourse = CoursePageFragment.getCourse(userBrowser); + bookedCourse + .assertOnTitle(title); + + //Author go in the list of bookings of the course + BookingPage bookingList = course + .openToolsMenu() + .bookingTool(); + bookingList + .assertFirstNameInListIsOk(user); + + //Author go to members list + course + .members() + .assertFirstNameInList(user); + } + /** * An author create a course, set a start and end date for life-cycle. * It add a participant to the course. It creates a reminder diff --git a/src/test/java/org/olat/selenium/page/core/BookingPage.java b/src/test/java/org/olat/selenium/page/core/BookingPage.java index 3f95b8be2440b7d5c1cf99e7716784e6844bce3d..fce48e8a4c746c64ae55efd534ba7a1861668a63 100644 --- a/src/test/java/org/olat/selenium/page/core/BookingPage.java +++ b/src/test/java/org/olat/selenium/page/core/BookingPage.java @@ -71,10 +71,9 @@ public class BookingPage { private BookingPage addMethod(String iconClassname) { //wait menu By addMenuBy = By.cssSelector("fieldset.o_ac_configuration ul.dropdown-menu"); - OOGraphene.waitElement(addMenuBy, 5, browser); - By addMethodBy = By.xpath("//fieldset[contains(@class,'o_ac_configuration')]//ul[contains(@class,'dropdown-menu')]//a[//i[contains(@class,'" + iconClassname + "')]]"); - WebElement methodLink = browser.findElement(addMethodBy); - methodLink.click(); + OOGraphene.waitElement(addMenuBy, browser); + By addMethodBy = By.xpath("//fieldset[contains(@class,'o_ac_configuration')]//ul[contains(@class,'dropdown-menu')]//a[i[contains(@class,'" + iconClassname + "')]]"); + browser.findElement(addMethodBy).click(); OOGraphene.waitBusy(browser); return this; } @@ -113,6 +112,33 @@ public class BookingPage { OOGraphene.waitBusy(browser); } + /** + * Select the free booking option + * + * @return Itself + */ + public BookingPage addFreeBooking() { + addMethod("o_ac_free_icon"); + OOGraphene.waitModalDialog(browser); + return this; + } + + /** + * Save the free booking. + * + * @param description The description of the booking. + * @return Itself + */ + public BookingPage configureFreeBooking(String description) { + By descriptionBy = By.cssSelector(".o_sel_accesscontrol_free_form .o_sel_accesscontrol_description textarea"); + browser.findElement(descriptionBy).sendKeys(description); + + By submitBy = By.cssSelector(".o_sel_accesscontrol_free_form button.btn-primary"); + browser.findElement(submitBy).click(); + OOGraphene.waitBusy(browser); + return this; + } + public void save() { By saveButtonBy = By.cssSelector("form button.btn-primary"); browser.findElement(saveButtonBy).click(); diff --git a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java index 4a058b65bcb9166c404610564733528737b139e0..5a016a79268b878f0281374531bd8f3369191038 100644 --- a/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java +++ b/src/test/java/org/olat/selenium/page/graphene/OOGraphene.java @@ -435,6 +435,15 @@ public class OOGraphene { waitModalDialogDisappears(browser); } + public static final void closeWarningBox(WebDriver browser) { + By errorBoxBy = By.cssSelector(".modal-body.alert.alert-warning"); + waitElement(errorBoxBy, 5, browser); + By closeButtonBy = By.xpath("//div[not(@id='o_form_dirty_message')]/div[contains(@class,'modal-dialog')]//button[@class='close']"); + waitElement(closeButtonBy, 5, browser); + browser.findElement(closeButtonBy).click(); + waitModalDialogDisappears(browser); + } + public static final void waitAndCloseBlueMessageWindow(WebDriver browser) { try { Graphene.waitModel(browser).withTimeout(5, TimeUnit.SECONDS)