UNPKG

coffeescript-ui

Version:
161 lines (129 loc) 4.55 kB
### * coffeescript-ui - Coffeescript User Interface System (CUI) * Copyright (c) 2013 - 2016 Programmfabrik GmbH * MIT Licence * https://github.com/programmfabrik/coffeescript-ui, http://www.coffeescript-ui.org ### # my_load = new CUI.CSSLoader() # my_load.load(theme: "1", url: "...theme1.css") -> Promise # my_load.load(theme: "roman", url: "...theme2.css") -> Promise # my_load.getActiveCSS() -> {theme: "roman", url: ...} class CUI.CSSLoader extends CUI.Element readOpts: -> super() if @_cssName @__cssName = @_cssName else @__cssName = "cui-css-"+@getUniqueId() return initOpts: -> super() @addOpts cssName: check: String __getCSSNodes: -> CUI.dom.matchSelector(document.documentElement, "link[name=\""+@__cssName+"\"]") getActiveCSS: -> for cssNode in @__getCSSNodes() if CUI.dom.getAttribute(cssNode, "data-cui-loading") continue return url: CUI.dom.getAttribute(cssNode, "data-cui-url") theme: CUI.dom.getAttribute(cssNode, "data-cui-theme") return null load: (_opts = {}) -> opts = CUI.Element.readOpts _opts, "CSSLoader", theme: check: String default: "" url: mandatory: true check: String # console.error "nodes:", @__getCSSNodes(), opts, @getActiveCSS() for oldCssNode in @__getCSSNodes() is_loading = CUI.dom.getAttribute(oldCssNode, "data-cui-loading") if is_loading console.warn("CSSLoader.load. CSS already loading.", opts: opts) return CUI.rejectedPromise() active = @getActiveCSS() if active and opts.url == active.url and active.theme == opts.theme return CUI.resolvedPromise() url = opts.url dfr = new CUI.Deferred() if url.startsWith("http://") or url.startsWith("https://") or url.startsWith("file://") css_href = url else if not url.startsWith("/") css_href = CUI.getPathToScript() + url else css_href = document.location.origin + url # console.info("CSSLoader: Loading:", css_href) # console.error "parsing location", url, CUI.getPathToScript(), css_href cssNode = CUI.dom.element "LINK", rel: "stylesheet" charset: "utf-8" name: @__cssName "data-cui-loading": "1" "data-cui-theme": opts.theme "data-cui-url": opts.url href: css_href old_css_nodes = CUI.dom.matchSelector(document.head, "link[name='"+@__cssName+"']") dfr.always => CUI.dom.removeAttribute(cssNode, "data-cui-loading") dfr.fail (css_href) => console.error("CSSLoader: Loading failed, removing node.", css_href) CUI.dom.remove(cssNode) CUI.Events.listen node: cssNode type: "load" call: (ev, info) => if dfr.state() != "pending" console.warn("CSSLoader.loadTheme: Caught event load second time, ignoring. IE does that for some reason.") return if CUI.browser.ie found_stylesheet = false # ok, let's check if the style sheet loaded actually applies # rules. IE tends to ignore 404 here. for styleSheet in document.styleSheets if styleSheet.href == css_href # this is the css loaded try if not styleSheet.cssRules?.length # we assume loading failed console.error("CSSLoader: Loaded a stylesheet with no rules: ", css_href, styleSheet) dfr.reject(css_href) return found_stylesheet = true catch ex ; # ignore, we output an error below break if not found_stylesheet console.error("CSSLoader: Stylesheet not correctly loaded: ", css_href) dfr.reject(css_href) return # old_css_nodes = [] for css_node in old_css_nodes # :not([loading])") if css_node == cssNode continue # console.info("CSSLoader.loadTheme: Removing old css node:", CUI.dom.getAttribute(css_node, "href"), "New Node is:", CUI.dom.getAttribute(cssNode, "href"), "Is loading:", CUI.dom.getAttribute(css_node, "loading")) CUI.dom.remove(css_node) # old_css_nodes.push(css_node) CUI.dom.setAttribute(document.body, "data-cui-theme", opts.theme) # console.info("CSSLoader.loadTheme: Loading went fine: ", url, "Removing the old CSS node: ", old_css_nodes) CUI.Events.trigger type: "viewport-resize" info: css_load: true dfr.resolve(css_href) return CUI.Events.listen node: cssNode type: "error" call: (ev, info) => console.error("CSS.load: loading error:", url) dfr.reject(css_href) return if old_css_nodes.length > 0 CUI.dom.insertAfter(old_css_nodes[old_css_nodes.length - 1], cssNode) else document.head.appendChild(cssNode) dfr.promise()