简体   繁体   中英

Using functions from external JavaScript libraries in Moodle plugins

I am making a Moodle plugin and wanted to use bowser to detect the user's web browser. I referenced the file by putting

$PAGE->requires->js( new moodle_url($CFG->wwwroot.MOODLE_TINYMCE_RECORDRTC_ROOT.'tinymce/js/bowser.js') );

in the plugin's plugintype_pluginname.php file (placeholders of course), and I call the bowser function from the plugin's module.js file.

When I load the plugin (it appears as a button in TinyMCE), the console throws ReferenceError: bowser not defined , so I'm assuming this means Moodle doesn't make the functions in Bowser globally available.

I read many in many places that I need to wrap my code in an AMD, or something to that effect, but after lots of reading it still goes over my head. Is there any way to make bowser's functions available to the main plugin module?

Note: This works for me in Moodle 3.3.2, ymmv.

Put bowser.js into my_plugin_folder/amd/src/ .

When using the original bowser.js I got Uncaught TypeError: bowser._detect is not a function . I don't exactly understand why I get this error but here's one way to fix it: Replace the top code block in bowser.js with this one from umdjs/umd .

Your file should now look like this:

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define([], factory);
    } else if (typeof module === 'object' && module.exports) {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();
    } else {
        // Browser globals (root is window)
        root.returnExports = factory();
    }
}(typeof self !== 'undefined' ? self : this, function () {

    // module definition here

    return bowser
}));

Moodle bundles all JavaScript modules together so that clients don't need to perform a separate HTTP request to get each one. This bundle is called first.js . It contains all modules that aren't lazy-loaded. If you load a Moodle page now it should contain the contents of bowser.js with some values replaced by Moodle.

If you don't want bowser to be loaded on every page, you can just rename it to bowser-lazy.js . Then it should only be loaded when you use it.


You can test if it worked by calling:

require(['plugintype_pluginname/bowser'], function(bowser) {
    var ua = bowser._detect(navigator.userAgent);
    console.log(ua);
});

Seems like you need to change the require call to use bowser-lazy instead of bowser when you want to use lazy-loading.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM