commit
fa321dad83
|
@ -6,10 +6,6 @@
|
||||||
color: var(--core-star-color);
|
color: var(--core-star-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-discussionusername {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.core-groupname {
|
.core-groupname {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -8,10 +8,6 @@
|
||||||
color: var(--core-star-color);
|
color: var(--core-star-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-discussionusername {
|
|
||||||
font-size: 1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.core-groupname {
|
.core-groupname {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 30 KiB |
|
@ -33,7 +33,7 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-button *ngIf="downloadCourseEnabled" (click)="prefetchCourse($event)" expand="block" fill="outline"
|
<ion-button *ngIf="downloadCourseEnabled" (click)="prefetchCourse($event)" expand="block" fill="outline"
|
||||||
class="ion-no-margin" [disabled]="prefetchCourseData.loading">
|
class="ion-no-margin" [disabled]="prefetchCourseData.loading">
|
||||||
<ion-icon *ngIf="!prefetchCourseData.loading" [name]="prefetchCourseData.icon" slot="start" />
|
<ion-icon *ngIf="!prefetchCourseData.loading" [name]="prefetchCourseData.icon" slot="start" aria-hidden="true" />
|
||||||
<ion-spinner *ngIf="prefetchCourseData.loading" slot="start" />
|
<ion-spinner *ngIf="prefetchCourseData.loading" slot="start" />
|
||||||
{{ prefetchCourseData.statusTranslatable | translate }}
|
{{ prefetchCourseData.statusTranslatable | translate }}
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
[attr.aria-label]="(section.expanded ? 'core.collapse' : 'core.expand') | translate"
|
[attr.aria-label]="(section.expanded ? 'core.collapse' : 'core.expand') | translate"
|
||||||
[attr.aria-expanded]="section.expanded" [attr.aria-controls]="'core-course-storage-section-' + section.id">
|
[attr.aria-expanded]="section.expanded" [attr.aria-controls]="'core-course-storage-section-' + section.id">
|
||||||
<ion-icon name="fas-chevron-right" flip-rtl slot="start" class="expandable-status-icon"
|
<ion-icon name="fas-chevron-right" flip-rtl slot="start" class="expandable-status-icon"
|
||||||
[class.expandable-status-icon-expanded]="section.expanded" />
|
[class.expandable-status-icon-expanded]="section.expanded" aria-hidden="true" />
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p class="item-heading ion-text-wrap">
|
<p class="item-heading ion-text-wrap">
|
||||||
<core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="section.course"
|
<core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="section.course"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<ng-container *ngIf="loaded && !svgLoaded">
|
<ng-container *ngIf="loaded && !svgIcon">
|
||||||
<img *ngIf="!isLocalUrl" [url]="iconUrl" core-external-content alt="" [component]="linkIconWithComponent ? modname : null"
|
<img *ngIf="!isLocalUrl" [url]="iconUrl" core-external-content alt="" [component]="linkIconWithComponent ? modname : null"
|
||||||
[componentId]="linkIconWithComponent ? componentId : null" (error)="loadFallbackIcon()">
|
[componentId]="linkIconWithComponent ? componentId : null" (error)="loadFallbackIcon()">
|
||||||
<img *ngIf="isLocalUrl" [src]="iconUrl" (error)="loadFallbackIcon()" alt="">
|
<img *ngIf="isLocalUrl" [src]="iconUrl" (error)="loadFallbackIcon()" alt="">
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<div [hidden]="!svgLoaded" #svg></div>
|
<div *ngIf="svgIcon" [innerHTML]="svgIcon"></div>
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreConstants, ModPurpose } from '@/core/constants';
|
import { CoreConstants, ModPurpose } from '@/core/constants';
|
||||||
import { Component, ElementRef, HostBinding, Input, OnChanges, OnInit, SimpleChange, ViewChild } from '@angular/core';
|
import { Component, ElementRef, HostBinding, Input, OnChanges, OnInit, SimpleChange } from '@angular/core';
|
||||||
|
import { SafeHtml } from '@angular/platform-browser';
|
||||||
import { CoreCourse } from '@features/course/services/course';
|
import { CoreCourse } from '@features/course/services/course';
|
||||||
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
||||||
import { CoreFile } from '@services/file';
|
import { CoreFile } from '@services/file';
|
||||||
|
@ -22,7 +23,7 @@ import { CoreSites } from '@services/sites';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUrlUtils } from '@services/utils/url';
|
import { CoreUrlUtils } from '@services/utils/url';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { Http } from '@singletons';
|
import { DomSanitizer, Http } from '@singletons';
|
||||||
import { firstValueFrom } from 'rxjs';
|
import { firstValueFrom } from 'rxjs';
|
||||||
|
|
||||||
const assetsPath = 'assets/img/';
|
const assetsPath = 'assets/img/';
|
||||||
|
@ -65,13 +66,11 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
||||||
return this.showAlt ? this.modNameTranslated : '';
|
return this.showAlt ? this.modNameTranslated : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewChild('svg') svgElement!: ElementRef<HTMLElement>;
|
|
||||||
|
|
||||||
iconUrl = '';
|
iconUrl = '';
|
||||||
|
|
||||||
modNameTranslated = '';
|
modNameTranslated = '';
|
||||||
isLocalUrl = false;
|
isLocalUrl = false;
|
||||||
svgLoaded = false;
|
svgIcon: SafeHtml = '';
|
||||||
linkIconWithComponent = false;
|
linkIconWithComponent = false;
|
||||||
loaded = false;
|
loaded = false;
|
||||||
|
|
||||||
|
@ -304,7 +303,7 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
||||||
protected async setSVGIcon(): Promise<void> {
|
protected async setSVGIcon(): Promise<void> {
|
||||||
if (this.iconVersion === IconVersion.LEGACY_VERSION) {
|
if (this.iconVersion === IconVersion.LEGACY_VERSION) {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
this.svgLoaded = false;
|
this.svgIcon = '';
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -347,7 +346,7 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mimetype !== 'image/svg+xml' || !fileContents) {
|
if (mimetype !== 'image/svg+xml' || !fileContents) {
|
||||||
this.svgLoaded = false;
|
this.svgIcon = '';
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +357,7 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
// Safety check.
|
// Safety check.
|
||||||
if (doc.documentElement.nodeName !== 'svg') {
|
if (doc.documentElement.nodeName !== 'svg') {
|
||||||
this.svgLoaded = false;
|
this.svgIcon = '';
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -397,10 +396,37 @@ export class CoreModIconComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.svgElement.nativeElement.replaceChildren(doc.documentElement);
|
// Prefix id's on svg DOM to avoid conflicts.
|
||||||
this.svgLoaded = true;
|
const uniqueId = 'modicon' + CoreUtils.getUniqueId('modicon') + '_';
|
||||||
|
const styleTags = Array.from(doc.documentElement.getElementsByTagName('style'));
|
||||||
|
const styleAttrs = Array.from(doc.documentElement.querySelectorAll('[style]'));
|
||||||
|
const idTags = Array.from(doc.documentElement.querySelectorAll('[id]'));
|
||||||
|
idTags.forEach((element) => {
|
||||||
|
if (!element.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newId = uniqueId + element.id;
|
||||||
|
// Regexp to replace all ocurrences of the id with workd bondaries.
|
||||||
|
const oldIdFinder = new RegExp(`#${element.id}\\b`, 'g');
|
||||||
|
|
||||||
|
element.id = newId;
|
||||||
|
|
||||||
|
// Prefix the elementId on style Tags.
|
||||||
|
styleTags.forEach((style) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
style.textContent = style.textContent!.replace(oldIdFinder, `#${newId}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also change ids on style attributes.
|
||||||
|
styleAttrs.forEach((attr) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
attr.setAttribute('style', attr.getAttribute('style')!.replace(oldIdFinder, `#${newId}`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.svgIcon = DomSanitizer.bypassSecurityTrustHtml(doc.documentElement.outerHTML);
|
||||||
} catch {
|
} catch {
|
||||||
this.svgLoaded = false;
|
this.svgIcon = '';
|
||||||
} finally {
|
} finally {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,24 +75,24 @@ ion-modal {
|
||||||
--ion-safe-area-left: 0px;
|
--ion-safe-area-left: 0px;
|
||||||
--ion-safe-area-right: 0px;
|
--ion-safe-area-right: 0px;
|
||||||
|
|
||||||
|
--height: 100% !important;
|
||||||
|
--width: calc(100% - var(--modal-lateral-margin));
|
||||||
|
--box-shadow: 0 28px 48px rgb(0 0 0 / 40%);
|
||||||
|
|
||||||
|
// These lines is intended to hide modal-shadow div only in iOS because it cannot be positioned correctly.
|
||||||
|
// Both are set on content part.
|
||||||
|
--max-height: 0px;
|
||||||
|
--max-width: 0px;
|
||||||
|
|
||||||
&::part(content) {
|
&::part(content) {
|
||||||
@include margin-horizontal(var(--modal-lateral-margin), null);
|
@include margin-horizontal(var(--modal-lateral-margin), null);
|
||||||
|
|
||||||
|
--max-width: calc(var(--modal-lateral-max-width));
|
||||||
|
--max-height: 100%;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@include position(0 !important, 0 !important, 0 !important, unset !important);
|
@include position(0 !important, 0 !important, 0 !important, unset !important);
|
||||||
display: block;
|
display: block;
|
||||||
height: 100% !important;
|
|
||||||
width: calc(100% - var(--modal-lateral-margin));
|
|
||||||
max-width: calc(var(--modal-lateral-max-width));
|
|
||||||
box-shadow: 0 28px 48px rgb(0 0 0 / 40%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::part(backdrop) {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-shadow {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +109,10 @@ ion-modal {
|
||||||
--width: 384px;
|
--width: 384px;
|
||||||
--height: auto;
|
--height: auto;
|
||||||
|
|
||||||
|
.ion-page {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
Loading…
Reference in New Issue