main and worldlist
parent
9b338008b0
commit
74c40f0055
|
@ -0,0 +1,3 @@
|
||||||
|
.titlebar {
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
}
|
23
index.html
23
index.html
|
@ -1,23 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html style="width: 100%;height: 100%;">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
|
||||||
<meta http-equiv="Content-Security-Policy-Report-Only">
|
|
||||||
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<title>MtAdmin</title>
|
|
||||||
<link rel="stylesheet" href="css/uikit.min.css" />
|
|
||||||
<script src="js/uikit.min.js"></script>
|
|
||||||
<script src="js/uikit-icons.min.js"></script>
|
|
||||||
<script src="js/jquery-3.5.1.min.js"></script>
|
|
||||||
<script src="js/anime.min.js"></script>
|
|
||||||
<script>if (typeof module === 'object') {window.jQuery = window.$ = module.exports;};</script>
|
|
||||||
</head>
|
|
||||||
<body style="background-color:#87CEFA;width: 100%;height: 100%;">
|
|
||||||
<h1 class="uk-heading-2xlarge" style="left: 30%;top: 30%;position: absolute">MTArk</h1>
|
|
||||||
<h2 id="description" class="uk-align-center" style="position: absolute;bottom: 2%;left: 2%;">初始化中......</h2>
|
|
||||||
<!-- You can also require other files to run in this process -->
|
|
||||||
<script src="./renderer.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html style="width: 100%;height: 100%;">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||||
|
<meta http-equiv="Content-Security-Policy-Report-Only">
|
||||||
|
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>MTArk</title>
|
||||||
|
<link rel="stylesheet" href="css/uikit.min.css" />
|
||||||
|
<script src="js/uikit.min.js"></script>
|
||||||
|
<script src="js/uikit-icons.min.js"></script>
|
||||||
|
<script src="js/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="js/anime.min.js"></script>
|
||||||
|
<script>if (typeof module === 'object') { window.jQuery = window.$ = module.exports; };</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="-webkit-app-region: drag;-webkit-user-select: none;background-color:#87CEFA;width: 100%;height: 100%;">
|
||||||
|
<ul id="topbar" class="topbar uk-iconnav" style="-webkit-app-region: no-drag;position: absolute;right: 5%;top: 2%">
|
||||||
|
<li><span id="min" uk-icon="icon: minus"></span></li>
|
||||||
|
<li><span id="max" uk-icon="icon: copy"></span></li>
|
||||||
|
<li><button id="close" type="button" class="uk-close-large" uk-close></button></li>
|
||||||
|
</ul>
|
||||||
|
<div id="mainwindow">
|
||||||
|
<h1 class="uk-heading-2xlarge" style="left: 30%;top: 30%;position: absolute">MTArk</h1>
|
||||||
|
<h2 id="description" class="uk-align-center" style="position: absolute;bottom: 2%;left: 2%;">初始化中......</h2>
|
||||||
|
</div>
|
||||||
|
<!-- You can also require other files to run in this process -->
|
||||||
|
<script src="./renderer.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,903 @@
|
||||||
|
/*!
|
||||||
|
* Copyright 2012, Chris Wanstrath
|
||||||
|
* Released under the MIT License
|
||||||
|
* https://github.com/defunkt/jquery-pjax
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($){
|
||||||
|
|
||||||
|
// When called on a container with a selector, fetches the href with
|
||||||
|
// ajax into the container or with the data-pjax attribute on the link
|
||||||
|
// itself.
|
||||||
|
//
|
||||||
|
// Tries to make sure the back button and ctrl+click work the way
|
||||||
|
// you'd expect.
|
||||||
|
//
|
||||||
|
// Exported as $.fn.pjax
|
||||||
|
//
|
||||||
|
// Accepts a jQuery ajax options object that may include these
|
||||||
|
// pjax specific options:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// container - String selector for the element where to place the response body.
|
||||||
|
// push - Whether to pushState the URL. Defaults to true (of course).
|
||||||
|
// replace - Want to use replaceState instead? That's cool.
|
||||||
|
//
|
||||||
|
// For convenience the second parameter can be either the container or
|
||||||
|
// the options object.
|
||||||
|
//
|
||||||
|
// Returns the jQuery object
|
||||||
|
function fnPjax(selector, container, options) {
|
||||||
|
options = optionsFor(container, options)
|
||||||
|
return this.on('click.pjax', selector, function(event) {
|
||||||
|
var opts = options
|
||||||
|
if (!opts.container) {
|
||||||
|
opts = $.extend({}, options)
|
||||||
|
opts.container = $(this).attr('data-pjax')
|
||||||
|
}
|
||||||
|
handleClick(event, opts)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public: pjax on click handler
|
||||||
|
//
|
||||||
|
// Exported as $.pjax.click.
|
||||||
|
//
|
||||||
|
// event - "click" jQuery.Event
|
||||||
|
// options - pjax options
|
||||||
|
//
|
||||||
|
// Examples
|
||||||
|
//
|
||||||
|
// $(document).on('click', 'a', $.pjax.click)
|
||||||
|
// // is the same as
|
||||||
|
// $(document).pjax('a')
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function handleClick(event, container, options) {
|
||||||
|
options = optionsFor(container, options)
|
||||||
|
|
||||||
|
var link = event.currentTarget
|
||||||
|
var $link = $(link)
|
||||||
|
|
||||||
|
if (link.tagName.toUpperCase() !== 'A')
|
||||||
|
throw "$.fn.pjax or $.pjax.click requires an anchor element"
|
||||||
|
|
||||||
|
// Middle click, cmd click, and ctrl click should open
|
||||||
|
// links in a new tab as normal.
|
||||||
|
if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
|
||||||
|
return
|
||||||
|
|
||||||
|
// Ignore cross origin links
|
||||||
|
if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
|
||||||
|
return
|
||||||
|
|
||||||
|
// Ignore case when a hash is being tacked on the current URL
|
||||||
|
if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
|
||||||
|
return
|
||||||
|
|
||||||
|
// Ignore event with default prevented
|
||||||
|
if (event.isDefaultPrevented())
|
||||||
|
return
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
url: link.href,
|
||||||
|
container: $link.attr('data-pjax'),
|
||||||
|
target: link
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts = $.extend({}, defaults, options)
|
||||||
|
var clickEvent = $.Event('pjax:click')
|
||||||
|
$link.trigger(clickEvent, [opts])
|
||||||
|
|
||||||
|
if (!clickEvent.isDefaultPrevented()) {
|
||||||
|
pjax(opts)
|
||||||
|
event.preventDefault()
|
||||||
|
$link.trigger('pjax:clicked', [opts])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public: pjax on form submit handler
|
||||||
|
//
|
||||||
|
// Exported as $.pjax.submit
|
||||||
|
//
|
||||||
|
// event - "click" jQuery.Event
|
||||||
|
// options - pjax options
|
||||||
|
//
|
||||||
|
// Examples
|
||||||
|
//
|
||||||
|
// $(document).on('submit', 'form', function(event) {
|
||||||
|
// $.pjax.submit(event, '[data-pjax-container]')
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function handleSubmit(event, container, options) {
|
||||||
|
options = optionsFor(container, options)
|
||||||
|
|
||||||
|
var form = event.currentTarget
|
||||||
|
var $form = $(form)
|
||||||
|
|
||||||
|
if (form.tagName.toUpperCase() !== 'FORM')
|
||||||
|
throw "$.pjax.submit requires a form element"
|
||||||
|
|
||||||
|
var defaults = {
|
||||||
|
type: ($form.attr('method') || 'GET').toUpperCase(),
|
||||||
|
url: $form.attr('action'),
|
||||||
|
container: $form.attr('data-pjax'),
|
||||||
|
target: form
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaults.type !== 'GET' && window.FormData !== undefined) {
|
||||||
|
defaults.data = new FormData(form)
|
||||||
|
defaults.processData = false
|
||||||
|
defaults.contentType = false
|
||||||
|
} else {
|
||||||
|
// Can't handle file uploads, exit
|
||||||
|
if ($form.find(':file').length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to manually serializing the fields
|
||||||
|
defaults.data = $form.serializeArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
pjax($.extend({}, defaults, options))
|
||||||
|
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loads a URL with ajax, puts the response body inside a container,
|
||||||
|
// then pushState()'s the loaded URL.
|
||||||
|
//
|
||||||
|
// Works just like $.ajax in that it accepts a jQuery ajax
|
||||||
|
// settings object (with keys like url, type, data, etc).
|
||||||
|
//
|
||||||
|
// Accepts these extra keys:
|
||||||
|
//
|
||||||
|
// container - String selector for where to stick the response body.
|
||||||
|
// push - Whether to pushState the URL. Defaults to true (of course).
|
||||||
|
// replace - Want to use replaceState instead? That's cool.
|
||||||
|
//
|
||||||
|
// Use it just like $.ajax:
|
||||||
|
//
|
||||||
|
// var xhr = $.pjax({ url: this.href, container: '#main' })
|
||||||
|
// console.log( xhr.readyState )
|
||||||
|
//
|
||||||
|
// Returns whatever $.ajax returns.
|
||||||
|
function pjax(options) {
|
||||||
|
options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
|
||||||
|
|
||||||
|
if ($.isFunction(options.url)) {
|
||||||
|
options.url = options.url()
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = parseURL(options.url).hash
|
||||||
|
|
||||||
|
var containerType = $.type(options.container)
|
||||||
|
if (containerType !== 'string') {
|
||||||
|
throw "expected string value for 'container' option; got " + containerType
|
||||||
|
}
|
||||||
|
var context = options.context = $(options.container)
|
||||||
|
if (!context.length) {
|
||||||
|
throw "the container selector '" + options.container + "' did not match anything"
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want the browser to maintain two separate internal caches: one
|
||||||
|
// for pjax'd partial page loads and one for normal page loads.
|
||||||
|
// Without adding this secret parameter, some browsers will often
|
||||||
|
// confuse the two.
|
||||||
|
if (!options.data) options.data = {}
|
||||||
|
if ($.isArray(options.data)) {
|
||||||
|
options.data.push({name: '_pjax', value: options.container})
|
||||||
|
} else {
|
||||||
|
options.data._pjax = options.container
|
||||||
|
}
|
||||||
|
|
||||||
|
function fire(type, args, props) {
|
||||||
|
if (!props) props = {}
|
||||||
|
props.relatedTarget = options.target
|
||||||
|
var event = $.Event(type, props)
|
||||||
|
context.trigger(event, args)
|
||||||
|
return !event.isDefaultPrevented()
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeoutTimer
|
||||||
|
|
||||||
|
options.beforeSend = function(xhr, settings) {
|
||||||
|
// No timeout for non-GET requests
|
||||||
|
// Its not safe to request the resource again with a fallback method.
|
||||||
|
if (settings.type !== 'GET') {
|
||||||
|
settings.timeout = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.setRequestHeader('X-PJAX', 'true')
|
||||||
|
xhr.setRequestHeader('X-PJAX-Container', options.container)
|
||||||
|
|
||||||
|
if (!fire('pjax:beforeSend', [xhr, settings]))
|
||||||
|
return false
|
||||||
|
|
||||||
|
if (settings.timeout > 0) {
|
||||||
|
timeoutTimer = setTimeout(function() {
|
||||||
|
if (fire('pjax:timeout', [xhr, options]))
|
||||||
|
xhr.abort('timeout')
|
||||||
|
}, settings.timeout)
|
||||||
|
|
||||||
|
// Clear timeout setting so jquerys internal timeout isn't invoked
|
||||||
|
settings.timeout = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = parseURL(settings.url)
|
||||||
|
if (hash) url.hash = hash
|
||||||
|
options.requestUrl = stripInternalParams(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
options.complete = function(xhr, textStatus) {
|
||||||
|
if (timeoutTimer)
|
||||||
|
clearTimeout(timeoutTimer)
|
||||||
|
|
||||||
|
fire('pjax:complete', [xhr, textStatus, options])
|
||||||
|
|
||||||
|
fire('pjax:end', [xhr, options])
|
||||||
|
}
|
||||||
|
|
||||||
|
options.error = function(xhr, textStatus, errorThrown) {
|
||||||
|
var container = extractContainer("", xhr, options)
|
||||||
|
|
||||||
|
var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
|
||||||
|
if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
|
||||||
|
locationReplace(container.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
options.success = function(data, status, xhr) {
|
||||||
|
var previousState = pjax.state
|
||||||
|
|
||||||
|
// If $.pjax.defaults.version is a function, invoke it first.
|
||||||
|
// Otherwise it can be a static string.
|
||||||
|
var currentVersion = typeof $.pjax.defaults.version === 'function' ?
|
||||||
|
$.pjax.defaults.version() :
|
||||||
|
$.pjax.defaults.version
|
||||||
|
|
||||||
|
var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
|
||||||
|
|
||||||
|
var container = extractContainer(data, xhr, options)
|
||||||
|
|
||||||
|
var url = parseURL(container.url)
|
||||||
|
if (hash) {
|
||||||
|
url.hash = hash
|
||||||
|
container.url = url.href
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a layout version mismatch, hard load the new url
|
||||||
|
if (currentVersion && latestVersion && currentVersion !== latestVersion) {
|
||||||
|
locationReplace(container.url)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the new response is missing a body, hard load the page
|
||||||
|
if (!container.contents) {
|
||||||
|
locationReplace(container.url)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pjax.state = {
|
||||||
|
id: options.id || uniqueId(),
|
||||||
|
url: container.url,
|
||||||
|
title: container.title,
|
||||||
|
container: options.container,
|
||||||
|
fragment: options.fragment,
|
||||||
|
timeout: options.timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.push || options.replace) {
|
||||||
|
window.history.replaceState(pjax.state, container.title, container.url)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only blur the focus if the focused element is within the container.
|
||||||
|
var blurFocus = $.contains(context, document.activeElement)
|
||||||
|
|
||||||
|
// Clear out any focused controls before inserting new page contents.
|
||||||
|
if (blurFocus) {
|
||||||
|
try {
|
||||||
|
document.activeElement.blur()
|
||||||
|
} catch (e) { /* ignore */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container.title) document.title = container.title
|
||||||
|
|
||||||
|
fire('pjax:beforeReplace', [container.contents, options], {
|
||||||
|
state: pjax.state,
|
||||||
|
previousState: previousState
|
||||||
|
})
|
||||||
|
context.html(container.contents)
|
||||||
|
|
||||||
|
// FF bug: Won't autofocus fields that are inserted via JS.
|
||||||
|
// This behavior is incorrect. So if theres no current focus, autofocus
|
||||||
|
// the last field.
|
||||||
|
//
|
||||||
|
// http://www.w3.org/html/wg/drafts/html/master/forms.html
|
||||||
|
var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
|
||||||
|
if (autofocusEl && document.activeElement !== autofocusEl) {
|
||||||
|
autofocusEl.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
executeScriptTags(container.scripts)
|
||||||
|
|
||||||
|
var scrollTo = options.scrollTo
|
||||||
|
|
||||||
|
// Ensure browser scrolls to the element referenced by the URL anchor
|
||||||
|
if (hash) {
|
||||||
|
var name = decodeURIComponent(hash.slice(1))
|
||||||
|
var target = document.getElementById(name) || document.getElementsByName(name)[0]
|
||||||
|
if (target) scrollTo = $(target).offset().top
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)
|
||||||
|
|
||||||
|
fire('pjax:success', [data, status, xhr, options])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize pjax.state for the initial page load. Assume we're
|
||||||
|
// using the container and options of the link we're loading for the
|
||||||
|
// back button to the initial page. This ensures good back button
|
||||||
|
// behavior.
|
||||||
|
if (!pjax.state) {
|
||||||
|
pjax.state = {
|
||||||
|
id: uniqueId(),
|
||||||
|
url: window.location.href,
|
||||||
|
title: document.title,
|
||||||
|
container: options.container,
|
||||||
|
fragment: options.fragment,
|
||||||
|
timeout: options.timeout
|
||||||
|
}
|
||||||
|
window.history.replaceState(pjax.state, document.title)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel the current request if we're already pjaxing
|
||||||
|
abortXHR(pjax.xhr)
|
||||||
|
|
||||||
|
pjax.options = options
|
||||||
|
var xhr = pjax.xhr = $.ajax(options)
|
||||||
|
|
||||||
|
if (xhr.readyState > 0) {
|
||||||
|
if (options.push && !options.replace) {
|
||||||
|
// Cache current container element before replacing it
|
||||||
|
cachePush(pjax.state.id, [options.container, cloneContents(context)])
|
||||||
|
|
||||||
|
window.history.pushState(null, "", options.requestUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
fire('pjax:start', [xhr, options])
|
||||||
|
fire('pjax:send', [xhr, options])
|
||||||
|
}
|
||||||
|
|
||||||
|
return pjax.xhr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public: Reload current page with pjax.
|
||||||
|
//
|
||||||
|
// Returns whatever $.pjax returns.
|
||||||
|
function pjaxReload(container, options) {
|
||||||
|
var defaults = {
|
||||||
|
url: window.location.href,
|
||||||
|
push: false,
|
||||||
|
replace: true,
|
||||||
|
scrollTo: false
|
||||||
|
}
|
||||||
|
|
||||||
|
return pjax($.extend(defaults, optionsFor(container, options)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Hard replace current state with url.
|
||||||
|
//
|
||||||
|
// Work for around WebKit
|
||||||
|
// https://bugs.webkit.org/show_bug.cgi?id=93506
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function locationReplace(url) {
|
||||||
|
window.history.replaceState(null, "", pjax.state.url)
|
||||||
|
window.location.replace(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var initialPop = true
|
||||||
|
var initialURL = window.location.href
|
||||||
|
var initialState = window.history.state
|
||||||
|
|
||||||
|
// Initialize $.pjax.state if possible
|
||||||
|
// Happens when reloading a page and coming forward from a different
|
||||||
|
// session history.
|
||||||
|
if (initialState && initialState.container) {
|
||||||
|
pjax.state = initialState
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-webkit browsers don't fire an initial popstate event
|
||||||
|
if ('state' in window.history) {
|
||||||
|
initialPop = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// popstate handler takes care of the back and forward buttons
|
||||||
|
//
|
||||||
|
// You probably shouldn't use pjax on pages with other pushState
|
||||||
|
// stuff yet.
|
||||||
|
function onPjaxPopstate(event) {
|
||||||
|
|
||||||
|
// Hitting back or forward should override any pending PJAX request.
|
||||||
|
if (!initialPop) {
|
||||||
|
abortXHR(pjax.xhr)
|
||||||
|
}
|
||||||
|
|
||||||
|
var previousState = pjax.state
|
||||||
|
var state = event.state
|
||||||
|
var direction
|
||||||
|
|
||||||
|
if (state && state.container) {
|
||||||
|
// When coming forward from a separate history session, will get an
|
||||||
|
// initial pop with a state we are already at. Skip reloading the current
|
||||||
|
// page.
|
||||||
|
if (initialPop && initialURL == state.url) return
|
||||||
|
|
||||||
|
if (previousState) {
|
||||||
|
// If popping back to the same state, just skip.
|
||||||
|
// Could be clicking back from hashchange rather than a pushState.
|
||||||
|
if (previousState.id === state.id) return
|
||||||
|
|
||||||
|
// Since state IDs always increase, we can deduce the navigation direction
|
||||||
|
direction = previousState.id < state.id ? 'forward' : 'back'
|
||||||
|
}
|
||||||
|
|
||||||
|
var cache = cacheMapping[state.id] || []
|
||||||
|
var containerSelector = cache[0] || state.container
|
||||||
|
var container = $(containerSelector), contents = cache[1]
|
||||||
|
|
||||||
|
if (container.length) {
|
||||||
|
if (previousState) {
|
||||||
|
// Cache current container before replacement and inform the
|
||||||
|
// cache which direction the history shifted.
|
||||||
|
cachePop(direction, previousState.id, [containerSelector, cloneContents(container)])
|
||||||
|
}
|
||||||
|
|
||||||
|
var popstateEvent = $.Event('pjax:popstate', {
|
||||||
|
state: state,
|
||||||
|
direction: direction
|
||||||
|
})
|
||||||
|
container.trigger(popstateEvent)
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
id: state.id,
|
||||||
|
url: state.url,
|
||||||
|
container: containerSelector,
|
||||||
|
push: false,
|
||||||
|
fragment: state.fragment,
|
||||||
|
timeout: state.timeout,
|
||||||
|
scrollTo: false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contents) {
|
||||||
|
container.trigger('pjax:start', [null, options])
|
||||||
|
|
||||||
|
pjax.state = state
|
||||||
|
if (state.title) document.title = state.title
|
||||||
|
var beforeReplaceEvent = $.Event('pjax:beforeReplace', {
|
||||||
|
state: state,
|
||||||
|
previousState: previousState
|
||||||
|
})
|
||||||
|
container.trigger(beforeReplaceEvent, [contents, options])
|
||||||
|
container.html(contents)
|
||||||
|
|
||||||
|
container.trigger('pjax:end', [null, options])
|
||||||
|
} else {
|
||||||
|
pjax(options)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force reflow/relayout before the browser tries to restore the
|
||||||
|
// scroll position.
|
||||||
|
container[0].offsetHeight // eslint-disable-line no-unused-expressions
|
||||||
|
} else {
|
||||||
|
locationReplace(location.href)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initialPop = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback version of main pjax function for browsers that don't
|
||||||
|
// support pushState.
|
||||||
|
//
|
||||||
|
// Returns nothing since it retriggers a hard form submission.
|
||||||
|
function fallbackPjax(options) {
|
||||||
|
var url = $.isFunction(options.url) ? options.url() : options.url,
|
||||||
|
method = options.type ? options.type.toUpperCase() : 'GET'
|
||||||
|
|
||||||
|
var form = $('<form>', {
|
||||||
|
method: method === 'GET' ? 'GET' : 'POST',
|
||||||
|
action: url,
|
||||||
|
style: 'display:none'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (method !== 'GET' && method !== 'POST') {
|
||||||
|
form.append($('<input>', {
|
||||||
|
type: 'hidden',
|
||||||
|
name: '_method',
|
||||||
|
value: method.toLowerCase()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = options.data
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
$.each(data.split('&'), function(index, value) {
|
||||||
|
var pair = value.split('=')
|
||||||
|
form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
|
||||||
|
})
|
||||||
|
} else if ($.isArray(data)) {
|
||||||
|
$.each(data, function(index, value) {
|
||||||
|
form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))
|
||||||
|
})
|
||||||
|
} else if (typeof data === 'object') {
|
||||||
|
var key
|
||||||
|
for (key in data)
|
||||||
|
form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document.body).append(form)
|
||||||
|
form.submit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Abort an XmlHttpRequest if it hasn't been completed,
|
||||||
|
// also removing its event handlers.
|
||||||
|
function abortXHR(xhr) {
|
||||||
|
if ( xhr && xhr.readyState < 4) {
|
||||||
|
xhr.onreadystatechange = $.noop
|
||||||
|
xhr.abort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Generate unique id for state object.
|
||||||
|
//
|
||||||
|
// Use a timestamp instead of a counter since ids should still be
|
||||||
|
// unique across page loads.
|
||||||
|
//
|
||||||
|
// Returns Number.
|
||||||
|
function uniqueId() {
|
||||||
|
return (new Date).getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloneContents(container) {
|
||||||
|
var cloned = container.clone()
|
||||||
|
// Unmark script tags as already being eval'd so they can get executed again
|
||||||
|
// when restored from cache. HAXX: Uses jQuery internal method.
|
||||||
|
cloned.find('script').each(function(){
|
||||||
|
if (!this.src) $._data(this, 'globalEval', false)
|
||||||
|
})
|
||||||
|
return cloned.contents()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Strip internal query params from parsed URL.
|
||||||
|
//
|
||||||
|
// Returns sanitized url.href String.
|
||||||
|
function stripInternalParams(url) {
|
||||||
|
url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '').replace(/^&/, '')
|
||||||
|
return url.href.replace(/\?($|#)/, '$1')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Parse URL components and returns a Locationish object.
|
||||||
|
//
|
||||||
|
// url - String URL
|
||||||
|
//
|
||||||
|
// Returns HTMLAnchorElement that acts like Location.
|
||||||
|
function parseURL(url) {
|
||||||
|
var a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Return the `href` component of given URL object with the hash
|
||||||
|
// portion removed.
|
||||||
|
//
|
||||||
|
// location - Location or HTMLAnchorElement
|
||||||
|
//
|
||||||
|
// Returns String
|
||||||
|
function stripHash(location) {
|
||||||
|
return location.href.replace(/#.*/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Build options Object for arguments.
|
||||||
|
//
|
||||||
|
// For convenience the first parameter can be either the container or
|
||||||
|
// the options object.
|
||||||
|
//
|
||||||
|
// Examples
|
||||||
|
//
|
||||||
|
// optionsFor('#container')
|
||||||
|
// // => {container: '#container'}
|
||||||
|
//
|
||||||
|
// optionsFor('#container', {push: true})
|
||||||
|
// // => {container: '#container', push: true}
|
||||||
|
//
|
||||||
|
// optionsFor({container: '#container', push: true})
|
||||||
|
// // => {container: '#container', push: true}
|
||||||
|
//
|
||||||
|
// Returns options Object.
|
||||||
|
function optionsFor(container, options) {
|
||||||
|
if (container && options) {
|
||||||
|
options = $.extend({}, options)
|
||||||
|
options.container = container
|
||||||
|
return options
|
||||||
|
} else if ($.isPlainObject(container)) {
|
||||||
|
return container
|
||||||
|
} else {
|
||||||
|
return {container: container}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Filter and find all elements matching the selector.
|
||||||
|
//
|
||||||
|
// Where $.fn.find only matches descendants, findAll will test all the
|
||||||
|
// top level elements in the jQuery object as well.
|
||||||
|
//
|
||||||
|
// elems - jQuery object of Elements
|
||||||
|
// selector - String selector to match
|
||||||
|
//
|
||||||
|
// Returns a jQuery object.
|
||||||
|
function findAll(elems, selector) {
|
||||||
|
return elems.filter(selector).add(elems.find(selector))
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseHTML(html) {
|
||||||
|
return $.parseHTML(html, document, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: Extracts container and metadata from response.
|
||||||
|
//
|
||||||
|
// 1. Extracts X-PJAX-URL header if set
|
||||||
|
// 2. Extracts inline <title> tags
|
||||||
|
// 3. Builds response Element and extracts fragment if set
|
||||||
|
//
|
||||||
|
// data - String response data
|
||||||
|
// xhr - XHR response
|
||||||
|
// options - pjax options Object
|
||||||
|
//
|
||||||
|
// Returns an Object with url, title, and contents keys.
|
||||||
|
function extractContainer(data, xhr, options) {
|
||||||
|
var obj = {}, fullDocument = /<html/i.test(data)
|
||||||
|
|
||||||
|
// Prefer X-PJAX-URL header if it was set, otherwise fallback to
|
||||||
|
// using the original requested url.
|
||||||
|
var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
|
||||||
|
obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl
|
||||||
|
|
||||||
|
var $head, $body
|
||||||
|
// Attempt to parse response html into elements
|
||||||
|
if (fullDocument) {
|
||||||
|
$body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
|
||||||
|
var head = data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)
|
||||||
|
$head = head != null ? $(parseHTML(head[0])) : $body
|
||||||
|
} else {
|
||||||
|
$head = $body = $(parseHTML(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
// If response data is empty, return fast
|
||||||
|
if ($body.length === 0)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
// If there's a <title> tag in the header, use it as
|
||||||
|
// the page's title.
|
||||||
|
obj.title = findAll($head, 'title').last().text()
|
||||||
|
|
||||||
|
if (options.fragment) {
|
||||||
|
var $fragment = $body
|
||||||
|
// If they specified a fragment, look for it in the response
|
||||||
|
// and pull it out.
|
||||||
|
if (options.fragment !== 'body') {
|
||||||
|
$fragment = findAll($fragment, options.fragment).first()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($fragment.length) {
|
||||||
|
obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()
|
||||||
|
|
||||||
|
// If there's no title, look for data-title and title attributes
|
||||||
|
// on the fragment
|
||||||
|
if (!obj.title)
|
||||||
|
obj.title = $fragment.attr('title') || $fragment.data('title')
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (!fullDocument) {
|
||||||
|
obj.contents = $body
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up any <title> tags
|
||||||
|
if (obj.contents) {
|
||||||
|
// Remove any parent title elements
|
||||||
|
obj.contents = obj.contents.not(function() { return $(this).is('title') })
|
||||||
|
|
||||||
|
// Then scrub any titles from their descendants
|
||||||
|
obj.contents.find('title').remove()
|
||||||
|
|
||||||
|
// Gather all script[src] elements
|
||||||
|
obj.scripts = findAll(obj.contents, 'script[src]').remove()
|
||||||
|
obj.contents = obj.contents.not(obj.scripts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim any whitespace off the title
|
||||||
|
if (obj.title) obj.title = $.trim(obj.title)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load an execute scripts using standard script request.
|
||||||
|
//
|
||||||
|
// Avoids jQuery's traditional $.getScript which does a XHR request and
|
||||||
|
// globalEval.
|
||||||
|
//
|
||||||
|
// scripts - jQuery object of script Elements
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function executeScriptTags(scripts) {
|
||||||
|
if (!scripts) return
|
||||||
|
|
||||||
|
var existingScripts = $('script[src]')
|
||||||
|
|
||||||
|
scripts.each(function() {
|
||||||
|
var src = this.src
|
||||||
|
var matchedScripts = existingScripts.filter(function() {
|
||||||
|
return this.src === src
|
||||||
|
})
|
||||||
|
if (matchedScripts.length) return
|
||||||
|
|
||||||
|
var script = document.createElement('script')
|
||||||
|
var type = $(this).attr('type')
|
||||||
|
if (type) script.type = type
|
||||||
|
script.src = $(this).attr('src')
|
||||||
|
document.head.appendChild(script)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal: History DOM caching class.
|
||||||
|
var cacheMapping = {}
|
||||||
|
var cacheForwardStack = []
|
||||||
|
var cacheBackStack = []
|
||||||
|
|
||||||
|
// Push previous state id and container contents into the history
|
||||||
|
// cache. Should be called in conjunction with `pushState` to save the
|
||||||
|
// previous container contents.
|
||||||
|
//
|
||||||
|
// id - State ID Number
|
||||||
|
// value - DOM Element to cache
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function cachePush(id, value) {
|
||||||
|
cacheMapping[id] = value
|
||||||
|
cacheBackStack.push(id)
|
||||||
|
|
||||||
|
// Remove all entries in forward history stack after pushing a new page.
|
||||||
|
trimCacheStack(cacheForwardStack, 0)
|
||||||
|
|
||||||
|
// Trim back history stack to max cache length.
|
||||||
|
trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shifts cache from directional history cache. Should be
|
||||||
|
// called on `popstate` with the previous state id and container
|
||||||
|
// contents.
|
||||||
|
//
|
||||||
|
// direction - "forward" or "back" String
|
||||||
|
// id - State ID Number
|
||||||
|
// value - DOM Element to cache
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function cachePop(direction, id, value) {
|
||||||
|
var pushStack, popStack
|
||||||
|
cacheMapping[id] = value
|
||||||
|
|
||||||
|
if (direction === 'forward') {
|
||||||
|
pushStack = cacheBackStack
|
||||||
|
popStack = cacheForwardStack
|
||||||
|
} else {
|
||||||
|
pushStack = cacheForwardStack
|
||||||
|
popStack = cacheBackStack
|
||||||
|
}
|
||||||
|
|
||||||
|
pushStack.push(id)
|
||||||
|
id = popStack.pop()
|
||||||
|
if (id) delete cacheMapping[id]
|
||||||
|
|
||||||
|
// Trim whichever stack we just pushed to to max cache length.
|
||||||
|
trimCacheStack(pushStack, pjax.defaults.maxCacheLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no
|
||||||
|
// longer than the specified length, deleting cached DOM elements as necessary.
|
||||||
|
//
|
||||||
|
// stack - Array of state IDs
|
||||||
|
// length - Maximum length to trim to
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function trimCacheStack(stack, length) {
|
||||||
|
while (stack.length > length)
|
||||||
|
delete cacheMapping[stack.shift()]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public: Find version identifier for the initial page load.
|
||||||
|
//
|
||||||
|
// Returns String version or undefined.
|
||||||
|
function findVersion() {
|
||||||
|
return $('meta').filter(function() {
|
||||||
|
var name = $(this).attr('http-equiv')
|
||||||
|
return name && name.toUpperCase() === 'X-PJAX-VERSION'
|
||||||
|
}).attr('content')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install pjax functions on $.pjax to enable pushState behavior.
|
||||||
|
//
|
||||||
|
// Does nothing if already enabled.
|
||||||
|
//
|
||||||
|
// Examples
|
||||||
|
//
|
||||||
|
// $.pjax.enable()
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function enable() {
|
||||||
|
$.fn.pjax = fnPjax
|
||||||
|
$.pjax = pjax
|
||||||
|
$.pjax.enable = $.noop
|
||||||
|
$.pjax.disable = disable
|
||||||
|
$.pjax.click = handleClick
|
||||||
|
$.pjax.submit = handleSubmit
|
||||||
|
$.pjax.reload = pjaxReload
|
||||||
|
$.pjax.defaults = {
|
||||||
|
timeout: 650,
|
||||||
|
push: true,
|
||||||
|
replace: false,
|
||||||
|
type: 'GET',
|
||||||
|
dataType: 'html',
|
||||||
|
scrollTo: 0,
|
||||||
|
maxCacheLength: 20,
|
||||||
|
version: findVersion
|
||||||
|
}
|
||||||
|
$(window).on('popstate.pjax', onPjaxPopstate)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable pushState behavior.
|
||||||
|
//
|
||||||
|
// This is the case when a browser doesn't support pushState. It is
|
||||||
|
// sometimes useful to disable pushState for debugging on a modern
|
||||||
|
// browser.
|
||||||
|
//
|
||||||
|
// Examples
|
||||||
|
//
|
||||||
|
// $.pjax.disable()
|
||||||
|
//
|
||||||
|
// Returns nothing.
|
||||||
|
function disable() {
|
||||||
|
$.fn.pjax = function() { return this }
|
||||||
|
$.pjax = fallbackPjax
|
||||||
|
$.pjax.enable = enable
|
||||||
|
$.pjax.disable = $.noop
|
||||||
|
$.pjax.click = $.noop
|
||||||
|
$.pjax.submit = $.noop
|
||||||
|
$.pjax.reload = function() { window.location.reload() }
|
||||||
|
|
||||||
|
$(window).off('popstate.pjax', onPjaxPopstate)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add the state property to jQuery's event object so we can use it in
|
||||||
|
// $(window).bind('popstate')
|
||||||
|
if ($.event.props && $.inArray('state', $.event.props) < 0) {
|
||||||
|
$.event.props.push('state')
|
||||||
|
} else if (!('state' in $.Event.prototype)) {
|
||||||
|
$.event.addProp('state')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is pjax supported by this browser?
|
||||||
|
$.support.pjax =
|
||||||
|
window.history && window.history.pushState && window.history.replaceState &&
|
||||||
|
// pushState isn't reliable on iOS until 5.
|
||||||
|
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
|
||||||
|
|
||||||
|
if ($.support.pjax) {
|
||||||
|
enable()
|
||||||
|
} else {
|
||||||
|
disable()
|
||||||
|
}
|
||||||
|
|
||||||
|
})(jQuery)
|
|
@ -0,0 +1,41 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="Content-Security-Policy-Report-Only">
|
||||||
|
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>MTArk</title>
|
||||||
|
<link rel="stylesheet" href="css/uikit.min.css" />
|
||||||
|
<script src="js/uikit.min.js"></script>
|
||||||
|
<script src="js/uikit-icons.min.js"></script>
|
||||||
|
<script src="js/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="js/anime.min.js"></script>
|
||||||
|
<script>if (typeof module === 'object') { window.jQuery = window.$ = module.exports; };</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ul id="topbar" class="topbar uk-iconnav" style="-webkit-app-region: no-drag;position: absolute;right: 5%;top: 2%">
|
||||||
|
<li><span id="min" uk-icon="icon: minus"></span></li>
|
||||||
|
<li><span id="max" uk-icon="icon: copy"></span></li>
|
||||||
|
<li><button id="close" type="button" class="uk-close-large" uk-close></button></li>
|
||||||
|
</ul>
|
||||||
|
<div class="uk-child-width-1-2 uk-text-center" uk-grid>
|
||||||
|
<div>
|
||||||
|
<div class="uk-card uk-card-default uk-card-body" onclick="jump('page-worlds')">世界列表</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="uk-child-width-1-2 uk-text-center" uk-grid>
|
||||||
|
<div>
|
||||||
|
<div class="uk-card uk-card-primary uk-card-body">资源大厅</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="uk-card uk-card-primary uk-card-body">设置</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="./renderer.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
37
main.js
37
main.js
|
@ -18,15 +18,46 @@ function createWindow() {
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload: path.join(__dirname, 'preload.js')
|
preload: path.join(__dirname, 'preload.js'),
|
||||||
|
nodeIntegration: true
|
||||||
},
|
},
|
||||||
transparent: true,
|
transparent: true,
|
||||||
frame: false
|
frame: false
|
||||||
})
|
})
|
||||||
|
let ipcMain = require('electron').ipcMain;
|
||||||
|
//接收最小化命令
|
||||||
|
ipcMain.on('window-min', function () {
|
||||||
|
mainWindow.minimize();
|
||||||
|
})
|
||||||
|
//接收最大化命令
|
||||||
|
ipcMain.on('window-max', function () {
|
||||||
|
if (mainWindow.isMaximized()) {
|
||||||
|
mainWindow.restore();
|
||||||
|
} else {
|
||||||
|
mainWindow.maximize();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//接收关闭命令
|
||||||
|
ipcMain.on('window-close', function () {
|
||||||
|
mainWindow.close();
|
||||||
|
})
|
||||||
|
mainWindow.on('maximize', function () {
|
||||||
|
mainWindow.webContents.send('main-window-max');
|
||||||
|
})
|
||||||
|
mainWindow.on('unmaximize', function () {
|
||||||
|
mainWindow.webContents.send('main-window-unmax');
|
||||||
|
})
|
||||||
|
ipcMain.on("page-main", function () {
|
||||||
|
mainWindow.loadURL(path.join(__dirname, '/main.html'))
|
||||||
|
})
|
||||||
|
ipcMain.on("page-worlds", function () {
|
||||||
|
mainWindow.loadURL(path.join(__dirname, '/worlds.html'))
|
||||||
|
})
|
||||||
|
|
||||||
mainWindow.webContents.openDevTools();
|
mainWindow.webContents.openDevTools();
|
||||||
//mainWindow.setSkipTaskbar(true);
|
//mainWindow.setSkipTaskbar(true);
|
||||||
// and load the index.html of the app.
|
// and load the index.html of the app.
|
||||||
mainWindow.loadFile('index.html')
|
mainWindow.loadFile('init.html')
|
||||||
// Open the DevTools.
|
// Open the DevTools.
|
||||||
// mainWindow.webContents.openDevTools()
|
// mainWindow.webContents.openDevTools()
|
||||||
}
|
}
|
||||||
|
@ -49,4 +80,4 @@ app.on('activate', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
// In this file you can include the rest of your app's specific main process
|
// In this file you can include the rest of your app's specific main process
|
||||||
// code. You can also put them in separate files and require them here.
|
// code. You can also put them in separate files and require them here.
|
|
@ -2,7 +2,6 @@ var fs = require("fs");
|
||||||
var tool = require("./tool")
|
var tool = require("./tool")
|
||||||
var execSync = require("child_process").execSync;
|
var execSync = require("child_process").execSync;
|
||||||
var compressing = require("compressing");
|
var compressing = require("compressing");
|
||||||
var fs = require("fs");
|
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var translater = require("./translater")
|
var translater = require("./translater")
|
||||||
var S = new translater()
|
var S = new translater()
|
||||||
|
@ -41,10 +40,11 @@ async function upgrade() {
|
||||||
var cpu = tool.getCPU();
|
var cpu = tool.getCPU();
|
||||||
try {
|
try {
|
||||||
var res = await tool.getsync(
|
var res = await tool.getsync(
|
||||||
"https://api.github.com/repos/minetest/minetest/releases/latest"
|
"https://api.github.com/repos/minetest/minetest/releases/latest", 1000
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Network timeout,sikpping upgrade")
|
console.log("Network timeout,sikpping upgrade");
|
||||||
|
ipcRenderer.send("page-main");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fs.existsSync(".minetest")) {
|
if (fs.existsSync(".minetest")) {
|
||||||
|
|
26
node/tool.js
26
node/tool.js
|
@ -148,7 +148,7 @@ class StreamDownload {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
function getsync(url) {
|
function getsync(url, limit = 5000) {
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
request.get(
|
request.get(
|
||||||
{
|
{
|
||||||
|
@ -158,13 +158,14 @@ function getsync(url) {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
"user-agent": "MTArk",
|
"user-agent": "MTArk",
|
||||||
},
|
},
|
||||||
timeout: 30000,
|
timeout: limit,
|
||||||
},
|
},
|
||||||
function (error, response, body) {
|
function (error, response, body) {
|
||||||
if (!error && response.statusCode == 200) {
|
if (!error && response.statusCode == 200) {
|
||||||
resolve(JSON.parse(body));
|
resolve(JSON.parse(body));
|
||||||
} else
|
} else {
|
||||||
reject(error);
|
reject(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -174,10 +175,27 @@ function getLanguage() {
|
||||||
return remote.getGlobal('sharedObject').language || "en";
|
return remote.getGlobal('sharedObject').language || "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delDir(path) {
|
||||||
|
let files = [];
|
||||||
|
if (fs.existsSync(path)) {
|
||||||
|
files = fs.readdirSync(path);
|
||||||
|
files.forEach((file, index) => {
|
||||||
|
let curPath = path + "/" + file;
|
||||||
|
if (fs.statSync(curPath).isDirectory()) {
|
||||||
|
delDir(curPath); //递归删除文件夹
|
||||||
|
} else {
|
||||||
|
fs.unlinkSync(curPath); //删除文件
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fs.rmdirSync(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
cp_r,
|
cp_r,
|
||||||
getsync,
|
getsync,
|
||||||
StreamDownload,
|
StreamDownload,
|
||||||
getCPU,
|
getCPU,
|
||||||
getLanguage
|
getLanguage,
|
||||||
|
delDir
|
||||||
}
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
var fs = require("fs");
|
||||||
|
var exec = require("child_process").exec;
|
||||||
|
var delDir = require("./tool").delDir
|
||||||
|
|
||||||
|
function open_world(name) {
|
||||||
|
// 执行命令行,如果命令不需要路径,或就是项目根目录,则不需要cwd参数:
|
||||||
|
workerProcess = exec(".minetest\\bin\\minetest.exe --console --go --worldname " + name, {})
|
||||||
|
// 不受child_process默认的缓冲区大小的使用方法,没参数也要写上{}:workerProcess = exec(cmdStr, {})
|
||||||
|
|
||||||
|
// 打印正常的后台可执行程序输出
|
||||||
|
workerProcess.stdout.on('data', function (data) {
|
||||||
|
console.log('stdout: ' + data)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 打印错误的后台可执行程序输出
|
||||||
|
workerProcess.stderr.on('data', function (data) {
|
||||||
|
console.log('stderr: ' + data)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 退出之后的输出
|
||||||
|
workerProcess.on('close', function (code) {
|
||||||
|
console.log('out code:' + code)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function del_world(name) {
|
||||||
|
delDir(".minetest\\worlds\\" + name)
|
||||||
|
$("#worldlist").empty()
|
||||||
|
worlds.show_worlds()
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_worlds() {
|
||||||
|
const files = fs.readdirSync('./.minetest/worlds')
|
||||||
|
files.forEach(function (worldname, index) {
|
||||||
|
let stat = fs.lstatSync("./.minetest/worlds/" + worldname)
|
||||||
|
if (stat.isDirectory() === true) {
|
||||||
|
var worldnameout = "<td>" + worldname + "</td>"
|
||||||
|
var ctimeout = "<td>" + stat.ctime.toLocaleString() + "</td>"
|
||||||
|
var openworldout = "<button class='uk-margin-right uk-button uk-button-primary uk-button-small' onclick='worlds.open_world(\"" + worldname + "\")'>进入世界</button>"
|
||||||
|
var delworldout = "<button class='uk-margin-right uk-button uk-button-danger uk-button-small' uk-toggle='target: #delworld_modal'>删除世界</button>"
|
||||||
|
var buttonout = "<td>" + openworldout + delworldout + "</td>"
|
||||||
|
$("#worldlist").append("<tr>" + worldnameout + ctimeout + buttonout + "</tr>")
|
||||||
|
$("#delworld").on("click", function () {
|
||||||
|
worlds.del_world(worldname)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
open_world,
|
||||||
|
show_worlds,
|
||||||
|
del_world
|
||||||
|
}
|
12
preload.js
12
preload.js
|
@ -1,6 +1,9 @@
|
||||||
// All of the Node.js APIs are available in the preload process.
|
// All of the Node.js APIs are available in the preload process.
|
||||||
// It has the same sandbox as a Chrome extension.
|
// It has the same sandbox as a Chrome extension.
|
||||||
var core = require("./node/core")
|
let ipcRenderer = require('electron').ipcRenderer;
|
||||||
|
var core = require("./node/core");
|
||||||
|
worlds = require("./node/worlds");
|
||||||
|
|
||||||
|
|
||||||
//keep setImmediate alive
|
//keep setImmediate alive
|
||||||
var _setImmediate = setImmediate;
|
var _setImmediate = setImmediate;
|
||||||
|
@ -14,5 +17,10 @@ async function init() {
|
||||||
await core.upgrade();
|
await core.upgrade();
|
||||||
}
|
}
|
||||||
window.addEventListener("load", function () {
|
window.addEventListener("load", function () {
|
||||||
init();
|
if (window.location.pathname.indexOf("init.html") != -1) {
|
||||||
|
init();
|
||||||
|
};
|
||||||
|
if (window.location.pathname.indexOf("worlds.html") != -1) {
|
||||||
|
worlds.show_worlds();
|
||||||
|
};
|
||||||
});
|
});
|
44
renderer.js
44
renderer.js
|
@ -18,8 +18,8 @@ CreateLodingRing = function (size, dotsize, dotcolor) {
|
||||||
loadingring.setAttribute("viewBox", "0 0" + " " + size + " " + size);
|
loadingring.setAttribute("viewBox", "0 0" + " " + size + " " + size);
|
||||||
loadingring.setAttribute("width", "10%")
|
loadingring.setAttribute("width", "10%")
|
||||||
loadingring.setAttribute("height", "10%")
|
loadingring.setAttribute("height", "10%")
|
||||||
loadingring.style.right = "2%";
|
loadingring.style.right = "5%";
|
||||||
loadingring.style.bottom = "2%";
|
loadingring.style.bottom = "5%";
|
||||||
loadingring.style.position = "absolute";
|
loadingring.style.position = "absolute";
|
||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
let dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
let dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
||||||
|
@ -70,4 +70,44 @@ CreateLodingRing = function (size, dotsize, dotcolor) {
|
||||||
ring.svgitem = loadingring;
|
ring.svgitem = loadingring;
|
||||||
|
|
||||||
return ring;
|
return ring;
|
||||||
|
}
|
||||||
|
let ipcRenderer = require('electron').ipcRenderer;
|
||||||
|
|
||||||
|
var max = document.getElementById('max');
|
||||||
|
if (max) {
|
||||||
|
max.addEventListener('click', () => {
|
||||||
|
//发送最大化命令
|
||||||
|
ipcRenderer.send('window-max');
|
||||||
|
//最大化图形切换
|
||||||
|
if (max.getAttribute('src') == 'images/max.png') {
|
||||||
|
max.setAttribute('src', 'images/maxed.png');
|
||||||
|
} else {
|
||||||
|
max.setAttribute('src', 'images/max.png');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var min = document.getElementById('min');
|
||||||
|
if (min) {
|
||||||
|
min.addEventListener('click', () => {
|
||||||
|
//发送最小化命令
|
||||||
|
ipcRenderer.send('window-min');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('close').addEventListener('click', () => {
|
||||||
|
//发送关闭命令
|
||||||
|
ipcRenderer.send('window-close');
|
||||||
|
})
|
||||||
|
ipcRenderer.on('main-window-max', (event) => {
|
||||||
|
max.classList.remove('icon-max');
|
||||||
|
max.classList.add('icon-maxed');
|
||||||
|
});
|
||||||
|
ipcRenderer.on('main-window-unmax', (event) => {
|
||||||
|
max.classList.remove('icon-maxed');
|
||||||
|
max.classList.add('icon-max');
|
||||||
|
});
|
||||||
|
|
||||||
|
function jump(text) {
|
||||||
|
ipcRenderer.send(text);
|
||||||
}
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="Content-Security-Policy-Report-Only">
|
||||||
|
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>MTArk</title>
|
||||||
|
<link rel="stylesheet" href="css/uikit.min.css" />
|
||||||
|
<script src="js/uikit.min.js"></script>
|
||||||
|
<script src="js/uikit-icons.min.js"></script>
|
||||||
|
<script src="js/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="js/anime.min.js"></script>
|
||||||
|
<script>if (typeof module === 'object') { window.jQuery = window.$ = module.exports; };</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ul id="topbar" class="topbar uk-iconnav" style="-webkit-app-region: no-drag;position: absolute;right: 5%;top: 2%">
|
||||||
|
<li><span id="min" uk-icon="icon: minus"></span></li>
|
||||||
|
<li><span id="max" uk-icon="icon: copy"></span></li>
|
||||||
|
<li><button id="close" type="button" class="uk-close-large" uk-close></button></li>
|
||||||
|
</ul>
|
||||||
|
<table class="uk-table uk-table-hover uk-table-divider uk-margin">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>世界名称</th>
|
||||||
|
<th>修改时间</th>
|
||||||
|
<th>操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="worldlist">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div id="delworld_modal" uk-modal>
|
||||||
|
<div class="uk-modal-dialog uk-modal-body">
|
||||||
|
<h2 class="uk-modal-title">你确定吗?</h2>
|
||||||
|
<p>你将会永远失去这个世界</p>
|
||||||
|
<p class="uk-text-right">
|
||||||
|
<button class="uk-button uk-button-primary uk-modal-close" type="button">取消</button>
|
||||||
|
<button id="delworld" class="uk-button uk-button-danger uk-modal-close" type="button">确定</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="./renderer.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue