| | @@ -263,36 +263,52 @@ |
| 263 | 263 | } |
| 264 | 264 | }; |
| 265 | 265 | |
| 266 | 266 | const WikiList = { |
| 267 | 267 | e: {}, |
| 268 | | - /** Update OPTION elements to reflect whether the page has |
| 268 | + /** Updates OPTION elements to reflect whether the page has |
| 269 | 269 | local changes or is new/unsaved. */ |
| 270 | 270 | refreshStashMarks: function(){ |
| 271 | | - this.e.select.querySelectorAll( |
| 272 | | - 'option' |
| 273 | | - ).forEach(function(o){ |
| 274 | | - const stashed = $stash.getWinfo({name:o.value}); |
| 271 | + const sel = this.e.select; |
| 272 | + Object.keys(sel.options).forEach(function(key){ |
| 273 | + const opt = sel.options[key]; |
| 274 | + const stashed = $stash.getWinfo({name:opt.value}); |
| 275 | 275 | if(stashed){ |
| 276 | 276 | const isNew = 'sandbox'===stashed.type ? false : !stashed.version; |
| 277 | | - D.addClass(o, isNew ? 'stashed-new' :'stashed'); |
| 277 | + D.addClass(opt, isNew ? 'stashed-new' :'stashed'); |
| 278 | 278 | }else{ |
| 279 | | - D.removeClass(o, 'stashed', 'stashed-new'); |
| 279 | + D.removeClass(opt, 'stashed', 'stashed-new'); |
| 280 | 280 | } |
| 281 | 281 | }); |
| 282 | 282 | }, |
| 283 | + /** Removes the given wiki page entry from the page selection |
| 284 | + list, if it's in the list. */ |
| 285 | + removeEntry: function(name){ |
| 286 | + const sel = this.e.select; |
| 287 | + const ndx = sel.selectedIndex; |
| 288 | + sel.value = name; |
| 289 | + if(sel.selectedIndex>-1){ |
| 290 | + sel.options.remove(sel.selectedIndex); |
| 291 | + } |
| 292 | + sel.selectedIndex = ndx; |
| 293 | + }, |
| 294 | + /** |
| 295 | + Installs a wiki page selection list into the given parent DOM |
| 296 | + element and loads the page list from the server. |
| 297 | + */ |
| 283 | 298 | init: function(parentElem){ |
| 284 | 299 | const sel = D.select(), btn = D.button("Reload page list"); |
| 285 | 300 | this.e.select = sel; |
| 286 | 301 | D.addClass(parentElem, 'wikiedit-page-list-wrapper'); |
| 287 | 302 | D.clearElement(parentElem); |
| 288 | 303 | D.append( |
| 289 | | - parentElem, btn, |
| 304 | + parentElem, |
| 290 | 305 | D.append(D.span(), "Select a page to edit:"), |
| 291 | 306 | sel, |
| 292 | | - D.append(D.span(), "* = local edits exist"), |
| 293 | | - D.append(D.span(), "+ = new/unsaved page") |
| 307 | + D.append(D.span(), "[*] = page has local edits"), |
| 308 | + D.append(D.span(), "[+] = page is new/unsaved"), |
| 309 | + btn |
| 294 | 310 | ); |
| 295 | 311 | D.attr(sel, 'size', 10); |
| 296 | 312 | D.option(D.disable(D.clearElement(sel)), "Loading..."); |
| 297 | 313 | const self = this; |
| 298 | 314 | btn.addEventListener( |
| | @@ -339,10 +355,11 @@ |
| 339 | 355 | F.page.addEventListener( |
| 340 | 356 | 'wiki-stash-updated', |
| 341 | 357 | ()=>this.refreshStashMarks(), |
| 342 | 358 | false |
| 343 | 359 | ); |
| 360 | + delete this.init; |
| 344 | 361 | } |
| 345 | 362 | }; |
| 346 | 363 | |
| 347 | 364 | /** |
| 348 | 365 | Keep track of how many in-flight AJAX requests there are so we |
| | @@ -469,15 +486,27 @@ |
| 469 | 486 | onconfirm: function(e){ |
| 470 | 487 | const w = P.winfo; |
| 471 | 488 | if(!w){ |
| 472 | 489 | F.error("No page loaded."); |
| 473 | 490 | return; |
| 474 | | - }else if(!w.version){ |
| 475 | | - F.error("Cannot reload a new/unsaved page."); |
| 491 | + } |
| 492 | + if(!w.version/* new/unsaved page */ && P.wikiContent()){ |
| 493 | + F.error("This new/unsaved page has content.", |
| 494 | + "To really discard this page,", |
| 495 | + "first clear its content", |
| 496 | + "then use the Discard button."); |
| 476 | 497 | return; |
| 477 | 498 | } |
| 478 | | - P.unstashContent().loadPage(); |
| 499 | + P.unstashContent() |
| 500 | + if(w.version){ |
| 501 | + P.loadPage(); |
| 502 | + }else{ |
| 503 | + delete P.winfo; |
| 504 | + WikiList.removeEntry(w.name); |
| 505 | + P.updatePageTitle(); |
| 506 | + F.message("Discarded new page ["+w.name+"]."); |
| 507 | + } |
| 479 | 508 | }, |
| 480 | 509 | ticks: 3 |
| 481 | 510 | }); |
| 482 | 511 | P.e.taEditor.addEventListener( |
| 483 | 512 | 'change', ()=>P.stashContentChange(), false |
| | @@ -560,26 +589,30 @@ |
| 560 | 589 | if(!P.winfo && !quiet) F.error("No wiki page is loaded."); |
| 561 | 590 | return !!P.winfo; |
| 562 | 591 | }; |
| 563 | 592 | |
| 564 | 593 | /** |
| 565 | | - Update the page title and header based on the state |
| 566 | | - of this.winfo. A no-op if this.winfo is not set. |
| 594 | + Update the page title and header based on the state of |
| 595 | + this.winfo. A no-op if this.winfo is not set. Returns this. |
| 567 | 596 | */ |
| 568 | 597 | P.updatePageTitle = function f(){ |
| 569 | | - if(!affirmPageLoaded(true)) return; |
| 570 | 598 | if(!f.titleElement){ |
| 571 | 599 | f.titleElement = document.head.querySelector('title'); |
| 572 | 600 | f.pageTitleHeader = document.querySelector('div.header .title'); |
| 573 | 601 | } |
| 574 | 602 | 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); |
| 603 | + if(P.winfo){ |
| 604 | + if(!P.winfo.version) title.push('[+]'); |
| 605 | + else if($stash.getWinfo(P.winfo)) title.push('[*]') |
| 606 | + title.push(P.winfo.name); |
| 607 | + }else{ |
| 608 | + title.push('(no page loaded)'); |
| 609 | + } |
| 578 | 610 | title = title.join(' '); |
| 579 | 611 | f.titleElement.innerText = title; |
| 580 | 612 | f.pageTitleHeader.innerText = title; |
| 613 | + return this; |
| 581 | 614 | }; |
| 582 | 615 | |
| 583 | 616 | /** |
| 584 | 617 | Getter (if called with no args) or setter (if passed an arg) for |
| 585 | 618 | the current file content. |
| | @@ -674,20 +707,20 @@ |
| 674 | 707 | name = arg.name; |
| 675 | 708 | } |
| 676 | 709 | const onload = (r)=>this.dispatchEvent('wiki-page-loaded', r); |
| 677 | 710 | const stashWinfo = this.getStashedWinfo({name: name}); |
| 678 | 711 | if(stashWinfo){ // fake a response from the stash... |
| 712 | + F.message("Fetched from the local-edit storage:", |
| 713 | + stashWinfo.name); |
| 679 | 714 | onload({ |
| 680 | 715 | name: stashWinfo.name, |
| 681 | 716 | mimetype: stashWinfo.mimetype, |
| 682 | 717 | type: stashWinfo.type, |
| 683 | 718 | version: stashWinfo.version, |
| 684 | 719 | parent: stashWinfo.parent, |
| 685 | 720 | content: $stash.stashedContent(stashWinfo) |
| 686 | 721 | }); |
| 687 | | - F.message("Fetched from the local-edit storage:", |
| 688 | | - stashWinfo.name); |
| 689 | 722 | return this; |
| 690 | 723 | } |
| 691 | 724 | F.message( |
| 692 | 725 | "Loading content..." |
| 693 | 726 | ).fetch('wikiajax/fetch',{ |
| | @@ -694,12 +727,12 @@ |
| 694 | 727 | urlParams: { |
| 695 | 728 | page: name |
| 696 | 729 | }, |
| 697 | 730 | responseType: 'json', |
| 698 | 731 | onload:(r)=>{ |
| 699 | | - onload(r); |
| 700 | 732 | F.message('Loaded page ['+r.name+'].'); |
| 733 | + onload(r); |
| 701 | 734 | } |
| 702 | 735 | }); |
| 703 | 736 | return this; |
| 704 | 737 | }; |
| 705 | 738 | |
| 706 | 739 | |