Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Zone already loaded with SharePoint OnLine #434

Closed
DSHaworth opened this issue Sep 10, 2016 · 14 comments
Closed

Zone already loaded with SharePoint OnLine #434

DSHaworth opened this issue Sep 10, 2016 · 14 comments

Comments

@DSHaworth
Copy link

This appeared with the latest release.

When using Angular2 RC6 and the newest zone.js within SharePoint OnLine, by the time Zone.JS is loaded, SharePoint has already staked a claim to "global.Zone" and stops dead in its tracks.

@lifan0127
Copy link

@DSHaworth have you tried to revert your code to pre-RC6 and see if the problem still exists? I also encountered this issue when upgrading yesterday, but somehow the error still exists after I reverted back to RC4. I wonder if something changed on the SharePoint side.

@lifan0127
Copy link

@DSHaworth A temporary solution is to use zone.js 0.6.12 instead of newer version. Below is the reason:

It appears since 0.6.13, zone.js will throw an error if global Zone has been defined.

https://github.com/angular/zone.js/blob/v0.6.13/dist/zone.js#L153

if (global.Zone) {
    throw new Error('Zone already loaded.');
}

which is the case in SharePoint where a Zone function has been defined in msformbundle.js to manipulate web parts:

function Zone(c, h, i, d, f, g) {
    var b = null ;
    if (c.rows.length == 1)
        webPartTableContainer = c.rows[0].cells[0];
    else
        webPartTableContainer = c.rows[1].cells[0];
    for (var a = 0; a < webPartTableContainer.childNodes.length; a++) {
        var e = webPartTableContainer.childNodes[a];
        if (e.tagName == "TABLE") {
            b = e;
            break
        }
    }
    this.zoneElement = c;
    this.zoneIndex = h;
    this.webParts = [];
    this.uniqueID = i;
    this.isVertical = d;
    this.allowLayoutChange = f;
    this.allowDrop = false;
    this.webPartTable = b;
    this.highlightColor = g;
    this.savedBorderColor = b != null ? b.style.borderColor : null ;
    this.dropCueElements = [];
    if (b != null )
        if (d)
            for (a = 0; a < b.rows.length; a += 2)
                this.dropCueElements[a / 2] = b.rows[a].cells[0].childNodes[0];
        else
            for (a = 0; a < b.rows[0].cells.length; a += 2)
                this.dropCueElements[a / 2] = b.rows[0].cells[a].childNodes[0];
    this.AddWebPart = Zone_AddWebPart;
    this.GetWebPartIndex = Zone_GetWebPartIndex;
    this.ToggleDropCues = Zone_ToggleDropCues;
    this.UpdatePosition = Zone_UpdatePosition;
    this.Dispose = Zone_Dispose;
    b.__zone = this;
    b.attachEvent("ondragenter", Zone_OnDragEnter);
    b.attachEvent("ondrop", Zone_OnDrop)
}

So a temporary solution for me is to stay with zonejs 0.6.12. However, allowing zonejs to overwrite global.Zone may have some negative impact on SharePoint functionalities that remain to be seen.

@DSHaworth
Copy link
Author

@lifan0127 Thanks for the response..AngularRC6 wants the latest zone.js, so I'd need to go back to RC5....that's the last time everything worked.

@mhevery
Copy link
Contributor

mhevery commented Sep 11, 2016

Not sure what the solution here is. Sharepoint should not litter global namespace. I think throwing an error is the right thing.

a workaround may be to clear the sharepoint Zone before loading zone.js

Closing as I don't think there is anything to be done on our part.

@mhevery mhevery closed this as completed Sep 11, 2016
@manlamcheng
Copy link

"a workaround may be to clear the sharepoint Zone before loading zone.j"

hi, can you tell me how to clear the SharePoint Zone ?

Thanks

@AntonFLB
Copy link

Clear SharePoint Zone leads to issues with "edit page" and ribbon command bar.
My question is why need zone.js to overwrite a global scope variable? (nevertheless what ms do is not the best way)
Maybe its possible to use a local or custom namespace?

Greetings
Anton

@dev4201
Copy link

dev4201 commented Oct 19, 2016

@lifan0127 - I'm facing the same issue, have you been able to find a workaround?

@AntonFLB - Can provide details how you were able to clear SharePoint zone?

@lifan0127
Copy link

@dev4201 I would just comment out the global.Zone check in zone.js and allow Angular and SharePoint to share the namespace.

@manlamcheng
Copy link

I was able to get it working without comment out the global zone check in zone.js. It's one of the modules or assemblies that loads global zone before zone.js. I tried to remove one by one from default.aspx page, and eventually got it working.
I would recommend to download shim, zone, reflect-metadata and system.src js files so that they can match the version on your package.json.


`<%@register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@register TagPrefix="PublishingRibbon" TagName="PublishingRibbon" Src="~/_controltemplates/15/Ribbon.ascx"%>

<head runat="server">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>

    <SharePoint:CssLink runat="server" Version="15"></SharePoint:CssLink>
    <SharePoint:ScriptLink language="javascript" name="core.js" OnDemand="true" runat="server" Localizable="false" />
    <SharePoint:ScriptLink language="javascript" name="menu.js" OnDemand="true" runat="server" Localizable="false" />


<link rel="stylesheet" href="../Content/bootstrap.min.css" />
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" media="all">
<link rel="stylesheet" href="../Content/app.css" />
<script type="text/javascript" src="../Scripts/jquery-3.1.0.min.js"></script>

    <script type="text/javascript" src="../Scripts/angular/shim.min.js"></script>
    <script type="text/javascript" src="../Scripts/angular/zone.js"></script>
    <script type="text/javascript" src="../Scripts/angular/reflect-metadata.js"></script>
    <script type="text/javascript" src="../Scripts/angular/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script type="text/javascript" src="../Scripts/systemjs.config.js"></script>
<script>System.import('appCode').catch(function (err) { console.error(err); });</script>
/SharePoint:SharePointForm
<my-app>Loading...</my-app>

<!--people picker-->
<SharePoint:ScriptLink name="clienttemplates.js" runat="server" LoadAfterUI="true" Localizable="false" />
<SharePoint:ScriptLink name="clientforms.js" runat="server" LoadAfterUI="true" Localizable="false" />
<SharePoint:ScriptLink name="clientpeoplepicker.js" runat="server" LoadAfterUI="true" Localizable="false" />
<SharePoint:ScriptLink name="autofill.js" runat="server" LoadAfterUI="true" Localizable="false" />
<SharePoint:ScriptLink name="sp.js" runat="server" LoadAfterUI="true" Localizable="false" />
<SharePoint:ScriptLink name="sp.runtime.js" runat="server" LoadAfterUI="true" Localizable="false" />
<SharePoint:ScriptLink name="sp.core.js" runat="server" LoadAfterUI="true" Localizable="false" />

`

@manlamcheng
Copy link

manlamcheng commented Oct 19, 2016

github remove few line of code on my reply
here it's

`

`

@dev4201
Copy link

dev4201 commented Oct 19, 2016

Got it to work with @lifan0127 suggestion, but I'll try to reorder my references.

Thank you both for your help!

@mhevery
Copy link
Contributor

mhevery commented Oct 19, 2016

Clobberin global Zone by suppressing the check means that we can just clear the Zone.

<script>window.Zone = undefined</scritp>
<script src="zone.js"></script>

@jarzimichal
Copy link

jarzimichal commented Dec 28, 2016

I have tried both methods:

  1. Commenting if (global.Zone) check in zone.js file
  2. setting window.Zone = undefined

and my Angular2 app in SharePonint Online works fine, however that breaks the Office 365 Ribbon when I hover Settings or Profile button (top right corner). I got errors from zone.js that the method is missing:
TypeError: $a is not a function.

Those buttons should use SharePoint Zone namespace, rather than zone.js, which override the MS namespace.

This is SharePoint issue as they polluted global namespace and we can't use zonej.js.
Does anyone know how to find a workaround for broken O365 Ribbon when using zone.js?
Is MS working on fix for that?

@lifan0127
Copy link

@jarzimichal In my case the SharePoint ribbon was still functional. However my app was built with ng2-beta + zone 0.6.13.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants