commit
21ccad82f0
|
@ -0,0 +1,80 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { CoreCanceledError } from '@classes/errors/cancelederror';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { ModalController } from '@singletons';
|
||||
import { AddonModAssignEditFeedbackModalComponent } from '../components/edit-feedback-modal/edit-feedback-modal';
|
||||
import { AddonModAssignFeedbackCommentsTextData } from '../feedback/comments/services/handler';
|
||||
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
|
||||
|
||||
/**
|
||||
* Base class for component to render a feedback plugin.
|
||||
*/
|
||||
@Component({
|
||||
template: '',
|
||||
})
|
||||
export class AddonModAssignFeedbackPluginBaseComponent {
|
||||
|
||||
@Input() assign!: AddonModAssignAssign; // The assignment.
|
||||
@Input() submission!: AddonModAssignSubmission; // The submission.
|
||||
@Input() plugin!: AddonModAssignPlugin; // The plugin object.
|
||||
@Input() userId!: number; // The user ID of the submission.
|
||||
@Input() configs?: Record<string,string>; // The configs for the plugin.
|
||||
@Input() canEdit = false; // Whether the user can edit.
|
||||
@Input() edit = false; // Whether the user is editing.
|
||||
|
||||
/**
|
||||
* Open a modal to edit the feedback plugin.
|
||||
*
|
||||
* @return Promise resolved with the input data, rejected if cancelled.
|
||||
*/
|
||||
async editFeedback(): Promise<AddonModAssignFeedbackCommentsTextData> {
|
||||
if (!this.canEdit) {
|
||||
throw new CoreError('Cannot edit feedback');
|
||||
}
|
||||
|
||||
// Create the navigation modal.
|
||||
const modal = await ModalController.create({
|
||||
component: AddonModAssignEditFeedbackModalComponent,
|
||||
componentProps: {
|
||||
assign: this.assign,
|
||||
submission: this.submission,
|
||||
plugin: this.plugin,
|
||||
userId: this.userId,
|
||||
},
|
||||
});
|
||||
|
||||
await modal.present();
|
||||
|
||||
const result = await modal.onDidDismiss();
|
||||
|
||||
if (typeof result.data == 'undefined') {
|
||||
throw new CoreCanceledError(); // User cancelled.
|
||||
} else {
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the data.
|
||||
*
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async invalidate(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
|
||||
|
||||
/**
|
||||
* Base class for component to render a submission plugin.
|
||||
*/
|
||||
@Component({
|
||||
template: '',
|
||||
})
|
||||
export class AddonModAssignSubmissionPluginBaseComponent {
|
||||
|
||||
@Input() assign!: AddonModAssignAssign; // The assignment.
|
||||
@Input() submission!: AddonModAssignSubmission; // The submission.
|
||||
@Input() plugin!: AddonModAssignPlugin; // The plugin object.
|
||||
@Input() configs?: Record<string, string>; // The configs for the plugin.
|
||||
@Input() edit = false; // Whether the user is editing.
|
||||
@Input() allowOffline = false; // Whether to allow offline.
|
||||
|
||||
/**
|
||||
* Invalidate the data.
|
||||
*
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async invalidate(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
|
@ -13,11 +13,8 @@
|
|||
// limitations under the License.
|
||||
|
||||
import { Component, Input, OnInit, ViewChild, Type } from '@angular/core';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
|
||||
import { CoreWSFile } from '@services/ws';
|
||||
import { ModalController } from '@singletons';
|
||||
import { AddonModAssignFeedbackCommentsTextData } from '../../feedback/comments/services/handler';
|
||||
import {
|
||||
AddonModAssignAssign,
|
||||
AddonModAssignSubmission,
|
||||
|
@ -27,7 +24,6 @@ import {
|
|||
} from '../../services/assign';
|
||||
import { AddonModAssignHelper, AddonModAssignPluginConfig } from '../../services/assign-helper';
|
||||
import { AddonModAssignFeedbackDelegate } from '../../services/feedback-delegate';
|
||||
import { AddonModAssignEditFeedbackModalComponent } from '../edit-feedback-modal/edit-feedback-modal';
|
||||
|
||||
/**
|
||||
* Component that displays an assignment feedback plugin.
|
||||
|
@ -99,38 +95,6 @@ export class AddonModAssignFeedbackPluginComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a modal to edit the feedback plugin.
|
||||
*
|
||||
* @return Promise resolved with the input data, rejected if cancelled.
|
||||
*/
|
||||
async editFeedback(): Promise<AddonModAssignFeedbackCommentsTextData> {
|
||||
if (!this.canEdit) {
|
||||
throw new CoreError('Cannot edit feedback');
|
||||
}
|
||||
|
||||
// Create the navigation modal.
|
||||
const modal = await ModalController.create({
|
||||
component: AddonModAssignEditFeedbackModalComponent,
|
||||
componentProps: {
|
||||
assign: this.assign,
|
||||
submission: this.submission,
|
||||
plugin: this.plugin,
|
||||
userId: this.userId,
|
||||
},
|
||||
});
|
||||
|
||||
await modal.present();
|
||||
|
||||
const result = await modal.onDidDismiss();
|
||||
|
||||
if (typeof result.data == 'undefined') {
|
||||
throw null; // User cancelled.
|
||||
} else {
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the plugin data.
|
||||
*
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
import { Component, OnInit, ElementRef } from '@angular/core';
|
||||
import { FormBuilder, FormControl } from '@angular/forms';
|
||||
import { AddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/components/feedback-plugin/feedback-plugin';
|
||||
import { AddonModAssign, AddonModAssignProvider } from '@addons/mod/assign/services/assign';
|
||||
import { CoreTextUtils } from '@services/utils/text';
|
||||
import {
|
||||
|
@ -25,6 +24,7 @@ import {
|
|||
import { AddonModAssignFeedbackDelegate } from '@addons/mod/assign/services/feedback-delegate';
|
||||
import { AddonModAssignOffline } from '@addons/mod/assign/services/assign-offline';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { AddonModAssignFeedbackPluginBaseComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
|
||||
/**
|
||||
* Component to render a comments feedback plugin.
|
||||
*/
|
||||
|
@ -32,7 +32,7 @@ import { CoreUtils } from '@services/utils/utils';
|
|||
selector: 'addon-mod-assign-feedback-comments',
|
||||
templateUrl: 'addon-mod-assign-feedback-comments.html',
|
||||
})
|
||||
export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||
export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedbackPluginBaseComponent implements OnInit {
|
||||
|
||||
control?: FormControl;
|
||||
component = AddonModAssignProvider.COMPONENT;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { AddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/components/feedback-plugin/feedback-plugin';
|
||||
import { AddonModAssignFeedbackPluginBaseComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
|
||||
import { AddonModAssignProvider, AddonModAssign } from '@addons/mod/assign/services/assign';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { CoreWSFile } from '@services/ws';
|
||||
|
@ -24,7 +24,7 @@ import { CoreWSFile } from '@services/ws';
|
|||
selector: 'addon-mod-assign-feedback-edit-pdf',
|
||||
templateUrl: 'addon-mod-assign-feedback-editpdf.html',
|
||||
})
|
||||
export class AddonModAssignFeedbackEditPdfComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||
export class AddonModAssignFeedbackEditPdfComponent extends AddonModAssignFeedbackPluginBaseComponent implements OnInit {
|
||||
|
||||
component = AddonModAssignProvider.COMPONENT;
|
||||
files: CoreWSFile[] = [];
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { AddonModAssignFeedbackPluginComponent } from '@addons/mod/assign/components/feedback-plugin/feedback-plugin';
|
||||
import { AddonModAssignFeedbackPluginBaseComponent } from '@addons/mod/assign/classes/base-feedback-plugin-component';
|
||||
import { AddonModAssign, AddonModAssignProvider } from '@addons/mod/assign/services/assign';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { CoreWSFile } from '@services/ws';
|
||||
|
@ -24,7 +24,7 @@ import { CoreWSFile } from '@services/ws';
|
|||
selector: 'addon-mod-assign-feedback-file',
|
||||
templateUrl: 'addon-mod-assign-feedback-file.html',
|
||||
})
|
||||
export class AddonModAssignFeedbackFileComponent extends AddonModAssignFeedbackPluginComponent implements OnInit {
|
||||
export class AddonModAssignFeedbackFileComponent extends AddonModAssignFeedbackPluginBaseComponent implements OnInit {
|
||||
|
||||
component = AddonModAssignProvider.COMPONENT;
|
||||
files: CoreWSFile[] = [];
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { AddonModAssignSubmissionPluginComponent } from '@addons/mod/assign/components/submission-plugin/submission-plugin';
|
||||
import { CoreCommentsCommentsComponent } from '@features/comments/components/comments/comments';
|
||||
import { CoreComments } from '@features/comments/services/comments';
|
||||
|
||||
|
@ -24,7 +24,7 @@ import { CoreComments } from '@features/comments/services/comments';
|
|||
selector: 'addon-mod-assign-submission-comments',
|
||||
templateUrl: 'addon-mod-assign-submission-comments.html',
|
||||
})
|
||||
export class AddonModAssignSubmissionCommentsComponent extends AddonModAssignSubmissionPluginComponent {
|
||||
export class AddonModAssignSubmissionCommentsComponent extends AddonModAssignSubmissionPluginBaseComponent {
|
||||
|
||||
@ViewChild(CoreCommentsCommentsComponent) commentsComponent!: CoreCommentsCommentsComponent;
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { AddonModAssignSubmissionPluginComponent } from '@addons/mod/assign/components/submission-plugin/submission-plugin';
|
||||
import { AddonModAssign, AddonModAssignProvider } from '@addons/mod/assign/services/assign';
|
||||
import { AddonModAssignHelper } from '@addons/mod/assign/services/assign-helper';
|
||||
import { AddonModAssignOffline } from '@addons/mod/assign/services/assign-offline';
|
||||
|
@ -22,6 +21,8 @@ import { CoreFileSession } from '@services/file-session';
|
|||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { AddonModAssignSubmissionFileHandlerService } from '../services/handler';
|
||||
import { FileEntry } from '@ionic-native/file/ngx';
|
||||
import { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
|
||||
import { CoreFileEntry } from '@services/file-helper';
|
||||
|
||||
/**
|
||||
* Component to render a file submission plugin.
|
||||
|
@ -30,9 +31,10 @@ import { FileEntry } from '@ionic-native/file/ngx';
|
|||
selector: 'addon-mod-assign-submission-file',
|
||||
templateUrl: 'addon-mod-assign-submission-file.html',
|
||||
})
|
||||
export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmissionPluginComponent implements OnInit {
|
||||
export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmissionPluginBaseComponent implements OnInit {
|
||||
|
||||
component = AddonModAssignProvider.COMPONENT;
|
||||
files: CoreFileEntry[] = [];
|
||||
|
||||
maxSize?: number;
|
||||
acceptedTypes?: string;
|
||||
|
@ -48,12 +50,12 @@ export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmiss
|
|||
undefined,
|
||||
);
|
||||
|
||||
this.acceptedTypes = this.data?.configs.filetypeslist;
|
||||
this.maxSize = this.data?.configs.maxsubmissionsizebytes
|
||||
? parseInt(this.data?.configs.maxsubmissionsizebytes, 10)
|
||||
this.acceptedTypes = this.configs?.filetypeslist;
|
||||
this.maxSize = this.configs?.maxsubmissionsizebytes
|
||||
? parseInt(this.configs.maxsubmissionsizebytes, 10)
|
||||
: undefined;
|
||||
this.maxSubmissions = this.data?.configs.maxfilesubmissions
|
||||
? parseInt(this.data?.configs.maxfilesubmissions, 10)
|
||||
this.maxSubmissions = this.configs?.maxfilesubmissions
|
||||
? parseInt(this.configs.maxfilesubmissions, 10)
|
||||
: undefined;
|
||||
|
||||
try {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { AddonModAssignSubmissionPluginComponent } from '@addons/mod/assign/components/submission-plugin/submission-plugin';
|
||||
import { AddonModAssignSubmissionPluginBaseComponent } from '@addons/mod/assign/classes/base-submission-plugin-component';
|
||||
import { AddonModAssignProvider, AddonModAssign } from '@addons/mod/assign/services/assign';
|
||||
import { AddonModAssignOffline } from '@addons/mod/assign/services/assign-offline';
|
||||
import { Component, OnInit, ElementRef } from '@angular/core';
|
||||
|
@ -29,7 +29,7 @@ import { AddonModAssignSubmissionOnlineTextPluginData } from '../services/handle
|
|||
selector: 'addon-mod-assign-submission-online-text',
|
||||
templateUrl: 'addon-mod-assign-submission-onlinetext.html',
|
||||
})
|
||||
export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignSubmissionPluginComponent implements OnInit {
|
||||
export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignSubmissionPluginBaseComponent implements OnInit {
|
||||
|
||||
control?: FormControl;
|
||||
words = 0;
|
||||
|
@ -62,8 +62,8 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS
|
|||
undefined,
|
||||
);
|
||||
|
||||
this.wordLimitEnabled = !!parseInt(this.data?.configs.wordlimitenabled || '0', 10);
|
||||
this.wordLimit = parseInt(this.data?.configs.wordlimit || '0');
|
||||
this.wordLimitEnabled = !!parseInt(this.configs?.wordlimitenabled || '0', 10);
|
||||
this.wordLimit = parseInt(this.configs?.wordlimit || '0');
|
||||
|
||||
try {
|
||||
if (offlineData && offlineData.plugindata && offlineData.plugindata.onlinetext_editor) {
|
||||
|
|
|
@ -31,6 +31,7 @@ export class CoreSitePluginsAssignFeedbackComponent extends CoreSitePluginsCompi
|
|||
@Input() submission!: AddonModAssignSubmission; // The submission.
|
||||
@Input() plugin!: AddonModAssignPlugin; // The plugin object.
|
||||
@Input() userId!: number; // The user ID of the submission.
|
||||
@Input() configs?: Record<string,string>; // The configs for the plugin.
|
||||
@Input() canEdit = false; // Whether the user can edit.
|
||||
@Input() edit = false; // Whether the user is editing.
|
||||
|
||||
|
@ -43,6 +44,7 @@ export class CoreSitePluginsAssignFeedbackComponent extends CoreSitePluginsCompi
|
|||
this.jsData.submission = this.submission;
|
||||
this.jsData.plugin = this.plugin;
|
||||
this.jsData.userId = this.userId;
|
||||
this.jsData.configs = this.configs;
|
||||
this.jsData.edit = this.edit;
|
||||
this.jsData.canEdit = this.canEdit;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ export class CoreSitePluginsAssignSubmissionComponent extends CoreSitePluginsCom
|
|||
@Input() assign!: AddonModAssignAssign; // The assignment.
|
||||
@Input() submission!: AddonModAssignSubmission; // The submission.
|
||||
@Input() plugin!: AddonModAssignPlugin; // The plugin object.
|
||||
@Input() configs?: Record<string, string>; // The configs for the plugin.
|
||||
@Input() edit = false; // Whether the user is editing.
|
||||
@Input() allowOffline = false; // Whether to allow offline.
|
||||
|
||||
|
@ -41,6 +42,7 @@ export class CoreSitePluginsAssignSubmissionComponent extends CoreSitePluginsCom
|
|||
this.jsData.assign = this.assign;
|
||||
this.jsData.submission = this.submission;
|
||||
this.jsData.plugin = this.plugin;
|
||||
this.jsData.configs = this.configs;
|
||||
this.jsData.edit = this.edit;
|
||||
this.jsData.allowOffline = this.allowOffline;
|
||||
|
||||
|
|
|
@ -304,6 +304,7 @@ export class CoreTextUtilsProvider {
|
|||
|
||||
/**
|
||||
* Count words in a text.
|
||||
* This function is based on Moodle's count_words.
|
||||
*
|
||||
* @param text Text to count.
|
||||
* @return Number of words.
|
||||
|
@ -312,27 +313,32 @@ export class CoreTextUtilsProvider {
|
|||
if (!text || typeof text != 'string') {
|
||||
return 0;
|
||||
}
|
||||
const blockTags = ['address', 'article', 'aside', 'blockquote', 'br', ' details', 'dialog', 'dd', 'div', 'dl', 'dt',
|
||||
'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr',
|
||||
'li', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'];
|
||||
|
||||
// Clean HTML scripts and tags.
|
||||
text = text.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
|
||||
// Replace block tags by space to get word count aware of line break and remove inline tags.
|
||||
text = text.replace(/<(\/[ ]*)?([a-zA-Z0-9]+)[^>]*>/gi, (str, p1, match) => {
|
||||
if (blockTags.indexOf(match) >= 0) {
|
||||
return ' ';
|
||||
}
|
||||
// Before stripping tags, add a space after the close tag of anything that is not obviously inline.
|
||||
// Also, br is a special case because it definitely delimits a word, but has no close tag.
|
||||
text = text.replace(/(<\/(?!a>|b>|del>|em>|i>|ins>|s>|small>|strong>|sub>|sup>|u>)\w+>|<br>|<br\s*\/>)/ig, '$1 ');
|
||||
|
||||
return '';
|
||||
});
|
||||
// Now remove HTML tags.
|
||||
text = text.replace(/(<([^>]+)>)/ig, '');
|
||||
// Decode HTML entities.
|
||||
text = this.decodeHTMLEntities(text);
|
||||
// Replace underscores (which are classed as word characters) with spaces.
|
||||
text = text.replace(/_/gi, ' ');
|
||||
|
||||
// This RegEx will detect any word change including Unicode chars. Some languages without spaces won't be counted fine.
|
||||
return text.match(/\S+/gi)?.length || 0;
|
||||
// Now, the word count is the number of blocks of characters separated
|
||||
// by any sort of space. That seems to be the definition used by all other systems.
|
||||
// To be precise about what is considered to separate words:
|
||||
// * Anything that Unicode considers a 'Separator'
|
||||
// * Anything that Unicode considers a 'Control character'
|
||||
// * An em- or en- dash.
|
||||
let words: string[];
|
||||
try {
|
||||
words = text.split(/[\p{Z}\p{Cc}—–]+/u);
|
||||
} catch {
|
||||
// Unicode-aware flag not supported.
|
||||
words = text.split(/\s+/);
|
||||
}
|
||||
|
||||
// Filter empty words.
|
||||
return words.filter(word => word).length;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue