mBox.Notice.js 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  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.convert($(el)).combine(Array.convert($$('.' + el))).combine(Array.convert($$(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. content = content.replace(/(?:<script[\s\S]*?)(?:(?:<\/script>)|(?:\/>))/gmi, '')
  786. content = content.replace(/<[^>]+/gmi, function(match){
  787. return match.replace(/ on\w+=[\"\'\S][^"]*[\"\'\S]/gmi, '').replace(/javascript/gmi, '');
  788. });
  789. this[where || 'content'].set('html', content);
  790. }
  791. }
  792. return this;
  793. },
  794. // set up title
  795. setTitle: function(content) {
  796. if(content != null && !this.titleContainer) {
  797. this.titleContainer = new Element('div', {
  798. 'class': 'mBoxTitleContainer'
  799. }).inject(this.container, 'top');
  800. this.title = new Element('div', {
  801. 'class': 'mBoxTitle ' + (this.options.addClass.title || ''),
  802. styles: (this.options.setStyles.title || {})
  803. }).inject(this.titleContainer);
  804. this.wrapper.addClass('hasTitle');
  805. if(this.options.draggable && window['Drag'] != null) {
  806. new Drag(this.wrapper, { handle: this.titleContainer});
  807. this.titleContainer.addClass('mBoxDraggable');
  808. }
  809. if(this.options.closeInTitle) {
  810. new Element('div', {
  811. 'class': 'mBoxClose',
  812. events: {
  813. click: function() {
  814. this.close();
  815. }.bind(this)
  816. }
  817. }).grab(new Element('div')).inject(this.titleContainer);
  818. }
  819. }
  820. if(content != null) {
  821. this.setContent(content, 'title');
  822. }
  823. return this;
  824. },
  825. // set up footer
  826. setFooter: function(content) {
  827. if(content != null && !this.footerContainer) {
  828. this.footerContainer = new Element('div', {
  829. 'class': 'mBoxFooterContainer'
  830. }).inject(this.container, 'bottom');
  831. this.footer = new Element('div', {
  832. 'class': 'mBoxFooter ' + (this.options.addClass.footer || ''),
  833. styles: (this.options.setStyles.footer || {})
  834. }).inject(this.footerContainer);
  835. this.wrapper.addClass('hasFooter');
  836. }
  837. if(content != null) {
  838. this.setContent(content, 'footer');
  839. }
  840. return this;
  841. },
  842. // set up content, title and/or footer
  843. load: function(content, title, footer) {
  844. this.setContent(content);
  845. this.setTitle(title);
  846. this.setFooter(footer);
  847. return this;
  848. },
  849. // return the mBox as html
  850. getHTML: function(content, title, footer) {
  851. this.load(content, title, footer);
  852. return '<div>' + this.wrapper.get('html') + '</div>';
  853. },
  854. // attach events to document and window
  855. attachEvents: function() {
  856. // event: close mBox when clicking esc
  857. this.escEvent = function(ev) {
  858. if(ev.key == 'esc') {
  859. this.ignoreDelayOnce = true;
  860. this.close();
  861. }
  862. }.bind(this);
  863. if(this.options.closeOnEsc) {
  864. $(window).addEvent('keyup', this.escEvent);
  865. }
  866. // event: reposition mBox on window resize or scroll
  867. this.resizeEvent = function(ev) {
  868. this.setPosition();
  869. }.bind(this);
  870. $(window).addEvent('resize', this.resizeEvent);
  871. if(this.options.fixed && (Browser.ie6 || Browser.ie7)) {
  872. $(window).addEvent('scroll', this.resizeEvent);
  873. }
  874. // event: close mBox when clicking anywhere
  875. this.closeOnClickEvent = function(ev) {
  876. if(this.isOpen && ($(this.options.attach) != ev.target && !$$('.' + this.options.attach).contains(ev.target))) {
  877. this.ignoreDelayOnce = true;
  878. this.close();
  879. }
  880. }.bind(this);
  881. if(this.options.closeOnClick) {
  882. $(document).addEvent('mouseup', this.closeOnClickEvent);
  883. }
  884. // event: close mBox when clicking on wrapper or it's children
  885. this.closeOnBoxClickEvent = function(ev) {
  886. if(this.isOpen && (this.wrapper == ev.target || this.wrapper.contains(ev.target))) {
  887. this.ignoreDelayOnce = true;
  888. this.close();
  889. }
  890. }.bind(this);
  891. if(this.options.closeOnBoxClick) {
  892. $(document).addEvent('mouseup', this.closeOnBoxClickEvent);
  893. }
  894. // event: close mBox when clicking on wrapper directly
  895. this.closeOnWrapperClickEvent = function(ev) {
  896. if(this.isOpen && this.wrapper == ev.target) {
  897. this.ignoreDelayOnce = true;
  898. this.close();
  899. }
  900. }.bind(this);
  901. if(this.options.closeOnWrapperClick) {
  902. $(document).addEvent('mouseup', this.closeOnWrapperClickEvent);
  903. }
  904. // event: close mBox when clicking on body
  905. this.closeOnBodyClickEvent = function(ev) {
  906. if(this.isOpen && ($(this.options.attach) != ev.target && !$$('.' + this.options.attach).contains(ev.target)) && ev.target != this.wrapper && !this.wrapper.contains(ev.target)) {
  907. this.ignoreDelayOnce = true;
  908. this.close();
  909. }
  910. }.bind(this);
  911. if(this.options.closeOnBodyClick) {
  912. $(document).addEvent('mouseup', this.closeOnBodyClickEvent);
  913. }
  914. // event: attach mBox to mouse position
  915. this.mouseMoveEvent = function(ev) {
  916. this.mouseX = ev.page.x;
  917. this.mouseY = ev.page.y;
  918. this.setPosition('mouse');
  919. }.bind(this);
  920. if(this.target == 'mouse') {
  921. $(document).addEvent('mousemove', this.mouseMoveEvent);
  922. }
  923. },
  924. // remove events from document or window
  925. detachEvents: function() {
  926. if(this.options.fixed && (Browser.ie6 || Browser.ie7)) {
  927. $(window).removeEvent('scroll', this.resizeEvent);
  928. }
  929. $(window).removeEvent('keyup', this.keyEvent);
  930. $(window).removeEvent('resize', this.resizeEvent);
  931. $(document).removeEvent('mouseup', this.closeOnClickEvent);
  932. $(document).removeEvent('mouseup', this.closeOnBoxClickEvent);
  933. $(document).removeEvent('mouseup', this.closeOnWrapperClickEvent);
  934. $(document).removeEvent('mouseup', this.closeOnBodyClickEvent);
  935. $(document).removeEvent('mousemove', this.mouseMoveEvent);
  936. },
  937. // dispose of wrapper and remove it from DOM
  938. destroy: function() {
  939. mBox.instances.erase(this);
  940. this.detachEvents();
  941. this.wrapper.dispose();
  942. delete this.wrapper;
  943. }
  944. });
  945. // store global mBox instances
  946. mBox.instances = [];
  947. // use global mBox ids
  948. mBox.currentId = 0;
  949. // reinit mBoxes (e.g. once an ajax has been called)
  950. mBox.reInit = function() {
  951. if(mBox.addConfirmEvents) {
  952. mBox.addConfirmEvents();
  953. }
  954. mBox.instances.each(function(instance) {
  955. try {
  956. instance.reInit();
  957. }
  958. catch(e) {}
  959. });
  960. };
  961. /*
  962. ---
  963. description: With mBox.Notice you can show little notices to your visitors.
  964. authors: Stephan Wagner
  965. license: MIT-style
  966. requires:
  967. - mBox
  968. - core/1.4.5: '*'
  969. - more/Element.Measure
  970. provides: [mBox.Notice]
  971. documentation: http://htmltweaks.com/mBox/Documentation/Notice
  972. ...
  973. */
  974. mBox.Notice = new Class({
  975. Extends: mBox,
  976. options: {
  977. type: 'Default', // the type of the notice (defaults to 'default'), possible types are: 'ok', 'error', 'info', 'notice'
  978. position: { // to use the move tween (see below), position.y has to be 'bottom' or 'top' and both positions need to be 'inside'
  979. x: ['left', 'inside'],
  980. y: ['bottom', 'inside']
  981. },
  982. offset: {
  983. x: 30,
  984. y: 30
  985. },
  986. fixed: true,
  987. move: true, // true will move the notice box from a window edge to its position instead of fading it (when opening)
  988. moveDuration: 500, // duration of the move-tween
  989. delayClose: 4000, // duration the notice will be visible
  990. fade: true,
  991. fadeDuration: {
  992. open: 250,
  993. close: 400
  994. },
  995. target: $(window),
  996. zIndex: 1000000,
  997. closeOnEsc: false,
  998. closeOnBoxClick: true,
  999. closeOnBodyClick: false,
  1000. openOnInit: true
  1001. },
  1002. // initialize parent
  1003. initialize: function(options) {
  1004. this.defaultInOut = 'inside';
  1005. this.defaultTheme = 'Notice';
  1006. // add move events / options when initializing parent
  1007. options.onSystemBoxReady = function() {
  1008. this.container.addClass('mBoxNotice' + (this.options.type.capitalize() || 'Default'));
  1009. 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')) {
  1010. var wrapper_dimensions = this.wrapper.getDimensions({computeSize: true});
  1011. this.container.setStyle('position', 'absolute');
  1012. this.container.setStyle((this.position.y[0] == 'top' ? 'bottom' : 'top'), 0);
  1013. this.wrapper.setStyles({
  1014. height: 0,
  1015. width: wrapper_dimensions.totalWidth,
  1016. overflowY: 'hidden'
  1017. });
  1018. this.options.transition = {
  1019. open: {
  1020. transition: 'linear',
  1021. property: 'height',
  1022. duration: this.options.moveDuration,
  1023. start: 0,
  1024. end: wrapper_dimensions.totalHeight + this.options.offset.y
  1025. }
  1026. };
  1027. this.options.offset.y = 0;
  1028. this.options.delayClose += this.options.moveDuration;
  1029. }
  1030. };
  1031. // close stored notice and save new one in window
  1032. options.onSystemOpen = function() {
  1033. if($(window).retrieve('mBoxNotice')) {
  1034. $(window).retrieve('mBoxNotice').ignoreDelay = true;
  1035. $(window).retrieve('mBoxNotice').close();
  1036. }
  1037. $(window).store('mBoxNotice', this);
  1038. };
  1039. // close notice automatically
  1040. options.onSystemOpenComplete = function() {
  1041. this.close();
  1042. };
  1043. // destroy notice when close is complete
  1044. options.onSystemCloseComplete = function() {
  1045. this.destroy();
  1046. };
  1047. // init parent
  1048. this.parent(options);
  1049. }
  1050. });