Passed
Branch develop (8dc305)
by M. Mikkel
06:28
created

src/resources/cpfieldinspect.js   B

Complexity

Total Complexity 46
Complexity/F 2.09

Size

Lines of Code 222
Function Count 22

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 145
c 0
b 0
f 0
dl 0
loc 222
rs 8.72
wmc 46
mnd 24
bc 24
fnc 22
bpm 1.0909
cpm 2.0909
noi 18

1 Function

Rating   Name   Duplication   Size   Complexity  
B cpfieldinspect.js ➔ getLivePreview 0 8 6

How to fix   Complexity   

Complexity

Complex classes like src/resources/cpfieldinspect.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
(function (window) {
2
3
    if (!window.Craft || !window.$) {
4
        return false;
5
    }
6
7
    Craft.CpFieldInspectPlugin = {
0 ignored issues
show
Bug introduced by
The variable Craft seems to be never declared. If this is a global, consider adding a /** global: Craft */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
8
        elementEditors: {},
9
        settings: {
10
            settingsClassSelector: 'cp-field-inspect-settings',
11
            infoClassSelector: 'cp-field-inspect-info',
12
            redirectKey: '_CpFieldInspectRedirectTo',
13
            actionInputKeys: [
14
                '[value="fields/save-field"]',
15
                '[value="sections/save-entry-type"]',
16
                '[value="globals/save-set"]',
17
                '[value="categories/save-group"]',
18
                '[value="volumes/save-volume"]',
19
                '[value="commerce/product-types/save-product-type"]'
20
            ]
21
        },
22
        init: function (data) {
23
24
            var _this = this;
25
26
            this.data = data;
27
            this.setPathAndRedirect();
28
29
            // Initialize Live Preview support
30
            var now = new Date().getTime(),
31
                livePreviewPoller = (function getLivePreview() {
32
                    if (Craft.livePreview) {
0 ignored issues
show
Bug introduced by
The variable Craft seems to be never declared. If this is a global, consider adding a /** global: Craft */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
33
                        Craft.livePreview.on('enter', this.onLivePreviewEnter.bind(this));
34
                        Craft.livePreview.on('exit', this.onLivePreviewExit.bind(this));
35
                    } else if (new Date().getTime() - now < 2000) {
36
                        Garnish.requestAnimationFrame(livePreviewPoller);
0 ignored issues
show
Bug introduced by
The variable Garnish seems to be never declared. If this is a global, consider adding a /** global: Garnish */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
37
                    }
38
                }).bind(this);
39
40
            livePreviewPoller();
41
42
            // Poll for address bar change
43
            var url = window.location.href;
44
            this.addressBarChangeInterval = setInterval(function () {
45
                var newUrl = window.location.href;
46
                if (newUrl === url) {
47
                    return;
48
                }
49
                url = newUrl;
50
                try {
51
                    Craft.postActionRequest('cp-field-inspect/default/get-redirect-hash', { url: url }, $.proxy(function (response) {
0 ignored issues
show
Bug introduced by
The variable Craft seems to be never declared. If this is a global, consider adding a /** global: Craft */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
52
                        this.data.redirectUrl = response.data || this.data.redirectUrl || null;
53
                    }, _this));
54
                } catch (error) {
55
                    console.error(error);
56
                }
57
            }, 100);
58
59
            // Add event handlers
60
            Garnish.$doc
0 ignored issues
show
Bug introduced by
The variable Garnish seems to be never declared. If this is a global, consider adding a /** global: Garnish */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
61
                .on('click', '[data-cpfieldlinks-sourcebtn]', $.proxy(this.onSourceEditBtnClick, this))
62
                .on('click', '.matrix .btn.add, .matrix .btn[data-type]', $.proxy(this.onMatrixBlockAddButtonClick, this))
63
                .ajaxComplete($.proxy(this.onAjaxComplete, this));
64
65
            Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
66
        },
67
68
        initElementEditor: function () {
69
            var now = new Date().getTime(),
70
                doInitElementEditor = $.proxy(function () {
71
                    var timestamp = new Date().getTime(),
72
                        $elementEditor = $('.elementeditor:last'),
73
                        $hud = $elementEditor.length > 0 ? $elementEditor.closest('.hud') : false,
74
                        elementEditor = $hud && $hud.length > 0 ? $hud.data('elementEditor') : false;
75
                    if (elementEditor && elementEditor.hud) {
76
                        this.elementEditors[elementEditor._namespace] = elementEditor;
77
                        elementEditor.hud.on('hide', $.proxy(this.destroyElementEditor, this, elementEditor));
78
                        Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
0 ignored issues
show
Bug introduced by
The variable Garnish seems to be never declared. If this is a global, consider adding a /** global: Garnish */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
79
                    } else if (timestamp - now < 2000) { // Poll for 2 secs
80
                        Garnish.requestAnimationFrame(doInitElementEditor);
81
                    }
82
                }, this);
83
            doInitElementEditor();
84
        },
85
86
        destroyElementEditor: function (elementEditor) {
87
            if (this.elementEditors.hasOwnProperty(elementEditor._namespace)) {
88
                delete this.elementEditors[elementEditor._namespace];
89
            }
90
        },
91
92
        setPathAndRedirect: function () {
93
            var redirectTo = Craft.getLocalStorage(this.settings.redirectKey);
0 ignored issues
show
Bug introduced by
The variable Craft seems to be never declared. If this is a global, consider adding a /** global: Craft */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
94
            if (redirectTo) {
95
                var $actionInput = $('input[type="hidden"][name="action"]').filter(this.settings.actionInputKeys.join(','));
96
                var $redirectInput = $('input[type="hidden"][name="redirect"]');
97
                if ($actionInput.length > 0 && $redirectInput.length > 0) {
98
                    $redirectInput.attr('value', redirectTo);
99
                }
100
            }
101
            Craft.setLocalStorage(this.settings.redirectKey, null);
102
        },
103
104
        addFieldLinks: function () {
105
            var self = this;
0 ignored issues
show
Unused Code introduced by
The variable self seems to be never used. Consider removing it.
Loading history...
106
            var targets = [$(this.getFieldContextSelector())];
107
            var $target;
108
109
            if (this.elementEditors && Object.keys(this.elementEditors).length) {
110
                for (var key in this.elementEditors) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
111
                    targets.push(this.elementEditors[key].$form);
112
                }
113
            }
114
115
            if (!targets.length) {
116
                return;
117
            }
118
119
            for (var i = 0; i < targets.length; ++i) {
120
121
                $target = targets[i];
122
                if (!$target || !$target.length) {
123
                    continue;
124
                }
125
126
                var _this = this;
127
128
                var $copyFieldHandleButtons = $target.find('.field .heading [id$=-field-attribute].code:not([data-cpfieldlinks-inited])');
129
                $copyFieldHandleButtons.each(function () {
130
131
                    var $btn = $(this);
132
                    $btn.attr('data-cpfieldlinks-inited', true);
133
134
                    var field = $btn.parents('.field').get().slice(-1).pop();
135
                    if (!field) {
136
                        return;
137
                    }
138
139
                    var fieldId = _this.getFieldId(field);
0 ignored issues
show
Bug introduced by
The variable _this is changed as part of the for loop for example by this on line 126. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
140
                    if (!fieldId) {
141
                        return;
142
                    }
143
144
                    $btn
145
                        .append('<span data-icon="settings" title="' + (_this.data.editFieldBtnLabel || 'Edit field settings') + '" />')
146
                        .on('click', '[data-icon="settings"]', function (e) {
147
                            e.preventDefault();
148
                            e.stopPropagation();
149
                            _this.redirectToFieldSettings(fieldId);
0 ignored issues
show
Bug introduced by
The variable _this is changed as part of the for loop for example by this on line 126. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
150
                        });
151
152
                }).on('mouseleave', function () {
153
                    $(this).blur();
154
                });
155
156
            }
157
        },
158
159
        doRedirect: function (href) {
160
            Craft.setLocalStorage(this.settings.redirectKey, this.data.redirectUrl || null);
0 ignored issues
show
Bug introduced by
The variable Craft seems to be never declared. If this is a global, consider adding a /** global: Craft */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
161
            window.location.href = href;
162
        },
163
164
        redirectToFieldSettings: function (fieldId) {
165
            var href = Craft.CpFieldInspectPlugin.data.baseEditFieldUrl + '/' + fieldId;
0 ignored issues
show
Bug introduced by
The variable Craft seems to be never declared. If this is a global, consider adding a /** global: Craft */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
166
            this.doRedirect(href);
167
        },
168
169
        getFieldId: function (field) {
170
            var id = $(field).attr('id');
171
            if (!id) {
172
                return null;
173
            }
174
            var segments = id.split('-');
175
            if (segments.length < 3) {
176
                return null;
177
            }
178
            var handle = segments[segments.length - 2];
179
            return (this.data.fields || {})[handle] || null;
180
        },
181
182
        getFieldContextSelector: function () {
183
            if (this.isLivePreview) {
184
                return '.lp-editor';
185
            }
186
            return '#main';
187
        },
188
189
        onLivePreviewEnter: function () {
190
            this.isLivePreview = true;
191
            Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
0 ignored issues
show
Bug introduced by
The variable Garnish seems to be never declared. If this is a global, consider adding a /** global: Garnish */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
192
        },
193
194
        onLivePreviewExit: function () {
195
            this.isLivePreview = false;
196
            Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
0 ignored issues
show
Bug introduced by
The variable Garnish seems to be never declared. If this is a global, consider adding a /** global: Garnish */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
197
        },
198
199
        onSourceEditBtnClick: function (e) {
200
            e.preventDefault();
201
            this.doRedirect(e.target.href);
202
        },
203
204
        onMatrixBlockAddButtonClick: function (e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
205
            Garnish.requestAnimationFrame($.proxy(this.addFieldLinks, this));
0 ignored issues
show
Bug introduced by
The variable Garnish seems to be never declared. If this is a global, consider adding a /** global: Garnish */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
206
        },
207
208
        onAjaxComplete: function(e, status, requestData) {
209
            if (requestData.url.indexOf('switch-entry-type') === -1) {
210
                return;
211
            }
212
            const $entryTypeSelect = $('#entryType');
213
            if ($entryTypeSelect.length) {
214
                const typeId = $entryTypeSelect.val();
215
                $('[data-cpfieldlinks-sourcebtn][data-typeid]:not([data-typeid="' + typeId + '"]').hide();
216
                $('[data-cpfieldlinks-sourcebtn][data-typeid="' + typeId + '"]').show();
217
            }
218
            this.addFieldLinks();
219
        }
220
    };
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
221
222
} (window));
223