Fossil

Check-in [a54a2c6ac3]
Login

Check-in [a54a2c6ac3]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added mjs (ES6 modules) mimetype. Changed JS mimetype from application/javascript to text/javascript to conform with the HTML spec. application/javascript is commonly used in the wild.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | pikchrshow-wasm
Files: files | file ages | folders
SHA3-256: a54a2c6ac3d7850b1373ee62fb3a245e79964701dbebe8241052ba6d537b4d7f
User & Date: stephan 2022-06-08 10:08:50.919
Context
2022-06-08
10:09
build.wiki: added notes about emsdk requirements and keeping it up to date. ... (check-in: b256c5bc7b user: stephan tags: pikchrshow-wasm)
10:08
Added mjs (ES6 modules) mimetype. Changed JS mimetype from application/javascript to text/javascript to conform with the HTML spec. application/javascript is commonly used in the wild. ... (check-in: a54a2c6ac3 user: stephan tags: pikchrshow-wasm)
08:44
Added missing section numbers 7.0 and 8.0 to the two newest sections in build.wiki. ... (check-in: fb9f3dcce6 user: stephan tags: pikchrshow-wasm)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/builtin.c.
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  blob_init(&x, (const char*)pData, nByte);
  blob_write_to_file(&x, g.argc==4 ? g.argv[3] : "-");
  blob_reset(&x);
}

/*
** Input zList is a list of numeric identifiers for files in
** aBuiltinFiles[].  Return the concatenation of all of those
** files using mimetype zType, or as application/javascript if
** zType is 0.
*/
static void builtin_deliver_multiple_js_files(
  const char *zList,   /* List of numeric identifiers */
  const char *zType    /* Override mimetype */
){
  Blob *pOut;
  if( zType==0 ) zType = "application/javascript";
  cgi_set_content_type(zType);
  pOut = cgi_output_blob();
  while( zList[0] ){
    int i = atoi(zList);
    if( i>0 && i<=count(aBuiltinFiles) ){
      blob_appendf(pOut, "/* %s */\n", aBuiltinFiles[i-1].zName);
      blob_append(pOut, (const char*)aBuiltinFiles[i-1].pData,







|
|
<






|







128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
144
145
146
147
148
149
150
  blob_init(&x, (const char*)pData, nByte);
  blob_write_to_file(&x, g.argc==4 ? g.argv[3] : "-");
  blob_reset(&x);
}

/*
** Input zList is a list of numeric identifiers for files in
** aBuiltinFiles[].  Return the concatenation of all of those files
** using mimetype zType, or as text/javascript if zType is 0.

*/
static void builtin_deliver_multiple_js_files(
  const char *zList,   /* List of numeric identifiers */
  const char *zType    /* Override mimetype */
){
  Blob *pOut;
  if( zType==0 ) zType = "text/javascript";
  cgi_set_content_type(zType);
  pOut = cgi_output_blob();
  while( zList[0] ){
    int i = atoi(zList);
    if( i>0 && i<=count(aBuiltinFiles) ){
      blob_appendf(pOut, "/* %s */\n", aBuiltinFiles[i-1].zName);
      blob_append(pOut, (const char*)aBuiltinFiles[i-1].pData,
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
    }
    cgi_set_status(404, "Not Found");
    @ File "%h(zName)" not found
    return;
  }
  if( zType==0 ){
    if( sqlite3_strglob("*.js", zName)==0 ){
      zType = "application/javascript";
    }else{
      zType = mimetype_from_name(zName);
    }
  }
  cgi_set_content_type(zType);
  if( zId
   && (nId = (int)strlen(zId))>=8







|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
    }
    cgi_set_status(404, "Not Found");
    @ File "%h(zName)" not found
    return;
  }
  if( zType==0 ){
    if( sqlite3_strglob("*.js", zName)==0 ){
      zType = "text/javascript";
    }else{
      zType = mimetype_from_name(zName);
    }
  }
  cgi_set_content_type(zType);
  if( zId
   && (nId = (int)strlen(zId))>=8
Changes to src/doc.c.
154
155
156
157
158
159
160
161





162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
  { "ips",        3, "application/x-ipscript"            },
  { "ipx",        3, "application/x-ipix"                },
  { "jad",        3, "text/vnd.sun.j2me.app-descriptor"  },
  { "jar",        3, "application/java-archive"          },
  { "jpe",        3, "image/jpeg"                        },
  { "jpeg",       4, "image/jpeg"                        },
  { "jpg",        3, "image/jpeg"                        },
  { "js",         2, "application/javascript"            },





  { "kar",        3, "audio/midi"                        },
  { "latex",      5, "application/x-latex"               },
  { "lha",        3, "application/octet-stream"          },
  { "lsp",        3, "application/x-lisp"                },
  { "lzh",        3, "application/octet-stream"          },
  { "m",          1, "text/plain"                        },
  { "m3u",        3, "audio/x-mpegurl"                   },
  { "man",        3, "text/plain"                        },
  { "markdown",   8, "text/x-markdown"                   },
  { "md",         2, "text/x-markdown"                   },
  { "me",         2, "application/x-troff-me"            },
  { "mesh",       4, "model/mesh"                        },
  { "mid",        3, "audio/midi"                        },
  { "midi",       4, "audio/midi"                        },
  { "mif",        3, "application/x-mif"                 },
  { "mime",       4, "www/mime"                          },

  { "mkd",        3, "text/x-markdown"                   },
  { "mov",        3, "video/quicktime"                   },
  { "movie",      5, "video/x-sgi-movie"                 },
  { "mp2",        3, "audio/mpeg"                        },
  { "mp3",        3, "audio/mpeg"                        },
  { "mp4",        3, "video/mp4"                         },
  { "mpe",        3, "video/mpeg"                        },







|
>
>
>
>
>
















>







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  { "ips",        3, "application/x-ipscript"            },
  { "ipx",        3, "application/x-ipix"                },
  { "jad",        3, "text/vnd.sun.j2me.app-descriptor"  },
  { "jar",        3, "application/java-archive"          },
  { "jpe",        3, "image/jpeg"                        },
  { "jpeg",       4, "image/jpeg"                        },
  { "jpg",        3, "image/jpeg"                        },
  { "js",         2, "text/javascript"                   },
  /* application/javascript is commonly used for JS, but the
  ** spec says text/javascript is correct:
  ** https://html.spec.whatwg.org/multipage/scripting.html
  ** #scriptingLanguages:javascript-mime-type */
  { "json",       4, "application/json"                  },
  { "kar",        3, "audio/midi"                        },
  { "latex",      5, "application/x-latex"               },
  { "lha",        3, "application/octet-stream"          },
  { "lsp",        3, "application/x-lisp"                },
  { "lzh",        3, "application/octet-stream"          },
  { "m",          1, "text/plain"                        },
  { "m3u",        3, "audio/x-mpegurl"                   },
  { "man",        3, "text/plain"                        },
  { "markdown",   8, "text/x-markdown"                   },
  { "md",         2, "text/x-markdown"                   },
  { "me",         2, "application/x-troff-me"            },
  { "mesh",       4, "model/mesh"                        },
  { "mid",        3, "audio/midi"                        },
  { "midi",       4, "audio/midi"                        },
  { "mif",        3, "application/x-mif"                 },
  { "mime",       4, "www/mime"                          },
  { "mjs",        3, "text/javascript" /*EM6 modules*/   },
  { "mkd",        3, "text/x-markdown"                   },
  { "mov",        3, "video/quicktime"                   },
  { "movie",      5, "video/x-sgi-movie"                 },
  { "mp2",        3, "audio/mpeg"                        },
  { "mp3",        3, "audio/mpeg"                        },
  { "mp4",        3, "video/mp4"                         },
  { "mpe",        3, "video/mpeg"                        },
Changes to src/json.c.
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
}

/*
** Guesses a RESPONSE Content-Type value based (primarily) on the
** HTTP_ACCEPT header.
**
** It will try to figure out if the client can support
** application/json or application/javascript, and will fall back to
** text/plain if it cannot figure out anything more specific.
**
** Returned memory is static and immutable, but if the environment
** changes after calling this then subsequent calls to this function
** might return different (also static/immutable) values.
*/
char const * json_guess_content_type(){
  char const * cset;
  char doUtf8;
  cset = PD("HTTP_ACCEPT_CHARSET",NULL);
  doUtf8 = ((NULL == cset) || (NULL!=strstr("utf-8",cset)))
    ? 1 : 0;
  if( g.json.jsonp ){
    return doUtf8
      ? "application/javascript; charset=utf-8"
      : "application/javascript";
  }else{
    /*
      Content-type

      If the browser does not sent an ACCEPT for application/json
      then we fall back to text/plain.
    */







|














|
|







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
}

/*
** Guesses a RESPONSE Content-Type value based (primarily) on the
** HTTP_ACCEPT header.
**
** It will try to figure out if the client can support
** application/json, text/javascript, and will fall back to
** text/plain if it cannot figure out anything more specific.
**
** Returned memory is static and immutable, but if the environment
** changes after calling this then subsequent calls to this function
** might return different (also static/immutable) values.
*/
char const * json_guess_content_type(){
  char const * cset;
  char doUtf8;
  cset = PD("HTTP_ACCEPT_CHARSET",NULL);
  doUtf8 = ((NULL == cset) || (NULL!=strstr("utf-8",cset)))
    ? 1 : 0;
  if( g.json.jsonp ){
    return doUtf8
      ? "text/javascript; charset=utf-8"
      : "text/javascript";
  }else{
    /*
      Content-type

      If the browser does not sent an ACCEPT for application/json
      then we fall back to text/plain.
    */
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

640
641
642
643
644
645
646
  }
}

/*
 ** Given a request CONTENT_TYPE value, this function returns true
 ** if it is of a type which the JSON API can ostensibly read.
 **
 ** It accepts any of application/json, text/plain, or
 ** application/javascript. The former is preferred, but was not
 ** widespread when this API was initially built, so the latter forms
 ** are permitted as fallbacks.
 */
int json_can_consume_content_type(const char * zType){
  return fossil_strcmp(zType, "application/json")==0
    || fossil_strcmp(zType,"text/plain")==0/*assume this MIGHT be JSON*/

    || fossil_strcmp(zType,"application/javascript")==0;
}

/*
** Sends pResponse to the output stream as the response object.  This
** function does no validation of pResponse except to assert() that it
** is not NULL. The caller is responsible for ensuring that it meets
** API response envelope conventions.
**
** In CLI mode pResponse is sent to stdout immediately. In HTTP
** mode pResponse replaces any current CGI content but cgi_reply()
** is not called to flush the output.
**
** If g.json.jsonp is not NULL then the content type is set to
** application/javascript and the output is wrapped in a jsonp
** wrapper.
*/
void json_send_response( cson_value const * pResponse ){
  assert( NULL != pResponse );
  if( g.isHTTP ){
    cgi_reset_content();
    if( g.json.jsonp ){

      cgi_printf("%s(",g.json.jsonp);
    }
    cson_output( pResponse, cson_data_dest_cgi, NULL, &g.json.outOpt );
    if( g.json.jsonp ){
      cgi_append_content(")",1);
    }
  }else{/*CLI mode*/







|
|
|
|




>














|







>







603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
  }
}

/*
 ** Given a request CONTENT_TYPE value, this function returns true
 ** if it is of a type which the JSON API can ostensibly read.
 **
 ** It accepts any of application/json, text/plain,
 ** application/javascript, or text/javascript. The former is
 ** preferred, but was not widespread when this API was initially
 ** built, so the latter forms are permitted as fallbacks.
 */
int json_can_consume_content_type(const char * zType){
  return fossil_strcmp(zType, "application/json")==0
    || fossil_strcmp(zType,"text/plain")==0/*assume this MIGHT be JSON*/
    || fossil_strcmp(zType,"text/javascript")==0
    || fossil_strcmp(zType,"application/javascript")==0;
}

/*
** Sends pResponse to the output stream as the response object.  This
** function does no validation of pResponse except to assert() that it
** is not NULL. The caller is responsible for ensuring that it meets
** API response envelope conventions.
**
** In CLI mode pResponse is sent to stdout immediately. In HTTP
** mode pResponse replaces any current CGI content but cgi_reply()
** is not called to flush the output.
**
** If g.json.jsonp is not NULL then the content type is set to
** text/javascript and the output is wrapped in a jsonp
** wrapper.
*/
void json_send_response( cson_value const * pResponse ){
  assert( NULL != pResponse );
  if( g.isHTTP ){
    cgi_reset_content();
    if( g.json.jsonp ){
      cgi_set_content_type("text/javascript");
      cgi_printf("%s(",g.json.jsonp);
    }
    cson_output( pResponse, cson_data_dest_cgi, NULL, &g.json.outOpt );
    if( g.json.jsonp ){
      cgi_append_content(")",1);
    }
  }else{/*CLI mode*/
Changes to src/style.c.
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
** Generate code to load all required javascript files.
*/
static void style_load_all_js_files(void){
  if( needHrefJs && g.perm.Hyperlink ){
    int nDelay = db_get_int("auto-hyperlink-delay",0);
    int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
                   && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
    @ <script id='href-data' type='application/json'>\
    @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
  }
  @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
  @ function debugMsg(msg){
  @ var n = document.getElementById("debugMsg");
  @ if(n){n.textContent=msg;}
  @ }







|







899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
** Generate code to load all required javascript files.
*/
static void style_load_all_js_files(void){
  if( needHrefJs && g.perm.Hyperlink ){
    int nDelay = db_get_int("auto-hyperlink-delay",0);
    int bMouseover = db_get_boolean("auto-hyperlink-mouseover",0)
                   && sqlite3_strglob("*Android*",PD("HTTP_USER_AGENT",""));
    @ <script id='href-data' type='text/json'>\
    @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script>
  }
  @ <script nonce="%h(style_nonce())">/* style.c:%d(__LINE__) */
  @ function debugMsg(msg){
  @ var n = document.getElementById("debugMsg");
  @ if(n){n.textContent=msg;}
  @ }
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
  const char *zScript = skin_get("js");
  if( P("test") ){
    /* Render the script as plain-text for testing purposes, if the "test"
    ** query parameter is present */
    cgi_set_content_type("text/plain");
  }else{
    /* Default behavior is to return javascript */
    cgi_set_content_type("application/javascript");
  }
  style_init_th1_vars(0);
  Th_Render(zScript?zScript:"");
}

/*
** Check for "name" or "page" query parameters on an /style.css







|







1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
  const char *zScript = skin_get("js");
  if( P("test") ){
    /* Render the script as plain-text for testing purposes, if the "test"
    ** query parameter is present */
    cgi_set_content_type("text/plain");
  }else{
    /* Default behavior is to return javascript */
    cgi_set_content_type("text/javascript");
  }
  style_init_th1_vars(0);
  Th_Render(zScript?zScript:"");
}

/*
** Check for "name" or "page" query parameters on an /style.css