mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[REL] v2.7.0
# v2.7.0 - [IMP] runtime/utils: export htmlEscape and add tests - [FIX] utils: Correct validation of mount target in shadow DOM/iframe - [IMP] runtime: add markup tag function
This commit is contained in:
+65
-11
@@ -276,13 +276,39 @@ function inOwnerDocument(el) {
|
|||||||
const rootNode = el.getRootNode();
|
const rootNode = el.getRootNode();
|
||||||
return rootNode instanceof ShadowRoot && el.ownerDocument.contains(rootNode.host);
|
return rootNode instanceof ShadowRoot && el.ownerDocument.contains(rootNode.host);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Determine whether the given element is contained in a specific root documnet:
|
||||||
|
* either directly or with a shadow root in between or in an iframe.
|
||||||
|
*/
|
||||||
|
function isAttachedToDocument(element, documentElement) {
|
||||||
|
let current = element;
|
||||||
|
const shadowRoot = documentElement.defaultView.ShadowRoot;
|
||||||
|
while (current) {
|
||||||
|
if (current === documentElement) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (current.parentNode) {
|
||||||
|
current = current.parentNode;
|
||||||
|
}
|
||||||
|
else if (current instanceof shadowRoot && current.host) {
|
||||||
|
current = current.host;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
function validateTarget(target) {
|
function validateTarget(target) {
|
||||||
// Get the document and HTMLElement corresponding to the target to allow mounting in iframes
|
// Get the document and HTMLElement corresponding to the target to allow mounting in iframes
|
||||||
const document = target && target.ownerDocument;
|
const document = target && target.ownerDocument;
|
||||||
if (document) {
|
if (document) {
|
||||||
|
if (!document.defaultView) {
|
||||||
|
throw new OwlError("Cannot mount a component: the target document is not attached to a window (defaultView is missing)");
|
||||||
|
}
|
||||||
const HTMLElement = document.defaultView.HTMLElement;
|
const HTMLElement = document.defaultView.HTMLElement;
|
||||||
if (target instanceof HTMLElement || target instanceof ShadowRoot) {
|
if (target instanceof HTMLElement || target instanceof ShadowRoot) {
|
||||||
if (!document.body.contains(target instanceof HTMLElement ? target : target.host)) {
|
if (!isAttachedToDocument(target, document)) {
|
||||||
throw new OwlError("Cannot mount a component on a detached dom node");
|
throw new OwlError("Cannot mount a component on a detached dom node");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -319,12 +345,40 @@ async function loadFile(url) {
|
|||||||
*/
|
*/
|
||||||
class Markup extends String {
|
class Markup extends String {
|
||||||
}
|
}
|
||||||
/*
|
function htmlEscape(str) {
|
||||||
* Marks a value as safe, that is, a value that can be injected as HTML directly.
|
if (str instanceof Markup) {
|
||||||
* It should be used to wrap the value passed to a t-out directive to allow a raw rendering.
|
return str;
|
||||||
*/
|
}
|
||||||
function markup(value) {
|
if (str === undefined) {
|
||||||
return new Markup(value);
|
return markup("");
|
||||||
|
}
|
||||||
|
if (typeof str === "number") {
|
||||||
|
return markup(String(str));
|
||||||
|
}
|
||||||
|
[
|
||||||
|
["&", "&"],
|
||||||
|
["<", "<"],
|
||||||
|
[">", ">"],
|
||||||
|
["'", "'"],
|
||||||
|
['"', """],
|
||||||
|
["`", "`"],
|
||||||
|
].forEach((pairs) => {
|
||||||
|
str = String(str).replace(new RegExp(pairs[0], "g"), pairs[1]);
|
||||||
|
});
|
||||||
|
return markup(str);
|
||||||
|
}
|
||||||
|
function markup(valueOrStrings, ...placeholders) {
|
||||||
|
if (!Array.isArray(valueOrStrings)) {
|
||||||
|
return new Markup(valueOrStrings);
|
||||||
|
}
|
||||||
|
const strings = valueOrStrings;
|
||||||
|
let acc = "";
|
||||||
|
let i = 0;
|
||||||
|
for (; i < placeholders.length; ++i) {
|
||||||
|
acc += strings[i] + htmlEscape(placeholders[i]);
|
||||||
|
}
|
||||||
|
acc += strings[i];
|
||||||
|
return new Markup(acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEventHandler(rawEvent) {
|
function createEventHandler(rawEvent) {
|
||||||
@@ -5704,7 +5758,7 @@ function compile(template, options = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// do not modify manually. This file is generated by the release script.
|
// do not modify manually. This file is generated by the release script.
|
||||||
const version = "2.6.1";
|
const version = "2.7.0";
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Scheduler
|
// Scheduler
|
||||||
@@ -6172,9 +6226,9 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export { App, Component, EventBus, OwlError, __info__, batched, blockDom, loadFile, markRaw, markup, mount, onError, onMounted, onPatched, onRendered, onWillDestroy, onWillPatch, onWillRender, onWillStart, onWillUnmount, onWillUpdateProps, reactive, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, validate, validateType, whenReady, xml };
|
export { App, Component, EventBus, OwlError, __info__, batched, blockDom, htmlEscape, loadFile, markRaw, markup, mount, onError, onMounted, onPatched, onRendered, onWillDestroy, onWillPatch, onWillRender, onWillStart, onWillUnmount, onWillUpdateProps, reactive, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, validate, validateType, whenReady, xml };
|
||||||
|
|
||||||
|
|
||||||
__info__.date = '2025-03-05T08:37:58.580Z';
|
__info__.date = '2025-03-26T12:58:40.935Z';
|
||||||
__info__.hash = '2b5cea9';
|
__info__.hash = 'e788e36';
|
||||||
__info__.url = 'https://github.com/odoo/owl';
|
__info__.url = 'https://github.com/odoo/owl';
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odoo/owl",
|
"name": "@odoo/owl",
|
||||||
"version": "2.6.1",
|
"version": "2.7.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odoo/owl",
|
"name": "@odoo/owl",
|
||||||
"version": "2.6.1",
|
"version": "2.7.0",
|
||||||
"description": "Odoo Web Library (OWL)",
|
"description": "Odoo Web Library (OWL)",
|
||||||
"main": "dist/owl.cjs.js",
|
"main": "dist/owl.cjs.js",
|
||||||
"module": "dist/owl.es.js",
|
"module": "dist/owl.es.js",
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
// do not modify manually. This file is generated by the release script.
|
// do not modify manually. This file is generated by the release script.
|
||||||
export const version = "2.6.1";
|
export const version = "2.7.0";
|
||||||
|
|||||||
Reference in New Issue
Block a user