Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle non declared classes #5222

Closed

Conversation

jgreywolf
Copy link
Contributor

@jgreywolf jgreywolf commented Jan 22, 2024

📑 Summary

This fix allows classes that have not yet been defined elsewhere to be used in an action such as creating a link, setting style/css class or annotations.

Resolves #2234, #2021

📏 Design Decisions

Used existing solution of calling addClass(className) before accessing getClasses

📋 Tasks

Make sure you

Copy link

netlify bot commented Jan 22, 2024

Deploy Preview for mermaid-js ready!

Name Link
🔨 Latest commit 5482d0a
🔍 Latest deploy log https://app.netlify.com/sites/mermaid-js/deploys/65af4d2634664a0008313dac
😎 Deploy Preview https://deploy-preview-5222--mermaid-js.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@github-actions github-actions bot added the Type: Bug / Error Something isn't working or is incorrect label Jan 22, 2024
@jgreywolf jgreywolf linked an issue Jan 22, 2024 that may be closed by this pull request
Copy link
Member

@sidharthv96 sidharthv96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation is good, but I'm not really sure about the feature.
Should we really be adding links, notes, styles etc to classes that have not been created? Would throwing an error make more sense?

If we release it, we can't revert it.

Approve on the code changes, On the fence about the feature.

Comment on lines +119 to 121
export const getClass = function (className: string): ClassNode {
return classes[className];
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: This would be a big change, but if we use this function everywhere instead of direct dictionary access, we'd only have to add the addClass function here, and also handle any future checks easily.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this will work, because there are places where we want to create the class, if it does not exist, and places where we don't want to create the class, if it doesn't exist.

Maybe a getOrCreateClass() function might help, though?

Copy link
Member

@aloisklink aloisklink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @sidharthv96, I'm not sure if we should add this feature.

But I'm also unsure if throwing an error is okay, since there might be a bunch of diagrams out in the wild that already have this currently ignored syntax.

Edit: Actually, if this is syntax that is already allowed (it's just being ignored), I think it's probably okay to add this feature. After all, we can't change this behaviour to instead throw an error if people already have this syntax in existing diagrams. Flowcharts also seem to work similarly, where using style before a node is first created is fine.

Btw, currently, it doesn't work with generic classes:

classDiagram
    style Square fill:#f9f,stroke:#333,stroke-width:4px

    class Square~Shape~{
        int id
        List~int~ position
        setPoints(List~int~ points)
        getPoints() List~int~
    }

renders:

image

while

classDiagram
    class Square~Shape~{
        int id
        List~int~ position
        setPoints(List~int~ points)
        getPoints() List~int~
    }

    style Square fill:#f9f,stroke:#333,stroke-width:4px

renders

image

if (classes[id] !== undefined) {
classes[id].link = utils.formatUrl(linkStr, config);
addClass(className);
if (classes[className] !== undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if() statement will always be true, since we always call addClass(className) before it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it might be required to satisfy typescript.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmmm, that's a good point. We could do something like:

function addClass(className: string): asserts classes[className] !== undefined {

See https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions

The issue is that calling addClass('Array~string~') creates classes['Array'], not classes['Array~string~'], so we'd probably need a new function like addClassID.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addClass('Array~string~') is SUPPOSED to create classes['Array']. The type is a property on the class object, and not part of the id.

At least, that is the way it is now. PR #5223 will change this so the generic type will be appended to the id. addClass(Array~string~) will create classes['Array-string']

@@ -458,6 +470,7 @@ export const addClassesToNamespace = function (id: string, classNames: string[])
};

export const setCssStyle = function (id: string, styles: string[]) {
addClass(id);
const thisClass = classes[id];
if (!styles || !thisClass) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thisClass will never be falsy, since we just created it with addClass.

@@ -308,6 +320,7 @@ const setClickFunc = function (_domId: string, functionName: string, functionArg
}

const id = domId;
addClass(id);
if (classes[id] !== undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

classes[id] !== undefined will never be falsey, since we just called addClass().

}
if (classes[id] !== undefined) {
classes[id].cssClasses.push(className);
if (classes[className] !== undefined) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if() statement will always be true, since we always call addClass(className) before it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed one of these cases - but forgot to look for any others ;)

Comment on lines +119 to 121
export const getClass = function (className: string): ClassNode {
return classes[className];
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this will work, because there are places where we want to create the class, if it does not exist, and places where we don't want to create the class, if it doesn't exist.

Maybe a getOrCreateClass() function might help, though?

@jgreywolf jgreywolf marked this pull request as draft January 28, 2024 01:02
@jgreywolf
Copy link
Contributor Author

I moved this back to draft, because there are changes in PR #5223 I want to use here, so will wait until that one is merged

@jgreywolf
Copy link
Contributor Author

This is no longer relevant

@jgreywolf jgreywolf closed this Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug / Error Something isn't working or is incorrect
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Link declaration depends on other declarations Line order influences syntactic validity
3 participants