/**
* JQUERY DEPRECATIONS - For JavaScript Files
* Deprecated jQuery methods and their modern replacements.
*/
export interface JQueryDeprecation {
method: string;
replacement: string;
reason: string;
example?: {
deprecated: string;
modern: string;
};
}
export const JQUERY_DEPRECATIONS: Record<string, JQueryDeprecation> = {
// === REMOVED IN JQUERY 3.0+ ===
'andSelf': {
method: '.andSelf()',
replacement: '.addBack()',
reason: 'Removed from jQuery - renamed to addBack()',
example: {
deprecated: '$("div").find("p").andSelf().addClass("highlight")',
modern: '$("div").find("p").addBack().addClass("highlight")'
}
},
'size': {
method: '.size()',
replacement: '.length property',
reason: 'Deprecated - use native .length property for better performance',
example: {
deprecated: 'var count = $("li").size();',
modern: 'var count = $("li").length;'
}
},
'trim': {
method: '$.trim()',
replacement: 'String.prototype.trim()',
reason: 'Use native JavaScript - better performance and no jQuery dependency',
example: {
deprecated: 'var trimmed = $.trim(str);',
modern: 'var trimmed = str.trim();'
}
},
// === EVENT HANDLING ===
'bind': {
method: '.bind()',
replacement: '.on()',
reason: 'Deprecated event binding - use .on() for consistency',
example: {
deprecated: '$("button").bind("click", handler);',
modern: '$("button").on("click", handler);'
}
},
'unbind': {
method: '.unbind()',
replacement: '.off()',
reason: 'Deprecated event unbinding - use .off() for consistency',
example: {
deprecated: '$("button").unbind("click", handler);',
modern: '$("button").off("click", handler);'
}
},
'delegate': {
method: '.delegate()',
replacement: '.on() with selector',
reason: 'Deprecated delegation - use .on() with selector parameter',
example: {
deprecated: '$("table").delegate("td", "click", handler);',
modern: '$("table").on("click", "td", handler);'
}
},
'undelegate': {
method: '.undelegate()',
replacement: '.off()',
reason: 'Deprecated delegation removal - use .off()',
example: {
deprecated: '$("table").undelegate("td", "click", handler);',
modern: '$("table").off("click", "td", handler);'
}
},
// === EVENT SHORTHANDS ===
'click_shorthand': {
method: '.click(fn)',
replacement: '.on("click", fn)',
reason: 'Event shorthand deprecated - use .on() for all event binding',
example: {
deprecated: '$("button").click(function() { ... });',
modern: '$("button").on("click", function() { ... });'
}
},
'blur_shorthand': {
method: '.blur(fn)',
replacement: '.on("blur", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("input").blur(function() { ... });',
modern: '$("input").on("blur", function() { ... });'
}
},
'focus_shorthand': {
method: '.focus(fn)',
replacement: '.on("focus", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("input").focus(function() { ... });',
modern: '$("input").on("focus", function() { ... });'
}
},
'load_shorthand': {
method: '.load(fn)',
replacement: '.on("load", fn)',
reason: 'Event shorthand deprecated and potentially confused with AJAX .load()',
example: {
deprecated: '$(window).load(function() { ... });',
modern: '$(window).on("load", function() { ... });'
}
},
'error_shorthand': {
method: '.error(fn)',
replacement: '.on("error", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("img").error(function() { ... });',
modern: '$("img").on("error", function() { ... });'
}
},
'keydown_shorthand': {
method: '.keydown(fn)',
replacement: '.on("keydown", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("input").keydown(function() { ... });',
modern: '$("input").on("keydown", function() { ... });'
}
},
'keyup_shorthand': {
method: '.keyup(fn)',
replacement: '.on("keyup", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("input").keyup(function() { ... });',
modern: '$("input").on("keyup", function() { ... });'
}
},
'keypress_shorthand': {
method: '.keypress(fn)',
replacement: '.on("keypress", fn) or better .on("keydown", fn)',
reason: 'Event shorthand deprecated, keypress itself is deprecated',
example: {
deprecated: '$("input").keypress(function() { ... });',
modern: '$("input").on("keydown", function() { ... });'
}
},
'mouseenter_shorthand': {
method: '.mouseenter(fn)',
replacement: '.on("mouseenter", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("div").mouseenter(function() { ... });',
modern: '$("div").on("mouseenter", function() { ... });'
}
},
'mouseleave_shorthand': {
method: '.mouseleave(fn)',
replacement: '.on("mouseleave", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("div").mouseleave(function() { ... });',
modern: '$("div").on("mouseleave", function() { ... });'
}
},
'submit_shorthand': {
method: '.submit(fn)',
replacement: '.on("submit", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("form").submit(function() { ... });',
modern: '$("form").on("submit", function() { ... });'
}
},
'change_shorthand': {
method: '.change(fn)',
replacement: '.on("change", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("select").change(function() { ... });',
modern: '$("select").on("change", function() { ... });'
}
},
// === DEPRECATED EXPRESSIONS ===
'deprecated_expr': {
method: 'Deprecated selectors (:eq, :first, :last, etc.)',
replacement: 'Use CSS selectors or .eq(), .first(), .last() methods',
reason: 'jQuery-specific selectors are slower and deprecated',
example: {
deprecated: '$("li:first")',
modern: '$("li").first() or $("li:first-child")'
}
},
// === MORE EVENT SHORTHANDS ===
'focusin_shorthand': {
method: '.focusin(fn)',
replacement: '.on("focusin", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("input").focusin(function() { ... });',
modern: '$("input").on("focusin", function() { ... });'
}
},
'focusout_shorthand': {
method: '.focusout(fn)',
replacement: '.on("focusout", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("input").focusout(function() { ... });',
modern: '$("input").on("focusout", function() { ... });'
}
},
'dblclick_shorthand': {
method: '.dblclick(fn)',
replacement: '.on("dblclick", fn)',
reason: 'Event shorthand deprecated',
example: {
deprecated: '$("button").dblclick(function() { ... });',
modern: '$("button").on("dblclick", function() { ... });'
}
},
'hover_shorthand': {
method: '.hover(fnIn, fnOut)',
replacement: '.on("mouseenter", fnIn).on("mouseleave", fnOut)',
reason: 'Event shorthand deprecated - use separate mouseenter/mouseleave',
example: {
deprecated: '$("div").hover(fnIn, fnOut);',
modern: '$("div").on("mouseenter", fnIn).on("mouseleave", fnOut);'
}
},
// === UTILITY METHODS ===
'isFunction': {
method: '$.isFunction()',
replacement: 'typeof fn === "function"',
reason: 'Deprecated - use native typeof check',
example: {
deprecated: 'if ($.isFunction(callback)) { ... }',
modern: 'if (typeof callback === "function") { ... }'
}
},
'type': {
method: '$.type()',
replacement: 'typeof operator or Object.prototype.toString',
reason: 'Deprecated - use native type checking',
example: {
deprecated: 'var type = $.type(obj);',
modern: 'var type = typeof obj;'
}
},
'isArray': {
method: '$.isArray()',
replacement: 'Array.isArray()',
reason: 'Deprecated - use native Array.isArray',
example: {
deprecated: 'if ($.isArray(arr)) { ... }',
modern: 'if (Array.isArray(arr)) { ... }'
}
},
'parseJSON': {
method: '$.parseJSON()',
replacement: 'JSON.parse()',
reason: 'Deprecated - use native JSON.parse',
example: {
deprecated: 'var data = $.parseJSON(jsonStr);',
modern: 'var data = JSON.parse(jsonStr);'
}
},
'isNumeric': {
method: '$.isNumeric()',
replacement: 'typeof n === "number" || !isNaN(parseFloat(n))',
reason: 'Deprecated - use native number checking',
example: {
deprecated: 'if ($.isNumeric(val)) { ... }',
modern: 'if (!isNaN(parseFloat(val)) && isFinite(val)) { ... }'
}
},
// === MISCELLANEOUS ===
'ready_shorthand': {
method: '$(fn) or $().ready(fn)',
replacement: '$(function() { }) or $(document).ready(fn)',
reason: 'While still supported, explicit syntax is clearer',
example: {
deprecated: '$(function() { ... });',
modern: '$(document).ready(function() { ... }); // or use DOMContentLoaded'
}
},
};
/**
* RequireJS/AMD patterns for Magento
*/
export const MAGENTO_JS_PATTERNS = {
requirejs_module: `define([
'jquery',
'mage/translate'
], function ($, $t) {
'use strict';
return function (config, element) {
$(element).on('click', function () {
// Use $.mage methods for Magento-specific functionality
});
};
});`,
uiComponent: `define([
'uiComponent',
'ko'
], function (Component, ko) {
'use strict';
return Component.extend({
defaults: {
template: 'Vendor_Module/component'
},
initialize: function () {
this._super();
return this;
}
});
});`,
widget: `define([
'jquery',
'jquery/ui'
], function ($) {
'use strict';
$.widget('vendor.widgetName', {
options: {
setting: 'default'
},
_create: function () {
this._on({
'click': this._onClick
});
},
_onClick: function (event) {
// Handle click
}
});
return $.vendor.widgetName;
});`
};
/**
* Check code for jQuery deprecations
*/
export function checkForJQueryDeprecations(code: string): JQueryDeprecation[] {
const found: JQueryDeprecation[] = [];
const patterns: Array<[RegExp, string]> = [
[/\.bind\s*\(/, 'bind'],
[/\.unbind\s*\(/, 'unbind'],
[/\.delegate\s*\(/, 'delegate'],
[/\.undelegate\s*\(/, 'undelegate'],
[/\.size\s*\(\s*\)/, 'size'],
[/\$\.trim\s*\(/, 'trim'],
[/\.andSelf\s*\(/, 'andSelf'],
[/\$\.isFunction\s*\(/, 'isFunction'],
[/\$\.type\s*\(/, 'type'],
[/\$\.isArray\s*\(/, 'isArray'],
[/\$\.parseJSON\s*\(/, 'parseJSON'],
[/\$\.isNumeric\s*\(/, 'isNumeric'],
[/\.live\s*\(/, 'bind'], // .live() was removed even earlier
[/\.die\s*\(/, 'unbind'], // .die() was removed even earlier
];
for (const [regex, key] of patterns) {
if (regex.test(code) && JQUERY_DEPRECATIONS[key]) {
found.push(JQUERY_DEPRECATIONS[key]);
}
}
return found;
}