/** * Find which bit contains offset. * * @param offset * @return the index of the bit plus whatever was left over or null when * offset is outside the document. */ private Pair<Integer, Integer> locate(int offset) { int index = 0; while (bits.size() > index && bits.get(index).size() <= offset) { offset -= bits.get(index).size(); index++; } return Pair.of(index, offset); }
private void parse(Document doc) { E bodyElement = Blips.getBody(doc); if (bodyElement != null) { N child = doc.getFirstChild(bodyElement); while (child != null) { T asText = doc.asText(child); int xmlPos = doc.getLocation(child); if (asText != null) { bits.add(new Bit(doc.getData(asText), xmlPos)); } else { E xmlElement = doc.asElement(child); if (xmlElement != null) { Element element = ElementSerializer.xmlToApiElement(doc, xmlElement, wavelet); // element can be null, but we still want to note that there // was something unknown. N next = doc.getNextSibling(child); int xmlSize; if (next != null) { xmlSize = doc.getLocation(next) - xmlPos; } else { // At the end of the document. XmlSize is the rest. xmlSize = doc.size() - 1 - xmlPos; } bits.add(new Bit(element, xmlPos, xmlSize)); } } child = doc.getNextSibling(child); } } }
Point<Doc.N> point = doc.locate(last.xmlPos + last.xmlSize); doc.insertXml(point, xml); bits.add(new Bit(element, last.xmlPos + last.xmlSize, doc.size() - beforeSize)); return; bit.xmlSize = offset; int nextIndex = bit.xmlPos + bit.xmlSize; bits.add(index + 1, new Bit(element, nextIndex, xmlSize)); nextIndex += xmlSize; bits.add(index + 2, new Bit(leftOver, nextIndex)); } else { bits.add(index, new Bit(element, bits.get(index).xmlPos, xmlSize)); shift(index + 1, xmlSize);
/** * Legacy support method. Return the index of the element that looks like the * one we passed for some value of looks like. */ public int locateElement(Element element) { int index = 0; for (Bit bit : bits) { if (bit.element != null && bit.element.getType().equals(element.getType())) { if (element.getType().equals(ElementType.GADGET)) { if (propertyMatch(bit.element, element, Gadget.URL)) { return index; } } else if (element.getType().equals(ElementType.LABEL)) { if (propertyMatch(bit.element, element, "for")) { return index; } } else if (elementMatch(element, bit.element)) { return index; } } index += bit.size(); } return -1; }
/** * @returns a list of ElementInfo's describing the elements in view. */ public List<ElementInfo> getElements() { List<ElementInfo> res = Lists.newArrayList(); int index = 0; for (Bit bit : bits) { if (bit.element != null) { res.add(new ElementInfo(bit.element, index, bit.xmlPos)); } index += bit.size(); } return res; }