package freenet.client.updaters;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.user.client.ui.RootPanel;
import freenet.client.l10n.L10n;
import freenet.client.messages.Message;
import freenet.client.messages.MessageManager;
import freenet.client.messages.Priority;
import freenet.client.FreenetJs;
/** An Updater that replaces the element and refreshes the image loading's overall progress message */
public class ImageElementUpdater extends ReplacerUpdater {
public ImageElementUpdater() {
int[] counted = countImageProgress();
lastCounted = counted;
if (counted[1] != 0) {
// Only show the messages if image loading is in progress
Message newMsg = makeProgressMsg(counted[0], counted[1]);
MessageManager.get().addMessage(newMsg);
lastMessage = newMsg;
}
}
/** The last message, that is currently showed */
private Message lastMessage = makeProgressMsg(0, 0);
/** The last result of progress counting */
private int[] lastCounted;
@Override
public void updated(String elementId, String content) {
// Saves the progress of the old image element
int[] previousFetched = new int[2];
if (MessageManager.get().isMessagePresent(lastMessage)) {
previousFetched = getProgressForElement(RootPanel.get(elementId).getElement());
}
// Replace the content
super.updated(elementId, content);
// If message is shown
if (MessageManager.get().isMessagePresent(lastMessage)) {
// Gets the progress
int[] counted = getProgressForElement(RootPanel.get(elementId).getElement());
int[] nowCounted = new int[2];
nowCounted[0] = lastCounted[0] - previousFetched[0] + counted[0];
nowCounted[1] = lastCounted[1] - previousFetched[1] + counted[1];
// Update the overall progress
lastCounted = nowCounted;
// Replace the message, if not complete yet
if (nowCounted[1] != 0) {
Message newMsg = makeProgressMsg(nowCounted[0], nowCounted[1]);
if (lastMessage != null) {
MessageManager.get().replaceMessageAtPosition(MessageManager.get().getMessagePosition(lastMessage), newMsg);
} else {
MessageManager.get().addMessage(newMsg);
}
lastMessage = newMsg;
}else if(lastMessage!=null){
MessageManager.get().removeMessage(lastMessage);
}
}
}
/**
* Creates the progress message for the given progress
*
* @param fetched
* - The number of the fetched blocks
* @param total
* - The number of the total blocks
* @return The message to be shown in the messages panel
*/
private Message makeProgressMsg(int fetched, int total) {
return new Message(L10n.get("imageprogress") + fetched + "/" + total, Priority.MINOR, null,true);
}
/**
* Returns the progress for a given element
*
* @param image
* - The image element
* @return [0]:the number of fetched blocks [1]:the total number of blocks
*/
private int[] getProgressForElement(Element image) {
int total = 0;
int fetched = 0;
// Finds the hidden inputs
NodeList<Element> inputs = image.getElementsByTagName("input");
for (int j = 0; j < inputs.getLength(); j++) {
Element input = inputs.getItem(j);
// Gets the data if the corresponding input is found
if (input.getAttribute("name").compareTo("fetchedBlocks") == 0) {
try {
fetched = Integer.parseInt(input.getAttribute("value"));
} catch (NumberFormatException e) {
FreenetJs.log("fetchedBlocks value \""+input.getAttribute("value")+"\" is invalid: "+e);
}
} else if (input.getAttribute("name").compareTo("requiredBlocks") == 0) {
try {
total = Integer.parseInt(input.getAttribute("value"));
} catch (NumberFormatException e) {
FreenetJs.log("requiredBlocks value \""+input.getAttribute("value")+"\" is invalid: "+e);
}
}
}
return new int[] { fetched, total };
}
/**
* Returns the overall progress for all images in the page
*
* @return [0]:the number of fetched blocks [1]:the total number of blocks
*/
private int[] countImageProgress() {
int fetched = 0;
int total = 0;
// Cycle through all 'span' elements
NodeList<Element> elements = Document.get().getElementsByTagName("span");
for (int i = 0; i < elements.getLength(); i++) {
Element e = elements.getItem(i);
// Checks if it is an ImageElement
if (e.getClassName().contains("ImageElement")) {
// Add it's progress to the overall
int[] status = getProgressForElement(e);
fetched += status[0];
total += status[1];
}
}
return new int[] { fetched, total };
}
}