forked from CIT/Vmeda.Online
		
	MOBILE-3814 chore: Remove deprecated String.substr calls
This commit is contained in:
		
							parent
							
								
									d8a1799b9f
								
							
						
					
					
						commit
						46dada14cb
					
				@ -190,7 +190,7 @@ export class AddonFilterMathJaxLoaderHandlerService extends CoreFilterDefaultHan
 | 
			
		||||
    protected insertSpan(text: string, start: number, end: number): string {
 | 
			
		||||
        return CoreTextUtils.substrReplace(
 | 
			
		||||
            text,
 | 
			
		||||
            '<span class="nolink">' + text.substr(start, end - start + 1) + '</span>',
 | 
			
		||||
            '<span class="nolink">' + text.substring(start, end - start + 1) + '</span>',
 | 
			
		||||
            start,
 | 
			
		||||
            end - start + 1,
 | 
			
		||||
        );
 | 
			
		||||
@ -265,7 +265,7 @@ export class AddonFilterMathJaxLoaderHandlerService extends CoreFilterDefaultHan
 | 
			
		||||
     */
 | 
			
		||||
    protected fixUseUrls(node: Element): void {
 | 
			
		||||
        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('#')));
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -53,14 +53,14 @@ export class AddonModChatHelperProvider {
 | 
			
		||||
        formattedMessage.message = formattedMessage.message.trim();
 | 
			
		||||
 | 
			
		||||
        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 ||
 | 
			
		||||
            (<AddonModChatMessage> message).system;
 | 
			
		||||
 | 
			
		||||
        if (formattedMessage.message.substr(0, 4) == '/me ') {
 | 
			
		||||
        if (formattedMessage.message.substring(0, 4) == '/me ') {
 | 
			
		||||
            formattedMessage.special = true;
 | 
			
		||||
            formattedMessage.message = formattedMessage.message.substr(4).trim();
 | 
			
		||||
            formattedMessage.message = formattedMessage.message.substring(4).trim();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!formattedMessage.special && formattedMessage.message.match(patternTo)) {
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
 | 
			
		||||
        const enabledName = 'f_' + field.id + '_z';
 | 
			
		||||
 | 
			
		||||
        if (inputData[enabledName] && typeof inputData[fieldName] == 'string') {
 | 
			
		||||
            const date = inputData[fieldName].substr(0, 10).split('-');
 | 
			
		||||
            const date = inputData[fieldName].substring(0, 10).split('-');
 | 
			
		||||
 | 
			
		||||
            return [
 | 
			
		||||
                {
 | 
			
		||||
@ -87,7 +87,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
 | 
			
		||||
            return [];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const date = inputData[fieldName].substr(0, 10).split('-');
 | 
			
		||||
        const date = inputData[fieldName].substring(0, 10).split('-');
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            {
 | 
			
		||||
@ -117,10 +117,10 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
 | 
			
		||||
        originalFieldData: AddonModDataEntryField,
 | 
			
		||||
    ): boolean {
 | 
			
		||||
        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 &&
 | 
			
		||||
                CoreTimeUtils.toDatetimeFormat(parseInt(originalFieldData.content, 10) * 1000).substr(0, 10)) || '';
 | 
			
		||||
                CoreTimeUtils.toDatetimeFormat(parseInt(originalFieldData.content, 10) * 1000).substring(0, 10)) || '';
 | 
			
		||||
 | 
			
		||||
        return input != content;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -53,10 +53,10 @@ export class AddonModFolderHelperProvider {
 | 
			
		||||
            let completePath = '';
 | 
			
		||||
 | 
			
		||||
            // Remove first and last slash if needed.
 | 
			
		||||
            if (path.substr(0, 1) === '/') {
 | 
			
		||||
                path = path.substr(1);
 | 
			
		||||
            if (path.substring(0, 1) === '/') {
 | 
			
		||||
                path = path.substring(1);
 | 
			
		||||
            }
 | 
			
		||||
            if (path.substr(path.length - 1) === '/') {
 | 
			
		||||
            if (path.substring(path.length - 1) === '/') {
 | 
			
		||||
                path = path.slice(0, -1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -292,7 +292,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
 | 
			
		||||
                    // Try to get the first letter without HTML tags.
 | 
			
		||||
                    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;
 | 
			
		||||
 | 
			
		||||
@ -155,7 +155,7 @@ export class AddonModImscpProvider {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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.
 | 
			
		||||
            return filePath === targetFilePath || filePathAlt === targetFilePath;
 | 
			
		||||
 | 
			
		||||
@ -760,8 +760,8 @@ export class AddonModLessonProvider {
 | 
			
		||||
            let ignoreCase = '';
 | 
			
		||||
 | 
			
		||||
            if (useRegExp) {
 | 
			
		||||
                if (expectedAnswer.substr(-2) == '/i') {
 | 
			
		||||
                    expectedAnswer = expectedAnswer.substr(0, expectedAnswer.length - 2);
 | 
			
		||||
                if (expectedAnswer.substring(-2) == '/i') {
 | 
			
		||||
                    expectedAnswer = expectedAnswer.substring(0, expectedAnswer.length - 2);
 | 
			
		||||
                    ignoreCase = 'i';
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
@ -792,12 +792,12 @@ export class AddonModLessonProvider {
 | 
			
		||||
                        isMatch = true;
 | 
			
		||||
                    }
 | 
			
		||||
                } else { // We are using regular expressions analysis.
 | 
			
		||||
                    const startCode = expectedAnswer.substr(0, 2);
 | 
			
		||||
                    const startCode = expectedAnswer.substring(0, 2);
 | 
			
		||||
 | 
			
		||||
                    switch (startCode){
 | 
			
		||||
                        // 1- Check for absence of required string in studentAnswer (coded by initial '--').
 | 
			
		||||
                        case '--':
 | 
			
		||||
                            expectedAnswer = expectedAnswer.substr(2);
 | 
			
		||||
                            expectedAnswer = expectedAnswer.substring(2);
 | 
			
		||||
                            if (!studentAnswer.match(new RegExp('^' + expectedAnswer + '$', ignoreCase))) {
 | 
			
		||||
                                isMatch = true;
 | 
			
		||||
                            }
 | 
			
		||||
@ -805,7 +805,7 @@ export class AddonModLessonProvider {
 | 
			
		||||
 | 
			
		||||
                        // 2- Check for code for marking wrong strings (coded by initial '++').
 | 
			
		||||
                        case '++': {
 | 
			
		||||
                            expectedAnswer = expectedAnswer.substr(2);
 | 
			
		||||
                            expectedAnswer = expectedAnswer.substring(2);
 | 
			
		||||
 | 
			
		||||
                            // Check for one or several matches.
 | 
			
		||||
                            const matches = studentAnswer.match(new RegExp(expectedAnswer, 'g' + ignoreCase));
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ export class AddonModPageHelperProvider {
 | 
			
		||||
                let key = content.filename;
 | 
			
		||||
                if (content.filepath !== '/') {
 | 
			
		||||
                    // Add the folders without the leading slash.
 | 
			
		||||
                    key = content.filepath.substr(1) + key;
 | 
			
		||||
                    key = content.filepath.substring(1) + key;
 | 
			
		||||
                }
 | 
			
		||||
                paths[CoreTextUtils.decodeURIComponent(key)] = url;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@ export class AddonModQuizOfflineProvider {
 | 
			
		||||
            if (!questionsWithAnswers[slot]) {
 | 
			
		||||
                questionsWithAnswers[slot] = {
 | 
			
		||||
                    answers: {},
 | 
			
		||||
                    prefix: name.substr(0, name.indexOf(nameWithoutPrefix)),
 | 
			
		||||
                    prefix: name.substring(0, name.indexOf(nameWithoutPrefix)),
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
            questionsWithAnswers[slot].answers[nameWithoutPrefix] = answers[name];
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@ export class AddonModResourceHelperProvider {
 | 
			
		||||
        let mainFilePath = mainFile.filename;
 | 
			
		||||
 | 
			
		||||
        if (mainFile.filepath !== '/') {
 | 
			
		||||
            mainFilePath = mainFile.filepath.substr(1) + mainFilePath;
 | 
			
		||||
            mainFilePath = mainFile.filepath.substring(1) + mainFilePath;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
@ -201,7 +201,7 @@ export class AddonModScormDataModel12 {
 | 
			
		||||
 | 
			
		||||
        for (const element in this.currentUserData[this.scoId].userdata) {
 | 
			
		||||
            // 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;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -748,16 +748,16 @@ export class AddonModScormDataModel12 {
 | 
			
		||||
                    const childrenStr = '._children';
 | 
			
		||||
                    const countStr = '._count';
 | 
			
		||||
 | 
			
		||||
                    if (elementModel.substr(elementModel.length - childrenStr.length, elementModel.length) == childrenStr) {
 | 
			
		||||
                        const parentModel = elementModel.substr(0, elementModel.length - childrenStr.length);
 | 
			
		||||
                    if (elementModel.substring(elementModel.length - childrenStr.length, elementModel.length) == childrenStr) {
 | 
			
		||||
                        const parentModel = elementModel.substring(0, elementModel.length - childrenStr.length);
 | 
			
		||||
 | 
			
		||||
                        if (this.dataModel[this.scoId][parentModel] !== undefined) {
 | 
			
		||||
                            this.errorCode = '202';
 | 
			
		||||
                        } else {
 | 
			
		||||
                            this.errorCode = '201';
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (elementModel.substr(elementModel.length - countStr.length, elementModel.length) == countStr) {
 | 
			
		||||
                        const parentModel = elementModel.substr(0, elementModel.length - countStr.length);
 | 
			
		||||
                    } else if (elementModel.substring(elementModel.length - countStr.length, elementModel.length) == countStr) {
 | 
			
		||||
                        const parentModel = elementModel.substring(0, elementModel.length - countStr.length);
 | 
			
		||||
 | 
			
		||||
                        if (this.dataModel[this.scoId][parentModel] !== undefined) {
 | 
			
		||||
                            this.errorCode = '203';
 | 
			
		||||
 | 
			
		||||
@ -947,7 +947,7 @@ export class AddonModScormProvider {
 | 
			
		||||
        if (parameters) {
 | 
			
		||||
            const connector = launchUrl.indexOf('?') > -1 ? '&' : '?';
 | 
			
		||||
            if (parameters.charAt(0) == '?') {
 | 
			
		||||
                parameters = parameters.substr(1);
 | 
			
		||||
                parameters = parameters.substring(1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            launchUrl += connector + parameters;
 | 
			
		||||
@ -1315,7 +1315,7 @@ export class AddonModScormProvider {
 | 
			
		||||
 | 
			
		||||
        if (link.match(/^https?:\/\//i) && !CoreUrlUtils.isLocalFileUrl(link)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        } else if (link.substr(0, 4) == 'www.') {
 | 
			
		||||
        } else if (link.substring(0, 4) == 'www.') {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -68,7 +68,7 @@ export class AddonModUrlProvider {
 | 
			
		||||
        const download = ['application/zip', 'application/x-tar', 'application/g-zip', 'application/pdf', 'text/html'];
 | 
			
		||||
        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)) {
 | 
			
		||||
            // Seems to be a web, use HTML mimetype.
 | 
			
		||||
            mimetype = 'text/html';
 | 
			
		||||
@ -158,7 +158,7 @@ export class AddonModUrlProvider {
 | 
			
		||||
        const matches = url.match(/\//g);
 | 
			
		||||
        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.
 | 
			
		||||
            return '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -226,7 +226,7 @@ export class AddonQtypeCalculatedHandlerService implements CoreQuestionHandler {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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.
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
@ -600,7 +600,7 @@ export class SQLiteDB {
 | 
			
		||||
            sql = equal ? '= ?' : '<> ?';
 | 
			
		||||
            params = Array.isArray(items) ? items : [items];
 | 
			
		||||
        } else {
 | 
			
		||||
            sql = (equal ? '' : 'NOT ') + 'IN (' + ',?'.repeat(items.length).substr(1) + ')';
 | 
			
		||||
            sql = (equal ? '' : 'NOT ') + 'IN (' + ',?'.repeat(items.length).substring(1) + ')';
 | 
			
		||||
            params = items;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -801,7 +801,7 @@ export class SQLiteDB {
 | 
			
		||||
 | 
			
		||||
        const keys = Object.keys(data);
 | 
			
		||||
        const fields = keys.join(',');
 | 
			
		||||
        const questionMarks = ',?'.repeat(keys.length).substr(1);
 | 
			
		||||
        const questionMarks = ',?'.repeat(keys.length).substring(1);
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            sql: `INSERT OR REPLACE INTO ${table} (${fields}) VALUES (${questionMarks})`,
 | 
			
		||||
@ -1139,7 +1139,7 @@ export class SQLiteDB {
 | 
			
		||||
            if (params.length == 1) {
 | 
			
		||||
                sql = sql + field + ' = ?';
 | 
			
		||||
            } else {
 | 
			
		||||
                const questionMarks = ',?'.repeat(params.length).substr(1);
 | 
			
		||||
                const questionMarks = ',?'.repeat(params.length).substring(1);
 | 
			
		||||
                sql = sql + field + ' IN (' + questionMarks + ')';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -52,16 +52,16 @@ export class CoreFaIconDirective implements AfterViewInit, OnChanges {
 | 
			
		||||
            switch (parts[0]) {
 | 
			
		||||
                case 'far':
 | 
			
		||||
                    library = 'regular';
 | 
			
		||||
                    iconName = iconName.substr(4);
 | 
			
		||||
                    iconName = iconName.substring(4);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'fa':
 | 
			
		||||
                case 'fas':
 | 
			
		||||
                    library = 'solid';
 | 
			
		||||
                    iconName = iconName.substr(parts[0].length + 1);
 | 
			
		||||
                    iconName = iconName.substring(parts[0].length + 1);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'fab':
 | 
			
		||||
                    library = 'brands';
 | 
			
		||||
                    iconName = iconName.substr(4);
 | 
			
		||||
                    iconName = iconName.substring(4);
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
@ -140,7 +140,7 @@ export class CoreLinkDirective implements OnInit {
 | 
			
		||||
 | 
			
		||||
        if (href.charAt(0) == '#') {
 | 
			
		||||
            // Look for id or name.
 | 
			
		||||
            href = href.substr(1);
 | 
			
		||||
            href = href.substring(1);
 | 
			
		||||
            CoreDomUtils.scrollToElementBySelector(
 | 
			
		||||
                this.element.closest('ion-content'),
 | 
			
		||||
                this.content,
 | 
			
		||||
@ -170,7 +170,7 @@ export class CoreLinkDirective implements OnInit {
 | 
			
		||||
     * @return Promise resolved when done.
 | 
			
		||||
     */
 | 
			
		||||
    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 })) {
 | 
			
		||||
            try {
 | 
			
		||||
 | 
			
		||||
@ -95,7 +95,7 @@ export class CoreContentLinksHandlerBase implements CoreContentLinksHandler {
 | 
			
		||||
        if (this.pattern) {
 | 
			
		||||
            const position = url.search(this.pattern);
 | 
			
		||||
            if (position > -1) {
 | 
			
		||||
                return url.substr(0, position);
 | 
			
		||||
                return url.substring(0, position);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -198,7 +198,7 @@ export class FileTransferObjectMock extends FileTransferObject {
 | 
			
		||||
                const headerString = headers[i];
 | 
			
		||||
                const separatorPos = headerString.indexOf(':');
 | 
			
		||||
                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 {
 | 
			
		||||
            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, ' ');
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
@ -82,7 +82,7 @@ export class ZipMock extends Zip {
 | 
			
		||||
 | 
			
		||||
            // First of all, create the directory where the files will be unzipped.
 | 
			
		||||
            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);
 | 
			
		||||
 | 
			
		||||
@ -95,7 +95,7 @@ export class ZipMock extends Zip {
 | 
			
		||||
                if (!file.dir) {
 | 
			
		||||
                    // It's a file.
 | 
			
		||||
                    const fileDir = name.substring(0, name.lastIndexOf('/'));
 | 
			
		||||
                    const fileName = name.substr(name.lastIndexOf('/') + 1);
 | 
			
		||||
                    const fileName = name.substring(name.lastIndexOf('/') + 1);
 | 
			
		||||
 | 
			
		||||
                    if (fileDir) {
 | 
			
		||||
                        // The file is in a subfolder, create it first.
 | 
			
		||||
 | 
			
		||||
@ -154,7 +154,7 @@ export class CoreGradesHelperProvider {
 | 
			
		||||
        for (const name in item) {
 | 
			
		||||
            const index = name.indexOf('formatted');
 | 
			
		||||
            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.itemname &&
 | 
			
		||||
                    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,
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -169,7 +169,7 @@ export class CoreH5PContentValidator {
 | 
			
		||||
 | 
			
		||||
        // Check if string is within allowed length.
 | 
			
		||||
        if (semantics.maxLength !== undefined) {
 | 
			
		||||
            text = text.substr(0, semantics.maxLength);
 | 
			
		||||
            text = text.substring(0, semantics.maxLength);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return text;
 | 
			
		||||
@ -357,8 +357,8 @@ export class CoreH5PContentValidator {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Remove temporary files suffix.
 | 
			
		||||
        if (file.path.substr(-4, 4) === '#tmp') {
 | 
			
		||||
            file.path = file.path.substr(0, file.path.length - 4);
 | 
			
		||||
        if (file.path.substring(-4, 4) === '#tmp') {
 | 
			
		||||
            file.path = file.path.substring(0, file.path.length - 4);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Make sure path and mime does not have any special chars
 | 
			
		||||
@ -670,7 +670,7 @@ export class CoreH5PContentValidator {
 | 
			
		||||
 | 
			
		||||
        const tag = tags[0];
 | 
			
		||||
 | 
			
		||||
        if (tag.substr(0, 1) != '<') {
 | 
			
		||||
        if (tag.substring(0, 1) != '<') {
 | 
			
		||||
            // We matched a lone ">" character.
 | 
			
		||||
            return '>';
 | 
			
		||||
        } else if (tag.length == 1) {
 | 
			
		||||
@ -746,7 +746,7 @@ export class CoreH5PContentValidator {
 | 
			
		||||
                    matches = attr.match(/^([-a-zA-Z]+)/);
 | 
			
		||||
                    if (matches && matches.length > 1) {
 | 
			
		||||
                        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.
 | 
			
		||||
                        working = mode = 1;
 | 
			
		||||
                        attr = attr.replace(/^[-a-zA-Z]+/, '');
 | 
			
		||||
@ -883,7 +883,7 @@ export class CoreH5PContentValidator {
 | 
			
		||||
 | 
			
		||||
            if (colonPos > 0) {
 | 
			
		||||
                // 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.
 | 
			
		||||
                // This must be a relative URL, which inherits the (safe) protocol of the base document.
 | 
			
		||||
                if (protocol.match(/[/?#]/)) {
 | 
			
		||||
@ -891,7 +891,7 @@ export class CoreH5PContentValidator {
 | 
			
		||||
                }
 | 
			
		||||
                // Check if this is a disallowed protocol.
 | 
			
		||||
                if (!allowedProtocols[protocol.toLowerCase()]) {
 | 
			
		||||
                    uri = uri.substr(colonPos + 1);
 | 
			
		||||
                    uri = uri.substring(colonPos + 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } while (before != uri);
 | 
			
		||||
 | 
			
		||||
@ -216,7 +216,7 @@ export class CoreH5PCore {
 | 
			
		||||
 | 
			
		||||
        // Prevent too long slug.
 | 
			
		||||
        if (newInput.length > 91) {
 | 
			
		||||
            newInput = newInput.substr(0, 92);
 | 
			
		||||
            newInput = newInput.substring(0, 92);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Prevent empty slug
 | 
			
		||||
 | 
			
		||||
@ -303,7 +303,7 @@ export class CoreQuestionHelperProvider {
 | 
			
		||||
 | 
			
		||||
                // Remove start and end of the match, we only want the object.
 | 
			
		||||
                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.
 | 
			
		||||
                question.initObjects = CoreTextUtils.parseJSON(initMatch, null);
 | 
			
		||||
 | 
			
		||||
@ -100,7 +100,7 @@ export class CoreSettingsDeviceInfoPage implements OnDestroy {
 | 
			
		||||
 | 
			
		||||
        if (window.location && 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) {
 | 
			
		||||
 | 
			
		||||
@ -232,8 +232,8 @@ export class CoreFileProvider {
 | 
			
		||||
        } else {
 | 
			
		||||
            // 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.
 | 
			
		||||
            const firstDir = path.substr(0, path.indexOf('/'));
 | 
			
		||||
            const restOfPath = path.substr(path.indexOf('/') + 1);
 | 
			
		||||
            const firstDir = path.substring(0, path.indexOf('/'));
 | 
			
		||||
            const restOfPath = path.substring(path.indexOf('/') + 1);
 | 
			
		||||
 | 
			
		||||
            this.logger.debug('Create dir ' + firstDir + ' in ' + base);
 | 
			
		||||
 | 
			
		||||
@ -692,7 +692,7 @@ export class CoreFileProvider {
 | 
			
		||||
     */
 | 
			
		||||
    async removeExternalFile(fullPath: string): Promise<void> {
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
@ -885,7 +885,7 @@ export class CoreFileProvider {
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        file.directory = path.substring(0, path.lastIndexOf('/'));
 | 
			
		||||
        file.name = path.substr(path.lastIndexOf('/') + 1);
 | 
			
		||||
        file.name = path.substring(path.lastIndexOf('/') + 1);
 | 
			
		||||
 | 
			
		||||
        return file;
 | 
			
		||||
    }
 | 
			
		||||
@ -1035,7 +1035,7 @@ export class CoreFileProvider {
 | 
			
		||||
     */
 | 
			
		||||
    removeStartingSlash(path: string): string {
 | 
			
		||||
        if (path[0] == '/') {
 | 
			
		||||
            return path.substr(1);
 | 
			
		||||
            return path.substring(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return path;
 | 
			
		||||
@ -1232,7 +1232,7 @@ export class CoreFileProvider {
 | 
			
		||||
        const position = window.location.href.indexOf(window.location.pathname);
 | 
			
		||||
 | 
			
		||||
        if (position != -1) {
 | 
			
		||||
            return window.location.href.substr(0, position);
 | 
			
		||||
            return window.location.href.substring(0, position);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return window.location.href;
 | 
			
		||||
 | 
			
		||||
@ -777,7 +777,7 @@ export class CoreFilepoolProvider {
 | 
			
		||||
                // Calculate the path to the file.
 | 
			
		||||
                path = file.filename || '';
 | 
			
		||||
                if (file.filepath && file.filepath !== '/') {
 | 
			
		||||
                    path = file.filepath.substr(1) + path;
 | 
			
		||||
                    path = file.filepath.substring(1) + path;
 | 
			
		||||
                }
 | 
			
		||||
                path = CoreTextUtils.concatenatePaths(dirPath, path);
 | 
			
		||||
            }
 | 
			
		||||
@ -871,7 +871,7 @@ export class CoreFilepoolProvider {
 | 
			
		||||
                    // Calculate the path to the file.
 | 
			
		||||
                    path = file.filename || '';
 | 
			
		||||
                    if (file.filepath && file.filepath !== '/') {
 | 
			
		||||
                        path = file.filepath.substr(1) + path;
 | 
			
		||||
                        path = file.filepath.substring(1) + path;
 | 
			
		||||
                    }
 | 
			
		||||
                    path = CoreTextUtils.concatenatePaths(dirPath, path);
 | 
			
		||||
                }
 | 
			
		||||
@ -1837,7 +1837,7 @@ export class CoreFilepoolProvider {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const relativePath = url.substr(url.indexOf('/pluginfile.php') + 16);
 | 
			
		||||
        const relativePath = url.substring(url.indexOf('/pluginfile.php') + 16);
 | 
			
		||||
        const args = relativePath.split('/');
 | 
			
		||||
 | 
			
		||||
        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.
 | 
			
		||||
            const params = CoreUrlUtils.extractUrlParams(fileUrl);
 | 
			
		||||
            if (params.file) {
 | 
			
		||||
                filename = params.file.substr(params.file.lastIndexOf('/') + 1);
 | 
			
		||||
                filename = params.file.substring(params.file.lastIndexOf('/') + 1);
 | 
			
		||||
            } else {
 | 
			
		||||
                // 'file' param not found. Extract what's after the last '/' without params.
 | 
			
		||||
                filename = CoreUrlUtils.getLastFileWithoutParams(fileUrl);
 | 
			
		||||
@ -2115,7 +2115,7 @@ export class CoreFilepoolProvider {
 | 
			
		||||
            // Remove the URL from the array.
 | 
			
		||||
            hashes.shift();
 | 
			
		||||
 | 
			
		||||
            filename = filename.substr(0, index);
 | 
			
		||||
            filename = filename.substring(0, index);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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.
 | 
			
		||||
            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'.
 | 
			
		||||
                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.
 | 
			
		||||
        if (url.indexOf('?') != -1) {
 | 
			
		||||
            url = url.substr(0, url.indexOf('?'));
 | 
			
		||||
            url = url.substring(0, url.indexOf('?'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!url.match(/https?:\/\//)) {
 | 
			
		||||
 | 
			
		||||
@ -443,7 +443,7 @@ export class CoreIframeUtilsProvider {
 | 
			
		||||
            }
 | 
			
		||||
        } else if (CoreUrlUtils.isLocalFileUrl(url)) {
 | 
			
		||||
            // It's a local file.
 | 
			
		||||
            const filename = url.substr(url.lastIndexOf('/') + 1);
 | 
			
		||||
            const filename = url.substring(url.lastIndexOf('/') + 1);
 | 
			
		||||
 | 
			
		||||
            if (!CoreFileHelper.isOpenableInApp({ filename })) {
 | 
			
		||||
                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.
 | 
			
		||||
            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 })) {
 | 
			
		||||
                try {
 | 
			
		||||
 | 
			
		||||
@ -84,13 +84,13 @@ export class CoreMimetypeUtilsProvider {
 | 
			
		||||
        // If the extension has parameters, remove them.
 | 
			
		||||
        let position = extension.indexOf('?');
 | 
			
		||||
        if (position > -1) {
 | 
			
		||||
            extension = extension.substr(0, position);
 | 
			
		||||
            extension = extension.substring(0, position);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the extension has an anchor, remove it.
 | 
			
		||||
        position = extension.indexOf('#');
 | 
			
		||||
        if (position > -1) {
 | 
			
		||||
            extension = extension.substr(0, position);
 | 
			
		||||
            extension = extension.substring(0, position);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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.
 | 
			
		||||
        if (extension && extension[0] == '.') {
 | 
			
		||||
            extension = extension.substr(1);
 | 
			
		||||
            extension = extension.substring(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return extension;
 | 
			
		||||
@ -311,12 +311,12 @@ export class CoreMimetypeUtilsProvider {
 | 
			
		||||
            // Remove params if any.
 | 
			
		||||
            position = candidate.indexOf('?');
 | 
			
		||||
            if (position > -1) {
 | 
			
		||||
                candidate = candidate.substr(0, position);
 | 
			
		||||
                candidate = candidate.substring(0, position);
 | 
			
		||||
            }
 | 
			
		||||
            // Remove anchor if any.
 | 
			
		||||
            position = candidate.indexOf('#');
 | 
			
		||||
            if (position > -1) {
 | 
			
		||||
                candidate = candidate.substr(0, position);
 | 
			
		||||
                candidate = candidate.substring(0, position);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (EXTENSION_REGEX.test(candidate)) {
 | 
			
		||||
@ -346,7 +346,7 @@ export class CoreMimetypeUtilsProvider {
 | 
			
		||||
        let ext;
 | 
			
		||||
 | 
			
		||||
        if (dot > -1) {
 | 
			
		||||
            ext = filename.substr(dot + 1).toLowerCase();
 | 
			
		||||
            ext = filename.substring(dot + 1).toLowerCase();
 | 
			
		||||
            ext = this.cleanExtension(ext);
 | 
			
		||||
 | 
			
		||||
            // Check extension corresponds to a mimetype to know if it's valid.
 | 
			
		||||
@ -589,9 +589,9 @@ export class CoreMimetypeUtilsProvider {
 | 
			
		||||
 | 
			
		||||
        if (position > -1) {
 | 
			
		||||
            // 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) {
 | 
			
		||||
                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);
 | 
			
		||||
 | 
			
		||||
        if (lastCharLeft === '/' && firstCharRight === '/') {
 | 
			
		||||
            return leftPath + rightPath.substr(1);
 | 
			
		||||
            return leftPath + rightPath.substring(1);
 | 
			
		||||
        } else if (lastCharLeft !== '/' && firstCharRight !== '/') {
 | 
			
		||||
            return leftPath + '/' + rightPath;
 | 
			
		||||
        } else {
 | 
			
		||||
@ -539,7 +539,7 @@ export class CoreTextUtilsProvider {
 | 
			
		||||
            const url = CoreFileHelper.getFileUrl(files[0]);
 | 
			
		||||
 | 
			
		||||
            // 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;
 | 
			
		||||
@ -778,9 +778,9 @@ export class CoreTextUtilsProvider {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Get the filename from the URL.
 | 
			
		||||
            let filename = url.substr(url.lastIndexOf('/') + 1);
 | 
			
		||||
            let filename = url.substring(url.lastIndexOf('/') + 1);
 | 
			
		||||
            if (filename.indexOf('?') != -1) {
 | 
			
		||||
                filename = filename.substr(0, filename.indexOf('?'));
 | 
			
		||||
                filename = filename.substring(0, filename.indexOf('?'));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (pluginfileMap[filename]) {
 | 
			
		||||
@ -904,12 +904,12 @@ export class CoreTextUtilsProvider {
 | 
			
		||||
     */
 | 
			
		||||
    shortenText(text: string, length: number): string {
 | 
			
		||||
        if (text.length > length) {
 | 
			
		||||
            text = text.substr(0, length);
 | 
			
		||||
            text = text.substring(0, length);
 | 
			
		||||
 | 
			
		||||
            // Now, truncate at the last word boundary (if exists).
 | 
			
		||||
            const lastWordPos = text.lastIndexOf(' ');
 | 
			
		||||
            if (lastWordPos > 0) {
 | 
			
		||||
                text = text.substr(0, lastWordPos);
 | 
			
		||||
                text = text.substring(0, lastWordPos);
 | 
			
		||||
            }
 | 
			
		||||
            text += '…';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -329,9 +329,9 @@ export class CoreUrlUtilsProvider {
 | 
			
		||||
     * @return Last file without params.
 | 
			
		||||
     */
 | 
			
		||||
    getLastFileWithoutParams(url: string): string {
 | 
			
		||||
        let filename = url.substr(url.lastIndexOf('/') + 1);
 | 
			
		||||
        let filename = url.substring(url.lastIndexOf('/') + 1);
 | 
			
		||||
        if (filename.indexOf('?') != -1) {
 | 
			
		||||
            filename = filename.substr(0, filename.indexOf('?'));
 | 
			
		||||
            filename = filename.substring(0, filename.indexOf('?'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return filename;
 | 
			
		||||
 | 
			
		||||
@ -1254,7 +1254,7 @@ export class CoreUtilsProvider {
 | 
			
		||||
        const mapped = {};
 | 
			
		||||
        objects.forEach((item) => {
 | 
			
		||||
            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];
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -112,7 +112,7 @@ export class CoreColors {
 | 
			
		||||
     */
 | 
			
		||||
    static hexToRGB(color: string): ColorComponents {
 | 
			
		||||
        if (color.charAt(0) == '#') {
 | 
			
		||||
            color = color.substr(1);
 | 
			
		||||
            color = color.substring(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (color.length === 3) {
 | 
			
		||||
@ -122,9 +122,9 @@ export class CoreColors {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            red: parseInt(color.substr(0, 2), 16),
 | 
			
		||||
            green: parseInt(color.substr(2, 2), 16),
 | 
			
		||||
            blue: parseInt(color.substr(4, 2), 16),
 | 
			
		||||
            red: parseInt(color.substring(0, 2), 16),
 | 
			
		||||
            green: parseInt(color.substring(2, 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
 | 
			
		||||
 | 
			
		||||
    if (escapedString && chr === '\\') {
 | 
			
		||||
      chr = String.fromCharCode(parseInt(str.substr(c + 1, 2), 16))
 | 
			
		||||
      chr = String.fromCharCode(parseInt(str.substring(c + 1, 2), 16))
 | 
			
		||||
      escapedChars++
 | 
			
		||||
 | 
			
		||||
      // each escaped sequence is 3 characters. Go 2 chars ahead.
 | 
			
		||||
@ -167,7 +167,7 @@ function expectString (str) {
 | 
			
		||||
 | 
			
		||||
  const len = parseInt(byteLenMatch, 10)
 | 
			
		||||
 | 
			
		||||
  str = str.substr(match.length)
 | 
			
		||||
  str = str.substring(match.length)
 | 
			
		||||
 | 
			
		||||
  let [ strMatch, bytes ] = readBytes(str, len)
 | 
			
		||||
 | 
			
		||||
@ -175,7 +175,7 @@ function expectString (str) {
 | 
			
		||||
    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
 | 
			
		||||
  if (!str.startsWith('";')) {
 | 
			
		||||
@ -195,7 +195,7 @@ function expectEscapedString (str) {
 | 
			
		||||
 | 
			
		||||
  const len = parseInt(strLenMatch, 10)
 | 
			
		||||
 | 
			
		||||
  str = str.substr(match.length)
 | 
			
		||||
  str = str.substring(match.length)
 | 
			
		||||
 | 
			
		||||
  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}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
  if (!str.startsWith('";')) {
 | 
			
		||||
@ -249,15 +249,15 @@ function expectObject (str, cache) {
 | 
			
		||||
  const obj = {}
 | 
			
		||||
  cache([obj])
 | 
			
		||||
 | 
			
		||||
  str = str.substr(totalOffset)
 | 
			
		||||
  str = str.substring(totalOffset)
 | 
			
		||||
 | 
			
		||||
  for (let i = 0; i < propCount; i++) {
 | 
			
		||||
    const prop = expectKeyOrIndex(str)
 | 
			
		||||
    str = str.substr(prop[1])
 | 
			
		||||
    str = str.substring(prop[1])
 | 
			
		||||
    totalOffset += prop[1] as number
 | 
			
		||||
 | 
			
		||||
    const value = expectType(str, cache)
 | 
			
		||||
    str = str.substr(value[1])
 | 
			
		||||
    str = str.substring(value[1])
 | 
			
		||||
    totalOffset += value[1]
 | 
			
		||||
 | 
			
		||||
    obj[prop[0]] = value[0]
 | 
			
		||||
@ -299,7 +299,7 @@ function expectArray (str, cache) {
 | 
			
		||||
    throw SyntaxError('Expected array length annotation')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  str = str.substr(arrayLiteralBeginMatch.length)
 | 
			
		||||
  str = str.substring(arrayLiteralBeginMatch.length)
 | 
			
		||||
 | 
			
		||||
  const array = expectArrayItems(str, parseInt(arrayLengthMatch, 10), cache)
 | 
			
		||||
 | 
			
		||||
@ -327,14 +327,14 @@ function expectArrayItems (str, expectedItems = 0, cache) {
 | 
			
		||||
      hasStringKeys = (typeof key[0] === 'string')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    str = str.substr(key[1])
 | 
			
		||||
    str = str.substring(key[1])
 | 
			
		||||
    totalOffset += key[1]
 | 
			
		||||
 | 
			
		||||
    // references are resolved immediately, so if duplicate key overwrites previous array index
 | 
			
		||||
    // the old value is anyway resolved
 | 
			
		||||
    // fixme: but next time the same reference should point to the new value
 | 
			
		||||
    item = expectType(str, cache)
 | 
			
		||||
    str = str.substr(item[1])
 | 
			
		||||
    str = str.substring(item[1])
 | 
			
		||||
    totalOffset += item[1]
 | 
			
		||||
 | 
			
		||||
    items[key[0]] = item[0]
 | 
			
		||||
@ -428,7 +428,7 @@ function substr_replace (str, replace, start, length) {
 | 
			
		||||
 | 
			
		||||
  return [
 | 
			
		||||
    str.slice(0, start),
 | 
			
		||||
    replace.substr(0, length),
 | 
			
		||||
    replace.substring(0, length),
 | 
			
		||||
    replace.slice(length),
 | 
			
		||||
    str.slice(start + length)
 | 
			
		||||
  ].join('')
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,7 @@ export class CoreText {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (text.slice(-1) == '/') {
 | 
			
		||||
            return text.substr(0, text.length - 1);
 | 
			
		||||
            return text.substring(0, text.length - 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return text;
 | 
			
		||||
 | 
			
		||||
@ -216,7 +216,7 @@ export class CoreUrl {
 | 
			
		||||
            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> {
 | 
			
		||||
        if (CoreUrlUtils.isLocalFileUrl(url)) {
 | 
			
		||||
            const filename = url.substr(url.lastIndexOf('/') + 1);
 | 
			
		||||
            const filename = url.substring(url.lastIndexOf('/') + 1);
 | 
			
		||||
 | 
			
		||||
            if (!CoreFileHelper.isOpenableInApp({ filename })) {
 | 
			
		||||
                try {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user