jQuery Modal Dialogs for Sitecore 6.5-7.0 to fix Chrome 37+ browser issues

tl;dr A fix for Google Chrome 37+ which removed support for showModalDialog() and broke a lot of functionality in older releases of Sitecore and can be found on Github

11/09/2014: Sitecore have officially released patches for v6.4 to 7.0 for this bug. Glad to see that I was not a million miles off in my implementation though. Please use these patches instead: https://kb.sitecore.net/articles/581527

With the release of Google Chrome 37 we have finally lost our beloved modal dialogs created with showModalDialog(). This is used in all versions of Sitecore up to version 7.1. There is no official workaround for this yet, aside from use EnableDeprecatedWebPlatformFeatures Chrome policy, use a different browser or upgrade as stated in this knowledge base.

There was a fair amount of talk of this issue towards the end of last week, I also contributed on the main SDN thread and it seems we totally missed the issue being raised by Alex Pershteyn a few weeks ago. Well it appears those showModalDialog() is deprecated messages in the console window actually meant something and apparently ignoring them didn’t make the problem go away 😦

showModalDialog deprecated

What’s the problem with showModalDialog?

Apparently they are evil! And we all know how much Google does not want to be evil 🙂

So Google Chrome has now officially removed support, Opera will follow suit and Mozilla Firefox is not far behind!

There is no issue in Sitecore 7.1+ since those use the jQuery UI Dialog for it’s modalling needs, which is one of the recommended ways to achieve modals. The new fangled way is to use the HTML <dialog> element, but browser support isn’t exactly forthcoming.

I was hoping some sort of polyfill would be available, or we could simply provide our own implementation of window.showModalDialog(), which is the route I went down first:

if (!scForm.browser.isIE) {
  window.showModalDialog = function (showModalDialog) {
    return function (url, name, features) {
      // some browsers dont support the call() method so call the method directly in such cases
      return open.call ?
        open.call(window, url, name, features)
        : open( url, name, features);
      };
    }(window.showModalDialog);
}

Although it kind of fixed the issue and popups were now openeing, the problem with this was that there was no return value, unlike window.showModalDialog(), nor was it blocking code execution, which in itself is not a bad thing but if your code was not written with that in mind things may not work as expected!

Stop jabbering on and give me the code already!

Ok, here: Sitecore Modal Fix on Github.

Or follow the official recommendation from the Sitecore Knowledge Base article.

So what does this do?

I’ve back-ported the newer jQuery UI Dialog functionality from Sitecore 7.1

The newer version has gone away from using browser specific Javascript files (InternetExplorer.js and Gecko.js) to using a single Browser.js file. That was probably too much work to integrate back into the older versions of Sitecore.

My initial commit followed a similar approach as Sitecore by copying the modal functionality into Sitecore.js which worked for Chrome and Firefox in all versions that I tested, and also worked for IE11 for Sitecore 6.5. For some reason, the following line in Default.aspx causes IE to go into a strange V5 compatibility mode and the popups rendered at the end of the page:

&amp;lt;meta http-equiv=&amp;quot;X-UA-Compatible&amp;quot; content=&amp;quot;IE=5&amp;quot;/&amp;gt;

showModalDialog IE Publish Window Under

Since Internet Explorer still supports the forbidden dialog, I decided to not battle it and to make the changes only to Gecko.js, this fixes the issue for Chrome 37 and any other browser that uses (I couldn’t figure out how/where this was referenced from…) but leaves Internet Explorer alone so it uses standard Sitecore functionality. The showModalDialog method calls the jQuery dialog method instead now (which was renamed to stop a recursive loop):

scBrowser.prototype.showModalDialog = function (url, arguments, features, request, callback) {
  this.showjQueryModalDialog(url, arguments, features, request, callback);
}

I also copied across JQueryModalDialogs.html and the referenced jQuery+UI files. I merged across some other changes from Sitecore.js and Gecko.js, and decided to throw in some conditional browser detection statements in there:

if (this.browser.isIE) {
  this.browser.showModalDialog(command.value, new Array(window), command.features, request);
} else {
  this.browser.showModalDialog(command.value, [window], command.features, request, request.onCloseModalDialogCallback);
  request.onCloseModalDialogCallback = null;
}

This was all working, aside from the Upload Package dialog, which would throw a very cryptic JavaScript error. The file was uploading successfully though!

showModalDialog anonymous error

This bug took the majority of my time to track down. Eventually Firefox to the rescue. Firebug FTW!

showModalDialog error firebug

I exported the code to a project using dotPeek and then used grepWin to find the offending code. Hardcoded JavaScript! Gaaaah!

HttpContext.Current.Response.Write(string.Format(&amp;quot;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;script type='text/JavaScript' language='javascript'&amp;gt;window.top.frames[0].scForm.postRequest('', '', '', '{0}(filename={1})')&amp;lt;/script&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;Done&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;quot;, (object) str1, (object) str2));

These pipelines upload the package file and send an OK response back to the browser. So I’ve provided new implementation of these 2 pipelines. Note that this uses a different JavaScript namespace than SC7.1 version since my modal dialog is declared in Gecko.js (so we need to declare it as scForm.browser. instead…)

window.top.scForm.browser.getTopModalDialog().frames[0].scForm.postRequest('', '', '', '{0}(filename={1})')

Take a look at the code on Github, I simply call the original Process method in IE otherwise render a modified version of Sitecore 7.1 code.

if (Sitecore.UIUtil.IsIE())
{
    base.Process(args);
    return;
}

There’s not much to it, but just diff the original files (which I have included in the source folder) with the modified files in Release. The only thing I should mention is that there was minimal differences between Sitecore 6.6 and 7.0 files, most likely bug fixes, which on the face of it should not make much difference hence the reason there is a single version for those.

So now IE is using the existing the functionality which continues to work and the other browsers use functionality from Sitecore 7.1+ release.

Does it actually work?

I’ve tested in following versions of Sitecore:

  • 6.5 rev 121009 (SP2)
  • 6.6 rev 140410 (SP2)
  • 7.0 rev 140408 (SP1)
  • Jetstream 2.0 demo – which uses 7.0 rev 130810

With the following browsers:

  • Internet Explorer 11
  • Mozilla Firefox 31
  • Google Chrome 36 + 37

Some of the basic tests I have carried out:

  • Publish window opens correctly
  • Package Installation Wizard opens correctly, able to select package and upload package correctly.
  • Prompts to overwrite existing files and Items displayed correctly
  • Can open Layout details, edit presentation renderings, add new controls, set datasources and edit rendering parameters
  • Can upload images to media library, attach new image and detach as expected, using both normal and advanced upload options.
  • Able to rename Items, set display name and change templates
  • General Link, Image Field and Rich Text Field command working correctly in Content Editor
  • Able to edit content in Page Editor, add new controls, set datasources, edit rendering parameters, insert images and DMS functionality working.
  • Basic tests using Web Forms for Marketers module.
  • Various other “blocking” popups working – e.g. Aliases, Publishing Viewer, My Item Locks, Clones.

Installation

Copy the files from the Release folder into your Sitecore installation. If you are using Sitecore 6.5 then rename the Geko.SC65.js and Sitecore.SC65.js files.

Something gone horribly wrong? Delete the patch include files and revert the original js files from the source folder.

The usual disclaimer, use at your own risk. This is highly experimental and not in any way officially endorsed by Sitecore.

What is remaining?

Plenty probably. The main issue will be hardcoded JavaScript code present in Sitecore.Kernel.dll and Sitecore.Client.dll

I’ve fixed 2 of the issues in the uiUpload pipeline, but there is code present in the following classes which may need to be addressed. I couldn’t actually find how to invoke this code so unable to fix/test. If you know, please get in touch:

Sitecore.Client.dll – Contains references to window.top.frames[0].scForm.postRequest() and window.top.close()

  • Sitecore.Shell.Application.Dialogs.Attach.AttachPage2
  • Sitecore.Shell.Application.Dialogs.Upload.UploadForm
  • Sitecore.Shell.Application.Install.Dialogs.UploadPackageForm
  • Sitecore.Shell.Application.Media.UploadMedia.UploadMediaPage2

Sitecore.Kernel.dll – Contains reference to window.top.close()

  • Sitecore.Shell.Framework.Windows

There is still a reference to showModalDialog() in Gecko.js but this only affects those using the Safari browser:

scBrowser.prototype.prompt = function(text, defaultValue) {
  if (!this.isSafari) {
    return prompt(text, defaultValue);
  } else {
    var arguments = new Array(text, defaultValue);
    var features = &amp;quot;dialogWidth:400px;dialogHeight:110px;help:no;scroll:no;resizable:no;status:no;center:yes&amp;quot;;
    return showModalDialog(&amp;quot;/sitecore/shell/prompt.html&amp;quot;, arguments, features);
  }
};

But the newer Browser.js still uses something similar so maybe this will be ok…

scBrowser.prototype.prompt = function (text, defaultValue) {
  if (navigator.userAgent.indexOf('Trident') &amp;gt; -1 || this.isSafari) {
    var arguments = new Array(text, defaultValue);
    var data = { height: &amp;quot;110&amp;quot;};
    var features = &amp;quot;dialogWidth:400px;dialogHeight:#{height}px;help:no;scroll:no;resizable:no;status:no;center:yes&amp;quot;.interpolate(data);
    return showModalDialog(&amp;quot;/sitecore/shell/prompt.html&amp;quot;, arguments, features);
  } else {
    return prompt(text, defaultValue);
  }
};

What next?

This needs testing. I haven’t done anything more than what I have said above, which is no way near enough for a production system! If it works for you then please let me know, if it doesn’t then:

  • Fork it on Github and make a pull request with suggested fixes
  • Comment and let me know what the issue is
  • Contact me on Twitter

UPDATE – 05-Sept-14:

Thanks to the testing and feedback from Rob and Ola there has been a small update to EditorPage.js file. When in Page Editor mode and you edit a Rich Text field by launching the RTE editor the modal would not correctly close when you click accept or reject. The code has been updated from Sitecore 7.1 with an IE specific check:

// Page editor
if (scForm.browser.isIE) {
  window.close();
} else if (top._scDialogs.length != 0) {
  top.dialogClose();
} else {
  scCloseRadWindow();
}

There may be more of this type of update that needs to be made, your testing and feedback appreciated.


More Reading:

Screenshots:

Chrome and Firefox now use the new jQuery Modal Dialogs:

showModalDialog Chrome Publish Window

showModalDialog Chrome Upload Window

showModalDialog Chrome Merge Window

showModalDialog Firefox Presentation Details

showModalDialog Chrome Page Editor Related Content

showModalDialog Chrome Page Editor Add Image

Internet Explorer continues to use the old, in-built modal (wich are draggable outside the window context):

showModalDialog IE Publish Window

Advertisements

45 comments

  1. Pingback: Sitecore Modal Dialogs Fix For Chrome 37+ | Sitecore Corner
  2. Rob · September 2, 2014

    Hi. Can you tell me what you modified for the Sitecore.Kernel and Sitecore.Client? Not sure we can override your changes for those in our environment. We have some custom code now that override those files. Thanks.

    • jammykam · September 2, 2014

      There is possibly more that needs to be modified, but I only made 2 small modification to the uiUpload pipeline: https://github.com/jammykam/Sitecore-Dialog-Fix/tree/master/Source/JammyKam.SC.ModalFix/Pipelines/Upload

      See the change applied in the config: https://github.com/jammykam/Sitecore-Dialog-Fix/blob/master/Source/JammyKam.SC.ModalFix/modal-fix.config

      And the only thing that I changed there was the Javascript that gets sent down to the browser: window.top.scForm.browser.getTopModalDialog().frames[0].scForm.postRequest(…)

      This is used to send a message to the browser, e.g. on file upload it moves it to the “successfully uploaded” message for example.

      • Rob · September 4, 2014

        I am still testing, but so far it looks like your fix is working. Thanks.

      • Rob · September 4, 2014

        Just came across one issue. On an RTF the Accept and Reject buttons do not work. Not sure why yet.

      • Ola Owolawi · September 4, 2014

        I did test the RTF accept and reject and it works for me.
        I did it in Canary, Chrome, IE, Safari and it did work for me.
        Please others comment.

      • Rob · September 4, 2014

        The data still gets saved, but just won’t close my window. I get the following in the console:
        Failed to call scGetFrameValue in IFrame tag. This typically happens due to a Permission Denied exception in IE9 caused by an intricate issue with Popup and ShowModalDialog calls. Permission denied to access property ‘scGetFrameValue’

      • Ola Owolawi · September 4, 2014

        I will like to update my comment above about Accept/Reject.
        It works fine via content editor, but not in page editor node.

      • Rob · September 4, 2014

        I was just about to respond and say the same thing as Ola. 🙂

      • jammykam · September 5, 2014

        Thanks for the feedback. I’m able to replicate so will see if I can fix it. Interestingly, by adding in stack trace message I’m getting “Error: Blocked a frame with origin “http://localhost” from accessing a cross-origin frame”… I’ll investigate.

      • jammykam · September 5, 2014

        Find me on Skype, I’ll email you my handle, maybe we can screen share and talk…?

    • Rob · September 5, 2014

      Thanks. I’ll keep testing in the meantime. For this project we use Page Editor a lot so I can test it from different angles.

    • jammykam · September 5, 2014

      Great, thanks for testing further. I’ve noticed that clicking “Accept” then closing the window with X the changes appear in the Page Editor, but rejecting then closing the changes do not, so it is kind of the expected behaviour, it’s just the window does not close. Is that what you are seeing?

      • Ola Owolawi · September 5, 2014

        Yes, that is what I observed too.
        How come Accept/Reject works fine in Content Editor Mode but not in Page Editor Mode?
        Should they not be making the same JS calls?

      • Rob · September 5, 2014

        That is what I am seeing too. If the close works then I think we are good. 🙂 Thanks.

      • jammykam · September 5, 2014

        Thanks for the feedback. I’ve updated the code on Github, there was a small modification required to EditorPage.js – essentially after the accept/reject button is clicked the call to close the modal needed to be updated. Took a while to find 😦

        https://github.com/jammykam/Sitecore-Dialog-Fix/tree/master/Release/sitecore/shell/Controls/Rich%20Text%20Editor

        Ola, the RTE control was updated in Sitecore 6.5 and since then in Content Editor it was been in a jQuery-ish modal, even in IE. There is obviously 2 different javascript calls to create these.

      • Ola Owolawi · September 5, 2014

        Good job Jammykam, I will test it now and update.

        Thanks

        Ola

      • Rob · September 5, 2014

        Thanks! I will test it now.

      • Rob · September 5, 2014

        It works in some cases, but got the errors on one of the RTF boxes. Let me know if you need more info.

        Error when opening RTF:
        Uncaught TypeError: Cannot read property ‘select’ of null Content%20Editor.js:2678Class.create.initializeTreeNodes Content%20Editor.js:2678(anonymous function) Content%20Editor.js:2663Object.extend.__method prototype.js:391responder prototype.js:5575fire prototype.js:5734Object.extend._methodized prototype.js:438fireContentLoadedEvent prototype.js:5820

        Error when clicking Accept:
        Uncaught TypeError: Cannot read property ‘saveRichText’ of undefined EditorPage.js:51Sitecore.Controls.RichEditor.Class.create.saveRichText EditorPage.js:51(anonymous function) VM1447:1scSitecore.process Sitecore.js:911scRequest.resume Sitecore.js:1640scRequest.handle Sitecore.js:1559scRequest.execute Sitecore.js:1529scSitecore.postRequest Sitecore.js:760scSendRequest EditorPage.aspx?da=core&id=%7B561CA33B-D641-4371-B754-2BBC123EC39D%7D&ed=FIELD695427529&vs&la=en&fl…:130(anonymous function) VM1445:1scSitecore.postEvent Sitecore.js:649onclick

      • jammykam · September 5, 2014

        Any consistency to when it works or when it does? Any particular text in the RTE or some actions you are doing? Maybe combination of inserting certain things from the toolbar?

      • Rob · September 5, 2014

        The Reject button always works. If I edit rich text directly that is on the page via page editor (click on editor button) that brings the RTF box with text and the Accept and Reject. That works. If I bring up the RTF editor directly, for instance we have a custom comment box it does not work. It comes up (first error) and then I click on the Show Editor link and the RTF box comes up. The Accept does not work, but the Reject does. I am not using anything special. Let me know if it would be easier to send you screen shots. I am trying to explain it the best I can. 🙂 Thanks.

      • Rob · September 5, 2014

        I sent you some screenshots via Skype. Let me know if you don’t get them. Thanks.

      • Rob · September 8, 2014

        Hello. I worked with another developer and we fixed one issue (Publishing) that we found. I am going to email you the code so you can add it to the file. Thanks.

      • Izzuddin Noor · November 27, 2014

        Rob what was your solution to Uncaught TypeError: Cannot read property ‘saveRichText’ of undefined

      • Rob · November 28, 2014

        Izzuddin Noor. We never could fix that. It looks like something that persisted in the hot fix as well. We ended upgrading to 7.2 and don’t get the error.

      • Izzuddin Noor · November 28, 2014

        Thanks Rob. Yeah I guess that is the current thought that we have in mind too.

      • jammykam · November 28, 2014

        The temp fix is to enable EnableDeprecatedWebPlatformFeatures but that is only valid until May 2015 (but at least it buys you some time…)

  3. Ola Owolawi · September 3, 2014

    I have tried this fix on my local version of our site Sitecore 7.0 and it works for me.

    • jammykam · September 4, 2014

      Great, thanks for the feedback. Let me know if you come across any issue.

  4. Paul Martin · September 5, 2014

    Nice work on this. I’m going to try this out today… I’ll let you know how it goes.

    • jammykam · September 5, 2014

      Thanks Paul. Just made a small update to fix an issue with the RTE in Page Editor mode, see the comments above. Code is in Github.

  5. Anders Pedersen (@bredstrup) · September 9, 2014

    Thanks Jammykam, nice work.

    I’ve installed the patch on a 7.0 solution using Page Edit and Webforms for Marketers. I’ve noticed a problem when editing a WFM form using Page Edit. When selecting the form, and clicking “Edit form” (The green pencil icon), I get the following JS error:

    Uncaught TypeError: Cannot read property ‘select’ of null (Content Editor.js:2686)

    When inspecting content editor.js line 2686, this is the offending code:

    initializeTreeNodes: function (root) {
    –> var elements = root.select(“.scContentTreeNodeNormal, .scContentTreeNodeActive”);

    obviously “root” is undefined. This is not the case, if I uninstall the patch. I’ve tested and confirmed this behavior on Firefox and Chrome.

    The error prevents the form editor dialog from closing when user clicks “close” and “save and close” ribbon buttons. Annoying. I’ve noticed that Webforms for Marketers use jQuery dialog even without the patch – could it be a clash between the patch and the WFM implementation of the jQuery dialog component?

    Best,
    Anders

  6. lashon daklem · October 14, 2014

    Hello! I’ve been reading your web site for a while now and finally got the bravery to
    go ahead and give you a shout out from Kingwood Texas!
    Just wanted to mention keep up the excellent job!

  7. Brian · November 6, 2014

    Hi.. great effort.
    I’ve just tested and the one that is not working for me is clicking ‘show editor’ after using the ‘edit the related item’ option on the page editor. You know, where you get split screen?
    The Sitecore fix doesn’t work for this one either.
    Anyone else having this problem?

    • jammykam · November 6, 2014

      Hi Brian,

      I kind if abandoned this as soon as Sitecore released their fix (which I am using myself now). The most likely reason for this not working is a modal window reference or something, do you get any Javascript errors? I would suggest raising a ticket with Sitecore directly, there were a couple of other things raised by other people which were not fixed correctly either 😦

      • Rob · November 6, 2014

        We had a hotfix from Sitecore, but still had trouble with the same thing. We tried to fix some of the issues, but had to find other ways around them. We ended upgrading to 7.2. The 7.2 upgrade fixed the issues I saw with the hotfix. Like jammykam said I would raise the issue with Sitecore. Good luck.

  8. Izzuddin Noor · November 27, 2014

    Runngin SC6.6 I had this problem same like Rob, does anyone knows the fix ?
    Uncaught TypeError: Cannot read property ‘saveRichText’ of undefined

    • jammykam · November 27, 2014

      Unfortunately Sitecore did not provide a fix for this. We may have this also become an issue on a 6.6 project which is using RTE fields in Rendering Parameters soon.. currently the solution seems to be to either upgrade to Sitecore 7.2 or use Internet Explorer/Firefox as a workaround (which is an acceptable solution for this us since it’s only the devs using Chrome)

      • Izzuddin Noor · November 27, 2014

        Thanks Jammy, I guess rolling chrome to version 36 might help for a moment.

      • jammykam · November 27, 2014

        You can also EnableDeprecatedWebPlatformFeatures in Chrome, see the last solution of https://kb.sitecore.net/articles/581527, but it will only work until May 2015. I would recommend this approach.

      • Izzuddin Noor · November 29, 2014

        Yes we done this, apparently Chrome 39 killing it too. Thanks for that suggestion.

      • jammykam · November 29, 2014

        Yes, it’s never coming back! Firefox will kill it too, Opera is close behind… I imagine IE will support it for a while…

  9. Shriroop · December 3, 2014

    Great work! Using your fix in our project – keep up the good work.

  10. Pingback: Fix Chrome Jquery Error Errors - Windows XP, Vista, 7, 8

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s