-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
Conversation
✅ Deploy Preview for mermaid-js ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
There was a problem hiding this 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.
export const getClass = function (className: string): ClassNode { | ||
return classes[className]; | ||
}; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this 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:
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
if (classes[id] !== undefined) { | ||
classes[id].link = utils.formatUrl(linkStr, config); | ||
addClass(className); | ||
if (classes[className] !== undefined) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 ;)
export const getClass = function (className: string): ClassNode { | ||
return classes[className]; | ||
}; |
There was a problem hiding this comment.
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?
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 |
This is no longer relevant |
📑 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
MERMAID_RELEASE_VERSION
is used for all new features.develop
branch