| 1 | efrain | 1 | /**
 | 
        
           |  |  | 2 |  * A type of dialogue used as for choosing options.
 | 
        
           |  |  | 3 |  *
 | 
        
           |  |  | 4 |  * @module moodle-core-chooserdialogue
 | 
        
           |  |  | 5 |  */
 | 
        
           |  |  | 6 |   | 
        
           |  |  | 7 | /**
 | 
        
           |  |  | 8 |  * A type of dialogue used as for choosing options.
 | 
        
           |  |  | 9 |  *
 | 
        
           |  |  | 10 |  * @constructor
 | 
        
           |  |  | 11 |  * @class M.core.chooserdialogue
 | 
        
           |  |  | 12 |  */
 | 
        
           |  |  | 13 | var CHOOSERDIALOGUE = function() {
 | 
        
           |  |  | 14 |     CHOOSERDIALOGUE.superclass.constructor.apply(this, arguments);
 | 
        
           |  |  | 15 | };
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 | Y.extend(CHOOSERDIALOGUE, Y.Base, {
 | 
        
           |  |  | 18 |     // The panel widget
 | 
        
           |  |  | 19 |     panel: null,
 | 
        
           |  |  | 20 |   | 
        
           |  |  | 21 |     // The submit button - we disable this until an element is set
 | 
        
           |  |  | 22 |     submitbutton: null,
 | 
        
           |  |  | 23 |   | 
        
           |  |  | 24 |     // The chooserdialogue container
 | 
        
           |  |  | 25 |     container: null,
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 |     // Any event listeners we may need to cancel later
 | 
        
           |  |  | 28 |     listenevents: [],
 | 
        
           |  |  | 29 |   | 
        
           |  |  | 30 |     bodycontent: null,
 | 
        
           |  |  | 31 |     headercontent: null,
 | 
        
           |  |  | 32 |     instanceconfig: null,
 | 
        
           |  |  | 33 |   | 
        
           |  |  | 34 |     // The hidden field storing the disabled element values for submission.
 | 
        
           |  |  | 35 |     hiddenRadioValue: null,
 | 
        
           |  |  | 36 |   | 
        
           |  |  | 37 |     setup_chooser_dialogue: function(bodycontent, headercontent, config) {
 | 
        
           |  |  | 38 |         this.bodycontent = bodycontent;
 | 
        
           |  |  | 39 |         this.headercontent = headercontent;
 | 
        
           |  |  | 40 |         this.instanceconfig = config;
 | 
        
           |  |  | 41 |     },
 | 
        
           |  |  | 42 |   | 
        
           |  |  | 43 |     prepare_chooser: function() {
 | 
        
           |  |  | 44 |         if (this.panel) {
 | 
        
           |  |  | 45 |             return;
 | 
        
           |  |  | 46 |         }
 | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 |         // Ensure that we're showing the JS version of the chooser.
 | 
        
           |  |  | 49 |         Y.one(Y.config.doc.body).addClass('jschooser');
 | 
        
           |  |  | 50 |   | 
        
           |  |  | 51 |         // Set Default options
 | 
        
           |  |  | 52 |         var paramkey,
 | 
        
           |  |  | 53 |             params = {
 | 
        
           |  |  | 54 |                 bodyContent: this.bodycontent.get('innerHTML'),
 | 
        
           |  |  | 55 |                 headerContent: this.headercontent.get('innerHTML'),
 | 
        
           |  |  | 56 |                 width: '540px',
 | 
        
           |  |  | 57 |                 draggable: true,
 | 
        
           |  |  | 58 |                 visible: false, // Hide by default
 | 
        
           |  |  | 59 |                 zindex: 100, // Display in front of other items
 | 
        
           |  |  | 60 |                 modal: true, // This dialogue should be modal.
 | 
        
           |  |  | 61 |                 shim: true,
 | 
        
           |  |  | 62 |                 closeButtonTitle: this.get('closeButtonTitle'),
 | 
        
           |  |  | 63 |                 focusOnPreviousTargetAfterHide: true,
 | 
        
           |  |  | 64 |                 render: false,
 | 
        
           |  |  | 65 |                 extraClasses: this._getClassNames()
 | 
        
           |  |  | 66 |             };
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 |         // Override with additional options
 | 
        
           |  |  | 69 |         for (paramkey in this.instanceconfig) {
 | 
        
           |  |  | 70 |           params[paramkey] = this.instanceconfig[paramkey];
 | 
        
           |  |  | 71 |         }
 | 
        
           |  |  | 72 |   | 
        
           |  |  | 73 |         // Create the panel
 | 
        
           |  |  | 74 |         this.panel = new M.core.dialogue(params);
 | 
        
           |  |  | 75 |   | 
        
           |  |  | 76 |         // Remove the template for the chooser
 | 
        
           |  |  | 77 |         this.bodycontent.remove();
 | 
        
           |  |  | 78 |         this.headercontent.remove();
 | 
        
           |  |  | 79 |   | 
        
           |  |  | 80 |         // Hide and then render the panel
 | 
        
           |  |  | 81 |         this.panel.hide();
 | 
        
           |  |  | 82 |         this.panel.render();
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 |         // Set useful links.
 | 
        
           |  |  | 85 |         this.container = this.panel.get('boundingBox').one('.choosercontainer');
 | 
        
           |  |  | 86 |         this.options = this.container.all('.option input[type=radio]');
 | 
        
           |  |  | 87 |   | 
        
           |  |  | 88 |         // The hidden form element we use when submitting.
 | 
        
           |  |  | 89 |         this.hiddenRadioValue = Y.Node.create('<input type="hidden" value="" />');
 | 
        
           |  |  | 90 |         this.container.one('form').appendChild(this.hiddenRadioValue);
 | 
        
           |  |  | 91 |   | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 |         // Add the chooserdialogue class to the container for styling
 | 
        
           |  |  | 94 |         this.panel.get('boundingBox').addClass('chooserdialogue');
 | 
        
           |  |  | 95 |     },
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 |     /**
 | 
        
           |  |  | 98 |       * Display the module chooser
 | 
        
           |  |  | 99 |       *
 | 
        
           |  |  | 100 |       * @method display_chooser
 | 
        
           |  |  | 101 |       * @param {EventFacade} e Triggering Event
 | 
        
           |  |  | 102 |       */
 | 
        
           |  |  | 103 |     display_chooser: function(e) {
 | 
        
           |  |  | 104 |         var bb, dialogue, thisevent;
 | 
        
           |  |  | 105 |         this.prepare_chooser();
 | 
        
           |  |  | 106 |   | 
        
           |  |  | 107 |         // Stop the default event actions before we proceed
 | 
        
           |  |  | 108 |         e.preventDefault();
 | 
        
           |  |  | 109 |   | 
        
           |  |  | 110 |         bb = this.panel.get('boundingBox');
 | 
        
           |  |  | 111 |         dialogue = this.container.one('.alloptions');
 | 
        
           |  |  | 112 |   | 
        
           |  |  | 113 |         // This will detect a change in orientation and retrigger centering
 | 
        
           |  |  | 114 |         thisevent = Y.one('document').on('orientationchange', function() {
 | 
        
           |  |  | 115 |             this.center_dialogue(dialogue);
 | 
        
           |  |  | 116 |         }, this);
 | 
        
           |  |  | 117 |         this.listenevents.push(thisevent);
 | 
        
           |  |  | 118 |   | 
        
           |  |  | 119 |         // Detect window resizes (most browsers)
 | 
        
           |  |  | 120 |         thisevent = Y.one('window').on('resize', function() {
 | 
        
           |  |  | 121 |             this.center_dialogue(dialogue);
 | 
        
           |  |  | 122 |         }, this);
 | 
        
           |  |  | 123 |         this.listenevents.push(thisevent);
 | 
        
           |  |  | 124 |   | 
        
           |  |  | 125 |         // These will trigger a check_options call to display the correct help
 | 
        
           |  |  | 126 |         thisevent = this.container.on('click', this.check_options, this);
 | 
        
           |  |  | 127 |         this.listenevents.push(thisevent);
 | 
        
           |  |  | 128 |         thisevent = this.container.on('key_up', this.check_options, this);
 | 
        
           |  |  | 129 |         this.listenevents.push(thisevent);
 | 
        
           |  |  | 130 |         thisevent = this.container.on('dblclick', function(e) {
 | 
        
           |  |  | 131 |             if (e.target.ancestor('div.option')) {
 | 
        
           |  |  | 132 |                 this.check_options();
 | 
        
           |  |  | 133 |   | 
        
           |  |  | 134 |                 // Prevent duplicate submissions
 | 
        
           |  |  | 135 |                 this.submitbutton.setAttribute('disabled', 'disabled');
 | 
        
           |  |  | 136 |                 this.options.setAttribute('disabled', 'disabled');
 | 
        
           |  |  | 137 |                 this.cancel_listenevents();
 | 
        
           |  |  | 138 |   | 
        
           |  |  | 139 |                 this.container.one('form').submit();
 | 
        
           |  |  | 140 |             }
 | 
        
           |  |  | 141 |         }, this);
 | 
        
           |  |  | 142 |         this.listenevents.push(thisevent);
 | 
        
           |  |  | 143 |   | 
        
           |  |  | 144 |         this.container.one('form').on('submit', function() {
 | 
        
           |  |  | 145 |             // Prevent duplicate submissions on submit
 | 
        
           |  |  | 146 |             this.submitbutton.setAttribute('disabled', 'disabled');
 | 
        
           |  |  | 147 |             this.options.setAttribute('disabled', 'disabled');
 | 
        
           |  |  | 148 |             this.cancel_listenevents();
 | 
        
           |  |  | 149 |         }, this);
 | 
        
           |  |  | 150 |   | 
        
           |  |  | 151 |         // Hook onto the cancel button to hide the form
 | 
        
           |  |  | 152 |         thisevent = this.container.one('.addcancel').on('click', this.cancel_popup, this);
 | 
        
           |  |  | 153 |         this.listenevents.push(thisevent);
 | 
        
           |  |  | 154 |   | 
        
           |  |  | 155 |         // Hide will be managed by cancel_popup after restoring the body overflow
 | 
        
           |  |  | 156 |         thisevent = bb.one('button.closebutton').on('click', this.cancel_popup, this);
 | 
        
           |  |  | 157 |         this.listenevents.push(thisevent);
 | 
        
           |  |  | 158 |   | 
        
           |  |  | 159 |         // Grab global keyup events and handle them
 | 
        
           |  |  | 160 |         thisevent = Y.one('document').on('keydown', this.handle_key_press, this);
 | 
        
           |  |  | 161 |         this.listenevents.push(thisevent);
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 |         // Add references to various elements we adjust
 | 
        
           |  |  | 164 |         this.submitbutton = this.container.one('.submitbutton');
 | 
        
           |  |  | 165 |   | 
        
           |  |  | 166 |         // Disable the submit element until the user makes a selection
 | 
        
           |  |  | 167 |         this.submitbutton.set('disabled', 'true');
 | 
        
           |  |  | 168 |   | 
        
           |  |  | 169 |         // Ensure that the options are shown
 | 
        
           |  |  | 170 |         this.options.removeAttribute('disabled');
 | 
        
           |  |  | 171 |   | 
        
           |  |  | 172 |         // Display the panel
 | 
        
           |  |  | 173 |         this.panel.show(e);
 | 
        
           |  |  | 174 |   | 
        
           |  |  | 175 |         // Re-centre the dialogue after we've shown it.
 | 
        
           |  |  | 176 |         this.center_dialogue(dialogue);
 | 
        
           |  |  | 177 |   | 
        
           |  |  | 178 |         // Finally, focus the first radio element - this enables form selection via the keyboard
 | 
        
           |  |  | 179 |         this.container.one('.option input[type=radio]').focus();
 | 
        
           |  |  | 180 |   | 
        
           |  |  | 181 |         // Trigger check_options to set the initial jumpurl
 | 
        
           |  |  | 182 |         this.check_options();
 | 
        
           |  |  | 183 |     },
 | 
        
           |  |  | 184 |   | 
        
           |  |  | 185 |     /**
 | 
        
           |  |  | 186 |      * Cancel any listen events in the listenevents queue
 | 
        
           |  |  | 187 |      *
 | 
        
           |  |  | 188 |      * Several locations add event handlers which should only be called before the form is submitted. This provides
 | 
        
           |  |  | 189 |      * a way of cancelling those events.
 | 
        
           |  |  | 190 |      *
 | 
        
           |  |  | 191 |      * @method cancel_listenevents
 | 
        
           |  |  | 192 |      */
 | 
        
           |  |  | 193 |     cancel_listenevents: function() {
 | 
        
           |  |  | 194 |         // Detach all listen events to prevent duplicate triggers
 | 
        
           |  |  | 195 |         var thisevent;
 | 
        
           |  |  | 196 |         while (this.listenevents.length) {
 | 
        
           |  |  | 197 |             thisevent = this.listenevents.shift();
 | 
        
           |  |  | 198 |             thisevent.detach();
 | 
        
           |  |  | 199 |         }
 | 
        
           |  |  | 200 |     },
 | 
        
           |  |  | 201 |   | 
        
           |  |  | 202 |     /**
 | 
        
           |  |  | 203 |       * Calculate the optimum height of the chooser dialogue
 | 
        
           |  |  | 204 |       *
 | 
        
           |  |  | 205 |       * This tries to set a sensible maximum and minimum to ensure that some options are always shown, and preferably
 | 
        
           |  |  | 206 |       * all, whilst fitting the box within the current viewport.
 | 
        
           |  |  | 207 |       *
 | 
        
           |  |  | 208 |       * @method center_dialogue
 | 
        
           |  |  | 209 |       * @param Node {dialogue} Y.Node The dialogue
 | 
        
           |  |  | 210 |       */
 | 
        
           |  |  | 211 |     center_dialogue: function(dialogue) {
 | 
        
           |  |  | 212 |         var bb = this.panel.get('boundingBox'),
 | 
        
           |  |  | 213 |             winheight = bb.get('winHeight'),
 | 
        
           |  |  | 214 |             newheight, totalheight;
 | 
        
           |  |  | 215 |   | 
        
           |  |  | 216 |         if (this.panel.shouldResizeFullscreen()) {
 | 
        
           |  |  | 217 |             dialogue.setStyle('maxHeight', '100%');
 | 
        
           |  |  | 218 |             dialogue.setStyle('height', 'auto');
 | 
        
           |  |  | 219 |             this.panel.makeResponsive();
 | 
        
           |  |  | 220 |             return;
 | 
        
           |  |  | 221 |         }
 | 
        
           |  |  | 222 |   | 
        
           |  |  | 223 |         // Try and set a sensible max-height -- this must be done before setting the top
 | 
        
           |  |  | 224 |         // Set a default height of 640px
 | 
        
           |  |  | 225 |         newheight = this.get('maxheight');
 | 
        
           |  |  | 226 |         if (winheight <= newheight) {
 | 
        
           |  |  | 227 |             // Deal with smaller window sizes
 | 
        
           |  |  | 228 |             if (winheight <= this.get('minheight')) {
 | 
        
           |  |  | 229 |                 newheight = this.get('minheight');
 | 
        
           |  |  | 230 |             } else {
 | 
        
           |  |  | 231 |                 newheight = winheight;
 | 
        
           |  |  | 232 |             }
 | 
        
           |  |  | 233 |         }
 | 
        
           |  |  | 234 |   | 
        
           |  |  | 235 |         // If the dialogue is larger than a reasonable minimum height, we
 | 
        
           |  |  | 236 |         // disable the page scrollbars.
 | 
        
           |  |  | 237 |         if (newheight > this.get('minheight')) {
 | 
        
           |  |  | 238 |             // Disable the page scrollbars.
 | 
        
           |  |  | 239 |             if (this.panel.lockScroll && !this.panel.lockScroll.isActive()) {
 | 
        
           |  |  | 240 |                 this.panel.lockScroll.enableScrollLock(true);
 | 
        
           |  |  | 241 |             }
 | 
        
           |  |  | 242 |         } else {
 | 
        
           |  |  | 243 |             // Re-enable the page scrollbars.
 | 
        
           |  |  | 244 |             if (this.panel.lockScroll && this.panel.lockScroll.isActive()) {
 | 
        
           |  |  | 245 |                 this.panel.lockScroll.disableScrollLock();
 | 
        
           |  |  | 246 |             }
 | 
        
           |  |  | 247 |         }
 | 
        
           |  |  | 248 |   | 
        
           |  |  | 249 |         // Take off 15px top and bottom for borders, plus 69px for the title and 57px for the
 | 
        
           |  |  | 250 |         // button area before setting the new max-height.
 | 
        
           |  |  | 251 |         totalheight = newheight;
 | 
        
           |  |  | 252 |         newheight = newheight - (69 + 57 + 15 + 15);
 | 
        
           |  |  | 253 |         dialogue.setStyle('maxHeight', newheight + 'px');
 | 
        
           |  |  | 254 |   | 
        
           |  |  | 255 |         var dialogueheight = bb.getStyle('height');
 | 
        
           |  |  | 256 |         if (dialogueheight.match(/.*px$/)) {
 | 
        
           |  |  | 257 |             dialogueheight = dialogueheight.replace(/px$/, '');
 | 
        
           |  |  | 258 |         } else {
 | 
        
           |  |  | 259 |             dialogueheight = totalheight;
 | 
        
           |  |  | 260 |         }
 | 
        
           |  |  | 261 |   | 
        
           |  |  | 262 |         if (dialogueheight < this.get('baseheight')) {
 | 
        
           |  |  | 263 |             dialogueheight = this.get('baseheight');
 | 
        
           |  |  | 264 |             dialogue.setStyle('height', dialogueheight + 'px');
 | 
        
           |  |  | 265 |         } else {
 | 
        
           |  |  | 266 |             dialogue.setStyle('height', 'auto');
 | 
        
           |  |  | 267 |         }
 | 
        
           |  |  | 268 |   | 
        
           |  |  | 269 |         this.panel.centerDialogue();
 | 
        
           |  |  | 270 |     },
 | 
        
           |  |  | 271 |   | 
        
           |  |  | 272 |     handle_key_press: function(e) {
 | 
        
           |  |  | 273 |         if (e.keyCode === 27) {
 | 
        
           |  |  | 274 |             this.cancel_popup(e);
 | 
        
           |  |  | 275 |         }
 | 
        
           |  |  | 276 |     },
 | 
        
           |  |  | 277 |   | 
        
           |  |  | 278 |     cancel_popup: function(e) {
 | 
        
           |  |  | 279 |         // Prevent normal form submission before hiding
 | 
        
           |  |  | 280 |         e.preventDefault();
 | 
        
           |  |  | 281 |         this.hide();
 | 
        
           |  |  | 282 |     },
 | 
        
           |  |  | 283 |   | 
        
           |  |  | 284 |     hide: function() {
 | 
        
           |  |  | 285 |         // Cancel all listen events
 | 
        
           |  |  | 286 |         this.cancel_listenevents();
 | 
        
           |  |  | 287 |   | 
        
           |  |  | 288 |         this.container.detachAll();
 | 
        
           |  |  | 289 |         this.panel.hide();
 | 
        
           |  |  | 290 |     },
 | 
        
           |  |  | 291 |   | 
        
           |  |  | 292 |     check_options: function() {
 | 
        
           |  |  | 293 |         // Check which options are set, and change the parent class
 | 
        
           |  |  | 294 |         // to show/hide help as required
 | 
        
           |  |  | 295 |         this.options.each(function(thisoption) {
 | 
        
           |  |  | 296 |             var optiondiv = thisoption.get('parentNode').get('parentNode');
 | 
        
           |  |  | 297 |             if (thisoption.get('checked')) {
 | 
        
           |  |  | 298 |                 optiondiv.addClass('selected');
 | 
        
           |  |  | 299 |   | 
        
           |  |  | 300 |                 // Trigger any events for this option
 | 
        
           |  |  | 301 |                 this.option_selected(thisoption);
 | 
        
           |  |  | 302 |   | 
        
           |  |  | 303 |                 // Ensure that the form may be submitted
 | 
        
           |  |  | 304 |                 this.submitbutton.removeAttribute('disabled');
 | 
        
           |  |  | 305 |   | 
        
           |  |  | 306 |                 // Ensure that the radio remains focus so that keyboard navigation is still possible
 | 
        
           |  |  | 307 |                 thisoption.focus();
 | 
        
           |  |  | 308 |             } else {
 | 
        
           |  |  | 309 |                 optiondiv.removeClass('selected');
 | 
        
           |  |  | 310 |             }
 | 
        
           |  |  | 311 |         }, this);
 | 
        
           |  |  | 312 |     },
 | 
        
           |  |  | 313 |   | 
        
           |  |  | 314 |     option_selected: function(e) {
 | 
        
           |  |  | 315 |         // Set a hidden input field with the value and name of the radio button.  When we submit the form, we
 | 
        
           |  |  | 316 |         // disable the radios to prevent duplicate submission. This has the result however that the value is never
 | 
        
           |  |  | 317 |         // submitted so we set this value to a hidden field instead
 | 
        
           |  |  | 318 |         this.hiddenRadioValue.setAttrs({
 | 
        
           |  |  | 319 |             value: e.get('value'),
 | 
        
           |  |  | 320 |             name: e.get('name')
 | 
        
           |  |  | 321 |         });
 | 
        
           |  |  | 322 |     },
 | 
        
           |  |  | 323 |   | 
        
           |  |  | 324 |     /**
 | 
        
           |  |  | 325 |      * Return an array of class names prefixed with 'chooserdialogue-' and
 | 
        
           |  |  | 326 |      * the name of the type of dialogue.
 | 
        
           |  |  | 327 |      *
 | 
        
           |  |  | 328 |      * Note: Class name are converted to lower-case.
 | 
        
           |  |  | 329 |      *
 | 
        
           |  |  | 330 |      * If an array of arguments is supplied, each of these is prefixed and
 | 
        
           |  |  | 331 |      * lower-cased also.
 | 
        
           |  |  | 332 |      *
 | 
        
           |  |  | 333 |      * If no arguments are supplied, then the prefix is returned on it's
 | 
        
           |  |  | 334 |      * own.
 | 
        
           |  |  | 335 |      *
 | 
        
           |  |  | 336 |      * @method _getClassNames
 | 
        
           |  |  | 337 |      * @param {Array} [args] Any additional names to prefix and lower-case.
 | 
        
           |  |  | 338 |      * @return {Array}
 | 
        
           |  |  | 339 |      * @private
 | 
        
           |  |  | 340 |      */
 | 
        
           |  |  | 341 |     _getClassNames: function(args) {
 | 
        
           |  |  | 342 |         var prefix = 'chooserdialogue-' + this.name,
 | 
        
           |  |  | 343 |             results = [];
 | 
        
           |  |  | 344 |   | 
        
           |  |  | 345 |         results.push(prefix.toLowerCase());
 | 
        
           |  |  | 346 |         if (args) {
 | 
        
           |  |  | 347 |             var arg;
 | 
        
           |  |  | 348 |             for (arg in args) {
 | 
        
           |  |  | 349 |                 results.push((prefix + '-' + arg).toLowerCase());
 | 
        
           |  |  | 350 |             }
 | 
        
           |  |  | 351 |         }
 | 
        
           |  |  | 352 |   | 
        
           |  |  | 353 |         return results;
 | 
        
           |  |  | 354 |     }
 | 
        
           |  |  | 355 | },
 | 
        
           |  |  | 356 | {
 | 
        
           |  |  | 357 |     NAME: 'moodle-core-chooserdialogue',
 | 
        
           |  |  | 358 |     ATTRS: {
 | 
        
           |  |  | 359 |         /**
 | 
        
           |  |  | 360 |          * The minimum height (in pixels) before resizing is prevented and scroll
 | 
        
           |  |  | 361 |          * locking disabled.
 | 
        
           |  |  | 362 |          *
 | 
        
           |  |  | 363 |          * @attribute minheight
 | 
        
           |  |  | 364 |          * @type Number
 | 
        
           |  |  | 365 |          * @default 300
 | 
        
           |  |  | 366 |          */
 | 
        
           |  |  | 367 |         minheight: {
 | 
        
           |  |  | 368 |             value: 300
 | 
        
           |  |  | 369 |         },
 | 
        
           |  |  | 370 |   | 
        
           |  |  | 371 |         /**
 | 
        
           |  |  | 372 |          * The base height??
 | 
        
           |  |  | 373 |          *
 | 
        
           |  |  | 374 |          * @attribute baseheight
 | 
        
           |  |  | 375 |          * @type Number
 | 
        
           |  |  | 376 |          * @default 400
 | 
        
           |  |  | 377 |          */
 | 
        
           |  |  | 378 |         baseheight: {
 | 
        
           |  |  | 379 |             value: 400
 | 
        
           |  |  | 380 |         },
 | 
        
           |  |  | 381 |   | 
        
           |  |  | 382 |         /**
 | 
        
           |  |  | 383 |          * The maximum height (in pixels) at which we stop resizing.
 | 
        
           |  |  | 384 |          *
 | 
        
           |  |  | 385 |          * @attribute maxheight
 | 
        
           |  |  | 386 |          * @type Number
 | 
        
           |  |  | 387 |          * @default 300
 | 
        
           |  |  | 388 |          */
 | 
        
           |  |  | 389 |         maxheight: {
 | 
        
           |  |  | 390 |             value: 660
 | 
        
           |  |  | 391 |         },
 | 
        
           |  |  | 392 |   | 
        
           |  |  | 393 |         /**
 | 
        
           |  |  | 394 |          * The title of the close button.
 | 
        
           |  |  | 395 |          *
 | 
        
           |  |  | 396 |          * @attribute closeButtonTitle
 | 
        
           |  |  | 397 |          * @type String
 | 
        
           |  |  | 398 |          * @default 'Close'
 | 
        
           |  |  | 399 |          */
 | 
        
           |  |  | 400 |         closeButtonTitle: {
 | 
        
           |  |  | 401 |             validator: Y.Lang.isString,
 | 
        
           |  |  | 402 |             value: 'Close'
 | 
        
           |  |  | 403 |         }
 | 
        
           |  |  | 404 |     }
 | 
        
           |  |  | 405 | });
 | 
        
           |  |  | 406 | M.core = M.core || {};
 | 
        
           |  |  | 407 | M.core.chooserdialogue = CHOOSERDIALOGUE;
 |