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

feat: Attributes support for insert script #1386

Merged
merged 27 commits into from
Feb 12, 2024

Conversation

nsrCodes
Copy link
Contributor

@nsrCodes nsrCodes commented Feb 5, 2024

Schema changes

  • Adds attributes attribute to the script object (so inside the schema it is rule > pair > script.attributes)
  • script.value still only contains the raw code.

Validations

During Editing

  • only one html node
  • only the correct html node
  • no innerText for html of script rule of url type

On Save:

  • if JS code has document.onLoad in any way, and loadtime is AfterPageLoad: updates load time and shows editor toast, rule is not saved tho
  • if, even after all the ongoing validations, script.value contains html code, error toast is shown

New functionalities:

Code editor now have their own toasts

New UI:

Screenshot 2024-02-05 at 5 47 07 AM Screenshot 2024-02-05 at 2 32 37 AM

@RuntimeTerror10
Copy link
Member

Editor toast is visible even after saving the rule
https://app.requestly.io/sessions/saved/U0Ke8ci3CvlxlbaTSjgK

return ruleData;
}

const ruleDataCopy = _.cloneDeep(ruleData);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need a deep copy of rule data? Can you also add a comment here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

RuleData is explicitly read-only (reference to value in store). Updating it directly is possible but leads to very messy code

Added a comment

Copy link
Contributor

Choose a reason for hiding this comment

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

@nsrCodes I am still not sure you really need to deep clone the ruleData

Looking at this code below 👇 You are again creating a new ruleObject with new rulePairs

image

Just sharing my understanding of ... operator

image

Copy link
Contributor

Choose a reason for hiding this comment

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

And, Please do not resolve any conversation just after your comment, let me resolve the conversation otherwise I will miss the responses.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This works for when we only need to change 1 level deep.
Here the whole object immutable, down to every scrip object which is why had to deep clone

Comment on lines 34 to 38
const isCompatibleWithAttributesForScriptRule = isFeatureCompatible(FEATURES.SCRIPT_RULE_HTML_BLOCK);

if (!isCompatibleWithAttributesForScriptRule) {
return ruleData;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be moved into a separate function like checkScriptRuleVersionCompatibility()

function checkcheckScriptRuleVersionCompatibility() {
    // Check for Attributes support added in Feb 2024
    const isCompatibleForAttribues = isFeatureCompatible(FEATURES.SCRIPT_RULE_ATTRIBUTES_SUPPORT);
    
    if (!isCompatibleForAttribues) return false;

    // We can similarly check other compatible things in future

}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

doing this just for this check would go agains the current convention across the code where we just use isFeatureCompatible(<feature>) for all such similar checks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

but extracting that to a variable here does seem redundant so replaced that with the function call itself

Comment on lines 34 to 79
const isCompatibleWithAttributesForScriptRule = isFeatureCompatible(FEATURES.SCRIPT_RULE_HTML_BLOCK);

if (!isCompatibleWithAttributesForScriptRule) {
return ruleData;
}

const ruleDataCopy = _.cloneDeep(ruleData);
const newPairs = [];

for (const pair of ruleDataCopy.pairs) {
const parsedPair = pair;
const newScripts = [];

for (const script of pair.scripts) {
let newScript = script;

const htmlNodeName = getHTMLNodeName(script.type, script.codeType);

if (script.type === GLOBAL_CONSTANTS.SCRIPT_TYPES.CODE) {
const res = await validateStringForSpecificHTMLNode(script.value, htmlNodeName);
if (!res.isValid) {
return {
error: res.validationError,
success: false,
message: res.errorMessage,
pairId: pair.id,
};
}
const { attributes, innerText: code } = extractInnerTextAndAttributesFromHTMLString(
script.value,
htmlNodeName
);
newScript = {
...script,
attributes,
value: code,
};
} else if (script.type === GLOBAL_CONSTANTS.SCRIPT_TYPES.URL) {
const res = await validateStringForSpecificHTMLNode(script.wrapperElement, htmlNodeName);
if (!res.isValid) {
return {
error: res.validationError,
success: false,
message: res.errorMessage,
pairId: pair.id,
};
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should break down this code into smaller functions. It will also help in writing UTs.

if (doesStringContainHTMLSnippet(code)) {
return {
isValid: false,
error: scriptLogicalErrors.CONTAINS_HTML_CODE,
Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly, update the error type CONTAINS_NON_JS_CSS

}

/* HTML VALIDATORS */
export const invalidHTMLError = {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be in CAPS HTML_ERRORS.COULD_NOT_PARSE

* @param {Document} doc Document created from the HTML string
* @returns {boolean}
*/
function isHTMLString(str, doc) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the difference between isHTMLString and doesContainHTMLString function that you defined above?

https://github.com/requestly/requestly/pull/1386/files#diff-9ba7447af01ba32e558b219199e9e0247e03e17cc3dfdb9e97ed91ccd1e170d9R67

I see the code is being duplicated. Can we avoid 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.

changed doesContainHTMLString to isJSOrCSS cause as you mentioned, that was the intent there

if (codeType === GLOBAL_CONSTANTS.SCRIPT_CODE_TYPES.JS) {
// else CSS
htmlNode = "script";
} else if (scriptType === GLOBAL_CONSTANTS.SCRIPT_TYPES.URL) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should still wrap this under codeType check

export function getHTMLNodeName(scriptType, codeType) {
let htmlNode = "";
if (codeType === GLOBAL_CONSTANTS.SCRIPT_CODE_TYPES.JS) {
// else CSS
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment isn't placed correctly

return htmlNode;
}

function extractDomNodeDetailsFromHTMLCodeString(htmlCodeString, nodeName) {
Copy link
Contributor

Choose a reason for hiding this comment

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

extractDOMNodeDetails

@@ -17,3 +17,7 @@
border-bottom-left-radius: var(--border-radius-sm);
border-bottom-right-radius: var(--border-radius-sm);
}

.code-editor-small {
max-height: 72px;
Copy link
Contributor

Choose a reason for hiding this comment

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

@rohanmathur91 @RuntimeTerror10 -- You can review how we put styles

Copy link
Member

Choose a reason for hiding this comment

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

Please remove this class as this is not being used

}),
[]
);
const isCompatibleWithAttributes = isFeatureCompatible(FEATURES.SCRIPT_RULE_HTML_BLOCK);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please rename to FEATURES.SCRIPT_RULE.ATTRIBUTES_SUPPORT because we still don't support HTML block. It sounds confusing

<Col xl="12" span={24}>
<CodeEditor
id={pair.id}
height={75}
Copy link
Contributor

Choose a reason for hiding this comment

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

@RuntimeTerror10 @rohanmathur91 Do we specify fixed values like this?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, the code editor height is resizable by dragging so we need to specify a fixed minimum height for the code editor.

box-shadow: none;
height: 100%;

align-self: center;
Copy link
Contributor

Choose a reason for hiding this comment

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

@RuntimeTerror10 -- I am leaving all the CSS and UI code changes to you.

if (script.type === RQ.SCRIPT_TYPES.URL) {
RQ.ClientUtils.addRemoteJS(script.value, callback);
if (script.attributes) {
RQ.ScriptRuleHandler.addRemoteJSWithAttributes(script.value, script.attributes, callback);
Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't create a separate function but instead just pass the attributes and the addRemoteJS function should check if there are attributes then add them otherwise not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated this in a separate PR to make it easy for @nafees87n to also review it - #1400

@@ -17,3 +17,7 @@
border-bottom-left-radius: var(--border-radius-sm);
border-bottom-right-radius: var(--border-radius-sm);
}

.code-editor-small {
max-height: 72px;
Copy link
Member

Choose a reason for hiding this comment

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

Please remove this class as this is not being used

@@ -55,6 +55,8 @@ const RuleBuilder = (props) => {
const currentlySelectedRuleData = useSelector(getCurrentlySelectedRuleData);
const currentlySelectedRuleConfig = useSelector(getCurrentlySelectedRuleConfig);

console.log("currentlySelectedRuleData", currentlySelectedRuleData);
Copy link
Member

Choose a reason for hiding this comment

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

Remove this log

Comment on lines 149 to 154
const handleCodeFormattedFlag = () => {
setIsCodeFormatted(true);
setTimeout(() => {
setIsCodeFormatted(false);
}, 2000);
};
Copy link
Member

Choose a reason for hiding this comment

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

This function is duplicated inside renderCodeEditor also.

Comment on lines 135 to 136
const renderURLInput = () => {
const renderCodeEditorForScriptAttributes = () => {
Copy link
Member

Choose a reason for hiding this comment

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

Can be very confusing.
renderCodeEditorForScriptAttributes inside renderURLInput.
Can we have a common code editor component which can be wrapper for CodeEditor pass props accordingly for script and url type code editor.
This will also remove code duplication in both editor render functions

@wrongsahil wrongsahil merged commit 7e64ba3 into master Feb 12, 2024
1 check passed
@wrongsahil wrongsahil deleted the RQ-1256-core-schema-updates branch February 12, 2024 17:54
@nsrCodes nsrCodes restored the RQ-1256-core-schema-updates branch February 12, 2024 19:31
@nsrCodes nsrCodes deleted the RQ-1256-core-schema-updates branch February 12, 2024 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants