1/** 2 * Class for the Dialogs 3 */ 4Dialog = new Class({ 5 Implements: [Events, Options] 6 , container: null 7 , waitOverlay: null 8 , containerSize: null 9 , tween: null 10 , apiEventRequest: null 11 , eventStack: [] 12 , clickIsInProgress: false 13 14 , options: { 15 useApiEvents: false 16 , apiUrl: null 17 , apiEventRequestParams: {} 18 } 19 20 , initialize: function (container, options) { 21 this.container = document.id(container); 22 this.container.removeClass('hideWhileWaiting'); 23 this.waitOverlay = document.id('waitingOverlay'); 24 this.waitOverlay.addClass('hide'); 25 this.setOptions(options); 26 this.addEvent('close', this.close.bind(this)); 27 } 28 29 , _initApiEvent: function () { 30 if (!this.options.useApiEvents) { 31 return; 32 } 33 this.apiEventRequest = new gm_Request({ 34 url: '/' + languagePath + '/api/' + this.options.apiUrl + '/' 35 , onStatusOkay: this._apiEventCompletes.bind(this) 36 , onStatusWarning: function () { 37 } 38 , onAnyError: this.fireEvent.pass('close', this) 39 , onRequest: this._showWaitOverlay.bind(this) 40 }); 41 } 42 43 /** 44 * Shows the wait/load indicator overlay. 45 */ 46 , _showWaitOverlay: function () { 47 // send the dialog behind the shade overlay 48 this.container.addClass('hideWhileWaiting'); 49 // show the waiting indicator and center it 50 this.waitOverlay.removeClass('hide'); 51 new gm_CenterElement(this.waitOverlay); 52 } 53 54 , _initButtons: function () { 55 this.container.getElements('*').each(function (element) { 56 if (!this._getElementHasEvents(element)) { 57 return; 58 } 59 // element.removeEvents( 'click' ); 60 61 element.addEvent('click', function (e) { 62 e.stop(); 63 this._handleClickEvent(e, element); 64 }.bind(this)); 65 }.bind(this)); 66 } 67 68 /** 69 * Returns if given element has events defined 70 */ 71 , _getElementHasEvents: function (element) { 72 return this._getEventsByElement(element).length > 0; 73 } 74 75 /** 76 * Returns the events defined for given element 77 */ 78 , _getEventsByElement: function (element) { 79 var classes = element.get('class'); 80 if (classes) { 81 var events = classes.clean().split(' ').filter(function (c) { 82 return c.test('^event:[a-z0-9]+$', 'i'); 83 }); 84 events.each(function (event, i, events) { 85 events[i] = event.split(':')[1]; 86 }); 87 return events; 88 } else { 89 return []; 90 } 91 } 92 93 /** 94 * Handles the click event 95 */ 96 , _handleClickEvent: function (e, element) { 97 if (this.clickIsInProgress) { 98 return; 99 } 100 this.clickIsInProgress = true; 101 // saving current event for later usage 102 this.eventStack.push([e, element, this._getEventsByElement(element)]); 103 var currentKey = this.eventStack.length - 1; 104 if (this.options.useApiEvents) { 105 // make an api request before doing anything else
106 Object.append(this.options.apiEventRequestParams, { 107 'clicked': element.get('id') 108 , 'events': this.eventStack[currentKey][2] 109 , 'eventNum': currentKey 110 }); 111 this.apiEventRequest.post(this.options.apiEventRequestParams); 112 } else { 113 this._fireEventsForEventStack(currentKey); 114 this.clickIsInProgress = false; 115 } 116 } 117 118 , _fireEventsForEventStack: function (key) { 119 this.eventStack[key][2].each(function (event) { 120 this.fireEvent(event, [this.eventStack[key][1], this.eventStack[key][2]]); 121 }, this); 122 } 123 124 , _apiEventCompletes: function (data) { 125 if (typeOf(data) === 'object' && typeOf(data.eventNum) === 'number') { 126 // is the click event is on an a tag element redirect to it 127 var eventData = this.eventStack[data.eventNum]; 128 var url = null; 129 if (eventData[1].get('tag') === 'a') { 130 if (!eventData[1].hasClass('no-redirect')) { 131 // ...but only if the element does not have a class "no-redirect" 132 url = eventData[1].get('href').replace(/^#/, '').trim(); 133 if (url.length === 0) { 134 url = null; 135 } 136 } 137 } 138 139 // is there a message to display? 140 if (typeOf(data.overlay) === 'object') { 141 // display message 142 gm_DialogHandler.add(new gm_dialog_Plain(data.overlay.title, data.overlay.text, {redirectOnClose: url})); 143 // close current message 144 this.fireEvent('close'); 145 return; 146 } 147 148 if (url !== null) { 149 // redirect to url 150 new URI(url).go(); 151 return; 152 } 153 154 // fire the events after request is complete 155 this._fireEventsForEventStack(data.eventNum); 156 } 157 } 158 159 , init: function () { 160 this._initButtons(); 161 this._initApiEvent(); 162 163 this._show(); 164 new gm_CenterElement(this.container); 165 } 166 167 , _show: function () { 168 this.container.removeClass('hide'); 169 this.clickIsInProgress = false; 170 Overlay.show(); 171 } 172 173 , close: function () { 174 this.container.addClass('hide'); 175 this.waitOverlay.addClass('hide'); 176 Overlay.hide(); 177 178 this.container.getElements('*').each(function (element) { 179 if (!this._getElementHasEvents(element)) { 180 return; 181 } 182 element.removeEvents('click'); 183 }.bind(this)); 184 185 } 186});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.