[JENKINS-70906] Remove prototype from core (#7781)

* Remove Ajax.Request from breadcrumbs

* Remove Ajax.Request from build-timeline-widget

* WIP

* Use crumb API for setting up crumb

* Use existing semantics

* Fix build button column

* Add comment explaining why catch is added

* Use post and crumb for combobox

* Lint fix

* More fixes

* Fixes

* Fix

* Fix validate button

htmlunit was a pain...

* Lint fix

* Fix URICheckEncodingMonitor

* Add a user experimental flag to run Jenkins without Prototype.js

* Adapt select.js

* Fix parameter support

* JENKINS-70922 Remove Prototype Ajax.Request usage from select.js

* Lint:fix

* More

* lint

* Rebased

* Lint

* Fix bad merge

* JENKINS-70931 Remove Prototype Ajax.Request usages from hudson-behavior.js

Co-authored-by: Basil Crow <me@basilcrow.com>

* Fix URICheckEncodingMonitor

* JENKINS-70921 Remove Prototype Ajax.Request usages from link.js

* Remove dead code

* JENKINS-70910 Remove Prototype.Browser usages from hudson-behavior.js

* JENKINS-70947 Remove Prototype $ usage from section_.js

* Prototype removal true

* Remove unneeded test

* Remove hacky test that doesn't work with fetch

* Remove unneeded workaround

* Fix test

* Minor improvements while debugging

* Fix repeatable.js

* JENKINS-71020 Remove Prototype usages from buildTimeTrend_resources.js

* lint

* JENKINS-71020 Remove Prototype usages from buildTimeTrend_resources.js

* Use escapeHTML instead of inlined references

* Fix issues

* JENKINS-70931 Remove Prototype Ajax.Request usages from hudson-behavior.js

Co-authored-by: Basil Crow <me@basilcrow.com>

* Remove hacky test that doesn't work with fetch

* Remove unused checkMethod

* Revert "Revert "JENKINS-70922 Remove Prototype Ajax.Request usage from select.js""

This reverts commit 2cff5b87b5.

* Serialise refills

Co-authored-by: Basil Crow <me@basilcrow.com>

* More reverts

* More merge

* Remove prototype.js

* Remove more references

---------

Co-authored-by: Basil Crow <me@basilcrow.com>
This commit is contained in:
Tim JacombandBasil Crow authored and GitHub committed 2023-10-01 15:56:56 -06:00
1 parent 02502e28b6
commit e37ef3a8e6
11 files changed
+7 -6356

No files matched your search

@@ -1,54 +0,0 @@
/*
* The MIT License
*
* Copyright (c) 2023, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package jenkins.model.experimentalflags;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import hudson.Extension;
@Extension
public final class RemovePrototypeUserExperimentalFlag extends BooleanUserExperimentalFlag {
public RemovePrototypeUserExperimentalFlag() {
super("remove-prototype.flag");
}
@NonNull
@Override
public Boolean getDefaultValue() {
return false;
}
@Override
public String getDisplayName() {
return "Remove Prototype.js";
}
@Nullable
@Override
public String getShortDescription() {
return "Remove Prototype.js from all Jenkins UI pages. This will break anything that depends on Prototype.js.";
}
}
@@ -109,13 +109,9 @@ function confirmAndRevokeAllSelected(button) {
selectedValues.push({ userId: userId, uuid: uuid });
}
// TODO simplify when Prototype.js is removed
fetch(url, {
method: "post",
body: Object.toJSON
? Object.toJSON({ values: selectedValues })
: JSON.stringify({ values: selectedValues }),
body: JSON.stringify({ values: selectedValues }),
headers: crumb.wrap({ "Content-Type": "application/json" }),
}).then(() => window.location.reload());
},
@@ -123,10 +123,6 @@ THE SOFTWARE.
<link rel="mask-icon" href="${resURL}/mask-icon.svg" color="#191717" />
<meta name="theme-color" content="#ffffff" />
<l:userExperimentalFlag var="removePrototype" flagClassName="jenkins.model.experimentalflags.RemovePrototypeUserExperimentalFlag" />
<j:if test="${!removePrototype}">
<script src="${resURL}/scripts/prototype.js" type="text/javascript"/>
</j:if>
<script src="${resURL}/scripts/behavior.js" type="text/javascript"/>
<st:adjunct includes="org.kohsuke.stapler.bind"/>
@@ -1,42 +0,0 @@
package hudson;
import hudson.model.InvisibleAction;
import hudson.model.RootAction;
import org.htmlunit.ScriptException;
import org.htmlunit.WebClientUtil;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.JenkinsRule.WebClient;
import org.jvnet.hudson.test.TestExtension;
/**
* @author Kohsuke Kawaguchi
*/
public class ExceptionTest {
@Rule public JenkinsRule j = new JenkinsRule();
/**
* Makes sure that an AJAX handler error results in a fatal problem in the unit test.
*/
@Test
public void testAjaxError() throws Exception {
WebClient webClient = j.createWebClient();
WebClientUtil.ExceptionListener exceptionListener = WebClientUtil.addExceptionListener(webClient);
webClient.goTo("self/ajaxError");
// Check for the error.
ScriptException e = exceptionListener.getExpectedScriptException();
Assert.assertTrue(e.getMessage().contains("simulated error"));
}
@TestExtension
public static final class RootActionImpl extends InvisibleAction implements RootAction {
@Override
public String getUrlName() {
return "self";
}
}
}
@@ -1,41 +0,0 @@
<!--
The MIT License
Copyright (c) 2004-2010, Sun Microsystems, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<!--
Entrance to the configuration page
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:s="/lib/form">
<l:layout title="Nodes">
<l:main-panel>
<script>
new Ajax.Request("./ajaxError", {
onComplete: function() {
throw "simulated error"; // simulated failure in AJAX call handling
}
});
</script>
</l:main-panel>
</l:layout>
</j:jelly>
+2 -9
View File
@@ -5,14 +5,7 @@ if (typeof JSON=="undefined") {
return String.evalJSON(str);
},
stringify : function (obj) {
// TODO simplify when Prototype.js is removed
if (Object.toJSON) {
// Prototype.js
return Object.toJSON(obj);
} else {
// Standard
return JSON.stringify(obj);
}
return JSON.stringify(obj);
}
};
}
}
-1
View File
@@ -11,5 +11,4 @@ jsbundles
# External scripts
src/main/webapp/scripts/yui
src/main/webapp/scripts/prototype.js
src/main/js/plugin-setup-wizard/bootstrap-detached.js
-1
View File
@@ -12,7 +12,6 @@ node/
# libraries / external deps / generated files
src/main/js/plugin-setup-wizard/bootstrap-detached.js
src/main/webapp/scripts/yui
src/main/webapp/scripts/prototype.js
src/main/webapp/jsbundles/
src/main/scss/_bootstrap.scss
+2 -38
View File
@@ -17,42 +17,6 @@ jenkins.baseUrl = function () {
return u;
};
// awful hack to get around JSONifying things with Prototype taking over wrong. ugh. Prototype is the worst.
jenkins.stringify = function (o) {
if (Array.prototype.toJSON) {
// Prototype f's this up something bad
var protoJSON = {
a: Array.prototype.toJSON,
o: Object.prototype.toJSON,
h: Hash.prototype.toJSON,
s: String.prototype.toJSON,
};
try {
delete Array.prototype.toJSON;
delete Object.prototype.toJSON;
delete Hash.prototype.toJSON;
delete String.prototype.toJSON;
return JSON.stringify(o);
} finally {
if (protoJSON.a) {
Array.prototype.toJSON = protoJSON.a;
}
if (protoJSON.o) {
Object.prototype.toJSON = protoJSON.o;
}
if (protoJSON.h) {
Hash.prototype.toJSON = protoJSON.h;
}
if (protoJSON.s) {
String.prototype.toJSON = protoJSON.s;
}
}
} else {
return JSON.stringify(o);
}
};
/**
* redirect
*/
@@ -82,7 +46,7 @@ jenkins.get = function (url, success, options) {
};
/**
* Jenkins AJAX POST callback, formats data as a JSON object post (note: works around prototype.js ugliness using stringify() above)
* Jenkins AJAX POST callback, formats data as a JSON object post
* If last parameter is an object, will be extended to jQuery options (e.g. pass { error: function() ... } to handle errors)
*/
jenkins.post = function (url, data, success, options) {
@@ -110,7 +74,7 @@ jenkins.post = function (url, data, success, options) {
formBody = $.extend({}, formBody);
formBody[crumb.fieldName] = crumb.value;
}
formBody = jenkins.stringify(formBody);
formBody = JSON.stringify(formBody);
}
var args = {
+2 -28
View File
@@ -2200,6 +2200,7 @@ function encode(str) {
// when there are multiple form elements of the same name,
// this method returns the input field of the given name that pairs up
// with the specified 'base' input element.
// eslint-disable-next-line no-unused-vars
function findMatchingFormInput(base, name) {
// find the FORM element that owns us
var f = base.closest("form");
@@ -2232,17 +2233,6 @@ function findMatchingFormInput(base, name) {
return null; // not found
}
// TODO remove when Prototype.js is removed
if (typeof Form === "object") {
/** @deprecated For backward compatibility only; use {@link findMatchingFormInput} instead. */
Form.findMatchingInput = function (base, name) {
console.warn(
"Deprecated call to Form.findMatchingInput detected; use findMatchingFormInput instead.",
);
return findMatchingFormInput(base, name);
};
}
// eslint-disable-next-line no-unused-vars
function toQueryString(params) {
var query = "";
@@ -2627,14 +2617,7 @@ function buildFormTree(form) {
}
}
// TODO simplify when Prototype.js is removed
if (Object.toJSON) {
// Prototype.js
jsonElement.value = Object.toJSON(form.formDom);
} else {
// Standard
jsonElement.value = JSON.stringify(form.formDom);
}
jsonElement.value = JSON.stringify(form.formDom);
// clean up
for (i = 0; i < doms.length; i++) {
@@ -2803,15 +2786,6 @@ function createComboBox(idOrField, valueFunction) {
}
}
// Exception in code during the AJAX processing should be reported,
// so that our users can find them more easily.
// TODO remove when Prototype.js is removed
if (typeof Ajax === "object" && Ajax.Request) {
Ajax.Request.prototype.dispatchException = function (e) {
throw e;
};
}
// event callback when layouts/visibility are updated and elements might have moved around
var layoutUpdateCallback = {
callbacks: [],
File diff suppressed because it is too large. Load diff