Skip to content

Commit

Permalink
move js to separate file to prevent escaped entities in Plone 5
Browse files Browse the repository at this point in the history
  • Loading branch information
pbauer committed Dec 28, 2014
1 parent d0660a9 commit 6aade69
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 139 deletions.
6 changes: 6 additions & 0 deletions src/z3c/form/browser/orderedselect.zcml
@@ -1,6 +1,7 @@
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:z3c="http://namespaces.zope.org/z3c"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="z3c.form">

<class class=".orderedselect.OrderedSelectWidget">
Expand Down Expand Up @@ -42,4 +43,9 @@
template="orderedselect_input.pt"
/>

<browser:resource
name="orderedselect_input.js"
file="orderedselect_input.js"
/>

</configure>
134 changes: 134 additions & 0 deletions src/z3c/form/browser/orderedselect_input.js
@@ -0,0 +1,134 @@
function moveItems(from, to)
{
// shortcuts for selection fields
var src = document.getElementById(from);
var tgt = document.getElementById(to);

if (src.selectedIndex == -1) selectionError();
else
{
// iterate over all selected items
// --> attribute "selectedIndex" doesn't support multiple selection.
// Anyway, it works here, as a moved item isn't selected anymore,
// thus "selectedIndex" indicating the "next" selected item :)
while (src.selectedIndex > -1)
if (src.options[src.selectedIndex].selected)
{
// create a new virtal object with values of item to copy
temp = new Option(src.options[src.selectedIndex].text,
src.options[src.selectedIndex].value);
// append virtual object to targe
tgt.options[tgt.length] = temp;
// want to select newly created item
temp.selected = true;
// delete moved item in source
src.options[src.selectedIndex] = null;
}
}
}

// move item from "from" selection to "to" selection
function from2to(name)
{
moveItems(name+"-from", name+"-to");
copyDataForSubmit(name);
}

// move item from "to" selection back to "from" selection
function to2from(name)
{
moveItems(name+"-to", name+"-from");
copyDataForSubmit(name);
}

function swapFields(a, b)
{
// swap text
var temp = a.text;
a.text = b.text;
b.text = temp;
// swap value
temp = a.value;
a.value = b.value;
b.value = temp;
// swap selection
temp = a.selected;
a.selected = b.selected;
b.selected = temp;
}

// move selected item in "to" selection one up
function moveUp(name)
{
// shortcuts for selection field
var toSel = document.getElementById(name+"-to");

if (toSel.selectedIndex == -1)
selectionError();
else if (toSel.options[0].selected)
alert("Cannot move further up!");
else for (var i = 0; i < toSel.length; i++)
if (toSel.options[i].selected)
{
swapFields(toSel.options[i-1], toSel.options[i]);
copyDataForSubmit(name);
}
}

// move selected item in "to" selection one down
function moveDown(name)
{
// shortcuts for selection field
var toSel = document.getElementById(name+"-to");

if (toSel.selectedIndex == -1) {
selectionError();
} else if (toSel.options[toSel.length-1].selected) {
alert("Cannot move further down!");
} else {
for (var i = toSel.length-1; i >= 0; i--) {
if (toSel.options[i].selected) {
swapFields(toSel.options[i+1], toSel.options[i]);
}
}
copyDataForSubmit(name);
}
}

// copy each item of "toSel" into one hidden input field
function copyDataForSubmit(name)
{
// shortcuts for selection field and hidden data field
var toSel = document.getElementById(name+"-to");
var toDataContainer = document.getElementById(name+"-toDataContainer");

// delete all child nodes (--> complete content) of "toDataContainer" span
while (toDataContainer.hasChildNodes())
toDataContainer.removeChild(toDataContainer.firstChild);

// create new hidden input fields - one for each selection item of
// "to" selection
for (var i = 0; i < toSel.options.length; i++)
{
// create virtual node with suitable attributes
var newNode = document.createElement("input");
var newAttr = document.createAttribute("name");
newAttr.nodeValue = name.replace(/-/g, '.')+':list';
newNode.setAttributeNode(newAttr);

newAttr = document.createAttribute("type");
newAttr.nodeValue = "hidden";
newNode.setAttributeNode(newAttr);

newAttr = document.createAttribute("value");
newAttr.nodeValue = toSel.options[i].value;
newNode.setAttributeNode(newAttr);

// actually append virtual node to DOM tree
toDataContainer.appendChild(newNode);
}
}

// error message for missing selection
function selectionError()
{alert("Must select something!")}
140 changes: 1 addition & 139 deletions src/z3c/form/browser/orderedselect_input.pt
Expand Up @@ -2,145 +2,7 @@
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
tal:omit-tag="">
<script type="text/javascript">
/* <![CDATA[ */
function moveItems(from, to)
{
// shortcuts for selection fields
var src = document.getElementById(from);
var tgt = document.getElementById(to);
if (src.selectedIndex == -1) selectionError();
else
{
// iterate over all selected items
// --> attribute "selectedIndex" doesn't support multiple selection.
// Anyway, it works here, as a moved item isn't selected anymore,
// thus "selectedIndex" indicating the "next" selected item :)
while (src.selectedIndex > -1)
if (src.options[src.selectedIndex].selected)
{
// create a new virtal object with values of item to copy
temp = new Option(src.options[src.selectedIndex].text,
src.options[src.selectedIndex].value);
// append virtual object to targe
tgt.options[tgt.length] = temp;
// want to select newly created item
temp.selected = true;
// delete moved item in source
src.options[src.selectedIndex] = null;
}
}
}
// move item from "from" selection to "to" selection
function from2to(name)
{
moveItems(name+"-from", name+"-to");
copyDataForSubmit(name);
}
// move item from "to" selection back to "from" selection
function to2from(name)
{
moveItems(name+"-to", name+"-from");
copyDataForSubmit(name);
}
function swapFields(a, b)
{
// swap text
var temp = a.text;
a.text = b.text;
b.text = temp;
// swap value
temp = a.value;
a.value = b.value;
b.value = temp;
// swap selection
temp = a.selected;
a.selected = b.selected;
b.selected = temp;
}
// move selected item in "to" selection one up
function moveUp(name)
{
// shortcuts for selection field
var toSel = document.getElementById(name+"-to");
if (toSel.selectedIndex == -1)
selectionError();
else if (toSel.options[0].selected)
alert("Cannot move further up!");
else for (var i = 0; i < toSel.length; i++)
if (toSel.options[i].selected)
{
swapFields(toSel.options[i-1], toSel.options[i]);
copyDataForSubmit(name);
}
}
// move selected item in "to" selection one down
function moveDown(name)
{
// shortcuts for selection field
var toSel = document.getElementById(name+"-to");
if (toSel.selectedIndex == -1) {
selectionError();
} else if (toSel.options[toSel.length-1].selected) {
alert("Cannot move further down!");
} else {
for (var i = toSel.length-1; i >= 0; i--) {
if (toSel.options[i].selected) {
swapFields(toSel.options[i+1], toSel.options[i]);
}
}
copyDataForSubmit(name);
}
}
// copy each item of "toSel" into one hidden input field
function copyDataForSubmit(name)
{
// shortcuts for selection field and hidden data field
var toSel = document.getElementById(name+"-to");
var toDataContainer = document.getElementById(name+"-toDataContainer");
// delete all child nodes (--> complete content) of "toDataContainer" span
while (toDataContainer.hasChildNodes())
toDataContainer.removeChild(toDataContainer.firstChild);
// create new hidden input fields - one for each selection item of
// "to" selection
for (var i = 0; i < toSel.options.length; i++)
{
// create virtual node with suitable attributes
var newNode = document.createElement("input");
var newAttr = document.createAttribute("name");
newAttr.nodeValue = name.replace(/-/g, '.')+':list';
newNode.setAttributeNode(newAttr);
newAttr = document.createAttribute("type");
newAttr.nodeValue = "hidden";
newNode.setAttributeNode(newAttr);
newAttr = document.createAttribute("value");
newAttr.nodeValue = toSel.options[i].value;
newNode.setAttributeNode(newAttr);
// actually append virtual node to DOM tree
toDataContainer.appendChild(newNode);
}
}
// error message for missing selection
function selectionError()
{alert("Must select something!")}
/* ]]> */
</script>
<script type="text/javascript" src="++resource++orderedselect_input.js" />

<table border="0" class="ordered-selection-field"
tal:attributes="id view/id">
Expand Down

9 comments on commit 6aade69

@mgedmin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit breaks tests: src/z3c/form/browser/orderedselect.txt expects

      <script type="text/javascript">...</script>

and instead gets

      <script src="++resource++orderedselect_input.js" type="text/javascript"></script>

Should be easy to fix. Can you do it?

@mgedmin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other test failure, in README.txt, is also attributable to this change:

File "c:\buildslave\z3c.form\build\src\z3c\form\browser\README.txt", line 25, in README.txt
Failed example:
    xmlconfig.XMLConfig('configure.zcml', z3c.form)()
Exception raised:
    Traceback (most recent call last):
      File "c:\Python26_32\lib\doctest.py", line 1253, in __run
        compileflags, 1) in test.globs
      File "<doctest README.txt[11]>", line 1, in <module>
        xmlconfig.XMLConfig('configure.zcml', z3c.form)()
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 552, in __init__
        include(context, file_name, module)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 402, in include
        processxmlfile(f, context)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 295, in processxmlfile
        parser.parse(src)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 107, in parse
        xmlreader.IncrementalParser.parse(self, source)
      File "c:\Python26_32\lib\xml\sax\xmlreader.py", line 123, in parse
        self.feed(buffer)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 207, in feed
        self._parser.Parse(data, isFinal)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 349, in end_element_ns
        self._cont_handler.endElementNS(pair, None)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 281, in endElementNS
        None, sys.exc_info()[2])
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 272, in endElementNS
        self.context.end()
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\config.py", line 345, in end
        self.stack.pop().finish()
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\config.py", line 453, in finish
        actions = self.handler(context, **args)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 402, in include
        processxmlfile(f, context)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 295, in processxmlfile
        parser.parse(src)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 107, in parse
        xmlreader.IncrementalParser.parse(self, source)
      File "c:\Python26_32\lib\xml\sax\xmlreader.py", line 123, in parse
        self.feed(buffer)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 207, in feed
        self._parser.Parse(data, isFinal)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 349, in end_element_ns
        self._cont_handler.endElementNS(pair, None)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 281, in endElementNS
        None, sys.exc_info()[2])
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 272, in endElementNS
        self.context.end()
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\config.py", line 345, in end
        self.stack.pop().finish()
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\config.py", line 453, in finish
        actions = self.handler(context, **args)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 402, in include
        processxmlfile(f, context)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 295, in processxmlfile
        parser.parse(src)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 107, in parse
        xmlreader.IncrementalParser.parse(self, source)
      File "c:\Python26_32\lib\xml\sax\xmlreader.py", line 123, in parse
        self.feed(buffer)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 207, in feed
        self._parser.Parse(data, isFinal)
      File "c:\Python26_32\lib\xml\sax\expatreader.py", line 338, in start_element_ns
        AttributesNSImpl(newattrs, qnames))
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 213, in startElementNS
        None, sys.exc_info()[2])
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\xmlconfig.py", line 204, in startElementNS
        self.context.begin(name, data, info)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\config.py", line 342, in begin
        self.stack.append(self.stack[-1].contained(__name, __data, __info))
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\config.py", line 509, in contained
        return RootStackItem.contained(self, name, data, info)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\config.py", line 473, in contained
        factory = self.context.factory(self.context, name)
      File "d:\eggs\zope.configuration-4.0.3-py2.6.egg\zope\configuration\config.py", line 311, in factory
        raise ConfigurationError("Unknown directive", ns, n)
    ZopeXMLConfigurationError: File "c:\buildslave\z3c.form\build\src\z3c\form\configure.zcml", line 36.2-36.32
        ZopeXMLConfigurationError: File "c:\buildslave\z3c.form\build\src\z3c\form\browser\configure.zcml", line 11.2-11.39
        ZopeXMLConfigurationError: File "c:\buildslave\z3c.form\build\src\z3c\form\browser\orderedselect.zcml", line 46.2
        ConfigurationError: ('Unknown directive', u'http://namespaces.zope.org/browser', u'resource')

@pbauer
Copy link
Member Author

@pbauer pbauer commented on 6aade69 Dec 30, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

@mgedmin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! 🍰

@davisagli
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pbauer
Copy link
Member Author

@pbauer pbauer commented on 6aade69 Jan 3, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the info, I missed that too.
fixed in collective/collective.z3cform.datetimewidget@957a55e (the commit did not trigger the 4.3-build)

@vangheem
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this commit might be causing this issue: plone/Products.CMFPlone#530

@cedricmessiant
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit also seems to break MultiSelectWidget in overlays. I get ReferenceError: to2from is not defined and ReferenceError: from2to is not defined javascript errors

@mgedmin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Filing bugs is better than commenting on old commits. I apologize for starting this trend here.)

Please sign in to comment.