kune-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
July 2011
- 3 participants
- 42 discussions
r1447 - in trunk/src/main/java/cc/kune: chat/client core/client/sitebar/spaces core/client/ws/entheader
by Vicente J. Ruiz Jurado 10 Jul '11
by Vicente J. Ruiz Jurado 10 Jul '11
10 Jul '11
Author: vjrj_
Date: 2011-07-10 22:58:52 +0200 (Sun, 10 Jul 2011)
New Revision: 1447
Modified:
trunk/src/main/java/cc/kune/chat/client/AvatarDecoratorImpl.java
trunk/src/main/java/cc/kune/chat/client/ChatParts.java
trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPanel.java
trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java
trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityTextLogo.java
Log:
Some fixes in avatar on/offline status
Modified: trunk/src/main/java/cc/kune/chat/client/AvatarDecoratorImpl.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/AvatarDecoratorImpl.java 2011-07-10 18:29:52 UTC (rev 1446)
+++ trunk/src/main/java/cc/kune/chat/client/AvatarDecoratorImpl.java 2011-07-10 20:58:52 UTC (rev 1447)
@@ -6,8 +6,12 @@
import com.calclab.emite.core.client.events.StateChangedEvent;
import com.calclab.emite.core.client.events.StateChangedHandler;
import com.calclab.emite.core.client.xmpp.session.XmppSession;
+import com.calclab.emite.core.client.xmpp.stanzas.Presence;
import com.calclab.emite.core.client.xmpp.stanzas.Presence.Show;
import com.calclab.emite.core.client.xmpp.stanzas.XmppURI;
+import com.calclab.emite.im.client.presence.PresenceManager;
+import com.calclab.emite.im.client.presence.events.OwnPresenceChangedEvent;
+import com.calclab.emite.im.client.presence.events.OwnPresenceChangedHandler;
import com.calclab.emite.im.client.roster.RosterItem;
import com.calclab.emite.im.client.roster.XmppRoster;
import com.calclab.emite.im.client.roster.events.RosterItemChangedEvent;
@@ -29,11 +33,14 @@
private final ImageResource chatDotBusy;
private final ImageResource chatDotExtendedAway;
private final ImageResource chatDotXA;
+ private final HandlerRegistration presenceHandler;
+ private final PresenceManager presenceManager;
private final XmppRoster roster;
private final HandlerRegistration rosterHandler;
private final XmppSession session;
private final HandlerRegistration sessionStateChangedHandler;
private XmppURI uri;
+ private final XmppSession xmppSession;
public AvatarDecoratorImpl(final ChatInstances chatInstances, final ChatClient chatClient,
final ImageResource chatDotBusy, final ImageResource chatDotXA, final ImageResource chatDotAway,
@@ -52,6 +59,8 @@
}
});
roster = chatInstances.roster;
+ xmppSession = chatInstances.xmppSession;
+ presenceManager = chatInstances.presenceManager;
rosterHandler = roster.addRosterItemChangedHandler(new RosterItemChangedHandler() {
@Override
public void onRosterItemChanged(final RosterItemChangedEvent event) {
@@ -61,23 +70,38 @@
}
}
});
-
+ presenceHandler = presenceManager.addOwnPresenceChangedHandler(new OwnPresenceChangedHandler() {
+ @Override
+ public void onOwnPresenceChanged(final OwnPresenceChangedEvent event) {
+ refresh();
+ }
+ });
}
private void clearDecorator() {
AvatarDecoratorImpl.this.clearImage();
}
+ protected boolean isMe() {
+ final XmppURI currentUserURI = xmppSession.getCurrentUserURI();
+ return currentUserURI != null && currentUserURI.getJID().equals(uri);
+ }
+
private void refresh() {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
if (uri != null) {
- final RosterItem item = roster.getItemByJID(uri);
- if (session.isReady() && item != null) {
- setIcon(item.isAvailable(), item.getShow(), item.getStatus());
+ if (isMe()) {
+ final Presence ownPresence = presenceManager.getOwnPresence();
+ setIcon(xmppSession.isReady(), ownPresence.getShow(), ownPresence.getStatus());
} else {
- clearDecorator();
+ final RosterItem item = roster.getItemByJID(uri.getJID());
+ if (session.isReady() && item != null) {
+ setIcon(item.isAvailable(), item.getShow(), item.getStatus());
+ } else {
+ clearDecorator();
+ }
}
} else {
clearDecorator();
@@ -119,6 +143,7 @@
rosterHandler.removeHandler();
sessionStateChangedHandler.removeHandler();
attachHandler.removeHandler();
+ presenceHandler.removeHandler();
}
}
});
Modified: trunk/src/main/java/cc/kune/chat/client/ChatParts.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/ChatParts.java 2011-07-10 18:29:52 UTC (rev 1446)
+++ trunk/src/main/java/cc/kune/chat/client/ChatParts.java 2011-07-10 20:58:52 UTC (rev 1447)
@@ -94,6 +94,7 @@
final MenuItemDescriptor item = new MenuItemDescriptor(startChatWithMemberAction.get());
item.add(isNotMe);
item.add(isPersonCondition);
+ item.add(isNotBuddieCondition);
item.add(isLogged);
return item;
}
@@ -149,6 +150,9 @@
snAdminsRegistry.get().add(startChatWithBuddieItem);
snCollabsItemsRegistry.get().add(startChatWithBuddieItem);
snPendingItemsRegistry.get().add(startChatWithBuddieItem);
+ snAdminsRegistry.get().add(addAsBuddieItem);
+ snCollabsItemsRegistry.get().add(addAsBuddieItem);
+ snPendingItemsRegistry.get().add(addAsBuddieItem);
userItemsRegistry.get().add(startChatWithBuddieItem);
userItemsRegistry.get().add(startChatWithPersonItem);
Modified: trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-10 18:29:52 UTC (rev 1446)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-10 20:58:52 UTC (rev 1447)
@@ -150,7 +150,7 @@
@ProxyEvent
public void onAppStart(final AppStartEvent event) {
- showTooltipWithDelay();
+ // showTooltipWithDelay();
}
private void onGroupSpaceSelect() {
Modified: trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPanel.java 2011-07-10 18:29:52 UTC (rev 1446)
+++ trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPanel.java 2011-07-10 20:58:52 UTC (rev 1447)
@@ -86,14 +86,10 @@
return mainPanel;
}
- private String getAvatarDecoratorParam(final GroupDTO group) {
- return group.isPersonal() ? group.getShortName() : null;
- }
-
@Override
public void reloadImage(final GroupDTO group) {
entityTextLogo.setLogoImage(downloadProvider.get().getLogoImageUrl(group.getStateToken())
- + "&nocache=" + new Date().getTime(), getAvatarDecoratorParam(group));
+ + "&nocache=" + new Date().getTime());
}
@Deprecated
@@ -118,8 +114,7 @@
@Override
public void setLogoImage(final GroupDTO group) {
- entityTextLogo.setLogoImage(downloadProvider.get().getLogoImageUrl(group.getStateToken()),
- getAvatarDecoratorParam(group));
+ entityTextLogo.setLogoImage(downloadProvider.get().getLogoImageUrl(group.getStateToken()));
}
@Override
@@ -137,23 +132,23 @@
entityTextLogo.setMediumFont();
}
- //
- // @Override
- // public void setTheme(final WsTheme oldTheme, final WsTheme newTheme) {
- // if (oldTheme != null) {
- // entityTextLogo.removeStyleDependentName(oldTheme.toString());
- // }
- // entityTextLogo.addStyleDependentName(newTheme.toString());
- // }
+ @Override
+ public void setOnlineStatusGroup(final String group) {
+ entityTextLogo.setOnlineStatusGroup(group);
+ }
+ public void setOnlineStatusVisible(final boolean visible) {
+ entityTextLogo.setOnlineStatusVisible(visible);
+ }
+
@Override
public void setSmallFont() {
entityTextLogo.setSmallFont();
}
@Override
- public void showDefUserLogo(final GroupDTO group) {
- entityTextLogo.setLogoImage(AbstractImagePrototype.create(images.unknown60()),
- getAvatarDecoratorParam(group));
+ public void showDefUserLogo() {
+ entityTextLogo.setLogoImage(AbstractImagePrototype.create(images.unknown60()));
}
+
}
Modified: trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java 2011-07-10 18:29:52 UTC (rev 1446)
+++ trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java 2011-07-10 20:58:52 UTC (rev 1447)
@@ -61,11 +61,13 @@
void setMediumFont();
+ void setOnlineStatusGroup(String group);
+
+ void setOnlineStatusVisible(boolean visible);
+
void setSmallFont();
- // void setTheme(final WsTheme oldTheme, WsTheme newTheme);
-
- void showDefUserLogo(GroupDTO group);
+ void showDefUserLogo();
}
private static final int LARGE_NAME_LIMIT = 17;
@@ -89,12 +91,6 @@
reloadGroupLogoImage();
}
});
- // theme.addOnThemeChanged(new Listener2<WsTheme, WsTheme>() {
- // @Override
- // public void onEvent(final WsTheme oldTheme, final WsTheme newTheme) {
- // // getView().setTheme(oldTheme, newTheme);
- // }
- // });
}
@Override
@@ -123,19 +119,25 @@
}
void setGroupLogo(final GroupDTO group) {
+ setLogoText(group.getLongName());
if (group.hasLogo()) {
- setLogoText(group.getLongName());
getView().setLogoImage(group);
getView().setLogoImageVisible(true);
} else {
- setLogoText(group.getLongName());
if (group.isPersonal()) {
- getView().showDefUserLogo(group);
+ getView().showDefUserLogo();
getView().setLogoImageVisible(true);
} else {
getView().setLogoImageVisible(false);
}
}
+ if (group.isPersonal()) {
+ getView().setOnlineStatusGroup(group.getShortName());
+ getView().setOnlineStatusVisible(true);
+ } else {
+ getView().setOnlineStatusGroup(null);
+ getView().setOnlineStatusVisible(false);
+ }
}
void setLogoText(final String name) {
Modified: trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityTextLogo.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityTextLogo.java 2011-07-10 18:29:52 UTC (rev 1446)
+++ trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityTextLogo.java 2011-07-10 20:58:52 UTC (rev 1447)
@@ -92,16 +92,14 @@
logoLabel.addStyleName(LOGO_LARGE_FONT_STYLE);
}
- public void setLogoImage(final AbstractImagePrototype imageProto, final String groupName) {
+ public void setLogoImage(final AbstractImagePrototype imageProto) {
imageProto.applyTo(logoImage);
- avatarDecorator.setItem(groupName);
}
- public void setLogoImage(final String url, final String groupName) {
+ public void setLogoImage(final String url) {
logoImage.setUrl("images/clear.gif");
Image.prefetch(url);
logoImage.setUrl(url);
- avatarDecorator.setItem(groupName);
}
public void setLogoText(final String text) {
@@ -114,7 +112,6 @@
public void setLogoVisible(final boolean visible) {
logoImage.setVisible(visible);
- avatarDecorator.setDecoratorVisible(visible);
}
public void setMediumFont() {
@@ -122,6 +119,14 @@
logoLabel.addStyleName(LOGO_MEDIUM_FONT_STYLE);
}
+ public void setOnlineStatusGroup(final String group) {
+ avatarDecorator.setItem(group);
+ }
+
+ public void setOnlineStatusVisible(final boolean visible) {
+ avatarDecorator.setDecoratorVisible(visible);
+ }
+
public void setSmallFont() {
resetFontSize();
logoLabel.addStyleName(LOGO_SMALL_FONT_STYLE);
1
0
Author: vjrj_
Date: 2011-07-10 20:29:52 +0200 (Sun, 10 Jul 2011)
New Revision: 1446
Added:
trunk/src/main/java/cc/kune/chat/client/AvatarDecoratorImpl.java
trunk/src/main/java/cc/kune/chat/client/ChatInstances.java
trunk/src/main/java/cc/kune/chat/client/MediumAvatarDecoratorImpl.java
trunk/src/main/java/cc/kune/chat/client/SmallAvatarDecoratorImpl.java
trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithThisPersonAction.java
trunk/src/main/java/cc/kune/chat/client/actions/conditions/
trunk/src/main/java/cc/kune/chat/client/actions/conditions/IsBuddieCondition.java
trunk/src/main/java/cc/kune/chat/client/actions/conditions/IsNotBuddieCondition.java
trunk/src/main/java/cc/kune/common/client/ui/AbstractDecorator.java
trunk/src/main/java/cc/kune/common/client/ui/AbstractDecorator.ui.xml
trunk/src/main/java/cc/kune/core/client/avatar/
trunk/src/main/java/cc/kune/core/client/avatar/AvatarDecorator.java
trunk/src/main/java/cc/kune/core/client/avatar/MediumAvatarDecorator.java
trunk/src/main/java/cc/kune/core/client/avatar/SmallAvatarDecorator.java
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-available-medium.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-available-small.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-away-medium.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-away-small.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-busy-medium.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-busy-small.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-extended-away-medium.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-extended-away-small.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-invisible-medium.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-invisible-small.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-offline-medium.png
trunk/src/main/java/cc/kune/core/client/resources/chat-dot-offline-small.png
Removed:
trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithUserAction.java
Modified:
trunk/
trunk/src/main/java/cc/kune/chat/client/ChatClientDefault.java
trunk/src/main/java/cc/kune/chat/client/ChatGinModule.java
trunk/src/main/java/cc/kune/chat/client/ChatOptions.java
trunk/src/main/java/cc/kune/chat/client/ChatParts.java
trunk/src/main/java/cc/kune/chat/client/KuneHablarSignals.java
trunk/src/main/java/cc/kune/chat/client/actions/AddAsBuddieHeaderButton.java
trunk/src/main/java/cc/kune/chat/client/actions/ChatSitebarActions.java
trunk/src/main/java/cc/kune/chat/client/actions/OpenGroupPublicChatRoomAction.java
trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithMemberAction.java
trunk/src/main/java/cc/kune/core/client/CoreGinModule.java
trunk/src/main/java/cc/kune/core/client/resources/CoreResources.java
trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
trunk/src/main/java/cc/kune/core/client/sn/AbstractSNPanel.java
trunk/src/main/java/cc/kune/core/client/sn/AbstractSNPanel.ui.xml
trunk/src/main/java/cc/kune/core/client/sn/GroupSNPanel.java
trunk/src/main/java/cc/kune/core/client/sn/UserSNPanel.java
trunk/src/main/java/cc/kune/core/client/sn/actions/conditions/IsMeCondition.java
trunk/src/main/java/cc/kune/core/client/sn/actions/conditions/IsNotMeCondition.java
trunk/src/main/java/cc/kune/core/client/sn/actions/registry/UserSNMenuItemsRegistry.java
trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPanel.java
trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java
trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityTextLogo.java
trunk/src/main/java/cc/kune/gspace/client/viewers/FolderViewerPresenter.java
trunk/src/main/java/cc/kune/wave/client/WaveStatusIndicator.java
Log:
Avatar of buddies with status; Several fixes in chat
Property changes on: trunk
___________________________________________________________________
Name: svn:ignore
- pmd-eclipse.log
.pmd
www-test
screenlog.0
client
public
target
target-local
Main-compile
.settings
.gwt-cache
repository
derby.log
star-yellow-grey.png
run.sh
tomcat
gwt-out
synccss.sh
.externalToolBuilders
.wtpmodules
www
testRepository
kune-OLD-jcr
KuneApp.launch
KuneApp NOSERVER.launch
old_src
org.ourproject.kune.app.Kune
org.ourproject.kune.iml
org.ourproject.kune.ipr
org.ourproject.kune.iws
nbproject
hibernate.reveng.xml
.gwt-tmp
target-eclipse
.checkstyle
.classpath-bien
pom.xml.*
.gwt
.jdee_sources
.jdee_classpath
prj.el
.factorypath
.apt_generated
target.old
_accounts
_certificates
_deltas
logs
test-output
+ pmd-eclipse.log
.pmd
www-test
screenlog.0
client
public
target
target-local
Main-compile
.settings
.gwt-cache
repository
derby.log
star-yellow-grey.png
run.sh
tomcat
gwt-out
synccss.sh
.externalToolBuilders
.wtpmodules
www
testRepository
kune-OLD-jcr
KuneApp.launch
KuneApp NOSERVER.launch
old_src
org.ourproject.kune.app.Kune
org.ourproject.kune.iml
org.ourproject.kune.ipr
org.ourproject.kune.iws
nbproject
hibernate.reveng.xml
.gwt-tmp
target-eclipse
.checkstyle
.classpath-bien
pom.xml.*
.gwt
.jdee_sources
.jdee_classpath
prj.el
.factorypath
.apt_generated
target.old
_accounts
_certificates
_deltas
logs
test-output
.recommenders
Added: trunk/src/main/java/cc/kune/chat/client/AvatarDecoratorImpl.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/AvatarDecoratorImpl.java (rev 0)
+++ trunk/src/main/java/cc/kune/chat/client/AvatarDecoratorImpl.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,127 @@
+package cc.kune.chat.client;
+
+import cc.kune.common.client.ui.AbstractDecorator;
+import cc.kune.core.client.avatar.AvatarDecorator;
+
+import com.calclab.emite.core.client.events.StateChangedEvent;
+import com.calclab.emite.core.client.events.StateChangedHandler;
+import com.calclab.emite.core.client.xmpp.session.XmppSession;
+import com.calclab.emite.core.client.xmpp.stanzas.Presence.Show;
+import com.calclab.emite.core.client.xmpp.stanzas.XmppURI;
+import com.calclab.emite.im.client.roster.RosterItem;
+import com.calclab.emite.im.client.roster.XmppRoster;
+import com.calclab.emite.im.client.roster.events.RosterItemChangedEvent;
+import com.calclab.emite.im.client.roster.events.RosterItemChangedHandler;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+import com.google.gwt.event.logical.shared.AttachEvent;
+import com.google.gwt.event.logical.shared.AttachEvent.Handler;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.ui.IsWidget;
+
+public class AvatarDecoratorImpl extends AbstractDecorator implements AvatarDecorator {
+
+ private HandlerRegistration attachHandler;
+ private final ChatClient chatClient;
+ private final ImageResource chatDotAvailable;
+ private final ImageResource chatDotAway;
+ private final ImageResource chatDotBusy;
+ private final ImageResource chatDotExtendedAway;
+ private final ImageResource chatDotXA;
+ private final XmppRoster roster;
+ private final HandlerRegistration rosterHandler;
+ private final XmppSession session;
+ private final HandlerRegistration sessionStateChangedHandler;
+ private XmppURI uri;
+
+ public AvatarDecoratorImpl(final ChatInstances chatInstances, final ChatClient chatClient,
+ final ImageResource chatDotBusy, final ImageResource chatDotXA, final ImageResource chatDotAway,
+ final ImageResource chatDotExtendedAway, final ImageResource chatDotAvailable) {
+ this.chatClient = chatClient;
+ this.chatDotBusy = chatDotBusy;
+ this.chatDotXA = chatDotXA;
+ this.chatDotAway = chatDotAway;
+ this.chatDotExtendedAway = chatDotExtendedAway;
+ this.chatDotAvailable = chatDotAvailable;
+ session = chatInstances.xmppSession;
+ sessionStateChangedHandler = session.addSessionStateChangedHandler(false, new StateChangedHandler() {
+ @Override
+ public void onStateChanged(final StateChangedEvent event) {
+ refresh();
+ }
+ });
+ roster = chatInstances.roster;
+ rosterHandler = roster.addRosterItemChangedHandler(new RosterItemChangedHandler() {
+ @Override
+ public void onRosterItemChanged(final RosterItemChangedEvent event) {
+ final RosterItem item = event.getRosterItem();
+ if (item.getJID().equals(uri)) {
+ setIcon(item.isAvailable(), item.getShow(), item.getStatus());
+ }
+ }
+ });
+
+ }
+
+ private void clearDecorator() {
+ AvatarDecoratorImpl.this.clearImage();
+ }
+
+ private void refresh() {
+ Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+ @Override
+ public void execute() {
+ if (uri != null) {
+ final RosterItem item = roster.getItemByJID(uri);
+ if (session.isReady() && item != null) {
+ setIcon(item.isAvailable(), item.getShow(), item.getStatus());
+ } else {
+ clearDecorator();
+ }
+ } else {
+ clearDecorator();
+ }
+ }
+ });
+ }
+
+ private void setIcon(final boolean available, final Show show, final String status) {
+ if (show == Show.dnd) {
+ super.setImage(chatDotBusy);
+ } else if (show == Show.xa) {
+ super.setImage(chatDotXA);
+ } else if (show == Show.away) {
+ super.setImage(chatDotAway);
+ } else if (show == Show.chat) {
+ super.setImage(chatDotExtendedAway);
+ } else if (available) {
+ super.setImage(chatDotAvailable);
+ } else {
+ clearDecorator();
+ }
+ super.setImageTooltip(status);
+ }
+
+ @Override
+ public void setItem(final String name) {
+ this.uri = (name != null ? chatClient.uriFrom(name) : null);
+ refresh();
+ }
+
+ @Override
+ public void setWidget(final IsWidget widget) {
+ super.setWidget(widget);
+ attachHandler = widget.asWidget().addAttachHandler(new Handler() {
+ @Override
+ public void onAttachOrDetach(final AttachEvent event) {
+ if (!event.isAttached()) {
+ rosterHandler.removeHandler();
+ sessionStateChangedHandler.removeHandler();
+ attachHandler.removeHandler();
+ }
+ }
+ });
+ }
+
+}
Modified: trunk/src/main/java/cc/kune/chat/client/ChatClientDefault.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/ChatClientDefault.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/ChatClientDefault.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -55,7 +55,6 @@
import com.calclab.emite.core.client.xmpp.stanzas.XmppURI;
import com.calclab.emite.im.client.chat.ChatManager;
import com.calclab.emite.im.client.roster.XmppRoster;
-import com.calclab.emite.reconnect.client.SessionReconnect;
import com.calclab.emite.xep.avatar.client.AvatarManager;
import com.calclab.emite.xep.muc.client.Room;
import com.calclab.emite.xep.muc.client.RoomManager;
@@ -69,7 +68,6 @@
import com.calclab.hablar.icons.alt.client.AltIconsBundle;
import com.calclab.hablar.login.client.HablarLogin;
import com.calclab.hablar.login.client.LoginConfig;
-import com.calclab.suco.client.Suco;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.google.gwt.core.client.GWT;
@@ -112,7 +110,9 @@
private static final String CHAT_TITLE = "Chat ;)";
private final ChatClientAction action;
+ private final AvatarManager avatarManager;
protected IconLabelDescriptor chatIcon;
+ private final ChatInstances chatInstances;
private final ChatManager chatManager;
private final ChatOptions chatOptions;
private final ChatResources chatResources;
@@ -122,7 +122,9 @@
private final RoomManager roomManager;
private final XmppRoster roster;
private final Session session;
+
private final GlobalShortcutRegister shorcutRegister;
+
private final SitebarActions siteActions;
private final XmppSession xmppSession;
@@ -131,10 +133,10 @@
public ChatClientDefault(final EventBus eventBus, final I18nTranslationService i18n,
final SitebarActions siteActions, final Session session,
final GlobalShortcutRegister shorcutRegister, final ChatOptions chatOptions,
- final ChatResources chatResources) {
-
+ final ChatResources chatResources, final ChatInstances chatInstances) {
this.eventBus = eventBus;
this.i18n = i18n;
+ this.chatInstances = chatInstances;
action = new ChatClientAction(eventBus, chatResources);
this.siteActions = siteActions;
this.session = session;
@@ -142,11 +144,13 @@
this.chatOptions = chatOptions;
this.chatResources = chatResources;
chatResources.css().ensureInjected();
- this.xmppSession = Suco.get(XmppSession.class);
- this.roster = Suco.get(XmppRoster.class);
- this.chatManager = Suco.get(ChatManager.class);
- this.roomManager = Suco.get(RoomManager.class);
- Suco.get(SessionReconnect.class);
+ this.xmppSession = chatInstances.xmppSession;
+ this.roster = chatInstances.roster;
+ this.chatManager = chatInstances.chatManager;
+ this.roomManager = chatInstances.roomManager;
+ this.avatarManager = chatInstances.avatarManager;
+ // Not necessary, in ChatInstance
+ // Suco.get(SessionReconnect.class);
session.onAppStart(true, new AppStartEvent.AppStartHandler() {
@Override
@@ -305,7 +309,7 @@
final KuneHablarWidget widget = new KuneHablarWidget(config.layout, config.tabHeaderSize);
final Hablar hablar = widget.getHablar();
HablarComplete.install(hablar, config);
- new KuneHablarSignals(eventBus, xmppSession, hablar, action);
+ new KuneHablarSignals(eventBus, xmppSession, hablar, action, chatInstances);
if (htmlConfig.hasLogger) {
new HablarConsole(hablar);
}
@@ -414,7 +418,7 @@
@Override
public void setAvatar(final String photoBinary) {
- Suco.get(AvatarManager.class).setVCardAvatar(photoBinary);
+ avatarManager.setVCardAvatar(photoBinary);
}
private void setSize(final Widget widget, final HtmlConfig htmlConfig) {
@@ -455,6 +459,6 @@
@Override
public XmppURI uriFrom(final String shortName) {
- return XmppURI.jid(shortName + "@" + chatOptions.domain);
+ return chatOptions.uriFrom(shortName);
}
}
Modified: trunk/src/main/java/cc/kune/chat/client/ChatGinModule.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/ChatGinModule.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/ChatGinModule.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -22,11 +22,11 @@
import cc.kune.chat.client.actions.AddAsBuddieHeaderButton;
import cc.kune.chat.client.actions.ChatClientActions;
import cc.kune.chat.client.actions.ChatSitebarActions;
+import cc.kune.common.client.ExtendedGinModule;
+import cc.kune.core.client.avatar.MediumAvatarDecorator;
+import cc.kune.core.client.avatar.SmallAvatarDecorator;
-import com.google.inject.Singleton;
-import com.gwtplatform.mvp.client.gin.AbstractPresenterModule;
-
-public class ChatGinModule extends AbstractPresenterModule {
+public class ChatGinModule extends ExtendedGinModule {
/*
* (non-Javadoc)
*
@@ -34,12 +34,15 @@
*/
@Override
protected void configure() {
- bind(ChatClient.class).to(ChatClientDefault.class).in(Singleton.class);
- bind(ChatOptions.class).in(Singleton.class);
- bind(ChatSitebarActions.class).in(Singleton.class);
- bind(AddAsBuddieHeaderButton.class).in(Singleton.class);
- // bind(OpenGroupPublicChatRoomButton.class).in(Singleton.class);
- bind(ChatClientTool.class).in(Singleton.class);
- bind(ChatClientActions.class).in(Singleton.class);
+ s(ChatInstances.class);
+ bind(SmallAvatarDecorator.class).to(SmallAvatarDecoratorImpl.class);
+ bind(MediumAvatarDecorator.class).to(MediumAvatarDecoratorImpl.class);
+ s(ChatClient.class, ChatClientDefault.class);
+ s(ChatOptions.class);
+ s(ChatSitebarActions.class);
+ s(AddAsBuddieHeaderButton.class);
+ // bind(OpenGroupPublicChatRoomButton.class);
+ s(ChatClientTool.class);
+ s(ChatClientActions.class);
}
}
Added: trunk/src/main/java/cc/kune/chat/client/ChatInstances.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/ChatInstances.java (rev 0)
+++ trunk/src/main/java/cc/kune/chat/client/ChatInstances.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,34 @@
+package cc.kune.chat.client;
+
+import com.calclab.emite.core.client.xmpp.session.XmppSession;
+import com.calclab.emite.im.client.chat.ChatManager;
+import com.calclab.emite.im.client.presence.PresenceManager;
+import com.calclab.emite.im.client.roster.XmppRoster;
+import com.calclab.emite.reconnect.client.SessionReconnect;
+import com.calclab.emite.xep.avatar.client.AvatarManager;
+import com.calclab.emite.xep.muc.client.RoomManager;
+import com.calclab.emite.xep.storage.client.PrivateStorageManager;
+import com.calclab.suco.client.Suco;
+
+public class ChatInstances {
+
+ public AvatarManager avatarManager;
+ public ChatManager chatManager;
+ public PresenceManager presenceManager;
+ public PrivateStorageManager privateStorageManager;
+ public RoomManager roomManager;
+ public XmppRoster roster;
+ public SessionReconnect sessionReconnect;
+ public XmppSession xmppSession;
+
+ public ChatInstances() {
+ this.xmppSession = Suco.get(XmppSession.class);
+ this.roster = Suco.get(XmppRoster.class);
+ this.chatManager = Suco.get(ChatManager.class);
+ this.roomManager = Suco.get(RoomManager.class);
+ this.sessionReconnect = Suco.get(SessionReconnect.class);
+ this.avatarManager = Suco.get(AvatarManager.class);
+ this.presenceManager = Suco.get(PresenceManager.class);
+ this.privateStorageManager = Suco.get(PrivateStorageManager.class);
+ }
+}
Modified: trunk/src/main/java/cc/kune/chat/client/ChatOptions.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/ChatOptions.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/ChatOptions.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -22,11 +22,15 @@
import com.calclab.emite.core.client.xmpp.stanzas.XmppURI;
public class ChatOptions {
- public String domain;
- public String httpBase;
- public String passwd;
- public String resource;
- public String roomHost;
- public String username;
- public XmppURI useruri;
+ public String domain;
+ public String httpBase;
+ public String passwd;
+ public String resource;
+ public String roomHost;
+ public String username;
+ public XmppURI useruri;
+
+ public XmppURI uriFrom(final String shortName) {
+ return XmppURI.jid(shortName + "@" + domain);
+ }
}
\ No newline at end of file
Modified: trunk/src/main/java/cc/kune/chat/client/ChatParts.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/ChatParts.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/ChatParts.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -27,7 +27,9 @@
import cc.kune.chat.client.actions.StartAssemblyWithMembers;
import cc.kune.chat.client.actions.StartChatWithMemberAction;
import cc.kune.chat.client.actions.StartChatWithThisBuddieAction;
-import cc.kune.chat.client.actions.StartChatWithUserAction;
+import cc.kune.chat.client.actions.StartChatWithThisPersonAction;
+import cc.kune.chat.client.actions.conditions.IsBuddieCondition;
+import cc.kune.chat.client.actions.conditions.IsNotBuddieCondition;
import cc.kune.chat.shared.ChatConstants;
import cc.kune.common.client.actions.AbstractAction;
import cc.kune.common.client.actions.PropertyChangeEvent;
@@ -68,10 +70,12 @@
final Provider<UserSNMenuItemsRegistry> userItemsRegistry, final IsNotMeCondition isNotMe,
final IsCurrentStateAdministrableCondition isAdministrableCondition,
final IsCurrentStateEditableCondition isEditableCondition,
+ final IsBuddieCondition isBuddieCondition, final IsNotBuddieCondition isNotBuddieCondition,
final IsCurrentStateAGroupCondition isGroupCondition, final IsPersonCondition isPersonCondition,
final Provider<AddAsBuddieAction> addAsBuddie,
final Provider<StartChatWithMemberAction> startChatWithMemberAction,
- final IsLoggedCondition isLogged, final Provider<StartChatWithUserAction> startChatWithUserAction,
+ final IsLoggedCondition isLogged,
+ final Provider<StartChatWithThisPersonAction> startChatWithPersonAction,
final Provider<StartChatWithThisBuddieAction> startChatWithBuddieAction,
final ChatClientActions chatActions, final Provider<StartAssemblyWithMembers> startAssembly,
final Provider<OpenGroupPublicChatRoomAction> openGroupRoomAction,
@@ -99,6 +103,7 @@
public MenuItemDescriptor get() {
final MenuItemDescriptor item = new MenuItemDescriptor(startChatWithBuddieAction.get());
item.add(isLogged);
+ item.add(isBuddieCondition);
item.add(isPersonCondition);
return item;
}
@@ -109,6 +114,7 @@
final AddAsBuddieAction action = addAsBuddie.get();
final MenuItemDescriptor item = new MenuItemDescriptor(action);
item.add(isNotMe);
+ item.add(isNotBuddieCondition);
item.add(isLogged);
item.add(isPersonCondition);
/**
@@ -125,21 +131,27 @@
return item;
}
};
- final Provider<MenuItemDescriptor> startChatWithUserItem = new Provider<MenuItemDescriptor>() {
+ final Provider<MenuItemDescriptor> startChatWithPersonItem = new Provider<MenuItemDescriptor>() {
@Override
public MenuItemDescriptor get() {
- final MenuItemDescriptor item = new MenuItemDescriptor(startChatWithUserAction.get());
+ final MenuItemDescriptor item = new MenuItemDescriptor(startChatWithPersonAction.get());
item.add(isNotMe);
item.add(isLogged);
item.add(isPersonCondition);
+ item.add(isNotBuddieCondition);
return item;
}
};
snAdminsRegistry.get().add(startChatWithMemberItem);
snCollabsItemsRegistry.get().add(startChatWithMemberItem);
- snPendingItemsRegistry.get().add(startChatWithUserItem);
+ snPendingItemsRegistry.get().add(startChatWithPersonItem);
+ snAdminsRegistry.get().add(startChatWithBuddieItem);
+ snCollabsItemsRegistry.get().add(startChatWithBuddieItem);
+ snPendingItemsRegistry.get().add(startChatWithBuddieItem);
+
userItemsRegistry.get().add(startChatWithBuddieItem);
+ userItemsRegistry.get().add(startChatWithPersonItem);
userItemsRegistry.get().add(addAsBuddieItem);
groupConfActions.get().add(startAssembly.get());
buddieButton.get();
Modified: trunk/src/main/java/cc/kune/chat/client/KuneHablarSignals.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/KuneHablarSignals.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/KuneHablarSignals.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -34,7 +34,6 @@
import com.calclab.hablar.signals.client.unattended.UnattendedPagesManager;
import com.calclab.hablar.signals.client.unattended.UnattendedPresenter;
import com.calclab.hablar.user.client.UserContainer;
-import com.calclab.suco.client.Suco;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.Window;
@@ -71,9 +70,9 @@
// FIXME: move to gin
@SuppressWarnings("deprecation")
public KuneHablarSignals(final EventBus kuneEventBus, final XmppSession session, final Hablar hablar,
- final ChatClientAction action) {
+ final ChatClientAction action, final ChatInstances chatInstances) {
final HablarEventBus hablarEventBus = hablar.getEventBus();
- final PrivateStorageManager storageManager = Suco.get(PrivateStorageManager.class);
+ final PrivateStorageManager storageManager = chatInstances.privateStorageManager;
final HasText titleDisplay = new HasText() {
@Override
Added: trunk/src/main/java/cc/kune/chat/client/MediumAvatarDecoratorImpl.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/MediumAvatarDecoratorImpl.java (rev 0)
+++ trunk/src/main/java/cc/kune/chat/client/MediumAvatarDecoratorImpl.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,17 @@
+package cc.kune.chat.client;
+
+import cc.kune.core.client.avatar.MediumAvatarDecorator;
+import cc.kune.core.client.resources.CoreResources;
+
+import com.google.inject.Inject;
+
+public class MediumAvatarDecoratorImpl extends AvatarDecoratorImpl implements MediumAvatarDecorator {
+
+ @Inject
+ public MediumAvatarDecoratorImpl(final CoreResources res, final ChatInstances chatInstances,
+ final ChatClient chatClient) {
+ super(chatInstances, chatClient, res.chatDotBusyMedium(), res.chatDotAwayMedium(),
+ res.chatDotAwayMedium(), res.chatDotExtendedAwayMedium(), res.chatDotAvailableMedium());
+ setImagePosition(53, -6, -10);
+ }
+}
Added: trunk/src/main/java/cc/kune/chat/client/SmallAvatarDecoratorImpl.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/SmallAvatarDecoratorImpl.java (rev 0)
+++ trunk/src/main/java/cc/kune/chat/client/SmallAvatarDecoratorImpl.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,17 @@
+package cc.kune.chat.client;
+
+import cc.kune.core.client.avatar.SmallAvatarDecorator;
+import cc.kune.core.client.resources.CoreResources;
+
+import com.google.inject.Inject;
+
+public class SmallAvatarDecoratorImpl extends AvatarDecoratorImpl implements SmallAvatarDecorator {
+
+ @Inject
+ public SmallAvatarDecoratorImpl(final CoreResources res, final ChatInstances chatInstances,
+ final ChatClient chatClient) {
+ super(chatInstances, chatClient, res.chatDotBusySmall(), res.chatDotAwaySmall(),
+ res.chatDotAwaySmall(), res.chatDotExtendedAwaySmall(), res.chatDotAvailableSmall());
+ setImagePosition(23, -9, -8);
+ }
+}
Modified: trunk/src/main/java/cc/kune/chat/client/actions/AddAsBuddieHeaderButton.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/AddAsBuddieHeaderButton.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/actions/AddAsBuddieHeaderButton.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -20,6 +20,7 @@
package cc.kune.chat.client.actions;
import cc.kune.chat.client.ChatClient;
+import cc.kune.chat.client.ChatInstances;
import cc.kune.common.client.actions.AbstractAction;
import cc.kune.common.client.actions.AbstractExtendedAction;
import cc.kune.common.client.actions.Action;
@@ -38,10 +39,8 @@
import cc.kune.core.shared.dto.StateAbstractDTO;
import cc.kune.core.shared.i18n.I18nTranslationService;
-import com.calclab.emite.im.client.roster.XmppRoster;
import com.calclab.emite.im.client.roster.events.RosterGroupChangedEvent;
import com.calclab.emite.im.client.roster.events.RosterGroupChangedHandler;
-import com.calclab.suco.client.Suco;
import com.google.inject.Inject;
public class AddAsBuddieHeaderButton {
@@ -52,7 +51,8 @@
@Inject
public AddAsBuddieAction(final ChatClient chatEngine, final Session session,
- final StateManager stateManager, final I18nTranslationService i18n, final CoreResources img) {
+ final ChatInstances chatInstances, final StateManager stateManager,
+ final I18nTranslationService i18n, final CoreResources img) {
super();
this.chatEngine = chatEngine;
this.session = session;
@@ -62,7 +62,7 @@
setState(event.getState());
}
});
- Suco.get(XmppRoster.class).addRosterGroupChangedHandler(new RosterGroupChangedHandler() {
+ chatInstances.roster.addRosterGroupChangedHandler(new RosterGroupChangedHandler() {
@Override
public void onGroupChanged(final RosterGroupChangedEvent event) {
Modified: trunk/src/main/java/cc/kune/chat/client/actions/ChatSitebarActions.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/ChatSitebarActions.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/actions/ChatSitebarActions.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -20,6 +20,7 @@
package cc.kune.chat.client.actions;
import cc.kune.chat.client.ChatClient;
+import cc.kune.chat.client.ChatInstances;
import cc.kune.chat.client.resources.ChatResources;
import cc.kune.common.client.actions.AbstractAction;
import cc.kune.common.client.actions.AbstractExtendedAction;
@@ -40,144 +41,151 @@
import com.calclab.emite.im.client.presence.PresenceManager;
import com.calclab.emite.im.client.presence.events.OwnPresenceChangedEvent;
import com.calclab.emite.im.client.presence.events.OwnPresenceChangedHandler;
-import com.calclab.suco.client.Suco;
import com.google.gwt.resources.client.ImageResource;
import com.google.inject.Inject;
public class ChatSitebarActions {
- public class ChangeOfflineStatusAction extends AbstractExtendedAction {
- public ChangeOfflineStatusAction(final ImageResource icon) {
- xmppSession.addSessionStateChangedHandler(true, new StateChangedHandler() {
- @Override
- public void onStateChanged(final StateChangedEvent event) {
- if (!xmppSession.isReady()) {
- SiteUserOptionsPresenter.LOGGED_USER_MENU.putValue(AbstractAction.SMALL_ICON, icon);
- }
- }
- });
- }
+ public class ChangeOfflineStatusAction extends AbstractExtendedAction {
+ private final XmppSession session;
+ public ChangeOfflineStatusAction(final XmppSession session, final ImageResource icon) {
+ this.session = session;
+ session.addSessionStateChangedHandler(true, new StateChangedHandler() {
@Override
- public void actionPerformed(final ActionEvent event) {
- // presenceManager.changeOwnPresence(Presence.build(NO_STATUS,
- // Show.xa));
- xmppSession.logout();
+ public void onStateChanged(final StateChangedEvent event) {
+ if (!session.isReady()) {
+ SiteUserOptionsPresenter.LOGGED_USER_MENU.putValue(AbstractAction.SMALL_ICON, icon);
+ }
}
+ });
}
- public class ChangeOnlineStatusAction extends AbstractExtendedAction {
- private final Presence thisPresence;
- public ChangeOnlineStatusAction(final String statusText, final Show show, final ImageResource icon) {
- thisPresence = Presence.build(statusText, show);
- presenceManager.addOwnPresenceChangedHandler(new OwnPresenceChangedHandler() {
+ @Override
+ public void actionPerformed(final ActionEvent event) {
+ // presenceManager.changeOwnPresence(Presence.build(NO_STATUS,
+ // Show.xa));
+ session.logout();
+ }
+ }
+ public class ChangeOnlineStatusAction extends AbstractExtendedAction {
+ private final PresenceManager manager;
+ private final Presence thisPresence;
- @Override
- public void onOwnPresenceChanged(final OwnPresenceChangedEvent event) {
- updateStatusIcon(icon, event.getCurrentPresence());
- }
+ public ChangeOnlineStatusAction(final PresenceManager presenceManager, final String statusText,
+ final Show show, final ImageResource icon) {
+ this.manager = presenceManager;
+ thisPresence = Presence.build(statusText, show);
+ presenceManager.addOwnPresenceChangedHandler(new OwnPresenceChangedHandler() {
- });
- updateStatusIcon(icon, presenceManager.getOwnPresence());
- }
-
@Override
- public void actionPerformed(final ActionEvent event) {
- if (!chatClient.loginIfNecessary()) {
- presenceManager.changeOwnPresence(thisPresence);
- }
- nextPresence = thisPresence;
+ public void onOwnPresenceChanged(final OwnPresenceChangedEvent event) {
+ updateStatusIcon(icon, event.getCurrentPresence());
}
- private void updateStatusIcon(final ImageResource icon, final Presence currentPresence) {
- if (thisPresence.getShow().equals(currentPresence.getShow())
- && ((currentPresence.getStatus() == null) || currentPresence.getStatus().equals(
- thisPresence.getStatus()))) {
- SiteUserOptionsPresenter.LOGGED_USER_MENU.putValue(AbstractAction.SMALL_ICON, icon);
- }
- }
+ });
+ updateStatusIcon(icon, presenceManager.getOwnPresence());
}
- private static final String CHAT_STATUS = "k-chat-status-group";
- private static final String GROUP_CHAT_STATUS = "k-group-chat-status";
- private static final String NO_STATUS = null;
- private final ChatClient chatClient;
- private final I18nTranslationService i18n;
- private Presence nextPresence = Presence.build(NO_STATUS, Show.notSpecified);
- private final PresenceManager presenceManager = Suco.get(PresenceManager.class);
- private final ChatResources res;
- private final Session session;
- private final SiteUserOptions userOptions;
- private final XmppSession xmppSession = Suco.get(XmppSession.class);
+ @Override
+ public void actionPerformed(final ActionEvent event) {
+ if (!chatClient.loginIfNecessary()) {
+ manager.changeOwnPresence(thisPresence);
+ }
+ nextPresence = thisPresence;
+ }
- @Inject
- public ChatSitebarActions(final Session session, final ChatClient chatClient, final SiteUserOptions userOptions,
- final I18nTranslationService i18n, final ChatResources res) {
- this.session = session;
- this.chatClient = chatClient;
- this.userOptions = userOptions;
- this.i18n = i18n;
- this.res = res;
- createActions();
+ private void updateStatusIcon(final ImageResource icon, final Presence currentPresence) {
+ if (thisPresence.getShow().equals(currentPresence.getShow())
+ && ((currentPresence.getStatus() == null) || currentPresence.getStatus().equals(
+ thisPresence.getStatus()))) {
+ SiteUserOptionsPresenter.LOGGED_USER_MENU.putValue(AbstractAction.SMALL_ICON, icon);
+ }
}
+ }
- private void createActions() {
- final MenuTitleItemDescriptor chatActionsTitle = new MenuTitleItemDescriptor(
- SiteUserOptionsPresenter.LOGGED_USER_MENU, i18n.t("Set your chat status"));
- userOptions.addAction(new MenuSeparatorDescriptor(SiteUserOptionsPresenter.LOGGED_USER_MENU));
- userOptions.addAction(chatActionsTitle);
- final MenuRadioItemDescriptor onlineItem = createChatStatusAction(res.online(), i18n.t("Available"),
- onlineAction(NO_STATUS, Show.notSpecified, res.online()));
- final MenuRadioItemDescriptor availableItem = createChatStatusAction(res.xa(), i18n.t("Available for chat"),
- onlineAction(NO_STATUS, Show.chat, res.xa()));
- final MenuRadioItemDescriptor awayItem = createChatStatusAction(res.away(), i18n.t("Away"),
- onlineAction(NO_STATUS, Show.away, res.away()));
- final MenuRadioItemDescriptor busyItem = createChatStatusAction(res.busy(), i18n.t("Busy"),
- onlineAction(NO_STATUS, Show.dnd, res.busy()));
- final MenuRadioItemDescriptor offlineItem = createChatStatusAction(res.offline(), i18n.t("Sign out of chat"),
- new ChangeOfflineStatusAction(res.offline()));
- userOptions.addAction(onlineItem);
- userOptions.addAction(availableItem);
- userOptions.addAction(awayItem);
- userOptions.addAction(busyItem);
- userOptions.addAction(offlineItem);
- xmppSession.addSessionStateChangedHandler(false, new StateChangedHandler() {
+ private static final String CHAT_STATUS = "k-chat-status-group";
+ private static final String GROUP_CHAT_STATUS = "k-group-chat-status";
+ private static final String NO_STATUS = null;
+ private final ChatClient chatClient;
+ private final I18nTranslationService i18n;
+ private Presence nextPresence = Presence.build(NO_STATUS, Show.notSpecified);
+ private final PresenceManager presenceManager;
+ private final ChatResources res;
+ private final SiteUserOptions userOptions;
+ private final XmppSession xmppSession;
- @Override
- public void onStateChanged(final StateChangedEvent event) {
- if (xmppSession.isReady()) {
- presenceManager.changeOwnPresence(nextPresence);
- switch (nextPresence.getShow()) {
- case notSpecified:
- onlineItem.setChecked(true);
- break;
- case dnd:
- busyItem.setChecked(true);
- break;
- case chat:
- availableItem.setChecked(true);
- break;
- case away:
- awayItem.setChecked(true);
- break;
- }
- } else {
- offlineItem.setChecked(true);
- }
- }
- });
- }
+ @Inject
+ public ChatSitebarActions(final Session session, final ChatClient chatClient,
+ final SiteUserOptions userOptions, final I18nTranslationService i18n, final ChatResources res,
+ final ChatInstances chatInstances) {
+ this.chatClient = chatClient;
+ this.userOptions = userOptions;
+ this.i18n = i18n;
+ this.res = res;
+ xmppSession = chatInstances.xmppSession;
+ presenceManager = chatInstances.presenceManager;
+ createActions();
+ }
- private MenuRadioItemDescriptor createChatStatusAction(final ImageResource icon, final String text,
- final AbstractAction action) {
- final MenuRadioItemDescriptor item = new MenuRadioItemDescriptor(SiteUserOptionsPresenter.LOGGED_USER_MENU,
- action, GROUP_CHAT_STATUS);
- item.putValue(AbstractAction.NAME, text);
- item.putValue(AbstractAction.SMALL_ICON, icon);
- return item;
- }
+ private void createActions() {
+ final MenuTitleItemDescriptor chatActionsTitle = new MenuTitleItemDescriptor(
+ SiteUserOptionsPresenter.LOGGED_USER_MENU, i18n.t("Set your chat status"));
+ userOptions.addAction(new MenuSeparatorDescriptor(SiteUserOptionsPresenter.LOGGED_USER_MENU));
+ userOptions.addAction(chatActionsTitle);
+ final MenuRadioItemDescriptor onlineItem = createChatStatusAction(res.online(), i18n.t("Available"),
+ onlineAction(NO_STATUS, Show.notSpecified, res.online()));
+ final MenuRadioItemDescriptor availableItem = createChatStatusAction(res.xa(),
+ i18n.t("Available for chat"), onlineAction(NO_STATUS, Show.chat, res.xa()));
+ final MenuRadioItemDescriptor awayItem = createChatStatusAction(res.away(), i18n.t("Away"),
+ onlineAction(NO_STATUS, Show.away, res.away()));
+ final MenuRadioItemDescriptor busyItem = createChatStatusAction(res.busy(), i18n.t("Busy"),
+ onlineAction(NO_STATUS, Show.dnd, res.busy()));
+ final MenuRadioItemDescriptor offlineItem = createChatStatusAction(res.offline(),
+ i18n.t("Sign out of chat"), new ChangeOfflineStatusAction(xmppSession, res.offline()));
+ userOptions.addAction(onlineItem);
+ userOptions.addAction(availableItem);
+ userOptions.addAction(awayItem);
+ userOptions.addAction(busyItem);
+ userOptions.addAction(offlineItem);
+ xmppSession.addSessionStateChangedHandler(false, new StateChangedHandler() {
- private AbstractExtendedAction onlineAction(final String statusText, final Show show, final ImageResource icon) {
- return new ChangeOnlineStatusAction(statusText, show, icon);
- }
+ @Override
+ public void onStateChanged(final StateChangedEvent event) {
+ if (xmppSession.isReady()) {
+ presenceManager.changeOwnPresence(nextPresence);
+ switch (nextPresence.getShow()) {
+ case notSpecified:
+ onlineItem.setChecked(true);
+ break;
+ case dnd:
+ busyItem.setChecked(true);
+ break;
+ case chat:
+ availableItem.setChecked(true);
+ break;
+ case away:
+ awayItem.setChecked(true);
+ break;
+ }
+ } else {
+ offlineItem.setChecked(true);
+ }
+ }
+ });
+ }
+
+ private MenuRadioItemDescriptor createChatStatusAction(final ImageResource icon, final String text,
+ final AbstractAction action) {
+ final MenuRadioItemDescriptor item = new MenuRadioItemDescriptor(
+ SiteUserOptionsPresenter.LOGGED_USER_MENU, action, GROUP_CHAT_STATUS);
+ item.putValue(AbstractAction.NAME, text);
+ item.putValue(AbstractAction.SMALL_ICON, icon);
+ return item;
+ }
+
+ private AbstractExtendedAction onlineAction(final String statusText, final Show show,
+ final ImageResource icon) {
+ return new ChangeOnlineStatusAction(presenceManager, statusText, show, icon);
+ }
}
Modified: trunk/src/main/java/cc/kune/chat/client/actions/OpenGroupPublicChatRoomAction.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/OpenGroupPublicChatRoomAction.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/actions/OpenGroupPublicChatRoomAction.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -23,6 +23,7 @@
import java.util.List;
import cc.kune.chat.client.ChatClient;
+import cc.kune.chat.client.ChatInstances;
import cc.kune.chat.client.resources.ChatResources;
import cc.kune.common.client.actions.Action;
import cc.kune.common.client.actions.ActionEvent;
@@ -43,7 +44,6 @@
import com.calclab.emite.xep.muc.client.Occupant;
import com.calclab.emite.xep.muc.client.Room;
import com.calclab.emite.xep.muc.client.RoomManager;
-import com.calclab.suco.client.Suco;
import com.google.inject.Inject;
public class OpenGroupPublicChatRoomAction extends RolActionAutoUpdated {
@@ -51,19 +51,19 @@
private final ChatClient chatClient;
private final I18nTranslationService i18n;
private boolean inviteMembers;
- private final RoomManager roomManager;
private final Session session;
@SuppressWarnings("deprecation")
@Inject
public OpenGroupPublicChatRoomAction(final Session session,
final AccessRightsClientManager accessRightsClientManager, final ChatClient chatClient,
- final StateManager stateManager, final I18nTranslationService i18n, final ChatResources res) {
+ final StateManager stateManager, final I18nTranslationService i18n, final ChatResources res,
+ final ChatInstances chatInstances) {
super(stateManager, session, accessRightsClientManager, AccessRolDTO.Editor, true, false, true);
this.session = session;
this.chatClient = chatClient;
this.i18n = i18n;
- roomManager = Suco.get(RoomManager.class);
+ final RoomManager roomManager = chatInstances.roomManager;
stateManager.onStateChanged(true, new StateChangedHandler() {
@Override
public void onStateChanged(final StateChangedEvent event) {
Modified: trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithMemberAction.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithMemberAction.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithMemberAction.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -26,33 +26,40 @@
import cc.kune.common.client.notify.NotifyUser;
import cc.kune.core.client.resources.CoreResources;
import cc.kune.core.shared.dto.GroupDTO;
+import cc.kune.core.shared.dto.UserSimpleDTO;
import cc.kune.core.shared.i18n.I18nTranslationService;
-import com.calclab.emite.core.client.xmpp.stanzas.XmppURI;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class StartChatWithMemberAction extends AbstractExtendedAction {
- private final Provider<ChatClient> chatClient;
- private final I18nTranslationService i18n;
+ private final Provider<ChatClient> chatClient;
+ private final I18nTranslationService i18n;
- @Inject
- public StartChatWithMemberAction(final I18nTranslationService i18n, final CoreResources res,
- final Provider<ChatClient> chatClient) {
- this.i18n = i18n;
- this.chatClient = chatClient;
- putValue(NAME, i18n.t("Chat with this member"));
- putValue(Action.SMALL_ICON, res.newChat());
- }
+ @Inject
+ public StartChatWithMemberAction(final I18nTranslationService i18n, final CoreResources res,
+ final Provider<ChatClient> chatClient) {
+ this.i18n = i18n;
+ this.chatClient = chatClient;
+ putValue(NAME, i18n.t("Chat with this member"));
+ putValue(Action.SMALL_ICON, res.newChat());
+ }
- @Override
- public void actionPerformed(final ActionEvent event) {
- chatClient.get().show();
- if (chatClient.get().isLoggedIn()) {
- chatClient.get().chat(XmppURI.jid(((GroupDTO) event.getTarget()).getShortName()));
- } else {
- NotifyUser.important(i18n.t("To start a chat you need to be 'online'"));
- }
+ @Override
+ public void actionPerformed(final ActionEvent event) {
+ chatClient.get().show();
+ if (chatClient.get().isLoggedIn()) {
+ String username = null;
+ if (event.getTarget() instanceof GroupDTO) {
+ username = ((GroupDTO) event.getTarget()).getShortName();
+ } else if (event.getTarget() instanceof UserSimpleDTO) {
+ username = ((UserSimpleDTO) event.getTarget()).getShortName();
+ }
+ if (username != null) {
+ chatClient.get().chat(username);
+ }
+ } else {
+ NotifyUser.important(i18n.t("To start a chat you need to be 'online'"));
}
-
+ }
}
Added: trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithThisPersonAction.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithThisPersonAction.java (rev 0)
+++ trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithThisPersonAction.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright (C) 2007-2011 The kune development team (see CREDITS for details)
+ * This file is part of kune.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package cc.kune.chat.client.actions;
+
+import cc.kune.chat.client.ChatClient;
+import cc.kune.core.client.resources.CoreResources;
+import cc.kune.core.shared.i18n.I18nTranslationService;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+public class StartChatWithThisPersonAction extends StartChatWithMemberAction {
+ @Inject
+ public StartChatWithThisPersonAction(final I18nTranslationService i18n, final CoreResources res,
+ final Provider<ChatClient> chatClient) {
+ super(i18n, res, chatClient);
+ putValue(NAME, i18n.t("Chat with this person"));
+ }
+}
Deleted: trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithUserAction.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithUserAction.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/chat/client/actions/StartChatWithUserAction.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -1,36 +0,0 @@
-/*
- *
- * Copyright (C) 2007-2011 The kune development team (see CREDITS for details)
- * This file is part of kune.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-package cc.kune.chat.client.actions;
-
-import cc.kune.chat.client.ChatClient;
-import cc.kune.core.client.resources.CoreResources;
-import cc.kune.core.shared.i18n.I18nTranslationService;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-
-public class StartChatWithUserAction extends StartChatWithMemberAction {
- @Inject
- public StartChatWithUserAction(final I18nTranslationService i18n, final CoreResources res,
- final Provider<ChatClient> chatClient) {
- super(i18n, res, chatClient);
- putValue(NAME, i18n.t("Chat with this person"));
- }
-}
Added: trunk/src/main/java/cc/kune/chat/client/actions/conditions/IsBuddieCondition.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/conditions/IsBuddieCondition.java (rev 0)
+++ trunk/src/main/java/cc/kune/chat/client/actions/conditions/IsBuddieCondition.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright (C) 2007-2011 The kune development team (see CREDITS for details)
+ * This file is part of kune.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package cc.kune.chat.client.actions.conditions;
+
+import cc.kune.chat.client.ChatClient;
+import cc.kune.common.client.actions.ui.descrip.GuiActionDescrip;
+import cc.kune.common.client.actions.ui.descrip.GuiAddCondition;
+import cc.kune.common.client.errors.UIException;
+import cc.kune.core.client.state.Session;
+import cc.kune.core.shared.dto.GroupDTO;
+import cc.kune.core.shared.dto.UserSimpleDTO;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+public class IsBuddieCondition implements GuiAddCondition {
+
+ private final ChatClient chatClient;
+ private final Session session;
+
+ @Inject
+ public IsBuddieCondition(final Session session, final ChatClient chatClient) {
+ this.chatClient = chatClient;
+ this.session = session;
+ }
+
+ private boolean isBuddie(final String targetName) {
+ return chatClient.isBuddie(targetName);
+ }
+
+ private boolean isThisGroupInRoster(final GuiActionDescrip descr) {
+ final String targetName = ((GroupDTO) descr.getTarget()).getShortName();
+ return isBuddie(targetName);
+ }
+
+ private boolean isThisPersonInRoster(final GuiActionDescrip descr) {
+ final String targetName = ((UserSimpleDTO) descr.getTarget()).getShortName();
+ return isBuddie(targetName);
+ }
+
+ @Override
+ public boolean mustBeAdded(final GuiActionDescrip descr) {
+ if (session.isNotLogged()) {
+ return false;
+ }
+ if (descr.getTarget() instanceof UserSimpleDTO) {
+ return isThisPersonInRoster(descr);
+ } else if (descr.getTarget() instanceof GroupDTO) {
+ return isThisGroupInRoster(descr);
+ } else {
+ throw new UIException("Unsupported target");
+ }
+ }
+}
Added: trunk/src/main/java/cc/kune/chat/client/actions/conditions/IsNotBuddieCondition.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/conditions/IsNotBuddieCondition.java (rev 0)
+++ trunk/src/main/java/cc/kune/chat/client/actions/conditions/IsNotBuddieCondition.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,23 @@
+package cc.kune.chat.client.actions.conditions;
+
+import cc.kune.chat.client.ChatClient;
+import cc.kune.common.client.actions.ui.descrip.GuiActionDescrip;
+import cc.kune.core.client.state.Session;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+@Singleton
+public class IsNotBuddieCondition extends IsBuddieCondition {
+
+ @Inject
+ public IsNotBuddieCondition(final Session session, final ChatClient chatClient) {
+ super(session, chatClient);
+ }
+
+ @Override
+ public boolean mustBeAdded(final GuiActionDescrip descr) {
+ return !super.mustBeAdded(descr);
+ }
+
+}
Added: trunk/src/main/java/cc/kune/common/client/ui/AbstractDecorator.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/ui/AbstractDecorator.java (rev 0)
+++ trunk/src/main/java/cc/kune/common/client/ui/AbstractDecorator.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,79 @@
+package cc.kune.common.client.ui;
+
+import cc.kune.common.client.tooltip.Tooltip;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Style.Float;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Image;
+import com.google.gwt.user.client.ui.IsWidget;
+import com.google.gwt.user.client.ui.SimplePanel;
+import com.google.gwt.user.client.ui.Widget;
+
+public class AbstractDecorator extends Composite {
+
+ interface Binder extends UiBinder<Widget, AbstractDecorator> {
+ }
+ private static final Binder BINDER = GWT.create(Binder.class);
+ @UiField
+ Image decorationImage;
+ private int left = 0;
+
+ @UiField
+ FlowPanel mainPanel;
+ private int offset = 0;
+ private int top = 0;
+ @UiField
+ SimplePanel widgetContainer;
+
+ public AbstractDecorator() {
+ initWidget(BINDER.createAndBindUi(this));
+ }
+
+ public void clearImage() {
+ decorationImage.setVisible(false);
+ }
+
+ public void setDecoratorVisible(final boolean visible) {
+ decorationImage.setVisible(visible);
+ }
+
+ public void setImage(final ImageResource img) {
+ decorationImage.setResource(img);
+ decorationImage.setVisible(true);
+ setPosition();
+ }
+
+ public void setImagePosition(final int top, final int left, final int offset) {
+ this.top = top;
+ this.left = left;
+ this.offset = offset;
+ setPosition();
+ }
+
+ public void setImageTooltip(final String text) {
+ Tooltip.to(decorationImage, text);
+ }
+
+ private void setPosition() {
+ final Element elem = decorationImage.getElement();
+ elem.getStyle().setPropertyPx("left", left);
+ elem.getStyle().setPropertyPx("top", top);
+ elem.getStyle().setPosition(Position.RELATIVE);
+ elem.getStyle().setFloat(Float.LEFT);
+ elem.getStyle().setMarginRight(offset, Unit.PX);
+ }
+
+ public void setWidget(final IsWidget widget) {
+ widgetContainer.clear();
+ widgetContainer.add(widget);
+ }
+
+}
Added: trunk/src/main/java/cc/kune/common/client/ui/AbstractDecorator.ui.xml
===================================================================
--- trunk/src/main/java/cc/kune/common/client/ui/AbstractDecorator.ui.xml (rev 0)
+++ trunk/src/main/java/cc/kune/common/client/ui/AbstractDecorator.ui.xml 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
+<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
+ xmlns:g='urn:import:com.google.gwt.user.client.ui'>
+ <ui:style>
+ .image {
+ position: relative;
+ top: 0px;
+ left: 0px;
+ float: left;
+ }
+
+ .container {
+ float: left;
+ }
+ </ui:style>
+
+ <g:FlowPanel ui:field="mainPanel">
+ <g:SimplePanel ui:field="widgetContainer" styleName="{style.container}" />
+ <g:Image ui:field="decorationImage"
+ styleName="{style.image}" />
+ </g:FlowPanel>
+</ui:UiBinder>
Modified: trunk/src/main/java/cc/kune/core/client/CoreGinModule.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/CoreGinModule.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/CoreGinModule.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -217,7 +217,7 @@
s(ErrorsDialog.class);
s(XMLActionsParser.class);
- bind(Services.class).to(GWTServices.class);
+ s(Services.class, GWTServices.class);
}
}
Added: trunk/src/main/java/cc/kune/core/client/avatar/AvatarDecorator.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/avatar/AvatarDecorator.java (rev 0)
+++ trunk/src/main/java/cc/kune/core/client/avatar/AvatarDecorator.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,13 @@
+package cc.kune.core.client.avatar;
+
+import com.google.gwt.user.client.ui.IsWidget;
+
+public interface AvatarDecorator {
+
+ void setDecoratorVisible(boolean visible);
+
+ void setItem(String name);
+
+ void setWidget(IsWidget widget);
+
+}
Added: trunk/src/main/java/cc/kune/core/client/avatar/MediumAvatarDecorator.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/avatar/MediumAvatarDecorator.java (rev 0)
+++ trunk/src/main/java/cc/kune/core/client/avatar/MediumAvatarDecorator.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,5 @@
+package cc.kune.core.client.avatar;
+
+public interface MediumAvatarDecorator extends AvatarDecorator {
+
+}
Added: trunk/src/main/java/cc/kune/core/client/avatar/SmallAvatarDecorator.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/avatar/SmallAvatarDecorator.java (rev 0)
+++ trunk/src/main/java/cc/kune/core/client/avatar/SmallAvatarDecorator.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -0,0 +1,5 @@
+package cc.kune.core.client.avatar;
+
+public interface SmallAvatarDecorator extends AvatarDecorator {
+
+}
Modified: trunk/src/main/java/cc/kune/core/client/resources/CoreResources.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/resources/CoreResources.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/resources/CoreResources.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -271,6 +271,42 @@
@Source("charfontname.png")
ImageResource charfontname();
+ @Source("chat-dot-available-medium.png")
+ ImageResource chatDotAvailableMedium();
+
+ @Source("chat-dot-available-small.png")
+ ImageResource chatDotAvailableSmall();
+
+ @Source("chat-dot-away-medium.png")
+ ImageResource chatDotAwayMedium();
+
+ @Source("chat-dot-away-small.png")
+ ImageResource chatDotAwaySmall();
+
+ @Source("chat-dot-busy-medium.png")
+ ImageResource chatDotBusyMedium();
+
+ @Source("chat-dot-busy-small.png")
+ ImageResource chatDotBusySmall();
+
+ @Source("chat-dot-extended-away-medium.png")
+ ImageResource chatDotExtendedAwayMedium();
+
+ @Source("chat-dot-extended-away-small.png")
+ ImageResource chatDotExtendedAwaySmall();
+
+ @Source("chat-dot-invisible-medium.png")
+ ImageResource chatDotInvisibleMedium();
+
+ @Source("chat-dot-invisible-small.png")
+ ImageResource chatDotInvisibleSmall();
+
+ @Source("chat-dot-offline-medium.png")
+ ImageResource chatDotOfflineMedium();
+
+ @Source("chat-dot-offline-small.png")
+ ImageResource chatDotOfflineSmall();
+
@Source("checked.png")
ImageResource checked();
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-available-medium.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-available-medium.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-available-small.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-available-small.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-away-medium.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-away-medium.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-away-small.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-away-small.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-busy-medium.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-busy-medium.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-busy-small.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-busy-small.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-extended-away-medium.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-extended-away-medium.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-extended-away-small.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-extended-away-small.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-invisible-medium.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-invisible-medium.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-invisible-small.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-invisible-small.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-offline-medium.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-offline-medium.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-offline-small.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/java/cc/kune/core/client/resources/chat-dot-offline-small.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -142,7 +142,7 @@
@Override
public void onWindowFocus(final WindowFocusEvent event) {
if (event.isHasFocus() && !mask.isShowing()) {
- showTooltipWithDelay();
+ // showTooltipWithDelay();
}
}
});
Modified: trunk/src/main/java/cc/kune/core/client/sn/AbstractSNPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sn/AbstractSNPanel.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/sn/AbstractSNPanel.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -29,6 +29,7 @@
import cc.kune.common.client.actions.ui.descrip.MenuDescriptor;
import cc.kune.common.client.tooltip.Tooltip;
import cc.kune.common.client.ui.BasicThumb;
+import cc.kune.core.client.avatar.SmallAvatarDecorator;
import cc.kune.core.shared.i18n.I18nTranslationService;
import cc.kune.gspace.client.GSpaceArmor;
@@ -43,6 +44,7 @@
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
+import com.google.inject.Provider;
import com.gwtplatform.mvp.client.ViewImpl;
public class AbstractSNPanel extends ViewImpl {
@@ -52,11 +54,11 @@
private final static int AVATARLABELMAXSIZE = 4;
private final static int AVATARSIZE = 22;
- private final static String CATEG_HEIGHT = "80px";
+ private final static String CATEG_HEIGHT = "84px";
private static AbstractSNPanelUiBinder uiBinder = GWT.create(AbstractSNPanelUiBinder.class);
-
protected final ActionSimplePanel actions;
protected final GSpaceArmor armor;
+ protected final Provider<SmallAvatarDecorator> avatarDecoratorProv;
ActionFlowPanel bottomActionsToolbar;
@UiField
FlowPanel bottomPanel;
@@ -103,8 +105,9 @@
protected final Widget widget;
public AbstractSNPanel(final I18nTranslationService i18n, final GuiProvider guiProvider,
- final GSpaceArmor armor) {
+ final GSpaceArmor armor, final Provider<SmallAvatarDecorator> avatarDecorator) {
this.armor = armor;
+ this.avatarDecoratorProv = avatarDecorator;
widget = uiBinder.createAndBindUi(this);
actions = new ActionSimplePanel(guiProvider);
}
@@ -144,6 +147,13 @@
return thumb;
}
+ public SmallAvatarDecorator decorateAvatarWithXmppStatus(final String shortname, final BasicThumb thumb) {
+ final SmallAvatarDecorator decorator = avatarDecoratorProv.get();
+ decorator.setWidget(thumb);
+ decorator.setItem(shortname);
+ return decorator;
+ }
+
public IsActionExtensible getBottomToolbar() {
return bottomActionsToolbar;
}
Modified: trunk/src/main/java/cc/kune/core/client/sn/AbstractSNPanel.ui.xml
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sn/AbstractSNPanel.ui.xml 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/sn/AbstractSNPanel.ui.xml 2011-07-10 18:29:52 UTC (rev 1446)
@@ -14,8 +14,9 @@
<g:Label ui:field="firstDeckLabel" addStyleNames="k-sn-novisible-label" />
<g:Label ui:field="sndDeckLabel" addStyleNames="k-sn-orphan-label" />
<g:FlowPanel width="100%" ui:field="categoriesFlow">
+ <!-- Seed AbstractSNPanel.CATEG_HEIGHT-->
<g:DockLayoutPanel unit="EM" width="100%" ui:field="firstCategoryPanel"
- addStyleNames="k-sn-1st-panel" height="80px">
+ addStyleNames="k-sn-1st-panel" height="84px">
<g:north size="1.2">
<g:FlowPanel>
<g:Label text="Admins" ui:field="firstCategoryLabel"
@@ -32,7 +33,7 @@
</g:DockLayoutPanel>
<g:DockLayoutPanel unit="EM" width="100%"
ui:field="sndCategoryPanel" addStyleNames="k-sn-2nd-panel"
- height="80px">
+ height="84px">
<g:north size="1.2">
<g:FlowPanel>
<g:Label text="Collabs" ui:field="sndCategoryLabel"
@@ -50,7 +51,7 @@
</g:DockLayoutPanel>
<g:DockLayoutPanel unit="EM" width="100%"
ui:field="trdCategoryPanel" addStyleNames="k-sn-3rd-panel"
- height="80px">
+ height="84px">
<g:north size="1.2">
<g:FlowPanel>
<g:Label text="Pendings" ui:field="trdCategoryLabel"
Modified: trunk/src/main/java/cc/kune/core/client/sn/GroupSNPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sn/GroupSNPanel.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/sn/GroupSNPanel.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -24,19 +24,22 @@
import cc.kune.common.client.actions.ui.descrip.GuiActionDescCollection;
import cc.kune.common.client.tooltip.Tooltip;
import cc.kune.common.client.ui.BasicThumb;
+import cc.kune.core.client.avatar.SmallAvatarDecorator;
import cc.kune.core.client.sn.GroupSNPresenter.GroupSNView;
import cc.kune.core.shared.dto.GroupDTO;
import cc.kune.core.shared.i18n.I18nTranslationService;
import cc.kune.gspace.client.GSpaceArmor;
+import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
+import com.google.inject.Provider;
public class GroupSNPanel extends AbstractSNPanel implements GroupSNView {
@Inject
public GroupSNPanel(final I18nTranslationService i18n, final GuiProvider guiProvider,
- final GSpaceArmor armor) {
- super(i18n, guiProvider, armor);
+ final GSpaceArmor armor, final Provider<SmallAvatarDecorator> avatarDecorator) {
+ super(i18n, guiProvider, armor, avatarDecorator);
setVisibleImpl(false);
mainTitle.setText(i18n.t("Group members"));
Tooltip.to(mainTitle, i18n.t("People and groups collaborating in this group"));
@@ -59,14 +62,16 @@
public void addAdmin(final GroupDTO group, final String avatarUrl, final String tooltip,
final String tooltipTitle, final GuiActionDescCollection menu) {
final BasicThumb thumb = createThumb(group.getShortName(), avatarUrl, tooltip, tooltipTitle, menu);
- firstCategoryFlow.add(thumb);
+ firstCategoryFlow.add(group.isPersonal() ? (Widget) decorateAvatarWithXmppStatus(
+ group.getShortName(), thumb) : thumb);
}
@Override
public void addCollab(final GroupDTO group, final String avatarUrl, final String tooltip,
final String tooltipTitle, final GuiActionDescCollection menu) {
final BasicThumb thumb = createThumb(group.getShortName(), avatarUrl, tooltip, tooltipTitle, menu);
- sndCategoryFlow.add(thumb);
+ sndCategoryFlow.add(group.isPersonal() ? (Widget) decorateAvatarWithXmppStatus(group.getShortName(),
+ thumb) : thumb);
}
@Override
Modified: trunk/src/main/java/cc/kune/core/client/sn/UserSNPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sn/UserSNPanel.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/sn/UserSNPanel.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -22,6 +22,8 @@
import cc.kune.common.client.actions.ui.ActionFlowPanel;
import cc.kune.common.client.actions.ui.bind.GuiProvider;
import cc.kune.common.client.actions.ui.descrip.GuiActionDescCollection;
+import cc.kune.common.client.ui.BasicThumb;
+import cc.kune.core.client.avatar.SmallAvatarDecorator;
import cc.kune.core.client.resources.CoreMessages;
import cc.kune.core.client.sn.UserSNPresenter.UserSNView;
import cc.kune.core.shared.dto.GroupDTO;
@@ -30,7 +32,9 @@
import cc.kune.gspace.client.GSpaceArmor;
import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
+import com.google.inject.Provider;
public class UserSNPanel extends AbstractSNPanel implements UserSNView {
@@ -38,9 +42,10 @@
@Inject
public UserSNPanel(final I18nTranslationService i18n, final GuiProvider guiProvider,
- final GSpaceArmor armor) {
- super(i18n, guiProvider, armor);
+ final GSpaceArmor armor, final Provider<SmallAvatarDecorator> avatarDecorator) {
+ super(i18n, guiProvider, armor, avatarDecorator);
this.i18n = i18n;
+
setVisibleImpl(false);
mainTitle.setText(i18n.t("His/her network:"));
mainTitle.setTitle(i18n.t("This user buddies and groups where participes"));
@@ -62,7 +67,8 @@
@Override
public void addBuddie(final UserSimpleDTO user, final String avatarUrl, final String tooltip,
final String tooltipTitle, final GuiActionDescCollection menu) {
- firstCategoryFlow.add(createThumb(user.getShortName(), avatarUrl, tooltip, tooltipTitle, menu));
+ final BasicThumb thumb = createThumb(user.getShortName(), avatarUrl, tooltip, tooltipTitle, menu);
+ firstCategoryFlow.add((Widget) decorateAvatarWithXmppStatus(user.getShortName(), thumb));
}
@Override
Modified: trunk/src/main/java/cc/kune/core/client/sn/actions/conditions/IsMeCondition.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sn/actions/conditions/IsMeCondition.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/sn/actions/conditions/IsMeCondition.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -28,13 +28,16 @@
@Singleton
public class IsMeCondition extends IsNotMeCondition {
- @Inject
- public IsMeCondition(final Session session) {
- super(session);
- }
+ @Inject
+ public IsMeCondition(final Session session) {
+ super(session);
+ }
- @Override
- public boolean mustBeAdded(final GuiActionDescrip descr) {
- return !super.mustBeAdded(descr);
+ @Override
+ public boolean mustBeAdded(final GuiActionDescrip descr) {
+ if (session.isNotLogged()) {
+ return false;
}
+ return !super.mustBeAdded(descr);
+ }
}
Modified: trunk/src/main/java/cc/kune/core/client/sn/actions/conditions/IsNotMeCondition.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sn/actions/conditions/IsNotMeCondition.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/sn/actions/conditions/IsNotMeCondition.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -32,40 +32,40 @@
@Singleton
public class IsNotMeCondition implements GuiAddCondition {
- private final Session session;
+ protected final Session session;
- @Inject
- public IsNotMeCondition(final Session session) {
- this.session = session;
- }
+ @Inject
+ public IsNotMeCondition(final Session session) {
+ this.session = session;
+ }
- private String currentName() {
- return session.getCurrentUser().getShortName();
- }
+ private String currentName() {
+ return session.getCurrentUser().getShortName();
+ }
- private boolean isNotThisGroup(final GuiActionDescrip descr) {
- final String targetName = ((GroupDTO) descr.getTarget()).getShortName();
- final String currentName = currentName();
- return !currentName.equals(targetName);
- }
+ private boolean isNotThisGroup(final GuiActionDescrip descr) {
+ final String targetName = ((GroupDTO) descr.getTarget()).getShortName();
+ final String currentName = currentName();
+ return !currentName.equals(targetName);
+ }
- private boolean isNotThisPerson(final GuiActionDescrip descr) {
- final String targetName = ((UserSimpleDTO) descr.getTarget()).getShortName();
- final String currentName = currentName();
- return !currentName.equals(targetName);
- }
+ private boolean isNotThisPerson(final GuiActionDescrip descr) {
+ final String targetName = ((UserSimpleDTO) descr.getTarget()).getShortName();
+ final String currentName = currentName();
+ return !currentName.equals(targetName);
+ }
- @Override
- public boolean mustBeAdded(final GuiActionDescrip descr) {
- if (session.isNotLogged()) {
- return true;
- }
- if (descr.getTarget() instanceof UserSimpleDTO) {
- return isNotThisPerson(descr);
- } else if (descr.getTarget() instanceof GroupDTO) {
- return isNotThisGroup(descr);
- } else {
- throw new UIException("Unsupported target");
- }
+ @Override
+ public boolean mustBeAdded(final GuiActionDescrip descr) {
+ if (session.isNotLogged()) {
+ return true;
}
+ if (descr.getTarget() instanceof UserSimpleDTO) {
+ return isNotThisPerson(descr);
+ } else if (descr.getTarget() instanceof GroupDTO) {
+ return isNotThisGroup(descr);
+ } else {
+ throw new UIException("Unsupported target");
+ }
+ }
}
Modified: trunk/src/main/java/cc/kune/core/client/sn/actions/registry/UserSNMenuItemsRegistry.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sn/actions/registry/UserSNMenuItemsRegistry.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/sn/actions/registry/UserSNMenuItemsRegistry.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -43,43 +43,52 @@
@SuppressWarnings("serial")
public class UserSNMenuItemsRegistry extends AbstractSNMembersActionsRegistry {
- @Inject
- public UserSNMenuItemsRegistry(final Session session,
- final IsCurrentStateAdministrableCondition isAdministrableCondition,
- final IsPersonCondition isPersonCondition, final IsGroupCondition isGroupCondition,
- final IsLoggedCondition isLoggedCondition, final IsMeCondition isMe, final IsNotMeCondition isNotMe,
- final ChangeToCollabAction changeToCollabAction, final ChangeToAdminAction changeToAdminAction,
- final RemoveMemberAction removeMemberAction, final AcceptJoinGroupAction acceptJoinGroupAction,
- final DenyJoinGroupAction denyJoinGroupAction, final GotoGroupAction gotoGroupAction,
- final GotoPersonAction gotoPersonAction, final UnJoinGroupAction unjoinAction,
- final GotoYourHomePageAction gotoYourHomePageAction) {
- add(new Provider<MenuItemDescriptor>() {
- @Override
- public MenuItemDescriptor get() {
- final MenuItemDescriptor item = new MenuItemDescriptor(gotoPersonAction);
- item.add(isPersonCondition);
- item.add(isNotMe);
- return item;
- }
- });
- add(new Provider<MenuItemDescriptor>() {
- @Override
- public MenuItemDescriptor get() {
- final MenuItemDescriptor item = new MenuItemDescriptor(gotoGroupAction);
- item.add(isGroupCondition);
- return item;
- }
- });
- // This doesn't works, because its unregister from current state not
- // from target group
- // add(new Provider<MenuItemDescriptor>() {
- // @Override
- // public MenuItemDescriptor get() {
- // final MenuItemDescriptor item = new MenuItemDescriptor(unjoinAction);
- // item.add(isLoggedCondition);
- // item.add(isGroupCondition);
- // return item;
- // }
- // });
- }
+ @Inject
+ public UserSNMenuItemsRegistry(final Session session,
+ final IsCurrentStateAdministrableCondition isAdministrableCondition,
+ final IsPersonCondition isPersonCondition, final IsGroupCondition isGroupCondition,
+ final IsLoggedCondition isLoggedCondition, final IsMeCondition isMe,
+ final IsNotMeCondition isNotMe, final ChangeToCollabAction changeToCollabAction,
+ final ChangeToAdminAction changeToAdminAction, final RemoveMemberAction removeMemberAction,
+ final AcceptJoinGroupAction acceptJoinGroupAction, final DenyJoinGroupAction denyJoinGroupAction,
+ final GotoGroupAction gotoGroupAction, final GotoPersonAction gotoPersonAction,
+ final UnJoinGroupAction unjoinAction, final GotoYourHomePageAction gotoYourHomePageAction) {
+ add(new Provider<MenuItemDescriptor>() {
+ @Override
+ public MenuItemDescriptor get() {
+ final MenuItemDescriptor item = new MenuItemDescriptor(gotoPersonAction);
+ item.add(isPersonCondition);
+ item.add(isNotMe);
+ return item;
+ }
+ });
+ add(new Provider<MenuItemDescriptor>() {
+ @Override
+ public MenuItemDescriptor get() {
+ final MenuItemDescriptor item = new MenuItemDescriptor(gotoGroupAction);
+ item.add(isGroupCondition);
+ return item;
+ }
+ });
+ add(new Provider<MenuItemDescriptor>() {
+ @Override
+ public MenuItemDescriptor get() {
+ final MenuItemDescriptor item = new MenuItemDescriptor(gotoYourHomePageAction);
+ item.add(isPersonCondition);
+ item.add(isMe);
+ return item;
+ }
+ });
+ // This doesn't works, because its unregister from current state not
+ // from target group
+ // add(new Provider<MenuItemDescriptor>() {
+ // @Override
+ // public MenuItemDescriptor get() {
+ // final MenuItemDescriptor item = new MenuItemDescriptor(unjoinAction);
+ // item.add(isLoggedCondition);
+ // item.add(isGroupCondition);
+ // return item;
+ // }
+ // });
+ }
}
Modified: trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPanel.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPanel.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -44,109 +44,116 @@
public class EntityHeaderPanel extends ViewImpl implements EntityHeaderView {
- private final Provider<FileDownloadUtils> downloadProvider;
- private final EntityTextLogo entityTextLogo;
- private final CoreResources images;
- private final HorizontalPanel mainPanel;
- private final ActionFlowPanel toolbar;
- private final VerticalPanel vpanel;
+ private final Provider<FileDownloadUtils> downloadProvider;
+ private final EntityTextLogo entityTextLogo;
+ private final CoreResources images;
+ private final HorizontalPanel mainPanel;
+ private final ActionFlowPanel toolbar;
+ private final VerticalPanel vpanel;
- @Inject
- public EntityHeaderPanel(final Provider<FileDownloadUtils> downloadProvider, final CoreResources images,
- final GuiProvider bindings, final GSpaceArmor armor) {
- mainPanel = new HorizontalPanel();
- mainPanel.setWidth("100%");
- this.downloadProvider = downloadProvider;
- this.images = images;
- vpanel = new VerticalPanel();
- vpanel.setWidth("100%");
- vpanel.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
- entityTextLogo = new EntityTextLogo();
- mainPanel.add(entityTextLogo);
- toolbar = new ActionFlowPanel(bindings);
- vpanel.add(toolbar);
- mainPanel.add(vpanel);
- armor.getEntityHeader().add(mainPanel);
- }
+ @Inject
+ public EntityHeaderPanel(final Provider<FileDownloadUtils> downloadProvider,
+ final CoreResources images, final GuiProvider bindings, final GSpaceArmor armor,
+ final EntityTextLogo entityTextLogo) {
+ this.entityTextLogo = entityTextLogo;
+ mainPanel = new HorizontalPanel();
+ mainPanel.setWidth("100%");
+ this.downloadProvider = downloadProvider;
+ this.images = images;
+ vpanel = new VerticalPanel();
+ vpanel.setWidth("100%");
+ vpanel.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
+ mainPanel.add(entityTextLogo);
+ toolbar = new ActionFlowPanel(bindings);
+ vpanel.add(toolbar);
+ mainPanel.add(vpanel);
+ armor.getEntityHeader().add(mainPanel);
+ }
- @Override
- public void addAction(final GuiActionDescrip descriptor) {
- toolbar.add(descriptor);
- }
+ @Override
+ public void addAction(final GuiActionDescrip descriptor) {
+ toolbar.add(descriptor);
+ }
- @Override
- public void addWidget(final IsWidget view) {
- final Widget widget = (Widget) view;
- vpanel.add(widget);
- }
+ @Override
+ public void addWidget(final IsWidget view) {
+ final Widget widget = (Widget) view;
+ vpanel.add(widget);
+ }
- @Override
- public Widget asWidget() {
- return mainPanel;
- }
+ @Override
+ public Widget asWidget() {
+ return mainPanel;
+ }
- @Override
- public void reloadImage(final GroupDTO group) {
- entityTextLogo.setLogoImage(downloadProvider.get().getLogoImageUrl(group.getStateToken()) + "&nocache="
- + new Date().getTime());
- }
+ private String getAvatarDecoratorParam(final GroupDTO group) {
+ return group.isPersonal() ? group.getShortName() : null;
+ }
- @Deprecated
- public void setFullLogo(final StateToken stateToken, final boolean clipped) {
- mainPanel.clear();
- final String imageUrl = downloadProvider.get().getImageUrl(stateToken);
- Image logo;
- if (clipped) {
- logo = new Image(imageUrl, 0, 0, FileConstants.LOGO_DEF_WIDTH, FileConstants.LOGO_DEF_HEIGHT);
- } else {
- logo = new Image(imageUrl);
- logo.setWidth(String.valueOf(FileConstants.LOGO_DEF_WIDTH));
- logo.setHeight(String.valueOf(FileConstants.LOGO_DEF_HEIGHT));
- }
- mainPanel.add(logo);
- }
+ @Override
+ public void reloadImage(final GroupDTO group) {
+ entityTextLogo.setLogoImage(downloadProvider.get().getLogoImageUrl(group.getStateToken())
+ + "&nocache=" + new Date().getTime(), getAvatarDecoratorParam(group));
+ }
- @Override
- public void setLargeFont() {
- entityTextLogo.setLargeFont();
+ @Deprecated
+ public void setFullLogo(final StateToken stateToken, final boolean clipped) {
+ mainPanel.clear();
+ final String imageUrl = downloadProvider.get().getImageUrl(stateToken);
+ Image logo;
+ if (clipped) {
+ logo = new Image(imageUrl, 0, 0, FileConstants.LOGO_DEF_WIDTH, FileConstants.LOGO_DEF_HEIGHT);
+ } else {
+ logo = new Image(imageUrl);
+ logo.setWidth(String.valueOf(FileConstants.LOGO_DEF_WIDTH));
+ logo.setHeight(String.valueOf(FileConstants.LOGO_DEF_HEIGHT));
}
+ mainPanel.add(logo);
+ }
- @Override
- public void setLogoImage(final StateToken stateToken) {
- entityTextLogo.setLogoImage(downloadProvider.get().getLogoImageUrl(stateToken));
- }
+ @Override
+ public void setLargeFont() {
+ entityTextLogo.setLargeFont();
+ }
- @Override
- public void setLogoImageVisible(final boolean visible) {
- entityTextLogo.setLogoVisible(visible);
- }
+ @Override
+ public void setLogoImage(final GroupDTO group) {
+ entityTextLogo.setLogoImage(downloadProvider.get().getLogoImageUrl(group.getStateToken()),
+ getAvatarDecoratorParam(group));
+ }
- @Override
- public void setLogoText(final String groupName) {
- entityTextLogo.setLogoText(groupName);
- }
+ @Override
+ public void setLogoImageVisible(final boolean visible) {
+ entityTextLogo.setLogoVisible(visible);
+ }
- @Override
- public void setMediumFont() {
- entityTextLogo.setMediumFont();
- }
+ @Override
+ public void setLogoText(final String groupName) {
+ entityTextLogo.setLogoText(groupName);
+ }
- //
- // @Override
- // public void setTheme(final WsTheme oldTheme, final WsTheme newTheme) {
- // if (oldTheme != null) {
- // entityTextLogo.removeStyleDependentName(oldTheme.toString());
- // }
- // entityTextLogo.addStyleDependentName(newTheme.toString());
- // }
+ @Override
+ public void setMediumFont() {
+ entityTextLogo.setMediumFont();
+ }
- @Override
- public void setSmallFont() {
- entityTextLogo.setSmallFont();
- }
+ //
+ // @Override
+ // public void setTheme(final WsTheme oldTheme, final WsTheme newTheme) {
+ // if (oldTheme != null) {
+ // entityTextLogo.removeStyleDependentName(oldTheme.toString());
+ // }
+ // entityTextLogo.addStyleDependentName(newTheme.toString());
+ // }
- @Override
- public void showDefUserLogo() {
- entityTextLogo.setLogoImage(AbstractImagePrototype.create(images.unknown60()));
- }
+ @Override
+ public void setSmallFont() {
+ entityTextLogo.setSmallFont();
+ }
+
+ @Override
+ public void showDefUserLogo(final GroupDTO group) {
+ entityTextLogo.setLogoImage(AbstractImagePrototype.create(images.unknown60()),
+ getAvatarDecoratorParam(group));
+ }
}
Modified: trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -24,7 +24,6 @@
import cc.kune.core.client.state.GroupChangedEvent.GroupChangedHandler;
import cc.kune.core.client.state.Session;
import cc.kune.core.client.state.StateManager;
-import cc.kune.core.shared.domain.utils.StateToken;
import cc.kune.core.shared.dto.GroupDTO;
import cc.kune.gspace.client.options.logo.CurrentLogoChangedEvent;
import cc.kune.gspace.client.options.logo.CurrentLogoChangedEvent.CurrentLogoChangedHandler;
@@ -54,7 +53,7 @@
void setLargeFont();
- void setLogoImage(StateToken stateToken);
+ void setLogoImage(GroupDTO group);
void setLogoImageVisible(boolean visible);
@@ -66,7 +65,7 @@
// void setTheme(final WsTheme oldTheme, WsTheme newTheme);
- void showDefUserLogo();
+ void showDefUserLogo(GroupDTO group);
}
private static final int LARGE_NAME_LIMIT = 17;
@@ -126,12 +125,12 @@
void setGroupLogo(final GroupDTO group) {
if (group.hasLogo()) {
setLogoText(group.getLongName());
- getView().setLogoImage(group.getStateToken());
+ getView().setLogoImage(group);
getView().setLogoImageVisible(true);
} else {
setLogoText(group.getLongName());
if (group.isPersonal()) {
- getView().showDefUserLogo();
+ getView().showDefUserLogo(group);
getView().setLogoImageVisible(true);
} else {
getView().setLogoImageVisible(false);
Modified: trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityTextLogo.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityTextLogo.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityTextLogo.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -19,11 +19,15 @@
*/
package cc.kune.core.client.ws.entheader;
+import cc.kune.core.client.avatar.MediumAvatarDecorator;
+
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.inject.Inject;
public class EntityTextLogo extends VerticalPanel {
@@ -34,16 +38,20 @@
private static final String LOGO_MEDIUM_FONT_STYLE = "k-elogo-l-m";
public static final String LOGO_NAME = "k-elogop-ln";
private static final String LOGO_SMALL_FONT_STYLE = "k-elogo-l-s";
+ private final MediumAvatarDecorator avatarDecorator;
private final Image logoImage;
private final Label logoLabel;
- public EntityTextLogo() {
+ @Inject
+ public EntityTextLogo(final MediumAvatarDecorator avatarDecorator) {
// Initialize
super();
+ this.avatarDecorator = avatarDecorator;
final HorizontalPanel generalHP = new HorizontalPanel();
final VerticalPanel logoTextVP = new VerticalPanel();
logoImage = new Image();
logoLabel = new Label();
+ avatarDecorator.setWidget(logoImage);
final Label expandCell = new Label("");
logoImage.ensureDebugId(LOGO_IMAGE);
@@ -51,7 +59,7 @@
// Layout
add(generalHP);
- generalHP.add(logoImage);
+ generalHP.add((Widget) avatarDecorator);
generalHP.add(logoTextVP);
logoTextVP.add(logoLabel);
@@ -84,14 +92,16 @@
logoLabel.addStyleName(LOGO_LARGE_FONT_STYLE);
}
- public void setLogoImage(final AbstractImagePrototype imageProto) {
+ public void setLogoImage(final AbstractImagePrototype imageProto, final String groupName) {
imageProto.applyTo(logoImage);
+ avatarDecorator.setItem(groupName);
}
- public void setLogoImage(final String url) {
+ public void setLogoImage(final String url, final String groupName) {
logoImage.setUrl("images/clear.gif");
Image.prefetch(url);
logoImage.setUrl(url);
+ avatarDecorator.setItem(groupName);
}
public void setLogoText(final String text) {
@@ -104,6 +114,7 @@
public void setLogoVisible(final boolean visible) {
logoImage.setVisible(visible);
+ avatarDecorator.setDecoratorVisible(visible);
}
public void setMediumFont() {
Modified: trunk/src/main/java/cc/kune/gspace/client/viewers/FolderViewerPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/viewers/FolderViewerPresenter.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/gspace/client/viewers/FolderViewerPresenter.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -81,8 +81,6 @@
void attach();
- void highlightTitle();
-
void clear();
void detach();
@@ -91,6 +89,8 @@
HasEditHandler getEditTitle();
+ void highlightTitle();
+
void setActions(GuiActionDescCollection actions);
void setContainer(StateContainerDTO state);
@@ -176,10 +176,6 @@
}
}
- public void highlightTitle() {
- getView().highlightTitle();
- }
-
String calculateStyle(final int pos, final int length) {
if (length == 1) {
return CSSBTN;
@@ -205,6 +201,7 @@
}
// Other contents (docs, etc)
for (final ContentSimpleDTO content : container.getContents()) {
+ assert content != null;
addItem(content, content.getMimeType(), content.getStatus(),
content.getStateToken().copy().clearDocument(), content.getRights(), content.getModifiedOn());
}
@@ -284,6 +281,10 @@
}
}
+ public void highlightTitle() {
+ getView().highlightTitle();
+ }
+
public void refreshState() {
setContent((HasContent) session.getCurrentState());
}
Modified: trunk/src/main/java/cc/kune/wave/client/WaveStatusIndicator.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/client/WaveStatusIndicator.java 2011-07-09 22:25:58 UTC (rev 1445)
+++ trunk/src/main/java/cc/kune/wave/client/WaveStatusIndicator.java 2011-07-10 18:29:52 UTC (rev 1446)
@@ -45,7 +45,7 @@
super(session, true);
ClientEvents.get().addNetworkStatusEventHandler(new NetworkStatusEventHandler() {
private void goOnline() {
- putValue(Action.NAME, i18n.t("Online"));
+ putValue(Action.NAME, ""); // i18n.t("Online"));
putValue(AbstractAction.STYLES, "k-sitebar-wave-status, k-sitebar-wave-status-online");
NotifyUser.hideProgress();
}
1
0
r1445 - in trunk: . src/main/java/cc/kune/core/client/sitebar/spaces
by Vicente J. Ruiz Jurado 09 Jul '11
by Vicente J. Ruiz Jurado 09 Jul '11
09 Jul '11
Author: vjrj_
Date: 2011-07-10 00:25:58 +0200 (Sun, 10 Jul 2011)
New Revision: 1445
Modified:
trunk/.classpath
trunk/pom.xml
trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
Log:
Closed issue #44 (SpaceSelector clicked twice) and #47 (updated to Guice 3.0)
Modified: trunk/.classpath
===================================================================
--- trunk/.classpath 2011-07-09 21:39:54 UTC (rev 1444)
+++ trunk/.classpath 2011-07-09 22:25:58 UTC (rev 1445)
@@ -44,10 +44,10 @@
<classpathentry kind="var" path="M2_REPO/net/sf/ezmorph/ezmorph/1.0.3/ezmorph-1.0.3.jar" sourcepath="M2_REPO/net/sf/ezmorph/ezmorph/1.0.3/ezmorph-1.0.3-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/freemarker/freemarker/2.3.8/freemarker-2.3.8.jar"/>
<classpathentry kind="var" path="M2_REPO/com/google/guava/guava-gwt/r09/guava-gwt-r09.jar"/>
- <classpathentry kind="var" path="M2_REPO/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.jar" sourcepath="M2_REPO/com/google/inject/guice/3.0-rc2/guice-3.0-rc2-sources.jar"/>
+ <classpathentry kind="var" path="M2_REPO/com/google/inject/guice/3.0/guice-3.0.jar" sourcepath="M2_REPO/com/google/inject/guice/3.0/guice-3.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/com/google/inject/extensions/guice-assisted-inject/2.0/guice-assisted-inject-2.0.jar"/>
- <classpathentry kind="var" path="M2_REPO/com/google/inject/extensions/guice-persist/3.0-rc2/guice-persist-3.0-rc2.jar" sourcepath="M2_REPO/com/google/inject/extensions/guice-persist/3.0-rc2/guice-persist-3.0-rc2-sources.jar"/>
- <classpathentry kind="var" path="M2_REPO/com/google/inject/extensions/guice-servlet/3.0-rc2/guice-servlet-3.0-rc2.jar" sourcepath="M2_REPO/com/google/inject/extensions/guice-servlet/3.0-rc2/guice-servlet-3.0-rc2-sources.jar"/>
+ <classpathentry kind="var" path="M2_REPO/com/google/inject/extensions/guice-persist/3.0/guice-persist-3.0.jar" sourcepath="M2_REPO/com/google/inject/extensions/guice-persist/3.0/guice-persist-3.0-sources.jar"/>
+ <classpathentry kind="var" path="M2_REPO/com/google/inject/extensions/guice-servlet/3.0/guice-servlet-3.0.jar" sourcepath="M2_REPO/com/google/inject/extensions/guice-servlet/3.0/guice-servlet-3.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/adamtacy/gwt-fx/r464/gwt-fx-r464.jar"/>
<classpathentry kind="var" path="M2_REPO/com/google/gwt/gwt-gin/1.0-r137/gwt-gin-1.0-r137.jar"/>
<classpathentry kind="var" path="M2_REPO/com/allen_sauer/gwt/log/gwt-log/gwt-log/3.0.1/gwt-log-3.0.1.jar"/>
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2011-07-09 21:39:54 UTC (rev 1444)
+++ trunk/pom.xml 2011-07-09 22:25:58 UTC (rev 1445)
@@ -213,19 +213,19 @@
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<!-- <version>2.1-SNAPSHOT-r1160</version> -->
- <version>3.0-rc2</version>
+ <version>3.0</version>
</dependency>
<!-- <dependency> <groupId>com.googlecode.gwt.inject</groupId> <artifactId>gin</artifactId>
<version>gin-1.1-SNAPSHOT</version> </dependency> -->
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
- <version>3.0-rc2</version>
+ <version>3.0</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-persist</artifactId>
- <version>3.0-rc2</version>
+ <version>3.0</version>
</dependency>
<dependency>
<groupId>com.extjs</groupId>
Modified: trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-09 21:39:54 UTC (rev 1444)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-09 22:25:58 UTC (rev 1445)
@@ -114,24 +114,28 @@
@Override
public void onClick(final ClickEvent event) {
stateManager.gotoHistoryToken(homeToken);
+ setDown(Space.homeSpace);
}
});
view.getUserBtn().addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
stateManager.gotoHistoryToken(userToken);
+ setDown(Space.userSpace);
}
});
view.getGroupBtn().addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
stateManager.gotoHistoryToken(groupToken);
+ setDown(Space.groupSpace);
}
});
view.getPublicBtn().addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent event) {
stateManager.gotoHistoryToken(publicToken);
+ setDown(Space.publicSpace);
}
});
eventBus.addHandler(WindowFocusEvent.getType(), new WindowFocusEvent.WindowFocusHandler() {
@@ -152,30 +156,21 @@
private void onGroupSpaceSelect() {
armor.selectGroupSpace();
backManager.restoreBackImage();
- getView().setHomeBtnDown(false);
- getView().setUserBtnDown(false);
- getView().setGroupBtnDown(true);
- getView().setPublicBtnDown(false);
+ setDown(Space.groupSpace);
currentSpace = Space.groupSpace;
}
private void onHomeSpaceSelect() {
armor.selectHomeSpace();
backManager.clearBackImage();
- getView().setHomeBtnDown(true);
- getView().setUserBtnDown(false);
- getView().setGroupBtnDown(false);
- getView().setPublicBtnDown(false);
+ setDown(Space.homeSpace);
currentSpace = Space.homeSpace;
}
private void onPublicSpaceSelect() {
armor.selectPublicSpace();
backManager.restoreBackImage();
- getView().setHomeBtnDown(false);
- getView().setUserBtnDown(false);
- getView().setGroupBtnDown(false);
- getView().setPublicBtnDown(true);
+ setDown(Space.publicSpace);
currentSpace = Space.publicSpace;
}
@@ -234,10 +229,7 @@
if (session.isLogged()) {
armor.selectUserSpace();
backManager.clearBackImage();
- getView().setHomeBtnDown(false);
- getView().setUserBtnDown(true);
- getView().setGroupBtnDown(false);
- getView().setPublicBtnDown(false);
+ setDown(Space.userSpace);
currentSpace = Space.userSpace;
} else {
signIn.get().setErrorMessage(i18n.t("Sign in or create an account to access to your inbox"),
@@ -252,6 +244,13 @@
RevealRootContentEvent.fire(this, this);
}
+ private void setDown(final Space space) {
+ getView().setHomeBtnDown(space.equals(Space.homeSpace));
+ getView().setUserBtnDown(space.equals(Space.userSpace));
+ getView().setGroupBtnDown(space.equals(Space.groupSpace));
+ getView().setPublicBtnDown(space.equals(Space.publicSpace));
+ }
+
private void showTooltipNow() {
if (currentSpace != null) {
switch (currentSpace) {
1
0
r1444 - in trunk/src/main/java/cc/kune: common/client/tooltip core/client/groups/newgroup core/client/sitebar/spaces core/client/ui core/client/ws/entheader core/public
by Vicente J. Ruiz Jurado 09 Jul '11
by Vicente J. Ruiz Jurado 09 Jul '11
09 Jul '11
Author: vjrj_
Date: 2011-07-09 23:39:54 +0200 (Sat, 09 Jul 2011)
New Revision: 1444
Modified:
trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java
trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPanel.java
trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorViewImpl.java
trunk/src/main/java/cc/kune/core/client/ui/DefaultFormUtils.java
trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java
trunk/src/main/java/cc/kune/core/public/ws.css
Log:
Some fixes/improvements in tooltips, new group creation...
Modified: trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java 2011-07-09 20:52:00 UTC (rev 1443)
+++ trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java 2011-07-09 21:39:54 UTC (rev 1444)
@@ -50,6 +50,8 @@
private static TooltipUiBinder uiBinder = GWT.create(TooltipUiBinder.class);
+ private static final int WIDTH_NOT_DEFINED = -1;
+
public static Tooltip to(final Widget widget, final String text) {
if (TextUtils.notEmpty(text)) {
final Tooltip tip = new Tooltip();
@@ -80,6 +82,7 @@
InlineLabel title;
@UiField
HTMLPanel tooltip;
+ private int width = WIDTH_NOT_DEFINED;
public Tooltip() {
super.add(uiBinder.createAndBindUi(this));
@@ -129,6 +132,10 @@
content.add(new Label(text));
}
+ public void setWidth(final int width) {
+ this.width = width;
+ }
+
@Override
public void show() {
if (!Tooltip.this.isShowing() && ofWidget.isVisible()) {
@@ -137,7 +144,9 @@
Window.getClientHeight(), ofWidget.getAbsoluteLeft(), ofWidget.getAbsoluteTop(),
ofWidget.getOffsetWidth(), ofWidget.getOffsetHeight(), Tooltip.this.getWidth(),
Tooltip.this.getHeight()));
- if (tooltip.getOffsetWidth() > 430) {
+ if (width != WIDTH_NOT_DEFINED) {
+ tooltip.getElement().getStyle().setWidth(width, Unit.PX);
+ } else if (tooltip.getOffsetWidth() > 430) {
tooltip.getElement().getStyle().setWidth(430, Unit.PX);
} else {
tooltip.getElement().getStyle().clearWidth();
Modified: trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPanel.java 2011-07-09 20:52:00 UTC (rev 1443)
+++ trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPanel.java 2011-07-09 21:39:54 UTC (rev 1444)
@@ -133,7 +133,7 @@
shortNameField.setName(SHORTNAME_FIELD);
shortNameField.setWidth(175);
shortNameField.setMinLength(3);
- shortNameField.setMaxLength(15);
+ shortNameField.setMaxLength(15); /* Same in Group.java/shortName */
shortNameField.setAllowBlank(false);
shortNameField.setRegex("^[a-z0-9]+$");
shortNameField.getMessages().setMinLengthText(i18n.t(CoreMessages.FIELD_MUST_BE_BETWEEN_3_AND_15));
@@ -150,7 +150,7 @@
longNameField.setWidth(BIG_FIELD_WIDTH);
longNameField.setAllowBlank(false);
longNameField.setMinLength(3);
- longNameField.setMaxLength(50);
+ longNameField.setMaxLength(50); /* Same in Group.java/longName */
longNameField.setValidationDelay(1000);
form.add(longNameField);
Modified: trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorViewImpl.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorViewImpl.java 2011-07-09 20:52:00 UTC (rev 1443)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorViewImpl.java 2011-07-09 21:39:54 UTC (rev 1444)
@@ -68,6 +68,10 @@
publicSpaceTooltip = Tooltip.to(publicButton,
i18n.t("Public space: In this space you can see a preview of how the Personal o"
+ "r Group Space looks like on the web, outside this site"));
+ // homeSpaceTooltip.setWidth(0);
+ userSpaceTooltip.setWidth(190);
+ groupSpaceTooltip.setWidth(170);
+ publicSpaceTooltip.setWidth(150);
}
@Override
@@ -115,18 +119,22 @@
userButton.setDown(down);
}
+ @Override
public void showGroupSpaceTooltip() {
groupSpaceTooltip.showTemporally();
}
+ @Override
public void showHomeSpaceTooltip() {
homeSpaceTooltip.showTemporally();
}
+ @Override
public void showPublicSpaceTooltip() {
publicSpaceTooltip.showTemporally();
}
+ @Override
public void showUserSpaceTooltip() {
userSpaceTooltip.showTemporally();
}
Modified: trunk/src/main/java/cc/kune/core/client/ui/DefaultFormUtils.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ui/DefaultFormUtils.java 2011-07-09 20:52:00 UTC (rev 1443)
+++ trunk/src/main/java/cc/kune/core/client/ui/DefaultFormUtils.java 2011-07-09 21:39:54 UTC (rev 1444)
@@ -43,6 +43,7 @@
public void handleEvent(final BaseEvent be) {
if (radioTip != null && tooltip == null) {
tooltip = Tooltip.to(radio, radioTip);
+ tooltip.setWidth(300);
tooltip.show();
tooltip.hide();
}
Modified: trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java 2011-07-09 20:52:00 UTC (rev 1443)
+++ trunk/src/main/java/cc/kune/core/client/ws/entheader/EntityHeaderPresenter.java 2011-07-09 21:39:54 UTC (rev 1444)
@@ -70,7 +70,7 @@
}
private static final int LARGE_NAME_LIMIT = 17;
- private static final int MEDIUM_NAME_LIMIT = 90;
+ private static final int MEDIUM_NAME_LIMIT = 80;
private final Session session;
@Inject
Modified: trunk/src/main/java/cc/kune/core/public/ws.css
===================================================================
--- trunk/src/main/java/cc/kune/core/public/ws.css 2011-07-09 20:52:00 UTC (rev 1443)
+++ trunk/src/main/java/cc/kune/core/public/ws.css 2011-07-09 21:39:54 UTC (rev 1444)
@@ -1,4 +1,4 @@
-CHARSET "UTF-8 "; body {
+CHARSET "UTF-8 "; body {
background-color: transparent;
color: black;
font-family: 'Ubuntu', Arial;
@@ -1065,13 +1065,17 @@
.k-elogo-l-l {
font-size: 46px;
+ line-height: 1em;
}
.k-elogo-l-m {
- font-size: 167%;
+ /* Right now the limit of size is 50 chars see EntityHeaderPresenter */
+ font-size: 181%;
+ line-height: 1.2em;
}
.k-elogo-l-s {
+ /* Not used because the limit is 50 chars (see Group.java) */
font-size: 108%;
}
@@ -1202,7 +1206,7 @@
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomleft: 5px;
border-bottom-left-radius: 5px;
- kfilter: alpha(opacity = 90);
+ kfilter: alpha(opacity = 90);
-moz-opacity: 0.90;
-khtml-opacity: 0.90;
opacity: 0.90;
1
0
Author: vjrj_
Date: 2011-07-09 22:52:00 +0200 (Sat, 09 Jul 2011)
New Revision: 1443
Modified:
trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java
trunk/src/main/java/cc/kune/common/client/ui/EditableLabel.java
trunk/src/main/java/cc/kune/common/client/ui/MaskWidget.java
trunk/src/main/java/cc/kune/common/client/ui/MaskWidgetView.java
trunk/src/main/java/cc/kune/core/client/errors/ErrorHandler.java
trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPanel.java
trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPresenter.java
trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupView.java
trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
trunk/src/main/java/cc/kune/core/client/sn/actions/registry/GroupSNConfActions.java
trunk/src/main/java/cc/kune/core/client/ui/DefaultFormUtils.java
trunk/src/main/java/cc/kune/core/server/manager/impl/GroupManagerDefault.java
trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkManagerDefault.java
trunk/src/main/java/cc/kune/core/shared/dto/GroupType.java
trunk/src/main/java/cc/kune/gspace/client/actions/NewContainerBtn.java
trunk/src/main/java/cc/kune/gspace/client/actions/NewContainerMenuItem.java
trunk/src/main/java/cc/kune/gspace/client/viewers/AbstractFolderViewerPanel.java
trunk/src/main/java/cc/kune/gspace/client/viewers/ContentTitleWidget.java
trunk/src/main/java/cc/kune/gspace/client/viewers/ContentViewerPanel.java
trunk/src/main/java/cc/kune/gspace/client/viewers/FolderViewerPresenter.java
trunk/src/main/webapp/others/kune-client-actions.xml
trunk/src/test/java/cc/kune/core/server/integration/kuneservice/GroupServiceTest.java
Log:
Closed groups; Rename title tooltip; Tooltip fixed
Modified: trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -176,6 +176,7 @@
}
public void showTemporally() {
+ show();
timers.showTemporally();
}
Modified: trunk/src/main/java/cc/kune/common/client/ui/EditableLabel.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/ui/EditableLabel.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/common/client/ui/EditableLabel.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -53,13 +53,15 @@
InlineLabel label;
@UiField
TextBox textbox;
- private String tooltip;
+ private Tooltip tooltip;
+ private String tooltipText;
+
public EditableLabel() {
initWidget(uiBinder.createAndBindUi(this));
label.setStylePrimaryName("k-editableLabel");
editable = false;
- tooltip = "";
+ tooltipText = "";
}
@Override
@@ -67,32 +69,6 @@
return addHandler(handler, EditEvent.getType());
}
- public void blink() {
- if (editable) {
- blinkTimer(true, new SimpleCallback() {
- @Override
- public void onCallback() {
- blinkTimer(false, new SimpleCallback() {
- @Override
- public void onCallback() {
- blinkTimer(true, new SimpleCallback() {
- @Override
- public void onCallback() {
- blinkTimer(false, new SimpleCallback() {
- @Override
- public void onCallback() {
- // nothing
- }
- });
- }
- });
- }
- });
- }
- });
- }
- }
-
private void blinkTimer(final boolean add, final SimpleCallback callback) {
new Timer() {
@Override
@@ -130,6 +106,32 @@
}
}
+ public void highlightTitle() {
+ if (editable) {
+ blinkTimer(true, new SimpleCallback() {
+ @Override
+ public void onCallback() {
+ blinkTimer(false, new SimpleCallback() {
+ @Override
+ public void onCallback() {
+ blinkTimer(true, new SimpleCallback() {
+ @Override
+ public void onCallback() {
+ blinkTimer(false, new SimpleCallback() {
+ @Override
+ public void onCallback() {
+ tooltip.showTemporally();
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+ }
+
@UiHandler("textbox")
void onBlur(final BlurEvent event) {
finishEdit();
@@ -156,7 +158,7 @@
public void setEditable(final boolean editable) {
this.editable = editable;
- Tooltip.to(label, editable ? tooltip : "");
+ tooltip = Tooltip.to(label, editable ? tooltipText : "");
}
public void setText(final String text) {
@@ -165,7 +167,7 @@
}
public void setTooltip(final String tooltip) {
- this.tooltip = tooltip;
+ this.tooltipText = tooltip;
}
}
Modified: trunk/src/main/java/cc/kune/common/client/ui/MaskWidget.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/ui/MaskWidget.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/common/client/ui/MaskWidget.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -35,53 +35,58 @@
public class MaskWidget extends PopupPanel implements MaskWidgetView {
- interface MaskWidgetUiBinder extends UiBinder<Widget, MaskWidget> {
- }
- private static MaskWidgetUiBinder uiBinder = GWT.create(MaskWidgetUiBinder.class);
- @UiField
- FlowPanel flow;
- @UiField
- Image icon;
- @UiField
- Label label;
+ interface MaskWidgetUiBinder extends UiBinder<Widget, MaskWidget> {
+ }
+ private static MaskWidgetUiBinder uiBinder = GWT.create(MaskWidgetUiBinder.class);
+ @UiField
+ FlowPanel flow;
+ @UiField
+ Image icon;
+ @UiField
+ Label label;
- @UiField
- SimplePanel mainPanel;
+ @UiField
+ SimplePanel mainPanel;
- public MaskWidget() {
- super(false, false);
- add(uiBinder.createAndBindUi(this));
- setStyleName("k-mask");
- }
+ public MaskWidget() {
+ super(false, false);
+ add(uiBinder.createAndBindUi(this));
+ setStyleName("k-mask");
+ }
- @Override
- @Nonnull
- public void mask(final IsWidget widget) {
- mask(widget, "");
- }
+ @Override
+ public boolean isShowing() {
+ return super.isShowing();
+ }
- @Override
- @Nonnull
- public void mask(final IsWidget widget, final String message) {
- label.setText(message);
- setPopupPositionAndShow(new PositionCallback() {
- @Override
- public void setPosition(final int offsetWidth, final int offsetHeight) {
- final Widget asWidget = widget.asWidget();
- final int w = asWidget.getOffsetWidth();
- final int h = asWidget.getOffsetHeight();
- MaskWidget.this.setPopupPosition(asWidget.getAbsoluteLeft(), asWidget.getAbsoluteTop());
- getElement().getStyle().setWidth(w, Unit.PX);
- getElement().getStyle().setHeight(h, Unit.PX);
- flow.getElement().getStyle().setTop((h - flow.getOffsetHeight()) / 2d, Unit.PX);
- flow.getElement().getStyle().setLeft((w - flow.getOffsetWidth()) / 2d, Unit.PX);
- }
- });
- }
+ @Override
+ @Nonnull
+ public void mask(final IsWidget widget) {
+ mask(widget, "");
+ }
- @Override
- public void unMask() {
- hide();
- }
+ @Override
+ @Nonnull
+ public void mask(final IsWidget widget, final String message) {
+ label.setText(message);
+ setPopupPositionAndShow(new PositionCallback() {
+ @Override
+ public void setPosition(final int offsetWidth, final int offsetHeight) {
+ final Widget asWidget = widget.asWidget();
+ final int w = asWidget.getOffsetWidth();
+ final int h = asWidget.getOffsetHeight();
+ MaskWidget.this.setPopupPosition(asWidget.getAbsoluteLeft(), asWidget.getAbsoluteTop());
+ getElement().getStyle().setWidth(w, Unit.PX);
+ getElement().getStyle().setHeight(h, Unit.PX);
+ flow.getElement().getStyle().setTop((h - flow.getOffsetHeight()) / 2d, Unit.PX);
+ flow.getElement().getStyle().setLeft((w - flow.getOffsetWidth()) / 2d, Unit.PX);
+ }
+ });
+ }
+ @Override
+ public void unMask() {
+ hide();
+ }
+
}
Modified: trunk/src/main/java/cc/kune/common/client/ui/MaskWidgetView.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/ui/MaskWidgetView.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/common/client/ui/MaskWidgetView.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -23,10 +23,12 @@
public interface MaskWidgetView {
- void mask(IsWidget widget);
+ boolean isShowing();
- void mask(IsWidget widget, String message);
+ void mask(IsWidget widget);
- void unMask();
+ void mask(IsWidget widget, String message);
+ void unMask();
+
}
Modified: trunk/src/main/java/cc/kune/core/client/errors/ErrorHandler.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/errors/ErrorHandler.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/client/errors/ErrorHandler.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -81,6 +81,7 @@
logException(caught);
eventBus.fireEvent(new UserNotifyEvent(NotifyLevel.error,
i18n.t("You do not have rights to perform that action")));
+ goHome();
} else if (caught instanceof SessionExpiredException) {
logException(caught);
doSessionExpired();
Modified: trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPanel.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPanel.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -46,6 +46,7 @@
public class NewGroupPanel extends ViewImpl implements NewGroupView {
private static final int BIG_FIELD_WIDTH = 280;
public static final String CANCEL_BUTTON = "k-ngp-cancel-bt";
+ public static final String CLOSED_GROUP_TYPE_ID = "k-ngp-type_of_group_closed";
public static final String COMM_GROUP_TYPE_ID = "k-ngp-type_of_group_comm";
public static final String ERROR_MSG_BAR = "k-ngp-error-mb";
private static final int LABEL_WIDTH = 100;
@@ -60,10 +61,11 @@
public static final String TAGS_FIELD = "k-ngp-tags";
public static final String TYPEOFGROUP_FIELD = "k-ngp-type_of_group";
+ private Radio closedRadio;
private Radio communityRadio;
private final BasicTopDialog dialog;
+
private final FormPanel form;
-
private final I18nTranslationService i18n;
private TextField<String> longNameField;
private final MaskWidgetView mask;
@@ -81,11 +83,11 @@
public NewGroupPanel(final I18nTranslationService i18n, final NotifyLevelImages img,
final MaskWidgetView mask) {
final Builder builder = new BasicTopDialog.Builder(NEWGROUP_WIZARD, false, true).autoscroll(true).height(
- "300px").title(i18n.t("Register a new group"));
+ "340px").title(i18n.t("Register a new group"));
builder.icon("k-newgroup-icon");
builder.firstButtonTitle(i18n.t("Register")).firstButtonId(REGISTER_BUTTON);
builder.sndButtonTitle(i18n.t("Cancel")).sndButtonId(CANCEL_BUTTON);
- builder.tabIndexStart(9);
+ builder.tabIndexStart(10);
dialog = builder.build();
this.i18n = i18n;
this.mask = mask;
@@ -195,12 +197,18 @@
+ "but organizations must be a legal entity."), ORG_GROUP_TYPE_ID);
orgRadio.setTabIndex(7);
+ closedRadio = DefaultFormUtils.createRadio(groupTypeFieldSet, i18n.t("Closed"), TYPEOFGROUP_FIELD,
+ i18n.t("Closed groups are social groups of persons "
+ + "like family, friends, buddies, etc, which are moderated to new members "
+ + "and with private contents (by default)"), CLOSED_GROUP_TYPE_ID);
+ closedRadio.setTabIndex(8);
+
communityRadio = DefaultFormUtils.createRadio(groupTypeFieldSet, i18n.t("Community"),
TYPEOFGROUP_FIELD, i18n.t("Communities are social groups of persons "
+ "with shared interests, which are open to new members "
+ "(for instance the environmental community or the LGBT community). "
+ "They rarely are a legal entity."), COMM_GROUP_TYPE_ID);
- communityRadio.setTabIndex(8);
+ communityRadio.setTabIndex(9);
return form;
}
@@ -257,6 +265,11 @@
}
@Override
+ public boolean isClosed() {
+ return closedRadio.getValue();
+ }
+
+ @Override
public boolean isCommunity() {
return communityRadio.getValue();
}
Modified: trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPresenter.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPresenter.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -114,6 +114,8 @@
return GroupType.PROJECT;
} else if (getView().isOrganization()) {
return GroupType.ORGANIZATION;
+ } else if (getView().isClosed()) {
+ return GroupType.CLOSED;
} else {
return GroupType.COMMUNITY;
}
Modified: trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupView.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupView.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupView.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -28,42 +28,44 @@
public interface NewGroupView extends View {
- void clearData();
+ void clearData();
- void focusOnShorName();
+ void focusOnShorName();
- HasCloseHandlers<PopupPanel> getClose();
+ HasCloseHandlers<PopupPanel> getClose();
- HasClickHandlers getFirstBtn();
+ HasClickHandlers getFirstBtn();
- String getLongName();
+ String getLongName();
- String getPublicDesc();
+ String getPublicDesc();
- HasClickHandlers getSecondBtn();
+ HasClickHandlers getSecondBtn();
- String getShortName();
+ String getShortName();
- String getTags();
+ String getTags();
- void hide();
+ void hide();
- void hideMessage();
+ void hideMessage();
- boolean isCommunity();
+ boolean isClosed();
- boolean isFormValid();
+ boolean isCommunity();
- boolean isOrganization();
+ boolean isFormValid();
- boolean isProject();
+ boolean isOrganization();
- void maskProcessing();
+ boolean isProject();
- void setMessage(String message, NotifyLevel level);
+ void maskProcessing();
- void show();
+ void setMessage(String message, NotifyLevel level);
- void unMask();
+ void show();
+ void unMask();
+
}
Modified: trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -20,6 +20,7 @@
package cc.kune.core.client.sitebar.spaces;
import cc.kune.common.client.notify.NotifyLevel;
+import cc.kune.common.client.ui.MaskWidgetView;
import cc.kune.core.client.auth.SignIn;
import cc.kune.core.client.events.WindowFocusEvent;
import cc.kune.core.client.init.AppStartEvent;
@@ -96,7 +97,7 @@
public SpaceSelectorPresenter(final EventBus eventBus, final StateManager stateManager,
final SpaceSelectorView view, final SpaceSelectorProxy proxy, final GSpaceArmor armor,
final Session session, final Provider<SignIn> signIn, final GSpaceBackManager backManager,
- final I18nTranslationService i18n) {
+ final I18nTranslationService i18n, final MaskWidgetView mask) {
super(eventBus, view, proxy);
this.stateManager = stateManager;
this.armor = armor;
@@ -136,7 +137,7 @@
eventBus.addHandler(WindowFocusEvent.getType(), new WindowFocusEvent.WindowFocusHandler() {
@Override
public void onWindowFocus(final WindowFocusEvent event) {
- if (event.isHasFocus()) {
+ if (event.isHasFocus() && !mask.isShowing()) {
showTooltipWithDelay();
}
}
@@ -252,19 +253,21 @@
}
private void showTooltipNow() {
- switch (currentSpace) {
- case homeSpace:
- getView().showHomeSpaceTooltip();
- break;
- case userSpace:
- getView().showUserSpaceTooltip();
- break;
- case groupSpace:
- getView().showGroupSpaceTooltip();
- break;
- case publicSpace:
- getView().showPublicSpaceTooltip();
- break;
+ if (currentSpace != null) {
+ switch (currentSpace) {
+ case homeSpace:
+ getView().showHomeSpaceTooltip();
+ break;
+ case userSpace:
+ getView().showUserSpaceTooltip();
+ break;
+ case groupSpace:
+ getView().showGroupSpaceTooltip();
+ break;
+ case publicSpace:
+ getView().showPublicSpaceTooltip();
+ break;
+ }
}
}
@@ -274,6 +277,6 @@
public void run() {
showTooltipNow();
}
- }.schedule(500);
+ }.schedule(200);
}
}
\ No newline at end of file
Modified: trunk/src/main/java/cc/kune/core/client/sn/actions/registry/GroupSNConfActions.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sn/actions/registry/GroupSNConfActions.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/client/sn/actions/registry/GroupSNConfActions.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -81,6 +81,7 @@
final MenuRadioItemDescriptor moderatedItem = membersModeration.get().withModeration(
AdmissionType.Moderated);
final MenuRadioItemDescriptor openItem = membersModeration.get().withModeration(AdmissionType.Open);
+
addImpl(OPTIONS_MENU);
addImpl(optionsTitle);
addImpl(VISIBILITY_SUBMENU.withText(i18n.t("Those who can view this member list")).withParent(
@@ -91,8 +92,7 @@
addImpl(onlyAdminsItem.withParent(VISIBILITY_SUBMENU).withText(i18n.t("only admins")));
addImpl(moderatedItem.withParent(MODERATION_SUBMENU).withText(i18n.t("moderate request to join")));
addImpl(openItem.withParent(MODERATION_SUBMENU).withText(i18n.t("auto accept request to join")));
- // add(closedItem.withParent(MODERATION_SUBMENU).withText(
- // i18n.t("closed for new members")));
+ addImpl(closedItem.withParent(MODERATION_SUBMENU).withText(i18n.t("closed for new members")));
final ButtonDescriptor joinBtn = new ButtonDescriptor(joinGroupAction);
final ButtonDescriptor unJoinBtn = new ButtonDescriptor(unJoinGroupAction);
Modified: trunk/src/main/java/cc/kune/core/client/ui/DefaultFormUtils.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/ui/DefaultFormUtils.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/client/ui/DefaultFormUtils.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -21,6 +21,9 @@
import cc.kune.common.client.tooltip.Tooltip;
+import com.extjs.gxt.ui.client.event.BaseEvent;
+import com.extjs.gxt.ui.client.event.Events;
+import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.form.Radio;
@@ -33,9 +36,18 @@
radio.setId(id);
fieldSet.add(radio);
- if (radioTip != null) {
- Tooltip.to(radio, radioTip);
- }
+ radio.addListener(Events.OnMouseOver, new Listener<BaseEvent>() {
+ private Tooltip tooltip;
+
+ @Override
+ public void handleEvent(final BaseEvent be) {
+ if (radioTip != null && tooltip == null) {
+ tooltip = Tooltip.to(radio, radioTip);
+ tooltip.show();
+ tooltip.hide();
+ }
+ }
+ });
radio.setBoxLabel(radioLabel);
return radio;
}
Modified: trunk/src/main/java/cc/kune/core/server/manager/impl/GroupManagerDefault.java
===================================================================
--- trunk/src/main/java/cc/kune/core/server/manager/impl/GroupManagerDefault.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/server/manager/impl/GroupManagerDefault.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -47,6 +47,7 @@
import cc.kune.core.shared.SearcherConstants;
import cc.kune.core.shared.domain.AdmissionType;
import cc.kune.core.shared.domain.GroupListMode;
+import cc.kune.core.shared.domain.SocialNetworkVisibility;
import cc.kune.core.shared.dto.GroupType;
import cc.kune.core.shared.i18n.I18nTranslationService;
import cc.kune.domain.AccessLists;
@@ -129,8 +130,14 @@
throws GroupNameInUseException, UserMustBeLoggedException {
final String defaultSiteWorkspaceTheme = kuneProperties.get(KuneProperties.WS_THEMES_DEF);
if (User.isKnownUser(user)) {
+ GroupListMode publicVisibility = GroupListMode.EVERYONE;
+ SocialNetworkVisibility snVisibility = SocialNetworkVisibility.anyone;
if (group.getGroupType().equals(GroupType.COMMUNITY)) {
group.setAdmissionType(AdmissionType.Open);
+ } else if (group.getGroupType().equals(GroupType.CLOSED)) {
+ group.setAdmissionType(AdmissionType.Closed);
+ publicVisibility = GroupListMode.NORMAL;
+ snVisibility = SocialNetworkVisibility.onlymembers;
} else if (group.getGroupType().equals(GroupType.ORGANIZATION)) {
group.setAdmissionType(AdmissionType.Moderated);
} else if (group.getGroupType().equals(GroupType.PROJECT)) {
@@ -142,7 +149,7 @@
final License license = licenseFinder.findByShortName(licName);
group.setDefaultLicense(license);
group.setWorkspaceTheme(defaultSiteWorkspaceTheme);
- initSocialNetwork(group, user.getUserGroup());
+ initSocialNetwork(group, user.getUserGroup(), publicVisibility, snVisibility);
final String title = i18n.t("About [%s]", group.getLongName());
initGroup(user, group, serverToolRegistry.getToolsForGroupsKeys(), title, publicDescrip);
return group;
@@ -177,7 +184,7 @@
userGroup.setWorkspaceTheme(defaultSiteWorkspaceTheme);
userGroup.setDefaultContent(null);
user.setUserGroup(userGroup);
- initSocialNetwork(userGroup, userGroup);
+ initSocialNetwork(userGroup, userGroup, GroupListMode.EVERYONE, SocialNetworkVisibility.anyone);
final String title = i18n.t("[%s] Bio", user.getName());
final String body = i18n.t("This user has not written its biography yet");
@@ -244,14 +251,16 @@
}
}
- private void initSocialNetwork(final Group group, final Group userGroup) {
+ private void initSocialNetwork(final Group group, final Group userGroup,
+ final GroupListMode publicVisibility, final SocialNetworkVisibility snVisibility) {
final SocialNetwork network = group.getSocialNetwork();
final AccessLists lists = network.getAccessLists();
lists.getEditors().setMode(GroupListMode.NOBODY);
- lists.getViewers().setMode(GroupListMode.EVERYONE);
+ lists.getViewers().setMode(publicVisibility);
if (!group.getGroupType().equals(GroupType.ORPHANED_PROJECT)) {
network.addAdmin(userGroup);
}
+ network.setVisibility(snVisibility);
}
@Override
Modified: trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkManagerDefault.java
===================================================================
--- trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkManagerDefault.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/server/manager/impl/SocialNetworkManagerDefault.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -23,7 +23,6 @@
import javax.persistence.EntityManager;
-
import cc.kune.core.client.errors.AccessViolationException;
import cc.kune.core.client.errors.AlreadyGroupMemberException;
import cc.kune.core.client.errors.AlreadyUserMemberException;
@@ -54,302 +53,311 @@
import com.google.inject.Singleton;
@Singleton
-public class SocialNetworkManagerDefault extends DefaultManager<SocialNetwork, Long> implements SocialNetworkManager {
+public class SocialNetworkManagerDefault extends DefaultManager<SocialNetwork, Long> implements
+ SocialNetworkManager {
- private final AccessRightsService accessRightsService;
- private final GroupFinder finder;
- private final UserManager userManager;
+ private final AccessRightsService accessRightsService;
+ private final GroupFinder finder;
+ private final UserManager userManager;
- @Inject
- public SocialNetworkManagerDefault(final Provider<EntityManager> provider, final GroupFinder finder,
- final AccessRightsService accessRightsService, final UserManager userManager) {
- super(provider, SocialNetwork.class);
- this.finder = finder;
- this.accessRightsService = accessRightsService;
- this.userManager = userManager;
- }
+ @Inject
+ public SocialNetworkManagerDefault(final Provider<EntityManager> provider, final GroupFinder finder,
+ final AccessRightsService accessRightsService, final UserManager userManager) {
+ super(provider, SocialNetwork.class);
+ this.finder = finder;
+ this.accessRightsService = accessRightsService;
+ this.userManager = userManager;
+ }
- @Override
- public void acceptJoinGroup(final User userLogged, final Group group, final Group inGroup) throws DefaultException,
- AccessViolationException {
- final SocialNetwork sn = inGroup.getSocialNetwork();
- checkUserLoggedIsAdmin(userLogged, sn);
- final List<Group> pendingCollabs = sn.getPendingCollaborators().getList();
- if (pendingCollabs.contains(group)) {
- sn.addCollaborator(group);
- sn.removePendingCollaborator(group);
- } else {
- throw new DefaultException("User is not a pending collaborator");
- }
+ @Override
+ public void acceptJoinGroup(final User userLogged, final Group group, final Group inGroup)
+ throws DefaultException, AccessViolationException {
+ final SocialNetwork sn = inGroup.getSocialNetwork();
+ checkUserLoggedIsAdmin(userLogged, sn);
+ final List<Group> pendingCollabs = sn.getPendingCollaborators().getList();
+ if (pendingCollabs.contains(group)) {
+ sn.addCollaborator(group);
+ sn.removePendingCollaborator(group);
+ } else {
+ throw new DefaultException("User is not a pending collaborator");
}
+ }
- void addAdmin(final User newAdmin, final Group group) {
- final SocialNetwork sn = group.getSocialNetwork();
- sn.addAdmin(newAdmin.getUserGroup());
- }
+ void addAdmin(final User newAdmin, final Group group) {
+ final SocialNetwork sn = group.getSocialNetwork();
+ sn.addAdmin(newAdmin.getUserGroup());
+ }
- @Override
- public void addGroupToAdmins(final User userLogged, final Group group, final Group inGroup) throws DefaultException {
- checkGroupAddingToSelf(group, inGroup);
- final SocialNetwork sn = inGroup.getSocialNetwork();
- checkUserLoggedIsAdmin(userLogged, sn);
- checkGroupIsNotAlreadyAMember(group, sn);
- sn.addAdmin(group);
- if (sn.isPendingCollab(group)) {
- sn.removePendingCollaborator(group);
- }
+ @Override
+ public void addGroupToAdmins(final User userLogged, final Group group, final Group inGroup)
+ throws DefaultException {
+ checkGroupAddingToSelf(group, inGroup);
+ final SocialNetwork sn = inGroup.getSocialNetwork();
+ checkUserLoggedIsAdmin(userLogged, sn);
+ checkGroupIsNotAlreadyAMember(group, sn);
+ sn.addAdmin(group);
+ if (sn.isPendingCollab(group)) {
+ sn.removePendingCollaborator(group);
}
+ }
- @Override
- public void addGroupToCollabs(final User userLogged, final Group group, final Group inGroup)
- throws DefaultException {
- checkGroupAddingToSelf(group, inGroup);
- final SocialNetwork sn = inGroup.getSocialNetwork();
- checkUserLoggedIsAdmin(userLogged, sn);
- checkGroupIsNotAlreadyAMember(group, sn);
- sn.addCollaborator(group);
- if (sn.isPendingCollab(group)) {
- sn.removePendingCollaborator(group);
- }
+ @Override
+ public void addGroupToCollabs(final User userLogged, final Group group, final Group inGroup)
+ throws DefaultException {
+ checkGroupAddingToSelf(group, inGroup);
+ final SocialNetwork sn = inGroup.getSocialNetwork();
+ checkUserLoggedIsAdmin(userLogged, sn);
+ checkGroupIsNotAlreadyAMember(group, sn);
+ sn.addCollaborator(group);
+ if (sn.isPendingCollab(group)) {
+ sn.removePendingCollaborator(group);
}
+ }
- @Override
- public void addGroupToViewers(final User userLogged, final Group group, final Group inGroup)
- throws DefaultException {
- checkGroupAddingToSelf(group, inGroup);
- final SocialNetwork sn = inGroup.getSocialNetwork();
- checkUserLoggedIsAdmin(userLogged, sn);
- checkGroupIsNotAlreadyAMember(group, sn);
- sn.addViewer(group);
- if (sn.isPendingCollab(group)) {
- sn.removePendingCollaborator(group);
- }
+ @Override
+ public void addGroupToViewers(final User userLogged, final Group group, final Group inGroup)
+ throws DefaultException {
+ checkGroupAddingToSelf(group, inGroup);
+ final SocialNetwork sn = inGroup.getSocialNetwork();
+ checkUserLoggedIsAdmin(userLogged, sn);
+ checkGroupIsNotAlreadyAMember(group, sn);
+ sn.addViewer(group);
+ if (sn.isPendingCollab(group)) {
+ sn.removePendingCollaborator(group);
}
+ }
- private void checkGroupAddingToSelf(final Group group, final Group inGroup) throws DefaultException {
- if (group.equals(inGroup)) {
- throwGroupMemberException(group);
- }
+ private void checkGroupAddingToSelf(final Group group, final Group inGroup) throws DefaultException {
+ if (group.equals(inGroup)) {
+ throwGroupMemberException(group);
}
+ }
- private void checkGroupIsNotAlreadyAMember(final Group group, final SocialNetwork sn) throws DefaultException {
- if (sn.isAdmin(group) || sn.isCollab(group) || sn.isViewer(group) && notEveryOneCanView(sn)) {
- throwGroupMemberException(group);
- }
+ private void checkGroupIsNotAlreadyAMember(final Group group, final SocialNetwork sn)
+ throws DefaultException {
+ if (sn.isAdmin(group) || sn.isCollab(group) || sn.isViewer(group) && notEveryOneCanView(sn)) {
+ throwGroupMemberException(group);
}
+ }
- private void checkUserLoggedIsAdmin(final User userLogged, final SocialNetwork sn) throws AccessViolationException {
- if (!accessRightsService.get(userLogged, sn.getAccessLists()).isAdministrable()) {
- throw new AccessViolationException();
- }
+ private void checkUserLoggedIsAdmin(final User userLogged, final SocialNetwork sn)
+ throws AccessViolationException {
+ if (!accessRightsService.get(userLogged, sn.getAccessLists()).isAdministrable()) {
+ throw new AccessViolationException();
}
+ }
- @Override
- public void deleteMember(final User userLogged, final Group group, final Group inGroup) throws DefaultException,
- AccessViolationException {
- final SocialNetwork sn = inGroup.getSocialNetwork();
+ @Override
+ public void deleteMember(final User userLogged, final Group group, final Group inGroup)
+ throws DefaultException, AccessViolationException {
+ final SocialNetwork sn = inGroup.getSocialNetwork();
- checkUserLoggedIsAdmin(userLogged, sn);
- unJoinGroup(group, inGroup);
- }
+ checkUserLoggedIsAdmin(userLogged, sn);
+ unJoinGroup(group, inGroup);
+ }
- @Override
- public void denyJoinGroup(final User userLogged, final Group group, final Group inGroup) throws DefaultException {
- final SocialNetwork sn = inGroup.getSocialNetwork();
- checkUserLoggedIsAdmin(userLogged, sn);
- final List<Group> pendingCollabs = sn.getPendingCollaborators().getList();
- if (pendingCollabs.contains(group)) {
- sn.removePendingCollaborator(group);
- } else {
- throw new DefaultException("Person/Group is not a pending collaborator");
- }
+ @Override
+ public void denyJoinGroup(final User userLogged, final Group group, final Group inGroup)
+ throws DefaultException {
+ final SocialNetwork sn = inGroup.getSocialNetwork();
+ checkUserLoggedIsAdmin(userLogged, sn);
+ final List<Group> pendingCollabs = sn.getPendingCollaborators().getList();
+ if (pendingCollabs.contains(group)) {
+ sn.removePendingCollaborator(group);
+ } else {
+ throw new DefaultException("Person/Group is not a pending collaborator");
}
+ }
- @Override
- public ParticipationData findParticipation(final User userLogged, final Group group)
- throws AccessViolationException {
- get(userLogged, group); // check access
- final Long groupId = group.getId();
- final List<Group> adminInGroups = finder.findAdminInGroups(groupId);
- // Don't show self user group
- if (group.isPersonal()) {
- adminInGroups.remove(group);
- }
- // adminInGroups.remove(userLogged.getUserGroup());
- final List<Group> collabInGroups = finder.findCollabInGroups(groupId);
- return new ParticipationData(adminInGroups, collabInGroups);
+ @Override
+ public ParticipationData findParticipation(final User userLogged, final Group group)
+ throws AccessViolationException {
+ get(userLogged, group); // check access
+ final Long groupId = group.getId();
+ final List<Group> adminInGroups = finder.findAdminInGroups(groupId);
+ // Don't show self user group
+ if (group.isPersonal()) {
+ adminInGroups.remove(group);
}
+ // adminInGroups.remove(userLogged.getUserGroup());
+ final List<Group> collabInGroups = finder.findCollabInGroups(groupId);
+ return new ParticipationData(adminInGroups, collabInGroups);
+ }
- @Override
- public SocialNetwork get(final User petitioner, final Group group) throws AccessViolationException {
- final SocialNetwork sn = group.getSocialNetwork();
- if (!sn.getAccessLists().getViewers().includes(petitioner.getUserGroup())) {
- throw new AccessViolationException();
- }
- return sn;
+ @Override
+ public SocialNetwork get(final User petitioner, final Group group) throws AccessViolationException {
+ final SocialNetwork sn = group.getSocialNetwork();
+ if (!sn.getAccessLists().getViewers().includes(petitioner.getUserGroup())
+ && !sn.getAccessLists().getEditors().includes(petitioner.getUserGroup())
+ && !sn.getAccessLists().getAdmins().includes(petitioner.getUserGroup())) {
+ throw new AccessViolationException();
}
+ return sn;
+ }
- @Override
- public SocialNetworkData getSocialNetworkData(final User userLogged, final Group group) {
- final SocialNetworkData socialNetData = new SocialNetworkData();
- socialNetData.setGroupMembers(get(userLogged, group));
- final AccessRights groupRights = accessRightsService.get(userLogged, group.getAccessLists());
- socialNetData.setGroupRights(groupRights);
- socialNetData.setUserParticipation(findParticipation(userLogged, group));
- socialNetData.setGroupMembers(get(userLogged, group));
- if (group.isPersonal()) {
- final UserBuddiesData userBuddies = userManager.getUserBuddies(group.getShortName());
- final User userGroup = userManager.findByShortname(group.getShortName());
- socialNetData.setUserBuddies(userBuddies);
- final UserSNetVisibility buddiesVisibility = userGroup.getSNetVisibility();
- socialNetData.setIsBuddiesVisible(true);
- switch (buddiesVisibility) {
- case anyone:
- break;
- case onlyyou:
- if (userLogged.equals(User.UNKNOWN_USER) || !userLogged.getUserGroup().equals(group)) {
- socialNetData.setIsBuddiesVisible(false);
- socialNetData.setUserBuddies(UserBuddiesData.EMPTY);
- }
- break;
- case yourbuddies:
- final boolean notMe = !userLogged.equals(userGroup);
- final boolean notABuddie = !userBuddies.contains(userLogged.getShortName());
- if (notMe && notABuddie) {
- socialNetData.setIsBuddiesVisible(false);
- socialNetData.setUserBuddies(UserBuddiesData.EMPTY);
- }
- break;
- }
- socialNetData.setUserBuddiesVisibility(buddiesVisibility);
- } else {
- final SocialNetworkVisibility visibility = group.getSocialNetwork().getVisibility();
- socialNetData.setIsMembersVisible(true);
- switch (visibility) {
- case anyone:
- break;
- case onlyadmins:
- if (!groupRights.isAdministrable()) {
- socialNetData.setIsMembersVisible(false);
- socialNetData.setGroupMembers(SocialNetwork.EMPTY);
- }
- break;
- case onlymembers:
- if (!groupRights.isEditable()) {
- socialNetData.setIsMembersVisible(false);
- socialNetData.setGroupMembers(SocialNetwork.EMPTY);
- }
- break;
- }
- socialNetData.setSocialNetworkVisibility(visibility);
- socialNetData.setUserBuddies(UserBuddiesData.EMPTY);
+ @Override
+ public SocialNetworkData getSocialNetworkData(final User userLogged, final Group group) {
+ final SocialNetworkData socialNetData = new SocialNetworkData();
+ socialNetData.setGroupMembers(get(userLogged, group));
+ final AccessRights groupRights = accessRightsService.get(userLogged, group.getAccessLists());
+ socialNetData.setGroupRights(groupRights);
+ socialNetData.setUserParticipation(findParticipation(userLogged, group));
+ socialNetData.setGroupMembers(get(userLogged, group));
+ if (group.isPersonal()) {
+ final UserBuddiesData userBuddies = userManager.getUserBuddies(group.getShortName());
+ final User userGroup = userManager.findByShortname(group.getShortName());
+ socialNetData.setUserBuddies(userBuddies);
+ final UserSNetVisibility buddiesVisibility = userGroup.getSNetVisibility();
+ socialNetData.setIsBuddiesVisible(true);
+ switch (buddiesVisibility) {
+ case anyone:
+ break;
+ case onlyyou:
+ if (userLogged.equals(User.UNKNOWN_USER) || !userLogged.getUserGroup().equals(group)) {
+ socialNetData.setIsBuddiesVisible(false);
+ socialNetData.setUserBuddies(UserBuddiesData.EMPTY);
}
- return socialNetData;
+ break;
+ case yourbuddies:
+ final boolean notMe = !userLogged.equals(userGroup);
+ final boolean notABuddie = !userBuddies.contains(userLogged.getShortName());
+ if (notMe && notABuddie) {
+ socialNetData.setIsBuddiesVisible(false);
+ socialNetData.setUserBuddies(UserBuddiesData.EMPTY);
+ }
+ break;
+ }
+ socialNetData.setUserBuddiesVisibility(buddiesVisibility);
+ } else {
+ final SocialNetworkVisibility visibility = group.getSocialNetwork().getVisibility();
+ socialNetData.setIsMembersVisible(true);
+ switch (visibility) {
+ case anyone:
+ break;
+ case onlyadmins:
+ if (!groupRights.isAdministrable()) {
+ socialNetData.setIsMembersVisible(false);
+ socialNetData.setGroupMembers(SocialNetwork.EMPTY);
+ }
+ break;
+ case onlymembers:
+ if (!groupRights.isEditable()) {
+ socialNetData.setIsMembersVisible(false);
+ socialNetData.setGroupMembers(SocialNetwork.EMPTY);
+ }
+ break;
+ }
+ socialNetData.setSocialNetworkVisibility(visibility);
+ socialNetData.setUserBuddies(UserBuddiesData.EMPTY);
}
+ return socialNetData;
+ }
- private boolean isClosed(final AdmissionType admissionType) {
- return admissionType.equals(AdmissionType.Closed);
- }
+ private boolean isClosed(final AdmissionType admissionType) {
+ return admissionType.equals(AdmissionType.Closed);
+ }
- private boolean isModerated(final AdmissionType admissionType) {
- return admissionType.equals(AdmissionType.Moderated);
- }
+ private boolean isModerated(final AdmissionType admissionType) {
+ return admissionType.equals(AdmissionType.Moderated);
+ }
- private boolean isOpen(final AdmissionType admissionType) {
- return admissionType.equals(AdmissionType.Open);
- }
+ private boolean isOpen(final AdmissionType admissionType) {
+ return admissionType.equals(AdmissionType.Open);
+ }
- private boolean notEveryOneCanView(final SocialNetwork sn) {
- return !sn.getAccessLists().getViewers().getMode().equals(GroupListMode.EVERYONE);
- }
+ private boolean notEveryOneCanView(final SocialNetwork sn) {
+ return !sn.getAccessLists().getViewers().getMode().equals(GroupListMode.EVERYONE);
+ }
- @Override
- public SocialNetworkRequestResult requestToJoin(final User userLogged, final Group inGroup)
- throws DefaultException, UserMustBeLoggedException {
- final SocialNetwork sn = inGroup.getSocialNetwork();
- if (!User.isKnownUser(userLogged)) {
- throw new UserMustBeLoggedException();
- }
- final AdmissionType admissionType = inGroup.getAdmissionType();
- if (admissionType == null) {
- throw new ServerException("No admissionType");
- }
- final Group userGroup = userLogged.getUserGroup();
- checkGroupIsNotAlreadyAMember(userGroup, sn);
- if (isModerated(admissionType)) {
- sn.addPendingCollaborator(userGroup);
- return SocialNetworkRequestResult.moderated;
- } else if (isOpen(admissionType)) {
- if (inGroup.getGroupType().equals(GroupType.ORPHANED_PROJECT)) {
- sn.addAdmin(userGroup);
- inGroup.setGroupType(GroupType.PROJECT);
- inGroup.setAdmissionType(AdmissionType.Moderated);
- persist(inGroup, Group.class);
- } else {
- sn.addCollaborator(userGroup);
- }
- return SocialNetworkRequestResult.accepted;
- } else if (isClosed(admissionType)) {
- return SocialNetworkRequestResult.denied;
- } else {
- throw new DefaultException("State not expected in SocialNetworkManagerDefault class");
- }
+ @Override
+ public SocialNetworkRequestResult requestToJoin(final User userLogged, final Group inGroup)
+ throws DefaultException, UserMustBeLoggedException {
+ final SocialNetwork sn = inGroup.getSocialNetwork();
+ if (!User.isKnownUser(userLogged)) {
+ throw new UserMustBeLoggedException();
}
+ final AdmissionType admissionType = inGroup.getAdmissionType();
+ if (admissionType == null) {
+ throw new ServerException("No admissionType");
+ }
+ final Group userGroup = userLogged.getUserGroup();
+ checkGroupIsNotAlreadyAMember(userGroup, sn);
+ if (isModerated(admissionType)) {
+ sn.addPendingCollaborator(userGroup);
+ return SocialNetworkRequestResult.moderated;
+ } else if (isOpen(admissionType)) {
+ if (inGroup.getGroupType().equals(GroupType.ORPHANED_PROJECT)) {
+ sn.addAdmin(userGroup);
+ inGroup.setGroupType(GroupType.PROJECT);
+ inGroup.setAdmissionType(AdmissionType.Moderated);
+ persist(inGroup, Group.class);
+ } else {
+ sn.addCollaborator(userGroup);
+ }
+ return SocialNetworkRequestResult.accepted;
+ } else if (isClosed(admissionType)) {
+ return SocialNetworkRequestResult.denied;
+ } else {
+ throw new DefaultException("State not expected in SocialNetworkManagerDefault class");
+ }
+ }
- @Override
- public void setAdminAsCollab(final User userLogged, final Group group, final Group inGroup) throws DefaultException {
- final SocialNetwork sn = inGroup.getSocialNetwork();
- checkUserLoggedIsAdmin(userLogged, sn);
- if (sn.isAdmin(group)) {
- if (sn.getAccessLists().getAdmins().getList().size() == 1) {
- throw new LastAdminInGroupException();
- }
- sn.removeAdmin(group);
- sn.addCollaborator(group);
- } else {
- throw new DefaultException("Person/Group is not an admin");
- }
+ @Override
+ public void setAdminAsCollab(final User userLogged, final Group group, final Group inGroup)
+ throws DefaultException {
+ final SocialNetwork sn = inGroup.getSocialNetwork();
+ checkUserLoggedIsAdmin(userLogged, sn);
+ if (sn.isAdmin(group)) {
+ if (sn.getAccessLists().getAdmins().getList().size() == 1) {
+ throw new LastAdminInGroupException();
+ }
+ sn.removeAdmin(group);
+ sn.addCollaborator(group);
+ } else {
+ throw new DefaultException("Person/Group is not an admin");
}
+ }
- @Override
- public void setCollabAsAdmin(final User userLogged, final Group group, final Group inGroup) throws DefaultException {
- final SocialNetwork sn = inGroup.getSocialNetwork();
- checkUserLoggedIsAdmin(userLogged, sn);
- if (sn.isCollab(group)) {
- sn.removeCollaborator(group);
- sn.addAdmin(group);
- } else {
- throw new DefaultException("Person/Group is not a collaborator");
- }
+ @Override
+ public void setCollabAsAdmin(final User userLogged, final Group group, final Group inGroup)
+ throws DefaultException {
+ final SocialNetwork sn = inGroup.getSocialNetwork();
+ checkUserLoggedIsAdmin(userLogged, sn);
+ if (sn.isCollab(group)) {
+ sn.removeCollaborator(group);
+ sn.addAdmin(group);
+ } else {
+ throw new DefaultException("Person/Group is not a collaborator");
}
+ }
- private void throwGroupMemberException(final Group group) throws DefaultException {
- if (group.isPersonal()) {
- throw new AlreadyUserMemberException();
- } else {
- throw new AlreadyGroupMemberException();
- }
+ private void throwGroupMemberException(final Group group) throws DefaultException {
+ if (group.isPersonal()) {
+ throw new AlreadyUserMemberException();
+ } else {
+ throw new AlreadyGroupMemberException();
}
+ }
- @Override
- public void unJoinGroup(final Group groupToUnJoin, final Group inGroup) throws DefaultException {
- final SocialNetwork sn = inGroup.getSocialNetwork();
+ @Override
+ public void unJoinGroup(final Group groupToUnJoin, final Group inGroup) throws DefaultException {
+ final SocialNetwork sn = inGroup.getSocialNetwork();
- if (sn.isAdmin(groupToUnJoin)) {
- if (sn.getAccessLists().getAdmins().getList().size() == 1) {
- if (sn.getAccessLists().getEditors().getList().size() > 0) {
- throw new LastAdminInGroupException();
- } else {
- inGroup.setGroupType(GroupType.ORPHANED_PROJECT);
- inGroup.setAdmissionType(AdmissionType.Open);
- }
- }
- sn.removeAdmin(groupToUnJoin);
- } else if (sn.isCollab(groupToUnJoin)) {
- sn.removeCollaborator(groupToUnJoin);
+ if (sn.isAdmin(groupToUnJoin)) {
+ if (sn.getAccessLists().getAdmins().getList().size() == 1) {
+ if (sn.getAccessLists().getEditors().getList().size() > 0) {
+ throw new LastAdminInGroupException();
} else {
- throw new DefaultException("Person/Group is not a collaborator");
+ inGroup.setGroupType(GroupType.ORPHANED_PROJECT);
+ inGroup.setAdmissionType(AdmissionType.Open);
}
+ }
+ sn.removeAdmin(groupToUnJoin);
+ } else if (sn.isCollab(groupToUnJoin)) {
+ sn.removeCollaborator(groupToUnJoin);
+ } else {
+ throw new DefaultException("Person/Group is not a collaborator");
}
+ }
}
Modified: trunk/src/main/java/cc/kune/core/shared/dto/GroupType.java
===================================================================
--- trunk/src/main/java/cc/kune/core/shared/dto/GroupType.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/core/shared/dto/GroupType.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -22,5 +22,5 @@
import com.google.gwt.user.client.rpc.IsSerializable;
public enum GroupType implements IsSerializable {
- ORGANIZATION, COMMUNITY, PROJECT, ORPHANED_PROJECT, PERSONAL
+ CLOSED, COMMUNITY, ORGANIZATION, ORPHANED_PROJECT, PERSONAL, PROJECT
}
Modified: trunk/src/main/java/cc/kune/gspace/client/actions/NewContainerBtn.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/actions/NewContainerBtn.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/gspace/client/actions/NewContainerBtn.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -75,7 +75,7 @@
stateManager.setRetrievedStateAndGo(state);
NotifyUser.hideProgress();
NotifyUser.info(i18n.tWithNT("[%s] created", "New folder created, for instance", newName));
- folderViewer.blinkTitle();
+ folderViewer.highlightTitle();
}
});
cache.removeContent(session.getCurrentStateToken());
Modified: trunk/src/main/java/cc/kune/gspace/client/actions/NewContainerMenuItem.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/actions/NewContainerMenuItem.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/gspace/client/actions/NewContainerMenuItem.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -78,7 +78,7 @@
stateManager.setRetrievedStateAndGo(state);
NotifyUser.hideProgress();
NotifyUser.info(i18n.tWithNT("[%s] created", "New folder created, for instance", newName));
- folderViewer.blinkTitle();
+ folderViewer.highlightTitle();
}
});
cache.removeContent(session.getCurrentStateToken());
Modified: trunk/src/main/java/cc/kune/gspace/client/viewers/AbstractFolderViewerPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/viewers/AbstractFolderViewerPanel.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/gspace/client/viewers/AbstractFolderViewerPanel.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -70,8 +70,8 @@
}
@Override
- public void blinkTitle() {
- contentTitle.blink();
+ public void highlightTitle() {
+ contentTitle.highlightTitle();
}
@Override
Modified: trunk/src/main/java/cc/kune/gspace/client/viewers/ContentTitleWidget.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/viewers/ContentTitleWidget.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/gspace/client/viewers/ContentTitleWidget.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -53,10 +53,6 @@
initWidget(flow);
}
- public void blink() {
- editableTitle.blink();
- }
-
public void edit() {
editableTitle.edit();
}
@@ -65,6 +61,10 @@
return editableTitle;
}
+ public void highlightTitle() {
+ editableTitle.highlightTitle();
+ }
+
public void setText(final String text) {
editableTitle.setText(text);
}
@@ -83,7 +83,7 @@
titleIcon.setVisible(hasIcon);
editableTitle.setText(title);
if (editable) {
- editableTitle.setTooltip(i18n.t("Click to edit"));
+ editableTitle.setTooltip(i18n.t("Click to rename"));
} else {
editableTitle.setTooltip("");
}
Modified: trunk/src/main/java/cc/kune/gspace/client/viewers/ContentViewerPanel.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/viewers/ContentViewerPanel.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/gspace/client/viewers/ContentViewerPanel.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -125,7 +125,7 @@
@Override
public void blinkTitle() {
- contentTitle.blink();
+ contentTitle.highlightTitle();
}
@Override
Modified: trunk/src/main/java/cc/kune/gspace/client/viewers/FolderViewerPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/viewers/FolderViewerPresenter.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/java/cc/kune/gspace/client/viewers/FolderViewerPresenter.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -81,7 +81,7 @@
void attach();
- void blinkTitle();
+ void highlightTitle();
void clear();
@@ -176,8 +176,8 @@
}
}
- public void blinkTitle() {
- getView().blinkTitle();
+ public void highlightTitle() {
+ getView().highlightTitle();
}
String calculateStyle(final int pos, final int length) {
Modified: trunk/src/main/webapp/others/kune-client-actions.xml
===================================================================
--- trunk/src/main/webapp/others/kune-client-actions.xml 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/main/webapp/others/kune-client-actions.xml 2011-07-09 20:52:00 UTC (rev 1443)
@@ -14,10 +14,10 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>Quick Notify</name>
- <installerUrl>http://code.google.com/p/wave-projects/source/browse/gadgets/wave-quick-not…
+ <installerUrl>http://code.google.com/p/wave-projects/source/browse/gadgets/wave-quick-not…
</installerUrl>
<gadgetUrl>http://wave-projects.googlecode.com/hg/gadgets/wave-quick-notify.xml
</gadgetUrl>
@@ -25,10 +25,10 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>tasklistbot</name>
- <installerUrl>http://tasklistbot.appspot.com/TaskList.xml
+ <installerUrl>http://tasklistbot.appspot.com/TaskList.xml
</installerUrl>
<gadgetUrl>http://everybodywave.appspot.com/gadget/foobar/main.xml
</gadgetUrl>
@@ -39,7 +39,7 @@
<extension>
<name>Yes/No/Mini</name>
- <installerUrl>http://mysite.verizon.net/zmyaro/mystuff/wave/ynmini.xml
+ <installerUrl>http://mysite.verizon.net/zmyaro/mystuff/wave/ynmini.xml
</installerUrl>
<gadgetUrl>http://mysite.verizon.net/zmyaro/projects/wave/gadgets/ynmini.xml
</gadgetUrl>
@@ -47,10 +47,10 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>Yes/No/Maybe/+</name>
- <installerUrl>http://everybodywave.appspot.com/gadget/foobar/xt.xml
+ <installerUrl>http://everybodywave.appspot.com/gadget/foobar/xt.xml
</installerUrl>
<gadgetUrl>http://everybodywave.appspot.com/gadget/foobar/main.xml
</gadgetUrl>
@@ -58,10 +58,10 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>Shorten URL with goo.gl</name>
- <installerUrl>http://haru1ban-wave.googlecode.com/svn/trunk/goo_gl/manifest.xml
+ <installerUrl>http://haru1ban-wave.googlecode.com/svn/trunk/goo_gl/manifest.xml
</installerUrl>
<gadgetUrl>http://haru1ban-wave.googlecode.com/svn/trunk/goo_gl/goo_gl.xml
</gadgetUrl>
@@ -69,10 +69,10 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>Poll</name>
- <installerUrl>http://wave.samuirai.de/install_poll.xml
+ <installerUrl>http://wave.samuirai.de/install_poll.xml
</installerUrl>
<gadgetUrl>http://wave.samuirai.de/poll.xml
</gadgetUrl>
@@ -80,10 +80,10 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>TaskToDo</name>
- <installerUrl>http://www.voizle.com/ToDoInstaller.xml
+ <installerUrl>http://www.voizle.com/ToDoInstaller.xml
</installerUrl>
<gadgetUrl>http://www.voizle.com/ToDo.xml
</gadgetUrl>
@@ -94,7 +94,7 @@
<extension>
<name>Picasa Gadget</name>
- <installerUrl>http://wave-picasa.googlecode.com/svn/trunk/manifest_wave_picasa.xml
+ <installerUrl>http://wave-picasa.googlecode.com/svn/trunk/manifest_wave_picasa.xml
</installerUrl>
<gadgetUrl>http://wave-picasa.googlecode.com/svn/trunk/picasa.xml
</gadgetUrl>
@@ -102,10 +102,10 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>Map</name>
- <installerUrl>http://google-wave-resources.googlecode.com/svn/trunk/samples/extensions/ga…
+ <installerUrl>http://google-wave-resources.googlecode.com/svn/trunk/samples/extensions/ga…
</installerUrl>
<gadgetUrl>http://google-wave-resources.googlecode.com/svn/trunk/samples/extensions/ga…
</gadgetUrl>
@@ -113,10 +113,10 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>MindMap</name>
- <installerUrl>http://cactus-wave.appspot.com/mindmap.xml
+ <installerUrl>http://cactus-wave.appspot.com/mindmap.xml
</installerUrl>
<gadgetUrl>http://cactus-wave.appspot.com/net.brucecooper.mindmapgadget.MindMapGadget/…
</gadgetUrl>
@@ -135,7 +135,7 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>waffle</name>
<installerUrl>http://www.waffle.dk/install.xml
@@ -186,12 +186,14 @@
<guiActionDescriptors>
- <guiActionDescriptor>
+ <guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>Map</extensionName>
<name>New Map</name>
<path>Gadget»Media</path>
- <description>Collaborate on a map of placemarks, paths, and shapes with other participants. Great for planning events and trips.</description>
+ <description>Collaborate on a map of placemarks, paths, and shapes
+ with other participants. Great for planning events and trips.
+ </description>
<new-content-title>New Map</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
@@ -209,7 +211,7 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>Picasa Gadget</extensionName>
@@ -233,13 +235,14 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>TaskToDo</extensionName>
<name>New To-Do list</name>
<path>Gadget»Tasks</path>
- <description>Make your To-Do list and mark your progress.</description>
+ <description>Make your To-Do list and mark your progress.
+ </description>
<new-content-title>New To-Do list</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
@@ -257,13 +260,14 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>Shorten URL with goo.gl</extensionName>
<name>New Shorten URL</name>
<path>Gadget»Links</path>
- <description>Shorten url with goo.gl, the new Google url shortener.(http://goo.gl/)</description>
+ <description>Shorten url with goo.gl, the new Google url
+ shortener.(http://goo.gl/)</description>
<new-content-title>New Shorten URL</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
@@ -281,14 +285,16 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
-
+
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>Poll</extensionName>
<name>New Advanced Poll</name>
<path>Gadget»Voting</path>
- <description>You can add a poll to your Wave. Accordingly you can embed the result with the Google Chart API into your Wave.</description>
+ <description>You can add a poll to your Wave. Accordingly you can
+ embed the result with the Google Chart API into your Wave.
+ </description>
<new-content-title>New Advanced Poll</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
@@ -306,14 +312,15 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
-
+
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>Yes/No/Maybe/+</extensionName>
<name>New Yes/No/Maybe/+ Voting</name>
<path>Gadget»Voting</path>
- <description>Same as Google's Yes/No/Maybe, only you can edit the titles and add new ones.</description>
+ <description>Same as Google's Yes/No/Maybe, only you can edit the
+ titles and add new ones.</description>
<new-content-title>New Yes/No/Maybe/+ Voting</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
@@ -331,13 +338,14 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>Yes/No/Mini</extensionName>
<name>New Yes/no/Mini Voting</name>
<path>Gadget»Voting</path>
- <description>A miniature version of the Yes/No/Maybe gadget.</description>
+ <description>A miniature version of the Yes/No/Maybe gadget.
+ </description>
<new-content-title>New Yes/no/Mini Voting</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
@@ -355,7 +363,7 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>tasklistbot</extensionName>
@@ -379,13 +387,14 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>Quick Notify</extensionName>
<name>New Notification</name>
<path>Gadget»Organization</path>
- <description>Quickly send a short email with a custom message to all participants.</description>
+ <description>Quickly send a short email with a custom message to
+ all participants.</description>
<new-content-title>New Notification</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
@@ -403,14 +412,15 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
-
+
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>MindMap</extensionName>
<name>New MindMap</name>
<path>Gadget»Organization</path>
- <description>Collaborate using a hierarchical mind map.</description>
+ <description>Collaborate using a hierarchical mind map.
+ </description>
<new-content-title>New MindMap</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
@@ -428,13 +438,14 @@
used yet) -->
<participants>ask</participants>
</guiActionDescriptor>
-
+
<guiActionDescriptor>
<type>wave-gadget</type>
<extensionName>Image</extensionName>
<name>New Image</name>
<path>Gadget»Media</path>
- <description>Lets you insert, resize and annotate any image from the web.</description>
+ <description>Lets you insert, resize and annotate any image from
+ the web.</description>
<new-content-title>New image</new-content-title>
<new-content-textintro></new-content-textintro>
<enabled>true</enabled>
Modified: trunk/src/test/java/cc/kune/core/server/integration/kuneservice/GroupServiceTest.java
===================================================================
--- trunk/src/test/java/cc/kune/core/server/integration/kuneservice/GroupServiceTest.java 2011-07-09 16:44:34 UTC (rev 1442)
+++ trunk/src/test/java/cc/kune/core/server/integration/kuneservice/GroupServiceTest.java 2011-07-09 20:52:00 UTC (rev 1443)
@@ -30,6 +30,7 @@
import cc.kune.core.server.integration.IntegrationTest;
import cc.kune.core.server.integration.IntegrationTestHelper;
import cc.kune.core.shared.domain.AdmissionType;
+import cc.kune.core.shared.domain.GroupListMode;
import cc.kune.core.shared.dto.GroupDTO;
import cc.kune.core.shared.dto.GroupType;
import cc.kune.core.shared.dto.LicenseDTO;
@@ -40,108 +41,134 @@
public class GroupServiceTest extends IntegrationTest {
- @Inject
- GroupFinder groupFinder;
+ @Inject
+ GroupFinder groupFinder;
- @Inject
- GroupService service;
+ @Inject
+ GroupService service;
- @Inject
- UserSession session;
+ @Inject
+ UserSession session;
- @Test
- public void createCommunity() throws Exception {
- doLogin();
+ @Test
+ public void createClosed() throws Exception {
+ doLogin();
- final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative", GroupType.COMMUNITY);
+ final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative",
+ GroupType.CLOSED);
- final LicenseDTO license = new LicenseDTO();
- license.setShortName("by-sa-v3.0");
- group.setDefaultLicense(license);
- service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
+ final LicenseDTO license = new LicenseDTO();
+ license.setShortName("by-sa-v3.0");
+ group.setDefaultLicense(license);
+ service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
- final Group groupCreated = groupFinder.findByShortName("ysei");
- assertEquals(groupCreated.getShortName(), group.getShortName());
- assertEquals(groupCreated.getLongName(), group.getLongName());
+ final Group groupCreated = groupFinder.findByShortName("ysei");
+ assertEquals(groupCreated.getShortName(), group.getShortName());
+ assertEquals(groupCreated.getLongName(), group.getLongName());
+ assertEquals(groupCreated.getAdmissionType(), AdmissionType.Closed);
+ assertEquals(groupCreated.getGroupType(), GroupType.CLOSED);
+ assertEquals(GroupListMode.NORMAL,
+ groupCreated.getSocialNetwork().getAccessLists().getViewers().getMode());
+ }
- assertEquals(groupCreated.getAdmissionType(), AdmissionType.Open);
- assertEquals(groupCreated.getGroupType(), GroupType.COMMUNITY);
- }
+ @Test
+ public void createCommunity() throws Exception {
+ doLogin();
- @Test(expected = Exception.class)
- public void createGroupNotLogged() throws Exception {
- final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative", GroupType.PROJECT);
- service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
- }
+ final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative",
+ GroupType.COMMUNITY);
- @Test(expected = UserMustBeLoggedException.class)
- public void createGroupNullUserHash() throws Exception {
- doLogin();
- final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative", GroupType.PROJECT);
- service.createNewGroup(null, group, "Public desc", "tag1 tag2", null);
- }
+ final LicenseDTO license = new LicenseDTO();
+ license.setShortName("by-sa-v3.0");
+ group.setDefaultLicense(license);
+ service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
- @Test
- public void createGroupUserLogged() throws Exception {
- doLogin();
+ final Group groupCreated = groupFinder.findByShortName("ysei");
+ assertEquals(groupCreated.getShortName(), group.getShortName());
+ assertEquals(groupCreated.getLongName(), group.getLongName());
- final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative", GroupType.PROJECT);
+ assertEquals(groupCreated.getAdmissionType(), AdmissionType.Open);
+ assertEquals(groupCreated.getGroupType(), GroupType.COMMUNITY);
+ }
- final LicenseDTO license = new LicenseDTO();
- license.setShortName("by-sa-v3.0");
- group.setDefaultLicense(license);
- service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
+ @Test(expected = Exception.class)
+ public void createGroupNotLogged() throws Exception {
+ final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative",
+ GroupType.PROJECT);
+ service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
+ }
- final Group groupCreated = groupFinder.findByShortName("ysei");
- assertEquals(groupCreated.getShortName(), group.getShortName());
- assertEquals(groupCreated.getLongName(), group.getLongName());
+ @Test(expected = UserMustBeLoggedException.class)
+ public void createGroupNullUserHash() throws Exception {
+ doLogin();
+ final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative",
+ GroupType.PROJECT);
+ service.createNewGroup(null, group, "Public desc", "tag1 tag2", null);
+ }
- assertEquals(groupCreated.getAdmissionType(), AdmissionType.Moderated);
- assertEquals(groupCreated.getGroupType(), GroupType.PROJECT);
- }
+ @Test
+ public void createGroupUserLogged() throws Exception {
+ doLogin();
- @Test
- public void createOrganization() throws Exception {
- doLogin();
+ final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative",
+ GroupType.PROJECT);
- final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative", GroupType.ORGANIZATION);
+ final LicenseDTO license = new LicenseDTO();
+ license.setShortName("by-sa-v3.0");
+ group.setDefaultLicense(license);
+ service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
- final LicenseDTO license = new LicenseDTO();
- license.setShortName("by-sa-v3.0");
- group.setDefaultLicense(license);
- service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
+ final Group groupCreated = groupFinder.findByShortName("ysei");
+ assertEquals(groupCreated.getShortName(), group.getShortName());
+ assertEquals(groupCreated.getLongName(), group.getLongName());
- final Group groupCreated = groupFinder.findByShortName("ysei");
- assertEquals(groupCreated.getShortName(), group.getShortName());
- assertEquals(groupCreated.getLongName(), group.getLongName());
- assertEquals(groupCreated.getAdmissionType(), AdmissionType.Moderated);
- assertEquals(groupCreated.getGroupType(), GroupType.ORGANIZATION);
- }
+ assertEquals(groupCreated.getAdmissionType(), AdmissionType.Moderated);
+ assertEquals(groupCreated.getGroupType(), GroupType.PROJECT);
+ }
- @Test
- public void createOrphanedProject() throws Exception {
- doLogin();
+ @Test
+ public void createOrganization() throws Exception {
+ doLogin();
- final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative",
- GroupType.ORPHANED_PROJECT);
+ final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative",
+ GroupType.ORGANIZATION);
- final LicenseDTO license = new LicenseDTO();
- license.setShortName("by-sa-v3.0");
- group.setDefaultLicense(license);
- service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
+ final LicenseDTO license = new LicenseDTO();
+ license.setShortName("by-sa-v3.0");
+ group.setDefaultLicense(license);
+ service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
- final Group groupCreated = groupFinder.findByShortName("ysei");
- assertEquals(groupCreated.getShortName(), group.getShortName());
- assertEquals(groupCreated.getLongName(), group.getLongName());
- assertEquals(groupCreated.getAdmissionType(), AdmissionType.Open);
- assertEquals(groupCreated.getGroupType(), GroupType.ORPHANED_PROJECT);
- assertEquals(0, groupCreated.getSocialNetwork().getAccessLists().getAdmins().getList().size());
- assertEquals(0, groupCreated.getSocialNetwork().getAccessLists().getEditors().getList().size());
- }
+ final Group groupCreated = groupFinder.findByShortName("ysei");
+ assertEquals(groupCreated.getShortName(), group.getShortName());
+ assertEquals(groupCreated.getLongName(), group.getLongName());
+ assertEquals(groupCreated.getAdmissionType(), AdmissionType.Moderated);
+ assertEquals(groupCreated.getGroupType(), GroupType.ORGANIZATION);
+ }
- @Before
- public void init() {
- new IntegrationTestHelper(this);
- }
+ @Test
+ public void createOrphanedProject() throws Exception {
+ doLogin();
+ final GroupDTO group = new GroupDTO("ysei", "Yellow Submarine Environmental Initiative",
+ GroupType.ORPHANED_PROJECT);
+
+ final LicenseDTO license = new LicenseDTO();
+ license.setShortName("by-sa-v3.0");
+ group.setDefaultLicense(license);
+ service.createNewGroup(session.getHash(), group, "Public desc", "tag1 tag2", null);
+
+ final Group groupCreated = groupFinder.findByShortName("ysei");
+ assertEquals(groupCreated.getShortName(), group.getShortName());
+ assertEquals(groupCreated.getLongName(), group.getLongName());
+ assertEquals(groupCreated.getAdmissionType(), AdmissionType.Open);
+ assertEquals(groupCreated.getGroupType(), GroupType.ORPHANED_PROJECT);
+ assertEquals(0, groupCreated.getSocialNetwork().getAccessLists().getAdmins().getList().size());
+ assertEquals(0, groupCreated.getSocialNetwork().getAccessLists().getEditors().getList().size());
+ }
+
+ @Before
+ public void init() {
+ new IntegrationTestHelper(this);
+ }
+
}
1
0
Author: vjrj_
Date: 2011-07-09 18:44:34 +0200 (Sat, 09 Jul 2011)
New Revision: 1442
Added:
trunk/src/main/java/cc/kune/chat/client/KuneBrowserFocusManager.java
trunk/src/main/java/cc/kune/core/client/events/WindowFocusEvent.java
trunk/src/main/java/cc/kune/wave/server/AbstractBaseRobotAgent.java
trunk/src/main/java/cc/kune/wave/server/KuneAgent.java
trunk/src/main/java/com/google/wave/splash/text/ContentNewUnrenderer.java
trunk/src/main/java/com/google/wave/splash/text/HtmlRawViewImpl.java
trunk/src/main/java/com/google/wave/splash/text/UnrenderUtils.java
trunk/src/test/java/cc/kune/wave/server/KuneAgentTest.java
trunk/src/test/java/com/
trunk/src/test/java/com/google/
trunk/src/test/java/com/google/wave/
trunk/src/test/java/com/google/wave/splash/
trunk/src/test/java/com/google/wave/splash/text/
trunk/src/test/java/com/google/wave/splash/text/ContentNewUnrendererTest.java
trunk/src/test/java/com/google/wave/splash/text/ContentUnrendererTest.java
Modified:
trunk/src/main/java/cc/kune/chat/client/KuneHablarSignals.java
trunk/src/main/java/cc/kune/chat/client/actions/OpenChatAction.java
trunk/src/main/java/cc/kune/chat/public/kune-hablar.css
trunk/src/main/java/cc/kune/common/client/actions/gwtui/AbstractGwtButtonGui.java
trunk/src/main/java/cc/kune/common/client/actions/gwtui/GwtMenuGui.java
trunk/src/main/java/cc/kune/common/client/actions/ui/AbstractGuiItem.java
trunk/src/main/java/cc/kune/common/client/actions/ui/descrip/AbstractGuiActionDescrip.java
trunk/src/main/java/cc/kune/common/client/actions/ui/descrip/GuiActionDescrip.java
trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java
trunk/src/main/java/cc/kune/common/client/tooltip/TooltipTimers.java
trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPresenter.java
trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorViewImpl.java
trunk/src/main/java/cc/kune/core/client/state/StateManagerDefault.java
trunk/src/main/java/cc/kune/core/public/ws.css
trunk/src/main/java/cc/kune/gspace/client/GSpaceArmorImpl.ui.xml
trunk/src/main/java/cc/kune/gspace/client/options/GroupOptions.java
trunk/src/main/java/cc/kune/gspace/client/options/GroupOptionsPresenter.java
trunk/src/main/java/cc/kune/gspace/client/resources/GSpaceArmorResources.java
trunk/src/main/java/cc/kune/gspace/client/resources/gSpaceArmor.css
trunk/src/main/java/cc/kune/gspace/client/resources/gSpaceArmorTheme.css
trunk/src/main/java/cc/kune/gspace/client/style/GSpaceBackManagerImpl.java
trunk/src/main/java/cc/kune/wave/server/KuneWaveManagerDefault.java
trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java
trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java
trunk/src/test/java/cc/kune/wave/server/KuneWaveManagerDefaultTest.java
Log:
Unrender wave revisited; Tooltips show on demand; css fixes; chatroom message when not logged; On window focus tooltip; Background fix
Added: trunk/src/main/java/cc/kune/chat/client/KuneBrowserFocusManager.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/KuneBrowserFocusManager.java (rev 0)
+++ trunk/src/main/java/cc/kune/chat/client/KuneBrowserFocusManager.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,58 @@
+package cc.kune.chat.client;
+
+import cc.kune.core.client.events.WindowFocusEvent;
+
+import com.calclab.hablar.chat.client.ui.ChatPresenter;
+import com.calclab.hablar.chat.client.ui.PairChatPresenter;
+import com.calclab.hablar.core.client.browser.BrowserFocusHandler;
+import com.calclab.hablar.core.client.browser.BrowserFocusHandler.BrowserFocusListener;
+import com.calclab.hablar.core.client.mvp.HablarEventBus;
+import com.calclab.hablar.core.client.page.Page;
+import com.calclab.hablar.core.client.page.PagePresenter.Visibility;
+import com.calclab.hablar.core.client.page.events.VisibilityChangedEvent;
+import com.calclab.hablar.core.client.page.events.VisibilityChangedHandler;
+import com.calclab.hablar.rooms.client.room.RoomPresenter;
+import com.calclab.hablar.signals.client.unattended.UnattendedPagesManager;
+import com.google.gwt.event.shared.EventBus;
+
+/**
+ * This class is a workaround to clear the focus on the active chat page FIXME:
+ * workaround to clear the focus <br/>
+ *
+ * <br/>
+ * TODO: change the page/header visibility system... quite a big job
+ *
+ *
+ */
+public class KuneBrowserFocusManager {
+
+ protected ChatPresenter currentFocused;
+
+ public KuneBrowserFocusManager(final EventBus kuneEventBus, final HablarEventBus eventBus,
+ final UnattendedPagesManager unattendedManager, final BrowserFocusHandler handler) {
+
+ eventBus.addHandler(VisibilityChangedEvent.TYPE, new VisibilityChangedHandler() {
+ @Override
+ public void onVisibilityChanged(final VisibilityChangedEvent event) {
+ if (event.getVisibility() == Visibility.focused) {
+ final Page<?> page = event.getPage();
+ if (PairChatPresenter.TYPE.equals(page.getType()) || RoomPresenter.TYPE.equals(page.getType())) {
+ currentFocused = (ChatPresenter) page;
+ }
+ }
+ }
+ });
+
+ handler.setFocusListener(new BrowserFocusListener() {
+ @Override
+ public void onBrowserFocusChanged(final boolean hasFocus) {
+ kuneEventBus.fireEvent(new WindowFocusEvent(hasFocus));
+ if (currentFocused != null) {
+ if (hasFocus == false) {
+ currentFocused.getDisplay().setTextBoxFocus(false);
+ }
+ }
+ }
+ });
+ }
+}
Modified: trunk/src/main/java/cc/kune/chat/client/KuneHablarSignals.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/KuneHablarSignals.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/chat/client/KuneHablarSignals.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -28,7 +28,6 @@
import com.calclab.hablar.core.client.mvp.HablarEventBus;
import com.calclab.hablar.signals.client.SignalMessages;
import com.calclab.hablar.signals.client.SignalPreferences;
-import com.calclab.hablar.signals.client.browserfocus.BrowserFocusManager;
import com.calclab.hablar.signals.client.notifications.NotificationManager;
import com.calclab.hablar.signals.client.preferences.SignalsPreferencesPresenter;
import com.calclab.hablar.signals.client.preferences.SignalsPreferencesWidget;
@@ -46,65 +45,64 @@
*/
public class KuneHablarSignals {
- public static SignalMessages signalMessages;
+ public static SignalMessages signalMessages;
- /**
- * Gets the {@link SignalMessages} object containing the internationalised
- * messages
- *
- * @return the SignalMessages object containing the internationalised
- * messages
- */
- public static SignalMessages i18n() {
- return signalMessages;
- }
+ /**
+ * Gets the {@link SignalMessages} object containing the internationalised
+ * messages
+ *
+ * @return the SignalMessages object containing the internationalised messages
+ */
+ public static SignalMessages i18n() {
+ return signalMessages;
+ }
- /**
- * Sets the {@link SignalMessages} object containing the internationalised
- * messages
- *
- * @param t
- * the messages object
- */
- public static void setMessages(final SignalMessages t) {
- KuneHablarSignals.signalMessages = t;
- }
+ /**
+ * Sets the {@link SignalMessages} object containing the internationalised
+ * messages
+ *
+ * @param t
+ * the messages object
+ */
+ public static void setMessages(final SignalMessages t) {
+ KuneHablarSignals.signalMessages = t;
+ }
- // FIXME: move to gin
- @SuppressWarnings("deprecation")
- public KuneHablarSignals(final EventBus eventBus, final XmppSession session, final Hablar hablar,
- final ChatClientAction action) {
- final HablarEventBus hablarEventBus = hablar.getEventBus();
- final PrivateStorageManager storageManager = Suco.get(PrivateStorageManager.class);
+ // FIXME: move to gin
+ @SuppressWarnings("deprecation")
+ public KuneHablarSignals(final EventBus kuneEventBus, final XmppSession session, final Hablar hablar,
+ final ChatClientAction action) {
+ final HablarEventBus hablarEventBus = hablar.getEventBus();
+ final PrivateStorageManager storageManager = Suco.get(PrivateStorageManager.class);
- final HasText titleDisplay = new HasText() {
- @Override
- public String getText() {
- return Window.getTitle();
- }
+ final HasText titleDisplay = new HasText() {
+ @Override
+ public String getText() {
+ return Window.getTitle();
+ }
- @Override
- public void setText(final String text) {
- Window.setTitle(text);
- }
- };
- final SignalPreferences preferences = new SignalPreferences();
+ @Override
+ public void setText(final String text) {
+ Window.setTitle(text);
+ }
+ };
+ final SignalPreferences preferences = new SignalPreferences();
- final UnattendedPagesManager manager = new UnattendedPagesManager(hablarEventBus,
- BrowserFocusHandler.getInstance());
- new BrowserFocusManager(hablarEventBus, manager, BrowserFocusHandler.getInstance());
- new UnattendedPresenter(hablarEventBus, preferences, manager, titleDisplay);
- new KuneUnattendedPresenter(eventBus, hablarEventBus, preferences, manager, action);
- final NotificationManager notificationManager = new NotificationManager(hablarEventBus, preferences);
+ final UnattendedPagesManager manager = new UnattendedPagesManager(hablarEventBus,
+ BrowserFocusHandler.getInstance());
+ new KuneBrowserFocusManager(kuneEventBus, hablarEventBus, manager, BrowserFocusHandler.getInstance());
+ new UnattendedPresenter(hablarEventBus, preferences, manager, titleDisplay);
+ new KuneUnattendedPresenter(kuneEventBus, hablarEventBus, preferences, manager, action);
+ final NotificationManager notificationManager = new NotificationManager(hablarEventBus, preferences);
- // notificationManager.addNotifier((BrowserPopupHablarNotifier)
- // GWT.create(BrowserPopupHablarNotifier.class),
- // true);
- notificationManager.addNotifier((KuneChatNotifier) GWT.create(KuneChatNotifier.class), true);
+ // notificationManager.addNotifier((BrowserPopupHablarNotifier)
+ // GWT.create(BrowserPopupHablarNotifier.class),
+ // true);
+ notificationManager.addNotifier((KuneChatNotifier) GWT.create(KuneChatNotifier.class), true);
- final SignalsPreferencesPresenter preferencesPage = new SignalsPreferencesPresenter(session, storageManager,
- hablarEventBus, preferences, new SignalsPreferencesWidget(), notificationManager);
- hablar.addPage(preferencesPage, UserContainer.ROL);
- }
+ final SignalsPreferencesPresenter preferencesPage = new SignalsPreferencesPresenter(session,
+ storageManager, hablarEventBus, preferences, new SignalsPreferencesWidget(), notificationManager);
+ hablar.addPage(preferencesPage, UserContainer.ROL);
+ }
}
Modified: trunk/src/main/java/cc/kune/chat/client/actions/OpenChatAction.java
===================================================================
--- trunk/src/main/java/cc/kune/chat/client/actions/OpenChatAction.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/chat/client/actions/OpenChatAction.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -2,11 +2,17 @@
import cc.kune.chat.client.ChatClient;
import cc.kune.common.client.actions.ActionEvent;
+import cc.kune.common.client.notify.NotifyLevel;
import cc.kune.core.client.actions.RolAction;
+import cc.kune.core.client.auth.SignIn;
import cc.kune.core.client.state.Session;
+import cc.kune.core.client.state.SiteTokens;
+import cc.kune.core.client.state.StateManager;
+import cc.kune.core.client.state.TokenUtils;
import cc.kune.core.shared.dto.AbstractContentSimpleDTO;
import cc.kune.core.shared.dto.AccessRolDTO;
import cc.kune.core.shared.dto.StateContainerDTO;
+import cc.kune.core.shared.i18n.I18nTranslationService;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -14,22 +20,36 @@
public class OpenChatAction extends RolAction {
private final Provider<ChatClient> chatClient;
+ private final I18nTranslationService i18n;
private final Session session;
+ private final Provider<SignIn> signIn;
+ private final StateManager stateManager;
@Inject
- public OpenChatAction(final Provider<ChatClient> chatClient, final Session session) {
- super(AccessRolDTO.Viewer, true);
+ public OpenChatAction(final Provider<ChatClient> chatClient, final Session session,
+ final StateManager stateManager, final Provider<SignIn> signIn, final I18nTranslationService i18n) {
+ super(AccessRolDTO.Viewer, false);
this.chatClient = chatClient;
this.session = session;
+ this.stateManager = stateManager;
+ this.signIn = signIn;
+ this.i18n = i18n;
}
@Override
public void actionPerformed(final ActionEvent event) {
- final ChatClient chat = chatClient.get();
- final Object target = event.getTarget();
- final String roomName = (target instanceof AbstractContentSimpleDTO) ? ((AbstractContentSimpleDTO) target).getName()
- : ((StateContainerDTO) session.getCurrentState()).getTitle();
- chat.joinRoom(roomName, session.getCurrentUserInfo().getShortName());
- chat.show();
+ if (session.isLogged()) {
+ final ChatClient chat = chatClient.get();
+ final Object target = event.getTarget();
+ final String roomName = (target instanceof AbstractContentSimpleDTO) ? ((AbstractContentSimpleDTO) target).getName()
+ : ((StateContainerDTO) session.getCurrentState()).getTitle();
+ chat.joinRoom(roomName, session.getCurrentUserInfo().getShortName());
+ chat.show();
+ } else {
+ signIn.get().setErrorMessage(i18n.t("Sign in or create an account to access to this room"),
+ NotifyLevel.info);
+ stateManager.gotoHistoryToken(TokenUtils.addRedirect(SiteTokens.SIGNIN,
+ session.getCurrentStateToken().toString()));
+ }
}
}
\ No newline at end of file
Modified: trunk/src/main/java/cc/kune/chat/public/kune-hablar.css
===================================================================
--- trunk/src/main/java/cc/kune/chat/public/kune-hablar.css 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/chat/public/kune-hablar.css 2011-07-09 16:44:34 UTC (rev 1442)
@@ -99,7 +99,6 @@
border-right: 1px solid #e9e9e9;
}
*/
-
input[disabled] {
background-color: #e9e9e9;
color: black;
@@ -231,8 +230,8 @@
}
/** IE6 ZINDEX BUG **/
-.hablar-HablarWidget {
- /* z-index: 1; */
+.hablar-HablarWidget { /* z-index: 1; */
+
}
html {
@@ -599,4 +598,14 @@
.gwt-TextArea {
border: 1px solid #bbbbbb;
-}
\ No newline at end of file
+}
+
+#gwt-debug-DoubleList-selectAll,#gwt-debug-DoubleList-selectSome,#gwt-debug-DoubleList-deselectAll,#gwt-debug-DoubleList-deselectSome
+ {
+ margin-left: -6px;
+}
+
+.hablar-RosterGroupWidget {
+ -moz-user-select: none;
+ -khtml-user-select: none;
+}
Modified: trunk/src/main/java/cc/kune/common/client/actions/gwtui/AbstractGwtButtonGui.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/actions/gwtui/AbstractGwtButtonGui.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/common/client/actions/gwtui/AbstractGwtButtonGui.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -43,6 +43,7 @@
protected boolean enableTongle;
private IconLabel iconLabel;
private boolean isChild;
+ private Tooltip tooltip;
public AbstractGwtButtonGui() {
this(null, false);
@@ -154,10 +155,10 @@
}
@Override
- public void setToolTipText(final String tooltip) {
- if (tooltip != null && !tooltip.isEmpty()) {
+ public void setToolTipText(final String tooltipText) {
+ if (tooltipText != null && !tooltipText.isEmpty()) {
final KeyStroke key = (KeyStroke) descriptor.getValue(Action.ACCELERATOR_KEY);
- Tooltip.to(button, key == null ? tooltip : tooltip + key.toString());
+ tooltip = Tooltip.to(button, key == null ? tooltipText : tooltipText + key.toString());
}
}
@@ -171,4 +172,15 @@
return !descriptor.isChild();
}
+ @Override
+ protected void toogleTooltipVisible() {
+ if (tooltip != null) {
+ if (tooltip.isVisible()) {
+ tooltip.hide();
+ } else {
+ tooltip.showTemporally();
+ }
+ }
+ }
+
}
Modified: trunk/src/main/java/cc/kune/common/client/actions/gwtui/GwtMenuGui.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/actions/gwtui/GwtMenuGui.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/common/client/actions/gwtui/GwtMenuGui.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -56,7 +56,7 @@
notStandAlone = !((MenuDescriptor) descriptor).isStandalone();
if (notStandAlone) {
button = new Button();
- // button.setStylePrimaryName("oc-button");
+ button.removeStyleName("gwt-Button");
iconLabel = new IconLabel("");
final ImageResource rightIcon = ((MenuDescriptor) descriptor).getRightIcon();
if (rightIcon != null) {
Modified: trunk/src/main/java/cc/kune/common/client/actions/ui/AbstractGuiItem.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/actions/ui/AbstractGuiItem.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/common/client/actions/ui/AbstractGuiItem.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -99,6 +99,8 @@
setToolTipText((String) newValue);
} else if (event.getPropertyName().equals(GuiActionDescrip.VISIBLE)) {
setVisible((Boolean) newValue);
+ } else if (event.getPropertyName().equals(GuiActionDescrip.TOOGLE_TOOLTIP_VISIBLE)) {
+ toogleTooltipVisible();
} else if (event.getPropertyName().equals(Action.STYLES)) {
setStyles((String) newValue);
}
@@ -160,6 +162,11 @@
protected abstract void setText(String text);
+ protected void toogleTooltipVisible() {
+ // do nothing by default
+ return;
+ }
+
protected abstract void setToolTipText(String text);
private void setVisible(final Boolean visible) {
Modified: trunk/src/main/java/cc/kune/common/client/actions/ui/descrip/AbstractGuiActionDescrip.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/actions/ui/descrip/AbstractGuiActionDescrip.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/common/client/actions/ui/descrip/AbstractGuiActionDescrip.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -33,244 +33,255 @@
*/
public abstract class AbstractGuiActionDescrip extends ChangeableObject implements GuiActionDescrip {
- /** The action. */
- private final AbstractAction action;
+ /** The action. */
+ private final AbstractAction action;
- private final List<GuiAddCondition> addConditions;
+ private final List<GuiAddCondition> addConditions;
- /** The item DOM id. */
- private String id;
+ /** The item DOM id. */
+ private String id;
- /** The item location. */
- private String location;
+ /** The item location. */
+ private String location;
- protected GuiActionDescrip parent = NO_PARENT;
+ protected GuiActionDescrip parent = NO_PARENT;
- /** The position where the item will be inserted. */
- private int position;
+ /** The position where the item will be inserted. */
+ private int position;
- /**
- * Instantiates a new abstract ui action descriptor. This is used for
- * describe UI button, menus, menu items and so on
- *
- * @param action
- * the action
- */
- public AbstractGuiActionDescrip(final AbstractAction action) {
- this.action = action;
- putValue(Action.ENABLED, Boolean.TRUE);
- putValue(VISIBLE, Boolean.TRUE);
- position = NO_POSITION;
- parent = NO_PARENT;
- addConditions = new ArrayList<GuiAddCondition>();
- }
+ /**
+ * Instantiates a new abstract ui action descriptor. This is used for describe
+ * UI button, menus, menu items and so on
+ *
+ * @param action
+ * the action
+ */
+ public AbstractGuiActionDescrip(final AbstractAction action) {
+ this.action = action;
+ putValue(Action.ENABLED, Boolean.TRUE);
+ putValue(VISIBLE, Boolean.TRUE);
+ position = NO_POSITION;
+ parent = NO_PARENT;
+ addConditions = new ArrayList<GuiAddCondition>();
+ }
- @Override
- public void add(final GuiAddCondition addCondition) {
- addConditions.add(addCondition);
- }
+ @Override
+ public void add(final GuiAddCondition addCondition) {
+ addConditions.add(addCondition);
+ }
- @Override
- public void fire(final ActionEvent event) {
- action.actionPerformed(event);
- }
+ @Override
+ public void fire(final ActionEvent event) {
+ action.actionPerformed(event);
+ }
- @Override
- public AbstractAction getAction() {
- return action;
- }
+ @Override
+ public AbstractAction getAction() {
+ return action;
+ }
- @Override
- public String getId() {
- return id;
- }
+ @Override
+ public String getId() {
+ return id;
+ }
- /**
- * Gets the location, a string used to group actions with locations (top
- * bar, bottom bar, user bar...).
- *
- * @return the location
- */
- @Override
- public String getLocation() {
- return location;
- }
+ /**
+ * Gets the location, a string used to group actions with locations (top bar,
+ * bottom bar, user bar...).
+ *
+ * @return the location
+ */
+ @Override
+ public String getLocation() {
+ return location;
+ }
- @Override
- public GuiActionDescrip getParent() {
- return parent;
- }
+ @Override
+ public GuiActionDescrip getParent() {
+ return parent;
+ }
- /**
- * Gets the position.
- *
- * @return the position
- */
- @Override
- public int getPosition() {
- return position;
- }
+ /**
+ * Gets the position.
+ *
+ * @return the position
+ */
+ @Override
+ public int getPosition() {
+ return position;
+ }
- @Override
- public Object getTarget() {
- return getValue(TARGET);
- }
+ @Override
+ public Object getTarget() {
+ return getValue(TARGET);
+ }
- @Override
- public abstract Class<?> getType();
+ @Override
+ public abstract Class<?> getType();
- @Override
- /**
- * We try to get the gui property (for instance the name) and if it's empty we try to get the same property in actions. This permit to have several gui items with the same action but different gui properties (like text descriptions) if necessary.
- */
- public Object getValue(final String key) {
- final Object guiValue = super.getValue(key);
- if (guiValue == null) {
- return action.getValue(key);
- } else {
- return guiValue;
- }
+ @Override
+ /**
+ * We try to get the gui property (for instance the name) and if it's empty we try to get the same property in actions. This permit to have several gui items with the same action but different gui properties (like text descriptions) if necessary.
+ */
+ public Object getValue(final String key) {
+ final Object guiValue = super.getValue(key);
+ if (guiValue == null) {
+ return action.getValue(key);
+ } else {
+ return guiValue;
}
+ }
- @Override
- public boolean hasTarget() {
- return getValue(TARGET) != null;
- }
+ @Override
+ public boolean hasTarget() {
+ return getValue(TARGET) != null;
+ }
- @Override
- public boolean isChild() {
- return !parent.equals(NO_PARENT);
- }
+ @Override
+ public boolean isChild() {
+ return !parent.equals(NO_PARENT);
+ }
- @Override
- public boolean isEnabled() {
- return (Boolean) getValue(Action.ENABLED);
- }
+ @Override
+ public boolean isEnabled() {
+ return (Boolean) getValue(Action.ENABLED);
+ }
- @Override
- public boolean isVisible() {
- return (Boolean) getValue(VISIBLE);
- }
+ @Override
+ public boolean isVisible() {
+ return (Boolean) getValue(VISIBLE);
+ }
- @Override
- public boolean mustBeAdded() {
- final boolean result = true;
- for (final GuiAddCondition addCondition : addConditions) {
- if (!addCondition.mustBeAdded(this)) {
- return false;
- }
- }
- return result;
+ @Override
+ public boolean mustBeAdded() {
+ final boolean result = true;
+ for (final GuiAddCondition addCondition : addConditions) {
+ if (!addCondition.mustBeAdded(this)) {
+ return false;
+ }
}
+ return result;
+ }
- @Override
- public void setEnabled(final boolean enabled) {
- putValue(Action.ENABLED, enabled);
- }
+ @Override
+ public void setEnabled(final boolean enabled) {
+ putValue(Action.ENABLED, enabled);
+ }
- @Override
- public void setId(final String id) {
- this.id = id;
- }
+ @Override
+ public void setId(final String id) {
+ this.id = id;
+ }
- /**
- * If we have several toolbars, we can group with the "location" string key
- * actions that must be in the same location (ex: top bar, bottom bar, and
- * so on).
- *
- * @param location
- * the new location
- */
- @Override
- public void setLocation(final String location) {
- this.location = location;
- }
+ /**
+ * If we have several toolbars, we can group with the "location" string key
+ * actions that must be in the same location (ex: top bar, bottom bar, and so
+ * on).
+ *
+ * @param location
+ * the new location
+ */
+ @Override
+ public void setLocation(final String location) {
+ this.location = location;
+ }
- @Override
- public void setParent(final GuiActionDescrip parent) {
- this.parent = parent;
- }
+ @Override
+ public void setParent(final GuiActionDescrip parent) {
+ this.parent = parent;
+ }
- /**
- * Sets the position (where the UI element will be positioned, for instance
- * in a toolbar or in a menu).
- *
- * @param position
- * the new position
- */
- @Override
- public void setPosition(final int position) {
- this.position = position;
- }
+ /**
+ * Sets the position (where the UI element will be positioned, for instance in
+ * a toolbar or in a menu).
+ *
+ * @param position
+ * the new position
+ */
+ @Override
+ public void setPosition(final int position) {
+ this.position = position;
+ }
- @Override
- public void setStyles(final String styles) {
- putValue(Action.STYLES, styles);
- }
+ @Override
+ public void setStyles(final String styles) {
+ putValue(Action.STYLES, styles);
+ }
- @Override
- public void setTarget(final Object object) {
- putValue(TARGET, object);
- }
+ @Override
+ public void setTarget(final Object object) {
+ putValue(TARGET, object);
+ }
- @Override
- public void setVisible(final boolean visible) {
- putValue(VISIBLE, visible);
- }
+ @Override
+ public void setVisible(final boolean visible) {
+ putValue(VISIBLE, visible);
+ }
- @Override
- public String toString() {
- final String name = (String) getValue(Action.NAME);
- final String tooltip = (String) getValue(Action.SHORT_DESCRIPTION);
- return "[GuiActionDescrip: " + getClass().getName() + (name == null ? "" : " " + name)
- + (tooltip == null ? "" : " " + tooltip) + "]";
- }
+ @Override
+ public void toggleTooltipVisible() {
+ final Object value = getValue(TOOGLE_TOOLTIP_VISIBLE);
+ putValue(TOOGLE_TOOLTIP_VISIBLE, value == null ? true : !(Boolean) value);
+ }
- @Override
- public GuiActionDescrip withIcon(final Object icon) {
- super.putValue(Action.SMALL_ICON, icon);
- return this;
- }
+ @Override
+ public void toogleVisible() {
+ putValue(VISIBLE, !isVisible());
+ }
- @Override
- public GuiActionDescrip withIconCls(final String icon) {
- putValue(Action.SMALL_ICON, icon);
- return this;
- }
+ @Override
+ public String toString() {
+ final String name = (String) getValue(Action.NAME);
+ final String tooltip = (String) getValue(Action.SHORT_DESCRIPTION);
+ return "[GuiActionDescrip: " + getClass().getName() + (name == null ? "" : " " + name)
+ + (tooltip == null ? "" : " " + tooltip) + "]";
+ }
- @Override
- public GuiActionDescrip withId(final String id) {
- setId(id);
- return this;
- }
+ @Override
+ public GuiActionDescrip withIcon(final Object icon) {
+ super.putValue(Action.SMALL_ICON, icon);
+ return this;
+ }
- @Override
- public GuiActionDescrip withParent(final GuiActionDescrip parent) {
- setParent(parent);
- return this;
- }
+ @Override
+ public GuiActionDescrip withIconCls(final String icon) {
+ putValue(Action.SMALL_ICON, icon);
+ return this;
+ }
- @Override
- public GuiActionDescrip withShortcut(final KeyStroke shortcut) {
- putValue(Action.ACCELERATOR_KEY, shortcut);
- return this;
- }
+ @Override
+ public GuiActionDescrip withId(final String id) {
+ setId(id);
+ return this;
+ }
- @Override
- public GuiActionDescrip withStyles(final String styles) {
- setStyles(styles);
- return this;
- }
+ @Override
+ public GuiActionDescrip withParent(final GuiActionDescrip parent) {
+ setParent(parent);
+ return this;
+ }
- @Override
- public GuiActionDescrip withText(final String text) {
- putValue(Action.NAME, text);
- return this;
- }
+ @Override
+ public GuiActionDescrip withShortcut(final KeyStroke shortcut) {
+ putValue(Action.ACCELERATOR_KEY, shortcut);
+ return this;
+ }
- @Override
- public GuiActionDescrip withToolTip(final String tooltip) {
- putValue(Action.SHORT_DESCRIPTION, tooltip);
- return this;
- }
+ @Override
+ public GuiActionDescrip withStyles(final String styles) {
+ setStyles(styles);
+ return this;
+ }
+
+ @Override
+ public GuiActionDescrip withText(final String text) {
+ putValue(Action.NAME, text);
+ return this;
+ }
+
+ @Override
+ public GuiActionDescrip withToolTip(final String tooltip) {
+ putValue(Action.SHORT_DESCRIPTION, tooltip);
+ return this;
+ }
}
Modified: trunk/src/main/java/cc/kune/common/client/actions/ui/descrip/GuiActionDescrip.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/actions/ui/descrip/GuiActionDescrip.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/common/client/actions/ui/descrip/GuiActionDescrip.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -26,88 +26,94 @@
public interface GuiActionDescrip {
- public static final AbstractGuiActionDescrip NO_PARENT = new NoParentGuiActionDescriptor();
+ public static final AbstractGuiActionDescrip NO_PARENT = new NoParentGuiActionDescriptor();
- public static final int NO_POSITION = -1;
+ public static final int NO_POSITION = -1;
- /**
- * {@link #TARGET} is used to associate a {@link #AbstractGuiActionDescrip}
- * with an object like groups, group names, users, and so on, and used to
- * execute actions against these targets
- */
- public static final String TARGET = "target";
+ /**
+ * {@link #TARGET} is used to associate a {@link #AbstractGuiActionDescrip}
+ * with an object like groups, group names, users, and so on, and used to
+ * execute actions against these targets
+ */
+ public static final String TARGET = "target";
- public static final String VISIBLE = "visibleprop";
+ public static final String TOOGLE_TOOLTIP_VISIBLE = "toogle-tooltip-visible";
- void add(final GuiAddCondition addCondition);
+ public static final String VISIBLE = "visibleprop";
- void addPropertyChangeListener(final PropertyChangeListener listener);
+ void add(final GuiAddCondition addCondition);
- void fire(final ActionEvent event);
+ void addPropertyChangeListener(final PropertyChangeListener listener);
- AbstractAction getAction();
+ void fire(final ActionEvent event);
- String getId();
+ AbstractAction getAction();
- Object[] getKeys();
+ String getId();
- String getLocation();
+ Object[] getKeys();
- GuiActionDescrip getParent();
+ String getLocation();
- int getPosition();
+ GuiActionDescrip getParent();
- PropertyChangeListener[] getPropertyChangeListeners();
+ int getPosition();
- Object getTarget();
+ PropertyChangeListener[] getPropertyChangeListeners();
- Class<?> getType();
+ Object getTarget();
- Object getValue(final String key);
+ Class<?> getType();
- boolean hasTarget();
+ Object getValue(final String key);
- boolean isChild();
+ boolean hasTarget();
- boolean isEnabled();
+ boolean isChild();
- boolean isVisible();
+ boolean isEnabled();
- boolean mustBeAdded();
+ boolean isVisible();
- public void putValue(final String key, final Object value);
+ boolean mustBeAdded();
- void removePropertyChangeListener(final PropertyChangeListener listener);
+ public void putValue(final String key, final Object value);
- void setEnabled(final boolean enabled);
+ void removePropertyChangeListener(final PropertyChangeListener listener);
- void setId(final String id);
+ void setEnabled(final boolean enabled);
- void setLocation(final String location);
+ void setId(final String id);
- void setParent(final GuiActionDescrip parent);
+ void setLocation(final String location);
- void setPosition(final int position);
+ void setParent(final GuiActionDescrip parent);
- void setStyles(final String styles);
+ void setPosition(final int position);
- void setTarget(final Object object);
+ void setStyles(final String styles);
- void setVisible(final boolean visible);
+ void setTarget(final Object object);
- GuiActionDescrip withIcon(Object icon);
+ void setVisible(final boolean visible);
- GuiActionDescrip withIconCls(String icon);
+ void toggleTooltipVisible();
- GuiActionDescrip withId(String id);
+ void toogleVisible();
- GuiActionDescrip withParent(GuiActionDescrip parent);
+ GuiActionDescrip withIcon(Object icon);
- GuiActionDescrip withShortcut(KeyStroke keystroke);
+ GuiActionDescrip withIconCls(String icon);
- GuiActionDescrip withStyles(String styles);
+ GuiActionDescrip withId(String id);
- GuiActionDescrip withText(String text);
+ GuiActionDescrip withParent(GuiActionDescrip parent);
- GuiActionDescrip withToolTip(String tooltip);
+ GuiActionDescrip withShortcut(KeyStroke keystroke);
+
+ GuiActionDescrip withStyles(String styles);
+
+ GuiActionDescrip withText(String text);
+
+ GuiActionDescrip withToolTip(String tooltip);
}
Modified: trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/common/client/tooltip/Tooltip.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -45,155 +45,165 @@
public class Tooltip extends PopupPanel {
- interface TooltipUiBinder extends UiBinder<Widget, Tooltip> {
- }
+ interface TooltipUiBinder extends UiBinder<Widget, Tooltip> {
+ }
- private static TooltipUiBinder uiBinder = GWT.create(TooltipUiBinder.class);
+ private static TooltipUiBinder uiBinder = GWT.create(TooltipUiBinder.class);
- public static Tooltip to(final Widget widget, final String text) {
- if (TextUtils.notEmpty(text)) {
- final Tooltip tip = new Tooltip();
- tip.to(widget);
- tip.setText(text);
- return tip;
- }
- return null;
+ public static Tooltip to(final Widget widget, final String text) {
+ if (TextUtils.notEmpty(text)) {
+ final Tooltip tip = new Tooltip();
+ tip.to(widget);
+ tip.setText(text);
+ return tip;
}
+ return null;
+ }
- public static Tooltip to(final Widget widget, final Widget withContent) {
- final Tooltip tip = new Tooltip();
- tip.to(widget);
- tip.setContent(withContent);
- return tip;
- }
- @UiField
- HTMLPanel arrow;
- @UiField
- HTMLPanel arrowBorder;
- @UiField
- FlowPanel content;
- @UiField
- FlowPanel flow;
- private Widget ofWidget;
- private final TooltipTimers timers;
- @UiField
- InlineLabel title;
- @UiField
- HTMLPanel tooltip;
+ public static Tooltip to(final Widget widget, final Widget withContent) {
+ final Tooltip tip = new Tooltip();
+ tip.to(widget);
+ tip.setContent(withContent);
+ return tip;
+ }
+ @UiField
+ HTMLPanel arrow;
+ @UiField
+ HTMLPanel arrowBorder;
+ @UiField
+ FlowPanel content;
+ @UiField
+ FlowPanel flow;
+ private Widget ofWidget;
+ private final TooltipTimers timers;
+ @UiField
+ InlineLabel title;
+ @UiField
+ HTMLPanel tooltip;
- public Tooltip() {
- super.add(uiBinder.createAndBindUi(this));
- super.setStyleName("k-tooltip-no-chrome");
- super.setAutoHideEnabled(false);
- super.setAnimationEnabled(false);
- final TimerWrapper overTimer = new TimerWrapper();
- overTimer.configure(new Executer() {
- @Override
- public void execute() {
- show();
- }
- });
- final Executer hideExecuter = new Executer() {
- @Override
- public void execute() {
- hide();
- }
- };
- final TimerWrapper outTimer = new TimerWrapper();
- final TimerWrapper securityTimer = new TimerWrapper();
- outTimer.configure(hideExecuter);
- securityTimer.configure(hideExecuter);
- timers = new TooltipTimers(overTimer, outTimer, securityTimer);
- }
+ public Tooltip() {
+ super.add(uiBinder.createAndBindUi(this));
+ super.setStyleName("k-tooltip-no-chrome");
+ super.setAutoHideEnabled(false);
+ super.setAnimationEnabled(false);
+ final TimerWrapper overTimer = new TimerWrapper();
+ overTimer.configure(new Executer() {
+ @Override
+ public void execute() {
+ show();
+ }
+ });
+ final Executer hideExecuter = new Executer() {
+ @Override
+ public void execute() {
+ hide();
+ }
+ };
+ final TimerWrapper outTimer = new TimerWrapper();
+ final TimerWrapper securityTimer = new TimerWrapper();
+ outTimer.configure(hideExecuter);
+ securityTimer.configure(hideExecuter);
+ timers = new TooltipTimers(overTimer, outTimer, securityTimer);
+ }
- protected int getHeight() {
- return tooltip.getElement().getOffsetHeight();
- }
+ protected int getHeight() {
+ return tooltip.getElement().getOffsetHeight();
+ }
- protected int getWidth() {
- return tooltip.getElement().getOffsetWidth();
- }
+ protected int getWidth() {
+ return tooltip.getElement().getOffsetWidth();
+ }
- private void setContent(final Widget widget) {
- content.clear();
- content.add(widget);
- }
+ @Override
+ public boolean isVisible() {
+ return super.isShowing();
+ }
- public void setText(final String text) {
- content.clear();
- content.add(new Label(text));
- }
+ private void setContent(final Widget widget) {
+ content.clear();
+ content.add(widget);
+ }
- @Override
- public void show() {
- if (!Tooltip.this.isShowing() && ofWidget.isVisible()) {
- Tooltip.super.show();
- Tooltip.this.showAt(TooltipPositionCalculator.calculate(Window.getClientWidth(), Window.getClientHeight(),
- ofWidget.getAbsoluteLeft(), ofWidget.getAbsoluteTop(), ofWidget.getOffsetWidth(),
- ofWidget.getOffsetHeight(), Tooltip.this.getWidth(), Tooltip.this.getHeight()));
- if (tooltip.getOffsetWidth() > 430) {
- tooltip.getElement().getStyle().setWidth(430, Unit.PX);
- } else {
- tooltip.getElement().getStyle().clearWidth();
- }
- }
+ public void setText(final String text) {
+ content.clear();
+ content.add(new Label(text));
+ }
+
+ @Override
+ public void show() {
+ if (!Tooltip.this.isShowing() && ofWidget.isVisible()) {
+ Tooltip.super.show();
+ Tooltip.this.showAt(TooltipPositionCalculator.calculate(Window.getClientWidth(),
+ Window.getClientHeight(), ofWidget.getAbsoluteLeft(), ofWidget.getAbsoluteTop(),
+ ofWidget.getOffsetWidth(), ofWidget.getOffsetHeight(), Tooltip.this.getWidth(),
+ Tooltip.this.getHeight()));
+ if (tooltip.getOffsetWidth() > 430) {
+ tooltip.getElement().getStyle().setWidth(430, Unit.PX);
+ } else {
+ tooltip.getElement().getStyle().clearWidth();
+ }
}
+ }
- protected void showAt(final TooltipPosition position) {
- this.setPopupPosition(position.getLeft(), position.getTop());
- switch (position.getArrowPosition()) {
- case N:
- case NW:
- case NE:
- arrow.getElement().getStyle().setLeft(position.getArrowLeft(), Unit.PX);
- arrow.getElement().getStyle().setTop(position.getArrowTop() + 3, Unit.PX);
- arrowBorder.getElement().getStyle().setLeft(position.getArrowLeft(), Unit.PX);
- arrowBorder.getElement().getStyle().setTop(position.getArrowTop() + 1, Unit.PX);
- arrow.getElement().removeClassName("k-tooltip-arrow-s");
- arrow.getElement().addClassName("k-tooltip-arrow-n");
- arrowBorder.getElement().removeClassName("k-tooltip-arrow-border-s");
- arrowBorder.getElement().addClassName("k-tooltip-arrow-border-n");
- break;
- case S:
- case SE:
- case SW:
- arrow.getElement().getStyle().setLeft(position.getArrowLeft(), Unit.PX);
- arrow.getElement().getStyle().setBottom(position.getArrowTop() + 2, Unit.PX);
- arrowBorder.getElement().getStyle().setLeft(position.getArrowLeft(), Unit.PX);
- arrowBorder.getElement().getStyle().setBottom(position.getArrowTop(), Unit.PX);
- arrow.getElement().addClassName("k-tooltip-arrow-s");
- arrow.getElement().removeClassName("k-tooltip-arrow-n");
- arrowBorder.getElement().addClassName("k-tooltip-arrow-border-s");
- arrowBorder.getElement().removeClassName("k-tooltip-arrow-border-n");
- break;
- }
+ protected void showAt(final TooltipPosition position) {
+ this.setPopupPosition(position.getLeft(), position.getTop());
+ switch (position.getArrowPosition()) {
+ case N:
+ case NW:
+ case NE:
+ arrow.getElement().getStyle().setLeft(position.getArrowLeft(), Unit.PX);
+ arrow.getElement().getStyle().setTop(position.getArrowTop() + 3, Unit.PX);
+ arrowBorder.getElement().getStyle().setLeft(position.getArrowLeft(), Unit.PX);
+ arrowBorder.getElement().getStyle().setTop(position.getArrowTop() + 1, Unit.PX);
+ arrow.getElement().removeClassName("k-tooltip-arrow-s");
+ arrow.getElement().addClassName("k-tooltip-arrow-n");
+ arrowBorder.getElement().removeClassName("k-tooltip-arrow-border-s");
+ arrowBorder.getElement().addClassName("k-tooltip-arrow-border-n");
+ break;
+ case S:
+ case SE:
+ case SW:
+ arrow.getElement().getStyle().setLeft(position.getArrowLeft(), Unit.PX);
+ arrow.getElement().getStyle().setBottom(position.getArrowTop() + 2, Unit.PX);
+ arrowBorder.getElement().getStyle().setLeft(position.getArrowLeft(), Unit.PX);
+ arrowBorder.getElement().getStyle().setBottom(position.getArrowTop(), Unit.PX);
+ arrow.getElement().addClassName("k-tooltip-arrow-s");
+ arrow.getElement().removeClassName("k-tooltip-arrow-n");
+ arrowBorder.getElement().addClassName("k-tooltip-arrow-border-s");
+ arrowBorder.getElement().removeClassName("k-tooltip-arrow-border-n");
+ break;
}
+ }
- private void to(final Widget ofWidget) {
- this.ofWidget = ofWidget;
- ofWidget.addDomHandler(new MouseOverHandler() {
- @Override
- public void onMouseOver(final MouseOverEvent event) {
- timers.onOver();
- }
- }, MouseOverEvent.getType());
- ofWidget.addDomHandler(new FocusHandler() {
- @Override
- public void onFocus(final FocusEvent event) {
- timers.onOut();
- }
- }, FocusEvent.getType());
- ofWidget.addDomHandler(new BlurHandler() {
- @Override
- public void onBlur(final BlurEvent event) {
- timers.onOut();
- }
- }, BlurEvent.getType());
- ofWidget.addDomHandler(new MouseOutHandler() {
- @Override
- public void onMouseOut(final MouseOutEvent event) {
- timers.onOut();
- }
- }, MouseOutEvent.getType());
- }
+ public void showTemporally() {
+ timers.showTemporally();
+ }
+
+ private void to(final Widget ofWidget) {
+ this.ofWidget = ofWidget;
+ ofWidget.addDomHandler(new MouseOverHandler() {
+ @Override
+ public void onMouseOver(final MouseOverEvent event) {
+ timers.onOver();
+ }
+ }, MouseOverEvent.getType());
+ ofWidget.addDomHandler(new FocusHandler() {
+ @Override
+ public void onFocus(final FocusEvent event) {
+ timers.onOut();
+ }
+ }, FocusEvent.getType());
+ ofWidget.addDomHandler(new BlurHandler() {
+ @Override
+ public void onBlur(final BlurEvent event) {
+ timers.onOut();
+ }
+ }, BlurEvent.getType());
+ ofWidget.addDomHandler(new MouseOutHandler() {
+ @Override
+ public void onMouseOut(final MouseOutEvent event) {
+ timers.onOut();
+ }
+ }, MouseOutEvent.getType());
+ }
}
Modified: trunk/src/main/java/cc/kune/common/client/tooltip/TooltipTimers.java
===================================================================
--- trunk/src/main/java/cc/kune/common/client/tooltip/TooltipTimers.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/common/client/tooltip/TooltipTimers.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -23,37 +23,48 @@
public class TooltipTimers {
- private final TimerWrapper hideTimer;
- private final TimerWrapper securityTimer;
- private final TimerWrapper showTimer;
+ private final TimerWrapper hideTimer;
+ private final TimerWrapper securityTimer;
+ private final TimerWrapper showTimer;
- public TooltipTimers(final TimerWrapper showTimer, final TimerWrapper hideTimer, final TimerWrapper securityTimer) {
- this.showTimer = showTimer;
- this.hideTimer = hideTimer;
- this.securityTimer = securityTimer;
+ public TooltipTimers(final TimerWrapper showTimer, final TimerWrapper hideTimer,
+ final TimerWrapper securityTimer) {
+ this.showTimer = showTimer;
+ this.hideTimer = hideTimer;
+ this.securityTimer = securityTimer;
+ }
+
+ public void onOut() {
+ if (showTimer.isScheduled()) {
+ showTimer.cancel();
}
+ if (!hideTimer.isScheduled()) {
+ hideTimer.schedule(650);
+ }
+ if (!securityTimer.isScheduled()) {
+ securityTimer.cancel();
+ }
+ }
- public void onOut() {
- if (showTimer.isScheduled()) {
- showTimer.cancel();
- }
- if (!hideTimer.isScheduled()) {
- hideTimer.schedule(650);
- }
- if (!securityTimer.isScheduled()) {
- securityTimer.cancel();
- }
+ public void onOver() {
+ if (!showTimer.isScheduled()) {
+ showTimer.schedule(700);
}
+ if (hideTimer.isScheduled()) {
+ hideTimer.cancel();
+ }
+ if (!securityTimer.isScheduled()) {
+ securityTimer.schedule(7000);
+ }
+ }
- public void onOver() {
- if (!showTimer.isScheduled()) {
- showTimer.schedule(700);
- }
- if (hideTimer.isScheduled()) {
- hideTimer.cancel();
- }
- if (!securityTimer.isScheduled()) {
- securityTimer.schedule(7000);
- }
+ public void showTemporally() {
+ if (showTimer.isScheduled()) {
+ showTimer.cancel();
}
+ if (hideTimer.isScheduled()) {
+ hideTimer.cancel();
+ }
+ securityTimer.schedule(5000);
+ }
}
Added: trunk/src/main/java/cc/kune/core/client/events/WindowFocusEvent.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/events/WindowFocusEvent.java (rev 0)
+++ trunk/src/main/java/cc/kune/core/client/events/WindowFocusEvent.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,81 @@
+package cc.kune.core.client.events;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.GwtEvent;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.event.shared.HasHandlers;
+
+public class WindowFocusEvent extends GwtEvent<WindowFocusEvent.WindowFocusHandler> {
+
+ public interface HasWindowFocusHandlers extends HasHandlers {
+ HandlerRegistration addWindowFocusHandler(WindowFocusHandler handler);
+ }
+
+ public interface WindowFocusHandler extends EventHandler {
+ public void onWindowFocus(WindowFocusEvent event);
+ }
+
+ private static final Type<WindowFocusHandler> TYPE = new Type<WindowFocusHandler>();
+
+ public static void fire(final HasHandlers source, final boolean hasFocus) {
+ source.fireEvent(new WindowFocusEvent(hasFocus));
+ }
+
+ public static Type<WindowFocusHandler> getType() {
+ return TYPE;
+ }
+
+ boolean hasFocus;
+
+ protected WindowFocusEvent() {
+ // Possibly for serialization.
+ }
+
+ public WindowFocusEvent(final boolean hasFocus) {
+ this.hasFocus = hasFocus;
+ }
+
+ @Override
+ protected void dispatch(final WindowFocusHandler handler) {
+ handler.onWindowFocus(this);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final WindowFocusEvent other = (WindowFocusEvent) obj;
+ if (hasFocus != other.hasFocus) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public Type<WindowFocusHandler> getAssociatedType() {
+ return TYPE;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 23;
+ hashCode = (hashCode * 37) + Boolean.valueOf(hasFocus).hashCode();
+ return hashCode;
+ }
+
+ public boolean isHasFocus() {
+ return hasFocus;
+ }
+
+ @Override
+ public String toString() {
+ return "WindowFocusEvent[" + hasFocus + "]";
+ }
+}
Modified: trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPresenter.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/core/client/groups/newgroup/NewGroupPresenter.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -36,7 +36,10 @@
import cc.kune.core.shared.dto.GroupType;
import cc.kune.core.shared.dto.LicenseDTO;
import cc.kune.core.shared.i18n.I18nTranslationService;
+import cc.kune.gspace.client.options.GroupOptions;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
@@ -51,145 +54,156 @@
import com.gwtplatform.mvp.client.proxy.Proxy;
import com.gwtplatform.mvp.client.proxy.RevealRootContentEvent;
-public class NewGroupPresenter extends Presenter<NewGroupView, NewGroupPresenter.NewGroupProxy> implements NewGroup {
+public class NewGroupPresenter extends Presenter<NewGroupView, NewGroupPresenter.NewGroupProxy>
+ implements NewGroup {
- @ProxyCodeSplit
- public interface NewGroupProxy extends Proxy<NewGroupPresenter> {
- }
+ @ProxyCodeSplit
+ public interface NewGroupProxy extends Proxy<NewGroupPresenter> {
+ }
- private final Provider<GroupServiceAsync> groupService;
+ private final GroupOptions groupOptions;
- private final I18nTranslationService i18n;
- private final Session session;
- private final Provider<SignIn> signIn;
- private final StateManager stateManager;
+ private final Provider<GroupServiceAsync> groupService;
+ private final I18nTranslationService i18n;
+ private final Session session;
+ private final Provider<SignIn> signIn;
- @Inject
- public NewGroupPresenter(final EventBus eventBus, final NewGroupView view, final NewGroupProxy proxy,
- final I18nTranslationService i18n, final Session session, final StateManager stateManager,
- final Provider<GroupServiceAsync> groupService, final Provider<SignIn> signIn) {
- super(eventBus, view, proxy);
- this.i18n = i18n;
- this.session = session;
- this.stateManager = stateManager;
- this.groupService = groupService;
- this.signIn = signIn;
- stateManager.addSiteToken(SiteTokens.NEWGROUP, new HistoryTokenCallback() {
- @Override
- public void onHistoryToken() {
- doNewGroup();
- }
- });
- }
+ private final StateManager stateManager;
- @Override
- public void doNewGroup() {
- session.check(new AsyncCallbackSimple<Void>() {
- @Override
- public void onSuccess(final Void result) {
- if (session.isLogged()) {
- NotifyUser.showProgressProcessing();
- getView().show();
- getView().focusOnShorName();
- NotifyUser.hideProgress();
- } else {
- // stateManager.restorePreviousToken();
- NotifyUser.info(i18n.t(CoreMessages.REGISTER_TO_CREATE_A_GROUP));
- signIn.get().showSignInDialog();
- }
- }
- });
- }
+ @Inject
+ public NewGroupPresenter(final EventBus eventBus, final NewGroupView view, final NewGroupProxy proxy,
+ final I18nTranslationService i18n, final Session session, final StateManager stateManager,
+ final Provider<GroupServiceAsync> groupService, final Provider<SignIn> signIn,
+ final GroupOptions groupOptions) {
+ super(eventBus, view, proxy);
+ this.i18n = i18n;
+ this.session = session;
+ this.stateManager = stateManager;
+ this.groupService = groupService;
+ this.signIn = signIn;
+ this.groupOptions = groupOptions;
+ stateManager.addSiteToken(SiteTokens.NEWGROUP, new HistoryTokenCallback() {
+ @Override
+ public void onHistoryToken() {
+ doNewGroup();
+ }
+ });
+ }
- private GroupType getTypeOfGroup() {
- if (getView().isProject()) {
- return GroupType.PROJECT;
- } else if (getView().isOrganization()) {
- return GroupType.ORGANIZATION;
+ @Override
+ public void doNewGroup() {
+ session.check(new AsyncCallbackSimple<Void>() {
+ @Override
+ public void onSuccess(final Void result) {
+ if (session.isLogged()) {
+ NotifyUser.showProgressProcessing();
+ getView().show();
+ getView().focusOnShorName();
+ NotifyUser.hideProgress();
} else {
- return GroupType.COMMUNITY;
+ // stateManager.restorePreviousToken();
+ signIn.get().setErrorMessage(i18n.t(CoreMessages.REGISTER_TO_CREATE_A_GROUP), NotifyLevel.info);
+ signIn.get().showSignInDialog();
}
+ }
+ });
+ }
+
+ private GroupType getTypeOfGroup() {
+ if (getView().isProject()) {
+ return GroupType.PROJECT;
+ } else if (getView().isOrganization()) {
+ return GroupType.ORGANIZATION;
+ } else {
+ return GroupType.COMMUNITY;
}
+ }
- @Override
- protected void onBind() {
- super.onBind();
- getView().getFirstBtn().addClickHandler(new ClickHandler() {
- @Override
- public void onClick(final ClickEvent event) {
- onRegister();
- }
- });
- getView().getSecondBtn().addClickHandler(new ClickHandler() {
- @Override
- public void onClick(final ClickEvent event) {
- onCancel();
- }
- });
- getView().getClose().addCloseHandler(new CloseHandler<PopupPanel>() {
+ @Override
+ protected void onBind() {
+ super.onBind();
+ getView().getFirstBtn().addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(final ClickEvent event) {
+ onRegister();
+ }
+ });
+ getView().getSecondBtn().addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(final ClickEvent event) {
+ onCancel();
+ }
+ });
+ getView().getClose().addCloseHandler(new CloseHandler<PopupPanel>() {
- @Override
- public void onClose(final CloseEvent<PopupPanel> event) {
- NewGroupPresenter.this.onClose();
- }
- });
- }
+ @Override
+ public void onClose(final CloseEvent<PopupPanel> event) {
+ NewGroupPresenter.this.onClose();
+ }
+ });
+ }
- public void onCancel() {
- getView().hide();
- }
+ public void onCancel() {
+ getView().hide();
+ }
- public void onClose() {
- reset();
- stateManager.redirectOrRestorePreviousToken();
- }
+ public void onClose() {
+ reset();
+ stateManager.redirectOrRestorePreviousToken();
+ }
- public void onRegister() {
- if (getView().isFormValid()) {
- getView().maskProcessing();
- final String shortName = getView().getShortName();
- final String longName = getView().getLongName();
- final String publicDesc = getView().getPublicDesc();
- final LicenseDTO license = session.getDefLicense();
- final GroupDTO group = new GroupDTO(shortName, longName, getTypeOfGroup());
- group.setDefaultLicense(license);
+ public void onRegister() {
+ if (getView().isFormValid()) {
+ getView().maskProcessing();
+ final String shortName = getView().getShortName();
+ final String longName = getView().getLongName();
+ final String publicDesc = getView().getPublicDesc();
+ final LicenseDTO license = session.getDefLicense();
+ final GroupDTO group = new GroupDTO(shortName, longName, getTypeOfGroup());
+ group.setDefaultLicense(license);
- final AsyncCallback<StateToken> callback = new AsyncCallback<StateToken>() {
- @Override
- public void onFailure(final Throwable caught) {
- if (caught instanceof GroupNameInUseException) {
- getView().unMask();
- setMessage(i18n.t(CoreMessages.NAME_IN_ALREADY_IN_USE), NotifyLevel.error);
- } else {
- getView().unMask();
- setMessage(i18n.t("Error creating group"), NotifyLevel.error);
- throw new UIException("Other kind of exception in group registration", caught);
- }
- }
+ final AsyncCallback<StateToken> callback = new AsyncCallback<StateToken>() {
+ @Override
+ public void onFailure(final Throwable caught) {
+ if (caught instanceof GroupNameInUseException) {
+ getView().unMask();
+ setMessage(i18n.t(CoreMessages.NAME_IN_ALREADY_IN_USE), NotifyLevel.error);
+ } else {
+ getView().unMask();
+ setMessage(i18n.t("Error creating group"), NotifyLevel.error);
+ throw new UIException("Other kind of exception in group registration", caught);
+ }
+ }
- @Override
- public void onSuccess(final StateToken token) {
- getView().hide();
- stateManager.gotoStateToken(token);
- reset();
- getView().unMask();
- }
- };
- groupService.get().createNewGroup(session.getUserHash(), group, publicDesc, getView().getTags(), null,
- callback);
+ @Override
+ public void onSuccess(final StateToken token) {
+ getView().hide();
+ Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+ @Override
+ public void execute() {
+ stateManager.gotoStateToken(token);
+ groupOptions.showTooltip();
+ }
+ });
+ reset();
+ getView().unMask();
}
+ };
+ groupService.get().createNewGroup(session.getUserHash(), group, publicDesc, getView().getTags(),
+ null, callback);
}
+ }
- private void reset() {
- getView().clearData();
- }
+ private void reset() {
+ getView().clearData();
+ }
- @Override
- protected void revealInParent() {
- RevealRootContentEvent.fire(this, this);
- }
+ @Override
+ protected void revealInParent() {
+ RevealRootContentEvent.fire(this, this);
+ }
- public void setMessage(final String message, final NotifyLevel level) {
- getView().setMessage(message, level);
- }
+ public void setMessage(final String message, final NotifyLevel level) {
+ getView().setMessage(message, level);
+ }
}
Modified: trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorPresenter.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -21,12 +21,14 @@
import cc.kune.common.client.notify.NotifyLevel;
import cc.kune.core.client.auth.SignIn;
+import cc.kune.core.client.events.WindowFocusEvent;
import cc.kune.core.client.init.AppStartEvent;
import cc.kune.core.client.state.Session;
import cc.kune.core.client.state.SiteTokens;
import cc.kune.core.client.state.StateManager;
import cc.kune.core.client.state.TokenUtils;
import cc.kune.core.client.state.UserSignOutEvent;
+import cc.kune.core.shared.i18n.I18nTranslationService;
import cc.kune.gspace.client.GSpaceArmor;
import cc.kune.gspace.client.style.GSpaceBackManager;
@@ -34,6 +36,7 @@
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.EventBus;
+import com.google.gwt.user.client.Timer;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.gwtplatform.mvp.client.Presenter;
@@ -67,6 +70,14 @@
void setPublicBtnDown(boolean down);
void setUserBtnDown(boolean down);
+
+ void showGroupSpaceTooltip();
+
+ void showHomeSpaceTooltip();
+
+ void showPublicSpaceTooltip();
+
+ void showUserSpaceTooltip();
}
private final GSpaceArmor armor;
@@ -74,6 +85,7 @@
private Space currentSpace;
private String groupToken;
private String homeToken;
+ private final I18nTranslationService i18n;
private String publicToken;
private final Session session;
private final Provider<SignIn> signIn;
@@ -83,13 +95,15 @@
@Inject
public SpaceSelectorPresenter(final EventBus eventBus, final StateManager stateManager,
final SpaceSelectorView view, final SpaceSelectorProxy proxy, final GSpaceArmor armor,
- final Session session, final Provider<SignIn> signIn, final GSpaceBackManager backManager) {
+ final Session session, final Provider<SignIn> signIn, final GSpaceBackManager backManager,
+ final I18nTranslationService i18n) {
super(eventBus, view, proxy);
this.stateManager = stateManager;
this.armor = armor;
this.session = session;
this.signIn = signIn;
this.backManager = backManager;
+ this.i18n = i18n;
currentSpace = null;
homeToken = SiteTokens.HOME;
userToken = SiteTokens.WAVEINBOX;
@@ -119,10 +133,19 @@
stateManager.gotoHistoryToken(publicToken);
}
});
+ eventBus.addHandler(WindowFocusEvent.getType(), new WindowFocusEvent.WindowFocusHandler() {
+ @Override
+ public void onWindowFocus(final WindowFocusEvent event) {
+ if (event.isHasFocus()) {
+ showTooltipWithDelay();
+ }
+ }
+ });
}
@ProxyEvent
public void onAppStart(final AppStartEvent event) {
+ showTooltipWithDelay();
}
private void onGroupSpaceSelect() {
@@ -195,7 +218,6 @@
default:
break;
}
- // getView().hideTooltip();
}
}
@@ -217,10 +239,10 @@
getView().setPublicBtnDown(false);
currentSpace = Space.userSpace;
} else {
- signIn.get().setErrorMessage("Sign in to access to your inbox", NotifyLevel.info);
+ signIn.get().setErrorMessage(i18n.t("Sign in or create an account to access to your inbox"),
+ NotifyLevel.info);
stateManager.gotoHistoryToken(TokenUtils.addRedirect(SiteTokens.SIGNIN, userToken));
getView().setUserBtnDown(false);
- // NotifyUser.info("Sign in to access to your workspace");
}
}
@@ -228,4 +250,30 @@
protected void revealInParent() {
RevealRootContentEvent.fire(this, this);
}
+
+ private void showTooltipNow() {
+ switch (currentSpace) {
+ case homeSpace:
+ getView().showHomeSpaceTooltip();
+ break;
+ case userSpace:
+ getView().showUserSpaceTooltip();
+ break;
+ case groupSpace:
+ getView().showGroupSpaceTooltip();
+ break;
+ case publicSpace:
+ getView().showPublicSpaceTooltip();
+ break;
+ }
+ }
+
+ protected void showTooltipWithDelay() {
+ new Timer() {
+ @Override
+ public void run() {
+ showTooltipNow();
+ }
+ }.schedule(500);
+ }
}
\ No newline at end of file
Modified: trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorViewImpl.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorViewImpl.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/core/client/sitebar/spaces/SpaceSelectorViewImpl.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -41,26 +41,31 @@
private static SpaceSelectorViewImplUiBinder uiBinder = GWT.create(SpaceSelectorViewImplUiBinder.class);
@UiField
ToggleButton groupButton;
+ private final Tooltip groupSpaceTooltip;
@UiField
ToggleButton homeButton;
+ private final Tooltip homeSpaceTooltip;
@UiField
HorizontalPanel panel;
@UiField
ToggleButton publicButton;
+ private final Tooltip publicSpaceTooltip;
@UiField
ToggleButton userButton;
+ private final Tooltip userSpaceTooltip;
@Inject
public SpaceSelectorViewImpl(final GSpaceArmor armor, final I18nTranslationService i18n,
final GSpaceArmorResources res) {
armor.getSitebar().insert(uiBinder.createAndBindUi(this), 0);
// homeButton.setVisible(false);
- Tooltip.to(homeButton, i18n.t("Your home page in this site"));
- Tooltip.to(userButton, i18n.t("User space: it shows a list of all your documents and contents "
- + "in which you participate"));
- Tooltip.to(groupButton, i18n.t("Group and personal space: Where you can create "
+ homeSpaceTooltip = Tooltip.to(homeButton, i18n.t("Your home page in this site"));
+ userSpaceTooltip = Tooltip.to(userButton,
+ i18n.t("User space: it shows a list of all your documents and contents "
+ + "in which you participate"));
+ groupSpaceTooltip = Tooltip.to(groupButton, i18n.t("Group and personal space: Where you can create "
+ "and publish contents for your personal or group web spaces"));
- Tooltip.to(publicButton,
+ publicSpaceTooltip = Tooltip.to(publicButton,
i18n.t("Public space: In this space you can see a preview of how the Personal o"
+ "r Group Space looks like on the web, outside this site"));
}
@@ -109,4 +114,20 @@
public void setUserBtnDown(final boolean down) {
userButton.setDown(down);
}
+
+ public void showGroupSpaceTooltip() {
+ groupSpaceTooltip.showTemporally();
+ }
+
+ public void showHomeSpaceTooltip() {
+ homeSpaceTooltip.showTemporally();
+ }
+
+ public void showPublicSpaceTooltip() {
+ publicSpaceTooltip.showTemporally();
+ }
+
+ public void showUserSpaceTooltip() {
+ userSpaceTooltip.showTemporally();
+ }
}
Modified: trunk/src/main/java/cc/kune/core/client/state/StateManagerDefault.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/state/StateManagerDefault.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/core/client/state/StateManagerDefault.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -415,7 +415,7 @@
// history.newItem(newToken.toString(), false);
StateChangedEvent.fire(eventBus, newState);
checkGroupAndToolChange(newState);
- previousToken = newToken;
+ previousToken = newToken.copy();
eventBus.fireEvent(new ProgressHideEvent());
}
Modified: trunk/src/main/java/cc/kune/core/public/ws.css
===================================================================
--- trunk/src/main/java/cc/kune/core/public/ws.css 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/core/public/ws.css 2011-07-09 16:44:34 UTC (rev 1442)
@@ -1,4 +1,4 @@
-CHARSET "UTF-8 "; body {
+CHARSET "UTF-8 "; body {
background-color: transparent;
color: black;
font-family: 'Ubuntu', Arial;
@@ -728,6 +728,7 @@
background: #FFB380 none repeat scroll 0% 50%;
/* color: #250; */
padding: 10px;
+ margin: 16px -20px -20px -20px;
}
.k-error-tb img {
@@ -832,7 +833,7 @@
white-space: nowrap;
}
*/
-.k-sn-mainpanel .x-btn button,.k-sn-mainpanel button,button.k-button,.gwt-FileUpload
+.k-sn-mainpanel .x-btn button,.k-sn-mainpanel button,button.k-button,.gwt-FileUpload,button.gwt-Button
{
font: 13px 'Ubuntu', arial;
border: 2px solid #CCCCCC;
@@ -854,7 +855,7 @@
height: 28px;
}
-.k-sn-mainpanel .x-btn button:hover,.k-sn-mainpanel button:hover,button.k-button:hover
+.k-sn-mainpanel .x-btn button:hover,.k-sn-mainpanel button:hover,button.k-button:hover,button.gwt-Button:hover
{
border: 2px orange solid;
outline: 0 none;
@@ -1201,7 +1202,7 @@
-webkit-border-bottom-left-radius: 5px;
-moz-border-radius-bottomleft: 5px;
border-bottom-left-radius: 5px;
- kfilter: alpha(opacity = 90);
+ kfilter: alpha(opacity = 90);
-moz-opacity: 0.90;
-khtml-opacity: 0.90;
opacity: 0.90;
@@ -1411,4 +1412,4 @@
.bullet-type-2 {
list-style-type: square;
-}
+}
\ No newline at end of file
Modified: trunk/src/main/java/cc/kune/gspace/client/GSpaceArmorImpl.ui.xml
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/GSpaceArmorImpl.ui.xml 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/gspace/client/GSpaceArmorImpl.ui.xml 2011-07-09 16:44:34 UTC (rev 1442)
@@ -38,7 +38,7 @@
<g:SplitLayoutPanel width="100%" height="100%" styleName="k-space"
ui:field="groupSpace">
<g:center size="1.0">
- <g:DockLayoutPanel unit="PX" ui:field="splitCenter">
+ <g:DockLayoutPanel unit="PX" ui:field="splitCenter" styleName="{res.style.entityCentralContainer}">
<g:north size="168">
<g:VerticalPanel width="100%" height="168px">
<g:FlowPanel height="70px" width="100%"
Modified: trunk/src/main/java/cc/kune/gspace/client/options/GroupOptions.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/options/GroupOptions.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/gspace/client/options/GroupOptions.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -20,4 +20,6 @@
package cc.kune.gspace.client.options;
public interface GroupOptions extends EntityOptions {
+
+ void showTooltip();
}
Modified: trunk/src/main/java/cc/kune/gspace/client/options/GroupOptionsPresenter.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/options/GroupOptionsPresenter.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/gspace/client/options/GroupOptionsPresenter.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -60,10 +60,12 @@
// groupPrefsAction.putValue(Action.NAME, i18n.t("Group options"));
groupPrefsAction.putValue(Action.SMALL_ICON, img.prefs());
prefsItem = new ButtonDescriptor(groupPrefsAction);
- prefsItem.withStyles("k-ent-header-btn, k-btn-min"); // , k-noborder,
- // k-nobackcolor,
- // k-btn-min");
+ prefsItem.withStyles("k-ent-header-btn, k-btn-min");
+ // k-noborder,
+ // k-nobackcolor,
+ // k-btn-min");
prefsItem.setId(GROUP_OPTIONS_ICON);
+ prefsItem.withToolTip(i18n.t("Set your group preferences here"));
prefsItem.setVisible(false);
view.addAction(prefsItem);
}
@@ -85,4 +87,9 @@
}
});
}
+
+ @Override
+ public void showTooltip() {
+ prefsItem.toggleTooltipVisible();
+ }
}
Modified: trunk/src/main/java/cc/kune/gspace/client/resources/GSpaceArmorResources.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/resources/GSpaceArmorResources.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/gspace/client/resources/GSpaceArmorResources.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -42,6 +42,8 @@
String docSubheaderLeft();
+ String entityCentralContainer();
+
String entityFooter();
String entityHeader();
Modified: trunk/src/main/java/cc/kune/gspace/client/resources/gSpaceArmor.css
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/resources/gSpaceArmor.css 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/gspace/client/resources/gSpaceArmor.css 2011-07-09 16:44:34 UTC (rev 1442)
@@ -34,6 +34,9 @@
opacity: 0.38 !important; */
}
+.entityCentralContainer {
+
+}
.entityHeader {
-webkit-border-top-right-radius: 7px;
-moz-border-radius-topright: 7px;
Modified: trunk/src/main/java/cc/kune/gspace/client/resources/gSpaceArmorTheme.css
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/resources/gSpaceArmorTheme.css 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/gspace/client/resources/gSpaceArmorTheme.css 2011-07-09 16:44:34 UTC (rev 1442)
@@ -25,7 +25,7 @@
color: c5;
}
-.entityToolsNorth span ,.k-sn-deck div {
+.entityToolsNorth span,.k-sn-deck div {
color: c1;
}
@@ -54,6 +54,7 @@
}
.k-tool-item {
+
}
.k-tool-item span {
@@ -69,6 +70,7 @@
}
.k-tool-item-nofocus {
+
}
.k-tool-item-nofocus span {
@@ -101,11 +103,15 @@
color: c4;
}
+.entityCentralContainer {
+ border-left: 2px solid bc1;
+}
+
.entityHeader {
background-color: bc5;
}
-.entityHeader span, .entityHeader div {
+.entityHeader span,.entityHeader div {
color: c5;
}
@@ -142,7 +148,7 @@
background-color: bc7;
}
-.k-empty-msg span, .k-folder-viewer span {
+.k-empty-msg span,.k-folder-viewer span {
color: c7;
}
Modified: trunk/src/main/java/cc/kune/gspace/client/style/GSpaceBackManagerImpl.java
===================================================================
--- trunk/src/main/java/cc/kune/gspace/client/style/GSpaceBackManagerImpl.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/gspace/client/style/GSpaceBackManagerImpl.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -43,10 +43,7 @@
@Override
public void clearBackImage() {
- if (!lastToken.equals(NO_TOKEN)) {
- gSpaceArmor.clearBackImage();
- lastToken = NO_TOKEN;
- }
+ gSpaceArmor.clearBackImage();
}
@Override
@@ -61,7 +58,7 @@
final StateToken tokenNoGroup = token.clearDocument().clearDocument();
if (!tokenNoGroup.equals(lastToken)) {
gSpaceArmor.setBackImage(downloadUtils.getBackgroundImageUrl(tokenNoGroup));
- lastToken = tokenNoGroup;
+ lastToken = tokenNoGroup.copy();
}
}
Added: trunk/src/main/java/cc/kune/wave/server/AbstractBaseRobotAgent.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/server/AbstractBaseRobotAgent.java (rev 0)
+++ trunk/src/main/java/cc/kune/wave/server/AbstractBaseRobotAgent.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,162 @@
+/**
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package cc.kune.wave.server;
+
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.waveprotocol.box.server.CoreSettings;
+import org.waveprotocol.box.server.account.AccountData;
+import org.waveprotocol.box.server.persistence.AccountStore;
+import org.waveprotocol.box.server.persistence.PersistenceException;
+import org.waveprotocol.box.server.robots.util.RobotsUtil;
+import org.waveprotocol.box.server.robots.util.RobotsUtil.RobotRegistrationException;
+import org.waveprotocol.wave.model.id.TokenGenerator;
+import org.waveprotocol.wave.model.wave.InvalidParticipantAddress;
+import org.waveprotocol.wave.model.wave.ParticipantId;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
+import com.google.wave.api.AbstractRobot;
+
+/**
+ * The base for robot agents that run on the WIAB server.
+ *
+ * @author yurize(a)apache.org (Yuri Zelikov)
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractBaseRobotAgent extends AbstractRobot {
+
+ static class ServerFrontendAddressHolder {
+
+ private final List<String> addresses;
+
+ @Inject
+ ServerFrontendAddressHolder((a)Named(CoreSettings.HTTP_FRONTEND_ADDRESSES) final List<String> addresses) {
+ this.addresses = addresses;
+ }
+
+ List<String> getAddresses() {
+ return addresses;
+ }
+ }
+
+ public static final String AGENT_PREFIX_URI = "/agent";
+ private static final Logger LOG = Logger.getLogger(AbstractBaseRobotAgent.class.getName());
+
+ /** Account store with user and robot accounts. */
+ private final AccountStore accountStore;
+
+ private final ServerFrontendAddressHolder frontendAddressHolder;
+
+ /** The wave server domain. */
+ private final String waveDomain;
+
+ /**
+ * Constructor. Initializes the agent to serve on the URI provided by
+ * {@link #getRobotUri()} and ensures that the agent is registered in the
+ * Account store.
+ *
+ * @param injector
+ * the injector instance.
+ */
+ public AbstractBaseRobotAgent(final Injector injector) {
+ this(injector.getInstance(Key.get(String.class, Names.named(CoreSettings.WAVE_SERVER_DOMAIN))),
+ injector.getInstance(AccountStore.class), injector.getInstance(TokenGenerator.class),
+ injector.getInstance(ServerFrontendAddressHolder.class));
+ }
+
+ /**
+ * Constructor. Initializes the agent to serve on the URI provided by
+ * {@link #getRobotUri()} and ensures that the agent is registered in the
+ * Account store.
+ */
+ AbstractBaseRobotAgent(final String waveDomain, final AccountStore accountStore,
+ final TokenGenerator tokenGenerator, final ServerFrontendAddressHolder frontendAddressHolder) {
+ this.waveDomain = waveDomain;
+ this.accountStore = accountStore;
+ this.frontendAddressHolder = frontendAddressHolder;
+ ensureRegistered(tokenGenerator, getFrontEndAddress()); // NOPMD by vjrj on
+ // 6/07/11 21:15
+ }
+
+ /**
+ * Ensures that the robot agent is registered in the {@link AccountStore}.
+ */
+ private void ensureRegistered(final TokenGenerator tokenGenerator, final String serverFrontendAddress) {
+ ParticipantId robotId = null;
+ try {
+ robotId = ParticipantId.of(getRobotId() + "@" + waveDomain);
+ } catch (final InvalidParticipantAddress e) {
+ LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
+ return;
+ }
+ try {
+ final String location = "http://" + serverFrontendAddress + getRobotUri();
+ // Register this agent in the account store. The registration is forced
+ // in order to re-register the agents if the server frontend address has
+ // changed.
+ final AccountData account = accountStore.getAccount(robotId);
+ if ((account == null || (account != null && !account.asRobot().getUrl().equals(location)))) {
+ RobotsUtil.registerRobotUri(location, robotId, accountStore, tokenGenerator, true);
+ }
+
+ } catch (final RobotRegistrationException e) {
+ LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
+ } catch (final PersistenceException e) {
+ LOG.log(Level.SEVERE, "Failed to register the agent:" + getRobotId(), e);
+ }
+ }
+
+ /**
+ * Returns the account store.
+ */
+ protected AccountStore getAccountStore() {
+ return accountStore;
+ }
+
+ public String getFrontEndAddress() {
+ return frontendAddressHolder.getAddresses().get(0);
+ }
+
+ /**
+ * Returns the robot participant id.
+ */
+ public abstract String getRobotId();
+
+ @Override
+ protected String getRobotProfilePageUrl() { // NOPMD by vjrj on 6/07/11 21:15
+ return null;
+ }
+
+ /**
+ * Returns the robot URI.
+ */
+ public abstract String getRobotUri();
+
+ /**
+ * Returns the wave domain.
+ */
+ public String getWaveDomain() {
+ return waveDomain;
+ }
+}
\ No newline at end of file
Added: trunk/src/main/java/cc/kune/wave/server/KuneAgent.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/server/KuneAgent.java (rev 0)
+++ trunk/src/main/java/cc/kune/wave/server/KuneAgent.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,140 @@
+package cc.kune.wave.server;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.Nonnull;
+
+import org.waveprotocol.box.server.account.RobotAccountData;
+import org.waveprotocol.box.server.persistence.AccountStore;
+import org.waveprotocol.box.server.persistence.PersistenceException;
+import org.waveprotocol.wave.model.id.TokenGenerator;
+import org.waveprotocol.wave.model.wave.ParticipantId;
+import org.waveprotocol.wave.model.waveref.WaveRef;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.google.wave.api.Wavelet;
+
+@SuppressWarnings("serial")
+@Singleton
+public class KuneAgent extends AbstractBaseRobotAgent implements KuneWaveManager {
+
+ private static final Logger LOG = Logger.getLogger(KuneAgent.class.getName());
+
+ private static final String NO_TITLE = "";
+ public static final String ROBOT_URI = AGENT_PREFIX_URI + "/kune-agent";
+
+ @Inject
+ public KuneAgent(final Injector injector) {
+ super(injector);
+ }
+
+ public KuneAgent(final String waveDomain, final AccountStore accountStore,
+ final TokenGenerator tokenGenerator, final ServerFrontendAddressHolder frontendAddressHolder) {
+ super(waveDomain, accountStore, tokenGenerator, frontendAddressHolder);
+ }
+
+ @Override
+ public void addGadget(final WaveRef waveName, final String author, final String gadgetUrl) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addParticipant(final WaveRef waveName, final String author, final String userWhoAdd,
+ final String newParticipant) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public WaveRef createWave(final String message, final ParticipantId participant) {
+ return createWave(NO_TITLE, message, participant);
+ }
+
+ @Override
+ public WaveRef createWave(@Nonnull final String title, final String message,
+ @Nonnull final ParticipantId... participantsArray) {
+ return createWave(title, message, WITHOUT_GADGET, participantsArray);
+ }
+
+ @Override
+ public WaveRef createWave(final String title, final String message, final URL gadgetUrl,
+ final ParticipantId... participantsArray) {
+ // super.newWave(getWaveDomain(), participantsArray);
+ final HashSet<String> parts = new HashSet<String>();
+ for (final ParticipantId part : participantsArray) {
+ parts.add(part.getAddress());
+ }
+ final Wavelet wave = newWave(getWaveDomain(), parts);
+ return WaveRef.of(wave.getWaveId(), wave.getWaveletId());
+ }
+
+ @Override
+ public Wavelet fetchWavelet(final WaveRef waveRef, final String author) {
+ // Preconditions.checkNotNull(author);
+ RobotAccountData account = null;
+ final String rpcUrl = "http://" + getFrontEndAddress() + "/robot/rpc";
+ try {
+ account = getAccountStore().getAccount(
+ ParticipantId.ofUnsafe(getRobotId() + "@" + getWaveDomain())).asRobot();
+ } catch (final PersistenceException e) {
+ LOG.log(Level.WARNING, "Cannot fetch account data for robot id: " + getRobotId(), e);
+ }
+ if (account != null) {
+ setupOAuth(account.getId().getAddress(), account.getConsumerSecret(), rpcUrl);
+ try {
+ return super.fetchWavelet(waveRef.getWaveId(), waveRef.getWaveletId(), "http://"
+ + getFrontEndAddress() + "/robot/rpc");
+ } catch (final IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getRobotId() {
+ return "kune-agent";
+ }
+
+ @Override
+ protected String getRobotName() {
+ return "Kune Agent";
+ }
+
+ @Override
+ public String getRobotUri() {
+ return ROBOT_URI;
+ }
+
+ @Override
+ public boolean isParticipant(final Wavelet wavelet, final String user) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public String render(final Wavelet wavelet) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String render(final WaveRef waveRef, final String author) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setTitle(final WaveRef waveName, final String title, final String author) {
+ // TODO Auto-generated method stub
+
+ }
+}
Modified: trunk/src/main/java/cc/kune/wave/server/KuneWaveManagerDefault.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/server/KuneWaveManagerDefault.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/cc/kune/wave/server/KuneWaveManagerDefault.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -77,6 +77,7 @@
// See: DocumentModifyServiceTest
private static final String NO_ANNOTATION_KEY = null;
private static final List<BundledAnnotation> NO_BUNDLED_ANNOTATIONS = Collections.emptyList();
+ private static final List<Element> NO_ELEMENTS = Collections.emptyList();
private static final String NO_TITLE = "";
private static final List<String> NO_VALUES = Collections.<String> emptyList();
@@ -163,8 +164,26 @@
final Wavelet newWavelet = opQueue.createWavelet(domain, participants);
opQueue.setTitleOfWavelet(newWavelet, title);
final Blip rootBlip = newWavelet.getRootBlip();
- // rootBlip.append(new com.google.wave.api.Markup(message).getText());
- rootBlip.appendMarkup(message);
+ rootBlip.append(new com.google.wave.api.Markup(message).getText());
+ // rootBlip.all().delete();
+ // rootBlip.appendMarkup(message);
+ // opQueue.appendMarkupToDocument(rootBlip,
+ // ContentNewUnrenderer.unrender(message).toXmlString());
+
+ // final OperationRequest modifyDocument = opQueue.modifyDocument(rootBlip);
+ // ImmutableList<String> of =
+ // ImmutableList.of(ContentNewUnrenderer.unrender(message).toXmlString());
+ // rootBlip.getContent().hackConsume(
+ // Nindo.fromDocOp(ContentNewUnrenderer.unrender(message).asOperation(),
+ // false));
+ // modifyDocument.addParameter(Parameter.of(ParamsProperty.MODIFY_ACTION,
+ // new DocumentModifyAction(
+ // ModifyHow.REPLACE,
+ // ImmutableList.of(ContentNewUnrenderer.unrender(message).toXmlString()),
+ // null,
+ // null, null, false)));
+ // NO_ANNOTATION_KEY, NO_ELEMENTS, NO_BUNDLED_ANNOTATIONS, false)));
+ // rootBlip.appendMarkup(message);
if (gadgetUrl != WITHOUT_GADGET) {
final Gadget gadget = new Gadget(gadgetUrl.toString());
rootBlip.append(gadget);
Added: trunk/src/main/java/com/google/wave/splash/text/ContentNewUnrenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/ContentNewUnrenderer.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/text/ContentNewUnrenderer.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,77 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.text;
+
+import java.util.logging.Logger;
+
+import org.waveprotocol.wave.model.document.indexed.IndexedDocument;
+import org.waveprotocol.wave.model.document.operation.Nindo;
+import org.waveprotocol.wave.model.document.raw.RawDocumentProviderImpl;
+import org.waveprotocol.wave.model.document.raw.impl.Element;
+import org.waveprotocol.wave.model.document.raw.impl.Node;
+import org.waveprotocol.wave.model.document.raw.impl.RawDocumentImpl;
+import org.waveprotocol.wave.model.document.raw.impl.Text;
+import org.waveprotocol.wave.model.document.util.DocProviders;
+import org.waveprotocol.wave.model.document.util.Point;
+import org.waveprotocol.wave.model.document.util.RawElementStyleView;
+import org.waveprotocol.wave.model.operation.OperationException;
+import org.waveprotocol.wave.model.richtext.RichTextMutationBuilder;
+import org.waveprotocol.wave.model.richtext.RichTextTokenizer;
+import org.waveprotocol.wave.model.richtext.RichTextTokenizerImpl;
+import org.waveprotocol.wave.model.util.Pair;
+import org.waveprotocol.wave.model.util.ReadableStringSet;
+
+import cc.kune.core.client.errors.DefaultException;
+
+public class ContentNewUnrenderer {
+
+ private static final Logger LOG = Logger.getLogger(ContentNewUnrenderer.class.getName());
+
+ private static Pair<Nindo, IndexedDocument<Node, Element, Text>> applyTokensToEmptyDoc(
+ final RichTextTokenizer tokens) {
+ // final IndexedDocument<Node, Element, Text> doc =
+ // DocProviders.POJO.parse("<body><line/></body>");
+ final IndexedDocument<Node, Element, Text> doc = DocProviders.POJO.parse("<line/>");
+ // final Point<Node> insertAt = doc.locate(3);
+ final Point<Node> insertAt = doc.locate(1);
+
+ final Nindo.Builder builder = new Nindo.Builder();
+ builder.skip(1);
+ // builder.skip(3);
+ final ReadableStringSet mutations = new RichTextMutationBuilder().applyMutations(tokens, builder,
+ doc, insertAt.getContainer());
+
+ final Nindo nindo = builder.build();
+ try {
+ doc.consumeAndReturnInvertible(nindo);
+ } catch (final OperationException e) {
+ throw new DefaultException("Operation Exception " + e);
+ }
+ doc.asOperation();
+ return new Pair<Nindo, IndexedDocument<Node, Element, Text>>(nindo, doc);
+ }
+
+ public static IndexedDocument<Node, Element, Text> unrender(final String content) {
+ final RawElementStyleView rawEl = new RawElementStyleView(RawDocumentProviderImpl.create(
+ RawDocumentImpl.BUILDER).parse("<div>" + content + "</div>"));
+ final RichTextTokenizerImpl<Node, Element, Text> tokenizer = new RichTextTokenizerImpl<Node, Element, Text>(
+ rawEl);
+ final Pair<Nindo, IndexedDocument<Node, Element, Text>> result = applyTokensToEmptyDoc(tokenizer);
+ return result.getSecond();
+ }
+
+}
Modified: trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -149,7 +149,8 @@
final String d = element.getProperty(Line.DIRECTION);
final Integer ident = i != null ? Integer.valueOf(i) : 0;
if (inheader) {
- builder.append("</div>");
+ // New line, we close previous header
+ builder.append("</div> <!-- end h1/h2... header -->");
inheader = false;
}
if (t != null && t.equals(Paragraph.LIST_TYPE)) {
Modified: trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -16,52 +16,54 @@
*/
package com.google.wave.splash.text;
+import java.util.Map;
+import java.util.logging.Logger;
-import com.google.common.collect.Maps;
-import com.google.wave.api.Annotations;
-import com.google.wave.api.Line;
-
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
+import org.jsoup.safety.Whitelist;
+import com.google.wave.api.Annotation;
+import com.google.common.collect.Maps;
+import com.google.wave.api.Annotations;
+import com.google.wave.api.Line;
-import java.util.Map;
-import java.util.logging.Logger;
-
-/**
- * @author anthonybaxter(a)gmail.com (Anthony Baxter)
- */
public class ContentUnrenderer {
- private static final Logger LOG = Logger.getLogger(ContentUnrenderer.class.getName());
-
/**
- * Turns a HTML document back into a set of text, elements, annotations.
+ * Container for the output of the unrender method.
*/
- public static UnrenderedBlip unrender(String content) {
- StringBuilder sb = new StringBuilder();
- Map<Integer, com.google.wave.api.Element> elements = Maps.newHashMap();
+ public static class UnrenderedBlip {
Annotations annotations = new Annotations();
- Document doc = Jsoup.parse(content);
- unrender(doc.body(), sb, elements, annotations);
- return new UnrenderedBlip(sb.toString(), elements, annotations);
+ public String contents;
+ Map<Integer, com.google.wave.api.Element> elements;
+
+ UnrenderedBlip(final String contents, final Map<Integer, com.google.wave.api.Element> elements,
+ final Annotations annotations) {
+ this.contents = contents;
+ this.elements = elements;
+ this.annotations = annotations;
+ }
}
+ private static final Logger LOG = Logger.getLogger(ContentUnrenderer.class.getName());
+
/**
- * Helper method to recursively parse a HTML element and construct a wave document.
+ * Helper method to recursively parse a HTML element and construct a wave
+ * document.
*/
- private static void unrender(Node parent, StringBuilder output, Map<Integer,
- com.google.wave.api.Element> elements, Annotations annotations) {
- for (Node node : parent.childNodes()) {
+ private static void unrender(final Node parent, final StringBuilder output,
+ final Map<Integer, com.google.wave.api.Element> elements, final Annotations annotations) {
+ for (final Node node : parent.childNodes()) {
if (node instanceof TextNode) {
- output.append(((TextNode)node).text());
- }
- else if (node instanceof Element) {
- int position = output.length();
- Element element = (Element)node;
- if ("p".equals(element.tag().getName())) {
+ output.append(((TextNode) node).text());
+ } else if (node instanceof Element) {
+ final int position = output.length();
+ final Element element = (Element) node;
+ final String name = element.tag().getName();
+ if ("p".equalsIgnoreCase(name)) {
elements.put(position, new Line());
// handle any attributes?
}
@@ -73,18 +75,16 @@
}
/**
- * Container for the output of the unrender method.
+ * Turns a HTML document back into a set of text, elements, annotations.
*/
- public static class UnrenderedBlip {
- public String contents;
- Map<Integer, com.google.wave.api.Element> elements;
- Annotations annotations = new Annotations();
-
- UnrenderedBlip(String contents, Map<Integer, com.google.wave.api.Element> elements,
- Annotations annotations) {
- this.contents = contents;
- this.elements = elements;
- this.annotations = annotations;
- }
+ public static UnrenderedBlip unrender(final String content) {
+ final StringBuilder sb = new StringBuilder();
+ final Map<Integer, com.google.wave.api.Element> elements = Maps.newHashMap();
+ final Annotations annotations = new Annotations();
+ // Sanitized
+ final String safe = Jsoup.clean(content, Whitelist.basic());
+ final Document doc = Jsoup.parse(safe);
+ unrender(doc.body(), sb, elements, annotations);
+ return new UnrenderedBlip(sb.toString(), elements, annotations);
}
}
Added: trunk/src/main/java/com/google/wave/splash/text/HtmlRawViewImpl.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/HtmlRawViewImpl.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/text/HtmlRawViewImpl.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,207 @@
+/**
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.text;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.waveprotocol.wave.model.document.raw.impl.Element;
+import org.waveprotocol.wave.model.document.raw.impl.Node;
+import org.waveprotocol.wave.model.document.raw.impl.Text;
+import org.waveprotocol.wave.model.document.util.ElementStyleView;
+import org.waveprotocol.wave.model.document.util.Point;
+
+/**
+ * Presents a simple view of a HTML document where you can walk through every
+ * node. It is rooted at a specific element (i.e. it can be a subtree of a full
+ * document). However the results of attempting to traverse outside the document
+ * are undefined.
+ *
+ * @author danilatos(a)google.com (Daniel Danilatos)
+ *
+ * Adapted to be used in served side by vjrj(a)ourproject.org
+ *
+ */
+public class HtmlRawViewImpl implements ElementStyleView<Node, Element, Text> { // HTMLView
+
+ /**
+ * Singleton instance, if you don't care about not having a document element
+ * defined.
+ */
+ public static final HtmlRawViewImpl INSTANCE = new HtmlRawViewImpl(null);
+
+ Element documentElement;
+
+ /**
+ * @param documentElement
+ * Root element for this "document"
+ */
+ public HtmlRawViewImpl(final Element documentElement) {
+ this.documentElement = documentElement;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Element asElement(final Node node) {
+ return node.asElement();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Text asText(final Node node) {
+ return node.asText();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getAttribute(final Element element, final String name) {
+ // FIXME: test!
+ return element.getAttribute(name);
+ // return name.equals("class") ? element.getClassName() :
+ // element.getAttribute(name);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Map<String, String> getAttributes(final Element element) {
+ return Collections.emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getData(final Text textNode) {
+ return textNode.getData();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Element getDocumentElement() {
+ return documentElement;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getFirstChild(final Node node) {
+ return node.getFirstChild();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getLastChild(final Node node) {
+ return node.getLastChild();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int getLength(final Text textNode) {
+ return textNode.getLength();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getNextSibling(final Node node) {
+ return node.getNextSibling();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public short getNodeType(final Node node) { // NOPMD by vjrj on 4/07/11 20:55
+ return node.getNodeType();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Element getParentElement(final Node node) {
+ return node.getParentElement();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getPreviousSibling(final Node node) {
+ return node.getPreviousSibling();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getStylePropertyValue(final Element element, final String name) {
+ return getStylePropertyValue(element.getAttribute("style"), name);
+ }
+
+ private String getStylePropertyValue(final String styles, final String name) {
+ if (styles != null && styles.contains(name)) {
+ for (final String stylePair : styles.split(";")) {
+ final int index = stylePair.indexOf(':');
+ if (index >= 0 && index < stylePair.length() - 1) {
+ final String key = stylePair.substring(0, index).trim();
+ final String value = stylePair.substring(index + 1);
+ if (key.equalsIgnoreCase(name)) {
+ return value.trim();
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getTagName(final Element element) {
+ return element.getTagName();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getVisibleNode(final Node node) {
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getVisibleNodeFirst(final Node node) {
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getVisibleNodeLast(final Node node) {
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getVisibleNodeNext(final Node node) {
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Node getVisibleNodePrevious(final Node node) {
+ return node;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isSameNode(final Node node, final Node other) {
+ // TODO(danilatos): Use .equals or isSameNode for nodelets in nodemanager,
+ // typing extractor, etc.
+ return node == other || (node != null && node.equals(other));
+ }
+
+ @Override
+ public void onBeforeFilter(final Point<Node> at) {
+ }
+}
Added: trunk/src/main/java/com/google/wave/splash/text/UnrenderUtils.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/UnrenderUtils.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/text/UnrenderUtils.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,123 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.google.wave.splash.text;
+
+import org.jsoup.nodes.Element;
+
+/**
+ * Adaptation from Wave RichTextTokenizer.
+ *
+ * Not used yet, so deprecated
+ */
+@Deprecated
+public class UnrenderUtils {
+
+ public static boolean isBlockElement(final String tagName) {
+ return "p".equalsIgnoreCase(tagName) || "div".equalsIgnoreCase(tagName) || isListItem(tagName);
+ }
+
+ public static boolean isHeading(final String tagName) {
+ if (tagName.length() == 2) {
+ if (tagName.charAt(0) == 'h' || tagName.charAt(0) == 'H') {
+ final int size = tagName.charAt(1) - '0';
+ if (size >= 1 && size <= 4) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static boolean isLink(final String tagName) {
+ return "a".equalsIgnoreCase(tagName);
+ }
+
+ public static boolean isList(final String tagName) {
+ return isOrderedList(tagName) || isUnorderedList(tagName);
+ }
+
+ public static boolean isListItem(final String tagName) {
+ return "li".equalsIgnoreCase(tagName);
+ }
+
+ public static boolean isNewline(final String tagName) {
+ return "br".equalsIgnoreCase(tagName);
+ }
+
+ public static boolean isOrderedList(final String tagName) {
+ return "ol".equalsIgnoreCase(tagName);
+ }
+
+ public static boolean isTable(final String tagName) {
+ return "table".equalsIgnoreCase(tagName);
+ }
+
+ public static boolean isTableCell(final String tagName) {
+ return "th".equalsIgnoreCase(tagName) || "td".equalsIgnoreCase(tagName);
+ }
+
+ public static boolean isTableRelated(final String tagName) {
+ // TODO(patcoleman): fix up table implementation once tables supported in
+ // the editor.
+ // When this happens, also extract out strings into symbolic constants.
+ return isTable(tagName) || isTableRow(tagName) || isTableCell(tagName)
+ || "thead".equalsIgnoreCase(tagName) || "tbody".equalsIgnoreCase(tagName);
+ }
+
+ public static boolean isTableRow(final String tagName) {
+ return "tr".equalsIgnoreCase(tagName);
+ }
+
+ public static boolean isUnorderedList(final String tagName) {
+ return "ul".equalsIgnoreCase(tagName);
+ }
+
+ private String getStylePropertyValue(final String styles, final String name) {
+ if (styles != null && styles.contains(name)) {
+ for (final String stylePair : styles.split(";")) {
+ final int index = stylePair.indexOf(':');
+ if (index >= 0 && index < stylePair.length() - 1) {
+ final String key = stylePair.substring(0, index).trim();
+ final String value = stylePair.substring(index + 1);
+ if (key.equalsIgnoreCase(name)) {
+ return value.trim();
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public boolean isBackgroundColor(final Element el) {
+ return isStylePropertySet(el, "backgroundColor");
+ }
+
+ public boolean isColor(final Element el) {
+ return isStylePropertySet(el, "color");
+ }
+
+ public boolean isFontFamily(final Element el) {
+ return isStylePropertySet(el, "fontFamily");
+ }
+
+ public boolean isStylePropertySet(final Element el, final String property) {
+ final String value = getStylePropertyValue(el.attr("style"), property);
+ return value != null && !value.isEmpty();
+ }
+
+}
Added: trunk/src/test/java/cc/kune/wave/server/KuneAgentTest.java
===================================================================
--- trunk/src/test/java/cc/kune/wave/server/KuneAgentTest.java (rev 0)
+++ trunk/src/test/java/cc/kune/wave/server/KuneAgentTest.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,72 @@
+package cc.kune.wave.server;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.waveprotocol.box.server.account.AccountData;
+import org.waveprotocol.box.server.account.RobotAccountData;
+import org.waveprotocol.box.server.persistence.AccountStore;
+import org.waveprotocol.box.server.persistence.PersistenceException;
+import org.waveprotocol.wave.model.id.TokenGenerator;
+import org.waveprotocol.wave.model.wave.InvalidParticipantAddress;
+import org.waveprotocol.wave.model.wave.ParticipantId;
+import org.waveprotocol.wave.model.waveref.WaveRef;
+
+import cc.kune.wave.server.AbstractBaseRobotAgent.ServerFrontendAddressHolder;
+
+import com.google.common.collect.Lists;
+import com.google.wave.api.Wavelet;
+
+public class KuneAgentTest {
+ private static final String MESSAGE = "testing";
+ private static final String NEW_PARTICIPANT = "newparti";
+ private static final String RICHTEXT_MESSAGE = "<b>" + MESSAGE + "</b>";
+ private static final String TEST_GADGET = "http://wave-api.appspot.com/public/gadgets/areyouin/gadget.xml";
+ private static final String TITLE = "title";
+ private static final String TITLENEW = "titleNew";
+
+ KuneAgent manager;
+
+ @Before
+ public void before() throws PersistenceException, InvalidParticipantAddress {
+ final ServerFrontendAddressHolder frontendAddressHolder = Mockito.mock(ServerFrontendAddressHolder.class);
+ Mockito.when(frontendAddressHolder.getAddresses()).thenReturn(Lists.newArrayList("localhost:9898"));
+ final TokenGenerator tokenGenerator = Mockito.mock(TokenGenerator.class);
+ Mockito.when(tokenGenerator.generateToken(Mockito.anyInt())).thenReturn("abcde");
+ final AccountStore accountStore = Mockito.mock(AccountStore.class);
+ final AccountData accountData = Mockito.mock(AccountData.class);
+ final RobotAccountData accountRobotData = Mockito.mock(RobotAccountData.class);
+ final ParticipantId participantId = ParticipantId.of("kune-agent(a)example.com");
+
+ Mockito.when(accountStore.getAccount((ParticipantId) Mockito.anyObject())).thenReturn(accountData);
+ Mockito.when(accountData.asRobot()).thenReturn(accountRobotData);
+ Mockito.when(accountRobotData.getUrl()).thenReturn(KuneAgent.ROBOT_URI);
+ Mockito.when(accountRobotData.getId()).thenReturn(participantId);
+ Mockito.when(accountRobotData.getConsumerSecret()).thenReturn("someconsumer");
+ manager = new KuneAgent("example.com", accountStore, tokenGenerator, frontendAddressHolder);
+ }
+
+ private String getSiteAdminShortName() {
+ // TODO Auto-generated method stub
+
+ return "admin(a)example.com";
+ }
+
+ @Ignore
+ @Test
+ public void testBasicCreation() throws InvalidParticipantAddress {
+ final WaveRef waveletName = manager.createWave(RICHTEXT_MESSAGE,
+ ParticipantId.of(getSiteAdminShortName()));
+ assertNotNull(waveletName);
+ final Wavelet fetchWavelet = manager.fetchWavelet(waveletName, getSiteAdminShortName());
+ assertNotNull(fetchWavelet);
+ assertTrue(fetchWavelet.getRootBlip().getAnnotations().size() > 0);
+ assertEquals("", fetchWavelet.getRootBlip().getContent());
+ assertTrue(fetchWavelet.getRootBlip().getContent().contains(MESSAGE));
+ }
+}
Modified: trunk/src/test/java/cc/kune/wave/server/KuneWaveManagerDefaultTest.java
===================================================================
--- trunk/src/test/java/cc/kune/wave/server/KuneWaveManagerDefaultTest.java 2011-07-08 00:00:41 UTC (rev 1441)
+++ trunk/src/test/java/cc/kune/wave/server/KuneWaveManagerDefaultTest.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -41,11 +41,12 @@
private static final String MESSAGE = "testing";
private static final String NEW_PARTICIPANT = "newparti";
+ private static final String RICHTEXT_MESSAGE = "<b>" + MESSAGE + "</b>";
private static final String TEST_GADGET = "http://wave-api.appspot.com/public/gadgets/areyouin/gadget.xml";
private static final String TITLE = "title";
private static final String TITLENEW = "titleNew";
@Inject
- KuneWaveManagerDefault manager;
+ KuneWaveManager manager;
@Inject
ParticipantUtils participantUtils;
@@ -78,27 +79,28 @@
@Before
public void before() {
new IntegrationTestHelper(this);
-
}
private WaveRef createTestWave() {
- return manager.createWave(TITLE, MESSAGE, participantUtils.of(getSiteAdminShortName()));
+ return manager.createWave(TITLE, RICHTEXT_MESSAGE, participantUtils.of(getSiteAdminShortName()));
}
@Test
public void createWave() throws DefaultException, IOException {
doLogin();
- final WaveRef waveletName = manager.createWave(MESSAGE, participantUtils.of(getSiteAdminShortName()));
+ final WaveRef waveletName = manager.createWave(RICHTEXT_MESSAGE,
+ participantUtils.of(getSiteAdminShortName()));
assertNotNull(waveletName);
final Wavelet fetchWavelet = manager.fetchWavelet(waveletName, getSiteAdminShortName());
assertNotNull(fetchWavelet);
+ assertTrue(fetchWavelet.getRootBlip().getAnnotations().size() > 0);
assertTrue(fetchWavelet.getRootBlip().getContent().contains(MESSAGE));
}
@Test
public void createWaveWithGadget() throws DefaultException, IOException {
doLogin();
- final WaveRef waveletName = manager.createWave(TITLE, MESSAGE, new URL(TEST_GADGET),
+ final WaveRef waveletName = manager.createWave(TITLE, RICHTEXT_MESSAGE, new URL(TEST_GADGET),
participantUtils.of(getSiteAdminShortName()));
assertNotNull(waveletName);
final Wavelet fetchWavelet = manager.fetchWavelet(waveletName, getSiteAdminShortName());
Added: trunk/src/test/java/com/google/wave/splash/text/ContentNewUnrendererTest.java
===================================================================
--- trunk/src/test/java/com/google/wave/splash/text/ContentNewUnrendererTest.java (rev 0)
+++ trunk/src/test/java/com/google/wave/splash/text/ContentNewUnrendererTest.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,20 @@
+package com.google.wave.splash.text;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.google.wave.splash.text.ContentUnrenderer.UnrenderedBlip;
+
+public class ContentNewUnrendererTest {
+
+ @Ignore
+ @Test
+ public void testBasicUnrender() {
+ // final IndexedDocument<Node, Element, Text> result =
+ // ContentNewUnrenderer.unrender("<b>Some <em>bold</em></b>");
+ final UnrenderedBlip result = ContentUnrenderer.unrender("<p></p><p><b>Some <em>bold</em></b></p>");
+ assertEquals("", result.elements.toString());
+ }
+}
Added: trunk/src/test/java/com/google/wave/splash/text/ContentUnrendererTest.java
===================================================================
--- trunk/src/test/java/com/google/wave/splash/text/ContentUnrendererTest.java (rev 0)
+++ trunk/src/test/java/com/google/wave/splash/text/ContentUnrendererTest.java 2011-07-09 16:44:34 UTC (rev 1442)
@@ -0,0 +1,22 @@
+package com.google.wave.splash.text;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.waveprotocol.wave.model.document.indexed.IndexedDocument;
+import org.waveprotocol.wave.model.document.raw.impl.Element;
+import org.waveprotocol.wave.model.document.raw.impl.Node;
+import org.waveprotocol.wave.model.document.raw.impl.Text;
+
+public class ContentUnrendererTest {
+
+ @Ignore
+ @Test
+ public void testBasicUnrender() {
+ final IndexedDocument<Node, Element, Text> unrender = ContentNewUnrenderer.unrender("<b>foo</b>");
+ assertEquals("", unrender.toXmlString());
+ // assertTrue(blip.annotations.size() > 0);
+ }
+
+}
1
0
r1441 - in trunk/src/main/java: cc/kune/core/public com/google/wave/splash/text
by Vicente J. Ruiz Jurado 08 Jul '11
by Vicente J. Ruiz Jurado 08 Jul '11
08 Jul '11
Author: vjrj_
Date: 2011-07-08 02:00:41 +0200 (Fri, 08 Jul 2011)
New Revision: 1441
Modified:
trunk/src/main/java/cc/kune/core/public/ws.css
trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java
Log:
Better render of waves
Modified: trunk/src/main/java/cc/kune/core/public/ws.css
===================================================================
--- trunk/src/main/java/cc/kune/core/public/ws.css 2011-07-02 11:35:31 UTC (rev 1440)
+++ trunk/src/main/java/cc/kune/core/public/ws.css 2011-07-08 00:00:41 UTC (rev 1441)
@@ -1385,4 +1385,30 @@
text-decoration: underline;
color: gray;
cursor: pointer;
-}
\ No newline at end of file
+}
+
+/*
+ * These attributes are required to make a paragraph look like a list-item
+ * across browsers. (copied from Editor.css)
+ */
+.simulated-li {
+ display: list-item;
+ list-style-type: disc;
+ list-style-position: outside;
+}
+
+.numbered {
+ list-style-type: decimal;
+}
+
+.bullet-type-0 {
+ list-style-type: disc;
+}
+
+.bullet-type-1 {
+ list-style-type: circle;
+}
+
+.bullet-type-2 {
+ list-style-type: square;
+}
Modified: trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java 2011-07-02 11:35:31 UTC (rev 1440)
+++ trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java 2011-07-08 00:00:41 UTC (rev 1441)
@@ -22,6 +22,10 @@
import java.util.SortedSet;
import java.util.TreeSet;
+import org.waveprotocol.wave.client.editor.content.paragraph.DefaultParagraphHtmlRenderer;
+import org.waveprotocol.wave.client.editor.content.paragraph.Paragraph;
+
+import com.google.gwt.dom.client.Style.FontWeight;
import com.google.inject.Inject;
import com.google.wave.api.Annotation;
import com.google.wave.api.Annotations;
@@ -29,6 +33,7 @@
import com.google.wave.api.Element;
import com.google.wave.api.ElementType;
import com.google.wave.api.Gadget;
+import com.google.wave.api.Line;
import com.google.wave.splash.web.template.WaveRenderer;
/**
@@ -93,6 +98,8 @@
}
private final GadgetRenderer gadgetRenderer;
+ private boolean identing;
+ private boolean inheader = false;
private final WaveRenderer waveRenderer;
@Inject
@@ -101,8 +108,17 @@
this.waveRenderer = waveRenderer;
}
- private void emitStyleAnnotation(final Marker marker, final StringBuilder builder) {
+ private void closeIndentIfNecessary(final StringBuilder builder) {
+ if (identing) {
+ // Close identations
+ identing = false;
+ builder.append("</li>");
+ }
+ }
+
+ private void emitAnnotation(final Marker marker, final StringBuilder builder) {
if (marker.isEnd) {
+ // if (marker.annotation.getName().)
builder.append("</span>");
} else {
// Transform name into dash-separated css property rather than lower camel
@@ -127,13 +143,54 @@
final ElementType type = element.getType();
switch (type) {
case LINE:
+ final String t = element.getProperty(Line.LINE_TYPE);
+ final String i = element.getProperty(Line.INDENT);
+ final String a = element.getProperty(Line.ALIGNMENT);
+ final String d = element.getProperty(Line.DIRECTION);
+ final Integer ident = i != null ? Integer.valueOf(i) : 0;
+ if (inheader) {
+ builder.append("</div>");
+ inheader = false;
+ }
+ if (t != null && t.equals(Paragraph.LIST_TYPE)) {
+ // type-0 to 2, margin 22px * i <li class="bullet-type-0"
+ // style="margin-left: 88px;">
+ // See DefaultParagraphHtml
+ builder.append("<li class=\"bullet-type-").append(ident % 3).append("\" style=\"margin-left: ").append(
+ (ident + 1) * 22).append("px;\">");
+ identing = true;
+ } else if (ident > 0) {
+ builder.append("<li style=\"margin-left: ").append(ident * 22).append("px;\">");
+ identing = true;
+ } else {
+ closeIndentIfNecessary(builder);
+ }
+ if (t != null && t.startsWith("h")) {
+ // See DefaultParagraphHtml
+ final String fontWeight = FontWeight.BOLD.getCssName();
+ final double headingNum = Integer.parseInt(t.substring(1));
+ // Do this with CSS instead.
+ // h1 -> 1.75, h4 -> 1, others linearly in between.
+ final double factor = 1 - (headingNum - 1) / (Paragraph.NUM_HEADING_SIZES - 1);
+ final double fontSize = DefaultParagraphHtmlRenderer.MIN_HEADING_SIZE_EM
+ + factor
+ * (DefaultParagraphHtmlRenderer.MAX_HEADING_SIZE_EM - DefaultParagraphHtmlRenderer.MIN_HEADING_SIZE_EM);
+ builder.append("<div style=\"font-size: ").append(fontSize).append("em; font-weight: ").append(
+ fontWeight).append(";\">");
+ inheader = true;
+ }
// TODO(anthonybaxter): need to handle <line t="li"> and <line t="li"
// i="3">
// TODO(anthonybaxter): also handle H1 &c
// Special case: If this is the first LINE element at position 0,
// ignore it because we've already appended the first <p> tag.
+
if (index > 0) {
builder.append("</p><p>");
+ } else {
+ // We build "<li>" with a main wrapper ul
+ // FIXME, close finally the ul
+ builder.append("<ul style=\"padding: 0px; margin: 0px;\">");
}
break;
case ATTACHMENT:
@@ -225,7 +282,7 @@
if (marker.isElement()) {
renderElement(marker.element, marker.index, contributors, builder);
} else {
- emitStyleAnnotation(marker, builder);
+ emitAnnotation(marker, builder);
}
}
@@ -235,6 +292,6 @@
}
// Replace empty paragraphs. (TODO expensive and silly)
- return builder.toString().replace("<p>\n</p>", "<p><br/></p>");
+ return builder.append("</ul>").toString().replace("<p>\n</p>", "<p><br/></p>");
}
}
1
0
Author: jpzafra
Date: 2011-07-02 13:35:31 +0200 (Sat, 02 Jul 2011)
New Revision: 1440
Modified:
trunk/src/main/webapp/others/kune-client-actions.xml
Log:
new list of extensions
Modified: trunk/src/main/webapp/others/kune-client-actions.xml
===================================================================
--- trunk/src/main/webapp/others/kune-client-actions.xml 2011-07-01 11:27:50 UTC (rev 1439)
+++ trunk/src/main/webapp/others/kune-client-actions.xml 2011-07-02 11:35:31 UTC (rev 1440)
@@ -4,8 +4,128 @@
<!-- List of Wave extensions to use in Kune ===================== -->
<waveExtensions>
+ <extension>
+ <name>Image</name>
+ <installerUrl>http://everybodywave.appspot.com/gadget/image/xt.xml
+ </installerUrl>
+ <gadgetUrl>http://everybodywave.appspot.com/gadget/image/gadget.xml
+ </gadgetUrl>
+ <iconUrl>http://everybodywave.appspot.com/gadget/image/icon.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>Quick Notify</name>
+ <installerUrl>http://code.google.com/p/wave-projects/source/browse/gadgets/wave-quick-not…
+ </installerUrl>
+ <gadgetUrl>http://wave-projects.googlecode.com/hg/gadgets/wave-quick-notify.xml
+ </gadgetUrl>
+ <iconUrl>http://wave-projects.googlecode.com/hg/gadgets/images/qn.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>tasklistbot</name>
+ <installerUrl>http://tasklistbot.appspot.com/TaskList.xml
+ </installerUrl>
+ <gadgetUrl>http://everybodywave.appspot.com/gadget/foobar/main.xml
+ </gadgetUrl>
+ <iconUrl>http://tasklistbot.appspot.com/resources/tasklistbot_avatar.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
<extension>
+ <name>Yes/No/Mini</name>
+ <installerUrl>http://mysite.verizon.net/zmyaro/mystuff/wave/ynmini.xml
+ </installerUrl>
+ <gadgetUrl>http://mysite.verizon.net/zmyaro/projects/wave/gadgets/ynmini.xml
+ </gadgetUrl>
+ <iconUrl>http://mysite.verizon.net/zmyaro/projects/wave/gadgets/ynmini_icon.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>Yes/No/Maybe/+</name>
+ <installerUrl>http://everybodywave.appspot.com/gadget/foobar/xt.xml
+ </installerUrl>
+ <gadgetUrl>http://everybodywave.appspot.com/gadget/foobar/main.xml
+ </gadgetUrl>
+ <iconUrl>http://everybodywave.appspot.com/gadget/foobar/icon.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>Shorten URL with goo.gl</name>
+ <installerUrl>http://haru1ban-wave.googlecode.com/svn/trunk/goo_gl/manifest.xml
+ </installerUrl>
+ <gadgetUrl>http://haru1ban-wave.googlecode.com/svn/trunk/goo_gl/goo_gl.xml
+ </gadgetUrl>
+ <iconUrl>http://haru1ban-wave.googlecode.com/svn/trunk/goo_gl/goo_gl_icon.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>Poll</name>
+ <installerUrl>http://wave.samuirai.de/install_poll.xml
+ </installerUrl>
+ <gadgetUrl>http://wave.samuirai.de/poll.xml
+ </gadgetUrl>
+ <iconUrl>http://wave.samuirai.de/poll_icon.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>TaskToDo</name>
+ <installerUrl>http://www.voizle.com/ToDoInstaller.xml
+ </installerUrl>
+ <gadgetUrl>http://www.voizle.com/ToDo.xml
+ </gadgetUrl>
+ <iconUrl>http://www.voizle.com/image/task.orig.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>Picasa Gadget</name>
+ <installerUrl>http://wave-picasa.googlecode.com/svn/trunk/manifest_wave_picasa.xml
+ </installerUrl>
+ <gadgetUrl>http://wave-picasa.googlecode.com/svn/trunk/picasa.xml
+ </gadgetUrl>
+ <iconUrl>http://wave-picasa.googlecode.com/svn/trunk/picasa_icon.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>Map</name>
+ <installerUrl>http://google-wave-resources.googlecode.com/svn/trunk/samples/extensions/ga…
+ </installerUrl>
+ <gadgetUrl>http://google-wave-resources.googlecode.com/svn/trunk/samples/extensions/ga…
+ </gadgetUrl>
+ <iconUrl>https://wave-api.appspot.com/public/images/insertMap.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
+ <name>MindMap</name>
+ <installerUrl>http://cactus-wave.appspot.com/mindmap.xml
+ </installerUrl>
+ <gadgetUrl>http://cactus-wave.appspot.com/net.brucecooper.mindmapgadget.MindMapGadget/…
+ </gadgetUrl>
+ <iconUrl>https://wave-api.appspot.com/public/images/insertMap.png
+ </iconUrl>
+ <iconCss></iconCss>
+ </extension>
+
+ <extension>
<name>pollo</name>
<installerUrl>http://wavepollo.appspot.com/pollo.xml
</installerUrl>
@@ -15,7 +135,7 @@
</iconUrl>
<iconCss></iconCss>
</extension>
-
+
<extension>
<name>waffle</name>
<installerUrl>http://www.waffle.dk/install.xml
@@ -66,8 +186,275 @@
<guiActionDescriptors>
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>Map</extensionName>
+ <name>New Map</name>
+ <path>Gadget»Media</path>
+ <description>Collaborate on a map of placemarks, paths, and shapes with other participants. Great for planning events and trips.</description>
+ <new-content-title>New Map</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
<guiActionDescriptor>
<type>wave-gadget</type>
+ <extensionName>Picasa Gadget</extensionName>
+ <name>New Album</name>
+ <path>Gadget»Media</path>
+ <description>Add a Picasa photo album to a wave.</description>
+ <new-content-title>New Album</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>TaskToDo</extensionName>
+ <name>New To-Do list</name>
+ <path>Gadget»Tasks</path>
+ <description>Make your To-Do list and mark your progress.</description>
+ <new-content-title>New To-Do list</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>Shorten URL with goo.gl</extensionName>
+ <name>New Shorten URL</name>
+ <path>Gadget»Links</path>
+ <description>Shorten url with goo.gl, the new Google url shortener.(http://goo.gl/)</description>
+ <new-content-title>New Shorten URL</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>Poll</extensionName>
+ <name>New Advanced Poll</name>
+ <path>Gadget»Voting</path>
+ <description>You can add a poll to your Wave. Accordingly you can embed the result with the Google Chart API into your Wave.</description>
+ <new-content-title>New Advanced Poll</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>Yes/No/Maybe/+</extensionName>
+ <name>New Yes/No/Maybe/+ Voting</name>
+ <path>Gadget»Voting</path>
+ <description>Same as Google's Yes/No/Maybe, only you can edit the titles and add new ones.</description>
+ <new-content-title>New Yes/No/Maybe/+ Voting</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>Yes/No/Mini</extensionName>
+ <name>New Yes/no/Mini Voting</name>
+ <path>Gadget»Voting</path>
+ <description>A miniature version of the Yes/No/Maybe gadget.</description>
+ <new-content-title>New Yes/no/Mini Voting</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>tasklistbot</extensionName>
+ <name>New Task List</name>
+ <path>Gadget»Tasks</path>
+ <description></description>
+ <new-content-title>New Task List</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>Quick Notify</extensionName>
+ <name>New Notification</name>
+ <path>Gadget»Organization</path>
+ <description>Quickly send a short email with a custom message to all participants.</description>
+ <new-content-title>New Notification</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>MindMap</extensionName>
+ <name>New MindMap</name>
+ <path>Gadget»Organization</path>
+ <description>Collaborate using a hierarchical mind map.</description>
+ <new-content-title>New MindMap</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
+ <extensionName>Image</extensionName>
+ <name>New Image</name>
+ <path>Gadget»Media</path>
+ <description>Lets you insert, resize and annotate any image from the web.</description>
+ <new-content-title>New image</new-content-title>
+ <new-content-textintro></new-content-textintro>
+ <enabled>true</enabled>
+ <typeIds>
+ <typeId origTypeId="docs.folder" destTypeId="docs.doc" />
+ <typeId origTypeId="docs.root" destTypeId="docs.doc" />
+ <typeId origTypeId="blogs.blog" destTypeId="blogs.post" />
+ </typeIds>
+ <rol>
+ <!-- Administrator, Editor, Viewer -->
+ <rolRequired>Editor</rolRequired>
+ <authNeed>true</authNeed>
+ </rol>
+ <!-- only for new waves: anyone, onlymembers, onlyadmins, ask (not
+ used yet) -->
+ <participants>ask</participants>
+ </guiActionDescriptor>
+
+ <guiActionDescriptor>
+ <type>wave-gadget</type>
<extensionName>massmob</extensionName>
<name>New meeting</name>
<path>Gadget»Calendar</path>
@@ -212,4 +599,4 @@
</guiActionDescriptors>
-</kuneClientActions>
\ No newline at end of file
+</kuneClientActions>
1
0
Author: vjrj_
Date: 2011-07-01 13:27:50 +0200 (Fri, 01 Jul 2011)
New Revision: 1439
Added:
trunk/src/main/java/com/google/
trunk/src/main/java/com/google/wave/
trunk/src/main/java/com/google/wave/splash/
trunk/src/main/java/com/google/wave/splash/rpc/
trunk/src/main/java/com/google/wave/splash/rpc/ClientAction.java
trunk/src/main/java/com/google/wave/splash/text/
trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java
trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java
trunk/src/main/java/com/google/wave/splash/text/GadgetRenderer.java
trunk/src/main/java/com/google/wave/splash/text/Markup.java
trunk/src/main/java/com/google/wave/splash/web/
trunk/src/main/java/com/google/wave/splash/web/template/
trunk/src/main/java/com/google/wave/splash/web/template/Templates.java
trunk/src/main/java/com/google/wave/splash/web/template/ThreadedWaveRenderer.java
trunk/src/main/java/com/google/wave/splash/web/template/WaveRenderer.java
trunk/src/main/webapp/others/splash/
trunk/src/main/webapp/others/splash/blip.html.fragment
trunk/src/main/webapp/others/splash/feed.html.fragment
trunk/src/main/webapp/others/splash/full_client.html
trunk/src/main/webapp/others/splash/header.html.fragment
trunk/src/main/webapp/others/splash/images/
trunk/src/main/webapp/others/splash/images/attachment.png
trunk/src/main/webapp/others/splash/images/avatar1.png
trunk/src/main/webapp/others/splash/images/avatar2.png
trunk/src/main/webapp/others/splash/images/avatar3.png
trunk/src/main/webapp/others/splash/images/avatar4.png
trunk/src/main/webapp/others/splash/images/avatar5.png
trunk/src/main/webapp/others/splash/images/avatar6.png
trunk/src/main/webapp/others/splash/images/background_dot.png
trunk/src/main/webapp/others/splash/images/close_window.png
trunk/src/main/webapp/others/splash/images/comment.png
trunk/src/main/webapp/others/splash/images/cross.png
trunk/src/main/webapp/others/splash/images/dialog_close.gif
trunk/src/main/webapp/others/splash/images/dialog_pointer.gif
trunk/src/main/webapp/others/splash/images/email.png
trunk/src/main/webapp/others/splash/images/group.png
trunk/src/main/webapp/others/splash/images/inline_reply_arrow.gif
trunk/src/main/webapp/others/splash/images/inline_reply_arrow_expanded.gif
trunk/src/main/webapp/others/splash/images/inline_reply_pointer.gif
trunk/src/main/webapp/others/splash/images/lightbox-blank.gif
trunk/src/main/webapp/others/splash/images/lightbox-btn-close.gif
trunk/src/main/webapp/others/splash/images/lightbox-btn-next.gif
trunk/src/main/webapp/others/splash/images/lightbox-btn-prev.gif
trunk/src/main/webapp/others/splash/images/lightbox-ico-loading.gif
trunk/src/main/webapp/others/splash/images/loading.gif
trunk/src/main/webapp/others/splash/images/loading_permalink.gif
trunk/src/main/webapp/others/splash/images/logo.png
trunk/src/main/webapp/others/splash/images/logo_on_black.png
trunk/src/main/webapp/others/splash/images/logo_small.png
trunk/src/main/webapp/others/splash/images/minimize_window.png
trunk/src/main/webapp/others/splash/images/page_edit.png
trunk/src/main/webapp/others/splash/images/pencil.png
trunk/src/main/webapp/others/splash/images/reply.png
trunk/src/main/webapp/others/splash/images/search_field_on_black.png
trunk/src/main/webapp/others/splash/images/search_field_on_black_button.png
trunk/src/main/webapp/others/splash/images/search_field_on_black_button_right.png
trunk/src/main/webapp/others/splash/images/search_field_on_black_left.png
trunk/src/main/webapp/others/splash/images/search_small_button.png
trunk/src/main/webapp/others/splash/images/share_icon.png
trunk/src/main/webapp/others/splash/images/user1.png
trunk/src/main/webapp/others/splash/images/user2.png
trunk/src/main/webapp/others/splash/images/user3.png
trunk/src/main/webapp/others/splash/images/user4.png
trunk/src/main/webapp/others/splash/images/user5.png
trunk/src/main/webapp/others/splash/images/user6.png
trunk/src/main/webapp/others/splash/images/wave-loading.gif
trunk/src/main/webapp/others/splash/js/
trunk/src/main/webapp/others/splash/js/common_client.js
trunk/src/main/webapp/others/splash/js/editor.js
trunk/src/main/webapp/others/splash/js/embed_support.js
trunk/src/main/webapp/others/splash/js/embed_test.js
trunk/src/main/webapp/others/splash/js/full_client.js
trunk/src/main/webapp/others/splash/js/gadget.js
trunk/src/main/webapp/others/splash/js/ie6sucks.js
trunk/src/main/webapp/others/splash/js/jScrollTouch.js
trunk/src/main/webapp/others/splash/js/jquery-1.4.2.min.js
trunk/src/main/webapp/others/splash/js/jquery.lightbox-0.5.min.js
trunk/src/main/webapp/others/splash/js/mobile_client.js
trunk/src/main/webapp/others/splash/js/permalink_client.js
trunk/src/main/webapp/others/splash/js/rpc.js
trunk/src/main/webapp/others/splash/js/rpc_test.js
trunk/src/main/webapp/others/splash/mobile_client.html
trunk/src/main/webapp/others/splash/permalink_client.html
trunk/src/main/webapp/others/splash/rpc_relay.html
trunk/src/main/webapp/others/splash/style/
trunk/src/main/webapp/others/splash/style/border-radius.htc
trunk/src/main/webapp/others/splash/style/jquery.lightbox-0.5.css
trunk/src/main/webapp/others/splash/style/main.css
trunk/src/main/webapp/others/splash/style/mobile.css
trunk/src/main/webapp/others/splash/style/orig-style.css
trunk/src/main/webapp/others/splash/style/permalink.css
trunk/src/main/webapp/others/splash/style/permalink_ie.css
trunk/src/main/webapp/others/splash/style/stuff.css
trunk/src/main/webapp/others/splash/wave_not_found.html.fragment
trunk/src/test/java/cc/kune/wave/server/KuneWaveMarkupTests.java
Removed:
trunk/src/main/java/org/ourproject/kune/chat/client/ctx/
trunk/src/main/java/org/ourproject/kune/wiki/client/
trunk/src/main/java/org/ourproject/kune/workspace/client/sitebar/
Modified:
trunk/.classpath
trunk/pom.xml
trunk/src/main/java/cc/kune/core/client/errors/DefaultException.java
trunk/src/main/java/cc/kune/core/client/services/FileDownloadUtils.java
trunk/src/main/java/cc/kune/core/public/ws.html
trunk/src/main/java/cc/kune/core/server/state/StateServiceDefault.java
trunk/src/main/java/cc/kune/wave/server/KuneWaveManager.java
trunk/src/main/java/cc/kune/wave/server/KuneWaveManagerDefault.java
trunk/src/test/java/cc/kune/wave/server/KuneWaveManagerDefaultTest.java
Log:
Wave renderer
Modified: trunk/.classpath
===================================================================
--- trunk/.classpath 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/.classpath 2011-07-01 11:27:50 UTC (rev 1439)
@@ -92,6 +92,7 @@
<classpathentry kind="var" path="M2_REPO/org/jruby/rack/jruby-rack/0.9.4/jruby-rack-0.9.4.jar"/>
<classpathentry kind="var" path="M2_REPO/org/json/json/20080701/json-20080701.jar" sourcepath="M2_REPO/org/json/json/20080701/json-20080701-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sf/json-lib/json-lib/2.1/json-lib-2.1-jdk15.jar" sourcepath="M2_REPO/net/sf/json-lib/json-lib/2.1/json-lib-2.1-jdk15-sources.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/jsoup/jsoup/1.2.2/jsoup-1.2.2.jar" sourcepath="M2_REPO/org/jsoup/jsoup/1.2.2/jsoup-1.2.2-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/findbugs/jsr-305/v0r47/jsr-305-v0r47.jar" sourcepath="M2_REPO/net/sourceforge/findbugs/jsr-305/v0r47/jsr-305-v0r47-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/jtidy/r8-20060801/jtidy-r8-20060801.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jukito/jukito/1.0/jukito-1.0.jar" sourcepath="M2_REPO/org/jukito/jukito/1.0/jukito-1.0-sources.jar"/>
@@ -111,6 +112,7 @@
<classpathentry kind="var" path="M2_REPO/org/waveprotocol/media-src/0.3.1-SNAPSHOT/media-src-0.3.1-SNAPSHOT.jar"/>
<classpathentry kind="var" path="M2_REPO/org/mockito/mockito-core/1.8.5/mockito-core-1.8.5.jar" sourcepath="M2_REPO/org/mockito/mockito-core/1.8.5/mockito-core-1.8.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/waveprotocol/model-src/0.3.1-SNAPSHOT/model-src-0.3.1-SNAPSHOT.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/mvel/mvel2/2.0.16/mvel2-2.0.16.jar" sourcepath="M2_REPO/org/mvel/mvel2/2.0.16/mvel2-2.0.16-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/mysql/mysql-connector-java/5.1.13/mysql-connector-java-5.1.13.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/nekohtml/nekohtml/1.9.14/nekohtml-1.9.14.jar" sourcepath="M2_REPO/net/sourceforge/nekohtml/nekohtml/1.9.14/nekohtml-1.9.14-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/objenesis/objenesis/1.0/objenesis-1.0.jar" sourcepath="M2_REPO/org/objenesis/objenesis/1.0/objenesis-1.0-sources.jar"/>
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/pom.xml 2011-07-01 11:27:50 UTC (rev 1439)
@@ -658,6 +658,17 @@
<version>1.4</version>
<type>jar</type>
</dependency>
+ <!-- splash -->
+<dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ <version>1.2.2</version>
+</dependency>
+<dependency>
+ <groupId>org.mvel</groupId>
+ <artifactId>mvel2</artifactId>
+ <version>2.0.16</version>
+</dependency>
<!-- gwtupload -->
<dependency>
<groupId>com.googlecode.gwtupload</groupId>
Modified: trunk/src/main/java/cc/kune/core/client/errors/DefaultException.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/errors/DefaultException.java 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/src/main/java/cc/kune/core/client/errors/DefaultException.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -24,18 +24,26 @@
public class DefaultException extends InvocationException implements IsSerializable {
- private static final long serialVersionUID = -6111471089427505005L;
+ private static final long serialVersionUID = -6111471089427505005L;
- public DefaultException() {
- this(0, "");
- }
+ public DefaultException() {
+ this(0, "");
+ }
- public DefaultException(final int statusCode, final String message) {
- super(statusCode + " " + message);
+ public DefaultException(final int statusCode, final String message) {
+ super(statusCode + " " + message);
- }
+ }
- public DefaultException(final String message) {
- super(message);
- }
+ public DefaultException(final String message) {
+ super(message);
+ }
+
+ public DefaultException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public DefaultException(final Throwable cause) {
+ super("", cause);
+ }
}
Modified: trunk/src/main/java/cc/kune/core/client/services/FileDownloadUtils.java
===================================================================
--- trunk/src/main/java/cc/kune/core/client/services/FileDownloadUtils.java 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/src/main/java/cc/kune/core/client/services/FileDownloadUtils.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -33,7 +33,7 @@
public class FileDownloadUtils {
- private static final String AVATARDOWNLOADSERVLET = "servlets/UserLogoDownloadManager";
+ public static final String AVATARDOWNLOADSERVLET = "servlets/UserLogoDownloadManager";
private static final String BACKDOWNLOADSERVLET = "servlets/EntityBackgroundDownloadManager";
private static final String DOWNLOADSERVLET = "servlets/FileDownloadManager";
protected static final String GROUP_NO_AVATAR_IMAGE = "images/group-def-icon.png";
Modified: trunk/src/main/java/cc/kune/core/public/ws.html
===================================================================
--- trunk/src/main/java/cc/kune/core/public/ws.html 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/src/main/java/cc/kune/core/public/ws.html 2011-07-01 11:27:50 UTC (rev 1439)
@@ -51,7 +51,15 @@
<link type="text/css" rel="stylesheet"
href="fontface/ubuntufontface.css">
<link type="text/css" rel="stylesheet" href="kune-message.css">
+<link type="text/css" rel="stylesheet" href="/others/splash/style/permalink.css">
+<link type="text/css" rel="stylesheet" href="/others/splash/style/stuff.css">
+<link type="text/css" rel="stylesheet" href="/others/splash/style/main.css">
<link type="text/css" rel="stylesheet" href="ws.css">
+<script type="text/javascript" src="/others/splash/js/gadget.js"></script>
+<script type="text/javascript" src="/others/splash/js/rpc.js"></script>
+<script type="text/javascript" src="/others/splash/js/common_client.js"></script>
+<script type="text/javascript" src="/others/splash/js/permalink_client.js"></script>
+
<style type="text/css">
body {
background-color: white;
Modified: trunk/src/main/java/cc/kune/core/server/state/StateServiceDefault.java
===================================================================
--- trunk/src/main/java/cc/kune/core/server/state/StateServiceDefault.java 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/src/main/java/cc/kune/core/server/state/StateServiceDefault.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -109,8 +109,8 @@
// FIXME if we remove the authors this fails...
final Wavelet wavelet = kuneWaveManager.fetchWavelet(
JavaWaverefEncoder.decodeWaveRefFromPath(waveId), content.getAuthors().get(0).getShortName());
- final String currentContent = wavelet.getRootBlip().getContent();
- state.setContent(currentContent);
+ // final String currentContent = wavelet.getRootBlip().getContent();
+ state.setContent(kuneWaveManager.render(wavelet));
// Well we "cache" the last modified time of waves in db (w'll find
// another way to do it better in the future with db persitence of
// waves)
Modified: trunk/src/main/java/cc/kune/wave/server/KuneWaveManager.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/server/KuneWaveManager.java 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/src/main/java/cc/kune/wave/server/KuneWaveManager.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -43,6 +43,10 @@
boolean isParticipant(Wavelet wavelet, String user);
+ String render(Wavelet wavelet);
+
+ String render(WaveRef waveRef, String author);
+
void setTitle(WaveRef waveName, String title, String author);
}
Modified: trunk/src/main/java/cc/kune/wave/server/KuneWaveManagerDefault.java
===================================================================
--- trunk/src/main/java/cc/kune/wave/server/KuneWaveManagerDefault.java 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/src/main/java/cc/kune/wave/server/KuneWaveManagerDefault.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -68,6 +68,8 @@
import com.google.wave.api.impl.DocumentModifyAction.BundledAnnotation;
import com.google.wave.api.impl.DocumentModifyAction.ModifyHow;
import com.google.wave.api.impl.WaveletData;
+import com.google.wave.splash.rpc.ClientAction;
+import com.google.wave.splash.web.template.WaveRenderer;
public class KuneWaveManagerDefault implements KuneWaveManager {
public static final Log LOG = LogFactory.getLog(KuneWaveManagerDefault.class);
@@ -86,17 +88,20 @@
private final ParticipantUtils participantUtils;
private final WaveletProvider waveletProvider;
+ private final WaveRenderer waveRenderer;
+
@Inject
public KuneWaveManagerDefault(final EventDataConverterManager converterManager,
@Named("DataApiRegistry") final OperationServiceRegistry operationRegistry,
final WaveletProvider waveletProvider, final ConversationUtil conversationUtil,
- final ParticipantUtils participantUtils,
+ final ParticipantUtils participantUtils, final WaveRenderer waveRenderer,
@Named(CoreSettings.WAVE_SERVER_DOMAIN) final String domain) {
this.converterManager = converterManager;
this.waveletProvider = waveletProvider;
this.conversationUtil = conversationUtil;
this.operationRegistry = operationRegistry;
this.participantUtils = participantUtils;
+ this.waveRenderer = waveRenderer;
this.domain = domain;
}
@@ -158,8 +163,8 @@
final Wavelet newWavelet = opQueue.createWavelet(domain, participants);
opQueue.setTitleOfWavelet(newWavelet, title);
final Blip rootBlip = newWavelet.getRootBlip();
- rootBlip.append(new com.google.wave.api.Markup(message).getText());
-
+ // rootBlip.append(new com.google.wave.api.Markup(message).getText());
+ rootBlip.appendMarkup(message);
if (gadgetUrl != WITHOUT_GADGET) {
final Gadget gadget = new Gadget(gadgetUrl.toString());
rootBlip.append(gadget);
@@ -295,6 +300,17 @@
}
@Override
+ public String render(final Wavelet wavelet) {
+ final ClientAction clientPage = waveRenderer.render(wavelet, 0);
+ return clientPage.getHtml();
+ }
+
+ @Override
+ public String render(final WaveRef waveRef, final String author) {
+ return render(fetchWavelet(waveRef, author));
+ }
+
+ @Override
public void setTitle(final WaveRef waveName, final String title, final String author) {
final Wavelet wavelet = fetchWavelet(waveName, author);
final OperationQueue opQueue = new OperationQueue();
Added: trunk/src/main/java/com/google/wave/splash/rpc/ClientAction.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/rpc/ClientAction.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/rpc/ClientAction.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,106 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.rpc;
+
+/**
+ * A value object that is transformed into a JSON return value for the web client
+ * to process.
+ *
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+public final class ClientAction {
+ private String waveId;
+ private String blipId;
+ private String action;
+ private String html = "";
+
+ private String parent;
+ private boolean indent;
+ private long version;
+
+ public ClientAction(String action) {
+ action(action);
+ }
+
+ public String getBlipId() {
+ return blipId;
+ }
+
+ public ClientAction blipId(String blipId) {
+ this.blipId = blipId;
+ return this;
+ }
+
+ public ClientAction waveId(String waveId) {
+ this.waveId = waveId;
+ return this;
+ }
+
+ public String getWaveId() {
+ return waveId;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public ClientAction action(String action) {
+ this.action = action;
+ return this;
+ }
+
+ public String getHtml() {
+ return html;
+ }
+
+ public ClientAction html(String html) {
+ this.html = html;
+ return this;
+ }
+
+ public String getParent() {
+ return parent;
+ }
+
+ public ClientAction parent(String parent) {
+ this.parent = parent;
+ return this;
+ }
+
+ public boolean isIndent() {
+ return indent;
+ }
+
+ public ClientAction indent() {
+ this.indent = true;
+ return this;
+ }
+
+ public ClientAction indent(boolean indent) {
+ this.indent = indent;
+ return this;
+ }
+
+ public ClientAction version(long version) {
+ this.version = version;
+ return this;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+}
Property changes on: trunk/src/main/java/com/google/wave/splash/rpc/ClientAction.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,240 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.text;
+
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import com.google.inject.Inject;
+import com.google.wave.api.Annotation;
+import com.google.wave.api.Annotations;
+import com.google.wave.api.Attachment;
+import com.google.wave.api.Element;
+import com.google.wave.api.ElementType;
+import com.google.wave.api.Gadget;
+import com.google.wave.splash.web.template.WaveRenderer;
+
+/**
+ * A utility class that converts blip content into html.
+ *
+ * @author David Byttow
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+public class ContentRenderer {
+
+ /**
+ * Represents a marker in content that is either the start or end of an
+ * annotation or a single element.
+ */
+ static class Marker implements Comparable<Marker> {
+ static Marker fromAnnotation(final Annotation annotation, final int index, final boolean isEnd) {
+ return new Marker(annotation, index, isEnd);
+ }
+
+ static Marker fromElement(final Element element, final int index) {
+ return new Marker(element, index);
+ }
+
+ private final Annotation annotation;
+ private final Element element;
+ private final int index;
+ private boolean isEnd;
+
+ private Marker(final Annotation annotation, final int index, final boolean isEnd) {
+ this.annotation = annotation;
+ this.element = null;
+ this.index = index;
+ this.isEnd = isEnd;
+ }
+
+ private Marker(final Element element, final int index) {
+ this.element = element;
+ this.annotation = null;
+ this.index = index;
+ }
+
+ @Override
+ public int compareTo(final Marker that) {
+ final int value = Integer.signum(this.index - that.index);
+ if (value == 0) {
+ if (this.isElement() != that.isElement()) {
+ // At boundaries, annotations should wrap elements.
+ final Marker annotation = this.isAnnotation() ? this : that;
+ return annotation.isEnd ? -1 : 1;
+ }
+ }
+ return value;
+ }
+
+ boolean isAnnotation() {
+ return this.annotation != null;
+ }
+
+ boolean isElement() {
+ return this.element != null;
+ }
+ }
+
+ private final GadgetRenderer gadgetRenderer;
+ private final WaveRenderer waveRenderer;
+
+ @Inject
+ public ContentRenderer(final GadgetRenderer gadgetRenderer, final WaveRenderer waveRenderer) {
+ this.gadgetRenderer = gadgetRenderer;
+ this.waveRenderer = waveRenderer;
+ }
+
+ private void emitStyleAnnotation(final Marker marker, final StringBuilder builder) {
+ if (marker.isEnd) {
+ builder.append("</span>");
+ } else {
+ // Transform name into dash-separated css property rather than lower camel
+ // case.
+ String name = Markup.sanitize(marker.annotation.getName());
+ final String value = Markup.sanitize(marker.annotation.getValue());
+
+ // Title annotations are translated as bold.
+ name = name.substring(marker.annotation.getName().indexOf("/") + 1);
+ name = Markup.toDashedStyle(name);
+
+ builder.append("<span style='");
+ builder.append(name);
+ builder.append(':');
+ builder.append(value);
+ builder.append("'>");
+ }
+ }
+
+ private void renderElement(final Element element, final int index, final List<String> contributors,
+ final StringBuilder builder) {
+ final ElementType type = element.getType();
+ switch (type) {
+ case LINE:
+ // TODO(anthonybaxter): need to handle <line t="li"> and <line t="li"
+ // i="3">
+ // TODO(anthonybaxter): also handle H1 &c
+ // Special case: If this is the first LINE element at position 0,
+ // ignore it because we've already appended the first <p> tag.
+ if (index > 0) {
+ builder.append("</p><p>");
+ }
+ break;
+ case ATTACHMENT:
+ final Attachment attachment = (Attachment) element;
+ final String url = Markup.sanitizeAndEncode(attachment.getAttachmentUrl());
+ String caption = Markup.sanitize(element.getProperty("caption"));
+ if (caption == null) {
+ caption = "";
+ }
+ // TODO: Revisit this questionable html.
+ builder.append("<table class=\"attachment-element\"><tr><td>").append(
+ "<a class=\"lightbox\" title=\"").append(caption).append("\" href=\"").append(url).append(
+ "\"><img src=\"").append(url).append(
+ "\"/></a></td></tr></td></tr><tr><td><div class=\"caption\">").append(caption).append(
+ "</div></td></tr></table>");
+ break;
+ case IMAGE:
+ String imageUrl = element.getProperty("url");
+
+ if (Markup.isTrustedImageUrl(imageUrl)) {
+ imageUrl = Markup.sanitizeAndEncode(imageUrl);
+ builder.append("<img src=\"").append(imageUrl).append("\"/>");
+ }
+ break;
+ case GADGET:
+ gadgetRenderer.render((Gadget) element, contributors, builder);
+ break;
+ case INLINE_BLIP:
+ waveRenderer.renderInlineReply(element, index, builder);
+
+ break;
+ default:
+ // Ignore all others.
+ }
+ }
+
+ /**
+ * Takes content and applies style and formatting to it based on its
+ * annotations and elements.
+ *
+ */
+ public String renderHtml(final String content, final Annotations annotations,
+ final SortedMap<Integer, Element> elements, final List<String> contributors) {
+ final StringBuilder builder = new StringBuilder();
+
+ // NOTE(dhanji): This step is enormously important!
+ final char[] raw = content.toCharArray();
+
+ final SortedSet<Marker> markers = new TreeSet<Marker>();
+
+ // First add annotations sorted by range.
+ for (final Annotation annotation : annotations.asList()) {
+ // Ignore anything but style or title annotations.
+ final String annotationName = annotation.getName();
+ if (annotationName.startsWith("style")) {
+ markers.add(Marker.fromAnnotation(annotation, annotation.getRange().getStart(), false));
+ markers.add(Marker.fromAnnotation(annotation, annotation.getRange().getEnd(), true));
+ } else if ("conv/title".equals(annotationName)) {
+ // Find the first newline and make sure the annotation only gets to that
+ // point.
+ final int start = annotation.getRange().getStart();
+ final int from = raw[0] == '\n' ? 1 : 0;
+ final int end = content.indexOf('\n', from);
+ if (end > start && start < end) {
+ // Commented (vjrj)
+ // final Annotation title = new Annotation(Annotation.FONT_WEIGHT,
+ // "bold", start, end);
+ // markers.add(Marker.fromAnnotation(title, start, false));
+ // markers.add(Marker.fromAnnotation(title, end, true));
+ }
+ }
+ }
+
+ // Now add elements sorted by index.
+ for (final Map.Entry<Integer, Element> entry : elements.entrySet()) {
+ markers.add(Marker.fromElement(entry.getValue(), entry.getKey()));
+ }
+
+ builder.append("<p>");
+ int cursor = 0;
+ for (final Marker marker : markers) {
+ if (marker.index > cursor) {
+ final int to = Math.min(raw.length, marker.index);
+ builder.append(Markup.sanitize(new String(raw, cursor, to - cursor)));
+ }
+
+ cursor = marker.index;
+
+ if (marker.isElement()) {
+ renderElement(marker.element, marker.index, contributors, builder);
+ } else {
+ emitStyleAnnotation(marker, builder);
+ }
+ }
+
+ // add any tail bits
+ if (cursor < raw.length - 1) {
+ builder.append(Markup.sanitize(new String(raw, cursor, raw.length - cursor)));
+ }
+
+ // Replace empty paragraphs. (TODO expensive and silly)
+ return builder.toString().replace("<p>\n</p>", "<p><br/></p>");
+ }
+}
Property changes on: trunk/src/main/java/com/google/wave/splash/text/ContentRenderer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,90 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.text;
+
+
+import com.google.common.collect.Maps;
+import com.google.wave.api.Annotations;
+import com.google.wave.api.Line;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.nodes.TextNode;
+
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * @author anthonybaxter(a)gmail.com (Anthony Baxter)
+ */
+public class ContentUnrenderer {
+
+ private static final Logger LOG = Logger.getLogger(ContentUnrenderer.class.getName());
+
+ /**
+ * Turns a HTML document back into a set of text, elements, annotations.
+ */
+ public static UnrenderedBlip unrender(String content) {
+ StringBuilder sb = new StringBuilder();
+ Map<Integer, com.google.wave.api.Element> elements = Maps.newHashMap();
+ Annotations annotations = new Annotations();
+ Document doc = Jsoup.parse(content);
+ unrender(doc.body(), sb, elements, annotations);
+ return new UnrenderedBlip(sb.toString(), elements, annotations);
+ }
+
+ /**
+ * Helper method to recursively parse a HTML element and construct a wave document.
+ */
+ private static void unrender(Node parent, StringBuilder output, Map<Integer,
+ com.google.wave.api.Element> elements, Annotations annotations) {
+ for (Node node : parent.childNodes()) {
+ if (node instanceof TextNode) {
+ output.append(((TextNode)node).text());
+ }
+ else if (node instanceof Element) {
+ int position = output.length();
+ Element element = (Element)node;
+ if ("p".equals(element.tag().getName())) {
+ elements.put(position, new Line());
+ // handle any attributes?
+ }
+ // Additional HTML element tags here.
+ unrender(element, output, elements, annotations);
+ }
+ }
+
+ }
+
+ /**
+ * Container for the output of the unrender method.
+ */
+ public static class UnrenderedBlip {
+ public String contents;
+ Map<Integer, com.google.wave.api.Element> elements;
+ Annotations annotations = new Annotations();
+
+ UnrenderedBlip(String contents, Map<Integer, com.google.wave.api.Element> elements,
+ Annotations annotations) {
+ this.contents = contents;
+ this.elements = elements;
+ this.annotations = annotations;
+ }
+ }
+}
Property changes on: trunk/src/main/java/com/google/wave/splash/text/ContentUnrenderer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/java/com/google/wave/splash/text/GadgetRenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/GadgetRenderer.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/text/GadgetRenderer.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,103 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.text;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.wave.api.Gadget;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * Render gadget iframes from Elements.
+ *
+ * @author David Byttow
+ */
+public class GadgetRenderer {
+ private static final Set<String> NON_STATE_PROPERTIES = ImmutableSet.of("author", "url");
+ private final Provider<HttpServletRequest> requestProvider;
+ private final AtomicInteger nextId = new AtomicInteger(0);
+
+ @Inject
+ public GadgetRenderer(Provider<HttpServletRequest> requestProvider) {
+ this.requestProvider = requestProvider;
+ }
+
+ void render(Gadget gadget, List<String> contributors, StringBuilder builder) {
+ String id = "g" + nextId.incrementAndGet();
+ String parentUrl = requestProvider.get().getRequestURL().toString();
+
+ appendState(gadget, id, contributors, builder);
+ builder.append("<iframe class=\"gadget\" "
+ + "id=\"").append(id).append("\" "
+ + "name=\"").append(id).append("\" "
+ + "width=\"100%\" height=\"1px\" ")
+ .append("frameBorder=\"no\" scrolling=\"no\" src=\""
+ + "http://www.gmodules.com/gadgets/ifr?container=wave&view=default&debug=0&"
+ + "lang=en&country=ALL&nocache=0&wave=1")
+ .append("&mid=").append(id)
+ .append("&parent=").append(Markup.sanitizeAndEncode(parentUrl))
+ .append("&url=").append(Markup.sanitizeAndEncode(gadget.getUrl()))
+ .append("\"/>");
+ }
+
+ private void appendState(Gadget gadget, String id, List<String> contributors,
+ StringBuilder builder) {
+ String output = "";
+ builder.append("<div class=\"invisible\" id=\"")
+ .append(id)
+ .append("_state\">");
+ for (Map.Entry<String, String> entry : gadget.getProperties().entrySet()) {
+ if (NON_STATE_PROPERTIES.contains(entry.getKey())) {
+ continue;
+ }
+ renderStateValue("gadget-state", entry.getKey(), entry.getValue(), builder);
+ }
+
+ for (String participantId : contributors) {
+ renderStateValue("gadget-participant", null, participantId, builder);
+ }
+ renderStateValue("gadget-author", null, gadget.getProperties().get("author"), builder);
+ builder.append("</div>");
+ }
+
+ private void renderStateValue(String className, String key, String value,
+ StringBuilder builder) {
+ // TODO: Is this kosher? Should we encode this data in
+ // another way?
+ builder.append("<span class=\"")
+ .append(className)
+ .append("\"");
+ if (key != null) {
+ builder.append(" hiddenKey=\"")
+ .append(Markup.sanitize(key))
+ .append('"');
+ }
+ builder.append(">");
+ if (value != null) {
+ builder.append(Markup.sanitize(value));
+ }
+ builder.append("</span>");
+ }
+}
Property changes on: trunk/src/main/java/com/google/wave/splash/text/GadgetRenderer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/java/com/google/wave/splash/text/Markup.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/text/Markup.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/text/Markup.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,262 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.text;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import cc.kune.core.client.errors.DefaultException;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * A utility class that converts raw wave documents into html.
+ *
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+@Singleton
+public class Markup {
+ private static final DateFormat MONTH_DAY_FORMATTER = new SimpleDateFormat("MMM dd");
+ private static final DateFormat MONTH_DAY_YEAR_FORMATTER = new SimpleDateFormat("MMM dd, yyyy");
+ private static final DateFormat TIME_FORMATTER = new SimpleDateFormat("h:mm a");
+ private static final DateFormat TIME_MILLIS_FORMATTER = new SimpleDateFormat("s.SSS");
+
+ public static String embedSnippet(final String waveId) {
+ // TODO(dhanji): Move to template
+ return "<script type=\"text/javascript\">" + " function load() {"
+ + " var targetDiv = document.getElementById('waveframe');"
+ + " var wavePanel = new google.wave.WavePanel({"
+ + " rootUrl: \"http://localhost:8080/\"," + " target: targetDiv,"
+ + " lite: true" + " }).loadWave(\"" + waveId + "\");" + " }"
+ + " </script>";
+ }
+
+ private static String extractScheme(final String uri) {
+ if (null == uri) {
+ return null;
+ }
+ final int colonPos = uri.indexOf(':');
+ if (colonPos < 0) {
+ return null;
+ }
+ final String scheme = uri.substring(0, colonPos);
+ if (scheme.indexOf('/') >= 0 || scheme.indexOf('#') >= 0) {
+ // The URI's prefix up to the first ':' contains other URI special
+ // chars, and won't be interpreted as a scheme.
+ return null;
+ }
+ return scheme;
+ }
+
+ /**
+ * Formats a given timestamp into a friendly date string. The output will look
+ * differently depending on the day and year. If the time given is the same
+ * day as "now", then it will only display the time (12:30 PM). If it's in the
+ * same year, then it will display the month and day (Jun 01) otherwise it
+ * will return the month, day and year (Jun 01, 2009).
+ *
+ * @param timestamp
+ * @return the formatted date time string.
+ */
+ public static String formatDateTime(final long timestamp) {
+ final Date date = new Date(timestamp);
+ final Date now = new Date();
+ if (now.getDay() == date.getDay()) {
+ return TIME_FORMATTER.format(date);
+ } else if (now.getYear() == date.getYear()) {
+ return MONTH_DAY_FORMATTER.format(date);
+ } else {
+ return MONTH_DAY_YEAR_FORMATTER.format(date);
+ }
+ }
+
+ public static String formatMillis(final long millis) {
+ return TIME_MILLIS_FORMATTER.format(new Date(millis)) + "s";
+ }
+
+ // TODO(dhanji): Should we allow more schemes? Like im:
+ private static boolean isSafeUri(final String uri) {
+ final String scheme = extractScheme(uri);
+ return (scheme == null || "http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme)
+ || "mailto".equalsIgnoreCase(scheme) || "ftp".equalsIgnoreCase(scheme));
+ }
+
+ /**
+ * Checks if an image URL is safe (i.e. hosted on Google)
+ *
+ * @param imageUrl
+ * A string URL
+ * @return True if this image URL is safe to use in a google-hosted page.
+ */
+ public static boolean isTrustedImageUrl(final String imageUrl) {
+ final String scheme = extractScheme(imageUrl);
+
+ // NOTE(dhanji): the trailing slash is extremely important.
+ return (scheme != null)
+ && (imageUrl.startsWith(scheme + "://www.google.com/") || imageUrl.startsWith(scheme
+ + "://google.com/"));
+ }
+
+ /**
+ * Sanitizes untrusted text so that it does not emit HTML markup. This utility
+ * is based on a similar one in GWT's SafeHtml.java. It eliminates all
+ * predefined entities in HTML/XHTML, replacing them with escape codes:
+ * http://
+ * en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
+ *
+ * @param text
+ * The untrusted text to sanitize
+ * @return Escaped text that can safely be rendered in a web page.
+ */
+ public static String sanitize(final String text) {
+ final StringBuilder out = new StringBuilder(text.length());
+
+ final char[] chars = text.toCharArray();
+ for (final char c : chars) {
+ switch (c) {
+ case '&':
+ out.append("&");
+ break;
+ case '\'':
+ out.append("'");
+ break;
+ case '"':
+ out.append(""");
+ break;
+ case '<':
+ out.append("<");
+ break;
+ case '>':
+ out.append(">");
+ break;
+ default:
+ // allow all other characters.
+ out.append(c);
+ }
+ }
+
+ return out.toString();
+ }
+
+ /**
+ * First sanitizes the given URI and then encodes it using the UTF-8 character
+ * set.
+ *
+ * @param uri
+ * An untrusted URI string
+ * @return Sanitized, URL-encoded URI for embedding in HTML
+ */
+ static String sanitizeAndEncode(final String uri) {
+ try {
+ return URLEncoder.encode(sanitizeUri(uri), "UTF-8");
+ } catch (final UnsupportedEncodingException e) {
+ throw new DefaultException(e);
+ }
+ }
+
+ /**
+ * Checks if the scheme is one of four simple types (see #isSafeUri), if not
+ * disallows the URI by reducing it to '#'
+ *
+ * @param uri
+ * An untrusted URI string to sanitize
+ * @return Returns a safe URI.
+ */
+ private static String sanitizeUri(final String uri) {
+ return isSafeUri(uri) ? uri : "#";
+ }
+
+ public static String toBlipId(final String id) {
+ // HACK to make blip ids work as DOM ids
+ return id.replace('-', '+');
+ }
+
+ //
+ // public static ClientAction measure(String action, long searchTime) {
+ // return new ClientAction("measure")
+ // .html(action + " completed in " + Markup.formatMillis(searchTime));
+ // }
+
+ /**
+ * Simply converts a lowerCamelCased symbol into a dashed one:
+ *
+ * <pre>
+ * fontWeight -> font-weight
+ * </pre>
+ *
+ * TODO: perhaps we should intern all these strings to save memory and remove
+ * the overhead of string allocation, they could also be perfectly hashed.
+ */
+ static String toDashedStyle(final String name) {
+ final char[] nameChars = name.toCharArray();
+
+ // Pre allocate buffer, +1 for '-' (2-dashes are uncommon)
+ final StringBuilder builder = new StringBuilder(nameChars.length + 1);
+ for (final char nameChar : nameChars) {
+ if (Character.isUpperCase(nameChar)) {
+ builder.append('-');
+ builder.append(Character.toLowerCase(nameChar));
+ continue;
+ }
+
+ builder.append(nameChar);
+ }
+
+ return builder.toString();
+ }
+
+ public static String toDomId(final String id) {
+ // HACK to make blip ids work as DOM ids
+ return id.replace('+', '-');
+ }
+
+ @Inject
+ Markup() {
+ }
+
+ /**
+ * @return the participant's display name.
+ */
+ // TODO: This doesn't belong here.
+ public String getDisplayName(final String participantId) {
+ return "FIXME";
+ }
+
+ public String getImageSize() {
+ return "33px";
+ }
+
+ /**
+ * @return the participant's image url.
+ */
+ // TODO: This doesn't belong here.
+ public String getImageUrl(final String participantId) {
+ // FIXME
+ return "others/unknown.jpg";
+ }
+
+ /**
+ * Helpful utility for templates.
+ */
+ public String sanitizeHtml(final String text) {
+ return Markup.sanitize(text);
+ }
+}
Property changes on: trunk/src/main/java/com/google/wave/splash/text/Markup.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/java/com/google/wave/splash/web/template/Templates.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/web/template/Templates.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/web/template/Templates.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,138 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.web.template;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Logger;
+
+import javax.annotation.Nullable;
+
+import org.mvel2.templates.CompiledTemplate;
+import org.mvel2.templates.TemplateCompiler;
+import org.mvel2.templates.TemplateRuntime;
+import org.mvel2.templates.util.TemplateTools;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.MapMaker;
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.wave.splash.text.Markup;
+
+/**
+ * Handles all our html templates, loading, parsing and processing them.
+ *
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+@Singleton
+public class Templates {
+ // Template file names go here.
+ public static final String BLIP_TEMPLATE = "blip.html.fragment";
+ public static final String CLIENT_TEMPLATE = "full_client.html";
+ public static final String FEED_TEMPLATE = "feed.html.fragment";
+ public static final String HEADER_TEMPLATE = "header.html.fragment";
+ private static final Logger LOG = Logger.getLogger(Templates.class.getName());
+ public static final String MOBILE_TEMPLATE = "mobile_client.html";
+ public static final String PERMALINK_WAVE_TEMPLATE = "permalink_client.html";
+
+ public static final String WAVE_NOT_FOUND_TEMPLATE = "wave_not_found.html.fragment";
+
+ private final Markup markup;
+
+ private final boolean productionMode = false;
+
+ /**
+ * file name of template -> compiled template lazy cache.
+ */
+ private final ConcurrentMap<String, CompiledTemplate> templates = new MapMaker().makeComputingMap(new Function<String, CompiledTemplate>() {
+ @Override
+ public CompiledTemplate apply(@Nullable final String template) {
+ return loadTemplate(template);
+ }
+ });
+
+ @Inject
+ public Templates(final Markup markup) {
+ this.markup = markup;
+ }
+
+ private CompiledTemplate loadTemplate(final String template) {
+ // Load from jar if in production mode, otherwise servlet root.
+ final InputStream input = openResource(template);
+ Preconditions.checkArgument(input != null, "Could not find template named: " + template);
+
+ try {
+ return TemplateCompiler.compileTemplate(TemplateTools.readStream(input));
+ } finally {
+ try {
+ input.close();
+ } catch (final IOException e) {
+ // Can't do much.
+ e.printStackTrace();
+ LOG.warning(e.toString());
+ }
+ }
+ }
+
+ /**
+ * Opens a packaged resource from the file system.
+ *
+ * @param file
+ * The name of the file/resource to open.
+ * @return An {@linkplain InputStream} to the named file, if found
+ */
+ public InputStream openResource(final String file) {
+ // final InputStream stream = productionMode ?
+ // Templates.class.getResourceAsStream(file)
+ // : servletContext.get().getResourceAsStream("/" + file);
+
+ FileInputStream stream = null;
+ try {
+ stream = new FileInputStream(new File("src/main/webapp/others/splash/" + file));
+ } catch (final FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ LOG.info("Could not find resource named: " + file);
+ }
+ return stream;
+ }
+
+ /**
+ * Loads templates if necessary.
+ *
+ * @param template
+ * Name of the template file. example: "blip.html.fragment"
+ * @param context
+ * an object to process against
+ * @return the processed, filled-in template.
+ */
+ public String process(final String template, final Object context) {
+ // Reload template each time for development mode.
+ final CompiledTemplate compiledTemplate = productionMode ? templates.get(template)
+ : loadTemplate(template);
+
+ final Map<String, Object> vars = Maps.newHashMap();
+ vars.put("markup", markup);
+ return TemplateRuntime.execute(compiledTemplate, context, vars).toString();
+ }
+}
Property changes on: trunk/src/main/java/com/google/wave/splash/web/template/Templates.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/java/com/google/wave/splash/web/template/ThreadedWaveRenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/web/template/ThreadedWaveRenderer.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/web/template/ThreadedWaveRenderer.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,434 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.web.template;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.waveprotocol.box.server.CoreSettings;
+
+import cc.kune.common.client.utils.Url;
+import cc.kune.common.client.utils.UrlParam;
+import cc.kune.core.client.services.FileConstants;
+import cc.kune.core.client.services.FileDownloadUtils;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
+import com.google.wave.api.Blip;
+import com.google.wave.api.BlipThread;
+import com.google.wave.api.Element;
+import com.google.wave.api.ParticipantProfile;
+import com.google.wave.api.Wavelet;
+import com.google.wave.splash.rpc.ClientAction;
+import com.google.wave.splash.text.ContentRenderer;
+import com.google.wave.splash.text.Markup;
+
+/**
+ * Does the actual conversion of a wavelet/blipdata tree into html, using the
+ * conversation-thread model, optionally falling back to the blip-hierarchy
+ * model, if so configured.
+ *
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+@Singleton
+class ThreadedWaveRenderer implements WaveRenderer {
+ private class PageTracker {
+ private int counter;
+ // Whether or not we're trying to deliver the first page.
+ private final boolean firstPage;
+ private final List<Integer> markers = Lists.newArrayList();
+
+ /**
+ * This is an alternate output string which will wrap all html content that
+ * is not immediately displayed. This is useful for inline replies that need
+ * to be moved in and out of the appropriate part of the DOM.
+ */
+ private final StringBuilder purgatory = new StringBuilder();
+
+ // The wavelet we're trying to render in this page.
+ private final Wavelet wavelet;
+
+ public PageTracker(final int page, final Wavelet wavelet) {
+ this.wavelet = wavelet;
+ firstPage = (page == 0);
+
+ // Start purgatory (will be ended by #render)
+ purgatory.append("<div id=\"purgatory\">");
+ }
+
+ public boolean hasPages() {
+ return !markers.isEmpty();
+ }
+
+ public int marker(final int page) {
+ return markers.get(page);
+ }
+
+ public String purgatoryElement() {
+ return purgatory.append("</div>").toString();
+ }
+
+ /**
+ * Returns true if a page boundary was crossed.
+ */
+ public boolean track(final StringBuilder builder) {
+ final int length = builder.length();
+ if (length - counter >= charsPerPage) {
+ markers.add(length);
+ counter = length;
+
+ // If this is the first page, short circuit the rendering
+ // process so we can deliver the page faster.
+ if (firstPage) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ private static final Set<String> HIDDEN_PARTICIPANTS = ImmutableSet.of("public");
+
+ // TODO(dhanji): This is expensive, see if we can precompute branch size
+ // when constructing the thread tree.
+ private static int sizeOfThreadTree(final BlipThread inlineReplyThread) {
+ final List<Blip> blips = inlineReplyThread.getBlips();
+ int size = blips.size();
+
+ for (final Blip blip : blips) {
+ for (final BlipThread thread : blip.getReplyThreads()) {
+ size += thread.getBlipIds().size();
+ }
+ }
+
+ return size;
+ }
+ private final int charsPerPage;
+ // Ugly, but we do this to avoid polluting all the rendering methods. =(
+ private final ThreadLocal<PageTracker> currentPage = new ThreadLocal<PageTracker>();
+ private final String domain;
+
+ private final boolean isReadOnly;
+
+ private final ContentRenderer renderer;
+ private final Templates templates;
+
+ @Inject
+ public ThreadedWaveRenderer(final Templates templates, final ContentRenderer renderer,
+ @Named(CoreSettings.WAVE_SERVER_DOMAIN) final String domain) {
+ this.templates = templates;
+ this.domain = domain;
+ // vjrj: manual setted
+ this.isReadOnly = true;
+ this.charsPerPage = 100000;
+ this.renderer = renderer;
+ }
+
+ private String getAvatarUrl(final String address) {
+ String avatar = "";
+ if (address.contains(domain)) {
+ avatar = new Url("/ws/" + FileDownloadUtils.AVATARDOWNLOADSERVLET, new UrlParam(
+ FileConstants.USERNAME, address.split("@")[0])).toString();
+ } else {
+ avatar = "/others/unknown.jpg";
+ }
+ return avatar;
+ }
+
+ private Map<String, ParticipantProfile> getProfiles(final Collection<String> participants) {
+ final HashMap<String, ParticipantProfile> profiles = new HashMap<String, ParticipantProfile>();
+ for (final String address : participants) {
+ final ParticipantProfile profile = new ParticipantProfile(address, address.split("@")[0],
+ getAvatarUrl(address), "");
+ profiles.put(address, profile);
+ }
+
+ return profiles;
+ }
+
+ List<ParticipantProfile> loadProfiles(final Collection<String> participants) {
+ final ImmutableList.Builder<ParticipantProfile> result = ImmutableList.builder();
+ final Map<String, ParticipantProfile> profiles = getProfiles(participants);
+ for (final String address : participants) {
+ result.add(profiles.get(address));
+ }
+ return result.build();
+ }
+
+ /**
+ *
+ * @param wavelet
+ * A wavelet to render as a single html blob.
+ * @param page
+ * The page number to send back. Use this to implement paging, if you
+ * specify page 1, the client action will only contain the second
+ * page as computed during the current render.
+ * @return the client action.
+ */
+ @Override
+ public ClientAction render(final Wavelet wavelet, final int page) {
+ Preconditions.checkState(null == currentPage.get(),
+ "A page render is already in progress (this is an algorithm bug)");
+ final StringBuilder builder = new StringBuilder();
+ final Blip rootBlip = wavelet.getRootBlip();
+
+ // The pagetracker tracks every page worth of HTML rendered.
+ final PageTracker pageTracker = new PageTracker(page, wavelet);
+ currentPage.set(pageTracker);
+ try {
+ return renderInternal(wavelet, page, builder, rootBlip, pageTracker);
+ } finally {
+ currentPage.remove();
+ }
+ }
+
+ private boolean renderBlip(final Blip blip, final StringBuilder builder, final String title,
+ final PageTracker pageTracker) {
+ builder.append("<div class='blip' id='");
+ builder.append(Markup.toDomId(blip.getBlipId()));
+ builder.append("'>");
+ builder.append(toHtml(blip, title));
+ builder.append("</div>");
+
+ // At the end of each blip, see if we've passed a page worth of content.
+ return pageTracker.track(builder);
+ }
+
+ String renderBlipTemplate(final Map<String, Object> blip) {
+ return templates.process(Templates.BLIP_TEMPLATE, blip);
+ }
+
+ private String renderContent(final Blip blip) {
+ return renderer.renderHtml(blip.getContent(), blip.getAnnotations(), blip.getElements(),
+ blip.getContributors());
+ }
+
+ /**
+ * Renders the header of a wavelet, including participants.
+ *
+ * @param profiles
+ * A list of profiles for each participant in the wave, in correct
+ * order.
+ * @return A {@code ClientAction} that inserts the rendered participant list
+ * in the header portion of the DOM.
+ */
+ @Override
+ public ClientAction renderHeader(final List<ParticipantProfile> profiles) {
+ final Map<String, Object> context = Maps.newHashMap();
+ final int max = Math.min(10, profiles.size());
+
+ final List<ParticipantProfile> renderedParticipants = Lists.newArrayListWithExpectedSize(max);
+ for (final ParticipantProfile p : profiles) {
+ // TODO: For some reason the address is an empty string, so
+ // we use name here instead.
+ if (HIDDEN_PARTICIPANTS.contains(p.getName())) {
+ continue;
+ }
+ if (renderedParticipants.size() >= max) {
+ break;
+ }
+ renderedParticipants.add(p);
+ }
+
+ context.put("participants", renderedParticipants);
+ return new ClientAction("update-header").html(templates.process(Templates.HEADER_TEMPLATE, context));
+ }
+
+ /**
+ * Renders an inline reply thread at the correct offset location inside a
+ * blip.
+ *
+ * @param element
+ * The element representing the position of the offset inline reply
+ * @param index
+ * @param builder
+ * The current HTML content StringBuilder of the wave so far
+ */
+ @Override
+ public void renderInlineReply(final Element element, final int index, final StringBuilder builder) {
+
+ final PageTracker pageTracker = currentPage.get();
+ final BlipThread inlineReplyThread = pageTracker.wavelet.getThread(element.getProperty("id"));
+
+ // inlineReplyThread can be null if a sub-thread was completely deleted.
+ // There's still
+ // an entry left behind in the conversation that points to nothing.
+ if (inlineReplyThread != null && !inlineReplyThread.getBlipIds().isEmpty()) {
+ builder.append(" <span class=\"inline-reply\" ir-id=\"");
+ builder.append(Markup.toDomId(inlineReplyThread.getId()));
+ builder.append("\"><span class=\"count\" title=\"Click to expand inline replies\"><span class=\"count-inner\">");
+ builder.append(sizeOfThreadTree(inlineReplyThread));
+ builder.append("</span><span class=\"pointer\"></span></span> ");
+
+ // Render this thread into purgatory, it will be transferred to the
+ // appropriate
+ // spot by the JS code. This is needed to prevent the browser from trying
+ // to pre-emptively "correct" our dom structure (and thus ruin it).
+ pageTracker.purgatory.append("<div class=\"inline-reply-content\" id=\"ir-");
+ pageTracker.purgatory.append(Markup.toDomId(inlineReplyThread.getId()));
+ pageTracker.purgatory.append("\"><div class=\"inline-reply-content-inner\">");
+ renderThreads(inlineReplyThread, pageTracker.purgatory, pageTracker);
+ pageTracker.purgatory.append("</div></div>");
+
+ builder.append("</span>"); // Close inline-reply
+ }
+ }
+
+ private ClientAction renderInternal(final Wavelet wavelet, final int page,
+ final StringBuilder builder, final Blip rootBlip, final PageTracker pageTracker) {
+ final boolean stopRender = renderThreads(wavelet.getRootThread(), builder, pageTracker);
+ String html;
+ if (page != ALL_PAGES && (stopRender || pageTracker.hasPages())) {
+ if (page == 0) {
+ builder.append("<img id=\"wave-loading\" src=\"images/wave-loading.gif\">");
+ html = builder.toString();
+ } else {
+ // If this is a request for the rest of the wave, start from end of page
+ // 0 and get
+ // the rest.
+ final int start = pageTracker.marker(0);
+
+ // Append purgatory--which contains all inline reply threads
+ builder.append(pageTracker.purgatoryElement());
+
+ html = builder.substring(start);
+ }
+ } else {
+ // Append purgatory--which contains all inline reply threads
+ builder.append(pageTracker.purgatoryElement());
+
+ html = builder.toString();
+ }
+
+ return new ClientAction("update-wave").version(wavelet.getLastModifiedTime()).html(html);
+ }
+
+ @Override
+ public ClientAction renderNotFound() {
+ // TODO: This should be an alert message once that system is
+ // implemented.
+ return new ClientAction("update-wave").html(templates.process(Templates.WAVE_NOT_FOUND_TEMPLATE,
+ ImmutableMap.of()));
+ }
+
+ /**
+ * This method renders the blip thread hierarchy using the new conversation
+ * structure.
+ *
+ * @return true if we should stop rendering because a page boundary was
+ * reached.
+ */
+ boolean renderThreads(final BlipThread thread, final StringBuilder builder,
+ final PageTracker pageTracker) {
+ builder.append("<div class=\"thread\" id=\"");
+ builder.append(Markup.toDomId(thread.getId()));
+ builder.append("\">");
+ final List<Blip> blipsInThread = thread.getBlips();
+
+ for (final Blip blip : blipsInThread) {
+ if (renderBlip(blip, builder, "", pageTracker)) {
+ return true;
+ }
+
+ // If this blip has any reply threads, they should be rendered indented.
+ if (blip.getReplyThreads().size() > 0) {
+ builder.append("<div class=\"indent\">");
+
+ for (final BlipThread childThread : blip.getReplyThreads()) {
+ if (renderThreads(childThread, builder, pageTracker)) {
+ return true;
+ }
+ }
+
+ builder.append("</div>");
+ }
+ }
+ builder.append("</div>");
+ return false;
+ }
+
+ /**
+ * Renders the content of a blip as html. If a title is specified, renders
+ * that specially as the root blip.
+ *
+ * @param blipData
+ * The blip whose content you want to render
+ * @param title
+ * The title string if this is a root blip or null
+ * @return Rendered HTML string with markup
+ */
+ @Override
+ public String toHtml(final Blip blipData, final String title) {
+ final List<String> contributors = blipData.getContributors();
+ final List<ParticipantProfile> authors = loadProfiles(contributors);
+
+ final Map<String, Object> blip = Maps.newHashMap();
+ blip.put("id", Markup.toDomId(blipData.getBlipId()));
+
+ final StringBuilder authorString = new StringBuilder();
+ final int numberOfAuthors = authors.size();
+ final int len = Math.min(3, numberOfAuthors);
+ for (int i = 0; i < len; i++) {
+ authorString.append("<div class='authorbar ");
+ if (i == 0) {
+ authorString.append("first");
+ }
+ authorString.append("'><div class=\"avatar\"><img src=\"");
+ final ParticipantProfile author = authors.get(i);
+ authorString.append(author.getImageUrl());
+ authorString.append("\" alt=\"");
+
+ final String name = author.getName();
+ authorString.append(name);
+ authorString.append("\"><span class=\"name\" title=\"");
+ authorString.append(name);
+ authorString.append("\">");
+ authorString.append(name);
+ authorString.append("</span></div></div>");
+ }
+
+ if (numberOfAuthors > 3) {
+ authorString.append("<div class=\"authorbar\">");
+ authorString.append("<div class=\"author-more\">+");
+ authorString.append(numberOfAuthors);
+ authorString.append(" others</div>");
+ authorString.append("</div>");
+
+ blip.put("authorCountClass", "author-count-many");
+ } else {
+ blip.put("authorCountClass", "author-count-" + contributors.size());
+ }
+
+ blip.put("authorString", authorString.toString());
+ blip.put("time", Markup.formatDateTime(blipData.getLastModifiedTime()));
+ blip.put("title", Markup.sanitize(title));
+ blip.put("content", renderContent(blipData));
+ blip.put("readonly", isReadOnly);
+
+ return renderBlipTemplate(blip);
+ }
+}
Property changes on: trunk/src/main/java/com/google/wave/splash/web/template/ThreadedWaveRenderer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/java/com/google/wave/splash/web/template/WaveRenderer.java
===================================================================
--- trunk/src/main/java/com/google/wave/splash/web/template/WaveRenderer.java (rev 0)
+++ trunk/src/main/java/com/google/wave/splash/web/template/WaveRenderer.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,78 @@
+/**
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package com.google.wave.splash.web.template;
+
+import com.google.inject.ImplementedBy;
+import com.google.wave.splash.rpc.ClientAction;
+import com.google.wave.api.Blip;
+import com.google.wave.api.Element;
+import com.google.wave.api.ParticipantProfile;
+import com.google.wave.api.Wavelet;
+
+import java.util.List;
+
+/**
+ * Does the actual conversion of a wavelet/blipdata tree into html. This
+ * interface is mainly to satisfy a circular dependency with ContentRenderer.
+ *
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+(a)ImplementedBy(ThreadedWaveRenderer.class) // We only have one impl.
+public interface WaveRenderer {
+ /**
+ * Page number sentinel value indicating that all pages are expected.
+ */
+ int ALL_PAGES = -1;
+
+ /**
+ * Renders an inline reply thread at the correct offset location inside a blip.
+ * @param element The element representing the position of the offset inline reply
+ * @param index The offset into the blip's text at which this element occurs
+ * @param builder The current HTML content StringBuilder of the wave so far
+ */
+ void renderInlineReply(Element element, int index, StringBuilder builder);
+
+ /**
+ *
+ * @param wavelet A wavelet to render as a single html blob.
+ * @param page The page number to send back. Use this to implement paging,
+ * if you specify page 1, the client action will only contain the second
+ * page as computed during the current render.
+ * @return the client action.
+ */
+ ClientAction render(Wavelet wavelet, int page);
+
+ /**
+ * Renders the header of a wavelet, including participants.
+ * @param profiles A list of profiles for each participant in the wave, in correct order.
+ * @return A {@code ClientAction} that inserts the rendered participant list in the header
+ * portion of the DOM.
+ */
+ ClientAction renderHeader(List<ParticipantProfile> profiles);
+
+ /**
+ * Renders the content of a blip as html. If a title is specified, renders
+ * that specially as the root blip.
+ *
+ * @param blipData The blip whose content you want to render
+ * @param title The title string if this is a root blip or null
+ * @return Rendered HTML string with markup
+ */
+ String toHtml(Blip blipData, String title);
+
+ ClientAction renderNotFound();
+}
Property changes on: trunk/src/main/java/com/google/wave/splash/web/template/WaveRenderer.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/blip.html.fragment
===================================================================
--- trunk/src/main/webapp/others/splash/blip.html.fragment (rev 0)
+++ trunk/src/main/webapp/others/splash/blip.html.fragment 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,16 @@
+<div class="left @{authorCountClass}">
+ @{authorString}
+ @if{!readonly}
+ <div class="toolbar">
+ <img src="images/cross.png" alt="delete">
+ <img class="edit-button" src="images/pencil.png" alt="edit">
+ <img class="reply-button" src="images/reply.png" alt="reply">
+ </div>
+ @end{}
+</div>
+<div class="right @{authorCountClass}">
+ <div class="right-inner">
+ <div class="time">@{time}</div>
+ <div class="content styleable">@{content}</div>
+ </div>
+</div>
Added: trunk/src/main/webapp/others/splash/feed.html.fragment
===================================================================
--- trunk/src/main/webapp/others/splash/feed.html.fragment (rev 0)
+++ trunk/src/main/webapp/others/splash/feed.html.fragment 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,19 @@
+<div style="display:none">
+@foreach{item : feed}
+<div class="item @if{item.unreadCount == 0}read@end{}" wave_id="@{item.waveId}">
+ <div class="time">
+ <p>@{markup.formatDateTime(item.lastModified)}</p>
+ <!-- TODO: i18n -->
+ <p class="messages">@{item.blipCount} msgs</p>
+ </div>
+ <div class="avatar">
+ <!-- TODO: Kinda hacky. -->
+ <img width="@{markup.getImageSize()}" height="@{markup.getImageSize()}" src="@{markup.getImageUrl(item.participants[0])}"
+ alt="@{markup.getDisplayName(item.participants[0])}"
+ title="@{markup.getDisplayName(item.participants[0])}"/>
+ </div>
+ <div class="title">@{markup.sanitizeHtml(item.title)}</div>
+ <div class="snippet">@{markup.sanitizeHtml(item.snippet)}</div>
+</div>
+@end{}
+</div>
Added: trunk/src/main/webapp/others/splash/full_client.html
===================================================================
--- trunk/src/main/webapp/others/splash/full_client.html (rev 0)
+++ trunk/src/main/webapp/others/splash/full_client.html 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <meta name="viewport" content="width=device-width" /> <!-- for ipad: prevents pinch zoom -->
+ <title>Google Wave Splash</title>
+ <link rel="stylesheet" href="style/stuff.css">
+ <link rel="stylesheet" href="style/main.css">
+ <link rel="stylesheet" type="text/css" href="style/jquery.lightbox-0.5.css" media="screen">
+
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
+ <script type="text/javascript" src="http://wave.google.com/gadgets/js/core:rpc.js?debug=1&c=1"></script>
+
+ <!-- [MINIFY] -->
+ <script type="text/javascript" src="js/jquery.lightbox-0.5.min.js"></script>
+ <script type="text/javascript" src="js/jScrollTouch.js"></script>
+ <script type="text/javascript" src="js/editor.js"></script>
+ <script type="text/javascript" src="js/gadget.js"></script>
+ <script type="text/javascript" src="js/rpc.js"></script>
+ <script type="text/javascript" src="js/common_client.js"></script>
+ <script type="text/javascript" src="js/full_client.js"></script>
+ <!-- [END_MINIFY] -->
+ <script type="text/javascript">
+ var BOOTSTRAP = {
+ 'email': '@{email}',
+ 'displayName': '@{displayName}'
+ };
+ </script>
+ <!--[if IE 6]>
+ <script type="text/javascript" src="js/ie6sucks.js"></script>
+ <![endif]-->
+</head>
+<body>
+
+<div id="header">
+ <div id="headerInner">
+ <table id="headerLayout" cellspacing="0" summary="">
+ <tr>
+ <td id="logo">
+ <h1>
+ <a href="#">Google Wave Splash</a>
+ </h1>
+ </td>
+ @if{enableHeaderButtons}
+ <td class="button">
+ <a href="#"><span>New wave</span></a>
+ </td>
+ <td class="button">
+ <a href="#"><span>Mark all read</span></a>
+ </td>
+ @end{}
+
+ <td class="control-bar">
+ <a href="/speedz">Speedz</a> | <a href="/logout">Sign out</a>
+ <div id="measure">Search completed in X.XXs</div>
+ </td>
+ <!--
+ TODO(dhanji): This is cool, bring it back in the right place
+ <td class="headerAlert">
+ <div id="alertbar" class="highlight"><div id="alert">You have a happy hippgray app now!</div></div>
+ </td>
+ -->
+ </tr>
+ <tr>
+ <td colspan="5">
+ <div id="alertbar" class="highlight"><div id="alert">You have a happy hippgray app now!</div></div>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <!-- /#headerInner" -->
+</div>
+<!-- /#header -->
+
+<div id="content">
+ <div id="wave" class="wave-window">
+ <div id="wave-header" class="header" style="display:none"></div>
+ <div id="conversation"></div>
+ </div>
+ <div id="feed-container" class="feed-container">
+
+ <div id="headerSearch">
+ <table id="search" cellspacing="0" summary="">
+ <tr>
+ <td>
+ <input id="searchField" name="searchField" value="Search your waves"/>
+ </td>
+ <td id="searchButton">
+ <span><span>Go</span></span>
+ </td>
+ </tr>
+ </table>
+ <!-- /#search -->
+ </div>
+
+ <div id="feed" class="feed">
+ <img id="feed-loading" src="images/loading.gif" alt="Loading feed contents...">
+ <div id="more-feed" class="more-button">Show More...</div>
+ </div>
+ </div>
+</div>
+
+</body>
+</html>
Property changes on: trunk/src/main/webapp/others/splash/full_client.html
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/header.html.fragment
===================================================================
--- trunk/src/main/webapp/others/splash/header.html.fragment (rev 0)
+++ trunk/src/main/webapp/others/splash/header.html.fragment 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,15 @@
+<table cellspacing="0" cellpadding="0"><tr>
+ <td width="100%">
+ <div class="participants">
+ @foreach{participant : participants}
+ <span class="avatar">
+ <img src="@{participant.imageUrl}" alt="@{participant.name}">
+ <span class="name">@{participant.name}</span>
+ </span>
+ @end{'<span class="punctuation">,</span>'}
+ </div>
+ </td>
+ <td valign="top">
+ <a class="detail" style="display:none" href="#">Show</a>
+ </td>
+</tr></table>
Added: trunk/src/main/webapp/others/splash/images/attachment.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/attachment.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/avatar1.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/avatar1.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/avatar2.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/avatar2.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/avatar3.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/avatar3.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/avatar4.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/avatar4.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/avatar5.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/avatar5.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/avatar6.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/avatar6.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/background_dot.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/background_dot.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/close_window.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/close_window.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/comment.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/comment.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/cross.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/cross.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/dialog_close.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/dialog_close.gif
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/dialog_pointer.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/dialog_pointer.gif
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/email.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/email.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/group.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/group.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/inline_reply_arrow.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/inline_reply_arrow.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/inline_reply_arrow_expanded.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/inline_reply_arrow_expanded.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/inline_reply_pointer.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/inline_reply_pointer.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/lightbox-blank.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/lightbox-blank.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/lightbox-btn-close.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/lightbox-btn-close.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/lightbox-btn-next.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/lightbox-btn-next.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/lightbox-btn-prev.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/lightbox-btn-prev.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/lightbox-ico-loading.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/lightbox-ico-loading.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/loading.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/loading.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/loading_permalink.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/loading_permalink.gif
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/logo.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/logo.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/logo_on_black.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/logo_on_black.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/logo_small.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/logo_small.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/minimize_window.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/minimize_window.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/page_edit.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/page_edit.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/pencil.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/pencil.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/reply.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/reply.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/search_field_on_black.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/search_field_on_black.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/search_field_on_black_button.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/search_field_on_black_button.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/search_field_on_black_button_right.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/search_field_on_black_button_right.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/search_field_on_black_left.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/search_field_on_black_left.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/search_small_button.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/search_small_button.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/share_icon.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/share_icon.png
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/user1.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/user1.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/user2.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/user2.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/user3.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/user3.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/user4.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/user4.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/user5.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/user5.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/user6.png
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/user6.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/images/wave-loading.gif
===================================================================
(Binary files differ)
Property changes on: trunk/src/main/webapp/others/splash/images/wave-loading.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/src/main/webapp/others/splash/js/common_client.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/common_client.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/common_client.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,130 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+function log(msg) {
+ if (window.console && window.console.log) {
+ console.log(msg);
+ }
+}
+
+function warn(msg) {
+ if (window.console && window.console.warn) {
+ console.warn(msg);
+ }
+}
+
+function showToolbar(blip) {
+ var toolbar = $('.toolbar', blip);
+ // stop currently running fade
+ toolbar.stop(true, true);
+ toolbar.delay(200).fadeIn('fast'); // delay to prevent spurious hovers
+}
+
+function hideToolbar(blip) {
+ var toolbar = $('.toolbar', blip);
+ toolbar.stop(true, true);
+ toolbar.delay(200).fadeOut('fast');
+}
+
+function expandHeader() {
+ var participantsRef = $('.participants');
+ participantsRef.addClass('expanded');
+ participantsRef.css('height', 'auto');
+ var height = participantsRef.height();
+ participantsRef.css('height', null);
+ participantsRef.animate({height: height});
+ $('.header .detail').text("Hide");
+}
+
+function collapseHeader() {
+ var participantsRef = $('.participants');
+ participantsRef.removeClass('expanded');
+ participantsRef.animate({height: 18});
+ $('.header .detail').text("Show");
+}
+
+function toggleHeader() {
+ if ($('.participants').hasClass('expanded')) {
+ collapseHeader();
+ } else {
+ expandHeader();
+ }
+}
+
+/**
+ * Application entry point.
+ */
+function initCommon() {
+ // Global client state, tells server what we desire each poll.
+ // Add a key to this object to create an open state.
+ // Manages open searches, waves, etc.
+ var waveOptions = {};
+ waveOptions.query = "";
+ waveOptions.startAt = 0;
+ waveOptions.numResults = 10;
+ waveOptions.currentFeedTime = 0;
+ waveOptions.page = 0;
+
+ window.waveOptions_ = waveOptions;
+
+ $('.header .detail').live('click', function() {
+ toggleHeader();
+ });
+
+ // Search box actions.
+ var searchBox = $('#searchField');
+
+ // Execute search.
+ searchBox.keydown(function(event) {
+ if (event.keyCode == 13) { /*Enter hit*/
+ onSearch()
+ }
+ });
+ $('#searchButton').click(onSearch);
+
+ // Page in more feed items.
+ $('#more-feed').live('click', function() {
+ // Advance the page and call rpcSearch again.
+ window.waveOptions_.startAt += window.waveOptions_.numResults;
+
+ wave.Rpc.getInstance().rpcSearch();
+ });
+
+ // Page in more of the wave if applicable.
+ // TODO(dhanji): get rid of this or hide behind flag?
+ $('#more-wave').live('click', function() {
+ // Advance the page and call wave open again.
+ window.waveOptions_.page += 1;
+
+ $(this).remove(); // it gets re-rendered.
+ wave.Rpc.getInstance().rpcOpenWave();
+ });
+
+ // Listen for expansion of collapsed inline replies.
+ // TODO(dhanji): Left factor with same impl in permalink_client.js
+ $('.inline-reply .count').live('click', function() {
+ var replyThreadRef = $('.content', $(this).parent());
+
+ if (replyThreadRef.is(":visible")) {
+ replyThreadRef.slideUp();
+ } else {
+ replyThreadRef.slideDown();
+ }
+ });
+
+ initEditor();
+ initGadgetSystem();
+}
Property changes on: trunk/src/main/webapp/others/splash/js/common_client.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/editor.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/editor.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/editor.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,78 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+function isEditing() {
+ return $('#editor').length > 0
+}
+
+function startEditMode(obj) {
+ stopEditMode();
+ var blipId = obj.closest('.blip').attr('id');
+ var contentRef = $('#' + blipId + ' .content');
+ contentRef.addClass('editor')
+ .attr('id', 'editor')
+ .attr('contentEditable', 'true')
+ .attr('blip_id', blipId)
+ .focus();
+ hideToolbar($('#' + blipId));
+}
+
+function stopEditMode() {
+ if (!isEditing()) {
+ // Not editing.
+ return;
+ }
+ var editorRef = $('#editor');
+ // Note: You cannot "removeAttr('contentEditable')" once its been added in
+ // FF
+ editorRef.removeClass('editor')
+ .attr('contentEditable', 'false')
+ .addClass('content-dirty')
+ .removeAttr('id');
+}
+
+function startReply(ref) {
+ var parentId = ref.closest('.blip').attr('id');
+ var parentRef = $('#' + parentId);
+ var newBlipRef = insertNewBlip('TBD_' + parentId, parentRef, null,
+ parentRef.html());
+ newBlipRef.find('.author').text(user.getDisplayName());
+ newBlipRef.find('.content').html('');
+ newBlipRef.data('parentId', parentId);
+ // TODO: Calling slideDown followed by focus does not seem
+ // to work well on FF, even when using a callback on slideDown.
+ newBlipRef.show();
+ startEditMode(newBlipRef);
+}
+
+function initEditor() {
+ $('.edit-button').live('click', function() {
+ startEditMode($(this));
+ });
+ $('.reply-button').live('click', function() {
+ startReply($(this));
+ });
+
+ // TODO: Add other ways to get into edit mode.
+
+ $('.editor').live('keypress', function(event) {
+ if (event.shiftKey && event.keyCode == '13') {
+ // Shift+enter!
+ stopEditMode();
+ event.preventDefault();
+ }
+ });
+}
Property changes on: trunk/src/main/webapp/others/splash/js/editor.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/embed_support.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/embed_support.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/embed_support.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,148 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+* /**
+ * @fileoverview Gadgets-RPC relay and embed client x-iframe support.
+ *
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+
+window.wave = window.wave || {};
+var wave = window.wave;
+
+/**
+ * Service name for loading a new wave in the current view.
+ */
+var LOAD_WAVE = "load_wave";
+
+/**
+ * Service name for loading a new wave in the current view,
+ * specific to a given user (without an explicit wave id).
+ */
+var LOAD_USER_WAVE = "load_user_wave";
+
+/**
+ * Event that is fired when wave load completes.
+ */
+var LOAD_DONE = "load_done";
+
+/**
+ * Api to communicate with the parent of this iframe.
+ * @constructor
+ * @export
+ */
+wave.EmbedApi = function() {
+ // Tests if gadgets library is loaded.
+ if (window.gadgets && window.gadgets.rpc && window.gadgets.config) {
+ this.configParentRelay_();
+ this.registerService(LOAD_WAVE);
+ this.registerService(LOAD_USER_WAVE);
+ } else {
+ throw "Error: gadget library has not loaded yet.";
+ }
+};
+
+/**
+ * Default configuration for the gadget relay.
+ */
+wave.EmbedApi.GADGET_CONFIG = {
+ rpc : {
+ useLegacyProtocol : false,
+ parentRelayUrl :
+ "http://wave.google.com/gadgets/files/container/rpc_relay.html"
+ },
+ "core.io" : {
+ jsonProxyUrl : "http://%host%/gadgets/makeRequest",
+ proxyUrl : "http://%host%/gadgets/proxy?refresh=%refresh%&url=%url%"
+ }
+};
+
+/**
+ * Registers an inter-iframe callback service provided by the embedded client.
+ *
+ * @param service {string} the name of the service.
+ */
+wave.EmbedApi.prototype.registerService = function(service) {
+ var hub = window.gadgets.rpc;
+ if (hub) {
+ hub.register(service, function() {
+ var service = this['s'];
+ var gadgetId = this['f'];
+ var args = this['a'];
+ this.callback(service, gadgetId, args);
+ });
+ }
+};
+
+/**
+ * Configures parent relay to send RPCs to wave-embedding container.
+ * @private
+ */
+wave.EmbedApi.prototype.configParentRelay_ = function() {
+ window.gadgets.config.init(wave.EmbedApi.GADGET_CONFIG);
+};
+
+/**
+ * Fires an event to the outer page via a callback.
+ *
+ * @private
+ * @param event {string} indicating the name of the event to fire.
+ * @param opt_args {Array.<Object>=} a list of parameters that the other side
+ * needs specific to the event (optional).
+ */
+wave.EmbedApi.prototype.fireEvent = function(event, opt_args) {
+ if (window.gadgets && window.gadgets.rpc) {
+ var base = [null, event, null];
+ var args = base.concat(opt_args);
+ window.gadgets.rpc.call.apply(null, args);
+ }
+};
+
+/**
+ * Receives events from the outer page (complement to
+ * <code>wave.EmbedApi.fireEvent()</code>).
+ * @export
+ * @param service {string} The name of the service that the gadget wants to
+ * call.
+ * @param gadgetId {string} The id of the gadget that initiated the RPC.
+ * @param args {Array<Object>} Generic RPC call argument array.
+ */
+wave.EmbedApi.prototype.callback = function(service, gadgetId, args) {
+ if (LOAD_WAVE == service) {
+ // load a new wave with wave id
+ window.wave.Rpc.getInstance().rpcOpenWave(args[0]);
+ } else if (LOAD_USER_WAVE == service) {
+ // load a "myembed" wave
+ // TODO(dhanji): Call the appropriate rpc when it is available.
+ }
+};
+
+/**
+ * Sends a notification to the containing page that wave load has completed.
+ *
+ * @export
+ */
+wave.EmbedApi.prototype.loaded = function() {
+ this.fireEvent(LOAD_DONE);
+};
+
+/**
+ * Register the singleton instance of <code>EmbedApi</code> as soon as possible.
+ */
+(wave.EmbedApi.initialize_ = function() {
+ window.wave.embedApi = window.wave.embedApi || new wave.EmbedApi();
+})();
+
Property changes on: trunk/src/main/webapp/others/splash/js/embed_support.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/embed_test.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/embed_test.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/embed_test.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,112 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @fileoverview Tests basic functionality of the Embed API
+ *
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+
+/**
+ * Stubs.
+ */
+var window = {};
+var gadgets = {};
+window.gadgets = gadgets;
+gadgets.util = {};
+gadgets.rpc = {};
+gadgets.config = {};
+
+/**
+ * Setup a light fake implementation of gadget.rpc:
+ */
+var callbacks = {};
+
+gadgets.rpc.call = function(frameid, method, c, param1, param2) {
+ method += "_done";
+ for (var name in callbacks){
+ if (method == name) {
+ tocall = callbacks[method];
+ tocall['a'] = new Array(param1, param2);
+ tocall['s'] = method;
+ tocall['f'] = frameid;
+ tocall['c'] = null;
+ tocall.call(tocall);
+ return;
+ }
+ }
+}
+
+gadgets.rpc.register = function(name, callback) {
+ callbacks[name] = callback;
+}
+
+gadgets.rpc.registerDefault = function(method) {
+}
+
+gadgets.rpc.setRelayUrl = function(url) {
+}
+
+/**
+ * Tests that we register available services on the gadget api,
+ * and perform the appropriate initialization steps.
+ */
+function testServicesInitialized() {
+ var initCalled = false;
+ gadgets.config.init = function() {
+ initCalled = true;
+ };
+ var embedApi = new EmbedApi();
+ assertTrue(callbacks['load_wave']);
+ assertTrue(callbacks['load_user_wave']);
+ assertTrue(initCalled);
+}
+
+/**
+ * Tests the event propagation system by simulating the
+ * firing of the 'loaded' event.
+ */
+function testLoadedEventFired() {
+ var embedApi = new EmbedApi();
+
+ var loadCalled = false;
+ gadgets.rpc.register('load_done', function() {
+ loadCalled = true;
+ });
+
+ // Trigger the load event and make sure it propagates
+ embedApi.loaded();
+ assertTrue(loadCalled);
+}
+
+/**
+ * Tests the event propagation system by simulating the
+ * firing of the 'loaded' event.
+ */
+function testLoadWave() {
+ var waveOpenId = '';
+ window.rpcOpenWave = function(waveId) {
+ waveOpenId = waveId;
+ };
+
+ var embedApi = new EmbedApi();
+ var expectedWaveId = 'google.com!w+somewaveid';
+ gadgets.rpc.call('frameId_1', 'load_wave', null, 'gadgetId', expectedWaveId);
+
+ // Make sure the correct wave id was passed thru.
+ assertEquals(expectedWaveId, waveOpenId);
+}
Property changes on: trunk/src/main/webapp/others/splash/js/embed_test.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/full_client.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/full_client.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/full_client.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,98 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+var RPC_UPDATE_INTERVAL_MS = 3000;
+
+/**
+ * Application entry point.
+ */
+$(document).ready(function() {
+ initCommon();
+
+ // Set up the wave panel.
+ var wave = $('#wave');
+
+ // toolbar on hover
+ $('.blip').live('mouseenter', function() {
+ if (!isEditing()) {
+ showToolbar($(this));
+ }
+ }).live('mouseleave', function() {
+ hideToolbar($(this));
+ });
+
+ // Dismiss yellow alert.
+ $('#alertbar').click(function() {
+ $(this).fadeOut();
+ });
+
+ // Clicking on a feed triggers an animation to open it.
+ $('.item').live('click', function() {
+ // First close the wave window if it's open (and erase current conversation)
+ $('#conversation').html('<img id="wave-loading" src="images/wave-loading.gif">');
+ $('#wave-header').hide();
+
+ var item = $(this);
+
+ // Send RPC to open wave at this point.
+ // TODO(dhanji): Make it possible to have many waves open
+ window.waveOptions_.waveId = item.attr('wave_id');
+ window.waveOptions_.waveVersion = -1;
+ window.waveOptions_.page = 0;
+ window.wave.Rpc.getInstance().rpcOpenWave();
+ });
+
+ // Search box actions.
+ var searchBox = $('#searchField');
+
+ // Watermark on/off
+ $('#searchField').focus(function() {
+ searchBox.text('');
+ });
+
+ $('#searchField').blur(function() {
+ if (searchBox.text() == '') {
+ searchBox.text('Search your waves');
+ }
+ });
+
+ initEditor();
+ initGadgetSystem();
+
+ // Enable touch scrolling for both our panels.
+ $('#feed').jScrollTouch();
+ // TODO(dhanji): Do this for the conversation too.
+
+ var rpc = window.wave.Rpc.getInstance();
+
+ // Run search immediately for our inbox.
+ rpc.rpcSearch();
+ setInterval(function() {
+ // This is needed to specify the scope of the function.
+ rpc.rpcAsyncUpdate.call(rpc);
+ }, RPC_UPDATE_INTERVAL_MS);
+});
+
+function onSearch() {
+ // Clear feed.
+ $('#feed')
+ .html('<img id="feed-loading" src="images/loading.gif" alt="Loading feed contents...">'
+ + '<div id="more-feed" class="more-button">Show More...</div>');
+
+ // Search for new query content
+ window.waveOptions_.query = $('#searchField').attr('value');
+ window.wave.Rpc.getInstance().rpcSearch();
+}
Property changes on: trunk/src/main/webapp/others/splash/js/full_client.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/gadget.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/gadget.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/gadget.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,119 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @fileoverview Gadget support.
+ *
+ * @author David Byttow
+ */
+
+// TODO(dhanji): we should eventually extract the relay host from
+// the iframe source rather than hardcoding it.
+var REMOTE_RPC_RELAY_URL =
+ "http://www.gmodules.com/gadgets/files/container/rpc_relay.html";
+
+var DEFAULT_GADGET_MODE = {'${playback}': '1', '${edit}': '0'};
+
+/**
+ * Registers an rpc handler.
+ *
+ * @param service the name of the service.
+ * @param handler the handler, which is of type
+ * Function(string, string, array.<string>)
+ */
+function registerRpc(service, handler) {
+ gadgets.rpc.register(service, function() {
+ var service = this['s'];
+ var gadgetId = this['f'];
+ var args = this['a'];
+ handler(service, gadgetId, args);
+ });
+}
+
+/**
+ * Extracts gadget state out of the DOM and pushes it down via gadgets.rpc and
+ * clear the DOM of the unnecessary state after.
+ *
+ * @param gadgetId the gadget id to extract.
+ */
+function extractGadgetState(gadgetId) {
+ // TODO: Use global objects or pool?
+ var state = {};
+ var participants = {
+ // TODO: Should be proper ID.
+ myId: "anonymous(a)a.gwave.com",
+ authorId: "",
+ participants: {}
+ };
+
+ // Fill in state and participants.
+ var id = '#' + gadgetId + '_state';
+ // Single loop and then if-else switch, rather than multiple loops.
+ $(id).find('span').each(function() {
+ var className = $(this).attr('class');
+ var key = $(this).attr('hiddenKey');
+ var value = $(this).text()
+ if ($(this).hasClass('gadget-state')) {
+ state[key] = value;
+ } else if ($(this).hasClass('gadget-participant')) {
+ // TODO: Profile thumbnail and displayName.
+ var p = {
+ 'id': value,
+ 'displayName': value,
+ 'thumbnailUrl': ''
+ };
+ participants['participants'][value] = p;
+ } else if ($(this).hasClass('gadget-author')) {
+ participants['authorId'] = value;
+ }
+ if (key) {
+ state[key] = value;
+ }
+ });
+
+ // TODO: Enable gadget updates.
+ gadgets.rpc.call(gadgetId, "wave_gadget_mode", null, DEFAULT_GADGET_MODE);
+ gadgets.rpc.call(gadgetId, "wave_participants", null, participants);
+ gadgets.rpc.call(gadgetId, "wave_gadget_state", null, state);
+ // TODO: Deliver the real private state to the gadgets.
+ gadgets.rpc.call(gadgetId, "wave_private_gadget_state", null, {});
+
+ // Clear state out of DOM.
+ $(id).remove();
+}
+
+/**
+ * Initializes the gadget system, call this once at startup.
+ */
+function initGadgetSystem() {
+ // Once a gadget has called us back, we can inject the state/participants.
+ registerRpc("wave_enable", function(service, gadgetId, args) {
+ gadgets.rpc.setRelayUrl(gadgetId, REMOTE_RPC_RELAY_URL);
+ extractGadgetState(gadgetId);
+ });
+
+ registerRpc("resize_iframe", function(service, gadgetId, args) {
+ $('#' + gadgetId).attr('height', args[0]);
+ });
+
+ gadgets.rpc.registerDefault(function() {
+ var eventType = this['s'];
+ var eventObj = this['a'][0];
+ //log(eventType + ": " + eventObj);
+ });
+}
+
Property changes on: trunk/src/main/webapp/others/splash/js/gadget.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/ie6sucks.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/ie6sucks.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/ie6sucks.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,76 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+function fixLayout() {
+ var targetHeight = $(window).height() - 70;
+ $('#feed').css("height", targetHeight);
+ $('#wave').css("height", targetHeight);
+
+ var targetWidth = 0.7 * $(window).width();
+ $('#wave').css("width", targetWidth + 'px');
+}
+
+/**
+ * Init, separate from the main init.
+ */
+$(document).ready(function() {
+ $('#feed').css("top", 0);
+ $('#content').css("position", "relative");
+ $('#content').css("top", 0);
+
+ fixLayout();
+
+ $(window).resize(fixLayout);
+
+ // Do this everytime a wave is opened
+ window.wave.uiCallbacks_.waveOpened = function() {
+ var waveRef = $('#wave');
+
+ $('.blip', waveRef).each(function() {
+ var leftRef = $('.left', $(this));
+ var rightRef = $('.right', $(this));
+ var leftHeight = leftRef.height();
+ var rightHeight = rightRef.height();
+
+ // Normalize heights
+ if (rightHeight < leftHeight) {
+ rightRef.css('height', leftHeight);
+ }
+
+ // The right half needs to be explicitly floated right or
+ // it just flows to the next line on the left.
+ rightRef.css('float', 'right');
+ rightRef.css('behavior', 'url(border-radius.htc)');
+
+ // The left half needs to be position absolute. Otherwise,
+ // it does not layout inside the correct blip.
+ leftRef.css({
+ 'position': 'absolute',
+ 'margin-top': '-12px'
+ });
+
+ // Set the height of a blip to the max of the
+ // left, right divs inside the blip. We add 10px for spacing.
+ $(this).css('height', Math.max(leftHeight, rightHeight) + 60);
+ });
+ };
+
+ // Do this everytime a search is rendered
+ window.wave.uiCallbacks_.feedOpened = function() {
+ $('.item', $('#feed')).css('overflow', 'hidden');
+ $('.snippet', $('#feed')).css('overflow', 'hidden');
+ };
+});
Property changes on: trunk/src/main/webapp/others/splash/js/ie6sucks.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/jScrollTouch.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/jScrollTouch.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/jScrollTouch.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,104 @@
+/*
+ * jQuery jScrollTouch plugin 1.1
+ *
+ * Copyright (c) 2010 Damien Rottemberg damien(a)dealinium.com
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ *
+ */
+
+
+(function($){
+ $.fn.jScrollTouch = function () {
+ if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) {
+ var isTouchScreen = 1;
+ }else{
+ var isTouchScreen = 0;
+ }
+ $(this).css({'overflow': 'auto','position':'relative'});
+ return this.each(function() {
+ var cont = $(this);
+
+ var height = 0;
+ var cpos = cont.scrollTop()
+ cont.scrollTop(100000);
+ height = cont.scrollTop();
+ cont.scrollTop(cpos);
+ var fullheight = height + cont.outerHeight();
+ var scrollbarV_length = cont.innerHeight()*(cont.innerHeight()/fullheight)+2;
+
+ var width = 0;
+ var lpos = cont.scrollLeft();
+ cont.scrollLeft(100000);
+ width = cont.scrollLeft();
+ cont.scrollLeft(lpos);
+ var fullwidth = width + cont.outerWidth();
+ var scrollbarH_length = cont.innerWidth()*(cont.innerWidth()/fullwidth)+2;
+
+
+ if(isTouchScreen){
+ var scrollbarV = $('<div></div>');
+ scrollbarV.css({'display':'none','position':'absolute','width':'5px','height':scrollbarV_length+'px','left':cont.innerWidth()-7+'px','top':0,'background':'black','border':'1px white solid','-webkit-border-radius':'5px','opacity':'0.9'});
+
+ var scrollbarH = $('<div></div>');
+ scrollbarH.css({'display':'none','position':'absolute','height':'5px','width':scrollbarH_length+'px','top':cont.innerHeight()-7+'px','left':0,'background':'black','border':'1px white solid','-webkit-border-radius':'5px','opacity':'0.9'});
+
+
+ if(height) cont.append(scrollbarV);
+ if(width) cont.append(scrollbarH);
+ }
+
+
+ cont.bind('mousedown touchstart',function(e){
+ cpos = cont.scrollTop();
+
+ if(isTouchScreen){
+ e = e.originalEvent.touches[0];
+ }
+
+ if(isTouchScreen){
+ scrollbarV.show();
+ scrollbarH.show();
+ }
+
+ var sY = e.pageY;
+ var sX = e.pageX;
+
+ cont.bind('mousemove touchmove ',function(ev){
+ if(isTouchScreen){
+ ev.preventDefault();
+ ev = ev.originalEvent.touches[0];
+
+ }
+
+ var top = cpos-(ev.pageY-sY);
+ var left = lpos-(ev.pageX-sX);
+
+ cont.scrollTop(top);
+ cpos = cont.scrollTop();
+ sY = ev.pageY;
+
+ cont.scrollLeft(left);
+ lpos = cont.scrollLeft();
+ sX = ev.pageX;
+ if(isTouchScreen){
+ scrollbarV.css({'left':Math.min(cont.innerWidth()-7+lpos,fullwidth)+'px','top':Math.min(cpos+cpos*cont.innerHeight()/fullheight,fullheight-scrollbarV_length)+'px'});
+ scrollbarH.css({'top':Math.min(cont.innerHeight()-7+cpos,fullheight)+'px','left':Math.min(lpos+lpos*cont.innerWidth()/fullwidth,fullwidth-scrollbarH_length)+'px'});
+
+ }
+ });
+ cont.bind('mouseup touchend',function(ev){
+ cont.unbind('mousemove touchmove mouseup touchend');
+ if(isTouchScreen){
+ scrollbarV.fadeOut();
+ scrollbarH.fadeOut();
+ }
+
+ });
+ });
+ });
+}
+})(jQuery);
\ No newline at end of file
Property changes on: trunk/src/main/webapp/others/splash/js/jScrollTouch.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/jquery-1.4.2.min.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/jquery-1.4.2.min.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/jquery-1.4.2.min.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
Property changes on: trunk/src/main/webapp/others/splash/js/jquery-1.4.2.min.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/jquery.lightbox-0.5.min.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/jquery.lightbox-0.5.min.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/jquery.lightbox-0.5.min.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,42 @@
+/**
+ * jQuery lightBox plugin
+ * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/)
+ * and adapted to me for use like a plugin from jQuery.
+ * @name jquery-lightbox-0.5.js
+ * @author Leandro Vieira Pinho - http://leandrovieira.com
+ * @version 0.5
+ * @date April 11, 2008
+ * @category jQuery plugin
+ * @copyright (c) 2008 Leandro Vieira Pinho (leandrovieira.com)
+ * @license CC Attribution-No Derivative Works 2.5 Brazil - http://creativecommons.org/licenses/by-nd/2.5/br/deed.en_US
+ * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin
+ */
+(function($){$.fn.lightBox=function(settings){settings=jQuery.extend({overlayBgColor:'#000',overlayOpacity:0.8,fixedNavigation:false,imageLoading:'images/lightbox-ico-loading.gif',imageBtnPrev:'images/lightbox-btn-prev.gif',imageBtnNext:'images/lightbox-btn-next.gif',imageBtnClose:'images/lightbox-btn-close.gif',imageBlank:'images/lightbox-blank.gif',containerBorderSize:10,containerResizeSpeed:400,txtImage:'Image',txtOf:'of',keyToClose:'c',keyToPrev:'p',keyToNext:'n',imageArray:[],activeImage:0},settings);var jQueryMatchedObj=this;function _initialize(){_start(this,jQueryMatchedObj);return false;}
+function _start(objClicked,jQueryMatchedObj){$('embed, object, select').css({'visibility':'hidden'});_set_interface();settings.imageArray.length=0;settings.activeImage=0;if(jQueryMatchedObj.length==1){settings.imageArray.push(new Array(objClicked.getAttribute('href'),objClicked.getAttribute('title')));}else{for(var i=0;i<jQueryMatchedObj.length;i++){settings.imageArray.push(new Array(jQueryMatchedObj[i].getAttribute('href'),jQueryMatchedObj[i].getAttribute('title')));}}
+while(settings.imageArray[settings.activeImage][0]!=objClicked.getAttribute('href')){settings.activeImage++;}
+_set_image_to_view();}
+function _set_interface(){$('body').append('<div id="jquery-overlay"></div><div id="jquery-lightbox"><div id="lightbox-container-image-box"><div id="lightbox-container-image"><img id="lightbox-image"><div style="" id="lightbox-nav"><a href="#" id="lightbox-nav-btnPrev"></a><a href="#" id="lightbox-nav-btnNext"></a></div><div id="lightbox-loading"><a href="#" id="lightbox-loading-link"><img src="'+settings.imageLoading+'"></a></div></div></div><div id="lightbox-container-image-data-box"><div id="lightbox-container-image-data"><div id="lightbox-image-details"><span id="lightbox-image-details-caption"></span><span id="lightbox-image-details-currentNumber"></span></div><div id="lightbox-secNav"><a href="#" id="lightbox-secNav-btnClose"><img src="'+settings.imageBtnClose+'"></a></div></div></div></div>');var arrPageSizes=___getPageSize();$('#jquery-overlay').css({backgroundColor:settings.overlayBgColor,opacity:settings.overlayOpacity,width:arrPageSizes[0],height:arrPageSizes[1]}).fadeIn();var arrPageScroll=___getPageScroll();$('#jquery-lightbox').css({top:arrPageScroll[1]+(arrPageSizes[3]/10),left:arrPageScroll[0]}).show();$('#jquery-overlay,#jquery-lightbox').click(function(){_finish();});$('#lightbox-loading-link,#lightbox-secNav-btnClose').click(function(){_finish();return false;});$(window).resize(function(){var arrPageSizes=___getPageSize();$('#jquery-overlay').css({width:arrPageSizes[0],height:arrPageSizes[1]});var arrPageScroll=___getPageScroll();$('#jquery-lightbox').css({top:arrPageScroll[1]+(arrPageSizes[3]/10),left:arrPageScroll[0]});});}
+function _set_image_to_view(){$('#lightbox-loading').show();if(settings.fixedNavigation){$('#lightbox-image,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide();}else{$('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide();}
+var objImagePreloader=new Image();objImagePreloader.onload=function(){$('#lightbox-image').attr('src',settings.imageArray[settings.activeImage][0]);_resize_container_image_box(objImagePreloader.width,objImagePreloader.height);objImagePreloader.onload=function(){};};objImagePreloader.src=settings.imageArray[settings.activeImage][0];};function _resize_container_image_box(intImageWidth,intImageHeight){var intCurrentWidth=$('#lightbox-container-image-box').width();var intCurrentHeight=$('#lightbox-container-image-box').height();var intWidth=(intImageWidth+(settings.containerBorderSize*2));var intHeight=(intImageHeight+(settings.containerBorderSize*2));var intDiffW=intCurrentWidth-intWidth;var intDiffH=intCurrentHeight-intHeight;$('#lightbox-container-image-box').animate({width:intWidth,height:intHeight},settings.containerResizeSpeed,function(){_show_image();});if((intDiffW==0)&&(intDiffH==0)){if($.browser.msie){___pause(250);}else{___pause(100);}}
+$('#lightbox-container-image-data-box').css({width:intImageWidth});$('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({height:intImageHeight+(settings.containerBorderSize*2)});};function _show_image(){$('#lightbox-loading').hide();$('#lightbox-image').fadeIn(function(){_show_image_data();_set_navigation();});_preload_neighbor_images();};function _show_image_data(){$('#lightbox-container-image-data-box').slideDown('fast');$('#lightbox-image-details-caption').hide();if(settings.imageArray[settings.activeImage][1]){$('#lightbox-image-details-caption').html(settings.imageArray[settings.activeImage][1]).show();}
+if(settings.imageArray.length>1){$('#lightbox-image-details-currentNumber').html(settings.txtImage+' '+(settings.activeImage+1)+' '+settings.txtOf+' '+settings.imageArray.length).show();}}
+function _set_navigation(){$('#lightbox-nav').show();$('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({'background':'transparent url('+settings.imageBlank+') no-repeat'});if(settings.activeImage!=0){if(settings.fixedNavigation){$('#lightbox-nav-btnPrev').css({'background':'url('+settings.imageBtnPrev+') left 15% no-repeat'}).unbind().bind('click',function(){settings.activeImage=settings.activeImage-1;_set_image_to_view();return false;});}else{$('#lightbox-nav-btnPrev').unbind().hover(function(){$(this).css({'background':'url('+settings.imageBtnPrev+') left 15% no-repeat'});},function(){$(this).css({'background':'transparent url('+settings.imageBlank+') no-repeat'});}).show().bind('click',function(){settings.activeImage=settings.activeImage-1;_set_image_to_view();return false;});}}
+if(settings.activeImage!=(settings.imageArray.length-1)){if(settings.fixedNavigation){$('#lightbox-nav-btnNext').css({'background':'url('+settings.imageBtnNext+') right 15% no-repeat'}).unbind().bind('click',function(){settings.activeImage=settings.activeImage+1;_set_image_to_view();return false;});}else{$('#lightbox-nav-btnNext').unbind().hover(function(){$(this).css({'background':'url('+settings.imageBtnNext+') right 15% no-repeat'});},function(){$(this).css({'background':'transparent url('+settings.imageBlank+') no-repeat'});}).show().bind('click',function(){settings.activeImage=settings.activeImage+1;_set_image_to_view();return false;});}}
+_enable_keyboard_navigation();}
+function _enable_keyboard_navigation(){$(document).keydown(function(objEvent){_keyboard_action(objEvent);});}
+function _disable_keyboard_navigation(){$(document).unbind();}
+function _keyboard_action(objEvent){if(objEvent==null){keycode=event.keyCode;escapeKey=27;}else{keycode=objEvent.keyCode;escapeKey=objEvent.DOM_VK_ESCAPE;}
+key=String.fromCharCode(keycode).toLowerCase();if((key==settings.keyToClose)||(key=='x')||(keycode==escapeKey)){_finish();}
+if((key==settings.keyToPrev)||(keycode==37)){if(settings.activeImage!=0){settings.activeImage=settings.activeImage-1;_set_image_to_view();_disable_keyboard_navigation();}}
+if((key==settings.keyToNext)||(keycode==39)){if(settings.activeImage!=(settings.imageArray.length-1)){settings.activeImage=settings.activeImage+1;_set_image_to_view();_disable_keyboard_navigation();}}}
+function _preload_neighbor_images(){if((settings.imageArray.length-1)>settings.activeImage){objNext=new Image();objNext.src=settings.imageArray[settings.activeImage+1][0];}
+if(settings.activeImage>0){objPrev=new Image();objPrev.src=settings.imageArray[settings.activeImage-1][0];}}
+function _finish(){$('#jquery-lightbox').remove();$('#jquery-overlay').fadeOut(function(){$('#jquery-overlay').remove();});$('embed, object, select').css({'visibility':'visible'});}
+function ___getPageSize(){var xScroll,yScroll;if(window.innerHeight&&window.scrollMaxY){xScroll=window.innerWidth+window.scrollMaxX;yScroll=window.innerHeight+window.scrollMaxY;}else if(document.body.scrollHeight>document.body.offsetHeight){xScroll=document.body.scrollWidth;yScroll=document.body.scrollHeight;}else{xScroll=document.body.offsetWidth;yScroll=document.body.offsetHeight;}
+var windowWidth,windowHeight;if(self.innerHeight){if(document.documentElement.clientWidth){windowWidth=document.documentElement.clientWidth;}else{windowWidth=self.innerWidth;}
+windowHeight=self.innerHeight;}else if(document.documentElement&&document.documentElement.clientHeight){windowWidth=document.documentElement.clientWidth;windowHeight=document.documentElement.clientHeight;}else if(document.body){windowWidth=document.body.clientWidth;windowHeight=document.body.clientHeight;}
+if(yScroll<windowHeight){pageHeight=windowHeight;}else{pageHeight=yScroll;}
+if(xScroll<windowWidth){pageWidth=xScroll;}else{pageWidth=windowWidth;}
+arrayPageSize=new Array(pageWidth,pageHeight,windowWidth,windowHeight);return arrayPageSize;};function ___getPageScroll(){var xScroll,yScroll;if(self.pageYOffset){yScroll=self.pageYOffset;xScroll=self.pageXOffset;}else if(document.documentElement&&document.documentElement.scrollTop){yScroll=document.documentElement.scrollTop;xScroll=document.documentElement.scrollLeft;}else if(document.body){yScroll=document.body.scrollTop;xScroll=document.body.scrollLeft;}
+arrayPageScroll=new Array(xScroll,yScroll);return arrayPageScroll;};function ___pause(ms){var date=new Date();curDate=null;do{var curDate=new Date();}
+while(curDate-date<ms);};return this.unbind('click').click(_initialize);};})(jQuery);
\ No newline at end of file
Property changes on: trunk/src/main/webapp/others/splash/js/jquery.lightbox-0.5.min.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/mobile_client.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/mobile_client.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/mobile_client.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,127 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+var RPC_UPDATE_INTERVAL_MS = 3000;
+
+function log(msg) {
+ if (window.console && window.console.log) {
+ console.log(msg);
+ }
+}
+
+function warn(msg) {
+ if (window.console && window.console.warn) {
+ console.warn(msg);
+ }
+}
+
+/**
+ * Application entry point.
+ */
+$(document).ready(function() {
+ initCommon();
+
+ // Set up the wave panel.
+ var wave = $('#wave');
+
+ // toolbar on hover
+ $('.blip').live('mouseenter', function() {
+ if (!isEditing()) {
+ showToolbar($(this));
+ }
+ }).live('mouseleave', function() {
+ hideToolbar($(this));
+ });
+
+ // Dismiss yellow alert.
+ $('#alertbar').click(function() {
+ $(this).fadeOut();
+ });
+
+ // Clicking on a feed triggers an animation to open it.
+ $('.item').live('click', function() {
+ // In the mobile client, we swap the wave and feed when a digest is clicked.
+ $('#feed').hide();
+
+ wave.show();
+ $('#conversation').html('<img id="wave-loading" src="images/wave-loading.gif">');
+ $('#main-button').text('Back to Waves');
+
+ var item = $(this);
+
+ // Send RPC to open wave at this point.
+ // TODO(dhanji): Make it possible to have many waves open
+ window.waveOptions_.waveId = item.attr('wave_id');
+ window.waveOptions_.waveVersion = -1;
+ window.waveOptions_.page = 0;
+ window.wave.Rpc.getInstance().rpcOpenWave();
+ });
+
+ // Search box actions.
+ var searchBox = $('#searchField');
+
+ $('#main-button').click(function() {
+ // If we're in wave mode, go back.
+ if (window.waveOptions_.waveId) {
+ wave.hide();
+ $('#feed').show();
+ $('#main-button').text('New Wave');
+ } else {
+ // TODO(dhanji): Implement.
+ }
+ });
+
+ $('#searchField').click(function() {
+ $('#searchField').val('');
+ });
+
+ $('#searchToggle').click(function() {
+ toggleSearch();
+ });
+
+ initEditor();
+ initGadgetSystem();
+
+ var rpc = window.wave.Rpc.getInstance();
+
+ // Run search immediately for our inbox.
+ rpc.rpcSearch();
+ setInterval(function() {
+ // This is needed to specify the scope of the function.
+ rpc.rpcAsyncUpdate.call(rpc);
+ }, RPC_UPDATE_INTERVAL_MS);
+});
+
+function onSearch() {
+ // Clear feed.
+ $('.feed')
+ .html('<img id="feed-loading" src="images/loading.gif" alt="Loading feed contents...">'
+ + '<div id="more-feed" class="more-button">Show More...</div>');
+
+ // Search for new query content
+ window.waveOptions_.query = $('#searchField').attr('value');
+ window.wave.Rpc.getInstance().rpcSearch();
+}
+
+function toggleSearch() {
+ var headerSearchRef = $('#headerSearch')
+ if (headerSearchRef.is(':visible')) {
+ headerSearchRef.fadeOut();
+ }
+ else {
+ headerSearchRef.fadeIn();
+ }
+}
Property changes on: trunk/src/main/webapp/others/splash/js/mobile_client.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/permalink_client.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/permalink_client.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/permalink_client.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,106 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @fileoverview JS for the standalone (permalink) version of the client.
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+
+
+var RPC_UPDATE_INTERVAL_MS = 3000;
+
+window.waveOptions_ = {};
+
+/**
+ * Application entry point.
+ */
+$(document).ready(function() {
+ var path = window.location.pathname;
+
+ // adjust the height of the content frame to fill the iframe height
+ $("#contentInner3")
+ .css("height", 0)
+ .css("height",
+ $(window).height() - $("#header").outerHeight()
+ - $("#content").outerHeight());
+
+ // extract wave id.
+ var waveId = $('#wave').attr('wave_id');
+
+ // run rpc right away to open the wave.
+ window.waveOptions_.waveId = waveId;
+ window.waveOptions_.page = 0;
+ window.waveOptions_.waveVersion = -1;
+
+ // Options for rendering the wave. Maybe we need a more robust solution.
+ window.waveOptions_.showHeader = $('#wave').attr('show_header');
+
+ // Override async update options, coz we don't need search and stuff.
+ // TODO(dhanji): this is broken, fix.
+ RPC_UPDATE_OPTIONS = "update_wave";
+
+ $('#share-link').click(function() {
+ var shareRef = $('#share-popup');
+ shareRef.fadeIn();
+ return false;
+ });
+
+ $(".dialog-close").mousedown(function() {
+ $(this).addClass("down");
+ });
+
+ $(".dialog-close").mouseout(function() {
+ $(this).removeClass("down");
+ });
+
+ $(document).click(function(event) {
+ if ($(event.target).is("#share-popup, #share-popup *")
+ && !$(event.target).is(".dialog-close, .dialog-close *"))
+ {
+ return false;
+ }
+
+ $('#share-popup').fadeOut();
+ });
+
+ // Listen for expansion of collapsed inline replies.
+ // TODO(dhanji): Merge into a common.js (NOT common_client.js)
+ $('.inline-reply .count').live('click', function() {
+ var inlineReplyId = '#ir-' + $(this).parent().attr('ir-id');
+ var countRef = $(this);
+
+ if (countRef.hasClass('expanded')) {
+ // Move this back to purgatory!
+ $(inlineReplyId).appendTo('#purgatory');
+ countRef.removeClass('expanded');
+ } else {
+ $(inlineReplyId).insertAfter(countRef);
+ countRef.addClass('expanded');
+ }
+ });
+
+ var rpc = window.wave.Rpc.getInstance();
+
+ initGadgetSystem();
+ rpc.rpcOpenWave();
+
+ setInterval(function() {
+ // This is needed to specify the scope of the function.
+ window.wave.Rpc.getInstance().rpcAsyncUpdate();
+ }, RPC_UPDATE_INTERVAL_MS);
+});
+
Property changes on: trunk/src/main/webapp/others/splash/js/permalink_client.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/rpc.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/rpc.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/rpc.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,708 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @fileoverview Client/Server RPC abstraction and UI update callback layer.
+ * The current user is provided to us by means for the global
+ * <code>BOOTSTRAP</code> constant, in the containing HTML template. This
+ * file also relies on the presence of the jQuery 1.4.2 library
+ * (http://code.jquery.com/jquery-1.4.2.js) and the jQuery lightbox 0.5.0
+ * plugin (http://leandrovieira.com/projects/jquery/lightbox/)
+ * We also require <code>window.waveOptions_</code> to be an object that is
+ * set to the current client state (essentially the open wave + version).
+ * Classes:
+ * wave.DataView
+ * wave.Rpc
+ * @author dhanji(a)google.com (Dhanji R. Prasanna)
+ */
+
+
+var wave = wave || {};
+
+/**
+ * Global user info.
+ *
+ * @type {!Object}
+ */
+wave.user = wave.user || {};
+
+/**
+ * A registry of UI callbacks.
+ *
+ * @type {!Object.<string,function()>}
+ * @private
+ */
+wave.uiCallbacks_ = wave.uiCallbacks_ || {};
+
+/**
+ * @return {string} Email address of the current user.
+ */
+wave.user.getEmail = function() {
+ // BOOTSTRAP is current user info provided by the HTML template.
+ return BOOTSTRAP.email;
+};
+
+/**
+ * @return {string} Full name of the current user.
+ */
+wave.user.getDisplayName = function() {
+ // BOOTSTRAP is current user info provided by the HTML template.
+ return BOOTSTRAP.displayName;
+};
+
+
+/**
+ * Represents all UI access to the data controls of the current client.
+ * Data from/to the server should be read and written to the UI using
+ * this class.
+ *
+ * @constructor
+ * @export
+ */
+wave.DataView = function() {
+ /**
+ * List of dirty blips that represent pending edits to the wave.
+ *
+ * @type {!Array<Element>}
+ * @private
+ */
+ this.pendingEdits_ = [];
+
+ /**
+ * A reference to the conversation element of the wave.
+ *
+ * @type {Element}
+ * @private
+ */
+ this.conversation_ = $('#conversation');
+};
+
+/**
+ * The nominal height of the wave header in pixels.
+ *
+ * @type {number}
+ * @private
+ */
+wave.DataView.WAVE_HEADER_HEIGHT_PX_ = 18;
+
+/**
+ * Gathers all the edited blips from the DOM (marked by class content-dirty)
+ * and adds them to the current client state as new or edited blips.
+ */
+wave.DataView.prototype.addPendingEdits = function() {
+ var requestId = 0;
+ $('.content-dirty').each(function() {
+ var dirtyRef = $(this);
+ var blipId = dirtyRef.attr('blip_id');
+ var blipRef = $('#' + blipId);
+ var parentId = blipRef.data('parentId');
+ var threadId = blipRef.parent('div.thread').attr('id');
+ var content = dirtyRef.html();
+ if (parentId) {
+ // If the parent id exists, we assume this is a new reply.
+ window.waveOptions_['newblip_' + requestId + '_previousBlip'] = parentId;
+ window.waveOptions_['newblip_' + requestId + '_text'] = content;
+ window.waveOptions_['newblip_' + requestId + '_threadId'] = threadId;
+ } else {
+ window.waveOptions_['editblip_' + blipId] = content;
+ }
+ requestId++;
+ this.pendingEdits_.push(dirtyRef);
+ });
+};
+
+/**
+ * Clears all the edited blips state stored in the client state, typically
+ * called after this state has been synchronized with the server. Acts as
+ * as complement to <code>addPendingEdits</code>.
+ */
+wave.DataView.prototype.clearPendingEdits = function() {
+ var requestId = 0;
+ for (var i = 0; i < this.pendingEdits_.length; i++) {
+ var dirtyRef = this.pendingEdits[i];
+ var blipId = dirtyRef.attr('blip_id');
+ var blipRef = $('#' + blipId);
+ var parentId = blipRef.data('parentId');
+
+ delete window.waveOptions_['newblip_' + requestId + '_previousBlip'];
+ delete window.waveOptions_['newblip_' + requestId + '_text'];
+ delete window.waveOptions_['newblip_' + requestId + '_threadId'];
+ delete window.waveOptions_['editblip_' + blipId];
+ dirtyRef.removeClass('content-dirty');
+ requestId++;
+ }
+
+ // Finally, clear all pending edits.
+ this.pendingEdits_.length = 0;
+};
+
+/**
+ * Updates the the time-measure field with the value from the last
+ * action. For example, "Search completed in XX.Xs"
+ *
+ * @param {string} html A String of processed html representing the
+ * measurement to be displayed.
+ */
+wave.DataView.prototype.measure = function(html) {
+ $('#measure').html(html);
+};
+
+/**
+ * Appends a conversation fragment to the existing wave conversation.
+ *
+ * @param {string} html A String of processed html representing the
+ * fragment of conversation to be appended.
+ */
+wave.DataView.prototype.appendConversation = function(html) {
+ this.conversation_.append($(html));
+ $('#wave-loading').remove();
+ $('#wave-header').show();
+
+ // Set up the lightbox for any slideshows in the wave (using the jQuery
+ // lightbox plugin).
+ $('a.lightbox').lightBox();
+};
+
+/**
+ * Replaces the existing wave conversation with a newly rendered html
+ * conversation.
+ *
+ * @param {string} html A string of processed html representing the
+ * fragment of conversation to place.
+ * @return {boolean} True if there is more conversation to be loaded for
+ * this wave.
+ */
+wave.DataView.prototype.insertConversation = function(html) {
+ this.conversation_.html($(html));
+
+ // Set up the lightbox for any slideshows in the wave.
+ $('a.lightbox').lightBox();
+
+ return $('#wave-loading').length > 0;
+};
+
+/**
+ * Replaces the existing wave header with a newly rendered html
+ * list of participants.
+ *
+ * @param {string} html A string of processed html representing the
+ * header of the wave.
+ */
+wave.DataView.prototype.insertHeader = function(html) {
+ var headerRef = $('#wave-header');
+ headerRef.removeClass('expanded');
+ headerRef.html($(html));
+ headerRef.show();
+
+ // Determine the actual height with all participants.
+ var participantsRef = $('.participants');
+ participantsRef.css('height', 'auto');
+ var height = participantsRef.height();
+ participantsRef.css('height', null);
+
+ // Display a "show more" option if the content height is greater than
+ // the default height of the wave header.
+ if (height > wave.DataView.WAVE_HEADER_HEIGHT_PX_) {
+ $('.header .detail').show();
+ }
+};
+
+/**
+ * Deletes the specified blip from view with an animation.
+ *
+ * @param {string} blipId A DOM selector for the blip to delete.
+ */
+wave.DataView.prototype.deleteBlip = function(blipId) {
+ // Animate by sliding it up out of view.
+ $(blipId).slideUp(function() {
+ $(this).remove();
+ });
+};
+
+/**
+ * Inserts a new blip into the wave conversation at the appropriate spot in the
+ * DOM.
+ *
+ * @param {string} blipId Id of the blip to be inserted into the DOM.
+ * @param {string=} opt_parent DOM selector of the parent blip to insert under
+ * (optional).
+ * @param {boolean=} opt_indent True if this blip should be rendered inside a
+ * new indent level under the parent. Default is false (optional).
+ * @param {string=} opt_html Processed html containing the content of the blip
+ * itself to be inserted directly into the DOM (optional).
+ * @param {number=} opt_version Version number of the of the new blip
+ * (optional).
+ * @return {Element} A reference to the blip DOM element that was just inserted.
+ */
+wave.DataView.prototype.insertBlip = function(blipId, opt_parent, opt_indent,
+ opt_html, opt_version) {
+ var indent = opt_indent || false;
+ var html = opt_html || 'TEST';
+ var version = opt_version || '0';
+
+ // Construct a blip html fragment and slide it in.
+ var htmlBuilder = [
+ '<div id="',
+ blipId,
+ '" class="blip" style="display:none">',
+ html,
+ '</div>'
+ ];
+ blipRef = $(htmlBuilder.join(''));
+
+ // Handle the indented reply case.
+ if (!opt_parent) {
+ // If this is the root blip. Add to container.
+ this.conversation_.prepend(blip);
+ } else if (indent) {
+ // See if the parent blip already has an inline child.
+ var parentRef = $(opt_parent);
+ var indentRef = parentRef.children('.indent');
+ if (indentRef.length) {
+ // If it does, insert into it.
+ indentRef.append(blipRef);
+ } else {
+ // Insert an indent wrapper.
+ indentRef = $('<div class="indent"></div>');
+ parentRef.after(indentRef);
+ indentRef.append(blipRef);
+ }
+ } else {
+ $(opt_parent).after(blipRef);
+ }
+ return blipRef;
+};
+
+/**
+ * Updates an existing blip in the wave conversation in place.
+ *
+ * @param {string} blipId A DOM selector of the blip id to update in place.
+ * @param {string} html Processed HTML of the new content of the blip.
+ */
+wave.DataView.prototype.replaceBlip = function(blipId, html) {
+ var blip = $(blipId);
+
+ // Animated transition from the old to the new content.
+ blip.fadeTo('slow', 0, function() {
+ blip.html(html);
+ blip.fadeTo('slow', 1);
+ });
+};
+
+/**
+ * Inserts the incoming HTML into the feed before the more feed button, and
+ * removes the feed loading indicator.
+ *
+ * @param {string} html Processed HTML of the new content of the feed.
+ */
+wave.DataView.prototype.insertFeed = function(html) {
+ var newFeed = $(html);
+
+ // Insert fragment into feed invisible, then slide in.
+ $('#feed-loading').remove();
+
+ // Insert it before the more button.
+ $('#more-feed').before(newFeed);
+ newFeed.show();
+};
+
+/**
+ * Tests if an element(s) exists in the DOM by its selector.
+ *
+ * @param {string} selector A DOM selector in CSS fashion.
+ * @return {boolean} True if this CSS selector exists in the DOM.
+ */
+wave.DataView.prototype.exists = function(selector) {
+ return $(selector).length > 0;
+};
+
+/**
+ * Determines if the given client action data is newer than the version of the
+ * existing blip.
+ *
+ * @param {!Object} data A client action that may or may not contain a version.
+ * @param {Element} blip A blip element on the page.
+ * @return {boolean} True if the data is newer than the blip on page.
+ */
+wave.DataView.prototype.hasNewer = function(data, blip) {
+ return data.version && blip.data('version') >= data.version;
+};
+
+/**
+ * Handles all high-level RPC communication with the web server.
+ *
+ * @param {!wave.DataView} dataView A handle to the underlying data view.
+ * @export
+ * @constructor
+ */
+wave.Rpc = function(dataView) {
+ /**
+ * The singleton data view to modify the UI.
+ *
+ * @type {wave.DataView}
+ * @private
+ */
+ this.dataView_ = dataView;
+ // Register global RPC server callbacks.
+ this.callbacks_ = {
+ 'add-blip': this.addBlipCallback_,
+ 'update-blip': this.updateBlipCallback_,
+ 'delete-blip': this.deleteBlipCallback_,
+ 'update-feed': this.updateFeedCallback_,
+ 'update-wave-version': this.updateWaveVersionCallback_,
+ 'update-wave': this.updateWaveCallback_,
+ 'update-header': this.updateHeaderCallback_,
+ 'measure': this.measureCallback_
+ };
+};
+
+/**
+ * Global instance.
+ *
+ * @type {wave.Rpc}
+ * @private
+ */
+wave.Rpc.instance_ = null;
+
+/**
+ * Singleton factory method.
+ *
+ * @return {wave.Rpc} Singleton instance of <code>wave.Rpc</code> class.
+ * @export
+ */
+wave.Rpc.getInstance = function() {
+ if (!wave.Rpc.instance_) {
+ wave.Rpc.instance_ = new wave.Rpc(new wave.DataView());
+ }
+
+ return wave.Rpc.instance_;
+};
+
+/**
+ * Default RPC endpoints requested by this edition of the client.
+ * A comma-separated list of rpc names that will be executed each
+ * time a short-poll request is made in the background.
+ *
+ * @type {string}
+ * @private
+ */
+wave.Rpc.RPC_UPDATE_OPTIONS_ = 'update_wave,edit_wave';
+
+/**
+ * The Ajax URL where RPCs should be sent for background batch
+ * execution. This URL accepts only POST messages.
+ *
+ * @type {string}
+ * @private
+ */
+wave.Rpc.ASYNC_UPDATE_URL_ = '/async/update?rpc=' +
+ wave.Rpc.RPC_UPDATE_OPTIONS_;
+
+/**
+ * The Ajax URL for executing searches immediately.
+ *
+ * @type {string}
+ * @private
+ */
+wave.Rpc.SYNC_SEARCH_URL_ = '/async/search?rpc=search';
+
+/**
+ * The Ajax URL for executing wave-open requests immediately.
+ *
+ * @type {string}
+ * @private
+ */
+wave.Rpc.SYNC_WAVE_URL_ = '/async/wave?rpc=open_wave';
+
+/**
+ * An internal map of RPC names to callbacks.
+ *
+ * @type {Object.<string,function(Object)>}
+ * @private
+ */
+wave.Rpc.prototype.callbacks_;
+
+/**
+ * Executes a search RPC immediately. Responses are handled
+ * via <code>updateFeedCallback</code>.
+ *
+ * @export
+ */
+wave.Rpc.prototype.rpcSearch = function() {
+ this.rpc_(wave.Rpc.SYNC_SEARCH_URL_);
+};
+
+/**
+ * Executes an open wave RPC immediately. Responses are handled
+ * via <code>updateWaveCallback</code>.
+ *
+ * @export
+ */
+wave.Rpc.prototype.rpcOpenWave = function() {
+ this.rpc_(wave.Rpc.SYNC_WAVE_URL_);
+};
+
+/**
+ * Synchronizes the client state with the server via a periodic
+ * short poll. This function is typically called by a timer and
+ * sends a batch of RPCs including edits, new blip additions, etc.
+ *
+ * @export
+ */
+wave.Rpc.prototype.rpcAsyncUpdate = function() {
+ this.dataView_.addPendingEdits();
+ this.rpc_(wave.Rpc.ASYNC_UPDATE_URL_);
+ this.dataView_.clearPendingEdits();
+};
+
+/**
+ * Tests if the given wave id is currently open in the client.
+ *
+ * @param {string} waveId A wave id of the form "[domain.com]![id]"
+ * as described in the wave protocol specification.
+ * @return {boolean} True if the given wave id is currently open.
+ * @private
+ */
+wave.Rpc.prototype.isCurrentWave_ = function(waveId) {
+ return window.waveOptions_.waveId == waveId;
+};
+
+/**
+ * A callback for handling network communication failure in the background.
+ * Displays a useful message to the user.
+ * TODO(dhanji): Revisit for i18n.
+ *
+ * @private
+ */
+wave.Rpc.prototype.onAjaxFailure_ = function() {
+ alert('Oops, there was a network failure. Please give it a few seconds' +
+ ' and try again.');
+};
+
+/**
+ * The central RPC invoker, takes the entire state of the client and posts it
+ * as name/value pairs to a given RPC endpoint. Asynchronous responses are
+ * processed in <code>handleRpcResponse_</code>.
+ *
+ * @param {string} url The relative URL representing an RPC endpoint.
+ * @private
+ */
+wave.Rpc.prototype.rpc_ = function(url) {
+ var self = this;
+ var success = function(data) {
+ self.handleRpcResponse_.call(self, data);
+ };
+ $.ajax({
+ type: 'POST',
+ url: url,
+ dataType: 'json',
+ data: window.waveOptions_,
+ success: success,
+ failure: self.onAjaxFailure_
+ });
+};
+
+/**
+ * Callback dispatcher, invoked when the server responds with
+ * any data at all, dispatches to the various *Callback() functions.
+ *
+ * @param {Array.<Object>} data The server response in the form of a
+ * list of <code>ClientAction</code> objects.
+ * @private
+ */
+wave.Rpc.prototype.handleRpcResponse_ = function(data) {
+ // Data is a list of client actions to perform.
+ if (data == null) {
+ warn('handleRpcResponse_ called with null data');
+ return;
+ }
+ for (var i = 0; i < data.length; i++) {
+ var clientAction = data[i];
+
+ // Dispatch result based on action name.
+ this.callbacks_[clientAction.action].call(this, clientAction);
+ }
+};
+
+/**
+ * Updates the the time-measure field with the value from the last
+ * action. For example, "Search completed in XX.Xs"
+ *
+ * @param {!Object} data A client action containing processed html
+ * representing the measurement to be displayed.
+ * @private
+ */
+wave.Rpc.prototype.measureCallback_ = function(data) {
+ this.dataView_.measure(data.html);
+};
+
+/**
+ * Updates the wave version that the client thinks it has. This is generally
+ * done when we have the streaming blip updates set, so we know to request a
+ * diff from the known version next time.
+ *
+ * @param {!Object} data A client action containing the current version of the
+ * wave being displayed.
+ * @private
+ */
+wave.Rpc.prototype.updateWaveVersionCallback_ = function(data) {
+ if (!this.isCurrentWave_(data.waveId)) {
+ return;
+ }
+
+ // Store the wave version as the current wave version.
+ window.waveOptions_.waveVersion = data.version;
+};
+
+/**
+ * Updates the wave window with an entire pre-rendered wave. Used for
+ * entire wave open, rather than incremental updates/adds of blips.
+ * This function actually pages in the wave, by loading an initial fragment
+ * and then if necessary issuing an immediate background request for the rest
+ * of the conversation.
+ *
+ * @param {!Object} data A client action containing the rendered html
+ * of the currently open wave conversation.
+ * @private
+ */
+wave.Rpc.prototype.updateWaveCallback_ = function(data) {
+ if (!this.isCurrentWave_(data.waveId)) {
+ return;
+ }
+
+ // Store the version we just fetched.
+ window.waveOptions_.waveVersion = data.version;
+
+ if (window.waveOptions_.page > 0) {
+ this.dataView_.appendConversation(data.html);
+ } else {
+ var hasMore = this.dataView_.insertConversation(data.html);
+ if (hasMore) {
+ // Advance the page and call wave open again (any page > 0 is the
+ // rest of the conversation).
+ window.waveOptions_.page = 1;
+ this.rpcOpenWave();
+ }
+ }
+
+ // Callback various event handlers to say the wave is ready.
+ if (window.embedApi) {
+ window.embedApi.loaded();
+ }
+ if (wave.uiCallbacks_.waveOpened) {
+ wave.uiCallbacks_.waveOpened();
+ }
+};
+
+/**
+ * Updates the wave window header with participant information and avatars.
+ * Replaces any existing content in the header.
+ *
+ * @param {!Object} data A client action object containing the processed html
+ * with participants and avatars.
+ * @private
+ */
+wave.Rpc.prototype.updateHeaderCallback_ = function(data) {
+ if (!this.isCurrentWave_(data.waveId)) {
+ return;
+ }
+
+ this.dataView_.insertHeader(data.html);
+};
+
+/**
+ * Updates the feed column with newer digest items, inserts
+ * them directly into the feed. Appends these items to the feed
+ * rather than replacing them directly.
+ *
+ * @param {!Object} data A client action containing processed html
+ * of the entire list of feed items.
+ * @private
+ */
+wave.Rpc.prototype.updateFeedCallback_ = function(data) {
+ this.dataView_.insertFeed(data.html);
+
+ if (wave.uiCallbacks_.feedOpened) {
+ wave.uiCallbacks_.feedOpened();
+ }
+};
+
+/**
+ * Deletes an existing blip from the wave conversation.
+ *
+ * @param {!Object} data A client action object containing a DOM selector
+ * of the blip id to be deleted.
+ * @private
+ */
+wave.Rpc.prototype.deleteBlipCallback_ = function(data) {
+ // We already have this version.
+ if (this.dataView_.hasNewer(data, $(data.blipId))) {
+ return;
+ }
+
+ this.dataView_.deleteBlip(data.blipId);
+};
+
+/**
+ * Append blip to the current wave conversation. If this blip already
+ * exists in the DOM, perform an update-in-place with the new content
+ * instead.
+ *
+ * @param {!Object} data A client action object containing the blip id
+ * of the the new blip and processed HTML of its content.
+ * @private
+ */
+wave.Rpc.prototype.addBlipCallback_ = function(data) {
+ // Kill the loading indicator if it's on.
+ if ($('#loading').length > 0) {
+ $('#loading').hide();
+ }
+
+ // If this element already exists, update it in place instead.
+ var selector = '#' + data.blipId;
+ if (this.dataView_.exists(selector)) {
+ data.blipId = selector;
+ this.updateBlipCallback_(data);
+ return;
+ }
+
+ this.dataView_.insertBlip(data.blipId, data.parent, data.indent, data.html,
+ data.version).slideDown();
+};
+
+/**
+ * Update blip in place, with new version. Fades out old content, replace, and
+ * fades in new content.
+ *
+ * @param {!Object} data A client action object containing DOM selector of the
+ * blip to update, its version for comparison and html content of the new
+ * state of the blip.
+ * @private
+ */
+wave.Rpc.prototype.updateBlipCallback_ = function(data) {
+ var blip = $(data.blipId);
+
+ // We already have this version.
+ if (this.dataView_.hasNewer(data, $(data.blipId))) {
+ return;
+ }
+
+ this.dataView_.replaceBlip(data.blipId, data.html);
+
+ // Remember this version so we ignore redundant updates.
+ blip.data('version', data.version);
+};
Property changes on: trunk/src/main/webapp/others/splash/js/rpc.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/js/rpc_test.js
===================================================================
--- trunk/src/main/webapp/others/splash/js/rpc_test.js (rev 0)
+++ trunk/src/main/webapp/others/splash/js/rpc_test.js 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,310 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * NOTE(dhanji): Edited for readability (temporary).
+ * @fileoverview Unit tests for rpc.js.
+ * @author dhanji(a)gmail.com (Dhanji R. Prasanna)
+ */
+
+function testMeasureCallback() {
+ var result;
+ var rpc = new wave.Rpc({
+ measure: function(html) {
+ result = html;
+ }
+ });
+
+ // Simulate data coming back from the server.
+ var expected = '<some_html>';
+ rpc.handleRpcResponse_([{
+ action: 'measure',
+ html: expected
+ }]);
+
+ assertEquals(expected, result);
+}
+
+
+function testUpdateWaveVersion() {
+ window = {};
+ window.waveOptions_ = {};
+ window.waveOptions_.waveId = 'aWaveId';
+
+ var rpc = new wave.Rpc({});
+
+ // Simulate data coming back from the server.
+ var expectedVersion = 1234567;
+ rpc.handleRpcResponse_([{
+ action: 'update-wave-version',
+ waveId: 'aWaveId',
+ version: expectedVersion
+ }]);
+
+ assertEquals(expectedVersion, window.waveOptions_.waveVersion);
+}
+
+
+function testUpdateWaveAppendsToConversation() {
+ window = {};
+ window.waveOptions_ = {};
+ window.waveOptions_.waveId = 'aWaveId';
+ window.waveOptions_.page = 1; // Forces append rather than replace.
+
+ var result;
+ var rpc = new wave.Rpc({
+ appendConversation: function(html) {
+ result = html;
+ }
+ });
+
+ // Simulate data coming back from the server.
+ var expectedVersion = 12345678;
+ var expectedHtml = '<some_html>';
+ rpc.handleRpcResponse_([{
+ action: 'update-wave',
+ waveId: 'aWaveId',
+ version: expectedVersion,
+ html: expectedHtml
+ }]);
+
+ // Ensure version was updated too.
+ assertEquals(expectedVersion, window.waveOptions_.waveVersion);
+ assertEquals(expectedHtml, result);
+}
+
+
+function testUpdateWaveInsertsConversationOnePage() {
+ window = {};
+ window.waveOptions_ = {};
+ window.waveOptions_.waveId = 'aWaveId';
+ window.waveOptions_.page = 0; // Forces replace conversation.
+
+ // Test on-wave opened callbacks too.
+ var embedApiSignaled = false, waveOpenCalled = false;
+ window.embedApi = {};
+ window.embedApi.loaded = function() {
+ embedApiSignaled = true;
+ };
+ window.wave.uiCallbacks_ = {};
+ window.wave.uiCallbacks_.waveOpened = function() {
+ waveOpenCalled = true;
+ };
+
+ var result;
+ var rpc = new wave.Rpc({
+ insertConversation: function(html) {
+ result = html;
+ return false; // Only one page exists.
+ }
+ });
+
+ // Simulate data coming back from the server.
+ var expectedVersion = 125678;
+ var expectedHtml = '<some_other_html_1>';
+ rpc.handleRpcResponse_([{
+ action: 'update-wave',
+ waveId: 'aWaveId',
+ version: expectedVersion,
+ html: expectedHtml
+ }]);
+
+ // Ensure version was updated too.
+ assertEquals(expectedVersion, window.waveOptions_.waveVersion);
+ assertEquals(expectedHtml, result);
+
+ // Page should not have advanced.
+ assertEquals(0, window.waveOptions_.page);
+
+ // Callbacks should fire.
+ assertTrue(embedApiSignaled);
+ assertTrue(waveOpenCalled);
+}
+
+
+function testUpdateWaveInsertsConversationManyPages() {
+ window = {};
+ window.waveOptions_ = {};
+ window.waveOptions_.waveId = 'aWaveId';
+ window.waveOptions_.page = 0; // Forces replace conversation.
+
+ // Mock Jquery ajax function
+ var ajaxPostData;
+ window.$ = {};
+ window.$.ajax = function(data) {
+ ajaxPostData = data;
+ };
+
+ var result;
+ var rpc = new wave.Rpc({
+ insertConversation: function(html) {
+ result = html;
+ return true; // Triggers load of additional page
+ }
+ });
+
+ // Simulate data coming back from the server.
+ var expectedVersion = 125678;
+ var expectedHtml = '<some_other_html>';
+ rpc.handleRpcResponse_([{
+ action: 'update-wave',
+ waveId: 'aWaveId',
+ version: expectedVersion,
+ html: expectedHtml
+ }]);
+
+ // Ensure version was updated too.
+ assertEquals(expectedVersion, window.waveOptions_.waveVersion);
+ assertEquals(expectedHtml, result);
+
+ // Page should have advanced
+ assertEquals(1, window.waveOptions_.page);
+
+ // Assert the right RPC was called for the second page
+ assertEquals(window.waveOptions_, ajaxPostData.data);
+ assertEquals('POST', ajaxPostData.type);
+}
+
+
+function testUpdateWaveHeader() {
+ window = {};
+ window.waveOptions_ = {};
+ window.waveOptions_.waveId = 'aWaveId';
+
+ var result;
+ var rpc = new wave.Rpc({
+ insertHeader: function(html) {
+ result = html;
+ }
+ });
+
+ // Simulate data coming back from the server.
+ var expected = '<some_header_html>';
+ rpc.handleRpcResponse_([{
+ action: 'update-header',
+ waveId: 'aWaveId',
+ html: expected
+ }]);
+
+ assertEquals(expected, result);
+}
+
+
+function testUpdateFeed() {
+ window = {};
+ window.wave.uiCallbacks_ = {};
+ var feedOpenCalled = false;
+ window.wave.uiCallbacks_.feedOpened = function() {
+ feedOpenCalled = true;
+ };
+
+ var result;
+ var rpc = new wave.Rpc({
+ insertFeed: function(html) {
+ result = html;
+ }
+ });
+
+ // Simulate data coming back from the server.
+ var expected = '<some_feed_html>';
+ rpc.handleRpcResponse_([{
+ action: 'update-feed',
+ html: expected
+ }]);
+
+ assertEquals(expected, result);
+ assertTrue(feedOpenCalled);
+}
+
+
+function testDeleteBlipOnNewerVersion() {
+ // Mock the jquery version discovery logic.
+ var expectedBlipId = 'aBlipId';
+ var expectedVersion = 7658;
+ $ = function(blipId) {
+ if (expectedBlipId = blipId) {
+ return {
+ data: function(arg) {
+ if ('version' == arg) {
+ expectedVersion - 1; /* -1 version should trigger a delete */
+ }
+ }
+ };
+ }
+ };
+
+ var toDelete;
+ var rpc = new wave.Rpc({
+ deleteBlip: function(blipId) {
+ toDelete = blipId;
+ },
+ hasNewer: function(data, blip) {
+ return false;
+ }
+ });
+
+ // Simulate data coming back from the server.
+ rpc.handleRpcResponse_([{
+ action: 'delete-blip',
+ blipId: 'aBlipId',
+ version: expectedVersion
+ }]);
+
+ assertEquals(expectedBlipId, toDelete);
+}
+
+
+function testUpdateBlip() {
+ var expectedBlipId = 'aBlipId';
+ var expectedHtml = '<a_replaced_blip>';
+ var expectedVersion = 128973;
+
+ var updatedVersion;
+ $ = function() {
+ return {
+ data: function(arg, version) {
+ if ('version' == arg) {
+ updatedVersion = version;
+ }
+ }
+ };
+ };
+
+ var replacedBlipId;
+ var replacedHtml;
+ var rpc = new wave.Rpc({
+ replaceBlip: function(blipId, html) {
+ replacedBlipId = blipId;
+ replacedHtml = html;
+ },
+ hasNewer: function(data, blip) {
+ return false;
+ }
+ });
+
+ // Simulate data coming back from the server.
+ rpc.handleRpcResponse_([{
+ action: 'update-blip',
+ blipId: 'aBlipId',
+ html: expectedHtml,
+ version: expectedVersion
+ }]);
+
+ assertEquals(expectedVersion, updatedVersion);
+ assertEquals(expectedBlipId, replacedBlipId);
+ assertEquals(expectedHtml, replacedHtml);
+}
Property changes on: trunk/src/main/webapp/others/splash/js/rpc_test.js
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/mobile_client.html
===================================================================
--- trunk/src/main/webapp/others/splash/mobile_client.html (rev 0)
+++ trunk/src/main/webapp/others/splash/mobile_client.html 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <title>Google Wave Splash v1.1</title>
+ <link rel="stylesheet" href="style/main.css">
+ <link rel="stylesheet" href="style/mobile.css">
+ <link rel="stylesheet" type="text/css" href="style/jquery.lightbox-0.5.css" media="screen">
+
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
+ <script type="text/javascript" src="js/jquery.lightbox-0.5.min.js"></script>
+ <script type="text/javascript"
+ src="http://wave.google.com/gadgets/js/core:rpc.js?debug=1&c=1"></script>
+
+ <!-- [MINIFY] -->
+ <script type="text/javascript" src="js/editor.js"></script>
+ <script type="text/javascript" src="js/gadget.js"></script>
+ <script type="text/javascript" src="js/rpc.js"></script>
+ <script type="text/javascript" src="js/common_client.js"></script>
+ <script type="text/javascript" src="js/mobile_client.js"></script>
+ <!-- [END_MINIFY] -->
+ <script type="text/javascript">
+ var BOOTSTRAP = {
+ 'email': '@{email}',
+ 'displayName': '@{displayName}'
+ };
+ </script>
+ <meta name="viewport" content="user-scalable=no" width="device-width" />
+</head>
+<body>
+
+<div id="header">
+ <div id="headerInner">
+ <table id="headerLayout" cellspacing="0" summary="">
+ <tr>
+ <td id="tdLogo">
+ <div id="logo"></div>
+ </td>
+ <td>
+ <div class="mobile-button">
+ <a href="#"><span id="main-button">New Wave</span></a>
+ </div>
+ </td>
+
+ <td id="tdSearchToggle" style="vertical-align:bottom;">
+ <img id="searchToggle" src="images/search_small_button.png" />
+ </td>
+ <td id="td-logout">
+ <div class="mobile-button">
+ <a id="logout" href="/logout">
+ <span>Sign out</span>
+ </a>
+ </div>
+ </td></tr>
+ </table>
+ </div>
+ <!-- /#headerInner" -->
+
+ <div id="headerSearch">
+ <table id="search" cellspacing="0" summary="">
+ <tr>
+ <td>
+ <input id="searchField" name="searchField" value="Search your waves"/>
+ </td>
+ <td id="searchButton">
+ <span><span>Go</span></span>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <!-- /#headerSearch" -->
+
+<!-- /#header -->
+
+</div>
+
+<div id="content">
+ <div id="wave" class="wave-window">
+ <div class="header" style="display:none"></div>
+ <div id="conversation"></div>
+ </div>
+
+ <div id="feed" class="feed">
+
+ <div id="loading-wrapper">
+ <img id="feed-loading" src="images/loading.gif" alt="Loading feed contents...">
+ </div>
+
+ <div id="more-feed" class="more-button">Show More...</div>
+ </div>
+</div>
+
+</body>
+</html>
Property changes on: trunk/src/main/webapp/others/splash/mobile_client.html
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/permalink_client.html
===================================================================
--- trunk/src/main/webapp/others/splash/permalink_client.html (rev 0)
+++ trunk/src/main/webapp/others/splash/permalink_client.html 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <title>Google Wave Splash</title>
+ <!-- TODO: FIX THE PATHS BEFORE CHECKING IN -->
+ <link rel="stylesheet" type="text/css" href="@{pathToRoot}style/permalink.css">
+
+ <!--[if lte IE 7]>
+ <link rel="stylesheet" type="text/css" href="@{pathToRoot}style/permalink_ie.css">
+ <![endif]-->
+
+ <style type="text/css" media="screen">@{style}</style>
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
+ <script type="text/javascript" src="@{pathToRoot}js/jquery.lightbox-0.5.min.js"></script>
+
+ <!-- [MINIFY] -->
+ <!-- please preserve this order: gadgets, rpc, permalink_client -->
+ <script type="text/javascript" src="@{pathToRoot}js/gadget.js"></script>
+ <script type="text/javascript" src="@{pathToRoot}js/rpc.js"></script>
+ <script type="text/javascript" src="@{pathToRoot}js/common_client.js"></script>
+ <script type="text/javascript" src="@{pathToRoot}js/permalink_client.js"></script>
+ <!-- [END_MINIFY] -->
+
+ <script type="text/javascript" src="http://wave.google.com/gadgets/js/core:rpc.js?c=1"></script>
+
+ @if{embedded}
+ <script type="text/javascript" src="@{pathToRoot}js/embed_support.js"></script>
+ @end{}
+
+ <!--[if IE 6]>
+ <script type="text/javascript" src="@{pathToRoot}/js/ie6sucks.js"></script>
+ <![endif]-->
+</head>
+<body@if{embedded} class="embedded"@end{}>
+<div id="wave" class="wave-window" wave_id="@{waveId}"
+ show_header="@{showHeader}">
+@if{embedded}
+ <div id="share-popup" class="popup">
+ <div class="popup-pointer"></div>
+ <a class="dialog-close" href="#"><span>Close</span></a>
+ <label for="share-popup-link">Copy this link:</label><div class="input-wrapper"><input id="share-popup-link" type="text" value="@{waveLink}"></div>
+ <div class="separator"><em>OR</em></div>
+ <label for="share-popup-embed">Paste this HTML to embed:</label><div class="input-wrapper"><input id="share-popup-embed" type="text" value="@{waveEmbed}"></div>
+ <div id="share-popup-wave-id">ID: @{waveId}</div>
+ </div>
+ <div id="frame">
+ <div id="header">
+ <div id="headerInner">
+ <div id="logo">
+ Google Wave
+ </div>
+ <ul id="menu">
+ <li class="first">
+ Anonymous
+ </li>
+ @if{showLoginLink}
+ <li>
+ <a href="@{waveLink}" target="_blank">View in Google Wave</a>
+ </li>
+ @end{}
+ <li id="shareLink">
+ <a id="share-link" href="#">Share this wave</a>
+ </li>
+ </ul>
+ <div id="participants">
+ <h3>Participants:</h3>
+ <div id="wave-header"><span style="font-weight:normal;">Loading...</span></div>
+ </div>
+ </div> <!-- /#headerInner -->
+ </div> <!-- /#header -->
+ <div id="content">
+ <div id="contentInner">
+ <div id="contentInner2">
+ <div id="contentInner3" class="styleable">
+@end{}
+ <div id="conversation">
+ @if{content == ''}
+ <img id="wave-loading" src="@{pathToRoot}images/loading_permalink.gif" alt="Loading...">
+ @end{}
+ @{content}
+ </div>
+@if{embedded}
+ </div> <!-- /#contentInner3 -->
+ </div> <!-- /#contentInner2 -->
+ </div> <!-- /#contentInner -->
+ </div> <!-- /#content -->
+ </div> <!-- /#frame -->
+@end{}
+</div>
+</body>
+</html>
Property changes on: trunk/src/main/webapp/others/splash/permalink_client.html
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/rpc_relay.html
===================================================================
--- trunk/src/main/webapp/others/splash/rpc_relay.html (rev 0)
+++ trunk/src/main/webapp/others/splash/rpc_relay.html 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,3 @@
+<script>
+var u = location.href, h = u.substr(u.indexOf('#') + 1).split('&'), t, r;try {t = h[0] === '..' ? parent.parent : parent.frames[h[0]];r = t.gadgets.rpc.receive;} catch (e) {}r && r(h);
+</script>
Property changes on: trunk/src/main/webapp/others/splash/rpc_relay.html
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/style/border-radius.htc
===================================================================
--- trunk/src/main/webapp/others/splash/style/border-radius.htc (rev 0)
+++ trunk/src/main/webapp/others/splash/style/border-radius.htc 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,143 @@
+--Do not remove this if you are using--
+Original Author: Remiz Rahnas
+Original Author URL: http://www.htmlremix.com
+Published date: 2008/09/24
+
+Changes by Nick Fetchak:
+- IE8 standards mode compatibility
+- VML elements now positioned behind original box rather than inside of it - should be less prone to breakage
+Published date : 2009/11/18
+
+
+<public:attach event="oncontentready" onevent="oncontentready('v08vnSVo78t4JfjH')" />
+<script type="text/javascript">
+
+// findPos() borrowed from http://www.quirksmode.org/js/findpos.html
+function findPos(obj) {
+ var curleft = curtop = 0;
+
+ if (obj.offsetParent) {
+ do {
+ curleft += obj.offsetLeft;
+ curtop += obj.offsetTop;
+ } while (obj = obj.offsetParent);
+ }
+
+ return({
+ 'x': curleft,
+ 'y': curtop
+ });
+}
+
+function oncontentready(classID) {
+ if (this.className.match(classID)) { return(false); }
+
+ if (!document.namespaces.v) { document.namespaces.add("v", "urn:schemas-microsoft-com:vml"); }
+
+ this.className = this.className.concat(' ', classID);
+ var arcSize = Math.min(parseInt(this.currentStyle['-moz-border-radius'] ||
+ this.currentStyle['-webkit-border-radius'] ||
+ this.currentStyle['border-radius'] ||
+ this.currentStyle['-khtml-border-radius']) /
+ Math.min(this.offsetWidth, this.offsetHeight), 1);
+ var fillColor = this.currentStyle.backgroundColor;
+ var fillSrc = this.currentStyle.backgroundImage.replace(/^url\("(.+)"\)$/, '$1');
+ var strokeColor = this.currentStyle.borderColor;
+ var strokeWeight = parseInt(this.currentStyle.borderWidth);
+ var stroked = 'true';
+ if (isNaN(strokeWeight)) {
+ strokeWeight = 0;
+ strokeColor = fillColor;
+ stroked = 'false';
+ }
+
+ this.style.background = 'transparent';
+ this.style.borderColor = 'transparent';
+
+ // Find which element provides position:relative for the target element (default to BODY)
+ var el = this;
+ var limit = 100, i = 0;
+ while ((typeof(el) != 'unknown') && (el.currentStyle.position != 'relative') && (el.tagName != 'BODY')) {
+ el = el.parentElement;
+ i++;
+ if (i >= limit) { return(false); }
+ }
+ var el_zindex = parseInt(el.currentStyle.zIndex);
+ if (isNaN(el_zindex)) { el_zindex = 0; }
+ //alert('got tag '+ el.tagName +' with pos '+ el.currentStyle.position);
+
+ var rect_size = {
+ 'width': this.offsetWidth - strokeWeight,
+ 'height': this.offsetHeight - strokeWeight
+ };
+ var el_pos = findPos(el);
+ var this_pos = findPos(this);
+ this_pos.y = this_pos.y + (0.5 * strokeWeight) - el_pos.y;
+ this_pos.x = this_pos.x + (0.5 * strokeWeight) - el_pos.x;
+
+ var rect = document.createElement('v:roundrect');
+ rect.arcsize = arcSize +'px';
+ rect.strokecolor = strokeColor;
+ rect.strokeWeight = strokeWeight +'px';
+ rect.stroked = stroked;
+ rect.style.display = 'block';
+ rect.style.position = 'absolute';
+ rect.style.top = this_pos.y +'px';
+ rect.style.left = this_pos.x +'px';
+ rect.style.width = rect_size.width +'px';
+ rect.style.height = rect_size.height +'px';
+ rect.style.antialias = true;
+ rect.style.zIndex = el_zindex - 1;
+
+ var fill = document.createElement('v:fill');
+ fill.color = fillColor;
+ fill.src = fillSrc;
+ fill.type = 'tile';
+
+ rect.appendChild(fill);
+ el.appendChild(rect);
+
+ var css = el.document.createStyleSheet();
+ css.addRule("v\\:roundrect", "behavior: url(#default#VML)");
+ css.addRule("v\\:fill", "behavior: url(#default#VML)");
+
+ isIE6 = /msie|MSIE 6/.test(navigator.userAgent);
+ // IE6 doesn't support transparent borders, use padding to offset original element
+ if (isIE6 && (strokeWeight > 0)) {
+ this.style.borderStyle = 'none';
+ this.style.paddingTop = parseInt(this.currentStyle.paddingTop || 0) + strokeWeight;
+ this.style.paddingBottom = parseInt(this.currentStyle.paddingBottom || 0) + strokeWeight;
+ }
+
+ if (typeof(window.rounded_elements) == 'undefined') {
+ window.rounded_elements = new Array();
+
+ if (typeof(window.onresize) == 'function') { window.previous_onresize = window.onresize; }
+ window.onresize = window_resize;
+ }
+ this.element.vml = rect;
+ window.rounded_elements.push(this.element);
+}
+
+function window_resize() {
+ if (typeof(window.rounded_elements) == 'undefined') { return(false); }
+
+ for (var i in window.rounded_elements) {
+ var el = window.rounded_elements[i];
+
+ var strokeWeight = parseInt(el.currentStyle.borderWidth);
+ if (isNaN(strokeWeight)) { strokeWeight = 0; }
+
+ var parent_pos = findPos(el.vml.parentNode);
+ var pos = findPos(el);
+ pos.y = pos.y + (0.5 * strokeWeight) - parent_pos.y;
+ pos.x = pos.x + (0.5 * strokeWeight) - parent_pos.x;
+
+ el.vml.style.top = pos.y +'px';
+ el.vml.style.left = pos.x +'px';
+ }
+
+ if (typeof(window.previous_onresize) == 'function') { window.previous_onresize(); }
+}
+</script>
+
Property changes on: trunk/src/main/webapp/others/splash/style/border-radius.htc
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/main/webapp/others/splash/style/jquery.lightbox-0.5.css
===================================================================
--- trunk/src/main/webapp/others/splash/style/jquery.lightbox-0.5.css (rev 0)
+++ trunk/src/main/webapp/others/splash/style/jquery.lightbox-0.5.css 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,112 @@
+/**
+ * jQuery lightBox plugin
+ * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/)
+ * and adapted to me for use like a plugin from jQuery.
+ * @name jquery-lightbox-0.5.css
+ * @author Leandro Vieira Pinho - http://leandrovieira.com
+ * @version 0.5
+ * @date April 11, 2008
+ * @category jQuery plugin
+ * @copyright (c) 2008 Leandro Vieira Pinho (leandrovieira.com)
+ * @license CC Attribution-No Derivative Works 2.5 Brazil - http://creativecommons.org/licenses/by-nd/2.5/br/deed.en_US
+ * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin
+ */
+#jquery-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 90;
+ width: 100%;
+ height: 500px;
+}
+#jquery-lightbox {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ z-index: 100;
+ text-align: center;
+ line-height: 0;
+}
+#jquery-lightbox a img {
+ border: none;
+}
+#lightbox-container-image-box {
+ position: relative;
+ background-color: #fff;
+ width: 250px;
+ height: 250px;
+ margin: 0 auto;
+}
+
+#lightbox-container-image {
+ padding: 10px;
+}
+#lightbox-loading {
+ position: absolute;
+ top: 40%;
+ left: 0%;
+ height: 25%;
+ width: 100%;
+ text-align: center;
+ line-height: 0;
+}
+#lightbox-nav {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ z-index: 10;
+}
+#lightbox-container-image-box>#lightbox-nav {
+ left: 0;
+}
+#lightbox-nav a {
+ outline: none;
+}
+#lightbox-nav-btnPrev,#lightbox-nav-btnNext {
+ width: 49%;
+ height: 100%;
+ zoom: 1;
+ display: block;
+}
+#lightbox-nav-btnPrev {
+ left: 0;
+ float: left;
+}
+#lightbox-nav-btnNext {
+ right: 0;
+ float: right;
+}
+#lightbox-container-image-data-box {
+ font: 10px Verdana, Helvetica, sans-serif;
+ background-color: #fff;
+ margin: 0 auto;
+ line-height: 1.4em;
+ overflow: auto;
+ width: 100%;
+ padding: 0 10px 0;
+}
+#lightbox-container-image-data {
+ padding: 0 10px;
+ color: #666;
+}
+#lightbox-container-image-data #lightbox-image-details {
+ width: 70%;
+ float: left;
+ text-align: left;
+}
+#lightbox-image-details-caption {
+ font-weight: bold;
+}
+#lightbox-image-details-currentNumber {
+ display: block;
+ clear: left;
+ padding-bottom: 1.0em;
+}
+#lightbox-secNav-btnClose {
+ width: 66px;
+ float: right;
+ padding-bottom: 0.7em;
+}
\ No newline at end of file
Property changes on: trunk/src/main/webapp/others/splash/style/jquery.lightbox-0.5.css
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/style/main.css
===================================================================
--- trunk/src/main/webapp/others/splash/style/main.css (rev 0)
+++ trunk/src/main/webapp/others/splash/style/main.css 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,236 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/* GENERAL ------------------------------------------------------------------ */
+
+/* Zero default margin & padding around common elements */
+body, dd, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, li, ol, p, ul {
+ margin: 0;
+ border: 0 none #FFFFFF;
+ padding: 0;
+}
+
+body {
+ overflow: hidden; /** HACK(dhanji): HEEEEELP! Horiz Scrollbar of doom **/
+ background-color: #ffffff;
+ color: #000000;
+ line-height: 1.4;
+ font-family: Helvetica, Arial, sans-serif;
+ font-size: 12px;
+}
+
+a {
+ color: #0066CC;
+ text-decoration: underline;
+}
+
+a:visited {
+ color: #0066CC;
+}
+
+a:hover {
+ text-decoration: none;
+}
+
+img {
+ border: 0 none transparent;
+}
+
+input, select, table, textarea {
+ font-size: 100%;
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+/* MAIN --------------------------------------------------------------------- */
+
+#header {
+ position: relative;
+ z-index: 2;
+ background-color: #202020;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#4c4c4c), to(#191919));
+ background-image: -moz-linear-gradient(top, #4c4c4c, #191919);
+ -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.35);
+ -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.35);
+}
+
+#headerInner {
+ height: 70px;
+ border-right: 0 none #ffffff;
+}
+
+#headerLayout {
+ width: 100%;
+}
+
+#headerLayout td {
+ padding: 0;
+ vertical-align: top;
+}
+
+#headerSearch {
+ width: 100%;
+ padding: 0 10px 0 0 !important;
+}
+
+h1 {
+ float: left;
+ width: 180px;
+ height: 43px;
+ margin: 6px 10px 0 10px;
+ background-image: url(../images/logo_on_black.png);
+ background-repeat: no-repeat;
+}
+
+h1 a {
+ display: block;
+ text-indent: -9999px;
+ text-decoration: none;
+}
+
+#td-logo {
+ width: 77px;
+}
+
+.button a {
+ display: block;
+ margin: 22px 7px 0 0;
+ border: 1px solid #191919;
+ border-radius: 3px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ color: #ffffff;
+ white-space: nowrap;
+ text-decoration: none;
+}
+
+.button a span {
+ display: block;
+ height: 23px;
+ border-top: 1px solid #7f7f7f;
+ border-left: 1px solid #7f7f7f;
+ border-radius: 3px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ padding: 0 7px 0 7px;
+ background-color: #333333;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#666666), to(#333333));
+ background-image: -moz-linear-gradient(top, #666666, #333333);
+ line-height: 24px;
+ text-align: center;
+}
+
+#search {
+ width: 100%;
+ height: 25px;
+ margin: 2px 0 0 0px;
+ background-image: url(../images/search_field_on_black_left.png);
+ background-repeat: no-repeat;
+}
+
+td.headerAlert {
+ width: 100%;
+}
+
+/** Alert bar **/
+div.highlight {
+ float: right;
+ overflow: hidden;
+ margin: 20px 36px 0 0;
+
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-top: 1px solid #000;
+ border-bottom: 1px solid #cecece;
+}
+
+#alert {
+ float: left;
+ font-size: 1.1em;
+ display: none;
+
+ padding: 3px 16px 2px 16px; /*border: 1px solid #000;*/
+ cursor: pointer;
+
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+
+ background-color: #eede54;
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0.0, #f5eca1), color-stop(1.0, #eede54));
+}
+
+#measure {
+ position: absolute;
+ color: #aaa;
+ right: 10px;
+ bottom: 2px;
+}
+
+#search td {
+ width: 100%;
+ padding: 0 0 0 20px;
+}
+
+#search input {
+ display: block;
+ height: 25px;
+ width: 100%;
+ margin: 0;
+ border: 0 none #ffffff;
+ padding: 0 0 0 4px;
+ outline: 0 none #ffffff;
+ background-color: #ffffff;
+ background-image: url(../images/search_field_on_black.png);
+ color: #999999;
+ line-height: 26px;
+}
+
+#search input.clicked {
+ color: #000000;
+}
+
+#search #searchButton {
+ width: auto;
+ padding: 0 0 0 2px;
+ background-repeat: no-repeat;
+ color: #ffffff;
+ cursor: pointer;
+}
+
+#searchButton span {
+ display: block;
+ height: 25px;
+ padding: 0 12px 0 0;
+ background-image: url(../images/search_field_on_black_button_right.png);
+ background-repeat: no-repeat;
+ background-position: 100% 0;
+ line-height: 26px;
+}
+
+#searchButton span span {
+ padding: 0 4px 0 11px;
+ background-image: url(../images/search_field_on_black_button.png);
+ background-repeat: repeat-x;
+}
+
+#content {
+ z-index: 1;
+ left: 0;
+ right: 0;
+ top: 70px;
+ bottom: 0;
+ overflow: auto;
+}
Property changes on: trunk/src/main/webapp/others/splash/style/main.css
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/style/mobile.css
===================================================================
--- trunk/src/main/webapp/others/splash/style/mobile.css (rev 0)
+++ trunk/src/main/webapp/others/splash/style/mobile.css 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,361 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/** Alternate stylesheet for android, iphone + mobile browsers **/
+
+body {
+ font-family: Arial, sans-serif;
+ font-size: 10pt;
+}
+
+a img input {
+ -webkit-tap-highlight-color: rgba(0,0,0,0);
+}
+
+#logo {
+ background-image: url(../images/logo_small.png);
+ float: left;
+ height: 43px;
+ margin: 6px 10px;
+ width: 77px;
+}
+
+.feed {
+ position: absolute;
+ background: #b5b9c2;
+ margin: 0;
+ width: 100%;
+ overflow: auto;
+}
+
+.feed .item {
+ overflow: hidden;
+ padding: 7px 7px 10px 7px;
+ border-bottom: 1px solid #999;
+ background: white;
+ position: relative;
+ cursor: pointer;
+}
+
+.feed .read {
+ background: #eaeaea !important;
+}
+
+.feed .item img.icon {
+ float: left;
+ padding-right: 6px;
+ padding-left: 6px;
+}
+
+.feed .item .title {
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ background: #C9E2FC;
+ font-weight: bold;
+ padding: 2px 6px;
+}
+
+.feed .item .time {
+ color: #9a9a9a;
+ float: right;
+ text-align: right;
+ font-weight: bold;
+ font-size: 75%;
+ padding: 4px 6px 0px 0px;
+}
+
+.read > .time {
+ color: #999;
+}
+
+.feed .item .avatar {
+ border: 3px solid #ccc;
+ border-radius: 3px 3px;
+ -moz-border-radius: 3px 3px;
+ float: left;
+ margin: 0 5px 2px 0;
+}
+
+.avatar img {
+ width: 32px;
+ height: 32px;
+ border: 1px solid #fff;
+}
+
+.messages {
+ border-radius: 3px 3px;
+ -moz-border-radius: 3px 3px;
+ background: #bdbdbd;
+ color: #fff;
+ font-size: 70%;
+ font-weight: bold;
+ margin: 3px 3px 3px 0px;
+ padding: 2px 4px 0px 4px;
+ float:right;
+}
+
+/** wave **/
+
+#conversation {
+ padding: 24px 6px06px 6px;
+}
+
+#conversation .blip {
+ position: relative;
+ right: 0;
+ overflow: hidden;
+ padding: 8px 0;
+ margin-top: -8px;
+}
+
+#conversation .blip:first-child {
+ border: none;
+}
+
+#conversation .blip div.left {
+ width: 95%;
+}
+
+#conversation .blip .authorbar {
+ float: left;
+ margin: 10px 5px 0px 3px;
+
+ background: #e5e5e5;
+
+ padding: 3px 4px;
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+#conversation .blip .author {
+ float: right;
+ padding: 2px 6px;
+
+ font-weight: bold;
+ text-shadow: -1px -1px 1px #555;
+ color: white;
+}
+
+#conversation .blip .author {
+ width: 100%;
+}
+
+#conversation .blip .author img {
+ float: left;
+ height: 32px;
+ width: 32px;
+}
+
+#conversation .blip .author .name {
+ float: right;
+}
+
+.author-more {
+ float: right;
+ clear: both;
+}
+
+.author-count-1 {
+ min-height: 24px;
+}
+
+.author-count-2 {
+ min-height: 45px;
+}
+
+.author-count-3 {
+ min-height: 136px;
+}
+
+.author-count-many {
+ min-height: 55px;
+}
+
+#conversation .blip div.left .toolbar {
+ display: none;
+ position: absolute;
+ margin: 16px 12px 0 0;
+ padding: 2px 4px 0 4px;
+ right: 0;
+
+ background: #fff;
+ -webkit-border-radius: 4px;
+ -webkit-box-shadow: 2px 2px 4px #111;
+ -moz-border-radius: 4px;
+ -moz-box-shadow: 2px 2px 4px #111;
+}
+
+.indent {
+ padding-left: 40px;
+}
+
+.unread {
+ background: #7aa2f2 !important;
+ color: #eee !important;
+}
+
+#conversation .blip div.right {
+ float: left;
+ width: 95%;
+ padding: 12px 12px 24px 12px;
+ margin: 0 auto;
+
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+
+ -webkit-box-shadow: 2px 2px 8px #000;
+ -moz-box-shadow: 2px 2px 8px #000;
+ background: white;
+}
+
+#conversation .blip div.right .time {
+ float: right;
+ font-size: 94%;
+ color: #999;
+}
+
+div.wave-window {
+ right: 0;
+ overflow: auto;
+ width: 100%;
+ height: 100%;
+ /*margin: 2px 0; *//** TODO:gradient for moz/IE **/
+ background-image: url('../images/background_dot.png');
+}
+
+.header {
+ background-color: #dfe3eb;
+
+ padding: 16px 12px 16px 24px;
+ margin: 0 auto;
+
+ -webkit-box-shadow: 2px 2px 8px #000;
+ -moz-box-shadow: 2px 2px 8px #000;
+}
+
+/** markup in text**/
+span.title {
+ font-weight: bold;
+}
+
+.avatar img {
+ width: 32px;
+ height: 32px;
+}
+
+.avatar .name {
+ margin: 0 5px;
+}
+
+.mobile-button a {
+ float: left;
+ margin: 22px 7px 0 0;
+ border: 1px solid #191919;
+ border-radius: 3px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ color: #ffffff;
+ white-space: nowrap;
+ text-decoration: none;
+}
+
+.mobile-button a span {
+ display: block;
+ height: 23px;
+ border-top: 1px solid #7f7f7f;
+ border-left: 1px solid #7f7f7f;
+ border-radius: 3px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ padding: 0 7px 0 7px;
+ background-color: #333333;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#666666), to(#333333));
+ background-image: -moz-linear-gradient(top, #666666, #333333);
+ line-height: 24px;
+}
+
+.more-button {
+ margin: 8px auto;
+ width: 100px;
+
+ color: #333;
+ padding: 4px 14px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+
+ background: #EDEDED;
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0.0, #FFF),
+ color-stop(0.7, #FEFEFE), color-stop(1.0, #EDEDED));
+}
+
+/** TODO(dhanji): Clean this up later when we reconcile stuff and main.css for all clients **/
+#search-container {
+ background-color: #202020;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#4c4c4c), to(#191919));
+ background-image: -moz-linear-gradient(top, #4c4c4c, #191919);
+ -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.35);
+ -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.35);
+}
+
+#search {
+ width: 200px;
+}
+
+#headerSearch {
+ display: none;
+ margin: -15px auto 0px;
+ padding: 10px 0px !important;
+ width: 200px;
+}
+
+#tdSearchToggle {
+ text-align: center;
+}
+
+#td-logout {
+ padding: 10px 0px 0px 0px;
+ text-align: right;
+}
+
+#td-logout .mobile-button {
+float:right;
+}
+
+#logout {
+ color: #fff;
+ text-decoration: none;
+}
+
+#logout span {
+ background-color: #111111;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#333333), to(#111111));
+ background-image: -moz-linear-gradient(top, #333333, #111111);
+}
+
+
+#loading-wrapper {
+ position: relative;
+ text-align: center;
+}
+
+#feed-loading, #wave-loading {
+ margin: 30px auto 0px auto;
+ text-align: center;
+}
Property changes on: trunk/src/main/webapp/others/splash/style/mobile.css
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/style/orig-style.css
===================================================================
--- trunk/src/main/webapp/others/splash/style/orig-style.css (rev 0)
+++ trunk/src/main/webapp/others/splash/style/orig-style.css 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,417 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+.header .title {
+ float: left;
+}
+
+.control-icon {
+ float: right;
+ width: 14px;
+ margin-left: 6px;
+ cursor: pointer;
+ cursor: hand;
+}
+
+.wnd-min {
+ background-image: url('../images/minimize_window.png')
+}
+
+.wnd-close {
+ background-image: url('../images/close_window.png')
+}
+
+.conversation {
+ padding: 24px 6px 206px 6px;
+}
+
+.conversation .blip {
+ position: relative;
+ right: 0;
+ overflow: hidden;
+ padding: 8px 0;
+ margin-top: -8px;
+}
+
+.conversation .blip:first-child {
+ border: none;
+}
+
+.conversation .blip div.left {
+ float: left;
+ width: 20%;
+}
+
+.conversation .blip .authorbar {
+ float: right;
+ margin: 12px 0 0 0;
+
+ background: #333;
+
+ padding: 3px 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.conversation .blip .author {
+ float: right;
+ padding: 2px 6px;
+
+ font-weight: bold;
+ text-shadow: -1px -1px 1px #555;
+ color: white;
+}
+
+.conversation .blip .author {
+ width: 100%;
+}
+
+.conversation .blip .author img {
+ float: left;
+ height: 32px;
+ width: 32px;
+}
+
+.conversation .blip .author .name {
+ float: right;
+}
+
+.author-more {
+ float: right;
+ clear: both;
+}
+
+.author-count-1 {
+ min-height: 24px;
+}
+
+.author-count-2 {
+ min-height: 84px;
+}
+
+.author-count-3 {
+ min-height: 136px;
+}
+
+.author-count-many {
+ min-height: 136px;
+}
+
+.conversation .blip div.left .toolbar {
+ display: none;
+ position: absolute;
+ margin: 16px 12px 0 0;
+ padding: 2px 4px 0 4px;
+ right: 0;
+
+ background: #fff;
+ -webkit-border-radius: 4px;
+ -webkit-box-shadow: 2px 2px 4px #111;
+ -moz-border-radius: 4px;
+ -moz-box-shadow: 2px 2px 4px #111;
+}
+
+.indent {
+ padding-left: 40px;
+}
+
+.unread {
+ background: #7aa2f2 !important;
+ color: #eee !important;
+}
+
+.conversation .blip div.right {
+ float: left;
+ width: 74%;
+
+ padding: 12px 12px 24px 12px;
+ margin: 0 auto;
+
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+
+ -webkit-box-shadow: 2px 2px 8px #000;
+ -moz-box-shadow: 2px 2px 8px #000;
+
+ background: white;
+}
+
+.conversation .blip div.right .time {
+ float: right;
+ font-size: 94%;
+ color: #999;
+}
+/** markup in text**/
+span.title {
+ font-weight: bold;
+}
+
+/** an unused button **/
+.more-button {
+ margin: 4px auto;
+
+ width: 120px;
+
+ cursor: pointer;
+ cursor: hand;
+
+ font-size: 11px;
+ color: #777;
+ padding: 4px 14px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+
+ background: #EDEDED;
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0.0, #FFF),
+ color-stop(0.7, #FEFEFE), color-stop(1.0, #EDEDED));
+}
+
+.more-button:hover {
+ background: #DEDEDE;
+}
+
+/*** Picture thumbnail embedded in blip **/
+.picture {
+ display: block;
+ width: 260px;
+ height: 180px;
+ border: 1px solid #999;
+ padding: 2px;
+ -webkit-border-radius: 2px;
+}
+
+/** offset the text a bit from the checkbox **/
+div.todo span {
+ padding-left: 6px;
+}
+
+div.todo div.due {
+ padding: 8px 18px;
+ float: right;
+ border-left: 1px solid #DDD;
+ margin: -4px 0;
+
+ color: #AAA;
+ font-size: 9px;
+}
+
+/*** search related stuff **/
+
+.blue {
+ color: white; /**background: rgb(142, 193, 255); **/
+ -webkit-box-shadow: none !important;
+
+}
+
+.orange {
+ color: white; /**background: rgb(142, 193, 255); **/
+ -webkit-box-shadow: none !important;
+
+ background: -webkit-gradient(linear, left top, left bottom,
+ from(rgb(255, 187, 83)), to(rgb(255, 167, 63)));
+}
+
+
+#zoomframe {
+ display: none;
+ position: absolute;
+ z-index: 2;
+
+ border: 1px solid #fff;
+}
+
+/** separate from zoomframe so we can assign different opacity **/
+#zoomframe div {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: #000;
+ opacity: 0.2;
+}
+
+.feed .item {
+ overflow: hidden;
+ padding: 14px 10px 18px 10px;
+ border-bottom: 1px solid #999;
+ background: white;
+
+ cursor: pointer;
+}
+
+.feed .item:hover {
+ background: #cacaca !important;
+}
+
+.feed .read {
+ background: #eaeaea !important;
+}
+
+.feed .item img.icon {
+ float: left;
+ padding-right: 6px;
+ padding-left: 6px;
+}
+
+.feed .item .title {
+ font-weight: bold;
+ margin-left: 45px;
+ padding-bottom: 2px;
+}
+
+.read > .title {
+ color: #777;
+}
+
+.feed .item .snippet {
+ margin-left: 45px;
+}
+
+.read > .snippet {
+ color: #999;
+}
+
+.feed .item .snippet .tid {
+ font-style: italic;
+ padding-right: 4px;
+}
+
+.feed .item .time {
+ float: right;
+ text-align: right;
+ font-weight: bold;
+}
+
+.read > .time {
+ color: #999;
+}
+
+.messages {
+ font-weight: normal;
+}
+
+.feed .item .avatar {
+ border: 3px solid #ccc;
+ border-radius: 3px 3px;
+ -moz-border-radius: 3px 3px;
+ float: left;
+ margin: 0 5px 2px 0;
+}
+
+.avatar > img {
+ width: 32px;
+ height: 32px;
+ border: 1px solid #fff;
+}
+
+/** a pulse animation **/
+@-webkit-keyframes pulse {
+ from {
+ -webkit-transform: scale(1.0);
+ }
+ 35% {
+ -webkit-transform: scale(1.10);
+ }
+ 65% {
+ -webkit-transform: scale(1.00);
+ }
+ 90% {
+ -webkit-transform: scale(1.02);
+ }
+ to {
+ -webkit-transform: scale(1.0);
+ }
+}
+
+/** this is how you add the pulse anim */
+.anim-pulse {
+ -webkit-animation-name: pulse;
+ -webkit-animation-duration: 0.4s;
+ -webkit-animation-iteration-count: 1;
+}
+
+.editor {
+ border: 1px solid green;
+ min-height: 40px;
+}
+
+.header {
+ background-color: #dfe3eb;
+
+ padding: 16px 12px 16px 24px;
+ margin: 0 auto;
+
+ -webkit-box-shadow: 2px 2px 8px #000;
+ -moz-box-shadow: 2px 2px 8px #000;
+}
+
+#headerLayout td.control-bar {
+ vertical-align: middle;
+ color: #ccc
+}
+
+.control-bar a {
+ color: #ccc;
+}
+
+.control-bar a:hover {
+ color: #ccc;
+ text-decoration: underline;
+}
+
+.participants {
+ overflow: hidden;
+ height: 18px;
+}
+
+.participants > .avatar > img {
+ width: 16px;
+ height: 16px;
+ margin-bottom: -4px;
+}
+
+.participants > .avatar > .name {
+ margin: 0 5px;
+}
+
+.unknown-element {
+ color: #999;
+ font-weight: bold;
+ border: 1px solid #C9E2FC;
+ padding-left: 2px;
+ padding-right: 2px;
+}
+
+.attachment-element {
+ border: 1px solid #C9E2FC;
+ width: auto;
+ font-weight: normal;
+ text-align: center;
+ margin: 2px;
+ display: inline-block;
+}
+
+.attachment-element img {
+ max-width: 128px;
+ max-height: 128px;
+}
+
+.caption {
+ text-align: center;
+}
Property changes on: trunk/src/main/webapp/others/splash/style/orig-style.css
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/style/permalink.css
===================================================================
--- trunk/src/main/webapp/others/splash/style/permalink.css (rev 0)
+++ trunk/src/main/webapp/others/splash/style/permalink.css 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,582 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/** Alternate stylesheet for permalink, embed and gmail integration waves **/
+
+/* Zero default margin & padding around common elements */
+blockquote, body, dd, dl, dt, fieldset, form, h1, h2, h3, h4, h5, h6, li, ol, p, ul
+{
+ margin: 0;
+ border: 0 none #FFFFFF;
+ padding: 0;
+}
+
+body {
+ background-color: #e5e5e5;
+ font-family: Arial, sans-serif;
+ font-size: 85%;
+ line-height: 1.3;
+}
+
+body.embedded {
+ background-color: transparent;
+}
+
+.wave-window {
+ width: 100%;
+ overflow: hidden;
+}
+
+a {
+ color: #003ea8;
+}
+
+
+
+
+/* HEADER ========================================= */
+
+#header
+{
+ border: 1px solid #C9E2FC;
+ border-right: 1px solid #AEC6DF;
+ -webkit-border-top-left-radius: 7px;
+ -webkit-border-top-right-radius: 7px;
+ -moz-border-radius-topleft: 7px;
+ -moz-border-radius-topright: 7px;
+ border-top-left-radius: 7px;
+ border-top-right-radius: 7px;
+ background-color: #C9E2FC;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#E6F0FB), to(#C9E2FC));
+ background-image: -moz-linear-gradient(top, #E6F0FB, #C9E2FC);
+ text-align: left;
+}
+
+#headerInner
+{
+ overflow: hidden;
+ border-top: 1px solid #ECF5FE;
+ border-left: 1px solid #ECF5FE;
+ -webkit-border-top-left-radius: 7px;
+ -webkit-border-top-right-radius: 7px;
+ -moz-border-radius-topleft: 7px;
+ -moz-border-radius-topright: 7px;
+ border-top-left-radius: 7px;
+ border-top-right-radius: 7px;
+ padding: 8px 10px 4px 5px;
+ line-height: 18px;
+}
+
+* html #headerInner
+{
+ overflow: visible;
+ height: 1px;
+}
+
+#logo
+{
+ float: left;
+ width: 98px;
+ height: 23px;
+ overflow: hidden;
+ background-image: url(../images/logo.png);
+ background-repeat: no-repeat;
+ text-indent: -9999px;
+}
+
+* html #logo
+{
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../images/logo.png", sizingMethod="crop");
+}
+
+#menu
+{
+ float: right;
+ white-space: nowrap;
+}
+
+#menu li
+{
+ display: inline;
+ float: left;
+ margin-left: 7px;
+ border-left: 1px solid #93ABC3;
+ padding-left: 7px;
+ font-weight: bold;
+ text-shadow: 1px 1px 0 rgba(255,255,255,0.75);
+}
+
+#menu li.first
+{
+ margin-left: 0;
+ border-left: 0 none #ffffff;
+ padding-left: 0;
+}
+
+#menu li a
+{
+ font-weight: normal;
+}
+
+#shareLink {
+ padding-left: 25px !important;
+ background-image: url(../images/share_icon.png);
+ background-repeat: no-repeat;
+ background-position: 5px 50%;
+ color: #003ea8;
+}
+
+* html #shareLink {
+ padding-left: 7px !important;
+ background-image: none;
+}
+
+#shareLink:visited {
+ color: #003ea8;
+}
+
+#participants
+{
+ clear: both;
+ padding: 0.4em 0 0 0;
+ font-weight: bold;
+ text-shadow: 1px 1px 0 rgba(255,255,255,0.75);
+}
+
+* html #participants
+{
+ height: 1px;
+}
+
+#participants h3
+{
+ float: left;
+ padding-right: 0.5em;
+ font-size: 100%;
+}
+
+#participants .avatar {
+ margin: 0;
+}
+
+#participants .avatar img {
+ display: none;
+}
+
+#participants .avatar .name {
+ display: inline;
+ height: auto;
+ padding: 0;
+ line-height: 1;
+ text-shadow: 1px 1px 0 rgba(255,255,255,0.75);
+ font-weight: normal;
+}
+
+#participants .punctuation {
+ margin-left: -0.2em;
+ margin-right: 0.1em;
+}
+
+.popup {
+ display: none;
+ position: absolute;
+ z-index: 999;
+ border: 1px solid #aec6df;
+ -webkit-border-radius: 7px;
+ -moz-border-radius: 7px;
+ border-radius: 7px;
+ padding: 12px;
+ background: #ffffff;
+ color: #b2b2b2;
+ -webkit-box-shadow: 5px 5px 10px rgba(0,0,0,0.2);
+ -moz-box-shadow: 5px 5px 10px rgba(0,0,0,0.2);
+ box-shadow: 5px 5px 10px rgba(0,0,0,0.2);
+}
+
+#share-popup {
+ right: 1.2em;
+ top: 2.8em;
+ width: 290px;
+}
+
+#inline-reply-popup {
+ width: 490px;
+ height: 50%;
+ overflow: auto;
+}
+
+.popup-pointer {
+ position: absolute;
+ right: 3em;
+ top: -10px;
+ width: 19px;
+ height: 10px;
+ background-image: url(../images/dialog_pointer.gif);
+ background-repeat: no-repeat;
+}
+
+.dialog-close {
+ position: absolute;
+ right: 8px;
+ top: 8px;
+ z-index: 100;
+ border: 1px solid #aec6df;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.dialog-close:hover {
+ border-color: #9fb5cc;
+ background-color: #c9d9ea;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#c9d9ea));
+ background-image: -moz-linear-gradient(top, #ffffff, #c9d9ea);
+}
+
+.dialog-close.down {
+ background-color: #aec6df;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#c9d9ea), to(#ffffff));
+ background-image: -moz-linear-gradient(top, #c9d9ea, #ffffff);
+}
+
+.dialog-close span {
+ display: block;
+ width: 9px;
+ height: 9px;
+ padding: 3px;
+ overflow: hidden;
+ background-image: url(../images/dialog_close.gif);
+ background-repeat: no-repeat;
+ background-position: 3px 3px;
+ text-indent: -9999px;
+}
+
+#share-popup h3 {
+ color: #738699;
+ font-weight: normal;
+ font-size: 135%;
+}
+
+#share-popup .separator {
+ margin: 1.7em 0 0.5em 0;
+ text-align: center;
+ border-top: 1px solid #dddddd;
+}
+
+#share-popup .separator em {
+ position: relative;
+ top: -0.7em;
+ padding: 0 0.5em;
+ background-color: #ffffff;
+ font-style: normal;
+}
+
+#share-popup label {
+ display: block;
+ margin: 0 0 0.3em 0;
+ color: #000000;
+}
+
+.input-wrapper {
+ margin-right: 10px;
+ overflow: visible;
+}
+
+#share-popup input {
+ border: 1px solid #666666;
+ background: #eee;
+ padding: 3px 4px;
+ width: 100%;
+ font-size: 100%;
+}
+
+#share-popup-wave-id {
+ margin-top: 1.4em;
+}
+
+
+
+
+/* CONTENT ========================================= */
+
+#content
+{
+ border-left: 1px solid #C9E2FC;
+ border-right: 1px solid #AEC6DF;
+ border-bottom: 1px solid #AEC6DF;
+ -webkit-border-bottom-left-radius: 7px;
+ -webkit-border-bottom-right-radius: 7px;
+ -moz-border-radius-bottomleft: 7px;
+ -moz-border-radius-bottomright: 7px;
+ border-bottom-left-radius: 7px;
+ border-bottom-right-radius: 7px;
+}
+
+#contentInner
+{
+ border-left: 1px solid #ECF5FE;
+ border-right: 3px solid #C9E2FC;
+ border-bottom: 3px solid #C9E2FC;
+ -webkit-border-bottom-left-radius: 5px;
+ -webkit-border-bottom-right-radius: 5px;
+ -moz-border-radius-bottomleft: 5px;
+ -moz-border-radius-bottomright: 5px;
+ border-bottom-left-radius: 5px;
+ border-bottom-right-radius: 5px;
+}
+
+#contentInner2
+{
+ border-left: 3px solid #C9E2FC;
+ border-right: 1px solid #ECF5FE;
+ border-bottom: 1px solid #ECF5FE;
+}
+
+#contentInner3
+{
+ position: relative; /* Required for IE weirdness because of relatively positioned avatar imgs */
+ height: 200px;
+ overflow: auto;
+ border-top: 1px solid #AEC6DF;
+ border-right: 1px solid #C9E2FC;
+ border-bottom: 1px solid #C9E2FC;
+ border-left: 1px solid #AEC6DF;
+}
+
+#conversation {
+ max-width: 60em;
+ overflow: hidden;
+ margin: 0 auto;
+ padding: 12px 24px 12px 24px;
+ background-color: #ffffff;
+ -webkit-box-shadow: 0 0 24px rgba(0,0,0,0.15);
+ -moz-box-shadow: 0 0 24px rgba(0,0,0,0.15);
+ box-shadow: 0 0 24px rgba(0,0,0,0.15);
+}
+
+#frame #conversation {
+ max-width: none;
+ padding: 12px;
+ background-color: transparent;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+.blip {
+ clear: both;
+ overflow: hidden;
+ border-top: 1px dashed #cccccc;
+ padding: 0.8em 0 1em 0;
+}
+
+* html .blip {
+ position: relative;
+ overflow: visible;
+ height: 1px;
+}
+
+.blip:first-child {
+ border-top: 0 none #ffffff;
+ padding-top: 0;
+}
+
+.indent .blip:first-child {
+ border-top: 1px dashed #cccccc;
+ padding-top: 0.8em;
+}
+
+.blip .left {
+ float: left;
+ width: 10em;
+}
+
+.blip .avatar {
+ margin: 0 0 4px 28px;
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-bottomright: 4px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ padding: 0 0.5em 0 0;
+/*
+ background-color: #e5e5e5;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eeeeee), to(#cccccc));
+ background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
+*/
+ color: #738699;
+ font-weight: bold;
+}
+
+.avatar img {
+ position: relative;
+ left: -28px;
+ float: left;
+ width: 20px;
+ height: 20px;
+ border: 1px solid #cccccc;
+ margin-right: -22px;
+}
+
+.avatar .name {
+ display: block;
+ width: 100%;
+ height: 22px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ line-height: 22px;
+ text-shadow: 1px 1px 0 #ffffff;
+}
+
+#conversation .blip .left .toolbar {
+ display: none;
+ position: absolute;
+ margin: 16px 12px 0 0;
+ padding: 2px 4px 0 4px;
+ right: 0;
+
+ background: #fff;
+ -webkit-border-radius: 4px;
+ -webkit-box-shadow: 2px 2px 4px #999;
+ -moz-border-radius: 4px;
+ -moz-box-shadow: 2px 2px 4px #999;
+}
+
+.indent {
+ margin: 0 0 1.3em 6em;
+ overflow: hidden;
+ padding-left: 1em;
+ border-left: 1px solid #cccccc;
+ border-bottom: 1px solid #cccccc;
+ -webkit-border-bottom-left-radius: 8px;
+ -moz-border-radius-bottomleft: 8px;
+ border-bottom-left-radius: 8px;
+ -webkit-box-shadow: -4px 4px 8px rgba(0,0,0,0.13);
+ -moz-box-shadow: -4px 4px 8px rgba(0,0,0,0.13);
+ box-shadow: -4px 4px 8px rgba(0,0,0,0.13);
+}
+
+.unread {
+ background: #7aa2f2 !important;
+ color: #eee !important;
+}
+
+#conversation .blip .right {
+ margin-left: 11em;
+}
+
+* html #conversation .blip .right {
+ height: 1px; /* Fixes 3px jog bug in IE6 */
+}
+
+#conversation .blip .right-inner {
+ width: 100%;
+ overflow: hidden;
+}
+
+#conversation .blip .right .time {
+ float: right;
+ margin: 0 0 0 1em;
+ color: #7f7f7f;
+}
+
+#conversation .content {
+ margin: 0.15em 0 0 0;
+}
+
+/** markup in text**/
+span.title {
+ font-weight: bold;
+}
+
+.content img {
+ max-width: 100%;
+}
+
+/** Inline replies styling **/
+.inline-reply {
+ display: inline;
+}
+
+.inline-reply .count {
+ position: relative;
+ top: -2px;
+ padding-left: 10px;
+ background-image: url(../images/inline_reply_arrow.gif);
+ background-repeat: no-repeat;
+ background-position: 2px 5px;
+}
+
+.inline-reply .expanded {
+ background-image: url(../images/inline_reply_arrow_expanded.gif);
+ background-position: 0 6px;
+}
+
+.inline-reply .count-inner {
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ border: 1px solid #5C8B09;
+ background: #99bb00;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#99bb00), to(#5C8B09));
+ background-image: -moz-linear-gradient(top, #99bb00, #5C8B09);
+ padding: 1px 7px;
+ color: #ffffff;
+ font-weight: bold;
+ font-size: 85%;
+ cursor: pointer;
+ cursor: hand;
+}
+
+.inline-reply .pointer {
+ display: none;
+ position: absolute;
+ width: 19px;
+ height: 10px;
+ right: 3px;
+ bottom: -15px;
+ background-image: url(../images/inline_reply_pointer.gif);
+ background-repeat: no-repeat;
+}
+
+.inline-reply .expanded .pointer {
+ display: inline;
+}
+
+.inline-reply-content {
+ display: inline;
+}
+
+#purgatory .inline-reply-content {
+ display: none;
+}
+
+.inline-reply-content-inner {
+ margin: 11px 5px 1.4em 5px;
+ border: 1px solid #cccccc;
+ -webkit-border-radius: 7px;
+ -moz-border-radius: 7px;
+ border-radius: 7px;
+ padding: 12px;
+ -webkit-box-shadow: 0 0 5px rgba(0,0,0,0.2);
+ -moz-box-shadow: 0 0 5px rgba(0,0,0,0.2);
+ box-shadow: 0 0 5px rgba(0,0,0,0.2);
+ font-weight: normal;
+}
+
Property changes on: trunk/src/main/webapp/others/splash/style/permalink.css
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/style/permalink_ie.css
===================================================================
--- trunk/src/main/webapp/others/splash/style/permalink_ie.css (rev 0)
+++ trunk/src/main/webapp/others/splash/style/permalink_ie.css 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,23 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/* HEADER ========================================= */
+
+
+
+
+/* CONTENT ========================================= */
+
Property changes on: trunk/src/main/webapp/others/splash/style/permalink_ie.css
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/style/stuff.css
===================================================================
--- trunk/src/main/webapp/others/splash/style/stuff.css (rev 0)
+++ trunk/src/main/webapp/others/splash/style/stuff.css 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,448 @@
+/**
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+body {
+ font-family: Arial, sans-serif;
+ font-size: 10pt;
+ background-color: #CCC;
+}
+
+.invisible {
+ display: none;
+}
+
+#content {
+ overflow: hidden;
+}
+
+#feed-loading {
+ display: block;
+ background: transparent;
+ margin: 0 auto 0 auto;
+ padding-top: 30px;
+}
+
+#wave-loading {
+ display: block;
+ background: transparent;
+ margin: 0 auto 0 auto;
+ padding-top: 20px;
+}
+
+.header .title {
+ float: left;
+}
+
+#conversation {
+ padding: 24px 24px 206px 12px;
+}
+
+#conversation .blip {
+ position: relative;
+ right: 0;
+ overflow: hidden;
+ padding: 8px 0;
+ margin-top: -8px;
+}
+
+#conversation .blip:first-child {
+ border: none;
+}
+
+#conversation .blip div.left {
+ float: left;
+ width: 18%;
+ margin-top: 7px;
+}
+
+#conversation .blip .authorbar {
+ margin: 2px 0 0 0;
+
+ background: #333;
+
+ padding: 3px 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+#wave-not-found {
+ text-align: center;
+ margin: 0 auto;
+ padding: 12px 12px 12px 12px;
+ width: 80%;
+ background: #fff;
+ -webkit-border-radius: 4px;
+ -webkit-box-shadow: 2px 2px 4px #111;
+ -moz-border-radius: 4px;
+ -moz-box-shadow: 2px 2px 4px #111;
+}
+
+.blip .content {
+ padding: 0px 12px 24px 42px;
+ clear: both;
+}
+
+.blip .time {
+ padding: 12px 12px 0 12px;
+ float: right;
+ font-size: 16px;
+ font-style: italic;
+}
+
+.author-more {
+}
+
+.author-count-1 {
+ min-height: 24px;
+}
+
+.author-count-2 {
+ min-height: 84px;
+}
+
+.author-count-3 {
+ min-height: 136px;
+}
+
+.author-count-many {
+ min-height: 136px;
+}
+
+#conversation .blip div.left .toolbar {
+ display: none;
+ position: absolute;
+ margin: 2px 12px 0 0;
+ padding: 2px 4px 0 4px;
+ right: 0;
+
+ background: #fff;
+ -webkit-border-radius: 4px;
+ -webkit-box-shadow: 2px 2px 4px #111;
+ -moz-border-radius: 4px;
+ -moz-box-shadow: 2px 2px 4px #111;
+}
+
+.indent {
+ padding-left: 40px;
+}
+
+.unread {
+ background: #7aa2f2 !important;
+ color: #eee !important;
+}
+
+#conversation .blip div.right {
+ float: left;
+ width: 82%;
+
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+
+ -webkit-box-shadow: 2px 2px 8px #000;
+ -moz-box-shadow: 2px 2px 8px #000;
+ background: white;
+}
+
+#conversation .blip div.right .time {
+ float: right;
+ font-size: 94%;
+ color: #999;
+}
+
+div.wave-window {
+ position: absolute;
+ right: 0;
+ overflow: auto;
+ width: 70%;
+ height: 100%;
+
+ /*margin: 2px 0; *//** TODO:gradient for moz/IE **/
+ background-image: url('../images/background_dot.png');
+}
+
+/** markup in text**/
+span.title {
+ font-weight: bold;
+}
+
+/** an unused button **/
+.more-button {
+ margin: 4px auto;
+
+ width: 120px;
+
+ cursor: pointer;
+ cursor: hand;
+
+ font-size: 11px;
+ color: #777;
+ padding: 4px 14px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+
+ background: #EDEDED;
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0.0, #FFF),
+ color-stop(0.7, #FEFEFE), color-stop(1.0, #EDEDED));
+}
+
+.more-button:hover {
+ background: #DEDEDE;
+}
+
+/*** Picture thumbnail embedded in blip **/
+.picture {
+ display: block;
+ width: 260px;
+ height: 180px;
+ border: 1px solid #999;
+ padding: 2px;
+ -webkit-border-radius: 2px;
+}
+
+/** offset the text a bit from the checkbox **/
+div.todo span {
+ padding-left: 6px;
+}
+
+div.todo div.due {
+ padding: 8px 18px;
+ float: right;
+ border-left: 1px solid #DDD;
+ margin: -4px 0;
+
+ color: #AAA;
+ font-size: 9px;
+}
+
+/*** search related stuff **/
+
+.blue {
+ color: white; /**background: rgb(142, 193, 255); **/
+ -webkit-box-shadow: none !important;
+
+}
+
+.orange {
+ color: white; /**background: rgb(142, 193, 255); **/
+ -webkit-box-shadow: none !important;
+
+ background: -webkit-gradient(linear, left top, left bottom,
+ from(rgb(255, 187, 83)), to(rgb(255, 167, 63)));
+}
+
+.feed-container {
+ position: absolute;
+ background: #b5b9c2;
+ margin: 0;
+ width: 30%;
+ height: 100%;
+}
+
+.feed {
+ background: #b5b9c2;
+
+ margin: 0;
+ width: 100%;
+ height: 97%;
+ overflow: auto;
+}
+
+.feed .item {
+ overflow: hidden;
+ padding: 14px 10px 18px 10px;
+ border-bottom: 1px solid #999;
+ background: white;
+
+ cursor: pointer;
+}
+
+.feed .item:hover {
+ background: #cacaca !important;
+}
+
+.feed .read {
+ background: #eaeaea !important;
+}
+
+.feed .item img.icon {
+ float: left;
+ padding-right: 6px;
+ padding-left: 6px;
+}
+
+.feed .item .title {
+ font-weight: bold;
+ margin-left: 45px;
+ padding-bottom: 2px;
+}
+
+.read > .title {
+ color: #777;
+}
+
+.feed .item .snippet {
+ margin-left: 45px;
+}
+
+.read > .snippet {
+ color: #999;
+}
+
+.feed .item .snippet .tid {
+ font-style: italic;
+ padding-right: 4px;
+}
+
+.feed .item .time {
+ float: right;
+ text-align: right;
+ font-weight: bold;
+}
+
+.read .time {
+ color: #999;
+}
+
+.messages {
+ font-weight: normal;
+}
+
+.feed .item .avatar {
+ border: 3px solid #ccc;
+ border-radius: 3px 3px;
+ -moz-border-radius: 3px 3px;
+ float: left;
+ margin: 0 5px 2px 0;
+}
+
+.feed .avatar img {
+ width: 32px;
+ height: 32px;
+ border: 1px solid #fff;
+}
+
+/** a pulse animation **/
+@-webkit-keyframes pulse {
+ from {
+ -webkit-transform: scale(1.0);
+ }
+ 35% {
+ -webkit-transform: scale(1.10);
+ }
+ 65% {
+ -webkit-transform: scale(1.00);
+ }
+ 90% {
+ -webkit-transform: scale(1.02);
+ }
+ to {
+ -webkit-transform: scale(1.0);
+ }
+}
+
+/** this is how you add the pulse anim */
+.anim-pulse {
+ -webkit-animation-name: pulse;
+ -webkit-animation-duration: 0.4s;
+ -webkit-animation-iteration-count: 1;
+}
+
+.editor {
+ border: 1px solid green;
+ min-height: 40px;
+}
+
+.header {
+ background-color: #dfe3eb;
+ padding: 8px 12px 8px 12px;
+ margin: 0 auto;
+ -webkit-box-shadow: 2px 2px 8px #000;
+ -moz-box-shadow: 2px 2px 8px #000;
+}
+
+#headerLayout td.control-bar {
+ vertical-align: middle;
+ color: #ccc
+}
+
+.control-bar a {
+ color: #ccc;
+}
+
+.control-bar a:hover {
+ color: #ccc;
+ text-decoration: underline;
+}
+
+.participants {
+ overflow: hidden;
+ height: 18px;
+ vertical-align: middle;
+}
+
+.participants .avatar {
+ float: left;
+ margin-bottom: 4px;
+}
+
+.blip .authorbar {
+ color: white;
+}
+
+.avatar {
+ white-space: nowrap;
+}
+
+.avatar img {
+ width: 33px;
+ height: 33px;
+ border: 1px solid #ccc;
+}
+
+.avatar .name {
+ margin: 0 5px;
+ vertical-align: top;
+}
+
+.unknown-element {
+ color: #999;
+ font-weight: bold;
+ border: 1px solid #C9E2FC;
+ padding-left: 2px;
+ padding-right: 2px;
+}
+
+.attachment-element {
+ border: 1px solid #C9E2FC;
+ width: auto;
+ font-weight: normal;
+ text-align: center;
+ margin: 2px;
+ display: inline-block;
+}
+
+.attachment-element img {
+ max-width: 128px;
+ max-height: 128px;
+}
+
+.caption {
+ text-align: center;
+}
Property changes on: trunk/src/main/webapp/others/splash/style/stuff.css
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:mime-type
+ text/plain
Added: trunk/src/main/webapp/others/splash/wave_not_found.html.fragment
===================================================================
--- trunk/src/main/webapp/others/splash/wave_not_found.html.fragment (rev 0)
+++ trunk/src/main/webapp/others/splash/wave_not_found.html.fragment 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,3 @@
+<div id="wave-not-found">
+ Sorry! There was a problem loading this wave.
+</div>
Modified: trunk/src/test/java/cc/kune/wave/server/KuneWaveManagerDefaultTest.java
===================================================================
--- trunk/src/test/java/cc/kune/wave/server/KuneWaveManagerDefaultTest.java 2011-07-01 01:37:33 UTC (rev 1438)
+++ trunk/src/test/java/cc/kune/wave/server/KuneWaveManagerDefaultTest.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -52,16 +52,14 @@
@Test
public void addGadget() throws DefaultException, IOException {
doLogin();
- final WaveRef waveletName = manager.createWave(TITLE, MESSAGE,
- participantUtils.of(getSiteAdminShortName()));
+ final WaveRef waveletName = createTestWave();
assertNotNull(waveletName);
manager.addGadget(waveletName, getSiteAdminShortName(), TEST_GADGET);
}
private void addParticipant(final String whoAdds) throws IOException {
doLogin();
- final WaveRef waveletName = manager.createWave(TITLE, MESSAGE,
- participantUtils.of(getSiteAdminShortName()));
+ final WaveRef waveletName = createTestWave();
assertNotNull(waveletName);
manager.addParticipant(waveletName, getSiteAdminShortName(), whoAdds, NEW_PARTICIPANT);
final Wavelet fetchWavelet = manager.fetchWavelet(waveletName, getSiteAdminShortName());
@@ -83,6 +81,10 @@
}
+ private WaveRef createTestWave() {
+ return manager.createWave(TITLE, MESSAGE, participantUtils.of(getSiteAdminShortName()));
+ }
+
@Test
public void createWave() throws DefaultException, IOException {
doLogin();
@@ -107,8 +109,7 @@
@Test
public void createWaveWithTitle() throws DefaultException, IOException {
doLogin();
- final WaveRef waveletName = manager.createWave(TITLE, MESSAGE,
- participantUtils.of(getSiteAdminShortName()));
+ final WaveRef waveletName = createTestWave();
assertNotNull(waveletName);
final Wavelet fetchWavelet = manager.fetchWavelet(waveletName, getSiteAdminShortName());
assertNotNull(fetchWavelet);
@@ -123,10 +124,16 @@
}
@Test
+ public void renderWave() throws DefaultException, IOException {
+ doLogin();
+ final WaveRef waveletName = createTestWave();
+ assertNotNull(manager.render(waveletName, getSiteAdminShortName()));
+ }
+
+ @Test
public void setTitle() throws DefaultException, IOException {
doLogin();
- final WaveRef waveletName = manager.createWave(TITLE, MESSAGE,
- participantUtils.of(getSiteAdminShortName()));
+ final WaveRef waveletName = createTestWave();
assertNotNull(waveletName);
manager.setTitle(waveletName, TITLENEW, getSiteAdminShortName());
final Wavelet fetchWavelet = manager.fetchWavelet(waveletName, getSiteAdminShortName());
Added: trunk/src/test/java/cc/kune/wave/server/KuneWaveMarkupTests.java
===================================================================
--- trunk/src/test/java/cc/kune/wave/server/KuneWaveMarkupTests.java (rev 0)
+++ trunk/src/test/java/cc/kune/wave/server/KuneWaveMarkupTests.java 2011-07-01 11:27:50 UTC (rev 1439)
@@ -0,0 +1,34 @@
+package cc.kune.wave.server;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.waveprotocol.wave.model.document.util.XmlStringBuilder;
+
+import cc.kune.core.server.manager.impl.ContentConstants;
+
+import com.google.wave.api.Markup;
+
+public class KuneWaveMarkupTests {
+
+ private static final String FOO_MARKUP = "<b>Foo</b><br/>";
+
+ @Test
+ public void testMarkup() {
+ final Markup markup = Markup.of(FOO_MARKUP);
+ assertNotNull(markup.getMarkup());
+ assertNotNull(markup.getText());
+ assertNotNull(markup.getText().contains("\n"));
+ }
+
+ @Test
+ public void testXmlStringBuilderOfMarkup() {
+ XmlStringBuilder builder = XmlStringBuilder.createFromXmlString(FOO_MARKUP);
+ assertTrue(builder.getLength() > 0);
+ builder = XmlStringBuilder.createFromXmlString(ContentConstants.INITIAL_CONTENT);
+ assertTrue(builder.getLength() > 0);
+ builder = XmlStringBuilder.createFromXmlString(ContentConstants.WELCOME_WAVE_CONTENT);
+ assertTrue(builder.getLength() > 0);
+ }
+}
Property changes on: trunk/src/test/java/cc/kune/wave/server/KuneWaveMarkupTests.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
1
0
Author: ecarrerasg
Date: 2011-07-01 03:37:33 +0200 (Fri, 01 Jul 2011)
New Revision: 1438
Modified:
donate/src/cc/kune/sandbox/donate/client/ButtonsPanel.java
donate/src/cc/kune/sandbox/donate/client/DonateConstants.java
donate/src/cc/kune/sandbox/donate/client/DonateConstants.properties
Log:
Fixed some links
Modified: donate/src/cc/kune/sandbox/donate/client/ButtonsPanel.java
===================================================================
--- donate/src/cc/kune/sandbox/donate/client/ButtonsPanel.java 2011-07-01 01:02:17 UTC (rev 1437)
+++ donate/src/cc/kune/sandbox/donate/client/ButtonsPanel.java 2011-07-01 01:37:33 UTC (rev 1438)
@@ -14,6 +14,8 @@
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
+import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;
public class ButtonsPanel extends Composite {
DonateMessages donateMessages = (DonateMessages) GWT.create(DonateMessages.class);
@@ -83,8 +85,19 @@
tbOtherValue.setText("");
}
}
- });
+ });
+ panelForm.addSubmitHandler(new SubmitHandler() {
+ public void onSubmit(SubmitEvent event)
+ {
+ String sActualValue = tbOtherValue.getText();
+ if(sActualValue.isEmpty() || sActualValue.equals(donateMessages.otherValue()))
+ {
+ event.cancel();
+ }
+ }
+ });
+
tbOtherValue.addBlurHandler(new BlurHandler() {
public void onBlur(BlurEvent event) {
String sActualValue = tbOtherValue.getText();
@@ -247,30 +260,39 @@
String sEqual = "=";
String sAnd = "&";
String sLink = "";
+
sLink += donateConstants.paypal_url();
sLink +=donateConstants.param1()+sEqual;
sLink +=donateConstants.valueParam1()+sAnd;
- sLink +=donateConstants.param2()+sEqual;
- sLink +=donateConstants.valueParam2()+sAnd;
sLink +=donateConstants.param3()+sEqual;
sLink +=donateConstants.valueParam3()+sAnd;
sLink +=donateConstants.param4()+sEqual;
- sLink +=donateConstants.valueParam4()+sAnd;
- sLink +=donateConstants.param5()+sEqual;
- sLink +=donateConstants.valueParam5()+sAnd;
- sLink +=donateConstants.param6()+sEqual;
- sLink +=donateConstants.valueParam6()+sAnd;
- sLink +=donateConstants.param7()+sEqual;
- sLink +=donateConstants.valueParam7()+sAnd;
- sLink +=donateConstants.param8()+sEqual;
- sLink +=donateConstants.valueParam8()+sAnd;
+ sLink +=sCurrency+sAnd;
sLink +=donateConstants.param9()+sEqual;
sLink +=donateConstants.valueParam9()+sAnd;
- sLink +=donateConstants.param10()+sEqual;
- sLink +=donateConstants.valueParam10()+sAnd;
- sLink +=donateConstants.param11()+sEqual;
- sLink +=donateConstants.valueParam11()+sAnd;
- sLink +=donateConstants.paypal_param_a3()+sEqual;
+ sLink +=donateConstants.param2()+sEqual;
+ if(iType == 2) //Only for regular donations
+ {
+ sLink +=donateConstants.valueParam2()+sAnd;
+ sLink +=donateConstants.param5()+sEqual;
+ sLink +=donateConstants.valueParam5()+sAnd;
+ sLink +=donateConstants.param6()+sEqual;
+ sLink +=donateConstants.valueParam6()+sAnd;
+ sLink +=donateConstants.param7()+sEqual;
+ sLink +=donateConstants.valueParam7()+sAnd;
+ sLink +=donateConstants.param8()+sEqual;
+ sLink +=donateConstants.valueParam8()+sAnd;
+ sLink +=donateConstants.param10()+sEqual;
+ sLink +=donateConstants.valueParam10()+sAnd;
+ sLink +=donateConstants.param11()+sEqual;
+ sLink +=donateConstants.valueParam11()+sAnd;
+ sLink +=donateConstants.paypal_param_a3()+sEqual;
+ }else
+ {
+ sLink +=donateConstants.valueParam2_single()+sAnd;
+ sLink +=donateConstants.paypal_param_amount()+sEqual;
+ }
+
sLink +=sValue;
return sLink;
Modified: donate/src/cc/kune/sandbox/donate/client/DonateConstants.java
===================================================================
--- donate/src/cc/kune/sandbox/donate/client/DonateConstants.java 2011-07-01 01:02:17 UTC (rev 1437)
+++ donate/src/cc/kune/sandbox/donate/client/DonateConstants.java 2011-07-01 01:37:33 UTC (rev 1438)
@@ -17,10 +17,12 @@
String single_donations();
String paypal_url();
String paypal_param_a3();
+ String paypal_param_amount();
String param1();
String valueParam1();
String param2();
String valueParam2();
+ String valueParam2_single();
String param3();
String valueParam3();
String param4();
Modified: donate/src/cc/kune/sandbox/donate/client/DonateConstants.properties
===================================================================
--- donate/src/cc/kune/sandbox/donate/client/DonateConstants.properties 2011-07-01 01:02:17 UTC (rev 1437)
+++ donate/src/cc/kune/sandbox/donate/client/DonateConstants.properties 2011-07-01 01:37:33 UTC (rev 1438)
@@ -13,11 +13,13 @@
paypal_url = https\u003A\u002F\u002Fwww.paypal.com\u002Fcgi-bin\u002Fwebscr\u003F
paypal_param_a3 = a3
+paypal_param_amount = amount
param1 = business
-valueParam1 = donate\u0040ourproject\u002Eorg
+valueParam1 = donate\u0040ourproject\u002Eorg
param2 = cmd
valueParam2 =\u005Fxclick\u002Dsubscriptions
-param3 = item_name
+valueParam2_single = \u005Fdonations
+param3 = item_name
valueParam3 = Donate to comunes\u002Eorg
param4 = currency\u005Fcode
valueParam4 =
1
0