forked from EVOgeek/Vmeda.Online
		
	
						commit
						9f0de18eaa
					
				| @ -5,7 +5,7 @@ | ||||
|         </core-horizontal-scroll-controls> | ||||
|     </div> | ||||
| </ion-item-divider> | ||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page margin"> | ||||
| <core-loading [hideUntil]="loaded" [fullscreen]="false" class="safe-area-page"> | ||||
|     <div | ||||
|         [id]="scrollElementId" | ||||
|         [hidden]="!items || items.length === 0" | ||||
|  | ||||
| @ -8,4 +8,7 @@ | ||||
|     .core-course-module-handler { | ||||
|         --inner-border-width: 0; | ||||
|     } | ||||
|     core-loading { | ||||
|         --loading-inline-min-height: 102px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -53,7 +53,7 @@ | ||||
|             </ion-item> | ||||
|         </ion-card> | ||||
| 
 | ||||
|         <core-empty-box *ngIf="!filteredEvents || !filteredEvents.length" icon="fas-calendar" inline="true" | ||||
|         <core-empty-box *ngIf="!filteredEvents || !filteredEvents.length" icon="fas-calendar" | ||||
|             [message]="'addon.calendar.noevents' | translate"> | ||||
|         </core-empty-box> | ||||
| 
 | ||||
|  | ||||
| @ -96,7 +96,7 @@ | ||||
|                             <core-user-avatar slot="start" [user]="members[message.useridfrom]" [linkProfile]="false" | ||||
|                                 aria-hidden="true"> | ||||
|                             </core-user-avatar> | ||||
|                             {{ members[message.useridfrom].fullname }} | ||||
|                             <div>{{ members[message.useridfrom].fullname }}</div> | ||||
|                         </div> | ||||
|                         <div *ngIf="!message.showUserData" class="sr-only"> | ||||
|                             {{ message.useridfrom == currentUserId | ||||
|  | ||||
| @ -8,7 +8,6 @@ | ||||
|             <h2>{{ user!.fullname }}</h2> | ||||
|             <ng-container *ngTemplateOutlet="submissionStatus"></ng-container> | ||||
|         </ion-label> | ||||
|         <ng-container *ngTemplateOutlet="submissionStatusBadges"></ng-container> | ||||
|     </ion-item> | ||||
| 
 | ||||
|     <!-- Status of the submission if user is blinded. --> | ||||
| @ -17,7 +16,6 @@ | ||||
|             <h2>{{ 'addon.mod_assign.hiddenuser' | translate }} {{blindId}}</h2> | ||||
|             <ng-container *ngTemplateOutlet="submissionStatus"></ng-container> | ||||
|         </ion-label> | ||||
|         <ng-container *ngTemplateOutlet="submissionStatusBadges"></ng-container> | ||||
|     </ion-item> | ||||
| 
 | ||||
|     <!-- Status of the submission in the rest of cases. --> | ||||
| @ -26,7 +24,6 @@ | ||||
|             <h2>{{ 'addon.mod_assign.submissionstatus' | translate }}</h2> | ||||
|             <ng-container *ngTemplateOutlet="submissionStatus"></ng-container> | ||||
|         </ion-label> | ||||
|         <ng-container *ngTemplateOutlet="submissionStatusBadges"></ng-container> | ||||
|     </ion-item> | ||||
| 
 | ||||
|     <!-- Tabs: see the submission or grade it. --> | ||||
| @ -385,12 +382,12 @@ | ||||
|             {{ 'addon.mod_assign.defaultteam' | translate }} | ||||
|         </p> | ||||
|     </ng-container> | ||||
| </ng-template> | ||||
| <ng-template #submissionStatusBadges> | ||||
|     <ion-badge slot="end" *ngIf="statusTranslated" [color]="statusColor"> | ||||
|     <p> | ||||
|         <ion-badge *ngIf="statusTranslated" [color]="statusColor"> | ||||
|             {{ statusTranslated }} | ||||
|         </ion-badge> | ||||
|     <ion-badge slot="end" *ngIf="gradingStatusTranslationId" [color]="gradingColor"> | ||||
|         <ion-badge class="ion-margin-start" *ngIf="gradingStatusTranslationId" [color]="gradingColor"> | ||||
|             {{ gradingStatusTranslationId | translate }} | ||||
|         </ion-badge> | ||||
|     </p> | ||||
| </ng-template> | ||||
|  | ||||
| @ -43,10 +43,10 @@ | ||||
|     </ion-card> | ||||
| 
 | ||||
|     <ng-container *ngIf="chat"> | ||||
|         <ion-button class="ion-margin" expand="block" color="primary" (click)="enterChat()"> | ||||
|         <ion-button class="ion-margin ion-text-wrap" expand="block" color="primary" (click)="enterChat()"> | ||||
|             {{ 'addon.mod_chat.enterchat' | translate }} | ||||
|         </ion-button> | ||||
|         <ion-button class="ion-margin" expand="block" color="light" *ngIf="sessionsAvailable" (click)="viewSessions()"> | ||||
|         <ion-button class="ion-margin ion-text-wrap" expand="block" color="light" *ngIf="sessionsAvailable" (click)="viewSessions()"> | ||||
|             {{ 'addon.mod_chat.viewreport' | translate }} | ||||
|         </ion-button> | ||||
|     </ng-container> | ||||
|  | ||||
| @ -10,11 +10,13 @@ | ||||
|         <core-context-menu-item *ngIf="blog" | ||||
|             [priority]="750" content="{{'addon.blog.blog' | translate}}" [iconAction]="'far-newspaper'" (action)="gotoBlog()"> | ||||
|         </core-context-menu-item> | ||||
|         <core-context-menu-item *ngIf="discussions.loaded && !(hasOffline || hasOfflineRatings) && isOnline" | ||||
|         <core-context-menu-item | ||||
|             *ngIf="discussions.onlineLoaded && discussions.loaded && !(hasOffline || hasOfflineRatings) && isOnline" | ||||
|             [priority]="700" [content]="'addon.mod_forum.refreshdiscussions' | translate" [iconAction]="refreshIcon" [closeOnClick]="false" | ||||
|             (action)="doRefresh(null, $event)"> | ||||
|         </core-context-menu-item> | ||||
|         <core-context-menu-item *ngIf="discussions.loaded && (hasOffline || hasOfflineRatings) && isOnline" | ||||
|         <core-context-menu-item | ||||
|             *ngIf="discussions.onlineLoaded && discussions.loaded && (hasOffline || hasOfflineRatings) && isOnline" | ||||
|             [priority]="600" [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false" | ||||
|             (action)="doRefresh(null, $event, true)"> | ||||
|         </core-context-menu-item> | ||||
| @ -37,11 +39,11 @@ | ||||
| 
 | ||||
| <!-- Content. --> | ||||
| <core-split-view> | ||||
|     <ion-refresher slot="fixed" [disabled]="!discussions.loaded" (ionRefresh)="doRefresh($event.target)"> | ||||
|     <ion-refresher slot="fixed" [disabled]="!discussions.onlineLoaded || !discussions.loaded" (ionRefresh)="doRefresh($event.target)"> | ||||
|         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||
|     </ion-refresher> | ||||
| 
 | ||||
|     <core-loading [hideUntil]="discussions.loaded"> | ||||
|     <core-loading [hideUntil]="discussions.onlineLoaded && discussions.loaded"> | ||||
|         <!-- Activity info. --> | ||||
|         <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" | ||||
|             (completionChanged)="onCompletionChange()"> | ||||
|  | ||||
| @ -49,7 +49,7 @@ | ||||
|         [autoFocus]="true" [lengthCheck]="2" (onClear)="toggleSearch()" searchArea="AddonModGlossary-{{module.id}}"> | ||||
|     </core-search-box> | ||||
| 
 | ||||
|     <core-loading [hideUntil]="entries.loaded"> | ||||
|     <core-loading [hideUntil]="loaded"> | ||||
|         <!-- Activity info. --> | ||||
|         <core-course-module-info *ngIf="showCompletion" [module]="module" [showManualCompletion]="true" | ||||
|             (completionChanged)="onCompletionChange()"> | ||||
|  | ||||
| @ -47,12 +47,8 @@ export class AddonModGlossaryEditLinkHandlerService extends CoreContentLinksHand | ||||
|                     const module = await CoreCourse.getModuleBasicInfo(cmId, siteId); | ||||
| 
 | ||||
|                     await CoreNavigator.navigateToSitePath( | ||||
|                         AddonModGlossaryModuleHandlerService.PAGE_NAME + '/edit/0', | ||||
|                         AddonModGlossaryModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/edit/0`, | ||||
|                         { | ||||
|                             params: { | ||||
|                                 cmId: module.id, | ||||
|                                 courseId: module.course, | ||||
|                             }, | ||||
|                             siteId, | ||||
|                         }, | ||||
|                     ); | ||||
|  | ||||
| @ -52,12 +52,8 @@ export class AddonModGlossaryEntryLinkHandlerService extends CoreContentLinksHan | ||||
|                     ); | ||||
| 
 | ||||
|                     await CoreNavigator.navigateToSitePath( | ||||
|                         AddonModGlossaryModuleHandlerService.PAGE_NAME + `/entry/${entryId}`, | ||||
|                         AddonModGlossaryModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/entry/${entryId}`, | ||||
|                         { | ||||
|                             params: { | ||||
|                                 cmId: module.id, | ||||
|                                 courseId: module.course, | ||||
|                             }, | ||||
|                             siteId, | ||||
|                         }, | ||||
|                     ); | ||||
|  | ||||
| @ -144,15 +144,36 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft | ||||
| 
 | ||||
|         this.tabBarHeight = this.tabBarElement.offsetHeight; | ||||
| 
 | ||||
|         if (this.tabsShown) { | ||||
|             // Smooth translation.
 | ||||
|             this.tabBarElement.style.top = - this.lastScroll + 'px'; | ||||
|             this.tabBarElement.style.height = 'calc(100% + ' + scroll + 'px'; | ||||
|         } else { | ||||
|             this.tabBarElement.classList.add('tabs-hidden'); | ||||
|             this.tabBarElement.style.top = '0'; | ||||
|             this.tabBarElement.style.height = ''; | ||||
|         this.applyScroll(this.tabsShown, this.lastScroll); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Apply scroll to hiding tabs. | ||||
|      * | ||||
|      * @param showTabs Show or completely hide tabs. | ||||
|      * @param scroll Scroll position. | ||||
|      */ | ||||
|     protected applyScroll(showTabs: boolean, scroll?: number): void { | ||||
|         if (!this.tabBarElement || !this.tabBarHeight) { | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (showTabs) { | ||||
|             // Smooth translation.
 | ||||
|             this.tabBarElement!.classList.remove('tabs-hidden'); | ||||
|             if (scroll === 0) { | ||||
|                 this.tabBarElement!.style.height = ''; | ||||
|                 this.lastScroll = 0; | ||||
|             } else if (scroll !== undefined) { | ||||
|                 this.tabBarElement!.style.height = (this.tabBarHeight - scroll) + 'px'; | ||||
|             } | ||||
|         } else { | ||||
|             this.tabBarElement!.classList.add('tabs-hidden'); | ||||
|             this.tabBarElement!.style.height = ''; | ||||
|         } | ||||
| 
 | ||||
|         this.tabsShown = showTabs; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -478,11 +499,7 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft | ||||
| 
 | ||||
|         if (scrollTop <= 0) { | ||||
|             // Ensure tabbar is shown.
 | ||||
|             this.tabsElement.style.top = '0'; | ||||
|             this.tabsElement.style.height = ''; | ||||
|             this.tabBarElement.classList.remove('tabs-hidden'); | ||||
|             this.tabsShown = true; | ||||
|             this.lastScroll = 0; | ||||
|             this.applyScroll(true, 0); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| @ -493,22 +510,17 @@ export class CoreTabsBaseComponent<T extends CoreTabBase> implements OnInit, Aft | ||||
|         } | ||||
| 
 | ||||
|         if (this.tabsShown && scrollTop > this.tabBarHeight) { | ||||
|             this.tabsShown = false; | ||||
| 
 | ||||
|             // Hide tabs.
 | ||||
|             this.tabBarElement.classList.add('tabs-hidden'); | ||||
|             this.tabsElement.style.top = '0'; | ||||
|             this.tabsElement.style.height = ''; | ||||
|             this.applyScroll(false); | ||||
|         } else if (!this.tabsShown && scrollTop <= this.tabBarHeight) { | ||||
|             this.tabsShown = true; | ||||
|             this.tabBarElement.classList.remove('tabs-hidden'); | ||||
|             this.applyScroll(true); | ||||
|         } | ||||
| 
 | ||||
|         if (this.tabsShown && scrollElement.scrollHeight > scrollElement.clientHeight + (this.tabBarHeight - scrollTop)) { | ||||
|             // Smooth translation.
 | ||||
|             this.tabsElement.style.top = - scrollTop + 'px'; | ||||
|             this.tabsElement.style.height = 'calc(100% + ' + scrollTop + 'px'; | ||||
|             this.applyScroll(true, scrollTop); | ||||
|         } | ||||
| 
 | ||||
|         // Use lastScroll after moving the tabs to avoid flickering.
 | ||||
|         this.lastScroll = scrollTop; | ||||
|     } | ||||
|  | ||||
| @ -13,7 +13,6 @@ | ||||
|         --color: var(--core-combobox-color); | ||||
|         --color-activated: var(--core-combobox-color); | ||||
|         --border-color: var(--core-combobox-border-color); | ||||
|         --border-width: 0 0 var(--core-combobox-border-width) 0; | ||||
|         --border-style: solid; | ||||
|         --color-focused: currentcolor; | ||||
|         --color-hover: currentcolor; | ||||
| @ -53,9 +52,7 @@ ion-button { | ||||
| } | ||||
| 
 | ||||
| ion-select { | ||||
|     border-color: var(--border-color); | ||||
|     border-width: var(--border-width); | ||||
|     border-style: var(--border-style); | ||||
|     border-bottom: var(--core-combobox-border-width) var(--border-style) var(--border-color); | ||||
| 
 | ||||
|     &::part(icon) { | ||||
|         margin: var(--icon-margin); | ||||
| @ -84,6 +81,8 @@ ion-select { | ||||
| 
 | ||||
| ion-button { | ||||
|     --border-radius: 0; | ||||
|     --border-width: 0 0 var(--core-combobox-border-width) 0; | ||||
| 
 | ||||
|     flex: 1; | ||||
|     min-height: 45px; | ||||
| 
 | ||||
|  | ||||
| @ -2,21 +2,24 @@ | ||||
| 
 | ||||
| :host { | ||||
|     --loading-background: var(--ion-background-color); | ||||
|     --loading-background-inline: var(--ion-background-color-rgb); | ||||
|     --loading-spinner: var(--ion-color-primary); | ||||
|     --loading-text-color: var(--ion-text-color); | ||||
|     --loading-inline-margin: 0; | ||||
|     --loading-inline-min-height: 28px; | ||||
|     --internal-loading-inline-min-height: var(--loading-inline-min-height); | ||||
| 
 | ||||
|     position: static; | ||||
|     color: var(--loading-text-color); | ||||
|     @include core-transition(all, 200ms); | ||||
| 
 | ||||
|     &.margin { | ||||
|         --loading-inline-margin: 10px; | ||||
|         --internal-loading-inline-min-height: calc(var(--loading-inline-min-height) + var(--loading-inline-margin) + var(--loading-inline-margin)); | ||||
|     } | ||||
| 
 | ||||
|     &.core-loading-loaded { | ||||
|         --loading-inline-margin: 0; | ||||
|         --loading-inline-min-height: 0; | ||||
|         --internal-loading-inline-min-height: 0; | ||||
|     } | ||||
| 
 | ||||
|     ion-spinner { | ||||
| @ -27,17 +30,17 @@ | ||||
|     .core-loading-container { | ||||
|         position: absolute; | ||||
|         @include position(0, 0, 0, 0); | ||||
|         display: flex; | ||||
|         height: 100%; | ||||
|         width: 100%; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         flex-direction: column; | ||||
|         z-index: 3; | ||||
|         margin: 0; | ||||
|         padding: 0; | ||||
|         background-color: var(--loading-background); | ||||
|         @include core-transition(all, 200ms); | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|         flex-direction: column; | ||||
|     } | ||||
| 
 | ||||
|     .core-loading-message { | ||||
| @ -54,15 +57,14 @@ | ||||
| 
 | ||||
|     &.core-loading-loaded { | ||||
|         position: unset; | ||||
|         display: contents; | ||||
|     } | ||||
| 
 | ||||
|     &.core-loading-inline { | ||||
|         --loading-background: transparent; | ||||
|         --loading-background: rgba(var(--loading-background-inline), 0.5); | ||||
|         position: relative; | ||||
|         display: block; | ||||
|         min-height: var(--loading-inline-min-height); | ||||
|         margin-top: var(--loading-inline-margin); | ||||
|         margin-bottom: var(--loading-inline-margin); | ||||
|         min-height: var(--internal-loading-inline-min-height); | ||||
| 
 | ||||
|         .core-loading-message { | ||||
|             @include margin(0, 0, 0, 10px); | ||||
|  | ||||
| @ -22,6 +22,8 @@ | ||||
|         -webkit-filter: drop-shadow(0px 3px 3px rgba(var(--drop-shadow))); | ||||
|         filter: drop-shadow(0px 3px 3px rgba(var(--drop-shadow))); | ||||
|         border: 0; | ||||
|         display: flex; | ||||
|         align-items: flex-end; | ||||
| 
 | ||||
|         ion-row { | ||||
|             width: 100%; | ||||
|  | ||||
| @ -72,6 +72,7 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|     @Input() wsNotFiltered?: boolean | string; // If true it means the WS didn't filter the text for some reason.
 | ||||
|     @Input() captureLinks?: boolean; // Whether links should tried to be opened inside the app. Defaults to true.
 | ||||
|     @Input() openLinksInApp?: boolean; // Whether links should be opened in InAppBrowser.
 | ||||
|     @Input() hideIfEmpty = false; // If true, the tag will contain nothing if text is empty.
 | ||||
| 
 | ||||
|     /** | ||||
|      * Max height in pixels to render the content box. It should be 50 at least to make sense. | ||||
| @ -86,6 +87,8 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|     protected element: HTMLElement; | ||||
|     protected showMoreDisplayed = false; | ||||
|     protected loadingChangedListener?: CoreEventObserver; | ||||
|     protected emptyText = ''; | ||||
|     protected contentSpan: HTMLElement; | ||||
| 
 | ||||
|     constructor( | ||||
|         element: ElementRef, | ||||
| @ -93,9 +96,20 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|         protected viewContainerRef: ViewContainerRef, | ||||
|         protected sanitizer: DomSanitizer, | ||||
|     ) { | ||||
| 
 | ||||
|         this.element = element.nativeElement; | ||||
|         this.element.classList.add('opacity-hide'); // Hide contents until they're treated.
 | ||||
|         this.element.classList.add('core-format-text-loading'); // Hide contents until they're treated.
 | ||||
| 
 | ||||
|         const placeholder = document.createElement('span'); | ||||
|         placeholder.classList.add('core-format-text-loader'); | ||||
|         this.element.appendChild(placeholder); | ||||
| 
 | ||||
|         this.contentSpan = document.createElement('span'); | ||||
|         this.contentSpan.classList.add('core-format-text-content'); | ||||
|         this.element.appendChild(this.contentSpan); | ||||
| 
 | ||||
|         this.emptyText = this.hideIfEmpty ? '' : ' '; | ||||
|         this.contentSpan.innerHTML = this.emptyText; | ||||
| 
 | ||||
|         this.afterRender = new EventEmitter<void>(); | ||||
| 
 | ||||
|         this.element.addEventListener('click', this.elementClicked.bind(this)); | ||||
| @ -183,7 +197,7 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|      * Add magnifying glass icons to view adapted images at full size. | ||||
|      */ | ||||
|     addMagnifyingGlasses(): void { | ||||
|         const imgs = Array.from(this.element.querySelectorAll('.core-adapted-img-container > img')); | ||||
|         const imgs = Array.from(this.contentSpan.querySelectorAll('.core-adapted-img-container > img')); | ||||
|         if (!imgs.length) { | ||||
|             return; | ||||
|         } | ||||
| @ -339,7 +353,7 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|      */ | ||||
|     protected finishRender(): void { | ||||
|         // Show the element again.
 | ||||
|         this.element.classList.remove('opacity-hide'); | ||||
|         this.element.classList.remove('core-format-text-loading'); | ||||
|         // Emit the afterRender output.
 | ||||
|         this.afterRender.emit(); | ||||
|     } | ||||
| @ -349,7 +363,7 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|      */ | ||||
|     protected async formatAndRenderContents(): Promise<void> { | ||||
|         if (!this.text) { | ||||
|             this.element.innerHTML = ''; // Remove current contents.
 | ||||
|             this.contentSpan.innerHTML = this.emptyText; // Remove current contents.
 | ||||
|             this.finishRender(); | ||||
| 
 | ||||
|             return; | ||||
| @ -370,12 +384,12 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|         // Disable media adapt to correctly calculate the height.
 | ||||
|         this.element.classList.add('core-disable-media-adapt'); | ||||
| 
 | ||||
|         this.element.innerHTML = ''; // Remove current contents.
 | ||||
|         this.contentSpan.innerHTML = ''; // Remove current contents.
 | ||||
|         if (this.maxHeight && result.div.innerHTML != '' && | ||||
|                 (this.fullOnClick || (window.innerWidth < 576 || window.innerHeight < 576))) { // Don't collapse in big screens.
 | ||||
| 
 | ||||
|             // Move the children to the current element to be able to calculate the height.
 | ||||
|             CoreDomUtils.moveChildren(result.div, this.element); | ||||
|             CoreDomUtils.moveChildren(result.div, this.contentSpan); | ||||
| 
 | ||||
|             // Calculate the height now.
 | ||||
|             this.calculateHeight(); | ||||
| @ -396,7 +410,7 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|                     }); | ||||
|             } | ||||
|         } else { | ||||
|             CoreDomUtils.moveChildren(result.div, this.element); | ||||
|             CoreDomUtils.moveChildren(result.div, this.contentSpan); | ||||
| 
 | ||||
|             // Add magnifying glasses to images.
 | ||||
|             this.addMagnifyingGlasses(); | ||||
| @ -405,7 +419,7 @@ export class CoreFormatTextDirective implements OnChanges { | ||||
|         if (result.options.filter) { | ||||
|             // Let filters handle HTML. We do it here because we don't want them to block the render of the text.
 | ||||
|             CoreFilterDelegate.handleHtml( | ||||
|                 this.element, | ||||
|                 this.contentSpan, | ||||
|                 result.filters, | ||||
|                 this.viewContainerRef, | ||||
|                 result.options, | ||||
|  | ||||
| @ -66,7 +66,7 @@ describe('CoreFormatTextDirective', () => { | ||||
|         ); | ||||
| 
 | ||||
|         // Assert
 | ||||
|         const text = fixture.nativeElement.querySelector('core-format-text'); | ||||
|         const text = fixture.nativeElement.querySelector('core-format-text .core-format-text-content'); | ||||
|         expect(text).not.toBeNull(); | ||||
|         expect(text.innerHTML).toEqual(sentence); | ||||
|     }); | ||||
|  | ||||
| @ -142,7 +142,10 @@ | ||||
|         </ion-item-divider> | ||||
| 
 | ||||
|         <ion-item class="ion-text-wrap" *ngIf="section.summary"> | ||||
|             <core-format-text [text]="section.summary" contextLevel="course" [contextInstanceId]="course?.id"></core-format-text> | ||||
|             <ion-label> | ||||
|                 <core-format-text [text]="section.summary" contextLevel="course" [contextInstanceId]="course?.id"> | ||||
|                 </core-format-text> | ||||
|             </ion-label> | ||||
|         </ion-item> | ||||
| 
 | ||||
|         <ng-container *ngFor="let module of section.modules"> | ||||
|  | ||||
							
								
								
									
										1
									
								
								src/theme/bootstrap.scss
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/theme/bootstrap.scss
									
									
									
									
										vendored
									
									
								
							| @ -9,6 +9,7 @@ | ||||
|     clip: rect(0, 0, 0, 0); | ||||
|     white-space: nowrap; | ||||
|     border: 0; | ||||
|     display: block !important; | ||||
| } | ||||
| 
 | ||||
| .sr-only-focusable:active, .sr-only-focusable:focus { | ||||
|  | ||||
| @ -2,22 +2,70 @@ | ||||
| /** Styles of elements inside the directive should be placed in format-text.scss */ | ||||
| @import "~theme/globals"; | ||||
| 
 | ||||
| :root { | ||||
|     --background: var(--background, #{$ion-item-background}); | ||||
|     --background-gradient-rgb: var(--background-rgb, #{color-to-rgb-list($ion-item-background)}); | ||||
|     --viewer-icon-background: rgba(255, 255, 255, .5); | ||||
| core-format-text { | ||||
|     --core-format-text-background: var(--background, #{$ion-item-background}); | ||||
|     --core-format-text-background-gradient-rgb: var(--background-rgb, #{color-to-rgb-list($ion-item-background)}); | ||||
|     --core-format-text-viewer-icon-background: rgba(255, 255, 255, .5); | ||||
|     --core-format-text-loader-shine: 251,251,251; | ||||
| } | ||||
| 
 | ||||
| :root body.dark { | ||||
|     --background: var(--background, #{$ion-item-background-dark}); | ||||
|     --background-gradient-rgb: var(--background-rgb, #{color-to-rgb-list($ion-item-background-dark)}); | ||||
|     --viewer-icon-background: rgba(0, 0, 0, .5); | ||||
| body.dark core-format-text { | ||||
|     --core-format-text-background: var(--background, #{$ion-item-background-dark}); | ||||
|     --core-format-text-background-gradient-rgb: var(--background-rgb, #{color-to-rgb-list($ion-item-background-dark)}); | ||||
|     --core-format-text-viewer-icon-background: rgba(0, 0, 0, .5); | ||||
|     --core-format-text-loader-shine: 90,90,90; | ||||
| } | ||||
| 
 | ||||
| core-format-text { | ||||
|     display: contents; | ||||
| 
 | ||||
|     .core-format-text-loader { | ||||
|         opacity: 0; | ||||
|         @include core-transition(opacity, 200ms); | ||||
|         display: contents; | ||||
|     } | ||||
| 
 | ||||
|     &.core-format-text-loading { | ||||
|         position: relative; | ||||
|         width: 100%; | ||||
|         height: 100%; | ||||
|         opacity: 1; | ||||
|         background-color: rgba(0,0,0,.1); | ||||
|         overflow: hidden; | ||||
|         border-radius: 5px; | ||||
|         display: block; | ||||
| 
 | ||||
|         .core-format-text-loader { | ||||
|             position: absolute; | ||||
|             left: -45%; | ||||
|             height: 100%; | ||||
|             width: 45%; | ||||
|             background-image: -webkit-linear-gradient(to left, rgba(var(--core-format-text-loader-shine), .05), rgba(var(--core-format-text-loader-shine), .3), rgba(var(--core-format-text-loader-shine), .6), rgba(var(--core-format-text-loader-shine), .3), rgba(var(--core-format-text-loader-shine), .05)); | ||||
|             background-image: linear-gradient(to left, rgba(var(--core-format-text-loader-shine), .05), rgba(var(--core-format-text-loader-shine), .3), rgba(var(--core-format-text-loader-shine), .6), rgba(var(--core-format-text-loader-shine), .3), rgba(var(--core-format-text-loader-shine), .05)); | ||||
|             animation: loading 1s infinite; | ||||
|             opacity: 1; | ||||
|             display: inline; | ||||
|         } | ||||
| 
 | ||||
|         .core-format-text-content { | ||||
|             opacity: 0; | ||||
|             display: inline; | ||||
|         } | ||||
| 
 | ||||
|         .core-show-more { | ||||
|             display: none !important; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     .core-format-text-content { | ||||
|         opacity: 1; | ||||
|         @include core-transition(opacity, 200ms); | ||||
| 
 | ||||
|         display: contents; | ||||
|         user-select: text; | ||||
|         word-break: break-word; | ||||
|         word-wrap: break-word; | ||||
|     } | ||||
| 
 | ||||
|     &[maxHeight], | ||||
|     &[ng-reflect-max-height] { | ||||
| @ -57,7 +105,7 @@ core-format-text { | ||||
|                     position: absolute; | ||||
|                     @include position(null, 0, 0, null); | ||||
|                     z-index: 7; | ||||
|                     background-color: var(--background); | ||||
|                     background-color: var(--core-format-text-background); | ||||
|                     color: var(--text-color); | ||||
|                     @include padding(null, null, null, 10px); | ||||
|                     margin: 0; | ||||
| @ -68,10 +116,8 @@ core-format-text { | ||||
|                     height: 100%; | ||||
|                     position: absolute; | ||||
|                     @include position(null, 0, 0, 0); | ||||
|                     background: -moz-linear-gradient(top, rgba(var(--background-gradient-rgb), 0) calc(100% - 50px), rgba(var(--background-gradient-rgb), 1) calc(100% - 15px)); | ||||
|                     background: -webkit-gradient(left top, left bottom, color-stop(calc(100% - 50px), rgba(var(--background-gradient-rgb), 0)), color-stop(calc(100% - 15px), rgba(var(--background-gradient-rgb), 1))); | ||||
|                     background: -webkit-linear-gradient(top, rgba(var(--background-gradient-rgb), 0) calc(100% - 50px), rgba(var(--background-gradient-rgb), 1) calc(100% - 15px)); | ||||
|                     background: linear-gradient(to bottom, rgba(var(--background-gradient-rgb), 0) calc(100% - 50px), rgba(var(--background-gradient-rgb), 1) calc(100% - 15px)); | ||||
|                     background: -webkit-linear-gradient(top, rgba(var(--core-format-text-background-gradient-rgb), 0) calc(100% - 50px), rgba(var(--core-format-text-background-gradient-rgb), 1) calc(100% - 15px)); | ||||
|                     background: linear-gradient(to bottom, rgba(var(--core-format-text-background-gradient-rgb), 0) calc(100% - 50px), rgba(var(--core-format-text-background-gradient-rgb), 1) calc(100% - 15px)); | ||||
|                     z-index: 6; | ||||
|                 } | ||||
|             } | ||||
| @ -115,15 +161,15 @@ core-format-text { | ||||
|     .core-adapted-img-container { | ||||
|         position: relative; | ||||
|         display: inline-block; | ||||
|         width: 100%; | ||||
|         max-width: 100%; | ||||
|     } | ||||
| 
 | ||||
|     .core-image-viewer-icon { | ||||
|         position: absolute; | ||||
|         @include position(null, 10px, 10px, null); | ||||
|         color: var(--black); | ||||
|         color: var(--ion-text-color); | ||||
|         border-radius: 5px; | ||||
|         background-color: var(--viewer-icon-background); | ||||
|         background-color: var(--core-format-text-viewer-icon-background); | ||||
|         display: flex; | ||||
| 
 | ||||
|         width: var(--a11y-min-target-size); | ||||
| @ -141,3 +187,13 @@ core-format-text { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @keyframes loading { | ||||
|     0% { | ||||
|         left: -45%; | ||||
|     } | ||||
|     100% { | ||||
|         left: 100%; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -685,7 +685,7 @@ audio.core-media-adapt-width { | ||||
| } | ||||
| 
 | ||||
| // Make links clickable when inside radio or checkbox items. Style part. | ||||
| @media (any-hover: hover) { | ||||
| @media (hover: hover) { | ||||
|     ion-item.item-multiple-inputs:hover::part(native) { | ||||
|         color: var(--color-hover); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user