const Blockbench = { isWeb: !isApp, isMobile: window.innerWidth <= 480, version: appVersion, platform: 'web', flags: [], drag_handlers: {}, events: {}, openTime: new Date(), get elements() { console.warn('Blockbench.elements is deprecated. Please use Outliner.elements instead.') return Outliner.elements }, get selection() { console.warn('Blockbench.selection is deprecated. Please use Cube.selected or Outliner.selected instead.') return Cube.selected }, get textures() { console.warn('Blockbench.textures is deprecated. Please just use textures instead.') return textures; }, edit(aspects, cb) { Undo.initEdit(aspects) cb() Undo.finishEdit() }, reload() { localStorage.removeItem('backup_model') if (isApp) { Blockbench.addFlag('allow_closing') Blockbench.addFlag('allow_reload') currentwindow.reload() } else { location.reload() } }, registerEdit() { console.warn('Blockbench.registerEdit is outdated. Please use Undo.initEdit and Undo.finishEdit') }, //Interface getIconNode(icon, color) { let node; if (typeof icon === 'function') { icon = icon() } if (icon === undefined) { //Missing node = document.createElement('i'); node.classList.add('material-icons', 'icon'); node.innerText = 'help_outline'; } else if (icon instanceof HTMLElement) { //Node node = icon } else if (icon === null) { //Node node = document.createElement('i'); node.classList.add('fa_big', 'icon'); } else if (icon.substr(0, 2) === 'fa') { //Font Awesome node = document.createElement('i'); node.classList.add('fa_big', 'icon'); if (icon.substr(3, 1) === '.') { node.classList.add(icon.substr(0, 3), icon.substr(4)); } else { node.classList.add('fa', icon); } } else if (icon.substr(0, 5) === 'icon-') { //Icomoon node = document.createElement('i'); node.classList.add(icon, 'icon'); } else if (icon.substr(0, 14) === 'data:image/png') { //Data URL node = document.createElement('img'); node.classList.add('icon'); node.src = icon; } else { //Material Icon node = document.createElement('i'); node.classList.add('material-icons', 'icon'); node.innerText = icon; } if (color) { if (color === 'x') { node.classList.add('color_x'); } else if (color === 'y') { node.classList.add('color_y'); } else if (color === 'z') { node.classList.add('color_z'); } else if (typeof color === 'string') { node.style.color = color; } } return node }, showQuickMessage(message, time) { $('#quick_message_box').remove() var quick_message_box = $('') $('body').append(quick_message_box) quick_message_box.text(tl(message)) quick_message_box.fadeIn(0) setTimeout(function() { quick_message_box.fadeOut(0) setTimeout(function() { quick_message_box.remove() }, 1) }, time ? time : 1000) }, showCenterTip(message, time) { $('#center_tip').remove() var center_tip = $(`
info${tl(message)}
`) $('#preview').append(center_tip) setTimeout(function() { center_tip.fadeOut(0) setTimeout(function() { center_tip.remove() }, 1) }, time ? time : 7500) }, showStatusMessage(message, time) { Blockbench.setStatusBarText(tl(message)) setTimeout(function() { Blockbench.setStatusBarText() }, time ? time : 800) }, setStatusBarText(text) { if (text !== undefined) { Prop.file_name = text } else { Prop.file_name = Prop.file_name_alt||'' } }, setProgress(progress, time, bar) { setProgressBar(bar, progress||0, time) }, showMessage(message, location) { if (location === 'status_bar') { Blockbench.showStatusMessage(message) } else if (location === 'center') { Blockbench.showQuickMessage(message) } }, showMessageBox(options, cb) { if (options.confirm === undefined) options.confirm = 0 if (options.cancel === undefined) options.cancel = 0 if (!options.buttons) options.buttons = [tl('dialog.ok')] if (options.translateKey) { if (!options.title) options.title = tl('message.'+options.translateKey+'.title') if (!options.message) options.message = tl('message.'+options.translateKey+'.message') } var jq_dialog = $('
'+options.title+'
') jq_dialog.append('
'+ marked(tl(options.message))+'
' ) if (options.icon) { jq_dialog.find('.dialog_bar').prepend($(Blockbench.getIconNode(options.icon)).addClass('message_box_icon')) } var buttons = [] options.buttons.forEach(function(b, i) { var btn = $('') btn.click(function(e) { hideDialog() setTimeout(function() { jq_dialog.remove() },200) if (cb) { cb(i) } }) buttons.push(btn) }) jq_dialog.hide = function() { $(jq_dialog.find('button').get(options.cancel)).click() } buttons[options.confirm].addClass('confirm_btn') buttons[options.cancel].addClass('cancel_btn') jq_dialog.append($('
').append(buttons)) buttons.forEach(b => { b.after(' ') }) jq_dialog.addClass('draggable') jq_dialog.draggable({ handle: ".dialog_handle", containment: '#page_wrapper' }) var x = ($(window).width()-540)/2 jq_dialog.css('left', x+'px') jq_dialog.css('position', 'absolute') $('#plugin_dialog_wrapper').append(jq_dialog) $('.dialog').hide() $('#blackout').show() jq_dialog.show() jq_dialog.css('top', limitNumber($(window).height()/2-jq_dialog.height()/2 - 140, 0, 2000)+'px') if (options.width) { jq_dialog.css('width', options.width+'px') } else { jq_dialog.css('width', limitNumber(options.buttons.length*170+44, 380, 894)+'px') } open_dialog = 'message_box' open_interface = 'message_box' return jq_dialog }, textPrompt(title, value, callback) { showDialog('text_input') $('#text_input h2').text(tl(title)) $('#text_input input#text_input_field').val(value).select() $('#text_input button.confirm_btn').off() $('#text_input button.confirm_btn').click(function() { var s = $('#text_input input#text_input_field').val() if (callback !== undefined) { callback(s) } }) }, addMenuEntry(name, icon, click) { var action = new Action(name, {icon: icon, name: name, click: click}) MenuBar.addAction(action, 'filter') }, removeMenuEntry(name) { MenuBar.removeAction('filter.'+name) }, openLink(link) { if (isApp) { shell.openExternal(link) } else { window.open(link) } }, notification(title, text, icon) { Notification.requestPermission().then(status => { if (status == 'granted') { let n = new Notification(title, {body: text, icon: icon||'favicon.png'}) n.onclick = function() { if (isApp) { currentwindow.focus(); } else { window.focus(); } } } }) }, //IO import(options, cb) { if (typeof options !== 'object') {options = {}} //extensions //type //readtype //multiple //startpath //title //errorbox //resource_id if (isApp) { var properties = [] if (options.multiple) { properties.push('multiSelections') } if (options.extensions[0] === 'image/*') { options.type = 'Images' options.extensions = ['png', 'jpg', 'jpeg', 'bmp', 'tiff', 'tif', 'gif'] } if (!options.startpath && options.resource_id) { options.startpath = StateMemory.dialog_paths[options.resource_id] } ElecDialogs.showOpenDialog( currentwindow, { title: options.title ? options.title : '', dontAddToRecent: true, filters: [{ name: options.type ? options.type : options.extensions[0], extensions: options.extensions }], properties: (properties.length && Blockbench.platform !== 'darwin')?properties:undefined, defaultPath: settings.streamer_mode.value ? app.getPath('desktop') : options.startpath }, function (fileNames) { if (!fileNames) return; if (options.resource_id) { StateMemory.dialog_paths[options.resource_id] = PathModule.dirname(fileNames[0]) StateMemory.save('dialog_paths') } Blockbench.read(fileNames, options, cb) }) } else { $('').change(function(e) { var input = this; var results = []; var result_count = 0; var i = 0; Blockbench.read(input.files, options, cb) }).click() } }, read(files, options, cb) { if (files == undefined) return false; if (typeof files == 'string') files = [files]; console.log(files) var results = []; var result_count = 0; var i = 0; var errant; if (isApp) { while (i < files.length) { (function() { var this_i = i; var file = files[i] let readtype = options.readtype; if (typeof readtype == 'function') { readtype = readtype(file); } else if (readtype != 'buffer' && readtype != 'binary') { readtype = 'text'; } if (readtype === 'image') { // var extension = pathToExtension(file) if (extension === 'tga') { var targa_loader = new Targa() targa_loader.open(file, () => { results[this_i] = { name: pathToName(file, true), path: file, content: targa_loader.getDataURL() } result_count++; if (result_count === files.length) { cb(results) } }) } else { results[this_i] = { name: pathToName(file, true), path: file } result_count++; if (result_count === files.length) { cb(results) } } } else /*text*/ { var load = function (data) { if ((readtype != 'buffer' && readtype != 'binary') && data.charCodeAt(0) === 0xFEFF) { data = data.substr(1) } results[this_i] = { name: pathToName(file, true), path: file, content: data } result_count++; if (result_count === files.length) { cb(results) } } var read_files; try { read_files = fs.readFileSync(file, readtype == 'text' ? 'utf8' : undefined); } catch(err) { console.log(err) if (!errant && options.errorbox !== false) { Blockbench.showMessageBox({ translateKey: 'file_not_found', icon: 'error_outline' }) } errant = true; return; } finally { load(read_files); } } })() i++; } } else { while (i < files.length) { (function() { var file = files[i] var reader = new FileReader() reader.i = i reader.onloadend = function() { if (reader.result.byteLength && pathToExtension(file.name) === 'tga') { var arr = new Uint8Array(reader.result) var targa_loader = new Targa() targa_loader.load(arr) var result = targa_loader.getDataURL() } else { var result = reader.result } results[this.i] = { name: file.name, path: file.name, content: result } result_count++; if (result_count === files.length) { cb(results) } } let readtype = options.readtype; if (typeof readtype == 'function') { readtype = readtype(file.name); } if (readtype === 'image') { if (pathToExtension(file.name) === 'tga') { reader.readAsArrayBuffer(file) } else { reader.readAsDataURL(file) } } else if (readtype === 'buffer' || readtype === 'binary') { reader.readAsArrayBuffer(file) } else /*text*/ { reader.readAsText(file) } i++; })() } } }, export(options, cb) { if (!options) return; /* type extensions name content startpath savetype project_file custom_writer resource_id */ if (Blockbench.isWeb) { var file_name = options.name + (options.extensions ? '.'+options.extensions[0] : '') if (options.custom_writer) { options.custom_writer(options.content, file_name) } else if (options.savetype === 'image') { var download = document.createElement('a'); download.href = options.content download.download = file_name; if (Blockbench.browser === 'firefox') document.body.appendChild(download); download.click(); if (Blockbench.browser === 'firefox') document.body.removeChild(download); } else if (options.savetype === 'zip' || options.savetype === 'buffer' || options.savetype === 'binary') { saveAs(options.content, file_name) } else { var blob = new Blob([options.content], {type: "text/plain;charset=utf-8"}); saveAs(blob, file_name, {autoBOM: true}) } if (typeof cb === 'function') { cb(file_name) } } else { if (!options.startpath && options.resource_id) { options.startpath = StateMemory.dialog_paths[options.resource_id] if (options.name) { options.startpath += osfs + options.name + (options.extensions ? '.'+options.extensions[0] : ''); } } ElecDialogs.showSaveDialog(currentwindow, { dontAddToRecent: true, filters: [ { name: options.type, extensions: options.extensions } ], defaultPath: settings.streamer_mode.value ? app.getPath('desktop') : ((options.startpath && options.startpath !== 'Unknown') ? options.startpath.replace(/\.\w+$/, '') : options.name) }, function (file_path) { if (!file_path) return; if (options.resource_id) { StateMemory.dialog_paths[options.resource_id] = PathModule.dirname(file_path) StateMemory.save('dialog_paths') } var extension = pathToExtension(file_path); if (!extension && options.extensions && options.extensions[0]) { file_path += '.'+options.extensions[0] } Blockbench.writeFile(file_path, options, cb) }) } }, writeFile(file_path, options, cb) { /* content savetype project_file custom_writer */ if (!isApp || !file_path) { return; } if (options.savetype === 'image' && typeof options.content === 'string') { if (options.content.substr(0, 10) === 'data:image') { options.content = nativeImage.createFromDataURL(options.content).toPNG() } else { options.content = options.content.replace(/\?\d+$/, ''); options.content = nativeImage.createFromPath(options.content).toPNG() } } if (options.savetype === 'zip') { var fileReader = new FileReader(); fileReader.onload = function(event) { var buffer = Buffer.from(new Uint8Array(this.result)); fs.writeFileSync(file_path, buffer) if (cb) { cb(file_path) } }; fileReader.readAsArrayBuffer(options.content); } else if (options.custom_writer) { options.custom_writer(options.content, file_path) } else { //text or binary fs.writeFileSync(file_path, options.content) if (cb) { cb(file_path) } } }, //Flags addFlag(flag) { this.flags[flag] = true }, removeFlag(flag) { delete this.flags[flag] }, hasFlag(flag) { return this.flags[flag] }, //Events dispatchEvent(event_name, data) { var list = this.events[event_name] if (!list) return; for (var i = 0; i < list.length; i++) { if (typeof list[i] === 'function') { list[i](data) } } }, addListener(event_name, cb) { if (!this.events[event_name]) { this.events[event_name] = [] } this.events[event_name].safePush(cb) return Blockbench; }, on(event_name, cb) { return Blockbench.addListener(event_name, cb) }, removeListener(event_name, cb) { if (!this.events[event_name]) return; this.events[event_name].remove(cb); }, //File Drag addDragHandler(id, options, cb) { var entry = { cb: cb, condition: options.condition } if (options.extensions && options.extensions.length) { entry.extensions = options.extensions } if (options.addClass !== false) entry.addClass = true; if (options.propagate) entry.propagate = true; if (options.readtype) entry.readtype = options.readtype; if (options.errorbox) entry.errorbox = true; if (options.element) entry.element = options.element; this.drag_handlers[id] = entry }, removeDragHandler(id) { delete this.drag_handlers[id] }, }; (function() { var last_welcome = localStorage.getItem('welcomed_version'); if (!last_welcome || last_welcome.replace(/.\d+$/, '') != appVersion.replace(/.\d+$/, '')) { Blockbench.addFlag('after_update'); } localStorage.setItem('welcomed_version', appVersion); })(); if (isApp) { Blockbench.platform = process.platform; switch (Blockbench.platform) { case 'win32': Blockbench.operating_system = 'Windows'; break; case 'darwin': Blockbench.operating_system = 'macOS'; break; default: Blockbench.operating_system = 'Linux'; break; } if (Blockbench.platform.includes('win32') === true) osfs = '\\'; } const StateMemory = { init(key, type) { let saved = localStorage.getItem(`StateMemory.${key}`) if (typeof saved == 'string') { try { saved = JSON.parse(saved) } catch (err) { localStorage.clearItem(`StateMemory.${key}`) } } if ( saved !== null && (typeof saved == type || (type == 'array' && saved instanceof Array)) ) { StateMemory[key] = saved; } else { StateMemory[key] = (() => {switch (type) { case 'string': return ''; break; case 'number': return 0; break; case 'boolean': return false; break; case 'object': return {}; break; case 'array': return []; break; }})(); } }, save(key) { let serialized = JSON.stringify(StateMemory[key]) localStorage.setItem(`StateMemory.${key}`, serialized) } } document.ondragover = function(event) { event.preventDefault() } document.body.ondrop = function(event) { event.preventDefault() forDragHandlers(event, function(handler, el) { var fileNames = event.dataTransfer.files var input = this; var results = []; var result_count = 0; var i = 0; var errant; var paths = [] if (isApp) { for (var file of fileNames) { paths.push(file.path) } } else { paths = fileNames } Blockbench.read(paths, handler, (content) => { handler.cb(content, event) }) }) } document.body.ondragenter = function(event) { event.preventDefault() forDragHandlers(event, function(handler, el) { //$(el).css('background-color', 'red') }) } document.body.ondragleave = function(event) { event.preventDefault() forDragHandlers(event, function(handler, el) { //$(el).css('background-color', '') }) } function forDragHandlers(event, cb) { if (event.dataTransfer == undefined || event.dataTransfer.files.length == 0 || !event.dataTransfer.files[0].name) { return; } for (var id in Blockbench.drag_handlers) { var handler = Blockbench.drag_handlers[id] var el = undefined; if (!Condition(handler.condition)) { continue; } if (!handler.element) { el = $('body').get(0) } else if ($(handler.element).get(0) === event.target) { el = event.target } else if (typeof handler.element === 'string' && $(event.target).is(handler.element)) { el = event.target } else if (typeof handler.element === 'function') { var result = handler.element() if (result === true) { el = $(event.target) } else if ($(result).length) { el = $(result).get(0) } } else if (handler.propagate) { var parent = $(handler.element) if (typeof handler.element === 'function' && !result) { parent = $(handler.element()) } if (parent && parent.has(event.target).length) { el = parent } } handler.extensions.includes( pathToExtension(event.dataTransfer.files[0].name).toLowerCase()) var name = event.dataTransfer.files[0].name; if (el && handler.extensions.filter(ex => { return name.substr(-ex.length) == ex; }).length) { cb(handler, el) break; } } }