Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Merge pull request #545 from jglick/Behaviour-specify-14495
[JENKINS-14495] Define Behaviour.specify.
- Loading branch information
|
@@ -56,6 +56,11 @@ |
|
|
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=--> |
|
|
<ul class=image> |
|
|
<li class=bug> |
|
|
Refactored <code>behavior.js</code> to run more predictably. |
|
|
Plugin JavaScript should use <code>Behaviour.specify</code> in place of |
|
|
<code>Behaviour.register</code>, <code>Behaviour.list</code>, |
|
|
<code>hudsonRules</code>, and <code>jenkinsRules</code>. |
|
|
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-14495">issue 14495</a> cont'd) |
|
|
Fixed a possible race condition in the remoting layer. |
|
|
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-14909">issue 14909</a>) |
|
|
<li class=bug> |
|
|
|
@@ -20,8 +20,7 @@ function showhideCategory(col) { |
|
|
row.style.display = newDisplay; |
|
|
} |
|
|
|
|
|
Behaviour.register({ |
|
|
"#filter-box": function(e) { |
|
|
Behaviour.specify("#filter-box", '_table', 0, function(e) { |
|
|
function applyFilter() { |
|
|
var filter = e.value.toLowerCase(); |
|
|
["TR.plugin","TR.plugin-category"].each(function(clz) { |
|
@@ -36,5 +35,4 @@ Behaviour.register({ |
|
|
} |
|
|
|
|
|
e.onkeyup = applyFilter; |
|
|
} |
|
|
}); |
|
|
@@ -1,11 +1,8 @@ |
|
|
(function() { |
|
|
Behaviour.register({ |
|
|
|
|
|
"INPUT.reveal-expandable-detail" : function(e) { |
|
|
Behaviour.specify("INPUT.reveal-expandable-detail", 'ExpandableDetailsNote', 0, function(e) { |
|
|
var detail = e.nextSibling; |
|
|
makeButton(e,function() { |
|
|
detail.style.display = (detail.style.display=="block")?"none":"block"; |
|
|
}); |
|
|
} |
|
|
}); |
|
|
}()); |
|
@@ -29,7 +29,7 @@ THE SOFTWARE. |
|
|
<f:entry title="${%Node/Label}" field="labels"> |
|
|
<div class="yahooTree labelAxis-tree" style="border: 1px solid gray; height: 10em; overflow:auto;" values="${instance.valueString}" /> |
|
|
<script> |
|
|
hudsonRules["DIV.labelAxis-tree"] = function(e) { |
|
|
Behaviour.specify("DIV.labelAxis-tree", 'LabelAxis', 0, function(e) { |
|
|
var tree = new YAHOO.widget.TreeView(e); |
|
|
|
|
|
var labels = new YAHOO.widget.TextNode("${%Labels}", tree.getRoot(), false); |
|
@@ -60,7 +60,7 @@ THE SOFTWARE. |
|
|
tree.subscribe("clickEvent", function(node) { |
|
|
return false; |
|
|
}); |
|
|
}; |
|
|
}); |
|
|
</script> |
|
|
</f:entry> |
|
|
</j:jelly> |
|
@@ -144,16 +144,15 @@ THE SOFTWARE. |
|
|
}); |
|
|
})(); |
|
|
|
|
|
Behaviour.register({ |
|
|
"#${strategyid} TD.stop A.remove" : function(e) { |
|
|
Behaviour.specify("#${strategyid} TD.stop A.remove", 'GlobalMatrixAuthorizationStrategy', 0, function(e) { |
|
|
e.onclick = function() { |
|
|
var tr = findAncestor(this,"TR"); |
|
|
tr.parentNode.removeChild(tr); |
|
|
return false; |
|
|
} |
|
|
e = null; <!-- avoid memory leak --> |
|
|
}, |
|
|
"#${strategyid} TD.stop A.toggleall" : function(e) { |
|
|
}); |
|
|
Behaviour.specify("#${strategyid} TD.stop A.toggleall", 'GlobalMatrixAuthorizationStrategy', 0, function(e) { |
|
|
e.onclick = function() { |
|
|
var tr = findAncestor(this,"TR"); |
|
|
var inputs = tr.getElementsByTagName("INPUT"); |
|
@@ -163,15 +162,14 @@ THE SOFTWARE. |
|
|
return false; |
|
|
}; |
|
|
e = null; <!-- avoid memory leak --> |
|
|
}, |
|
|
}); |
|
|
<j:if test="${empty(descriptorPath)}"> |
|
|
<j:set var="descriptorPath" value="${descriptor.descriptorFullUrl}"/> |
|
|
</j:if> |
|
|
<!-- validates the name --> |
|
|
"#${strategyid} TR.permission-row" : function(e) { |
|
|
Behaviour.specify("#${strategyid} TR.permission-row", 'GlobalMatrixAuthorizationStrategy', 0, function(e) { |
|
|
FormChecker.delayedCheck("${descriptorPath}/checkName?value="+encodeURIComponent(e.getAttribute("name")),"GET",e.firstChild); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
</script> |
|
|
</f:block> |
|
|
</j:jelly> |
|
|
@@ -1,5 +1,4 @@ |
|
|
Behaviour.register({ |
|
|
"INPUT.advanced-button" : function(e) { |
|
|
Behaviour.specify("INPUT.advanced-button", 'advanced', 0, function(e) { |
|
|
makeButton(e,function(e) { |
|
|
var link = e.target; |
|
|
while(!Element.hasClassName(link,"advancedLink")) |
|
@@ -23,5 +22,4 @@ Behaviour.register({ |
|
|
layoutUpdateCallback.call(); |
|
|
}); |
|
|
e = null; // avoid memory leak |
|
|
} |
|
|
});
|
|
|
@@ -1,5 +1,4 @@ |
|
|
Behaviour.register({ |
|
|
"INPUT.apply-button":function (e) { |
|
|
Behaviour.specify("INPUT.apply-button", 'apply', 0, function (e) { |
|
|
var id; |
|
|
var containerId = "container"+(iota++); |
|
|
|
|
@@ -63,5 +62,4 @@ Behaviour.register({ |
|
|
f.target = null; |
|
|
} |
|
|
}); |
|
|
} |
|
|
});
|
|
|
@@ -1,5 +1,4 @@ |
|
|
Behaviour.register({ |
|
|
"INPUT.combobox2" : function(e) { |
|
|
Behaviour.specify("INPUT.combobox2", 'combobox', 0, function(e) { |
|
|
var items = []; |
|
|
|
|
|
var c = new ComboBox(e,function(value) { |
|
@@ -21,5 +20,4 @@ Behaviour.register({ |
|
|
} |
|
|
}); |
|
|
}); |
|
|
} |
|
|
});
|
|
@@ -2,8 +2,7 @@ |
|
|
|
|
|
// do the ones that extract innerHTML so that they can get their original HTML before |
|
|
// other behavior rules change them (like YUI buttons.) |
|
|
Behaviour.list.unshift({ |
|
|
"DIV.hetero-list-container" : function(e) { |
|
|
Behaviour.specify("DIV.hetero-list-container", 'hetero-list', -100, function(e) { |
|
|
e=$(e); |
|
|
if(isInsideRemovable(e)) return; |
|
|
|
|
@@ -134,15 +133,14 @@ Behaviour.list.unshift({ |
|
|
} |
|
|
}); |
|
|
} |
|
|
}, |
|
|
}); |
|
|
|
|
|
"DIV.dd-handle" : function(e) { |
|
|
Behaviour.specify("DIV.dd-handle", 'hetero-list', -100, function(e) { |
|
|
e=$(e); |
|
|
e.on("mouseover",function() { |
|
|
$(this).up(".repeated-chunk").addClassName("hover"); |
|
|
}); |
|
|
e.on("mouseout",function() { |
|
|
$(this).up(".repeated-chunk").removeClassName("hover"); |
|
|
}); |
|
|
} |
|
|
}); |
|
@@ -24,11 +24,8 @@ var radioBlockSupport = { |
|
|
} |
|
|
}; |
|
|
|
|
|
Behaviour.list.unshift({ |
|
|
// this needs to happen before TR.row-set-end rule kicks in. |
|
|
// but this is a hack. |
|
|
// TODO: how do we handle ordering? |
|
|
"INPUT.radio-block-control" : function(r) { |
|
|
// this needs to happen before TR.row-set-end rule kicks in. |
|
|
Behaviour.specify("INPUT.radio-block-control", 'radioBlock', -100, function(r) { |
|
|
r.id = "radio-block-"+(iota++); |
|
|
|
|
|
// when one radio button is clicked, we need to update foldable block for |
|
@@ -73,5 +70,4 @@ Behaviour.list.unshift({ |
|
|
// install event handlers to update visibility. |
|
|
// needs to use onclick and onchange for Safari compatibility |
|
|
r.onclick = r.onchange = function() { g.updateButtons(); }; |
|
|
} |
|
|
}); |
|
@@ -99,8 +99,7 @@ var repeatableSupport = { |
|
|
|
|
|
// do the ones that extract innerHTML so that they can get their original HTML before |
|
|
// other behavior rules change them (like YUI buttons.) |
|
|
Behaviour.list.unshift({ |
|
|
"DIV.repeated-container" : function(e) { |
|
|
Behaviour.specify("DIV.repeated-container", 'repeatable', -100, function(e) { |
|
|
if(isInsideRemovable(e)) return; |
|
|
|
|
|
// compute the insertion point |
|
@@ -109,27 +108,25 @@ Behaviour.list.unshift({ |
|
|
ip = ip.previous(); |
|
|
// set up the logic |
|
|
object(repeatableSupport).init(e, e.firstChild, ip); |
|
|
} |
|
|
}); |
|
|
|
|
|
Behaviour.register({ |
|
|
// button to add a new repeatable block |
|
|
"INPUT.repeatable-add" : function(e) { |
|
|
Behaviour.specify("INPUT.repeatable-add", 'repeatable', 0, function(e) { |
|
|
makeButton(e,function(e) { |
|
|
repeatableSupport.onAdd(e.target); |
|
|
}); |
|
|
e = null; // avoid memory leak |
|
|
}, |
|
|
}); |
|
|
|
|
|
"INPUT.repeatable-delete" : function(e) { |
|
|
Behaviour.specify("INPUT.repeatable-delete", 'repeatable', 0, function(e) { |
|
|
makeButton(e,function(e) { |
|
|
repeatableSupport.onDelete(e.target); |
|
|
}); |
|
|
e = null; // avoid memory leak |
|
|
}, |
|
|
}); |
|
|
|
|
|
// radio buttons in repeatable content |
|
|
"DIV.repeated-chunk" : function(d) { |
|
|
Behaviour.specify("DIV.repeated-chunk", 'repeatable', 0, function(d) { |
|
|
var inputs = d.getElementsByTagName('INPUT'); |
|
|
for (var i = 0; i < inputs.length; i++) { |
|
|
if (inputs[i].type == 'radio') { |
|
@@ -145,5 +142,4 @@ Behaviour.register({ |
|
|
if (inputs[i].defaultChecked) inputs[i].checked = true; |
|
|
} |
|
|
} |
|
|
} |
|
|
});
|
|
@@ -40,8 +40,7 @@ function updateListBox(listBox,url,config) { |
|
|
new Ajax.Request(url, config); |
|
|
} |
|
|
|
|
|
Behaviour.register({ |
|
|
"SELECT.select" : function(e) { |
|
|
Behaviour.specify("SELECT.select", 'select', 0, function(e) { |
|
|
// controls that this SELECT box depends on |
|
|
refillOnChange(e,function(params) { |
|
|
var value = e.value; |
|
@@ -63,5 +62,4 @@ Behaviour.register({ |
|
|
} |
|
|
}); |
|
|
}); |
|
|
} |
|
|
});
|
|
|
@@ -1,5 +1,4 @@ |
|
|
Behaviour.register({ |
|
|
"TEXTAREA.codemirror" : function(e) { |
|
|
Behaviour.specify("TEXTAREA.codemirror", 'textarea', 0, function(e) { |
|
|
var h = e.clientHeight; |
|
|
var config = e.getAttribute("codemirror-config") || ""; |
|
|
config = eval('({'+config+'})'); |
|
@@ -14,9 +13,9 @@ Behaviour.register({ |
|
|
var scroller = codemirror.getScrollerElement(); |
|
|
scroller.setAttribute("style","border:1px solid black;"); |
|
|
scroller.style.height = h+"px"; |
|
|
}, |
|
|
}); |
|
|
|
|
|
"DIV.textarea-preview-container" : function (e) { |
|
|
Behaviour.specify("DIV.textarea-preview-container", 'textarea', 100, function (e) { |
|
|
var previewDiv = findElementsBySelector(e,".textarea-preview")[0]; |
|
|
var showPreview = findElementsBySelector(e,".textarea-show-preview")[0]; |
|
|
var hidePreview = findElementsBySelector(e,".textarea-hide-preview")[0]; |
|
@@ -54,5 +53,4 @@ Behaviour.register({ |
|
|
$(hidePreview).hide(); |
|
|
$(previewDiv).hide(); |
|
|
}; |
|
|
} |
|
|
});
|
|
@@ -21,7 +21,7 @@ |
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
|
* THE SOFTWARE. |
|
|
*/ |
|
|
hudsonRules["IMG.treeview-fold-control"] = function(e) { |
|
|
Behaviour.specify("IMG.treeview-fold-control", 'projectViewNested', 0, function(e) { |
|
|
e.onexpanded = function() { |
|
|
var img = this; |
|
|
var tr = findAncestor(img, "TR"); |
|
@@ -50,4 +50,4 @@ hudsonRules["IMG.treeview-fold-control"] = function(e) { |
|
|
}); |
|
|
}; |
|
|
e = null; |
|
|
}; |
|
|
}); |
|
@@ -117,17 +117,17 @@ var breadcrumbs = (function() { |
|
|
return false; |
|
|
} |
|
|
|
|
|
jenkinsRules["#breadcrumbs LI"] = function (e) { |
|
|
Behaviour.specify("#breadcrumbs LI", 'breadcrumbs', 0, function (e) { |
|
|
// when the mouse hovers over LI, activate the menu |
|
|
e = $(e); |
|
|
if (e.hasClassName("no-context-menu")) return; |
|
|
e.observe("mouseover", function () { handleHover(e.firstChild,0) }); |
|
|
}; |
|
|
}); |
|
|
|
|
|
jenkinsRules["A.model-link"] = function (a) { |
|
|
Behaviour.specify("A.model-link", 'breadcrumbs', 0, function (a) { |
|
|
// ditto for model-link, but give it a larger delay to avoid unintended menus to be displayed |
|
|
$(a).observe("mouseover", function () { handleHover(a,500); }); |
|
|
}; |
|
|
}); |
|
|
|
|
|
/** |
|
|
* @namespace breadcrumbs |
|
|
|
|
@@ -1,7 +1,6 @@ |
|
|
// @include "org.kohsuke.stapler.zeroclipboard" |
|
|
|
|
|
Behaviour.register({ |
|
|
"span.copy-button" : function(e) { |
|
|
Behaviour.specify("span.copy-button", 'copyButton', 0, function(e) { |
|
|
var btn = e.firstChild; |
|
|
var id = "copy-button"+(iota++); |
|
|
btn.id = id; |
|
@@ -35,5 +34,4 @@ Behaviour.register({ |
|
|
clip.addEventListener('onMouseUp',function() { |
|
|
$(id).removeClassName('yui-button-active') |
|
|
}); |
|
|
} |
|
|
}); |
|
@@ -61,4 +61,10 @@ public void testDuplicateRegistrations() throws Exception { |
|
|
assertEquals("initial and appended yet different", r.getJavaScriptResult().toString()); |
|
|
} |
|
|
|
|
|
public void testSelectorOrdering() throws Exception { |
|
|
HtmlPage p = createWebClient().goTo("self/testSelectorOrdering"); |
|
|
ScriptResult r = p.executeJavaScript("document.getElementsBySelector('DIV.a')[0].innerHTML"); |
|
|
assertEquals("initial early counted! generic weevils! late", r.getJavaScriptResult().toString()); |
|
|
} |
|
|
|
|
|
} |
|
@@ -30,10 +30,8 @@ THE SOFTWARE. |
|
|
<l:layout title=""> |
|
|
<l:main-panel> |
|
|
<script> |
|
|
Behaviour.register({ |
|
|
".a" : function (e) { |
|
|
e.innerHTML = e.getAttribute("value"); |
|
|
} |
|
|
Behaviour.specify(".a", 'test', 0, function (e) { |
|
|
e.innerHTML = e.getAttribute("value"); |
|
|
}); |
|
|
</script> |
|
|
|
|
|
|
@@ -26,20 +26,14 @@ THE SOFTWARE. |
|
|
<l:layout title=""> |
|
|
<l:main-panel> |
|
|
<script> |
|
|
Behaviour.register({ |
|
|
".a" : function (e) { |
|
|
e.innerHTML += ' and appended'; |
|
|
} |
|
|
Behaviour.specify(".a", 'test1', 0, function (e) { |
|
|
e.innerHTML += ' and appended'; |
|
|
}); |
|
|
Behaviour.register({ |
|
|
".a" : function (e) { |
|
|
e.innerHTML += ' and appended'; |
|
|
} |
|
|
Behaviour.specify(".a", 'test1', 0, function (e) { |
|
|
e.innerHTML += ' and appended'; |
|
|
}); |
|
|
Behaviour.register({ |
|
|
".a" : function (e) { |
|
|
e.innerHTML += ' yet different'; |
|
|
} |
|
|
Behaviour.specify(".a", 'test2', 0, function (e) { |
|
|
e.innerHTML += ' yet different'; |
|
|
}); |
|
|
</script> |
|
|
<div class="a">initial</div> |
|
|
Oops, something went wrong.