<html> <head> <style type="text/css"> <!-- h1 { background-color: #ccccee; text-align: center; } h3 { background-color: #ccccee; } li { padding: 4px; } pre { background-color: #CCCCCC; margin-right: 16px; margin-left: 16px; padding: 6px; } .imgcaption { font-weight: bold; text-align: center; } .precaption { font-weight: bold; text-align: center; } --> </style> </head> <body> <h1> KJSEmbed</h1> <h3>Introduction</h3> <p>KJSEmbed is a library for embedding the KJS Javascript (ECMAScript) interpreter in KDE applications. It provides developers with an easy way to allow users to extend application, and can even be used with applications that have not been designed with this in mind thanks to a KParts plugin. In addition, KJSEmbed provides a command line tool for running scripts so users can easily create simple applications of their own in Javascript. KJSEmbed scripts are surprisingly powerful because they access the properties and slots of QObjects, and can even load widgets and dialogs created with Qt's graphical dialog editor.</p> <h3>Features</h3> <p>To give you an idea of what KJSEmbed provides, here is a brief summary of the more interesting features:</p> <ul> <li>KParts plugin for extending existing KDE applications with scripts. </li> <li>KPart for embedding Javascript in your own applications.</li> <li>Console dialog that can be used to execute Javascript interactively.</li> <li>Command line tool for running scripts (this can even operate without an X server if you don't need to display a GUI).</li> <li>Define new KActions using XML.</li> <li>Scripts can access the properties and slots of QObjects as if they were normal Javascript properties and methods.</li> <li>Scripts can load dialogs and widgets created with Qt Designer.</li> <li>Scripts can create instances of anu QWidget subclass supported by QWidgetFactory.</li> <li>Making your own QObjects/QWidgets available for scripting is one-liner.</li> <li>Scripts can traverse the widget tree, so your entire application can be made scriptable without explicitly binding every object.</li> </ul> <h3>First Steps - The Console Dialog</h3> <p>The quickest way to see what KJSEmbed can do is with kjscmd, a tool for running scripts from the command line. To begin, we'll run kjscmd without any parameters which brings up the KJSEmbed console dialog. The console provides an easy way to run short (one line) scripts, as you can see in figure 1 the scripts have full access to the core Javascript language, and to standard objects such as Math. In addition to the standard Javascript operations, this screenshot also demonstrates the global function print() provided by KJSEmbed.</p> <pre> -- Enter a JS expression and press enter -- kjs> 10+20 30 kjs> print(&quot;Hello World!&quot;) Hello World! undefined kjs> Math.sin(0) 0 kjs> Math.cos(0) 1 </pre> <p class="imgcaption">Figure 1: The KJSEmbed Console Dialog</p> <p>Things get more interesting when you realise that we also have access to the widgets that make up the dialog, as you can in figure 2:</p> <pre> kjs> console JSConsoleWidget (KJSEmbed::JSConsoleWidget) kjs> console.childCount() 4 kjs> console.childAt(1) CmdEdit (QComboBox) kjs> console.childAt(2) RunButton (QPushButton) kjs> console.child(&quot;RunButton&quot;) RunButton (QPushButton) kjs> console.child(&quot;RunButton&quot;).text = &quot;Go!&quot; Go! kjs> console.caption = &quot;Different Title&quot; Different Title kjs&gt; console.child(&quot;Title&quot;).hide() undefined </pre> <p class="imgcaption">Figure 2: Modifying the Console Dialog</p> <p>As you can see, the console dialog has been made available to scripts as the global variable 'console'. We can access the child widgets that make up the dialog either by index using the childCount() and childAt() methods, or by name using the child() method. As well as being able to see the widgets, we can modify them by setting properties - in this example, we modify the caption property of the widget 'console' (changing the window title) and the text property of the widget 'RunButton' (changing the label it displays). For the sake of completeness, the final command illustrates the other way of modifying widgets available to us - it calls hide() slot of the widget 'Title' (what this does is left as an exercise for the reader).</p> <h3>Displaying A Grep Dialog</h3> <p>Now that we've seen how to use kjscmd interactively, lets take a look at a more complex example that displays a dialog for running grep. The complete script is shown in listing 1 and as you'll see, is very simple. Loading and displaying the dialog takes only two lines of code because KJSEmbed provides a built-in Factory object that supports Designer files, most of the work is getting the values out of the dialog and building the command line.</p> <pre> // Create and show the dialog var dlg = Factory.loadui('grepdlg.ui'); dlg.exec(); // Extract the parameters var search = dlg.child('search_edit').text; var files = dlg.child('files_edit').text; var matchcase = dlg.child('case_check').checked; var invert = dlg.child('invert_check').checked; // Build the command line var options; if ( matchcase ) { options = '-i'; } if ( invert ) { options += ' -v'; } cmd = 'grep '+options+&quot;'&quot;+search+&quot;' &quot;+files; // Print the command line print( cmd ); </pre> <p class="precaption">Listing 1: A Script That Displays the Grep Dialog</p> <p>In order to find out what the user asked us to search for we need to extract the contents of the various fields in our dialog. We know that the field for entering the text to be searched for is a QLineEdit called 'search_edit', so we can use the child() method to get hold of it (this method searches through the children of an object until it finds one with a matching name). Once we've found the right object getting hold of the text is easy because all QLineEdits make their contents available as a property called 'text'. The code that gets the value of the check boxes is almost identical, except that these are QCheckBoxes so it's the 'checked' property we're interested in.</p> <p align="center"><img src="grepdlg.png" alt="Grep Dialog Screenshot" width="327" height="241"></p> <p class="imgcaption">Figure 3: The Grep Dialog</p> <p>When this script is run you'll see a dialog like the one shown in figure 3.</p> <h3>Extending Applications with Javascript Plugins</h3> <p>As its name implies KJSEmbed is not just a tool for writing standalone Javascript tools, it also provides facilities for extending existing applications, these facilities being with a KParts plugin for running scripts. The next example uses the plugin to add a simple HTML-to-text action to Kate, the standard KDE editor. </p> <pre> function html2text( html ) { var text = html.replace( /&lt;[^&gt;]*&gt;/g, '' ); text = text.replace( /&amp;quot;/g, '&quot;' ); text = text.replace( /&amp;lt;/g, '&lt;' ); text = text.replace( /&amp;amp;/g, '&amp;' ); return text; } function text2html( text ) { var html = text.replace( /&amp;/g,&quot;&amp;amp;&quot;); html = html.replace( /&quot;/g,&quot;&amp;quot;&quot;); html = html.replace( /&lt;/g,&quot;&amp;lt;&quot;); return html; } </pre> <p>The details...</p> <pre>&lt;!DOCTYPE actionset&gt;<br>&lt;actionset&gt;<br>&lt;header&gt;<br> &lt;name&gt;html2text_actions&lt;/name&gt;<br> &lt;label&gt;HTML To Text Actions&lt;/label&gt;<br> &lt;script type=&quot;js&quot; src=&quot;html2text_plugin.js&quot;&gt;&lt;/script&gt;<br>&lt;/header&gt;<br>&lt;action&gt;<br> &lt;name&gt;html_to_text&lt;/name&gt;<br> &lt;type&gt;KAction&lt;/type&gt;<br> &lt;icons&gt;text&lt;/icons&gt;<br> &lt;label&gt;&lt;text&gt;Convert HTML To Text&lt;/text&gt;&lt;/label&gt;<br> &lt;statustext&gt;Converts the selected text from HTML to text.&lt;/statustext&gt;<br> &lt;script type=&quot;js&quot;&gt;kpart.selectedText = html2text( kpart.selectedText )&lt;/script&gt;<br>&lt;/action&gt;<br>&lt;action&gt;<br> &lt;name&gt;text_to_html&lt;/name&gt;<br> &lt;type&gt;KAction&lt;/type&gt;<br> &lt;icons&gt;html&lt;/icons&gt;<br> &lt;label&gt;&lt;text&gt;Quote For HTML&lt;/text&gt;&lt;/label&gt;<br> &lt;statustext&gt;Quotes the selected text for inclusion in an HTML document.&lt;/statustext&gt;<br> &lt;script type=&quot;js&quot;&gt;kpart.selectedText = text2html( kpart.selectedText )&lt;/script&gt;<br>&lt;/action&gt;<br>&lt;/actionset&gt;<br></pre> <p><br> The xmlgui:</p> <pre> &lt;!DOCTYPE kpartgui&gt;<br>&lt;kpartplugin name=&quot;html2text_plugin&quot; library=&quot;libkjsembedplugin&quot;&gt;<br>&lt;MenuBar&gt;<br> &lt;Menu name=&quot;tools&quot;&gt;&lt;Text&gt;&amp;amp;Tools&lt;/Text&gt;<br> &lt;Action name=&quot;html_to_text&quot;/&gt;<br> &lt;Action name=&quot;text_to_html&quot;/&gt;<br> &lt;Action name=&quot;jsconsole&quot;/&gt;<br> &lt;/Menu&gt;<br>&lt;/MenuBar&gt;<br>&lt;/kpartplugin&gt;<br> </pre> <h3>Missing</h3> <ul> <li>XMLActions</li> <li>Plugin</li> <li>MainWindow</li> </ul> <h3>References</h3> <dl> <dt><a href="http://www.mozilla.org/js/language/">http://www.mozilla.org/js/language/</a></dt> <dd>Javascript (ECMAScript) language information.</dd> </dl> <h3>To Do</h3> <ul> <li>Replace figures 1 and 2 with images</li> <li></li> </ul> <p>&nbsp;</p> <p>&nbsp;</p> <p>&nbsp;</p> </body> </html>