| Total Complexity | 32 |
| Complexity/F | 1.68 |
| Lines of Code | 168 |
| Function Count | 19 |
| Duplicated Lines | 0 |
| Ratio | 0 % |
| Changes | 3 | ||
| Bugs | 1 | Features | 0 |
| 1 | function PageAnalyzer(cont, url){ |
||
| 2 | $ = jQuery; |
||
| 3 | |||
| 4 | this.cont = cont; |
||
| 5 | this.url = url; |
||
| 6 | this.data = {'desktop': undefined, 'mobile': undefined}; |
||
| 7 | this.preview = {'desktop': undefined, 'mobile': undefined}; |
||
| 8 | |||
| 9 | this.create_google_preview = function(agent){ |
||
| 10 | this.preview[agent] = $('<div class="search_snippet"></div>') |
||
| 11 | .append('<div class="g gtitle"></div><div class="g gurl"></div><div class="g gdesc"></div>'); |
||
| 12 | return this.preview[agent]; |
||
| 13 | }; |
||
| 14 | |||
| 15 | this.meta_data_handler = function(){ |
||
| 16 | var self = this; |
||
| 17 | |||
| 18 | $('#Form_EditForm_Title, #Form_EditForm_MetaTitle, #Form_EditForm_MetaDescription, input[name="URLSegment"]').change(function(){ |
||
| 19 | var title = $('#Form_EditForm_MetaTitle').val() || $('#Form_EditForm_Title').val(), |
||
| 20 | url = $('input[name="URLSegment"]').attr('data-prefix') + self.url, |
||
| 21 | desc = $('#Form_EditForm_MetaDescription').val(); |
||
| 22 | |||
| 23 | for(var agent in self.preview){ |
||
|
1 ignored issue
–
show
|
|||
| 24 | self.preview[agent].find('.gtitle').html(title); |
||
| 25 | self.preview[agent].find('.gurl').html(self.truncate(url, 115)); |
||
| 26 | self.preview[agent].find('.gdesc').html(self.truncate(desc, (agent) == 'mobile' ? 120 : 156)); |
||
| 27 | } |
||
| 28 | }); |
||
| 29 | |||
| 30 | $('#Form_EditForm_Title').trigger('change'); |
||
| 31 | }; |
||
| 32 | |||
| 33 | this.truncate = function(text, limit){ |
||
|
1 ignored issue
–
show
|
|||
| 34 | return (text.length > limit) ? text.substr(0, limit-2) + '...' : text; |
||
| 35 | }, |
||
| 36 | |||
| 37 | this.add_result_label = function(title, test, text_true, text_false){ |
||
| 38 | var span = '<span class="'+(test ? 'green' : 'red')+'">'+(test ? text_true : text_false)+'</span>'; |
||
| 39 | return '<div><p><strong>'+title+'</strong>'+span+'</p>'; |
||
| 40 | }; |
||
| 41 | |||
| 42 | this.calculate_keyword_density = function(phrases, keyword, word_count){ |
||
| 43 | var count = 0; |
||
| 44 | for(var phrase in phrases) if( phrases[phrase].indexOf(keyword.toLowerCase()) >= 0) count ++; |
||
|
2 ignored issues
–
show
|
|||
| 45 | return (((count / word_count) * 100) / keyword.split(' ').length).toFixed(2); |
||
| 46 | }; |
||
| 47 | |||
| 48 | this.get_word_count = function(phrases){ |
||
| 49 | var count = 0; |
||
| 50 | for(var phrase in phrases) count += phrases[phrase].split(' ').length; |
||
|
2 ignored issues
–
show
|
|||
| 51 | return count; |
||
| 52 | }; |
||
| 53 | |||
| 54 | this.create_other_tests_box = function(data, cont){ |
||
| 55 | var html = $(data['body']), |
||
| 56 | h1_count = html.find('h1').length, |
||
| 57 | h2_count = html.find('h2').length, |
||
| 58 | word_count = this.get_word_count(data['field_data']['3']), |
||
| 59 | missing_alt_count = this.get_missing_alt_count(html); |
||
| 60 | |||
| 61 | cont |
||
| 62 | .append(this.add_result_label('H1 count', h1_count == 1, '1', h1_count)) |
||
| 63 | .append(this.add_result_label('H2 count', h2_count == 1, '1', h2_count)) |
||
| 64 | .append(this.add_result_label('Article Word Count', word_count >= 700, word_count, word_count)) |
||
| 65 | .append(this.add_result_label('Images missing alt tag', missing_alt_count <= 0, 0, missing_alt_count)); |
||
| 66 | |||
| 67 | }; |
||
| 68 | |||
| 69 | this.get_missing_alt_count = function(html){ |
||
| 70 | var count = 0; |
||
| 71 | $.each( html.find( 'img' ), function(){ if( !$(this).attr( 'alt' ) ) count++; }); |
||
|
1 ignored issue
–
show
|
|||
| 72 | return count; |
||
| 73 | }; |
||
| 74 | |||
| 75 | this.create_layout = function(title, extraCSS){ |
||
| 76 | extraCSS = (extraCSS) ? extraCSS : ''; |
||
| 77 | return $('<div class="result_side_cont '+title.toLowerCase()+' '+extraCSS+'"></div>') |
||
| 78 | .append($('<h3>'+title+'</h3>')) |
||
| 79 | .append($('<div class="field text"></div>')); |
||
| 80 | }; |
||
| 81 | |||
| 82 | this.create_keyword_search_box = function(){ |
||
| 83 | var self = this, |
||
| 84 | agents = ['desktop', 'mobile'], |
||
| 85 | keyword_box = $('<div class="field text"></div>'), |
||
| 86 | middle_col = $('<div class="keyword_search"></div>').appendTo(keyword_box), |
||
| 87 | text_box = $('<input type="text" class="text" />').appendTo(middle_col), |
||
| 88 | analyze_btn = $('<button class="ss-ui-button ss-ui-button-medium">Analyze</button>').appendTo(middle_col); |
||
| 89 | |||
| 90 | analyze_btn.click(function(){ |
||
| 91 | if( self.data['desktop'] === undefined || self.data['mobile'] === undefined ) return true; |
||
|
1 ignored issue
–
show
|
|||
| 92 | |||
| 93 | $('.keyword_result').remove(); |
||
| 94 | |||
| 95 | for(var i in agents){ |
||
|
1 ignored issue
–
show
|
|||
| 96 | var data = self.data[agents[i]], |
||
| 97 | layout = self.create_layout(agents[i].capitalize()).addClass('keyword_result'), |
||
| 98 | results_box = layout.find('.field.text'), |
||
| 99 | keyword = text_box.val(), |
||
| 100 | html = $(data['body']), |
||
| 101 | in_h1 = html.find("h1:containsi('"+keyword+"')").length > 0, |
||
| 102 | first_p_with_keyword = html.find("p:containsi('"+keyword+"')").first(), |
||
| 103 | first_p_tag = html.find('p').first(), |
||
| 104 | in_first_paragraph = first_p_tag.html() == first_p_with_keyword.html(), |
||
| 105 | word_count = self.get_word_count(data['phrases']), |
||
| 106 | density = self.calculate_keyword_density(data['phrases'], keyword, word_count); |
||
| 107 | |||
| 108 | results_box |
||
| 109 | .append(self.add_result_label('Keyword in h1', in_h1, 'Yes', 'No')) |
||
| 110 | .append(self.add_result_label('Keyword in first p tag', in_first_paragraph, 'Yes', 'No')) |
||
| 111 | .append(self.add_result_label('Word Count', true, word_count, '')) |
||
| 112 | .append(self.add_result_label('Keyword Density', true, density+'%', '')); |
||
| 113 | |||
| 114 | self.cont.append(layout); |
||
| 115 | } |
||
| 116 | }); |
||
| 117 | |||
| 118 | return keyword_box; |
||
| 119 | }; |
||
| 120 | |||
| 121 | this.init = function(){ |
||
| 122 | // Google Preview Section |
||
| 123 | this.cont.append('<h2>Google Preview</h2>'); |
||
| 124 | var preview_d = this.create_layout('Desktop', 'google').appendTo(this.cont), |
||
| 125 | preview_m = this.create_layout('Mobile', 'google').appendTo(this.cont); |
||
| 126 | preview_d.find('.field.text').append(this.create_google_preview('desktop')); |
||
| 127 | preview_m.find('.field.text').append(this.create_google_preview('mobile')); |
||
| 128 | this.meta_data_handler(); |
||
| 129 | |||
| 130 | // Tests Section |
||
| 131 | this.cont.append('<h2>SEO Tests</h2>'); |
||
| 132 | var tests_d = this.create_layout('Desktop').appendTo(this.cont), |
||
| 133 | tests_m = this.create_layout('Mobile').appendTo(this.cont); |
||
| 134 | |||
| 135 | // Keywords Section |
||
| 136 | this.cont.append('<h2>Keywords Analyzer</h2>'); |
||
| 137 | this.cont.append(this.create_keyword_search_box()); |
||
| 138 | |||
| 139 | this.send_ajax('mobile', tests_m.find('.field.text')); |
||
| 140 | this.send_ajax('desktop', tests_d.find('.field.text')); |
||
| 141 | }; |
||
| 142 | |||
| 143 | this.send_ajax = function(agent, cont){ |
||
| 144 | var self = this; |
||
| 145 | $.ajax({ |
||
| 146 | dataType: 'json', |
||
| 147 | data: {'u': self.url, 'agent': agent}, |
||
| 148 | url: location.protocol + '//' + location.hostname + '/seotest/getPageData', |
||
| 149 | success: function (data) { |
||
| 150 | self.data[agent] = data; |
||
| 151 | self.create_other_tests_box(data, cont); |
||
| 152 | } |
||
| 153 | }); |
||
| 154 | }; |
||
| 155 | |||
| 156 | this.init(); |
||
| 157 | } |
||
| 158 | |||
| 159 | // Add a case insensitive version of the contains function |
||
| 160 | jQuery.extend(jQuery.expr[':'], { |
||
| 161 | 'containsi': function(elem, i, match, array){ |
||
| 162 | return (elem.textContent || elem.innerText || '').toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0; |
||
| 163 | } |
||
| 164 | }); |
||
| 165 | |||
| 166 | String.prototype.capitalize = function() { |
||
|
1 ignored issue
–
show
|
|||
| 167 | return this.charAt(0).toUpperCase() + this.slice(1); |
||
| 168 | }; |
||
| 169 |
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: