diff --git a/src/services/miiverse-api/routes/portal.html b/src/portal/index.html similarity index 82% rename from src/services/miiverse-api/routes/portal.html rename to src/portal/index.html index e5d8c31..d5facf9 100644 --- a/src/services/miiverse-api/routes/portal.html +++ b/src/portal/index.html @@ -2,6 +2,7 @@ Miiverse Testing + @@ -12,6 +13,9 @@ cave.snd_playBgm(BGM_CAVE_MAIN); cave.transition_end(); cave.toolbar_setVisible(visibility = true); + + \ No newline at end of file diff --git a/src/portal/js/olv.js b/src/portal/js/olv.js new file mode 100644 index 0000000..88d0d9e --- /dev/null +++ b/src/portal/js/olv.js @@ -0,0 +1,1894 @@ +var Olv = Olv || {}; +(function(a, b) { + b.init || (b.init = a.Deferred(function() { + a(this.resolve) + }).promise(), b.Router = function() { + this.routes = [], this.guard = a.Deferred() + }, a.extend(b.Router.prototype, { + connect: function(a, b) { + a instanceof RegExp || (a = new RegExp(a)), this.routes.push([a, b]) + }, + dispatch: function(b) { + this.guard.resolve(b), this.guard = a.Deferred(); + for (var c, d = b.pathname, e = 0; c = this.routes[e]; e++) { + var f = d.match(c[0]); + f && c[1].call(this, f, b, this.guard.promise()) + } + } + }), b.router = new b.Router, a(document).on("pjax:end", function(c, d) { + a(document).trigger("olv:pagechange", [d]), b.router.dispatch(location) + }), b.init.done(function() { + b.init.done(function() { + b.router.dispatch(location) + }) + }), b.Locale = { + Data: {}, + text: function(a) { + var c = Array.prototype.slice.call(arguments); + return c.splice(1, 0, -1), b.Locale.textN.apply(this, c) + }, + textN: function(a, c) { + if (b.Cookie.get("plain_msgid")) return a; + c = +c || 0; + var d = b.Locale.Data[a]; + if (!d) return a; + var e, f, g = d.quanttype || "o", + h = "1_o" === g && 1 === c || "01_o" === g && (0 === c || 1 === c); + if (h ? (e = d.text_value_1 || d.value_1, f = d.text_args_1 || d.args_1) : (e = d.text_value || d.value, f = d.text_args || d.args), !f) return e; + var i = Array.prototype.slice.call(arguments, 2), + j = 0; + return e.replace(/%s/g, function() { + return i[f[j++] - 1] + }) + } + }, b.loc = b.Locale.text, b.loc_n = b.Locale.textN, b.print = function(a) { + "undefined" != typeof console && console.log(a) + }, b.deferredAlert = function(b) { + var c = a.Deferred(); + return setTimeout(function() { + alert(b), c.resolve() + }, 0), c.promise() + }, b.deferredConfirm = function(b) { + var c = a.Deferred(); + return setTimeout(function() { + var a = confirm(b); + c.resolve(a) + }, 0), c.promise() + }, b.Cookie = { + set: function(a, b, c) { + var d = encodeURIComponent(a) + "=" + encodeURIComponent(b) + "; path=/"; + c && (d += "; expires=" + c.toUTCString()), document.cookie = d + }, + get: function(a) { + if (a && document.cookie) + for (var b = document.cookie.split("; "), c = 0; c < b.length; c++) { + var d = b[c].split("="); + if (a === decodeURIComponent(d[0])) return decodeURIComponent(d[1]) + } + } + }, b.ErrorViewer = { + open: function(a) { + a = a || {}; + var c = +a.error_code, + d = a.message || a.msgid && b.loc(a.msgid); + c || (c = 1219999, d = d || b.loc("olv.portal.error.500.for_offdevice")); + var e = String(c).match(/^([0-9]{3})([0-9]{4})$/); + e && (c = e[1] + "-" + e[2]); + var f = b.loc("olv.portal.error.code", c); + return b.showMessage(f, d || "") + } + }, b.Net = { + ajax: function(c) { + var d = a.ajax(c), + e = b.Net._pageId, + f = d.then(function(c, d, f) { + var g = b.Net._pageId === e, + h = c && "object" == typeof c && !c.success || !g, + i = [c, d, f, g]; + return h ? a.Deferred().rejectWith(this, i) : a.Deferred().resolveWith(this, i) + }, function(c, d) { + var f = b.Net.getDataFromXHR(c); + void 0 === f && (f = c.responseText); + var g = b.Net._pageId === e; + return a.Deferred().rejectWith(this, [f, d, c, g]) + }); + return f.fail(b.Net.errorFeedbackHandler), f.promise(d), d + }, + _pageId: 1, + getDataFromXHR: function(b) { + var c = b.responseText, + d = b.getResponseHeader("Content-Type"); + if (c && d && /^application\/json(?:;|$)/.test(d)) try { + return a.parseJSON(c) + } catch (e) {} + }, + getErrorFromXHR: function(a) { + var c = b.Net.getDataFromXHR(a), + d = c && c.errors && c.errors[0]; + if (d && "object" == typeof d) return d; + var e = a.status; + return e ? e < 500 ? { + error_code: 1210902, + message: b.loc("olv.portal.error.failed_to_connect.for_offdevice") + } : { + error_code: 1219999, + message: b.loc("olv.portal.error.500.for_offdevice") + } : { + error_code: 1219998, + message: b.loc("olv.portal.error.network_unavailable.for_offdevice") + } + }, + _isLeavingPage: !1, + willLeavePage: function() { + b.Net._isLeavingPage = !0, setTimeout(function() { + b.Net._isLeavingPage = !1 + }, 100) + }, + errorFeedbackHandler: function(a, c, d, e) { + if ("abort" !== c && e && (d.status || !b.Net._isLeavingPage)) { + var f = this, + g = arguments; + setTimeout(function() { + b.Net._errorFeedbackHandler.apply(f, g) + }, d.status ? 0 : 5e3) + } + }, + _errorFeedbackHandler: function(c, d, e, f) { + var g = b.Net.getErrorFromXHR(e); + this.silent || b.ErrorViewer.open(g), a(document).trigger("olv:ajax:error", [g, d, e]) + }, + get: function(a, c, d, e) { + return b.Net.ajax({ + method: "GET", + url: a, + data: c, + success: d, + dataType: e + }) + }, + post: function(a, c, d, e) { + return b.Net.ajax({ + method: "POST", + url: a, + data: c, + success: d, + dataType: e + }) + } + }, b.Browsing = { + setup: function() { + a(document).on("click", "[data-href]", this.onDataHrefClick), a(window).on("click submit", this.onMayLeavePage) + }, + onDataHrefClick: function(c) { + if (!c.isDefaultPrevented() && !a(c.target).closest("a,button").length) { + var d = a(this); + if (!d.hasClass("disabled")) { + var e = d.attr("data-href"); + e && (b.Net.willLeavePage(), window.location.href = e, c.preventDefault()) + } + } + }, + onMayLeavePage: function(c) { + c.isDefaultPrevented() || "click" === c.type && !a(c.target).closest("[href]").length || b.Net.willLeavePage() + } + }, b.init.done(function() { + b.Browsing.setup() + }), b.Utils = {}, b.Utils.toJSONString = "undefined" != typeof JSON ? JSON.stringify : function() { + function a(a) { + return "\\u" + (65536 + a.charCodeAt(0)).toString(16).substring(1) + } + + function b(c) { + switch (typeof c) { + case "string": + return '"' + c.replace(/[\u0000-\u001f\"\\\u2028\u2029]/g, a) + '"'; + case "number": + case "boolean": + return "" + c; + case "object": + if (!c) return "null"; + switch (Object.prototype.toString.call(c).slice(8, -1)) { + case "String": + case "Number": + case "Boolean": + return b(c.valueOf()); + case "Array": + for (var d = [], e = 0; e < c.length; e++) d.push(b(c[e])); + return "[" + d.join(",") + "]"; + case "Object": + var d = []; + for (var e in c) c.hasOwnProperty(e) && d.push(b(e) + ":" + b(c[e])); + return "{" + d.join(",") + "}" + } + return "null" + } + return "null" + } + return b + }(), b.Utils._staticRoot = null, b.Utils.staticURL = function(c) { + if (/^https?:/.test(c)) return c; + var d = b.Utils._staticRoot; + return null === d && document.body && (d = b.Utils._staticRoot = (a(document.body).attr("data-static-root") || "").replace(/\/$/, "")), (d || "") + c.replace(/^(?!\/)/, "/") + }, b.Utils.isIE8AndEarlierStyle = !!document.createStyleSheet && void 0 === document.documentElement.style.opacity, b.Utils.isIEStyle = !!window.TextRange, b.Utils.addPlatformClass = function() { + var c = a(document.documentElement), + d = navigator.userAgent, + e = /\bWin/.test(d) ? "win" : /\bMac/.test(d) ? "mac" : "other"; + c.addClass("os-" + e), b.Utils.isIE8AndEarlierStyle && c.addClass("ie8-earlier"), b.Utils.isIEStyle && c.addClass("ie") + }, b.Utils.addPlatformClass(), b.Utils.fixWebFontLoadTiming = function() { + var a = document.createStyleSheet(); + a.cssText = ":before, :after { content: none !important; }", setTimeout(function() { + var b = a.owningElement; + b.parentNode.removeChild(b) + }, 20) + }, b.Utils.isIE8AndEarlierStyle && b.init.done(b.Utils.fixWebFontLoadTiming), b.Utils.triggerHandlers = { + keypress: function(b) { + 13 !== b.which || b.isDefaultPrevented() || (b.preventDefault(), a(this).click()) + }, + mouseup: function(a) { + this.blur() + } + }, b.init.done(function(a) { + a(document).on(b.Utils.triggerHandlers, ".trigger") + }), b.Content = {}, b.Content.autopagerize = function(c, d) { + function e() { + if (!(k._disabledCount || h.scrollTop() + h.height() + 200 < f.offset().top + f.outerHeight())) { + var d = a("
").attr("class", "post-list-loading").append(a("").attr({ + src: b.Utils.staticURL("/img/loading-image-green.gif"), + alt: "" + })).appendTo(f); + i = a.ajax({ + url: g, + headers: { + "X-AUTOPAGERIZE": !0 + } + }).done(function(b) { + var h = a("
" + b + "
").find(c); + g = h.attr("data-next-page-url") || "", g || j.resolve(), f.trigger("olv:autopagerize", [h, g, d]), h.children().each(function() { + this.id && a("#" + this.id).length && a(this).detach() + }), f.attr("data-next-page-url", g), f.append(h.children()), g && setTimeout(e, 0) + }).always(function() { + d.remove(), i = null + }), k.disable(i) + } + } + var f = a(c), + g = f.attr("data-next-page-url"); + if (g) { + a(document.body).addClass("is-autopagerized"); + var h = a(window), + i = null, + j = a.Deferred(), + k = b.Content.autopagerize; + h.on("scroll", e), j.done(function() { + h.off("scroll", e), i && i.abort(), a(document.body).removeClass("is-autopagerized") + }), setTimeout(e, 0), d.done(j.resolve) + } + }, b.Content.autopagerize._disabledCount = 0, b.Content.autopagerize.disable = function(a) { + var c = b.Content.autopagerize; + c._disabledCount++, a.always(function() { + c._disabledCount-- + }) + }, b.Content.preloadImages = function() { + for (var a = arguments.length, b = a; b--;) { + document.createElement("img").src = arguments[b] + } + }, b.Form = { + toggleDisabled: function(c, d) { + var e = void 0 === d; + return c.each(function() { + var c = a(this), + f = e ? !b.Form.isDisabled(c) : d; + if (c.toggleClass("disabled", f), void 0 !== this.form) c.prop("disabled", f); + else { + var g = f ? "href" : "data-disabled-href", + h = f ? "data-disabled-href" : "href", + i = c.attr(g); + void 0 !== i && (c.removeAttr(g), c.attr(h, i)) + } + }), c + }, + isDisabled: function(a) { + return a.length && void 0 !== a[0].form ? a.prop("disabled") : a.hasClass("disabled") + }, + disable: function(a, c) { + return b.Form.toggleDisabled(a, !0), c.always(function() { + b.Form.toggleDisabled(a, !1) + }), a + }, + disableSoon: function(a, c) { + return setTimeout(function() { + "pending" === c.state() && b.Form.toggleDisabled(a, !0) + }, 0), c.always(function() { + b.Form.toggleDisabled(a, !1) + }), a + }, + emulateInputEvent: function(b, c) { + if (b.length && void 0 === b[0].oninput) { + var d = a.map(b, function(a) { + return a.value + }), + e = setInterval(function() { + for (var c = 0, e = b.length; c < e; c++) { + var f = b[c].value; + f !== d[c] && (d[c] = f, a(b[c]).trigger("input")) + } + }, 100); + c.always(function() { + clearInterval(e) + }) + } + }, + submit: function(b, c) { + b.trigger("olv:form:submit", [c || a()]); + var d = b.serializeArray(), + e = c && c.is("input, button") && c.prop("name"); + e && d.push({ + name: e, + value: c.val() + }); + var f = { + method: b.prop("method"), + url: b.attr("action"), + data: d + }; + return this.send(f, c) + }, + get: function(a, b, c) { + var d = { + method: "GET", + url: a, + data: b + }; + return this.send(d, c) + }, + _token: null, + token: function() { + return null === b.Form._token && (b.Form._token = a("body").attr("data-token")), b.Form._token + }, + post: function(c, d, e) { + d || (d = {}), a.isArray(d) ? d.push({ + name: "token", + value: b.Form.token() + }) : d.token = b.Form.token(); + var f = { + method: "POST", + url: c, + data: d + }; + return this.send(f, e) + }, + send: function(c, d) { + var e = b.Net.ajax(c); + return a(document).trigger("olv:form:send", [e, c, d || a()]), d && (b.Form.disableSoon(d, e), d.addClass("loading"), e.always(function() { + d.removeClass("loading") + })), e + }, + updateParentClass: function(c) { + switch (c.type) { + case "radio": + var d = a(c.form ? c.form.elements[c.name] : 'input[name="' + c.name + '"]'); + d.each(function() { + a(this).parent().toggleClass("checked", this.checked) + }), b.Utils.isIE8AndEarlierStyle && d.parent().addClass("changing").removeClass("changing"); + break; + case "checkbox": + a(c).parent().toggleClass("checked", c.checked) + } + }, + setup: function() { + a(document).on("click", "input", function(a) { + a.isDefaultPrevented() || b.Form.updateParentClass(this) + }) + }, + setupForPage: function() { + a("input:checked").each(function() { + b.Form.updateParentClass(this) + }) + }, + reset: function(c) { + c.each(function() { + this.reset(), a(this).find("input").each(function() { + b.Form.updateParentClass(this) + }) + }) + }, + validateValueLength: function(b) { + a(this).find("[minlength], [maxlength]").each(function() { + var c = a(this), + d = +c.attr("minlength"); + isNaN(d) && (d = -(1 / 0)); + var e = +c.attr("maxlength"); + isNaN(e) && (e = 1 / 0); + var f = c.val(); + if (!(f.length >= d && f.length <= e)) return void b.preventDefault() + }) + } + }, b.init.done(b.Form.setup), b.router.connect("", b.Form.setupForPage), b.Guest = { + isGuest: function() { + return a("body").hasClass("guest") + } + }, b.DecreasingTimer = function(a, b, c) { + this.callback_ = a, this.initialInterval_ = b || 1e4, this.maxInterval_ = c || 1 / 0, this.interval_ = this.initialInterval_, this.timeouts_ = [] + }, b.DecreasingTimer.prototype.resetInterval = function() { + this.interval_ = this.initialInterval_, this.clearAllTimeouts(), this.invoke() + }, b.DecreasingTimer.prototype.clearAllTimeouts = function() { + a(this.timeouts_).each(a.proxy(function(a, b) { + this.clearTimeout(b) + }, this)) + }, b.DecreasingTimer.prototype.clearTimeout = function(a) { + for (var b = 0, c = this.timeouts_.length; b < c; ++b) + if (this.timeouts_[b] == a) { + clearTimeout(this.timeouts_[b]), this.timeouts_.splice(b, 1); + break + } + }, b.DecreasingTimer.prototype.invoke = function() { + this.callback_(); + var b; + b = setTimeout(a.proxy(function() { + this.invoke(), this.clearTimeout(b) + }, this), this.interval_), this.timeouts_.push(b), this.interval_ = Math.min(Math.floor(1.5 * this.interval_), this.maxInterval_) + }, b.UpdateChecker = function(a, c) { + this._settings = {}, b.DecreasingTimer.call(this, this.callback_, a, c) + }, b.UpdateChecker.prototype = new b.DecreasingTimer, b.UpdateChecker.getInstance = function() { + return void 0 == b.UpdateChecker.instance && (b.UpdateChecker.instance = new b.UpdateChecker(2e4, 18e5)), b.UpdateChecker.instance + }, b.UpdateChecker.prototype.callback_ = function() { + var c = {}; + a.each(this._settings, a.proxy(function(d) { + void 0 != this._settings[d].pathname && this._settings[d].pathname != location.pathname ? delete this._settings[d] : a.each(this._settings[d].params, a.proxy(function(a, d) { + c[a] = b.Utils.toJSONString(d) + }, this)) + }, this)), b.Net.ajax({ + url: "/check_update.json", + data: c, + silent: !0, + cache: !1 + }).done(a.proxy(function(b) { + a(this).triggerHandler("update", [b]) + }, this)) + }, b.UpdateChecker.prototype.onUpdate = function(a, b, c, d) { + this._settings[a] = { + params: b, + update: c + }, d && (this._settings[a].pathname = location.pathname) + }, b.SocialButton = {}, b.SocialButton.popUpDialog = function(a) { + window.open(a.attr("data-share-url"), "miiverse_share_" + a.attr("data-service-name"), ["width=" + a.attr("data-width"), "height=" + a.attr("data-height"), "location=yes", "resizable=yes", "toolbar=no", "menubar=no", "scrollbars=no", "status=no"].join(",")) + }, b.SocialButton.onClick = function(c) { + if (!c.isDefaultPrevented()) { + c.preventDefault(); + var d = a(this); + "1" === d.attr("data-is-popup") ? b.SocialButton.popUpDialog(d) : location.href = d.attr("data-share-url") + } + }, b.SocialButton.setup = function(c) { + a(document).on("click", ".social-button", b.SocialButton.onClick), c.done(function() { + a(document).off("click", ".social-button", b.SocialButton.onClick) + }) + }, b.CookiePolicyNotice = {}, b.CookiePolicyNotice.setup = function(c) { + var d = a("#cookie-policy-notice"); + d.length && d.find(".js-cookie-policy-notice").on("click", function() { + var a = new Date; + a.setFullYear(a.getFullYear() + 1), b.Cookie.set("cookie_policy_notice_seen", "true", a), d.slideUp("fast", function() { + d.remove() + }) + }) + }, b.OpenTruncatedTextButton = {}, b.OpenTruncatedTextButton.setup = function(b) { + var c = a(b); + c.on("click", ".js-open-truncated-text-button", function(a) { + a.preventDefault(), c.find(".js-truncated-text, .js-open-truncated-text-button").addClass("none"), c.find(".js-full-text").removeClass("none") + }) + }, b.ModalWindowManager = {}, b.ModalWindowManager._windows = [], b.ModalWindowManager.currentWindow = null, b.ModalWindowManager.closeAll = function() { + for (; this.currentWindow;) this.currentWindow.close() + }, b.ModalWindowManager.closeUntil = function(a) { + if (a.guard) + for (var b; + (b = this.currentWindow) && (b.close(), b !== a);); + }, b.ModalWindowManager.register = function(a) { + var b = this._windows; + b.length ? b[b.length - 1].element.removeClass("active-dialog") : this.toggleMask(!0), a.element.addClass("active-dialog"), b.push(a), this.currentWindow = a + }, b.ModalWindowManager.unregister = function(a) { + if (this.currentWindow !== a) throw new Error("Failed to unregister modal window"); + var b = this._windows; + b.pop().element.removeClass("active-dialog"); + var c = b.length ? b[b.length - 1] : null; + c ? c.element.addClass("active-dialog") : this.toggleMask(!1), this.currentWindow = c + }, b.ModalWindowManager._mask = null, b.ModalWindowManager.toggleMask = function(b) { + var c = this._mask; + c || (c = this._mask = a("
", { + class: "mask none" + }).on("click", new Function).appendTo(document.body)), c.toggleClass("none", !b) + }, b.ModalWindowManager.setup = function() { + a(document).on("click", "[data-modal-open]", function(c) { + var d = a(this); + if (!b.Form.isDisabled(d) && !c.isDefaultPrevented()) { + c.preventDefault(); + var e = a.Event("olv:modalopen"); + if (d.trigger(e), !e.isDefaultPrevented()) { + var f = a(d.attr("data-modal-open")); + f.attr("data-is-template") && (f = f.clone().removeAttr("id")); + new b.ModalWindow(f, this).open() + } + } + }), a(document).on("click", ".olv-modal-close-button", function(a) { + if (!a.isDefaultPrevented()) { + a.preventDefault(); + var c = b.ModalWindowManager.currentWindow; + c && c.close() + } + }), a(document).on("olv:modal", function(a, c, d) { + b.Content.autopagerize.disable(d) + }) + }, b.init.done(function() { + b.ModalWindowManager.setup() + }), a(document).on("olv:pagechange", function() { + b.ModalWindowManager.closeAll() + }), b.ModalWindow = function(b, c) { + this.element = a(b), this.triggerElement = a(c), this.temporary = !this.element.parent().length; + var d = a.trim(this.element.attr("data-modal-types")); + this.types = d ? d.split(/\s+/) : [], this.guard = null + }, b.ModalWindow.prototype.open = function() { + if (!this.guard) return document.activeElement && document.activeElement.blur(), b.ModalWindowManager.register(this), b.Form.toggleDisabled(this.triggerElement, !0), this.element.addClass("modal-window-open").removeClass("none"), this.temporary && this.element.appendTo(document.body), this.triggerOpenHandlers(a.Deferred()), this + }, b.ModalWindow.prototype.triggerOpenHandlers = function(a) { + this.guard = a; + for (var b, c = [this, a.promise()], d = 0; b = this.types[d]; d++) this.element.trigger("olv:modal:" + b, c); + this.element.trigger("olv:modal", c) + }, b.ModalWindow.prototype.close = function() { + if (this.guard) return this.guard.resolve(), this.guard = null, b.ModalWindowManager.unregister(this), this.temporary && this.element.remove(), this.element.addClass("none").removeClass("modal-window-open"), b.Form.toggleDisabled(this.triggerElement, !1), this + }, b.SimpleDialog = { + _element: null, + element: function() { + return (this._element || (this._element = a("
", { + class: "dialog" + }).append(a("
", { + class: "dialog-inner" + }).append(a("
", { + class: "window" + }).append(a("

", { + class: "window-title" + }), a("
", { + class: "window-body" + }).append(a("

", { + class: "window-body-content" + }), a("

", { + class: "form-buttons" + }).append(a("