Example #1
0
 @Override
 public void onWaveletAdded(ObservableWavelet wavelet) {
   String id = ModernIdSerialiser.INSTANCE.serialiseWaveletId(wavelet.getId());
   if (channels.containsKey(id)) {
     connect(id);
   } else {
     // This will trigger the onOperationChannelCreated callback below.
     mux.createOperationChannel(wavelet.getId(), wavelet.getCreatorId());
   }
 }
Example #2
0
  @Override
  public void onOperationChannelCreated(
      OperationChannel channel, ObservableWaveletData snapshot, Accessibility accessibility) {
    WaveletId wid = snapshot.getWaveletId();
    String id = ModernIdSerialiser.INSTANCE.serialiseWaveletId(wid);

    Preconditions.checkState(!channels.containsKey(id));
    channels.put(id, channel);

    if (wave.getWavelet(wid) != null) {
      connect(id);
    } else {
      // This will trigger the onWaveletAdded callback above.
      wave.addWavelet(operationalizer.operationalize(snapshot));
    }
  }
Example #3
0
  public void computeKeySignalType(
      Result result,
      String typeName,
      int keyCode,
      int which,
      String keyIdentifier,
      boolean metaKey,
      boolean ctrlKey,
      boolean altKey,
      boolean shiftKey) {

    boolean ret = true;

    int typeInt;
    if ("keydown".equals(typeName)) {
      typeInt = Event.ONKEYDOWN;
    } else if ("keypress".equals(typeName)) {
      typeInt = Event.ONKEYPRESS;
    } else if ("keyup".equals(typeName)) {
      result.type = null;
      return;
    } else {
      throw new AssertionError("Non-key-event passed to computeKeySignalType");
    }

    KeySignalType type;

    int computedKeyCode = which != 0 ? which : keyCode;

    if (computedKeyCode == 10) {
      computedKeyCode = KeyCodes.KEY_ENTER;
    }

    // For non-firefox browsers, we only get keydown events for IME, no keypress
    boolean isIME = computedKeyCode == IME_CODE;

    boolean commandKey = commandIsCtrl ? ctrlKey : metaKey;

    // Some trace logging very useful to debug
    EditorStaticDeps.logger
        .trace()
        .log(
            "KEY SIGNAL IN PROCESS identifier = "
                + keyIdentifier
                + " code = "
                + computedKeyCode
                + " type = "
                + (typeInt == Event.ONKEYDOWN ? "KeyDown" : "KeyPress")
                + (ctrlKey ? " CTRL" : "")
                + (shiftKey ? " SHIFT" : "")
                + (altKey ? " ALT" : ""));

    switch (userAgent) {
      case WEBKIT:
        // This is a bit tricky because there are significant differences
        // between safari 3.0 and safari 3.1...

        // We could probably actually almost use the same code that we use for IE
        // for safari 3.1, because with 3.1 the webkit folks made a big shift to
        // get the events to be in line with IE for compatibility. 3.0 events
        // are a lot more similar to FF, but different enough to need special
        // handling. However, it seems that using more advanced features like
        // keyIdentifier for safaris is probably better and more future-proof,
        // as well as being compatible between the two, so for now we're not
        // using IE logic for safari 3.1

        // Weird special large keycode numbers for safari 3.0, where it gives
        // us keypress events (though they happen after the dom is changed,
        // for some things like delete. So not too useful). The number
        // 63200 is known as the cutoff mark.
        if (typeInt == Event.ONKEYDOWN && computedKeyCode > 63200) {
          result.type = null;
          return;
        } else if (typeInt == Event.ONKEYPRESS) {
          // Skip keypress for tab and escape, because they are the only non-input keys
          // that don't have keycodes above 63200. This is to prevent them from being treated
          // as INPUT in the || = keypress below. See (X) below
          if (computedKeyCode == KeyCodes.KEY_ESCAPE || computedKeyCode == KeyCodes.KEY_TAB) {
            result.type = null;
            return;
          }
        }

        // boolean isPossiblyCtrlInput = typeInt == Event.ONKEYDOWN && ret.getCtrlKey();
        boolean isActuallyCtrlInput = false;

        boolean startsWithUPlus = keyIdentifier != null && keyIdentifier.startsWith("U+");

        // Need to use identifier for the delete key because the keycode conflicts
        // with the keycode for the full stop.
        if (isIME) {
          // If is IME, override the logic below - we get keyIdentifiers for IME events,
          // but those are basically useless as the event is basically still an IME input
          // event (e.g. keyIdentifier might say "Up", but it's certainly not navigation,
          // it's just the user selecting from the IME dialog).
          type = KeySignalType.INPUT;
        } else if ((DELETE_KEY_IDENTIFIER.equals(keyIdentifier) && typeInt == Event.ONKEYDOWN)
            || computedKeyCode == KeyCodes.KEY_BACKSPACE) {
          // WAVE-407 Avoid missing the '.' char (KEYPRESS + CODE 46)
          // ensuring it's a KEYDOWN event with a DELETE_KEY_IDENTIFIER

          type = KeySignalType.DELETE;
        } else if (NAVIGATION_KEY_IDENTIFIERS.containsKey(keyIdentifier)
            && typeInt == Event.ONKEYDOWN) {
          // WAVE-407 Avoid missing chars with NAVIGATION_KEY_IDENTIFIERS but
          // represeting a SHIFT + key char (! " ยท ...). Navigation events come
          // with KEYDOWN, not with KEYPRESS

          type = KeySignalType.NAVIGATION;
          // Escape, backspace and context-menu-key (U+0010) are, to my knowledge,
          // the only non-navigation keys that
          // have a "U+..." keyIdentifier, so we handle them explicitly.
          // (Backspace was handled earlier).
        } else if (computedKeyCode == KeyCodes.KEY_ESCAPE || "U+0010".equals(keyIdentifier)) {
          type = KeySignalType.NOEFFECT;
        } else if (computedKeyCode < 63200
            && // if it's not a safari 3.0 non-input key (See (X) above)
            (typeInt == Event.ONKEYPRESS
                || // if it's a regular keypress
                startsWithUPlus
                || computedKeyCode == KeyCodes.KEY_ENTER)) {
          type = KeySignalType.INPUT;
          isActuallyCtrlInput = ctrlKey || (commandComboDoesntGiveKeypress && commandKey);
        } else {
          type = KeySignalType.NOEFFECT;
        }

        // Maybe nullify it with the same logic as IE, EXCEPT for the special
        // Ctrl Input webkit behaviour, and IME for windows
        if (isActuallyCtrlInput) {
          if (computedKeyCode == KeyCodes.KEY_ENTER) {
            ret = typeInt == Event.ONKEYDOWN;
          }
          // HACK(danilatos): Don't actually nullify isActuallyCtrlInput for key press.
          // We get that for AltGr combos on non-mac computers.
        } else if (isIME || keyCode == KeyCodes.KEY_TAB) {
          ret = typeInt == Event.ONKEYDOWN;
        } else {
          ret = maybeNullWebkitIE(ret, typeInt, type);
        }
        if (!ret) {
          result.type = null;
          return;
        }
        break;
      case GECKO:
        boolean hasKeyCodeButNotWhich = keyCode != 0 && which == 0;

        // Firefox is easy for deciding signal events, because it issues a keypress for
        // whenever we would want a signal. So we can basically ignore all keydown events.
        // It also, on all OSes, does any default action AFTER the keypress (even for
        // things like Ctrl/Meta+C, etc). So keypress is perfect for us.
        // Ctrl+Space is an exception, where we don't get a keypress
        // Firefox also gives us keypress events even for Windows IME input
        if (ctrlKey && !altKey && !shiftKey && computedKeyCode == ' ') {
          if (typeInt != Event.ONKEYDOWN) {
            result.type = null;
            return;
          }
        } else if (typeInt == Event.ONKEYDOWN) {
          result.type = null;
          return;
        }

        // Backspace fails the !hasKeyCodeButNotWhich test, so check it explicitly first
        if (computedKeyCode == KeyCodes.KEY_BACKSPACE) {
          type = KeySignalType.DELETE;
          // This 'keyCode' but not 'which' works very nicely for catching normal typing input keys,
          // the only 'exceptions' I've seen so far are bksp & enter which have both
        } else if (!hasKeyCodeButNotWhich
            || computedKeyCode == KeyCodes.KEY_ENTER
            || computedKeyCode == KeyCodes.KEY_TAB) {
          type = KeySignalType.INPUT;
        } else if (computedKeyCode == KeyCodes.KEY_DELETE) {
          type = KeySignalType.DELETE;
        } else if (NAVIGATION_KEYS.contains(computedKeyCode)) {
          type = KeySignalType.NAVIGATION;
        } else {
          type = KeySignalType.NOEFFECT;
        }

        break;
      case IE:

        // Unfortunately IE gives us the least information, so there are no nifty tricks.
        // So we pretty much need to use some educated guessing based on key codes.
        // Experimentation page to the rescue.

        boolean isKeydownForInputKey = isInputKeyCodeIE(computedKeyCode);

        // IE has some strange behaviour with modifiers and whether or not there will
        // be a keypress. Ctrl kills the keypress, unless shift is also held.
        // Meta doesn't kill it. Alt always kills the keypress, overriding other rules.
        boolean hasModifiersThatResultInNoKeyPress = altKey || (ctrlKey && !shiftKey);

        if (typeInt == Event.ONKEYDOWN) {
          if (isKeydownForInputKey) {
            type = KeySignalType.INPUT;
          } else if (computedKeyCode == KeyCodes.KEY_BACKSPACE
              || computedKeyCode == KeyCodes.KEY_DELETE) {
            type = KeySignalType.DELETE;
          } else if (NAVIGATION_KEYS.contains(computedKeyCode)) {
            type = KeySignalType.NAVIGATION;
          } else {
            type = KeySignalType.NOEFFECT;
          }
        } else {
          // Escape is the only non-input thing that has a keypress event
          if (computedKeyCode == KeyCodes.KEY_ESCAPE) {
            result.type = null;
            return;
          }
          assert typeInt == Event.ONKEYPRESS;
          // I think the guessCommandFromModifiers() check here isn't needed,
          // but i feel safer putting it in.
          type = KeySignalType.INPUT;
        }

        if (hasModifiersThatResultInNoKeyPress || isIME || computedKeyCode == KeyCodes.KEY_TAB) {
          ret = typeInt == Event.ONKEYDOWN ? ret : false;
        } else {
          ret = maybeNullWebkitIE(ret, typeInt, type);
        }
        if (!ret) {
          result.type = null;
          return;
        }
        break;
      default:
        throw new UnsupportedOperationException("Unhandled user agent");
    }

    if (ret) {
      result.type = type;
      result.keyCode = computedKeyCode;
    } else {
      result.type = null;
      return;
    }
  }
 public void deregisterChannel(String objectId) {
   Preconditions.checkState(
       channels.containsKey(objectId), "Channel handler not registered for %s", objectId);
   channels.remove(objectId);
 }
  public void registerChannel(String objectId, GaeChannel channel) {
    Preconditions.checkState(
        !channels.containsKey(objectId), "Channel handler already registered for " + objectId);

    channels.put(objectId, channel);
  }