Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | /wikiedit and /fileedit now dump all of their common static JS into a single SCRIPT tag instead of making numerous requests, per forum feedback. Fixed/expanded some of the newer script-emitting logic in style.c to handle these. wikiedit no longer mangles the page-level header. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | ajax-wiki-editor |
| Files: | files | file ages | folders |
| SHA3-256: |
a4b73fd081e9bb45d57da293693ca70d |
| User & Date: | stephan 2020-07-31 14:44:49.006 |
Context
|
2020-07-31
| ||
| 16:14 | Extended /builtin/filename to support /builtin/:filename for packing up cacheable bundles of page-specific code. /wikiedit, /fileedit, and /forumpost now serve their JS that way. ... (check-in: 18da05b903 user: stephan tags: ajax-wiki-editor) | |
| 14:44 | /wikiedit and /fileedit now dump all of their common static JS into a single SCRIPT tag instead of making numerous requests, per forum feedback. Fixed/expanded some of the newer script-emitting logic in style.c to handle these. wikiedit no longer mangles the page-level header. ... (check-in: a4b73fd081 user: stephan tags: ajax-wiki-editor) | |
| 12:35 | Minor style tweaks after trying the editor in different skins. ... (check-in: 7418144b3f user: stephan tags: ajax-wiki-editor) | |
Changes
Changes to src/fileedit.c.
| ︙ | ︙ | |||
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 |
db_end_transaction(0/*noting that dry-run mode will have already
** set this to rollback mode. */);
fossil_free(zNewUuid);
blob_reset(&err);
blob_reset(&manifest);
CheckinMiniInfo_cleanup(&cimi);
}
/*
** WEBPAGE: fileedit
**
** Enables the online editing and committing of individual text files.
** Requires that the user have Write permissions.
**
| > > > > > > > > > > > > > > > > > > > > > > > > > | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 |
db_end_transaction(0/*noting that dry-run mode will have already
** set this to rollback mode. */);
fossil_free(zNewUuid);
blob_reset(&err);
blob_reset(&manifest);
CheckinMiniInfo_cleanup(&cimi);
}
/*
** Emits all of the "core" static JS needed by /fileedit into a single
** SCRIPT tag.
**
** TODO: a common mechanism which will let us bundle this type of
** blob into a single cacheable request.
*/
static void fileedit_emit_js(void){
style_emit_script_tag(0,0);
style_emit_script_fossil_bootstrap(1);
style_emit_script_builtin(1,0,"sbsdiff.js");
style_emit_script_fetch(1,0);
style_emit_script_tabs(1,0)/*also emits fossil.dom*/;
style_emit_script_confirmer(1,0);
style_emit_script_builtin(1, 0, "fossil.storage.js");
/*
** Set up a JS-side mapping of the AJAX_RENDER_xyz values. This is
** used for dynamically toggling certain UI components on and off.
** Must come before fossil.page.fileedit.js.
*/
ajax_emit_js_preview_modes(0);
style_emit_script_builtin(1, 0, "fossil.page.fileedit.js");
style_emit_script_tag(1,0);
}
/*
** WEBPAGE: fileedit
**
** Enables the online editing and committing of individual text files.
** Requires that the user have Write permissions.
**
|
| ︙ | ︙ | |||
1947 1948 1949 1950 1951 1952 1953 |
blob_appendf(&endScript,"}");
}
blob_appendf(&endScript,");\n");
}
blob_reset(&err);
CheckinMiniInfo_cleanup(&cimi);
| < < < < < < | < < < < < < < < | 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 |
blob_appendf(&endScript,"}");
}
blob_appendf(&endScript,");\n");
}
blob_reset(&err);
CheckinMiniInfo_cleanup(&cimi);
fileedit_emit_js();
if(blob_size(&endScript)>0){
style_emit_script_tag(0,0);
CX("\n(function(){\n");
CX("try{\n%b}\n"
"catch(e){"
"fossil.error(e); console.error('Exception:',e);"
"}\n",
|
| ︙ | ︙ |
Changes to src/forum.c.
| ︙ | ︙ | |||
759 760 761 762 763 764 765 |
*/
static void forum_emit_page_js(){
static int once = 0;
if(0==once){
once = 1;
style_load_js("forum.js");
style_emit_script_fossil_bootstrap(0);
| | | | 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 |
*/
static void forum_emit_page_js(){
static int once = 0;
if(0==once){
once = 1;
style_load_js("forum.js");
style_emit_script_fossil_bootstrap(0);
style_emit_script_dom(0, 1);
style_emit_script_builtin(0, 1, "fossil.page.forumpost.js");
}
}
/*
** WEBPAGE: forumpost
**
** Show a single forum posting. The posting is shown in context with
|
| ︙ | ︙ |
Changes to src/fossil.page.wikiedit.js.
| ︙ | ︙ | |||
795 796 797 798 799 800 801 |
/**
Update the page title and header based on the state of
this.winfo. A no-op if this.winfo is not set. Returns this.
*/
P.updatePageTitle = function f(){
if(!f.titleElement){
f.titleElement = document.head.querySelector('title');
| | | | | < | 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 |
/**
Update the page title and header based on the state of
this.winfo. A no-op if this.winfo is not set. Returns this.
*/
P.updatePageTitle = function f(){
if(!f.titleElement){
f.titleElement = document.head.querySelector('title');
f.pageTitleHeader = document.querySelector('#wikiedit-page-name > span');
}
const title = ['Wiki Editor:'];
const wi = P.winfo;
if(wi){
if(!wi.version && 'sandbox'!==wi.type) title.push(P.config.editStateMarkers.isNew);
else if($stash.getWinfo(wi)) title.push(P.config.editStateMarkers.isModified)
title.push(wi.name);
}else{
title.push('(no page loaded)');
}
f.pageTitleHeader.innerText = title[1];
f.titleElement.innerText = title.join(' ');
return this;
};
/**
Change the save button depending on whether we have stuff to save
or not.
*/
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
1533 1534 1535 1536 1537 1538 1539 | /* ** The first time this is called, it emits code to install and ** bootstrap the window.fossil object, using the built-in file ** fossil.bootstrap.js (not to be confused with bootstrap.js). ** ** Subsequent calls are no-ops. ** | | | | | > > > | | | > > | > | 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 |
/*
** The first time this is called, it emits code to install and
** bootstrap the window.fossil object, using the built-in file
** fossil.bootstrap.js (not to be confused with bootstrap.js).
**
** Subsequent calls are no-ops.
**
** It emits 2 parts:
**
** 1) window.fossil core object, some of which depends on C-lelel
** runtime data. That part of the script is always emitted inline. If
** addScripTag is true then it is wrapped in its own SCRIPT tag, else
** it is assumed that the caller already opened a tag.
**
** 2) Emits the static fossil.bootstrap.js. If asInline is true then
** it is emitted inline with the components from (1), else it is
** emitted as a separate SCRIPT tag with
** src=/builtin/fossil.bootstrap.js (so causes another HTTP request).
*/
void style_emit_script_fossil_bootstrap(int asInline){
static int once = 0;
if(0==once++){
/* Set up the generic/app-agnostic parts of window.fossil
** which require C-level state... */
if(asInline==0){
style_emit_script_tag(0,0);
}
CX("(function(){\n"
"if(!window.fossil) window.fossil={};\n"
"window.fossil.version = %!j;\n"
/* fossil.rootPath is the top-most CGI/server path,
** including a trailing slash. */
"window.fossil.rootPath = %!j+'/';\n",
get_version(), g.zTop);
|
| ︙ | ︙ | |||
1577 1578 1579 1580 1581 1582 1583 |
*/
CX("window.fossil.page = {"
"name:\"%T\""
"};\n", g.zPath);
CX("})();\n");
/* The remaining fossil object bootstrap code is not dependent on
** C-runtime state... */
| | | | < | | 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 |
*/
CX("window.fossil.page = {"
"name:\"%T\""
"};\n", g.zPath);
CX("})();\n");
/* The remaining fossil object bootstrap code is not dependent on
** C-runtime state... */
if(asInline!=0){
CX("%s\n", builtin_text("fossil.bootstrap.js"));
}else{
style_emit_script_tag(1,0);
style_emit_script_builtin(0,1,"fossil.bootstrap.js");
}
}
}
/*
** If passed 0 as its first argument, it emits a script opener tag
** with this request's nonce. If passed non-0 it emits a script
|
| ︙ | ︙ | |||
1620 1621 1622 1623 1624 1625 1626 |
CX("</script>\n");
}
}
/*
** Emits a script tag which uses content from a builtin script file.
**
| | > | > > | > < < | > > > > | | | > > > > | | | < | < < < < | | | < | < < < < | | | 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 |
CX("</script>\n");
}
}
/*
** Emits a script tag which uses content from a builtin script file.
**
** If asInline is false, the script is emitted as a SCRIPT tag with a
** src attribute of /builtin/zName and the 2nd parameter is
** ignored. If asInline is true then the contents of the script are
** emitted directly, with a wrapping SCRIPT tag if addScripTag is
** true, else no wrapping script tag..
**
** If it is false, a script tag loading it via
** src=builtin/{{zName}}?cache=XYZ is emitted, where XYZ is a
** build-time-dependent cache-buster value.
*/
void style_emit_script_builtin(int asInline, int addScripTag,
char const * zName){
if(asInline){
CX("%s", builtin_text(zName));
}else{
char * zFullName = mprintf("builtin/%s",zName);
const char * zHash = fossil_exe_id();
CX("<script src='%R/%T?cache=%.8s'></script>\n",
zFullName, zHash);
fossil_free(zFullName);
}
}
/*
** The first time this is called it emits the JS code from the
** built-in file fossil.fossil.js. Subsequent calls are no-ops.
**
** If passed a true first argument, it emits the contents directly
** to the page output, else it emits a script tag with a
** src=builtin/... to load the script.
**
** If asInline is true and addScripTag is true then the contents
** are emitted directly but wrapped in a SCRIPT tag. If asInline
** is false, addScriptTag is ignored.
**
** Note that this code relies on that loaded via
** style_emit_script_fossil_bootstrap() but it does not call that
** routine.
*/
void style_emit_script_fetch(int asInline, int addScripTag){
static int once = 0;
if(0==once++){
style_emit_script_builtin(asInline, addScripTag, "fossil.fetch.js");
}
}
/*
** The first time this is called it emits the JS code from the
** built-in file fossil.dom.js. Subsequent calls are no-ops.
**
** If passed a true first argument, it emits the contents directly
** to the page output, else it emits a script tag with a
** src=builtin/... to load the script.
**
** If asInline is true and addScripTag is true then the contents
** are emitted directly but wrapped in a SCRIPT tag. If asInline
** is false, addScriptTag is ignored.
**
** Note that this code relies on that loaded via
** style_emit_script_fossil_bootstrap(), but it does not call that
** routine.
*/
void style_emit_script_dom(int asInline, int addScripTag){
static int once = 0;
if(0==once++){
style_emit_script_builtin(asInline, addScripTag, "fossil.dom.js");
}
}
/*
** The fossil.tabs.js counterpart of style_emit_script_fetch().
** Also emits fossil.dom.js.
*/
void style_emit_script_tabs(int asInline, int addScripTag){
static int once = 0;
if(0==once++){
style_emit_script_dom(asInline, addScripTag);
style_emit_script_builtin(asInline, addScripTag, "fossil.tabs.js");
}
}
/*
** The fossil.confirmer.js counterpart of style_emit_script_fetch().
*/
void style_emit_script_confirmer(int asInline, int addScripTag){
static int once = 0;
if(0==once++){
style_emit_script_builtin(asInline, 0, "fossil.confirmer.js");
}
}
|
Changes to src/style.wikiedit.css.
| ︙ | ︙ | |||
114 115 116 117 118 119 120 |
body.wikiedit span.save-button-slot {
/* These invisible placeholders mark spots in the UI
(max. 1 per tab) to where the save button gets
relocated as we switch between tabs. */
display: none;
}
| > > > > | 114 115 116 117 118 119 120 121 122 123 124 |
body.wikiedit span.save-button-slot {
/* These invisible placeholders mark spots in the UI
(max. 1 per tab) to where the save button gets
relocated as we switch between tabs. */
display: none;
}
body.wikiedit #wikiedit-page-name > span {
font-family: monospace;
}
|
Changes to src/wiki.c.
| ︙ | ︙ | |||
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 |
"CSRF violation (make sure sending of HTTP "
"Referer headers is enabled for XHR "
"connections).");
return;
}
pRoute->xCallback();
}
/*
** WEBPAGE: wikiedit
** URL: /wikedit?name=PAGENAME
**
** The main front-end for the Ajax-based wiki editor app. Passing
** in the name of an unknown page will trigger the creation
| > > > > > > > > > > > > > > > > > > > | 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 |
"CSRF violation (make sure sending of HTTP "
"Referer headers is enabled for XHR "
"connections).");
return;
}
pRoute->xCallback();
}
/*
** Emits all of the "core" static JS needed by /wikiedit into a single
** SCRIPT tag.
**
** TODO: a common mechanism which will let us bundle this type of
** blob into a single cacheable request.
*/
static void wikiedit_emit_js(void){
style_emit_script_tag(0,0);
style_emit_script_fossil_bootstrap(1);
style_emit_script_builtin(1,0,"sbsdiff.js");
style_emit_script_fetch(1, 0);
style_emit_script_tabs(1,0)/*also emits fossil.dom*/;
style_emit_script_confirmer(1,0);
style_emit_script_builtin(1, 0, "fossil.storage.js");
style_emit_script_builtin(1, 0, "fossil.page.wikiedit.js");
style_emit_script_tag(1,0);
}
/*
** WEBPAGE: wikiedit
** URL: /wikedit?name=PAGENAME
**
** The main front-end for the Ajax-based wiki editor app. Passing
** in the name of an unknown page will trigger the creation
|
| ︙ | ︙ | |||
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 |
style_header("Wiki Editor");
/* Status bar */
CX("<div id='fossil-status-bar' "
"title='Status message area. Double-click to clear them.'>"
"Status messages will go here.</div>\n"
/* will be moved into the tab container via JS */);
/* Main tab container... */
CX("<div id='wikiedit-tabs' class='tab-container'>Loading...</div>");
/* The .hidden class on the following tab elements is to help lessen
the FOUC effect of the tabs before JS re-assembles them. */
/******* Page list *******/
| > > | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 |
style_header("Wiki Editor");
/* Status bar */
CX("<div id='fossil-status-bar' "
"title='Status message area. Double-click to clear them.'>"
"Status messages will go here.</div>\n"
/* will be moved into the tab container via JS */);
CX("<div id='wikiedit-page-name'>Editing: <span>(no file loaded)</span></div>");
/* Main tab container... */
CX("<div id='wikiedit-tabs' class='tab-container'>Loading...</div>");
/* The .hidden class on the following tab elements is to help lessen
the FOUC effect of the tabs before JS re-assembles them. */
/******* Page list *******/
|
| ︙ | ︙ | |||
1239 1240 1241 1242 1243 1244 1245 |
"without having to actually save anything, nor pollute "
"the repo with endless test runs. Any attempt to save the "
"sandbox page will fail.</p>");
CX("<hr><h3>Wiki Name Rules</h3>");
well_formed_wiki_name_rules();
CX("</div>"/*#wikiedit-tab-save*/);
}
| | < < | < < < < | 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 |
"without having to actually save anything, nor pollute "
"the repo with endless test runs. Any attempt to save the "
"sandbox page will fail.</p>");
CX("<hr><h3>Wiki Name Rules</h3>");
well_formed_wiki_name_rules();
CX("</div>"/*#wikiedit-tab-save*/);
}
wikiedit_emit_js();
/* Dynamically populate the editor... */
style_emit_script_tag(0,0);
CX("\nfossil.onPageLoad(function(){\n");
CX("const P = fossil.page;\n"
"try{\n");
if(found){
|
| ︙ | ︙ |