| @@ -0,0 +1,9 @@ | ||
| #!/bin/bash | ||
|
|
||
| if [ ! -d ./bin ]; then | ||
| mkdir -p ./bin | ||
| fi | ||
|
|
||
| coffee --compile --output ./bin ./src | ||
|
|
||
| echo "... Done" |
| @@ -0,0 +1,145 @@ | ||
| ### | ||
| gara - Javascript Toolkit | ||
| Copyright (c) 2007 Thomas Gossmann | ||
| Homepage: | ||
| http://garajs.org | ||
| This library is free software you can redistribute it and/or | ||
| modify it under the terms of the GNU Lesser General Public | ||
| License as published by the Free Software Foundation either | ||
| version 2.1 of the License, or (at your option) any later version. | ||
| This library is distributed in the hope that it will be useful, | ||
| but WITHOUT ANY WARRANTY without even the implied warranty of | ||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| Lesser General Public License for more details. | ||
| ### | ||
|
|
||
|
|
||
| define 'gara/widgets/CheckboxItem', ['require', 'exports'], (require, exports) -> | ||
|
|
||
| ### | ||
| A trait for checkbox items | ||
| @require checkWidget | ||
| @require handle | ||
| @require config | ||
| ### | ||
| class CheckboxItem | ||
|
|
||
|
|
||
| initCheckbox: (config = {}) -> | ||
| @checkbox = null | ||
| @config.checked = config.checked || false | ||
| @config.grayed = config.grayed || false | ||
|
|
||
| ### | ||
| Internal creation process of this item | ||
| @private | ||
| @returns {void} | ||
| ### | ||
| createCheckbox: -> | ||
| @checkbox = gara.global.document.createElement('span') | ||
| @checkbox.id = @getId() + '-checkbox' | ||
| @checkbox.widget = this | ||
| @checkbox.control = @parent | ||
| @checkbox.setAttribute('role', 'presentation') | ||
|
|
||
| @setCheckboxClass() | ||
|
|
||
| @handle.appendChild(@checkbox) | ||
| @handle.setAttribute('aria-checked', @config.checked) | ||
|
|
||
| # register events | ||
| handleCheckbox = (e) => | ||
| @checkWidget() | ||
| if ((e.target is @checkbox and e.type is 'mousedown') or | ||
| (e.target is @checkbox and e.type is 'mouseup') or | ||
| (e.type is 'keydown' and e.keyCode is gara.SPACE)) and | ||
| !@config.grayed | ||
| @fireEvent('selection', gara.CHECK) | ||
| @setChecked(!@checked) | ||
|
|
||
| @addListener('mousedown', handleCheckbox) | ||
| @addListener('mouseup', handleCheckbox) | ||
| @addListener('keydown', handleCheckbox) | ||
|
|
||
|
|
||
| ### | ||
| Returns the receiver's checked state. | ||
| @see gara.widgets.ListItem#setChecked | ||
| @returns {boolean} <code>true</code> for checked and <code>false</code> otherwise | ||
| ### | ||
| getChecked: -> | ||
| @checkWidget() | ||
| @config.checked | ||
|
|
||
|
|
||
| ### | ||
| Returns the receiver's grayed state. | ||
| @see gara.widgets.ListItem#setGrayed | ||
| @returns {boolean} <code>true</code> for grayed and <code>false</code> otherwise | ||
| ### | ||
| getGrayed: -> | ||
| @checkWidget() | ||
| @config.grayed | ||
|
|
||
|
|
||
| ### | ||
| @private | ||
| ### | ||
| setCheckboxClass: -> | ||
| if !@checkbox | ||
| return | ||
|
|
||
| @checkbox.className = 'gara-checkbox' | ||
| if @config.checked and @config.grayed | ||
| @checkbox.className += ' gara-checkbox-grayed-checked' | ||
| else if @config.grayed | ||
| @checkbox.className += ' gara-checkbox-grayed' | ||
| else if @config.checked | ||
| @checkbox.className += ' gara-checkbox-checked' | ||
|
|
||
|
|
||
| ### | ||
| Sets the receiver's checked state. | ||
| @see gara.widgets.ListItem#getChecked | ||
| @param {boolean} checked <code>true</code> for checked and <code>false</code> otherwise | ||
| @returns {void} | ||
| ### | ||
| setChecked: (checked) -> | ||
| @checkWidget() | ||
| if !@config.grayed | ||
| @config.checked = checked | ||
| @handle.setAttribute('aria-checked', checked) | ||
| @setCheckboxClass() | ||
|
|
||
| this | ||
|
|
||
|
|
||
| ### | ||
| Sets the receiver's grayed state. | ||
| @see gara.widgets.ListItem#getGrayed | ||
| @param {boolean} grayed <code>true</code> for grayed and <code>false</code> otherwise | ||
| @returns {void} | ||
| ### | ||
| setGrayed: (grayed) -> | ||
| @checkWidget() | ||
| @config.grayed = grayed | ||
| if @checkbox | ||
| @checkbox.setAttribute('aria-disabled', grayed) | ||
| @setCheckboxClass() | ||
|
|
||
| this | ||
|
|
||
|
|
||
| gara.namespace('gara.widgets') | ||
| gara.widgets.CheckboxItem = CheckboxItem | ||
| exports.CheckboxItem = CheckboxItem |
| @@ -0,0 +1,309 @@ | ||
| ### | ||
| gara - Javascript Toolkit | ||
| Copyright (c) 2007 Thomas Gossmann | ||
| Homepage: | ||
| http:#garajs.org | ||
| This library is free software; you can redistribute it and/or | ||
| modify it under the terms of the GNU Lesser General Public | ||
| License as published by the Free Software Foundation; either | ||
| version 2.1 of the License, or (at your option) any later version. | ||
| This library is distributed in the hope that it will be useful, | ||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| Lesser General Public License for more details. | ||
| ### | ||
|
|
||
| define 'gara/widgets/Composite', ['require', 'exports', 'gara/widgets/Scrollable'], (require, exports) -> | ||
|
|
||
| #gara.use("gara.widgets.Control"); | ||
| Scrollable = require('gara/widgets/Scrollable') | ||
|
|
||
| class Composite extends Scrollable | ||
| ### | ||
| A specific Layout of the receiver | ||
| @private | ||
| @type {gara.layout.Layout} | ||
| ### | ||
| layoutInformation: null | ||
|
|
||
| constructor: (parent, config) -> | ||
| @layoutInformation = null | ||
|
|
||
| super(parent, config) | ||
| #@resize(); | ||
|
|
||
| createHandle: (element) -> | ||
| super(element); | ||
| @addClass("gara-composite") | ||
|
|
||
|
|
||
| createWidget: -> | ||
| @createHandle("div") | ||
| @handle.tabIndex = -1 | ||
|
|
||
|
|
||
| getChildren: -> | ||
| ### | ||
| @summary | ||
| Returns a (possibly empty) array containing the receiver's children. | ||
| @description | ||
| Returns a (possibly empty) array containing the receiver's children. Children are returned | ||
| in the order that they are drawn. The topmost control appears at the beginning of the array. | ||
| Subsequent controls draw beneath this control and appear later in the array. | ||
| @returns {gara.widgets.Control[]} an array of children | ||
| ### | ||
| temp = {} | ||
| layers = {} | ||
| max = 0 | ||
| controls = [] | ||
| childs = @getClientArea().childNodes | ||
| addControl = (widget) -> controls[controls.length] = widget | ||
|
|
||
| # SELECT childNodes FROM @getClientArea() WHERE childNode[widget] | ||
| # ORDER BY childNode.style.zIndex DESC | ||
| for child in childs | ||
| if child.widget and child.widget isnt this and | ||
| child.widget instanceof gara.widgets.Control | ||
| z = if child.widget.handle.style.zIndex is "" then 0 else child.widget.handle.style.zIndex | ||
| layers[z] = [] if !layers[z] | ||
| layers[z][layers[z].length] = child.widget | ||
| max = Math.max(max, z) | ||
|
|
||
| for i in [max..0] | ||
| layers[i].forEach(addControl, this) if layers[i] | ||
|
|
||
| controls | ||
|
|
||
|
|
||
|
|
||
| getLayout: -> | ||
| ### | ||
| Returns layout which is associated with the receiver, or null if one has not been set. | ||
| @see gara.widgets.Composite#setLayout | ||
| @returns {gara.layout.Layout} the receiver's layout or null | ||
| ### | ||
| @layoutInformation | ||
|
|
||
|
|
||
| layout: -> | ||
| ### | ||
| If the receiver has a layout, asks the layout to <em>lay out</em> (that is, set the size and | ||
| location of) the receiver's children. If the receiver does not have a layout, do nothing. | ||
| @see gara.widgets.Composite#setLayout | ||
| @returns {void} | ||
| ### | ||
| # var resizeable = [], lastHeight, ratio, widgetHeight, | ||
| # autoHeight = [], percentHeight = [], cssHeight = [], | ||
| # heights = ["h25", "h50", "h75", "h33", "h66"], | ||
| # widths = ["w25", "w50", "w75", "w33", "w66"], | ||
| # ratios = [0.25, 0.5, 0.75, 0.3333, 0.6666], | ||
| # width, height, | ||
| # overflowX = gara.getStyle(@getClientArea(), "overflow-x"), | ||
| # overflowY = gara.getStyle(@getClientArea(), "overflow-y"); | ||
| # | ||
| # console.log("Composite ("+this+").layout"); | ||
| # | ||
| # @update(); | ||
| # | ||
| # @getClientArea().style.overflowX = "hidden"; | ||
| # @getClientArea().style.overflowY = "hidden"; | ||
| # | ||
| # height = @getClientArea().clientHeight; | ||
| # width = @getClientArea().clientWidth; | ||
| # | ||
| # if (width === 0 || height === 0) { | ||
| # return; | ||
| # } | ||
| # | ||
| # if (@layoutInformation !== null) { | ||
| # @layoutInformation.layout(this); | ||
| # @getClientArea().style.overflowY = overflowY; | ||
| # @getClientArea().style.overflowX = overflowX; | ||
| # return; | ||
| # } | ||
| # | ||
| # @getChildren().forEach(function (widget) { | ||
| # # console.log("Composite.layout: " + widget + " " + widget.getHeight()); | ||
| # if (widget instanceof gara.widgets.Scrollable) { | ||
| # # if (!(widget.hasClass("h25") || widget.hasClass("h50" || widget.hasClass("h75") || widget.hasClass("h100") || widget.hasClass("h33") || widget.hasClass("h66") || widget.getHeight() >= 0 && widget.getHeight() <= 1))) { | ||
| # # console.log(this + ".setHeight push changeable"); | ||
| # # changeable.push(widget); | ||
| # # } else { | ||
| # # if (widget.getHeight() === null) { | ||
| # # widgetHeight = widget.handle.clientHeight - gara.getNumStyle(widget.handle, "padding-top") - gara.getNumStyle(widget.handle, "padding-bottom") - gara.getNumStyle(widget.handle, "border-top") - gara.getNumStyle(widget.handle, "border-bottom"); | ||
| # # # console.log("Composite.setHeight, widgetHeight: " + widgetHeight); | ||
| # # widget.setHeight(widgetHeight); | ||
| # # widget.setHeight(null); | ||
| # # newHeight -= widgetHeight; | ||
| # # } | ||
| # # } | ||
| # | ||
| # # css width | ||
| # # if (widget.hasClass("w25") || widget.hasClass("w50") || widget.hasClass("w75") || widget.hasClass("w33") || widget.hasClass("w66")) { | ||
| # # widths.forEach(function (cssHeightClass, j) { | ||
| # # if (widget.hasClass(cssHeightClass)) { | ||
| # # ratio = ratios[j]; | ||
| # # return; | ||
| # # } | ||
| # # }, this); | ||
| # # widget.adjustWidth(Math.floor(ratiowidth)); | ||
| # # } | ||
| # | ||
| # # no width | ||
| # if (widget.getWidth() === null) { | ||
| # widget.adjustWidth(width); | ||
| # } | ||
| # | ||
| # # height | ||
| # if (widget.getHeight() > 1) { | ||
| # height -= widget.getHeight(); | ||
| # } else if (widget.hasClass("h25") || widget.hasClass("h50") || widget.hasClass("h75") || widget.hasClass("h33") || widget.hasClass("h66")) { | ||
| # # console.log(this + ".layout push cssHeight of " + widget); | ||
| # cssHeight.push(widget); | ||
| # } else if (widget.getHeight() === null) { | ||
| # # console.log(this + ".setHeight push autoHeight"); | ||
| # # resizeable.push(widget); | ||
| # autoHeight.push(widget); | ||
| # } else if (widget.getHeight() >= 0 && widget.getHeight() <= 1) { | ||
| # # resizeable.push(widget); | ||
| # percentHeight.push(widget); | ||
| # } | ||
| # } | ||
| # }, this); | ||
| # | ||
| # lastHeight = height; | ||
| # | ||
| # # widths.forEach(function (widget) { | ||
| # # | ||
| # # }); | ||
| # | ||
| # autoHeight.forEach(function (widget, i, arr) { | ||
| # # console.log("Composite.layout auto height"); | ||
| # if (i === arr.length - 1) { | ||
| # # console.log("Layout.setHeight last-autoHeight("+lastHeight+")"); | ||
| # # widget.setHeight(newHeight); | ||
| # # widget.setHeight(null); | ||
| # # console.log("Composite.layout(autoHeight) " + widget + " " + lastHeight); | ||
| # # widget.handle.style.height = lastHeight + "px"; | ||
| # widget.adjustHeight(lastHeight); | ||
| # } else { | ||
| # widgetHeight = Math.floor(lastHeight / autoHeight.length); | ||
| # # console.log("Layout.setHeight autoHeight("+widgetHeight+")"); | ||
| # # widget.setHeight(widgetHeight); | ||
| # # widget.setHeight(null); | ||
| # # console.log("Composite.layout(autoHeight) " + widget + " " + widgetHeight); | ||
| # # widget.handle.style.height = widgetHeight + "px"; | ||
| # widget.adjustHeight(widgetHeight); | ||
| # lastHeight -= widgetHeight; | ||
| # } | ||
| # }, this); | ||
| # | ||
| # percentHeight.forEach(function (widget, i, arr) { | ||
| # if (i === arr.length - 1) { | ||
| # # console.log("Layout.setHeight last-percentHeight("+lastHeight+")"); | ||
| # # widget.setHeight(newHeight); | ||
| # # widget.setHeight(null); | ||
| # # widget.handle.style.height = lastHeight + "px"; | ||
| # widget.adjustHeight(lastHeight); | ||
| # } else { | ||
| # widgetHeight = Math.floor(widget.getHeight()height); | ||
| # # console.log("Layout.setHeight percentHeight("+widgetHeight+")"); | ||
| # # widget.setHeight(widgetHeight); | ||
| # # widget.setHeight(null); | ||
| # widget.adjustHeight(widgetHeight); | ||
| # # widget.handle.style.height = widgetHeight + "px"; | ||
| # lastHeight -= widgetHeight; | ||
| # } | ||
| # }, this); | ||
| # | ||
| # cssHeight.forEach(function (widget, i, arr) { | ||
| # if (i === arr.length - 1) { | ||
| # # console.log("Layout.setHeight last-cssHeight("+lastHeight+")"); | ||
| # widget.adjustHeight(lastHeight); | ||
| # # widget.handle.style.height = lastHeight + "px"; | ||
| # } else { | ||
| # heights.forEach(function (cssHeightClass, j) { | ||
| # if (widget.hasClass(cssHeightClass)) { | ||
| # ratio = ratios[j]; | ||
| # return; | ||
| # } | ||
| # }, this); | ||
| # widgetHeight = Math.floor(ratioheight); | ||
| # # console.log("Layout.setHeight cssHeight("+widgetHeight+")"); | ||
| # # widget.setHeight(widgetHeight); | ||
| # # widget.setHeight(null); | ||
| # widget.adjustHeight(widgetHeight); | ||
| # # widget.handle.style.height = widgetHeight + "px"; | ||
| # lastHeight -= widgetHeight; | ||
| # } | ||
| # }, this); | ||
| # | ||
| # @getChildren().forEach(function (widget) { | ||
| # if (widget instanceof gara.widgets.Composite) { | ||
| # widget.layout(); | ||
| # } else if (widget.update) { | ||
| # widget.update(); | ||
| # } | ||
| # }); | ||
| # | ||
| # @getClientArea().style.overflowY = overflowY; | ||
| # @getClientArea().style.overflowX = overflowX; | ||
|
|
||
|
|
||
|
|
||
| releaseChildren: -> | ||
| ### | ||
| Releases all children from the receiver | ||
| @private | ||
| @returns {void} | ||
| ### | ||
| @getChildren().forEach (control) -> | ||
| control.release() | ||
|
|
||
|
|
||
| setLayout: (layout) -> | ||
| ### | ||
| Sets the layout which is associated with the receiver to be the argument which may be null. | ||
| @see gara.widgets.Composite#getLayout | ||
| @see gara.widgets.Composite#layout | ||
| @param {gara.layout.Layout} layout the receiver's new layout or null | ||
| @returns {gara.widgets.Composite} this | ||
| ### | ||
| if !layout instanceof gara.layout.Layout | ||
| throw new TypeError("layout not instance of gara.layout.Layout") | ||
|
|
||
| @layoutInformation.deconstruct(this) if @layoutInformation isnt null | ||
| @layoutInformation = layout | ||
| @layoutInformation.construct(this) | ||
| this | ||
|
|
||
| # setHeight : function (height) { | ||
| # @$super(height); | ||
| ## @layout(); | ||
| # return this; | ||
| # }, | ||
| # | ||
| # setWidth : function (width) { | ||
| # @$super(width); | ||
| ## @layout(); | ||
| # return this; | ||
| # }, | ||
|
|
||
| toString: -> | ||
| '[gara.widgets.Composite]' | ||
|
|
||
|
|
||
| gara.namespace('gara.widgets') | ||
| gara.widgets.Composite = Composite | ||
| exports.Composite = Composite |
| @@ -0,0 +1,378 @@ | ||
| ### | ||
| gara - Javascript Toolkit | ||
| Copyright (c) 2007 Thomas Gossmann | ||
| Homepage: | ||
| http://garajs.org | ||
| This library is free software; you can redistribute it and/or | ||
| modify it under the terms of the GNU Lesser General Public | ||
| License as published by the Free Software Foundation; either | ||
| version 2.1 of the License, or (at your option) any later version. | ||
| This library is distributed in the hope that it will be useful, | ||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| Lesser General Public License for more details. | ||
| ### | ||
|
|
||
| define 'gara/widgets/Display', ['require', 'exports', 'gara/widgets/Shell'], (require, exports) -> | ||
| #gara.use('gara.widgets.Widget'); | ||
| #gara.use('gara.widgets.Control'); | ||
| #gara.use('gara.widgets.Shell'); | ||
|
|
||
|
|
||
| class Display | ||
|
|
||
| ### | ||
| Holds the current focus control. | ||
| @private | ||
| @type gara.wigets.Control | ||
| ### | ||
| #focusControl: null | ||
|
|
||
| ### | ||
| @private | ||
| @type Object | ||
| ### | ||
| #disposeListener: null | ||
|
|
||
| ### | ||
| Contains the widgets attached to this display | ||
| @private | ||
| @type gara.wigets.Widget[] | ||
| ### | ||
| #widgets: [] | ||
|
|
||
| ### | ||
| Contains the shells attached to this display | ||
| @private | ||
| @type gara.wigets.Shell[] | ||
| ### | ||
| #shells: [] | ||
|
|
||
| ### | ||
| @private | ||
| @type {gara.widgets.Shell} | ||
| ### | ||
| #activeShell: null | ||
|
|
||
| ### | ||
| @private | ||
| @static | ||
| @type {gara.widgets.Display} | ||
| ### | ||
| @defaultDisplay: null | ||
|
|
||
| constructor: -> | ||
| gara.addEventListener(document, 'keydown', this); | ||
| gara.addEventListener(document, 'keypress', this); | ||
| gara.addEventListener(document, 'keyup', this); | ||
| gara.addEventListener(document, 'mousedown', this); | ||
| gara.addEventListener(document, 'mouseup', this); | ||
| gara.addEventListener(document, 'dblclick', this); | ||
| gara.addEventListener(document, 'contextmenu', this); | ||
|
|
||
| @shells = [] | ||
| @widgets = [] | ||
| @activeShell = null | ||
| @focusControl = null | ||
| @clientArea = window.document.getElementsByTagName('body')[0] | ||
| @disposeListener = | ||
| widgetDisposed: (widget) => | ||
| @removeWidget(widget) | ||
|
|
||
|
|
||
| ### | ||
| Adds a widget to the Display. | ||
| @private | ||
| @param {gara.widgets.Widget} widget the widget | ||
| @returns {void} | ||
| ### | ||
| addWidget: (widget) -> | ||
| if !widget instanceof gara.widgets.Widget | ||
| throw new TypeError('widget is not a gara.widgets.Widget'); | ||
|
|
||
| if !@widgets.contains(widget) | ||
| @widgets[@widgets.length] = widget; | ||
| widget.addDisposeListener(@disposeListener); | ||
| if widget instanceof gara.widgets.Control | ||
| gara.addEventListener(widget.handle, 'focusin', this) | ||
| gara.addEventListener(widget.handle, 'focus', this) | ||
| #gara.addEventListener(widget.handle, 'focusout', this) | ||
| gara.addEventListener(widget.handle, 'blur', this) | ||
|
|
||
|
|
||
| # | ||
| # if (widget.getParent() instanceof gara.widgets.Widget) { | ||
| # id = widget.getParent().getId(); | ||
| # } | ||
| # | ||
| # # html node | ||
| # else { | ||
| # if (widget.getParent().id) { | ||
| # id = widget.getParent().id; | ||
| # } else { | ||
| # id = gara.generateUID(); | ||
| # widget.getParent().id = id; | ||
| # } | ||
| # } | ||
| # | ||
| # | ||
| # if (!this.layers[id]) { | ||
| # this.layers[id] = []; | ||
| # } | ||
| # | ||
| # if (!this.layers[id].contains(widget)) { | ||
| # this.layers[id].push(widget); | ||
| # } | ||
|
|
||
| @shells[@shells.length] = widget if widget instanceof gara.widgets.Shell and !@shells.contains(widget) | ||
|
|
||
|
|
||
| getActiveShell: -> | ||
| @activeShell | ||
|
|
||
|
|
||
| ### | ||
| Returns a HTMLElement describes the area which is capable of displaying data. | ||
| The <body> element. | ||
| @returns {HTMLElement} | ||
| ### | ||
| getClientArea: -> | ||
| @clientArea | ||
|
|
||
|
|
||
| ### | ||
| @static | ||
| ### | ||
| @getDefault: -> | ||
| if !gara.widgets.Display.defaultDisplay? | ||
| gara.widgets.Display.defaultDisplay = new gara.widgets.Display() | ||
| gara.widgets.Display.defaultDisplay | ||
|
|
||
|
|
||
| ### | ||
| Returns the control which currently has keyboard focus, or null if | ||
| keyboard events are not currently going to any of the controls built by | ||
| the currently running application. | ||
| @returns {gara.widgets.Control} | ||
| ### | ||
| getFocusControl: -> | ||
| @focusControl | ||
|
|
||
| ### | ||
| Returns a (possibly empty) array containing the receiver's shells. | ||
| @description | ||
| Returns a (possibly empty) array containing the receiver's shells. Shells are returned | ||
| in the order that they are drawn. The topmost shell appears at the beginning of the array. | ||
| Subsequent shells draw beneath this shell and appear later in the array. | ||
| @returns {gara.widgets.Shell[]} an array of children | ||
| ### | ||
| getShells: -> | ||
| shells = [] | ||
| addShell = (shell) -> | ||
| shells[shells.length] = shell | ||
|
|
||
| @shells.forEach (shell) -> | ||
| if !shell.isDisposed() | ||
| z = if shell.handle.style.zIndex is '' then 0 else shell.handle.style.zIndex | ||
| layers[z] = [] if !layers[z] | ||
| layers[z][layers[z].length] = shell | ||
| max = Math.max(max, z) | ||
|
|
||
| for i in [max..0] | ||
| layers[i].forEach(addShell, this) if layers[i] | ||
|
|
||
|
|
||
|
|
||
| # for (i = max; i >= 0; i--) { | ||
| # if (layers[i]) { | ||
| # layers[i].forEach(addShell, this); | ||
| # } | ||
| # } | ||
|
|
||
| shells | ||
|
|
||
|
|
||
| ### | ||
| @private | ||
| ### | ||
| getSiblingControls: (control) -> | ||
| if control.getParent and control.getParent().getId | ||
| id = control.getParent().getId() | ||
| else if control.getParent().id | ||
| id = control.getParent().id | ||
|
|
||
| if @layers[id] | ||
| return @layers[id] | ||
|
|
||
| [] | ||
|
|
||
|
|
||
| ### | ||
| Internal event handler to pass keyboard events and focussing the active widget | ||
| @private | ||
| @param {Event} e the event | ||
| @returns {void} | ||
| ### | ||
| handleEvent: (e) -> | ||
|
|
||
|
|
||
| console.log 'Display.handleEvent ' + e.type + ' on ' + e.target + ', widget: ' + e.target.widget + ', control: ' + e.target.control | ||
|
|
||
| if e.target.widget? && e.target.widget instanceof gara.widgets.Widget | ||
| e.widget = e.target.widget | ||
| e.item = e.widget if e.widget instanceof gara.widgets.Item | ||
| control = e.widget if e.widget instanceof gara.widgets.Control | ||
| control = e.target.control if e.target.control? && !control? | ||
| e.control = control if control? | ||
|
|
||
| switch e.type | ||
| when 'focus' | ||
| if control? | ||
| success = true | ||
| layers = {} | ||
|
|
||
| if control is @focusControl | ||
| return | ||
|
|
||
| # get shell | ||
| shell = control.getShell() | ||
|
|
||
| # handle layers | ||
| # save layers | ||
| @widgets.forEach (widget) -> | ||
| layers[widget.handle.id] = widget.handle.style.zIndex | ||
|
|
||
| # move every layer in the control hierarchy from control to the shell on top | ||
| control.moveAbove(); | ||
| parent = control; | ||
| while shell isnt null and parent isnt shell and parent.getParent | ||
| parent.moveAbove() | ||
| parent = parent.getParent() | ||
|
|
||
| # if parent is a shell and cannot be activated -> exit | ||
| if shell instanceof gara.widgets.Shell and | ||
| !control.handle.dataset.garaSuppressFocusNotify and | ||
| !shell.setActive() | ||
| # restore layers, focus active shell and exit | ||
| for own id in layers | ||
| window.document.getElementById(id).style.zIndex = layers[id] | ||
|
|
||
| @activeShell.setFocus() | ||
| return false | ||
|
|
||
| # notifyFocusListener | ||
| @focusControl = control | ||
| if !control.handle.dataset.garaSuppressFocusNotify | ||
| notifyResult = control.notifyFocusListener('focusGained') | ||
| success = success and | ||
| if control.handle.dataset.garaForcefocus then true else notifyResult | ||
|
|
||
| # remove obsolete data-gara-* attributes | ||
| control.handle.dataset.garaSuppressFocusNotify = null | ||
| control.handle.dataset.garaForcefocus = null | ||
|
|
||
| # restore layers, if something wasn't allowed | ||
| if !success | ||
| for own id in layers | ||
| gara.global.document.getElementById(id).style.zIndex = layers[id] | ||
|
|
||
| @focusControl = null | ||
| control.handle.dataset.garaSuppressBlurNotify = true | ||
| control.handle.blur() | ||
|
|
||
| when 'blur' | ||
| if control? and !e.target.dataset.garaSuppressBlurNotify | ||
| if e.widget.notifyFocusListener('focusLost') | ||
| @focusControl = null | ||
| else | ||
| # workaround for re-focus | ||
| # bug in FF, see: https://bugzilla.mozilla.org/show_bug.cgi?id=53579 | ||
| e.target.dataset.garaSuppressFocusNotify = true | ||
| window.setTimeout (-> | ||
| e.target.focus() | ||
| ), 0 | ||
|
|
||
| e.target.dataset.garaSuppressBlurNotify = null | ||
|
|
||
|
|
||
| if control? || (@focusControl isnt null && e.type of ['keydown', 'keyup']) | ||
| e.control ||= @focusControl | ||
| e.control.dispatchEvent(e) | ||
|
|
||
| if e.item? and e.item.isListening(e.type) | ||
| e.item.dispatchEvent(e) | ||
|
|
||
| #e.stopPropagation() | ||
|
|
||
| if e.type is 'contextmenu' | ||
| e.preventDefault() | ||
|
|
||
|
|
||
| ### | ||
| Removes a widget from the Dialog. The Dialog removes the | ||
| previous registered when added with addWidget. | ||
| @private | ||
| @param {gara.widgets.Widget} widget the widget | ||
| @returns {void} | ||
| ### | ||
| removeWidget: (widget) -> | ||
| if !widget instanceof gara.widgets.Widget | ||
| throw new TypeError('widget is not a gara.widgets.Widget'); | ||
|
|
||
| if @widgets.contains(widget) | ||
| @focusControl = null if @focusControl is widget | ||
| widget.removeDisposeListener(@disposeListener) | ||
|
|
||
| if widget instanceof gara.widgets.Control | ||
| # widget.removeListener('focus', this) | ||
| # widget.removeListener('blur', this) | ||
| gara.removeEventListener(widget.handle, 'focus', this) | ||
| gara.removeEventListener(widget.handle, 'blur', this) | ||
|
|
||
| @shells.remove(widget) if widget instanceof gara.widgets.Shell | ||
|
|
||
| @widgets.remove(widget) | ||
|
|
||
|
|
||
| ### | ||
| @private | ||
| @param {gara.widgets.Shell} shell | ||
| @returns {void} | ||
| ### | ||
| setActiveShell: (shell) -> | ||
| if shell isnt null and !shell instanceof gara.widgets.Shell | ||
| throw new TypeError('shell is not a gara.widgets.Shell') | ||
|
|
||
| @activeShell = shell | ||
|
|
||
| ### | ||
| @private | ||
| @param {gara.widgets.Control} control | ||
| @returns {void} | ||
| ### | ||
| setFocusControl: (control) -> | ||
| if control isnt null and !control instanceof gara.widgets.Control | ||
| throw new TypeError('shell is not a gara.widgets.Control') | ||
|
|
||
| @focusControl = control | ||
|
|
||
| toString: -> | ||
| '[gara.widgets.Display]' | ||
|
|
||
| gara.namespace('gara.widgets') | ||
| gara.widgets.Display = Display | ||
| exports.Display = Display |
| @@ -0,0 +1,141 @@ | ||
| ### | ||
| gara - Javascript Toolkit | ||
| Copyright (c) 2007 Thomas Gossmann | ||
| Homepage: | ||
| http:#garajs.org | ||
| This library is free software; you can redistribute it and/or | ||
| modify it under the terms of the GNU Lesser General Public | ||
| License as published by the Free Software Foundation; either | ||
| version 2.1 of the License, or (at your option) any later version. | ||
| This library is distributed in the hope that it will be useful, | ||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| Lesser General Public License for more details. | ||
| ### | ||
|
|
||
| define 'gara/widgets/Item', ['require', 'exports', 'gara/widgets/Widget'], (require, exports) -> | ||
|
|
||
| Widget = require('gara/widgets/Widget') | ||
|
|
||
| class Item extends Widget | ||
| ### | ||
| 'Abstract' Item class | ||
| @class gara.widgets.Item | ||
| @extends gara.widgets.Widget | ||
| ### | ||
|
|
||
|
|
||
| # ### | ||
| # Holds the active state. | ||
| # | ||
| # @private | ||
| # ### | ||
| # active: false | ||
| # | ||
| # ### | ||
| # The <code>Item</code>'s image. | ||
| # | ||
| # @private | ||
| # ### | ||
| # image: null | ||
| # | ||
| # ### | ||
| # | ||
| # The <code>Item</code>'s text. | ||
| # | ||
| # @private | ||
| # ### | ||
| # text: "" | ||
|
|
||
| constructor: (parent, config) -> | ||
| ### | ||
| Creates a new Item. | ||
| @constructs | ||
| @extends gara.widgets.Widget | ||
| @param {gara.widgets.List} parent the parent <code>Control</code> widget | ||
| @param {int} style information for this <code>Item</code> | ||
| ### | ||
|
|
||
| @active = false | ||
|
|
||
| #parse config | ||
| @config.image = config.image || null if !@config.image? | ||
| @config.text = config.text || "" if !@config.text? | ||
|
|
||
| super(parent, config) | ||
|
|
||
|
|
||
| destroyWidget: -> | ||
| @config.image = null | ||
| @config.text = null | ||
|
|
||
| # if (@parentNode !== null) { | ||
| # @parentNode.removeChild(@handle); | ||
| # } | ||
| super | ||
|
|
||
|
|
||
| getImage: -> | ||
| ### | ||
| Returns the items image. | ||
| @author Thomas Gossmann | ||
| @return {Image} the items image | ||
| ### | ||
| @config.image | ||
|
|
||
|
|
||
| getText: -> | ||
| ### | ||
| Returns the items text. | ||
| @return {String} the text for this item | ||
| ### | ||
| @config.text | ||
|
|
||
|
|
||
| setActive: (@active) -> | ||
| ### | ||
| Sets the item active state. | ||
| @private | ||
| @param {boolean} active <code>true</code> for active and <code>false</code> for inactive | ||
| @returns {gara.widgets.Item} this | ||
| ### | ||
| @setClass("gara-item-active", @active) | ||
| this | ||
|
|
||
|
|
||
| setImage: (image) -> | ||
| ### | ||
| Sets the image for the item. | ||
| @param {Image} image the new image | ||
| @returns {gara.widgets.Item} this | ||
| ### | ||
| @config.image = image | ||
| this | ||
|
|
||
|
|
||
| setText: (text) -> | ||
| ### | ||
| Sets the text for the item. | ||
| @param {String} text the new text | ||
| @returns {gara.widgets.Item} this | ||
| ### | ||
| @config.text = text | ||
| this | ||
|
|
||
|
|
||
| toString: -> | ||
| return '[gara.widgets.Item]' | ||
|
|
||
| gara.namespace('gara.widgets') | ||
| gara.widgets.Item = Item | ||
| exports.Item = Item |
| @@ -0,0 +1,188 @@ | ||
| ### | ||
| gara - Javascript Toolkit | ||
| Copyright (c) 2007 Thomas Gossmann | ||
| Homepage: | ||
| http:#garajs.org | ||
| This library is free software you can redistribute it and/or | ||
| modify it under the terms of the GNU Lesser General Public | ||
| License as published by the Free Software Foundation either | ||
| version 2.1 of the License, or (at your option) any later version. | ||
| This library is distributed in the hope that it will be useful, | ||
| but WITHOUT ANY WARRANTY without even the implied warranty of | ||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| Lesser General Public License for more details. | ||
| ### | ||
|
|
||
|
|
||
| define 'gara/widgets/ListItem', | ||
| ['require', 'exports', 'gara/widgets/Item', 'gara/widgets/List', 'gara/widgets/CheckboxItem', 'gara/widgets/SelectItem'], | ||
| (require, exports) -> | ||
|
|
||
| Item = require('gara/widgets/Item') | ||
| CheckboxItem = require('gara/widgets/CheckboxItem') | ||
| SelectItem = require('gara/widgets/SelectItem') | ||
|
|
||
| class ListItem extends Item | ||
| ### | ||
| gara ListItem for List Widget | ||
| @class gara.widgets.ListItem | ||
| @extends gara.widgets.Item | ||
| ### | ||
|
|
||
| gara.mixin @, CheckboxItem, SelectItem | ||
|
|
||
| # HTML Node Reference | ||
| # | ||
| # @span - holds the span for the text | ||
| # @text - holds the text | ||
| # @image - holds the image | ||
|
|
||
| constructor: (parent, config = {}, index) -> | ||
| ### | ||
| Creates a new ListItem | ||
| @constructs | ||
| @extends gara.widgets.Item | ||
| @param {gara.widgets.List} parent the List Widget for this item | ||
| @param {int} style the style for this item | ||
| @param {int} index index to insert the item at | ||
| @throws {TypeError} if the list is not a List widget | ||
| ### | ||
| if !parent instanceof gara.widgets.List | ||
| throw new TypeError("parent is not type of gara.widgets.List") | ||
|
|
||
| # parse config | ||
| @config = {} | ||
|
|
||
| # init mixins | ||
| @initCheckbox(config) | ||
| @initSelect(config) | ||
|
|
||
| super(parent, config) | ||
|
|
||
| @parentNode = @parent.addItem(this, index) | ||
| @createWidget() | ||
|
|
||
|
|
||
| createWidget: -> | ||
| ### | ||
| Internal creation process of this item | ||
| @private | ||
| @returns {void} | ||
| ### | ||
|
|
||
| # handle | ||
| @handle = gara.global.document.createElement("li") | ||
| @handle.widget = this | ||
| @handle.control = @parent | ||
| @handle.setAttribute("id", @getId()) | ||
| @handle.setAttribute("role", "option") | ||
| @handle.setAttribute("aria-selected", @selected) | ||
| @handle.setAttribute("aria-labelledby", @getId()+"-label") | ||
|
|
||
| # checkbox | ||
| @createCheckbox() if @parent.getConfig().check | ||
|
|
||
| # create image node | ||
| @image = window.document.createElement("img") | ||
| @image.id = @getId() + "-image" | ||
| @image.className = "gara-list-item-image gara-item-image" | ||
| @image.widget = this | ||
| @image.control = @parent | ||
| @image.setAttribute("role", "presentation") | ||
|
|
||
| # set image | ||
| if @config.image isnt null | ||
| @image.src = @config.image.src | ||
| else | ||
| @image.style.display = "none" | ||
|
|
||
| @text = window.document.createTextNode(@config.text) | ||
| @span = window.document.createElement("span") | ||
| @span.id = @getId()+"-label" | ||
| @span.className = "gara-list-item-text gara-item-text" | ||
| @span.widget = this | ||
| @span.control = @parent | ||
| @span.appendChild(@text) | ||
| @span.setAttribute("role", "presentation") | ||
|
|
||
| @handle.appendChild(@image) | ||
| @handle.appendChild(@span) | ||
|
|
||
| # CSS | ||
| @addClass("gara-list-item") | ||
|
|
||
| # append to dom | ||
| items = @parent.getItems() | ||
| index = items.indexOf(this) | ||
|
|
||
| if index is items.length - 1 | ||
| @parentNode.appendChild(@handle) | ||
| else | ||
| nextNode = if index is 0 then @parentNode.firstChild else items[index - 1].handle.nextSibling | ||
| @parentNode.insertBefore(@handle, nextNode) | ||
|
|
||
|
|
||
| destroyWidget: -> | ||
| ### | ||
| Destroys the <code>ListItem</code> | ||
| @private | ||
| @returns {void} | ||
| ### | ||
| @parent.releaseItem(this) | ||
|
|
||
| @image = null | ||
| @span = null | ||
| @text = null | ||
|
|
||
| super | ||
|
|
||
|
|
||
| setImage: (image) -> | ||
| ### | ||
| Sets the receiver's image. | ||
| @param {Image} image the new image | ||
| @returns {gara.widgets.ListItem} this | ||
| ### | ||
| super(image) | ||
|
|
||
| # update image | ||
| if image isnt null | ||
| @image.src = image.src | ||
| @image.style.display = "" | ||
|
|
||
| # hide image | ||
| else | ||
| @image.src = "" | ||
| @image.style.display = "none" | ||
|
|
||
| this | ||
|
|
||
|
|
||
| setText: (text) -> | ||
| ### | ||
| Sets the receiver's text. | ||
| @param {String} text the new text | ||
| @returns {gara.widgets.ListItem} this | ||
| ### | ||
| super(text) | ||
| @text.nodeValue = text | ||
| this | ||
|
|
||
|
|
||
| toString: -> | ||
| return '[gara.widgets.ListItem]' | ||
|
|
||
|
|
||
| gara.namespace('gara.widgets') | ||
| gara.widgets.ListItem = ListItem | ||
| exports.ListItem = ListItem |
| @@ -0,0 +1,72 @@ | ||
| ### | ||
| gara - Javascript Toolkit | ||
| Copyright (c) 2007 Thomas Gossmann | ||
| Homepage: | ||
| http:#garajs.org | ||
| This library is free software; you can redistribute it and/or | ||
| modify it under the terms of the GNU Lesser General Public | ||
| License as published by the Free Software Foundation; either | ||
| version 2.1 of the License, or (at your option) any later version. | ||
| This library is distributed in the hope that it will be useful, | ||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| Lesser General Public License for more details. | ||
| ### | ||
|
|
||
| define 'gara/widgets/Scrollable', ['require', 'exports', 'gara/widgets/Control'], (require, exports) -> | ||
|
|
||
| #gara.use("gara.widgets.Composite"); | ||
|
|
||
| Control = require 'gara/widgets/Control' | ||
|
|
||
| class Scrollable extends Control | ||
|
|
||
| constructor: (parent, config) -> | ||
| super(parent, config) | ||
| parent.layout() if parent instanceof gara.widgets.Composite | ||
|
|
||
|
|
||
| getClientArea: -> | ||
| ### | ||
| Returns the receiver's client area. | ||
| @returns {HTMLElement} the scrolled HTMLElement | ||
| ### | ||
| @scrolledHandle() | ||
|
|
||
|
|
||
| getHorizontalScrollbar: -> | ||
| ### | ||
| Returns true when the receiver has a horizontal scrollbar, false otherwise | ||
| @returns {boolean} true wether there is a horizontal scrollbar otherwise false | ||
| ### | ||
| @scrolledHandle().clientWidth < @scrolledHandle().scrollWidth and @scrolledHandle().style.overflowX isnt "hidden" | ||
|
|
||
|
|
||
| getVerticalScrollbar: -> | ||
| ### | ||
| Returns true when the receiver has a vertical scrollbar, false otherwise | ||
| @returns {boolean} true wether there is a vertical scrollbar otherwise false | ||
| ### | ||
| @scrolledHandle().clientHeight < @scrolledHandle().scrollHeight and @scrolledHandle().style.overflowY isnt "hidden" | ||
|
|
||
|
|
||
| scrolledHandle: -> | ||
| ### | ||
| Returns the scrolled handle of the receiver | ||
| @private | ||
| @returns {HTMLElement} | ||
| ### | ||
| @handle | ||
|
|
||
|
|
||
| gara.namespace('gara.widgets') | ||
| gara.widgets.Scrollable = Scrollable | ||
| exports.Scrollable = Scrollable |
| @@ -0,0 +1,53 @@ | ||
| ### | ||
| gara - Javascript Toolkit | ||
| Copyright (c) 2007 Thomas Gossmann | ||
| Homepage: | ||
| http://garajs.org | ||
| This library is free software you can redistribute it and/or | ||
| modify it under the terms of the GNU Lesser General Public | ||
| License as published by the Free Software Foundation either | ||
| version 2.1 of the License, or (at your option) any later version. | ||
| This library is distributed in the hope that it will be useful, | ||
| but WITHOUT ANY WARRANTY without even the implied warranty of | ||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| Lesser General Public License for more details. | ||
| ### | ||
|
|
||
|
|
||
| define 'gara/widgets/SelectItem', ['require', 'exports'], (require, exports) -> | ||
|
|
||
| class SelectItem | ||
| ### | ||
| A trait for checkbox items | ||
| @require checkWidget | ||
| @require handle | ||
| @require config | ||
| @class gara.widgets.ListItem | ||
| @extends gara.widgets.Item | ||
| ### | ||
|
|
||
| initSelect: (config) -> | ||
| @selected = false | ||
|
|
||
|
|
||
| setSelected: (selected) -> | ||
| ### | ||
| Sets the receiver's selected state. | ||
| @private | ||
| @param {boolean} selected <code>true</code> for selected and <code>false</code> otherwise | ||
| ### | ||
| @checkWidget() | ||
| @selected = selected | ||
| @handle.setAttribute('aria-selected', selected) | ||
| this | ||
|
|
||
|
|
||
| gara.namespace('gara.widgets') | ||
| gara.widgets.SelectItem = SelectItem | ||
| exports.SelectItem = SelectItem |