Skip to content
4 changes: 3 additions & 1 deletion _layouts/fomantic.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.js"></script>
<script>
$('#keyboard-shortcuts').popup({ on: 'click', inline: true });
$('.ui.popup').each((i, el) => {
$(el).prev().popup({ on: 'click', inline: true, preserve: true });
});
</script>
</body>
</html>
44 changes: 44 additions & 0 deletions playground/next/editor.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ window.app = createApp({
},
remoteDocURL: '',
remoteSideDocURL: '',
message: {type: '', text: ''},
parseError: '',
inputTab: 'json-ld',
outputTab: 'expanded',
Expand Down Expand Up @@ -349,6 +350,20 @@ window.app = createApp({
}
return '';
},
get permalinkURL() {
const url = new URL(window.location);
const hash = new URLSearchParams();
hash.set('json-ld', JSON.stringify(this.doc));
if (this.contextDoc && JSON.stringify(this.contextDoc) !== '{}') {
hash.set('context', JSON.stringify(this.contextDoc));
}
if (this.frameDoc && JSON.stringify(this.frameDoc) !== '{}') {
hash.set('frame', JSON.stringify(this.frameDoc));
}
hash.set('startTab', `tab-${this.outputTab}`);
url.hash = hash.toString();
return url.toString();
},
get sideDoc() {
if (this.outputTab === 'framed') {
return 'frameDoc';
Expand All @@ -370,6 +385,14 @@ window.app = createApp({
return 'Context URL';
}
},
copyPermalink() {
const url = this.permalinkURL;
navigator.clipboard.writeText(url).then(() => {
console.log('Permalink copied to clipboard:', url);
}).catch(err => {
console.error('Failed to copy permalink:', err);
});
},
// methods
async retrieveDoc(_editor, docVar, url) {
try {
Expand Down Expand Up @@ -539,5 +562,26 @@ window.app = createApp({
'@context': this.doc['@context']
};
setEditorValue(this.contextEditor, this.contextDoc);
},
async gatherHash() {
const url = new URL(window.location);
const hash = new URLSearchParams(url?.hash.slice(1));
this.contextDoc = JSON.parse(hash.get('context')) || {};
setEditorValue(this.contextEditor, this.contextDoc);
this.frameDoc = JSON.parse(hash.get('frame')) || {};
setEditorValue(this.frameEditor, this.frameDoc);
// the `json-ld` parameter can be JSON or a URL
const jsonLdOrUrl = hash.get('json-ld');
try {
this.doc = JSON.parse(jsonLdOrUrl);
setEditorValue(this.mainEditor, this.doc);
} catch {
this.remoteDocURL = jsonLdOrUrl;
await this.retrieveDoc(this.mainEditor, 'doc', this.remoteDocURL);
}
if (hash.get('copyContext') === 'true') {
this.copyContext();
}
this.outputTab = hash.get('startTab')?.slice(4);
}
}).mount();
79 changes: 53 additions & 26 deletions playground/next/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@ <h2 class="ui massive header">JSON-LD Playground</h2>
</li>
<li>
Other related playgrounds:
<a href="./1.0/">Classic JSON-LD 1.0 Playground</a> |
<a href="http://rdf.greggkellogg.net/distiller">RDF Distiller</a> |
<a href="../1.0/">Classic JSON-LD 1.0 Playground</a> |
<a href="https://vcplayground.org/">Verifiable Credentials Playground</a>
</li>
</ul>
<p>Accesibility note: use <code>Esc</code> and then <code>Tab</code> (or
<code>Shift+Tab</code>) to navigate out of the editor.</p>
</div>

<div class="ui wide container" v-scope v-effect="setOutputTab()">
<div class="ui wide container" v-scope v-effect="setOutputTab()" @vue:mounted="gatherHash()">
<div class="ui buttons">
<button class="ui large basic right pointing label">Examples</button>
<button id="btn-person" class="ui button"
Expand Down Expand Up @@ -69,33 +68,61 @@ <h2 class="ui massive header">JSON-LD Playground</h2>
</button>
</div>

<button id="keyboard-shortcuts" class="ui right floated button" data-position="left center">
<i class="icon keyboard"></i> Shortcuts
</button>
<div class="ui popup">
<div class="ui top attached label">Keyboard Shortcuts</div>
<table class="ui very basic single line celled table">
<thead>
<tr>
<th>Key</th>
<th>Autocomplete</th>
</tr>
</thead>
<tbody>
<tr>
<td><label class="ui label">@</label></td>
<td>all of the <b>@</b> keywords</td>
</tr>
<tr>
<td><label class="ui label">Ctrl+Space</label></td>
<td>available keys in <b>@context</b></td>
</tr>
</tbody>
</table>
<div class="ui right floated buttons">
<button id="permalink" class="ui icon button" data-position="left center">
<i class="icon linkify"></i>
</button>
<div class="ui popup" style="min-width: 20em;">
<div class="ui top attached label">Share this</div>
<div class="ui fluid action input">
<input type="text" readonly v-model="permalinkURL" @focus="$event.target.select()">
<button class="ui icon button" @click="copyPermalink()">
<i class="icon copy"></i>
</button>
</div>
<div class="ui warning message" v-show="permalinkURL.length > 2048">
This link is longer than 2kb, and may not work.
</div>
</div>
<button id="keyboard-shortcuts" class="ui icon button" data-position="left center">
<i class="icon keyboard"></i>
</button>
<div class="ui popup">
<div class="ui top attached label">Keyboard Shortcuts</div>
<table class="ui very basic single line celled table">
<thead>
<tr>
<th>Key</th>
<th>Autocomplete</th>
</tr>
</thead>
<tbody>
<tr>
<td><label class="ui label">@</label></td>
<td>all of the <b>@</b> keywords</td>
</tr>
<tr>
<td><label class="ui label">Ctrl+Space</label></td>
<td>available keys in <b>@context</b></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- main editor area -->
<div class="ui one column wide compact grid container" :class="[editorColumns]">
<div class="column" :class="{ 'sixteen wide': editorColumns == '' }">
<div class="ui icon message" v-show="message.text" :class="message.type">
<i class="icon" :class="{
'info circle': message.type == 'info',
'check circle': message.type == 'success',
'times circle': message.type == 'error',
'exclamation triangle': message.type == 'warning'
}"></i>
<div class="content">
<div class="header" v-text="message.text"></div>
</div>
</div>
<div class="ui top attached tabular menu">
<div :class="{ active: inputTab == 'json-ld' }" class="item" @click="inputTab = 'json-ld'"><i class="pencil alternate icon"></i> JSON-LD Input</div>
<div :class="{ active: inputTab == 'options' }" class="item" @click="inputTab = 'options'"><i class="wrench icon"></i> Options</div>
Expand Down