UNPKG

coffeescript-ui

Version:
321 lines (255 loc) 7.73 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 ### marked = require('marked') CUI.Template.loadTemplateText(require('./Label.html')); # @param [Object] options for {Label} creation # @option options [boolean] centered , label will be centered with css style 'position: absolute'. class CUI.Label extends CUI.DOMElement @defaults: manage_overflow: icon_inactive: "down" icon_active: "up" active_css_class: "" constructor: (opts) -> super(opts) if @_rotate_90 tname = "label-rotate-90" else if @_icon or not CUI.__ng__ tname = "label" else tname = "label-no-icon" @__label = new CUI.Template name: tname map_prefix: "cui-label" map: icon: if tname == "label-no-icon" then undefined else true content: true @registerTemplate(@__label) if @_icon and @_icon != true @setIcon(@_icon) if not CUI.util.isEmpty(@_text) @setText(@_text) else @setContent(@_content) if @_tooltip tt_opts = CUI.util.copyObject(@_tooltip) tt_opts.element ?= @DOM @__tooltip = new CUI.Tooltip(tt_opts) if @_multiline @addClass("cui-label-multiline") if @_centered @addClass("cui-label-centered") if @_markdown @addClass("cui-label-markdown") if @_manage_overflow @addClass("cui-label-manage-overflow") if @_padded @addClass("cui-label--padded") if @_size @addClass("cui-label-size-"+@_size) else if not CUI.__ng__ @addClass("cui-label-size-normal") #need to set normal as default for mediathek! and light if @_appearance @addClass("cui-label-appearance-"+@_appearance) if @_manage_overflow if @_manage_overflow == true btn_opts = CUI.util.copyObject(CUI.defaults.class.Label.defaults.manage_overflow, true) else btn_opts = @_manage_overflow for k, v of { class: "cui-label-manage-overflow-button" appearance: "flat" switch: true hidden: true onActivate: => @__label.addClass("cui-label--show-overflow") onDeactivate: => @__label.removeClass("cui-label--show-overflow") } if not btn_opts.hasOwnProperty(k) or k not in ["class"] btn_opts[k] = v continue btn_opts[k] += " "+v @__overflow_button = new CUI.defaults.class.Button(btn_opts) # push in global markup @append(@__overflow_button) # throttle the check to partially mitigate the performance bottleneck # when resizing via resize handle when a lot of "manage overflow" # labels are in the DOM checkOverflow = => @checkOverflowSize() CUI.Events.listen node: @DOM type: "viewport-resize" call: => CUI.scheduleCallback(ms: 500, call: checkOverflow) return initOpts: -> super() @addOpts text: check: (v) -> CUI.util.isString(v) or CUI.util.isNumber(v) text_node_func: check: Function content: check: (v) -> CUI.util.isContent(v) or CUI.util.isString(v) icon: check: (v) -> v instanceof CUI.Icon or CUI.util.isString(v) or v == true size: check: ["mini","normal","big","bigger"] appearance: check: ["title","secondary","muted"] # set to true if text is markdown markdown: mandatory: true default: false check: Boolean markdown_opts: check: "PlainObject" tooltip: check: "PlainObject" group: check: String rotate_90: default: false check: Boolean centered: default: false check: Boolean multiline: default: false check: Boolean padded: default: false check: Boolean manage_overflow: check: (v) -> CUI.util.isPlainObject(v) or v == true or v == false readOpts: -> super() if CUI.util.isNull(@_text) and CUI.util.isNull(@_content) @_text = "" if @_markdown CUI.util.assert(not @_content, "new "+@__cls, "opts.markdown cannot be combined with opts.content, use opts.text instead.", opts: @opts) if not marked console.error("new CUI.Label: Could not find markdown renderer 'marked'. Disabling markedown option.", opts: @opts) @__markdown = false else @__markdown = true @__currentText = null CUI.util.assert(CUI.util.xor(CUI.util.isNull(@_text), CUI.util.isNull(@_content)), "new CUI.Label", "opts.text and opts.content cannot both be set.", opts: @opts) if @_markdown_opts @__markdown_opts = CUI.util.copyObject(CUI.defaults.marked_opts, false) for k, v of @_markdown_opts @__markdown_opts[k] = v else @__markdown_opts = CUI.defaults.marked_opts if @_manage_overflow CUI.util.assert(@_multiline, "new CUI.Label", "opts.multiline needs to be set for opts.manage_overflow", opts: @opts) @ setText: (@__currentText, markdown = @__markdown) -> if CUI.util.isEmpty(@__currentText) @empty("content") else if markdown @setContent(CUI.dom.htmlToNodes(marked(@__currentText, @__markdown_opts))) @addClass("cui-label-markdown") else if @_text_node_func @setContent(@_text_node_func(@__currentText)) @removeClass("cui-label-markdown") else @setContent(CUI.dom.text(@__currentText)) @removeClass("cui-label-markdown") @ setTextMaxChars: (max_chars) -> CUI.dom.setAttribute(@__label.map.content, "data-max-chars", max_chars) getText: -> @__currentText setContent: (content) -> if CUI.util.isString(content) @replace(CUI.dom.htmlToNodes(content), 'content') else @replace(content, "content") if not @_manage_overflow return # append overflow button to the whole thing @append(@__overflow_button) CUI.dom.waitForDOMInsert(node: @DOM) .done => @checkOverflowSize() return checkOverflowSize: -> if not @__overflow_button return # show full content and see if it fits @__label.removeClass("cui-label--show-overflow") @__label.addClass("cui-label--measure-overflow") @__overflow_button.hide() dim_div = CUI.dom.getDimensions(@__label.map.content) max_height = CUI.dom.getCSSFloatValue(dim_div.computedStyle.maxHeight) if not (max_height > 0) max_height = dim_div.clientHeight # console.info("Label.checkOverflowSize: Scroll Height:", dim_div.scrollHeight, " Using Height: ", max_height, "Element:", @__label.map.content) if dim_div.scrollHeight > max_height # really to big, show button @__overflow_button.show() if @__overflow_button.isActive() @__label.addClass("cui-label--show-overflow") else @__label.addClass("cui-label--show-overflow") @__label.removeClass("cui-label--measure-overflow") @ getGroup: -> @_group setIcon: (icon) -> if icon instanceof CUI.Icon __icon = icon else if not CUI.util.isEmpty(icon) __icon = new CUI.Icon(icon: icon) else __icon = null @replace(__icon, "icon") @ destroy: -> @__tooltip?.destroy() super() # reads the input txt, parses links and returns # dom notes. suitable to use as text_node_func. @parseLinks: (txt) -> nodes = [] text = [] append_text = => if text.length == 0 return nodes.push(CUI.dom.text(text.join(""))) text = [] return for el, idx in txt.split(/(\n| )/) if CUI.EmailInput.regexp.exec(el) a_node = CUI.dom.element("a", href: "mailto:"+el) else m = el.match("^(?:www\..+\..+|(http(?:s|)):\/\/)") if not m a_node = null else if not m[1] prefix = "http://" else prefix = "" # use the given prefix a_node = CUI.dom.element("a", target: "_blank", href: prefix+el) if not a_node text.push(el) continue # append the link append_text() a_node.textContent = el nodes.push(a_node) append_text() return nodes CUI.defaults.class.Label = CUI.Label