Skip to content

Commit

Permalink
[JENKINS-74067] Extract inline JavaScript from `BuildMonitorView/inde…
Browse files Browse the repository at this point in the history
…x.jelly` (#1034)
  • Loading branch information
yaroslavafenkin authored Nov 13, 2024
1 parent f827941 commit 0e937b4
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 80 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
window.addEventListener("DOMContentLoaded", () => {
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;

const {
buildMonitorVersion,
jenkinsVersion,
installationSize,
itemsSize,
installationAudience,
anonymousCorrelationId
} = document.querySelector('.build-monitor-ga-data-holder').dataset;

ga('create', 'UA-61694827-4', 'auto', {
'userId': anonymousCorrelationId,
'sampleRate': 1
});

ga('set', {
'forceSSL': true,
'appName': 'Build Monitor',
'appId': 'build-monitor-plugin',

'appVersion': buildMonitorVersion,
'appInstallerId': jenkinsVersion,

'dimension1': installationSize,
'dimension2': itemsSize,
'dimension3': installationAudience,
'dimension4': anonymousCorrelationId
});

ga('send', 'screenview', {screenName: 'Dashboard'});
});
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,7 @@
<script src="${resourcesURL}/vendor/angular-slider-5.4.0/rzslider.min.js"></script>

<j:if test="${it.collectAnonymousUsageStatistics()}">
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;

ga('create', 'UA-61694827-4', 'auto', {
'userId': '${it.installation.anonymousCorrelationId()}',
'sampleRate': 1
});

ga('set', {
'forceSSL': true,
'appName': 'Build Monitor',
'appId': 'build-monitor-plugin',

'appVersion': '${it.installation.buildMonitorVersion()}',
'appInstallerId': '${h.version}',

'dimension1': '${it.installation.size()}',
'dimension2': '${it.items.size()}',
'dimension3': '${it.installation.audience()}',
'dimension4': '${it.installation.anonymousCorrelationId()}'
});

ga('send', 'screenview', {screenName: 'Dashboard'});
</script>
<st:adjunct includes="com.smartcodeltd.jenkinsci.plugins.buildmonitor.BuildMonitorView.collect-usage-stats"/>
<script async="async" src='//www.google-analytics.com/analytics.js'></script>
</j:if>
</head>
Expand All @@ -92,6 +69,15 @@
<a class="home-link" href="${rootURL}/" title="Jenkins">Jenkins</a>
<h1><a href="configure" title="Configure the '${it.title}' view">${it.title}</a></h1>
<st:include page="main-settings.jelly"/>
<j:if test="${it.collectAnonymousUsageStatistics()}">
<span class="build-monitor-ga-data-holder"
data-build-monitor-version="${it.installation.buildMonitorVersion()}"
data-jenkins-version="${h.version}"
data-installation-size="${it.installation.size()}"
data-items-size="${it.items.size()}"
data-installation-audience="${it.installation.audience()}"
data-anonymous-correlation-id="${it.installation.anonymousCorrelationId()}"/>
</j:if>
</header>

<j:choose>
Expand Down Expand Up @@ -128,44 +114,9 @@
</div>
</footer>

<script>
/*
* todo: (13.08.2013) Replace the below workaround with a custom Jelly tag (ExposeBindTag)
* extending either org.kohsuke.stapler.jelly.BindTag or AbstractStaplerTag,
* that would supersede currently defective BindTag implementation:
* - https://groups.google.com/forum/#!topic/jenkinsci-dev/S9bhX4ts0g4
* - https://issues.jenkins-ci.org/browse/JENKINS-18641
*
* Defect in BindTag manifests itself by causing a JavaScript error and preventing scripts after
* the &lt;st:bind&gt; invocation from executing, which results in an "empty Build Monitor".
* The issue occurs on Jenkins 1.521-1.526, only if the jQuery plugin is used.
*
* Motivation behind a custom Jelly tag:
* Original implementation of the BindTag doesn't provide an easy way of handling AJAX errors,
* which may happen if a network connection is lost or when Jenkins is restarted (which then makes
* Stapler's binding hash obsolete and Jenkins return 404 for any subsequent requests).
*
* Custom Jelly tag should generate a JSON object exposing the binding, leaving the implementation
* of the proxy to the Developer. It makes more sense for a developer to require a binding adapter
* implementation specific to their JavaScript framework of choice, rather than for Stapler to try
* to predict what JavaScript libraries will ever be used with it in the future...
*/
window.originalMakeStaplerProxy = window.makeStaplerProxy;
window.makeStaplerProxy = function(url, crumb, methods) {
return { url: url, crumb: crumb, methods: methods }
};
window.bindings={};
</script>
<st:adjunct includes="com.smartcodeltd.jenkinsci.plugins.buildmonitor.BuildMonitorView.replace-stapler-proxy"/>
<st:bind var="buildMonitorBind" value="${it}" />
<script>
window.bindings['buildMonitor'] = buildMonitorBind
window.makeStaplerProxy = window.originalMakeStaplerProxy;
try {
delete window.originalMakeStaplerProxy;
} catch(e) {
window["originalMakeStaplerProxy"] = undefined;
}
</script>
<st:adjunct includes="com.smartcodeltd.jenkinsci.plugins.buildmonitor.BuildMonitorView.restore-stapler-proxy"/>

<!-- todo: use require.js and bundle it all up -->
<script src="${resourcesURL}/scripts/app.js"></script>
Expand All @@ -180,26 +131,11 @@
<script src="${resourcesURL}/scripts/expansions/build-number.js"></script>
<script src="${resourcesURL}/scripts/expansions/build-time.js"></script>
<script src="${resourcesURL}/scripts/slot.js"></script>
<script>
'use strict';

angular.

module('buildMonitor').

constant('BUILD_MONITOR_VERSION', '${it.installation.buildMonitorVersion()}').
constant('CSRF_CRUMB_FIELD_NAME', '${it.csrfCrumbFieldName}').

config(function(proxyProvider, cookieJarProvider, hashCodeProvider) {
var hashCodeOf = hashCodeProvider.hashCodeOf;

proxyProvider.configureProxiesUsing(window.bindings);

cookieJarProvider.describe({
label: 'buildMonitor.' + hashCodeOf(document.body.dataset.displayName)
});
});
</script>
<span class="build-monitor-data-holder"
data-build-monitor-version="${it.installation.buildMonitorVersion()}"
data-csrf-crumb-field-name="${it.csrfCrumbFieldName}"/>
<st:adjunct includes="com.smartcodeltd.jenkinsci.plugins.buildmonitor.BuildMonitorView.init-build-monitor"/>
</body>
</html>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

(function() {
const { buildMonitorVersion, csrfCrumbFieldName } = document.querySelector(".build-monitor-data-holder").dataset;

angular
.module('buildMonitor')
.constant('BUILD_MONITOR_VERSION', buildMonitorVersion)
.constant('CSRF_CRUMB_FIELD_NAME', csrfCrumbFieldName)
.config(function(proxyProvider, cookieJarProvider, hashCodeProvider) {
var hashCodeOf = hashCodeProvider.hashCodeOf;

proxyProvider.configureProxiesUsing(window.bindings);

cookieJarProvider.describe({
label: 'buildMonitor.' + hashCodeOf(document.body.dataset.displayName)
});
});
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* todo: (13.08.2013) Replace the below workaround with a custom Jelly tag (ExposeBindTag)
* extending either org.kohsuke.stapler.jelly.BindTag or AbstractStaplerTag,
* that would supersede currently defective BindTag implementation:
* - https://groups.google.com/forum/#!topic/jenkinsci-dev/S9bhX4ts0g4
* - https://issues.jenkins-ci.org/browse/JENKINS-18641
*
* Defect in BindTag manifests itself by causing a JavaScript error and preventing scripts after
* the &lt;st:bind&gt; invocation from executing, which results in an "empty Build Monitor".
* The issue occurs on Jenkins 1.521-1.526, only if the jQuery plugin is used.
*
* Motivation behind a custom Jelly tag:
* Original implementation of the BindTag doesn't provide an easy way of handling AJAX errors,
* which may happen if a network connection is lost or when Jenkins is restarted (which then makes
* Stapler's binding hash obsolete and Jenkins return 404 for any subsequent requests).
*
* Custom Jelly tag should generate a JSON object exposing the binding, leaving the implementation
* of the proxy to the Developer. It makes more sense for a developer to require a binding adapter
* implementation specific to their JavaScript framework of choice, rather than for Stapler to try
* to predict what JavaScript libraries will ever be used with it in the future...
*/
window.originalMakeStaplerProxy = window.makeStaplerProxy;
window.makeStaplerProxy = function(url, crumb, methods) {
return { url, crumb, methods }
};
window.bindings = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
window.bindings['buildMonitor'] = buildMonitorBind;
window.makeStaplerProxy = window.originalMakeStaplerProxy;
try {
delete window.originalMakeStaplerProxy;
} catch(e) {
window["originalMakeStaplerProxy"] = undefined;
}

0 comments on commit 0e937b4

Please sign in to comment.