@hyperframes/lint 0.8.22 → 0.8.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +41 -0
- package/dist/browser.js.map +1 -1
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2941,6 +2941,47 @@ ${other.raw}`)
|
|
|
2941
2941
|
}
|
|
2942
2942
|
return findings;
|
|
2943
2943
|
},
|
|
2944
|
+
// gsap_timeline_return_used_as_tween — `tl.to()` returns the TIMELINE, not the tween it just
|
|
2945
|
+
// created. `gsap.to()` returns a Tween, so the two read identically and behave nothing alike.
|
|
2946
|
+
// Capturing the timeline's return and later treating it as an individual animation aims a
|
|
2947
|
+
// tween-scoped call at the whole composition: `.kill()` on it interrupts the master timeline
|
|
2948
|
+
// and detaches it from its parent, which stops a parent-driven seek dead while leaving an
|
|
2949
|
+
// explicit `tl.progress()` still working -- so a render of the packaged defaults looks fine
|
|
2950
|
+
// and only live playback breaks. A rebuild that collected these to discard them also leaves
|
|
2951
|
+
// every previous keyframe in place and stacks the new ones on top.
|
|
2952
|
+
({ scripts }) => {
|
|
2953
|
+
const findings = [];
|
|
2954
|
+
for (const script of scripts) {
|
|
2955
|
+
const source = stripJsComments(script.content);
|
|
2956
|
+
const timelineVars = collectTimelineVarNames(source);
|
|
2957
|
+
if (timelineVars.length === 0) continue;
|
|
2958
|
+
const receivers = timelineVars.map(escapeRegExp2).join("|");
|
|
2959
|
+
const pattern = new RegExp(
|
|
2960
|
+
String.raw`(?:\.push\s*\(\s*|(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*)(?:${receivers})\s*\.\s*(to|from|fromTo|set|call|add)\s*\(`,
|
|
2961
|
+
"g"
|
|
2962
|
+
);
|
|
2963
|
+
let match;
|
|
2964
|
+
while ((match = pattern.exec(source)) !== null) {
|
|
2965
|
+
const boundName = match[1];
|
|
2966
|
+
const method = match[2];
|
|
2967
|
+
if (boundName) {
|
|
2968
|
+
const treatedAsTween = new RegExp(
|
|
2969
|
+
String.raw`\b${escapeRegExp2(boundName)}\s*\.\s*(?:kill|revert|invalidate|pause|resume|restart|seek|progress|timeScale)\s*\(`
|
|
2970
|
+
);
|
|
2971
|
+
if (!treatedAsTween.test(source)) continue;
|
|
2972
|
+
}
|
|
2973
|
+
const contextStart = Math.max(0, match.index - 40);
|
|
2974
|
+
findings.push({
|
|
2975
|
+
code: "gsap_timeline_return_used_as_tween",
|
|
2976
|
+
severity: "error",
|
|
2977
|
+
message: `\`${match[0].includes(".push") ? "push" : boundName}\` captures the return of \`.${method}()\` on timeline \`${timelineVars[0]}\`, but a timeline's \`.to()\`/\`.from()\`/\`.set()\` returns THE TIMELINE ITSELF, not the tween it created. Every captured value is the same master timeline, so a tween-scoped call on it \u2014 \`.kill()\` above all \u2014 hits the whole composition: it interrupts the timeline and detaches it from its parent, which freezes a parent-driven seek while an explicit \`tl.progress()\` keeps working. Only \`gsap.to()\` returns a tween.`,
|
|
2978
|
+
fixHint: "To build a group of keyframes you can later discard, put them in a nested timeline: `const nested = gsap.timeline(); nested.to(...); tl.add(nested, 0);` \u2014 then `nested.kill()` replaces exactly those keyframes and cannot reach `tl`. Children keep their absolute times when the nest is added at 0. To hold a single real tween, create it with `gsap.to(...)` and place it with `tl.add(tween, at)`.",
|
|
2979
|
+
snippet: truncateSnippet(source.slice(contextStart, match.index + match[0].length + 60))
|
|
2980
|
+
});
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
return findings;
|
|
2984
|
+
},
|
|
2944
2985
|
// gsap_group_selector_keyframes
|
|
2945
2986
|
({ scripts }) => {
|
|
2946
2987
|
const findings = [];
|