/** * {@inheritDoc} * * @see AbstractSelectionExecutable#execute(String) */ public boolean execute(String param) { // Get the selected anchor AnchorElement selectedAnchor = LinkExecutableUtils.getSelectedAnchor(rta); if (selectedAnchor == null) { return false; } Range range = rta.getDocument().getSelection().getRangeAt(0); // unlink // but first check where is the selection. If the selection is a caret and is at one side of the // anchor, just // move the caret out instead of removing the link boolean moveSelection = range.isCollapsed(); boolean isBeginning = false; boolean isEnd = false; if (moveSelection) { // check if it's at the beginning or at the end isBeginning = (domUtils.getFirstAncestor( domUtils.getPreviousLeaf(range), LinkExecutableUtils.ANCHOR_TAG_NAME) != selectedAnchor) && range.getStartOffset() == 0; isEnd = (domUtils.getFirstAncestor( domUtils.getNextLeaf(range), LinkExecutableUtils.ANCHOR_TAG_NAME) != selectedAnchor) && range.getEndOffset() == domUtils.getLength(range.getEndContainer()); } if (moveSelection && (isEnd || isBeginning) && selectedAnchor.getOffsetWidth() > 0) { // cursor it's at the beginning or at the end, move it out of the anchor moveCaretOuside(rta, Element.as(selectedAnchor), isEnd); } else { Element.as(selectedAnchor).unwrap(); } return true; }
/** * Updates the meta data of the given anchor. * * @param anchor the anchor whose meta data will be updated * @param reference the new link reference * @param linkType the new link type */ private void updateMetaData(AnchorElement anchor, String reference, LinkType linkType) { Document document = (Document) anchor.getOwnerDocument(); DocumentFragment metaData = document.createDocumentFragment(); metaData.appendChild( document.createComment("startwikilink:" + EscapeUtils.escapeComment(reference))); metaData.appendChild(document.createSpanElement()); if (CLASS_NAME_MAPPING.containsKey(linkType)) { Element.as(metaData.getChild(1)).setClassName(CLASS_NAME_MAPPING.get(linkType)); } metaData.getChild(1).appendChild(document.createTextNode(Element.INNER_HTML_PLACEHOLDER)); metaData.appendChild(document.createComment("stopwikilink")); Element.as(anchor).setMetaData(metaData); }
/** * Create a table from TableConfig configuration. * * <p>We create the table using innerHTML instead of creating each DOM node in order to improve * the speed. In most of the browsers setting the innerHTML is faster than creating the DOM nodes * and appending them. * * @param doc currently edited document. * @param config table configuration (row number, etc). * @return the newly created table. */ public Element createTable(Document doc, TableConfig config) { StringBuffer table = new StringBuffer("<table>"); StringBuffer row = new StringBuffer("<tr>"); for (int i = 0; i < config.getColNumber(); i++) { row.append("<td>"); // The default cell content depends on the browser. In Firefox the best option is to use a BR. // Firefox // itself uses BRs in order to allow the user to place the caret inside empty block elements. // In Internet // Explorer the best option is to set the inner HTML of each cell to the empty string, after // creation. For // now lets keep the non-breaking space. At some point we should have browser specific // implementations for // FF and IE. Each will overwrite this method and add specific initialization. row.append(TableUtils.CELL_DEFAULTHTML); row.append("</td>"); } row.append("</tr>"); if (config.hasHeader()) { table.append("<thead>"); if (config.getRowNumber() > 0) { table.append(row.toString().replace("td", "th")); } table.append("</thead>"); } table.append("<tbody>"); for (int i = config.hasHeader() ? 1 : 0; i < config.getRowNumber(); i++) { table.append(row.toString()); } table.append("</tbody></table>"); Element container = doc.createDivElement().cast(); container.setInnerHTML(table.toString()); Element tableElement = (Element) container.getFirstChild(); container.removeChild(tableElement); return tableElement; }
/** * {@inheritDoc} * * @see ConfigDOMWriter#write(Object, com.google.gwt.dom.client.Element) */ public void write(LinkConfig config, AnchorElement anchor) { // Required attributes. updateMetaData(anchor, config.getReference(), config.getType()); anchor.setHref(config.getUrl()); // Optional attributes. updateAttribute(anchor, "title", config.getTooltip()); if (config.isOpenInNewWindow()) { anchor.setRel(TARGET_BLANK); } else if (TARGET_BLANK.equalsIgnoreCase(anchor.getRel())) { anchor.removeAttribute("rel"); } // Update the content. if (!anchor.getInnerHTML().equals(config.getLabel())) { // Inner HTML listeners have to be notified in order to extract the meta data. Element.as(anchor).xSetInnerHTML(config.getLabel()); } }