SQLite

Timeline
Login

50 most recent check-ins

2026-06-13
20:16
Speed up SQL aggregate functions percentile() and median() by avoiding a full sort of the array of arguments. (leaf check-in: 9232b5f21d ... user: dan tags: pecentile-partial-sort)
18:17
Make the --header option to the CLI sticky, so that it does not get turned off by subsequence --csv or similar mode change options. (leaf check-in: 5019306601 ... user: drh tags: branch-3.53)
18:04
Make the --header option to the CLI sticky, so that it does not get turned off by subsequence --csv or similar mode change options. Bug 2026-06-13T11:49:18Z (leaf check-in: b19cef1862 ... user: drh tags: trunk)
2026-06-12
18:38
When reading a super-journal name from a journal file, allocate a new buffer rather than using Pager.pTmpSpace. This prevents a buffer overrun that could occur when using a VFS with a large sqlite3_vfs.mxPathname value with a database with a small page size. (check-in: aa756c8038 ... user: drh tags: branch-3.53)
18:35
When reading a super-journal name from a journal file, allocate a new buffer rather than using Pager.pTmpSpace. This prevents a buffer overrun that could occur when using a VFS with a large sqlite3_vfs.mxPathname value with a database with a small page size. (check-in: 7f71859841 ... user: dan tags: trunk)
17:32
Fix errors in comments on this branch. Also prefer SQLITE_NOMEM_BKPT to SQLITE_NOMEM. (closed check-in: ac17669e84 ... user: dan tags: super-journal-malloc)
17:16
Fix a memory leak that could follow an OOM error in the new code on this branch. (check-in: d4774a8987 ... user: dan tags: super-journal-malloc)
16:47
Improved documentation for sqlite3_deserialize(). (check-in: f15d076820 ... user: drh tags: trunk)
16:26
Do not use shared locks on SHM files when the filename is a long DOS-device path. Only used shared locks for UNC paths. Do not confuse the long-DOS-device syntax with UNC paths. (check-in: a4691489f2 ... user: drh tags: trunk)
16:04
Fix a buffer overwrite in fts3 that could occur while processing NEAR queries against corrupt records. (check-in: 85afd8e291 ... user: drh tags: branch-3.53)
15:36
Fix a buffer overwrite in fts3 that could occur while processing NEAR queries against corrupt records. Bug 2026-06-11T23:11:26Z. (check-in: b0f773e99e ... user: dan tags: trunk)
12:20
When using a read-only WAL/SHM, handle a corrupt page size in the WAL file correctly. (check-in: 9a79ca31ff ... user: drh tags: branch-3.53)
12:15
When using a read-only WAL/SHM, handle a corrupt page size in the WAL file correctly. Bug 2026-06-11T22:20:03Z. (check-in: 09ab0a1bac ... user: drh tags: trunk)
11:55
Add the --raw option to the dbtotxt command-line tool, for debugging. (check-in: abfecc0820 ... user: drh tags: trunk)
11:45
Fix a signed integer overflow that could occur in fts3 when processing corrupt database records. (check-in: 42fe4d2e8b ... user: drh tags: branch-3.53)
11:24
Fix a signed integer overflow that could occur in fts3 when processing corrupt database records. Bug 2026-06-11T23:12:25Z. (check-in: 978d04f051 ... user: dan tags: trunk)
00:13
Defense against a read-only WAL file that has an invalid page size. (closed check-in: ce3a8f9122 ... user: drh tags: corrupt-readonly-wal)
2026-06-11
23:28
Fix a signed-integer overflow in fts5 that might occur when dealing with strategicly corrupted records. (check-in: a36fc58e55 ... user: drh tags: branch-3.53)
23:26
Fix a possible signed integer overflow in the RBU extension given a maliciously crafted delta. (check-in: c40f3e8e78 ... user: drh tags: branch-3.53)
23:22
Harden code that processes Fossil Deltas against OOM and maliciously malformed delta blobs. (check-in: 1657b9716f ... user: drh tags: branch-3.53)
23:18
Enhance the ".ar -x" command to add the undocumented --debug option and to give enhanced robustness to deliberately malformed archives. (check-in: cd7bb77fdf ... user: drh tags: branch-3.53)
23:11
Comment improvements on the ".ar -x" command of the CLI. No changes to code. (check-in: 5b939fb1a2 ... user: drh tags: trunk)
22:48
Fix harmless compiler warnings. (check-in: dd0c161fcd ... user: drh tags: trunk)
16:39
Further improvements to the ".ar" command of the CLI. (check-in: 6149b938c7 ... user: drh tags: trunk)
14:28
Three-pass algorithm for the ".ar x" command in the CLI, so that symlinks are created after all regular files are created. (check-in: 37a80d20fe ... user: drh tags: trunk)
14:14
Add the (undocumented) --debug option to the ".ar" command in the CLI (check-in: 3a040ffc47 ... user: drh tags: trunk)
01:37
Improved detection of corrupt node IDs in RTree shadow tables. (check-in: 4e875ae5c3 ... user: drh tags: branch-3.53)
01:31
Improved detection of corrupt node IDs in RTree shadow tables. Test case in TH3. (check-in: e01a185a69 ... user: drh tags: trunk)
2026-06-10
20:10
When reading a super-journal name from a journal file, allocate a new buffer rather than using Pager.pTmpSpace. This prevents a buffer overrun that could occur when using a VFS with a large sqlite3_vfs.mxPathname value with a database with a small page size. (check-in: 37aa82a50a ... user: dan tags: super-journal-malloc)
16:51
Fix a signed-integer overflow in fts5 that might occur when dealing with strategicly corrupted records. Bug 2026-06-10T03:56:42Z. (check-in: fc6442ee54 ... user: dan tags: trunk)
10:40
Detect an OOM condition in the realpath() function of the fileio.c extension and cause that function to return NULL. To Do: we should go back in and fix realpath() to raise an SQLITE_NOMEM error on OOM rather than returning NULL. But we will delay that, in as much as OOMs are all but impossible on modern OSes. Bug 2026-06-10T07:46:32Z. (check-in: 8b961dc3d2 ... user: drh tags: trunk)
10:13
Fix a possible signed integer overflow in the RBU extension given a maliciously crafted delta. Bug 2026-06-10T06:41:54Z. (check-in: 8531c0c3b6 ... user: drh tags: trunk)
09:51
Harden code that processes Fossil Deltas against OOM and maliciously malformed delta blobs. Bug 2026-06-10T07:01:00Z and Bug 2026-06-10T07:06:43Z. (check-in: 67271c3129 ... user: drh tags: trunk)
2026-06-09
10:43
Avoid a possible integer overflow when fts5 tokenizes a very large document. Only possible with non-standard builds that use large values of SQLITE_MAX_LENGTH. Bug 2026-06-09T05:27:16Z. (check-in: d562e91374 ... user: dan tags: trunk)
10:16
Change loop counter variables from int to i64 to avoid a potential integer overflow inside an assert() statement when SQLite is compiled with SQLITE_DEBUG and an extra-large SQLITE_MAX_LENGTH. Does not affect production builds. Bug 2026-06-09T08:53:14Z. (check-in: 77f615d983 ... user: drh tags: trunk)
2026-06-08
19:23
Fix four obscure yet separate problems in FTS5. (check-in: a6eb055c35 ... user: drh tags: branch-3.53)
18:15
Fix builds on i486 CPUs. Forum 2025-01-25T12:58:44Z. (check-in: 4cb349370d ... user: drh tags: trunk)
17:48
Fix another buffer overread in fts5 when processing corrupt records. Bug 2026-06-08T16:03:39Z . (check-in: 8ba5acabf9 ... user: dan tags: trunk)
15:20
Fix a buffer overread that could occur in fts5 when processing corrupt records. Bug 2026-06-08T11:15:52Z (check-in: b07441cfc0 ... user: dan tags: trunk)
12:03
Avoid a potential use-after-free in fts5. Report 2026-06-08T08:45:27Z. (check-in: 9c018b02db ... user: dan tags: trunk)
11:24
Clamp the nToken parameter to the fts5 snippet() function between 0 and 64. It has always been documented this way, but not previously implemented. Report 2026-06-08T08:29:00Z. (check-in: 4af1d9b3e5 ... user: dan tags: trunk)
10:47
Add extra tests to check that non-deterministic functions may not be used in indexes. (check-in: beeef9dc2b ... user: dan tags: trunk)
2026-06-06
18:32
Improvements to the GCC compiler bug work-around of check-in [7fae321095ebec77]. (check-in: 247894f70d ... user: drh tags: trunk)
17:20
Minor performance enhancement and improved comments on the quicksort algorithm used by the median() implementation in func.c. (check-in: 2800f6a75b ... user: drh tags: trunk)
2026-06-05
00:11
A new approach to working around the GCC bug. (closed check-in: 2f95186ea5 ... user: drh tags: gcc-bug-114659)
2026-06-04
16:58
Disable the vector-IN-SELECT optimization if the number of columns is so large that it would cause the WhereTerm.nChild column to wrap. (check-in: 10d9da4f48 ... user: drh tags: branch-3.53)
16:56
Disable the vector-IN-SELECT optimization if the number of columns is so large that it would cause the WhereTerm.nChild column to wrap. Bug 2026-06-04T10:00:49Z. (check-in: bb49dfc948 ... user: drh tags: trunk)
12:27
Fix a crash that could be caused by configuring the pager-cache with a bulk allocation too small to fit even one page. (check-in: 3be41e1752 ... user: drh tags: branch-3.53)
11:48
Fix a crash that could be caused by configuring the pager-cache with a bulk allocation too small to fit even one page. Bug 2026-06-04T07:03:12Z. (check-in: b4b9dc632b ... user: dan tags: trunk)
11:42
Fix a possible NULL pointer derefence in the (experimental and untested) uuid.c extension. Bug 2026-06-04T09:50:59Z. (check-in: fa6374fe3a ... user: drh tags: trunk)
More ↓
" + ""; } if( !tx.omitDescenders ){ if( p.u==0 ){ if( p.hasOwnProperty('mo') && p.r==p.mo ){ var ix = p.hasOwnProperty('cu') ? p.cu : p.mu; var top = tx.rowinfo[ix-tx.iTopRow] drawUpArrow(p,{x: p.x, y: top.y-node.h}, p.fg, p.id); }else if( p.y>100 ){ drawUpArrow(p,{x: p.x, y: p.y-50}, p.fg, p.id); }else{ drawUpArrow(p,{x: p.x, y: 0},p.fg, p.id); } } if( p.hasOwnProperty('d') ){ if( p.y + 150 >= btm ){ drawUpArrow({x: p.x, y: btm - node.h/2},p,p.fg,p.id); }else{ drawUpArrow({x: p.x, y: p.y+50},p,p.fg,p.id); drawDotted({x: p.x, y: p.y+63},{x: p.x, y: p.y+50-node.h/2},p.fg,p.id); } } } if( p.hasOwnProperty('mo') ){ var x0 = p.x + node.w/2; var x1 = p.mo*railPitch + node.w/2; var u = tx.rowinfo[p.mu-tx.iTopRow]; var mtop = u; if( p.hasOwnProperty('cu') ){ mtop = tx.rowinfo[p.cu-tx.iTopRow]; } var y1 = miLineY(u); if( p.u<=0 || p.mo!=p.r ){ if( p.u==0 && p.mo==p.r ){ mergeLines[p.mo] = mtop.r
=0; i-- ){ drawNode(tx.rowinfo[i], btm); } } var selRow; function clickOnNode(e){ hideGraphTooltip() var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow]; if( !selRow ){ selRow = p; this.className += " sel"; canvasDiv.className += " sel"; }else if( selRow==p ){ selRow = null; this.className = this.className.replace(" sel", ""); canvasDiv.className = canvasDiv.className.replace(" sel", ""); }else{ if( tx.fileDiff ){ location.href=tx.baseUrl + "/fdiff?v1="+selRow.h+"&v2="+p.h; }else{ var href = tx.baseUrl + "/vdiff?from="+selRow.h+"&to="+p.h; let params = (new URL(document.location)).searchParams; if(params && typeof params === "object"){ let glob = params.get("chng"); if( !glob ){ glob = params.get("glob"); } if( glob ){ href += "&glob=" + glob; } } location.href = href; } } e.stopPropagation() } function dblclickOnNode(e){ var p = tx.rowinfo[parseInt(this.id.match(/\d+$/)[0], 10)-tx.iTopRow]; window.location.href = tx.baseUrl+"/info/"+p.h e.stopPropagation() } function findTxIndex(e){ if( !tx.rowinfo ) return -1; var x = e.clientX + window.pageXOffset - absoluteX(canvasDiv); var y = e.clientY + window.pageYOffset - absoluteY(canvasDiv); var aNode = canvasDiv.childNodes var nNode = aNode.length; var i; for(i=0;in.offsetLeft+n.offsetWidth+5 ) continue; if( yn.offsetTop+n.offsetHeight ) continue; return n.getAttribute("data-ix") } return -1 } function branchHyperlink(ix){ var br = tx.rowinfo[ix].br var dest = tx.baseUrl + "/timeline?r=" + encodeURIComponent(br) dest += tx.fileDiff ? "&m&cf=" : "&m&c=" dest += encodeURIComponent(tx.rowinfo[ix].h) return dest } function clickOnGraph(e){ stopCloseTimer(); stopDwellTimer(); tooltipInfo.ixHover = findTxIndex(e); tooltipInfo.posX = e.clientX; tooltipInfo.posY = e.clientY; showGraphTooltip(); } function showGraphTooltip(){ var html = null var ix = -1 if( tooltipInfo.ixHover==-2 ){ ix = parseInt(tooltipInfo.nodeHover.id.match(/\d+$/)[0],10)-tx.iTopRow var h = tx.rowinfo[ix].h var dest = tx.baseUrl + "/info/" + h h = h.slice(0,tooltipInfo.hashDigits); if( tx.fileDiff ){ html = "artifact "+h+"" }else{ html = "check-in "+h+"" } tooltipInfo.ixActive = -2; tooltipInfo.idNodeActive = tooltipInfo.nodeHover.id; }else if( tooltipInfo.ixHover>=0 ){ ix = tooltipInfo.ixHover var br = tx.rowinfo[ix].br var dest = branchHyperlink(ix) var hbr = br.replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); html = "branch "+hbr+"" tooltipInfo.ixActive = ix; tooltipInfo.idNodeActive = 0; } if( html ){ var s = getComputedStyle(document.body) if( tx.rowinfo[ix].bg.length ){ tooltipObj.style.backgroundColor = tx.rowinfo[ix].bg }else{ tooltipObj.style.backgroundColor = s.getPropertyValue('background-color') } tooltipObj.style.borderColor = tooltipObj.style.color = s.getPropertyValue('color') tooltipObj.style.visibility = "hidden" tooltipObj.innerHTML = html tooltipObj.insertBefore(makeCopyButton("tooltip-link",0,0), tooltipObj.childNodes[1]); tooltipObj.style.display = "inline" tooltipObj.style.position = "absolute" var x = tooltipInfo.posX + 4 + window.pageXOffset - absoluteX(tooltipObj.offsetParent) tooltipObj.style.left = x+"px" var y = tooltipInfo.posY + window.pageYOffset - tooltipObj.clientHeight - 4 - absoluteY(tooltipObj.offsetParent) tooltipObj.style.top = y+"px" tooltipObj.style.visibility = "visible" document.addEventListener('keydown',onKeyDown,true); }else{ hideGraphTooltip() } } function dblclickOnGraph(e){ var ix = findTxIndex(e); hideGraphTooltip() if( ix>=0 ){ var dest = branchHyperlink(ix) window.location.href = dest } } function changeDisplay(selector,value){ var x = document.getElementsByClassName(selector); var n = x.length; for(var i=0; i0 ) window.scrollTo(0, y); } } if( tx.rowinfo ){ var lastRow = document.getElementById("m"+tx.rowinfo[tx.rowinfo.length-1].id); var lastY = 0; function checkHeight(){ var h = absoluteY(lastRow); if( h!=lastY ){ renderGraph(); lastY = h; } setTimeout(checkHeight, 1000); } initGraph(); checkHeight(); }else{ function checkHeight(){} } if( tx.scrollToSelect ){ scrollToSelected(); } var lx = topObj.getElementsByClassName('timelineEllipsis'); var i; for(i=0; i0 ){ text = text.slice(0,cchLength); } } copyTextToClipboard(text); } } function copyTextToClipboard(text){ if( window.clipboardData && window.clipboardData.setData ){ window.clipboardData.setData("Text",text); }else{ var elTextarea = document.createElement("textarea"); elTextarea.style.position = "fixed"; elTextarea.value = text; document.body.appendChild(elTextarea); elTextarea.select(); try{ document.execCommand("copy"); }catch(err){ }finally{ document.body.removeChild(elTextarea); } } } /* fossil.bootstrap.js *************************************************************/ "use strict"; (function () { if(typeof window.CustomEvent === "function") return false; window.CustomEvent = function(event, params) { if(!params) params = {bubbles: false, cancelable: false, detail: null}; const evt = document.createEvent('CustomEvent'); evt.initCustomEvent( event, !!params.bubbles, !!params.cancelable, params.detail ); return evt; }; })(); (function(global){ const F = global.fossil; F.nu = (...obj)=>Object.assign(Object.create(null),...obj); const timestring = function f(){ if(!f.rx1){ f.rx1 = /\.\d+Z$/; } const d = new Date(); return d.toISOString().replace(f.rx1,'').split('T').join(' '); }; const localTimeString = function ff(d){ if(!ff.pad){ ff.pad = (x)=>(''+x).length>1 ? x : '0'+x; } d || (d = new Date()); return [ d.getFullYear(),'-',ff.pad(d.getMonth()+1), '-',ff.pad(d.getDate()), ' ',ff.pad(d.getHours()),':',ff.pad(d.getMinutes()), ':',ff.pad(d.getSeconds()) ].join(''); }; F.message = function f(){ const args = Array.prototype.slice.call(arguments,0); const tgt = f.targetElement; if(args.length) args.unshift( localTimeString()+':' ); if(tgt){ tgt.classList.remove('error'); tgt.innerText = args.join(' '); } else{ if(args.length){ args.unshift('Fossil status:'); console.debug.apply(console,args); } } return this; }; F.message.targetElement = document.querySelector('#fossil-status-bar'); if(F.message.targetElement){ F.message.targetElement.addEventListener( 'dblclick', ()=>F.message(), false ); } F.error = function f(){ const args = Array.prototype.slice.call(arguments,0); const tgt = F.message.targetElement; args.unshift(timestring(),'UTC:'); if(tgt){ tgt.classList.add('error'); tgt.innerText = args.join(' '); }else{ args.unshift('Fossil error:'); console.error.apply(console,args); } return this; }; F.encodeUrlArgs = function(obj,tgtArray,fakeEncode){ if(!obj) return ''; const a = (tgtArray instanceof Array) ? tgtArray : [], enc = fakeEncode ? (x)=>x : encodeURIComponent; let k, i = 0; for( k in obj ){ if(i++) a.push('&'); a.push(enc(k),'=',enc(obj[k])); } return a===tgtArray ? a : a.join(''); }; F.repoUrl = function(path,urlParams){ if(!urlParams) return this.rootPath+path; const url=[this.rootPath,path]; url.push('?'); if('string'===typeof urlParams) url.push(urlParams); else if(urlParams && 'object'===typeof urlParams){ this.encodeUrlArgs(urlParams, url); } return url.join(''); }; F.isObject = function(v){ return v && (v instanceof Object) && ('[object Object]' === Object.prototype.toString.apply(v) ); }; F.mergeLastWins = function(){ var k, o, i; const n = arguments.length, rc={}; for(i = 0; i < n; ++i){ if(!F.isObject(o = arguments[i])) continue; for( k in o ){ if(o.hasOwnProperty(k)) rc[k] = o[k]; } } return rc; }; F.hashDigits = function(hash,forUrl){ const n = ('number'===typeof forUrl) ? forUrl : F.config[forUrl ? 'hashDigitsUrl' : 'hashDigits']; return ('string'==typeof hash ? hash.substr( 0, n ) : hash); }; F.onPageLoad = function(callback){ window.addEventListener('load', callback, false); return this; }; F.onDOMContentLoaded = function(callback){ window.addEventListener('DOMContentLoaded', callback, false); return this; }; F.shortenFilename = function(name){ const a = name.split('/'); if(a.length<=2) return name; while(a.length>2) a.shift(); return '.../'+a.join('/'); }; F.page.addEventListener = function f(eventName, callback){ if(!f.proxy){ f.proxy = document.createElement('span'); } f.proxy.addEventListener(eventName, callback, false); return this; }; F.page.dispatchEvent = function(eventName, eventDetail){ if(this.addEventListener.proxy){ try{ this.addEventListener.proxy.dispatchEvent( new CustomEvent(eventName,{detail: eventDetail}) ); }catch(e){ console.error(eventName,"event listener threw:",e); } } return this; }; F.page.setPageTitle = function(title){ const t = document.querySelector('title'); if(t) t.innerText = title; return this; }; F.debounce = function f(func, waitMs, immediate) { var timeoutId; if(!waitMs) waitMs = f.$defaultDelay; return function() { const context = this, args = Array.prototype.slice.call(arguments); const later = function() { timeoutId = undefined; if(!immediate) func.apply(context, args); }; const callNow = immediate && !timeoutId; clearTimeout(timeoutId); timeoutId = setTimeout(later, waitMs); if(callNow) func.apply(context, args); }; }; F.debounce.$defaultDelay = 500; })(window); /* fossil.dom.js *************************************************************/ "use strict"; (function(F){ const argsToArray = (a)=>Array.prototype.slice.call(a,0); const isArray = (v)=>v instanceof Array; const dom = { create: function(elemType){ return document.createElement(elemType); }, createElemFactory: function(eType){ return function(){ return document.createElement(eType); }; }, remove: function(e){ if(e?.forEach){ e.forEach( (x)=>x?.parentNode?.removeChild(x) ); }else{ e?.parentNode?.removeChild(e); } return e; }, clearElement: function f(e){ if(!f.each){ f.each = function(e){ if(e.forEach){ e.forEach((x)=>f(x)); return e; } while(e.firstChild) e.removeChild(e.firstChild); }; } argsToArray(arguments).forEach(f.each); return arguments[0]; }, }; dom.splitClassList = function f(str){ if(!f.rx){ f.rx = /(\s+|\s*,\s*)/; } return str ? str.split(f.rx) : [str]; }; dom.div = dom.createElemFactory('div'); dom.p = dom.createElemFactory('p'); dom.code = dom.createElemFactory('code'); dom.pre = dom.createElemFactory('pre'); dom.header = dom.createElemFactory('header'); dom.footer = dom.createElemFactory('footer'); dom.section = dom.createElemFactory('section'); dom.span = dom.createElemFactory('span'); dom.strong = dom.createElemFactory('strong'); dom.em = dom.createElemFactory('em'); dom.ins = dom.createElemFactory('ins'); dom.del = dom.createElemFactory('del'); dom.label = function(forElem, text){ const rc = document.createElement('label'); if(forElem){ if(forElem instanceof HTMLElement){ forElem = this.attr(forElem, 'id'); } if(forElem){ dom.attr(rc, 'for', forElem); } } if(text) this.append(rc, text); return rc; }; dom.img = function(src){ const e = this.create('img'); if(src) e.setAttribute('src',src); return e; }; dom.a = function(href,label){ const e = this.create('a'); if(href) e.setAttribute('href',href); if(label) e.appendChild(dom.text(true===label ? href : label)); return e; }; dom.hr = dom.createElemFactory('hr'); dom.br = dom.createElemFactory('br'); dom.text = function(){ return document.createTextNode(argsToArray(arguments).join('')); }; dom.button = function(label,callback){ const b = this.create('button'); if(label) b.appendChild(this.text(label)); if('function' === typeof callback){ b.addEventListener('click', callback, false); } return b; }; dom.textarea = function(){ const rc = this.create('textarea'); let rows, cols, readonly; if(1===arguments.length){ if('boolean'===typeof arguments[0]){ readonly = !!arguments[0]; }else{ rows = arguments[0]; } }else if(arguments.length){ rows = arguments[0]; cols = arguments[1]; readonly = arguments[2]; } if(rows) rc.setAttribute('rows',rows); if(cols) rc.setAttribute('cols', cols); if(readonly) rc.setAttribute('readonly', true); return rc; }; dom.select = dom.createElemFactory('select'); dom.option = function(value,label){ const a = arguments; var sel; if(1==a.length){ if(a[0] instanceof HTMLElement){ sel = a[0]; }else{ value = a[0]; } }else if(2==a.length){ if(a[0] instanceof HTMLElement){ sel = a[0]; value = a[1]; }else{ value = a[0]; label = a[1]; } } else if(3===a.length){ sel = a[0]; value = a[1]; label = a[2]; } const o = this.create('option'); if(undefined !== value){ o.value = value; this.append(o, this.text(label || value)); }else if(undefined !== label){ this.append(o, label); } if(sel) this.append(sel, o); return o; }; dom.h = function(level){ return this.create('h'+level); }; dom.ul = dom.createElemFactory('ul'); dom.li = function(parent){ const li = this.create('li'); if(parent) parent.appendChild(li); return li; }; dom.createElemFactoryWithOptionalParent = function(childType){ return function(parent){ const e = this.create(childType); if(parent) parent.appendChild(e); return e; }; }; dom.table = dom.createElemFactory('table'); dom.thead = dom.createElemFactoryWithOptionalParent('thead'); dom.tbody = dom.createElemFactoryWithOptionalParent('tbody'); dom.tfoot = dom.createElemFactoryWithOptionalParent('tfoot'); dom.tr = dom.createElemFactoryWithOptionalParent('tr'); dom.td = dom.createElemFactoryWithOptionalParent('td'); dom.th = dom.createElemFactoryWithOptionalParent('th'); dom.fieldset = function(legendText){ const fs = this.create('fieldset'); if(legendText){ this.append( fs, (legendText instanceof HTMLElement) ? legendText : this.append(this.legend(legendText)) ); } return fs; }; dom.legend = function(legendText){ const rc = this.create('legend'); if(legendText) this.append(rc, legendText); return rc; }; dom.append = function f(parent){ const a = argsToArray(arguments); a.shift(); for(let i in a) { var e = a[i]; if(isArray(e) || e.forEach){ e.forEach((x)=>f.call(this, parent,x)); continue; } if('string'===typeof e || 'number'===typeof e || 'boolean'===typeof e || e instanceof Error) e = this.text(e); parent.appendChild(e); } return parent; }; dom.input = function(type){ return this.attr(this.create('input'), 'type', type); }; dom.checkbox = function(value, checked){ const rc = this.input('checkbox'); if(1===arguments.length && 'boolean'===typeof value){ checked = !!value; value = undefined; } if(undefined !== value) rc.value = value; if(!!checked) rc.checked = true; return rc; }; dom.radio = function(){ const rc = this.input('radio'); let name, value, checked; if(1===arguments.length && 'boolean'===typeof name){ checked = arguments[0]; name = value = undefined; }else if(2===arguments.length){ name = arguments[0]; if('boolean'===typeof arguments[1]){ checked = arguments[1]; }else{ value = arguments[1]; checked = undefined; } }else if(arguments.length){ name = arguments[0]; value = arguments[1]; checked = arguments[2]; } if(name) this.attr(rc, 'name', name); if(undefined!==value) rc.value = value; if(!!checked) rc.checked = true; return rc; }; const domAddRemoveClass = function f(action,e){ if(!f.rxSPlus){ f.rxSPlus = /\s+/; f.applyAction = function(e,a,v){ if(!e || !v ) return; else if(e.forEach){ e.forEach((E)=>E.classList[a](v)); }else{ e.classList[a](v); } }; } var i = 2, n = arguments.length; for( ; i < n; ++i ){ let c = arguments[i]; if(!c) continue; else if(isArray(c) || ('string'===typeof c && c.indexOf(' ')>=0 && (c = c.split(f.rxSPlus))) || c.forEach ){ c.forEach((k)=>k ? f.applyAction(e, action, k) : false); }else if(c){ f.applyAction(e, action, c); } } return e; }; dom.addClass = function(e,c){ const a = argsToArray(arguments); a.unshift('add'); return domAddRemoveClass.apply(this, a); }; dom.removeClass = function(e,c){ const a = argsToArray(arguments); a.unshift('remove'); return domAddRemoveClass.apply(this, a); }; dom.toggleClass = function f(e,c){ if(e.forEach){ e.forEach((x)=>x.classList.toggle(c)); }else{ e.classList.toggle(c); } return e; }; dom.hasClass = function(e,c){ return (e && e.classList) ? e.classList.contains(c) : false; }; dom.moveTo = function(dest,e){ const n = arguments.length; var i = 1; const self = this; for( ; i < n; ++i ){ e = arguments[i]; this.append(dest, e); } return dest; }; dom.moveChildrenTo = function f(dest,e){ if(!f.mv){ f.mv = function(d,v){ if(d instanceof Array){ d.push(v); if(v.parentNode) v.parentNode.removeChild(v); } else d.appendChild(v); }; } const n = arguments.length; var i = 1; for( ; i < n; ++i ){ e = arguments[i]; if(!e){ console.warn("Achtung: dom.moveChildrenTo() passed a falsy value at argument",i,"of", arguments,arguments[i]); continue; } if(e.forEach){ e.forEach((x)=>f.mv(dest, x)); }else{ while(e.firstChild){ f.mv(dest, e.firstChild); } } } return dest; }; dom.replaceNode = function f(old,nu){ var i = 1, n = arguments.length; ++f.counter; try { for( ; i < n; ++i ){ const e = arguments[i]; if(e.forEach){ e.forEach((x)=>f.call(this,old,e)); continue; } old.parentNode.insertBefore(e, old); } } finally{ --f.counter; } if(!f.counter){ old.parentNode.removeChild(old); } }; dom.replaceNode.counter = 0; dom.attr = function f(e){ if(2===arguments.length) return e.getAttribute(arguments[1]); const a = argsToArray(arguments); if(e.forEach){ e.forEach(function(x){ a[0] = x; f.apply(f,a); }); return e; } a.shift(); while(a.length){ const key = a.shift(), val = a.shift(); if(null===val || undefined===val){ e.removeAttribute(key); }else{ e.setAttribute(key,val); } } return e; }; const enableDisable = function f(enable){ var i = 1, n = arguments.length; for( ; i < n; ++i ){ let e = arguments[i]; if(e.forEach){ e.forEach((x)=>f(enable,x)); }else{ e.disabled = !enable; } } return arguments[1]; }; dom.enable = function(e){ const args = argsToArray(arguments); args.unshift(true); return enableDisable.apply(this,args); }; dom.disable = function(e){ const args = argsToArray(arguments); args.unshift(false); return enableDisable.apply(this,args); }; dom.selectOne = function(x,origin){ var src = origin || document, e = src.querySelector(x); if(!e){ e = new Error("Cannot find DOM element: "+x); console.error(e, src); throw e; } return e; }; dom.flashOnce = function f(e,howLongMs,afterFlashCallback){ if(e.dataset.isBlinking){ return; } if(2===arguments.length && 'function' ===typeof howLongMs){ afterFlashCallback = howLongMs; howLongMs = f.defaultTimeMs; } if(!howLongMs || 'number'!==typeof howLongMs){ howLongMs = f.defaultTimeMs; } e.dataset.isBlinking = true; const transition = e.style.transition; e.style.transition = "opacity "+howLongMs+"ms ease-in-out"; const opacity = e.style.opacity; e.style.opacity = 0; setTimeout(function(){ e.style.transition = transition; e.style.opacity = opacity; delete e.dataset.isBlinking; if(afterFlashCallback) afterFlashCallback(); }, howLongMs); return e; }; dom.flashOnce.defaultTimeMs = 400; dom.flashOnce.eventHandler = (event)=>dom.flashOnce(event.target) dom.flashNTimes = function(e,n,howLongMs,afterFlashCallback){ const args = argsToArray(arguments); args.splice(1,1); if(arguments.length===3 && 'function'===typeof howLongMs){ afterFlashCallback = howLongMs; howLongMs = args[1] = this.flashOnce.defaultTimeMs; }else if(arguments.length<3){ args[1] = this.flashOnce.defaultTimeMs; } n = +n; const self = this; const cb = args[2] = function f(){ if(--n){ setTimeout(()=>self.flashOnce(e, howLongMs, f), howLongMs+(howLongMs*0.1)); }else if(afterFlashCallback){ afterFlashCallback(); } }; this.flashOnce.apply(this, args); return this; }; dom.addClassBriefly = function f(e, className, howLongMs, afterCallback){ if(arguments.length<4 && 'function'===typeof howLongMs){ afterCallback = howLongMs; howLongMs = f.defaultTimeMs; }else if(arguments.length<3 || !+howLongMs){ howLongMs = f.defaultTimeMs; } this.addClass(e, className); setTimeout(function(){ dom.removeClass(e, className); if(afterCallback) afterCallback(); }, howLongMs); return this; }; dom.addClassBriefly.defaultTimeMs = 1000; dom.copyTextToClipboard = function(text){ if( window.clipboardData && window.clipboardData.setData ){ window.clipboardData.setData('Text',text); return true; }else{ const x = document.createElement("textarea"); x.style.position = 'fixed'; x.value = text; document.body.appendChild(x); x.select(); var rc; try{ document.execCommand('copy'); rc = true; }catch(err){ rc = false; }finally{ document.body.removeChild(x); } return rc; } }; dom.copyStyle = function f(e, style){ if(e.forEach){ e.forEach((x)=>f(x, style)); return e; } if(style){ let k; for(k in style){ if(style.hasOwnProperty(k)) e.style[k] = style[k]; } } return e; }; dom.effectiveHeight = function f(e){ if(!e) return 0; if(!f.measure){ f.measure = function callee(e, depth){ if(!e) return; const m = e.getBoundingClientRect(); if(0===depth){ callee.top = m.top; callee.bottom = m.bottom; }else{ callee.top = m.top ? Math.min(callee.top, m.top) : callee.top; callee.bottom = Math.max(callee.bottom, m.bottom); } Array.prototype.forEach.call(e.children,(e)=>callee(e,depth+1)); if(0===depth){ f.extra += callee.bottom - callee.top; } return f.extra; }; } f.extra = 0; f.measure(e,0); return f.extra; }; dom.parseHtml = function(){ let childs, string, tgt; if(1===arguments.length){ string = arguments[0]; }else if(2==arguments.length){ tgt = arguments[0]; string = arguments[1]; } if(string){ const newNode = new DOMParser().parseFromString(string, 'text/html'); childs = newNode.documentElement.querySelector('body'); childs = childs ? Array.prototype.slice.call(childs.childNodes, 0) : []; }else{ childs = []; } return tgt ? this.moveTo(tgt, childs) : childs; }; F.connectPagePreviewers = function f(selector,methodNamespace){ if('string'===typeof selector){ selector = document.querySelectorAll(selector); }else if(!selector.forEach){ selector = [selector]; } if(!methodNamespace){ methodNamespace = F.page; } selector.forEach(function(e){ e.addEventListener( 'click', function(r){ const eTo = '#'===e.dataset.fPreviewTo[0] ? document.querySelector(e.dataset.fPreviewTo) : methodNamespace[e.dataset.fPreviewTo], eFrom = '#'===e.dataset.fPreviewFrom[0] ? document.querySelector(e.dataset.fPreviewFrom) : methodNamespace[e.dataset.fPreviewFrom], asText = +(e.dataset.fPreviewAsText || 0); eTo.textContent = "Fetching preview..."; methodNamespace[e.dataset.fPreviewVia]( (eFrom instanceof Function ? eFrom.call(methodNamespace) : eFrom.value), function(r){ if(eTo instanceof Function) eTo.call(methodNamespace, r||''); else if(!r){ dom.clearElement(eTo); }else if(asText){ eTo.textContent = r; }else{ dom.parseHtml(dom.clearElement(eTo), r); } } ); }, false ); }); return this; }; return F.dom = dom; })(window.fossil); /* fossil.pikchr.js *************************************************************/ (function(F){ "use strict"; const D = F.dom, P = F.pikchr = {}; P.addSrcView = function f(svg){ if(!f.hasOwnProperty('parentClick')){ f.parentClick = function(ev){ if(ev.altKey || ev.metaKey || ev.ctrlKey || this.classList.contains('toggle')){ this.classList.toggle('source'); ev.stopPropagation(); ev.preventDefault(); } }; f.clickPikchrShow = function(ev){ const pId = this.dataset['pikchrid']; if(!pId) return; const ePikchr = this.parentNode.parentNode.querySelector('#'+pId); if(!ePikchr) return; ev.stopPropagation(); window.sessionStorage.setItem('pikchr-xfer', ePikchr.innerText); }; }; if(!svg) svg = 'svg.pikchr'; if('string' === typeof svg){ document.querySelectorAll(svg).forEach((e)=>f.call(this, e)); return this; }else if(svg.forEach){ svg.forEach((e)=>f.call(this, e)); return this; } if(svg.dataset.pikchrProcessed){ return this; } svg.dataset.pikchrProcessed = 1; const parent = svg.parentNode.parentNode; const srcView = parent ? svg.parentNode.nextElementSibling : undefined; if(srcView && srcView.classList.contains('pikchr-src')){ parent.addEventListener('click', f.parentClick, false); const eSpan = window.sessionStorage ? srcView.querySelector('span') : undefined; if(eSpan){ const openLink = eSpan.querySelector('a'); if(openLink){ openLink.addEventListener('click', f.clickPikchrShow, false); eSpan.classList.remove('hidden'); } } } return this; }; })(window.fossil); /* menu.js *************************************************************/ function toggle_annotation_log(){ var w = document.getElementById("annotation_log"); var x = document.forms["f01"].elements["log"].checked w.style.display = x ? "block" : "none"; } function submenu_onchange_submit(){ var w = document.getElementById("f01"); w.submit(); } (function (){ for(var i=0; 1; i++){ var x = document.getElementById("submenuctrl-"+i); if(!x) break; if( !x.hasAttribute('data-ctrl') ){ x.onchange = submenu_onchange_submit; }else{ var cx = x.getAttribute('data-ctrl'); if( cx=="toggle_annotation_log" ){ x.onchange = toggle_annotation_log; } } } })();