commit
686f35d544
|
@ -3,6 +3,9 @@
|
||||||
:host {
|
:host {
|
||||||
.core-horizontal-scroll div.core-horizontal-scroll-item {
|
.core-horizontal-scroll div.core-horizontal-scroll-item {
|
||||||
@include horizontal_scroll_item(80%, 250px, 300px);
|
@include horizontal_scroll_item(80%, 250px, 300px);
|
||||||
|
ion-card {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-course-module-handler {
|
.core-course-module-handler {
|
||||||
|
|
|
@ -190,7 +190,7 @@ export class AddonFilterMathJaxLoaderHandlerService extends CoreFilterDefaultHan
|
||||||
protected insertSpan(text: string, start: number, end: number): string {
|
protected insertSpan(text: string, start: number, end: number): string {
|
||||||
return CoreTextUtils.substrReplace(
|
return CoreTextUtils.substrReplace(
|
||||||
text,
|
text,
|
||||||
'<span class="nolink">' + text.substr(start, end - start + 1) + '</span>',
|
'<span class="nolink">' + text.substring(start, end - start + 1) + '</span>',
|
||||||
start,
|
start,
|
||||||
end - start + 1,
|
end - start + 1,
|
||||||
);
|
);
|
||||||
|
@ -265,7 +265,7 @@ export class AddonFilterMathJaxLoaderHandlerService extends CoreFilterDefaultHan
|
||||||
*/
|
*/
|
||||||
protected fixUseUrls(node: Element): void {
|
protected fixUseUrls(node: Element): void {
|
||||||
Array.from(node.querySelectorAll('use')).forEach((useElem) => {
|
Array.from(node.querySelectorAll('use')).forEach((useElem) => {
|
||||||
useElem.setAttribute('href', useElem.href.baseVal.substr(useElem.href.baseVal.indexOf('#')));
|
useElem.setAttribute('href', useElem.href.baseVal.substring(useElem.href.baseVal.indexOf('#')));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,11 @@
|
||||||
[attr.aria-label]="(favourites.expanded ? 'core.collapse' : 'core.expand') | translate"
|
[attr.aria-label]="(favourites.expanded ? 'core.collapse' : 'core.expand') | translate"
|
||||||
[attr.aria-expanded]="favourites.expanded" aria-controls="addon-messages-groupconversations-favourite" role="heading"
|
[attr.aria-expanded]="favourites.expanded" aria-controls="addon-messages-groupconversations-favourite" role="heading"
|
||||||
detail="false">
|
detail="false">
|
||||||
<ion-icon *ngIf="!favourites.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true">
|
<ion-icon *ngIf="!favourites.expanded" name="fas-chevron-right" flip-rtl slot="start" aria-hidden="true"
|
||||||
|
class="expandable-status-icon">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon *ngIf="favourites.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon *ngIf="favourites.expanded" name="fas-chevron-down" slot="start" aria-hidden="true"
|
||||||
|
class="expandable-status-icon"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'core.favourites' | translate }} ({{ favourites.count }})</h2>
|
<h2>{{ 'core.favourites' | translate }} ({{ favourites.count }})</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
@ -74,8 +76,10 @@
|
||||||
<ion-item button class="divider ion-text-wrap" (click)="toggle(group)" sticky="true"
|
<ion-item button class="divider ion-text-wrap" (click)="toggle(group)" sticky="true"
|
||||||
[attr.aria-label]="(group.expanded ? 'core.collapse' : 'core.expand') | translate" [attr.aria-expanded]="group.expanded"
|
[attr.aria-label]="(group.expanded ? 'core.collapse' : 'core.expand') | translate" [attr.aria-expanded]="group.expanded"
|
||||||
aria-controls="addon-messages-groupconversations-group" role="heading" detail="false">
|
aria-controls="addon-messages-groupconversations-group" role="heading" detail="false">
|
||||||
<ion-icon *ngIf="!group.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon *ngIf="!group.expanded" name="fas-chevron-right" flip-rtl slot="start" aria-hidden="true"
|
||||||
<ion-icon *ngIf="group.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
|
class="expandable-status-icon"></ion-icon>
|
||||||
|
<ion-icon *ngIf="group.expanded" name="fas-chevron-down" slot="start" aria-hidden="true" class="expandable-status-icon">
|
||||||
|
</ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'addon.messages.groupconversations' | translate }} ({{ group.count }})</h2>
|
<h2>{{ 'addon.messages.groupconversations' | translate }} ({{ group.count }})</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
@ -107,9 +111,11 @@
|
||||||
[attr.aria-label]="(individual.expanded ? 'core.collapse' : 'core.expand') | translate"
|
[attr.aria-label]="(individual.expanded ? 'core.collapse' : 'core.expand') | translate"
|
||||||
[attr.aria-expanded]="individual.expanded" aria-controls="addon-messages-groupconversations-individual" role="heading"
|
[attr.aria-expanded]="individual.expanded" aria-controls="addon-messages-groupconversations-individual" role="heading"
|
||||||
detail="false">
|
detail="false">
|
||||||
<ion-icon *ngIf="!individual.expanded" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true">
|
<ion-icon *ngIf="!individual.expanded" name="fas-chevron-right" flip-rtl slot="start" aria-hidden="true"
|
||||||
|
class="expandable-status-icon">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon *ngIf="individual.expanded" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon *ngIf="individual.expanded" name="fas-chevron-down" slot="start" aria-hidden="true"
|
||||||
|
class="expandable-status-icon"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'addon.messages.individualconversations' | translate }} ({{ individual.count }})</h2>
|
<h2>{{ 'addon.messages.individualconversations' | translate }} ({{ individual.count }})</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline">
|
[courseId]="courseId" [hasDataToSync]="hasOffline">
|
||||||
<ion-list inset="true" description *ngIf="assign && assign.introattachments && assign.introattachments.length">
|
<ion-list inset="true" description *ngIf="assign && assign.introattachments && assign.introattachments.length">
|
||||||
<core-file *ngFor="let file of assign.introattachments" [file]="file" [component]="component" [componentId]="componentId">
|
<core-file *ngFor="let file of assign.introattachments" [file]="file" [component]="component" [componentId]="componentId">
|
||||||
</core-file>
|
</core-file>
|
||||||
|
@ -148,4 +148,5 @@
|
||||||
</addon-mod-assign-submission>
|
</addon-mod-assign-submission>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id"></core-course-module-navigation>
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -23,8 +23,8 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
<core-loading [hideUntil]="loaded" class="safe-area-page">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId">
|
[courseId]="courseId">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ng-container *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)">
|
<ng-container *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)">
|
||||||
|
@ -126,5 +126,5 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId">
|
[courseId]="courseId">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ion-card class="core-warning-card" *ngIf="warning">
|
<ion-card class="core-warning-card" *ngIf="warning">
|
||||||
|
@ -56,5 +56,5 @@
|
||||||
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId">
|
[courseId]="courseId">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ion-card *ngIf="chatInfo" class="core-info-card">
|
<ion-card *ngIf="chatInfo" class="core-info-card">
|
||||||
|
@ -48,5 +48,5 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -53,14 +53,14 @@ export class AddonModChatHelperProvider {
|
||||||
formattedMessage.message = formattedMessage.message.trim();
|
formattedMessage.message = formattedMessage.message.trim();
|
||||||
|
|
||||||
formattedMessage.showDate = this.showDate(message, prevMessage);
|
formattedMessage.showDate = this.showDate(message, prevMessage);
|
||||||
formattedMessage.beep = (message.message.substr(0, 5) == 'beep ' && message.message.substr(5).trim()) || undefined;
|
formattedMessage.beep = (message.message.substring(0, 5) == 'beep ' && message.message.substring(5).trim()) || undefined;
|
||||||
|
|
||||||
formattedMessage.special = !!formattedMessage.beep || (<AddonModChatSessionMessage> message).issystem ||
|
formattedMessage.special = !!formattedMessage.beep || (<AddonModChatSessionMessage> message).issystem ||
|
||||||
(<AddonModChatMessage> message).system;
|
(<AddonModChatMessage> message).system;
|
||||||
|
|
||||||
if (formattedMessage.message.substr(0, 4) == '/me ') {
|
if (formattedMessage.message.substring(0, 4) == '/me ') {
|
||||||
formattedMessage.special = true;
|
formattedMessage.special = true;
|
||||||
formattedMessage.message = formattedMessage.message.substr(4).trim();
|
formattedMessage.message = formattedMessage.message.substring(4).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!formattedMessage.special && formattedMessage.message.match(patternTo)) {
|
if (!formattedMessage.special && formattedMessage.message.match(patternTo)) {
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline">
|
[courseId]="courseId" [hasDataToSync]="hasOffline">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<!-- Activity availability messages -->
|
<!-- Activity availability messages -->
|
||||||
|
@ -155,7 +155,7 @@
|
||||||
</ion-card>
|
</ion-card>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
||||||
<!-- Template to render a choice option label. -->
|
<!-- Template to render a choice option label. -->
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings">
|
[courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ion-item class="ion-text-wrap" *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)">
|
<ion-item class="ion-text-wrap" *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)">
|
||||||
|
@ -138,7 +138,7 @@
|
||||||
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
||||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canAdd">
|
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canAdd">
|
||||||
|
|
|
@ -52,7 +52,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
|
||||||
const enabledName = 'f_' + field.id + '_z';
|
const enabledName = 'f_' + field.id + '_z';
|
||||||
|
|
||||||
if (inputData[enabledName] && typeof inputData[fieldName] == 'string') {
|
if (inputData[enabledName] && typeof inputData[fieldName] == 'string') {
|
||||||
const date = inputData[fieldName].substr(0, 10).split('-');
|
const date = inputData[fieldName].substring(0, 10).split('-');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const date = inputData[fieldName].substr(0, 10).split('-');
|
const date = inputData[fieldName].substring(0, 10).split('-');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -117,10 +117,10 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
|
||||||
originalFieldData: AddonModDataEntryField,
|
originalFieldData: AddonModDataEntryField,
|
||||||
): boolean {
|
): boolean {
|
||||||
const fieldName = 'f_' + field.id;
|
const fieldName = 'f_' + field.id;
|
||||||
const input = inputData[fieldName] && inputData[fieldName].substr(0, 10) || '';
|
const input = inputData[fieldName] && inputData[fieldName].substring(0, 10) || '';
|
||||||
|
|
||||||
const content = (originalFieldData && originalFieldData?.content &&
|
const content = (originalFieldData && originalFieldData?.content &&
|
||||||
CoreTimeUtils.toDatetimeFormat(parseInt(originalFieldData.content, 10) * 1000).substr(0, 10)) || '';
|
CoreTimeUtils.toDatetimeFormat(parseInt(originalFieldData.content, 10) * 1000).substring(0, 10)) || '';
|
||||||
|
|
||||||
return input != content;
|
return input != content;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline">
|
[courseId]="courseId" [hasDataToSync]="hasOffline">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<core-tabs [hideUntil]="tabsReady" [selectedIndex]="firstSelectedTab">
|
<core-tabs [hideUntil]="tabsReady" [selectedIndex]="firstSelectedTab">
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
</core-tabs>
|
</core-tabs>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
||||||
<ng-template #basicInfo>
|
<ng-template #basicInfo>
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="!subfolder" [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info *ngIf="!subfolder" [module]="module" [description]="description" [component]="component"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId">
|
[componentId]="componentId" [courseId]="courseId">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ion-list *ngIf="contents && (contents.files.length + contents.folders.length > 0)">
|
<ion-list *ngIf="contents && (contents.files.length + contents.folders.length > 0)">
|
||||||
|
@ -49,5 +49,5 @@
|
||||||
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -53,10 +53,10 @@ export class AddonModFolderHelperProvider {
|
||||||
let completePath = '';
|
let completePath = '';
|
||||||
|
|
||||||
// Remove first and last slash if needed.
|
// Remove first and last slash if needed.
|
||||||
if (path.substr(0, 1) === '/') {
|
if (path.substring(0, 1) === '/') {
|
||||||
path = path.substr(1);
|
path = path.substring(1);
|
||||||
}
|
}
|
||||||
if (path.substr(path.length - 1) === '/') {
|
if (path.substring(path.length - 1) === '/') {
|
||||||
path = path.slice(0, -1);
|
path = path.slice(0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,10 +38,9 @@
|
||||||
|
|
||||||
<core-loading [hideUntil]="discussions && discussions.loaded">
|
<core-loading [hideUntil]="discussions && discussions.loaded">
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()"
|
<core-course-module-info [module]="module" [description]="forum && forum.type != 'single' && description" [component]="component"
|
||||||
[description]="forum && forum.type != 'single' && description" [component]="component" [componentId]="componentId"
|
[componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings">
|
||||||
[courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings">
|
<ion-item lines="none" class="ion-text-wrap">
|
||||||
<ion-item>
|
|
||||||
<ion-label>
|
<ion-label>
|
||||||
{{descriptionNote}}
|
{{descriptionNote}}
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
@ -140,7 +139,8 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module"
|
||||||
|
(completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
||||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="forum && canAddDiscussion">
|
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="forum && canAddDiscussion">
|
||||||
|
|
|
@ -118,8 +118,10 @@
|
||||||
<ion-item button class="divider ion-text-wrap" (click)="toggleAdvanced()" detail="false" [attr.aria-expanded]="advanced"
|
<ion-item button class="divider ion-text-wrap" (click)="toggleAdvanced()" detail="false" [attr.aria-expanded]="advanced"
|
||||||
[attr.aria-controls]="'addon-forum-reply-edit-form-advanced-' + uniqueId"
|
[attr.aria-controls]="'addon-forum-reply-edit-form-advanced-' + uniqueId"
|
||||||
[attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate">
|
[attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate">
|
||||||
<ion-icon *ngIf="!advanced" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon *ngIf="!advanced" name="fas-chevron-right" flip-rtl slot="start" aria-hidden="true"
|
||||||
<ion-icon *ngIf="advanced" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
|
class="expandable-status-icon"></ion-icon>
|
||||||
|
<ion-icon *ngIf="advanced" name="fas-chevron-down" slot="start" aria-hidden="true" class="expandable-status-icon">
|
||||||
|
</ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'addon.mod_forum.advanced' | translate }}</h2>
|
<h2>{{ 'addon.mod_forum.advanced' | translate }}</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
|
|
@ -34,8 +34,10 @@
|
||||||
<ion-item button class="divider ion-text-wrap" (click)="toggleAdvanced()" detail="false" [attr.aria-expanded]="advanced"
|
<ion-item button class="divider ion-text-wrap" (click)="toggleAdvanced()" detail="false" [attr.aria-expanded]="advanced"
|
||||||
[attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate" role="heading"
|
[attr.aria-label]="(advanced ? 'core.hideadvanced' : 'core.showadvanced') | translate" role="heading"
|
||||||
aria-controls="addon-mod-forum-new-discussion-advanced">
|
aria-controls="addon-mod-forum-new-discussion-advanced">
|
||||||
<ion-icon *ngIf="!advanced" name="fas-caret-right" flip-rtl slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon *ngIf="!advanced" name="fas-chevron-right" flip-rtl slot="start" aria-hidden="true"
|
||||||
<ion-icon *ngIf="advanced" name="fas-caret-down" slot="start" aria-hidden="true"></ion-icon>
|
class="expandable-status-icon"></ion-icon>
|
||||||
|
<ion-icon *ngIf="advanced" name="fas-chevron-down" slot="start" aria-hidden="true" class="expandable-status-icon">
|
||||||
|
</ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ 'addon.mod_forum.advanced' | translate }}</h2>
|
<h2>{{ 'addon.mod_forum.advanced' | translate }}</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
|
|
@ -50,8 +50,8 @@
|
||||||
|
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info *ngIf="!isSearch" [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info *ngIf="!isSearch" [module]="module" [description]="description" [component]="component"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings">
|
[componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline || hasOfflineRatings">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ion-list *ngIf="!isSearch && entries && entries.offlineEntries.length > 0">
|
<ion-list *ngIf="!isSearch && entries && entries.offlineEntries.length > 0">
|
||||||
|
@ -96,7 +96,8 @@
|
||||||
</core-infinite-loading>
|
</core-infinite-loading>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module"
|
||||||
|
(completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
||||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canAdd">
|
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canAdd">
|
||||||
|
|
|
@ -292,7 +292,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
|
||||||
// Try to get the first letter without HTML tags.
|
// Try to get the first letter without HTML tags.
|
||||||
const noTags = CoreTextUtils.cleanTags(entry.concept);
|
const noTags = CoreTextUtils.cleanTags(entry.concept);
|
||||||
|
|
||||||
return (noTags || entry.concept).substr(0, 1).toUpperCase();
|
return (noTags || entry.concept).substring(0, 1).toUpperCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getDivider = getDivider;
|
this.getDivider = getDivider;
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline">
|
[courseId]="courseId" [hasDataToSync]="hasOffline">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<!-- Offline disabled. -->
|
<!-- Offline disabled. -->
|
||||||
|
@ -85,5 +85,5 @@
|
||||||
</core-h5p-iframe>
|
</core-h5p-iframe>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()">
|
<core-course-module-info [module]="module">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ion-card class="core-warning-card" *ngIf="warning">
|
<ion-card class="core-warning-card" *ngIf="warning">
|
||||||
|
@ -46,5 +46,5 @@
|
||||||
</div>
|
</div>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -155,7 +155,7 @@ export class AddonModImscpProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
const filePath = CoreTextUtils.concatenatePaths(item.filepath, item.filename);
|
const filePath = CoreTextUtils.concatenatePaths(item.filepath, item.filename);
|
||||||
const filePathAlt = filePath.charAt(0) === '/' ? filePath.substr(1) : '/' + filePath;
|
const filePathAlt = filePath.charAt(0) === '/' ? filePath.substring(1) : '/' + filePath;
|
||||||
|
|
||||||
// Check if it's main file.
|
// Check if it's main file.
|
||||||
return filePath === targetFilePath || filePathAlt === targetFilePath;
|
return filePath === targetFilePath || filePathAlt === targetFilePath;
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
<ng-template>
|
<ng-template>
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline">
|
[courseId]="courseId" [hasDataToSync]="hasOffline">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<!-- Prevent access messages. Only show the first one. -->
|
<!-- Prevent access messages. Only show the first one. -->
|
||||||
|
@ -298,5 +298,5 @@
|
||||||
</core-tabs>
|
</core-tabs>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -760,8 +760,8 @@ export class AddonModLessonProvider {
|
||||||
let ignoreCase = '';
|
let ignoreCase = '';
|
||||||
|
|
||||||
if (useRegExp) {
|
if (useRegExp) {
|
||||||
if (expectedAnswer.substr(-2) == '/i') {
|
if (expectedAnswer.substring(-2) == '/i') {
|
||||||
expectedAnswer = expectedAnswer.substr(0, expectedAnswer.length - 2);
|
expectedAnswer = expectedAnswer.substring(0, expectedAnswer.length - 2);
|
||||||
ignoreCase = 'i';
|
ignoreCase = 'i';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -792,12 +792,12 @@ export class AddonModLessonProvider {
|
||||||
isMatch = true;
|
isMatch = true;
|
||||||
}
|
}
|
||||||
} else { // We are using regular expressions analysis.
|
} else { // We are using regular expressions analysis.
|
||||||
const startCode = expectedAnswer.substr(0, 2);
|
const startCode = expectedAnswer.substring(0, 2);
|
||||||
|
|
||||||
switch (startCode){
|
switch (startCode){
|
||||||
// 1- Check for absence of required string in studentAnswer (coded by initial '--').
|
// 1- Check for absence of required string in studentAnswer (coded by initial '--').
|
||||||
case '--':
|
case '--':
|
||||||
expectedAnswer = expectedAnswer.substr(2);
|
expectedAnswer = expectedAnswer.substring(2);
|
||||||
if (!studentAnswer.match(new RegExp('^' + expectedAnswer + '$', ignoreCase))) {
|
if (!studentAnswer.match(new RegExp('^' + expectedAnswer + '$', ignoreCase))) {
|
||||||
isMatch = true;
|
isMatch = true;
|
||||||
}
|
}
|
||||||
|
@ -805,7 +805,7 @@ export class AddonModLessonProvider {
|
||||||
|
|
||||||
// 2- Check for code for marking wrong strings (coded by initial '++').
|
// 2- Check for code for marking wrong strings (coded by initial '++').
|
||||||
case '++': {
|
case '++': {
|
||||||
expectedAnswer = expectedAnswer.substr(2);
|
expectedAnswer = expectedAnswer.substring(2);
|
||||||
|
|
||||||
// Check for one or several matches.
|
// Check for one or several matches.
|
||||||
const matches = studentAnswer.match(new RegExp(expectedAnswer, 'g' + ignoreCase));
|
const matches = studentAnswer.match(new RegExp(expectedAnswer, 'g' + ignoreCase));
|
||||||
|
|
|
@ -20,9 +20,8 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()"
|
<core-course-module-info [module]="module" [description]="lti && lti.showdescriptionlaunch && description" [component]="component"
|
||||||
[description]="lti && lti.showdescriptionlaunch && description" [component]="component" [componentId]="componentId"
|
[componentId]="componentId" [courseId]="courseId">
|
||||||
[courseId]="courseId">
|
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<div class="ion-padding">
|
<div class="ion-padding">
|
||||||
|
@ -33,5 +32,5 @@
|
||||||
</div>
|
</div>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="displayDescription && description"
|
<core-course-module-info [module]="module" [description]="displayDescription && description" [component]="component"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId">
|
[componentId]="componentId" [courseId]="courseId">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ion-card class="core-warning-card" *ngIf="warning">
|
<ion-card class="core-warning-card" *ngIf="warning">
|
||||||
|
@ -49,5 +49,5 @@
|
||||||
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -52,7 +52,7 @@ export class AddonModPageHelperProvider {
|
||||||
let key = content.filename;
|
let key = content.filename;
|
||||||
if (content.filepath !== '/') {
|
if (content.filepath !== '/') {
|
||||||
// Add the folders without the leading slash.
|
// Add the folders without the leading slash.
|
||||||
key = content.filepath.substr(1) + key;
|
key = content.filepath.substring(1) + key;
|
||||||
}
|
}
|
||||||
paths[CoreTextUtils.decodeURIComponent(key)] = url;
|
paths[CoreTextUtils.decodeURIComponent(key)] = url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId"
|
[courseId]="courseId" [hasDataToSync]="buttonText && hasOffline && !showStatusSpinner">
|
||||||
[hasDataToSync]="buttonText && hasOffline && !showStatusSpinner">
|
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<!-- Access rules description messages. -->
|
<!-- Access rules description messages. -->
|
||||||
|
@ -227,5 +226,5 @@
|
||||||
</ion-card>
|
</ion-card>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class AddonModQuizOfflineProvider {
|
||||||
if (!questionsWithAnswers[slot]) {
|
if (!questionsWithAnswers[slot]) {
|
||||||
questionsWithAnswers[slot] = {
|
questionsWithAnswers[slot] = {
|
||||||
answers: {},
|
answers: {},
|
||||||
prefix: name.substr(0, name.indexOf(nameWithoutPrefix)),
|
prefix: name.substring(0, name.indexOf(nameWithoutPrefix)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
questionsWithAnswers[slot].answers[nameWithoutPrefix] = answers[name];
|
questionsWithAnswers[slot].answers[nameWithoutPrefix] = answers[name];
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" [courseId]="courseId" (completionChanged)="onCompletionChange()"
|
<core-course-module-info [module]="module" [courseId]="courseId"
|
||||||
[description]="mode != 'iframe' && (mode != 'embedded' || displayDescription) && description" [component]="component"
|
[description]="mode != 'iframe' && (mode != 'embedded' || displayDescription) && description" [component]="component"
|
||||||
[componentId]="componentId">
|
[componentId]="componentId">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
@ -61,5 +61,5 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -70,7 +70,7 @@ export class AddonModResourceHelperProvider {
|
||||||
let mainFilePath = mainFile.filename;
|
let mainFilePath = mainFile.filename;
|
||||||
|
|
||||||
if (mainFile.filepath !== '/') {
|
if (mainFile.filepath !== '/') {
|
||||||
mainFilePath = mainFile.filepath.substr(1) + mainFilePath;
|
mainFilePath = mainFile.filepath.substring(1) + mainFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -201,7 +201,7 @@ export class AddonModScormDataModel12 {
|
||||||
|
|
||||||
for (const element in this.currentUserData[this.scoId].userdata) {
|
for (const element in this.currentUserData[this.scoId].userdata) {
|
||||||
// Ommit for example the nav. elements and the session time element.
|
// Ommit for example the nav. elements and the session time element.
|
||||||
if (element.substr(0, 3) != 'cmi' || element == 'cmi.core.session_time') {
|
if (element.substring(0, 3) != 'cmi' || element == 'cmi.core.session_time') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,16 +748,16 @@ export class AddonModScormDataModel12 {
|
||||||
const childrenStr = '._children';
|
const childrenStr = '._children';
|
||||||
const countStr = '._count';
|
const countStr = '._count';
|
||||||
|
|
||||||
if (elementModel.substr(elementModel.length - childrenStr.length, elementModel.length) == childrenStr) {
|
if (elementModel.substring(elementModel.length - childrenStr.length, elementModel.length) == childrenStr) {
|
||||||
const parentModel = elementModel.substr(0, elementModel.length - childrenStr.length);
|
const parentModel = elementModel.substring(0, elementModel.length - childrenStr.length);
|
||||||
|
|
||||||
if (this.dataModel[this.scoId][parentModel] !== undefined) {
|
if (this.dataModel[this.scoId][parentModel] !== undefined) {
|
||||||
this.errorCode = '202';
|
this.errorCode = '202';
|
||||||
} else {
|
} else {
|
||||||
this.errorCode = '201';
|
this.errorCode = '201';
|
||||||
}
|
}
|
||||||
} else if (elementModel.substr(elementModel.length - countStr.length, elementModel.length) == countStr) {
|
} else if (elementModel.substring(elementModel.length - countStr.length, elementModel.length) == countStr) {
|
||||||
const parentModel = elementModel.substr(0, elementModel.length - countStr.length);
|
const parentModel = elementModel.substring(0, elementModel.length - countStr.length);
|
||||||
|
|
||||||
if (this.dataModel[this.scoId][parentModel] !== undefined) {
|
if (this.dataModel[this.scoId][parentModel] !== undefined) {
|
||||||
this.errorCode = '203';
|
this.errorCode = '203';
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="!errorMessage && hasOffline">
|
[courseId]="courseId" [hasDataToSync]="!errorMessage && hasOffline">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<!-- Warning message. -->
|
<!-- Warning message. -->
|
||||||
|
@ -237,5 +237,5 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -947,7 +947,7 @@ export class AddonModScormProvider {
|
||||||
if (parameters) {
|
if (parameters) {
|
||||||
const connector = launchUrl.indexOf('?') > -1 ? '&' : '?';
|
const connector = launchUrl.indexOf('?') > -1 ? '&' : '?';
|
||||||
if (parameters.charAt(0) == '?') {
|
if (parameters.charAt(0) == '?') {
|
||||||
parameters = parameters.substr(1);
|
parameters = parameters.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
launchUrl += connector + parameters;
|
launchUrl += connector + parameters;
|
||||||
|
@ -1315,7 +1315,7 @@ export class AddonModScormProvider {
|
||||||
|
|
||||||
if (link.match(/^https?:\/\//i) && !CoreUrlUtils.isLocalFileUrl(link)) {
|
if (link.match(/^https?:\/\//i) && !CoreUrlUtils.isLocalFileUrl(link)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (link.substr(0, 4) == 'www.') {
|
} else if (link.substring(0, 4) == 'www.') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,8 @@
|
||||||
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
<core-loading [hideUntil]="loaded" class="safe-area-padding">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()"
|
<core-course-module-info [module]="module" [description]="survey && !survey.surveydone && !hasOffline && description"
|
||||||
[description]="survey && !survey.surveydone && !hasOffline && description" [component]="component" [componentId]="componentId"
|
[component]="component" [componentId]="componentId" [courseId]="courseId" [hasDataToSync]="hasOffline">
|
||||||
[courseId]="courseId" [hasDataToSync]="hasOffline">
|
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<!-- Survey already done -->
|
<!-- Survey already done -->
|
||||||
|
@ -148,5 +147,5 @@
|
||||||
|
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="displayDescription && description"
|
<core-course-module-info [module]="module" [description]="displayDescription && description" [component]="component"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId">
|
[componentId]="componentId" [courseId]="courseId">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<div *ngIf="shouldIframe || (shouldEmbed && isOther)" class="addon-mod_url-embedded-url">
|
<div *ngIf="shouldIframe || (shouldEmbed && isOther)" class="addon-mod_url-embedded-url">
|
||||||
|
@ -53,5 +53,5 @@
|
||||||
</ion-list>
|
</ion-list>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -68,7 +68,7 @@ export class AddonModUrlProvider {
|
||||||
const download = ['application/zip', 'application/x-tar', 'application/g-zip', 'application/pdf', 'text/html'];
|
const download = ['application/zip', 'application/x-tar', 'application/g-zip', 'application/pdf', 'text/html'];
|
||||||
let mimetype = CoreMimetypeUtils.getMimeType(extension);
|
let mimetype = CoreMimetypeUtils.getMimeType(extension);
|
||||||
|
|
||||||
if (url.externalurl.indexOf('.php') != -1 || url.externalurl.substr(-1) === '/' ||
|
if (url.externalurl.indexOf('.php') != -1 || url.externalurl.substring(-1) === '/' ||
|
||||||
(url.externalurl.indexOf('//') != -1 && url.externalurl.match(/\//g)?.length == 2)) {
|
(url.externalurl.indexOf('//') != -1 && url.externalurl.match(/\//g)?.length == 2)) {
|
||||||
// Seems to be a web, use HTML mimetype.
|
// Seems to be a web, use HTML mimetype.
|
||||||
mimetype = 'text/html';
|
mimetype = 'text/html';
|
||||||
|
@ -158,7 +158,7 @@ export class AddonModUrlProvider {
|
||||||
const matches = url.match(/\//g);
|
const matches = url.match(/\//g);
|
||||||
const extension = CoreMimetypeUtils.getFileExtension(url);
|
const extension = CoreMimetypeUtils.getFileExtension(url);
|
||||||
|
|
||||||
if (!matches || matches.length < 3 || url.substr(-1) === '/' || extension == 'php') {
|
if (!matches || matches.length < 3 || url.substring(-1) === '/' || extension == 'php') {
|
||||||
// Use default icon.
|
// Use default icon.
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,8 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [description]="description"
|
<core-course-module-info [module]="module" [description]="description" [component]="component" [componentId]="componentId"
|
||||||
[component]="component" [componentId]="componentId" [courseId]="courseId">
|
[courseId]="courseId">
|
||||||
<h2 *ngIf="pageTitle" title>{{pageTitle}}</h2>
|
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<div *ngIf="pageIsOffline || hasOffline || pageWarning">
|
<div *ngIf="pageIsOffline || hasOffline || pageWarning">
|
||||||
|
@ -74,6 +73,7 @@
|
||||||
</ion-card>
|
</ion-card>
|
||||||
</div>
|
</div>
|
||||||
<div class="ion-padding addon-mod_wiki-page-content">
|
<div class="ion-padding addon-mod_wiki-page-content">
|
||||||
|
<h2 *ngIf="pageTitle">{{pageTitle}}</h2>
|
||||||
<article [ngClass]="{'addon-mod_wiki-noedit': !canEdit}">
|
<article [ngClass]="{'addon-mod_wiki-noedit': !canEdit}">
|
||||||
<core-format-text *ngIf="pageContent" [component]="component" [componentId]="componentId" [text]="pageContent"
|
<core-format-text *ngIf="pageContent" [component]="component" [componentId]="componentId" [text]="pageContent"
|
||||||
contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
|
contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
</div>
|
</div>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
||||||
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canEdit">
|
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="canEdit">
|
||||||
|
|
|
@ -427,7 +427,6 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
|
||||||
const pageContents = await this.fetchPageContents(this.currentPage);
|
const pageContents = await this.fetchPageContents(this.currentPage);
|
||||||
|
|
||||||
if (pageContents) {
|
if (pageContents) {
|
||||||
this.dataRetrieved.emit(pageContents.title);
|
|
||||||
this.setSelectedWiki(pageContents.subwikiid, pageContents.userid, pageContents.groupid);
|
this.setSelectedWiki(pageContents.subwikiid, pageContents.userid, pageContents.groupid);
|
||||||
|
|
||||||
this.pageTitle = pageContents.title;
|
this.pageTitle = pageContents.title;
|
||||||
|
|
|
@ -8,10 +8,6 @@
|
||||||
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
|
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
</h1>
|
</h1>
|
||||||
<h2>
|
|
||||||
<core-format-text [text]="pageTitle" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
|
|
||||||
</core-format-text>
|
|
||||||
</h2>
|
|
||||||
</ion-title>
|
</ion-title>
|
||||||
|
|
||||||
<ion-buttons slot="end">
|
<ion-buttons slot="end">
|
||||||
|
|
|
@ -49,18 +49,6 @@ export class AddonModWikiIndexPage extends CoreCourseModuleMainActivityPage<Addo
|
||||||
this.groupId = CoreNavigator.getRouteNumberParam('groupId');
|
this.groupId = CoreNavigator.getRouteNumberParam('groupId');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritdoc
|
|
||||||
*/
|
|
||||||
updateData(data: { name: string } | string): void {
|
|
||||||
if (typeof data == 'string') {
|
|
||||||
// We received the title to display.
|
|
||||||
this.pageTitle = data;
|
|
||||||
} else {
|
|
||||||
super.updateData(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User entered the page.
|
* User entered the page.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
|
|
||||||
<!-- Activity info. -->
|
<!-- Activity info. -->
|
||||||
<core-course-module-info [module]="module" (completionChanged)="onCompletionChange()" [hasDataToSync]="hasOffline">
|
<core-course-module-info [module]="module" [hasDataToSync]="hasOffline">
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
|
|
||||||
<ion-card *ngIf="phases">
|
<ion-card *ngIf="phases">
|
||||||
|
@ -254,5 +254,5 @@
|
||||||
</div>
|
</div>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id">
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module" (completionChanged)="onCompletionChange()">
|
||||||
</core-course-module-navigation>
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -226,7 +226,7 @@ export class AddonQtypeCalculatedHandlerService implements CoreQuestionHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
const numberString = match[0];
|
const numberString = match[0];
|
||||||
const unit = unitsLeft ? answer.substr(0, answer.length - match[0].length) : answer.substr(match[0].length);
|
const unit = unitsLeft ? answer.substring(0, answer.length - match[0].length) : answer.substring(match[0].length);
|
||||||
|
|
||||||
// No need to calculate the multiplier.
|
// No need to calculate the multiplier.
|
||||||
return { answer: Number(numberString), unit };
|
return { answer: Number(numberString), unit };
|
||||||
|
|
|
@ -58,7 +58,7 @@ export class CoreInterceptor implements HttpInterceptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return query.length ? query.substr(0, query.length - 1) : query;
|
return query.length ? query.substring(0, query.length - 1) : query;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
|
|
@ -600,7 +600,7 @@ export class SQLiteDB {
|
||||||
sql = equal ? '= ?' : '<> ?';
|
sql = equal ? '= ?' : '<> ?';
|
||||||
params = Array.isArray(items) ? items : [items];
|
params = Array.isArray(items) ? items : [items];
|
||||||
} else {
|
} else {
|
||||||
sql = (equal ? '' : 'NOT ') + 'IN (' + ',?'.repeat(items.length).substr(1) + ')';
|
sql = (equal ? '' : 'NOT ') + 'IN (' + ',?'.repeat(items.length).substring(1) + ')';
|
||||||
params = items;
|
params = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,7 +801,7 @@ export class SQLiteDB {
|
||||||
|
|
||||||
const keys = Object.keys(data);
|
const keys = Object.keys(data);
|
||||||
const fields = keys.join(',');
|
const fields = keys.join(',');
|
||||||
const questionMarks = ',?'.repeat(keys.length).substr(1);
|
const questionMarks = ',?'.repeat(keys.length).substring(1);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sql: `INSERT OR REPLACE INTO ${table} (${fields}) VALUES (${questionMarks})`,
|
sql: `INSERT OR REPLACE INTO ${table} (${fields}) VALUES (${questionMarks})`,
|
||||||
|
@ -1139,7 +1139,7 @@ export class SQLiteDB {
|
||||||
if (params.length == 1) {
|
if (params.length == 1) {
|
||||||
sql = sql + field + ' = ?';
|
sql = sql + field + ' = ?';
|
||||||
} else {
|
} else {
|
||||||
const questionMarks = ',?'.repeat(params.length).substr(1);
|
const questionMarks = ',?'.repeat(params.length).substring(1);
|
||||||
sql = sql + field + ' IN (' + questionMarks + ')';
|
sql = sql + field + ' IN (' + questionMarks + ')';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,9 @@
|
||||||
<ion-button
|
<ion-button fill="clear" color="dark" (click)="scroll('backward')" [hidden]="scrollPosition === 'hidden'"
|
||||||
fill="clear"
|
[disabled]="scrollPosition === 'start'" [attr.aria-label]="'core.scrollbackward' | translate" [attr.aria-controls]="targetId">
|
||||||
color="dark"
|
<ion-icon name="fas-chevron-left" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
(click)="scroll('backward')"
|
|
||||||
[hidden]="scrollPosition === 'hidden'"
|
|
||||||
[disabled]="scrollPosition === 'start'"
|
|
||||||
[attr.aria-label]="'core.scrollbackward' | translate"
|
|
||||||
[attr.aria-controls]="targetId"
|
|
||||||
>
|
|
||||||
<ion-icon name="fas-caret-left" slot="icon-only" aria-hidden="true"></ion-icon>
|
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
|
||||||
<ion-button
|
<ion-button fill="clear" color="dark" (click)="scroll('forward')" [hidden]="scrollPosition === 'hidden'"
|
||||||
fill="clear"
|
[disabled]="scrollPosition === 'end'" [attr.aria-label]="'core.scrollforward' | translate" [attr.aria-controls]="targetId">
|
||||||
color="dark"
|
<ion-icon name="fas-chevron-right" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
(click)="scroll('forward')"
|
|
||||||
[hidden]="scrollPosition === 'hidden'"
|
|
||||||
[disabled]="scrollPosition === 'end'"
|
|
||||||
[attr.aria-label]="'core.scrollforward' | translate"
|
|
||||||
[attr.aria-controls]="targetId"
|
|
||||||
>
|
|
||||||
<ion-icon name="fas-caret-right" slot="icon-only" aria-hidden="true"></ion-icon>
|
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
|
|
@ -52,16 +52,16 @@ export class CoreFaIconDirective implements AfterViewInit, OnChanges {
|
||||||
switch (parts[0]) {
|
switch (parts[0]) {
|
||||||
case 'far':
|
case 'far':
|
||||||
library = 'regular';
|
library = 'regular';
|
||||||
iconName = iconName.substr(4);
|
iconName = iconName.substring(4);
|
||||||
break;
|
break;
|
||||||
case 'fa':
|
case 'fa':
|
||||||
case 'fas':
|
case 'fas':
|
||||||
library = 'solid';
|
library = 'solid';
|
||||||
iconName = iconName.substr(parts[0].length + 1);
|
iconName = iconName.substring(parts[0].length + 1);
|
||||||
break;
|
break;
|
||||||
case 'fab':
|
case 'fab':
|
||||||
library = 'brands';
|
library = 'brands';
|
||||||
iconName = iconName.substr(4);
|
iconName = iconName.substring(4);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -140,7 +140,7 @@ export class CoreLinkDirective implements OnInit {
|
||||||
|
|
||||||
if (href.charAt(0) == '#') {
|
if (href.charAt(0) == '#') {
|
||||||
// Look for id or name.
|
// Look for id or name.
|
||||||
href = href.substr(1);
|
href = href.substring(1);
|
||||||
CoreDomUtils.scrollToElementBySelector(
|
CoreDomUtils.scrollToElementBySelector(
|
||||||
this.element.closest('ion-content'),
|
this.element.closest('ion-content'),
|
||||||
this.content,
|
this.content,
|
||||||
|
@ -170,7 +170,7 @@ export class CoreLinkDirective implements OnInit {
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async openLocalFile(path: string): Promise<void> {
|
protected async openLocalFile(path: string): Promise<void> {
|
||||||
const filename = path.substr(path.lastIndexOf('/') + 1);
|
const filename = path.substring(path.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
if (!CoreFileHelper.isOpenableInApp({ filename })) {
|
if (!CoreFileHelper.isOpenableInApp({ filename })) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -95,7 +95,7 @@ export class CoreContentLinksHandlerBase implements CoreContentLinksHandler {
|
||||||
if (this.pattern) {
|
if (this.pattern) {
|
||||||
const position = url.search(this.pattern);
|
const position = url.search(this.pattern);
|
||||||
if (position > -1) {
|
if (position > -1) {
|
||||||
return url.substr(0, position);
|
return url.substring(0, position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<core-mod-icon slot="start" [modicon]="modicon" [modname]="module.modname" [componentId]="module.instance">
|
<core-mod-icon slot="start" [modicon]="modicon" [modname]="module.modname" [componentId]="module.instance">
|
||||||
</core-mod-icon>
|
</core-mod-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
|
<p class="core-modulename" *ngIf="moduleNameTranslated">{{moduleNameTranslated}}</p>
|
||||||
<h1>
|
<h1>
|
||||||
<core-format-text [text]="module.name" contextLevel="module" [component]="component" [componentId]="componentId"
|
<core-format-text [text]="module.name" contextLevel="module" [component]="component" [componentId]="componentId"
|
||||||
[contextInstanceId]="module.id" [courseId]="courseId">
|
[contextInstanceId]="module.id" [courseId]="courseId">
|
||||||
|
@ -18,21 +19,12 @@
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ng-content select="[description]"></ng-content>
|
<ng-content select="[description]"></ng-content>
|
||||||
<ion-item class="ion-text-wrap" lines="none" *ngIf="showCompletion && (module.dates?.length ||
|
<!-- Activity dates. -->
|
||||||
(module.completiondata && (module.completiondata.isautomatic || showManualCompletion) && module.uservisible))">
|
<ion-item class="ion-text-wrap core-module-dates" lines="none" *ngIf="showCompletion && module.dates?.length">
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<!-- Activity dates. -->
|
|
||||||
<div *ngIf="module.dates?.length" class="core-module-dates">
|
|
||||||
<p *ngFor="let date of module.dates">
|
<p *ngFor="let date of module.dates">
|
||||||
<strong>{{ date.label }}</strong> {{ date.timestamp * 1000 | coreFormatDate:'strftimedatetime' }}
|
<strong>{{ date.label }}</strong> {{ date.timestamp * 1000 | coreFormatDate:'strftimedatetime' }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Module completion. -->
|
|
||||||
<core-course-module-completion *ngIf="module.completiondata && module.uservisible" [completion]="module.completiondata"
|
|
||||||
[moduleName]="module.name" [moduleId]="module.id" [showCompletionConditions]="true"
|
|
||||||
[showManualCompletion]="showManualCompletion" (completionChanged)="completionChanged.emit($event)">
|
|
||||||
</core-course-module-completion>
|
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
|
|
|
@ -8,4 +8,12 @@
|
||||||
background-color: var(--contrast-background);
|
background-color: var(--contrast-background);
|
||||||
|
|
||||||
@include padding-horizontal(var(--ion-safe-area-left), var(--ion-safe-area-right));
|
@include padding-horizontal(var(--ion-safe-area-left), var(--ion-safe-area-right));
|
||||||
|
|
||||||
|
.core-modulename {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
core-mod-icon {
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { CoreCourse } from '@features/course/services/course';
|
import { CoreCourse } from '@features/course/services/course';
|
||||||
import { CoreCourseModuleData, CoreCourseModuleCompletionData } from '@features/course/services/course-helper';
|
import { CoreCourseModuleData } from '@features/course/services/course-helper';
|
||||||
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ import { CoreSites } from '@services/sites';
|
||||||
export class CoreCourseModuleInfoComponent implements OnInit {
|
export class CoreCourseModuleInfoComponent implements OnInit {
|
||||||
|
|
||||||
@Input() module!: CoreCourseModuleData; // The module to render.
|
@Input() module!: CoreCourseModuleData; // The module to render.
|
||||||
@Input() showManualCompletion = true; // Whether to show manual completion, true by default.
|
|
||||||
@Input() courseId!: number; // The courseId the module belongs to.
|
@Input() courseId!: number; // The courseId the module belongs to.
|
||||||
|
|
||||||
@Input() component!: string; // Component for format text directive.
|
@Input() component!: string; // Component for format text directive.
|
||||||
|
@ -47,8 +46,6 @@ export class CoreCourseModuleInfoComponent implements OnInit {
|
||||||
|
|
||||||
@Input() hasDataToSync = false; // If the activity has any data to be synced.
|
@Input() hasDataToSync = false; // If the activity has any data to be synced.
|
||||||
|
|
||||||
@Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when completion changes.
|
|
||||||
|
|
||||||
modicon = '';
|
modicon = '';
|
||||||
showCompletion = false; // Whether to show completion.
|
showCompletion = false; // Whether to show completion.
|
||||||
moduleNameTranslated = '';
|
moduleNameTranslated = '';
|
||||||
|
@ -60,7 +57,6 @@ export class CoreCourseModuleInfoComponent implements OnInit {
|
||||||
this.modicon = await CoreCourseModuleDelegate.getModuleIconSrc(this.module.modname, this.module.modicon, this.module);
|
this.modicon = await CoreCourseModuleDelegate.getModuleIconSrc(this.module.modname, this.module.modicon, this.module);
|
||||||
|
|
||||||
this.moduleNameTranslated = CoreCourse.translateModuleName(this.module.modname || '');
|
this.moduleNameTranslated = CoreCourse.translateModuleName(this.module.modname || '');
|
||||||
|
|
||||||
this.showCompletion = CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11');
|
this.showCompletion = CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,14 @@
|
||||||
<ion-icon name="fas-arrow-left" slot="icon-only" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-arrow-left" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
|
<ion-col *ngIf="showCompletion && (currentModule.completiondata &&
|
||||||
|
(currentModule.completiondata.isautomatic || showManualCompletion) && currentModule.uservisible)">
|
||||||
|
<!-- Module completion. -->
|
||||||
|
<core-course-module-completion [completion]="currentModule.completiondata" [moduleName]="currentModule.name"
|
||||||
|
[moduleId]="currentModule.id" [showCompletionConditions]="true" [showManualCompletion]="showManualCompletion"
|
||||||
|
(completionChanged)="completionChanged.emit($event)">
|
||||||
|
</core-course-module-completion>
|
||||||
|
</ion-col>
|
||||||
<ion-col size="auto">
|
<ion-col size="auto">
|
||||||
<ion-button fill="clear" class="core-course-next-module" *ngIf="nextModule" (click)="goToActivity(true)"
|
<ion-button fill="clear" class="core-course-next-module" *ngIf="nextModule" (click)="goToActivity(true)"
|
||||||
[attr.aria-label]="'core.course.gotonextactivity' | translate">
|
[attr.aria-label]="'core.course.gotonextactivity' | translate">
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, ElementRef, Input, OnDestroy, OnInit } from '@angular/core';
|
import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||||
import { CoreCourse, CoreCourseProvider, CoreCourseWSSection } from '@features/course/services/course';
|
import { CoreCourse, CoreCourseProvider, CoreCourseWSSection } from '@features/course/services/course';
|
||||||
import { CoreCourseModuleData } from '@features/course/services/course-helper';
|
import { CoreCourseModuleCompletionData, CoreCourseModuleData } from '@features/course/services/course-helper';
|
||||||
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
|
||||||
import { IonContent } from '@ionic/angular';
|
import { IonContent } from '@ionic/angular';
|
||||||
import { ScrollDetail } from '@ionic/core';
|
import { ScrollDetail } from '@ionic/core';
|
||||||
|
@ -29,7 +29,7 @@ import { CoreMath } from '@singletons/math';
|
||||||
* Component to show a button to go to the next resource/activity.
|
* Component to show a button to go to the next resource/activity.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
* <core-course-module-navigation [courseId]="courseId" [currentModuleId]="module.id"></core-course-module-navigation>
|
* <core-course-module-navigation [courseId]="courseId" [currentModule]="module"></core-course-module-navigation>
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'core-course-module-navigation',
|
selector: 'core-course-module-navigation',
|
||||||
|
@ -39,13 +39,17 @@ import { CoreMath } from '@singletons/math';
|
||||||
export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
|
export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input() courseId!: number; // Course ID.
|
@Input() courseId!: number; // Course ID.
|
||||||
@Input() currentModuleId!: number; // Current module ID.
|
@Input() currentModule!: CoreCourseModuleData; // Current module.
|
||||||
|
@Input() showManualCompletion = true; // Whether to show manual completion, true by default.
|
||||||
|
|
||||||
|
@Output() completionChanged = new EventEmitter<CoreCourseModuleCompletionData>(); // Notify when completion changes.
|
||||||
|
|
||||||
nextModule?: CoreCourseModuleData;
|
nextModule?: CoreCourseModuleData;
|
||||||
previousModule?: CoreCourseModuleData;
|
previousModule?: CoreCourseModuleData;
|
||||||
nextModuleSection?: CoreCourseWSSection;
|
nextModuleSection?: CoreCourseWSSection;
|
||||||
previousModuleSection?: CoreCourseWSSection;
|
previousModuleSection?: CoreCourseWSSection;
|
||||||
loaded = false;
|
loaded = false;
|
||||||
|
showCompletion = false; // Whether to show completion.
|
||||||
|
|
||||||
protected element: HTMLElement;
|
protected element: HTMLElement;
|
||||||
protected initialHeight = 0;
|
protected initialHeight = 0;
|
||||||
|
@ -78,6 +82,8 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
|
this.showCompletion = CoreSites.getRequiredCurrentSite().isVersionGreaterEqualThan('3.11');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.setNextAndPreviousModules(CoreSitesReadingStrategy.PREFER_CACHE);
|
await this.setNextAndPreviousModules(CoreSitesReadingStrategy.PREFER_CACHE);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -172,6 +178,7 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
const preSets = CoreSites.getReadingStrategyPreSets(readingStrategy);
|
const preSets = CoreSites.getReadingStrategyPreSets(readingStrategy);
|
||||||
|
const currentModuleId = this.currentModule.id;
|
||||||
|
|
||||||
const sections = await CoreCourse.getSections(this.courseId, false, true, preSets);
|
const sections = await CoreCourse.getSections(this.courseId, false, true, preSets);
|
||||||
|
|
||||||
|
@ -184,7 +191,7 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentModuleIndex = section.modules.findIndex((module: CoreCourseModuleData) => module.id == this.currentModuleId);
|
currentModuleIndex = section.modules.findIndex((module: CoreCourseModuleData) => module.id == currentModuleId);
|
||||||
|
|
||||||
return currentModuleIndex >= 0;
|
return currentModuleIndex >= 0;
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<core-course-module-info [module]="module" [courseId]="courseId" [description]="module.description" [component]="module.modname"
|
<core-course-module-info [module]="module" [courseId]="courseId" [description]="module.description" [component]="module.modname"
|
||||||
[componentId]="module.id" (completionChanged)="onCompletionChange()" [expandDescription]="true"
|
[componentId]="module.id" [expandDescription]="true">
|
||||||
[showManualCompletion]="showManualCompletion">
|
|
||||||
|
|
||||||
<div class="safe-area-padding-horizontal ion-padding" *ngIf="module.handlerData?.extraBadge">
|
<div class="safe-area-padding-horizontal ion-padding" *ngIf="module.handlerData?.extraBadge">
|
||||||
<ion-badge class="ion-text-wrap ion-text-start" [color]="module.handlerData?.extraBadgeColor">
|
<ion-badge class="ion-text-wrap ion-text-start" [color]="module.handlerData?.extraBadgeColor">
|
||||||
|
@ -61,5 +60,6 @@
|
||||||
</core-course-module-info>
|
</core-course-module-info>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
|
|
||||||
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModuleId]="module.id"></core-course-module-navigation>
|
<core-course-module-navigation [hidden]="!loaded" [courseId]="courseId" [currentModule]="module"
|
||||||
|
(completionChanged)="onCompletionChange()" [showManualCompletion]="showManualCompletion"></core-course-module-navigation>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
:host ::ng-deep ion-item-divider {
|
:host ::ng-deep ion-item-divider {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
:host ::ng-deep core-loading {
|
||||||
|
--internal-loading-inline-min-height: calc(100vh - var(--core-header-toolbar-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(ion-tabs.placement-bottom) ::ng-deep core-loading {
|
||||||
|
--internal-loading-inline-min-height: calc(100vh - var(--core-header-toolbar-height) - var(--bottom-tabs-size) - 2px);
|
||||||
|
}
|
||||||
|
|
|
@ -198,7 +198,7 @@ export class FileTransferObjectMock extends FileTransferObject {
|
||||||
const headerString = headers[i];
|
const headerString = headers[i];
|
||||||
const separatorPos = headerString.indexOf(':');
|
const separatorPos = headerString.indexOf(':');
|
||||||
if (separatorPos != -1) {
|
if (separatorPos != -1) {
|
||||||
result[headerString.substr(0, separatorPos)] = headerString.substr(separatorPos + 1).trim();
|
result[headerString.substring(0, separatorPos)] = headerString.substring(separatorPos + 1).trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -444,7 +444,7 @@ export class FileMock extends File {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
path: fullPath.substring(0, fullPath.lastIndexOf('/')),
|
path: fullPath.substring(0, fullPath.lastIndexOf('/')),
|
||||||
name: fullPath.substr(fullPath.lastIndexOf('/') + 1),
|
name: fullPath.substring(fullPath.lastIndexOf('/') + 1),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ export class ZipMock extends Zip {
|
||||||
destination = destination.replace(/%20/g, ' ');
|
destination = destination.replace(/%20/g, ' ');
|
||||||
|
|
||||||
const sourceDir = source.substring(0, source.lastIndexOf('/'));
|
const sourceDir = source.substring(0, source.lastIndexOf('/'));
|
||||||
const sourceName = source.substr(source.lastIndexOf('/') + 1);
|
const sourceName = source.substring(source.lastIndexOf('/') + 1);
|
||||||
const zip = new JSZip();
|
const zip = new JSZip();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -82,7 +82,7 @@ export class ZipMock extends Zip {
|
||||||
|
|
||||||
// First of all, create the directory where the files will be unzipped.
|
// First of all, create the directory where the files will be unzipped.
|
||||||
const destParent = destination.substring(0, destination.lastIndexOf('/'));
|
const destParent = destination.substring(0, destination.lastIndexOf('/'));
|
||||||
const destFolderName = destination.substr(destination.lastIndexOf('/') + 1);
|
const destFolderName = destination.substring(destination.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
await this.file.createDir(destParent, destFolderName, true);
|
await this.file.createDir(destParent, destFolderName, true);
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ export class ZipMock extends Zip {
|
||||||
if (!file.dir) {
|
if (!file.dir) {
|
||||||
// It's a file.
|
// It's a file.
|
||||||
const fileDir = name.substring(0, name.lastIndexOf('/'));
|
const fileDir = name.substring(0, name.lastIndexOf('/'));
|
||||||
const fileName = name.substr(name.lastIndexOf('/') + 1);
|
const fileName = name.substring(name.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
if (fileDir) {
|
if (fileDir) {
|
||||||
// The file is in a subfolder, create it first.
|
// The file is in a subfolder, create it first.
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
</td>
|
</td>
|
||||||
<th class="core-grades-table-gradeitem ion-text-start" [attr.colspan]="row.colspan">
|
<th class="core-grades-table-gradeitem ion-text-start" [attr.colspan]="row.colspan">
|
||||||
<ion-icon *ngIf="row.expandable && showSummary" aria-hidden="true" slot="start"
|
<ion-icon *ngIf="row.expandable && showSummary" aria-hidden="true" slot="start"
|
||||||
[name]="row.expanded ? 'fas-caret-down' : 'fas-caret-right'">
|
[name]="row.expanded ? 'fas-chevron-down' : 'fas-chevron-right'" class="expandable-status-icon">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
<ion-icon *ngIf="row.icon" name="{{row.icon}}" slot="start" [attr.aria-label]="row.iconAlt">
|
<ion-icon *ngIf="row.icon" name="{{row.icon}}" slot="start" [attr.aria-label]="row.iconAlt">
|
||||||
</ion-icon>
|
</ion-icon>
|
||||||
|
|
|
@ -100,6 +100,11 @@
|
||||||
@include margin(null, null, null, 5px);
|
@include margin(null, null, null, 5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expandable-status-icon {
|
||||||
|
font-size: 14px;
|
||||||
|
@include margin-horizontal(0, 2px);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.core-grades-table-feedback {
|
.core-grades-table-feedback {
|
||||||
|
|
|
@ -154,7 +154,7 @@ export class CoreGradesHelperProvider {
|
||||||
for (const name in item) {
|
for (const name in item) {
|
||||||
const index = name.indexOf('formatted');
|
const index = name.indexOf('formatted');
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
item[name.substr(0, index)] = item[name];
|
item[name.substring(0, index)] = item[name];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ export class CoreGradesHelperProvider {
|
||||||
(row) =>
|
(row) =>
|
||||||
row.itemname &&
|
row.itemname &&
|
||||||
row.itemname.id &&
|
row.itemname.id &&
|
||||||
row.itemname.id.substr(0, 3) == 'row' &&
|
row.itemname.id.substring(0, 3) == 'row' &&
|
||||||
parseInt(row.itemname.id.split('_')[1], 10) == gradeId,
|
parseInt(row.itemname.id.split('_')[1], 10) == gradeId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ export class CoreH5PContentValidator {
|
||||||
|
|
||||||
// Check if string is within allowed length.
|
// Check if string is within allowed length.
|
||||||
if (semantics.maxLength !== undefined) {
|
if (semantics.maxLength !== undefined) {
|
||||||
text = text.substr(0, semantics.maxLength);
|
text = text.substring(0, semantics.maxLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
|
@ -357,8 +357,8 @@ export class CoreH5PContentValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove temporary files suffix.
|
// Remove temporary files suffix.
|
||||||
if (file.path.substr(-4, 4) === '#tmp') {
|
if (file.path.substring(-4, 4) === '#tmp') {
|
||||||
file.path = file.path.substr(0, file.path.length - 4);
|
file.path = file.path.substring(0, file.path.length - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure path and mime does not have any special chars
|
// Make sure path and mime does not have any special chars
|
||||||
|
@ -670,7 +670,7 @@ export class CoreH5PContentValidator {
|
||||||
|
|
||||||
const tag = tags[0];
|
const tag = tags[0];
|
||||||
|
|
||||||
if (tag.substr(0, 1) != '<') {
|
if (tag.substring(0, 1) != '<') {
|
||||||
// We matched a lone ">" character.
|
// We matched a lone ">" character.
|
||||||
return '>';
|
return '>';
|
||||||
} else if (tag.length == 1) {
|
} else if (tag.length == 1) {
|
||||||
|
@ -746,7 +746,7 @@ export class CoreH5PContentValidator {
|
||||||
matches = attr.match(/^([-a-zA-Z]+)/);
|
matches = attr.match(/^([-a-zA-Z]+)/);
|
||||||
if (matches && matches.length > 1) {
|
if (matches && matches.length > 1) {
|
||||||
attrName = matches[1].toLowerCase();
|
attrName = matches[1].toLowerCase();
|
||||||
skip = attrName == 'style' || attrName.substr(0, 2) == 'on' || attrName.substr(0, 1) == '-' ||
|
skip = attrName == 'style' || attrName.substring(0, 2) == 'on' || attrName.substring(0, 1) == '-' ||
|
||||||
attrName.length > 96; // Ignore long attributes to avoid unnecessary processing overhead.
|
attrName.length > 96; // Ignore long attributes to avoid unnecessary processing overhead.
|
||||||
working = mode = 1;
|
working = mode = 1;
|
||||||
attr = attr.replace(/^[-a-zA-Z]+/, '');
|
attr = attr.replace(/^[-a-zA-Z]+/, '');
|
||||||
|
@ -883,7 +883,7 @@ export class CoreH5PContentValidator {
|
||||||
|
|
||||||
if (colonPos > 0) {
|
if (colonPos > 0) {
|
||||||
// We found a colon, possibly a protocol. Verify.
|
// We found a colon, possibly a protocol. Verify.
|
||||||
const protocol = uri.substr(0, colonPos);
|
const protocol = uri.substring(0, colonPos);
|
||||||
// If a colon is preceded by a slash, question mark or hash, it cannot possibly be part of the URL scheme.
|
// If a colon is preceded by a slash, question mark or hash, it cannot possibly be part of the URL scheme.
|
||||||
// This must be a relative URL, which inherits the (safe) protocol of the base document.
|
// This must be a relative URL, which inherits the (safe) protocol of the base document.
|
||||||
if (protocol.match(/[/?#]/)) {
|
if (protocol.match(/[/?#]/)) {
|
||||||
|
@ -891,7 +891,7 @@ export class CoreH5PContentValidator {
|
||||||
}
|
}
|
||||||
// Check if this is a disallowed protocol.
|
// Check if this is a disallowed protocol.
|
||||||
if (!allowedProtocols[protocol.toLowerCase()]) {
|
if (!allowedProtocols[protocol.toLowerCase()]) {
|
||||||
uri = uri.substr(colonPos + 1);
|
uri = uri.substring(colonPos + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (before != uri);
|
} while (before != uri);
|
||||||
|
|
|
@ -216,7 +216,7 @@ export class CoreH5PCore {
|
||||||
|
|
||||||
// Prevent too long slug.
|
// Prevent too long slug.
|
||||||
if (newInput.length > 91) {
|
if (newInput.length > 91) {
|
||||||
newInput = newInput.substr(0, 92);
|
newInput = newInput.substring(0, 92);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent empty slug
|
// Prevent empty slug
|
||||||
|
|
|
@ -14,23 +14,21 @@
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item button class="core-user-profile-maininfo" *ngIf="siteInfo" lines="full" (click)="switchAccounts($event)" detail="true"
|
<ion-item button class="core-usermenu-siteinfo ion-text-wrap" *ngIf="siteInfo" lines="full" detail="false" [href]="siteUrl"
|
||||||
[attr.aria-label]="'core.mainmenu.switchaccount' | translate">
|
core-link auto-login="yes">
|
||||||
<core-user-avatar [user]="siteInfo" [userId]="siteInfo.userid" [linkProfile]="false" slot="start"></core-user-avatar>
|
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>{{ siteInfo.fullname }}</h2>
|
<p class="core-usermenu-sitename">
|
||||||
<p class="core-usermenu-siteinfo core-usermenu-sitename">
|
|
||||||
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
|
||||||
</core-format-text>
|
</core-format-text>
|
||||||
</p>
|
</p>
|
||||||
|
<a [href]="siteUrl" core-link auto-login="yes" class="core-usermenu-siteurl">{{ siteUrl }}</a>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
<ion-item button class="core-usermenu-handler ion-text-wrap" *ngIf="siteInfo" lines="full" (click)="openUserProfile($event)"
|
||||||
<ion-item button class="ion-text-wrap core-usermenu-handler" (click)="openUserProfile($event)"
|
detail="true" [attr.aria-label]="'core.user.profile' | translate">
|
||||||
[attr.aria-label]="'core.user.details' | translate" detail="true" lines="none">
|
<core-user-avatar [user]="siteInfo" [userId]="siteInfo.userid" [linkProfile]="false" slot="start"></core-user-avatar>
|
||||||
<ion-icon name="fas-user" slot="start" aria-hidden="true"></ion-icon>
|
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<p class="item-heading">{{ 'core.user.profile' | translate }}</p>
|
<h2>{{ siteInfo.fullname }}</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
|
@ -66,10 +64,18 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
<ion-footer class="ion-padding">
|
<ion-footer>
|
||||||
|
<ion-item button lines="full" (click)="switchAccounts($event)" detail="true" class="ion-text-wrap">
|
||||||
|
<ion-icon name="fas-exchange-alt" slot="start" aria-hidden="true"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<p class="item-heading">{{ 'core.mainmenu.switchaccount' | translate }}</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
|
<div class="ion-padding">
|
||||||
<ion-button (click)="logout($event)" expand="block" color="danger" [attr.aria-label]="'core.mainmenu.logout' | translate"
|
<ion-button (click)="logout($event)" expand="block" color="danger" [attr.aria-label]="'core.mainmenu.logout' | translate"
|
||||||
class="ion-text-wrap">
|
class="ion-text-wrap">
|
||||||
<ion-icon name="fas-sign-out-alt" slot="start" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-sign-out-alt" slot="start" aria-hidden="true"></ion-icon>
|
||||||
{{ 'core.mainmenu.logout' | translate }}
|
{{ 'core.mainmenu.logout' | translate }}
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
</div>
|
||||||
</ion-footer>
|
</ion-footer>
|
||||||
|
|
|
@ -7,12 +7,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.core-usermenu-siteinfo {
|
||||||
|
--padding-top: 10px;
|
||||||
|
--padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
@if ($core-user-hide-siteinfo) {
|
@if ($core-user-hide-siteinfo) {
|
||||||
.core-usermenu-siteinfo {
|
.core-usermenu-siteinfo {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.core-usermenu-sitename {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
@if ($core-user-hide-sitename) {
|
@if ($core-user-hide-sitename) {
|
||||||
.core-usermenu-sitename {
|
.core-usermenu-sitename {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -24,3 +33,7 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ion-footer {
|
||||||
|
background: var(--contrast-background);
|
||||||
|
}
|
||||||
|
|
|
@ -303,7 +303,7 @@ export class CoreQuestionHelperProvider {
|
||||||
|
|
||||||
// Remove start and end of the match, we only want the object.
|
// Remove start and end of the match, we only want the object.
|
||||||
initMatch = initMatch.replace('M.qtype_' + question.type + '.init_question(', '');
|
initMatch = initMatch.replace('M.qtype_' + question.type + '.init_question(', '');
|
||||||
initMatch = initMatch.substr(0, initMatch.length - 2);
|
initMatch = initMatch.substring(0, initMatch.length - 2);
|
||||||
|
|
||||||
// Try to convert it to an object and add it to the question.
|
// Try to convert it to an object and add it to the question.
|
||||||
question.initObjects = CoreTextUtils.parseJSON(initMatch, null);
|
question.initObjects = CoreTextUtils.parseJSON(initMatch, null);
|
||||||
|
|
|
@ -100,7 +100,7 @@ export class CoreSettingsDeviceInfoPage implements OnDestroy {
|
||||||
|
|
||||||
if (window.location && window.location.href) {
|
if (window.location && window.location.href) {
|
||||||
const url = window.location.href;
|
const url = window.location.href;
|
||||||
this.deviceInfo.locationHref = url.indexOf('#') > 0 ? url.substr(0, url.indexOf('#')) : url;
|
this.deviceInfo.locationHref = url.indexOf('#') > 0 ? url.substring(0, url.indexOf('#')) : url;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.screen) {
|
if (window.screen) {
|
||||||
|
|
|
@ -30,4 +30,5 @@
|
||||||
(onLoadingContent)="contentLoading()">
|
(onLoadingContent)="contentLoading()">
|
||||||
</core-site-plugins-plugin-content>
|
</core-site-plugins-plugin-content>
|
||||||
|
|
||||||
<core-course-module-navigation *ngIf="module" [courseId]="courseId" [currentModuleId]="module.id"></core-course-module-navigation>
|
<core-course-module-navigation *ngIf="module" [courseId]="courseId" [currentModule]="module">
|
||||||
|
</core-course-module-navigation>
|
||||||
|
|
|
@ -232,8 +232,8 @@ export class CoreFileProvider {
|
||||||
} else {
|
} else {
|
||||||
// The file plugin doesn't allow creating more than 1 level at a time (e.g. tmp/folder).
|
// The file plugin doesn't allow creating more than 1 level at a time (e.g. tmp/folder).
|
||||||
// We need to create them 1 by 1.
|
// We need to create them 1 by 1.
|
||||||
const firstDir = path.substr(0, path.indexOf('/'));
|
const firstDir = path.substring(0, path.indexOf('/'));
|
||||||
const restOfPath = path.substr(path.indexOf('/') + 1);
|
const restOfPath = path.substring(path.indexOf('/') + 1);
|
||||||
|
|
||||||
this.logger.debug('Create dir ' + firstDir + ' in ' + base);
|
this.logger.debug('Create dir ' + firstDir + ' in ' + base);
|
||||||
|
|
||||||
|
@ -692,7 +692,7 @@ export class CoreFileProvider {
|
||||||
*/
|
*/
|
||||||
async removeExternalFile(fullPath: string): Promise<void> {
|
async removeExternalFile(fullPath: string): Promise<void> {
|
||||||
const directory = fullPath.substring(0, fullPath.lastIndexOf('/'));
|
const directory = fullPath.substring(0, fullPath.lastIndexOf('/'));
|
||||||
const filename = fullPath.substr(fullPath.lastIndexOf('/') + 1);
|
const filename = fullPath.substring(fullPath.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
await File.removeFile(directory, filename);
|
await File.removeFile(directory, filename);
|
||||||
}
|
}
|
||||||
|
@ -885,7 +885,7 @@ export class CoreFileProvider {
|
||||||
};
|
};
|
||||||
|
|
||||||
file.directory = path.substring(0, path.lastIndexOf('/'));
|
file.directory = path.substring(0, path.lastIndexOf('/'));
|
||||||
file.name = path.substr(path.lastIndexOf('/') + 1);
|
file.name = path.substring(path.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
@ -1035,7 +1035,7 @@ export class CoreFileProvider {
|
||||||
*/
|
*/
|
||||||
removeStartingSlash(path: string): string {
|
removeStartingSlash(path: string): string {
|
||||||
if (path[0] == '/') {
|
if (path[0] == '/') {
|
||||||
return path.substr(1);
|
return path.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
|
@ -1232,7 +1232,7 @@ export class CoreFileProvider {
|
||||||
const position = window.location.href.indexOf(window.location.pathname);
|
const position = window.location.href.indexOf(window.location.pathname);
|
||||||
|
|
||||||
if (position != -1) {
|
if (position != -1) {
|
||||||
return window.location.href.substr(0, position);
|
return window.location.href.substring(0, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
return window.location.href;
|
return window.location.href;
|
||||||
|
|
|
@ -777,7 +777,7 @@ export class CoreFilepoolProvider {
|
||||||
// Calculate the path to the file.
|
// Calculate the path to the file.
|
||||||
path = file.filename || '';
|
path = file.filename || '';
|
||||||
if (file.filepath && file.filepath !== '/') {
|
if (file.filepath && file.filepath !== '/') {
|
||||||
path = file.filepath.substr(1) + path;
|
path = file.filepath.substring(1) + path;
|
||||||
}
|
}
|
||||||
path = CoreTextUtils.concatenatePaths(dirPath, path);
|
path = CoreTextUtils.concatenatePaths(dirPath, path);
|
||||||
}
|
}
|
||||||
|
@ -871,7 +871,7 @@ export class CoreFilepoolProvider {
|
||||||
// Calculate the path to the file.
|
// Calculate the path to the file.
|
||||||
path = file.filename || '';
|
path = file.filename || '';
|
||||||
if (file.filepath && file.filepath !== '/') {
|
if (file.filepath && file.filepath !== '/') {
|
||||||
path = file.filepath.substr(1) + path;
|
path = file.filepath.substring(1) + path;
|
||||||
}
|
}
|
||||||
path = CoreTextUtils.concatenatePaths(dirPath, path);
|
path = CoreTextUtils.concatenatePaths(dirPath, path);
|
||||||
}
|
}
|
||||||
|
@ -1837,7 +1837,7 @@ export class CoreFilepoolProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const relativePath = url.substr(url.indexOf('/pluginfile.php') + 16);
|
const relativePath = url.substring(url.indexOf('/pluginfile.php') + 16);
|
||||||
const args = relativePath.split('/');
|
const args = relativePath.split('/');
|
||||||
|
|
||||||
if (args.length < 3) {
|
if (args.length < 3) {
|
||||||
|
@ -2084,7 +2084,7 @@ export class CoreFilepoolProvider {
|
||||||
// It's a pluginfile URL. Search for the 'file' param to extract the name.
|
// It's a pluginfile URL. Search for the 'file' param to extract the name.
|
||||||
const params = CoreUrlUtils.extractUrlParams(fileUrl);
|
const params = CoreUrlUtils.extractUrlParams(fileUrl);
|
||||||
if (params.file) {
|
if (params.file) {
|
||||||
filename = params.file.substr(params.file.lastIndexOf('/') + 1);
|
filename = params.file.substring(params.file.lastIndexOf('/') + 1);
|
||||||
} else {
|
} else {
|
||||||
// 'file' param not found. Extract what's after the last '/' without params.
|
// 'file' param not found. Extract what's after the last '/' without params.
|
||||||
filename = CoreUrlUtils.getLastFileWithoutParams(fileUrl);
|
filename = CoreUrlUtils.getLastFileWithoutParams(fileUrl);
|
||||||
|
@ -2115,7 +2115,7 @@ export class CoreFilepoolProvider {
|
||||||
// Remove the URL from the array.
|
// Remove the URL from the array.
|
||||||
hashes.shift();
|
hashes.shift();
|
||||||
|
|
||||||
filename = filename.substr(0, index);
|
filename = filename.substring(0, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the extension from the filename.
|
// Remove the extension from the filename.
|
||||||
|
|
|
@ -256,7 +256,7 @@ export class CoreLangProvider {
|
||||||
// Language code defined by locale has a dash, like en-US or es-ES. Check if it's supported.
|
// Language code defined by locale has a dash, like en-US or es-ES. Check if it's supported.
|
||||||
if (CoreConstants.CONFIG.languages && CoreConstants.CONFIG.languages[preferredLanguage] === undefined) {
|
if (CoreConstants.CONFIG.languages && CoreConstants.CONFIG.languages[preferredLanguage] === undefined) {
|
||||||
// Code is NOT supported. Fallback to language without dash. E.g. 'en-US' would fallback to 'en'.
|
// Code is NOT supported. Fallback to language without dash. E.g. 'en-US' would fallback to 'en'.
|
||||||
preferredLanguage = preferredLanguage.substr(0, preferredLanguage.indexOf('-'));
|
preferredLanguage = preferredLanguage.substring(0, preferredLanguage.indexOf('-'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ export class CoreCustomURLSchemesProvider {
|
||||||
|
|
||||||
// Remove the params to get the site URL.
|
// Remove the params to get the site URL.
|
||||||
if (url.indexOf('?') != -1) {
|
if (url.indexOf('?') != -1) {
|
||||||
url = url.substr(0, url.indexOf('?'));
|
url = url.substring(0, url.indexOf('?'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!url.match(/https?:\/\//)) {
|
if (!url.match(/https?:\/\//)) {
|
||||||
|
|
|
@ -443,7 +443,7 @@ export class CoreIframeUtilsProvider {
|
||||||
}
|
}
|
||||||
} else if (CoreUrlUtils.isLocalFileUrl(url)) {
|
} else if (CoreUrlUtils.isLocalFileUrl(url)) {
|
||||||
// It's a local file.
|
// It's a local file.
|
||||||
const filename = url.substr(url.lastIndexOf('/') + 1);
|
const filename = url.substring(url.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
if (!CoreFileHelper.isOpenableInApp({ filename })) {
|
if (!CoreFileHelper.isOpenableInApp({ filename })) {
|
||||||
try {
|
try {
|
||||||
|
@ -522,7 +522,7 @@ export class CoreIframeUtilsProvider {
|
||||||
// Opening links with _parent, _top or _blank can break the app. We'll open it in InAppBrowser.
|
// Opening links with _parent, _top or _blank can break the app. We'll open it in InAppBrowser.
|
||||||
event && event.preventDefault();
|
event && event.preventDefault();
|
||||||
|
|
||||||
const filename = link.href.substr(link.href.lastIndexOf('/') + 1);
|
const filename = link.href.substring(link.href.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
if (!CoreFileHelper.isOpenableInApp({ filename })) {
|
if (!CoreFileHelper.isOpenableInApp({ filename })) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -84,13 +84,13 @@ export class CoreMimetypeUtilsProvider {
|
||||||
// If the extension has parameters, remove them.
|
// If the extension has parameters, remove them.
|
||||||
let position = extension.indexOf('?');
|
let position = extension.indexOf('?');
|
||||||
if (position > -1) {
|
if (position > -1) {
|
||||||
extension = extension.substr(0, position);
|
extension = extension.substring(0, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the extension has an anchor, remove it.
|
// If the extension has an anchor, remove it.
|
||||||
position = extension.indexOf('#');
|
position = extension.indexOf('#');
|
||||||
if (position > -1) {
|
if (position > -1) {
|
||||||
extension = extension.substr(0, position);
|
extension = extension.substring(0, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove hash in extension if there's any (added by filepool).
|
// Remove hash in extension if there's any (added by filepool).
|
||||||
|
@ -98,7 +98,7 @@ export class CoreMimetypeUtilsProvider {
|
||||||
|
|
||||||
// Remove dot from the extension if found.
|
// Remove dot from the extension if found.
|
||||||
if (extension && extension[0] == '.') {
|
if (extension && extension[0] == '.') {
|
||||||
extension = extension.substr(1);
|
extension = extension.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return extension;
|
return extension;
|
||||||
|
@ -311,12 +311,12 @@ export class CoreMimetypeUtilsProvider {
|
||||||
// Remove params if any.
|
// Remove params if any.
|
||||||
position = candidate.indexOf('?');
|
position = candidate.indexOf('?');
|
||||||
if (position > -1) {
|
if (position > -1) {
|
||||||
candidate = candidate.substr(0, position);
|
candidate = candidate.substring(0, position);
|
||||||
}
|
}
|
||||||
// Remove anchor if any.
|
// Remove anchor if any.
|
||||||
position = candidate.indexOf('#');
|
position = candidate.indexOf('#');
|
||||||
if (position > -1) {
|
if (position > -1) {
|
||||||
candidate = candidate.substr(0, position);
|
candidate = candidate.substring(0, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EXTENSION_REGEX.test(candidate)) {
|
if (EXTENSION_REGEX.test(candidate)) {
|
||||||
|
@ -346,7 +346,7 @@ export class CoreMimetypeUtilsProvider {
|
||||||
let ext;
|
let ext;
|
||||||
|
|
||||||
if (dot > -1) {
|
if (dot > -1) {
|
||||||
ext = filename.substr(dot + 1).toLowerCase();
|
ext = filename.substring(dot + 1).toLowerCase();
|
||||||
ext = this.cleanExtension(ext);
|
ext = this.cleanExtension(ext);
|
||||||
|
|
||||||
// Check extension corresponds to a mimetype to know if it's valid.
|
// Check extension corresponds to a mimetype to know if it's valid.
|
||||||
|
@ -589,9 +589,9 @@ export class CoreMimetypeUtilsProvider {
|
||||||
|
|
||||||
if (position > -1) {
|
if (position > -1) {
|
||||||
// Check extension corresponds to a mimetype to know if it's valid.
|
// Check extension corresponds to a mimetype to know if it's valid.
|
||||||
extension = path.substr(position + 1).toLowerCase();
|
extension = path.substring(position + 1).toLowerCase();
|
||||||
if (this.getMimeType(extension) !== undefined) {
|
if (this.getMimeType(extension) !== undefined) {
|
||||||
return path.substr(0, position); // Remove extension.
|
return path.substring(0, position); // Remove extension.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ export class CoreTextUtilsProvider {
|
||||||
const firstCharRight = rightPath.charAt(0);
|
const firstCharRight = rightPath.charAt(0);
|
||||||
|
|
||||||
if (lastCharLeft === '/' && firstCharRight === '/') {
|
if (lastCharLeft === '/' && firstCharRight === '/') {
|
||||||
return leftPath + rightPath.substr(1);
|
return leftPath + rightPath.substring(1);
|
||||||
} else if (lastCharLeft !== '/' && firstCharRight !== '/') {
|
} else if (lastCharLeft !== '/' && firstCharRight !== '/') {
|
||||||
return leftPath + '/' + rightPath;
|
return leftPath + '/' + rightPath;
|
||||||
} else {
|
} else {
|
||||||
|
@ -539,7 +539,7 @@ export class CoreTextUtilsProvider {
|
||||||
const url = CoreFileHelper.getFileUrl(files[0]);
|
const url = CoreFileHelper.getFileUrl(files[0]);
|
||||||
|
|
||||||
// Remove text after last slash (encoded or not).
|
// Remove text after last slash (encoded or not).
|
||||||
return url?.substr(0, Math.max(url.lastIndexOf('/'), url.lastIndexOf('%2F')));
|
return url?.substring(0, Math.max(url.lastIndexOf('/'), url.lastIndexOf('%2F')));
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -778,9 +778,9 @@ export class CoreTextUtilsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the filename from the URL.
|
// Get the filename from the URL.
|
||||||
let filename = url.substr(url.lastIndexOf('/') + 1);
|
let filename = url.substring(url.lastIndexOf('/') + 1);
|
||||||
if (filename.indexOf('?') != -1) {
|
if (filename.indexOf('?') != -1) {
|
||||||
filename = filename.substr(0, filename.indexOf('?'));
|
filename = filename.substring(0, filename.indexOf('?'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pluginfileMap[filename]) {
|
if (pluginfileMap[filename]) {
|
||||||
|
@ -904,12 +904,12 @@ export class CoreTextUtilsProvider {
|
||||||
*/
|
*/
|
||||||
shortenText(text: string, length: number): string {
|
shortenText(text: string, length: number): string {
|
||||||
if (text.length > length) {
|
if (text.length > length) {
|
||||||
text = text.substr(0, length);
|
text = text.substring(0, length);
|
||||||
|
|
||||||
// Now, truncate at the last word boundary (if exists).
|
// Now, truncate at the last word boundary (if exists).
|
||||||
const lastWordPos = text.lastIndexOf(' ');
|
const lastWordPos = text.lastIndexOf(' ');
|
||||||
if (lastWordPos > 0) {
|
if (lastWordPos > 0) {
|
||||||
text = text.substr(0, lastWordPos);
|
text = text.substring(0, lastWordPos);
|
||||||
}
|
}
|
||||||
text += '…';
|
text += '…';
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,9 +329,9 @@ export class CoreUrlUtilsProvider {
|
||||||
* @return Last file without params.
|
* @return Last file without params.
|
||||||
*/
|
*/
|
||||||
getLastFileWithoutParams(url: string): string {
|
getLastFileWithoutParams(url: string): string {
|
||||||
let filename = url.substr(url.lastIndexOf('/') + 1);
|
let filename = url.substring(url.lastIndexOf('/') + 1);
|
||||||
if (filename.indexOf('?') != -1) {
|
if (filename.indexOf('?') != -1) {
|
||||||
filename = filename.substr(0, filename.indexOf('?'));
|
filename = filename.substring(0, filename.indexOf('?'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return filename;
|
return filename;
|
||||||
|
|
|
@ -1254,7 +1254,7 @@ export class CoreUtilsProvider {
|
||||||
const mapped = {};
|
const mapped = {};
|
||||||
objects.forEach((item) => {
|
objects.forEach((item) => {
|
||||||
const keyValue = item[keyName] as string;
|
const keyValue = item[keyName] as string;
|
||||||
const key = prefixSubstr > 0 ? keyValue.substr(prefixSubstr) : keyValue;
|
const key = prefixSubstr > 0 ? keyValue.substring(prefixSubstr) : keyValue;
|
||||||
mapped[key] = item[valueName];
|
mapped[key] = item[valueName];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ export class CoreColors {
|
||||||
*/
|
*/
|
||||||
static hexToRGB(color: string): ColorComponents {
|
static hexToRGB(color: string): ColorComponents {
|
||||||
if (color.charAt(0) == '#') {
|
if (color.charAt(0) == '#') {
|
||||||
color = color.substr(1);
|
color = color.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (color.length === 3) {
|
if (color.length === 3) {
|
||||||
|
@ -122,9 +122,9 @@ export class CoreColors {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
red: parseInt(color.substr(0, 2), 16),
|
red: parseInt(color.substring(0, 2), 16),
|
||||||
green: parseInt(color.substr(2, 2), 16),
|
green: parseInt(color.substring(2, 2), 16),
|
||||||
blue: parseInt(color.substr(4, 2), 16),
|
blue: parseInt(color.substring(4, 2), 16),
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ function readBytes (str, len, escapedString = false) {
|
||||||
const isLowSurrogate = code >= 0xdc00 && code <= 0xdfff
|
const isLowSurrogate = code >= 0xdc00 && code <= 0xdfff
|
||||||
|
|
||||||
if (escapedString && chr === '\\') {
|
if (escapedString && chr === '\\') {
|
||||||
chr = String.fromCharCode(parseInt(str.substr(c + 1, 2), 16))
|
chr = String.fromCharCode(parseInt(str.substring(c + 1, 2), 16))
|
||||||
escapedChars++
|
escapedChars++
|
||||||
|
|
||||||
// each escaped sequence is 3 characters. Go 2 chars ahead.
|
// each escaped sequence is 3 characters. Go 2 chars ahead.
|
||||||
|
@ -167,7 +167,7 @@ function expectString (str) {
|
||||||
|
|
||||||
const len = parseInt(byteLenMatch, 10)
|
const len = parseInt(byteLenMatch, 10)
|
||||||
|
|
||||||
str = str.substr(match.length)
|
str = str.substring(match.length)
|
||||||
|
|
||||||
let [ strMatch, bytes ] = readBytes(str, len)
|
let [ strMatch, bytes ] = readBytes(str, len)
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ function expectString (str) {
|
||||||
throw SyntaxError(`Expected string of ${len} bytes, but got ${bytes}`)
|
throw SyntaxError(`Expected string of ${len} bytes, but got ${bytes}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
str = str.substr((strMatch as string).length)
|
str = str.substring((strMatch as string).length)
|
||||||
|
|
||||||
// strict parsing, match closing "; chars
|
// strict parsing, match closing "; chars
|
||||||
if (!str.startsWith('";')) {
|
if (!str.startsWith('";')) {
|
||||||
|
@ -195,7 +195,7 @@ function expectEscapedString (str) {
|
||||||
|
|
||||||
const len = parseInt(strLenMatch, 10)
|
const len = parseInt(strLenMatch, 10)
|
||||||
|
|
||||||
str = str.substr(match.length)
|
str = str.substring(match.length)
|
||||||
|
|
||||||
let [ strMatch, bytes, escapedChars ] = readBytes(str, len, true)
|
let [ strMatch, bytes, escapedChars ] = readBytes(str, len, true)
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ function expectEscapedString (str) {
|
||||||
throw SyntaxError(`Expected escaped string of ${len} bytes, but got ${bytes}`)
|
throw SyntaxError(`Expected escaped string of ${len} bytes, but got ${bytes}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
str = str.substr((strMatch as string).length + (escapedChars as number) * 2)
|
str = str.substring((strMatch as string).length + (escapedChars as number) * 2)
|
||||||
|
|
||||||
// strict parsing, match closing "; chars
|
// strict parsing, match closing "; chars
|
||||||
if (!str.startsWith('";')) {
|
if (!str.startsWith('";')) {
|
||||||
|
@ -249,15 +249,15 @@ function expectObject (str, cache) {
|
||||||
const obj = {}
|
const obj = {}
|
||||||
cache([obj])
|
cache([obj])
|
||||||
|
|
||||||
str = str.substr(totalOffset)
|
str = str.substring(totalOffset)
|
||||||
|
|
||||||
for (let i = 0; i < propCount; i++) {
|
for (let i = 0; i < propCount; i++) {
|
||||||
const prop = expectKeyOrIndex(str)
|
const prop = expectKeyOrIndex(str)
|
||||||
str = str.substr(prop[1])
|
str = str.substring(prop[1])
|
||||||
totalOffset += prop[1] as number
|
totalOffset += prop[1] as number
|
||||||
|
|
||||||
const value = expectType(str, cache)
|
const value = expectType(str, cache)
|
||||||
str = str.substr(value[1])
|
str = str.substring(value[1])
|
||||||
totalOffset += value[1]
|
totalOffset += value[1]
|
||||||
|
|
||||||
obj[prop[0]] = value[0]
|
obj[prop[0]] = value[0]
|
||||||
|
@ -299,7 +299,7 @@ function expectArray (str, cache) {
|
||||||
throw SyntaxError('Expected array length annotation')
|
throw SyntaxError('Expected array length annotation')
|
||||||
}
|
}
|
||||||
|
|
||||||
str = str.substr(arrayLiteralBeginMatch.length)
|
str = str.substring(arrayLiteralBeginMatch.length)
|
||||||
|
|
||||||
const array = expectArrayItems(str, parseInt(arrayLengthMatch, 10), cache)
|
const array = expectArrayItems(str, parseInt(arrayLengthMatch, 10), cache)
|
||||||
|
|
||||||
|
@ -327,14 +327,14 @@ function expectArrayItems (str, expectedItems = 0, cache) {
|
||||||
hasStringKeys = (typeof key[0] === 'string')
|
hasStringKeys = (typeof key[0] === 'string')
|
||||||
}
|
}
|
||||||
|
|
||||||
str = str.substr(key[1])
|
str = str.substring(key[1])
|
||||||
totalOffset += key[1]
|
totalOffset += key[1]
|
||||||
|
|
||||||
// references are resolved immediately, so if duplicate key overwrites previous array index
|
// references are resolved immediately, so if duplicate key overwrites previous array index
|
||||||
// the old value is anyway resolved
|
// the old value is anyway resolved
|
||||||
// fixme: but next time the same reference should point to the new value
|
// fixme: but next time the same reference should point to the new value
|
||||||
item = expectType(str, cache)
|
item = expectType(str, cache)
|
||||||
str = str.substr(item[1])
|
str = str.substring(item[1])
|
||||||
totalOffset += item[1]
|
totalOffset += item[1]
|
||||||
|
|
||||||
items[key[0]] = item[0]
|
items[key[0]] = item[0]
|
||||||
|
@ -428,7 +428,7 @@ function substr_replace (str, replace, start, length) {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
str.slice(0, start),
|
str.slice(0, start),
|
||||||
replace.substr(0, length),
|
replace.substring(0, length),
|
||||||
replace.slice(length),
|
replace.slice(length),
|
||||||
str.slice(start + length)
|
str.slice(start + length)
|
||||||
].join('')
|
].join('')
|
||||||
|
|
|
@ -34,7 +34,7 @@ export class CoreText {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text.slice(-1) == '/') {
|
if (text.slice(-1) == '/') {
|
||||||
return text.substr(0, text.length - 1);
|
return text.substring(0, text.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
|
|
|
@ -216,7 +216,7 @@ export class CoreUrl {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url.substr(firstAnchorIndex);
|
return url.substring(firstAnchorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -82,7 +82,7 @@ export class CoreWindow {
|
||||||
*/
|
*/
|
||||||
static async open(url: string, name?: string): Promise<void> {
|
static async open(url: string, name?: string): Promise<void> {
|
||||||
if (CoreUrlUtils.isLocalFileUrl(url)) {
|
if (CoreUrlUtils.isLocalFileUrl(url)) {
|
||||||
const filename = url.substr(url.lastIndexOf('/') + 1);
|
const filename = url.substring(url.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
if (!CoreFileHelper.isOpenableInApp({ filename })) {
|
if (!CoreFileHelper.isOpenableInApp({ filename })) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -209,7 +209,7 @@
|
||||||
--vertical-margin: 10px;
|
--vertical-margin: 10px;
|
||||||
--horizontal-margin: 10px;
|
--horizontal-margin: 10px;
|
||||||
|
|
||||||
width: calc(100% - var(--vertical-margin) - var(--vertical-margin));
|
width: calc(100% - var(--horizontal-margin) - var(--horizontal-margin));
|
||||||
height: calc(100% - var(--vertical-margin) - var(--vertical-margin));
|
height: calc(100% - var(--vertical-margin) - var(--vertical-margin));
|
||||||
margin: var(--vertical-margin) var(--horizontal-margin);
|
margin: var(--vertical-margin) var(--horizontal-margin);
|
||||||
|
|
||||||
|
|
|
@ -554,7 +554,7 @@ body.core-iframe-fullscreen ion-router-outlet {
|
||||||
display: block;
|
display: block;
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: #{$modal-lateral-width};
|
min-width: calc(#{$modal-lateral-width} - 16px);
|
||||||
box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4);
|
box-shadow: 0 28px 48px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
ion-backdrop {
|
ion-backdrop {
|
||||||
|
|
|
@ -215,6 +215,10 @@
|
||||||
--color: var(--item-divider-color);
|
--color: var(--item-divider-color);
|
||||||
--min-height: var(--item-divider-min-height);
|
--min-height: var(--item-divider-min-height);
|
||||||
min-height: var(--min-height);
|
min-height: var(--min-height);
|
||||||
|
|
||||||
|
.expandable-status-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
--spacer-background: var(--item-divider-background);
|
--spacer-background: var(--item-divider-background);
|
||||||
|
|
Loading…
Reference in New Issue