mBox.Notice.js 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262
  1. /*
  2. ---
  3. description: mBox is a powerful library, helping you to easily create tooltips, modal windows, notice messages and more.
  4. authors: Stephan Wagner
  5. license: MIT-style
  6. requires:
  7. - core/1.4.5: '*'
  8. - more/Element.Measure
  9. provides: [mBox]
  10. documentation: http://htmltweaks.com/mBox/Documentation
  11. ...
  12. */
  13. var mBox = new Class({
  14. Implements: [Options,Events],
  15. options: {
  16. id: '', // id of the mBox wrapper (defaults to mBox_1, mBox_2, mBox_3...)
  17. theme: '', // themes can be defined by css, e.g. in assets/themes/mBoxMyTheme.css
  18. addClass: { // add additional classes to wrapper, container, title and/or footer
  19. wrapper: '',
  20. container: '',
  21. content: '',
  22. title: '',
  23. footer: ''
  24. },
  25. setStyles: { // set additional styles to wrapper, container, title and/or footer
  26. wrapper: {},
  27. container: {},
  28. content: {},
  29. title: {},
  30. footer: {}
  31. },
  32. target: $(window), // element reference or element-id where the mBox will be opened (use 'mouse' to show mBox on mouse-position)
  33. attach: null, // element reference or element-id or element-classes of the elements which will open / close the mBox
  34. event: 'click', // the event which will trigger the mBox to show (can be: 'click' || 'mouseover' (= 'mouseenter'))
  35. preventDefault: false, // prevents the default action when clicking on attached item (e.g. prevents to follow a link when clicking on a link)
  36. //inject: null, // TODO element to inject the wrapper to (open and close will be disabled)
  37. width: 'auto', // width of the content area
  38. height: 'auto', // height of the content area
  39. zIndex: 8000, // z-index of wrapper
  40. content: null, // element reference or element-id or element classes to inject into the content, use a string to set a string as content
  41. setContent:
  42. 'data-setContent', // if the attached element has the attribute data-setContent it's value will be set as new content on open
  43. load: null, // set to ajax to load the content from url
  44. url: '', // the url to load the content from if load is set to ajax or iframe
  45. reload: false, // reloads the content each time the mBox is opened
  46. title: null, // adds a title (element reference, element-id or string)
  47. footer: null, // adds a footer (element reference, element-id or string)
  48. draggable: false, // mBox can be dragged when clicking on title
  49. position: {
  50. x: 'center', // horizontal position (use array to define outside or inside positions e.g. ['right', 'inside'] or ['left', 'center'])
  51. y: 'center' // vertical position (use array to define outside or inside positions e.g. ['top', 'inside'] or ['bottom', 'center'])
  52. }, // the position-attributes default to 'left' and 'top', to change them to 'right' or 'bottom', define a third value in the array e.g. ['left', 'inside', 'right']
  53. fixed: null, // set to false to force mBox to be absolute or true to force mBox to be fixed
  54. offset: { // offsets to be added to position
  55. x: 0,
  56. y: 0
  57. },
  58. pointer: false, // set to true to show a pointer (at least one position value needs to be 'outside')
  59. // set to 'right', 'left', 'top', 'bottom' to adjust the pointers position
  60. // if you want to add an offset to the pointer, provide an array, e.g. ['left', 10]
  61. fade: { // set to false or 0 if you want to open/close the tooltip instantly (fade: false will open and close tooltip instantly)
  62. open: true,
  63. close: true
  64. },
  65. fadeDuration: { // default fade duration when opening or closing (set fadeDuration: 250 to use it for open and close)
  66. open: 200,
  67. close: 300
  68. },
  69. fadeWhenOpen: false, // set to true if you want to fade the mBox on open even if it's already open
  70. overlay: false, // adds a overlay just underneath the mBox to prevent clicks on body
  71. overlayStyles: { // set the color and the opacity of the overlay
  72. color: 'black',
  73. opacity: 0.75
  74. },
  75. overlayFadeDuration: 100, // default fade duration for the overlay
  76. transition: { // adds a transition when mBox is opened or closed, following shortcuts are availible:
  77. // transition: ['flyin', 'flyout', 'flyinout', 'flyoutin', 'bounce', 'bouncefly']
  78. open: null, // you can also define your own transitions by using mootools transitions:
  79. close: null // transition: {open: {transition: 'bounce:in', property: 'top', duration: 400, difference_start: 50, difference_end: 0}
  80. },
  81. closeOnEsc: true, // close mBox when pressing esc
  82. closeOnClick: false, // close mBox when clicking anywhere
  83. closeOnBoxClick: false, // close mBox when clicking on the mBox
  84. closeOnWrapperClick: false, // close mBox when clicking on the Wrapper of the mBox (wont close when clicking on children of mBox like title, content etc.)
  85. closeOnBodyClick: true, // close mBox when clicking anywhere except the mBox itself
  86. closeOnMouseleave: false, // close mBox when the mouse leaves the mBox area or the attached area
  87. closeInTitle: false, // adds a close button in the title area // TODO won't work in tooltip title yet
  88. //closeInContainer: false, // TODO add a close button to the container
  89. //closeInWindow: false, // TODO add a close button to the window
  90. delayOpen: 0, // delay opening the mBox in ms
  91. delayClose: 0, // delay closing the mBox in ms
  92. delayOpenOnce: true, // set to true if you want the delay to be ignored when the mBox didnt finish closing yet
  93. constructOnInit: true, // true will construct the mBox once its finished initializing
  94. openOnInit: false // true will construct (if it hasbn't been) and open the mBox once its finished initializing
  95. // Events:
  96. // onInit: function() {},
  97. // onOpen: function() {},
  98. // onOpenComplete: function() {},
  99. // onClose: function() {},
  100. // onCloseComplete: function() {}
  101. // onBoxReady: function() {}
  102. // onAjaxComplete: function() {}
  103. },
  104. // initialize
  105. initialize: function(options) {
  106. // set global vars
  107. this.block = false; // set this.block to true so the mBox wont be opened until set to false again
  108. this.ignoreDelay = false; // set this.ignoreDelay to true if you want to ignore the delays until set to false again
  109. this.ignoreDelayOnce = false; // set this.ignoreDelayOnce to true if you want to ignore the delay only for one closing / opening
  110. // set the options
  111. this.setOptions(options);
  112. // fix options addClass, setStyles, fade, fadeDuration
  113. this.fixOptions();
  114. this.getPosition();
  115. // save current target in this.target
  116. this.target = this.getTarget();
  117. // set fixed to true or false depending on target
  118. if (this.options.fixed == null) {
  119. this.options.fixed = [$(window), $(document), $(document.body)].contains(this.target);
  120. }
  121. // no pointer if target == 'mouse'
  122. if (this.target == 'mouse') { this.options.pointer = false; }
  123. // targets will be saved in this.targets
  124. this.targets = [];
  125. // get mBox id
  126. this.id = (this.options.id || 'mBox' + (++mBox.currentId));
  127. // add listeners to elements
  128. this.addListeners();
  129. // construct the mBox
  130. if(this.options.constructOnInit) {
  131. this.construct();
  132. }
  133. // fire onInit events
  134. this.fireEvent('init').fireEvent('systemInit');
  135. // open mBox on init
  136. if(this.options.openOnInit) {
  137. this.open();
  138. }
  139. // add this instance to global collector
  140. mBox.instances.push(this);
  141. },
  142. // re-initialize mBox (e.g. after an ajax call)
  143. reInit: function() {
  144. // add listeners to new elements
  145. this.addListeners();
  146. },
  147. // fix options
  148. fixOptions: function() {
  149. if(typeof this.options.addClass == 'string') {
  150. this.options.addClass = {
  151. wrapper: this.options.addClass
  152. };
  153. }
  154. if(typeof this.options.setStyles == 'object' && !this.options.setStyles.wrapper && !this.options.setStyles.container && !this.options.setStyles.content && !this.options.setStyles.title && !this.options.setStyles.footer) {
  155. this.options.setStyles = {
  156. wrapper: this.options.setStyles
  157. };
  158. }
  159. this.options.fade = {
  160. open: this.options.fade.open || (this.options.fade == true),
  161. close: this.options.fade.close || (this.options.fade == true)
  162. };
  163. this.options.fadeDuration = {
  164. open: this.options.fadeDuration.open || this.options.fadeDuration,
  165. close: this.options.fadeDuration.close || this.options.fadeDuration
  166. };
  167. },
  168. // contruct the mBox
  169. construct: function() {
  170. if(this.wrapper) {
  171. return null;
  172. }
  173. // create wrapper
  174. this.wrapper = new Element('div', {
  175. id: this.id,
  176. 'class': 'mBox ' + (this.defaultTheme || 'Core') + (this.options.theme ? '-' + this.options.theme : '') + ' ' + (this.options.addClass.wrapper || ''),
  177. styles: {
  178. zIndex: this.options.zIndex,
  179. position: (this.options.fixed == false || Browser.ie6 || Browser.ie7) ? 'absolute' : 'fixed',
  180. display: 'none',
  181. opacity: 0.00001,
  182. top: -12000,
  183. left: -12000,
  184. zoom: 1
  185. }
  186. //}).setStyles(this.options.setStyles.wrapper || {}).inject(document.body, 'bottom');
  187. }).setStyles(this.options.setStyles.wrapper || {});
  188. var target = $(target) || target || this.target || $(this.options.target) || this.options.target || $(this.options.attach);
  189. if (target && typeOf(target)==="element"){
  190. this.wrapper.inject(target, "after");
  191. }else{
  192. this.wrapper.inject(document.body, 'bottom');
  193. }
  194. // add mouse events to wrapper
  195. if(this.options.closeOnMouseleave) {
  196. this.wrapper.addEvents({
  197. mouseenter: function(ev) {
  198. this.open();
  199. }.bind(this),
  200. mouseleave: function(ev) {
  201. this.close();
  202. }.bind(this)
  203. });
  204. }
  205. // create container (contains content, title, footer)
  206. this.container = new Element('div', {
  207. 'class': 'mBoxContainer' + ' ' + (this.options.addClass.container || '')
  208. }).setStyles(this.options.setStyles.container || {}).inject(this.wrapper);
  209. // create content
  210. this.content = new Element('div', {
  211. 'class': 'mBoxContent' + ' ' + (this.options.addClass.content || ''),
  212. styles: {
  213. width: this.options.width,
  214. height: this.options.height
  215. }
  216. }).setStyles(this.options.setStyles.content || {}).inject(this.container);
  217. // load content into mBox
  218. this.load(this.options.content, this.options.title, this.options.footer, true); // TODO whats the true for?
  219. // fire boxReady events
  220. this.fireEvent('systemBoxReady').fireEvent('boxReady');
  221. },
  222. // add event listerners to elements
  223. addListeners: function(el) {
  224. // get elements to add events to, if none given use this.options.attach
  225. el = el || this.options.attach;
  226. elements = Array.from($(el)).combine(Array.from($$('.' + el))).combine(Array.from($$(el))).clean();
  227. if(!elements || elements.length == 0) return this;
  228. // add elements to this.targets
  229. this.targets.combine(elements);
  230. // create click or mouseenter/mouseleave events
  231. switch(this.options.event) {
  232. case 'mouseenter':
  233. case 'mouseover':
  234. var events = {
  235. mouseenter: function(ev) {
  236. this.target = this.getTargetFromEvent(ev);
  237. this.source = this.getTargetElementFromEvent(ev);
  238. this.open();
  239. }.bind(this),
  240. mouseleave: function(ev) {
  241. this.close();
  242. }.bind(this)
  243. };
  244. break;
  245. default:
  246. var events = {
  247. click: function(ev) {
  248. if(this.options.preventDefault) {
  249. ev.preventDefault();
  250. }
  251. if(this.isOpen) {
  252. this.close();
  253. } else {
  254. this.target = this.getTargetFromEvent(ev);
  255. this.source = this.getTargetElementFromEvent(ev);
  256. this.open();
  257. }
  258. }.bind(this)
  259. };
  260. }
  261. // add events if not already added
  262. $$(elements).each(function(el) {
  263. if(!el.retrieve('mBoxElementEventsAdded' + this.id)) {
  264. el.addEvents(events).store('mBoxElementEventsAdded' + this.id, true);
  265. }
  266. }.bind(this));
  267. },
  268. // load content with ajax into mBox
  269. loadAjax: function(sendObj) {
  270. if(!this.ajaxRequest) {
  271. this.ajaxRequest = new Request.HTML({
  272. link: 'cancel',
  273. update: this.content,
  274. onRequest: function() {
  275. this.setContent('');
  276. this.wrapper.addClass('mBoxLoading');
  277. }.bind(this),
  278. onComplete: function() {
  279. this.wrapper.removeClass('mBoxLoading');
  280. if(this.options.width == 'auto' || this.options.height == 'auto') {
  281. this.setPosition();
  282. }
  283. this.fireEvent('ajaxComplete');
  284. }.bind(this)
  285. }).send();
  286. }
  287. this.ajaxRequest.send(sendObj);
  288. this.ajaxLoaded = true;
  289. },
  290. // open / show the mBox
  291. open: function(options) {
  292. if(!this.wrapper) {
  293. // construct the mBox
  294. this.construct();
  295. }
  296. if(typeof options != 'object') options = {};
  297. clearTimeout(this.timer);
  298. if(!this.isOpen && !this.block) {
  299. var complete = function() {
  300. this.ignoreDelayOnce = false;
  301. this.fireEvent('systemOpenComplete').fireEvent('openComplete');
  302. }.bind(this);
  303. var open = function(complete) {
  304. this.isOpen = true;
  305. // load content from ajax
  306. if(this.options.load == 'ajax' && this.options.url && (!this.ajaxLoaded || this.options.reload)) {
  307. this.loadAjax({url: this.options.url});
  308. }
  309. // set target
  310. this.target = this.getTarget(options.target || null);
  311. // set new content
  312. if (this.options.setContent && this.source && this.source.getAttribute(this.options.setContent)) {
  313. if ($(this.source.getAttribute(this.options.setContent))) {
  314. this.content.getChildren().setStyle('display', 'none');
  315. $(this.source.getAttribute(this.options.setContent)).setStyle('display', '');
  316. } else {
  317. var attribute_array = this.source.getAttribute(this.options.setContent).split('|'),
  318. content = attribute_array[0] || null,
  319. title = attribute_array[1] || null,
  320. footer = attribute_array[2] || null;
  321. this.load(content, title, footer);
  322. }
  323. }
  324. if (this.wrapper) this.wrapper.inject(document.body, 'bottom');
  325. // set new position
  326. this.setPosition(null, options.position || null, options.offset || null);
  327. // fire open events
  328. this.fireEvent('systemOpen').fireEvent('open');
  329. // fade mBox
  330. if(this.fx) { this.fx.cancel(); }
  331. this.wrapper.setStyles({
  332. display: ''
  333. });
  334. if(this.options.fadeWhenOpen) {
  335. this.wrapper.setStyle('opacity', 0);
  336. }
  337. this.fx = new Fx.Tween(this.wrapper, {
  338. property: 'opacity',
  339. duration: this.options.fadeDuration.open,
  340. link: 'cancel',
  341. onComplete: complete
  342. })[(options.instant || !this.options.fade.open) ? 'set' : 'start'](1);
  343. // call complete function when showing instantly
  344. if(options.instant || !this.options.fade.open) {
  345. complete();
  346. }
  347. // start additional transition
  348. var transition = this.getTransition();
  349. if(transition.open) {
  350. var fx = new Fx.Tween(this.wrapper, {
  351. property: transition.open.property || 'top',
  352. duration: transition.open.duration || this.options.fadeDuration.open,
  353. transition: transition.open.transition || null,
  354. onStart: transition.open.onStart || null,
  355. onComplete: transition.open.onComplete || null
  356. });
  357. fx.start((transition.open.start || (this.wrapper.getStyle(transition.open.property || 'top').toInt() + (transition.open.difference_start || 0))),
  358. (transition.open.end || (this.wrapper.getStyle(transition.open.property || 'top').toInt() + (transition.open.difference_end || 0))));
  359. }
  360. // attach events to document and window
  361. this.attachEvents();
  362. // add overlay
  363. if(this.options.overlay) {
  364. this.addOverlay((options.instant || !this.options.fade.open));
  365. }
  366. // set delay open once to true, set to false again when closing is finished
  367. if(this.options.delayOpenOnce) {
  368. this.delayOpenOnce = true;
  369. }
  370. }.bind(this);
  371. // delay open or close instantly
  372. if(this.options.delayOpen > 0 && !this.ignoreDelay && !this.ignoreDelayOnce && !this.delayOpenOnce) {
  373. this.timer = open.delay(this.options.delayOpen, this, complete);
  374. } else {
  375. open(complete);
  376. }
  377. }
  378. return this;
  379. },
  380. // close / hide the mBox
  381. close: function(options) {
  382. if(typeof options != 'object') options = {};
  383. clearTimeout(this.timer);
  384. if(this.isOpen && !this.block) {
  385. var complete = function() {
  386. this.delayOpenOnce = false;
  387. this.ignoreDelayOnce = false;
  388. this.wrapper.setStyle('display', 'none');
  389. this.fireEvent('systemCloseComplete').fireEvent('closeComplete');
  390. if (this.wrapper){
  391. var target = this.target || $(this.options.target) || this.options.target || $(this.options.attach);
  392. if (target && typeOf(target)==="element"){
  393. this.wrapper.inject(target);
  394. }
  395. }
  396. }.bind(this);
  397. var close = function(complete) {
  398. this.isOpen = false;
  399. // fire close events
  400. this.fireEvent('systemClose').fireEvent('close');
  401. // detach document and window events
  402. this.detachEvents();
  403. // remove overlay
  404. if(this.options.overlay) {
  405. this.removeOverlay((options.instant || !this.options.fade.close));
  406. }
  407. // fade mBox
  408. if(this.fx) { this.fx.cancel(); }
  409. this.fx = new Fx.Tween(this.wrapper, {
  410. property: 'opacity',
  411. duration: this.options.fadeDuration.close,
  412. link: 'cancel',
  413. onComplete: complete
  414. })[(options.instant || !this.options.fade.close) ? 'set' : 'start'](0);
  415. // call complete function when hiding instantly
  416. if(options.instant || !this.options.fade.close) {
  417. complete();
  418. }
  419. // start additionel transition
  420. var transition = this.getTransition();
  421. if(transition.close) {
  422. var fx = new Fx.Tween(this.wrapper, {
  423. property: transition.close.property || 'top',
  424. duration: transition.close.duration || this.options.fadeDuration.close,
  425. transition: transition.close.transition || null,
  426. onStart: transition.open.onStart || null,
  427. onComplete: transition.open.onComplete || null
  428. });
  429. fx.start((transition.close.start || (this.wrapper.getStyle(transition.close.property || 'top').toInt() + (transition.close.difference_start || 0))),
  430. (transition.close.end || (this.wrapper.getStyle(transition.close.property || 'top').toInt() + (transition.close.difference_end || 0))));
  431. }
  432. }.bind(this);
  433. // delay close or close instantly
  434. if(this.options.delayClose > 0 && !this.ignoreDelay && !this.ignoreDelayOnce) {
  435. this.timer = close.delay(this.options.delayClose, this, complete);
  436. } else {
  437. close(complete);
  438. }
  439. }
  440. return this;
  441. },
  442. // adds a overlay just beneath the mBox to prevent clicks on body
  443. addOverlay: function(instant) {
  444. if(!this.overlay) {
  445. this.overlay = new Element('div', { styles: {
  446. position: 'fixed',
  447. top: 0,
  448. left: 0,
  449. width: '100%',
  450. height: '100%',
  451. zIndex: (this.wrapper.getStyle('zIndex') - 1),
  452. background: this.options.overlayStyles.color || 'white',
  453. opacity: 0.001,
  454. display: 'none'
  455. }}).set('tween', {
  456. duration: this.options.overlayFadeDuration,
  457. link: 'cancel'
  458. }).inject($(document.body), 'bottom');
  459. }
  460. this.overlay.setStyle('display', 'block')[instant ? 'set' : 'tween']('opacity', (this.options.overlayStyles.opacity || 0.001));
  461. return this;
  462. },
  463. // remove the overlay
  464. removeOverlay: function(instant) {
  465. if(this.overlay) {
  466. this.overlay[instant ? 'set' : 'tween']('opacity', 0).get('tween').chain(function() {
  467. this.overlay.setStyle('display', 'none');
  468. }.bind(this));
  469. }
  470. return this;
  471. },
  472. // get the current or given target
  473. getTarget: function(target) {
  474. var target = $(target) || target || this.target || $(this.options.target) || this.options.target || $(this.options.attach);
  475. return target == 'mouse' ? 'mouse' : this.fixOperaPositioning($(target));
  476. },
  477. // get the target element from event target
  478. getTargetFromEvent: function(ev) {
  479. if(this.options.target) return this.fixOperaPositioning($(this.options.target));
  480. return this.getTargetElementFromEvent(ev);
  481. },
  482. // get the attached element from event
  483. getTargetElementFromEvent: function(ev) {
  484. if(ev && ev.target) {
  485. if(this.targets.contains(ev.target)) return this.fixOperaPositioning(ev.target);
  486. var parent_element = ev.target.getParent();
  487. while(parent_element != null) {
  488. if(this.targets.contains(parent_element)) {
  489. return this.fixOperaPositioning(parent_element);
  490. }
  491. parent_element = parent_element.getParent();
  492. }
  493. }
  494. return null;
  495. },
  496. // TEMP: This function fixes temporarily the mootools 1.4.5 positioning bug in opera
  497. fixOperaPositioning: function(el) {
  498. if($(el) && !$(el).retrieve('OperaBugFixed') && el != window) {
  499. try {
  500. if(!($(el).getStyle('border-top-width').toInt() + $(el).getStyle('border-right-width').toInt() + $(el).getStyle('border-bottom-width').toInt() + $(el).getStyle('border-left-width').toInt())) {
  501. $(el).setStyle('border', 0);
  502. }
  503. }
  504. catch(e) {}
  505. $(el).store('OperaBugFixed');
  506. }
  507. return el;
  508. },
  509. // get cached variable position or get a clean position variable
  510. getPosition: function(position) {
  511. if(!position && this.position) return this.position;
  512. position = position || this.options.position;
  513. this.position = {};
  514. // TODO shortcuts 'top' 'topRight' 'bottomLeft' etc.
  515. // get a clean x-position
  516. this.position.x = (typeof position == 'object' && typeof position.x == 'number') ?
  517. [position.x.toInt(), null] : ((typeof position != 'object' || !position.x || position.x == 'center' || (typeof position.x == 'object' && position.x[0] == 'center')) ?
  518. ['center', null] : (['right', 'left'].contains(position.x) ?
  519. [position.x, (this.defaultInOut || 'inside')] : ((typeof position.x == 'object' && ['right', 'left'].contains(position.x[0])) ?
  520. [position.x[0], (['inside', 'center', 'outside'].contains(position.x[1]) ? position.x[1] : (this.defaultInOut || 'inside'))] : ['center', null])));
  521. this.position.xAttribute = (this.position.x[3] == 'right' || (this.position.x[1] == 'inside' && this.position.x[0] == 'right')) ? 'right' : 'left';
  522. // get a clean y-position
  523. this.position.y = (typeof position == 'object' && typeof position.y == 'number') ?
  524. [position.y.toInt(), null] : ((typeof position != 'object' || !position.y || position.y == 'center' || (typeof position.y == 'object' && position.y[0] == 'center')) ?
  525. ['center', null] : (['top', 'bottom'].contains(position.y) ?
  526. [position.y, (this.defaultInOut || 'inside')] : ((typeof position.y == 'object' && ['top', 'bottom'].contains(position.y[0])) ?
  527. [position.y[0], (['inside', 'center', 'outside'].contains(position.y[1]) ? position.y[1] : (this.defaultInOut || 'inside'))] : ['center', null])));
  528. this.position.yAttribute = (this.position.x[3] == 'bottom' || (this.position.y[1] == 'inside' && this.position.y[0] == 'bottom')) ? 'bottom' : 'top';
  529. return this.position;
  530. },
  531. // get cached offset variable or get a clean one
  532. getOffset: function(offset) {
  533. if(!offset && this.offset) return this.offset;
  534. offset = offset || this.options.offset;
  535. this.offset = {};
  536. this.offset.x = (typeof offset == 'number') ? offset : (!offset.x ? 0 : (offset.x.toInt() >= 0 || offset.x.toInt() < 0) ? offset.x.toInt() : 0);
  537. this.offset.y = (typeof offset == 'number') ? offset : (!offset.y ? 0 : (offset.y.toInt() >= 0 || offset.y.toInt() < 0) ? offset.y.toInt() : 0);
  538. return this.offset;
  539. },
  540. // get cached pointer variable or get a clean one
  541. getPointer: function(pointer) {
  542. if(!pointer && this.pointer) return this.pointer;
  543. pointer = pointer || this.options.pointer;
  544. if(!pointer) return false;
  545. var position = this.getPosition();
  546. this.pointer = {};
  547. if(position.y[1] == 'outside') {
  548. this.pointer.position = (position.y[0] == 'bottom') ? 'top' : 'bottom';
  549. this.pointer.adjustment = (typeof pointer == 'object' && ['center', 'right', 'left'].contains(pointer[0])) ? pointer[0] : (['center', 'right', 'left'].contains(pointer) ? pointer : 'center');
  550. } else if(position.x[1] == 'outside') {
  551. this.pointer.position = (position.x[0] == 'left') ? 'right' : 'left';
  552. this.pointer.adjustment = (typeof pointer == 'object' && ['center', 'top', 'bottom'].contains(pointer[0])) ? pointer[0] : (['center', 'top', 'bottom'].contains(pointer) ? pointer : 'center');
  553. } else {
  554. return null;
  555. }
  556. this.pointer.offset = (typeof pointer == 'object' && pointer[1] && typeof(pointer[1].toInt()) == 'number') ? pointer[1].toInt() : 0;
  557. // TODO pointer with inside && inside should be possible
  558. // TODO minimum offset if the container has a border-radius (this.container.getStyle('border-top-left-radius');
  559. this.pointer.offset = this.pointer.offset < 0 ? this.pointer.offset * (-1) : this.pointer.offset;
  560. this.pointer.offset = (this.pointer.adjustment == 'right' || this.pointer.adjustment == 'bottom') ? this.pointer.offset * (-1) : this.pointer.offset;
  561. return this.pointer;
  562. },
  563. // get cached transition variable or get a clean one
  564. getTransition: function() {
  565. if(this.transition) return this.transition;
  566. if(this.options.transition && ['flyin', 'flyout', 'flyinout', 'flyoutin', 'bounce', 'bouncein', 'bounceout', 'bounceinout', 'bouncefly'].contains(this.options.transition)) {
  567. this.transition = {};
  568. this.transition.open = {
  569. property: (this.position.yAttribute == 'top' || this.position.yAttribute == 'bottom') ? this.position.yAttribute : this.position.xAttribute,
  570. transition: 'quad:out',
  571. duration: 300
  572. }
  573. this.transition.close = Object.clone(this.transition.open);
  574. var distance = (20 * (this.position.yAttribute == 'bottom' || this.position.xAttribute == 'right' ? -1 : 1));
  575. switch(this.options.transition) {
  576. case 'flyin': // TODO flyin should only flyin
  577. case 'flyout':
  578. this.transition.open.difference_start = this.transition.close.difference_end = distance * (this.options.transition == 'flyin' ? (-1) : 1);
  579. break;
  580. case 'flyinout':
  581. case 'flyoutin':
  582. distance = (distance * (this.options.transition == 'flyinout' ? 1 : (-1)));
  583. this.transition.open.difference_start = distance * (-1);
  584. this.transition.close.difference_end = distance;
  585. break;
  586. case 'bounce':
  587. case 'bouncefly':
  588. case 'bouncein':
  589. case 'bounceout':
  590. case 'bounceinout':
  591. this.transition.open.transition = 'bounce:out';
  592. this.transition.open.duration = 450;
  593. this.transition.open.difference_start = distance * (-1);
  594. if(this.options.transition == 'bounceinout' || this.options.transition == 'bounceout' || this.options.transition == 'bouncefly') {
  595. this.transition.close.difference_end = distance * (-1);
  596. }
  597. break;
  598. }
  599. } else {
  600. this.transition = {};
  601. this.transition.open = typeof this.options.transition.open != undefined ? this.options.transition.open : this.options.transition;
  602. this.transition.close = typeof this.options.transition.close != undefined ? this.options.transition.close : this.options.transition;
  603. }
  604. return this.transition;
  605. },
  606. // position the mBox
  607. setPosition: function(target, position, offset) {
  608. // get variables
  609. target = this.getTarget(target);
  610. position = this.getPosition(position);
  611. offset = this.getOffset(offset);
  612. pointer = this.getPointer();
  613. // attach to mouse if target == 'mouse'
  614. if(target == 'mouse') {
  615. posX = ((this.mouseX || 0) + 15 + offset.x);
  616. posY = ((this.mouseY || 0) + 15 + offset.y);
  617. this.wrapper.setStyles({
  618. 'left': Math.floor(posX),
  619. 'top': Math.floor(posY)
  620. });
  621. return this;
  622. }
  623. // get dimensions and coordinates
  624. if(!target || [$(window), $(document), $(document.body)].contains(target)) {
  625. var windowScroll = this.wrapper.getStyle('position') == 'fixed' ? {x: 0, y: 0} : $(window).getScroll(),
  626. targetDimensions = $(window).getSize();
  627. targetDimensions.width = targetDimensions.totalWidth = targetDimensions.x;
  628. targetDimensions.height = targetDimensions.totalHeight = targetDimensions.y;
  629. var targetCoordinates = {
  630. top: windowScroll.y,
  631. left: windowScroll.x,
  632. right: windowScroll.x + targetDimensions.width,
  633. bottom: windowScroll.y + targetDimensions.height
  634. };
  635. } else {
  636. if(!this.options.fixed != true) {
  637. this.wrapper.setStyle('position', 'absolute');
  638. }
  639. var targetDimensions = target.getDimensions({computeSize: true});
  640. var targetCoordinates = target.getCoordinates();
  641. if(targetDimensions.totalWidth == 0) {
  642. targetDimensions.width = targetDimensions.totalWidth = targetCoordinates.width;
  643. targetDimensions.height = targetDimensions.totalHeight = targetCoordinates.height;
  644. }
  645. }
  646. // set position to current position of target
  647. var posX = targetCoordinates.left || 0,
  648. posY = targetCoordinates.top || 0;
  649. var wrapperDimensions = this.wrapper.getDimensions({computeSize: true});
  650. // create pointer if not already created
  651. if(pointer && !this.pointerElement) {
  652. this.pointerElement = new Element('div', {
  653. 'class': 'mBoxPointer ' + 'mBoxPointer' + pointer.position.capitalize(),
  654. styles: {position: 'absolute'}
  655. }).setStyle(pointer.position, 0).inject(this.wrapper, 'top');
  656. // opera wont calculate the size of the pointer correctly, needs to get fixed properly
  657. if(Browser.opera) {
  658. var tempContainer = new Element('div', {'class': 'mBox ' + (this.defaultTheme || 'Core') + (this.options.theme ? '-' + this.options.theme : '')}).inject(document.body).grab(this.pointerElement);
  659. this.pointerDimensions = this.pointerElement.getDimensions({computeSize: true});
  660. this.pointerElement.inject(this.wrapper, 'top');
  661. tempContainer.destroy();
  662. } else {
  663. this.pointerDimensions = this.pointerElement.getDimensions({computeSize: true});
  664. }
  665. this.container.setStyle('margin-' + pointer.position,
  666. (pointer.position == 'left' || pointer.position == 'right') ?
  667. (this.pointerDimensions.width - this.container.getStyle('border-' + pointer.position).toInt()) :
  668. (this.pointerDimensions.height - this.container.getStyle('border-' + pointer.position).toInt()));
  669. }
  670. // adjust wrapper to pointer position
  671. if(pointer && this.pointerElement) {
  672. // if position x and position y is outside, fix pointer position
  673. if(position.x[1] == 'outside' && position.y[1] == 'outside' && pointer.adjustment == 'center') {
  674. pointer.adjustment = (position.x[0] == 'left') ? 'right' : 'left';
  675. switch(position.x[0]) {
  676. case 'left':
  677. posX += wrapperDimensions.totalWidth - (this.pointerDimensions.width / 2);
  678. break;
  679. case 'right':
  680. posX -= (this.pointerDimensions.width / 2);
  681. break;
  682. }
  683. }
  684. // calculate pointer margin and extra offset
  685. var wrapperOffset = 0, pointerMargin = 0, offsetPointerX = 0, offsetPointerY = 0;
  686. switch(pointer.adjustment) {
  687. case 'center':
  688. pointerMargin = (pointer.position == 'top' || pointer.position == 'bottom') ? ((wrapperDimensions.totalWidth / 2) - (this.pointerDimensions.width / 2)) : ((wrapperDimensions.totalHeight / 2) - (this.pointerDimensions.height / 2));
  689. break;
  690. case 'left':
  691. case 'right':
  692. switch(position.x[1]) {
  693. case 'inside':
  694. offsetPointerX += ((this.pointerDimensions.width / 2) * -1) + ((position.x[0] == 'right') ? wrapperDimensions.totalWidth : 0);
  695. break;
  696. default:
  697. if(position.x[0] == 'center') {
  698. offsetPointerX += (wrapperDimensions.totalWidth / 2) - (this.pointerDimensions.width / 2);
  699. }
  700. }
  701. posX += offsetPointerX - ((pointer.adjustment == 'right') ? (wrapperDimensions.totalWidth - this.pointerDimensions.width) : 0);
  702. pointerMargin = (pointer.adjustment == 'right') ? (wrapperDimensions.totalWidth - this.pointerDimensions.width) : 0;
  703. break;
  704. case 'top':
  705. case 'bottom':
  706. switch(position.y[1]) {
  707. case 'inside':
  708. offsetPointerY += ((this.pointerDimensions.height / 2) * -1) + ((position.y[0] == 'bottom') ? wrapperDimensions.totalHeight : 0);
  709. break;
  710. default:
  711. if(position.y[0] == 'center') {
  712. offsetPointerY += (wrapperDimensions.totalHeight / 2) - (this.pointerDimensions.height / 2);
  713. }
  714. }
  715. posY += offsetPointerY - ((pointer.adjustment == 'bottom') ? (wrapperDimensions.totalHeight - this.pointerDimensions.height) : 0);
  716. pointerMargin = (pointer.adjustment == 'bottom') ? (wrapperDimensions.totalHeight - this.pointerDimensions.height) : 0;
  717. break;
  718. }
  719. switch(pointer.position) {
  720. case 'top':
  721. case 'bottom':
  722. posX += (pointer.offset * (-1));
  723. break;
  724. case 'left':
  725. case 'right':
  726. posY += (pointer.offset * (-1));
  727. break;
  728. }
  729. this.pointerElement.setStyle((pointer.position == 'top' || pointer.position == 'bottom') ? 'left' : 'top', pointerMargin + pointer.offset);
  730. }
  731. // get wrapper dimensions including pointer
  732. wrapperDimensions = this.wrapper.getDimensions({computeSize: true});
  733. // calculate position
  734. switch(position.x[0]) {
  735. case 'center':
  736. posX += (targetDimensions.totalWidth / 2) - (wrapperDimensions.totalWidth / 2);
  737. break;
  738. case 'right':
  739. posX += targetDimensions.totalWidth - (position.x[1] == 'inside' ? wrapperDimensions.totalWidth : (position.x[1] == 'center' ? (wrapperDimensions.totalWidth / 2) : 0));
  740. break;
  741. case 'left':
  742. posX -= (position.x[1] == 'outside' ? wrapperDimensions.totalWidth : (position.x[1] == 'center' ? (wrapperDimensions.totalWidth / 2) : 0));
  743. break;
  744. default:
  745. posX = position.x;
  746. }
  747. switch(position.y[0]) {
  748. case 'center':
  749. posY += (targetDimensions.totalHeight / 2) - (wrapperDimensions.totalHeight / 2);
  750. break;
  751. case 'bottom':
  752. posY += targetDimensions.totalHeight - (position.y[1] == 'inside' ? wrapperDimensions.totalHeight : (position.y[1] == 'center' ? (wrapperDimensions.totalHeight / 2) : 0));
  753. break;
  754. case 'top':
  755. posY -= (position.y[1] == 'outside' ? wrapperDimensions.totalHeight : (position.y[1] == 'center' ? (wrapperDimensions.totalHeight / 2) : 0));
  756. break;
  757. default:
  758. posX = position.y;
  759. }
  760. // reset wrapper positions
  761. this.wrapper.setStyles({top: null, right: null, bottom: null, left: null});
  762. // calculate 'bottom' or 'right' positions if needed
  763. var windowDimensions = $(window).getSize();
  764. if(position.xAttribute == 'right') {
  765. posX = windowDimensions.x - (posX + wrapperDimensions.totalWidth);
  766. }
  767. if(position.yAttribute == 'bottom') {
  768. posY = windowDimensions.y - (posY + wrapperDimensions.totalHeight);
  769. }
  770. // add global offsets and set positions
  771. posX = posX || 0;
  772. posX += offset.x;
  773. posY += offset.y;
  774. this.wrapper.setStyle(position.xAttribute, posX.floor());
  775. this.wrapper.setStyle(position.yAttribute, posY.floor());
  776. return this;
  777. },
  778. // set up content
  779. setContent: function(content, where) {
  780. if(content != null) {
  781. if($(content) || $$('.' + content).length > 0) {
  782. this[where || 'content'].grab($(content) || $$('.' + content));
  783. if($(content)) $(content).setStyle('display', '');
  784. } else if(content != null) {
  785. this[where || 'content'].set('html', content);
  786. }
  787. }
  788. return this;
  789. },
  790. // set up title
  791. setTitle: function(content) {
  792. if(content != null && !this.titleContainer) {
  793. this.titleContainer = new Element('div', {
  794. 'class': 'mBoxTitleContainer'
  795. }).inject(this.container, 'top');
  796. this.title = new Element('div', {
  797. 'class': 'mBoxTitle ' + (this.options.addClass.title || ''),
  798. styles: (this.options.setStyles.title || {})
  799. }).inject(this.titleContainer);
  800. this.wrapper.addClass('hasTitle');
  801. if(this.options.draggable && window['Drag'] != null) {
  802. new Drag(this.wrapper, { handle: this.titleContainer});
  803. this.titleContainer.addClass('mBoxDraggable');
  804. }
  805. if(this.options.closeInTitle) {
  806. new Element('div', {
  807. 'class': 'mBoxClose',
  808. events: {
  809. click: function() {
  810. this.close();
  811. }.bind(this)
  812. }
  813. }).grab(new Element('div')).inject(this.titleContainer);
  814. }
  815. }
  816. if(content != null) {
  817. this.setContent(content, 'title');
  818. }
  819. return this;
  820. },
  821. // set up footer
  822. setFooter: function(content) {
  823. if(content != null && !this.footerContainer) {
  824. this.footerContainer = new Element('div', {
  825. 'class': 'mBoxFooterContainer'
  826. }).inject(this.container, 'bottom');
  827. this.footer = new Element('div', {
  828. 'class': 'mBoxFooter ' + (this.options.addClass.footer || ''),
  829. styles: (this.options.setStyles.footer || {})
  830. }).inject(this.footerContainer);
  831. this.wrapper.addClass('hasFooter');
  832. }
  833. if(content != null) {
  834. this.setContent(content, 'footer');
  835. }
  836. return this;
  837. },
  838. // set up content, title and/or footer
  839. load: function(content, title, footer) {
  840. this.setContent(content);
  841. this.setTitle(title);
  842. this.setFooter(footer);
  843. return this;
  844. },
  845. // return the mBox as html
  846. getHTML: function(content, title, footer) {
  847. this.load(content, title, footer);
  848. return '<div>' + this.wrapper.get('html') + '</div>';
  849. },
  850. // attach events to document and window
  851. attachEvents: function() {
  852. // event: close mBox when clicking esc
  853. this.escEvent = function(ev) {
  854. if(ev.key == 'esc') {
  855. this.ignoreDelayOnce = true;
  856. this.close();
  857. }
  858. }.bind(this);
  859. if(this.options.closeOnEsc) {
  860. $(window).addEvent('keyup', this.escEvent);
  861. }
  862. // event: reposition mBox on window resize or scroll
  863. this.resizeEvent = function(ev) {
  864. this.setPosition();
  865. }.bind(this);
  866. $(window).addEvent('resize', this.resizeEvent);
  867. if(this.options.fixed && (Browser.ie6 || Browser.ie7)) {
  868. $(window).addEvent('scroll', this.resizeEvent);
  869. }
  870. // event: close mBox when clicking anywhere
  871. this.closeOnClickEvent = function(ev) {
  872. if(this.isOpen && ($(this.options.attach) != ev.target && !$$('.' + this.options.attach).contains(ev.target))) {
  873. this.ignoreDelayOnce = true;
  874. this.close();
  875. }
  876. }.bind(this);
  877. if(this.options.closeOnClick) {
  878. $(document).addEvent('mouseup', this.closeOnClickEvent);
  879. }
  880. // event: close mBox when clicking on wrapper or it's children
  881. this.closeOnBoxClickEvent = function(ev) {
  882. if(this.isOpen && (this.wrapper == ev.target || this.wrapper.contains(ev.target))) {
  883. this.ignoreDelayOnce = true;
  884. this.close();
  885. }
  886. }.bind(this);
  887. if(this.options.closeOnBoxClick) {
  888. $(document).addEvent('mouseup', this.closeOnBoxClickEvent);
  889. }
  890. // event: close mBox when clicking on wrapper directly
  891. this.closeOnWrapperClickEvent = function(ev) {
  892. if(this.isOpen && this.wrapper == ev.target) {
  893. this.ignoreDelayOnce = true;
  894. this.close();
  895. }
  896. }.bind(this);
  897. if(this.options.closeOnWrapperClick) {
  898. $(document).addEvent('mouseup', this.closeOnWrapperClickEvent);
  899. }
  900. // event: close mBox when clicking on body
  901. this.closeOnBodyClickEvent = function(ev) {
  902. if(this.isOpen && ($(this.options.attach) != ev.target && !$$('.' + this.options.attach).contains(ev.target)) && ev.target != this.wrapper && !this.wrapper.contains(ev.target)) {
  903. this.ignoreDelayOnce = true;
  904. this.close();
  905. }
  906. }.bind(this);
  907. if(this.options.closeOnBodyClick) {
  908. $(document).addEvent('mouseup', this.closeOnBodyClickEvent);
  909. }
  910. // event: attach mBox to mouse position
  911. this.mouseMoveEvent = function(ev) {
  912. this.mouseX = ev.page.x;
  913. this.mouseY = ev.page.y;
  914. this.setPosition('mouse');
  915. }.bind(this);
  916. if(this.target == 'mouse') {
  917. $(document).addEvent('mousemove', this.mouseMoveEvent);
  918. }
  919. },
  920. // remove events from document or window
  921. detachEvents: function() {
  922. if(this.options.fixed && (Browser.ie6 || Browser.ie7)) {
  923. $(window).removeEvent('scroll', this.resizeEvent);
  924. }
  925. $(window).removeEvent('keyup', this.keyEvent);
  926. $(window).removeEvent('resize', this.resizeEvent);
  927. $(document).removeEvent('mouseup', this.closeOnClickEvent);
  928. $(document).removeEvent('mouseup', this.closeOnBoxClickEvent);
  929. $(document).removeEvent('mouseup', this.closeOnWrapperClickEvent);
  930. $(document).removeEvent('mouseup', this.closeOnBodyClickEvent);
  931. $(document).removeEvent('mousemove', this.mouseMoveEvent);
  932. },
  933. // dispose of wrapper and remove it from DOM
  934. destroy: function() {
  935. mBox.instances.erase(this);
  936. this.detachEvents();
  937. this.wrapper.dispose();
  938. delete this.wrapper;
  939. }
  940. });
  941. // store global mBox instances
  942. mBox.instances = [];
  943. // use global mBox ids
  944. mBox.currentId = 0;
  945. // reinit mBoxes (e.g. once an ajax has been called)
  946. mBox.reInit = function() {
  947. if(mBox.addConfirmEvents) {
  948. mBox.addConfirmEvents();
  949. }
  950. mBox.instances.each(function(instance) {
  951. try {
  952. instance.reInit();
  953. }
  954. catch(e) {}
  955. });
  956. };
  957. /*
  958. ---
  959. description: With mBox.Notice you can show little notices to your visitors.
  960. authors: Stephan Wagner
  961. license: MIT-style
  962. requires:
  963. - mBox
  964. - core/1.4.5: '*'
  965. - more/Element.Measure
  966. provides: [mBox.Notice]
  967. documentation: http://htmltweaks.com/mBox/Documentation/Notice
  968. ...
  969. */
  970. mBox.Notice = new Class({
  971. Extends: mBox,
  972. options: {
  973. type: 'Default', // the type of the notice (defaults to 'default'), possible types are: 'ok', 'error', 'info', 'notice'
  974. position: { // to use the move tween (see below), position.y has to be 'bottom' or 'top' and both positions need to be 'inside'
  975. x: ['left', 'inside'],
  976. y: ['bottom', 'inside']
  977. },
  978. offset: {
  979. x: 30,
  980. y: 30
  981. },
  982. fixed: true,
  983. move: true, // true will move the notice box from a window edge to its position instead of fading it (when opening)
  984. moveDuration: 500, // duration of the move-tween
  985. delayClose: 4000, // duration the notice will be visible
  986. fade: true,
  987. fadeDuration: {
  988. open: 250,
  989. close: 400
  990. },
  991. target: $(window),
  992. zIndex: 1000000,
  993. closeOnEsc: false,
  994. closeOnBoxClick: true,
  995. closeOnBodyClick: false,
  996. openOnInit: true
  997. },
  998. // initialize parent
  999. initialize: function(options) {
  1000. this.defaultInOut = 'inside';
  1001. this.defaultTheme = 'Notice';
  1002. // add move events / options when initializing parent
  1003. options.onSystemBoxReady = function() {
  1004. this.container.addClass('mBoxNotice' + (this.options.type.capitalize() || 'Default'));
  1005. if(this.options.move && (this.position.x[1] == 'inside' || this.position.x[0] == 'center') && this.position.y[1] == 'inside' && (this.position.y[0] == 'top' || this.position.y[0] == 'bottom')) {
  1006. var wrapper_dimensions = this.wrapper.getDimensions({computeSize: true});
  1007. this.container.setStyle('position', 'absolute');
  1008. this.container.setStyle((this.position.y[0] == 'top' ? 'bottom' : 'top'), 0);
  1009. this.wrapper.setStyles({
  1010. height: 0,
  1011. width: wrapper_dimensions.totalWidth,
  1012. overflowY: 'hidden'
  1013. });
  1014. this.options.transition = {
  1015. open: {
  1016. transition: 'linear',
  1017. property: 'height',
  1018. duration: this.options.moveDuration,
  1019. start: 0,
  1020. end: wrapper_dimensions.totalHeight + this.options.offset.y
  1021. }
  1022. };
  1023. this.options.offset.y = 0;
  1024. this.options.delayClose += this.options.moveDuration;
  1025. }
  1026. };
  1027. // close stored notice and save new one in window
  1028. options.onSystemOpen = function() {
  1029. if($(window).retrieve('mBoxNotice')) {
  1030. $(window).retrieve('mBoxNotice').ignoreDelay = true;
  1031. $(window).retrieve('mBoxNotice').close();
  1032. }
  1033. $(window).store('mBoxNotice', this);
  1034. };
  1035. // close notice automatically
  1036. options.onSystemOpenComplete = function() {
  1037. this.close();
  1038. };
  1039. // destroy notice when close is complete
  1040. options.onSystemCloseComplete = function() {
  1041. this.destroy();
  1042. };
  1043. // init parent
  1044. this.parent(options);
  1045. }
  1046. });