pict-docuserve 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/indoctrinate_content_staging/Indoctrinate-Catalog-AppData.json +267 -458
- package/dist/pict-docuserve.js +73 -17
- package/dist/pict-docuserve.js.map +1 -1
- package/dist/pict-docuserve.min.js +2 -2
- package/dist/pict-docuserve.min.js.map +1 -1
- package/package.json +3 -3
- package/source/Pict-Application-Docuserve.js +2 -2
- package/source/cli/Docuserve-CLI-Program.js +2 -1
- package/source/cli/commands/Docuserve-Command-CheckLinks.js +428 -0
- package/source/cli/commands/Docuserve-Command-StageExamples.js +32 -27
- package/source/providers/Pict-Provider-Docuserve-Documentation.js +150 -15
- package/source/views/PictView-Docuserve-Splash.js +126 -0
package/dist/pict-docuserve.js
CHANGED
|
@@ -6050,7 +6050,12 @@ if(tmpInList){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');tmpInList=false;}
|
|
|
6050
6050
|
if(tmpLine.match(/^(-{3,}|\*{3,}|_{3,})\s*$/)){fFlushParagraph();if(tmpInList){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');tmpInList=false;}tmpHTML.push('<hr>');continue;}// Headings
|
|
6051
6051
|
let tmpHeadingMatch=tmpLine.match(/^(#{1,6})\s+(.+)/);if(tmpHeadingMatch){fFlushParagraph();if(tmpInList){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');tmpInList=false;}let tmpLevel=tmpHeadingMatch[1].length;let tmpText=this.parseInline(tmpHeadingMatch[2],pLinkResolver,pImageResolver,pVocabularyResolver);let tmpID=tmpHeadingMatch[2].toLowerCase().replace(/[^\w\s-]/g,'').replace(/\s+/g,'-');tmpHTML.push('<h'+tmpLevel+' id="'+tmpID+'">'+tmpText+'</h'+tmpLevel+'>');continue;}// Unordered list items
|
|
6052
6052
|
let tmpULMatch=tmpLine.match(/^(\s*)[-*+]\s+(.*)/);if(tmpULMatch){fFlushParagraph();if(!tmpInList||tmpListType!=='ul'){if(tmpInList){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');}tmpHTML.push('<ul>');tmpInList=true;tmpListType='ul';}tmpHTML.push('<li>'+this.parseInline(tmpULMatch[2],pLinkResolver,pImageResolver,pVocabularyResolver)+'</li>');continue;}// Ordered list items
|
|
6053
|
-
let tmpOLMatch=tmpLine.match(/^(\s*)\d+\.\s+(.*)/);if(tmpOLMatch){fFlushParagraph();if(!tmpInList||tmpListType!=='ol'){if(tmpInList){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');}tmpHTML.push('<ol>');tmpInList=true;tmpListType='ol';}tmpHTML.push('<li>'+this.parseInline(tmpOLMatch[2],pLinkResolver,pImageResolver,pVocabularyResolver)+'</li>');continue;}//
|
|
6053
|
+
let tmpOLMatch=tmpLine.match(/^(\s*)\d+\.\s+(.*)/);if(tmpOLMatch){fFlushParagraph();if(!tmpInList||tmpListType!=='ol'){if(tmpInList){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');}tmpHTML.push('<ol>');tmpInList=true;tmpListType='ol';}tmpHTML.push('<li>'+this.parseInline(tmpOLMatch[2],pLinkResolver,pImageResolver,pVocabularyResolver)+'</li>');continue;}// Indented continuation line of a wrapped list item — fold its
|
|
6054
|
+
// content into the last <li> instead of closing the list. Closing
|
|
6055
|
+
// here would split a real <ol>/<ul>, and each fragment restarts
|
|
6056
|
+
// ordered numbering. A non-indented non-marker line still closes
|
|
6057
|
+
// the list (handled below); blank lines never reach this branch.
|
|
6058
|
+
if(tmpInList&&tmpLine.match(/^\s+\S/)&&tmpHTML.length>0&&tmpHTML[tmpHTML.length-1].endsWith('</li>')){let tmpLastIndex=tmpHTML.length-1;let tmpListItemBody=tmpHTML[tmpLastIndex].slice(0,-'</li>'.length);tmpHTML[tmpLastIndex]=tmpListItemBody+' '+this.parseInline(tmpLine.trim(),pLinkResolver,pImageResolver,pVocabularyResolver)+'</li>';continue;}// Close list if we've left list items
|
|
6054
6059
|
if(tmpInList&&tmpLine.trim()!==''){tmpHTML.push(tmpListType==='ul'?'</ul>':'</ol>');tmpInList=false;}// Empty line — flush any accumulated paragraph
|
|
6055
6060
|
if(tmpLine.trim()===''){fFlushParagraph();continue;}// Table detection
|
|
6056
6061
|
if(tmpLine.match(/^\|/)&&i+1<tmpLines.length&&tmpLines[i+1].match(/^\|[\s-:|]+\|/)){fFlushParagraph();// Close any open list
|
|
@@ -12634,7 +12639,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
|
|
|
12634
12639
|
// presumably different callback function.
|
|
12635
12640
|
// This makes sure that own properties are retained, so that
|
|
12636
12641
|
// decorations and such are not lost along the way.
|
|
12637
|
-
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],346:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],347:[function(require,module,exports){module.exports={"name":"pict-docuserve","version":"1.3.
|
|
12642
|
+
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],346:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],347:[function(require,module,exports){module.exports={"name":"pict-docuserve","version":"1.3.4","description":"Pict Documentation Server - A single-page documentation viewer built on Pict","main":"source/Pict-Application-Docuserve.js","bin":{"pict-docuserve":"source/cli/Docuserve-CLI-Run.js"},"files":["source/","dist/","html/"],"scripts":{"start":"node source/cli/Docuserve-CLI-Run.js serve","brand":"node node_modules/pict-section-theme/bin/pict-section-theme-brand.js --manifest ../../../Retold-Modules-Manifest.json --module pict-docuserve","prebuild":"npm run brand","build":"npx quack build && npx quack copy","prebuild-docs":"npm run brand","build-docs":"npx quack build && npx quack copy && node source/cli/Docuserve-CLI-Run.js inject ./docs && node example_applications/build-examples.js stage-docs","serve-docs":"node source/cli/Docuserve-CLI-Run.js serve ./docs","serve-examples":"node example_applications/build-examples.js","test":"npx quack test","tests":"npx quack test -g","coverage":"npx quack coverage","prepublishOnly":"npm run build"},"author":"steven velozo <steven@velozo.com>","license":"MIT","dependencies":{"fable-serviceproviderbase":"^3.0.19","lunr":"^2.3.9","pict":"^1.0.372","pict-application":"^1.0.34","pict-provider":"^1.0.13","pict-section-code":"^1.0.11","pict-section-content":"^1.0.4","pict-section-histogram":"^1.0.1","pict-section-modal":"^1.1.1","pict-section-theme":"^1.0.5","pict-service-commandlineutility":"^1.0.19","pict-view":"^1.0.68"},"devDependencies":{"pict-docuserve":"^1.3.3","quackage":"^1.2.4"},"copyFilesSettings":{"whenFileExists":"overwrite"},"copyFiles":[{"from":"./html/*","to":"./dist/"}],"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"retold":{"brand":{"Hash":"pict-docuserve","Name":"Pict Docuserve","Tagline":"A documentation viewer built on Pict","Palette":"default","Icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"frame-pict-docuserve-filled-light\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#692bbf\"/>\n\t\t<g clip-path=\"url(#frame-pict-docuserve-filled-light)\"><rect x=\"18\" y=\"30\" width=\"48\" height=\"48\" rx=\"8\" fill=\"#c13ccd\" opacity=\"0.9\"/>\n\t\t\t\t\t<rect x=\"30\" y=\"18\" width=\"48\" height=\"48\" rx=\"8\" fill=\"rgba(255,255,255,0.18)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"38\" font-weight=\"600\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">PD</text>\n\t</svg>","IconType":"svg","Favicon":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-pict-docuserve-light\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#692bbf\"/>\n\t\t<g clip-path=\"url(#fav-pict-docuserve-light)\"><rect x=\"28\" y=\"16\" width=\"52\" height=\"52\" rx=\"9\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#ffffff\" letter-spacing=\"-1\">P</text>\n\t</svg>","FaviconDark":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 96 96\" width=\"96\" height=\"96\">\n\t\t<defs>\n\t\t\t<clipPath id=\"fav-pict-docuserve-dark\">\n\t\t\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\"/>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<path d=\"M 2 48\n\t\t\tC 2 18.0222416, 18.0222416 2, 48 2\n\t\t\tC 77.9777584 2, 94 18.0222416, 94 48\n\t\t\tC 94 77.9777584, 77.9777584 94, 48 94\n\t\t\tC 18.0222416 94, 2 77.9777584, 2 48 Z\" fill=\"#9a6fd8\"/>\n\t\t<g clip-path=\"url(#fav-pict-docuserve-dark)\"><rect x=\"28\" y=\"16\" width=\"52\" height=\"52\" rx=\"9\" fill=\"rgba(255,255,255,0.22)\"/></g>\n\t\t<text x=\"48\" y=\"50\" text-anchor=\"middle\" dominant-baseline=\"central\"\n\t\t\tfont-family=\"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\"\n\t\t\tfont-size=\"60\" font-weight=\"800\"\n\t\t\tfill=\"#101418\" letter-spacing=\"-1\">P</text>\n\t</svg>","Colors":{"Primary":"#692bbf","Secondary":"#c13ccd","PrimaryLight":"#692bbf","PrimaryDark":"#9a6fd8","SecondaryLight":"#c13ccd","SecondaryDark":"#d48adb"}}}};},{}],348:[function(require,module,exports){/**
|
|
12638
12643
|
* Docuserve-Brand — docuserve's own wordmark, used only as a fallback.
|
|
12639
12644
|
*
|
|
12640
12645
|
* Docuserve is a viewer: the docs being served dictate the brand, not
|
|
@@ -12814,9 +12819,9 @@ let tmpPath=pDocPath;if(!tmpPath.match(/\.md$/)){tmpPath=tmpPath+'.md';}tmpDocPr
|
|
|
12814
12819
|
// <path>/README.md so directory-style links resolve.
|
|
12815
12820
|
if(pError&&!tmpPath.match(/(^|\/)README\.md$/i)){let tmpReadmePath=tmpPath.replace(/\.md$/i,'')+'/README.md';tmpDocProvider.fetchLocalDocument(tmpReadmePath,(pReadmeError,pReadmeHTML)=>{// Show the README on success, else the original
|
|
12816
12821
|
// not-found page (it names the path the user asked for).
|
|
12817
|
-
tmpContentView.displayContent(pReadmeError?pHTML:pReadmeHTML);});return;}// fetchDocument always provides displayable HTML in pHTML,
|
|
12822
|
+
tmpContentView.displayContent(pReadmeError?pHTML:pReadmeHTML);},'','',tmpReadmePath);return;}// fetchDocument always provides displayable HTML in pHTML,
|
|
12818
12823
|
// even on error, so we can use it directly.
|
|
12819
|
-
tmpContentView.displayContent(pHTML);});}/**
|
|
12824
|
+
tmpContentView.displayContent(pHTML);},'','',tmpPath);}/**
|
|
12820
12825
|
* Navigate to the search page with an optional query.
|
|
12821
12826
|
*
|
|
12822
12827
|
* @param {string} pQuery - The search query (may be empty for blank search page)
|
|
@@ -12932,14 +12937,19 @@ this._ContentProvider=this.pict.addProvider('Pict-Content',libPictContentProvide
|
|
|
12932
12937
|
* @param {string} [pCurrentModule] - The current module name
|
|
12933
12938
|
* @param {string} [pCurrentDocPath] - The current document path
|
|
12934
12939
|
* @returns {Function} A link resolver callback
|
|
12935
|
-
*/_createLinkResolver(pCurrentGroup,pCurrentModule,pCurrentDocPath){return(pHref,pLinkText)=>{
|
|
12940
|
+
*/_createLinkResolver(pCurrentGroup,pCurrentModule,pCurrentDocPath){return(pHref,pLinkText)=>{let tmpHref=String(pHref||'');let tmpIsModuleMode=this.getDocsMode()==='module';// Built example applications (and other static .html pages) are
|
|
12936
12941
|
// served as plain files alongside the docs. Link straight to
|
|
12937
|
-
// them in a new tab rather than SPA-routing through #/page/.
|
|
12938
|
-
//
|
|
12939
|
-
//
|
|
12940
|
-
|
|
12941
|
-
if(
|
|
12942
|
-
let
|
|
12942
|
+
// them in a new tab rather than SPA-routing through #/page/. In
|
|
12943
|
+
// module mode the href is resolved against the current
|
|
12944
|
+
// document's directory, exactly the way a .md link is — so every
|
|
12945
|
+
// relative link in the docs shares one base.
|
|
12946
|
+
if(!tmpHref.match(/^[a-z][a-z0-9+.-]*:/i)&&tmpHref.match(/\.html($|[?#])/i)){let tmpAssetHref=tmpIsModuleMode?this._toModuleAssetHref(tmpHref,pCurrentDocPath):tmpHref;return{href:tmpAssetHref,target:'_blank',rel:'noopener'};}// Convert internal doc links to hash routes
|
|
12947
|
+
if(tmpHref.match(/^\//)||tmpHref.match(/^[^:]+\.md/)){let tmpRoute=this.convertDocLink(tmpHref,pCurrentGroup,pCurrentModule,pCurrentDocPath);return{href:tmpRoute};}// Check if this is a GitHub URL that matches a catalog module
|
|
12948
|
+
let tmpCatalogRoute=this.resolveGitHubURLToRoute(tmpHref);if(tmpCatalogRoute){return{href:tmpCatalogRoute};}// Module mode: a remaining relative link (a directory, a media
|
|
12949
|
+
// file, a .json) is resolved against the current document's
|
|
12950
|
+
// directory too, so it shares the one base every other link uses
|
|
12951
|
+
// rather than silently falling back to the docs root.
|
|
12952
|
+
if(tmpIsModuleMode&&tmpHref&&tmpHref.charAt(0)!=='#'&&tmpHref.indexOf('//')!==0&&!tmpHref.match(/^[a-z][a-z0-9+.-]*:/i)){return{href:this._toModuleAssetHref(tmpHref,pCurrentDocPath)};}// Use default behavior for other links
|
|
12943
12953
|
return null;};}/**
|
|
12944
12954
|
* Create an image resolver closure for the content provider.
|
|
12945
12955
|
*
|
|
@@ -12998,7 +13008,9 @@ if(!this.pict.AppData.Docuserve.CoverLoaded){this.pict.AppData.Docuserve.Cover={
|
|
|
12998
13008
|
*
|
|
12999
13009
|
* @param {string} pMarkdown - Raw _cover.md content
|
|
13000
13010
|
* @returns {Object} Parsed cover data
|
|
13001
|
-
*/parseCover(pMarkdown){let tmpCover={Title:'',Tagline:'',Description:'',Highlights:[],Actions:[]};let tmpLines=pMarkdown.split('\n');for(let i=0;i<tmpLines.length;i++){let tmpLine=tmpLines[i].trim()
|
|
13011
|
+
*/parseCover(pMarkdown){let tmpCover={Title:'',Tagline:'',Description:'',Highlights:[],Actions:[],ExamplesMarkdown:''};let tmpLines=pMarkdown.split('\n');let tmpInExamples=false;for(let i=0;i<tmpLines.length;i++){let tmpLine=tmpLines[i].trim();// Generated examples region — collected verbatim for the splash's
|
|
13012
|
+
// "Interactive Examples" section, never parsed as cover fields.
|
|
13013
|
+
if(tmpLine==='<!-- docuserve:examples:start -->'){tmpInExamples=true;continue;}if(tmpLine==='<!-- docuserve:examples:end -->'){tmpInExamples=false;continue;}if(tmpInExamples){if(tmpLine){tmpCover.ExamplesMarkdown+=(tmpCover.ExamplesMarkdown?'\n':'')+tmpLine;}continue;}if(!tmpLine){continue;}// Heading — the title
|
|
13002
13014
|
let tmpHeadingMatch=tmpLine.match(/^#+\s+(.+)/);if(tmpHeadingMatch){tmpCover.Title=tmpHeadingMatch[1].trim();continue;}// Blockquote — the tagline
|
|
13003
13015
|
let tmpBlockquoteMatch=tmpLine.match(/^>\s*(.*)/);if(tmpBlockquoteMatch){tmpCover.Tagline=tmpBlockquoteMatch[1].trim();continue;}// Bullet list — highlights (e.g. "- **Fable** — Core ecosystem, DI, config")
|
|
13004
13016
|
let tmpBulletMatch=tmpLine.match(/^[-*+]\s+(.*)/);if(tmpBulletMatch){let tmpBulletContent=tmpBulletMatch[1];// Try to split on bold label: **Label** — rest
|
|
@@ -13109,11 +13121,41 @@ let tmpURL;if(pGroup&&pModule&&this._Catalog){tmpURL=this.resolveDocumentURL(pGr
|
|
|
13109
13121
|
* @returns {string} 'module' | 'ecosystem' | 'legacy'
|
|
13110
13122
|
*/getDocsMode(){if(this._Catalog&&(this._Catalog.Mode==='module'||this._Catalog.Mode==='ecosystem')){return this._Catalog.Mode;}if(this._KeywordIndexMode==='module'||this._KeywordIndexMode==='ecosystem'){return this._KeywordIndexMode;}return'legacy';}/**
|
|
13111
13123
|
* Module-mode link resolution: every internal documentation reference is
|
|
13112
|
-
* a local page.
|
|
13124
|
+
* a local page. Relative links (./sibling.md, ../other.md, bare names)
|
|
13125
|
+
* resolve against the directory of the document that contains them — the
|
|
13126
|
+
* way the links read on disk — while a /-rooted href resolves against the
|
|
13127
|
+
* docs root. "." and ".." segments are collapsed; ".." is clamped at the
|
|
13128
|
+
* docs root so a link can never escape above it.
|
|
13113
13129
|
*
|
|
13114
13130
|
* @param {string} pHref - The raw link href
|
|
13131
|
+
* @param {string} [pCurrentDocPath] - Docs-root-relative path of the
|
|
13132
|
+
* document the link lives in (e.g.
|
|
13133
|
+
* "examples/gradebook/README.md"). Absent for root-level
|
|
13134
|
+
* contexts such as the sidebar.
|
|
13115
13135
|
* @returns {string} A #/page/ hash route (#/Home for an empty path)
|
|
13116
|
-
*/_toModulePageRoute(pHref){let
|
|
13136
|
+
*/_toModulePageRoute(pHref,pCurrentDocPath){let tmpHref=String(pHref||'').trim();// A /-rooted href resolves against the docs root; every other href
|
|
13137
|
+
// resolves against the current document's directory.
|
|
13138
|
+
let tmpBaseDir='';if(tmpHref.charAt(0)==='/'){tmpHref=tmpHref.replace(/^\/+/,'');}else if(pCurrentDocPath){let tmpDirParts=String(pCurrentDocPath).split('/');tmpDirParts.pop();tmpBaseDir=tmpDirParts.join('/');}let tmpPath=this._resolveRelativeDocPath(tmpBaseDir,tmpHref);if(!tmpPath){return'#/Home';}return'#/page/'+tmpPath.replace(/\.md$/i,'');}/**
|
|
13139
|
+
* Resolve a relative href against a base directory, collapsing "." and
|
|
13140
|
+
* ".." segments. ".." is clamped at the docs root — it can never escape
|
|
13141
|
+
* above it. Both arguments are POSIX-style docs-root-relative paths.
|
|
13142
|
+
*
|
|
13143
|
+
* @param {string} pBaseDir - The directory the href is relative to.
|
|
13144
|
+
* @param {string} pHref - The href to resolve.
|
|
13145
|
+
* @returns {string} The resolved docs-root-relative path (no leading slash).
|
|
13146
|
+
*/_resolveRelativeDocPath(pBaseDir,pHref){let tmpSegments=[];let tmpCombined=(pBaseDir?pBaseDir+'/':'')+String(pHref||'');let tmpParts=tmpCombined.split('/');for(let i=0;i<tmpParts.length;i++){let tmpPart=tmpParts[i];if(tmpPart===''||tmpPart==='.'){continue;}if(tmpPart==='..'){if(tmpSegments.length>0){tmpSegments.pop();}continue;}tmpSegments.push(tmpPart);}return tmpSegments.join('/');}/**
|
|
13147
|
+
* Module-mode resolution for a non-routed link — a built .html page, a
|
|
13148
|
+
* media file, a directory. Resolves the href against the current
|
|
13149
|
+
* document's directory (a /-rooted href against the docs root), the same
|
|
13150
|
+
* way _toModulePageRoute resolves a .md link, and returns a plain
|
|
13151
|
+
* docs-root-relative href. The browser resolves that href against the
|
|
13152
|
+
* docs-root index.html, so it points at the right file from any page.
|
|
13153
|
+
*
|
|
13154
|
+
* @param {string} pHref - The raw link href
|
|
13155
|
+
* @param {string} [pCurrentDocPath] - Docs-root-relative path of the
|
|
13156
|
+
* document the link lives in.
|
|
13157
|
+
* @returns {string} A docs-root-relative href.
|
|
13158
|
+
*/_toModuleAssetHref(pHref,pCurrentDocPath){let tmpHref=String(pHref||'').trim();if(!tmpHref){return tmpHref;}let tmpBaseDir='';if(tmpHref.charAt(0)==='/'){tmpHref=tmpHref.replace(/^\/+/,'');}else if(pCurrentDocPath){let tmpDirParts=String(pCurrentDocPath).split('/');tmpDirParts.pop();tmpBaseDir=tmpDirParts.join('/');}return this._resolveRelativeDocPath(tmpBaseDir,tmpHref);}/**
|
|
13117
13159
|
* Check whether a group/module pair exists in the loaded catalog.
|
|
13118
13160
|
*
|
|
13119
13161
|
* Used by search() to decide whether a result should route to
|
|
@@ -13322,8 +13364,9 @@ if(this._ContentCache[pURL]){return tmpCallback(null,this._ContentCache[pURL]);}
|
|
|
13322
13364
|
* @param {string} [pCurrentModule] - The current module name (e.g. "fable")
|
|
13323
13365
|
* @param {string} [pCurrentDocPath] - The current document path within the module (e.g. "services/README.md")
|
|
13324
13366
|
* @returns {string} The converted hash route
|
|
13325
|
-
*/convertDocLink(pHref,pCurrentGroup,pCurrentModule,pCurrentDocPath){// Single-module docs site: every internal reference is a local page
|
|
13326
|
-
|
|
13367
|
+
*/convertDocLink(pHref,pCurrentGroup,pCurrentModule,pCurrentDocPath){// Single-module docs site: every internal reference is a local page,
|
|
13368
|
+
// resolved relative to the current document's directory.
|
|
13369
|
+
if(this.getDocsMode()==='module'){return this._toModulePageRoute(pHref,pCurrentDocPath);}// Strip leading ./ prefix for relative paths
|
|
13327
13370
|
let tmpPath=pHref.replace(/^\.\//,'');// Remove leading slash
|
|
13328
13371
|
tmpPath=tmpPath.replace(/^\//,'');// If it looks like an absolute module path (group/module/...), route directly.
|
|
13329
13372
|
// Both the group AND the module must exist in the catalog, otherwise treat
|
|
@@ -13885,7 +13928,9 @@ let tmpGroupRoute=tmpGroup.Route||'';if(!tmpGroupRoute){for(let k=0;k<tmpGroup.M
|
|
|
13885
13928
|
// new section each time the title changes.
|
|
13886
13929
|
if(tmpSidebar&&tmpSidebar.length>0){let tmpCurrentSection=null;for(let i=0;i<tmpSidebar.length;i++){let tmpEntry=tmpSidebar[i];if(tmpEntry.Children){tmpCurrentSection={TitleSlot:[{Title:tmpEntry.Title}],Items:[]};tmpSections.push(tmpCurrentSection);for(let j=0;j<tmpEntry.Children.length;j++){let tmpChild=tmpEntry.Children[j];if(tmpChild.Path){tmpCurrentSection.Items.push({Title:tmpChild.Title,Route:tmpRoutePrefix+tmpChild.Path,ActiveClass:''});}}}else if(tmpEntry.Path){if(!tmpCurrentSection||tmpCurrentSection.TitleSlot.length>0){tmpCurrentSection={TitleSlot:[],Items:[]};tmpSections.push(tmpCurrentSection);}tmpCurrentSection.Items.push({Title:tmpEntry.Title,Route:tmpRoutePrefix+tmpEntry.Path,ActiveClass:''});}}}// Demos sub-section: titled, with active state mirroring the
|
|
13887
13930
|
// current demo route.
|
|
13888
|
-
if(tmpDemos.length>0){let tmpDemoSection={TitleSlot:[{Title:'Demos'}],Items:[]};for(let i=0;i<tmpDemos.length;i++){let tmpDemo=tmpDemos[i];tmpDemoSection.Items.push({Title:tmpDemo.Name||tmpDemo.Hash,Route:tmpDemoPrefix+tmpDemo.Hash,ActiveClass:tmpDemo.Hash===tmpCurrentDemo?'active':''});}tmpSections.push(tmpDemoSection);}this.pict.AppData.Docuserve.ModuleNavSections=tmpSections;}_refreshSearchResults(pQuery){let tmpDocuserve=this.pict.AppData.Docuserve;if(!pQuery||!pQuery.trim()){tmpDocuserve.SidebarSearchResults=[];tmpDocuserve.SidebarSearchOverflow=[];tmpDocuserve.SidebarSearchEmpty=[];return;}let tmpDocProvider=this.pict.providers['Docuserve-Documentation'];let tmpResults=tmpDocProvider.search(pQuery);if(tmpResults.length===0){tmpDocuserve.SidebarSearchResults=[];tmpDocuserve.SidebarSearchOverflow=[];tmpDocuserve.SidebarSearchEmpty=[{}];return;}let tmpMaxResults=8;let tmpDisplayResults=[];for(let i=0;i<tmpResults.length&&i<tmpMaxResults;i++){let tmpResult=tmpResults[i];let tmpMeta=tmpResult.Group&&tmpResult.Module?tmpResult.Group+' / '+tmpResult.Module:'';tmpDisplayResults.push({Title:tmpResult.Title,Route:tmpResult.Route,MetaSlot:tmpMeta?[{Meta:tmpMeta}]:[]});}tmpDocuserve.SidebarSearchResults=tmpDisplayResults;tmpDocuserve.SidebarSearchEmpty=[];if(tmpResults.length>tmpMaxResults){tmpDocuserve.SidebarSearchOverflow=[{EncodedQuery:encodeURIComponent(pQuery),TotalCount:tmpResults.length}];}else{tmpDocuserve.SidebarSearchOverflow=[];}}}module.exports=DocusserveSidebarView;module.exports.default_configuration=_ViewConfiguration;},{"pict-view":231}],359:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"Docuserve-Splash",DefaultRenderable:"Docuserve-Splash-Content",DefaultDestinationAddress:"#Docuserve-Content-Container",AutoRender:false,CSS:/*css*/"\n\t\t.docuserve-splash {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmin-height: calc(100vh - 56px);\n\t\t\tpadding: 3em 2em;\n\t\t\ttext-align: center;\n\t\t\tbackground: var(--theme-color-background-primary, #FDFBF7);\n\t\t}\n\t\t.docuserve-splash h1 {\n\t\t\tfont-size: 3em;\n\t\t\tfont-weight: 700;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tmargin: 0 0 0.25em 0;\n\t\t}\n\t\t.docuserve-splash h1 small {\n\t\t\tfont-size: 0.4em;\n\t\t\tfont-weight: 400;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tvertical-align: middle;\n\t\t\tmargin-left: 0.15em;\n\t\t}\n\t\t.docuserve-splash-tagline {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmargin-bottom: 1.5em;\n\t\t\tfont-style: italic;\n\t\t}\n\t\t.docuserve-splash-description {\n\t\t\tfont-size: 1em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmax-width: 600px;\n\t\t\tline-height: 1.7;\n\t\t\tmargin-bottom: 2em;\n\t\t}\n\t\t.docuserve-splash-highlights {\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n\t\t\tgap: 1.25em;\n\t\t\tmax-width: 900px;\n\t\t\twidth: 100%;\n\t\t\tmargin-bottom: 2.5em;\n\t\t}\n\t\t.docuserve-splash-highlight-card {\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 8px;\n\t\t\tpadding: 1.25em;\n\t\t\ttext-align: left;\n\t\t\ttransition: box-shadow 0.2s, border-color 0.2s;\n\t\t}\n\t\t.docuserve-splash-highlight-card:hover {\n\t\t\tbox-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-highlight-card h3 {\n\t\t\tmargin: 0 0 0.5em 0;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.docuserve-splash-highlight-card p {\n\t\t\tmargin: 0;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tfont-size: 0.85em;\n\t\t\tline-height: 1.5;\n\t\t}\n\t\t.docuserve-splash-actions {\n\t\t\tdisplay: flex;\n\t\t\tgap: 1em;\n\t\t\tflex-wrap: wrap;\n\t\t\tjustify-content: center;\n\t\t}\n\t\t.docuserve-splash-actions a {\n\t\t\tdisplay: inline-block;\n\t\t\tpadding: 0.7em 1.5em;\n\t\t\tborder-radius: 6px;\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\ttext-decoration: none;\n\t\t\ttransition: background-color 0.15s, color 0.15s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-splash-actions .primary {\n\t\t\tbackground-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t\t/* text-on-brand falls to a fixed light hex \u2014 never to background-panel,\n\t\t\t which inverts contrast in dark themes (dark text on brand bg). */\n\t\t\tcolor: var(--theme-color-text-on-brand, #fff);\n\t\t}\n\t\t.docuserve-splash-actions .primary:hover {\n\t\t\tbackground-color: var(--theme-color-brand-primary-hover, #236660);\n\t\t}\n\t\t.docuserve-splash-actions .secondary {\n\t\t\tbackground-color: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-actions .secondary:hover {\n\t\t\tborder-color: var(--theme-color-brand-primary-hover, #236660);\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t",Templates:[{Hash:"Docuserve-Splash-Template",Template:/*html*/"\n<div class=\"docuserve-splash\">\n\t<h1 id=\"Docuserve-Splash-Title\"></h1>\n\t<div class=\"docuserve-splash-tagline\" id=\"Docuserve-Splash-Tagline\"></div>\n\t<div class=\"docuserve-splash-description\" id=\"Docuserve-Splash-Description\"></div>\n\t<div class=\"docuserve-splash-highlights\" id=\"Docuserve-Splash-Highlights\"></div>\n\t<div class=\"docuserve-splash-actions\" id=\"Docuserve-Splash-Actions\"></div>\n</div>\n"}],Renderables:[{RenderableHash:"Docuserve-Splash-Content",TemplateHash:"Docuserve-Splash-Template",DestinationAddress:"#Docuserve-Content-Container",RenderMethod:"replace"}]};class DocusserveSplashView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}onAfterRender(pRenderable,pRenderDestinationAddress,pRecord,pContent){let tmpDocuserve=this.pict.AppData.Docuserve;if(tmpDocuserve.CoverLoaded&&tmpDocuserve.Cover){this.renderFromCover(tmpDocuserve.Cover);}else{this.renderFromCatalog(tmpDocuserve);}
|
|
13931
|
+
if(tmpDemos.length>0){let tmpDemoSection={TitleSlot:[{Title:'Demos'}],Items:[]};for(let i=0;i<tmpDemos.length;i++){let tmpDemo=tmpDemos[i];tmpDemoSection.Items.push({Title:tmpDemo.Name||tmpDemo.Hash,Route:tmpDemoPrefix+tmpDemo.Hash,ActiveClass:tmpDemo.Hash===tmpCurrentDemo?'active':''});}tmpSections.push(tmpDemoSection);}this.pict.AppData.Docuserve.ModuleNavSections=tmpSections;}_refreshSearchResults(pQuery){let tmpDocuserve=this.pict.AppData.Docuserve;if(!pQuery||!pQuery.trim()){tmpDocuserve.SidebarSearchResults=[];tmpDocuserve.SidebarSearchOverflow=[];tmpDocuserve.SidebarSearchEmpty=[];return;}let tmpDocProvider=this.pict.providers['Docuserve-Documentation'];let tmpResults=tmpDocProvider.search(pQuery);if(tmpResults.length===0){tmpDocuserve.SidebarSearchResults=[];tmpDocuserve.SidebarSearchOverflow=[];tmpDocuserve.SidebarSearchEmpty=[{}];return;}let tmpMaxResults=8;let tmpDisplayResults=[];for(let i=0;i<tmpResults.length&&i<tmpMaxResults;i++){let tmpResult=tmpResults[i];let tmpMeta=tmpResult.Group&&tmpResult.Module?tmpResult.Group+' / '+tmpResult.Module:'';tmpDisplayResults.push({Title:tmpResult.Title,Route:tmpResult.Route,MetaSlot:tmpMeta?[{Meta:tmpMeta}]:[]});}tmpDocuserve.SidebarSearchResults=tmpDisplayResults;tmpDocuserve.SidebarSearchEmpty=[];if(tmpResults.length>tmpMaxResults){tmpDocuserve.SidebarSearchOverflow=[{EncodedQuery:encodeURIComponent(pQuery),TotalCount:tmpResults.length}];}else{tmpDocuserve.SidebarSearchOverflow=[];}}}module.exports=DocusserveSidebarView;module.exports.default_configuration=_ViewConfiguration;},{"pict-view":231}],359:[function(require,module,exports){const libPictView=require('pict-view');const _ViewConfiguration={ViewIdentifier:"Docuserve-Splash",DefaultRenderable:"Docuserve-Splash-Content",DefaultDestinationAddress:"#Docuserve-Content-Container",AutoRender:false,CSS:/*css*/"\n\t\t.docuserve-splash {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: column;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmin-height: calc(100vh - 56px);\n\t\t\tpadding: 3em 2em;\n\t\t\ttext-align: center;\n\t\t\tbackground: var(--theme-color-background-primary, #FDFBF7);\n\t\t}\n\t\t.docuserve-splash h1 {\n\t\t\tfont-size: 3em;\n\t\t\tfont-weight: 700;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tmargin: 0 0 0.25em 0;\n\t\t}\n\t\t.docuserve-splash h1 small {\n\t\t\tfont-size: 0.4em;\n\t\t\tfont-weight: 400;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tvertical-align: middle;\n\t\t\tmargin-left: 0.15em;\n\t\t}\n\t\t.docuserve-splash-tagline {\n\t\t\tfont-size: 1.25em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmargin-bottom: 1.5em;\n\t\t\tfont-style: italic;\n\t\t}\n\t\t.docuserve-splash-description {\n\t\t\tfont-size: 1em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tmax-width: 600px;\n\t\t\tline-height: 1.7;\n\t\t\tmargin-bottom: 2em;\n\t\t}\n\t\t.docuserve-splash-highlights {\n\t\t\tdisplay: grid;\n\t\t\tgrid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n\t\t\tgap: 1.25em;\n\t\t\tmax-width: 900px;\n\t\t\twidth: 100%;\n\t\t\tmargin-bottom: 2.5em;\n\t\t}\n\t\t.docuserve-splash-highlight-card {\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 8px;\n\t\t\tpadding: 1.25em;\n\t\t\ttext-align: left;\n\t\t\ttransition: box-shadow 0.2s, border-color 0.2s;\n\t\t}\n\t\t.docuserve-splash-highlight-card:hover {\n\t\t\tbox-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n\t\t\tborder-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-highlight-card h3 {\n\t\t\tmargin: 0 0 0.5em 0;\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tfont-size: 1em;\n\t\t}\n\t\t.docuserve-splash-highlight-card p {\n\t\t\tmargin: 0;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\tfont-size: 0.85em;\n\t\t\tline-height: 1.5;\n\t\t}\n\t\t.docuserve-splash-actions {\n\t\t\tdisplay: flex;\n\t\t\tgap: 1em;\n\t\t\tflex-wrap: wrap;\n\t\t\tjustify-content: center;\n\t\t}\n\t\t.docuserve-splash-actions a {\n\t\t\tdisplay: inline-block;\n\t\t\tpadding: 0.7em 1.5em;\n\t\t\tborder-radius: 6px;\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 600;\n\t\t\ttext-decoration: none;\n\t\t\ttransition: background-color 0.15s, color 0.15s;\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.docuserve-splash-actions .primary {\n\t\t\tbackground-color: var(--theme-color-brand-primary, #2E7D74);\n\t\t\t/* text-on-brand falls to a fixed light hex \u2014 never to background-panel,\n\t\t\t which inverts contrast in dark themes (dark text on brand bg). */\n\t\t\tcolor: var(--theme-color-text-on-brand, #fff);\n\t\t}\n\t\t.docuserve-splash-actions .primary:hover {\n\t\t\tbackground-color: var(--theme-color-brand-primary-hover, #236660);\n\t\t}\n\t\t.docuserve-splash-actions .secondary {\n\t\t\tbackground-color: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tcolor: var(--theme-color-text-primary, #3D3229);\n\t\t\tborder: 2px solid var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-actions .secondary:hover {\n\t\t\tborder-color: var(--theme-color-brand-primary-hover, #236660);\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t}\n\t\t.docuserve-splash-examples {\n\t\t\tmax-width: 900px;\n\t\t\twidth: 100%;\n\t\t\tmargin-bottom: 2.5em;\n\t\t}\n\t\t/* No staged examples \u2014 collapse the section entirely. */\n\t\t.docuserve-splash-examples:empty {\n\t\t\tdisplay: none;\n\t\t\tmargin: 0;\n\t\t}\n\t\t.docuserve-splash-examples-heading {\n\t\t\tfont-size: 0.95em;\n\t\t\tfont-weight: 700;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.08em;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tmargin: 0 0 0.85em 0;\n\t\t}\n\t\t.docuserve-splash-examples table {\n\t\t\twidth: 100%;\n\t\t\tborder-collapse: collapse;\n\t\t\tbackground: var(--theme-color-background-panel, #FFFFFF);\n\t\t\tborder: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tborder-radius: 8px;\n\t\t\toverflow: hidden;\n\t\t}\n\t\t.docuserve-splash-examples thead th {\n\t\t\ttext-align: left;\n\t\t\tfont-size: 0.72em;\n\t\t\tfont-weight: 700;\n\t\t\ttext-transform: uppercase;\n\t\t\tletter-spacing: 0.06em;\n\t\t\tcolor: var(--theme-color-text-muted, #8A7F72);\n\t\t\tpadding: 0.7em 1.1em;\n\t\t\tbackground: var(--theme-color-background-tertiary, #F4EFE6);\n\t\t}\n\t\t.docuserve-splash-examples tbody td {\n\t\t\tpadding: 0.7em 1.1em;\n\t\t\tborder-top: 1px solid var(--theme-color-border-default, #DDD6CA);\n\t\t\tfont-size: 0.9em;\n\t\t\tcolor: var(--theme-color-text-secondary, #5E5549);\n\t\t\ttext-align: left;\n\t\t}\n\t\t.docuserve-splash-examples tbody tr:hover td {\n\t\t\tbackground: var(--theme-color-background-tertiary, #F4EFE6);\n\t\t}\n\t\t.docuserve-splash-examples a {\n\t\t\tcolor: var(--theme-color-brand-primary, #2E7D74);\n\t\t\tfont-weight: 600;\n\t\t\ttext-decoration: none;\n\t\t}\n\t\t.docuserve-splash-examples a:hover {\n\t\t\ttext-decoration: underline;\n\t\t}\n\t\t/* docs/README.md content rendered beneath the hero. */\n\t\t.docuserve-splash-readme {\n\t\t\tmax-width: 820px;\n\t\t\tmargin: 0 auto;\n\t\t\tpadding: 3.5em 2em 5em 2em;\n\t\t\ttext-align: left;\n\t\t}\n\t\t.docuserve-splash-readme:empty {\n\t\t\tdisplay: none;\n\t\t}\n\t",Templates:[{Hash:"Docuserve-Splash-Template",Template:/*html*/"\n<div class=\"docuserve-splash\">\n\t<h1 id=\"Docuserve-Splash-Title\"></h1>\n\t<div class=\"docuserve-splash-tagline\" id=\"Docuserve-Splash-Tagline\"></div>\n\t<div class=\"docuserve-splash-description\" id=\"Docuserve-Splash-Description\"></div>\n\t<div class=\"docuserve-splash-highlights\" id=\"Docuserve-Splash-Highlights\"></div>\n\t<div class=\"docuserve-splash-examples\" id=\"Docuserve-Splash-Examples\"></div>\n\t<div class=\"docuserve-splash-actions\" id=\"Docuserve-Splash-Actions\"></div>\n</div>\n<div class=\"docuserve-splash-readme\" id=\"Docuserve-Splash-Readme\"></div>\n"}],Renderables:[{RenderableHash:"Docuserve-Splash-Content",TemplateHash:"Docuserve-Splash-Template",DestinationAddress:"#Docuserve-Content-Container",RenderMethod:"replace"}]};class DocusserveSplashView extends libPictView{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);}onAfterRender(pRenderable,pRenderDestinationAddress,pRecord,pContent){let tmpDocuserve=this.pict.AppData.Docuserve;if(tmpDocuserve.CoverLoaded&&tmpDocuserve.Cover){this.renderFromCover(tmpDocuserve.Cover);this.renderExamples(tmpDocuserve.Cover);}else{this.renderFromCatalog(tmpDocuserve);}// Render docs/README.md beneath the hero — the splash fills the
|
|
13932
|
+
// viewport above the fold, the README content follows on scroll.
|
|
13933
|
+
this.renderReadme();return super.onAfterRender(pRenderable,pRenderDestinationAddress,pRecord,pContent);}/**
|
|
13889
13934
|
* Render the splash screen from parsed _cover.md data.
|
|
13890
13935
|
*
|
|
13891
13936
|
* @param {Object} pCover - The parsed cover data { Title, Tagline, Description, Highlights, Actions }
|
|
@@ -13903,6 +13948,17 @@ let tmpTitle='Documentation';let tmpTagline='';if(pDocuserve.CatalogLoaded&&pDoc
|
|
|
13903
13948
|
let tmpHighlightsHTML='';let tmpGroups=pDocuserve.SidebarGroups||[];for(let i=0;i<tmpGroups.length;i++){let tmpGroup=tmpGroups[i];// Skip groups with no modules (like "Home" or "Getting Started")
|
|
13904
13949
|
if(!tmpGroup.Modules||tmpGroup.Modules.length<1){continue;}let tmpDescription=tmpGroup.Description||tmpGroup.Modules.length+' modules';tmpHighlightsHTML+='<div class="docuserve-splash-highlight-card">';tmpHighlightsHTML+='<h3>'+this.escapeHTML(tmpGroup.Name)+'</h3>';tmpHighlightsHTML+='<p>'+this.escapeHTML(tmpDescription)+'</p>';tmpHighlightsHTML+='</div>';}this.pict.ContentAssignment.assignContent('#Docuserve-Splash-Highlights',tmpHighlightsHTML);// Default action buttons
|
|
13905
13950
|
this.pict.ContentAssignment.assignContent('#Docuserve-Splash-Actions','');}/**
|
|
13951
|
+
* Render the "Interactive Examples" section of the splash from the
|
|
13952
|
+
* examples region of _cover.md. When the cover carries no examples the
|
|
13953
|
+
* section is left empty — CSS collapses it — so it appears only when a
|
|
13954
|
+
* module has staged interactive examples.
|
|
13955
|
+
*
|
|
13956
|
+
* @param {Object} pCover - The parsed cover data.
|
|
13957
|
+
*/renderExamples(pCover){let tmpExamplesMarkdown=pCover&&pCover.ExamplesMarkdown?pCover.ExamplesMarkdown:'';let tmpDocProvider=this.pict.providers['Docuserve-Documentation'];if(!tmpExamplesMarkdown||!tmpDocProvider||!tmpDocProvider._ContentProvider){this.pict.ContentAssignment.assignContent('#Docuserve-Splash-Examples','');return;}let tmpLinkResolver=tmpDocProvider._createLinkResolver('','','');let tmpExamplesHTML=tmpDocProvider._ContentProvider.parseMarkdown(tmpExamplesMarkdown,tmpLinkResolver);this.pict.ContentAssignment.assignContent('#Docuserve-Splash-Examples','<h2 class="docuserve-splash-examples-heading">Interactive Examples</h2>'+tmpExamplesHTML);}/**
|
|
13958
|
+
* Render docs/README.md beneath the splash hero. The landing page is the
|
|
13959
|
+
* full-viewport splash above the fold and the module's README content on
|
|
13960
|
+
* scroll. A missing or unreadable README simply leaves the section empty.
|
|
13961
|
+
*/renderReadme(){let tmpDocProvider=this.pict.providers['Docuserve-Documentation'];let tmpDocsBase=this.pict.AppData.Docuserve.DocsBaseURL||'';fetch(tmpDocsBase+'README.md').then(pResponse=>pResponse.ok?pResponse.text():null).then(pMarkdown=>{if(!pMarkdown||!tmpDocProvider||!tmpDocProvider._ContentProvider){this.pict.ContentAssignment.assignContent('#Docuserve-Splash-Readme','');return;}let tmpLinkResolver=tmpDocProvider._createLinkResolver('','','README.md');let tmpImageResolver=tmpDocProvider._createImageResolver(tmpDocsBase+'README.md');let tmpHTML=tmpDocProvider._ContentProvider.parseMarkdown(pMarkdown,tmpLinkResolver,tmpImageResolver);this.pict.ContentAssignment.assignContent('#Docuserve-Splash-Readme','<div class="pict-content">'+tmpHTML+'</div>');}).catch(()=>{this.pict.ContentAssignment.assignContent('#Docuserve-Splash-Readme','');});}/**
|
|
13906
13962
|
* Sanitize a title string, preserving only <small> tags.
|
|
13907
13963
|
* All other HTML is escaped.
|
|
13908
13964
|
*
|