sketcher window solution

User 870ab5b546

30-06-2016 23:41:50

Hi,


Even with the ability to resize the MarvinJS canvas, I find that sometimes, the canvas is not large enough for my students. However, I have devised a solution that works a lot like the sketcher window in MarvinSketch.


We use the following code to launch any MarvinJS instance:


    <span id="marvinJSInstanceCell" style="text-align:center;">
<script type="text/javascript">
// <!-- >
startMarvinJS('', 'marvinJSInstance');
// -->
</script>
</span>

Note the name of the spanning element is the same as the name of the MarvinJS instance plus 'Cell'. startMarvinJS() calls this resource:


var marvinSketcherInstance;
function startMarvinJS(mol, appletName) {
"use strict";
var panelWidth = '400px',
panelHeight = '400px',
iframeBld;
if (appletName === 'sketcher') { // only in marvinJSWindow.jsp
panelWidth = '95%';
panelHeight = 0.9 * window.innerHeight + 'px'; // % doesn't work in Chrome or Firefox
} // if sketcher window
iframeBld = new String.builder().
append('<div class="resizable" ' +
'style="margin-left:auto; margin-right:auto;">' +
'<iframe id="').
append(appletName).append('" class="sketcher-frame" ' +
'src="marvinJS\/editorws.html" ' +
'style="overflow:hidden; border:1px solid darkgray; min-width:').
append(panelWidth).append('; min-height:').append(panelHeight).
append(';"\/><\/iframe><\/div>');
document.getElementById(appletName + 'Cell').value = iframeBld.toString();
document.getElementById(appletName).addEventListener('load', function () {
// the iframe (id = appletName) has now been loaded
MarvinJSUtil.getEditor('#' + appletName).then(function (sketcher) {
// the Marvin JS editor (id = #appletName) has now been loaded
marvinSketcherInstance = sketcher;
if (appletName !== 'sketcher') { // except in marvinJSWindow.jsp
   var expandButtonAttributes = {
    "name" : "Expand window",
    "image-url" : "images/expand.png", // icon for expand button
    "toolbar" : "S"
    };
    marvinSketcherInstance.addButton(expandButtonAttributes, function() {
    openSketcherWindow('marvinJSWindow.jsp');
    });
} // if sketcher window
...
}, function (error) {
alert('Marvin JS did not load: ' + error);
}); // getEditor.then()
}); // addEventListener()
} // startMarvinJS()

function openSketcherWindow(url) {
"use strict";
var w = window.open(url, 'MarvinJS sketcher window',
'resizable=yes,scrollbars=yes,status=yes');
w.focus();
}

Finally, marvinJSWindow.jsp contains the following code:


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

function getStarted() {
MarvinJSUtil.getEditor('#sketcher').then(function (sketcher) {
opener.marvinSketcherInstance.exportStructure('mrv').
then(function(mol) {
sketcher.importStructure(null, mol);
}, function(error) {
alert('Molecule export to opener failed:' + error);
});
sketcher.on('molchange', changeOpener);
}, function (error) {
alert('Marvin JS did not load: ' + error);
}); // getEditor.then()
} // getStarted()

function changeOpener() {
marvinSketcherInstance.exportStructure('mrv').then(function(mol) {
opener.marvinSketcherInstance.importStructure(null, mol);
}, function(error) {
alert('Molecule export to opener failed:' + error);
});
} // changeOpener()

</script>
</head>

<body onload="getStarted();" style="overflow:auto;">
<span id="sketcherCell" style="text-align:center;">
<script type="text/javascript">
// <!-- >
startMarvinJS('', 'sketcher');
// -->
</script>
</span>
</body>
</html>

Now, pressing the expand button in the original MarvinJS instance will open a new window that contains nothing but MarvinJS, the new MarvinJS will be initiated with the contents of the original MarvinJS, and anything the user draws in this new MarvinJS will be mirrored in the original MarvinJS (but not vice versa).


I hope someone finds this code useful. Feel free to add it to your examples. Let me know if you find any problems with it on any PC browsers -- I've only tested it on a Mac. 

ChemAxon 7c2d26e5cf

11-07-2016 10:54:37

Hi Bob,
Thanks for the contributed code.

Just one note.
Following resources should be loaded at startup both in the host page and in the marvinJSWindow.js document.


<script src="gui/lib/promise-1.0.0.min.js"></script>

<script src="js/marvinjslauncher.js"></script>



The first one is an ES6 Promise polyfill (require for IE support).


The second one loads the MarvinJSUtil object that is referred in startMarvinJS and in getStarted functions.