Version Description
Download this release
Release Info
Developer | boldgrid |
Plugin | BoldGrid Easy SEO – Simple and Effective SEO |
Version | 1.6.0-rc.1 |
Comparing to | |
See all releases |
Code changes from version 1.5.1 to 1.6.0-rc.1
- assets/js/bgseo.js +423 -159
- assets/js/bgseo.min.js +1 -1
- assets/js/bgseo/boldgrid-seo-editor.js +164 -0
- assets/js/bgseo/boldgrid-seo-gutenberg.js +115 -0
- assets/js/bgseo/boldgrid-seo-headings.js +5 -4
- assets/js/bgseo/boldgrid-seo-keywords.js +4 -6
- assets/js/bgseo/boldgrid-seo-report.js +17 -23
- assets/js/bgseo/boldgrid-seo-tinymce.js +65 -96
- assets/js/bgseo/boldgrid-seo-wordcount.js +52 -31
- assets/js/text-statistics/README.md +2 -4
- assets/js/text-statistics/index.js +15 -17
- boldgrid-easy-seo.php +2 -2
- includes/class-boldgrid-seo-butterbean.php +9 -3
- includes/configs/i18n/seoDescription.config.php +3 -3
- includes/configs/meta-box.config.php +1 -1
- languages/bgseo.pot +4 -4
- readme.txt +10 -2
assets/js/bgseo.js
CHANGED
@@ -481,48 +481,69 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
481 |
|
482 |
( function( $, counter ) {
|
483 |
|
484 |
-
|
485 |
-
|
486 |
-
var $content = $( '#content' ),
|
487 |
-
$count = $( '#wp-word-count' ).find( '.word-count' ),
|
488 |
-
prevCount = 0,
|
489 |
-
contentEditor,
|
490 |
-
words;
|
491 |
|
492 |
-
|
493 |
-
var text, count;
|
494 |
|
495 |
-
|
496 |
-
text = $content.val();
|
497 |
-
} else {
|
498 |
-
text = contentEditor.getContent( { format: 'raw' } );
|
499 |
-
}
|
500 |
|
501 |
-
|
502 |
-
|
|
|
|
|
|
|
|
|
503 |
|
504 |
-
|
505 |
-
|
506 |
-
|
|
|
|
|
|
|
|
|
|
|
507 |
|
508 |
-
|
509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
510 |
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
|
|
|
|
|
|
|
|
515 |
|
516 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
517 |
|
518 |
-
|
519 |
-
|
520 |
|
521 |
-
|
|
|
|
|
522 |
|
523 |
-
|
|
|
|
|
|
|
524 |
|
525 |
-
|
526 |
|
527 |
} )( jQuery, new wp.utils.WordCounter() );
|
528 |
|
@@ -643,10 +664,9 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
643 |
|
644 |
'use strict';
|
645 |
|
646 |
-
var self,
|
647 |
|
648 |
api = BOLDGRID.SEO;
|
649 |
-
report = api.report;
|
650 |
|
651 |
/**
|
652 |
* BoldGrid TinyMCE Analysis.
|
@@ -660,42 +680,32 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
660 |
api.TinyMCE = {
|
661 |
|
662 |
/**
|
663 |
-
*
|
664 |
*
|
665 |
-
* @since 1.
|
|
|
|
|
666 |
*/
|
667 |
-
|
668 |
-
self.onloadContent();
|
669 |
-
$( document ).ready( function() {
|
670 |
-
self.editorChange();
|
671 |
-
});
|
672 |
-
},
|
673 |
|
674 |
/**
|
675 |
-
*
|
676 |
*
|
677 |
-
*
|
678 |
-
* initial page load ( text editor or visual editor ), and also
|
679 |
-
* is responsible for creating the iframe preview of the page/post
|
680 |
-
* so we can get the raw html in use by the template/theme the user
|
681 |
-
* has activated.
|
682 |
*
|
683 |
-
* @
|
684 |
*/
|
685 |
-
|
686 |
-
var text,
|
687 |
-
editor = $( '#content.wp-editor-area[aria-hidden=false]' );
|
688 |
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
});
|
699 |
});
|
700 |
},
|
701 |
|
@@ -708,11 +718,11 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
708 |
*/
|
709 |
getContent : function() {
|
710 |
var content;
|
711 |
-
|
712 |
if ( tinymce.ActiveEditor ) {
|
713 |
content = tinyMCE.get( wpActiveEditor ).getContent();
|
714 |
} else {
|
715 |
-
content =
|
716 |
// Remove newlines and carriage returns.
|
717 |
content = content.replace( /\r?\n|\r/g, '' );
|
718 |
}
|
@@ -722,64 +732,33 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
722 |
// Stores raw and stripped down versions of the content for analysis.
|
723 |
content = {
|
724 |
'raw': rawContent,
|
725 |
-
'text':
|
726 |
};
|
727 |
|
728 |
return content;
|
729 |
},
|
730 |
|
|
|
731 |
/**
|
732 |
-
*
|
733 |
-
* impacts "New" page and posts. To counter
|
734 |
-
* this we will disable the checks made until the content has had
|
735 |
-
* a chance to be updated. We will store the found headings minus
|
736 |
-
* the initial found headings in the content, so we know what the
|
737 |
-
* template has in use on the actual rendered page.
|
738 |
*
|
739 |
-
* @since 1.
|
740 |
*
|
741 |
-
* @
|
742 |
*/
|
743 |
-
|
744 |
-
var
|
745 |
-
|
746 |
-
// Get the preview url from WordPress.
|
747 |
-
preview = $( '#preview-action > .preview.button' ).attr( 'href' );
|
748 |
-
|
749 |
-
if ( $( '#sample-permalink' ).length ) {
|
750 |
-
// Only run this once after the initial iframe has loaded to get current template stats.
|
751 |
-
$.get( preview, function( renderedTemplate ) {
|
752 |
-
var headings, h1, h2, $rendered;
|
753 |
-
|
754 |
-
// The rendered page content.
|
755 |
-
$rendered = $( renderedTemplate );
|
756 |
-
|
757 |
-
// H1's that appear in rendered content.
|
758 |
-
h1 = $rendered.find( 'h1' );
|
759 |
-
// HS's that appear in rendered content.
|
760 |
-
h2 = $rendered.find( 'h2' );
|
761 |
-
|
762 |
-
// The rendered content stats.
|
763 |
-
renderedContent = {
|
764 |
-
h1Count : h1.length - report.rawstatistics.h1Count,
|
765 |
-
h1text : _.filter( api.Headings.getHeadingText( h1 ), function( obj ){
|
766 |
-
return ! _.findWhere( report.rawstatistics.h1text, obj );
|
767 |
-
}),
|
768 |
-
h2Count : h2.length - report.rawstatistics.h2Count,
|
769 |
-
h2text : _.filter( api.Headings.getHeadingText( h2 ), function( obj ){
|
770 |
-
return ! _.findWhere( report.rawstatistics.h2text, obj );
|
771 |
-
}),
|
772 |
-
};
|
773 |
-
|
774 |
-
// Add the rendered stats to our report for use later.
|
775 |
-
_.extend( report, { rendered : renderedContent } );
|
776 |
-
|
777 |
-
// Trigger the SEO report to rebuild in the template after initial stats are created.
|
778 |
-
$( '#content' ).trigger( 'bgseo-analysis', [ self.getContent() ] );
|
779 |
|
780 |
-
|
|
|
|
|
|
|
781 |
}
|
|
|
|
|
782 |
},
|
|
|
783 |
/**
|
784 |
* Listens for changes made in the text editor mode.
|
785 |
*
|
@@ -813,6 +792,17 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
813 |
return text;
|
814 |
},
|
815 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
816 |
/**
|
817 |
* Checks which editor is the active editor.
|
818 |
*
|
@@ -833,7 +823,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
833 |
text = tinyMCE.get( wpActiveEditor ).getContent();
|
834 |
break;
|
835 |
case 'content' :
|
836 |
-
text =
|
837 |
text = text.replace( /\r?\n|\r/g, '' );
|
838 |
break;
|
839 |
}
|
@@ -843,32 +833,32 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
843 |
|
844 |
text = {
|
845 |
'raw': rawText,
|
846 |
-
'text':
|
847 |
};
|
848 |
|
849 |
// Trigger the text analysis for report.
|
850 |
-
|
851 |
},
|
852 |
|
853 |
/**
|
854 |
-
*
|
855 |
-
*
|
856 |
-
* This is helpful in removing the remaining traces of HTML
|
857 |
-
* that is sometimes leftover to form our clean text output and
|
858 |
-
* run our text analysis on.
|
859 |
-
*
|
860 |
-
* @since 1.3.1
|
861 |
*
|
862 |
-
* @
|
863 |
*/
|
864 |
-
|
865 |
-
var
|
866 |
|
867 |
-
|
868 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
869 |
|
870 |
-
return tmp.textContent || tmp.innerText || " ";
|
871 |
-
},
|
872 |
};
|
873 |
|
874 |
self = api.TinyMCE;
|
@@ -1289,6 +1279,287 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
1289 |
|
1290 |
})( jQuery );
|
1291 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1292 |
( function ( $ ) {
|
1293 |
|
1294 |
'use strict';
|
@@ -1347,7 +1618,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
1347 |
_checkbox : function() {
|
1348 |
// Listen for changes to input value.
|
1349 |
self.settings.displayTitle.on( 'change', _.debounce( function() {
|
1350 |
-
$( this ).trigger( 'bgseo-analysis', [ api.
|
1351 |
}, 1000 ) );
|
1352 |
},
|
1353 |
|
@@ -1519,10 +1790,11 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
1519 |
},
|
1520 |
};
|
1521 |
|
1522 |
-
content = api.
|
|
|
1523 |
|
1524 |
-
h1s =
|
1525 |
-
h2s =
|
1526 |
|
1527 |
// If no h1s or h2s are found return the defaults.
|
1528 |
if ( ! h1s.length && ! h2s.length ) return headings;
|
@@ -1593,7 +1865,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
1593 |
getSettings : function() {
|
1594 |
self.settings = {
|
1595 |
keyword : $( '#bgseo-custom-keyword' ),
|
1596 |
-
content :
|
1597 |
};
|
1598 |
},
|
1599 |
|
@@ -1700,7 +1972,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
1700 |
keyword = keyword.toLowerCase();
|
1701 |
|
1702 |
keywordCount = self.keywordCount( content, keyword );
|
1703 |
-
wordCount = api.
|
1704 |
// Get the density.
|
1705 |
result = ( ( keywordCount / wordCount ) * 100 );
|
1706 |
// Round it off.
|
@@ -1818,7 +2090,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
1818 |
*/
|
1819 |
getKeyword : function() {
|
1820 |
var customKeyword,
|
1821 |
-
content = api.
|
1822 |
|
1823 |
if ( self.getCustomKeyword().length ) {
|
1824 |
customKeyword = self.getCustomKeyword();
|
@@ -1850,9 +2122,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
1850 |
var count;
|
1851 |
|
1852 |
if ( _.isUndefined( markup ) ) {
|
1853 |
-
markup =
|
1854 |
-
api.Words.words( self.settings.content.val() ) :
|
1855 |
-
api.Words.words( tinyMCE.activeEditor.getContent({ format : 'raw' }) );
|
1856 |
}
|
1857 |
|
1858 |
count = _.modifyObject( _bgseoContentAnalysis.keywords.recommendedCount, function( item ) {
|
@@ -2263,7 +2533,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2263 |
report = api.report;
|
2264 |
|
2265 |
/**
|
2266 |
-
* BoldGrid
|
2267 |
*
|
2268 |
* This is responsible for generating the actual reports
|
2269 |
* displayed within the BoldGrid SEO Dashboard when the user
|
@@ -2274,7 +2544,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2274 |
api.Report = {
|
2275 |
|
2276 |
/**
|
2277 |
-
* Initialize
|
2278 |
*
|
2279 |
* @since 1.3.1
|
2280 |
*/
|
@@ -2300,16 +2570,10 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2300 |
getSettings : function() {
|
2301 |
self.settings = {
|
2302 |
title : $( '#boldgrid-seo-field-meta_title' ),
|
2303 |
-
description : $( '#boldgrid-seo-field-meta_description' )
|
2304 |
-
wordCounter : $( '#wp-word-count .word-count' ),
|
2305 |
-
content : $( '#content' ),
|
2306 |
};
|
2307 |
},
|
2308 |
|
2309 |
-
getWordCount : function() {
|
2310 |
-
return Number( self.settings.wordCounter.text() );
|
2311 |
-
},
|
2312 |
-
|
2313 |
/**
|
2314 |
* Generate the Report based on analysis done.
|
2315 |
*
|
@@ -2341,10 +2605,10 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2341 |
if ( eventInfo ) {
|
2342 |
// Listen for changes to raw HTML in editor.
|
2343 |
if ( eventInfo.raw ) {
|
2344 |
-
var raws = eventInfo.raw;
|
2345 |
|
2346 |
-
var h1 = $
|
2347 |
-
h2 = $
|
2348 |
headings = {};
|
2349 |
|
2350 |
headings = {
|
@@ -2352,7 +2616,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2352 |
h1text : api.Headings.getHeadingText( h1 ),
|
2353 |
h2Count : h2.length,
|
2354 |
h2text : api.Headings.getHeadingText( h2 ),
|
2355 |
-
imageCount: $
|
2356 |
};
|
2357 |
// Set the heading counts and image count found in new content update.
|
2358 |
_( report.rawstatistics ).extend( headings );
|
@@ -2371,7 +2635,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2371 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
2372 |
},
|
2373 |
keywordContent : {
|
2374 |
-
lengthScore : api.Keywords.contentScore( api.ContentAnalysis.keywords( api.
|
2375 |
},
|
2376 |
keywordHeadings : {
|
2377 |
length : api.Headings.keywords( api.Headings.getRealHeadingCount() ),
|
@@ -2385,7 +2649,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2385 |
if ( eventInfo.text ) {
|
2386 |
var kw, headingCount = api.Headings.getRealHeadingCount(),
|
2387 |
content = eventInfo.text,
|
2388 |
-
raw =
|
2389 |
|
2390 |
// Get length of title field.
|
2391 |
titleLength = self.settings.title.val().length;
|
@@ -2443,7 +2707,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2443 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
2444 |
},
|
2445 |
keywordContent : {
|
2446 |
-
lengthScore : api.Keywords.contentScore( api.ContentAnalysis.keywords( api.
|
2447 |
},
|
2448 |
keywordHeadings : {
|
2449 |
length : api.Headings.keywords( headingCount ),
|
@@ -2455,8 +2719,8 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2455 |
},
|
2456 |
headings : headingCount,
|
2457 |
wordCount : {
|
2458 |
-
length :
|
2459 |
-
lengthScore : api.ContentAnalysis.seoContentLengthScore(
|
2460 |
},
|
2461 |
sectionScore: {},
|
2462 |
sectionStatus: {},
|
@@ -2485,7 +2749,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2485 |
_( report.bgseo_keywords.keywordTitle ).extend({
|
2486 |
lengthScore : api.Keywords.titleScore( api.Title.keywords() ),
|
2487 |
});
|
2488 |
-
|
2489 |
}
|
2490 |
|
2491 |
// Listen to changes to the SEO Description and update report.
|
@@ -2503,7 +2767,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2503 |
_( report.bgseo_keywords.keywordDescription ).extend({
|
2504 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
2505 |
});
|
2506 |
-
|
2507 |
}
|
2508 |
|
2509 |
// Listen for changes to noindex/index and update report.
|
@@ -2511,7 +2775,7 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2511 |
_( report.bgseo_visibility.robotIndex ).extend({
|
2512 |
lengthScore : eventInfo.robotIndex,
|
2513 |
});
|
2514 |
-
|
2515 |
}
|
2516 |
|
2517 |
// Listen for changes to nofollow/follow and update report.
|
@@ -2519,12 +2783,12 @@ BOLDGRID.SEO = BOLDGRID.SEO || {};
|
|
2519 |
_( report.bgseo_visibility.robotFollow ).extend({
|
2520 |
lengthScore : eventInfo.robotFollow,
|
2521 |
});
|
2522 |
-
|
2523 |
}
|
2524 |
}
|
2525 |
|
2526 |
// Send the final analysis to display the report.
|
2527 |
-
|
2528 |
});
|
2529 |
},
|
2530 |
|
481 |
|
482 |
( function( $, counter ) {
|
483 |
|
484 |
+
'use strict';
|
|
|
|
|
|
|
|
|
|
|
|
|
485 |
|
486 |
+
var self, api;
|
|
|
487 |
|
488 |
+
api = BOLDGRID.SEO;
|
|
|
|
|
|
|
|
|
489 |
|
490 |
+
/**
|
491 |
+
* Handle tracking of wordcount.
|
492 |
+
*
|
493 |
+
* @since 1.6.0
|
494 |
+
*/
|
495 |
+
api.Wordcount = {
|
496 |
|
497 |
+
/**
|
498 |
+
* Number of words in the content.
|
499 |
+
*
|
500 |
+
* @since 1.6.0
|
501 |
+
*
|
502 |
+
* @type {Number}
|
503 |
+
*/
|
504 |
+
count: 0,
|
505 |
|
506 |
+
/**
|
507 |
+
* List of words on the page.
|
508 |
+
*
|
509 |
+
* @since 1.6.0
|
510 |
+
*
|
511 |
+
* @type {array}
|
512 |
+
*/
|
513 |
+
words: [],
|
514 |
|
515 |
+
/**
|
516 |
+
* When the page loads, run the update methods.
|
517 |
+
*
|
518 |
+
* @since 1.6.0
|
519 |
+
*/
|
520 |
+
init : function () {
|
521 |
+
$( self.update );
|
522 |
+
},
|
523 |
|
524 |
+
/**
|
525 |
+
* Update this classes word count metrics.
|
526 |
+
*
|
527 |
+
* @since 1.6.0
|
528 |
+
*/
|
529 |
+
update : function () {
|
530 |
+
var count,
|
531 |
+
words,
|
532 |
+
text = api.Editor.ui.getRawText();
|
533 |
|
534 |
+
count = counter.count( text );
|
535 |
+
words = BOLDGRID.SEO.Words.words( text );
|
536 |
|
537 |
+
if ( count !== self.count ) {
|
538 |
+
api.Editor.element.trigger( 'bgseo-analysis', [{ words : words, count : count }] );
|
539 |
+
}
|
540 |
|
541 |
+
self.words = words;
|
542 |
+
self.count = count;
|
543 |
+
}
|
544 |
+
};
|
545 |
|
546 |
+
self = api.Wordcount;
|
547 |
|
548 |
} )( jQuery, new wp.utils.WordCounter() );
|
549 |
|
664 |
|
665 |
'use strict';
|
666 |
|
667 |
+
var self, api;
|
668 |
|
669 |
api = BOLDGRID.SEO;
|
|
|
670 |
|
671 |
/**
|
672 |
* BoldGrid TinyMCE Analysis.
|
680 |
api.TinyMCE = {
|
681 |
|
682 |
/**
|
683 |
+
* Selector to find editor id.
|
684 |
*
|
685 |
+
* @since 1.6.0
|
686 |
+
*
|
687 |
+
* @type {String}
|
688 |
*/
|
689 |
+
selector : '#content',
|
|
|
|
|
|
|
|
|
|
|
690 |
|
691 |
/**
|
692 |
+
* Selector to find preview button.
|
693 |
*
|
694 |
+
* @since 1.6.0
|
|
|
|
|
|
|
|
|
695 |
*
|
696 |
+
* @type {String}
|
697 |
*/
|
698 |
+
previewSelector : '#preview-action > .preview.button',
|
|
|
|
|
699 |
|
700 |
+
/**
|
701 |
+
* Initialize TinyMCE Content.
|
702 |
+
*
|
703 |
+
* @since 1.3.1
|
704 |
+
*/
|
705 |
+
setup : function () {
|
706 |
+
$( document ).ready( function() {
|
707 |
+
self._setupWordCount();
|
708 |
+
self.editorChange();
|
|
|
709 |
});
|
710 |
},
|
711 |
|
718 |
*/
|
719 |
getContent : function() {
|
720 |
var content;
|
721 |
+
|
722 |
if ( tinymce.ActiveEditor ) {
|
723 |
content = tinyMCE.get( wpActiveEditor ).getContent();
|
724 |
} else {
|
725 |
+
content = api.Editor.element.val();
|
726 |
// Remove newlines and carriage returns.
|
727 |
content = content.replace( /\r?\n|\r/g, '' );
|
728 |
}
|
732 |
// Stores raw and stripped down versions of the content for analysis.
|
733 |
content = {
|
734 |
'raw': rawContent,
|
735 |
+
'text': api.Editor.stripper( content.toLowerCase() ),
|
736 |
};
|
737 |
|
738 |
return content;
|
739 |
},
|
740 |
|
741 |
+
|
742 |
/**
|
743 |
+
* Get the raw text from the editor.
|
|
|
|
|
|
|
|
|
|
|
744 |
*
|
745 |
+
* @since 1.6.0
|
746 |
*
|
747 |
+
* @return {string} Editor content.
|
748 |
*/
|
749 |
+
getRawText: function() {
|
750 |
+
var text,
|
751 |
+
contentEditor = tinyMCE.get( wpActiveEditor );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
752 |
|
753 |
+
if ( ! contentEditor || contentEditor.isHidden() ) {
|
754 |
+
text = api.Editor.element.val();
|
755 |
+
} else {
|
756 |
+
text = contentEditor.getContent( { format: 'raw' } );
|
757 |
}
|
758 |
+
|
759 |
+
return text;
|
760 |
},
|
761 |
+
|
762 |
/**
|
763 |
* Listens for changes made in the text editor mode.
|
764 |
*
|
792 |
return text;
|
793 |
},
|
794 |
|
795 |
+
/**
|
796 |
+
* Is this a new Post?
|
797 |
+
*
|
798 |
+
* @since 1.6.0
|
799 |
+
*
|
800 |
+
* @return {boolean} Is this post-new.php?
|
801 |
+
*/
|
802 |
+
isNewPost : function () {
|
803 |
+
return ! $( '#sample-permalink' ).length;
|
804 |
+
},
|
805 |
+
|
806 |
/**
|
807 |
* Checks which editor is the active editor.
|
808 |
*
|
823 |
text = tinyMCE.get( wpActiveEditor ).getContent();
|
824 |
break;
|
825 |
case 'content' :
|
826 |
+
text = api.Editor.element.val();
|
827 |
text = text.replace( /\r?\n|\r/g, '' );
|
828 |
break;
|
829 |
}
|
833 |
|
834 |
text = {
|
835 |
'raw': rawText,
|
836 |
+
'text': api.Editor.stripper( text.toLowerCase() ),
|
837 |
};
|
838 |
|
839 |
// Trigger the text analysis for report.
|
840 |
+
api.Editor.element.trigger( 'bgseo-analysis', [text] );
|
841 |
},
|
842 |
|
843 |
/**
|
844 |
+
* Bind events to the editor input and update the wordcount class.
|
|
|
|
|
|
|
|
|
|
|
|
|
845 |
*
|
846 |
+
* @since 1.6.0
|
847 |
*/
|
848 |
+
_setupWordCount : function() {
|
849 |
+
var debouncedCb = _.debounce( api.Wordcount.update, 1000 );
|
850 |
|
851 |
+
$( document ).on( 'tinymce-editor-init', function( event, editor ) {
|
852 |
+
if ( editor.id !== 'content' ) {
|
853 |
+
return;
|
854 |
+
}
|
855 |
+
|
856 |
+
editor.on( 'AddUndo keyup', debouncedCb );
|
857 |
+
} );
|
858 |
+
|
859 |
+
api.Editor.element.on( 'input keyup', debouncedCb );
|
860 |
+
}
|
861 |
|
|
|
|
|
862 |
};
|
863 |
|
864 |
self = api.TinyMCE;
|
1279 |
|
1280 |
})( jQuery );
|
1281 |
|
1282 |
+
( function ( $ ) {
|
1283 |
+
|
1284 |
+
'use strict';
|
1285 |
+
|
1286 |
+
var self, api, report;
|
1287 |
+
|
1288 |
+
api = BOLDGRID.SEO;
|
1289 |
+
report = api.report;
|
1290 |
+
|
1291 |
+
/**
|
1292 |
+
* BoldGrid Editor Interface.
|
1293 |
+
*
|
1294 |
+
* This class allows us to control which editor interface functions will run.
|
1295 |
+
* On first load the it runs the setup method of whichever ui is currently loaded.
|
1296 |
+
* It then assigns that ui to this classes ui variable for cross api use.
|
1297 |
+
*
|
1298 |
+
* @since 1.6.0
|
1299 |
+
*/
|
1300 |
+
api.Editor = {
|
1301 |
+
|
1302 |
+
/**
|
1303 |
+
* Interface loaded.
|
1304 |
+
*
|
1305 |
+
* @since 1.6.0
|
1306 |
+
*
|
1307 |
+
* @type {object} seo.tinymce or seo-Gutenberg
|
1308 |
+
*/
|
1309 |
+
ui: null,
|
1310 |
+
|
1311 |
+
/**
|
1312 |
+
* WP Element to use to trigger events.
|
1313 |
+
*
|
1314 |
+
* @since 1.6.0
|
1315 |
+
*
|
1316 |
+
* @type {$} Editor jQuery Element.
|
1317 |
+
*/
|
1318 |
+
element: null,
|
1319 |
+
|
1320 |
+
/**
|
1321 |
+
* Setup the correct editor interface.
|
1322 |
+
*
|
1323 |
+
* @since 1.3.1
|
1324 |
+
*/
|
1325 |
+
init : function () {
|
1326 |
+
self.ui = wp.data ? api.Gutenberg : api.TinyMCE;
|
1327 |
+
self.element = $( self.ui.selector );
|
1328 |
+
self.ui.setup();
|
1329 |
+
self.onloadContent();
|
1330 |
+
},
|
1331 |
+
|
1332 |
+
/**
|
1333 |
+
* Runs actions on window load to prepare for analysis.
|
1334 |
+
*
|
1335 |
+
* This method gets the current editor in use by the user on the
|
1336 |
+
* initial page load ( text editor or visual editor ), and also
|
1337 |
+
* is responsible for creating the iframe preview of the page/post
|
1338 |
+
* so we can get the raw html in use by the template/theme the user
|
1339 |
+
* has activated.
|
1340 |
+
*
|
1341 |
+
* @since 1.3.1
|
1342 |
+
*/
|
1343 |
+
onloadContent : function() {
|
1344 |
+
var text,
|
1345 |
+
editor = $( '#content.wp-editor-area[aria-hidden=false]' );
|
1346 |
+
|
1347 |
+
$( window ).on( 'load bgseo-media-inserted', function() {
|
1348 |
+
var content = self.ui.getContent();
|
1349 |
+
|
1350 |
+
// Get rendered page content from frontend site.
|
1351 |
+
self.getRenderedContent();
|
1352 |
+
|
1353 |
+
// Trigger the content analysis for the content.
|
1354 |
+
_.defer( function() {
|
1355 |
+
self.element.trigger( 'bgseo-analysis', [content] );
|
1356 |
+
} );
|
1357 |
+
} );
|
1358 |
+
},
|
1359 |
+
|
1360 |
+
/**
|
1361 |
+
* Only ajax for preview if permalink is available. This only
|
1362 |
+
* impacts "New" page and posts. To counter
|
1363 |
+
* this we will disable the checks made until the content has had
|
1364 |
+
* a chance to be updated. We will store the found headings minus
|
1365 |
+
* the initial found headings in the content, so we know what the
|
1366 |
+
* template has in use on the actual rendered page.
|
1367 |
+
*
|
1368 |
+
* @since 1.3.1
|
1369 |
+
*
|
1370 |
+
* @returns null No return.
|
1371 |
+
*/
|
1372 |
+
getRenderedContent : function() {
|
1373 |
+
var renderedContent, preview;
|
1374 |
+
|
1375 |
+
// Get the preview url from WordPress.
|
1376 |
+
preview = $( api.Editor.ui.previewSelector ).attr( 'href' );
|
1377 |
+
|
1378 |
+
if ( ! api.Editor.ui.isNewPost() ) {
|
1379 |
+
// Only run this once after the initial iframe has loaded to get current template stats.
|
1380 |
+
$.get( preview, function( renderedTemplate ) {
|
1381 |
+
var headings, h1, h2, $rendered;
|
1382 |
+
|
1383 |
+
// The rendered page content.
|
1384 |
+
$rendered = $( renderedTemplate );
|
1385 |
+
|
1386 |
+
// H1's that appear in rendered content.
|
1387 |
+
h1 = $rendered.find( 'h1' );
|
1388 |
+
// HS's that appear in rendered content.
|
1389 |
+
h2 = $rendered.find( 'h2' );
|
1390 |
+
|
1391 |
+
// The rendered content stats.
|
1392 |
+
renderedContent = {
|
1393 |
+
h1Count : h1.length - report.rawstatistics.h1Count,
|
1394 |
+
h1text : _.filter( api.Headings.getHeadingText( h1 ), function( obj ){
|
1395 |
+
return ! _.findWhere( report.rawstatistics.h1text, obj );
|
1396 |
+
}),
|
1397 |
+
h2Count : h2.length - report.rawstatistics.h2Count,
|
1398 |
+
h2text : _.filter( api.Headings.getHeadingText( h2 ), function( obj ){
|
1399 |
+
return ! _.findWhere( report.rawstatistics.h2text, obj );
|
1400 |
+
}),
|
1401 |
+
};
|
1402 |
+
|
1403 |
+
// Add the rendered stats to our report for use later.
|
1404 |
+
_.extend( report, { rendered : renderedContent } );
|
1405 |
+
|
1406 |
+
// Trigger the SEO report to rebuild in the template after initial stats are created.
|
1407 |
+
self.triggerAnalysis();
|
1408 |
+
|
1409 |
+
}, 'html' );
|
1410 |
+
}
|
1411 |
+
},
|
1412 |
+
|
1413 |
+
/**
|
1414 |
+
* Strips out unwanted html.
|
1415 |
+
*
|
1416 |
+
* This is helpful in removing the remaining traces of HTML
|
1417 |
+
* that is sometimes leftover to form our clean text output and
|
1418 |
+
* run our text analysis on.
|
1419 |
+
*
|
1420 |
+
* @since 1.3.1
|
1421 |
+
*
|
1422 |
+
* @returns {string} The content with any remaining html removed.
|
1423 |
+
*/
|
1424 |
+
stripper : function( html ) {
|
1425 |
+
var tmp;
|
1426 |
+
|
1427 |
+
tmp = document.implementation.createHTMLDocument( 'New' ).body;
|
1428 |
+
tmp.innerHTML = html;
|
1429 |
+
|
1430 |
+
return tmp.textContent || tmp.innerText || " ";
|
1431 |
+
},
|
1432 |
+
|
1433 |
+
/**
|
1434 |
+
* Fire an event that will force, analysis to run.
|
1435 |
+
*
|
1436 |
+
* @since 1.6.0
|
1437 |
+
*/
|
1438 |
+
triggerAnalysis: function() {
|
1439 |
+
self.element.trigger( 'bgseo-analysis', [ self.ui.getContent() ] );
|
1440 |
+
}
|
1441 |
+
};
|
1442 |
+
|
1443 |
+
self = api.Editor;
|
1444 |
+
|
1445 |
+
})( jQuery );
|
1446 |
+
|
1447 |
+
( function ( $ ) {
|
1448 |
+
|
1449 |
+
'use strict';
|
1450 |
+
|
1451 |
+
var self, api;
|
1452 |
+
|
1453 |
+
api = BOLDGRID.SEO;
|
1454 |
+
|
1455 |
+
/**
|
1456 |
+
* BoldGrid Gutenberg Analysis.
|
1457 |
+
*
|
1458 |
+
* This is responsible for generating the actual reports
|
1459 |
+
* displayed within the BoldGrid SEO Dashboard when the user
|
1460 |
+
* is on a page or a post.
|
1461 |
+
*
|
1462 |
+
* @since 1.3.1
|
1463 |
+
*/
|
1464 |
+
api.Gutenberg = {
|
1465 |
+
|
1466 |
+
/**
|
1467 |
+
* Selector to find editor id.
|
1468 |
+
*
|
1469 |
+
* This is only used to trigger events. No dom content queries in Gutenberg context.
|
1470 |
+
*
|
1471 |
+
* @since 1.6.0
|
1472 |
+
*
|
1473 |
+
* @type {String}
|
1474 |
+
*/
|
1475 |
+
selector : '#editor',
|
1476 |
+
|
1477 |
+
/**
|
1478 |
+
* Selector to find preview button.
|
1479 |
+
*
|
1480 |
+
* @since 1.6.0
|
1481 |
+
*
|
1482 |
+
* @type {String}
|
1483 |
+
*/
|
1484 |
+
previewSelector : '.editor-post-preview',
|
1485 |
+
|
1486 |
+
/**
|
1487 |
+
* Initialize Content.
|
1488 |
+
*
|
1489 |
+
* @since 1.6.0
|
1490 |
+
*/
|
1491 |
+
setup : function () {
|
1492 |
+
$( api.Editor.triggerAnalysis );
|
1493 |
+
self._setupEditorChange();
|
1494 |
+
},
|
1495 |
+
|
1496 |
+
/**
|
1497 |
+
* Are we currently on a new post?
|
1498 |
+
*
|
1499 |
+
* @since 1.6.0
|
1500 |
+
*
|
1501 |
+
* @return {boolean} Is this a post-new.php?
|
1502 |
+
*/
|
1503 |
+
isNewPost : function() {
|
1504 |
+
return wp.data.select( 'core/editor' ).isCleanNewPost();
|
1505 |
+
},
|
1506 |
+
|
1507 |
+
/**
|
1508 |
+
* Gets the content from the editor for analysis.
|
1509 |
+
*
|
1510 |
+
* @since 1.6.0
|
1511 |
+
*
|
1512 |
+
* @returns {Object} content Contains content in raw and text formats.
|
1513 |
+
*/
|
1514 |
+
getContent : function() {
|
1515 |
+
var content = self.getRawText();
|
1516 |
+
|
1517 |
+
// Stores raw and stripped down versions of the content for analysis.
|
1518 |
+
content = {
|
1519 |
+
'raw': content,
|
1520 |
+
'text': api.Editor.stripper( content.toLowerCase() ),
|
1521 |
+
};
|
1522 |
+
|
1523 |
+
return content;
|
1524 |
+
},
|
1525 |
+
|
1526 |
+
/**
|
1527 |
+
* Get the raw text from the editor.
|
1528 |
+
*
|
1529 |
+
* @since 1.6.0
|
1530 |
+
*
|
1531 |
+
* @return {string} Editor content.
|
1532 |
+
*/
|
1533 |
+
getRawText : function () {
|
1534 |
+
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'content' );
|
1535 |
+
},
|
1536 |
+
|
1537 |
+
/**
|
1538 |
+
* Listens for changes made in the text editor mode.
|
1539 |
+
*
|
1540 |
+
* @since 1.6.0
|
1541 |
+
*
|
1542 |
+
* @returns {string} text The new content to perform analysis on.
|
1543 |
+
*/
|
1544 |
+
_setupEditorChange: function() {
|
1545 |
+
var latestContent = '';
|
1546 |
+
|
1547 |
+
wp.data.subscribe( _.debounce( function () {
|
1548 |
+
|
1549 |
+
// Make sure content is different before running analysis.
|
1550 |
+
if ( self.getRawText() !== latestContent ) {
|
1551 |
+
api.Wordcount.update();
|
1552 |
+
api.Editor.triggerAnalysis();
|
1553 |
+
latestContent = self.getRawText();
|
1554 |
+
}
|
1555 |
+
}, 1000 ) );
|
1556 |
+
}
|
1557 |
+
};
|
1558 |
+
|
1559 |
+
self = api.Gutenberg;
|
1560 |
+
|
1561 |
+
})( jQuery );
|
1562 |
+
|
1563 |
( function ( $ ) {
|
1564 |
|
1565 |
'use strict';
|
1618 |
_checkbox : function() {
|
1619 |
// Listen for changes to input value.
|
1620 |
self.settings.displayTitle.on( 'change', _.debounce( function() {
|
1621 |
+
$( this ).trigger( 'bgseo-analysis', [ api.Editor.ui.getContent() ] );
|
1622 |
}, 1000 ) );
|
1623 |
},
|
1624 |
|
1790 |
},
|
1791 |
};
|
1792 |
|
1793 |
+
content = api.Editor.ui.getContent();
|
1794 |
+
content = $( '<div>' + content.raw + '</div>' );
|
1795 |
|
1796 |
+
h1s = content.find( 'h1' );
|
1797 |
+
h2s = content.find( 'h2' );
|
1798 |
|
1799 |
// If no h1s or h2s are found return the defaults.
|
1800 |
if ( ! h1s.length && ! h2s.length ) return headings;
|
1865 |
getSettings : function() {
|
1866 |
self.settings = {
|
1867 |
keyword : $( '#bgseo-custom-keyword' ),
|
1868 |
+
content : api.Editor.element,
|
1869 |
};
|
1870 |
},
|
1871 |
|
1972 |
keyword = keyword.toLowerCase();
|
1973 |
|
1974 |
keywordCount = self.keywordCount( content, keyword );
|
1975 |
+
wordCount = api.Wordcount.count;
|
1976 |
// Get the density.
|
1977 |
result = ( ( keywordCount / wordCount ) * 100 );
|
1978 |
// Round it off.
|
2090 |
*/
|
2091 |
getKeyword : function() {
|
2092 |
var customKeyword,
|
2093 |
+
content = api.Editor.ui.getRawText();
|
2094 |
|
2095 |
if ( self.getCustomKeyword().length ) {
|
2096 |
customKeyword = self.getCustomKeyword();
|
2122 |
var count;
|
2123 |
|
2124 |
if ( _.isUndefined( markup ) ) {
|
2125 |
+
markup = api.Words.words( api.Editor.ui.getRawText() );
|
|
|
|
|
2126 |
}
|
2127 |
|
2128 |
count = _.modifyObject( _bgseoContentAnalysis.keywords.recommendedCount, function( item ) {
|
2533 |
report = api.report;
|
2534 |
|
2535 |
/**
|
2536 |
+
* BoldGrid Editor Content Analysis.
|
2537 |
*
|
2538 |
* This is responsible for generating the actual reports
|
2539 |
* displayed within the BoldGrid SEO Dashboard when the user
|
2544 |
api.Report = {
|
2545 |
|
2546 |
/**
|
2547 |
+
* Initialize Content.
|
2548 |
*
|
2549 |
* @since 1.3.1
|
2550 |
*/
|
2570 |
getSettings : function() {
|
2571 |
self.settings = {
|
2572 |
title : $( '#boldgrid-seo-field-meta_title' ),
|
2573 |
+
description : $( '#boldgrid-seo-field-meta_description' )
|
|
|
|
|
2574 |
};
|
2575 |
},
|
2576 |
|
|
|
|
|
|
|
|
|
2577 |
/**
|
2578 |
* Generate the Report based on analysis done.
|
2579 |
*
|
2605 |
if ( eventInfo ) {
|
2606 |
// Listen for changes to raw HTML in editor.
|
2607 |
if ( eventInfo.raw ) {
|
2608 |
+
var $raws = $( '<div>' + eventInfo.raw + '</div>' );
|
2609 |
|
2610 |
+
var h1 = $raws.find( 'h1' ),
|
2611 |
+
h2 = $raws.find( 'h2' ),
|
2612 |
headings = {};
|
2613 |
|
2614 |
headings = {
|
2616 |
h1text : api.Headings.getHeadingText( h1 ),
|
2617 |
h2Count : h2.length,
|
2618 |
h2text : api.Headings.getHeadingText( h2 ),
|
2619 |
+
imageCount: $raws.find( 'img' ).length,
|
2620 |
};
|
2621 |
// Set the heading counts and image count found in new content update.
|
2622 |
_( report.rawstatistics ).extend( headings );
|
2635 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
2636 |
},
|
2637 |
keywordContent : {
|
2638 |
+
lengthScore : api.Keywords.contentScore( api.ContentAnalysis.keywords( api.Editor.ui.getContent().text ) ),
|
2639 |
},
|
2640 |
keywordHeadings : {
|
2641 |
length : api.Headings.keywords( api.Headings.getRealHeadingCount() ),
|
2649 |
if ( eventInfo.text ) {
|
2650 |
var kw, headingCount = api.Headings.getRealHeadingCount(),
|
2651 |
content = eventInfo.text,
|
2652 |
+
raw = api.Editor.ui.getRawText();
|
2653 |
|
2654 |
// Get length of title field.
|
2655 |
titleLength = self.settings.title.val().length;
|
2707 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
2708 |
},
|
2709 |
keywordContent : {
|
2710 |
+
lengthScore : api.Keywords.contentScore( api.ContentAnalysis.keywords( api.Editor.ui.getContent().text ) ),
|
2711 |
},
|
2712 |
keywordHeadings : {
|
2713 |
length : api.Headings.keywords( headingCount ),
|
2719 |
},
|
2720 |
headings : headingCount,
|
2721 |
wordCount : {
|
2722 |
+
length : api.Wordcount.count,
|
2723 |
+
lengthScore : api.ContentAnalysis.seoContentLengthScore( api.Wordcount.count ),
|
2724 |
},
|
2725 |
sectionScore: {},
|
2726 |
sectionStatus: {},
|
2749 |
_( report.bgseo_keywords.keywordTitle ).extend({
|
2750 |
lengthScore : api.Keywords.titleScore( api.Title.keywords() ),
|
2751 |
});
|
2752 |
+
api.Editor.triggerAnalysis();
|
2753 |
}
|
2754 |
|
2755 |
// Listen to changes to the SEO Description and update report.
|
2767 |
_( report.bgseo_keywords.keywordDescription ).extend({
|
2768 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
2769 |
});
|
2770 |
+
api.Editor.triggerAnalysis();
|
2771 |
}
|
2772 |
|
2773 |
// Listen for changes to noindex/index and update report.
|
2775 |
_( report.bgseo_visibility.robotIndex ).extend({
|
2776 |
lengthScore : eventInfo.robotIndex,
|
2777 |
});
|
2778 |
+
api.Editor.triggerAnalysis();
|
2779 |
}
|
2780 |
|
2781 |
// Listen for changes to nofollow/follow and update report.
|
2783 |
_( report.bgseo_visibility.robotFollow ).extend({
|
2784 |
lengthScore : eventInfo.robotFollow,
|
2785 |
});
|
2786 |
+
api.Editor.triggerAnalysis();
|
2787 |
}
|
2788 |
}
|
2789 |
|
2790 |
// Send the final analysis to display the report.
|
2791 |
+
api.Editor.element.trigger( 'bgseo-report', [ report ] );
|
2792 |
});
|
2793 |
},
|
2794 |
|
assets/js/bgseo.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
var BOLDGRID=BOLDGRID||{};BOLDGRID.SEO={report:{bgseo_visibility:{},bgseo_keywords:{},bgseo_meta:{},rawstatistics:{},textstatistics:{}}},function(e){"use strict";butterbean.views.register_control("dashboard",{tagName:"div",attributes:function(){return{id:"butterbean-control-"+this.model.get("name"),"class":"butterbean-control butterbean-control-"+this.model.get("type")}},initialize:function(){e(window).bind("bgseo-report",_.bind(this.setAnalysis,this)),this.bgseo_template=wp.template("butterbean-control-dashboard"),_.bindAll(this,"render"),this.model.bind("change",this.render)},results:function(e){var t={};return _.each(e,function(e){_.extend(t,e)}),t},setAnalysis:function(e,t){var n,o=this.model.get("section"),s=_.pick(t,o);this.sectionReport=this.results(s),this.model.set("analysis",this.sectionReport),_(t).each(function(e){_.isUndefined(e.sectionScore)||(n=BOLDGRID.SEO.Sections.score(e),_(e).extend(n))}),_(t.bgseo_keywords).extend({overview:{score:BOLDGRID.SEO.Dashboard.overviewScore(t)}}),_(t.bgseo_keywords.overview).extend({status:BOLDGRID.SEO.Dashboard.overviewStatus(t.bgseo_keywords.overview.score)}),BOLDGRID.SEO.Sections.navHighlight(t),BOLDGRID.SEO.Sections.overviewStatus(t)},render:function(){return this.model.get("active")&&(this.el.innerHTML=this.bgseo_template(this.model.toJSON())),this}})}(jQuery),function(e){"use strict";butterbean.views.register_control("keywords",{tagName:"div",attributes:function(){return{id:"butterbean-control-"+this.model.get("name"),"class":"butterbean-control butterbean-control-"+this.model.get("type")}},initialize:function(){e(window).bind("bgseo-report",_.bind(this.setAnalysis,this)),this.bgseo_template=wp.template("butterbean-control-keywords"),_.bindAll(this,"render"),this.model.bind("change",this.render)},setAnalysis:function(e,t){this.model.set(t)},render:function(){return this.model.get("active")&&(this.el.innerHTML=this.bgseo_template(this.model.toJSON())),this}})}(jQuery);var BOLDGRID=BOLDGRID||{};BOLDGRID.SEO=BOLDGRID.SEO||{},function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Util={init:function(){_.mixin({modifyObject:function(e,t){return _.object(_.map(e,function(e,n){return[n,t(e)]}))},pickDeep:function(e){var t={},n=Array.prototype.concat.apply(Array.prototype,Array.prototype.slice.call(arguments,1));return this.each(n,function(n){var o=n.split(".");n=o.shift(),n in e&&(o.length>0?t[n]?_.extend(t[n],_.pickDeep(e[n],o.join("."))):t[n]=_.pickDeep(e[n],o.join(".")):t[n]=e[n])}),t}}),Number.prototype.isBetween||(Number.prototype.isBetween=function(e,t){_.isUndefined(e)&&(e=0),_.isUndefined(t)&&(t=0);var n=Math.max(e,t),o=Math.min(e,t);return this>o&&this<n}),Number.prototype.rounded||(Number.prototype.rounded=function(e){_.isUndefined(e)&&(e=0);var t=Math.pow(10,e),n=Math.round(this*t)/t;return n}),String.prototype.printf||(String.prototype.printf=function(){for(var e=this,t=0;/%s/.test(e);)e=e.replace("%s",arguments[t++]);return e}),String.prototype.occurences||(String.prototype.occurences=function(e,t){if(e+="",e.length<=0)return this.length+1;for(var n=0,o=0,s=t?1:e.length;;){if(o=this.indexOf(e,o),!(o>=0))break;++n,o+=s}return n})}},t=o.Util}(jQuery),function(){"use strict";var e,t;t=BOLDGRID.SEO,t.Words={init:function(t){var n,o;if(t)for(n in t)t.hasOwnProperty(n)&&(e.settings[n]=t[n]);o=e.settings.l10n.shortcodes,o&&o.length&&(e.settings.shortcodesRegExp=new RegExp("\\[\\/?(?:"+o.join("|")+")[^\\]]*?\\]","g"))},settings:{HTMLRegExp:/<\/?[a-z][^>]*?>/gi,HTMLcommentRegExp:/<!--[\s\S]*?-->/g,spaceRegExp:/ | /gi,HTMLEntityRegExp:/&\S+?;/g,connectorRegExp:/--|\u2014/g,removeRegExp:new RegExp(["[","!-@[-`{-~","-¿×÷"," -⯿","⸀-","]"].join(""),"g"),astralRegExp:/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,wordsRegExp:/.+?\s+/g,characters_excluding_spacesRegExp:/\S/g,characters_including_spacesRegExp:/[^\f\n\r\t\v\u00AD\u2028\u2029]/g,l10n:window.wordCountL10n||{}},words:function(t,n){var o=0;return n=n||e.settings.l10n.type,"characters_excluding_spaces"!==n&&"characters_including_spaces"!==n&&(n="words"),t&&(t+="\n",t=t.replace(e.settings.HTMLRegExp,"\n"),t=t.replace(e.settings.HTMLcommentRegExp,""),e.settings.shortcodesRegExp&&(t=t.replace(e.settings.shortcodesRegExp,"\n")),t=t.replace(e.settings.spaceRegExp," "),"words"===n?(t=t.replace(e.settings.HTMLEntityRegExp,""),t=t.replace(e.settings.connectorRegExp," "),t=t.replace(e.settings.removeRegExp,"")):(t=t.replace(e.settings.HTMLEntityRegExp,"a"),t=t.replace(e.settings.astralRegExp,"a")),t=t.match(e.settings[n+"RegExp"]),t&&(o=t)),o}},e=t.Words}(),function(e,t){e(function(){function n(){var e,n;e=!o||o.isHidden()?r.val():o.getContent({format:"raw"}),n=t.count(e),s=BOLDGRID.SEO.Words.words(e),n!==i&&r.trigger("bgseo-analysis",[{words:s,count:n}]),i=n}var o,s,r=e("#content"),i=(e("#wp-word-count").find(".word-count"),0);e(document).on("tinymce-editor-init",function(e,t){"content"===t.id&&(o=t,t.on("nodechange keyup",_.debounce(n,1e3)))}),r.on("input keyup",_.debounce(n,1e3)),n()})}(jQuery,new wp.utils.WordCounter),function(e){"use strict";var t;BOLDGRID.SEO.Admin={init:function(){e(document).ready(function(){t._setWordCounts()})},wordCount:function(n){var o=n.attr("maxlength"),s=e("<span />",{"class":"boldgrid-seo-meta-counter",style:"font-weight: bold"}),r=e("<div />",{"class":"boldgrid-seo-meta-countdown boldgrid-seo-meta-extra",html:" characters left"});o&&n.removeAttr("maxlength").after(r.prepend(s)).on("keyup focus",function(){t.setCounter(s,n,o)}),t.setCounter(s,n,o)},setCounter:function(e,t,n){var o=t.val(),s=o.length;e.html(n-s),"boldgrid-seo-field-meta_description"===t.context.id?s>n?e.css({color:"#EA4335"}):s.isBetween(0,_bgseoContentAnalysis.seoDescription.length.okScore)?e.css({color:"#FBBC05"}):s.isBetween(_bgseoContentAnalysis.seoDescription.length.okScore-1,_bgseoContentAnalysis.seoDescription.length.goodScore+1)?e.css({color:"#34A853"}):e.css({color:"black"}):s>n?e.css({color:"#EA4335"}):s.isBetween(0,_bgseoContentAnalysis.seoTitle.length.okScore)?e.css({color:"#FBBC05"}):s>_bgseoContentAnalysis.seoTitle.length.okScore-1?e.css({color:"#34A853"}):e.css({color:"black"})},_setWordCounts:function(){e("#boldgrid-seo-field-meta_title, #boldgrid-seo-field-meta_description").each(function(){t.wordCount(e(this))})}},t=BOLDGRID.SEO.Admin}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.TinyMCE={init:function(){t.onloadContent(),e(document).ready(function(){t.editorChange()})},onloadContent:function(){e("#content.wp-editor-area[aria-hidden=false]");e(window).on("load bgseo-media-inserted",function(){var n=t.getContent();t.getRenderedContent(),_.defer(function(){e("#content").trigger("bgseo-analysis",[n])})})},getContent:function(){var n;tinymce.ActiveEditor?n=tinyMCE.get(wpActiveEditor).getContent():(n=e("#content").val(),n=n.replace(/\r?\n|\r/g,""));var o=e.parseHTML(n);return n={raw:o,text:t.stripper(n.toLowerCase())}},getRenderedContent:function(){var s,r;r=e("#preview-action > .preview.button").attr("href"),e("#sample-permalink").length&&e.get(r,function(r){var i,a,d;d=e(r),i=d.find("h1"),a=d.find("h2"),s={h1Count:i.length-n.rawstatistics.h1Count,h1text:_.filter(o.Headings.getHeadingText(i),function(e){return!_.findWhere(n.rawstatistics.h1text,e)}),h2Count:a.length-n.rawstatistics.h2Count,h2text:_.filter(o.Headings.getHeadingText(a),function(e){return!_.findWhere(n.rawstatistics.h2text,e)})},_.extend(n,{rendered:s}),e("#content").trigger("bgseo-analysis",[t.getContent()])},"html")},editorChange:function(){var n,o;return e("#content.wp-editor-area").on("input propertychange paste nodechange",function(){o=e(this).attr("id"),n=t.wpContent(o)}),n},tmceChange:function(e){var n,o;return o=e.target.id,n=t.wpContent(o)},wpContent:function(n){var o={};switch(n){case"tinymce":tinymce.activeEditor&&(o=tinyMCE.get(wpActiveEditor).getContent());break;case"content":o=e("#content").val(),o=o.replace(/\r?\n|\r/g,"")}var s=e.parseHTML(o);o={raw:s,text:t.stripper(o.toLowerCase())},e("#content").trigger("bgseo-analysis",[o])},stripper:function(e){var t;return t=document.implementation.createHTMLDocument("New").body,t.innerHTML=e,t.textContent||t.innerText||" "}},t=o.TinyMCE}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.ContentAnalysis={seoContentLengthScore:function(e){var t,n,o={};return e=Number(e),t=_bgseoContentAnalysis.content.length,n=t.contentLength.printf(e)+" ",0===e&&(o={status:"red",msg:t.badEmpty}),e.isBetween(0,t.badShortScore)&&(o={status:"red",msg:n+t.badShort}),e.isBetween(t.badShortScore-1,t.okScore)&&(o={status:"yellow",msg:n+t.ok}),e>t.okScore-1&&(o={status:"green",msg:n+t.good}),o},seoImageLengthScore:function(e){var t={status:"green",msg:_bgseoContentAnalysis.image.length.good};return e||(t={status:"red",msg:_bgseoContentAnalysis.image.length.bad}),t},keywords:function(e){var t=o.Keywords.getKeyword();return e.occurences(t)}},t=o.ContentAnalysis}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Dashboard={overviewScore:function(e){var n,o=t.totalScore(e),s=_.size(butterbean.models.sections);return n=2*s,(o/n*100).rounded(2)},overviewStatus:function(e){var t;return t="green",e<40&&(t="red"),e.isBetween(39,76)&&(t="yellow"),t},getStatuses:function(e){var t={};return _.each(butterbean.models.sections,function(n){var o,s=n.get("name");o=e[s].sectionStatus,t[s]=o,_(t[s]).extend(o)}),t},assignNumbers:function(e){var n,o;return o=t.getStatuses(e),n=_.mapObject(o,function(e){var t;return"red"===e&&(t=0),"yellow"===e&&(t=1),"green"===e&&(t=2),t})},totalScore:function(e){var n,o=t.assignNumbers(e);return n=_(o).reduce(function(e,t){return e+t},0)}},t=o.Dashboard}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Description={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._description()},getSettings:function(){t.settings={description:e("#boldgrid-seo-field-meta_description")}},_description:function(){t.settings.description.on("input propertychange paste",_.debounce(function(){e(this).trigger("bgseo-analysis",[{descLength:t.settings.description.val().length}])},1e3))},getDescription:function(){return t.settings.description},descriptionScore:function(e){var t,n={};return t=_bgseoContentAnalysis.seoDescription.length,0===e&&(n={status:"red",msg:t.badEmpty}),e.isBetween(0,t.okScore)&&(n={status:"yellow",msg:t.ok}),e.isBetween(t.okScore-1,t.goodScore+1)&&(n={status:"green",msg:t.good}),e>t.goodScore&&(n={status:"red",msg:t.badLong}),n},keywords:function(){var e,n;return e=o.Keywords.getKeyword(),n=t.getDescription().val(),n=n.toLowerCase(),n.occurences(e)}},t=o.Description}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Headings={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._checkbox()},getSettings:function(){t.settings={displayTitle:e('[name="boldgrid-display-post-title"]').last()}},_checkbox:function(){t.settings.displayTitle.on("change",_.debounce(function(){e(this).trigger("bgseo-analysis",[o.TinyMCE.getContent()])},1e3))},score:function(e){var n;return n={status:"green",msg:_bgseoContentAnalysis.headings.h1.good},e>1&&(n={status:"red",msg:_bgseoContentAnalysis.headings.h1.badMultiple}),e>1&&t.settings.displayTitle.is(":checked")&&(n={status:"red",msg:_bgseoContentAnalysis.headings.h1.badBoldgridTheme}),0===e&&(n={status:"red",msg:_bgseoContentAnalysis.headings.h1.badEmpty}),n},keywords:function(e){var n={length:0},s=o.Keywords.getKeyword();if(_.isUndefined(e)&&(e={count:t.getRealHeadingCount()}),!_.isEmpty(e))return _(e.count).each(function(e,t){var o=e.text;_(o).each(function(e){n.length=Number(n.length)+Number(e.heading.occurences(s)*e.count)})}),n.length},getHeadingText:function(t){var n={};return n=_.countBy(t,function(t,n){return e.trim(e(t).text().toLowerCase())}),n=_.map(n,function(e,t){return!_(n).has({heading:t,count:e})&&{heading:t,count:e}})},getRealHeadingCount:function(){var e={};return _.isUndefined(n.rendered)?e=t.getContentHeadings():(e={count:{h1:{length:n.rendered.h1Count+n.rawstatistics.h1Count,text:_(n.rendered.h1text).union(n.rawstatistics.h1text)},h2:{length:n.rendered.h2Count+n.rawstatistics.h2Count,text:_(n.rendered.h2text).union(n.rawstatistics.h2text)}}},_(e).extend({lengthScore:t.score(e.count.h1.length)})),e},getContentHeadings:function(){var n,s,r,i;return n={count:{h1:{length:0,text:{}},h2:{length:0,text:{}}}},i=o.TinyMCE.getContent(),s=e(i.raw).find("h1"),r=e(i.raw).find("h2"),s.length||r.length?n={count:{h1:{length:s.length,text:t.getHeadingText(s)},h2:{length:r.length,text:t.getHeadingText(r)}}}:n}},t=o.Headings}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Keywords={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._keywords(),t.setPlaceholder()},getSettings:function(){t.settings={keyword:e("#bgseo-custom-keyword"),content:e("#content")}},_keywords:function(){t.settings.keyword.on("input propertychange paste",_.debounce(function(){var e={};t.settings.keyword.val().length;e={keywords:{title:{length:o.Title.keywords(),lengthScore:0},description:{length:o.Description.keywords(),lengthScore:0},keyword:t.getCustomKeyword()}},t.settings.keyword.trigger("bgseo-analysis",[e])},1e3))},setPlaceholder:function(e){t.settings.keyword.attr("placeholder",e)},keywordCount:function(e,t){var n;return n=e.split(t).length-1},phraseLength:function(e){return 0===e.length?0:(e=e.replace(/(^\s*)|(\s*$)/gi,""),e=e.replace(/[ ]{2,}/gi," "),e=e.replace(/\n /,"\n"),e.split(" ").length)},keywordDensity:function(e){var n,s,r,i;return i=t.getKeyword(),_.isUndefined(i)?0:(i=i.toLowerCase(),s=t.keywordCount(e,i),r=o.Report.getWordCount(),n=s/r*100,n=Math.round(10*n)/10)},normalizeWords:function(e){return e.replace("'","")},trim:function(e){return e.trim()},recommendedKeywords:function(n,o){var s,r=_bgseoContentAnalysis.stopWords,i={},a=[];if(!_.isEmpty(n)){r=r.split(",").map(t.trim),r=r.map(t.normalizeWords);for(var d=0;d<n.length;d++){var g=e.trim(n[d]).toLowerCase();!g||g.length<3||r.indexOf(g)>-1||(_.isUndefined(i[g])?(i[g]=a.length,a.push([g,1])):a[i[g]][1]++)}return a.sort(function(e,t){return t[1]-e[1]}),s=a.slice(0,o)}},getCustomKeyword:function(){return e.trim(t.settings.keyword.val()).toLowerCase()},getKeyword:function(){var s,r=o.TinyMCE.getContent();return t.getCustomKeyword().length?s=t.getCustomKeyword():_.isUndefined(n.textstatistics.recommendedKeywords)||_.isUndefined(n.textstatistics.recommendedKeywords[0])?_.isEmpty(e.trim(r.text))?s=void 0:t.recommendedKeywords(o.Words.words(r.raw),1):s=n.textstatistics.recommendedKeywords[0][0],s},getRecommendedCount:function(e){var n;return _.isUndefined(e)&&(e=!tinyMCE.activeEditor||tinyMCE.activeEditor.hidden?o.Words.words(t.settings.content.val()):o.Words.words(tinyMCE.activeEditor.getContent({format:"raw"}))),n=_.modifyObject(_bgseoContentAnalysis.keywords.recommendedCount,function(t){var n=Number(t/100*o.Words.words(e).length).rounded(0);return n>0?n:1})},score:function(){var e={};return e={title:t.titleScore(),description:t.descriptionScore()}},titleScore:function(e){var t;return t={status:"green",msg:_bgseoContentAnalysis.seoTitle.keywordUsage.good},0===e&&(t={status:"red",msg:_bgseoContentAnalysis.seoTitle.keywordUsage.bad}),e>1&&(t={status:"yellow",msg:_bgseoContentAnalysis.seoTitle.keywordUsage.ok}),t},descriptionScore:function(e){var t;return t={status:"green",msg:_bgseoContentAnalysis.seoDescription.keywordUsage.good},0===e&&(t={status:"red",msg:_bgseoContentAnalysis.seoDescription.keywordUsage.bad}),e>1&&(t={status:"yellow",msg:_bgseoContentAnalysis.seoDescription.keywordUsage.ok}),t},contentScore:function(e){var n,o,s;return o=t.getRecommendedCount(),0===e&&(n={status:"red",msg:_bgseoContentAnalysis.content.keywordUsage.bad}),e.isBetween(o.min-1,o.max+1)&&(s=1===o.min?_bgseoContentAnalysis.content.keywordUsage.goodSingular:_bgseoContentAnalysis.content.keywordUsage.good.printf(o.min),n={status:"green",msg:s}),e<o.min&&0!==e&&(s=1===o.min?_bgseoContentAnalysis.content.keywordUsage.okShortSingular:_bgseoContentAnalysis.content.keywordUsage.okShort.printf(o.min),n={status:"yellow",msg:s}),e>o.max&&(s=1===o.min?_bgseoContentAnalysis.content.keywordUsage.okLongSingular:_bgseoContentAnalysis.content.keywordUsage.okLong.printf(o.min),n={status:"red",msg:s}),n},headingScore:function(e){var t;return t={status:"green",msg:_bgseoContentAnalysis.headings.keywordUsage.good},0===e&&(t={status:"red",msg:_bgseoContentAnalysis.headings.keywordUsage.bad}),e>3&&(t={status:"yellow",msg:_bgseoContentAnalysis.headings.keywordUsage.ok}),t},keywordPhraseScore:function(e){var t;return t={status:"green",msg:_bgseoContentAnalysis.keywords.keywordPhrase.good},1===e&&(t={status:"yellow",msg:_bgseoContentAnalysis.keywords.keywordPhrase.ok}),0===e&&(t={status:"red",msg:_bgseoContentAnalysis.keywords.keywordPhrase.bad}),t}},t=o.Keywords}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Readability={gradeLevel:function(e){var n,o={};return n=textstatistics(e).fleschKincaidReadingEase(),o=t.gradeAnalysis(n)},gradeAnalysis:function(e){var t,n={};return e>90&&(n={score:e,gradeLevel:"5th grade",explanation:"Very easy to read. Easily understood by an average 11-year-old student.",lengthScore:{status:"green",msg:_bgseoContentAnalysis.readingEase.goodHigh}}),e.isBetween(79,91)&&(n={score:e,gradeLevel:"6th grade",explanation:"Easy to read. Conversational English for consumers.",lengthScore:{status:"green",msg:_bgseoContentAnalysis.readingEase.goodMedHigh}}),e.isBetween(69,81)&&(n={score:e,gradeLevel:"7th grade",explanation:"Fairly easy to read.",lengthScore:{status:"green",msg:_bgseoContentAnalysis.readingEase.goodMedLow}}),e.isBetween(59,71)&&(n={score:e,gradeLevel:"8th & 9th",explanation:"Plain English. Easily understood by 13- to 15-year-old students.",lengthScore:{status:"green",msg:_bgseoContentAnalysis.readingEase.goodLow}}),e.isBetween(49,61)&&(n={score:e,gradeLevel:"10th to 12th",explanation:"Fairly difficult to read.",lengthScore:{status:"yellow",msg:_bgseoContentAnalysis.readingEase.ok}}),e.isBetween(29,51)&&(n={score:e,gradeLevel:"College Student",explanation:"Difficult to read.",lengthScore:{status:"red",msg:_bgseoContentAnalysis.readingEase.badHigh}}),e<30&&(n={score:e,gradeLevel:"College Graduate",explanation:"Difficult to read.",lengthScore:{status:"red",msg:_bgseoContentAnalysis.readingEase.badLow}}),t=_bgseoContentAnalysis.readingEase.score.printf(e)+" ",n.lengthScore.msg=n.lengthScore.msg.replace(/^/,t),n}},t=o.Readability}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Report={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t.generateReport()},getSettings:function(){t.settings={title:e("#boldgrid-seo-field-meta_title"),description:e("#boldgrid-seo-field-meta_description"),wordCounter:e("#wp-word-count .word-count"),content:e("#content")}},getWordCount:function(){return Number(t.settings.wordCounter.text())},generateReport:function(){_.isUndefined(t.settings)||e(document).on("bgseo-analysis",function(s,r){var i,a;if(i=t.settings.title.val().length,a=t.settings.description.val().length,r.words&&_(n.textstatistics).extend({recommendedKeywords:o.Keywords.recommendedKeywords(r.words,1),customKeyword:o.Keywords.getKeyword()}),r){if(r.raw){var d=r.raw,g=e(d).find("h1"),c=e(d).find("h2"),l={};l={h1Count:g.length,h1text:o.Headings.getHeadingText(g),h2Count:c.length,h2text:o.Headings.getHeadingText(c),imageCount:e(d).find("img").length},_(n.rawstatistics).extend(l)}if(r.keywords&&_(n.bgseo_keywords).extend({keywordPhrase:{length:o.Keywords.phraseLength(o.Keywords.settings.keyword.val()),lengthScore:o.Keywords.keywordPhraseScore(o.Keywords.phraseLength(o.Keywords.settings.keyword.val()))},keywordTitle:{lengthScore:o.Keywords.titleScore(o.Title.keywords())},keywordDescription:{lengthScore:o.Keywords.descriptionScore(o.Description.keywords())},keywordContent:{lengthScore:o.Keywords.contentScore(o.ContentAnalysis.keywords(o.TinyMCE.getContent().text))},keywordHeadings:{length:o.Headings.keywords(o.Headings.getRealHeadingCount()),lengthScore:o.Keywords.headingScore(o.Headings.keywords(o.Headings.getRealHeadingCount()))},customKeyword:r.keywords.keyword}),r.text){var u,y=o.Headings.getRealHeadingCount(),h=r.text,w=!tinyMCE.activeEditor||tinyMCE.activeEditor.hidden?o.Words.words(t.settings.content.val()):o.Words.words(tinyMCE.activeEditor.getContent({format:"raw"}));i=t.settings.title.val().length,a=t.settings.description.val().length,u=o.Keywords.recommendedKeywords(w,1),_.isUndefined(u)||_.isUndefined(u[0])||o.Keywords.setPlaceholder(u[0][0]),_(n).extend({bgseo_meta:{title:{length:i,lengthScore:o.Title.titleScore(i)},description:{length:a,lengthScore:o.Description.descriptionScore(a),keywordUsage:o.Description.keywords()},titleKeywordUsage:{lengthScore:o.Keywords.titleScore(o.Title.keywords())},descKeywordUsage:{lengthScore:o.Keywords.descriptionScore(o.Description.keywords())},sectionScore:{},sectionStatus:{}},bgseo_visibility:{robotIndex:{lengthScore:o.Robots.indexScore()},robotFollow:{lengthScore:o.Robots.followScore()},sectionScore:{},sectionStatus:{}},bgseo_keywords:{keywordPhrase:{length:o.Keywords.phraseLength(o.Keywords.settings.keyword.val()),lengthScore:o.Keywords.keywordPhraseScore(o.Keywords.phraseLength(o.Keywords.settings.keyword.val()))},keywordTitle:{lengthScore:o.Keywords.titleScore(o.Title.keywords())},keywordDescription:{lengthScore:o.Keywords.descriptionScore(o.Description.keywords())},keywordContent:{lengthScore:o.Keywords.contentScore(o.ContentAnalysis.keywords(o.TinyMCE.getContent().text))},keywordHeadings:{length:o.Headings.keywords(y),lengthScore:o.Keywords.headingScore(o.Headings.keywords(y))},image:{length:n.rawstatistics.imageCount,lengthScore:o.ContentAnalysis.seoImageLengthScore(n.rawstatistics.imageCount)},headings:y,wordCount:{length:t.getWordCount(),lengthScore:o.ContentAnalysis.seoContentLengthScore(t.getWordCount())},sectionScore:{},sectionStatus:{}},textstatistics:{recommendedKeywords:u,recommendedCount:o.Keywords.getRecommendedCount(w),keywordDensity:o.Keywords.keywordDensity(h,o.Keywords.getKeyword())}})}r.titleLength&&(_(n.bgseo_meta.title).extend({length:r.titleLength,lengthScore:o.Title.titleScore(r.titleLength)}),_(n.bgseo_meta.titleKeywordUsage).extend({lengthScore:o.Keywords.titleScore(o.Title.keywords())}),_(n.bgseo_keywords.keywordTitle).extend({lengthScore:o.Keywords.titleScore(o.Title.keywords())}),t.settings.content.trigger("bgseo-analysis",[o.TinyMCE.getContent()])),r.descLength&&(_(n.bgseo_meta.description).extend({length:r.descLength,lengthScore:o.Description.descriptionScore(r.descLength)}),_(n.bgseo_meta.descKeywordUsage).extend({lengthScore:o.Keywords.descriptionScore(o.Description.keywords())}),_(n.bgseo_keywords.keywordDescription).extend({lengthScore:o.Keywords.descriptionScore(o.Description.keywords())}),t.settings.content.trigger("bgseo-analysis",[o.TinyMCE.getContent()])),r.robotIndex&&(_(n.bgseo_visibility.robotIndex).extend({lengthScore:r.robotIndex}),t.settings.content.trigger("bgseo-analysis",[o.TinyMCE.getContent()])),r.robotFollow&&(_(n.bgseo_visibility.robotFollow).extend({lengthScore:r.robotFollow}),t.settings.content.trigger("bgseo-analysis",[o.TinyMCE.getContent()]))}t.settings.content.trigger("bgseo-report",[n])})},get:function(e){var t={};return t=_.isUndefined(e)?n:_.pickDeep(n,e)}},t=o.Report}(jQuery);var BOLDGRID=BOLDGRID||{};BOLDGRID.SEO=BOLDGRID.SEO||{},function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Robots={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._index(),t._follow()},getSettings:function(){t.settings={indexInput:e("input[name=butterbean_boldgrid_seo_setting_bgseo_robots_index]"),noIndex:e('input[name=butterbean_boldgrid_seo_setting_bgseo_robots_index][value="noindex"]'),followInput:e("input[name=butterbean_boldgrid_seo_setting_bgseo_robots_follow]"),noFollow:e('input[name=butterbean_boldgrid_seo_setting_bgseo_robots_follow][value="nofollow"]')}},_index:function(){t.settings.indexInput.on("change",function(){e(this).trigger("bgseo-analysis",[{robotIndex:t.indexScore()}])})},indexScore:function(){var e;return e={status:"green",msg:_bgseoContentAnalysis.noIndex.good},t.settings.noIndex.is(":checked")&&(e={status:"red",msg:_bgseoContentAnalysis.noIndex.bad}),e},_follow:function(){t.settings.followInput.on("change",function(){e(this).trigger("bgseo-analysis",[{robotFollow:t.followScore()}])})},followScore:function(){var e={status:"green",msg:_bgseoContentAnalysis.noFollow.good};return t.settings.noFollow.is(":checked")&&(e={status:"yellow",msg:_bgseoContentAnalysis.noFollow.bad}),e}},t=o.Robots}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Sections={status:function(e){var t="green";return e.red>0?t="red":e.yellow>0&&(t="yellow"),t},score:function(e){var n,o,s;return n={red:0,green:0,yellow:0},o=_(e).countBy(function(t){return _.isUndefined(t.lengthScore)||"sectionScore"===_.property("sectionScore")(e)?"":t.lengthScore.status}),_(o).each(function(e,t){_.has(n,t)&&(n[t]=e)}),s={sectionScore:n,sectionStatus:t.status(n)}},removeStatus:function(e){e.removeClass("red yellow green")},navHighlight:function(n){_.each(butterbean.models.sections,function(o){var s,r=o.get("manager"),i=o.get("name");s=e('[href="#butterbean-'+r+"-section-"+i+'"]').closest("li"),t.removeStatus(s),s.addClass(n[i].sectionStatus)})},overviewStatus:function(n){var o=e("#butterbean-ui-boldgrid_seo.postbox > h2 > span:contains('Easy SEO')");t.removeStatus(o),o.addClass("overview-status "+n.bgseo_keywords.overview.status)}},t=o.Sections}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Title={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._title()},getSettings:function(){t.settings={title:e("#boldgrid-seo-field-meta_title")}},getTitle:function(){return t.settings.title},_title:function(){t.settings.title.on("input propertychange paste",_.debounce(function(){t.settings.title.trigger("bgseo-analysis",[{titleLength:t.settings.title.val().length}])},1e3))},titleScore:function(e){var t,n={};return t=_bgseoContentAnalysis.seoTitle.length,0===e&&(n={status:"red",msg:t.badEmpty}),e.isBetween(0,t.okScore+1)&&(n={status:"yellow",msg:t.ok}),e.isBetween(t.okScore-1,t.goodScore+1)&&(n={status:"green",msg:t.good}),e>t.goodScore&&(n={status:"red",msg:t.badLong}),n},keywords:function(e,n){return 0===arguments.length?(n=o.Keywords.getKeyword(),e=t.getTitle().val()):1===arguments.length&&(n=o.Keywords.getKeyword()),e=e.toLowerCase(),e.occurences(n)}},t=o.Title}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Tooltips={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t.hideTooltips(),t._enableTooltips(),t._toggleTooltip()},getSettings:function(){t.settings={description:e(".butterbean-control .butterbean-description"),tooltip:e("<span />",{"class":"bgseo-tooltip dashicons dashicons-editor-help","aria-expanded":"false"}),onClick:e(".butterbean-label, .bgseo-tooltip")}},_toggleTooltip:function(){t.settings.onClick.on("click",function(e){t.toggleTooltip(e)})},_enableTooltips:function(){t.settings.description.prev().append(t.settings.tooltip)},toggleTooltip:function(t){e(t.currentTarget).next(".butterbean-description").slideToggle()},hideTooltips:function(){t.settings.description.hide()}},t=o.Tooltips}(jQuery);var BOLDGRID=BOLDGRID||{};BOLDGRID.SEO=BOLDGRID.SEO||{},function(e){"use strict";var t;t=BOLDGRID.SEO,t.Init={load:function(){_.each(t,function(e){return e.init&&e.init()})}}}(jQuery),BOLDGRID.SEO.Init.load();
|
1 |
+
var BOLDGRID=BOLDGRID||{};BOLDGRID.SEO={report:{bgseo_visibility:{},bgseo_keywords:{},bgseo_meta:{},rawstatistics:{},textstatistics:{}}},function(e){"use strict";butterbean.views.register_control("dashboard",{tagName:"div",attributes:function(){return{id:"butterbean-control-"+this.model.get("name"),"class":"butterbean-control butterbean-control-"+this.model.get("type")}},initialize:function(){e(window).bind("bgseo-report",_.bind(this.setAnalysis,this)),this.bgseo_template=wp.template("butterbean-control-dashboard"),_.bindAll(this,"render"),this.model.bind("change",this.render)},results:function(e){var t={};return _.each(e,function(e){_.extend(t,e)}),t},setAnalysis:function(e,t){var n,o=this.model.get("section"),s=_.pick(t,o);this.sectionReport=this.results(s),this.model.set("analysis",this.sectionReport),_(t).each(function(e){_.isUndefined(e.sectionScore)||(n=BOLDGRID.SEO.Sections.score(e),_(e).extend(n))}),_(t.bgseo_keywords).extend({overview:{score:BOLDGRID.SEO.Dashboard.overviewScore(t)}}),_(t.bgseo_keywords.overview).extend({status:BOLDGRID.SEO.Dashboard.overviewStatus(t.bgseo_keywords.overview.score)}),BOLDGRID.SEO.Sections.navHighlight(t),BOLDGRID.SEO.Sections.overviewStatus(t)},render:function(){return this.model.get("active")&&(this.el.innerHTML=this.bgseo_template(this.model.toJSON())),this}})}(jQuery),function(e){"use strict";butterbean.views.register_control("keywords",{tagName:"div",attributes:function(){return{id:"butterbean-control-"+this.model.get("name"),"class":"butterbean-control butterbean-control-"+this.model.get("type")}},initialize:function(){e(window).bind("bgseo-report",_.bind(this.setAnalysis,this)),this.bgseo_template=wp.template("butterbean-control-keywords"),_.bindAll(this,"render"),this.model.bind("change",this.render)},setAnalysis:function(e,t){this.model.set(t)},render:function(){return this.model.get("active")&&(this.el.innerHTML=this.bgseo_template(this.model.toJSON())),this}})}(jQuery);var BOLDGRID=BOLDGRID||{};BOLDGRID.SEO=BOLDGRID.SEO||{},function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Util={init:function(){_.mixin({modifyObject:function(e,t){return _.object(_.map(e,function(e,n){return[n,t(e)]}))},pickDeep:function(e){var t={},n=Array.prototype.concat.apply(Array.prototype,Array.prototype.slice.call(arguments,1));return this.each(n,function(n){var o=n.split(".");n=o.shift(),n in e&&(o.length>0?t[n]?_.extend(t[n],_.pickDeep(e[n],o.join("."))):t[n]=_.pickDeep(e[n],o.join(".")):t[n]=e[n])}),t}}),Number.prototype.isBetween||(Number.prototype.isBetween=function(e,t){_.isUndefined(e)&&(e=0),_.isUndefined(t)&&(t=0);var n=Math.max(e,t),o=Math.min(e,t);return this>o&&this<n}),Number.prototype.rounded||(Number.prototype.rounded=function(e){_.isUndefined(e)&&(e=0);var t=Math.pow(10,e),n=Math.round(this*t)/t;return n}),String.prototype.printf||(String.prototype.printf=function(){for(var e=this,t=0;/%s/.test(e);)e=e.replace("%s",arguments[t++]);return e}),String.prototype.occurences||(String.prototype.occurences=function(e,t){if(e+="",e.length<=0)return this.length+1;for(var n=0,o=0,s=t?1:e.length;;){if(o=this.indexOf(e,o),!(o>=0))break;++n,o+=s}return n})}},t=o.Util}(jQuery),function(){"use strict";var e,t;t=BOLDGRID.SEO,t.Words={init:function(t){var n,o;if(t)for(n in t)t.hasOwnProperty(n)&&(e.settings[n]=t[n]);o=e.settings.l10n.shortcodes,o&&o.length&&(e.settings.shortcodesRegExp=new RegExp("\\[\\/?(?:"+o.join("|")+")[^\\]]*?\\]","g"))},settings:{HTMLRegExp:/<\/?[a-z][^>]*?>/gi,HTMLcommentRegExp:/<!--[\s\S]*?-->/g,spaceRegExp:/ | /gi,HTMLEntityRegExp:/&\S+?;/g,connectorRegExp:/--|\u2014/g,removeRegExp:new RegExp(["[","!-@[-`{-~","-¿×÷"," -⯿","⸀-","]"].join(""),"g"),astralRegExp:/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,wordsRegExp:/.+?\s+/g,characters_excluding_spacesRegExp:/\S/g,characters_including_spacesRegExp:/[^\f\n\r\t\v\u00AD\u2028\u2029]/g,l10n:window.wordCountL10n||{}},words:function(t,n){var o=0;return n=n||e.settings.l10n.type,"characters_excluding_spaces"!==n&&"characters_including_spaces"!==n&&(n="words"),t&&(t+="\n",t=t.replace(e.settings.HTMLRegExp,"\n"),t=t.replace(e.settings.HTMLcommentRegExp,""),e.settings.shortcodesRegExp&&(t=t.replace(e.settings.shortcodesRegExp,"\n")),t=t.replace(e.settings.spaceRegExp," "),"words"===n?(t=t.replace(e.settings.HTMLEntityRegExp,""),t=t.replace(e.settings.connectorRegExp," "),t=t.replace(e.settings.removeRegExp,"")):(t=t.replace(e.settings.HTMLEntityRegExp,"a"),t=t.replace(e.settings.astralRegExp,"a")),t=t.match(e.settings[n+"RegExp"]),t&&(o=t)),o}},e=t.Words}(),function(e,t){"use strict";var n,o;o=BOLDGRID.SEO,o.Wordcount={count:0,words:[],init:function(){e(n.update)},update:function(){var e,s,r=o.Editor.ui.getRawText();e=t.count(r),s=BOLDGRID.SEO.Words.words(r),e!==n.count&&o.Editor.element.trigger("bgseo-analysis",[{words:s,count:e}]),n.words=s,n.count=e}},n=o.Wordcount}(jQuery,new wp.utils.WordCounter),function(e){"use strict";var t;BOLDGRID.SEO.Admin={init:function(){e(document).ready(function(){t._setWordCounts()})},wordCount:function(n){var o=n.attr("maxlength"),s=e("<span />",{"class":"boldgrid-seo-meta-counter",style:"font-weight: bold"}),r=e("<div />",{"class":"boldgrid-seo-meta-countdown boldgrid-seo-meta-extra",html:" characters left"});o&&n.removeAttr("maxlength").after(r.prepend(s)).on("keyup focus",function(){t.setCounter(s,n,o)}),t.setCounter(s,n,o)},setCounter:function(e,t,n){var o=t.val(),s=o.length;e.html(n-s),"boldgrid-seo-field-meta_description"===t.context.id?s>n?e.css({color:"#EA4335"}):s.isBetween(0,_bgseoContentAnalysis.seoDescription.length.okScore)?e.css({color:"#FBBC05"}):s.isBetween(_bgseoContentAnalysis.seoDescription.length.okScore-1,_bgseoContentAnalysis.seoDescription.length.goodScore+1)?e.css({color:"#34A853"}):e.css({color:"black"}):s>n?e.css({color:"#EA4335"}):s.isBetween(0,_bgseoContentAnalysis.seoTitle.length.okScore)?e.css({color:"#FBBC05"}):s>_bgseoContentAnalysis.seoTitle.length.okScore-1?e.css({color:"#34A853"}):e.css({color:"black"})},_setWordCounts:function(){e("#boldgrid-seo-field-meta_title, #boldgrid-seo-field-meta_description").each(function(){t.wordCount(e(this))})}},t=BOLDGRID.SEO.Admin}(jQuery),function(e){"use strict";var t,n;n=BOLDGRID.SEO,n.TinyMCE={selector:"#content",previewSelector:"#preview-action > .preview.button",setup:function(){e(document).ready(function(){t._setupWordCount(),t.editorChange()})},getContent:function(){var t;tinymce.ActiveEditor?t=tinyMCE.get(wpActiveEditor).getContent():(t=n.Editor.element.val(),t=t.replace(/\r?\n|\r/g,""));var o=e.parseHTML(t);return t={raw:o,text:n.Editor.stripper(t.toLowerCase())}},getRawText:function(){var e,t=tinyMCE.get(wpActiveEditor);return e=!t||t.isHidden()?n.Editor.element.val():t.getContent({format:"raw"})},editorChange:function(){var n,o;return e("#content.wp-editor-area").on("input propertychange paste nodechange",function(){o=e(this).attr("id"),n=t.wpContent(o)}),n},tmceChange:function(e){var n,o;return o=e.target.id,n=t.wpContent(o)},isNewPost:function(){return!e("#sample-permalink").length},wpContent:function(t){var o={};switch(t){case"tinymce":tinymce.activeEditor&&(o=tinyMCE.get(wpActiveEditor).getContent());break;case"content":o=n.Editor.element.val(),o=o.replace(/\r?\n|\r/g,"")}var s=e.parseHTML(o);o={raw:s,text:n.Editor.stripper(o.toLowerCase())},n.Editor.element.trigger("bgseo-analysis",[o])},_setupWordCount:function(){var t=_.debounce(n.Wordcount.update,1e3);e(document).on("tinymce-editor-init",function(e,n){"content"===n.id&&n.on("AddUndo keyup",t)}),n.Editor.element.on("input keyup",t)}},t=n.TinyMCE}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.ContentAnalysis={seoContentLengthScore:function(e){var t,n,o={};return e=Number(e),t=_bgseoContentAnalysis.content.length,n=t.contentLength.printf(e)+" ",0===e&&(o={status:"red",msg:t.badEmpty}),e.isBetween(0,t.badShortScore)&&(o={status:"red",msg:n+t.badShort}),e.isBetween(t.badShortScore-1,t.okScore)&&(o={status:"yellow",msg:n+t.ok}),e>t.okScore-1&&(o={status:"green",msg:n+t.good}),o},seoImageLengthScore:function(e){var t={status:"green",msg:_bgseoContentAnalysis.image.length.good};return e||(t={status:"red",msg:_bgseoContentAnalysis.image.length.bad}),t},keywords:function(e){var t=o.Keywords.getKeyword();return e.occurences(t)}},t=o.ContentAnalysis}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Dashboard={overviewScore:function(e){var n,o=t.totalScore(e),s=_.size(butterbean.models.sections);return n=2*s,(o/n*100).rounded(2)},overviewStatus:function(e){var t;return t="green",e<40&&(t="red"),e.isBetween(39,76)&&(t="yellow"),t},getStatuses:function(e){var t={};return _.each(butterbean.models.sections,function(n){var o,s=n.get("name");o=e[s].sectionStatus,t[s]=o,_(t[s]).extend(o)}),t},assignNumbers:function(e){var n,o;return o=t.getStatuses(e),n=_.mapObject(o,function(e){var t;return"red"===e&&(t=0),"yellow"===e&&(t=1),"green"===e&&(t=2),t})},totalScore:function(e){var n,o=t.assignNumbers(e);return n=_(o).reduce(function(e,t){return e+t},0)}},t=o.Dashboard}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Description={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._description()},getSettings:function(){t.settings={description:e("#boldgrid-seo-field-meta_description")}},_description:function(){t.settings.description.on("input propertychange paste",_.debounce(function(){e(this).trigger("bgseo-analysis",[{descLength:t.settings.description.val().length}])},1e3))},getDescription:function(){return t.settings.description},descriptionScore:function(e){var t,n={};return t=_bgseoContentAnalysis.seoDescription.length,0===e&&(n={status:"red",msg:t.badEmpty}),e.isBetween(0,t.okScore)&&(n={status:"yellow",msg:t.ok}),e.isBetween(t.okScore-1,t.goodScore+1)&&(n={status:"green",msg:t.good}),e>t.goodScore&&(n={status:"red",msg:t.badLong}),n},keywords:function(){var e,n;return e=o.Keywords.getKeyword(),n=t.getDescription().val(),n=n.toLowerCase(),n.occurences(e)}},t=o.Description}(jQuery),function(e){"use strict";var t,n,o;n=BOLDGRID.SEO,o=n.report,n.Editor={ui:null,element:null,init:function(){t.ui=wp.data?n.Gutenberg:n.TinyMCE,t.element=e(t.ui.selector),t.ui.setup(),t.onloadContent()},onloadContent:function(){e("#content.wp-editor-area[aria-hidden=false]");e(window).on("load bgseo-media-inserted",function(){var e=t.ui.getContent();t.getRenderedContent(),_.defer(function(){t.element.trigger("bgseo-analysis",[e])})})},getRenderedContent:function(){var s,r;r=e(n.Editor.ui.previewSelector).attr("href"),n.Editor.ui.isNewPost()||e.get(r,function(r){var i,a,d;d=e(r),i=d.find("h1"),a=d.find("h2"),s={h1Count:i.length-o.rawstatistics.h1Count,h1text:_.filter(n.Headings.getHeadingText(i),function(e){return!_.findWhere(o.rawstatistics.h1text,e)}),h2Count:a.length-o.rawstatistics.h2Count,h2text:_.filter(n.Headings.getHeadingText(a),function(e){return!_.findWhere(o.rawstatistics.h2text,e)})},_.extend(o,{rendered:s}),t.triggerAnalysis()},"html")},stripper:function(e){var t;return t=document.implementation.createHTMLDocument("New").body,t.innerHTML=e,t.textContent||t.innerText||" "},triggerAnalysis:function(){t.element.trigger("bgseo-analysis",[t.ui.getContent()])}},t=n.Editor}(jQuery),function(e){"use strict";var t,n;n=BOLDGRID.SEO,n.Gutenberg={selector:"#editor",previewSelector:".editor-post-preview",setup:function(){e(n.Editor.triggerAnalysis),t._setupEditorChange()},isNewPost:function(){return wp.data.select("core/editor").isCleanNewPost()},getContent:function(){var e=t.getRawText();return e={raw:e,text:n.Editor.stripper(e.toLowerCase())}},getRawText:function(){return wp.data.select("core/editor").getEditedPostAttribute("content")},_setupEditorChange:function(){var e="";wp.data.subscribe(_.debounce(function(){t.getRawText()!==e&&(n.Wordcount.update(),n.Editor.triggerAnalysis(),e=t.getRawText())},1e3))}},t=n.Gutenberg}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Headings={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._checkbox()},getSettings:function(){t.settings={displayTitle:e('[name="boldgrid-display-post-title"]').last()}},_checkbox:function(){t.settings.displayTitle.on("change",_.debounce(function(){e(this).trigger("bgseo-analysis",[o.Editor.ui.getContent()])},1e3))},score:function(e){var n;return n={status:"green",msg:_bgseoContentAnalysis.headings.h1.good},e>1&&(n={status:"red",msg:_bgseoContentAnalysis.headings.h1.badMultiple}),e>1&&t.settings.displayTitle.is(":checked")&&(n={status:"red",msg:_bgseoContentAnalysis.headings.h1.badBoldgridTheme}),0===e&&(n={status:"red",msg:_bgseoContentAnalysis.headings.h1.badEmpty}),n},keywords:function(e){var n={length:0},s=o.Keywords.getKeyword();if(_.isUndefined(e)&&(e={count:t.getRealHeadingCount()}),!_.isEmpty(e))return _(e.count).each(function(e,t){var o=e.text;_(o).each(function(e){n.length=Number(n.length)+Number(e.heading.occurences(s)*e.count)})}),n.length},getHeadingText:function(t){var n={};return n=_.countBy(t,function(t,n){return e.trim(e(t).text().toLowerCase())}),n=_.map(n,function(e,t){return!_(n).has({heading:t,count:e})&&{heading:t,count:e}})},getRealHeadingCount:function(){var e={};return _.isUndefined(n.rendered)?e=t.getContentHeadings():(e={count:{h1:{length:n.rendered.h1Count+n.rawstatistics.h1Count,text:_(n.rendered.h1text).union(n.rawstatistics.h1text)},h2:{length:n.rendered.h2Count+n.rawstatistics.h2Count,text:_(n.rendered.h2text).union(n.rawstatistics.h2text)}}},_(e).extend({lengthScore:t.score(e.count.h1.length)})),e},getContentHeadings:function(){var n,s,r,i;return n={count:{h1:{length:0,text:{}},h2:{length:0,text:{}}}},i=o.Editor.ui.getContent(),i=e("<div>"+i.raw+"</div>"),s=i.find("h1"),r=i.find("h2"),s.length||r.length?n={count:{h1:{length:s.length,text:t.getHeadingText(s)},h2:{length:r.length,text:t.getHeadingText(r)}}}:n}},t=o.Headings}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Keywords={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._keywords(),t.setPlaceholder()},getSettings:function(){t.settings={keyword:e("#bgseo-custom-keyword"),content:o.Editor.element}},_keywords:function(){t.settings.keyword.on("input propertychange paste",_.debounce(function(){var e={};t.settings.keyword.val().length;e={keywords:{title:{length:o.Title.keywords(),lengthScore:0},description:{length:o.Description.keywords(),lengthScore:0},keyword:t.getCustomKeyword()}},t.settings.keyword.trigger("bgseo-analysis",[e])},1e3))},setPlaceholder:function(e){t.settings.keyword.attr("placeholder",e)},keywordCount:function(e,t){var n;return n=e.split(t).length-1},phraseLength:function(e){return 0===e.length?0:(e=e.replace(/(^\s*)|(\s*$)/gi,""),e=e.replace(/[ ]{2,}/gi," "),e=e.replace(/\n /,"\n"),e.split(" ").length)},keywordDensity:function(e){var n,s,r,i;return i=t.getKeyword(),_.isUndefined(i)?0:(i=i.toLowerCase(),s=t.keywordCount(e,i),r=o.Wordcount.count,n=s/r*100,n=Math.round(10*n)/10)},normalizeWords:function(e){return e.replace("'","")},trim:function(e){return e.trim()},recommendedKeywords:function(n,o){var s,r=_bgseoContentAnalysis.stopWords,i={},a=[];if(!_.isEmpty(n)){r=r.split(",").map(t.trim),r=r.map(t.normalizeWords);for(var d=0;d<n.length;d++){var g=e.trim(n[d]).toLowerCase();!g||g.length<3||r.indexOf(g)>-1||(_.isUndefined(i[g])?(i[g]=a.length,a.push([g,1])):a[i[g]][1]++)}return a.sort(function(e,t){return t[1]-e[1]}),s=a.slice(0,o)}},getCustomKeyword:function(){return e.trim(t.settings.keyword.val()).toLowerCase()},getKeyword:function(){var s,r=o.Editor.ui.getRawText();return t.getCustomKeyword().length?s=t.getCustomKeyword():_.isUndefined(n.textstatistics.recommendedKeywords)||_.isUndefined(n.textstatistics.recommendedKeywords[0])?_.isEmpty(e.trim(r.text))?s=void 0:t.recommendedKeywords(o.Words.words(r.raw),1):s=n.textstatistics.recommendedKeywords[0][0],s},getRecommendedCount:function(e){var t;return _.isUndefined(e)&&(e=o.Words.words(o.Editor.ui.getRawText())),t=_.modifyObject(_bgseoContentAnalysis.keywords.recommendedCount,function(t){var n=Number(t/100*o.Words.words(e).length).rounded(0);return n>0?n:1})},score:function(){var e={};return e={title:t.titleScore(),description:t.descriptionScore()}},titleScore:function(e){var t;return t={status:"green",msg:_bgseoContentAnalysis.seoTitle.keywordUsage.good},0===e&&(t={status:"red",msg:_bgseoContentAnalysis.seoTitle.keywordUsage.bad}),e>1&&(t={status:"yellow",msg:_bgseoContentAnalysis.seoTitle.keywordUsage.ok}),t},descriptionScore:function(e){var t;return t={status:"green",msg:_bgseoContentAnalysis.seoDescription.keywordUsage.good},0===e&&(t={status:"red",msg:_bgseoContentAnalysis.seoDescription.keywordUsage.bad}),e>1&&(t={status:"yellow",msg:_bgseoContentAnalysis.seoDescription.keywordUsage.ok}),t},contentScore:function(e){var n,o,s;return o=t.getRecommendedCount(),0===e&&(n={status:"red",msg:_bgseoContentAnalysis.content.keywordUsage.bad}),e.isBetween(o.min-1,o.max+1)&&(s=1===o.min?_bgseoContentAnalysis.content.keywordUsage.goodSingular:_bgseoContentAnalysis.content.keywordUsage.good.printf(o.min),n={status:"green",msg:s}),e<o.min&&0!==e&&(s=1===o.min?_bgseoContentAnalysis.content.keywordUsage.okShortSingular:_bgseoContentAnalysis.content.keywordUsage.okShort.printf(o.min),n={status:"yellow",msg:s}),e>o.max&&(s=1===o.min?_bgseoContentAnalysis.content.keywordUsage.okLongSingular:_bgseoContentAnalysis.content.keywordUsage.okLong.printf(o.min),n={status:"red",msg:s}),n},headingScore:function(e){var t;return t={status:"green",msg:_bgseoContentAnalysis.headings.keywordUsage.good},0===e&&(t={status:"red",msg:_bgseoContentAnalysis.headings.keywordUsage.bad}),e>3&&(t={status:"yellow",msg:_bgseoContentAnalysis.headings.keywordUsage.ok}),t},keywordPhraseScore:function(e){var t;return t={status:"green",msg:_bgseoContentAnalysis.keywords.keywordPhrase.good},1===e&&(t={status:"yellow",msg:_bgseoContentAnalysis.keywords.keywordPhrase.ok}),0===e&&(t={status:"red",msg:_bgseoContentAnalysis.keywords.keywordPhrase.bad}),t}},t=o.Keywords}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Readability={gradeLevel:function(e){var n,o={};return n=textstatistics(e).fleschKincaidReadingEase(),o=t.gradeAnalysis(n)},gradeAnalysis:function(e){var t,n={};return e>90&&(n={score:e,gradeLevel:"5th grade",explanation:"Very easy to read. Easily understood by an average 11-year-old student.",lengthScore:{status:"green",msg:_bgseoContentAnalysis.readingEase.goodHigh}}),e.isBetween(79,91)&&(n={score:e,gradeLevel:"6th grade",explanation:"Easy to read. Conversational English for consumers.",lengthScore:{status:"green",msg:_bgseoContentAnalysis.readingEase.goodMedHigh}}),e.isBetween(69,81)&&(n={score:e,gradeLevel:"7th grade",explanation:"Fairly easy to read.",lengthScore:{status:"green",msg:_bgseoContentAnalysis.readingEase.goodMedLow}}),e.isBetween(59,71)&&(n={score:e,gradeLevel:"8th & 9th",explanation:"Plain English. Easily understood by 13- to 15-year-old students.",lengthScore:{status:"green",msg:_bgseoContentAnalysis.readingEase.goodLow}}),e.isBetween(49,61)&&(n={score:e,gradeLevel:"10th to 12th",explanation:"Fairly difficult to read.",lengthScore:{status:"yellow",msg:_bgseoContentAnalysis.readingEase.ok}}),e.isBetween(29,51)&&(n={score:e,gradeLevel:"College Student",explanation:"Difficult to read.",lengthScore:{status:"red",msg:_bgseoContentAnalysis.readingEase.badHigh}}),e<30&&(n={score:e,gradeLevel:"College Graduate",explanation:"Difficult to read.",lengthScore:{status:"red",msg:_bgseoContentAnalysis.readingEase.badLow}}),t=_bgseoContentAnalysis.readingEase.score.printf(e)+" ",n.lengthScore.msg=n.lengthScore.msg.replace(/^/,t),n}},t=o.Readability}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Report={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t.generateReport()},getSettings:function(){t.settings={title:e("#boldgrid-seo-field-meta_title"),description:e("#boldgrid-seo-field-meta_description")}},generateReport:function(){_.isUndefined(t.settings)||e(document).on("bgseo-analysis",function(s,r){var i,a;if(i=t.settings.title.val().length,a=t.settings.description.val().length,r.words&&_(n.textstatistics).extend({recommendedKeywords:o.Keywords.recommendedKeywords(r.words,1),customKeyword:o.Keywords.getKeyword()}),r){if(r.raw){var d=e("<div>"+r.raw+"</div>"),g=d.find("h1"),c=d.find("h2"),l={};l={h1Count:g.length,h1text:o.Headings.getHeadingText(g),h2Count:c.length,h2text:o.Headings.getHeadingText(c),imageCount:d.find("img").length},_(n.rawstatistics).extend(l)}if(r.keywords&&_(n.bgseo_keywords).extend({keywordPhrase:{length:o.Keywords.phraseLength(o.Keywords.settings.keyword.val()),lengthScore:o.Keywords.keywordPhraseScore(o.Keywords.phraseLength(o.Keywords.settings.keyword.val()))},keywordTitle:{lengthScore:o.Keywords.titleScore(o.Title.keywords())},keywordDescription:{lengthScore:o.Keywords.descriptionScore(o.Description.keywords())},keywordContent:{lengthScore:o.Keywords.contentScore(o.ContentAnalysis.keywords(o.Editor.ui.getContent().text))},keywordHeadings:{length:o.Headings.keywords(o.Headings.getRealHeadingCount()),lengthScore:o.Keywords.headingScore(o.Headings.keywords(o.Headings.getRealHeadingCount()))},customKeyword:r.keywords.keyword}),r.text){var u,y=o.Headings.getRealHeadingCount(),h=r.text,w=o.Editor.ui.getRawText();i=t.settings.title.val().length,a=t.settings.description.val().length,u=o.Keywords.recommendedKeywords(w,1),_.isUndefined(u)||_.isUndefined(u[0])||o.Keywords.setPlaceholder(u[0][0]),_(n).extend({bgseo_meta:{title:{length:i,lengthScore:o.Title.titleScore(i)},description:{length:a,lengthScore:o.Description.descriptionScore(a),keywordUsage:o.Description.keywords()},titleKeywordUsage:{lengthScore:o.Keywords.titleScore(o.Title.keywords())},descKeywordUsage:{lengthScore:o.Keywords.descriptionScore(o.Description.keywords())},sectionScore:{},sectionStatus:{}},bgseo_visibility:{robotIndex:{lengthScore:o.Robots.indexScore()},robotFollow:{lengthScore:o.Robots.followScore()},sectionScore:{},sectionStatus:{}},bgseo_keywords:{keywordPhrase:{length:o.Keywords.phraseLength(o.Keywords.settings.keyword.val()),lengthScore:o.Keywords.keywordPhraseScore(o.Keywords.phraseLength(o.Keywords.settings.keyword.val()))},keywordTitle:{lengthScore:o.Keywords.titleScore(o.Title.keywords())},keywordDescription:{lengthScore:o.Keywords.descriptionScore(o.Description.keywords())},keywordContent:{lengthScore:o.Keywords.contentScore(o.ContentAnalysis.keywords(o.Editor.ui.getContent().text))},keywordHeadings:{length:o.Headings.keywords(y),lengthScore:o.Keywords.headingScore(o.Headings.keywords(y))},image:{length:n.rawstatistics.imageCount,lengthScore:o.ContentAnalysis.seoImageLengthScore(n.rawstatistics.imageCount)},headings:y,wordCount:{length:o.Wordcount.count,lengthScore:o.ContentAnalysis.seoContentLengthScore(o.Wordcount.count)},sectionScore:{},sectionStatus:{}},textstatistics:{recommendedKeywords:u,recommendedCount:o.Keywords.getRecommendedCount(w),keywordDensity:o.Keywords.keywordDensity(h,o.Keywords.getKeyword())}})}r.titleLength&&(_(n.bgseo_meta.title).extend({length:r.titleLength,lengthScore:o.Title.titleScore(r.titleLength)}),_(n.bgseo_meta.titleKeywordUsage).extend({lengthScore:o.Keywords.titleScore(o.Title.keywords())}),_(n.bgseo_keywords.keywordTitle).extend({lengthScore:o.Keywords.titleScore(o.Title.keywords())}),o.Editor.triggerAnalysis()),r.descLength&&(_(n.bgseo_meta.description).extend({length:r.descLength,lengthScore:o.Description.descriptionScore(r.descLength)}),_(n.bgseo_meta.descKeywordUsage).extend({lengthScore:o.Keywords.descriptionScore(o.Description.keywords())}),_(n.bgseo_keywords.keywordDescription).extend({lengthScore:o.Keywords.descriptionScore(o.Description.keywords())}),o.Editor.triggerAnalysis()),r.robotIndex&&(_(n.bgseo_visibility.robotIndex).extend({lengthScore:r.robotIndex}),o.Editor.triggerAnalysis()),r.robotFollow&&(_(n.bgseo_visibility.robotFollow).extend({lengthScore:r.robotFollow}),o.Editor.triggerAnalysis())}o.Editor.element.trigger("bgseo-report",[n])})},get:function(e){var t={};return t=_.isUndefined(e)?n:_.pickDeep(n,e)}},t=o.Report}(jQuery);var BOLDGRID=BOLDGRID||{};BOLDGRID.SEO=BOLDGRID.SEO||{},function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Robots={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._index(),t._follow()},getSettings:function(){t.settings={indexInput:e("input[name=butterbean_boldgrid_seo_setting_bgseo_robots_index]"),noIndex:e('input[name=butterbean_boldgrid_seo_setting_bgseo_robots_index][value="noindex"]'),followInput:e("input[name=butterbean_boldgrid_seo_setting_bgseo_robots_follow]"),noFollow:e('input[name=butterbean_boldgrid_seo_setting_bgseo_robots_follow][value="nofollow"]')}},_index:function(){t.settings.indexInput.on("change",function(){e(this).trigger("bgseo-analysis",[{robotIndex:t.indexScore()}])})},indexScore:function(){var e;return e={status:"green",msg:_bgseoContentAnalysis.noIndex.good},t.settings.noIndex.is(":checked")&&(e={status:"red",msg:_bgseoContentAnalysis.noIndex.bad}),e},_follow:function(){t.settings.followInput.on("change",function(){e(this).trigger("bgseo-analysis",[{robotFollow:t.followScore()}])})},followScore:function(){var e={status:"green",msg:_bgseoContentAnalysis.noFollow.good};return t.settings.noFollow.is(":checked")&&(e={status:"yellow",msg:_bgseoContentAnalysis.noFollow.bad}),e}},t=o.Robots}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Sections={status:function(e){var t="green";return e.red>0?t="red":e.yellow>0&&(t="yellow"),t},score:function(e){var n,o,s;return n={red:0,green:0,yellow:0},o=_(e).countBy(function(t){return _.isUndefined(t.lengthScore)||"sectionScore"===_.property("sectionScore")(e)?"":t.lengthScore.status}),_(o).each(function(e,t){_.has(n,t)&&(n[t]=e)}),s={sectionScore:n,sectionStatus:t.status(n)}},removeStatus:function(e){e.removeClass("red yellow green")},navHighlight:function(n){_.each(butterbean.models.sections,function(o){var s,r=o.get("manager"),i=o.get("name");s=e('[href="#butterbean-'+r+"-section-"+i+'"]').closest("li"),t.removeStatus(s),s.addClass(n[i].sectionStatus)})},overviewStatus:function(n){var o=e("#butterbean-ui-boldgrid_seo.postbox > h2 > span:contains('Easy SEO')");t.removeStatus(o),o.addClass("overview-status "+n.bgseo_keywords.overview.status)}},t=o.Sections}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Title={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t._title()},getSettings:function(){t.settings={title:e("#boldgrid-seo-field-meta_title")}},getTitle:function(){return t.settings.title},_title:function(){t.settings.title.on("input propertychange paste",_.debounce(function(){t.settings.title.trigger("bgseo-analysis",[{titleLength:t.settings.title.val().length}])},1e3))},titleScore:function(e){var t,n={};return t=_bgseoContentAnalysis.seoTitle.length,0===e&&(n={status:"red",msg:t.badEmpty}),e.isBetween(0,t.okScore+1)&&(n={status:"yellow",msg:t.ok}),e.isBetween(t.okScore-1,t.goodScore+1)&&(n={status:"green",msg:t.good}),e>t.goodScore&&(n={status:"red",msg:t.badLong}),n},keywords:function(e,n){return 0===arguments.length?(n=o.Keywords.getKeyword(),e=t.getTitle().val()):1===arguments.length&&(n=o.Keywords.getKeyword()),e=e.toLowerCase(),e.occurences(n)}},t=o.Title}(jQuery),function(e){"use strict";var t,n,o;o=BOLDGRID.SEO,n=o.report,o.Tooltips={init:function(){e(document).ready(t.onReady)},onReady:function(){t.getSettings(),t.hideTooltips(),t._enableTooltips(),t._toggleTooltip()},getSettings:function(){t.settings={description:e(".butterbean-control .butterbean-description"),tooltip:e("<span />",{"class":"bgseo-tooltip dashicons dashicons-editor-help","aria-expanded":"false"}),onClick:e(".butterbean-label, .bgseo-tooltip")}},_toggleTooltip:function(){t.settings.onClick.on("click",function(e){t.toggleTooltip(e)})},_enableTooltips:function(){t.settings.description.prev().append(t.settings.tooltip)},toggleTooltip:function(t){e(t.currentTarget).next(".butterbean-description").slideToggle()},hideTooltips:function(){t.settings.description.hide()}},t=o.Tooltips}(jQuery);var BOLDGRID=BOLDGRID||{};BOLDGRID.SEO=BOLDGRID.SEO||{},function(e){"use strict";var t;t=BOLDGRID.SEO,t.Init={load:function(){_.each(t,function(e){return e.init&&e.init()})}}}(jQuery),BOLDGRID.SEO.Init.load();
|
assets/js/bgseo/boldgrid-seo-editor.js
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
( function ( $ ) {
|
2 |
+
|
3 |
+
'use strict';
|
4 |
+
|
5 |
+
var self, api, report;
|
6 |
+
|
7 |
+
api = BOLDGRID.SEO;
|
8 |
+
report = api.report;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* BoldGrid Editor Interface.
|
12 |
+
*
|
13 |
+
* This class allows us to control which editor interface functions will run.
|
14 |
+
* On first load the it runs the setup method of whichever ui is currently loaded.
|
15 |
+
* It then assigns that ui to this classes ui variable for cross api use.
|
16 |
+
*
|
17 |
+
* @since 1.6.0
|
18 |
+
*/
|
19 |
+
api.Editor = {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Interface loaded.
|
23 |
+
*
|
24 |
+
* @since 1.6.0
|
25 |
+
*
|
26 |
+
* @type {object} seo.tinymce or seo-Gutenberg
|
27 |
+
*/
|
28 |
+
ui: null,
|
29 |
+
|
30 |
+
/**
|
31 |
+
* WP Element to use to trigger events.
|
32 |
+
*
|
33 |
+
* @since 1.6.0
|
34 |
+
*
|
35 |
+
* @type {$} Editor jQuery Element.
|
36 |
+
*/
|
37 |
+
element: null,
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Setup the correct editor interface.
|
41 |
+
*
|
42 |
+
* @since 1.3.1
|
43 |
+
*/
|
44 |
+
init : function () {
|
45 |
+
self.ui = wp.data ? api.Gutenberg : api.TinyMCE;
|
46 |
+
self.element = $( self.ui.selector );
|
47 |
+
self.ui.setup();
|
48 |
+
self.onloadContent();
|
49 |
+
},
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Runs actions on window load to prepare for analysis.
|
53 |
+
*
|
54 |
+
* This method gets the current editor in use by the user on the
|
55 |
+
* initial page load ( text editor or visual editor ), and also
|
56 |
+
* is responsible for creating the iframe preview of the page/post
|
57 |
+
* so we can get the raw html in use by the template/theme the user
|
58 |
+
* has activated.
|
59 |
+
*
|
60 |
+
* @since 1.3.1
|
61 |
+
*/
|
62 |
+
onloadContent : function() {
|
63 |
+
var text,
|
64 |
+
editor = $( '#content.wp-editor-area[aria-hidden=false]' );
|
65 |
+
|
66 |
+
$( window ).on( 'load bgseo-media-inserted', function() {
|
67 |
+
var content = self.ui.getContent();
|
68 |
+
|
69 |
+
// Get rendered page content from frontend site.
|
70 |
+
self.getRenderedContent();
|
71 |
+
|
72 |
+
// Trigger the content analysis for the content.
|
73 |
+
_.defer( function() {
|
74 |
+
self.element.trigger( 'bgseo-analysis', [content] );
|
75 |
+
} );
|
76 |
+
} );
|
77 |
+
},
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Only ajax for preview if permalink is available. This only
|
81 |
+
* impacts "New" page and posts. To counter
|
82 |
+
* this we will disable the checks made until the content has had
|
83 |
+
* a chance to be updated. We will store the found headings minus
|
84 |
+
* the initial found headings in the content, so we know what the
|
85 |
+
* template has in use on the actual rendered page.
|
86 |
+
*
|
87 |
+
* @since 1.3.1
|
88 |
+
*
|
89 |
+
* @returns null No return.
|
90 |
+
*/
|
91 |
+
getRenderedContent : function() {
|
92 |
+
var renderedContent, preview;
|
93 |
+
|
94 |
+
// Get the preview url from WordPress.
|
95 |
+
preview = $( api.Editor.ui.previewSelector ).attr( 'href' );
|
96 |
+
|
97 |
+
if ( ! api.Editor.ui.isNewPost() ) {
|
98 |
+
// Only run this once after the initial iframe has loaded to get current template stats.
|
99 |
+
$.get( preview, function( renderedTemplate ) {
|
100 |
+
var headings, h1, h2, $rendered;
|
101 |
+
|
102 |
+
// The rendered page content.
|
103 |
+
$rendered = $( renderedTemplate );
|
104 |
+
|
105 |
+
// H1's that appear in rendered content.
|
106 |
+
h1 = $rendered.find( 'h1' );
|
107 |
+
// HS's that appear in rendered content.
|
108 |
+
h2 = $rendered.find( 'h2' );
|
109 |
+
|
110 |
+
// The rendered content stats.
|
111 |
+
renderedContent = {
|
112 |
+
h1Count : h1.length - report.rawstatistics.h1Count,
|
113 |
+
h1text : _.filter( api.Headings.getHeadingText( h1 ), function( obj ){
|
114 |
+
return ! _.findWhere( report.rawstatistics.h1text, obj );
|
115 |
+
}),
|
116 |
+
h2Count : h2.length - report.rawstatistics.h2Count,
|
117 |
+
h2text : _.filter( api.Headings.getHeadingText( h2 ), function( obj ){
|
118 |
+
return ! _.findWhere( report.rawstatistics.h2text, obj );
|
119 |
+
}),
|
120 |
+
};
|
121 |
+
|
122 |
+
// Add the rendered stats to our report for use later.
|
123 |
+
_.extend( report, { rendered : renderedContent } );
|
124 |
+
|
125 |
+
// Trigger the SEO report to rebuild in the template after initial stats are created.
|
126 |
+
self.triggerAnalysis();
|
127 |
+
|
128 |
+
}, 'html' );
|
129 |
+
}
|
130 |
+
},
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Strips out unwanted html.
|
134 |
+
*
|
135 |
+
* This is helpful in removing the remaining traces of HTML
|
136 |
+
* that is sometimes leftover to form our clean text output and
|
137 |
+
* run our text analysis on.
|
138 |
+
*
|
139 |
+
* @since 1.3.1
|
140 |
+
*
|
141 |
+
* @returns {string} The content with any remaining html removed.
|
142 |
+
*/
|
143 |
+
stripper : function( html ) {
|
144 |
+
var tmp;
|
145 |
+
|
146 |
+
tmp = document.implementation.createHTMLDocument( 'New' ).body;
|
147 |
+
tmp.innerHTML = html;
|
148 |
+
|
149 |
+
return tmp.textContent || tmp.innerText || " ";
|
150 |
+
},
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Fire an event that will force, analysis to run.
|
154 |
+
*
|
155 |
+
* @since 1.6.0
|
156 |
+
*/
|
157 |
+
triggerAnalysis: function() {
|
158 |
+
self.element.trigger( 'bgseo-analysis', [ self.ui.getContent() ] );
|
159 |
+
}
|
160 |
+
};
|
161 |
+
|
162 |
+
self = api.Editor;
|
163 |
+
|
164 |
+
})( jQuery );
|
assets/js/bgseo/boldgrid-seo-gutenberg.js
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
( function ( $ ) {
|
2 |
+
|
3 |
+
'use strict';
|
4 |
+
|
5 |
+
var self, api;
|
6 |
+
|
7 |
+
api = BOLDGRID.SEO;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* BoldGrid Gutenberg Analysis.
|
11 |
+
*
|
12 |
+
* This is responsible for generating the actual reports
|
13 |
+
* displayed within the BoldGrid SEO Dashboard when the user
|
14 |
+
* is on a page or a post.
|
15 |
+
*
|
16 |
+
* @since 1.3.1
|
17 |
+
*/
|
18 |
+
api.Gutenberg = {
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Selector to find editor id.
|
22 |
+
*
|
23 |
+
* This is only used to trigger events. No dom content queries in Gutenberg context.
|
24 |
+
*
|
25 |
+
* @since 1.6.0
|
26 |
+
*
|
27 |
+
* @type {String}
|
28 |
+
*/
|
29 |
+
selector : '#editor',
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Selector to find preview button.
|
33 |
+
*
|
34 |
+
* @since 1.6.0
|
35 |
+
*
|
36 |
+
* @type {String}
|
37 |
+
*/
|
38 |
+
previewSelector : '.editor-post-preview',
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Initialize Content.
|
42 |
+
*
|
43 |
+
* @since 1.6.0
|
44 |
+
*/
|
45 |
+
setup : function () {
|
46 |
+
$( api.Editor.triggerAnalysis );
|
47 |
+
self._setupEditorChange();
|
48 |
+
},
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Are we currently on a new post?
|
52 |
+
*
|
53 |
+
* @since 1.6.0
|
54 |
+
*
|
55 |
+
* @return {boolean} Is this a post-new.php?
|
56 |
+
*/
|
57 |
+
isNewPost : function() {
|
58 |
+
return wp.data.select( 'core/editor' ).isCleanNewPost();
|
59 |
+
},
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Gets the content from the editor for analysis.
|
63 |
+
*
|
64 |
+
* @since 1.6.0
|
65 |
+
*
|
66 |
+
* @returns {Object} content Contains content in raw and text formats.
|
67 |
+
*/
|
68 |
+
getContent : function() {
|
69 |
+
var content = self.getRawText();
|
70 |
+
|
71 |
+
// Stores raw and stripped down versions of the content for analysis.
|
72 |
+
content = {
|
73 |
+
'raw': content,
|
74 |
+
'text': api.Editor.stripper( content.toLowerCase() ),
|
75 |
+
};
|
76 |
+
|
77 |
+
return content;
|
78 |
+
},
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Get the raw text from the editor.
|
82 |
+
*
|
83 |
+
* @since 1.6.0
|
84 |
+
*
|
85 |
+
* @return {string} Editor content.
|
86 |
+
*/
|
87 |
+
getRawText : function () {
|
88 |
+
return wp.data.select( 'core/editor' ).getEditedPostAttribute( 'content' );
|
89 |
+
},
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Listens for changes made in the text editor mode.
|
93 |
+
*
|
94 |
+
* @since 1.6.0
|
95 |
+
*
|
96 |
+
* @returns {string} text The new content to perform analysis on.
|
97 |
+
*/
|
98 |
+
_setupEditorChange: function() {
|
99 |
+
var latestContent = '';
|
100 |
+
|
101 |
+
wp.data.subscribe( _.debounce( function () {
|
102 |
+
|
103 |
+
// Make sure content is different before running analysis.
|
104 |
+
if ( self.getRawText() !== latestContent ) {
|
105 |
+
api.Wordcount.update();
|
106 |
+
api.Editor.triggerAnalysis();
|
107 |
+
latestContent = self.getRawText();
|
108 |
+
}
|
109 |
+
}, 1000 ) );
|
110 |
+
}
|
111 |
+
};
|
112 |
+
|
113 |
+
self = api.Gutenberg;
|
114 |
+
|
115 |
+
})( jQuery );
|
assets/js/bgseo/boldgrid-seo-headings.js
CHANGED
@@ -56,7 +56,7 @@
|
|
56 |
_checkbox : function() {
|
57 |
// Listen for changes to input value.
|
58 |
self.settings.displayTitle.on( 'change', _.debounce( function() {
|
59 |
-
$( this ).trigger( 'bgseo-analysis', [ api.
|
60 |
}, 1000 ) );
|
61 |
},
|
62 |
|
@@ -228,10 +228,11 @@
|
|
228 |
},
|
229 |
};
|
230 |
|
231 |
-
content = api.
|
|
|
232 |
|
233 |
-
h1s =
|
234 |
-
h2s =
|
235 |
|
236 |
// If no h1s or h2s are found return the defaults.
|
237 |
if ( ! h1s.length && ! h2s.length ) return headings;
|
56 |
_checkbox : function() {
|
57 |
// Listen for changes to input value.
|
58 |
self.settings.displayTitle.on( 'change', _.debounce( function() {
|
59 |
+
$( this ).trigger( 'bgseo-analysis', [ api.Editor.ui.getContent() ] );
|
60 |
}, 1000 ) );
|
61 |
},
|
62 |
|
228 |
},
|
229 |
};
|
230 |
|
231 |
+
content = api.Editor.ui.getContent();
|
232 |
+
content = $( '<div>' + content.raw + '</div>' );
|
233 |
|
234 |
+
h1s = content.find( 'h1' );
|
235 |
+
h2s = content.find( 'h2' );
|
236 |
|
237 |
// If no h1s or h2s are found return the defaults.
|
238 |
if ( ! h1s.length && ! h2s.length ) return headings;
|
assets/js/bgseo/boldgrid-seo-keywords.js
CHANGED
@@ -43,7 +43,7 @@
|
|
43 |
getSettings : function() {
|
44 |
self.settings = {
|
45 |
keyword : $( '#bgseo-custom-keyword' ),
|
46 |
-
content :
|
47 |
};
|
48 |
},
|
49 |
|
@@ -150,7 +150,7 @@
|
|
150 |
keyword = keyword.toLowerCase();
|
151 |
|
152 |
keywordCount = self.keywordCount( content, keyword );
|
153 |
-
wordCount = api.
|
154 |
// Get the density.
|
155 |
result = ( ( keywordCount / wordCount ) * 100 );
|
156 |
// Round it off.
|
@@ -268,7 +268,7 @@
|
|
268 |
*/
|
269 |
getKeyword : function() {
|
270 |
var customKeyword,
|
271 |
-
content = api.
|
272 |
|
273 |
if ( self.getCustomKeyword().length ) {
|
274 |
customKeyword = self.getCustomKeyword();
|
@@ -300,9 +300,7 @@
|
|
300 |
var count;
|
301 |
|
302 |
if ( _.isUndefined( markup ) ) {
|
303 |
-
markup =
|
304 |
-
api.Words.words( self.settings.content.val() ) :
|
305 |
-
api.Words.words( tinyMCE.activeEditor.getContent({ format : 'raw' }) );
|
306 |
}
|
307 |
|
308 |
count = _.modifyObject( _bgseoContentAnalysis.keywords.recommendedCount, function( item ) {
|
43 |
getSettings : function() {
|
44 |
self.settings = {
|
45 |
keyword : $( '#bgseo-custom-keyword' ),
|
46 |
+
content : api.Editor.element,
|
47 |
};
|
48 |
},
|
49 |
|
150 |
keyword = keyword.toLowerCase();
|
151 |
|
152 |
keywordCount = self.keywordCount( content, keyword );
|
153 |
+
wordCount = api.Wordcount.count;
|
154 |
// Get the density.
|
155 |
result = ( ( keywordCount / wordCount ) * 100 );
|
156 |
// Round it off.
|
268 |
*/
|
269 |
getKeyword : function() {
|
270 |
var customKeyword,
|
271 |
+
content = api.Editor.ui.getRawText();
|
272 |
|
273 |
if ( self.getCustomKeyword().length ) {
|
274 |
customKeyword = self.getCustomKeyword();
|
300 |
var count;
|
301 |
|
302 |
if ( _.isUndefined( markup ) ) {
|
303 |
+
markup = api.Words.words( api.Editor.ui.getRawText() );
|
|
|
|
|
304 |
}
|
305 |
|
306 |
count = _.modifyObject( _bgseoContentAnalysis.keywords.recommendedCount, function( item ) {
|
assets/js/bgseo/boldgrid-seo-report.js
CHANGED
@@ -8,7 +8,7 @@
|
|
8 |
report = api.report;
|
9 |
|
10 |
/**
|
11 |
-
* BoldGrid
|
12 |
*
|
13 |
* This is responsible for generating the actual reports
|
14 |
* displayed within the BoldGrid SEO Dashboard when the user
|
@@ -19,7 +19,7 @@
|
|
19 |
api.Report = {
|
20 |
|
21 |
/**
|
22 |
-
* Initialize
|
23 |
*
|
24 |
* @since 1.3.1
|
25 |
*/
|
@@ -45,16 +45,10 @@
|
|
45 |
getSettings : function() {
|
46 |
self.settings = {
|
47 |
title : $( '#boldgrid-seo-field-meta_title' ),
|
48 |
-
description : $( '#boldgrid-seo-field-meta_description' )
|
49 |
-
wordCounter : $( '#wp-word-count .word-count' ),
|
50 |
-
content : $( '#content' ),
|
51 |
};
|
52 |
},
|
53 |
|
54 |
-
getWordCount : function() {
|
55 |
-
return Number( self.settings.wordCounter.text() );
|
56 |
-
},
|
57 |
-
|
58 |
/**
|
59 |
* Generate the Report based on analysis done.
|
60 |
*
|
@@ -86,10 +80,10 @@
|
|
86 |
if ( eventInfo ) {
|
87 |
// Listen for changes to raw HTML in editor.
|
88 |
if ( eventInfo.raw ) {
|
89 |
-
var raws = eventInfo.raw;
|
90 |
|
91 |
-
var h1 = $
|
92 |
-
h2 = $
|
93 |
headings = {};
|
94 |
|
95 |
headings = {
|
@@ -97,7 +91,7 @@
|
|
97 |
h1text : api.Headings.getHeadingText( h1 ),
|
98 |
h2Count : h2.length,
|
99 |
h2text : api.Headings.getHeadingText( h2 ),
|
100 |
-
imageCount: $
|
101 |
};
|
102 |
// Set the heading counts and image count found in new content update.
|
103 |
_( report.rawstatistics ).extend( headings );
|
@@ -116,7 +110,7 @@
|
|
116 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
117 |
},
|
118 |
keywordContent : {
|
119 |
-
lengthScore : api.Keywords.contentScore( api.ContentAnalysis.keywords( api.
|
120 |
},
|
121 |
keywordHeadings : {
|
122 |
length : api.Headings.keywords( api.Headings.getRealHeadingCount() ),
|
@@ -130,7 +124,7 @@
|
|
130 |
if ( eventInfo.text ) {
|
131 |
var kw, headingCount = api.Headings.getRealHeadingCount(),
|
132 |
content = eventInfo.text,
|
133 |
-
raw =
|
134 |
|
135 |
// Get length of title field.
|
136 |
titleLength = self.settings.title.val().length;
|
@@ -188,7 +182,7 @@
|
|
188 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
189 |
},
|
190 |
keywordContent : {
|
191 |
-
lengthScore : api.Keywords.contentScore( api.ContentAnalysis.keywords( api.
|
192 |
},
|
193 |
keywordHeadings : {
|
194 |
length : api.Headings.keywords( headingCount ),
|
@@ -200,8 +194,8 @@
|
|
200 |
},
|
201 |
headings : headingCount,
|
202 |
wordCount : {
|
203 |
-
length :
|
204 |
-
lengthScore : api.ContentAnalysis.seoContentLengthScore(
|
205 |
},
|
206 |
sectionScore: {},
|
207 |
sectionStatus: {},
|
@@ -230,7 +224,7 @@
|
|
230 |
_( report.bgseo_keywords.keywordTitle ).extend({
|
231 |
lengthScore : api.Keywords.titleScore( api.Title.keywords() ),
|
232 |
});
|
233 |
-
|
234 |
}
|
235 |
|
236 |
// Listen to changes to the SEO Description and update report.
|
@@ -248,7 +242,7 @@
|
|
248 |
_( report.bgseo_keywords.keywordDescription ).extend({
|
249 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
250 |
});
|
251 |
-
|
252 |
}
|
253 |
|
254 |
// Listen for changes to noindex/index and update report.
|
@@ -256,7 +250,7 @@
|
|
256 |
_( report.bgseo_visibility.robotIndex ).extend({
|
257 |
lengthScore : eventInfo.robotIndex,
|
258 |
});
|
259 |
-
|
260 |
}
|
261 |
|
262 |
// Listen for changes to nofollow/follow and update report.
|
@@ -264,12 +258,12 @@
|
|
264 |
_( report.bgseo_visibility.robotFollow ).extend({
|
265 |
lengthScore : eventInfo.robotFollow,
|
266 |
});
|
267 |
-
|
268 |
}
|
269 |
}
|
270 |
|
271 |
// Send the final analysis to display the report.
|
272 |
-
|
273 |
});
|
274 |
},
|
275 |
|
8 |
report = api.report;
|
9 |
|
10 |
/**
|
11 |
+
* BoldGrid Editor Content Analysis.
|
12 |
*
|
13 |
* This is responsible for generating the actual reports
|
14 |
* displayed within the BoldGrid SEO Dashboard when the user
|
19 |
api.Report = {
|
20 |
|
21 |
/**
|
22 |
+
* Initialize Content.
|
23 |
*
|
24 |
* @since 1.3.1
|
25 |
*/
|
45 |
getSettings : function() {
|
46 |
self.settings = {
|
47 |
title : $( '#boldgrid-seo-field-meta_title' ),
|
48 |
+
description : $( '#boldgrid-seo-field-meta_description' )
|
|
|
|
|
49 |
};
|
50 |
},
|
51 |
|
|
|
|
|
|
|
|
|
52 |
/**
|
53 |
* Generate the Report based on analysis done.
|
54 |
*
|
80 |
if ( eventInfo ) {
|
81 |
// Listen for changes to raw HTML in editor.
|
82 |
if ( eventInfo.raw ) {
|
83 |
+
var $raws = $( '<div>' + eventInfo.raw + '</div>' );
|
84 |
|
85 |
+
var h1 = $raws.find( 'h1' ),
|
86 |
+
h2 = $raws.find( 'h2' ),
|
87 |
headings = {};
|
88 |
|
89 |
headings = {
|
91 |
h1text : api.Headings.getHeadingText( h1 ),
|
92 |
h2Count : h2.length,
|
93 |
h2text : api.Headings.getHeadingText( h2 ),
|
94 |
+
imageCount: $raws.find( 'img' ).length,
|
95 |
};
|
96 |
// Set the heading counts and image count found in new content update.
|
97 |
_( report.rawstatistics ).extend( headings );
|
110 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
111 |
},
|
112 |
keywordContent : {
|
113 |
+
lengthScore : api.Keywords.contentScore( api.ContentAnalysis.keywords( api.Editor.ui.getContent().text ) ),
|
114 |
},
|
115 |
keywordHeadings : {
|
116 |
length : api.Headings.keywords( api.Headings.getRealHeadingCount() ),
|
124 |
if ( eventInfo.text ) {
|
125 |
var kw, headingCount = api.Headings.getRealHeadingCount(),
|
126 |
content = eventInfo.text,
|
127 |
+
raw = api.Editor.ui.getRawText();
|
128 |
|
129 |
// Get length of title field.
|
130 |
titleLength = self.settings.title.val().length;
|
182 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
183 |
},
|
184 |
keywordContent : {
|
185 |
+
lengthScore : api.Keywords.contentScore( api.ContentAnalysis.keywords( api.Editor.ui.getContent().text ) ),
|
186 |
},
|
187 |
keywordHeadings : {
|
188 |
length : api.Headings.keywords( headingCount ),
|
194 |
},
|
195 |
headings : headingCount,
|
196 |
wordCount : {
|
197 |
+
length : api.Wordcount.count,
|
198 |
+
lengthScore : api.ContentAnalysis.seoContentLengthScore( api.Wordcount.count ),
|
199 |
},
|
200 |
sectionScore: {},
|
201 |
sectionStatus: {},
|
224 |
_( report.bgseo_keywords.keywordTitle ).extend({
|
225 |
lengthScore : api.Keywords.titleScore( api.Title.keywords() ),
|
226 |
});
|
227 |
+
api.Editor.triggerAnalysis();
|
228 |
}
|
229 |
|
230 |
// Listen to changes to the SEO Description and update report.
|
242 |
_( report.bgseo_keywords.keywordDescription ).extend({
|
243 |
lengthScore : api.Keywords.descriptionScore( api.Description.keywords() ),
|
244 |
});
|
245 |
+
api.Editor.triggerAnalysis();
|
246 |
}
|
247 |
|
248 |
// Listen for changes to noindex/index and update report.
|
250 |
_( report.bgseo_visibility.robotIndex ).extend({
|
251 |
lengthScore : eventInfo.robotIndex,
|
252 |
});
|
253 |
+
api.Editor.triggerAnalysis();
|
254 |
}
|
255 |
|
256 |
// Listen for changes to nofollow/follow and update report.
|
258 |
_( report.bgseo_visibility.robotFollow ).extend({
|
259 |
lengthScore : eventInfo.robotFollow,
|
260 |
});
|
261 |
+
api.Editor.triggerAnalysis();
|
262 |
}
|
263 |
}
|
264 |
|
265 |
// Send the final analysis to display the report.
|
266 |
+
api.Editor.element.trigger( 'bgseo-report', [ report ] );
|
267 |
});
|
268 |
},
|
269 |
|
assets/js/bgseo/boldgrid-seo-tinymce.js
CHANGED
@@ -2,10 +2,9 @@
|
|
2 |
|
3 |
'use strict';
|
4 |
|
5 |
-
var self,
|
6 |
|
7 |
api = BOLDGRID.SEO;
|
8 |
-
report = api.report;
|
9 |
|
10 |
/**
|
11 |
* BoldGrid TinyMCE Analysis.
|
@@ -19,42 +18,32 @@
|
|
19 |
api.TinyMCE = {
|
20 |
|
21 |
/**
|
22 |
-
*
|
23 |
*
|
24 |
-
* @since 1.
|
|
|
|
|
25 |
*/
|
26 |
-
|
27 |
-
self.onloadContent();
|
28 |
-
$( document ).ready( function() {
|
29 |
-
self.editorChange();
|
30 |
-
});
|
31 |
-
},
|
32 |
|
33 |
/**
|
34 |
-
*
|
35 |
*
|
36 |
-
*
|
37 |
-
* initial page load ( text editor or visual editor ), and also
|
38 |
-
* is responsible for creating the iframe preview of the page/post
|
39 |
-
* so we can get the raw html in use by the template/theme the user
|
40 |
-
* has activated.
|
41 |
*
|
42 |
-
* @
|
43 |
*/
|
44 |
-
|
45 |
-
var text,
|
46 |
-
editor = $( '#content.wp-editor-area[aria-hidden=false]' );
|
47 |
-
|
48 |
-
$( window ).on( 'load bgseo-media-inserted', function() {
|
49 |
-
var content = self.getContent();
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
58 |
});
|
59 |
},
|
60 |
|
@@ -67,11 +56,11 @@
|
|
67 |
*/
|
68 |
getContent : function() {
|
69 |
var content;
|
70 |
-
|
71 |
if ( tinymce.ActiveEditor ) {
|
72 |
content = tinyMCE.get( wpActiveEditor ).getContent();
|
73 |
} else {
|
74 |
-
content =
|
75 |
// Remove newlines and carriage returns.
|
76 |
content = content.replace( /\r?\n|\r/g, '' );
|
77 |
}
|
@@ -81,64 +70,33 @@
|
|
81 |
// Stores raw and stripped down versions of the content for analysis.
|
82 |
content = {
|
83 |
'raw': rawContent,
|
84 |
-
'text':
|
85 |
};
|
86 |
|
87 |
return content;
|
88 |
},
|
89 |
|
|
|
90 |
/**
|
91 |
-
*
|
92 |
-
* impacts "New" page and posts. To counter
|
93 |
-
* this we will disable the checks made until the content has had
|
94 |
-
* a chance to be updated. We will store the found headings minus
|
95 |
-
* the initial found headings in the content, so we know what the
|
96 |
-
* template has in use on the actual rendered page.
|
97 |
*
|
98 |
-
* @since 1.
|
99 |
*
|
100 |
-
* @
|
101 |
*/
|
102 |
-
|
103 |
-
var
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
$.get( preview, function( renderedTemplate ) {
|
111 |
-
var headings, h1, h2, $rendered;
|
112 |
-
|
113 |
-
// The rendered page content.
|
114 |
-
$rendered = $( renderedTemplate );
|
115 |
-
|
116 |
-
// H1's that appear in rendered content.
|
117 |
-
h1 = $rendered.find( 'h1' );
|
118 |
-
// HS's that appear in rendered content.
|
119 |
-
h2 = $rendered.find( 'h2' );
|
120 |
-
|
121 |
-
// The rendered content stats.
|
122 |
-
renderedContent = {
|
123 |
-
h1Count : h1.length - report.rawstatistics.h1Count,
|
124 |
-
h1text : _.filter( api.Headings.getHeadingText( h1 ), function( obj ){
|
125 |
-
return ! _.findWhere( report.rawstatistics.h1text, obj );
|
126 |
-
}),
|
127 |
-
h2Count : h2.length - report.rawstatistics.h2Count,
|
128 |
-
h2text : _.filter( api.Headings.getHeadingText( h2 ), function( obj ){
|
129 |
-
return ! _.findWhere( report.rawstatistics.h2text, obj );
|
130 |
-
}),
|
131 |
-
};
|
132 |
-
|
133 |
-
// Add the rendered stats to our report for use later.
|
134 |
-
_.extend( report, { rendered : renderedContent } );
|
135 |
-
|
136 |
-
// Trigger the SEO report to rebuild in the template after initial stats are created.
|
137 |
-
$( '#content' ).trigger( 'bgseo-analysis', [ self.getContent() ] );
|
138 |
-
|
139 |
-
}, 'html' );
|
140 |
}
|
|
|
|
|
141 |
},
|
|
|
142 |
/**
|
143 |
* Listens for changes made in the text editor mode.
|
144 |
*
|
@@ -172,6 +130,17 @@
|
|
172 |
return text;
|
173 |
},
|
174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
/**
|
176 |
* Checks which editor is the active editor.
|
177 |
*
|
@@ -192,7 +161,7 @@
|
|
192 |
text = tinyMCE.get( wpActiveEditor ).getContent();
|
193 |
break;
|
194 |
case 'content' :
|
195 |
-
text =
|
196 |
text = text.replace( /\r?\n|\r/g, '' );
|
197 |
break;
|
198 |
}
|
@@ -202,32 +171,32 @@
|
|
202 |
|
203 |
text = {
|
204 |
'raw': rawText,
|
205 |
-
'text':
|
206 |
};
|
207 |
|
208 |
// Trigger the text analysis for report.
|
209 |
-
|
210 |
},
|
211 |
|
212 |
/**
|
213 |
-
*
|
214 |
*
|
215 |
-
*
|
216 |
-
* that is sometimes leftover to form our clean text output and
|
217 |
-
* run our text analysis on.
|
218 |
-
*
|
219 |
-
* @since 1.3.1
|
220 |
-
*
|
221 |
-
* @returns {string} The content with any remaining html removed.
|
222 |
*/
|
223 |
-
|
224 |
-
var
|
225 |
|
226 |
-
|
227 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
|
229 |
-
return tmp.textContent || tmp.innerText || " ";
|
230 |
-
},
|
231 |
};
|
232 |
|
233 |
self = api.TinyMCE;
|
2 |
|
3 |
'use strict';
|
4 |
|
5 |
+
var self, api;
|
6 |
|
7 |
api = BOLDGRID.SEO;
|
|
|
8 |
|
9 |
/**
|
10 |
* BoldGrid TinyMCE Analysis.
|
18 |
api.TinyMCE = {
|
19 |
|
20 |
/**
|
21 |
+
* Selector to find editor id.
|
22 |
*
|
23 |
+
* @since 1.6.0
|
24 |
+
*
|
25 |
+
* @type {String}
|
26 |
*/
|
27 |
+
selector : '#content',
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
/**
|
30 |
+
* Selector to find preview button.
|
31 |
*
|
32 |
+
* @since 1.6.0
|
|
|
|
|
|
|
|
|
33 |
*
|
34 |
+
* @type {String}
|
35 |
*/
|
36 |
+
previewSelector : '#preview-action > .preview.button',
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
+
/**
|
39 |
+
* Initialize TinyMCE Content.
|
40 |
+
*
|
41 |
+
* @since 1.3.1
|
42 |
+
*/
|
43 |
+
setup : function () {
|
44 |
+
$( document ).ready( function() {
|
45 |
+
self._setupWordCount();
|
46 |
+
self.editorChange();
|
47 |
});
|
48 |
},
|
49 |
|
56 |
*/
|
57 |
getContent : function() {
|
58 |
var content;
|
59 |
+
|
60 |
if ( tinymce.ActiveEditor ) {
|
61 |
content = tinyMCE.get( wpActiveEditor ).getContent();
|
62 |
} else {
|
63 |
+
content = api.Editor.element.val();
|
64 |
// Remove newlines and carriage returns.
|
65 |
content = content.replace( /\r?\n|\r/g, '' );
|
66 |
}
|
70 |
// Stores raw and stripped down versions of the content for analysis.
|
71 |
content = {
|
72 |
'raw': rawContent,
|
73 |
+
'text': api.Editor.stripper( content.toLowerCase() ),
|
74 |
};
|
75 |
|
76 |
return content;
|
77 |
},
|
78 |
|
79 |
+
|
80 |
/**
|
81 |
+
* Get the raw text from the editor.
|
|
|
|
|
|
|
|
|
|
|
82 |
*
|
83 |
+
* @since 1.6.0
|
84 |
*
|
85 |
+
* @return {string} Editor content.
|
86 |
*/
|
87 |
+
getRawText: function() {
|
88 |
+
var text,
|
89 |
+
contentEditor = tinyMCE.get( wpActiveEditor );
|
90 |
+
|
91 |
+
if ( ! contentEditor || contentEditor.isHidden() ) {
|
92 |
+
text = api.Editor.element.val();
|
93 |
+
} else {
|
94 |
+
text = contentEditor.getContent( { format: 'raw' } );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
+
|
97 |
+
return text;
|
98 |
},
|
99 |
+
|
100 |
/**
|
101 |
* Listens for changes made in the text editor mode.
|
102 |
*
|
130 |
return text;
|
131 |
},
|
132 |
|
133 |
+
/**
|
134 |
+
* Is this a new Post?
|
135 |
+
*
|
136 |
+
* @since 1.6.0
|
137 |
+
*
|
138 |
+
* @return {boolean} Is this post-new.php?
|
139 |
+
*/
|
140 |
+
isNewPost : function () {
|
141 |
+
return ! $( '#sample-permalink' ).length;
|
142 |
+
},
|
143 |
+
|
144 |
/**
|
145 |
* Checks which editor is the active editor.
|
146 |
*
|
161 |
text = tinyMCE.get( wpActiveEditor ).getContent();
|
162 |
break;
|
163 |
case 'content' :
|
164 |
+
text = api.Editor.element.val();
|
165 |
text = text.replace( /\r?\n|\r/g, '' );
|
166 |
break;
|
167 |
}
|
171 |
|
172 |
text = {
|
173 |
'raw': rawText,
|
174 |
+
'text': api.Editor.stripper( text.toLowerCase() ),
|
175 |
};
|
176 |
|
177 |
// Trigger the text analysis for report.
|
178 |
+
api.Editor.element.trigger( 'bgseo-analysis', [text] );
|
179 |
},
|
180 |
|
181 |
/**
|
182 |
+
* Bind events to the editor input and update the wordcount class.
|
183 |
*
|
184 |
+
* @since 1.6.0
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
*/
|
186 |
+
_setupWordCount : function() {
|
187 |
+
var debouncedCb = _.debounce( api.Wordcount.update, 1000 );
|
188 |
|
189 |
+
$( document ).on( 'tinymce-editor-init', function( event, editor ) {
|
190 |
+
if ( editor.id !== 'content' ) {
|
191 |
+
return;
|
192 |
+
}
|
193 |
+
|
194 |
+
editor.on( 'AddUndo keyup', debouncedCb );
|
195 |
+
} );
|
196 |
+
|
197 |
+
api.Editor.element.on( 'input keyup', debouncedCb );
|
198 |
+
}
|
199 |
|
|
|
|
|
200 |
};
|
201 |
|
202 |
self = api.TinyMCE;
|
assets/js/bgseo/boldgrid-seo-wordcount.js
CHANGED
@@ -1,46 +1,67 @@
|
|
1 |
( function( $, counter ) {
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
-
$count = $( '#wp-word-count' ).find( '.word-count' ),
|
7 |
-
prevCount = 0,
|
8 |
-
contentEditor,
|
9 |
-
words;
|
10 |
|
11 |
-
|
12 |
-
var text, count;
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
19 |
|
20 |
-
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
-
|
36 |
-
|
37 |
-
editor.on( 'nodechange keyup', _.debounce( update, 1000 ) );
|
38 |
-
} );
|
39 |
|
40 |
-
|
|
|
|
|
41 |
|
42 |
-
|
|
|
|
|
|
|
43 |
|
44 |
-
|
45 |
|
46 |
} )( jQuery, new wp.utils.WordCounter() );
|
1 |
( function( $, counter ) {
|
2 |
|
3 |
+
'use strict';
|
4 |
|
5 |
+
var self, api;
|
|
|
|
|
|
|
|
|
6 |
|
7 |
+
api = BOLDGRID.SEO;
|
|
|
8 |
|
9 |
+
/**
|
10 |
+
* Handle tracking of wordcount.
|
11 |
+
*
|
12 |
+
* @since 1.6.0
|
13 |
+
*/
|
14 |
+
api.Wordcount = {
|
15 |
|
16 |
+
/**
|
17 |
+
* Number of words in the content.
|
18 |
+
*
|
19 |
+
* @since 1.6.0
|
20 |
+
*
|
21 |
+
* @type {Number}
|
22 |
+
*/
|
23 |
+
count: 0,
|
24 |
|
25 |
+
/**
|
26 |
+
* List of words on the page.
|
27 |
+
*
|
28 |
+
* @since 1.6.0
|
29 |
+
*
|
30 |
+
* @type {array}
|
31 |
+
*/
|
32 |
+
words: [],
|
33 |
|
34 |
+
/**
|
35 |
+
* When the page loads, run the update methods.
|
36 |
+
*
|
37 |
+
* @since 1.6.0
|
38 |
+
*/
|
39 |
+
init : function () {
|
40 |
+
$( self.update );
|
41 |
+
},
|
42 |
|
43 |
+
/**
|
44 |
+
* Update this classes word count metrics.
|
45 |
+
*
|
46 |
+
* @since 1.6.0
|
47 |
+
*/
|
48 |
+
update : function () {
|
49 |
+
var count,
|
50 |
+
words,
|
51 |
+
text = api.Editor.ui.getRawText();
|
52 |
|
53 |
+
count = counter.count( text );
|
54 |
+
words = BOLDGRID.SEO.Words.words( text );
|
|
|
|
|
55 |
|
56 |
+
if ( count !== self.count ) {
|
57 |
+
api.Editor.element.trigger( 'bgseo-analysis', [{ words : words, count : count }] );
|
58 |
+
}
|
59 |
|
60 |
+
self.words = words;
|
61 |
+
self.count = count;
|
62 |
+
}
|
63 |
+
};
|
64 |
|
65 |
+
self = api.Wordcount;
|
66 |
|
67 |
} )( jQuery, new wp.utils.WordCounter() );
|
assets/js/text-statistics/README.md
CHANGED
@@ -6,10 +6,8 @@ JavaScript port of [TextStatistics.php](https://github.com/DaveChild/Text-Statis
|
|
6 |
I've done what I think is a reasonably faithful port. Documentation incoming!
|
7 |
I removed a lot of the original comments during the port, but seeing as the API remained largely the same, I'll add them in shortly.
|
8 |
|
9 |
-
|
10 |
|
11 |
## Installation
|
12 |
|
13 |
-
Run this in the browser using a simple `<script>` include - or you can install for node with `npm install text-statistics`.
|
14 |
-
|
15 |
-
**[Famous! As seen in Time!](http://time.com/2958650/twitter-reading-level/)** (heh.)
|
6 |
I've done what I think is a reasonably faithful port. Documentation incoming!
|
7 |
I removed a lot of the original comments during the port, but seeing as the API remained largely the same, I'll add them in shortly.
|
8 |
|
9 |
+
Same goes for a test suite - I'll get something working in node in a bit. :)
|
10 |
|
11 |
## Installation
|
12 |
|
13 |
+
Run this in the browser using a simple `<script>` include - or you can install for node with `npm install text-statistics`.
|
|
|
|
assets/js/text-statistics/index.js
CHANGED
@@ -12,23 +12,21 @@
|
|
12 |
|
13 |
fullStopTags.forEach(function(tag) {
|
14 |
text = text.replace("</" + tag + ">",".");
|
15 |
-
})
|
16 |
|
17 |
text = text
|
18 |
.replace(/<[^>]+>/g, "") // Strip tags
|
19 |
-
.replace(/[,:;()
|
20 |
-
.replace(/[\.!?]
|
21 |
-
.replace(/^\s+/,
|
22 |
-
.replace(/[
|
23 |
-
.replace(/[
|
24 |
-
.replace(/([\.])
|
25 |
-
.replace(
|
26 |
-
.replace(/\s
|
27 |
-
.replace(/\s+$/, ""); // Strip trailing whitespace
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
}
|
32 |
return text;
|
33 |
}
|
34 |
|
@@ -86,7 +84,7 @@
|
|
86 |
|
87 |
TextStatistics.prototype.wordCount = function(text) {
|
88 |
text = text ? cleanText(text) : this.text;
|
89 |
-
return text.split(/[^a-z0-9
|
90 |
};
|
91 |
|
92 |
TextStatistics.prototype.averageWordsPerSentence = function(text) {
|
@@ -147,7 +145,7 @@
|
|
147 |
};
|
148 |
|
149 |
// Return if we've hit one of those...
|
150 |
-
if (problemWords
|
151 |
|
152 |
// These syllables would be counted as two but should be one
|
153 |
var subSyllables = [
|
@@ -212,7 +210,7 @@
|
|
212 |
wordPartCount = word
|
213 |
.split(/[^aeiouy]+/ig)
|
214 |
.filter(function(wordPart) {
|
215 |
-
return !!wordPart.replace(/\s+/ig,"").length
|
216 |
})
|
217 |
.length;
|
218 |
|
@@ -236,4 +234,4 @@
|
|
236 |
}
|
237 |
|
238 |
(typeof module != "undefined" && module.exports) ? (module.exports = textStatistics) : (typeof define != "undefined" ? (define("textstatistics", [], function() { return textStatistics; })) : (glob.textstatistics = textStatistics));
|
239 |
-
})(this);
|
12 |
|
13 |
fullStopTags.forEach(function(tag) {
|
14 |
text = text.replace("</" + tag + ">",".");
|
15 |
+
})
|
16 |
|
17 |
text = text
|
18 |
.replace(/<[^>]+>/g, "") // Strip tags
|
19 |
+
.replace(/[,:;()\-]/, " ") // Replace commans, hyphens etc (count them as spaces)
|
20 |
+
.replace(/[\.!?]/, ".") // Unify terminators
|
21 |
+
.replace(/^\s+/,"") // Strip leading whitespace
|
22 |
+
.replace(/[ ]*(\n|\r\n|\r)[ ]*/," ") // Replace new lines with spaces
|
23 |
+
.replace(/([\.])[\. ]+/,".") // Check for duplicated terminators
|
24 |
+
.replace(/[ ]*([\.])/,". ") // Pad sentence terminators
|
25 |
+
.replace(/\s+/," ") // Remove multiple spaces
|
26 |
+
.replace(/\s+$/,""); // Strip trailing whitespace
|
|
|
27 |
|
28 |
+
text += "."; // Add final terminator, just in case it's missing.
|
29 |
+
|
|
|
30 |
return text;
|
31 |
}
|
32 |
|
84 |
|
85 |
TextStatistics.prototype.wordCount = function(text) {
|
86 |
text = text ? cleanText(text) : this.text;
|
87 |
+
return text.split(/[^a-z0-9]+/i).length || 1;
|
88 |
};
|
89 |
|
90 |
TextStatistics.prototype.averageWordsPerSentence = function(text) {
|
145 |
};
|
146 |
|
147 |
// Return if we've hit one of those...
|
148 |
+
if (problemWords[word]) return problemWords[word];
|
149 |
|
150 |
// These syllables would be counted as two but should be one
|
151 |
var subSyllables = [
|
210 |
wordPartCount = word
|
211 |
.split(/[^aeiouy]+/ig)
|
212 |
.filter(function(wordPart) {
|
213 |
+
return !!wordPart.replace(/\s+/ig,"").length
|
214 |
})
|
215 |
.length;
|
216 |
|
234 |
}
|
235 |
|
236 |
(typeof module != "undefined" && module.exports) ? (module.exports = textStatistics) : (typeof define != "undefined" ? (define("textstatistics", [], function() { return textStatistics; })) : (glob.textstatistics = textStatistics));
|
237 |
+
})(this);
|
boldgrid-easy-seo.php
CHANGED
@@ -14,8 +14,8 @@
|
|
14 |
* Plugin Name: BoldGrid Easy SEO
|
15 |
* Plugin URI: https://www.boldgrid.com/boldgrid-seo/
|
16 |
* Description: Easily manage your website's search engine optimization with Easy SEO by BoldGrid!
|
17 |
-
* Version: 1.
|
18 |
-
* Author: BoldGrid
|
19 |
* Author URI: https://www.boldgrid.com/
|
20 |
* License: GPL-2.0+
|
21 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
14 |
* Plugin Name: BoldGrid Easy SEO
|
15 |
* Plugin URI: https://www.boldgrid.com/boldgrid-seo/
|
16 |
* Description: Easily manage your website's search engine optimization with Easy SEO by BoldGrid!
|
17 |
+
* Version: 1.6.0-rc.1
|
18 |
+
* Author: BoldGrid <support@boldgrid.com>
|
19 |
* Author URI: https://www.boldgrid.com/
|
20 |
* License: GPL-2.0+
|
21 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
includes/class-boldgrid-seo-butterbean.php
CHANGED
@@ -67,11 +67,15 @@ class Boldgrid_Seo_Butterbean {
|
|
67 |
/* === Register Settings === */
|
68 |
$manager->register_setting(
|
69 |
'bgseo_title',
|
70 |
-
array( 'sanitize_callback' =>
|
|
|
|
|
71 |
);
|
72 |
$manager->register_setting(
|
73 |
'bgseo_description',
|
74 |
-
array( 'sanitize_callback' =>
|
|
|
|
|
75 |
);
|
76 |
$manager->register_setting(
|
77 |
'bgseo_canonical',
|
@@ -93,7 +97,9 @@ class Boldgrid_Seo_Butterbean {
|
|
93 |
);
|
94 |
$manager->register_setting(
|
95 |
'bgseo_custom_keyword',
|
96 |
-
array( 'sanitize_callback' =>
|
|
|
|
|
97 |
);
|
98 |
|
99 |
}
|
67 |
/* === Register Settings === */
|
68 |
$manager->register_setting(
|
69 |
'bgseo_title',
|
70 |
+
array( 'sanitize_callback' => function( $setting ) {
|
71 |
+
return wp_specialchars_decode( wp_filter_nohtml_kses ( $setting ) );
|
72 |
+
} )
|
73 |
);
|
74 |
$manager->register_setting(
|
75 |
'bgseo_description',
|
76 |
+
array( 'sanitize_callback' => function( $setting ) {
|
77 |
+
return wp_specialchars_decode( wp_kses_post( $setting ) );
|
78 |
+
} )
|
79 |
);
|
80 |
$manager->register_setting(
|
81 |
'bgseo_canonical',
|
97 |
);
|
98 |
$manager->register_setting(
|
99 |
'bgseo_custom_keyword',
|
100 |
+
array( 'sanitize_callback' => function( $setting ) {
|
101 |
+
return wp_specialchars_decode( wp_filter_nohtml_kses ( $setting ) );
|
102 |
+
} )
|
103 |
);
|
104 |
|
105 |
}
|
includes/configs/i18n/seoDescription.config.php
CHANGED
@@ -7,12 +7,12 @@ return array(
|
|
7 |
'</a>'
|
8 |
),
|
9 |
/* translators: 1: opening <a> tag 2: closing </a> tag */
|
10 |
-
'badLong' => sprintf( __( 'Your custom %1$sSEO Description%2$s is over the
|
11 |
'<a href="https://www.boldgrid.com/support/seo/title-and-description#description" target="_blank">',
|
12 |
'</a>'
|
13 |
),
|
14 |
/* translators: 1: opening <a> tag 2: closing </a> tag */
|
15 |
-
'ok' => sprintf( __( 'You should make your %1$sSEO Description%2$s longer! We recommend 125-
|
16 |
'<a href="https://www.boldgrid.com/support/seo/title-and-description#description" target="_blank">',
|
17 |
'</a>'
|
18 |
),
|
@@ -24,7 +24,7 @@ return array(
|
|
24 |
// Max value.
|
25 |
'okScore' => 125,
|
26 |
// Max value.
|
27 |
-
'goodScore' =>
|
28 |
),
|
29 |
'keywordUsage' => array(
|
30 |
/* translators: 1: opening <a> tag 2: closing </a> tag */
|
7 |
'</a>'
|
8 |
),
|
9 |
/* translators: 1: opening <a> tag 2: closing </a> tag */
|
10 |
+
'badLong' => sprintf( __( 'Your custom %1$sSEO Description%2$s is over the 300 character recommended length, you should consider making it shorter.', 'bgseo' ),
|
11 |
'<a href="https://www.boldgrid.com/support/seo/title-and-description#description" target="_blank">',
|
12 |
'</a>'
|
13 |
),
|
14 |
/* translators: 1: opening <a> tag 2: closing </a> tag */
|
15 |
+
'ok' => sprintf( __( 'You should make your %1$sSEO Description%2$s longer! We recommend 125-300 characters for the best results.', 'bgseo' ),
|
16 |
'<a href="https://www.boldgrid.com/support/seo/title-and-description#description" target="_blank">',
|
17 |
'</a>'
|
18 |
),
|
24 |
// Max value.
|
25 |
'okScore' => 125,
|
26 |
// Max value.
|
27 |
+
'goodScore' => 300,
|
28 |
),
|
29 |
'keywordUsage' => array(
|
30 |
/* translators: 1: opening <a> tag 2: closing </a> tag */
|
includes/configs/meta-box.config.php
CHANGED
@@ -51,7 +51,7 @@ return array(
|
|
51 |
'attr' => array(
|
52 |
'id' => 'boldgrid-seo-field-meta_description',
|
53 |
'placeholder' => $this->util->meta_description(),
|
54 |
-
'maxlength' => '
|
55 |
'class' => 'widefat',
|
56 |
),
|
57 |
'label' => __( 'SEO Description', 'bgseo' ),
|
51 |
'attr' => array(
|
52 |
'id' => 'boldgrid-seo-field-meta_description',
|
53 |
'placeholder' => $this->util->meta_description(),
|
54 |
+
'maxlength' => '300',
|
55 |
'class' => 'widefat',
|
56 |
),
|
57 |
'label' => __( 'SEO Description', 'bgseo' ),
|
languages/bgseo.pot
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
# Copyright (C)
|
2 |
# This file is distributed under the same license as the bgseo package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
@@ -7,7 +7,7 @@ msgstr ""
|
|
7 |
"MIME-Version: 1.0\n"
|
8 |
"Content-Type: text/plain; charset=UTF-8\n"
|
9 |
"Content-Transfer-Encoding: 8bit\n"
|
10 |
-
"PO-Revision-Date:
|
11 |
"Language-Team: The BoldGrid Team <support@boldgrid.com>\n"
|
12 |
"X-Poedit-Basepath: ..\n"
|
13 |
"X-Poedit-SourceCharset: UTF-8\n"
|
@@ -181,11 +181,11 @@ msgid "Your custom %1$sSEO Description%2$s is empty! Try adding a description w
|
|
181 |
msgstr ""
|
182 |
|
183 |
#: includes/configs/i18n/seoDescription.config.php:10
|
184 |
-
msgid "Your custom %1$sSEO Description%2$s is over the
|
185 |
msgstr ""
|
186 |
|
187 |
#: includes/configs/i18n/seoDescription.config.php:15
|
188 |
-
msgid "You should make your %1$sSEO Description%2$s longer! We recommend 125-
|
189 |
msgstr ""
|
190 |
|
191 |
#: includes/configs/i18n/seoDescription.config.php:20
|
1 |
+
# Copyright (C) 2018 bgseo
|
2 |
# This file is distributed under the same license as the bgseo package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
7 |
"MIME-Version: 1.0\n"
|
8 |
"Content-Type: text/plain; charset=UTF-8\n"
|
9 |
"Content-Transfer-Encoding: 8bit\n"
|
10 |
+
"PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
|
11 |
"Language-Team: The BoldGrid Team <support@boldgrid.com>\n"
|
12 |
"X-Poedit-Basepath: ..\n"
|
13 |
"X-Poedit-SourceCharset: UTF-8\n"
|
181 |
msgstr ""
|
182 |
|
183 |
#: includes/configs/i18n/seoDescription.config.php:10
|
184 |
+
msgid "Your custom %1$sSEO Description%2$s is over the 300 character recommended length, you should consider making it shorter."
|
185 |
msgstr ""
|
186 |
|
187 |
#: includes/configs/i18n/seoDescription.config.php:15
|
188 |
+
msgid "You should make your %1$sSEO Description%2$s longer! We recommend 125-300 characters for the best results."
|
189 |
msgstr ""
|
190 |
|
191 |
#: includes/configs/i18n/seoDescription.config.php:20
|
readme.txt
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
Contributors: boldgrid, timph, rramo012, imh_brad, joemoto
|
3 |
Tags: seo, search engine optimization, content analysis, readability, boldgrid
|
4 |
Requires at least: 4.4
|
5 |
-
Tested up to:
|
6 |
Requires PHP: 5.3
|
7 |
-
Stable tag: 1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -77,6 +77,14 @@ The BoldGrid Easy SEO plugin is open source software. Join in on our [GitHub rep
|
|
77 |
|
78 |
== Changelog ==
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
= 1.5.1 =
|
81 |
|
82 |
Release Date: November 14th, 2017
|
2 |
Contributors: boldgrid, timph, rramo012, imh_brad, joemoto
|
3 |
Tags: seo, search engine optimization, content analysis, readability, boldgrid
|
4 |
Requires at least: 4.4
|
5 |
+
Tested up to: 5.0
|
6 |
Requires PHP: 5.3
|
7 |
+
Stable tag: 1.6.0-rc.1
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
77 |
|
78 |
== Changelog ==
|
79 |
|
80 |
+
= 1.6.0 =
|
81 |
+
|
82 |
+
Release Date: November 26th, 2018
|
83 |
+
|
84 |
+
* New Feature: Added Gutenberg and WordPress 5 compatibility.
|
85 |
+
* Update: Max length for meta descriptions was updated to 300.
|
86 |
+
* Bug Fix: Save special chars for meta fields.
|
87 |
+
|
88 |
= 1.5.1 =
|
89 |
|
90 |
Release Date: November 14th, 2017
|