|  | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | 
|  | <html xmlns="http://www.w3.org/1999/xhtml"> | 
|  | <head> | 
|  | <title>Mark Occurrences Module Tutorial for the NetBeans Platform</title> | 
|  | <link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/> | 
|  | <meta name="AUDIENCE" content="NBUSER"/> | 
|  | <meta name="TYPE" content="ARTICLE"/> | 
|  | <meta name="EXPIRES" content="N"/> | 
|  | <meta name="developer" content="gwielenga@netbeans.org"/> | 
|  | <meta name="indexed" content="y"/> | 
|  | <meta name="description" content="A short guide to using Highlighting SPI."/> | 
|  | <!--     Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Oracle and/or its affiliates. All rights reserved. --> | 
|  | <!--     Use is subject to license terms.--> | 
|  | </head> | 
|  | <body> | 
|  | <h1>NetBeans Mark Occurrences Module Tutorial</h1> | 
|  |  | 
|  | <p>This tutorial demonstrates how to create a NetBeans module that highlights | 
|  | all instances of a selected word in an HTML file, as shown below:</p> | 
|  | <p><img src="../images/tutorials/mark-occs/72/result-3.png" alt="result"/></p> | 
|  |  | 
|  | <p><b>Contents</b></p> | 
|  |  | 
|  | <p><img src="../images/articles/80/netbeans-stamp.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 7.2" title="Content on this page applies to NetBeans IDE 7.2"/></p> | 
|  | <ul class="toc"> | 
|  | <li><a href="#intro">Introduction to Highlight Layers</a> | 
|  | <ul> | 
|  | <li><a href="#installing-sample">Getting to Know the Sample</a></li> | 
|  | </ul> | 
|  | </li> | 
|  |  | 
|  | <li><a href="#creatingthemoduleproject">Setting Up the Module Project</a></li> | 
|  |  | 
|  | <li><a href="#coding-module">Creating the Highlight Layer and Factory</a> | 
|  | <ul> | 
|  | <li><a href="#specifying">Specifying the Module's Dependencies</a></li> | 
|  | <li><a href="#creating-highlight">Creating the Highlight Layer</a></li> | 
|  | <li><a href="#creating-factory">Creating the Highlight Layer Factory</a></li> | 
|  | </ul></li> | 
|  |  | 
|  | <li><a href="#building">Building and Installing the Module</a></li> | 
|  | </ul> | 
|  |  | 
|  | <p><b>To follow this tutorial, you need the software and resources listed in the following | 
|  | table.</b></p> | 
|  |  | 
|  | <table> | 
|  | <tbody> | 
|  | <tr> | 
|  | <th class="tblheader" scope="col">Software or Resource</th> | 
|  | <th class="tblheader" scope="col">Version Required</th> | 
|  | </tr> | 
|  | <tr> | 
|  | <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td> | 
|  | <td class="tbltd1">version 8.0</td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td> | 
|  | <td class="tbltd1">version 7 or above</td> | 
|  | </tr> | 
|  | </tbody> | 
|  | </table> | 
|  |  | 
|  | <p class="tips">For troubleshooting purposes, you are welcome to download the <a href="http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/8.0/tutorials/MarkHTMLOccurrences">completed tutorial source code</a>.</p> | 
|  |  | 
|  | <h2 class="tutorial"><a name="intro"></a>Introduction to Highlight Layers</h2> | 
|  |  | 
|  | <p>In this tutorial, you implement several classes provided by the | 
|  | <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/package-summary.html">NetBeans Highlighting SPI</a>. | 
|  | The two principle classes in this context are as follows:</p> | 
|  |  | 
|  | <ul> | 
|  | <li><b><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayer.html">Highlight Layer</a></b>. | 
|  | Defines a set of highlights used for rendering a document.</li> | 
|  | <li><b><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayerFactory.html">Highlight Layer Factory</a></b>. | 
|  | Defines a MIME-specific factory for creating highlight layers.</li> | 
|  | </ul> | 
|  |  | 
|  | <p>The above two classes need to be registered in the module's <tt>layer.xml</tt> file, | 
|  | within the editor folder of the relevant MIME-type.</p> | 
|  |  | 
|  | <!-- ===================================================================================== --> | 
|  |  | 
|  | <h2 class="tutorial"><a name="creatingthemoduleproject"></a>Setting up the Module Project</h2> | 
|  | <p>Before you start writing the module, you have to make sure you | 
|  | that your project is set up correctly. The IDE provides a wizard that sets up all the basic files | 
|  | needed for a module.</p> | 
|  | <div class="indent"> | 
|  | <ol> | 
|  | <li>Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. | 
|  | Under Projects, select Module. Click Next.</li> | 
|  | <li>In the Name and Location panel, type <tt>MarkHTMLOccurrences</tt> in the Project Name field. | 
|  | Change the Project Location to any directory on your computer. Click Next.</li> | 
|  | <li>In the Basic Module Configuration panel, type <tt>org.netbeans.modules.markhtmloccurrences</tt> | 
|  | in Code Name Base. Click Finish.</li> | 
|  | </ol> | 
|  | </div> | 
|  | <p> The IDE creates the <tt>MarkHTMLOccurrences</tt> | 
|  | project. The project contains all of your sources and | 
|  | project metadata, such as the project's Ant build script. The project | 
|  | opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its | 
|  | file structure in the Files window (Ctrl-2).</p> | 
|  |  | 
|  | <!-- ===================================================================================== --> | 
|  | <h2><a name="coding-module"></a>Creating the Highlight Layer and Factory</h2> | 
|  |  | 
|  | <p>Next, we will implement the Highlighting SPI. The SPI's classes are as follows:</p> | 
|  |  | 
|  | <table> | 
|  | <tbody> | 
|  | <tr> | 
|  | <th class="tblheader" scope="col">Class</th> | 
|  | <th class="tblheader" scope="col">Description</th> | 
|  | </tr> | 
|  | <tr> | 
|  | <td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayerFactory.html">HighlightsLayerFactory</a></td> | 
|  | <td class="tbltd1">Defines the factory for creating highlight layers.</td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayerFactory.Context.html">HighlightsLayerFactory.Context</a></td> | 
|  | <td class="tbltd1">Defines the context passed to the factory when the | 
|  | factory is asked to create highlight layers.</td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsContainer.html">HighlightsContainer</a></td> | 
|  | <td class="tbltd1">Defines the container of highlighted | 
|  | areas and related attributes.</td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayer.html">HighlightsLayer</a></td> | 
|  | <td class="tbltd1">Defines the highlight layer, consisting | 
|  | of attributes.</td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/ZOrder.html">ZOrder</a></td> | 
|  | <td class="tbltd1">Defines position of highlight layer | 
|  | in relation to other highlight layers.</td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td class="tbltd1"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/support/OffsetsBag.html">OffsetsBag</a></td> | 
|  | <td class="tbltd1">Defines a set of highlighted areas | 
|  | specified by their offsets in the document.</td> | 
|  | </tr> | 
|  | </tbody> | 
|  | </table> | 
|  |  | 
|  | <div class="indent"> | 
|  |  | 
|  | <h3 class="tutorial"><a name="specifying"></a>Specifying the Module's Dependencies</h3> | 
|  |  | 
|  | <p>You will need to subclass several classes that belong to <a href="http://bits.netbeans.org/dev/javadoc/index.html">NetBeans APIs</a>. | 
|  | Each has to be declared as a Module dependency. Use the Project Properties dialog box for this purpose.</p> | 
|  | <div class="indent"> | 
|  |  | 
|  | <ol> | 
|  | <li>In the Projects window, right-click the Libraries node | 
|  | in the <tt>MarkHTMLOccurrences</tt> project and choose Add Module Dependency.</li> | 
|  |  | 
|  | <li>For each of the following APIs, select the name from | 
|  | the Module list, and then click OK to confirm that | 
|  | you want to depend on it: | 
|  | <br/><br/> | 
|  | <ul> | 
|  | <li>Datasystems API</li> | 
|  | <li>Editor</li> | 
|  | <li>Editor Library 2</li> | 
|  | <li>Editor Settings</li> | 
|  | <li>File System API</li> | 
|  | <li>Lookup API</li> | 
|  | <li>MIME Lookup API</li> | 
|  | <li>Nodes API</li> | 
|  | <li>Text API</li> | 
|  | <li>UI Utilities API</li> | 
|  | <li>Utilities API</li> | 
|  | </ul> | 
|  | <p>You should now see the following:</p> | 
|  | <br/><img src="../images/tutorials/mark-occs/72/project-1.png" alt="Step 0 of New Project wizard"/> | 
|  | </li> | 
|  |  | 
|  | <li>In the Projects window, expand the Important Files node, double-click the Project Metadata node, and note the | 
|  | long list of APIs that you selected have been | 
|  | declared as module dependencies. When the module | 
|  | is built, the dependencies will be registered | 
|  | in the manifest file.</li> | 
|  |  | 
|  | </ol> | 
|  | </div> | 
|  | <h3 class="tutorial"><a name="creating-factory"></a>Creating the Highlight Layer Factory</h3> | 
|  |  | 
|  | <p>Highlight layer factories are defined | 
|  | by the <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/package-summary.html">Highlighting SPI</a>.</p> | 
|  |  | 
|  | <p>To use the Highlighting SPI to create the palette in this tutorial, take the following steps:</p> | 
|  | <div class="indent"> | 
|  |  | 
|  | <ol> | 
|  |  | 
|  | <li>Right-click the <tt>MarkHTMLOccurrences</tt> project node and | 
|  | choose New > Java Class. Create a Java file | 
|  | called <tt>MarkHTMLOccurrencesHighlightsLayerFactory</tt>.</li> | 
|  |  | 
|  | <li>Replace the default content of the <tt>MarkHTMLOccurrencesHighlightsLayerFactory.java</tt> file with the following: | 
|  |  | 
|  | <pre class="examplecode">import javax.swing.text.Document; | 
|  | import org.netbeans.api.editor.mimelookup.MimeRegistration; | 
|  | import org.netbeans.api.editor.mimelookup.MimeRegistrations; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayer.html">org.netbeans.spi.editor.highlighting.HighlightsLayer</a>; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayerFactory.html">org.netbeans.spi.editor.highlighting.HighlightsLayerFactory</a>; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/ZOrder.html">org.netbeans.spi.editor.highlighting.ZOrder</a>; | 
|  |  | 
|  | @MimeRegistrations({ | 
|  | @MimeRegistration(mimeType = "text/html", service = HighlightsLayerFactory.class), | 
|  | @MimeRegistration(mimeType = "text/xml", service = HighlightsLayerFactory.class) | 
|  | }) | 
|  | public class MarkHTMLOccurrencesHighlightsLayerFactory implements <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayerFactory.html">HighlightsLayerFactory</a> { | 
|  |  | 
|  | public static MarkHTMLOccurrencesHighlighter getMarkOccurrencesHighlighter(Document doc) { | 
|  | MarkHTMLOccurrencesHighlighter highlighter = | 
|  | (MarkHTMLOccurrencesHighlighter) doc.getProperty(MarkHTMLOccurrencesHighlighter.class); | 
|  | if (highlighter == null) { | 
|  | doc.putProperty(MarkHTMLOccurrencesHighlighter.class, | 
|  | highlighter = new MarkHTMLOccurrencesHighlighter(doc)); | 
|  | } | 
|  | return highlighter; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public HighlightsLayer[] <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayerFactory.html#createLayers(org.netbeans.spi.editor.highlighting.HighlightsLayerFactory.Context)">createLayers</a>(<a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayerFactory.Context.html">Context</a> context) { | 
|  | return new HighlightsLayer[]{ | 
|  | <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsLayer.html#create(java.lang.String,%20org.netbeans.spi.editor.highlighting.ZOrder,%20boolean,%20org.netbeans.spi.editor.highlighting.HighlightsContainer)">HighlightsLayer.create</a>( | 
|  | MarkHTMLOccurrencesHighlighter.class.getName(), | 
|  | <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/ZOrder.html">ZOrder.CARET_RACK.forPosition(2000)</a>, | 
|  | true, | 
|  | <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/HighlightsContainer.html">getMarkOccurrencesHighlighter(context.getDocument()).getHighlightsBag()</a>) | 
|  | }; | 
|  | } | 
|  |  | 
|  | }</pre></li> | 
|  |  | 
|  | </ol> | 
|  | </div> | 
|  | <p class="tips">Several statements remain underlined in red | 
|  | because they refer to the "MarkHTMLOccurrencesHighlighter" class, | 
|  | which we will create in the next section.</p> | 
|  | <h3 class="tutorial"><a name="creating-highlight"></a>Creating the Highlight Layer</h3> | 
|  |  | 
|  | <p>In this section, we create the highlight layer. Create a new Java | 
|  | class named <tt>MarkHTMLOccurrencesHighlighter</tt>, with the content below.</p> | 
|  |  | 
|  | <pre class="examplecode">import java.awt.Color; | 
|  | import java.lang.ref.WeakReference; | 
|  | import java.util.regex.Matcher; | 
|  | import java.util.regex.Pattern; | 
|  | import javax.swing.JEditorPane; | 
|  | import javax.swing.event.CaretEvent; | 
|  | import javax.swing.event.CaretListener; | 
|  | import javax.swing.text.AttributeSet; | 
|  | import javax.swing.text.Document; | 
|  | import javax.swing.text.JTextComponent; | 
|  | import javax.swing.text.StyleConstants; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-settings/org/netbeans/api/editor/settings/AttributesUtilities.html">org.netbeans.api.editor.settings.AttributesUtilities</a>; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor/org/netbeans/modules/editor/NbEditorUtilities.html">org.netbeans.modules.editor.NbEditorUtilities</a>; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/support/OffsetsBag.html">org.netbeans.spi.editor.highlighting.support.OffsetsBag</a>; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-text/org/openide/cookies/EditorCookie.html">org.openide.cookies.EditorCookie</a>; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-loaders/org/openide/loaders/DataObject.html">org.openide.loaders.DataObject</a>; | 
|  | import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/RequestProcessor.html">org.openide.util.RequestProcessor</a>; | 
|  |  | 
|  | public class MarkHTMLOccurrencesHighlighter implements CaretListener { | 
|  |  | 
|  | private static final AttributeSet defaultColors = | 
|  | AttributesUtilities.createImmutable(StyleConstants.Background, | 
|  | new Color(236, 235, 163)); | 
|  |  | 
|  | private final OffsetsBag bag; | 
|  |  | 
|  | private JTextComponent comp; | 
|  | private final WeakReference<Document> weakDoc; | 
|  |  | 
|  | private final RequestProcessor rp; | 
|  | private final static int REFRESH_DELAY = 100; | 
|  | private RequestProcessor.Task lastRefreshTask; | 
|  |  | 
|  | public MarkHTMLOccurrencesHighlighter(Document doc) { | 
|  | rp = new RequestProcessor(MarkHTMLOccurrencesHighlighter.class); | 
|  | bag = new OffsetsBag(doc); | 
|  | weakDoc = new WeakReference<Document>((Document) doc); | 
|  | DataObject dobj = NbEditorUtilities.getDataObject(weakDoc.get()); | 
|  | if (dobj != null) { | 
|  | EditorCookie pane = dobj.getLookup().lookup(EditorCookie.class); | 
|  | JEditorPane[] panes = pane.getOpenedPanes(); | 
|  | if (panes != null && panes.length > 0) { | 
|  | comp = panes[0]; | 
|  | comp.addCaretListener(this); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public void caretUpdate(CaretEvent e) { | 
|  | bag.clear(); | 
|  | setupAutoRefresh(); | 
|  | } | 
|  |  | 
|  | public void setupAutoRefresh() { | 
|  | if (lastRefreshTask == null) { | 
|  | lastRefreshTask = rp.create(new Runnable() { | 
|  | @Override | 
|  | public void run() { | 
|  | String selection = comp.getSelectedText(); | 
|  | if (selection != null) { | 
|  | Pattern p = Pattern.compile(selection); | 
|  | Matcher m = p.matcher(comp.getText()); | 
|  | while (m.find() == true) { | 
|  | int startOffset = m.start(); | 
|  | int endOffset = m.end(); | 
|  | bag.addHighlight(startOffset, endOffset, defaultColors); | 
|  | } | 
|  | } | 
|  | } | 
|  | }); | 
|  | } | 
|  | lastRefreshTask.schedule(REFRESH_DELAY); | 
|  | } | 
|  |  | 
|  | public OffsetsBag getHighlightsBag() { | 
|  | return bag; | 
|  | } | 
|  |  | 
|  | }</pre> | 
|  |  | 
|  | </div> | 
|  |  | 
|  |  | 
|  | <!-- ======================================================================================= --> | 
|  |  | 
|  | <h2><a name="building"></a>Building and Installing the Module</h2> | 
|  | <p>The IDE uses an Ant build script to build and install your module. The build script is created for you | 
|  | when you create the module project.</p> | 
|  | <div class="indent"> | 
|  | <ol> | 
|  | <li>In the Projects window, right-click | 
|  | the <tt>MarkHTMLOccurrences</tt> project and choose Run.</li> | 
|  | <li>The module is built and installed in a new instance of the IDE. | 
|  | Open an HTML file or an XML file, double-click on a word, | 
|  | and notice that all matching words are automatically | 
|  | highlighted: | 
|  | <br/><br/><img src="../images/tutorials/mark-occs/72/result-3.png" alt="result"/></p> | 
|  | </li> | 
|  | <li>Navigate from one matching word to the next | 
|  | via Ctrl-F3.</li> | 
|  | </ol> | 
|  | </div> | 
|  |  | 
|  | <div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&subject=Feedback:%20Mark%20Occurrences%20Module%208.0%20Tutorial">Send Us Your Feedback</a></div> | 
|  |  | 
|  | <!-- ======================================================================================== --> | 
|  |  | 
|  | <h2><a name="nextsteps"></a>Next Steps</h2> | 
|  |  | 
|  | <p>For more information about creating and developing NetBeans modules, see the following resources:</p> | 
|  |  | 
|  | <ul> | 
|  | <li><a href="https://netbeans.org/kb/trails/platform.html">Other Related Tutorials</a></li> | 
|  | <li><a href="http://bits.netbeans.org/dev/javadoc/index.html">NetBeans API Javadoc</a></li> | 
|  | </ul> | 
|  |  | 
|  | <!-- ======================================================================================== --> | 
|  | <!-- | 
|  | <h2><a name="version"></a>Versioning </h2> | 
|  |  | 
|  | <table width="76%" border="1"> | 
|  | <tbody> | 
|  | <tr> | 
|  | <td> | 
|  | <div align="left"><b>Version</b></div> | 
|  | </td> | 
|  | <td> | 
|  | <div align="left"><b>Date</b></div> | 
|  | </td> | 
|  | <td> | 
|  | <div align="left"><b>Changes</b></div> | 
|  | </td> | 
|  | <td> | 
|  | <div align="left"><b>Open Issues</b></div> | 
|  | </td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td> | 
|  | 1 | 
|  | </td> | 
|  | <td> | 
|  | 5 November 2008 | 
|  | </td> | 
|  | <td> | 
|  | Initial version | 
|  | </td> | 
|  | <td> | 
|  | ... | 
|  | </td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td> | 
|  | 2 | 
|  | </td> | 
|  | <td> | 
|  | 16 November 2008 | 
|  | </td> | 
|  | <td> | 
|  | Added more details, including more links to Javadoc. | 
|  | </td> | 
|  | <tr> | 
|  | <td> | 
|  | 3 | 
|  | </td> | 
|  | <td> | 
|  | 13 November 2011 | 
|  | </td> | 
|  | <td> | 
|  | Updated to 7.1. Added null check for DataObject and rewrote the RequestProcessor. | 
|  | </td> | 
|  | <tr> | 
|  | <td> | 
|  | 4 | 
|  | </td> | 
|  | <td> | 
|  | 15 July 2012 | 
|  | </td> | 
|  | <td> | 
|  | Updated to 7.2. Replaced getCookie with getLookup and added screenshots. | 
|  | </td> | 
|  | </tr> | 
|  | <tr> | 
|  | <td> | 
|  | 4 | 
|  | </td> | 
|  | <td> | 
|  | 3 July 2014 | 
|  | </td> | 
|  | <td> | 
|  | Updated to 8.0. | 
|  | </td> | 
|  | </tr> | 
|  | </tbody> | 
|  | </table> | 
|  | --> | 
|  | </body> | 
|  | </html> |