lpio
Version:
The last dashboard app you'll ever need
256 lines (213 loc) • 9.83 kB
HTML
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../lp-imports/underscore.html" />
<link rel="import" href="./lp-widget-styles.html" />
<!--
@package lp
@element lp-widget
-->
<dom-module id="lp-widget">
<template>
<style is="custom-style" include="lp-widget-styles"></style>
<!-- This will be dynamically added for model.css
<style id="widget-model-styles" is="custom-style" include="lp-widget-styles"></style>
-->
<div class="widget-inner">
<template is="dom-if" if="[[showTitle]]">
<span class="widget-title title widgetOverlayControls">{{widget.name}}</span>
</template>
<template is="dom-if" if="{{demo}}">
<span class="widget-demo-mode widgetOverlayControls">Demo Mode</span>
</template>
<template is="dom-if" if="{{showControls}}">
showControls?
<div id="widgetDragHandle">
<paper-button raised="" class="widget-move-handle" role="button" title="Move widget" role="button" aria-label="Move widget">
<paper-ripple fit></paper-ripple>
<span class="label">Move</span>
<iron-icon icon="open-with" aria-label="open-with" role="img"></iron-icon>
</paper-button>
</div>
<div class="widget-settings widgetOverlayControls">
<div class="fixed-action-btn horizontal click-to-toggle" style="bottom: 45px; right: 24px;">
<a class="btn-floating btn-large black white-text">
<i class="fa fa-ellipsis-v"></i>
</a>
<ul>
<li><a class="btn-floating red moveWidget draggable" on-tap="showDragHandle"><i class="fa fa-arrows"></i></a></li>
<li><a class="btn-floating yellow darken-1" on-tap="editWidget"><i class="fa fa-pencil"></i></a></li>
<li><a class="btn-floating green" on-tap="removeWidget"><i class="fa fa-trash"></i></a></li>
<li><a class="btn-floating blue" on-tap="shareWidget"><i class="fa fa-share-alt"></i></a></li>
</ul>
</div>
</div>
</template>
<div id="javascriptError">
<div class="warning">
<iron-icon icon="warning" aria-label="warning" role="img"></iron-icon>
</div>
<div class="error-text" id="javascriptErrorText"></div>
<div class="close">
<iron-icon on-tap="hideJsError" icon="close" aria-label="close" role="img"></iron-icon>
</div>
</div>
<div class="widget-content" id="content"></div>
</div>
</template>
</dom-module>
<script>
(function () {
Polymer({
is: 'lp-widget',
behaviors: [
],
properties: {
widget: {
type: Object,
observer: '_widgetChanged'
},
demo: {
type: Boolean,
value: false
},
showTitle: {
type: Boolean,
value: false
},
showControls: {
type: Boolean,
value: true
},
draggable: {
type: Boolean,
value: false
},
tabindex: {
type: Number,
value: 0
},
dataOrder: {
type: Number,
value: 0
}
},
ready: function () {
// self.addEventListener("linchpin-html5-sdk:dashboard:sorted", self.hideDragHandle.bind(self));
// self.fire('linchpin-html5-sdk:dashboard:widget:ready', self);
},
_widgetChanged: function(newValue, oldValue) {
if(!newValue){
return;
}
if(typeof newValue !== 'object'){
throw Error('widget set but not object !');
}
console.log("lp-widget._widgetChanged()");
console.log(JSON.stringify(newValue));
var self = this;
self.$.content.innerHTML = self.widget.html;
self._setWidgetStylesOnDynamicContent();
try {
self.evalJs();
} catch(ex){
console.error(ex);
}
self.fire('linchpin-html5-sdk:dashboard:widget:changed', self);
},
_injectWidgetStyleTag: function() { var self = this;
var prepped = self._prepareModelCss(self.widget.css, 'guid-'+self.widget._id);
$(self).append('<style id="widget-model-styles">'+prepped+'</style>');
},
_setWidgetStylesOnDynamicContent: function(n) { var self = this;
// Custom scope to widget guid
self._scopify(this, 'guid-'+self.widget._id);
// Now add our styles to the style doc
self._injectWidgetStyleTag();
},
evalJs: function(e){ var self = this;
var ev = function(javascript){
eval(javascript);
};
try{
if(self.widget!==null && _.isString(self.widget.js)){
ev.call(this.$.content,self.widget.js);
}
}catch(e){
self.showJsError(e);
}
},
showJsError: function(e){ var self = this;
self.$.javascriptErrorText.textContent = e;
self.$.javascriptError.style.display = "block";
console.error("lp-widget.evalJs() threw error: "+e);
},
aboutWidget: function(e) { var self = this;
e.stopPropagation();
alert('aboutWidget');
self.fire('linchpin-html5-sdk:dashboard:widget:about', self.model);
},
editWidget: function(e) { var self = this;
e.stopPropagation();
self.fire('linchpin-html5-sdk:dashboard:widget:edit', self.model);
},
showDragHandle: function(e) { var self = this;
if(e!==undefined){
e.stopPropagation();
}
self.fire('linchpin-html5-sdk:dashboard:widget:drag:handle:shown', self.model);
var dragHandle = self.querySelector('#widgetDragHandle');
dragHandle.classList.add("showing");
},
hideDragHandle: function(e) { var self = this;
if(e!==undefined){
e.stopPropagation();
}
self.fire('linchpin-html5-sdk:dashboard:widget:drag:handle:hidden', self.model);
var dragHandle = self.querySelector('#widgetDragHandle');
dragHandle.classList.remove("showing");
},
removeWidget: function(e) { var self = this;
e.stopPropagation();
self.fire('linchpin-html5-sdk:dashboard:widget:remove', self.model);
},
shareWidget: function(e) { var self = this;
e.stopPropagation();
self.fire('linchpin-html5-sdk:dashboard:widget:share', self.model);
},
hideJsError: function(e) { var self = this;
e.stopPropagation();
var errorDisplay = self.$.javascriptError;
errorDisplay.style.display = "none";
},
// Copied from a closure inside scopeSubtree() here:
// https://github.com/Polymer/polymer/blob/master/src/standard/styling.html#L120
_scopify: function(node, nodeName) { var self = this;
// node.className = self._scopeElementClass(node, nodeName);
var n$ = node.querySelectorAll('*');
Array.prototype.forEach.call(n$, function(n) {
if(n.nodeName==='TEMPLATE'){
return;
}
this._addElementStyle(n, nodeName);
// n.className = self._scopeElementClass(n, nodeName);
}.bind(this));
},
// Mostly from here: https://github.com/Polymer/polymer/blob/master/src/lib/style-transformer.html#L73
_addElementStyle: function(element, scope) { var self = this;
// note: svg on IE does not have classList so fallback to class
if (element.classList) {
element.classList.add(scope);
} else if (element.getAttribute) {
element.setAttribute('class', c + (c ? ' ' : '') + ' ' + scope);
}
},
// https://github.com/Polymer/polymer/blob/master/src/lib/style-transformer.html#L114
_prepareModelCss: function(styleText, scope) { var self = this;
if(styleText && styleText.trim()!=="") {
return Polymer.StyleTransformer.css(styleText, scope);
}
}
});
})();
</script>