]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-dom): set width/height with units as attribute (#8781)
authorzhoulixiang <18366276315@163.com>
Thu, 30 Nov 2023 09:27:23 +0000 (17:27 +0800)
committerGitHub <noreply@github.com>
Thu, 30 Nov 2023 09:27:23 +0000 (17:27 +0800)
Technically, width / height on `<img>`, `<video>` etc must be integers and cannot contain units. When set as a DOM property, the DOM force converts strings with units to 0. However, this is such a common mistake that most browsers nowadays supports such usage, and it makes sense for Vue to at least let it be set as an attribute.

packages/runtime-dom/__tests__/patchProps.spec.ts
packages/runtime-dom/src/patchProp.ts

index bf6362e7a0cc96fd656cde3961c43f6fc72bb82c..19554b028104bb1ee183798bbac6b1cadaedb4cf 100644 (file)
@@ -291,6 +291,15 @@ describe('runtime-dom: props patching', () => {
     expect(el.value).toBe('baz')
   })
 
+  // #8780
+  test('embedded tag with width and height', () => {
+    // Width and height of some embedded element such as img、video、source、canvas
+    // must be set as attribute
+    const el = document.createElement('img')
+    patchProp(el, 'width', null, '24px')
+    expect(el.getAttribute('width')).toBe('24px')
+  })
+
   test('translate attribute', () => {
     const el = document.createElement('div')
     patchProp(el, 'translate', null, 'no')
index 38ad5b9f8b8f6502afb7891ed8d1cc2586dea548..15f4f73edc47a5b31c6f725559286bb2f6395eab 100644 (file)
@@ -8,6 +8,8 @@ import { RendererOptions } from '@vue/runtime-core'
 
 const nativeOnRE = /^on[a-z]/
 
+const embeddedTags = ['IMG', 'VIDEO', 'CANVAS', 'SOURCE']
+
 type DOMRendererOptions = RendererOptions<Node, Element>
 
 export const patchProp: DOMRendererOptions['patchProp'] = (
@@ -105,6 +107,14 @@ function shouldSetAsProp(
     return false
   }
 
+  // #8780 the width or heigth of embedded tags must be set as attribute
+  if (
+    (key === 'width' || key === 'height') &&
+    embeddedTags.includes(el.tagName)
+  ) {
+    return false
+  }
+
   // native onclick with string value, must be set as attribute
   if (nativeOnRE.test(key) && isString(value)) {
     return false