diff --git a/404.php b/404.php index 75e9215..e786e83 100644 --- a/404.php +++ b/404.php @@ -9,7 +9,7 @@ get_header(); ?>
-
+
diff --git a/README.md b/README.md index 36f5376..090022f 100644 --- a/README.md +++ b/README.md @@ -7,21 +7,21 @@ English | [简体中文](README.zh-CN.md)

- - + + - - + + - - + +

- Report Bug + Report Bug · - Request Feature + Request Feature

WordPress theme that focus on reading experience

@@ -44,4 +44,4 @@ We welcome all contributions. You can submit any ideas as pull requests or as is ## 📃 License -The project is released under the GNU General Public License v3.0, see the [LICENCE](https://github.com/seatonjiang/kratos/blob/main/LICENSE) file for details. +The project is released under the GNU General Public License v3.0, see the [LICENCE](https://github.com/devhaozi/kratos/blob/main/LICENSE) file for details. diff --git a/README.zh-CN.md b/README.zh-CN.md index 5bf231a..8e53184 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -7,21 +7,21 @@

- - + + - - + + - - + +

- 报告问题 + 报告问题 · - 功能需求 + 功能需求

专注阅读体验的 WordPress 主题

@@ -44,4 +44,4 @@ ## 📃 开源许可 -项目基于 GNU 通用公共许可证 v3.0 发布,详细说明请参阅 [LICENCE](https://github.com/seatonjiang/kratos/blob/main/LICENSE) 文件。 +项目基于 GNU 通用公共许可证 v3.0 发布,详细说明请参阅 [LICENCE](https://github.com/devhaozi/kratos/blob/main/LICENSE) 文件。 diff --git a/assets/css/loader.css b/assets/css/loader.css new file mode 100644 index 0000000..acc1d3f --- /dev/null +++ b/assets/css/loader.css @@ -0,0 +1,236 @@ +@charset "utf-8"; +/* +Loader CSS +By:耗子 +*/ +body .loader { + position: fixed; + top: 0; + left: 0; + z-index: 99999; + display: none; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, .2); + text-align: center; + font-size: 2em +} +body .loader_overlay { + width: 150px; + height: 150px; + background: transparent; + box-shadow: 0px 0px 0px 1000px rgba(255, 255, 255, 0.67), 0px 0px 19px 0px rgba(0, 0, 0, 0.16) inset; + border-radius: 100%; + z-index: -1; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; +} +body .loader_cogs { + z-index: -2; + width: 100px; + height: 100px; + top: -120px !important; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; +} +body .loader_cogs__top { + position: relative; + width: 100px; + height: 100px; + -webkit-transform-origin: 50px 50px; + transform-origin: 50px 50px; + -webkit-animation: rotate 10s infinite linear; + animation: rotate 10s infinite linear; +} +body .loader_cogs__top div:nth-of-type(1) { + -webkit-transform: rotate(30deg); + transform: rotate(30deg); +} +body .loader_cogs__top div:nth-of-type(2) { + -webkit-transform: rotate(60deg); + transform: rotate(60deg); +} +body .loader_cogs__top div:nth-of-type(3) { + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} +body .loader_cogs__top div.top_part { + width: 100px; + border-radius: 10px; + position: absolute; + height: 100px; + background: #f98db9; +} +body .loader_cogs__top div.top_hole { + width: 50px; + height: 50px; + border-radius: 100%; + background: white; + position: absolute; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; +} +body .loader_cogs__left { + position: relative; + width: 80px; + -webkit-transform: rotate(16deg); + transform: rotate(16deg); + top: 28px; + -webkit-transform-origin: 40px 40px; + transform-origin: 40px 40px; + -webkit-animation: rotate_left 10s .1s infinite reverse linear; + animation: rotate_left 10s .1s infinite reverse linear; + left: -24px; + height: 80px; +} +body .loader_cogs__left div:nth-of-type(1) { + -webkit-transform: rotate(30deg); + transform: rotate(30deg); +} +body .loader_cogs__left div:nth-of-type(2) { + -webkit-transform: rotate(60deg); + transform: rotate(60deg); +} +body .loader_cogs__left div:nth-of-type(3) { + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} +body .loader_cogs__left div.left_part { + width: 80px; + border-radius: 6px; + position: absolute; + height: 80px; + background: #97ddff; +} +body .loader_cogs__left div.left_hole { + width: 40px; + height: 40px; + border-radius: 100%; + background: white; + position: absolute; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; +} +body .loader_cogs__bottom { + position: relative; + width: 60px; + top: -65px; + -webkit-transform-origin: 30px 30px; + transform-origin: 30px 30px; + -webkit-animation: rotate_left 10.2s .4s infinite linear; + animation: rotate_left 10.2s .4s infinite linear; + -webkit-transform: rotate(4deg); + transform: rotate(4deg); + left: 79px; + height: 60px; +} +body .loader_cogs__bottom div:nth-of-type(1) { + -webkit-transform: rotate(30deg); + transform: rotate(30deg); +} +body .loader_cogs__bottom div:nth-of-type(2) { + -webkit-transform: rotate(60deg); + transform: rotate(60deg); +} +body .loader_cogs__bottom div:nth-of-type(3) { + -webkit-transform: rotate(90deg); + transform: rotate(90deg); +} +body .loader_cogs__bottom div.bottom_part { + width: 60px; + border-radius: 5px; + position: absolute; + height: 60px; + background: #ffcd66; +} +body .loader_cogs__bottom div.bottom_hole { + width: 30px; + height: 30px; + border-radius: 100%; + background: white; + position: absolute; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; +} + +/* Animations */ +@-webkit-keyframes rotate { + from { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes rotate { + from { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@-webkit-keyframes rotate_left { + from { + -webkit-transform: rotate(16deg); + transform: rotate(16deg); + } + to { + -webkit-transform: rotate(376deg); + transform: rotate(376deg); + } +} +@keyframes rotate_left { + from { + -webkit-transform: rotate(16deg); + transform: rotate(16deg); + } + to { + -webkit-transform: rotate(376deg); + transform: rotate(376deg); + } +} +@-webkit-keyframes rotate_right { + from { + -webkit-transform: rotate(4deg); + transform: rotate(4deg); + } + to { + -webkit-transform: rotate(364deg); + transform: rotate(364deg); + } +} +@keyframes rotate_right { + from { + -webkit-transform: rotate(4deg); + transform: rotate(4deg); + } + to { + -webkit-transform: rotate(364deg); + transform: rotate(364deg); + } +} diff --git a/assets/js/kratos.js b/assets/js/kratos.js index c70de31..748cb54 100644 --- a/assets/js/kratos.js +++ b/assets/js/kratos.js @@ -150,9 +150,9 @@ var consoleConfig = function () { console.log( - "\n Kratos v" + + "\n Kratos Pjax Edition v" + KRATOS_VERSION + - "\n\n https://github.com/seatonjiang/kratos \n\n" + "\n\n https://github.com/devhaozi/kratos \n\n" ); }; diff --git a/assets/js/pjax.js b/assets/js/pjax.js new file mode 100644 index 0000000..1e6b6de --- /dev/null +++ b/assets/js/pjax.js @@ -0,0 +1,929 @@ +/*! + * 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 - Where to stick the response body. Usually a String selector. + // $(container).html(xhr.responseBody) + // (default: current jquery context) + // 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) { + var context = this + return this.on('click.pjax', selector, function(event) { + var opts = $.extend({}, optionsFor(container, options)) + if (!opts.container) + opts.container = $(this).attr('data-pjax') || context + 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') + // + // $(document).on('click', 'a', function(event) { + // var container = $(this).closest('[data-pjax-container]') + // $.pjax.click(event, container) + // }) + // + // Returns nothing. + function handleClick(event, container, options) { + options = optionsFor(container, options) + + var link = event.currentTarget + + 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) { + // var container = $(this).closest('[data-pjax-container]') + // $.pjax.submit(event, 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 - Where to stick the response body. + // $(container).html(xhr.responseBody) + // 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 target = options.target + + var hash = parseURL(options.url).hash + + var context = options.context = findContainerFor(options.container) + + // 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: context.selector }) + } else { + options.data._pjax = context.selector + } + // + function fire(type, args, props) { + if (!props) props = {} + props.relatedTarget = 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', context.selector) + + 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: context.selector, + 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(options.container, document.activeElement) + + // Clear out any focused controls before inserting new page contents. + if (blurFocus) { + try { + document.activeElement.blur() + } catch (e) { } + } + + 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: context.selector, + 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, 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' + } + //changed by jackchain cancel cache; + var cache = cacheMapping[state.id] || [] + //console.log(cache); + var container = $(cache[0] || state.container), contents = cache[1] + //console.log(container); + if (container.length) { + if (previousState) { + // Cache current container before replacement and inform the + // cache which direction the history shifted. + cachePop(direction, previousState.id, cloneContents(container)) + } + + var popstateEvent = $.Event('pjax:popstate', { + state: state, + direction: direction + }) + container.trigger(popstateEvent) + + var options = { + id: state.id, + url: state.url, + container: container, + 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 + } 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 = $('
', { + method: method === 'GET' ? 'GET' : 'POST', + action: url, + style: 'display:none' + }) + + if (method !== 'GET' && method !== 'POST') { + form.append($('', { + 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($('', {type: 'hidden', name: pair[0], value: pair[1]})) + }) + } else if ($.isArray(data)) { + $.each(data, function(index, value) { + form.append($('', {type: 'hidden', name: value.name, value: value.value})) + }) + } else if (typeof data === 'object') { + var key + for (key in data) + form.append($('', {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) jQuery._data(this, 'globalEval', false) + }) + return [container.selector, 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, '') + 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) { + // Both container and options + if ( container && options ) + options.container = container + + // First argument is options Object + else if ( $.isPlainObject(container) ) + options = container + + // Only container + else + options = {container: container} + + // Find and validate container + if (options.container) + options.container = findContainerFor(options.container) + + return options + } + + // Internal: Find container element for a variety of inputs. + // + // Because we can't persist elements using the history API, we must be + // able to find a String selector that will consistently find the Element. + // + // container - A selector String, jQuery object, or DOM Element. + // + // Returns a jQuery object whose context is `document` and has a selector. + function findContainerFor(container) { + container = $(container) + + if ( !container.length ) { + throw "no pjax container for " + container.selector + } else if ( container.selector !== '' && container.context === document ) { + return container + } else if ( container.attr('id') ) { + return $('#' + container.attr('id')) + } else { + throw "cant get selector for pjax 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 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 + + // Attempt to parse response html into elements + if (fullDocument) { + var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0])) + var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0])) + } else { + var $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) { + // If they specified a fragment, look for it in the response + // and pull it out. + if (options.fragment === 'body') { + var $fragment = $body + } else { + var $fragment = findAll($body, 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 + //console.log(obj.contents); + //obj.scripts = findAll(obj.contents, 'script[src]').remove() + //console.log(obj.contents); + //console.log(obj.scripts); + //obj.contents = obj.contents.not(obj.scripts) + //console.log(obj.contents); + } + + // 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) + if (id = popStack.pop()) + 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: 0, + //cache:false,//changed by jackchain fire IE cache bug + 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 ( $.inArray('state', $.event.props) < 0 ) + $.event.props.push('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)/) + + $.support.pjax ? enable() : disable() + + })(jQuery); \ No newline at end of file diff --git a/footer.php b/footer.php index f3ed76f..5a4a279 100644 --- a/footer.php +++ b/footer.php @@ -14,14 +14,14 @@ <span class="kicon i-up"></span> </div> </div> - <?php if (!empty(kratos_option('g_wechat_fieldset')['g_wechat'])) { ?> + <?php if (!empty(kratos_option('g_wechat_fieldset')['g_wechat'])) { ?> <div class="wechat"> <span class="kicon i-wechat"></span> <div class="wechat-pic"> <img src="<?php echo kratos_option('g_wechat_fieldset')['g_wechat_img']; ?>"> </div> </div> - <?php } ?> + <?php } ?> <div class="search"> <span class="kicon i-find"></span> <form class="search-form" role="search" method="get" action="<?php echo home_url('/'); ?>"> @@ -33,31 +33,122 @@ <div class="row"> <div class="col-12 text-center"> <p class="social"> - <?php - if (!empty(kratos_option('s_social_fieldset'))) { - foreach (kratos_option('s_social_fieldset') as $key => $value) { - if (kratos_option('s_social_fieldset')[$key]) { - echo '<a target="_blank" rel="nofollow" href="' . kratos_option('s_social_fieldset')[$key] . '"><i class="kicon i-' . str_replace(array("s_", "_url"), array('', ''), $key) . '"></i></a>'; - } - } - } - ?> + <?php + if (!empty(kratos_option('s_social_fieldset'))) { + foreach (kratos_option('s_social_fieldset') as $key => $value) { + if (kratos_option('s_social_fieldset')[$key]) { + echo '<a target="_blank" rel="nofollow" href="' . kratos_option('s_social_fieldset')[$key] . '"><i class="kicon i-' . str_replace(array("s_", "_url"), array('', ''), $key) . '"></i></a>'; + } + } + } + ?> </p> - <?php - echo '<p>' . kratos_option('s_copyright', 'COPYRIGHT © ' . wp_date('Y') . ' ' . get_bloginfo('name') . '. ALL RIGHTS RESERVED.') . '</p>'; - echo '<p>Theme <a href="https://github.com/seatonjiang/kratos" target="_blank" rel="nofollow">Kratos</a> Made By <a href="https://seatonjiang.com" target="_blank" rel="nofollow">Seaton Jiang</a></p>'; - if (kratos_option('s_icp')) { - echo '<p><a href="https://beian.miit.gov.cn/" target="_blank" rel="nofollow">' . kratos_option('s_icp') . '</a></p>'; - } - if (kratos_option('s_gov')) { - echo '<p><a href="' . kratos_option('s_gov_link') . '" target="_blank" rel="nofollow" ><i class="police-ico"></i>' . kratos_option('s_gov') . '</a></p>'; - } - ?> + <p class="social"> + <?php + $bookmarks = get_bookmarks([ + 'orderby' => 'name', + 'order' => 'ASC' + ]); + foreach ($bookmarks as $bookmark) { + echo '<a href="' . esc_url($bookmark->link_url) . '">' . esc_html($bookmark->link_name) . '</a>'; + } + ?> + </p> + <?php + if (kratos_option('s_icp')) { + echo '<p><a href="https://beian.miit.gov.cn/" target="_blank" rel="nofollow">' . kratos_option('s_icp') . '</a></p>'; + } + if (kratos_option('g_performance')) { + echo '<p>'. sprintf( '请求次数:%d 次,加载用时:%.3f 秒,内存占用:%.2f MB', get_num_queries(), timer_stop(), memory_get_peak_usage() / 1024 / 1024 ) . '</p>'; + } + echo '<p>' . kratos_option('s_copyright', 'COPYRIGHT © ' . wp_date('Y') . ' ' . get_bloginfo('name') . '. ALL RIGHTS RESERVED.') . '</p>'; + if (kratos_option('s_icp')) { + echo '<p><a href="https://beian.miit.gov.cn/" target="_blank" rel="nofollow">' . kratos_option('s_icp') . '</a></p>'; + } + if (kratos_option('s_gov')) { + echo '<p><a href="' . kratos_option('s_gov_link') . '" target="_blank" rel="nofollow" ><i class="police-ico"></i>' . kratos_option('s_gov') . '</a></p>'; + } + ?> </div> </div> </div> </div> + +<?php if (kratos_option('g_pjax')): ?> +<div class='loader'> + <div class='loader_overlay'></div> + <div class='loader_cogs'> + <div class='loader_cogs__top'> + <div class='top_part'></div> + <div class='top_part'></div> + <div class='top_part'></div> + <div class='top_hole'></div> + </div> + <div class='loader_cogs__left'> + <div class='left_part'></div> + <div class='left_part'></div> + <div class='left_part'></div> + <div class='left_hole'></div> + </div> + <div class='loader_cogs__bottom'> + <div class='bottom_part'></div> + <div class='bottom_part'></div> + <div class='bottom_part'></div> + <div class='bottom_hole'></div> + </div> + <p>Loading...</p> + </div> +</div> +<?php endif; ?> + <?php wp_footer(); ?> + +<?php if (kratos_option('g_pjax')): ?> + <script> + let myhkTipsTime = null; + let myhkTips = { + show: function (a) { + clearTimeout(myhkTipsTime); + jQuery("#myhkTips")["text"](a)["addClass"]("show"); + this["hide"](); + }, + hide: function () { + myhkTipsTime = setTimeout(function () { + jQuery("#myhkTips")["removeClass"]("show"); + }, 3000); + } + }; + + +(function ($) { + let pjax_container = '#pjax', + pjax_timeout = 15000 + $(document).pjax('a[target!=_blank]', pjax_container, { + fragment: pjax_container, + timeout: pjax_timeout + }) + $(document).on('submit', 'form.search-form', function (event) { + $.pjax.submit(event, pjax_container, { + fragment: pjax_container, + timeout: pjax_timeout + }) + }) + $(document).on('pjax:send', function () { + $(".loader").css("display", "block") + }) + $(document).on('pjax:complete', function (xhr, textStatus, options) { + $(".loader").css("display", "none") + if ("undefined" != typeof myhkplayer) { + myhkTips.show(document.title + " 加载完成") + } + }) + })(jQuery); + </script> +<?php endif; ?> + +<?php if (kratos_option('myhk_player_fieldset')['myhk_player'] ?? false): ?> + <script defer src="https://myhkw.cn/player/js/player.js" id="myhk" key="<?php echo kratos_option('myhk_player_fieldset')['myhk_player_key']; ?>" m="1"></script> +<?php endif; ?> + </body> </html> \ No newline at end of file diff --git a/inc/theme-core.php b/inc/theme-core.php index 344c5da..e100982 100644 --- a/inc/theme-core.php +++ b/inc/theme-core.php @@ -11,7 +11,7 @@ use YahnisElsts\PluginUpdateChecker\v5\PucFactory; // CDN 资源地址 if (kratos_option('g_cdn', false)) { - $asset_path = 'https://cdn.jsdelivr.net/gh/seatonjiang/kratos@v' . THEME_VERSION; + $asset_path = 'https://cdn.jsdelivr.net/gh/devhaozi/kratos@v' . THEME_VERSION; } else { $asset_path = get_template_directory_uri(); } @@ -54,6 +54,9 @@ function theme_autoload() wp_enqueue_style('fontawesome', ASSET_PATH . '/assets/css/fontawesome.min.css', array(), '5.15.2'); } wp_enqueue_style('kratos', ASSET_PATH . '/style.css', array(), THEME_VERSION); + if (kratos_option('g_pjax')) { + wp_enqueue_style( 'loader', ASSET_PATH . '/assets/css/loader.css', array(), THEME_VERSION ); + } if (is_child_theme()) { wp_enqueue_style('kratos-child', get_stylesheet_uri(), array(), wp_get_theme()->get('Version')); } @@ -100,6 +103,9 @@ function theme_autoload() wp_enqueue_script('layer', ASSET_PATH . '/assets/js/layer.min.js', array('jquery'), '3.1.1', true); wp_enqueue_script('dplayer', ASSET_PATH . '/assets/js/DPlayer.min.js', array(), THEME_VERSION, true); wp_enqueue_script('kratos', ASSET_PATH . '/assets/js/kratos.js', array('jquery'), THEME_VERSION, true); + if (kratos_option('g_pjax')) { + wp_enqueue_script('pjax', ASSET_PATH . '/assets/js/pjax.js', array('jquery'), THEME_VERSION, true); + } $data = array( 'site' => home_url(), @@ -208,11 +214,10 @@ if (kratos_option('g_replace_gravatar_url_fieldset')['g_replace_gravatar_url'] ? function replace_gravatar_url($avatar) { $gravatar_server_list = array( - 'geekzu' => 'sdn.geekzu.org', - 'loli' => 'gravatar.loli.net', + 'weavatar' => 'weavatar.com', 'other' => kratos_option('g_replace_gravatar_url_fieldset')['g_custom_gravatar_server'] ?? null, ); - $gravatar_server = $gravatar_server_list[kratos_option('g_replace_gravatar_url_fieldset')['g_select_gravatar_server'] ?? 'geekzu']; + $gravatar_server = $gravatar_server_list[kratos_option('g_replace_gravatar_url_fieldset')['g_select_gravatar_server'] ?? 'weavatar']; $avatar = str_replace(array('www.gravatar.com', '0.gravatar.com', '1.gravatar.com', '2.gravatar.com', '3.gravatar.com', 'secure.gravatar.com'), $gravatar_server, $avatar); $avatar = str_replace('http://', 'https://', $avatar); @@ -225,7 +230,7 @@ if (kratos_option('g_replace_gravatar_url_fieldset')['g_replace_gravatar_url'] ? // 主题更新检测 $myUpdateChecker = PucFactory::buildUpdateChecker( - 'https://cdn.jsdelivr.net/gh/seatonjiang/kratos/inc/update-checker/update.json', + 'https://cdn.jsdelivr.net/gh/devhaozi/kratos/inc/update-checker/update.json', get_template_directory() . '/functions.php', 'Kratos' ); diff --git a/inc/theme-options.php b/inc/theme-options.php index eee082f..2aac0bf 100644 --- a/inc/theme-options.php +++ b/inc/theme-options.php @@ -50,7 +50,7 @@ CSF::createOptions($prefix, array( 'admin_bar_menu_icon' => 'dashicons-admin-generic', 'framework_title' => '主题设置<small style="margin-left:10px">Kratos v' . THEME_VERSION . '</small>', 'theme' => 'light', - 'footer_credit' => '感谢使用 <a target="_blank" href="https://github.com/seatonjiang/kratos">Kratos</a> 主题开始创作,欢迎加入交流群:<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=_7pE5U4pbq4j2xeu_cyZqvasEd_i9wTf">618958939</a>、<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=8Okzvj3TP67642FTRvC1mKT7f8L4NOrk">839687348</a>、<a target="_blank" href="https://qm.qq.com/cgi-bin/qm/qr?k=b37-78PbXYvTdoUZq9rW-nEF6CEl4wBv">852844975</a>', + 'footer_credit' => '感谢使用 <a target="_blank" href="https://github.com/devhaozi/kratos">Kratos Pjax Edition</a> 主题开始创作,欢迎加入交流群:<a target="_blank" href="https://jq.qq.com/?_wv=1027&k=I1oJKSTH">12370907</a>', )); CSF::createSection($prefix, array( @@ -127,6 +127,20 @@ CSF::createSection($prefix, array( 'subtitle' => __('启用/禁用静态资源加速(jsDelivr)', 'kratos'), 'default' => false, ), + array( + 'id' => 'g_pjax', + 'type' => 'switcher', + 'title' => __('Pjax 加载', 'kratos'), + 'subtitle' => __('启用/禁用 Pjax 加载', 'kratos'), + 'default' => true, + ), + array( + 'id' => 'g_performance', + 'type' => 'switcher', + 'title' => __('性能显示', 'kratos'), + 'subtitle' => __('启用/禁用 页脚性能显示', 'kratos'), + 'default' => false, + ), array( 'id' => 'g_renameimg', 'type' => 'switcher', @@ -175,11 +189,10 @@ CSF::createSection($prefix, array( 'title' => __('Gravatar 加速服务地址', 'kratos'), 'subtitle' => __('请选择 Gravatar 加速服务地址', 'kratos'), 'options' => array( - 'loli' => __('Loli 加速服务', 'kratos'), - 'geekzu' => __('极客族加速服务', 'kratos'), + 'weavatar' => __('WeAvatar.com', 'kratos'), 'other' => __('自定义加速服务', 'kratos'), ), - 'desc' => __('国内用户推荐「极客族加速服务」,海外用户推荐「Loli 加速服务」。', 'kratos'), + 'desc' => __('推荐「WeAvatar.com」', 'kratos'), 'dependency' => array('g_replace_gravatar_url', '==', 'true'), ), array( @@ -194,7 +207,7 @@ CSF::createSection($prefix, array( ), 'default' => array( 'g_replace_gravatar_url' => 1, - 'g_select_gravatar_server' => 'geekzu', + 'g_select_gravatar_server' => 'weavatar', ) ), array( @@ -419,7 +432,41 @@ CSF::createSection($prefix, array( array( 'type' => 'notice', 'style' => 'info', - 'content' => '提示:<strong>DogeCloud 云存储</strong> 与 <strong>火山引擎 ImageX</strong>请勿同时开启!', + 'content' => '提示:<strong>DogeCloud 云存储</strong> 与 <strong>火山引擎 ImageX</strong>请勿同时开启,开启播放器后建议同时开启 Pjax 加载!', + ), + array( + 'id' => 'myhk_player_fieldset', + 'type' => 'fieldset', + 'fields' => array( + array( + 'type' => 'subheading', + 'content' => __('明月浩空音乐播放器', 'kratos'), + ), + array( + 'type' => 'submessage', + 'style' => 'info', + 'content' => '明月浩空音乐播放器提供<strong> 免费 </strong>的网站音乐播放器服务,如需购买付费版本,联系 QQ 826896000 购买价格更优!', + ), + array( + 'id' => 'myhk_player', + 'type' => 'switcher', + 'title' => __('功能开关', 'kratos'), + 'subtitle' => __('开启/关闭明月浩空音乐播放器', 'kratos'), + 'text_on' => __('开启', 'kratos'), + 'text_off' => __('关闭', 'kratos'), + ), + array( + 'id' => 'myhk_player_key', + 'type' => 'text', + 'title' => __('播放器 Key', 'kratos'), + 'subtitle' => __('播放器 Key 可在明月浩空音乐播放器后台查看', 'kratos'), + 'desc' => __('<a target="_blank" href="https://myhkw.cn/admin/">点击这里</a>查询播放器 Key', 'kratos'), + ), + ), + 'default' => array( + 'myhk_player' => false, + 'myhk_player_key' => '', + ), ), array( 'id' => 'g_cos_fieldset', @@ -1201,7 +1248,7 @@ CSF::createSection($prefix, array( ), array( 'type' => 'content', - 'content' => '<ul style="margin: 0 auto;"><li>' . __('问题反馈:', 'kratos') . '<a href="https://github.com/seatonjiang/kratos/issues" target="_blank">https://github.com/seatonjiang/kratos/issues</a></li> <li>' . __('使用说明:', 'kratos') . '<a href="https://github.com/seatonjiang/kratos/wiki" target="_blank">https://github.com/seatonjiang/kratos/wiki</a></li> <li>' . __('更新日志:', 'kratos') . '<a href="https://github.com/seatonjiang/kratos/releases" target="_blank">https://github.com/seatonjiang/kratos/releases</a></li> </ul>', + 'content' => '<ul style="margin: 0 auto;"><li>' . __('问题反馈:', 'kratos') . '<a href="https://github.com/devhaozi/kratos/issues" target="_blank">https://github.com/devhaozi/kratos/issues</a></li> <li>' . __('使用说明:', 'kratos') . '<a href="https://github.com/seatonjiang/kratos/wiki" target="_blank">https://github.com/seatonjiang/kratos/wiki</a></li> <li>' . __('更新日志:', 'kratos') . '<a href="https://github.com/devhaozi/kratos/releases" target="_blank">https://github.com/devhaozi/kratos/releases</a></li> </ul>', ), array( 'type' => 'subheading', @@ -1209,7 +1256,7 @@ CSF::createSection($prefix, array( ), array( 'type' => 'content', - 'content' => __('主题源码使用 <a href="https://github.com/seatonjiang/kratos/blob/main/LICENSE" target="_blank">GPL-3.0 协议</a> 进行许可,说明文档使用 <a href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank">CC BY-NC-ND 4.0</a> 进行许可。', 'kratos'), + 'content' => __('主题源码使用 <a href="https://github.com/devhaozi/kratos/blob/main/LICENSE" target="_blank">GPL-3.0 协议</a> 进行许可,说明文档使用 <a href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank">CC BY-NC-ND 4.0</a> 进行许可。', 'kratos'), ), array( 'type' => 'subheading', diff --git a/inc/update-checker/update.json b/inc/update-checker/update.json index a04d9c9..7a5f4fd 100644 --- a/inc/update-checker/update.json +++ b/inc/update-checker/update.json @@ -1,5 +1,5 @@ { "version": "4.2.4", - "details_url": "https://github.com/seatonjiang/kratos/releases/tag/v4.2.4", + "details_url": "https://github.com/devhaozi/kratos/releases/tag/v4.2.4", "download_url": "https://cdn.seatonjiang.com/kratos/v4.2.4.zip" } diff --git a/index.php b/index.php index 5d384bf..f547835 100644 --- a/index.php +++ b/index.php @@ -8,7 +8,7 @@ */ get_header(); ?> <div class="k-main <?php echo kratos_option('top_img_switch', true) ? 'banner' : 'color' ?>" style="background:<?php echo kratos_option('g_background', '#f5f5f5'); ?>"> - <div class="container"> + <div id="pjax" class="container"> <div class="row"> <div class="col-lg-8 board"> <?php if (is_home() && kratos_option('g_carousel', false)) { diff --git a/languages/en_US.po b/languages/en_US.po index 93f045b..00a4f3e 100644 --- a/languages/en_US.po +++ b/languages/en_US.po @@ -1116,8 +1116,8 @@ msgid "版权声明" msgstr "Copyright claims" #: inc/theme-options.php:1175 -msgid "主题源码使用 <a href=\"https://github.com/seatonjiang/kratos/blob/main/LICENSE\" target=\"_blank\">GPL-3.0 协议</a> 进行许可,说明文档使用 <a href=\"https://creativecommons.org/licenses/by-nc-nd/4.0/\" target=\"_blank\">CC BY-NC-ND 4.0</a> 进行许可。" -msgstr "The theme source code is licensed under the <a href=\"https://github.com/seatonjiang/kratos/blob/main/LICENSE\" target=\"_blank\">GPL-3.0 agreement</a>, and the documentation uses <a href= \"https://creativecommons.org/licenses/by-nc-nd/4.0/\" target=\"_blank\">CC BY-NC-ND 4.0</a> for licensing。" +msgid "主题源码使用 <a href=\"https://github.com/devhaozi/kratos/blob/main/LICENSE\" target=\"_blank\">GPL-3.0 协议</a> 进行许可,说明文档使用 <a href=\"https://creativecommons.org/licenses/by-nc-nd/4.0/\" target=\"_blank\">CC BY-NC-ND 4.0</a> 进行许可。" +msgstr "The theme source code is licensed under the <a href=\"https://github.com/devhaozi/kratos/blob/main/LICENSE\" target=\"_blank\">GPL-3.0 agreement</a>, and the documentation uses <a href= \"https://creativecommons.org/licenses/by-nc-nd/4.0/\" target=\"_blank\">CC BY-NC-ND 4.0</a> for licensing。" #: inc/theme-options.php:1179 msgid "讨论交流" @@ -1473,8 +1473,8 @@ msgid "下一篇 >" msgstr "Next article >" #. Theme URI of the plugin/theme -msgid "https://github.com/seatonjiang/kratos" -msgstr "https://github.com/seatonjiang/kratos" +msgid "https://github.com/devhaozi/kratos" +msgstr "https://github.com/devhaozi/kratos" #. Description of the plugin/theme msgid "主题提供了多种针对自媒体博客需求的侧栏工具,删繁就简专注于用户的阅读体验,优化的邮件中心为你的网站留存加分添彩。" diff --git a/languages/kratos.pot b/languages/kratos.pot index e07a4b4..4f08074 100644 --- a/languages/kratos.pot +++ b/languages/kratos.pot @@ -1138,7 +1138,7 @@ msgstr "" #: inc/theme-options.php:1175 msgid "" -"主题源码使用 <a href=\"https://github.com/seatonjiang/kratos/blob/main/" +"主题源码使用 <a href=\"https://github.com/devhaozi/kratos/blob/main/" "LICENSE\" target=\"_blank\">GPL-3.0 协议</a> 进行许可,说明文档使用 <a href=" "\"https://creativecommons.org/licenses/by-nc-nd/4.0/\" target=\"_blank\">CC " "BY-NC-ND 4.0</a> 进行许可。" @@ -1499,7 +1499,7 @@ msgid "下一篇 >" msgstr "" #. Theme URI of the plugin/theme -msgid "https://github.com/seatonjiang/kratos" +msgid "https://github.com/devhaozi/kratos" msgstr "" #. Description of the plugin/theme diff --git a/page-full.php b/page-full.php index 3d14634..d1f3a8d 100644 --- a/page-full.php +++ b/page-full.php @@ -9,7 +9,7 @@ get_header(); ?> <div class="k-main <?php echo kratos_option('top_img_switch', true) ? 'banner' : 'color' ?>" style="background:<?php echo kratos_option('g_background', '#f5f5f5'); ?>"> - <div class="container"> + <div id="pjax" class="container"> <div class="row"> <div class="col-lg-12 details"> <?php if (have_posts()) : the_post(); diff --git a/page.php b/page.php index ef65b97..064d42a 100644 --- a/page.php +++ b/page.php @@ -9,7 +9,7 @@ get_header(); ?> <div class="k-main <?php echo kratos_option('top_img_switch', true) ? 'banner' : 'color' ?>" style="background:<?php echo kratos_option('g_background', '#f5f5f5'); ?>"> - <div class="container"> + <div id="pjax" class="container"> <div class="row"> <div class="col-lg-8 details"> <?php if (have_posts()) : the_post(); diff --git a/single.php b/single.php index 4a7c076..9442a3c 100644 --- a/single.php +++ b/single.php @@ -14,7 +14,7 @@ $col_array = array( ); ?> <div class="k-main <?php echo kratos_option('top_img_switch', true) ? 'banner' : 'color' ?>" style="background:<?php echo kratos_option('g_background', '#f5f5f5'); ?>"> - <div class="container"> + <div id="pjax" class="container"> <div class="row"> <div class="<?php echo $col_array[kratos_option('g_article_widgets', 'two_side')] ?> details"> <?php if (have_posts()) : the_post(); diff --git a/style.css b/style.css index fb0d32e..40bb46e 100644 --- a/style.css +++ b/style.css @@ -1,6 +1,6 @@ @charset "UTF-8"; /* -Theme Name: Kratos +Theme Name: Kratos Pjax Edition Text Domain: kratos Version: 4.2.4 Requires PHP: 7.4 @@ -9,9 +9,9 @@ Description: 主题提供了多种针对自媒体博客需求的侧栏工具, Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好 Author: Seaton Jiang Author URI: https://seatonjiang.com -Theme URI: https://github.com/seatonjiang/kratos +Theme URI: https://github.com/devhaozi/kratos License: GPL-3.0 License -License URI: https://github.com/seatonjiang/kratos/blob/main/LICENSE +License URI: https://github.com/devhaozi/kratos/blob/main/LICENSE */ /*--------------------------------------------------------------