├── README.md ├── ouiseo.css ├── ouiseo.min.js └── ouiseo.js /README.md: -------------------------------------------------------------------------------- 1 | # OuiSEO 2 | 3 | An open-source bookmarklet that shows you on-page SEO and social meta data information. 4 | 5 | ## Why should I use this? 6 | 7 | As an internet marketer you'll often find yourself looking at a website's source code to verify the page's title tag, meta description, see if the Facebook image meta tag was added, look at the text used for the Twitter card, etc. This process is tedious AND time consuming. 8 | 9 | OuiSEO was primarily built to save me time (and, let's be honest, to have some fun coding). If you have any ideas or suggestions please [get in touch](https://twitter.com/CarlSednaoui). If anything seems broken please [submit a Github issue](https://github.com/carlsednaoui/ouiseo/issues/new). 10 | 11 | __Note:__ OuiSEO is an evolving project and new features may be added in the future. 12 | 13 | ## Installation 14 | 15 | To install OuiSEO simply go [here](http://carlsednaoui.github.io/seo-bookmarklet/install.html). 16 | 17 | ## Demo 18 | ![OuiSEO Demo Image 1](http://f.cl.ly/items/202d2s2W2x2y1x2e0K1g/ouiseo_demo_1.png) 19 | ![OuiSEO Demo Image 2](http://f.cl.ly/items/0o04060g0x301m3E3w16/ouiseo_demo_2.png) 20 | ![OuiSEO Demo Image 3](http://f.cl.ly/items/2F1Q293i2w0R1R2v2m2G/ouiseo_demo_3.png) 21 | ![OuiSEO Demo Image 4](http://f.cl.ly/items/0X421F1o1I0k0m0u2x0A/ouiseo_demo_4.png) 22 | 23 | 24 | ## Inspiration 25 | 26 | OuiSEO is greatly inspired by this [SEO Bookmarklet](http://twkm.ca/seo-bookmarklet/) made by Troy Meier. Thank you Troy! 27 | 28 | ## Resources 29 | 30 | ### Facebook Resources 31 | - [Open graph documentation](https://developers.facebook.com/docs/opengraph/) 32 | - [Undestanding Facebook object types](https://developers.facebook.com/docs/opengraph/creating-object-types/) 33 | - [Facebook Open Graph Debugger](https://developers.facebook.com/tools/debug) 34 | - [The Open Graph protocol](http://ogp.me/) 35 | 36 | ### Twitter Resources 37 | - [Twitter Cards Documentation](https://dev.twitter.com/docs/cards) 38 | - [Twitter Cards Validator](https://dev.twitter.com/docs/cards/validation/validator) 39 | 40 | ## [License](http://opensource.org/licenses/MIT) 41 | 42 | >The MIT License (MIT) 43 | > 44 | >Copyright (c) 45 | > 46 | >Permission is hereby granted, free of charge, to any person obtaining a copy 47 | >of this software and associated documentation files (the "Software"), to deal 48 | >in the Software without restriction, including without limitation the rights 49 | >to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 50 | >copies of the Software, and to permit persons to whom the Software is 51 | >furnished to do so, subject to the following conditions: 52 | > 53 | >The above copyright notice and this permission notice shall be included in 54 | >all copies or substantial portions of the Software. 55 | > 56 | >THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 57 | >IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 58 | >FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 59 | >AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 60 | >LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 61 | >OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 62 | >THE SOFTWARE. 63 | 64 | ## Facebook Open Graph Notes 65 | - Fb url: The URL should be the canonical address for the given page 66 | - Fb title: The title should typically match page title 67 | - Fb description: A short description or summary of the object 68 | - Fb type: Tells Facebook how you'd like your website to be categorized. You can find [more info here](https://developers.facebook.com/docs/reference/opengraph/object-type/) 69 | - __Note__: The og:type meta tag is necessary for Facebook to render a News Feed story that generates a high click-through rate 70 | - Fb img: The URL of an image for this Open Graph object. They suggest that you give them an image of at least 200x200 pixels. However, bigger is better, so if you have a 1500x1500 image that you can use, use that instead (Note: image sizes must be no more than 5MB in size.) 71 | 72 | ## TODO 73 | - Refactor JS 74 | - Create minified version 75 | - Check if they use KM, GA, Mixpanel, Optimizely, VWO, MouseFlow, Google Remarketing, AdRoll, CrazyEgg 76 | - Add 'SEO' score? 77 | - Add 'SEO' suggestions? 78 | -------------------------------------------------------------------------------- /ouiseo.css: -------------------------------------------------------------------------------- 1 | @media all { 2 | /**************************/ 3 | /* Basic CSS Reset 4 | /**************************/ 5 | 6 | .ouiseo * { 7 | color: black; 8 | font-family: Helvetica, Arial, sans-serif; 9 | font-size: 16px; 10 | text-align: left; 11 | vertical-align: baseline; 12 | float: none; 13 | margin: 0; 14 | padding: 0; 15 | border: 0; 16 | line-height: 1; 17 | } 18 | 19 | /**************************/ 20 | /* Frame Styles 21 | /**************************/ 22 | 23 | #ouiseo_frame { 24 | position: fixed; 25 | width: 100%; 26 | height: 100%; 27 | top: 0; 28 | left: 0; 29 | background-color: rgba(255,255,255,.75); 30 | cursor: pointer; 31 | z-index: 2147483640; 32 | } 33 | 34 | /**************************/ 35 | /* OuiSEO Basic Container Styles 36 | /**************************/ 37 | 38 | #ouiseo { 39 | background: white; 40 | background-color: #384b5f; 41 | position: fixed; 42 | margin: -5px 0 0 -5px; 43 | top: 10%; 44 | left: 10%; 45 | width: 80%; 46 | height: 80%; 47 | z-index: 2147483647; 48 | border: 10px solid rgba(0,0,0,.5); 49 | overflow-y: scroll; 50 | } 51 | 52 | /**************************/ 53 | /* OuiSEO Default Container Styles 54 | /**************************/ 55 | 56 | #ouiseo p { 57 | font-size: 16px; 58 | color: black; 59 | text-align: left; 60 | float: none; 61 | } 62 | 63 | #ouiseo-author { 64 | color: white; 65 | text-align: center; 66 | padding: 10px; 67 | font-style: normal; 68 | font-weight: normal; 69 | text-decoration: none; 70 | text-transform: none; 71 | letter-spacing: 0px; 72 | display: block; 73 | font-size: 16px; 74 | } 75 | 76 | #ouiseo-author a { 77 | color: white; 78 | } 79 | 80 | #ouiseo h2 { 81 | color: white; 82 | font-size: 1.2em; 83 | font-weight: bold; 84 | font-style: normal; 85 | text-decoration: none; 86 | text-transform: none; 87 | letter-spacing: 0px; 88 | margin: 10px 10px 20px 10px; 89 | } 90 | 91 | #ouiseo-results { 92 | margin: 10px; 93 | } 94 | 95 | input[type='text'].ouiseo-input-text { 96 | width: 500px; 97 | font-size: 16px; 98 | color: black; 99 | border: 1px gray solid; 100 | padding: 2px 5px; 101 | margin: 7px 0; 102 | width: 98%; 103 | border-radius: 3px; 104 | -webkit-border-radius: 3px; 105 | -moz-border-radius: 3px; 106 | -webkit-box-sizing: border-box; 107 | -moz-box-sizing: border-box; 108 | box-sizing: border-box; 109 | float: none; 110 | text-align: left; 111 | height: auto; 112 | line-height: 1; 113 | } 114 | 115 | .ouiseo-basic-result, .ouiseo-social-result { 116 | margin: 12px; 117 | } 118 | 119 | .ouiseo-social-image { 120 | margin: 0 10px 10px 10px; 121 | height: 50px; 122 | width: 50px; 123 | } 124 | 125 | /**************************/ 126 | /* SEO Section Styles 127 | /**************************/ 128 | 129 | #ouiseo-basic-seo { 130 | background-color: #d87d6d; 131 | padding: 5px; 132 | } 133 | 134 | #ouiseo-basic-seo p.ouiseo-basic-result, #ouiseo-basic-seo p.ouiseo-basic-result span { 135 | color: #73473d; 136 | } 137 | 138 | #ouiseo-basic-seo p.ouiseo-basic-result input.ouiseo-input-text { 139 | color: white; 140 | background-color: #d87d6d; 141 | border: 1px #73473d solid; 142 | padding: 7px; 143 | } 144 | 145 | /**************************/ 146 | /* Facebook Section Styles 147 | /**************************/ 148 | 149 | #ouiseo-facebook { 150 | background-color: #4b9ed3; 151 | padding: 5px; 152 | } 153 | 154 | #ouiseo-facebook p.ouiseo-social-result, #ouiseo-facebook p.ouiseo-social-result span { 155 | color: #31566e; 156 | } 157 | 158 | #ouiseo-facebook p.ouiseo-social-result input.ouiseo-input-text { 159 | color: white; 160 | background-color: #4b9ed3; 161 | border: 1px #31566e solid; 162 | padding: 7px; 163 | } 164 | 165 | /**************************/ 166 | /* Twitter Section Styles 167 | /**************************/ 168 | 169 | #ouiseo-twitter { 170 | background-color: #6cc3e9; 171 | padding: 5px; 172 | } 173 | 174 | #ouiseo-twitter p.ouiseo-social-result, #ouiseo-twitter p.ouiseo-social-result span { 175 | color: #356d91; 176 | } 177 | 178 | #ouiseo-twitter p.ouiseo-social-result input.ouiseo-input-text { 179 | color: white; 180 | background-color: #6cc3e9; 181 | border: 1px #356d91 solid; 182 | padding: 7px; 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /ouiseo.min.js: -------------------------------------------------------------------------------- 1 | ;(function(){function r(){function e(){return""}function t(){var e="";e+=n().outerHTML;e+=r().outerHTML;return e}function n(){var e=document.createElement("div");e.id="ouiseo_frame";return e}function r(){var e=i();var t=s();t.appendChild(o());t.appendChild(u());t.appendChild(a());t.appendChild(l());t.appendChild(p());t.appendChild(d());t.appendChild(v());t.appendChild(m());e.appendChild(t);var n=g();n.appendChild(y());n.appendChild(b());e.appendChild(n);return e}function i(){var e=document.createElement("div"),t=document.createElement("h1");e.id="ouiseo";e.className="ouiseo";t.id="ouiseo-author";t.innerHTML="Made by ";t.innerHTML+='Carl Sednaoui';t.innerHTML+=" - Open sourced on ";t.innerHTML+='Github';e.appendChild(t);return e}function s(){var e=document.createElement("div");e.id="ouiseo-basic-seo";var t=document.createElement("h2");t.innerHTML="SEO";e.appendChild(t);return e}function o(){var e=document.createElement("p"),t=document.createElement("span"),n=document.createElement("input");e.className="ouiseo-basic-result";t.id="ouiseo-title-length";n.type="text";n.id="ouiseo-title";n.className="ouiseo-input-text";var r=$("title").text()||"";var i=0;if(!!r)i=r.replace(/\n$/,"").length;t.innerHTML=i;n.setAttribute("value",r);e.innerHTML="Title (";e.appendChild(t);e.innerHTML+=")";e.appendChild(n);return e}function u(){var e=document.createElement("p"),t=document.createElement("span"),n=document.createElement("input");e.className="ouiseo-basic-result";t.id="ouiseo-description-length";n.type="text";n.id="ouiseo-description";n.className="ouiseo-input-text";var r=$("meta[name=description]").attr("content")||"";var i=0;if(!!r)i=r.replace(/\n$/,"").length;t.innerHTML=i;n.setAttribute("value",r);e.innerHTML="Meta Description (";e.appendChild(t);e.innerHTML+=")";e.appendChild(n);return e}function a(){var e=document.createElement("p"),t=document.createElement("span"),n=document.createElement("input");e.className="ouiseo-basic-result";t.id="ouiseo-keywords-length";n.type="text";n.id="ouiseo-keywords";n.className="ouiseo-input-text";var r=$("meta[name=keywords]").attr("content")||"";var i=0;if(r!=="")i=r.split(",").length;t.innerHTML=i;n.setAttribute("value",r);e.innerHTML="Meta Keywords (";e.appendChild(t);e.innerHTML+=")";e.appendChild(n);return e}function f(){var e=0;$.each($("img"),function(t){if($("img")[t].alt)e++});return e==[]?0:e}function l(){var e=document.createElement("p");e.className="ouiseo-basic-result";var t=$("img").length,n=f();e.innerHTML="Images with alt text: ";e.innerHTML+=n;e.innerHTML+=" out of ";e.innerHTML+=t;return e}function c(){var e=0;$.each($("a"),function(t){if($("a")[t].title!=="")e++});return e==[]?0:e}function h(){var e=0;$.each($("a"),function(t){if($("a")[t].rel=="nofollow")e++});return e}function p(){var e=document.createElement("p");e.className="ouiseo-basic-result";var t=$("a").length,n=c(),r=h();e.innerHTML="Links with title set: ";e.innerHTML+=n;e.innerHTML+=" out of ";e.innerHTML+=t;e.innerHTML+=" links. This page has ";e.innerHTML+=r;e.innerHTML+=" nofollow links.";return e}function d(){var e=document.createElement("p");e.className="ouiseo-basic-result";var t=$("h1").length||0,n=$("h2").length||0,r=$("h3").length||0;e.innerHTML="H1: ";e.innerHTML+=t;e.innerHTML+="
H2: ";e.innerHTML+=n;e.innerHTML+="
H3: ";e.innerHTML+=r;return e}function v(){var e=document.createElement("p");e.className="ouiseo-basic-result";var t=$("link[rel='canonical']").length||0;e.innerHTML="Rel Canonical (";e.innerHTML+=t;e.innerHTML+=")";if(t!==0){$.each($("link[rel='canonical']"),function(t){e.innerHTML+="
";e.innerHTML+=$("link[rel='canonical']")[t].href})}return e}function m(){var e=document.createElement("p"),t=document.createElement("span"),n=document.createElement("input");e.className="ouiseo-basic-result";t.id="ouiseo-cookie-count";n.type="text";n.id="ouiseo-cookie";n.className="ouiseo-input-text";var r=document.cookie;n.setAttribute("value",r);t.innerHTML="0";if(r!=="")t.innerHTML=r.split(";").length;e.innerHTML="Site cookie: (";e.appendChild(t);e.innerHTML+=")";e.appendChild(n);return e}function g(){var e=document.createElement("div");e.id="ouiseo-social-section";return e}function y(){var e=document.createElement("div");title=document.createElement("h2");e.id="ouiseo-facebook";title.innerHTML="Facebook";e.appendChild(title);e.appendChild(E("FB App Id","fb-app-id",'meta[property="fb:app_id"]'));e.appendChild(E("OG URL","fb-url",'meta[property="og:url"]'));e.appendChild(E("OG Site Name","fb-site-name",'meta[property="og:site_name"]'));e.appendChild(E("OG Title","fb-title",'meta[property="og:title"]'));e.appendChild(E("OG Description","fb-description",'meta[property="og:description"]'));e.appendChild(E("OG Type","fb-type",'meta[property="og:type"]'));e.appendChild(S("OG Image",'meta[property="og:image"]'));return e}function b(){var e=document.createElement("div");title=document.createElement("h2");e.id="ouiseo-twitter";title.innerHTML="Twitter";e.appendChild(title);e.appendChild(E("Card type","twitter-card-type",'meta[name="twitter:card"]'));e.appendChild(w("Site","twitter-site",'meta[name="twitter:site"]','meta[name="twitter:site:id"]'));e.appendChild(w("Creator","twitter-creator",'meta[name="twitter:creator"]','meta[name="twitter:creator:id"]'));e.appendChild(E("Card title","twitter-card-title",'meta[name="twitter:title"]'));e.appendChild(E("Card description","twitter-card-description",'meta[name="twitter:description"]'));e.appendChild(S("Image",'meta[name="twitter:image:src"]'));return e}function w(e,t,n,r){var i=document.createElement("p"),s=document.createElement("input"),o;i.className="ouiseo-social-result";s.type="text";s.id="ouiseo-"+t;s.className="ouiseo-input-text";i.innerHTML=e;if($(n)[0]){o=$(n)[0].content}else if($(r)[0]){i.innerHTML+=" ID";o=$(r)[0].content}else{o=""}s.setAttribute("value",o);i.appendChild(s);return i}function E(e,t,n){var r=document.createElement("p"),i=document.createElement("input"),s;r.className="ouiseo-social-result";i.type="text";i.id="ouiseo-"+t;i.className="ouiseo-input-text";s=$(n)[0]?$(n)[0].content:"";r.innerHTML=e;i.setAttribute("value",s);r.appendChild(i);return r}function S(e,t){var n=document.createElement("p");n.className="ouiseo-social-result";n.innerHTML=e;if($(t)[0]){n.appendChild(document.createElement("div"));var r=document.createElement("img");r.src=$(t)[0].content;r.className="ouiseo-social-image";n.appendChild(r)}else{n.innerHTML+=": none"}return n}function x(){function e(e){return $(e).val().length}$("#ouiseo-title").keyup(function(){$("#ouiseo-title-length").text(e("#ouiseo-title"))});$("#ouiseo-description").keyup(function(){$("#ouiseo-description-length").text(e("#ouiseo-description"))});$("#ouiseo-keywords").keyup(function(){$("#ouiseo-keywords-length").text($("#ouiseo-keywords").val().split(",").length)})}(window.ouiseo=function(){$("head").append("");$("body").append(t());x();$("#ouiseo").fadeIn(250);$("head").append(e());$("#ouiseo_frame").click(function(e){$("#ouiseo").fadeOut(750);$("#ouiseo_frame").slideUp(750);setTimeout("$('#ouiseo_frame').remove()",750);setTimeout("$('#ouiseo-styles').remove()",750);setTimeout("$('#ouiseo-ga').remove()",750);setTimeout("$('#ouiseo').remove()",750)})})()}var e="1.10.2";if(window.jQuery===undefined||window.jQuery.fn.jquery"); 28 | $('body').append(createHTML()); 29 | initializeOuiseoHandlers(); 30 | $("#ouiseo").fadeIn(250); 31 | $('head').append(addOuiseoGA()); 32 | 33 | // Remove ouiseo when user clicks outside of frame 34 | $("#ouiseo_frame").click(function(event) { 35 | $("#ouiseo").fadeOut(750); 36 | $("#ouiseo_frame").slideUp(750); 37 | setTimeout("$('#ouiseo_frame').remove()", 750); 38 | setTimeout("$('#ouiseo-styles').remove()", 750); 39 | setTimeout("$('#ouiseo-ga').remove()", 750); 40 | setTimeout("$('#ouiseo').remove()", 750); 41 | }); 42 | })(); 43 | 44 | function addOuiseoGA() { 45 | return ""; 46 | } 47 | 48 | function createHTML() { 49 | var html = ''; 50 | html += createOuiseoFrame().outerHTML; 51 | html += createOuiseoBody().outerHTML; 52 | return html; 53 | } 54 | 55 | // Create ouiseo_frame -- allows user to close ouiseo 56 | 57 | function createOuiseoFrame() { 58 | var frame = document.createElement('div'); 59 | frame.id = 'ouiseo_frame'; 60 | return frame; 61 | } 62 | 63 | // Call ouiseo html element creation functions 64 | 65 | function createOuiseoBody() { 66 | var container = createOuiseoContainer(); 67 | 68 | var basicSection = createBasicSEOSection(); 69 | basicSection.appendChild(getTitle()); 70 | basicSection.appendChild(getDescription()); 71 | basicSection.appendChild(getKeywords()); 72 | basicSection.appendChild(getImages()); 73 | basicSection.appendChild(getLinks()); 74 | basicSection.appendChild(getHeaders()); 75 | basicSection.appendChild(getCanonical()); 76 | basicSection.appendChild(getCookie()); 77 | container.appendChild(basicSection); 78 | 79 | var socialSection = createSocialSection(); 80 | socialSection.appendChild(getFacebook()); 81 | socialSection.appendChild(getTwitter()); 82 | container.appendChild(socialSection); 83 | 84 | return container; 85 | } 86 | 87 | function createOuiseoContainer() { 88 | var container = document.createElement('div'), 89 | author = document.createElement('h1'); 90 | 91 | container.id = 'ouiseo'; 92 | container.className = 'ouiseo'; 93 | author.id = 'ouiseo-author'; 94 | author.innerHTML = 'Made by '; 95 | author.innerHTML += 'Carl Sednaoui'; 96 | author.innerHTML += ' - Open sourced on '; 97 | author.innerHTML += 'Github'; 98 | 99 | container.appendChild(author); 100 | 101 | return container; 102 | } 103 | 104 | //////////////////////////////// 105 | // Create Basic SEO Section 106 | //////////////////////////////// 107 | 108 | function createBasicSEOSection() { 109 | var div = document.createElement('div'); 110 | div.id = 'ouiseo-basic-seo'; 111 | 112 | var title = document.createElement('h2'); 113 | title.innerHTML = 'SEO'; 114 | 115 | div.appendChild(title); 116 | return div; 117 | } 118 | 119 | function getTitle() { 120 | var el = document.createElement('p'), 121 | span = document.createElement('span'), 122 | input = document.createElement('input'); 123 | 124 | el.className = 'ouiseo-basic-result'; 125 | span.id = 'ouiseo-title-length'; 126 | input.type = 'text'; 127 | input.id = 'ouiseo-title'; 128 | input.className = 'ouiseo-input-text'; 129 | 130 | var title = $('title').text() || ''; 131 | var titleLen = 0; 132 | if ( !! title) 133 | titleLen = title.replace(/\n$/, '').length; // Remove last line return, if present 134 | 135 | span.innerHTML = titleLen; 136 | input.setAttribute('value', title); // Need to use setAttribute here so that value gets pased when appending child 137 | 138 | el.innerHTML = 'Title ('; 139 | el.appendChild(span); 140 | el.innerHTML += ')'; 141 | el.appendChild(input); 142 | 143 | return el; 144 | } 145 | 146 | function getDescription() { 147 | var el = document.createElement('p'), 148 | span = document.createElement('span'), 149 | input = document.createElement('input'); 150 | 151 | el.className = 'ouiseo-basic-result'; 152 | span.id = 'ouiseo-description-length'; 153 | input.type = 'text'; 154 | input.id = 'ouiseo-description'; 155 | input.className = 'ouiseo-input-text'; 156 | 157 | var metaDescription = $('meta[name=description]').attr('content') || ''; 158 | var metaDescriptionLen = 0; 159 | if ( !! metaDescription) 160 | metaDescriptionLen = metaDescription.replace(/\n$/, '').length; // Remove last line return, if present 161 | 162 | span.innerHTML = metaDescriptionLen; 163 | input.setAttribute('value', metaDescription); // Need to use setAttribute here so that value gets pased when appending child 164 | 165 | el.innerHTML = 'Meta Description ('; 166 | el.appendChild(span); 167 | el.innerHTML += ')'; 168 | el.appendChild(input); 169 | 170 | return el; 171 | } 172 | 173 | function getKeywords() { 174 | var el = document.createElement('p'), 175 | span = document.createElement('span'), 176 | input = document.createElement('input'); 177 | 178 | el.className = 'ouiseo-basic-result'; 179 | span.id = 'ouiseo-keywords-length'; 180 | input.type = 'text'; 181 | input.id = 'ouiseo-keywords'; 182 | input.className = 'ouiseo-input-text'; 183 | 184 | var metaKeywords = $('meta[name=keywords]').attr('content') || ''; 185 | var metaKeywordsLen = 0; 186 | if (metaKeywords !== '') 187 | metaKeywordsLen = metaKeywords.split(',').length; 188 | 189 | span.innerHTML = metaKeywordsLen; 190 | input.setAttribute('value', metaKeywords); // Need to use setAttribute here so that value gets pased when appending child 191 | 192 | el.innerHTML = 'Meta Keywords ('; 193 | el.appendChild(span); 194 | el.innerHTML += ')'; 195 | el.appendChild(input); 196 | 197 | return el; 198 | } 199 | 200 | function calculateImageAltTextCount() { 201 | var imgAltCount = 0; 202 | $.each($('img'), function(index) { 203 | if ($('img')[index].alt) imgAltCount++; 204 | }); 205 | return imgAltCount == [] ? 0 : imgAltCount; 206 | } 207 | 208 | function getImages() { 209 | var el = document.createElement('p'); 210 | el.className = 'ouiseo-basic-result'; 211 | 212 | var imgCount = $('img').length, 213 | imgAltCount = calculateImageAltTextCount(); 214 | 215 | el.innerHTML = 'Images with alt text: '; 216 | el.innerHTML += imgAltCount; 217 | el.innerHTML += ' out of '; 218 | el.innerHTML += imgCount; 219 | 220 | return el; 221 | } 222 | 223 | function calculateLinksWithTitleCount() { 224 | var linkTitleCount = 0; 225 | $.each($('a'), function(index) { 226 | if ($('a')[index].title !== '') linkTitleCount++; 227 | }); 228 | return linkTitleCount == [] ? 0 : linkTitleCount; 229 | } 230 | 231 | function calculateNoFollowLinkCount() { 232 | var noFollowedLinkCount = 0; 233 | $.each($('a'), function(index) { 234 | if ($('a')[index].rel == 'nofollow') noFollowedLinkCount++; 235 | }); 236 | return noFollowedLinkCount; 237 | } 238 | 239 | function getLinks() { 240 | var el = document.createElement('p'); 241 | el.className = 'ouiseo-basic-result'; 242 | 243 | var linkCount = $('a').length, 244 | linkWithTitleCount = calculateLinksWithTitleCount(), 245 | noFollowLinkCount = calculateNoFollowLinkCount(); 246 | 247 | el.innerHTML = 'Links with title set: '; 248 | el.innerHTML += linkWithTitleCount; 249 | el.innerHTML += ' out of '; 250 | el.innerHTML += linkCount; 251 | el.innerHTML += ' links. This page has '; 252 | el.innerHTML += noFollowLinkCount; 253 | el.innerHTML += ' nofollow links.'; 254 | 255 | return el; 256 | } 257 | 258 | function getHeaders() { 259 | var el = document.createElement('p'); 260 | el.className = 'ouiseo-basic-result'; 261 | 262 | var hOneCount = $('h1').length || 0, 263 | hTwoCount = $('h2').length || 0, 264 | hThreeCount = $('h3').length || 0; 265 | 266 | el.innerHTML = 'H1: '; 267 | el.innerHTML += hOneCount; 268 | el.innerHTML += "
H2: "; 269 | el.innerHTML += hTwoCount; 270 | el.innerHTML += "
H3: "; 271 | el.innerHTML += hThreeCount; 272 | 273 | return el; 274 | } 275 | 276 | function getCanonical() { 277 | var el = document.createElement('p'); 278 | el.className = 'ouiseo-basic-result'; 279 | 280 | var canonicalCount = $("link[rel='canonical']").length || 0; 281 | el.innerHTML = 'Rel Canonical ('; 282 | el.innerHTML += canonicalCount; 283 | el.innerHTML += ')'; 284 | 285 | if (canonicalCount !== 0) { 286 | $.each($("link[rel='canonical']"), function(index) { 287 | el.innerHTML += '
'; 288 | el.innerHTML += $("link[rel='canonical']")[index].href; 289 | }); 290 | } 291 | 292 | return el; 293 | } 294 | 295 | function getCookie() { 296 | var el = document.createElement('p'), 297 | span = document.createElement('span'), 298 | input = document.createElement('input'); 299 | 300 | el.className = 'ouiseo-basic-result'; 301 | span.id = 'ouiseo-cookie-count'; 302 | input.type = 'text'; 303 | input.id = 'ouiseo-cookie'; 304 | input.className = 'ouiseo-input-text'; 305 | 306 | var cookie = document.cookie; 307 | input.setAttribute('value', cookie); // Need to use setAttribute here so that value gets pased when appending child 308 | span.innerHTML = '0'; 309 | if (cookie !== '') 310 | span.innerHTML = cookie.split(';').length; 311 | 312 | el.innerHTML = 'Site cookie: ('; 313 | el.appendChild(span); 314 | el.innerHTML += ')'; 315 | el.appendChild(input); 316 | 317 | return el; 318 | } 319 | 320 | //////////////////////////////// 321 | // Create Social Section 322 | //////////////////////////////// 323 | 324 | function createSocialSection() { 325 | var div = document.createElement('div'); 326 | div.id = 'ouiseo-social-section'; 327 | 328 | return div; 329 | } 330 | 331 | ////////////////////////////// 332 | // Get Facebook Data 333 | ////////////////////////////// 334 | 335 | function getFacebook() { 336 | var result = document.createElement('div'); 337 | title = document.createElement('h2'); 338 | 339 | result.id = 'ouiseo-facebook'; 340 | title.innerHTML = 'Facebook'; 341 | result.appendChild(title); 342 | 343 | result.appendChild(createElWithSelector('FB App Id', 'fb-app-id', 'meta[property="fb:app_id"]')); 344 | result.appendChild(createElWithSelector('OG URL', 'fb-url', 'meta[property="og:url"]')); 345 | result.appendChild(createElWithSelector('OG Site Name', 'fb-site-name', 'meta[property="og:site_name"]')); 346 | result.appendChild(createElWithSelector('OG Title', 'fb-title', 'meta[property="og:title"]')); 347 | result.appendChild(createElWithSelector('OG Description', 'fb-description', 'meta[property="og:description"]')); 348 | result.appendChild(createElWithSelector('OG Type', 'fb-type', 'meta[property="og:type"]')); 349 | result.appendChild(createImageEl('OG Image', 'meta[property="og:image"]')); 350 | 351 | return result; 352 | } 353 | 354 | ////////////////////////////// 355 | // Get Twitter Data 356 | ////////////////////////////// 357 | 358 | function getTwitter() { 359 | var result = document.createElement('div'); 360 | title = document.createElement('h2'); 361 | 362 | result.id = 'ouiseo-twitter'; 363 | title.innerHTML = 'Twitter'; 364 | result.appendChild(title); 365 | 366 | result.appendChild(createElWithSelector('Card type', 'twitter-card-type', 'meta[name="twitter:card"]')); 367 | result.appendChild(createElWithAlternateSelector('Site', 'twitter-site', 'meta[name="twitter:site"]', 'meta[name="twitter:site:id"]')); 368 | result.appendChild(createElWithAlternateSelector('Creator', 'twitter-creator', 'meta[name="twitter:creator"]', 'meta[name="twitter:creator:id"]')); 369 | result.appendChild(createElWithSelector('Card title', 'twitter-card-title', 'meta[name="twitter:title"]')); 370 | result.appendChild(createElWithSelector('Card description', 'twitter-card-description','meta[name="twitter:description"]')); 371 | result.appendChild(createImageEl('Image', 'meta[name="twitter:image:src"]')); 372 | 373 | return result; 374 | } 375 | 376 | function createElWithAlternateSelector(name, title, first_selector, secondary_selector) { 377 | var el = document.createElement('p'), 378 | input = document.createElement('input'), 379 | result; 380 | 381 | el.className = 'ouiseo-social-result'; 382 | input.type = 'text'; 383 | input.id = 'ouiseo-' + title; 384 | input.className = 'ouiseo-input-text'; 385 | 386 | 387 | el.innerHTML = name; 388 | 389 | if ($(first_selector)[0]) { 390 | result = $(first_selector)[0].content; 391 | } else if ($(secondary_selector)[0]) { 392 | el.innerHTML += ' ID'; 393 | result = $(secondary_selector)[0].content; 394 | } else { 395 | result = ''; 396 | } 397 | 398 | input.setAttribute('value', result); 399 | 400 | el.appendChild(input); 401 | return el; 402 | } 403 | 404 | function createElWithSelector(name, title, selector) { 405 | var el = document.createElement('p'), 406 | input = document.createElement('input'), 407 | result; 408 | 409 | el.className = 'ouiseo-social-result'; 410 | input.type = 'text'; 411 | input.id = 'ouiseo-' + title; 412 | input.className = 'ouiseo-input-text'; 413 | 414 | result = $(selector)[0] ? $(selector)[0].content : ''; 415 | 416 | el.innerHTML = name; 417 | input.setAttribute('value', result); 418 | 419 | el.appendChild(input); 420 | return el; 421 | } 422 | 423 | function createImageEl(name, selector) { 424 | var el = document.createElement('p'); 425 | el.className = 'ouiseo-social-result'; 426 | el.innerHTML = name; 427 | 428 | if ($(selector)[0]) { 429 | el.appendChild(document.createElement('div')); // To show images below title 430 | var img = document.createElement('img'); 431 | img.src = $(selector)[0].content; 432 | img.className = 'ouiseo-social-image'; 433 | el.appendChild(img); 434 | } else { 435 | el.innerHTML += ': none'; 436 | } 437 | 438 | return el; 439 | } 440 | 441 | ////////////////////////////////////////// 442 | // Initialize Handlers To Update Values 443 | ////////////////////////////////////////// 444 | 445 | function initializeOuiseoHandlers() { 446 | function calculateCharLen(selector) { 447 | return $(selector).val().length; 448 | } 449 | 450 | $('#ouiseo-title').keyup(function() { 451 | $('#ouiseo-title-length').text(calculateCharLen('#ouiseo-title')); 452 | }); 453 | $('#ouiseo-description').keyup(function() { 454 | $('#ouiseo-description-length').text(calculateCharLen('#ouiseo-description')); 455 | }); 456 | $('#ouiseo-keywords').keyup(function() { 457 | $('#ouiseo-keywords-length').text($('#ouiseo-keywords').val().split(',').length); 458 | }); 459 | } 460 | } 461 | })(); 462 | --------------------------------------------------------------------------------