Skip to content

Commit

Permalink
indexing on the markdown preview
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilkalburgi committed Sep 3, 2024
1 parent a65d95e commit 4476a79
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 67 deletions.
97 changes: 95 additions & 2 deletions src/PreviewMarkdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,15 @@ function getWebviewContent(context: vscode.ExtensionContext, webview: vscode.Web
<link rel="stylesheet" href="${globalsCSS}"/>
</head>
<body x-timestamp="${Date.now()}">
<div class="expand-contract-btn">
<div class="contract-btn">&lt;</div>
<div class="expand-btn">&gt;</div>
</div>
<div id="index">
<h2> Index </h2>
<a href="#index-info">Info</a>
<p class="index-part-title">Operations</p>
</div>
<div class="container">
<div class="section" id="section1">${result}</div>
<div class="section" id="section2">${flowchart}</div>
Expand Down Expand Up @@ -362,7 +370,91 @@ function getWebviewContent(context: vscode.ExtensionContext, webview: vscode.Web
const { x, y } = panZoomClassDiagramInstance.getTransform()
panZoomClassDiagramInstance.smoothMoveTo(x+50, y);
}
});
});
function toggleSection(event) {
const title = event.currentTarget;
const content = title.nextElementSibling;
const arrow = title.querySelector('.arrow');
title.style.outline = '0px';
title.style.border = '0px';
if (content?.style?.display === 'none') {
content.style.display = 'block';
arrow.style.transform = 'rotate(90deg)';
} else {
content.style.display = 'none';
arrow.style.transform = 'rotate(0deg)';
}
}
const expandContractBtn = document.querySelector('.expand-contract-btn');
const expandBtn = document.querySelector('.expand-btn');
const contractBtn = document.querySelector('.contract-btn');
const index = document.querySelector('#index');
expandBtn.addEventListener('click',()=>{
index.style.width = '20%' ;
index.style.padding = '10px'
expandContractBtn.style.left = "calc(20% - 10px)";
})
contractBtn.addEventListener('click',()=>{
index.style.width = '0%' ;
index.style.padding = '0px'
expandContractBtn.style.left = "-35px";
})
const indexSections = document.querySelectorAll('.index-section');
let channelList = [];
let msgList = [];
let newSection = '<div>';
indexSections.forEach((part)=> {
const channel = part.querySelectorAll('p');
const operationId = part.querySelectorAll('li');
const h4Elements = part.querySelectorAll('h4');
const h5Elements = part.querySelectorAll('h5');
channel[0].id = 'id_' + parseInt(Math.random() * 1000 * (channel[0].textContent.length ?? 3));
operationId[0].id = 'id_' + parseInt(Math.random() * 1000 * (operationId[0].textContent.length ?? 3));
newSection += '<div class="index-part"> <a href="#'+operationId[0].id+'" class="index-part-title"> <span class="arrow">&gt;</span> '+operationId[0].textContent?.replaceAll("Operation ID:","")+'</a> <div class="index-part-content" style="display: none;"> <ul>';
newSection += '<li><a href="#'+channel[0].id+'">Channel</a></li> ';
channelList.push('<li><a href="#'+channel[0].id+'">'+channel[0].textContent+'</a></li> ');
h4Elements.forEach((h4)=> {
h4.id = parseInt(Math.random() * 10000 * (h4.textContent.length ?? 4));
newSection += '<li><a href="#'+h4.id+'">'+h4.textContent+'</a></li> ';
if(h4.textContent.indexOf('Message') >= 0){
msgList.push('<li><a href="#'+h4.id+'">'+h4.textContent+'</a></li> ')
}
})
h5Elements.forEach((h5)=> {
h5.id = parseInt(Math.random()* 100000 * (h5.textContent.length ?? 5));
newSection += '<li><a href="#'+h5.id+'">'+h5.textContent+'</a></li> ';
})
newSection += '</ul></div></div> ';
});
newSection += '</div><p class="index-part-title"> Channels </p> <ul>';
channelList.forEach(element => {
newSection += element;
});
newSection += '</ul><p class="index-part-title"> Messages </p> <ul>';
msgList.forEach(element => {
newSection += element;
});
newSection += '</ul>';
index.innerHTML += newSection;
// Add event listeners to all section and list item titles
const sectionTitles = document.querySelectorAll('.index-part-title');
sectionTitles.forEach(title => {
console.log(title);
title.addEventListener('click', toggleSection);
});
});
document.getElementById('copy-button').addEventListener('click', function() {
Expand Down Expand Up @@ -447,6 +539,7 @@ function getWebviewContent(context: vscode.ExtensionContext, webview: vscode.Web
edge.addEventListener('mouseleave', removeHighlights);
});
}
</script>
</body>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Info.ejs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h1><%= title %> <%= version %> documentation</h1>
<h1 id="index-info"><%= title %> <%= version %> documentation</h1>

<ul>
<% if (specId) { %>
Expand Down
124 changes: 60 additions & 64 deletions src/components/Operations.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<% let type;
const applyToAllServers = allServersLength === channel.servers().all().length;
const servers = applyToAllServers ? [] : channel.servers().all();
const showInfoList = operation.operationId() || (servers && servers.length);
if (operation.isSend()) {
if (operation.reply()) {
type = 'request';
Expand All @@ -20,72 +19,69 @@
type = 'receive';
}
} %>
<%- md.render(`${getRenderedTypeForOperation({type})} \`${channel.address()}\` <b>Operation</b>`) %>
<% if(operation.summary()) { %>
<%- md.render(`*${operation.summary().trim()}*`) %>
<% } %>
<% if(showInfoList) { %>
<ul>
<% if(operation.operationId()) { %>
<li><b>Operation ID:</b> <%= operation.operationId() %></li>
<% if(servers && servers.length) { %>
<li>Available Only on Server:
<%= servers.map(s => {
const serverId = s.id();
const slug = FormatHelpers.slugify(serverId);
return `[${serverId}](#${slug}-server)`;
}).join(', ') %>
</li>
<% } %>
<% } %>
</ul>
<% } %>
<% if(channel.hasDescription()) { %>
<%- md.render(channel.description()) %>
<% } %>
<% if(operation.hasDescription()) { %>
<%- md.render(operation.description()) %>
<% } %>
<% if(operation.externalDocs()?.hasDescription() ) { %>
<a href="<%= operation.externalDocs().url() %>"><%= (operation.externalDocs().description() || 'Find more info here.') %></a>
<% } %>
<%- include(tagsPath,{ name:"Operation tags", tags: operation.tags() }) %>
<% const parameters = schemaHelper.parametersToSchema(channel.parameters().all()); %>
<% if(parameters) { %>
<h4>Parameters</h4>
<%- include(schemaPath,{ schema: parameters, schemaName: "Parameters", hideTitle: true, schemaHelper, md, path:"" }) %>
<% } %>
<%- include(securityPath,{ header:'Additional security requirements', protocol: null, security: operation.security(), serverHelper, md }) %>
<%- include(bindingsPath,{ name:"Channel specific information", bindings: channel.bindings(), schemaHelper, schemaPath, md }) %>
<%- include(bindingsPath,{ name:"Operation specific information", bindings: operation.bindings(), schemaHelper, schemaPath, md }) %>
<%- include(extensionsPath,{ name:"Channel extensions", extensions: channel.extensions(), schemaHelper, schemaPath, md }) %>
<%- include(extensionsPath,{ name:"Operation extensions", extensions: operation.extensions(), schemaHelper, schemaPath, md }) %>
<% const messages = operation.messages().all(); %>
<% if (messages.length !== 0) { %>
<% const messageText = getOperationMessageText({type}); %>
<% if(messages.length > 1) { %>
<p><%- md.render(messageText) %></p>
<div class="index-section">
<%- md.render(`${getRenderedTypeForOperation({type})} \`${channel.address()}\` <b>Operation</b>`) %>
<% if(operation.summary()) { %>
<%- md.render(`*${operation.summary().trim()}*`) %>
<% } %>
<ul>
<li><b>Operation ID:</b> <%= operation.operationId() ?? 'Operation_ID_not_available' %></li>
<% if(servers && servers.length) { %>
<li>Available Only on Server:
<%= servers.map(s => {
const serverId = s.id();
const slug = FormatHelpers.slugify(serverId);
return `[${serverId}](#${slug}-server)`;
}).join(', ') %>
</li>
<% } %>
</ul>
<% if(channel.hasDescription()) { %>
<%- md.render(channel.description()) %>
<% } %>
<% for(let message of messages) { %>
<%- include(messagePath,{message, bindingsPath, extensionsPath, schemaHelper, schemaPath, md, messageHelper}) %>
<% if(operation.hasDescription()) { %>
<%- md.render(operation.description()) %>
<% } %>
<% if(operation.externalDocs()?.hasDescription() ) { %>
<a href="<%= operation.externalDocs().url() %>"><%= (operation.externalDocs().description() || 'Find more info here.') %></a>
<% } %>
<%- include(tagsPath,{ name:"Operation tags", tags: operation.tags() }) %>
<% const parameters = schemaHelper.parametersToSchema(channel.parameters().all()); %>
<% if(parameters) { %>
<h4>Parameters</h4>
<%- include(schemaPath,{ schema: parameters, schemaName: "Parameters", hideTitle: true, schemaHelper, md, path:"" }) %>
<% } %>
<%- include(securityPath,{ header:'Additional security requirements', protocol: null, security: operation.security(), serverHelper, md }) %>
<%- include(bindingsPath,{ name:"Channel specific information", bindings: channel.bindings(), schemaHelper, schemaPath, md }) %>
<%- include(bindingsPath,{ name:"Operation specific information", bindings: operation.bindings(), schemaHelper, schemaPath, md }) %>
<%- include(extensionsPath,{ name:"Channel extensions", extensions: channel.extensions(), schemaHelper, schemaPath, md }) %>
<%- include(extensionsPath,{ name:"Operation extensions", extensions: operation.extensions(), schemaHelper, schemaPath, md }) %>
<% const messages = operation.messages().all(); %>
<% if (messages.length !== 0) { %>
<% const messageText = getOperationMessageText({type}); %>
<% if(messages.length > 1) { %>
<p><%- md.render(messageText) %></p>
<% } %>
<% for(let message of messages) { %>
<%- include(messagePath,{message, bindingsPath, extensionsPath, schemaHelper, schemaPath, md, messageHelper}) %>
<% } %>
<% } %>
<% if(operation.traits().incorrect && Object.values(operation.traits() || []).length > 1) { %>
<div>
<h5>Operation Traits</h5>
<ul><%= renderObject(operation.traits(), 0) %></ul>
</div>
<% } %>
<% if(operation.traits().incorrect && Object.values(operation.traits() || []).length > 1) { %>
<div>
<h5>Operation Traits</h5>
<ul><%= renderObject(operation.traits(), 0) %></ul>
</div>
<% } %>
<hr/>
</div>
<hr/>
<% } %>
<% } %>
<% } %>
Expand Down
102 changes: 102 additions & 0 deletions src/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,105 @@ a:hover {
stroke-width: 5px !important;
}

#index {
width: 0px;
padding: 0px;
background-color: #bbbbbb;
position: fixed;
height: 100%;
overflow-y: auto;
transition: width 0.4s, padding 0.4s;
z-index: 1;
white-space: nowrap;
}

.index-part {
width: 40vw;
overflow: hidden;
}

.index-part-title{
cursor: pointer;
font-weight: bold;
margin-bottom: 10px;
display: flex;
align-items: center;
}

#index ul {
list-style-type: none;
padding-left: 15px;
}
#index li {
white-space: nowrap;
padding-bottom: 5px;
width: 100%;
text-overflow: ellipsis;
}


.arrow {
display: inline-block;
margin-right: 10px;
transition: transform 0.3s ease;
font-family: cursive;
text-decoration: none;
}

.index-part-content{
display: none;
padding-left: 20px;
}

h4, h5 {
margin-top: 20px;
margin-bottom: 10px;
}

#index a{
text-decoration: none;
color: #333;
padding-right: 5px;
}

#index a:active {
border: 0px;
outline: 0px;
}

#index a:hover {
text-decoration: underline;
}

.expand-contract-btn {
display: flex;
flex-direction: row;
justify-content: center;
border: 0.5px solid #c9c8c8;
border-radius: 100%;
position: absolute;
top: 50%;
left: -35px;
z-index: 2;
width: 60px;
height: 60px;
background: #ddd;
transition: left 0.4s;
}

.contract-btn, .expand-btn {
position: relative;
top: 50%;
transform: translateY(-30px);
font-size: 40px;
font-weight: bolder;
font-family: cursive;
cursor: pointer;
}

.contract-btn {
border-right: 0.1px solid #8d8c8c;
}
.expand-btn {
border-left: 0.1px solid #8d8c8c;
}

0 comments on commit 4476a79

Please sign in to comment.