2017-09-26 20 views
7

में विंडो ऑब्जेक्ट मुझे विंडो ऑब्जेक्ट बनाने की आवश्यकता है ताकि बाहरी फ़ाइल, जो iframe के अंदर लोड हो, नेटिवस्क्रिप्ट फ़ंक्शन को कॉल कर सकती है।मूल ऑब्जेक्ट्स

मुझे विशेष रूप से विंडो ऑब्जेक्ट की आवश्यकता है क्योंकि फ़ाइल जो मैं लोड कर रहा हूं वह कोई भी फ़ाइल हो सकती है जो एलएमएस से संबंधित अनुरूप (एससीओआरएम) का पालन करती है।

धन्यवाद

संपादित: फ़ाइल मैं भरी हुई है एक SCORM अनुरूप फ़ाइल है। वे कंटेनर के साथ संचार शुरू करने के लिए, जिन्हें वे लोड कर चुके हैं, विंडो.एपीआई ऑब्जेक्ट/window.parent.API और इसी तरह की खोज करते हैं। मैं उस फाइल को बदल नहीं सकता।

मुझे बताएं कि अधिक जानकारी की आवश्यकता है या नहीं।

+0

कृपया टिप्पणी करें क्यों डाउनवोट? – Deepika

+0

ब्राउज़र में 'विंडो' यह है कि वैश्विक जावास्क्रिप्ट ऑब्जेक्ट का नाम कैसे दिया जाता है, यह कुछ ऑब्जेक्ट्स और फ़ंक्शंस का खुलासा करता है जो केवल ब्राउज़र के संदर्भ में मान्य होते हैं और कहीं और नहीं। मूल निवासी में कोई 'विंडो' नहीं है, न तो iframes हैं। यदि आप कुछ कार्यक्षमता का मज़ाक उड़ाना चाहते हैं, तो 'global.window' संपत्ति बनाना पूरी तरह ठीक है। इसके अलावा, आप जो हासिल करने की कोशिश कर रहे हैं उसका एक और विशिष्ट वर्णन हमें आपको कहां देखना है, इस पर पॉइंटर्स देने की अनुमति देगा। – pkanev

+0

धन्यवाद @pkanev, क्या आप लिंक साझा कर सकते हैं ताकि मैं इसका उल्लेख कर सकूं। – Deepika

उत्तर

0

हम अपने नेटस्क्रिप्ट एप्लिकेशन में सफलतापूर्वक एससीओआरएम सामग्री को संभालने में कामयाब रहे हैं, लेकिन इसे पूरा करने के लिए हैकरी की थोड़ी सी आवश्यकता होती है।

मैंने एक उपयोगिता वर्ग लिखा है जो एससीओआरएम सामग्री की मुख्य प्रविष्टि फ़ाइल (अनुक्रमणिका) में विंडो एपीआई के लिए ओवरराइड में इंजेक्ट करेगा।

पृष्ठभूमि:

  • हमारे एप्लिकेशन में हम उपकरणों के लिए ज़िप पाठ्यक्रमों को संपीड़ित: दस्तावेज/पाठ्यक्रम/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; 
    } 

} 
+0

अरे @ सेन आप डेटा संचार कैसे कर रहे हैं, जैसे कि LMSGetValue ट्रिगर किया गया है। – Deepika

+0

WKWebView कार्यान्वयन फ्रेम से उत्सर्जित संदेशों को सुनने के लिए अनुमति देता है: https://github.com/triniwiz/nativescript-webkit-webview/blob/master/src/webkit-webview.ios.ts#L384। हमने व्यक्तिगत रूप से उन लोगों में शामिल नहीं किया है, लेकिन मैंने भविष्य में कार्यान्वयन के लिए उन पोस्ट मैसेज हुक को जोड़ा है। –

+0

मैंने market.nativescript.org/plugins/nativescript-webview-interfa ce प्लगइन स्थापित किया है जो मुझे संवाद करने और मूलभूत पक्ष से मूल्य वापस करने में मदद करता है। – Deepika

संबंधित मुद्दे