mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d0a46c5dc |
@@ -41,7 +41,7 @@ one. There can also be multiple apps loaded in the page like in website:
|
||||
|
||||
There is a convenient search bar at the top of the components tree which will help finding
|
||||
the components tou want in the tree and also, an element picker can be used to directly select
|
||||
the component you want to focus on in the page which is especially useful when 1trying to find
|
||||
the component you want to focus on in the page which is especially useful when trying to find
|
||||
what you want. Just click on the elements picker icon and click on the element you want to focus
|
||||
on in the page and it will be selected in the devtools accordingly. Hovering any element in the
|
||||
page in this mode will highlight it and the same happens anytime in the components tree.
|
||||
|
||||
+8
-15
@@ -2073,7 +2073,7 @@ function basicProxyHandler(callback) {
|
||||
set(target, key, value, receiver) {
|
||||
const hadKey = objectHasOwnProperty.call(target, key);
|
||||
const originalValue = Reflect.get(target, key, receiver);
|
||||
const ret = Reflect.set(target, key, toRaw(value), receiver);
|
||||
const ret = Reflect.set(target, key, value, receiver);
|
||||
if (!hadKey && objectHasOwnProperty.call(target, key)) {
|
||||
notifyReactives(target, KEYCHANGES);
|
||||
}
|
||||
@@ -3197,14 +3197,7 @@ class TemplateSet {
|
||||
this.translateFn = config.translateFn;
|
||||
this.translatableAttributes = config.translatableAttributes;
|
||||
if (config.templates) {
|
||||
if (config.templates instanceof Document || typeof config.templates === "string") {
|
||||
this.addTemplates(config.templates);
|
||||
}
|
||||
else {
|
||||
for (const name in config.templates) {
|
||||
this.addTemplate(name, config.templates[name]);
|
||||
}
|
||||
}
|
||||
this.addTemplates(config.templates);
|
||||
}
|
||||
}
|
||||
static registerTemplate(name, fn) {
|
||||
@@ -5286,14 +5279,14 @@ function parseComponent(node, ctx) {
|
||||
// be ignored)
|
||||
let el = slotNode.parentElement;
|
||||
let isInSubComponent = false;
|
||||
while (el && el !== clone) {
|
||||
while (el !== clone) {
|
||||
if (el.hasAttribute("t-component") || el.tagName[0] === el.tagName[0].toUpperCase()) {
|
||||
isInSubComponent = true;
|
||||
break;
|
||||
}
|
||||
el = el.parentElement;
|
||||
}
|
||||
if (isInSubComponent || !el) {
|
||||
if (isInSubComponent) {
|
||||
continue;
|
||||
}
|
||||
slotNode.removeAttribute("t-set-slot");
|
||||
@@ -5562,7 +5555,7 @@ function compile(template, options = {}) {
|
||||
}
|
||||
|
||||
// do not modify manually. This file is generated by the release script.
|
||||
const version = "2.2.7";
|
||||
const version = "2.2.6";
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Scheduler
|
||||
@@ -5909,7 +5902,7 @@ function useChildSubEnv(envExtension) {
|
||||
*
|
||||
* @template T
|
||||
* @param {Effect<T>} effect the effect to run on component mount and/or patch
|
||||
* @param {()=>[...T]} [computeDependencies=()=>[NaN]] a callback to compute
|
||||
* @param {()=>T} [computeDependencies=()=>[NaN]] a callback to compute
|
||||
* dependencies that will decide if the effect needs to be cleaned up and
|
||||
* run again. If the dependencies did not change, the effect will not run
|
||||
* again. The default value returns an array containing only NaN because
|
||||
@@ -5991,6 +5984,6 @@ TemplateSet.prototype._compileTemplate = function _compileTemplate(name, templat
|
||||
export { App, Component, EventBus, OwlError, __info__, 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 };
|
||||
|
||||
|
||||
__info__.date = '2023-12-06T13:56:01.636Z';
|
||||
__info__.hash = 'e94428a';
|
||||
__info__.date = '2023-09-25T11:48:01.531Z';
|
||||
__info__.hash = '752160f';
|
||||
__info__.url = 'https://github.com/odoo/owl';
|
||||
|
||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@odoo/owl",
|
||||
"version": "2.2.7",
|
||||
"version": "2.2.6",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@odoo/owl",
|
||||
"version": "2.2.7",
|
||||
"version": "2.2.6",
|
||||
"description": "Odoo Web Library (OWL)",
|
||||
"main": "dist/owl.cjs.js",
|
||||
"module": "dist/owl.es.js",
|
||||
|
||||
@@ -740,14 +740,14 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
|
||||
// be ignored)
|
||||
let el = slotNode.parentElement!;
|
||||
let isInSubComponent = false;
|
||||
while (el && el !== clone) {
|
||||
while (el !== clone) {
|
||||
if (el!.hasAttribute("t-component") || el!.tagName[0] === el!.tagName[0].toUpperCase()) {
|
||||
isInSubComponent = true;
|
||||
break;
|
||||
}
|
||||
el = el.parentElement!;
|
||||
}
|
||||
if (isInSubComponent || !el) {
|
||||
if (isInSubComponent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ export type ComponentConstructor<P extends Props = any, E = any> = (new (
|
||||
|
||||
export class Component<Props = any, Env = any> {
|
||||
static template: string = "";
|
||||
static props?: Schema;
|
||||
static props?: any;
|
||||
static defaultProps?: any;
|
||||
|
||||
props: Props;
|
||||
|
||||
@@ -65,7 +65,7 @@ export class Portal extends Component {
|
||||
type: String,
|
||||
},
|
||||
slots: true,
|
||||
} as const;
|
||||
};
|
||||
|
||||
setup() {
|
||||
const node: any = this.__owl__;
|
||||
|
||||
@@ -41,7 +41,7 @@ export interface TemplateSetConfig {
|
||||
dev?: boolean;
|
||||
translatableAttributes?: string[];
|
||||
translateFn?: (s: string) => string;
|
||||
templates?: string | Document | Record<string, string>;
|
||||
templates?: string | Document;
|
||||
}
|
||||
|
||||
export class TemplateSet {
|
||||
@@ -60,13 +60,7 @@ export class TemplateSet {
|
||||
this.translateFn = config.translateFn;
|
||||
this.translatableAttributes = config.translatableAttributes;
|
||||
if (config.templates) {
|
||||
if (config.templates instanceof Document || typeof config.templates === "string") {
|
||||
this.addTemplates(config.templates);
|
||||
} else {
|
||||
for (const name in config.templates) {
|
||||
this.addTemplate(name, config.templates[name]);
|
||||
}
|
||||
}
|
||||
this.addTemplates(config.templates);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ type BaseType =
|
||||
| typeof Date
|
||||
| typeof Object
|
||||
| typeof Array
|
||||
| typeof Function
|
||||
| true
|
||||
| "*";
|
||||
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
// do not modify manually. This file is generated by the release script.
|
||||
export const version = "2.2.7";
|
||||
export const version = "2.2.6";
|
||||
|
||||
@@ -57,19 +57,6 @@ exports[`app can configure an app with props 1`] = `
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`app can load templates from an object name-string 1`] = `
|
||||
"function anonymous(app, bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
|
||||
|
||||
let block1 = createBlock(\`<div class=\\"hello\\">hello</div>\`);
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return block1();
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`app can mount app in an iframe 1`] = `
|
||||
"function anonymous(app, bdom, helpers
|
||||
) {
|
||||
|
||||
@@ -167,21 +167,4 @@ describe("app", () => {
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test("can load templates from an object name-string", async () => {
|
||||
const templates = {
|
||||
hello: `<div class="hello">hello</div>`,
|
||||
world: `<div>world</div>`,
|
||||
};
|
||||
class SomeComponent extends Component {
|
||||
static template = "hello";
|
||||
}
|
||||
|
||||
const app = new App(SomeComponent, { templates });
|
||||
await app.mount(fixture);
|
||||
expect(fixture.querySelector(".hello")).toBeDefined();
|
||||
// Only the "hello" template is used, so the "world" template is not yet loaded
|
||||
expect(Object.keys(app.templates)).toEqual(["hello"]);
|
||||
expect(Object.keys(app.rawTemplates)).toEqual(["hello", "world"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1066,45 +1066,6 @@ exports[`slots multiple slots containing components 3`] = `
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`slots named slot inside named slot in t-component 1`] = `
|
||||
"function anonymous(app, bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
|
||||
let { capture, markRaw } = helpers;
|
||||
const comp1 = app.createComponent(null, false, true, false, []);
|
||||
const comp2 = app.createComponent(\`Child\`, true, true, false, []);
|
||||
|
||||
function slot1(ctx, node, key = \\"\\") {
|
||||
const b2 = text(\` outer \`);
|
||||
const ctx2 = capture(ctx);
|
||||
const Comp1 = ctx['Child'];
|
||||
const b4 = toggler(Comp1, comp1({slots: markRaw({'brol': {__render: slot2.bind(this), __ctx: ctx2}})}, (Comp1).name + key + \`__1\`, node, this, Comp1));
|
||||
return multi([b2, b4]);
|
||||
}
|
||||
|
||||
function slot2(ctx, node, key = \\"\\") {
|
||||
return text(ctx['value']);
|
||||
}
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
const ctx1 = capture(ctx);
|
||||
return comp2({slots: markRaw({'brol': {__render: slot1.bind(this), __ctx: ctx1}})}, key + \`__2\`, node, this, null);
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`slots named slot inside named slot in t-component 2`] = `
|
||||
"function anonymous(app, bdom, helpers
|
||||
) {
|
||||
let { text, createBlock, list, multi, html, toggler, comment } = bdom;
|
||||
let { callSlot } = helpers;
|
||||
|
||||
return function template(ctx, node, key = \\"\\") {
|
||||
return callSlot(ctx, node, key, 'brol', false, {});
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`slots named slot inside slot 1`] = `
|
||||
"function anonymous(app, bdom, helpers
|
||||
) {
|
||||
|
||||
@@ -594,7 +594,7 @@ describe("props validation", () => {
|
||||
|
||||
test("props: can be defined with a boolean", async () => {
|
||||
class SubComp extends Component {
|
||||
static props = { message: true } as const;
|
||||
static props = { message: true };
|
||||
}
|
||||
expect(() => {
|
||||
validateProps(SubComp as any, {});
|
||||
@@ -636,7 +636,7 @@ describe("props validation", () => {
|
||||
|
||||
test("props: extra props cause an error, part 2", async () => {
|
||||
class SubComp extends Component {
|
||||
static props = { message: true } as const;
|
||||
static props = { message: true };
|
||||
}
|
||||
expect(() => {
|
||||
validateProps(SubComp as any, { message: 1, flag: true });
|
||||
|
||||
@@ -1673,31 +1673,6 @@ describe("slots", () => {
|
||||
expect(fixture.innerHTML).toBe("<div><div><p>Ablip</p><div><p>Bblip</p></div></div></div>");
|
||||
});
|
||||
|
||||
test("named slot inside named slot in t-component", async () => {
|
||||
class Child extends Component {
|
||||
static template = xml`<t t-slot="brol"/>`;
|
||||
}
|
||||
class Parent extends Component {
|
||||
static template = xml`
|
||||
<Child>
|
||||
<t t-set-slot="brol">
|
||||
outer
|
||||
<t t-component="Child">
|
||||
<t t-set-slot="brol">
|
||||
<t t-esc="value"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</Child>`;
|
||||
static components = { Child };
|
||||
Child = Child;
|
||||
value = "inner";
|
||||
}
|
||||
await mount(Parent, fixture);
|
||||
|
||||
expect(fixture.innerHTML).toBe(" outer inner");
|
||||
});
|
||||
|
||||
test("can render only empty slot", async () => {
|
||||
class Parent extends Component {
|
||||
static template = xml`<t t-slot="default"/>`;
|
||||
|
||||
Reference in New Issue
Block a user