Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Added hash_digits() info to fossil.config object and added fossil.hashDigits(). Factored out fileedit JS use of innerHTML where possible. Reworked the Version Info tab a bit. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | fileedit-ajaxify |
| Files: | files | file ages | folders |
| SHA3-256: |
29567e6e7ef1b05adaa9b5b4b33115c5 |
| User & Date: | stephan 2020-05-07 01:19:09.770 |
Context
|
2020-05-07
| ||
| 02:36 | Merged in trunk. ... (check-in: 087c5d1f3e user: stephan tags: fileedit-ajaxify) | |
| 01:19 | Added hash_digits() info to fossil.config object and added fossil.hashDigits(). Factored out fileedit JS use of innerHTML where possible. Reworked the Version Info tab a bit. ... (check-in: 29567e6e7e user: stephan tags: fileedit-ajaxify) | |
|
2020-05-06
| ||
| 23:53 | Added a 'tick' mode to fossil.confirmer to more easily allow the triggering element to be visibly updated to reflect the countdown state. The editor's discard/reload button now visibly counts down from 3 if clicked. ... (check-in: 3da4b94c44 user: stephan tags: fileedit-ajaxify) | |
Changes
Changes to src/fileedit.c.
| ︙ | ︙ | |||
1551 1552 1553 1554 1555 1556 1557 |
/***** File/version info tab *****/
{
CX("<div id='fileedit-tab-version' "
"data-tab-parent='fileedit-tabs' "
"data-tab-label='Version Info'"
">");
CX("File: "
| < < > | 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 |
/***** File/version info tab *****/
{
CX("<div id='fileedit-tab-version' "
"data-tab-parent='fileedit-tabs' "
"data-tab-label='Version Info'"
">");
CX("File: "
"<code id='finfo-file-name'>(loading)</code><br>");
CX("Checkin Version: "
"[<a id='timeline-link' href='#'>/timeline</a>] "
"[<a id='r-link' href='#'>/info</a>] "
/* %R/info/%!S */
"<code id='r-label'>(loading...)</code><br>"
);
CX("Permalink: <code>"
"<a id='permalink' href='#'>(loading...)</a></code><br>"
"(Clicking the permalink will reload the page and discard "
|
| ︙ | ︙ |
Changes to src/fossil.bootstrap.js.
| ︙ | ︙ | |||
139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
if(!F.isObject(o = arguments[i])) continue;
for( k in o ){
if(o.hasOwnProperty(k)) rc[k] = o[k];
}
}
return rc;
};
/**
Sets up pseudo-automatic content preview handling between a
source element (typically a TEXTAREA) and a target rendering
element (typically a DIV). The selector argument must be one of:
- A single DOM element
| > > > > > > > > > > > > > > > > > | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
if(!F.isObject(o = arguments[i])) continue;
for( k in o ){
if(o.hasOwnProperty(k)) rc[k] = o[k];
}
}
return rc;
};
/**
Expects to be passed as hash code as its first argument. It
returns a "shortened" form of hash, with a length which depends
on the 2nd argument: truthy = fossil.config.hashDigitsUrl, falsy
= fossil.config.hashDigits. Both of those values are derived from
the 'hash-digits' repo-level config setting or the
FOSSIL_HASH_DIGITS_URL/FOSSIL_HASH_DIGITS compile-time options.
If its first arugment is a non-string, that value is returned
as-is.
*/
F.hashDigits = function(hash,forUrl){
return ('string'==typeof hash ? hash.substr(
0, F.config[forUrl ? 'hashDigitsUrl' : 'hashDigits']
) : hash);
};
/**
Sets up pseudo-automatic content preview handling between a
source element (typically a TEXTAREA) and a target rendering
element (typically a DIV). The selector argument must be one of:
- A single DOM element
|
| ︙ | ︙ | |||
248 249 250 251 252 253 254 255 |
(r)=>eTo[asText ? 'textContent' : 'innerHTML'] = r||''
);
}, false
);
});
return this;
};
| < | 265 266 267 268 269 270 271 272 273 |
(r)=>eTo[asText ? 'textContent' : 'innerHTML'] = r||''
);
}, false
);
});
return this;
};
})(window);
|
Changes to src/fossil.dom.js.
1 2 3 |
"use strict";
(function(F/*fossil object*/){
/**
| | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
"use strict";
(function(F/*fossil object*/){
/**
A collection of HTML DOM utilities to simplify, a bit, using the
DOM API. It is focused on manipulation of the DOM, but one of its
core mantras is "No innerHTML." Using innerHTML in this code, in
particular assigning to it, is absolutely verboten.
*/
const argsToArray = (a)=>Array.prototype.slice.call(a,0);
const isArray = (v)=>v instanceof Array;
const dom = {
create: function(elemType){
return document.createElement(elemType);
|
| ︙ | ︙ |
Changes to src/fossil.page.fileedit.js.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 |
);
diffButtons.querySelector('button.unified').addEventListener(
"click",(e)=>P.diff(false), false
);
P.e.btnCommit.addEventListener(
"click",(e)=>P.commit(), false
);
| < < | | | | | < | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
);
diffButtons.querySelector('button.unified').addEventListener(
"click",(e)=>P.diff(false), false
);
P.e.btnCommit.addEventListener(
"click",(e)=>P.commit(), false
);
F.confirmer(P.e.btnReload, {
confirmText: "Really reload, losing edits?",
onconfirm: (e)=>P.loadFile(),
ticks: 3
});
/**
Cosmetic: jump through some hoops to enable/disable
certain preview options depending on the current
preview mode...
*/
const selectPreviewMode =
P.e.selectPreviewModeWrap.querySelector('select');
|
| ︙ | ︙ | |||
103 104 105 106 107 108 109 |
}, false
);
selectFontSize.dispatchEvent(
// Force UI update
new Event('change',{target:selectFontSize})
);
}
| < | > > | > > > | | > > > | < | < | < | > | | | < | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
}, false
);
selectFontSize.dispatchEvent(
// Force UI update
new Event('change',{target:selectFontSize})
);
}
}, false)/*onload event handler*/;
/**
updateVersion() updates the filename and version in various UI
elements...
Returns this object.
*/
P.updateVersion = function(file,rev){
this.finfo = {filename:file,checkin:rev};
const E = (s)=>document.querySelector(s),
euc = encodeURIComponent,
rHuman = F.hashDigits(rev),
rUrl = F.hashDigits(rev,true);
D.append(
D.clearElement(E('#r-label')),
rHuman
);
var e;
e = E('#timeline-link');
D.attr(e, 'href',F.repoUrl('timeline',{c:rUrl}));
e = E('#finfo-file-name');
D.append(
D.clearElement(e),
D.a(F.repoUrl('finfo',{name:file, m:rUrl}), file)
);
e = E('#r-link');
D.attr(e, 'href', F.repoUrl('info/'+rUrl));
e = E('#r-label');
D.append(D.clearElement(e),rHuman);
const purlArgs = F.encodeUrlArgs({
filename: this.finfo.filename,
checkin: rUrl
},false,true);
const purl = F.repoUrl('fileedit',purlArgs);
e = E('#permalink');
D.attr(D.append(D.clearElement(e),'?'+purlArgs),'href', purl);
return this;
};
/**
loadFile() loads (file,checkinVersion) and updates the relevant
UI elements to reflect the loaded state.
|
| ︙ | ︙ | |||
185 186 187 188 189 190 191 |
}
const target = this.e.tabs.preview.querySelector(
'#fileedit-tab-preview-wrapper'
);
const self = this;
const updateView = function(c){
D.clearElement(target);
| | < < | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
}
const target = this.e.tabs.preview.querySelector(
'#fileedit-tab-preview-wrapper'
);
const self = this;
const updateView = function(c){
D.clearElement(target);
if('string'===typeof c) target.innerHTML = c;
if(switchToTab) self.tabs.switchToTab(self.e.tabs.preview);
};
const content = this.e.taEditor.value;
if(!content){
updateView('');
return this;
}
|
| ︙ | ︙ | |||
288 289 290 291 292 293 294 |
isDryRun = cbDryRun.checked,
filename = this.finfo.filename;
if(!f.updateView){
f.updateView = function(c){
target.innerHTML = [
"<h3>Manifest",
(c.dryRun?" (dry run)":""),
| | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
isDryRun = cbDryRun.checked,
filename = this.finfo.filename;
if(!f.updateView){
f.updateView = function(c){
target.innerHTML = [
"<h3>Manifest",
(c.dryRun?" (dry run)":""),
": ", F.hashDigits(c.uuid),"</h3>",
"<code class='fileedit-manifest'>",
c.manifest,
"</code></pre>"
].join('');
const msg = [
'Committed',
c.dryRun ? '(dry run)' : '',
'[', F.hashDigits(c.uuid) ,'].'
];
if(!c.dryRun){
msg.push('Re-activating dry-run mode.');
self.e.taComment.value = '';
cbDryRun.checked = true;
P.updateVersion(filename, c.uuid);
}
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
1445 1446 1447 1448 1449 1450 1451 |
/* Set up the generic/app-agnostic parts of window.fossil
** which require C-level state... */
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,
| | > > > > | | | > | | 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 |
/* Set up the generic/app-agnostic parts of window.fossil
** which require C-level state... */
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);
/* fossil.config = {...various config-level options...} */
CX("window.fossil.config = {"
"hashDigits: %d, hashDigitsUrl: %d"
"};\n", hash_digits(0), hash_digits(1));
/*
** fossil.page holds info about the current page. This is also
** where the current page "should" store any of its own
** page-specific state, and it is reserved for that purpose.
*/
CX("window.fossil.page = {"
"page:\"%T\""
"};\n", g.zPath);
CX("})();\n");
/* The remaining fossil object bootstrap code is not dependent on
** C-runtime state... */
if(asInline){
CX("%s\n", builtin_text("fossil.bootstrap.js"));
}
style_emit_script_tag(1,0);
if(asInline==0){
style_emit_script_tag(0,"builtin/fossil.bootstrap.js");
}
|
| ︙ | ︙ |