The C-level extensibility mechanism lets you implement MX extensibility files using a combination of JavaScript and your own C code. You define functions using C, bundle them in a DLL or shared library, save the library in the Configuration/JSExtensions folder within the application folder, and then call the functions from JavaScript using the JavaScript interpreter that is built into .
For example, you might want to define a object that inserts the contents of a user-specified file into the current document. Because client-side JavaScript does not provide support for file I/O, you must write a function in C to provide this functionality.
You can use the following HTML and JavaScript to create a simple Insert Text from File object. Notice that the objectTag() function calls a C function named readContentsOfFile() , which is stored in a library named myLibrary .
<HTML> <HEAD> <SCRIPT> function objectTag() { fileName = document.forms[0].myFile.value; return myLibrary.readContentsOfFile(fileName); } </SCRIPT> </HEAD> <BODY> <FORM> Enter the name of the file to be inserted: <INPUT TYPE="file" NAME="myFile"> </FORM> </BODY> </HTML>The readContentsOfFile() function accepts a list of arguments from the user, unpacks the argument that contains the filename, reads the contents of the file, and packages the contents of the file as the return value. For more information about the JavaScript data structures and functions that appear in readContentsOfFile() , see C-level extensibility and the JavaScript interpreter .
JSBool readContentsOfFile(JSContext *cx, JSObject *obj, unsigned int ¬ argc, jsval *argv, jsval *rval) { char *fileName, *fileContents; JSBool success; unsigned int length; /* Make sure caller passed in exactly one argument. If not, * then tell the interpreter to abort script execution. */ if (argc != 1){ JS_ReportError(cx, "Wrong number of arguments", 0); return JS_FALSE; } /* Convert the argument to a string */ fileName = JS_ValueToString(cx, argv[0], &length); if (fileName == NULL){ JS_ReportError(cx, "The argument must be a string", 0); return JS_FALSE; } /* Use the string (the file name) to open and read a file */ fileContents = exerciseLeftToTheReader(fileName); /* Store file contents in rval, which is the return value ¬ passed * back to the caller */ success = JS_StringToValue(cx, fileContents, 0, *rval); free(fileContents); /* Return true to continue or false to abort the script */ return success; }To ensure that the readContentsOfFile() function executes as designed rather than causing a JavaScript error, you must register the function with the JavaScript interpreter by including a function called MM_Init() in your library. When loads the library at startup, it calls the MM_Init() function to get the following three pieces of information:
The following example shows how MM_Init() function for myLibrary might look:
void MM_Init() { JS_DefineFunction("readContentsOfFile", readContentsOfFile, 1); }Your library must include exactly one instance of the following macro:
/* MM_STATE is a macro that expands to some definitions that are * needed to interact with . This macro must * be defined exactly once in your library. */ MM_STATENote: The library can be implemented in either C or C++, but the file that contains MM_Init() and MM_STATE must be implemented in C. The C++ compiler garbles function names, which makes it impossible for to find the MM_Init() function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117