var saku, postForm; var UPLOADING_MSG = 'Uploading...'; var PLACEHOLDER = '〉〉〉'; connSM.on('synced', postSM.feeder('sync')); connSM.on('dropped', postSM.feeder('desync')); connSM.on('desynced', postSM.feeder('desync')); postSM.act('* + desync -> none', function () { if (postForm) { postForm.$el.removeClass('editing'); postForm.$input.val(''); postForm.finish(); } $('aside').remove(); }); postSM.act('none + sync, draft, alloc + done -> ready', function () { if (postForm) { postForm.remove(); postForm = null; saku = null; } insert_pbs(); var m = window.location.hash.match(/^#q(\d+)$/); if (m) { var id = parseInt(m[1], 10); if ($('#' + id).hasClass('highlight')) { window.location.hash = '#' + id; open_post_box(id); postForm.add_ref(id); } } }); postSM.act('ready + new -> draft', function (aside) { var op = null; var $sec = aside.closest('section'); if ($sec.length) { op = extract_num($sec); } else { $sec = $('
'); } saku = new Saku({op: op}); postForm = new ComposerView({model: saku, dest: aside, thread: $sec}); }); postSM.preflight('draft', function (aside) { return aside.is('aside'); }); postSM.act('draft + alloc -> alloc', function (msg) { postForm.on_allocation(msg); }); $DOC.on('click', 'aside a', _.wrap(function () { postSM.feed('new', $(this).parent()); }, with_dom)); $DOC.on('keydown', handle_shortcut); var vapor = 0, wombo = 0, eject = 0; menuHandlers.Eject = function () { vapor = wombo = eject = 0; ComposerView.prototype.word_filter = function (w) { return w; }; flash_bg('white'); }; function handle_shortcut(event) { var k = event.which; if (vapor < 0 || wombo < 0) { if (event.shiftKey && k == [69,74,69,67,84,49][eject]) { if (++eject >= 6) { menuHandlers.Eject(); event.stopImmediatePropagation(); event.preventDefault(); } } else eject = 0; } else if (event.shiftKey && k > 85 && k < 88) { if (k == 86 && ++vapor > 10) { menuHandlers.Vapor(); event.stopImmediatePropagation(); event.preventDefault(); } if (k == 87 && ++wombo > 10) { wombo = -1; $.getScript(mediaURL + 'js/wordfilter.js'); } } else vapor = wombo = 0; if (!event.altKey) return; var used = false; switch (event.which) { case shortcutKeys['new']: var $aside = THREAD ? $('aside') : $ceiling.next(); if ($aside.is('aside') && $aside.length == 1) { with_dom(function () { postSM.feed('new', $aside); }); used = true; } break; case shortcutKeys.togglespoiler: if (postForm) { postForm.on_toggle(event); used = true; } break; case shortcutKeys.done: if (postForm) { if (!postForm.submit.attr('disabled')) { postForm.finish_wrapped(); used = true; } } break; case shortcutKeys.flip: menuHandlers.Flip(); used = true; break; } if (used) { event.stopImmediatePropagation(); event.preventDefault(); } } function open_post_box(num) { var a = $('#' + num); postSM.feed('new', a.is('section') ? a.children('aside') : a.siblings('aside')); } function make_reply_box() { return $(''); } function insert_pbs() { if (hot.get('readOnly') || readOnly.indexOf(BOARD) >= 0) return; if (THREAD ? $('aside').length : $ceiling.next().is('aside')) return; make_reply_box().appendTo('section'); if (!nashi.upload && BUMP) $ceiling.after(''); } function get_nonces() { var nonces; if (window.localStorage) { try { nonces = JSON.parse(localStorage.postNonces); } catch (e) {} } else { nonces = ComposerView.nonces; } return nonces || {}; } function save_nonces(nonces) { if (window.localStorage) localStorage.postNonces = JSON.stringify(nonces); else ComposerView.nonces = nonces; } function today_id() { return Math.floor(new Date().getTime() / (1000*60*60*24)); } function create_nonce() { var nonces = get_nonces(); var nonce = random_id(); nonces[nonce] = { tab: TAB_ID, day: today_id(), }; save_nonces(nonces); return nonce; } function expire_nonces() { if (!window.localStorage) return; // we need a lock on postNonces really var nonces = get_nonces(); // people messing with their system clock will mess with expiry, doh var changed = false; var yesterday = today_id() - 1; for (var nonce in nonces) { if (nonces[nonce].day >= yesterday) continue; delete nonces[nonce]; changed = true; } if (changed) save_nonces(nonces); } setTimeout(expire_nonces, Math.floor(Math.random()*5000)); function destroy_nonce(nonce) { var nonces = get_nonces(); if (!nonces[nonce]) return; delete nonces[nonce]; save_nonces(nonces); } var Saku = Backbone.Model.extend({ idAttribute: 'num', }); var ComposerView = Backbone.View.extend({ events: { 'input #subject': model_link('subject'), 'keydown #trans': 'on_key_down', 'click #done': 'finish_wrapped', 'click #toggle': 'on_toggle', }, initialize: function (dest) { this.listenTo(this.model, 'change', this.render_buttons); this.listenTo(this.model, 'change:spoiler', this.render_spoiler_pane); this.listenTo(this.model, 'change:floop', this.render_floop); var attrs = this.model.attributes; var op = attrs.op; var post = op ? $('
') : this.options.thread; this.setElement(post[0]); this.buffer = $('

'); this.line_buffer = $('

'); this.meta = $('

'); this.$input = $('