fix(core): [CORE-25] read defaults without navigator

This commit is contained in:
Harvey Zhao committed 2026-09-13 13:53:49 +08:00
1 parent 4a299eb2d4
commit 3b016970f2
26 files changed
+916 -35

No files matched your search

+1 -1
View File
@@ -67,4 +67,4 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),c=r(t);if("object"===s){if("object"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(c,"'"));Object.keys(e).forEach(function(r){var s=t[r],c=e[r],l=n.slice();l.push(r),i(s,c,l),a(s,c,l),o(s,c,l)})}if("array"===s){if("array"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(c,"'"));t.forEach(function(r,s){var c=t[s],l=e[s]||e[0],d=n.slice();d.push(s),i(c,l,d),a(c,l,d),o(c,l,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),r.exports);const o=t(n),i="5.4.1";function a(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),c=/^(?:(?!chrome|android).)*safari/i.test(s),l=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=l||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,u=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,p="undefined"!==typeof window&&"undefined"!==typeof document;const f={properties:["audioTracks","autoplay","buffered","controller","controlLine truncated !function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),c=r(t);if("object"===s){if("object"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(c,"'"));Object.keys(e).forEach(function(r){var s=t[r],c=e[r],l=n.slice();l.push(r),i(s,c,l),a(s,c,l),o(s,c,l)})}if("array"===s){if("array"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(c,"'"));t.forEach(function(r,s){var c=t[s],l=e[s]||e[0],d=n.slice();d.push(s),i(c,l,d),a(c,l,d),o(c,l,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),r.exports);const o=t(n),i="5.4.1";function a(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),c=/^(?:(?!chrome|android).)*safari/i.test(s),l=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=l||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,u=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,p="undefined"!==typeof window&&"undefined"!==typeof document;const f={properties:["audioTracks","autoplay","buffered","controller","controlLine truncated
+1 -1
View File
@@ -67,4 +67,4 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var f=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),l=r(t);if("object"===s){if("object"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(l,"'"));Object.keys(e).forEach(function(r){var s=t[r],l=e[r],c=n.slice();c.push(r),i(s,l,c),a(s,l,c),o(s,l,c)})}if("array"===s){if("array"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(l,"'"));t.forEach(function(r,s){var l=t[s],c=e[s]||e[0],d=n.slice();d.push(s),i(l,c,d),a(l,c,d),o(l,c,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),p.exports);const h=d(f),m="5.4.1";function v(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.apLine truncated !function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var f=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),l=r(t);if("object"===s){if("object"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(l,"'"));Object.keys(e).forEach(function(r){var s=t[r],l=e[r],c=n.slice();c.push(r),i(s,l,c),a(s,l,c),o(s,l,c)})}if("array"===s){if("array"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(l,"'"));t.forEach(function(r,s){var l=t[s],c=e[s]||e[0],d=n.slice();d.push(s),i(l,c,d),a(l,c,d),o(l,c,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),p.exports);const h=d(f),m="5.4.1";function v(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.apLine truncated
+1 -1
View File
@@ -4304,7 +4304,7 @@ function createDefaults() {
icons: {}, icons: {},
cssVar: {}, cssVar: {},
customType: {}, customType: {},
lang: navigator?.language.toLowerCase() lang: typeof navigator === "undefined" ? void 0 : navigator?.language.toLowerCase()
}; };
} }
function resolveOption(input, defaults2) { function resolveOption(input, defaults2) {
+10
View File
@@ -156,6 +156,16 @@ order. All subsystem assignments and mutable static assignments keep their origi
order. bootstrap/browser.ts owns global publication, style injection and the deferred order. bootstrap/browser.ts owns global publication, style injection and the deferred
version log; server imports do none of those browser operations. version log; server imports do none of those browser operations.
option/defaults.ts can be read without browser globals: an absent navigator yields
an own lang field with value undefined. It still reads browser language on each access
and returns fresh nested containers. DefaultOption describes this unvalidated state;
ResolvedOption keeps a required language after the existing validator succeeds.
Do not treat optional chaining on an undeclared navigator as a presence check or
weaken the validated I18nHost type. Regression entrypoints are test/options.test.js,
test/types/options-source.ts, test/package/runtime.cjs and test/browser/options.spec.js.
The installed fixture checks missing navigator on every Node, including newer versions
that normally provide it. See refactor/changes/2026-09-13-CORE-25-defaults-ssr.md.
option/runtime.ts is the compatibility boundary between old external callback option/runtime.ts is the compatibility boundary between old external callback
declarations and internal module views. It keeps validated merge behavior, callback declarations and internal module views. It keeps validated merge behavior, callback
identity and runtime receivers; it does not wrap callbacks or assert the whole player identity and runtime receivers; it does not wrap callbacks or assert the whole player
+1 -1
View File
@@ -67,4 +67,4 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),c=r(t);if("object"===s){if("object"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(c,"'"));Object.keys(e).forEach(function(r){var s=t[r],c=e[r],l=n.slice();l.push(r),i(s,c,l),a(s,c,l),o(s,c,l)})}if("array"===s){if("array"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(c,"'"));t.forEach(function(r,s){var c=t[s],l=e[s]||e[0],d=n.slice();d.push(s),i(c,l,d),a(c,l,d),o(c,l,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),r.exports);const o=t(n),i="5.4.1";function a(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),c=/^(?:(?!chrome|android).)*safari/i.test(s),l=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=l||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,u=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,p="undefined"!==typeof window&&"undefined"!==typeof document;const f={properties:["audioTracks","autoplay","buffered","controller","controlLine truncated !function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";function t(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var e,r={exports:{}};var n=(e||(e=1,r.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),c=r(t);if("object"===s){if("object"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(c,"'"));Object.keys(e).forEach(function(r){var s=t[r],c=e[r],l=n.slice();l.push(r),i(s,c,l),a(s,c,l),o(s,c,l)})}if("array"===s){if("array"!==c)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(c,"'"));t.forEach(function(r,s){var c=t[s],l=e[s]||e[0],d=n.slice();d.push(s),i(c,l,d),a(c,l,d),o(c,l,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),r.exports);const o=t(n),i="5.4.1";function a(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.appendChild(r)}):(document.head||document.documentElement).appendChild(r)),r.textContent=e}const s=globalThis.CUSTOM_USER_AGENT??("undefined"===typeof navigator?"":navigator.userAgent),c=/^(?:(?!chrome|android).)*safari/i.test(s),l=/iPad|iPhone|iPod/i.test(s)&&("undefined"===typeof window||!window.MSStream),d=l||s.includes("Macintosh")&&"undefined"!==typeof navigator&&navigator.maxTouchPoints>=1,u=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(s)||d,p="undefined"!==typeof window&&"undefined"!==typeof document;const f={properties:["audioTracks","autoplay","buffered","controller","controlLine truncated
+1 -1
View File
@@ -67,4 +67,4 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
!function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var f=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),l=r(t);if("object"===s){if("object"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(l,"'"));Object.keys(e).forEach(function(r){var s=t[r],l=e[r],c=n.slice();c.push(r),i(s,l,c),a(s,l,c),o(s,l,c)})}if("array"===s){if("array"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(l,"'"));t.forEach(function(r,s){var l=t[s],c=e[s]||e[0],d=n.slice();d.push(s),i(l,c,d),a(l,c,d),o(l,c,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),p.exports);const h=d(f),m="5.4.1";function v(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.apLine truncated !function(t,e){"object"===typeof exports&&"undefined"!==typeof module?module.exports=e():"function"==typeof define&&define.amd?(t.Artplayer=e(),define(function(){return t.Artplayer})):(t="undefined"!==typeof globalThis?globalThis:t||self).Artplayer=e()}(this,function(){"use strict";var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,a=(e,r,n)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,s=(t,e)=>{for(var r in e||(e={}))o.call(e,r)&&a(t,r,e[r]);if(n)for(var r of n(e))i.call(e,r)&&a(t,r,e[r]);return t},l=(t,n)=>e(t,r(n)),c=(t,e,r)=>new Promise((n,o)=>{var i=t=>{try{s(r.next(t))}catch(e){o(e)}},a=t=>{try{s(r.throw(t))}catch(e){o(e)}},s=t=>t.done?n(t.value):Promise.resolve(t.value).then(i,a);s((r=r.apply(t,e)).next())});function d(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var u,p={exports:{}};var f=(u||(u=1,p.exports=function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}var e=Object.prototype.toString,r=function(r){if(void 0===r)return"undefined";if(null===r)return"null";var o=t(r);if("boolean"===o)return"boolean";if("string"===o)return"string";if("number"===o)return"number";if("symbol"===o)return"symbol";if("function"===o)return"GeneratorFunction"===n(r)?"generatorfunction":"function";if(function(t){return Array.isArray?Array.isArray(t):t instanceof Array}(r))return"array";if(function(t){return!(!t.constructor||"function"!=typeof t.constructor.isBuffer)&&t.constructor.isBuffer(t)}(r))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(e){if(-1!==e.message.indexOf("callee"))return!0}return!1}(r))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(r))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(r))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(r))return"regexp";switch(n(r)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(r))return"generator";switch(o=e.call(r)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return o.slice(8,-1).toLowerCase().replace(/\s/g,"")};function n(t){return t.constructor?t.constructor.name:null}function o(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["option"];return i(t,e,n),a(t,e,n),function(t,e,n){var s=r(e),l=r(t);if("object"===s){if("object"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'object' type, but got '").concat(l,"'"));Object.keys(e).forEach(function(r){var s=t[r],l=e[r],c=n.slice();c.push(r),i(s,l,c),a(s,l,c),o(s,l,c)})}if("array"===s){if("array"!==l)throw new Error("[Type Error]: '".concat(n.join("."),"' require 'array' type, but got '").concat(l,"'"));t.forEach(function(r,s){var l=t[s],c=e[s]||e[0],d=n.slice();d.push(s),i(l,c,d),a(l,c,d),o(l,c,d)})}}(t,e,n),t}function i(t,e,n){if("string"===r(e)){var o=r(t);if("?"===e[0]&&(e=e.slice(1)+"|undefined"),!(-1<e.indexOf("|")?e.split("|").map(function(t){return t.toLowerCase().trim()}).filter(Boolean).some(function(t){return o===t}):e.toLowerCase().trim()===o))throw new Error("[Type Error]: '".concat(n.join("."),"' require '").concat(e,"' type, but got '").concat(o,"'"))}}function a(t,e,n){if("function"===r(e)){var o=e(t,r(t),n);if(!0!==o){var i=r(o);throw"string"===i?new Error(o):"error"===i?o:new Error("[Validator Error]: The scheme for '".concat(n.join("."),"' validator require return true, but got '").concat(o,"'"))}}}return o.kindOf=r,o}()),p.exports);const h=d(f),m="5.4.1";function v(t,e){let r=document.getElementById(t);r||(r=document.createElement("style"),r.id=t,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{document.head.apLine truncated
+1 -1
View File
@@ -4304,7 +4304,7 @@ function createDefaults() {
icons: {}, icons: {},
cssVar: {}, cssVar: {},
customType: {}, customType: {},
lang: navigator?.language.toLowerCase() lang: typeof navigator === "undefined" ? void 0 : navigator?.language.toLowerCase()
}; };
} }
function resolveOption(input, defaults2) { function resolveOption(input, defaults2) {
+3 -3
View File
@@ -1,7 +1,7 @@
import type { ResolvedOption } from './types' import type { DefaultOption } from './types'
import { isSafari } from '../utils/compatibility' import { isSafari } from '../utils/compatibility'
export default function createDefaults(): ResolvedOption { export default function createDefaults(): DefaultOption {
return { return {
id: '', id: '',
container: '#artplayer', container: '#artplayer',
@@ -70,6 +70,6 @@ export default function createDefaults(): ResolvedOption {
icons: {}, icons: {},
cssVar: {}, cssVar: {},
customType: {}, customType: {},
lang: navigator?.language.toLowerCase(), lang: typeof navigator === 'undefined' ? undefined : navigator?.language.toLowerCase(),
} }
} }
+2 -2
View File
@@ -1,9 +1,9 @@
import type { OptionInput, ResolvedInput, ResolvedOption } from './types' import type { DefaultOption, OptionInput, ResolvedInput } from './types'
import validator from 'option-validator' import validator from 'option-validator'
import scheme from '../scheme' import scheme from '../scheme'
import { mergeDeep } from '../utils/property' import { mergeDeep } from '../utils/property'
export default function resolveOption<Input extends OptionInput>(input: Input, defaults: ResolvedOption): ResolvedInput<Input> { export default function resolveOption<Input extends OptionInput>(input: Input, defaults: DefaultOption): ResolvedInput<Input> {
const merged = mergeDeep(defaults, input) const merged = mergeDeep(defaults, input)
merged.container = input.container merged.container = input.container
// Keep the existing runtime validator. It checks the known schema, not extension data. // Keep the existing runtime validator. It checks the known schema, not extension data.
+2 -2
View File
@@ -5,7 +5,7 @@ import type { MediaSurface } from '../media/types'
import type { PluginFactory } from '../plugins/types' import type { PluginFactory } from '../plugins/types'
import type { SettingItem } from '../setting/types' import type { SettingItem } from '../setting/types'
import type { UrlHost } from '../source/types' import type { UrlHost } from '../source/types'
import type { OptionInput, ResolvedOption } from './types' import type { DefaultOption, OptionInput, ResolvedOption } from './types'
import resolveOption from './resolve' import resolveOption from './resolve'
interface RuntimeCallbacks<Host> { interface RuntimeCallbacks<Host> {
@@ -20,7 +20,7 @@ interface RuntimeCallbacks<Host> {
export type RuntimeOption<Host> = Omit<ResolvedOption, keyof RuntimeCallbacks<Host>> & RuntimeCallbacks<Host> export type RuntimeOption<Host> = Omit<ResolvedOption, keyof RuntimeCallbacks<Host>> & RuntimeCallbacks<Host>
export default function resolveRuntimeOption<Host>(input: OptionInput, defaults: ResolvedOption): RuntimeOption<Host> { export default function resolveRuntimeOption<Host>(input: OptionInput, defaults: DefaultOption): RuntimeOption<Host> {
// The external declaration facade and internal module views describe the same // The external declaration facade and internal module views describe the same
// caller-owned callbacks. Do not wrap, clone or rebind their runtime identity. // caller-owned callbacks. Do not wrap, clone or rebind their runtime identity.
// All non-callback options still derive directly from the validated merge type. // All non-callback options still derive directly from the validated merge type.
+4
View File
@@ -10,4 +10,8 @@ export interface ResolvedOption extends Omit<Required<OptionInput>, 'proxy' | 's
thumbnails: Required<Thumbnails> thumbnails: Required<Thumbnails>
} }
export interface DefaultOption extends Omit<ResolvedOption, 'lang'> {
lang: OptionInput['lang']
}
export type ResolvedInput<Input extends OptionInput> = ResolvedOption & Omit<Input, keyof OptionInput> export type ResolvedInput<Input extends OptionInput> = ResolvedOption & Omit<Input, keyof OptionInput>
@@ -0,0 +1,704 @@
{
"schemaVersion": 1,
"task": "CORE-25",
"date": "2026-09-13",
"baseCommit": "4a299eb2d4d4123f2b81e086c19ccbfd23bf3c2b",
"change": "Guard the absent navigator binding before reading the existing optional language path",
"unit": {
"before": {
"passed": 9,
"failed": 1,
"error": "ReferenceError: navigator is not defined"
},
"afterFocused": 16
},
"ci": {
"passed": 2432,
"unit": 2033,
"engineering": 28,
"baseline": 371,
"seconds": 240.93
},
"package": {
"name": "artplayer",
"version": "5.4.1",
"archiveSha256": "9c33c718db08109be7572d8a6ba2201cd2d5a1e6bd0e8845d141f0e5238cc4a3",
"legacyTypeModes": 5,
"preciseTypeModes": 8,
"knownTypeBlockers": 0,
"knownRuntimeBlockers": 0,
"sourceCopiesRemovedBy": "ENG-12"
},
"runs": [
{
"node": "20.19.0",
"candidateChecks": 36,
"publishedChecks": 31,
"defaults": {
"historical": false,
"resolved": true,
"ownLang": true,
"langType": "undefined"
},
"publishedDefaults": {
"name": "ReferenceError",
"message": "navigator is not defined",
"historical": true,
"resolved": false
},
"file": "refactor/.cache/packages/run-DWeEeu/runtime-node-20.19.0.json",
"sha256": "2a80dc04c57c76fb0fa61da3bf8e59764264ebf5af67e9535b60000e8f4512d9"
},
{
"node": "22.12.0",
"candidateChecks": 36,
"publishedChecks": 31,
"defaults": {
"historical": false,
"resolved": true,
"ownLang": true,
"langType": "undefined"
},
"publishedDefaults": {
"name": "ReferenceError",
"message": "navigator is not defined",
"historical": true,
"resolved": false
},
"file": "refactor/.cache/packages/run-DWeEeu/runtime-node-22.12.0.json",
"sha256": "d0bf3dbbc8c050555d359b495b805f1353bdd7d53c96b42696581eeac6b88244"
},
{
"node": "24.21.0",
"candidateChecks": 36,
"publishedChecks": 31,
"defaults": {
"historical": false,
"resolved": true,
"ownLang": true,
"langType": "undefined"
},
"publishedDefaults": {
"name": "ReferenceError",
"message": "navigator is not defined",
"historical": true,
"resolved": false
},
"file": "refactor/.cache/packages/run-DWeEeu/runtime-node-24.21.0.json",
"sha256": "133cedb07f29ed324757aa5e7c492771ca3f1beb7b907323a271029e19c81ffc"
}
],
"browsers": [
{
"entry": "source",
"passed": 30,
"file": "refactor/.cache/core25-browser/source/report.json",
"sha256": "828391f7973208461c3a68ab785ef2e87f5cd1ab468ff20c926c131e800eeb4a",
"rows": [
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "d9aeee649395b78eb30b38dcaefb3c19c731c21b08e356485bac7cda08ead242"
}
]
},
{
"entry": "main",
"passed": 30,
"file": "refactor/.cache/core25-browser/main/report.json",
"sha256": "8a67e34409f89d02ffde591e3e00842ab94e3fd403ef985c1cc9055fc2e9c583",
"rows": [
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335"
}
]
},
{
"entry": "legacy",
"passed": 30,
"file": "refactor/.cache/core25-browser/legacy/report.json",
"sha256": "e02ad726266d1524c329445d511d2481ef42a7071b5f8414b7e5720222090db9",
"rows": [
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: expanded option input preserves historical JS forms",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: expanded option input preserves historical JS forms",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: configuration errors occur before mounting and preserve allocation timing",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: container identity, partial defaults, custom fields and normal callbacks",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "chromium",
"browser": "153.0.8010.12",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "firefox",
"browser": "155.0",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "published: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
},
{
"project": "webkit",
"browser": "26.6",
"title": "candidate: language defaults follow the browser and explicit language still overrides",
"candidateSha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04"
}
]
}
],
"browserLimit": "Windows Playwright engines; not physical Safari or mobile devices",
"logs": [
{
"file": "refactor/.cache/core25-before.log",
"sha256": "db374872a1cdf5d0a11616d8286bd992a5dd2ca6c42b56128cf09ffa6db96e2c"
},
{
"file": "refactor/.cache/core25-focused.log",
"sha256": "afd16364ac51b390697f830a6c9c602315ab79ec0196c63b01219b45fd1c2301"
},
{
"file": "refactor/.cache/core25-lint.log",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"file": "refactor/.cache/core25-package-final.log",
"sha256": "5f6aaf334f32a172b2a2be079b71ea0d9e3cb0c8d276c4678761b5e71bb8dd4e"
},
{
"file": "refactor/.cache/core25-ci.log",
"sha256": "fe6248a222bf1bf65cfe4cdee2d350ba4231187eeb1fd55e2f1d01ce0e124824"
},
{
"file": "refactor/.cache/core25-build.log",
"sha256": "8085c31783906a518aad707bd4b461a0947f756746c3636a0cc1416bfa91a963"
}
],
"initialBuildFailure": "Vite implicit publicDir copy; independently fixed and committed as ENG-12",
"shippedArtifacts": [
{
"file": "packages/artplayer/dist/artplayer.js",
"sha256": "6dc8ca6d6eb34aa8a056cbc31328efd634530b3c5c60f0014cb7ce719fabc335",
"docsIdentical": true
},
{
"file": "packages/artplayer/dist/artplayer.legacy.js",
"sha256": "80f74a8a39df4baf64cc00c65d21cd57c011bfcdead0da38eea077fbc67c5c04",
"docsIdentical": true
},
{
"file": "packages/artplayer/dist/artplayer.mjs",
"sha256": "432e2b0ad92009a09743e020bf7c928c8b8f18a52496622b16259ec9ab20059f",
"docsIdentical": true
}
],
"remoteActions": null,
"fullReleaseReady": false
}
@@ -0,0 +1,49 @@
# CORE-25 无 navigator 默认选项修复
CI-01 的 Node 20 安装测试发现 Artplayer.option 在没有 navigator 时抛出 ReferenceError,
旧 npm 5.4.0 和重构候选均复现。较新 Node 自带 navigator,原测试没有覆盖这个环境。
本任务修复安全读取默认值,不改变浏览器构造、语言配置或公开声明。
## 实现与类型边界
option/defaults.ts 用 typeof navigator 检查全局绑定是否存在,再沿用原来的可选访问和
小写转换。没有绑定或值为 null/undefined 时,返回的默认对象仍拥有 lang 字段,其值
是 undefined;浏览器每次读取实际语言,显式配置的 lang 仍覆盖默认值。没有新全局对象、
补丁或缓存,也没有引入旧浏览器不具备的 globalThis 依赖。
完整检查进一步指出,原 ResolvedOption 错把未校验的默认语言标为必定存在。现在
option/types.ts 增加私有 DefaultOption,只有 lang 可以为 undefined,其余嵌套默认值
仍完整;resolve.ts/runtime.ts 接受这种输入,校验成功后仍返回原 ResolvedOption。
原 validator 在缺失语言且未提供覆盖值时继续拒绝,不通过类型断言或弱化 I18nHost
掩盖问题。公开 Option 本来就允许 lang 缺省,public/types 文件及消费者调用无需变化。
## 验证
- 新源码回归在修复前 9 项通过、1 项按预期失败;修复后相关 16 项通过,覆盖缺少绑定、
undefined/null、独立对象、实时语言读取、缺失语言校验失败与显式语言覆盖。
- 内部类型反例确认未校验 lang 不能直接 toLowerCase,校验后仍是 string;核心严格检查通过。
首次完整检查发现的内部类型错误已修复并保留日志,随后完整 ci:check 2432 项通过
(2033 单元、28 工程、371 基线),不是忽略类型错误换取成功。
- 同一干净 tarball 在 Node 20.19.0/22.12.0/24.21.0 各跑 36 项候选和 31 项发布观察,
实际 CJS/ESM/legacy 默认读取成功;发布版的精确 ReferenceError 继续单独保留。
严格 package:release 通过,五个旧类型与八个精确类型模式零诊断,当前夹具的 runtime blocker 为零。
- Chromium/Firefox/Windows WebKit,对源码、安装 main、安装 legacy 各跑 30 项,共 90 项。
en-US/zh-CN 浏览器环境的默认值、实例语言、显式 fr 覆盖及后续默认读取保持原行为;
既有正常选项、失败构造和实际媒体 ready 回归同时运行,没有未处理浏览器错误。
版本、逐项浏览器结果、实际 Node、产物与日志摘要见
[验证记录](../baselines/defaults-ssr-validation.json)。Windows WebKit 不代表物理 Safari/移动设备。
## 构建与关联修复
构建时另外发现 Vite 把声明 public 源码复制进 dist。已由独立 ENG-12 提交 4a299eb2d
修复,完整 21 库/文档构建通过;本任务在该提交后重新生成干净 tarball 并重跑三个 Node。
浏览器使用的 JS 与最终 tarball、正常生成的 dist 和 docs 副本逐字一致,因此独立的
源码复制清理没有使浏览器证据失效。正常 build artplayer 与 build:i18n 已重新通过。
没有版本或依赖变化,没有手改 dist 内容。JS 改进仅作用于原先抛错的无 navigator 路径,
旧浏览器语言与包入口保持兼容。CORE-DEFAULTS-SSR-01 关闭;三轮全项目复盘及其余
生态/设备/远端 CI 门槛仍未完成,不能据此发布 npm。
维护入口为包内 ARCHITECTURE.md。回退本提交会重新引入此 SSR 默认值缺陷;发布基线
反例应保留。独立提交主题:fix(core): [CORE-25] read defaults without navigator。
+2 -1
View File
@@ -79,7 +79,8 @@ summary.md 和 GitHub Job Summary,不依赖先前下载的 artifact 来判断
本地验证与指纹见 [CI-01 记录](changes/2026-09-13-CI-01-matrix-summary.md)。 本地验证与指纹见 [CI-01 记录](changes/2026-09-13-CI-01-matrix-summary.md)。
三个 Node 的 Windows 安装证据及新发现见 [消费者记录](changes/2026-09-13-CI-01-node-consumers.md)。 三个 Node 的 Windows 安装证据及新发现见 [消费者记录](changes/2026-09-13-CI-01-node-consumers.md)。
CORE-25 的无 navigator 默认选项缺陷尚未修复,严格 test:package:release 会因此失败。 CORE-25 已修复无 navigator 默认选项缺陷,严格 test:package:release 的当前 core/chapter
夹具已通过;此前的失败记录保留,见 [修复证据](changes/2026-09-13-CORE-25-defaults-ssr.md)。
更早 Node 消费/最低工具环境、全生态安装矩阵和有证据的影响调度仍待 CI-01;CI-04 负责 更早 Node 消费/最低工具环境、全生态安装矩阵和有证据的影响调度仍待 CI-01;CI-04 负责
各系统远端运行、冷热缓存、失败/取消演练及 required check 设置。没有新增远端通过证据。 各系统远端运行、冷热缓存、失败/取消演练及 required check 设置。没有新增远端通过证据。
+3 -3
View File
@@ -54,9 +54,9 @@ ENG-PERF-01/02 的后续核心性能工作归 MOD-03,并在 REVIEW-01 重新
CI-01 后续 Node 20 安装消费发现 CORE-25:静态 option 在没有 navigator 时抛出 CI-01 后续 Node 20 安装消费发现 CORE-25:静态 option 在没有 navigator 时抛出
ReferenceError,发布 5.4.0 和当前候选均复现。较新 Node 的全局 navigator 掩盖了它。 ReferenceError,发布 5.4.0 和当前候选均复现。较新 Node 的全局 navigator 掩盖了它。
已新增独立修复任务与 REVIEW-01 前置,并使严格 package release 检查阻断。 已由 CORE-25 独立修复并验证三 Node 与三浏览器,严格 package release 检查恢复通过,
本核心阶段的历史完成记录不代表这个后续发现已修复,见 见 [修复记录](changes/2026-09-13-CORE-25-defaults-ssr.md)。此前失败继续保存在
[Node 消费者记录](changes/2026-09-13-CI-01-node-consumers.md)。 [Node 消费者记录](changes/2026-09-13-CI-01-node-consumers.md),历史阶段验收不替代后续发现的验证。
- 各 PKG-*-01/05/06:完整发布基线、支持范围旧核心/新插件、新核心/旧插件、SDK/组合/分发; - 各 PKG-*-01/05/06:完整发布基线、支持范围旧核心/新插件、新核心/旧插件、SDK/组合/分发;
chapter 的本轮四组合不能代替所有包,也不能代替它自己的最终进度/质量/全屏组合任务。 chapter 的本轮四组合不能代替所有包,也不能代替它自己的最终进度/质量/全屏组合任务。
+3 -3
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 225 项,范围 22 个包及工作区/示例。 基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 225 项,范围 22 个包及工作区/示例。
状态:todo 87 / doing 16 / blocked 0 / done 122 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。 状态:todo 86 / doing 16 / blocked 0 / done 123 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。 前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -132,7 +132,7 @@
| CORE-23 | artplayer<br>检查并补齐键盘、焦点与可访问名称 | CORE-13, CORE-14, CORE-17, ENG-05, BASE-04 | 主要控件/设置/模式退出的键盘与焦点回归、名称和字幕可用性检查及必要兼容修正 | 保持旧快捷键和 DOM/CSS 钩子;真实浏览器验证,不以静态属性检查代替交互;处理 BASE-DOM-01 的主要控件 Tab 不可达,保留既有名称与快捷键 | H | done | | CORE-23 | artplayer<br>检查并补齐键盘、焦点与可访问名称 | CORE-13, CORE-14, CORE-17, ENG-05, BASE-04 | 主要控件/设置/模式退出的键盘与焦点回归、名称和字幕可用性检查及必要兼容修正 | 保持旧快捷键和 DOM/CSS 钩子;真实浏览器验证,不以静态属性检查代替交互;处理 BASE-DOM-01 的主要控件 Tab 不可达,保留既有名称与快捷键 | H | done |
| CORE-22 | artplayer<br>核心阶段完整验收 | CORE-21, CORE-23, PILOT-01, ENG-08, ENG-10, ENG-11 | 核心与旧插件的可自动化完整回归、资源/性能及明确外部验证缺口 | 核心自动化和公开差异处置通过;真实环境缺口链接包集成/REL 门槛,阶段完成不代表可公开发布 | H | done | | CORE-22 | artplayer<br>核心阶段完整验收 | CORE-21, CORE-23, PILOT-01, ENG-08, ENG-10, ENG-11 | 核心与旧插件的可自动化完整回归、资源/性能及明确外部验证缺口 | 核心自动化和公开差异处置通过;真实环境缺口链接包集成/REL 门槛,阶段完成不代表可公开发布 | H | done |
| CORE-24 | artplayer<br>修复连续切源的播放意图继承 | CORE-22, PKG-AUDIO-04 | 连续切源保留原播放意图,同时尊重显式暂停与最新来源,回归旧/新 audio | 真实暂停状态的受控测试、重入/取消/失败/销毁、三引擎和 main/legacy 产物验证通过;不恢复过期来源的公开副作用 | H | done | | CORE-24 | artplayer<br>修复连续切源的播放意图继承 | CORE-22, PKG-AUDIO-04 | 连续切源保留原播放意图,同时尊重显式暂停与最新来源,回归旧/新 audio | 真实暂停状态的受控测试、重入/取消/失败/销毁、三引擎和 main/legacy 产物验证通过;不恢复过期来源的公开副作用 | H | done |
| CORE-25 | artplayer<br>修复无 navigator 环境读取默认选项 | CORE-22, ENG-12 | 安全读取默认语言并保留浏览器已有默认值;实际 Node 与发布产物正反例 | 记录旧发布版 ReferenceError;候选在无 navigator 时可读默认选项,浏览器语言和公开类型不回归;不以补全局对象隐藏错误 | M | todo | | CORE-25 | artplayer<br>修复无 navigator 环境读取默认选项 | CORE-22, ENG-12 | 安全读取默认语言并保留浏览器已有默认值;实际 Node 与发布产物正反例 | 记录旧发布版 ReferenceError;候选在无 navigator 时可读默认选项,浏览器语言和公开类型不回归;不以补全局对象隐藏错误 | M | done |
## 5 包迁移:artplayer-plugin-chapter ## 5 包迁移:artplayer-plugin-chapter
@@ -562,5 +562,5 @@
- PKG-TOOL-THUMB-03: [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-input-checkpoint.md) [记录](baselines/thumbnail-input-checkpoint.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-lifecycle.md) [记录](baselines/thumbnail-lifecycle-validation.json) - PKG-TOOL-THUMB-03: [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-input-checkpoint.md) [记录](baselines/thumbnail-input-checkpoint.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-03-lifecycle.md) [记录](baselines/thumbnail-lifecycle-validation.json)
- PKG-TOOL-THUMB-04: [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-runtime-types.md) [记录](baselines/thumbnail-runtime-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-public-types.md) [记录](baselines/thumbnail-public-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-emitter.md) [记录](baselines/thumbnail-emitter-validation.json) - PKG-TOOL-THUMB-04: [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-runtime-types.md) [记录](baselines/thumbnail-runtime-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-public-types.md) [记录](baselines/thumbnail-public-types-validation.json) [记录](changes/2026-09-13-PKG-TOOL-THUMB-04-emitter.md) [记录](baselines/thumbnail-emitter-validation.json)
- PKG-FACTORY-01: [记录](baselines/factory-assignment-gaps.json) [记录](baselines/factory-compatibility-proposals.json) [记录](factory-compatibility-decision.md) [记录](changes/2026-09-12-PKG-FACTORY-01-decision.md) - PKG-FACTORY-01: [记录](baselines/factory-assignment-gaps.json) [记录](baselines/factory-compatibility-proposals.json) [记录](factory-compatibility-decision.md) [记录](changes/2026-09-12-PKG-FACTORY-01-decision.md)
- CORE-25: [记录](changes/2026-09-13-CI-01-node-consumers.md) - CORE-25: [记录](changes/2026-09-13-CORE-25-defaults-ssr.md) [记录](baselines/defaults-ssr-validation.json)
- ENG-12: [记录](changes/2026-09-13-ENG-12-library-public.md) [记录](baselines/library-public-validation.json) - ENG-12: [记录](changes/2026-09-13-ENG-12-library-public.md) [记录](baselines/library-public-validation.json)
+14
View File
@@ -1,5 +1,19 @@
# 进度与证据 # 进度与证据
## CORE-25 无 navigator 默认选项修复完成
defaults.ts 使用 typeof 保护不存在的全局绑定,保留浏览器语言小写、lang 自有字段及每次
独立默认对象;构造仍只在浏览器执行。源码反例 9 过/1 失败,修复后定向 16 项通过。
严格包检查通过,3 个 Node 各 36 候选/31 发布观察,候选默认选项问题清零;旧错误保留。
三浏览器源码/main/legacy 各 30 项共 90 项通过,英语/中文默认语言与显式覆盖保持一致。
完整本地 CI 2432 项通过(2033 单元、28 工程、371 基线)。三个正常构建与安装测试
使用相同 JS 字节,docs 副本一致;公开声明、依赖和版本不变。
生成时发现的 public 复制另由 ENG-12 提交 4a299eb2d 修复;最终干净 tarball 重新验证。
见[变更](changes/2026-09-13-CORE-25-defaults-ssr.md)和[证据](baselines/defaults-ssr-validation.json)。
225 项:123 done、16 doing、86 todo;202 风险,CORE-DEFAULTS-SSR-01 关闭。
独立本地提交,不推送、不发布;全生态/CI-01/真实远端与最终复盘仍待完成。
## ENG-12 库声明源码复制修复完成 ## ENG-12 库声明源码复制修复完成
CORE-25 构建期间发现 Vite 默认复制 core/public 到 dist;实际候选 tarball 含 37 个 CORE-25 构建期间发现 Vite 默认复制 core/public 到 dist;实际候选 tarball 含 37 个
+1 -1
View File
@@ -204,5 +204,5 @@
| MULTI-SUB-ENTITY-01 | open / 已复现 | Vendored cue entity decoding retains semicolons after lt, gt and amp entities | PKG-MULTI-SUB-05 | | MULTI-SUB-ENTITY-01 | open / 已复现 | Vendored cue entity decoding retains semicolons after lt, gt and amp entities | PKG-MULTI-SUB-05 |
| JASSUB-TYPE-01 | open / 已复现 | JASSUB declared required URLs, Promise methods and resize parameter order differ from actual historical behavior | PKG-JASSUB-04 | | JASSUB-TYPE-01 | open / 已复现 | JASSUB declared required URLs, Promise methods and resize parameter order differ from actual historical behavior | PKG-JASSUB-04 |
| JASSUB-EXPORT-01 | open / 已复现 | JASSUB historical CommonJS object.default changes to a direct factory in 1.1.0 | PKG-JASSUB-04, PKG-JASSUB-06 | | JASSUB-EXPORT-01 | open / 已复现 | JASSUB historical CommonJS object.default changes to a direct factory in 1.1.0 | PKG-JASSUB-04, PKG-JASSUB-06 |
| CORE-DEFAULTS-SSR-01 | open / 已复现 | Reading static defaults throws when navigator is absent | CORE-25 | | CORE-DEFAULTS-SSR-01 | resolved / 已复现 | Reading static defaults throws when navigator is absent | CORE-25 |
| ENG-DIST-PUBLIC-01 | resolved / 已复现 | Vite copied authored declarations into library distribution | ENG-12 | | ENG-DIST-PUBLIC-01 | resolved / 已复现 | Vite copied authored declarations into library distribution | ENG-12 |
+7 -2
View File
@@ -4501,7 +4501,7 @@
"id": "CORE-DEFAULTS-SSR-01", "id": "CORE-DEFAULTS-SSR-01",
"title": "Reading static defaults throws when navigator is absent", "title": "Reading static defaults throws when navigator is absent",
"confirmation": "reproduced", "confirmation": "reproduced",
"status": "open", "status": "resolved",
"owners": [ "owners": [
"CORE-25" "CORE-25"
], ],
@@ -4513,7 +4513,12 @@
], ],
"compatibleResolution": "Read navigator through a guarded global lookup while preserving browser language defaults and public declaration shape.", "compatibleResolution": "Read navigator through a guarded global lookup while preserving browser language defaults and public declaration shape.",
"closureCriteria": "Published failure remains explicit; source and actual installed candidate defaults work without navigator on selected Node versions and browser language behavior stays unchanged.", "closureCriteria": "Published failure remains explicit; source and actual installed candidate defaults work without navigator on selected Node versions and browser language behavior stays unchanged.",
"workspaceState": "Node 20.19.0 actual installed probe fails with ReferenceError: navigator is not defined. Published 5.4.0 and candidate 5.4.1 both reproduce under explicitly absent navigator on every selected runtime. CI-01 records this known failure, then compares default values under the same controlled en-US navigator; this is not a production fix." "workspaceState": "Node 20.19.0 actual installed probe fails with ReferenceError: navigator is not defined. Published 5.4.0 and candidate 5.4.1 both reproduce under explicitly absent navigator on every selected runtime. CI-01 records this known failure, then compares default values under the same controlled en-US navigator; this is not a production fix.",
"resolutionEvidence": [
"refactor/changes/2026-09-13-CORE-25-defaults-ssr.md",
"refactor/baselines/defaults-ssr-validation.json"
],
"resolutionRationale": "Candidate source and actual installed main/legacy/ESM defaults work without navigator on Node 20.19.0/22.12.0/24.21.0. Three-engine source/main/legacy browser cases preserve en-US/zh-CN defaults and explicit language overrides; historical failure remains exact. Strict package release now reports zero known runtime blockers for this fixture."
}, },
{ {
"id": "ENG-DIST-PUBLIC-01", "id": "ENG-DIST-PUBLIC-01",
+3 -2
View File
@@ -4493,12 +4493,13 @@
"CORE-22", "CORE-22",
"ENG-12" "ENG-12"
], ],
"status": "todo", "status": "done",
"risk": "M", "risk": "M",
"deliverable": "安全读取默认语言并保留浏览器已有默认值;实际 Node 与发布产物正反例", "deliverable": "安全读取默认语言并保留浏览器已有默认值;实际 Node 与发布产物正反例",
"acceptance": "记录旧发布版 ReferenceError;候选在无 navigator 时可读默认选项,浏览器语言和公开类型不回归;不以补全局对象隐藏错误", "acceptance": "记录旧发布版 ReferenceError;候选在无 navigator 时可读默认选项,浏览器语言和公开类型不回归;不以补全局对象隐藏错误",
"evidence": [ "evidence": [
"changes/2026-09-13-CI-01-node-consumers.md" "changes/2026-09-13-CORE-25-defaults-ssr.md",
"baselines/defaults-ssr-validation.json"
] ]
}, },
{ {
+2 -1
View File
@@ -13,7 +13,8 @@
使用 Node 24.21.0;CI-01 已在 Windows 的 20.19.0/22.12.0/24.21.0 上重装消费相同 使用 Node 24.21.0;CI-01 已在 Windows 的 20.19.0/22.12.0/24.21.0 上重装消费相同
core/chapter tarball,见 [Node 记录](changes/2026-09-13-CI-01-node-consumers.md)。 core/chapter tarball,见 [Node 记录](changes/2026-09-13-CI-01-node-consumers.md)。
这不是在最低 Node 上完成仓库工具链的干净安装/构建测试,也不是发布包的最低 Node 声明。 这不是在最低 Node 上完成仓库工具链的干净安装/构建测试,也不是发布包的最低 Node 声明。
CORE-25 默认选项缺陷仍在严格发布检查中阻断;完整工具与消费范围由 CI-01 继续验证。 CORE-25 默认选项缺陷已修复并通过相同三 Node 与严格打包检查,见
[修复记录](changes/2026-09-13-CORE-25-defaults-ssr.md);完整工具与消费范围由 CI-01 继续验证。
## 锁文件和依赖维护 ## 锁文件和依赖维护
+26
View File
@@ -1,5 +1,31 @@
import { expect, test } from './fixtures.js' import { expect, test } from './fixtures.js'
for (const locale of ['en-US', 'zh-CN']) {
test.describe(`default language ${locale}`, () => {
test.use({ locale })
for (const core of ['published', 'candidate']) {
test(`${core}: language defaults follow the browser and explicit language still overrides`, async ({ page }) => {
await page.goto(`/test/player.html?core=${core}&chapter=published`)
const result = await page.evaluate(() => {
const container = document.createElement('div')
document.body.append(container)
const { Artplayer } = window
const initial = new Artplayer({ container })
const observed = { browser: navigator.language, defaults: Artplayer.option.lang, instance: initial.option.lang }
initial.destroy()
document.body.append(container)
const explicit = new Artplayer({ container, lang: 'fr' })
observed.explicit = explicit.option.lang
observed.defaultAfterOverride = Artplayer.option.lang
explicit.destroy()
return observed
})
expect(result).toEqual({ browser: locale, defaults: locale.toLowerCase(), instance: locale.toLowerCase(), explicit: 'fr', defaultAfterOverride: locale.toLowerCase() })
})
}
})
}
for (const core of ['published', 'candidate']) { for (const core of ['published', 'candidate']) {
test(`${core}: expanded option input preserves historical JS forms`, async ({ page }) => { test(`${core}: expanded option input preserves historical JS forms`, async ({ page }) => {
await page.goto(`/test/player.html?core=${core}&chapter=published`) await page.goto(`/test/player.html?core=${core}&chapter=published`)
+49
View File
@@ -40,6 +40,55 @@ test('default values, keys and nested order match the published getter', () => {
assert.deepEqual(Object.keys(current.Artplayer.option), Object.keys(published.Artplayer.option)) assert.deepEqual(Object.keys(current.Artplayer.option), Object.keys(published.Artplayer.option))
}) })
test('candidate defaults are readable without navigator and keep independent option containers', () => {
const descriptor = Object.getOwnPropertyDescriptor(globalThis, 'navigator')
try {
for (const mode of ['absent', 'undefined', 'null']) {
assert(delete globalThis.navigator)
if (mode !== 'absent')
Object.defineProperty(globalThis, 'navigator', { configurable: true, value: mode === 'null' ? null : undefined })
const first = current.Artplayer.option
const second = current.Artplayer.option
assert.equal(first.lang, undefined, mode)
assert(Object.hasOwn(first, 'lang'))
assert.notEqual(first, second)
assert.notEqual(first.subtitle, second.subtitle)
assert.deepEqual(first.plugins, [])
assert.equal(first.subtitle.onVttLoad('text'), 'text')
assert.throws(() => resolveOption({ container: '#player' }, first), /option.lang/)
assert.equal(resolveOption({ container: '#player', lang: 'en' }, first).lang, 'en')
}
}
finally {
if (descriptor)
Object.defineProperty(globalThis, 'navigator', descriptor)
else
delete globalThis.navigator
}
})
test('candidate defaults read the current browser language on each access without caching it', () => {
const descriptor = Object.getOwnPropertyDescriptor(globalThis, 'navigator')
try {
let language = 'EN-us'
Object.defineProperty(globalThis, 'navigator', { configurable: true, value: {
get language() {
return language
},
} })
for (const value of ['EN-us', 'zh-CN', '']) {
language = value
assert.equal(current.Artplayer.option.lang, value.toLowerCase())
}
}
finally {
if (descriptor)
Object.defineProperty(globalThis, 'navigator', descriptor)
else
delete globalThis.navigator
}
})
for (const [name, resolve, Artplayer] of [['published', oldResolve, published.Artplayer], ['workspace', resolveOption, current.Artplayer]]) { for (const [name, resolve, Artplayer] of [['published', oldResolve, published.Artplayer], ['workspace', resolveOption, current.Artplayer]]) {
test(`resolved options preserve unknown fields, merge ownership and collection item identity: ${name}`, () => { test(`resolved options preserve unknown fields, merge ownership and collection item identity: ${name}`, () => {
const callback = () => {} const callback = () => {}
+6 -5
View File
@@ -47,11 +47,12 @@ the actual child version. Reports and failure logs are `runtime-node-<version>.*
the same package output directory. Old reports without source/toolchain fields must the same package output directory. Old reports without source/toolchain fields must
be rebuilt. CI restores canonical Node before running browser tools. be rebuilt. CI restores canonical Node before running browser tools.
CORE-25 remains an explicit defect: both published and candidate static defaults throw CORE-25 fixed candidate static defaults without navigator. The fixture preserves the
without navigator. The fixture tests that exact failure on every runtime, then uses an published ReferenceError while requiring candidate main/legacy/ESM defaults to succeed,
identical controlled language for default-value comparison and restores the global. then uses an identical controlled language for comparison and restores the global.
`knownRuntimeBlockers=1` prevents strict release success; ordinary observation tests The fixture now reports zero known runtime blockers; it is still only core/chapter
passing do not mean the defect is fixed. See [Node evidence](../../refactor/changes/2026-09-13-CI-01-node-consumers.md). acceptance, not full release readiness. See [the fix](../../refactor/changes/2026-09-13-CORE-25-defaults-ssr.md)
and the earlier [Node evidence](../../refactor/changes/2026-09-13-CI-01-node-consumers.md).
The optional core `artplayer/runtime` entry has eight additional strict consumer The optional core `artplayer/runtime` entry has eight additional strict consumer
groups: TS 5.1.6 and 5.9.3 each check Node10 CommonJS, NodeNext CJS/ESM and Bundler. groups: TS 5.1.6 and 5.9.3 each check Node10 CommonJS, NodeNext CJS/ESM and Bundler.
+15 -4
View File
@@ -189,10 +189,21 @@ const vm = require('node:vm');
const defaultNavigator = Object.getOwnPropertyDescriptor(globalThis, 'navigator') const defaultNavigator = Object.getOwnPropertyDescriptor(globalThis, 'navigator')
try { try {
assert(delete globalThis.navigator) assert(delete globalThis.navigator)
// CORE-25 tracks this reproduced published and candidate failure separately. if (expected.baseline) {
assert.throws(() => core.option, { name: 'ReferenceError', message: 'navigator is not defined' }) assert.throws(() => core.option, { name: 'ReferenceError', message: 'navigator is not defined' })
observations.defaultsWithoutNavigator = { name: 'ReferenceError', message: 'navigator is not defined', historical: !!expected.baseline, resolved: false } observations.defaultsWithoutNavigator = { name: 'ReferenceError', message: 'navigator is not defined', historical: true, resolved: false }
check('SSR.defaults-missing-navigator-known-failure', true) check('SSR.defaults-missing-navigator-known-failure', true)
}
else {
const defaults = core.option
assert.equal(defaults.lang, undefined)
assert(Object.hasOwn(defaults, 'lang'))
assert.notEqual(core.option, defaults)
for (const Class of [esm.default, legacy.default, require('artplayer/legacy')])
assert.equal(Class.option.lang, undefined)
observations.defaultsWithoutNavigator = { historical: false, resolved: true, ownLang: true, langType: typeof defaults.lang }
check('SSR.defaults-without-navigator', true)
}
Object.defineProperty(globalThis, 'navigator', { configurable: true, value: { language: 'en-US' } }) Object.defineProperty(globalThis, 'navigator', { configurable: true, value: { language: 'en-US' } })
observations.api = { static: shape(core), prototype: shape(core.prototype), emitter: shape(core.Emitter.prototype), factory: shape(chapter), defaults: JSON.parse(JSON.stringify(core.option, (_, value) => typeof value === 'function' ? '$function' : value)) } observations.api = { static: shape(core), prototype: shape(core.prototype), emitter: shape(core.Emitter.prototype), factory: shape(chapter), defaults: JSON.parse(JSON.stringify(core.option, (_, value) => typeof value === 'function' ? '$function' : value)) }
check('API.defaults-controlled-language', observations.api.defaults.lang === 'en-us') check('API.defaults-controlled-language', observations.api.defaults.lang === 'en-us')
+5
View File
@@ -4,6 +4,11 @@ import resolveOption from '../../packages/artplayer/src/option/resolve'
const input: Option = { container: '#player', url: 'video.mp4', subtitle: { encoding: 'utf-8' } } const input: Option = { container: '#player', url: 'video.mp4', subtitle: { encoding: 'utf-8' } }
const resolved: ResolvedOption = resolveOption(input, createDefaults()) const resolved: ResolvedOption = resolveOption(input, createDefaults())
const defaultLanguage: string | undefined = createDefaults().lang
const validatedLanguage: string = resolved.lang.toLowerCase()
void [defaultLanguage, validatedLanguage]
// @ts-expect-error Unvalidated defaults may have no browser language.
createDefaults().lang.toLowerCase()
resolved.subtitle.onVttLoad(resolved.subtitle.url) resolved.subtitle.onVttLoad(resolved.subtitle.url)
resolved.thumbnails.column.toFixed() resolved.thumbnails.column.toFixed()
resolved.volume.toFixed() resolved.volume.toFixed()