gpt4 book ai didi

iframe - nativescript 中的窗口对象

转载 作者:行者123 更新时间:2023-12-04 12:57:18 24 4
gpt4 key购买 nike

我需要创建一个窗口对象,以便在 iframe 中加载的外部文件可以调用 nativescript 函数。

我,特别需要窗口对象,因为我正在加载的文件可以是任何遵循与 LMS 相关的一致性 (SCORM) 的文件。

编辑 :
我加载的文件是符合 SCORM 的文件。他们搜索 window.API 对象/window.parent.API 等,以开始与加载它们的容器进行通信。我无法更改该文件。

如果需要更多详细信息,请告诉我。

最佳答案

我们在 NativeScript 应用程序中成功地处理了 SCORM 内容,但它确实需要一些技巧来完成。

我编写了一个实用程序类,它将注入(inject)到 SCORM 内容的主条目文件(索引)中,以覆盖窗口 API。

背景:

  • 在我们的应用程序中,我们将 zip 类(class)解压缩到设备:documents/courses/UUID(这就是身份引用的内容)
  • 您可以根据实现需要更改路径

  • 实用程序类的示例用法:
    const documents = fs.knownFolders.documents();
    const destination = fs.path.join(documents.path, 'courses', this.media.identity);
    this._readAccessUrl = destination;
    const src = `file://${destination}`;
    if (fs.File.exists(destination)) {
    SCORMUtils.readSCORMManifest(this.media.identity).then(fileName => {
    this._src = `${src}/${fileName}`;
    SCORMUtils.makeOfflineCompatible(fs.path.join(destination, fileName))
    .then(() => {
    this._loading = false;
    });
    this._loading = false;
    });
    }

    实用程序类:
    import { File, knownFolders } from 'tns-core-modules/file-system';

    const SCORM_API = `
    <script type="text/javascript">
    (function () {
    window.parent.API = (function() {
    return {
    LMSInitialize: function () {
    if (window && window.webkit) {
    window.webkit.messageHandlers.print.postMessage("LMSInitialize");
    }
    return "true";
    },
    LMSCommit: function () {
    if (window && window.webkit) {
    window.webkit.messageHandlers.print.postMessage("LMSCommit");
    }
    return "true";
    },
    LMSFinish: function () {
    if (window && window.webkit) {
    window.webkit.messageHandlers.print.postMessage("LMSFinish");
    }
    return "true";
    },
    LMSGetValue: function (key) {
    if (window && window.webkit) {
    window.webkit.messageHandlers.print.postMessage("LMSGetValue");
    }
    return "";
    },
    LMSSetValue: function (key, value) {
    if (window && window.webkit) {
    window.webkit.messageHandlers.print.postMessage("LMSSetValue");
    }
    return "true";
    },
    LMSGetLastError: function () {
    if (window && window.webkit) {
    window.webkit.messageHandlers.print.postMessage("LMSGetLastError");
    }
    return "0";
    },
    LMSGetErrorString: function (errorCode) {
    if (window && window.webkit) {
    window.webkit.messageHandlers.print.postMessage("LMSGetErrorString");
    }
    return "No error";
    },
    LMSGetDiagnostic: function (errorCode) {
    if (window && window.webkit) {
    window.webkit.messageHandlers.print.postMessage("LMSGetDiagnostic");
    }
    return "No error";
    }
    }
    })();
    })();
    </script>
    </head>
    `;

    export class SCORMUtils {

    /**
    * Converts a SCORM course to be opened offline
    * @param entryFile The main entry point determined by imsmanifest.xml
    */
    static makeOfflineCompatible(entryFile: string) {
    return new Promise((resolve, reject) => {
    // Rewrite the entry file first
    this._rewriteFile(entryFile)
    .then(() => {
    this._discoverHTMLEntry(entryFile)
    .then(() => {
    resolve();
    }, () => {
    console.error('Unable to rewrite alternative HTML entry');
    reject();
    });
    }, () => {
    console.error(`Unable to rewrite primary entry point: ${entryFile}`);
    reject();
    });
    });
    }

    /**
    * Digests a SCORM Manifest file to determine the main point of entry
    * for the course viewer. Normally this is a index.html file.
    */
    static readSCORMManifest(identity: string): Promise<string> {
    return new Promise((resolve, reject) => {
    const manifestFile = knownFolders.documents()
    .getFolder('courses')
    .getFolder(identity)
    .getFile('imsmanifest.xml');
    if (!File.exists(manifestFile.path)) {
    alert({
    title: 'Error',
    message: 'Course is missing imsmanifest.xml file',
    okButtonText: 'Ok'
    });
    return reject();
    }
    const data = manifestFile.readTextSync(() => {
    alert({
    title: 'Error',
    message: 'Cannot open course.',
    okButtonText: 'Ok'
    });
    return reject();
    });
    const matches = data.match(/type="webcontent"+.+?href="(.*?)"/);
    if (matches === null || matches.length < 1) {
    alert({
    title: 'Error',
    message: 'Invalid imsmanifest.xml file',
    okButtonText: 'Ok'
    });
    }
    else {
    resolve(matches[1]);
    }
    });
    }

    /**
    * Rewrites a file to be SCORM offline-compliant
    * @param path The path of the file to re-write
    */
    private static _rewriteFile(path: string) {
    return new Promise((resolve, reject) => {
    const entryFile = File.fromPath(path);
    entryFile.readText()
    .then(htmlText => {
    this._injectOfflineAPI(htmlText)
    .then(updatedHtml => {
    entryFile.writeText(updatedHtml).then(() => {
    resolve();
    }, () => {
    console.error(`Error writing to file: ${path}`);
    reject();
    });
    });
    }, () => {
    console.error(`There was an entry reading the entry file at: ${path}`);
    reject();
    });
    });
    }

    /**
    * Attempts to find another SCORM entry point for re-write
    * @param mainEntry The main entry point to branch from
    */
    private static _discoverHTMLEntry(mainEntry: string): Promise<any> {
    return new Promise((resolve, reject) => {
    const entryFile = File.fromPath(mainEntry);
    entryFile.readText()
    .then(htmlText => {
    let htmlEntry = htmlText.match(/{"type":"html5","url":"(.*?)"}/);
    if (htmlEntry === null || htmlEntry.length < 1) {
    // Check for Articulate
    htmlEntry = htmlText.match(/location\.href\.replace\("index_lms", "(.*?)"/);
    }
    if (htmlEntry !== null && htmlEntry.length > 0) {
    let fileName = htmlEntry[1];
    if (fileName.indexOf('.html') === -1) {
    fileName = `${fileName}.html`;
    }
    const directory = mainEntry.substr(0, mainEntry.lastIndexOf('/'));
    const entryPoint = `${directory}/${fileName}`;
    if (File.exists(entryPoint)) {
    this._rewriteFile(entryPoint)
    .then(() => {
    resolve();
    }, () => {
    console.error('Error discovering main entry point.');
    reject();
    });
    }
    else {
    console.error(`Cannot find alternative entry point: ${entryPoint}`);
    reject();
    }
    }
    else {
    // This course does not have an alternative entry point
    console.error('Course does not have an alternative entry, skipping...');
    resolve();
    }
    }, () => {
    reject();
    });
    });
    }

    /**
    * Injects the extended SCORM API for offline-compatible viewing
    * @param text The unmodified HTML source text
    */
    private static _injectOfflineAPI(text: string): Promise<string> {
    return new Promise((resolve, reject) => {
    // Prevent multiple rewrites of the same file
    if (this._isConverted(text)) {
    return resolve(text);
    }
    // Finds the end of the head tag for script injection
    const head = text.match(/<\/head>/gi);
    if (head !== null && head.length > 0) {
    resolve(text.replace(head.toString(), SCORM_API));
    }
    else {
    console.error('Unable to parse incoming HTML for head tag.');
    reject({
    message: 'Unable to parse HTML'
    });
    }
    });
    }

    /**
    * Checks if the HTML has already been converted for offline-viewing
    * @param text The incoming HTML source text
    */
    private static _isConverted(text: string) {
    const match = text.match(/window.parent.API/);
    return match !== null && match.length > 0;
    }

    }

    关于iframe - nativescript 中的窗口对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46426848/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com