diff --git a/build/js/ox.js b/build/js/ox.js index 28be12e6..d5f49a53 100644 --- a/build/js/ox.js +++ b/build/js/ox.js @@ -177,6 +177,8 @@ Ox.equals = function(obj0, obj1) { } else if (Ox.isObject(obj0)) { ret = Ox.equals(Ox.keys(obj0), Ox.keys(obj1)) && Ox.equals(Ox.values(obj0), Ox.values(obj1)); + } else if (Ox.isFunction(obj0)) { + ret = obj0.toString() == obj1.toString(); } } Ox.print('Ox.equals', obj0, obj1, ret) @@ -1727,7 +1729,7 @@ Ox.toTitleCase = function(str) { >>> Ox.toTitleCase("Apple releases iPhone, IBM stock plummets") "Apple Releases iPhone, IBM Stock Plummets" */ - return $.map(str.split(" "), function(v) { + return $.map(str.split(' '), function(v) { var sub = v.substr(1), low = sub.toLowerCase(); if (sub == low) { diff --git a/build/js/ox.load.js b/build/js/ox.load.js index dc721feb..43c05b53 100644 --- a/build/js/ox.load.js +++ b/build/js/ox.load.js @@ -30,7 +30,7 @@ $(function() { 'Chrome': 'http://www.google.com/chrome/', 'Firefox': 'http://www.mozilla.org/firefox/', 'Internet Explorer': '', - 'Opera': '', + 'Opera': 'http://www.opera.com/', 'Safari': 'http://www.apple.com/safari/' }; diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js index 56d38d41..d70004ba 100644 --- a/build/js/ox.ui.js +++ b/build/js/ox.ui.js @@ -103,7 +103,7 @@ requires $elements = {}, $window, $document, $body; - //_$elements = $elements; + _$elements = $elements; $(function() { $window = $(window), @@ -151,6 +151,7 @@ requires function getUserData() { //return {}; + return {}; return { navigator: { cookieEnabled: navigator.cookieEnabled, @@ -208,7 +209,7 @@ requires that.launch = function(callback) { var time = +new Date(), userAgent = getUserAgent(), - userAgents = ['Chrome', 'Firefox', 'Safari']; + userAgents = ['Chrome', 'Firefox', 'Opera', 'Safari']; $.ajaxSetup({ timeout: self.options.apiTimeout, type: self.options.apiType, @@ -623,7 +624,7 @@ requires buffer += key == 'SPACE' ? ' ' : key; bufferTime = time; } - focused && $elements[focused].trigger('ox_key_' + key); + focused && $elements[focused].triggerEvent('key_' + key); //return false; /* $.each(stack, function(i, v) { @@ -741,12 +742,21 @@ requires try { data = JSON.parse(request.responseText); } catch (err) { - data = { - status: { - code: request ? request.status : '0', - text: request ? request.statusText : 'Unknown Error' - } - }; + try { + data = { + status: { + code: request.status, + text: request.statusText + } + }; + } catch (err) { + data = { + status: { + code: '500', + text: 'Unknown Error' + } + }; + } } } if (data.status.code < 500) { @@ -884,27 +894,29 @@ requires return function(options, self) { // construct - options = options || {}; self = self || {}; + self.options = options || {}; + if (!self.$eventHandler) { + self.$eventHandler = $('
'); + } var that = this; // init (function() { - // allow for Ox.Widget('tagname', self) - if (typeof options == 'string') { - options = { - element: options + // allow for Ox.Element('tagname', self) + if (typeof self.options == 'string') { + self.options = { + element: self.options }; } that.ox = Ox.version; that.id = Ox.uid(); - that.$element = $('<' + (options.element || 'div') + '/>', { + that.$element = $('<' + (self.options.element || 'div') + '/>', { data: { ox: that.id } }); $elements[that.id] = that; - self.$eventHandler = $('
'); wrapjQuery(); })(); @@ -1027,24 +1039,25 @@ requires returns that */ var args, - id = self.options && self.options.id, length = arguments.length, oldOptions, ret; if (length == 0) { // options() - ret = self.options || options; // this is silly. make sure self.options get populated with options + ret = self.options; } else if (length == 1 && typeof arguments[0] == 'string') { // options(str) ret = self.options ? self.options[arguments[0]] : options[arguments[0]]; } else { // options (str, val) or options({str: val, ...}) // translate (str, val) to ({str: val}) - args = Ox.makeObject.apply(that, arguments); + args = Ox.makeObject.apply(that, arguments || {}); oldOptions = $.extend({}, self.options); // if options have not been set, extend defaults, // otherwise, extend options - self.options = $.extend(self.options || self.defaults, args); + //self.options = $.extend(self.options, self.options ? {} : self.defaults, args); + self.options = $.extend({}, self.defaults, self.options, args); + //self.options = $.extend(self.options || self.defaults, args); $.each(args, function(key, value) { // key == 'id' && id && Ox.Event.changeId(id, value); /*!Ox.equals(value, oldOptions[key]) &&*/ self.onChange(key, value); @@ -1057,7 +1070,7 @@ requires that.remove = function() { // fixme: clashes with jquery, should be removeElement //self.options && Ox.Event.unbind(self.options.id); // there are optionless elements, like the dialog layer //that.loseFocus(); - delete self.$eventHandler; + //delete self.$eventHandler; that.$element.remove(); delete $elements[that.ox]; return that; @@ -1074,7 +1087,7 @@ requires self.$eventHandler.trigger('ox_' + event, data); }); } else { - Ox.print(that.id, self.options ? self.options.id : '', 'trigger', arguments[0], arguments[1] || {}); + Ox.print('??', that.id, self.options ? self.options.id : '', 'trigger', arguments[0], arguments[1] || {}); self.$eventHandler.trigger('ox_' + arguments[0], arguments[1] || {}); } return that; @@ -5762,8 +5775,11 @@ requires id: '', item: function() {}, keys: [], + max: -1, + min: 0, orientation: 'both', request: function() {}, + selected: [], size: 128, sort: [], }) @@ -5782,12 +5798,15 @@ requires keys: self.options.keys, orientation: self.options.orientation, keys: self.options.keys, + max: self.options.max, + min: self.options.min, request: self.options.request, + selected: self.options.selected, size: self.options.size, sort: self.options.sort, type: 'icon', unique: self.options.unique - }/*, self*/) + }, $.extend({}, self)) // pass event handler .addClass('OxIconList Ox' + Ox.toTitleCase(self.options.orientation)) .click(click) .dblclick(dblclick) @@ -5867,9 +5886,9 @@ requires .options(options || {}) $.extend(self, { - fontSize: self.options.size == 64 ? 7 : 9, + fontSize: self.options.size == 64 ? 6 : 9, height: self.options.size * 1.5, - lineLength: self.options.size == 64 ? 17 : 23, + lineLength: self.options.size == 64 ? 15 : 23, lines: self.options.size == 64 ? 4 : 5, url: oxui.path + '/png/ox.ui/transparent.png', width: self.options.size @@ -5884,7 +5903,7 @@ requires that.$icon = $('
') .addClass('OxIcon') .css({ - top: self.options.size == 64 ? -72 : -124, + top: self.options.size == 64 ? -64 : -124, width: (self.options.size + 4) + 'px', height: (self.options.size + 4) + 'px' }); @@ -5906,7 +5925,7 @@ requires .css({ top: (self.options.size / 2) + 'px', width: (self.options.size + 4) + 'px', - height: (self.options.size == 64 ? 38 : 58) + 'px' + height: (self.options.size == 64 ? 30 : 58) + 'px' }) that.$text = $('
') .addClass('OxTarget') @@ -6013,9 +6032,12 @@ requires itemHeight: 16, itemWidth: 16, keys: [], + max: -1, + min: 0, orientation: 'vertical', pageLength: 100, request: function() {}, // (data, callback), without data returns {items, size etc.} + selected: [], sort: [], type: 'text', unique: '' @@ -6032,9 +6054,6 @@ requires ids: {}, itemMargin: self.options.type == 'text' ? 0 : 8, // 2 x 4 px margin ... fixme: the 2x should be computed later keyboardEvents: { - key_alt_control_a: invertSelection, - key_control_a: selectAll, - key_control_shift_a: selectNone, key_end: scrollToFirst, key_enter: open, key_home: scrollToLast, @@ -6050,23 +6069,41 @@ requires scrollTimeout: 0, selected: [] }); + if (self.options.max == -1) { + $.extend(self.keyboardEvents, { + key_alt_control_a: invertSelection, + key_control_a: selectAll + }); + } + if (self.options.min == 0) { + $.extend(self.keyboardEvents, { + key_control_shift_a: selectNone + }); + } self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'up' : 'left')] = selectPrevious; self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'down' : 'right')] = selectNext; - self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'shift_up' : 'shift_left')] = addPreviousToSelection; - self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'shift_down' : 'shift_right')] = addNextToSelection; + if (self.options.max == -1) { + self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'shift_up' : 'shift_left')] = addPreviousToSelection; + self.keyboardEvents['key_' + (self.options.orientation == 'vertical' ? 'shift_down' : 'shift_right')] = addNextToSelection; + } if (self.options.orientation == 'both') { $.extend(self.keyboardEvents, { key_down: selectBelow, - key_up: selectAbove, - key_shift_down: addBelowToSelection, - key_shift_up: addAboveToSelection + key_up: selectAbove }); + if (self.options.max == -1) { + $.extend(self.keyboardEvents, { + key_shift_down: addBelowToSelection, + key_shift_up: addAboveToSelection + }); + } self.pageLengthByRowLength = [ 0, 60, 60, 60, 60, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68, 72, 76, 60 ]; } updateQuery(); + self.options.selected.length && getPositions(self.options.selected); Ox.print('s.o', self.options) that.bindEvent(self.keyboardEvents); $window.resize(that.size); @@ -6252,8 +6289,10 @@ requires return that.height() - (that.$content.width() > that.width() ? oxui.scrollbarSize : 0); } - function getListHeight() { - return Math.ceil(self.listLength * (self.options.itemHeight + self.itemMargin) / self.rowLength); // fixme: should be listSize + function getListSize() { + return Math.ceil(self.listLength * + (self.options[self.options.orientation == 'horizontal' ? + 'itemWidth' : 'itemHeight'] + self.itemMargin) / self.rowLength); } function getNext() { @@ -6293,22 +6332,21 @@ requires ) * self.rowLength; } - function getPositions() { - Ox.print('getPositions', $.map(self.selected, function(v, i) { - return self.ids[v]; - })); + function getPositions(ids) { + ids = ids || getSelectedIds(); // fixme: optimize: send non-selected ids if more than half of the items are selected - if (self.selected.length /*&& self.selected.length < self.listLength*/) { - Ox.print('-- request', { - ids: $.map(self.selected, function(v, i) { - return self.ids[v]; - }), + if (ids.length /*&& ids.length < self.listLength*/) { + alert('getPositions ' + JSON.stringify(ids) ) + Ox.print('-------- request', { + ids: ids, sort: self.options.sort }); + alert(JSON.stringify({ + ids: ids, + sort: self.options.sort + })) self.requests.push(self.options.request({ - ids: $.map(self.selected, function(v, i) { - return self.ids[v]; - }), + ids: ids, sort: self.options.sort }, getPositionsCallback)); } else { @@ -6320,6 +6358,7 @@ requires Ox.print('getPositionsCallback', result) var pos = 0; if (result) { + alert('getPositionsCallback ' + JSON.stringify(result)) $.extend(self, { ids: {}, selected: [] @@ -6398,15 +6437,19 @@ requires range: range, sort: self.options.sort }, function(result) { - self.$pages[page] = new Ox.ListPage() - .css({ - width: self.pageWidth + 'px' - }); + self.$pages[page] = new Ox.ListPage(); if (self.options.orientation == 'horizontal') { - + self.$pages[page].css({ + left: (page * self.pageWidth + self.listMargin / 2) + 'px', + top: (self.listMargin / 2) + 'px', + width: (page < self.pages - 1 ? self.pageWidth : + self.listLength % self.pageLength * + (self.options.itemWidth + self.itemMargin)) + 'px' + }); } else { self.$pages[page].css({ - top: (page * self.pageHeight + self.listMargin / 2) + 'px' + top: (page * self.pageHeight + self.listMargin / 2) + 'px', + width: self.pageWidth + 'px' }); } $.each(result.data.items, function(i, v) { @@ -6459,13 +6502,13 @@ requires if (!self.clickTimeout) { // click pos = $item.data('position'); - if (e.metaKey) { + if (e.metaKey && self.options.max == -1) { if (!isSelected(pos)) { addToSelection(pos); } else { deselectTimeout = true; } - } else if (e.shiftKey) { + } else if (e.shiftKey && self.options.max == -1) { addAllToSelection(pos); } else if (!isSelected(pos)) { select(pos); @@ -6486,7 +6529,7 @@ requires self.clickTimeout = 0; open(); } - } else { + } else if (self.options.min == 0) { selectNone(); } } @@ -6549,12 +6592,22 @@ requires } function scrollTo(value) { - that.animate({ - scrollTop: (self.listHeight * value) + 'px' - }, 0) + that.animate(self.options.orientation == 'horizontal' ? { + scrollLeft: (self.listSize * value) + 'px' + } : { + scrollTop: (self.listSize * value) + 'px' + }, 0); } - function scrollToPosition(pos, topAlign) { + function scrollToFirst() { + that[self.options.orientation == 'horizontal' ? 'scrollLeft' : 'scrollTop'](0); + } + + function scrollToLast() { + that[self.options.orientation == 'horizontal' ? 'scrollLeft' : 'scrollTop'](self.listSize); + } + + function scrollToPosition(pos, leftOrTopAlign) { var itemHeight = self.options.itemHeight + self.itemMargin, itemWidth = self.options.itemWidth + self.itemMargin, positions = [], @@ -6562,15 +6615,24 @@ requires size; if (self.options.orientation == 'horizontal') { positions[0] = pos * itemWidth; - positions[1] = positions[0] + itemWidth; + positions[1] = positions[0] + itemWidth + self.itemMargin; scroll = that.scrollLeft(); size = getWidth(); + if (positions[0] < scroll || leftOrTopAlign) { + that.animate({ + scrollLeft: positions[0] + 'px' + }, 0); + } else if (positions[1] > scroll + size) { + that.animate({ + scrollLeft: (positions[1] - size) + 'px' + }, 0); + } } else { positions[0] = (self.options.orientation == 'vertical' ? pos : getRow(pos)) * itemHeight; positions[1] = positions[0] + itemHeight + (self.options.orientation == 'vertical' ? 0 : self.itemMargin); scroll = that.scrollTop(); size = getHeight(); - if (positions[0] < scroll || topAlign) { + if (positions[0] < scroll || leftOrTopAlign) { that.animate({ scrollTop: positions[0] + 'px' }, 0); @@ -6582,14 +6644,6 @@ requires } } - function scrollToFirst() { - that.scrollTop(0); - } - - function scrollToLast() { - that.scrollTop(self.listHeight); - } - function select(pos) { if (!isSelected(pos) || self.selected.length > 1) { selectNone(); @@ -6710,15 +6764,18 @@ requires listLength: result.data.items, pages: Math.ceil(result.data.items / self.pageLength), pageWidth: self.options.orientation == 'vertical' ? 0 : - (self.options.itemWidth + self.itemMargin) * self.rowLength, + (self.options.itemWidth + self.itemMargin) * + (self.options.orientation == 'horizontal' ? + self.pageLength : self.rowLength), pageHeight: self.options.orientation == 'horizontal' ? 0 : - Math.ceil(self.pageLength * (self.options.itemHeight + self.itemMargin) / self.rowLength) - }); - self.listHeight = getListHeight(); - Ox.print('list self', self, self.listHeight); - that.$content.css({ - height: self.listHeight + 'px' + Math.ceil(self.pageLength * (self.options.itemHeight + + self.itemMargin) / self.rowLength) }); + self.listSize = getListSize(); + that.$content.css( + self.options.orientation == 'horizontal' ? 'width' : 'height', + self.listSize + 'px' + ); getPositions(); })); } @@ -6728,13 +6785,13 @@ requires clear(); self.pageLength = self.pageLengthByRowLength[self.rowLength] $.extend(self, { - listHeight: getListHeight(), // fixme: should be listSize + listSize: getListSize(), pages: Math.ceil(self.listLength / self.pageLength), pageWidth: (self.options.itemWidth + self.itemMargin) * self.rowLength, pageHeight: getPageHeight() }); that.$content.css({ - height: self.listHeight + 'px' + height: self.listSize + 'px' }); self.page = getPageByPosition(pos); //that.scrollTop(0); @@ -6782,7 +6839,7 @@ requires var rowLength = getRowLength(), pageLength = self.pageLengthByRowLength[rowLength], pos = getPosition(), - scroll = that.scrollTop() / self.listHeight; + scroll = that.scrollTop() / self.listSize; if (pageLength != self.pageLength) { self.pageLength = pageLength; self.rowLength = rowLength; @@ -6790,7 +6847,7 @@ requires } else if (rowLength != self.rowLength) { self.rowLength = rowLength; self.pageWidth = (self.options.itemWidth + self.itemMargin) * self.rowLength; // fixme: make function - self.listHeight = getListHeight(); + self.listSize = getListSize(); self.pageHeight = getPageHeight(); $.each(self.$pages, function(i, $page) { !Ox.isUndefined($page) && $page.css({ @@ -6799,7 +6856,7 @@ requires }); }); that.$content.css({ - height: self.listHeight + 'px' + height: self.listSize + 'px' }); Ox.print('scrolling to', scroll) scrollTo(scroll); @@ -6872,6 +6929,9 @@ requires columnsResizable: false, columnWidth: [40, 800], id: '', + max: -1, + min: 0, + selected: [], request: function() {}, // {sort, range, keys, callback} sort: [] }) @@ -6948,12 +7008,15 @@ requires keys: $.map(self.visibleColumns, function(v, i) { return v.id; }), + max: self.options.max, + min: self.options.min, orientation: 'vertical', request: self.options.request, + selected: self.options.selected, sort: self.options.sort, type: 'text', unique: self.unique - }) + }, $.extend({}, self)) // pass event handler .addClass('OxBody') .scroll(function() { var scrollLeft = $(this).scrollLeft();