Fossil SCM

Added ability to create new pages passed to the editor via /wikinew and integrated them into the local edit stash.

stephan 2020-07-30 19:12 ajax-wiki-editor
Commit 7894674dd430e68bd4062b636c177dc42e9d98f8220147525ccc13544678dc10
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -240,12 +240,12 @@
240240
console.warn("Pruned oldest local file edit entry:",e);
241241
}
242242
if(n) this._fireStashEvent();
243243
}
244244
};
245
- $stash.prune.defaultMaxCount = P.config.defaultMaxStashSize;
246
-
245
+ $stash.prune.defaultMaxCount = P.config.defaultMaxStashSize || 10;
246
+ P.$stash = $stash /* we have to expose this for the new-page case :/ */;
247247
248248
/**
249249
Internal workaround to select the current preview mode
250250
and fire a change event if the value actually changes
251251
or if forceEvent is truthy.
@@ -263,16 +263,23 @@
263263
}
264264
};
265265
266266
const WikiList = {
267267
e: {},
268
+ /** Update OPTION elements to reflect whether the page has
269
+ local changes or is new/unsaved. */
268270
refreshStashMarks: function(){
269271
this.e.select.querySelectorAll(
270272
'option'
271273
).forEach(function(o){
272
- if($stash.hasStashedContent(o.value)) D.addClass(o, 'stashed');
273
- else D.removeClass(o, 'stashed');
274
+ const stashed = $stash.getWinfo({name:o.value});
275
+ if(stashed){
276
+ const isNew = 'sandbox'===stashed.type ? false : !stashed.version;
277
+ D.addClass(o, isNew ? 'stashed-new' :'stashed');
278
+ }else{
279
+ D.removeClass(o, 'stashed', 'stashed-new');
280
+ }
274281
});
275282
},
276283
init: function(parentElem){
277284
const sel = D.select(), btn = D.button("Reload page list");
278285
this.e.select = sel;
@@ -280,25 +287,45 @@
280287
D.clearElement(parentElem);
281288
D.append(
282289
parentElem, btn,
283290
D.append(D.span(), "Select a page to edit:"),
284291
sel,
285
- D.append(D.span(), "* = local edits exist."),
292
+ D.append(D.span(), "* = local edits exist"),
293
+ D.append(D.span(), "+ = new/unsaved page")
286294
);
287295
D.attr(sel, 'size', 10);
288296
D.option(D.disable(D.clearElement(sel)), "Loading...");
289297
const self = this;
290298
btn.addEventListener(
291299
'click',
292
- function(){
300
+ function click(){
301
+ if(!click.sorticase){
302
+ click.sorticase = function(l,r){
303
+ l = l.toLowerCase();
304
+ r = r.toLowerCase();
305
+ return l<=r ? -1 : 1;
306
+ };
307
+ }
293308
F.fetch('wikiajax/list',{
294309
responseType: 'json',
295310
onload: function(list){
311
+ /* Jump through some hoops to integrate new/unsaved
312
+ pages into the list of existing pages... We use a map
313
+ as an intermediary in order to filter out any local-stash
314
+ dupes from server-side copies. */
315
+ const map = {}, ndx = $stash.getIndex();
296316
D.clearElement(sel);
297
- list.forEach((e)=>D.option(sel, e));
298
- //D.option(sel, "sandbox");
317
+ list.forEach((name)=>map[name] = true);
318
+ Object.keys(ndx).forEach(function(key){
319
+ const winfo = ndx[key];
320
+ if(!winfo.version/*new page*/) map[winfo.name] = true;
321
+ });
322
+ Object.keys(map)
323
+ .sort(click.sorticase)
324
+ .forEach((name)=>D.option(sel, name));
299325
D.enable(sel);
326
+ if(P.winfo) sel.value = P.winfo.name;
300327
self.refreshStashMarks();
301328
}
302329
});
303330
},
304331
false
@@ -338,11 +365,15 @@
338365
toDisable: undefined /* elements to disable during ajax activity */
339366
};
340367
F.fetch.beforesend = function f(){
341368
if(!ajaxState.toDisable){
342369
ajaxState.toDisable = document.querySelectorAll(
343
- 'button, input, select, textarea'
370
+ ['button:not([disabled])',
371
+ 'input:not([disabled])',
372
+ 'select:not([disabled])',
373
+ 'textarea:not([disabled])'
374
+ ].join(',')
344375
);
345376
}
346377
if(1===++ajaxState.count){
347378
D.addClass(document.body, 'waiting');
348379
D.disable(ajaxState.toDisable);
@@ -433,11 +464,21 @@
433464
if(0) P.e.btnCommit.addEventListener(
434465
"click",(e)=>P.commit(), false
435466
);
436467
F.confirmer(P.e.btnReload, {
437468
confirmText: "Really reload, losing edits?",
438
- onconfirm: (e)=>P.unstashContent().loadPage(),
469
+ onconfirm: function(e){
470
+ const w = P.winfo;
471
+ if(!w){
472
+ F.error("No page loaded.");
473
+ return;
474
+ }else if(!w.version){
475
+ F.error("Cannot reload a new/unsaved page.");
476
+ return;
477
+ }
478
+ P.unstashContent().loadPage();
479
+ },
439480
ticks: 3
440481
});
441482
P.e.taEditor.addEventListener(
442483
'change', ()=>P.stashContentChange(), false
443484
);
@@ -451,11 +492,10 @@
451492
P.stashContentChange(true);
452493
}
453494
},
454495
false
455496
);
456
-
457497
458498
const selectFontSize = E('select[name=editor_font_size]');
459499
if(selectFontSize){
460500
selectFontSize.addEventListener(
461501
"change",function(e){
@@ -472,32 +512,43 @@
472512
}
473513
474514
P.addEventListener(
475515
// Clear certain views when new content is loaded/set
476516
'wiki-content-replaced',
477
- ()=>D.clearElement(P.e.diffTarget, P.e.previewTarget)
517
+ ()=>{
518
+ P.previewNeedsUpdate = true;
519
+ D.clearElement(P.e.diffTarget, P.e.previewTarget);
520
+ }
478521
);
479522
P.addEventListener(
480523
// Clear certain views after a save
481524
'wiki-saved',
482525
(e)=>{
483
- if(!e.detail.dryRun){
484
- D.clearElement(P.e.diffTarget, P.e.previewTarget);
485
- }
526
+ D.clearElement(P.e.diffTarget, P.e.previewTarget);
527
+ // TODO: replace preview with new content
486528
}
487529
);
530
+ WikiList.init( P.e.tabs.pageList.firstElementChild );
488531
P.addEventListener(
489
- // Update title on wiki page load
532
+ // Update various state on wiki page load
490533
'wiki-page-loaded',
491534
function(ev){
492
- const title = 'Wiki Editor: '+ev.detail.name;
493
- document.head.querySelector('title').innerText = title;
494
- document.querySelector('div.header .title').innerText = title;
535
+ delete P.winfo;
536
+ const winfo = ev.detail;
537
+ P.winfo = winfo;
538
+ P.previewNeedsUpdate = true;
539
+ P.e.selectMimetype.value = winfo.mimetype;
540
+ P.tabs.switchToTab(P.e.tabs.content);
541
+ P.wikiContent(winfo.content || '');
542
+ WikiList.e.select.value = winfo.name;
543
+ if(!winfo.version){
544
+ F.error('You are editing a new, unsaved page:',winfo.name);
545
+ }
546
+ P.updatePageTitle();
495547
},
496548
false
497549
);
498
- WikiList.init( P.e.tabs.pageList.firstElementChild );
499550
}/*F.onPageLoad()*/);
500551
501552
/**
502553
Returns true if fossil.page.winfo is set, indicating that a page
503554
has been loaded, else it reports an error and returns false.
@@ -507,10 +558,29 @@
507558
*/
508559
const affirmPageLoaded = function(quiet){
509560
if(!P.winfo && !quiet) F.error("No wiki page is loaded.");
510561
return !!P.winfo;
511562
};
563
+
564
+ /**
565
+ Update the page title and header based on the state
566
+ of this.winfo. A no-op if this.winfo is not set.
567
+ */
568
+ P.updatePageTitle = function f(){
569
+ if(!affirmPageLoaded(true)) return;
570
+ if(!f.titleElement){
571
+ f.titleElement = document.head.querySelector('title');
572
+ f.pageTitleHeader = document.querySelector('div.header .title');
573
+ }
574
+ var title = ['Wiki Editor:'];
575
+ if(!P.winfo.version) title.push('[+]');
576
+ else if($stash.getWinfo(P.winfo)) title.push('[*]')
577
+ title.push(P.winfo.name);
578
+ title = title.join(' ');
579
+ f.titleElement.innerText = title;
580
+ f.pageTitleHeader.innerText = title;
581
+ };
512582
513583
/**
514584
Getter (if called with no args) or setter (if passed an arg) for
515585
the current file content.
516586
@@ -601,37 +671,20 @@
601671
}else if(1===arguments.length && 'string' !== typeof name){
602672
/* Assume winfo-like object */
603673
const arg = arguments[0];
604674
name = arg.name;
605675
}
606
- const self = this;
607
- const onload = (r)=>{
608
- delete self.winfo;
609
- self.winfo = {
610
- name: r.name,
611
- mimetype: r.mimetype,
612
- type: r.type,
613
- version: r.version,
614
- parent: r.parent
615
- };
616
- self.previewNeedsUpdate = true;
617
- self.e.selectMimetype.value = r.mimetype;
618
- self.tabs.switchToTab(self.e.tabs.content);
619
- self.wikiContent(r.content);
620
- self.dispatchEvent('wiki-page-loaded', r);
621
- };
622
- const semiWinfo = {name: name};
623
- const stashWinfo = this.getStashedWinfo(semiWinfo);
676
+ const onload = (r)=>this.dispatchEvent('wiki-page-loaded', r);
677
+ const stashWinfo = this.getStashedWinfo({name: name});
624678
if(stashWinfo){ // fake a response from the stash...
625
- this.winfo = stashWinfo;
626679
onload({
627680
name: stashWinfo.name,
628681
mimetype: stashWinfo.mimetype,
629682
type: stashWinfo.type,
630683
version: stashWinfo.version,
631684
parent: stashWinfo.parent,
632
- content: this.contentFromStash()
685
+ content: $stash.stashedContent(stashWinfo)
633686
});
634687
F.message("Fetched from the local-edit storage:",
635688
stashWinfo.name);
636689
return this;
637690
}
@@ -774,10 +827,11 @@
774827
$stash.updateWinfo(wi);
775828
}else{
776829
$stash.updateWinfo(wi, P.wikiContent());
777830
}
778831
F.message("Stashed change(s) to page ["+wi.name+"].");
832
+ P.updatePageTitle();
779833
$stash.prune();
780834
this.previewNeedsUpdate = true;
781835
}
782836
return this;
783837
};
@@ -818,8 +872,7 @@
818872
filename/checkin values), return it, else return undefined.
819873
*/
820874
P.getStashedWinfo = function(winfo){
821875
return $stash.getWinfo(winfo);
822876
};
823
- P.$stash = $stash /* only for development/debugging */;
824877
825878
})(window.fossil);
826879
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -240,12 +240,12 @@
240 console.warn("Pruned oldest local file edit entry:",e);
241 }
242 if(n) this._fireStashEvent();
243 }
244 };
245 $stash.prune.defaultMaxCount = P.config.defaultMaxStashSize;
246
247
248 /**
249 Internal workaround to select the current preview mode
250 and fire a change event if the value actually changes
251 or if forceEvent is truthy.
@@ -263,16 +263,23 @@
263 }
264 };
265
266 const WikiList = {
267 e: {},
 
 
268 refreshStashMarks: function(){
269 this.e.select.querySelectorAll(
270 'option'
271 ).forEach(function(o){
272 if($stash.hasStashedContent(o.value)) D.addClass(o, 'stashed');
273 else D.removeClass(o, 'stashed');
 
 
 
 
 
274 });
275 },
276 init: function(parentElem){
277 const sel = D.select(), btn = D.button("Reload page list");
278 this.e.select = sel;
@@ -280,25 +287,45 @@
280 D.clearElement(parentElem);
281 D.append(
282 parentElem, btn,
283 D.append(D.span(), "Select a page to edit:"),
284 sel,
285 D.append(D.span(), "* = local edits exist."),
 
286 );
287 D.attr(sel, 'size', 10);
288 D.option(D.disable(D.clearElement(sel)), "Loading...");
289 const self = this;
290 btn.addEventListener(
291 'click',
292 function(){
 
 
 
 
 
 
 
293 F.fetch('wikiajax/list',{
294 responseType: 'json',
295 onload: function(list){
 
 
 
 
 
296 D.clearElement(sel);
297 list.forEach((e)=>D.option(sel, e));
298 //D.option(sel, "sandbox");
 
 
 
 
 
 
299 D.enable(sel);
 
300 self.refreshStashMarks();
301 }
302 });
303 },
304 false
@@ -338,11 +365,15 @@
338 toDisable: undefined /* elements to disable during ajax activity */
339 };
340 F.fetch.beforesend = function f(){
341 if(!ajaxState.toDisable){
342 ajaxState.toDisable = document.querySelectorAll(
343 'button, input, select, textarea'
 
 
 
 
344 );
345 }
346 if(1===++ajaxState.count){
347 D.addClass(document.body, 'waiting');
348 D.disable(ajaxState.toDisable);
@@ -433,11 +464,21 @@
433 if(0) P.e.btnCommit.addEventListener(
434 "click",(e)=>P.commit(), false
435 );
436 F.confirmer(P.e.btnReload, {
437 confirmText: "Really reload, losing edits?",
438 onconfirm: (e)=>P.unstashContent().loadPage(),
 
 
 
 
 
 
 
 
 
 
439 ticks: 3
440 });
441 P.e.taEditor.addEventListener(
442 'change', ()=>P.stashContentChange(), false
443 );
@@ -451,11 +492,10 @@
451 P.stashContentChange(true);
452 }
453 },
454 false
455 );
456
457
458 const selectFontSize = E('select[name=editor_font_size]');
459 if(selectFontSize){
460 selectFontSize.addEventListener(
461 "change",function(e){
@@ -472,32 +512,43 @@
472 }
473
474 P.addEventListener(
475 // Clear certain views when new content is loaded/set
476 'wiki-content-replaced',
477 ()=>D.clearElement(P.e.diffTarget, P.e.previewTarget)
 
 
 
478 );
479 P.addEventListener(
480 // Clear certain views after a save
481 'wiki-saved',
482 (e)=>{
483 if(!e.detail.dryRun){
484 D.clearElement(P.e.diffTarget, P.e.previewTarget);
485 }
486 }
487 );
 
488 P.addEventListener(
489 // Update title on wiki page load
490 'wiki-page-loaded',
491 function(ev){
492 const title = 'Wiki Editor: '+ev.detail.name;
493 document.head.querySelector('title').innerText = title;
494 document.querySelector('div.header .title').innerText = title;
 
 
 
 
 
 
 
 
 
495 },
496 false
497 );
498 WikiList.init( P.e.tabs.pageList.firstElementChild );
499 }/*F.onPageLoad()*/);
500
501 /**
502 Returns true if fossil.page.winfo is set, indicating that a page
503 has been loaded, else it reports an error and returns false.
@@ -507,10 +558,29 @@
507 */
508 const affirmPageLoaded = function(quiet){
509 if(!P.winfo && !quiet) F.error("No wiki page is loaded.");
510 return !!P.winfo;
511 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
513 /**
514 Getter (if called with no args) or setter (if passed an arg) for
515 the current file content.
516
@@ -601,37 +671,20 @@
601 }else if(1===arguments.length && 'string' !== typeof name){
602 /* Assume winfo-like object */
603 const arg = arguments[0];
604 name = arg.name;
605 }
606 const self = this;
607 const onload = (r)=>{
608 delete self.winfo;
609 self.winfo = {
610 name: r.name,
611 mimetype: r.mimetype,
612 type: r.type,
613 version: r.version,
614 parent: r.parent
615 };
616 self.previewNeedsUpdate = true;
617 self.e.selectMimetype.value = r.mimetype;
618 self.tabs.switchToTab(self.e.tabs.content);
619 self.wikiContent(r.content);
620 self.dispatchEvent('wiki-page-loaded', r);
621 };
622 const semiWinfo = {name: name};
623 const stashWinfo = this.getStashedWinfo(semiWinfo);
624 if(stashWinfo){ // fake a response from the stash...
625 this.winfo = stashWinfo;
626 onload({
627 name: stashWinfo.name,
628 mimetype: stashWinfo.mimetype,
629 type: stashWinfo.type,
630 version: stashWinfo.version,
631 parent: stashWinfo.parent,
632 content: this.contentFromStash()
633 });
634 F.message("Fetched from the local-edit storage:",
635 stashWinfo.name);
636 return this;
637 }
@@ -774,10 +827,11 @@
774 $stash.updateWinfo(wi);
775 }else{
776 $stash.updateWinfo(wi, P.wikiContent());
777 }
778 F.message("Stashed change(s) to page ["+wi.name+"].");
 
779 $stash.prune();
780 this.previewNeedsUpdate = true;
781 }
782 return this;
783 };
@@ -818,8 +872,7 @@
818 filename/checkin values), return it, else return undefined.
819 */
820 P.getStashedWinfo = function(winfo){
821 return $stash.getWinfo(winfo);
822 };
823 P.$stash = $stash /* only for development/debugging */;
824
825 })(window.fossil);
826
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -240,12 +240,12 @@
240 console.warn("Pruned oldest local file edit entry:",e);
241 }
242 if(n) this._fireStashEvent();
243 }
244 };
245 $stash.prune.defaultMaxCount = P.config.defaultMaxStashSize || 10;
246 P.$stash = $stash /* we have to expose this for the new-page case :/ */;
247
248 /**
249 Internal workaround to select the current preview mode
250 and fire a change event if the value actually changes
251 or if forceEvent is truthy.
@@ -263,16 +263,23 @@
263 }
264 };
265
266 const WikiList = {
267 e: {},
268 /** Update OPTION elements to reflect whether the page has
269 local changes or is new/unsaved. */
270 refreshStashMarks: function(){
271 this.e.select.querySelectorAll(
272 'option'
273 ).forEach(function(o){
274 const stashed = $stash.getWinfo({name:o.value});
275 if(stashed){
276 const isNew = 'sandbox'===stashed.type ? false : !stashed.version;
277 D.addClass(o, isNew ? 'stashed-new' :'stashed');
278 }else{
279 D.removeClass(o, 'stashed', 'stashed-new');
280 }
281 });
282 },
283 init: function(parentElem){
284 const sel = D.select(), btn = D.button("Reload page list");
285 this.e.select = sel;
@@ -280,25 +287,45 @@
287 D.clearElement(parentElem);
288 D.append(
289 parentElem, btn,
290 D.append(D.span(), "Select a page to edit:"),
291 sel,
292 D.append(D.span(), "* = local edits exist"),
293 D.append(D.span(), "+ = new/unsaved page")
294 );
295 D.attr(sel, 'size', 10);
296 D.option(D.disable(D.clearElement(sel)), "Loading...");
297 const self = this;
298 btn.addEventListener(
299 'click',
300 function click(){
301 if(!click.sorticase){
302 click.sorticase = function(l,r){
303 l = l.toLowerCase();
304 r = r.toLowerCase();
305 return l<=r ? -1 : 1;
306 };
307 }
308 F.fetch('wikiajax/list',{
309 responseType: 'json',
310 onload: function(list){
311 /* Jump through some hoops to integrate new/unsaved
312 pages into the list of existing pages... We use a map
313 as an intermediary in order to filter out any local-stash
314 dupes from server-side copies. */
315 const map = {}, ndx = $stash.getIndex();
316 D.clearElement(sel);
317 list.forEach((name)=>map[name] = true);
318 Object.keys(ndx).forEach(function(key){
319 const winfo = ndx[key];
320 if(!winfo.version/*new page*/) map[winfo.name] = true;
321 });
322 Object.keys(map)
323 .sort(click.sorticase)
324 .forEach((name)=>D.option(sel, name));
325 D.enable(sel);
326 if(P.winfo) sel.value = P.winfo.name;
327 self.refreshStashMarks();
328 }
329 });
330 },
331 false
@@ -338,11 +365,15 @@
365 toDisable: undefined /* elements to disable during ajax activity */
366 };
367 F.fetch.beforesend = function f(){
368 if(!ajaxState.toDisable){
369 ajaxState.toDisable = document.querySelectorAll(
370 ['button:not([disabled])',
371 'input:not([disabled])',
372 'select:not([disabled])',
373 'textarea:not([disabled])'
374 ].join(',')
375 );
376 }
377 if(1===++ajaxState.count){
378 D.addClass(document.body, 'waiting');
379 D.disable(ajaxState.toDisable);
@@ -433,11 +464,21 @@
464 if(0) P.e.btnCommit.addEventListener(
465 "click",(e)=>P.commit(), false
466 );
467 F.confirmer(P.e.btnReload, {
468 confirmText: "Really reload, losing edits?",
469 onconfirm: function(e){
470 const w = P.winfo;
471 if(!w){
472 F.error("No page loaded.");
473 return;
474 }else if(!w.version){
475 F.error("Cannot reload a new/unsaved page.");
476 return;
477 }
478 P.unstashContent().loadPage();
479 },
480 ticks: 3
481 });
482 P.e.taEditor.addEventListener(
483 'change', ()=>P.stashContentChange(), false
484 );
@@ -451,11 +492,10 @@
492 P.stashContentChange(true);
493 }
494 },
495 false
496 );
 
497
498 const selectFontSize = E('select[name=editor_font_size]');
499 if(selectFontSize){
500 selectFontSize.addEventListener(
501 "change",function(e){
@@ -472,32 +512,43 @@
512 }
513
514 P.addEventListener(
515 // Clear certain views when new content is loaded/set
516 'wiki-content-replaced',
517 ()=>{
518 P.previewNeedsUpdate = true;
519 D.clearElement(P.e.diffTarget, P.e.previewTarget);
520 }
521 );
522 P.addEventListener(
523 // Clear certain views after a save
524 'wiki-saved',
525 (e)=>{
526 D.clearElement(P.e.diffTarget, P.e.previewTarget);
527 // TODO: replace preview with new content
 
528 }
529 );
530 WikiList.init( P.e.tabs.pageList.firstElementChild );
531 P.addEventListener(
532 // Update various state on wiki page load
533 'wiki-page-loaded',
534 function(ev){
535 delete P.winfo;
536 const winfo = ev.detail;
537 P.winfo = winfo;
538 P.previewNeedsUpdate = true;
539 P.e.selectMimetype.value = winfo.mimetype;
540 P.tabs.switchToTab(P.e.tabs.content);
541 P.wikiContent(winfo.content || '');
542 WikiList.e.select.value = winfo.name;
543 if(!winfo.version){
544 F.error('You are editing a new, unsaved page:',winfo.name);
545 }
546 P.updatePageTitle();
547 },
548 false
549 );
 
550 }/*F.onPageLoad()*/);
551
552 /**
553 Returns true if fossil.page.winfo is set, indicating that a page
554 has been loaded, else it reports an error and returns false.
@@ -507,10 +558,29 @@
558 */
559 const affirmPageLoaded = function(quiet){
560 if(!P.winfo && !quiet) F.error("No wiki page is loaded.");
561 return !!P.winfo;
562 };
563
564 /**
565 Update the page title and header based on the state
566 of this.winfo. A no-op if this.winfo is not set.
567 */
568 P.updatePageTitle = function f(){
569 if(!affirmPageLoaded(true)) return;
570 if(!f.titleElement){
571 f.titleElement = document.head.querySelector('title');
572 f.pageTitleHeader = document.querySelector('div.header .title');
573 }
574 var title = ['Wiki Editor:'];
575 if(!P.winfo.version) title.push('[+]');
576 else if($stash.getWinfo(P.winfo)) title.push('[*]')
577 title.push(P.winfo.name);
578 title = title.join(' ');
579 f.titleElement.innerText = title;
580 f.pageTitleHeader.innerText = title;
581 };
582
583 /**
584 Getter (if called with no args) or setter (if passed an arg) for
585 the current file content.
586
@@ -601,37 +671,20 @@
671 }else if(1===arguments.length && 'string' !== typeof name){
672 /* Assume winfo-like object */
673 const arg = arguments[0];
674 name = arg.name;
675 }
676 const onload = (r)=>this.dispatchEvent('wiki-page-loaded', r);
677 const stashWinfo = this.getStashedWinfo({name: name});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
678 if(stashWinfo){ // fake a response from the stash...
 
679 onload({
680 name: stashWinfo.name,
681 mimetype: stashWinfo.mimetype,
682 type: stashWinfo.type,
683 version: stashWinfo.version,
684 parent: stashWinfo.parent,
685 content: $stash.stashedContent(stashWinfo)
686 });
687 F.message("Fetched from the local-edit storage:",
688 stashWinfo.name);
689 return this;
690 }
@@ -774,10 +827,11 @@
827 $stash.updateWinfo(wi);
828 }else{
829 $stash.updateWinfo(wi, P.wikiContent());
830 }
831 F.message("Stashed change(s) to page ["+wi.name+"].");
832 P.updatePageTitle();
833 $stash.prune();
834 this.previewNeedsUpdate = true;
835 }
836 return this;
837 };
@@ -818,8 +872,7 @@
872 filename/checkin values), return it, else return undefined.
873 */
874 P.getStashedWinfo = function(winfo){
875 return $stash.getWinfo(winfo);
876 };
 
877
878 })(window.fossil);
879
--- src/style.wikiedit.css
+++ src/style.wikiedit.css
@@ -53,10 +53,13 @@
5353
body.wikiedit .wikiedit-page-list-wrapper select option {
5454
margin: 0.5em 0;
5555
}
5656
body.wikiedit .wikiedit-page-list-wrapper select option.stashed::before {
5757
content: "* ";
58
+}
59
+body.wikiedit .wikiedit-page-list-wrapper select option.stashed-new::before {
60
+ content: "+ ";
5861
}
5962
body.wikiedit textarea {
6063
max-width: calc(100% - 1em);
6164
}
6265
6366
--- src/style.wikiedit.css
+++ src/style.wikiedit.css
@@ -53,10 +53,13 @@
53 body.wikiedit .wikiedit-page-list-wrapper select option {
54 margin: 0.5em 0;
55 }
56 body.wikiedit .wikiedit-page-list-wrapper select option.stashed::before {
57 content: "* ";
 
 
 
58 }
59 body.wikiedit textarea {
60 max-width: calc(100% - 1em);
61 }
62
63
--- src/style.wikiedit.css
+++ src/style.wikiedit.css
@@ -53,10 +53,13 @@
53 body.wikiedit .wikiedit-page-list-wrapper select option {
54 margin: 0.5em 0;
55 }
56 body.wikiedit .wikiedit-page-list-wrapper select option.stashed::before {
57 content: "* ";
58 }
59 body.wikiedit .wikiedit-page-list-wrapper select option.stashed-new::before {
60 content: "+ ";
61 }
62 body.wikiedit textarea {
63 max-width: calc(100% - 1em);
64 }
65
66
+11 -14
--- src/wiki.c
+++ src/wiki.c
@@ -1122,29 +1122,26 @@
11221122
11231123
/* Dynamically populate the editor... */
11241124
style_emit_script_tag(0,0);
11251125
CX("\nfossil.onPageLoad(function(){\n");
11261126
CX("try{\n");
1127
- if(zMimetype && *zMimetype){
1128
- CX("fossil.page.selectMimetype(%!j);\n",
1129
- zMimetype);
1130
- }
11311127
if(found){
11321128
CX("fossil.page.loadPage(%!j);\n", zPageName);
11331129
}else if(zPageName && *zPageName){
1134
- /*
1135
- FIXME: we don't yet have a good way to integrate a
1136
- not-yet-existing/new/unsaved page into the UI.
1137
- */
1138
- CX("fossil.page.config.newPage = {"
1139
- "\"name\": %!j, \"mimetype\": %!j"
1130
+ /* For a new page, stick a dummy entry in the JS-side stash
1131
+ and simulate an on-load reaction to update the editor
1132
+ with that stashed state. */
1133
+ CX("const winfo = {"
1134
+ "\"name\": %!j, \"mimetype\": %!j, "
1135
+ "\"type\": %!j, "
1136
+ "\"parent\": null, \"version\": null"
11401137
"};\n",
11411138
zPageName,
1142
- zMimetype ? zMimetype : "text/x-fossil-wiki");
1143
- CX("fossil.error('You are editing a new, "
1144
- "unsaved page:',%!j);\n",
1145
- zPageName);
1139
+ zMimetype ? zMimetype : "text/x-fossil-wiki",
1140
+ wiki_page_type_name(zPageName));
1141
+ CX("fossil.page.$stash.updateWinfo(winfo,'');\n");
1142
+ CX("fossil.page.dispatchEvent('wiki-page-loaded',winfo);\n");
11461143
}
11471144
CX("}catch(e){"
11481145
"fossil.error(e); console.error('Exception:',e);"
11491146
"}\n");
11501147
CX("});\n"/*fossil.onPageLoad()*/);
11511148
--- src/wiki.c
+++ src/wiki.c
@@ -1122,29 +1122,26 @@
1122
1123 /* Dynamically populate the editor... */
1124 style_emit_script_tag(0,0);
1125 CX("\nfossil.onPageLoad(function(){\n");
1126 CX("try{\n");
1127 if(zMimetype && *zMimetype){
1128 CX("fossil.page.selectMimetype(%!j);\n",
1129 zMimetype);
1130 }
1131 if(found){
1132 CX("fossil.page.loadPage(%!j);\n", zPageName);
1133 }else if(zPageName && *zPageName){
1134 /*
1135 FIXME: we don't yet have a good way to integrate a
1136 not-yet-existing/new/unsaved page into the UI.
1137 */
1138 CX("fossil.page.config.newPage = {"
1139 "\"name\": %!j, \"mimetype\": %!j"
 
1140 "};\n",
1141 zPageName,
1142 zMimetype ? zMimetype : "text/x-fossil-wiki");
1143 CX("fossil.error('You are editing a new, "
1144 "unsaved page:',%!j);\n",
1145 zPageName);
1146 }
1147 CX("}catch(e){"
1148 "fossil.error(e); console.error('Exception:',e);"
1149 "}\n");
1150 CX("});\n"/*fossil.onPageLoad()*/);
1151
--- src/wiki.c
+++ src/wiki.c
@@ -1122,29 +1122,26 @@
1122
1123 /* Dynamically populate the editor... */
1124 style_emit_script_tag(0,0);
1125 CX("\nfossil.onPageLoad(function(){\n");
1126 CX("try{\n");
 
 
 
 
1127 if(found){
1128 CX("fossil.page.loadPage(%!j);\n", zPageName);
1129 }else if(zPageName && *zPageName){
1130 /* For a new page, stick a dummy entry in the JS-side stash
1131 and simulate an on-load reaction to update the editor
1132 with that stashed state. */
1133 CX("const winfo = {"
1134 "\"name\": %!j, \"mimetype\": %!j, "
1135 "\"type\": %!j, "
1136 "\"parent\": null, \"version\": null"
1137 "};\n",
1138 zPageName,
1139 zMimetype ? zMimetype : "text/x-fossil-wiki",
1140 wiki_page_type_name(zPageName));
1141 CX("fossil.page.$stash.updateWinfo(winfo,'');\n");
1142 CX("fossil.page.dispatchEvent('wiki-page-loaded',winfo);\n");
1143 }
1144 CX("}catch(e){"
1145 "fossil.error(e); console.error('Exception:',e);"
1146 "}\n");
1147 CX("});\n"/*fossil.onPageLoad()*/);
1148

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button