reload-0.0.0.1: web/bower_components/juicy-ace-editor/juicy-ace-editor.html
<!--
Custom Element with Ace code editor
http://juicy.github.io/juicy-ace-editor/
version: 1.2.0
@demo index.html
@license MIT
@author
-->
<script src="../ace-builds/src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="../ace-builds/src-min-noconflict/ext-searchbox.js" type="text/javascript" charset="utf-8"></script>
<template id="juicy-ace-editor">
<style>
:host{
display: flex;
min-height: 1em;
flex-direction: column;
}
#juicy-ace-editor-container{
flex: 1;
}
</style>
<div id="juicy-ace-editor-container"></div>
</template>
<script>
(function(window, document, undefined) {
// Refers to the "importer", which is index.html
var thatDoc = document;
// Refers to the "importee", which is juicy-ace-editor.html
var thisDoc = (document._currentScript || document.currentScript).ownerDocument;
// Gets content from <template>
var template = thisDoc.querySelector('template#juicy-ace-editor').content;
// Shim Shadow DOM styles if needed
if (window.ShadowDOMPolyfill) {
WebComponents.ShadowCSS.shimStyling(template, 'juicy-ace-editor');
}
// Creates an object based in the HTML Element prototype
var TomalecAceEditorPrototype = Object.create(HTMLElement.prototype);
// Fires when an instance of the element is created
TomalecAceEditorPrototype.createdCallback = function() {
var value = "";
Object.defineProperty(this, "value", {
set: function(val){
this.editor && this.editor.setValue( val );
value = val;
},
get: function(){
value = this.editor && this.editor.getValue() || value;
return value;
}
});
// Creates the shadow root
var shadowRoot = this.createShadowRoot();
// Adds a template clone into shadow root
var clone = thatDoc.importNode(template, true);
this.container = clone.getElementById("juicy-ace-editor-container");
shadowRoot.appendChild(clone);
};
// Fires when an instance was inserted into the document
TomalecAceEditorPrototype.attachedCallback = function() {
var text = this.childNodes[0];
var container = this.container;
var element = this;
if(this.editor){
editor = this.editor;
this.value = text.textContent || this.value;
} else {
// container.appendChild(text);
container.innerHTML = this.innerHTML || this.value;
editor = ace.edit(container);
this.dispatchEvent(new CustomEvent("editor-ready", {detail: editor}));
this.editor = editor;
// inject base editor styles
this.injectTheme('#ace_editor\\.css');
this.injectTheme('#ace-tm');
this.injectTheme('#ace_searchbox');
editor.getSession().on('change', function(event){
element.dispatchEvent(new CustomEvent("change", {detail: event}));
});
}
// handle theme changes
editor.renderer.addEventListener("themeLoaded", this.onThemeLoaded.bind(this));
// initial attributes
editor.setTheme( this.getAttribute("theme") );
editor.setFontSize( this.getAttribute("fontsize") );
editor.setReadOnly( this.hasAttribute("readonly") );
var session = editor.getSession();
session.setMode( this.getAttribute("mode") );
session.setUseSoftTabs( this.getAttribute("softtabs") );
this.getAttribute("tabsize") && session.setTabSize( this.getAttribute("tabsize") );
session.setUseWrapMode( this.hasAttribute("wrapmode") );
// Observe input textNode changes
// Could be buggy as editor was also added to Light DOM;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
// console.log("observation", mutation.type, arguments, mutations, editor, text);
if(mutation.type == "characterData"){
element.value = text.data;
}
});
});
text && observer.observe(text, { characterData: true });
// container.appendChild(text);
this._attached = true;
};
// Fires when an instance was removed from the document
TomalecAceEditorPrototype.detachedCallback = function() {
this._attached = false;
};
// Fires when an attribute was added, removed, or updated
TomalecAceEditorPrototype.attributeChangedCallback = function(attr, oldVal, newVal) {
if(!this._attached){
return false;
}
switch(attr){
case "theme":
this.editor.setTheme( newVal );
break;
case "mode":
this.editor.getSession().setMode( newVal );
break;
case "fontsize":
this.editor.setFontSize( newVal );
break;
case "softtabs":
this.editor.getSession().setUseSoftTabs( newVal );
break;
case "tabsize":
this.editor.getSession().setTabSize( newVal );
break;
case "readonly":
this.editor.setReadOnly( newVal === '' || newVal );
break;
case "wrapmode":
this.editor.getSession().setUseWrapMode( newVal !== null );
break;
}
};
TomalecAceEditorPrototype.onThemeLoaded = function(e){
var themeId = "#" + e.theme.cssClass;
this.injectTheme(themeId);
// Workaround Chrome stable bug, force repaint
this.container.style.display='none';
this.container.offsetHeight;
this.container.style.display='';
};
// inject the style tag of a theme to the element
TomalecAceEditorPrototype.injectTheme = function(themeId){
var n = document.querySelector(themeId);
this.shadowRoot.appendChild(cloneStyle(n));
};
//helper function to clone a style
function cloneStyle(style) {
var s = document.createElement('style');
s.id = style.id;
s.textContent = style.textContent;
return s;
}
document.registerElement('juicy-ace-editor', {
prototype: TomalecAceEditorPrototype
});
}(window, document));
</script>