Internet Explorer 9 (IE9) CSS3 Support – Platform Preview

by Filip Stanek 16. March 2010 16:05

I downloaded the platform preview version of IE9 today to test out some CSS support. I ran a few tests through it, with the following results.  The picture on the left was generated using Firefox 3.6 (keep in mind that I did have to use the “-moz” prefix in front of all but one style to make it work in FF). The IE content is on the right.

ie9css1

It certainly is possible that IE requires some vendor-specific suffix like Firefox did. However, I did not use any prefix, so the style may actually be supported in some form.

In any case, the only supported feature out of the four I tested was border-radius (and that is actually the one I’m most excited about). The box-shadow would be next on my list. Hopefully that gets put in the next preview.

Tags: , ,

Web Development

HTML5 or Flash – Be careful what you ask for…

by Filip Stanek 9. March 2010 00:51

Ok, I’ll get straight to the point: There is a lot to dislike about many websites right now when it comes to how these websites generate revenue. On many sites it is hard to actually find the content you were seeking due to the huge amount of ads that get displayed. I’ve had my browser crash countless times due to poorly designed ads (generally, it is due to Flash ads, but it certainly can happen with JavaScript as well).

Is Flash a problem? With the way it is currently being used by advertisers, it would be hard to argue that it isn’t. However, HTML5 isn’t the solution. In fact, I think HTML5 will be a bigger problem than Flash ever was.

More...

Tags: , ,

Web Development

Updated Contact Page – Now with a reCaptcha

by Filip Stanek 7. March 2010 01:15

I’ve added the reCaptcha to my contact page.  If anyone who has installed the reCaptcha wants to add it to their contact page, the files are available here.

These are just the updated contact page files.  You must have the reCaptcha already installed for these to work.

Tags:

Web Development

Blogengine.NET – reCaptcha 0.93 Installation Instructions

by Filip Stanek 26. February 2010 01:33

These installation instructions now apply to version 0.95

First, the linked ZIP file contains the updated files for installing the Recaptcha control.

UPDATES:

  • Version 0.95 – Changed initial loading method to fix error that occurred in certain cases in IE. If upgrading from 0.94, you only need to replace the Recaptcha.cs file.
  • Version 0.94 – Logging fixes
  • Version 0.93 – Added logging.
  • Version 0.92 - The recaptcha will no longer get focus after it has been loaded. Install procedure is unchanged from version 0.91.
  • Version 0.91 - Changed the way that Recaptcha is verified.  It should no longer be possible to bypass the recaptcha by manually executing JavaScript on the page.
  • Version 0.9 - Initial Version

More...

Tags: , , , , , ,

Web Development

Blogengine.NET Recaptcha 0.91 Installation Instructions

by Filip Stanek 20. February 2010 23:27

NOTE: THESE INSTALLATION INSTRUCTIONS HAVE BEEN UPDATED: To get the latest version, follow the instructions located at: http://www.bloodforge.com/post/BlogengineNET-reCaptcha-093-Installation-Instructions.aspx

First, the linked ZIP file contains the updated files for installing the Recaptcha control.

UPDATES:

  • Version 0.92 - The recaptcha will no longer get focus after it has been loaded. Install procedure is unchanged from version 0.91.
  • Version 0.91 - Changed the way that Recaptcha is verified.  It should no longer be possible to bypass the recaptcha by manually executing JavaScript on the page.
  • Version 0.9 - Initial Version

Quick Installation

First, back up your files in case you need to revert for any reason. If you have not modified any of the BlogEngine files, you can extract the ZIP linked to above and place all of the files into their proper locations ( the unzipped files should contain a folder structure ). There is no need to recompile.

You may need to force a refresh of your browser on the site, since there is a JavaScript file updated, and most browsers like to cache these files.

Manual Installation

Below is a complete summary of what needs to be altered to make the Recaptcha control work.  You’ll need to do this for any files manually modified in your BlogEngine.NET instance.

/App_Code/Controls/Recaptcha.cs

This file was not included in the BlogEngine.NET installation, and should be placed in the ‘/App_Code/Controls/’ folder.

/blog.js

There are three functions in this file that need to be updated to the following:

onCommentError: function(error, context) {
        BlogEngine.toggleCommentSavingIndicators(false);
        error = error || "Unknown error occurred.";
        var iDelimiterPos = error.indexOf("|");
        if (iDelimiterPos > 0) {
            error = error.substr(0, iDelimiterPos);
            // Remove numbers from end of error message.
            while (error.length > 0 && error.substr(error.length - 1, 1).match(/\d/)) {
                error = error.substr(0, error.length - 1);
            }
        }
        
        if( document.getElementById('recaptcha_response_field') )
        {
           Recaptcha.reload();
        }
 
        alert("Sorry, the following error occurred while processing your comment:\n\n" + error);
    }
addComment: function(preview) {
        var isPreview = preview == true;
        if (!isPreview) {
            BlogEngine.toggleCommentSavingIndicators(true);
            this.$("status").innerHTML = BlogEngine.i18n.savingTheComment;
        }
 
        var author = BlogEngine.comments.nameBox.value;
        var email = BlogEngine.comments.emailBox.value;
        var website = BlogEngine.comments.websiteBox.value;
        var country = BlogEngine.comments.countryDropDown ? BlogEngine.comments.countryDropDown.value : "";
        var content = BlogEngine.comments.contentBox.value;
        var notify = BlogEngine.$("cbNotify").checked;
        var captcha = BlogEngine.comments.captchaField.value;
        var replyToId = BlogEngine.comments.replyToId ? BlogEngine.comments.replyToId.value : "";
        
        var recaptchaResponseField = document.getElementById('recaptcha_response_field');        
        var recaptchaResponse = recaptchaResponseField ? recaptchaResponseField.value : "";
        
        var recaptchaChallengeField = document.getElementById('recaptcha_challenge_field');
        var recaptchaChallenge = recaptchaChallengeField ? recaptchaChallengeField.value : "";
 
        var avatarInput = BlogEngine.$("avatarImgSrc");
        var avatar = (avatarInput && avatarInput.value) ? avatarInput.value : "";
 
        var callback = isPreview ? BlogEngine.endShowPreview : BlogEngine.appendComment;
        var argument = author + "-|-" + email + "-|-" + website + "-|-" + country + "-|-" + content + "-|-" + notify + "-|-" + isPreview + "-|-" + captcha + "-|-" + replyToId + "-|-" + avatar + "-|-" + recaptchaResponse + "-|-" + recaptchaChallenge;
 
        WebForm_DoCallback(BlogEngine.comments.controlId, argument, callback, 'comment', BlogEngine.onCommentError, false);
 
        if (!isPreview && typeof (OnComment) != "undefined")
            OnComment(author, email, website, country, content);
    }
appendComment: function(args, context) {
        if (context == "comment") {
        
            if( document.getElementById('recaptcha_response_field') )
            {
               Recaptcha.reload();
            }
        
            if( args == "RecaptchaIncorrect" )
            {
               if( document.getElementById("spnCaptchaIncorrect") ) document.getElementById("spnCaptchaIncorrect").style.display = "";
               BlogEngine.toggleCommentSavingIndicators(false);
            }
            else
            {
            
                if( document.getElementById("spnCaptchaIncorrect") ) document.getElementById("spnCaptchaIncorrect").style.display = "none";
 
                var commentList = BlogEngine.$("commentlist");
                if (commentList.innerHTML.length < 10)
                    commentList.innerHTML = "<h1 id='comment'>" + BlogEngine.i18n.comments + "</h1>"
 
                // add comment html to the right place
                var id = BlogEngine.comments.replyToId ? BlogEngine.comments.replyToId.value : '';
 
                if (id != '') {
                    var replies = BlogEngine.$('replies_' + id);
                    replies.innerHTML += args;
                } else {
                    commentList.innerHTML += args;
                    commentList.style.display = 'block';
                }
 
                // reset form values
                BlogEngine.comments.contentBox.value = "";
                BlogEngine.comments.contentBox = BlogEngine.$(BlogEngine.comments.contentBox.id);
                BlogEngine.toggleCommentSavingIndicators(false);
                BlogEngine.$("status").className = "success";
 
                if (!BlogEngine.comments.moderation)
                    BlogEngine.$("status").innerHTML = BlogEngine.i18n.commentWasSaved;
                else
                    BlogEngine.$("status").innerHTML = BlogEngine.i18n.commentWaitingModeration;
 
                // move form back to bottom
                var commentForm = BlogEngine.$('comment-form');
                commentList.appendChild(commentForm);
                // reset reply to
                if (BlogEngine.comments.replyToId) BlogEngine.comments.replyToId.value = '';
                if (BlogEngine.$('cancelReply')) BlogEngine.$('cancelReply').style.display = 'none';
            
            }
        }
 
        BlogEngine.$("btnSaveAjax").disabled = false;
    }

/User controls/CommentView.ascx.cs

One method in this file needs to be updated:

/// <summary>
    /// Processes a callback event that targets a control.
    /// </summary>
    /// <param name="eventArgument">A string that represents an event argument to pass to the event handler.</param>
    public void RaiseCallbackEvent(string eventArgument)
    {
        if (!BlogSettings.Instance.IsCommentsEnabled)
            return;
 
        string[] args = eventArgument.Split(new string[] { "-|-" }, StringSplitOptions.None);
        string author = args[0];
        string email = args[1];
        string website = args[2];
        string country = args[3];
        string content = args[4];
        bool notify = bool.Parse(args[5]);
        bool isPreview = bool.Parse(args[6]);
        string sentCaptcha = args[7];
        //If there is no "reply to" comment, args[8] is empty
        Guid replyToCommentID = String.IsNullOrEmpty(args[8]) ? Guid.Empty : new Guid(args[8]);
        string avatar = args[9];
 
        string recaptchaResponse = args[10];
        string recaptchaChallenge = args[11];
 
        if (!isPreview && recaptcha.RecaptchaEnabled && recaptcha.RecaptchaNecessary)
        {
            if (!recaptcha.ValidateAsync(recaptchaResponse, recaptchaChallenge))
            {
                _Callback = "RecaptchaIncorrect";
                return;
            }
        }
 
        string storedCaptcha = hfCaptcha.Value;
 
        if (sentCaptcha != storedCaptcha)
            return;
 
        Comment comment = new Comment();
        comment.Id = Guid.NewGuid();
        comment.ParentId = replyToCommentID;
        comment.Author = Server.HtmlEncode(author);
        comment.Email = email;
        comment.Content = Server.HtmlEncode(content);
        comment.IP = Request.UserHostAddress;
        comment.Country = country;
        comment.DateCreated = DateTime.Now;
        comment.Parent = Post;
        comment.IsApproved = !BlogSettings.Instance.EnableCommentsModeration;
        comment.Avatar = avatar.Trim();
 
        if (Page.User.Identity.IsAuthenticated)
            comment.IsApproved = true;
 
        if (website.Trim().Length > 0)
        {
            if (!website.ToLowerInvariant().Contains("://"))
                website = "http://" + website;
 
            Uri url;
            if (Uri.TryCreate(website, UriKind.Absolute, out url))
                comment.Website = url;
        }
 
        if (!isPreview)
        {
            if (notify && !Post.NotificationEmails.Contains(email))
                Post.NotificationEmails.Add(email);
            else if (!notify && Post.NotificationEmails.Contains(email))
                Post.NotificationEmails.Remove(email);
 
            Post.AddComment(comment);
            SetCookie(author, email, website, country);
        }
 
        string path = Utils.RelativeWebRoot + "themes/" + BlogSettings.Instance.Theme + "/CommentView.ascx";
 
        CommentViewBase control = (CommentViewBase)LoadControl(path);
        control.Comment = comment;
        control.Post = Post;
 
        using (StringWriter sw = new StringWriter())
        {
            control.RenderControl(new HtmlTextWriter(sw));
            _Callback = sw.ToString();
        }
    }

/User controls/CommentView.ascx

Finally, the following line needs to be added to this file, at the location you would like the Recaptcha control to appear. Remember to update your TabIndexes for proper tab button navigation.

<blog:RecaptchaControl ID="recaptcha" runat="server" TabIndex="8" />

Recaptcha Settings

You can edit the Recaptcha settings via the Extension Manager. You probably should enter in your own Public and Private keys, as the provided keys are for this site ( they are global, so they will work on other sites ).

Recaptcha Theming

There are 4 built-in themes that you can change via the ExtensionManager. You can also create your own theme by adding it in the following way to the Recaptcha control:

<blog:RecaptchaControl ID="recaptcha" runat="server" TabIndex="8" Theme="MyCustomTheme" />

For detailed instructions on what your theme needs to look like, visit the Recaptcha site.

Tags: , , , , , ,

Web Development

Tag cloud

About Filip Stanek

Death Note Pic I'm a developer at ACG Multimedia in Cincinnati, OH. Besides working with ASP.NET, Flash, and other web technologies, I enjoy playing chess, video games, etc.

Currently playing:
- Final Fantasy XIII
E-mail me Send mail

Recent Comments

Comment RSS

Month List

Page List