Dee*_*ika 7 iframe nativescript
我需要创建一个窗口对象,以便在iframe中加载的外部文件可以调用nativescript函数.
我特别需要窗口对象,因为我加载的文件可以是符合LMS的符合(SCORM)的任何文件.
谢谢
编辑:我加载的文件是符合SCORM的文件.他们搜索window.API对象/ window.parent.API等,以便开始与已加载它们的容器进行通信.我不能改变那个文件.
告诉我是否需要更多细节.
我们成功地在 NativeScript 应用程序中处理 SCORM 内容,但它确实需要一些技巧才能完成。
我编写了一个实用程序类,它将注入到 SCORM 内容的主条目文件(索引)中,并覆盖窗口 API。
背景:
实用程序类的用法示例:
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;
});
}
Run Code Online (Sandbox Code Playgroud)
实用类:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
753 次 |
| 最近记录: |