UNPKG

spincycle

Version:

A reactive message router and object manager that lets clients subscribe to object property changes on the server

177 lines (166 loc) 6.23 kB
<!-- @author Horacio Gonzalez (@lostinbrittany) @license Apache 2.0 Inspired by [ace-shim-about-shadow-dom project](https://github.com/valaxy/ace-shim-about-shadow-dom/) A behavior to allow ace-edit to work under ShadowDom. If the app is in ShadowDOM mode, it copies ace-editor's styles into the component ShadowDOM. --> <script> /* * Quick fix for Polymer bug #3840, * while waiting for official correction. * https://github.com/Polymer/polymer/issues/3840 */ (function(){ var matchesSelector = Polymer.DomApi.matchesSelector; var styleUtil = Polymer.StyleUtil; var styleTransformer = Polymer.StyleTransformer; var IS_IE = navigator.userAgent.match('Trident'); var settings = Polymer.Settings; Polymer.StyleProperties.whenHostOrRootRule = function(scope, rule, style, callback) { if (!rule.propertyInfo) { this.decorateRule(rule); } if (!rule.propertyInfo.properties) { return; } var hostScope = scope.is ? styleTransformer._calcHostScope(scope.is, scope.extends) : 'html'; var parsedSelector = rule.parsedSelector; var isRoot = parsedSelector === ':root'; var isHost = parsedSelector.indexOf(':host') === 0; // build info is either in scope (when scope is an element) or in the style // when scope is the default scope; note: this allows default scope to have // mixed mode built and unbuilt styles. var cssBuild = scope.__cssBuild || style.__cssBuild; if (cssBuild === 'shady') { // :root -> x-foo > *.x-foo for elements and html for custom-style isRoot = parsedSelector === (hostScope + ' > *.' + hostScope) || parsedSelector.indexOf('html') !== -1; // :host -> x-foo for elements, but sub-rules have .x-foo in them isHost = !isRoot && parsedSelector.indexOf(hostScope) === 0; } if (cssBuild === 'shadow') { isRoot = parsedSelector === ':host > *' || parsedSelector === 'html'; isHost = isHost && !isRoot; } if (!isRoot && !isHost) { return; } var selectorToMatch = hostScope; if (isHost) { // need to transform :host under ShadowDOM because `:host` does not work with `matches` if (settings.useNativeShadow && !rule.transformedSelector) { // transform :host into a matchable selector rule.transformedSelector = styleTransformer._transformRuleCss( rule, styleTransformer._transformComplexSelector, scope.is, hostScope ); } // parsedSelector fallback for 'shady' css build selectorToMatch = rule.transformedSelector || rule.parsedSelector; } callback({ selector: selectorToMatch, isHost: isHost, isRoot: isRoot }); }; })(); AceWidgetShadowDom = (function(){ var aceShadowRoots = []; var AceWidgetShadowDom = { // Properties properties: { _styles: { type: Array, }, _domHook: { type: Object, }, }, init: function() { if (window.Polymer.Settings.dom === 'shadow') { aceShadowRoots.push(Polymer.dom(this.root)); this._hookDom(); this._getStyle(); this._hookEditor(); this._fixStyle(); } }, _hookDom: function() { var root = this.root; this._domHook = ace.require('ace/lib/dom') var dom = { getDocumentHead: this._domHook.getDocumentHead, importCssString: this._domHook.importCssString, hasCssString : this._domHook.hasCssString } var docHook = { createElement : document.createElement.bind(document), createTextNode: document.createTextNode.bind(document), cssHead : null // change by importCssString } this._domHook.getDocumentHead = function (doc) { if (doc === docHook) { return docHook.cssHead; } return dom.getDocumentHead.apply(doc, arguments); } this._domHook.hasCssString = function (id, doc) { if (doc === docHook) { var index = 0, sheets; doc = docHook.cssHead || document; if (doc.createStyleSheet && (sheets = doc.styleSheets)) { while (index < sheets.length) if (sheets[index++].owningElement.id === id) return true; } else if ((sheets = Polymer.dom(doc).querySelectorAll(("style")))) { while (index < sheets.length) if (sheets[index++].id === id) return true; } return false; } return dom.hasCssString(id, doc); } this._domHook.importCssString = function (cssText, id, doc) { var result aceShadowRoots.forEach(function (cssHead) { docHook.cssHead = cssHead result = dom.importCssString.call(this, cssText, id, docHook) }) return result } }, _getStyle: function() { var style1 = document.getElementById('ace_editor.css') || document.getElementById('ace_editor'); var style2 = document.getElementById('ace-tm'); var style3 = style2.nextSibling; this._styles = [style1, style2, style3]; this._styles.forEach(function (style) { // style.parentNode.removeChild(style) }); }, _hookEditor: function() { var EditorHook = ace.require('ace/editor').Editor; var Editor = { setTheme: EditorHook.prototype.setTheme } EditorHook.prototype.setTheme = function () { Editor.setTheme.apply(this, arguments); } }, _addEditor: function() { this._fixStyle(); }, _fixStyle: function() { var root = this.root this._styles.forEach(function (style) { Polymer.dom(root).appendChild(style.cloneNode(true)); }) } }; return AceWidgetShadowDom; })(); </script>