Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/core/src/utils-hoist/normalize.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import { isSyntheticEvent, isVueViewModel } from './is';
import { convertToPlainObject } from './object';
import { getFunctionName } from './stacktrace';

type Prototype = { constructor: (...args: unknown[]) => unknown };
type Prototype = { constructor?: (...args: unknown[]) => unknown };
// This is a hack to placate TS, relying on the fact that technically, arrays are objects with integer keys. Normally we
// think of those keys as actual numbers, but `arr['0']` turns out to work just as well as `arr[0]`, and doing it this
// way lets us use a single type in the places where behave as if we are only dealing with objects, even if some of them
Expand DownExpand Up@@ -264,7 +264,7 @@ function stringifyValue(
function getConstructorName(value: unknown): string {
const prototype: Prototype | null = Object.getPrototypeOf(value);

return prototype ? prototype.constructor.name : 'null prototype';
return prototype?.constructor ? prototype.constructor.name : 'null prototype';
}

/** Calculates bytes size of input string */
Expand Down
11 changes: 11 additions & 0 deletions packages/core/test/utils-hoist/normalize.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -484,6 +484,17 @@ describe('normalize()', () => {
foo: '[VueViewModel]',
});
});

test('null prototype', () => {
const obj = Object.create(null);
expect(normalize(obj, 0)).toEqual('[null prototype]');
});

test('null prototype base', () => {
const base = Object.create(null);
const obj = Object.create(base);
expect(normalize(obj, 0)).toEqual('[null prototype]');
});
});

describe('can limit object to depth', () => {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/core/src/utils-hoist/normalize.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import { isSyntheticEvent, isVueViewModel } from './is';
import { convertToPlainObject } from './object';
import { getFunctionName } from './stacktrace';

type Prototype = { constructor: (...args: unknown[]) => unknown };
type Prototype = { constructor?: (...args: unknown[]) => unknown };
// This is a hack to placate TS, relying on the fact that technically, arrays are objects with integer keys. Normally we
// think of those keys as actual numbers, but `arr['0']` turns out to work just as well as `arr[0]`, and doing it this
// way lets us use a single type in the places where behave as if we are only dealing with objects, even if some of them
Expand DownExpand Up@@ -264,7 +264,7 @@ function stringifyValue(
function getConstructorName(value: unknown): string {
const prototype: Prototype | null = Object.getPrototypeOf(value);

return prototype ? prototype.constructor.name : 'null prototype';
return prototype?.constructor ? prototype.constructor.name : 'null prototype';
}

/** Calculates bytes size of input string */
Expand Down
11 changes: 11 additions & 0 deletions packages/core/test/utils-hoist/normalize.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -484,6 +484,17 @@ describe('normalize()', () => {
foo: '[VueViewModel]',
});
});

test('null prototype', () => {
const obj = Object.create(null);
expect(normalize(obj, 0)).toEqual('[null prototype]');
});

test('null prototype base', () => {
const base = Object.create(null);
const obj = Object.create(base);
expect(normalize(obj, 0)).toEqual('[null prototype]');
});
});

describe('can limit object to depth', () => {
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/core/src/utils-hoist/normalize.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ import { isSyntheticEvent, isVueViewModel } from './is';
import { convertToPlainObject } from './object';
import { getFunctionName } from './stacktrace';

type Prototype = { constructor: (...args: unknown[]) => unknown };
type Prototype = { constructor?: (...args: unknown[]) => unknown };
// This is a hack to placate TS, relying on the fact that technically, arrays are objects with integer keys. Normally we
// think of those keys as actual numbers, but `arr['0']` turns out to work just as well as `arr[0]`, and doing it this
// way lets us use a single type in the places where behave as if we are only dealing with objects, even if some of them
Expand DownExpand Up@@ -264,7 +264,7 @@ function stringifyValue(
function getConstructorName(value: unknown): string {
const prototype: Prototype | null = Object.getPrototypeOf(value);

return prototype ? prototype.constructor.name : 'null prototype';
return prototype?.constructor ? prototype.constructor.name : 'null prototype';
}

/** Calculates bytes size of input string */
Expand Down
11 changes: 11 additions & 0 deletions packages/core/test/utils-hoist/normalize.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -484,6 +484,17 @@ describe('normalize()', () => {
foo: '[VueViewModel]',
});
});

test('null prototype', () => {
const obj = Object.create(null);
expect(normalize(obj, 0)).toEqual('[null prototype]');
});

test('null prototype base', () => {
const base = Object.create(null);
const obj = Object.create(base);
expect(normalize(obj, 0)).toEqual('[null prototype]');
});
});

describe('can limit object to depth', () => {
Expand Down