blob: 4f8a1715810d970b404d01615b787a4f093a284e [file] [log] [blame]
<!-- The <fiddle-sk> custom element declaration.
Handles displaying and running a fiddle. Note that the code
should be supplied as a child element textarea.
Attributes:
width - The width of the fiddle image.
height - The height of the fiddle image.
source - The index of the source image to use as input.
bug_link - If true then display a link to report a bug.
embed_button - If true then display the embed button.
Methods:
None.
Events:
fiddle-success - generates an event when a succesful run is complete. The event contains
the hash of the new fiddle, to be used to retrieve the resultant images.
-->
<link rel="import" href="/res/imp/bower_components/iron-icon/iron-icon.html">
<link rel="import" href="/res/imp/bower_components/iron-icons/iron-icons.html">
<link rel="import" href="/res/imp/bower_components/iron-selector/iron-selector.html">
<link rel="import" href="/res/imp/bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html">
<link rel="import" href="/res/imp/bower_components/paper-spinner/paper-spinner.html">
<link rel="stylesheet" href="/res/common/css/md.css" type="text/css" media="all">
<link rel="import" href="/res/common/imp/details-summary.html">
<link rel="import" href="/res/common/imp/toggle.html">
<link rel="import" href="/res/common/imp/login.html">
<link rel="import" href="/res/imp/text-src.html">
<dom-module id="fiddle-sk">
<style>
#namer,
#embedder {
display: none;
margin-left: 2em;
}
#namer.display,
#embedder.display {
display: block;
}
img {
box-shadow: 2px 2px 5px gray;
display: inline-block;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAAXNSR0IArs4c6QAAAAJiS0dEAP+Hj8y/AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gUBEi4DGRAQYgAAAB1JREFUGNNjfMoAAVJQmokBDdBHgPE/lPFsYN0BABdaAwN6tehMAAAAAElFTkSuQmCC');
}
#submit {
margin-top: 1em;
}
button.action {
margin-left: 0;
}
paper-spinner {
display: inline-block;
top: 10px;
}
#results {
margin-top: 1em;
}
#results > div {
display: inline-block;
margin-right: 1em;
}
.compile-error {
margin: 0 0 0 2em;
font-weight: bold;
cursor: pointer;
}
.compile-error:hover {
background: #eee;
}
h2 {
color: #E31A1C;
font-size: 18px;
}
details-sk {
display: inline-block;
padding-bottom: 1em;
}
.options {
margin-left: 3em;
}
#bug {
display: inline-block;
margin-left: 1em;
}
iron-selector img {
margin: 0.5em;
}
img.iron-selected {
border: solid #1F78B4 3px;
}
.source-select {
margin: 1em 0 0.5em 0;
}
paper-input {
display: inline-block;
}
#textonly {
display: block;
}
.textoutput {
box-shadow: 2px 2px 5px gray;
padding: 0.8em;
font-family: monospace;
border: solid lightgray 1px;
color: darkgreen;
margin-bottom: 1em;
width: 56em;
font-family: monospace;
font-size: 13px;
}
.hint {
color: #666;
}
</style>
<template>
<template is="dom-if" if="{{display_options}}">
<details-sk>
<summary-sk>Options</summary-sk>
<div class=options>
<paper-checkbox id=textonly title="A text-only fiddle." checked="{{textonly}}">Text Only <span class=hint>[Use SkDebugf()]</span></paper-checkbox>
<paper-input label="Width" size=5 auto-validate allowed-pattern="[0-9]" value="{{width}}" disabled="[[textonly]]"></paper-input>
<paper-input label="Height" size=5 auto-validate allowed-pattern="[0-9]" value="{{height}}" disabled="[[textonly]]"></paper-input>
<pre class=source-select>SkBitmap source;
sk_sp&lt;SkImage> image;
</pre>
<iron-selector selected="{{source}}" attr-for-selected="name" class="layout horizontal wrap">
<template is="dom-repeat" items="{{sources}}">
<img width=64 height=64 name="{{item}}" src="[[domain]]/s/{{item}}">
</template>
</iron-selector>
</div>
</details-sk>
</template>
<content></content>
<div id=submit>
<template is="dom-if" if="{{embed_button}}">
<button class=action on-tap="_run">Run</button>
<paper-spinner></paper-spinner>
<template is="dom-if" if="{{bug_link}}">
<a id=bug target=_blank href$="{{_bugLink(fiddlehash)}}">File Bug</a>
</template>
<toggle-display-sk>Embed</toggle-display-sk>
<div id=embedder>
<h3>Embed as an iframe:</h3>
<input type="text" readonly size=150 value="&lt;iframe src='https://fiddle.skia.org/iframe/{{fiddlehash}}' style='border: none; width: 60em; height: 20em;'>&lt;/iframe> ">
<h3>Embed as an image with a backlink:</h3>
<input type="text" readonly size=150 value="&lt;a href='https://fiddle.skia.org/c/{{fiddlehash}}'>&lt;img src='https://fiddle.skia.org/i/{{fiddlehash}}_raster.png'>&lt;/a>">
<h3>Embed as custom element (skia.org only):</h3>
<input type="text" readonly size=150 value="&lt;fiddle-embed name='{{fiddlehash}}'>&lt;/fiddle-embed> ">
</div>
<toggle-display-sk disabled$={{_not_logged_in}}>Name</toggle-display-sk>
<div id=namer>
<h3>Create a name for this fiddle:</h3>
<paper-input id=name label="Name" placeholder="fiddle_name_goes_here" size=40 auto-validate allowed-pattern="[0-9a-zA-Z_]" value="{{_name}}"></paper-input>
<!-- Add a pop-up menu here that has completions based on what's been typed so far, and also any names that this page has loaded previously.-->
<paper-checkbox id=overwrite title="Overwrite the existing name if one exists.">Overwrite</paper-checkbox>
<button class=save on-tap="_submit_name" disabled="{{_isEmpty(_name)}}">Save</button>
</div>
</template>
</div>
<div on-tap="_errSelect">
<template is="dom-if" if="{{_hasCompileErrors(_compile_errors)}}">
<h2>Compilation Errors</h2>
<template is="dom-repeat" items="{{_compile_errors}}">
<pre class=compile-error data-line$="{{item.line}}" data-col$="{{item.col}}">{{item.text}}</pre>
</template>
</template>
</div>
<template is="dom-if" if="{{_runtime_error}}">
<h2>Runtime Errors</h2>
<div>{{_runtime_error}}</div>
</template>
<template is="dom-if" if="{{_hasImages(fiddlehash, _compile_errors, _runtime_error, textonly)}}">
<div id=results class="horizontal layout">
<div class="vertical layout center-justified">
<img src="[[domain]]/i/{{fiddlehash}}_raster.png" width="{{width}}" height="{{height}}">
<template is="dom-if" if="{{embed_button}}">
<p>
CPU
<a href="https://imageinfo.skia.org/info?url=https://fiddle.skia.org/i/{{fiddlehash}}_raster.png"
title="Inspect the image in https://imageinfo.skia.org."
target=_blank
>
<iron-icon icon="pageview"></iron-icon></a>
</p>
</template>
</div>
<template is="dom-if" if="{{embed_button}}">
<div class="vertical layout center-justified">
<img src="[[domain]]/i/{{fiddlehash}}_gpu.png" width="{{width}}" height="{{height}}">
<p>
GPU
<a href="https://imageinfo.skia.org/info?url=https://fiddle.skia.org/i/{{fiddlehash}}_gpu.png"
title="Inspect the image in https://imageinfo.skia.org."
target=_blank
>
<iron-icon icon="pageview"></iron-icon></a>
</p>
</div>
<div class="vertical layout center">
<a href="[[domain]]/i/{{fiddlehash}}.pdf">PDF</a>
</div>
<div class="vertical layout center">
<a href="[[domain]]/i/{{fiddlehash}}.skp">SKP</a>
</div>
<div class="vertical layout center" hidden$={{_not_logged_in}} >
<a href="https://debugger.skia.org/loadfrom?url=https://fiddle.skia.org/i/{{fiddlehash}}.skp">Debug</a>
</div>
</template>
</div>
</template>
<template is="dom-if" if="{{textonly}}">
<template is="dom-if" if="{{embed_button}}">
<h2>Output</h2>
</template>
<div class=textoutput>
<text-src src="[[_textURL(domain, fiddlehash)]]"></text-src>
</div>
</template>
<template is="dom-if" if="{{_not(embed_button)}}">
<button class=action on-tap="_run">Run</button>
<paper-spinner></paper-spinner>
<a href="https://fiddle.skia.org/c/{{fiddlehash}}" target=_blank">Pop-out</a>
</template>
</template>
</dom-module>
<script>
Polymer({
is: "fiddle-sk",
properties: {
width: {
type: Number,
value: 256,
reflectToAttribute: true,
},
height: {
type: Number,
value: 256,
reflectToAttribute: true,
},
textonly: {
type: Boolean,
value: false,
reflectToAttribute: true,
},
source: {
type: Number,
value: 0,
reflectToAttribute: true,
},
sources: {
type: Array,
value: function() { return []; },
reflectToAttribute: true,
},
fiddlehash: {
type: String,
value: "",
reflectToAttribute: true,
},
domain: {
type: String,
value: "",
reflectToAttribute: true,
},
bug_link: {
type: Boolean,
value: false,
reflectToAttribute: true,
},
embed_button: {
type: Boolean,
value: false,
reflectToAttribute: true,
},
display_options: {
type: Boolean,
value: false,
reflectToAttribute: true,
},
_compile_errors: {
type: Array,
value: function() { return []; },
reflectToAttribute: false,
},
_runtime_error: {
type: String,
value: "",
reflectToAttribute: false,
},
_not_logged_in: {
type: Boolean,
value: true,
reflectToAttribute: false,
},
_name: {
type: String,
value: "",
reflectToAttribute: false,
},
},
ready: function() {
this._errorLinesRe = /draw.cpp:([0-9]+):([0-9]+):/;
this._editor = $$$('textarea-numbers-sk', this);
sk.Login.then(function(status) {
this._not_logged_in = (status.Email == "");
}.bind(this));
},
_run: function() {
this._run_impl({});
},
_submit_name: function() {
this._run_impl({
name: this._name,
overwrite: this.$.overwrite.checked,
});
},
_run_impl: function(extra) {
this.fiddlehash = "";
$$("paper-spinner", this).forEach(function(s) {
s.active = true;
}, this);
body = {
code: $$$('textarea', this).value,
options: {
width: +this.width,
height: +this.height,
source: +this.source,
textOnly: this.textonly,
}
};
for (key in extra) {
body[key] = extra[key];
}
sk.post(this.domain + "/_/run", JSON.stringify(body)).then(JSON.parse).then(function(json) {
this.fiddlehash = json.fiddleHash;
this._compile_errors = json.compile_errors || [];
this._runtime_error = json.runtime_error || "";
$$("paper-spinner", this).forEach(function(s) {
s.active = false;
}, this);
this.fire("fiddle-success", json.fiddleHash);
this._compile_errors.forEach(function(err) {
this._editor.setErrorLine(+err.line);
}.bind(this));
if (this.$.overwrite) {
this.$.overwrite.checked = false;
}
}.bind(this)).catch(function(err) {
$$("paper-spinner", this).forEach(function(s) {
s.active = false;
}, this);
sk.errorMessage(err);
}.bind(this));
},
_errSelect: function(e) {
if (e.target.nodeName == "PRE") {
this._editor.setCursor(+e.target.dataset.line, +e.target.dataset.col);
this._editor.focus();
}
},
_bugLink: function(fiddleHash) {
var comment = "Visit this link to see the issue on fiddle:\n\n https://fiddle.skia.org/c/" + fiddleHash;
return "https://bugs.chromium.org/p/skia/issues/entry?" + sk.query.fromObject({
comment: comment,
});
},
_hasImages: function(fiddlehash, compile_errors, runtime_error, textonly) {
return !textonly && fiddlehash != "" && runtime_error == "" && (compile_errors.length == 0);
},
_hasCompileErrors: function(compile_errors) {
return compile_errors.length > 0;
},
_isEmpty: function(name) {
return name == "";
},
_not: function(b) {
return !b;
},
_textURL: function(domain, fiddlehash) {
if (fiddlehash == "") {
return "";
}
return domain + "/i/" + fiddlehash + ".txt";
}
});
</script>