Example #1
0
            /// <summary>
            /// Adds an event listener. A listener can only be added once to an
            /// object and if it is added again the key for the listener is
            /// returned.
            ///
            /// Note that a one-off listener will not change an existing listener,
            /// if any. On the other hand a normal listener will change existing
            /// one-off listener to become a normal listener.
            /// </summary>
            /// <param name="type">The listener event type.</param>
            /// <param name="listener">This listener callback method.</param>
            /// <param name="callOnce">Whether the listener is a one-off listener.</param>
            /// <param name="opt_useCapture">The capture mode of the listener.</param>
            /// <param name="opt_listenerScope">Object in whose scope to call the
            /// listener.</param>
            /// <returns>Unique key for the listener.</returns>
            public Listener add(string type, Delegate listener, bool callOnce, bool opt_useCapture, object opt_listenerScope)
            {
                var typeStr = type.ToString();

                if (!this.listeners.TryGetValue(typeStr, out var listenerArray))
                {
                    listenerArray = this.listeners[typeStr] = new JsArray <Listener>();
                    this.typeCount_++;
                }

                Listener listenerObj;
                var      index = goog.events.ListenerMap.findListenerIndex_(
                    listenerArray, listener, opt_useCapture, opt_listenerScope);

                if (index > -1)
                {
                    listenerObj = listenerArray[index];
                    if (!callOnce)
                    {
                        // Ensure that, if there is an existing callOnce listener, it is no
                        // longer a callOnce listener.
                        listenerObj.callOnce = false;
                    }
                }
                else
                {
                    listenerObj = new goog.events.Listener(
                        listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope);
                    listenerObj.callOnce = callOnce;
                    listenerArray.Push(listenerObj);
                }
                return(listenerObj);
            }
Example #2
0
        /// <summary>
        /// Create a date picker under the date field.
        /// </summary>
        public override void showEditor_(bool opt_quietInput)
        {
            WidgetDiv.show(this, this.sourceBlock_.RTL,
                           new Action(FieldDate.widgetDispose_));
            // Create the date picker using Closure.
            FieldDate.loadLanguage_();
            var picker = new goog.ui.DatePicker();

            picker.setAllowNone(false);
            picker.setShowWeekNum(false);

            // Position the picker to line up with the field.
            // Record windowSize and scrollOffset before adding the picker.
            var windowSize   = goog.dom.getViewportSize();
            var scrollOffset = goog.style.getViewportPageOffset(Document.Instance);
            var xy           = this.getAbsoluteXY_();
            var borderBBox   = this.getScaledBBox_();
            var div          = WidgetDiv.DIV;

            picker.render(div);
            picker.setDate(new Date(this.getValue()));
            // Record pickerSize after adding the date picker.
            var pickerSize = goog.style.getSize(picker.getElement());

            // Flip the picker vertically if off the bottom.
            if (xy.y + pickerSize.height + borderBBox.height >=
                windowSize.height + scrollOffset.y)
            {
                xy.y -= pickerSize.height - 1;
            }
            else
            {
                xy.y += borderBBox.height - 1;
            }
            if (this.sourceBlock_.RTL)
            {
                xy.x += borderBBox.width;
                xy.x -= pickerSize.width;
                // Don't go offscreen left.
                if (xy.x < scrollOffset.x)
                {
                    xy.x = scrollOffset.x;
                }
            }
            else
            {
                // Don't go offscreen right.
                if (xy.x > windowSize.width + scrollOffset.x - pickerSize.width)
                {
                    xy.x = windowSize.width + scrollOffset.x - pickerSize.width;
                }
            }
            WidgetDiv.position(xy.x, xy.y, windowSize, scrollOffset,
                               this.sourceBlock_.RTL);

            // Configure event handler.
            var thisField = this;

            FieldDate.changeEventKey_ = goog.events.listen(picker,
                                                           goog.ui.DatePicker.Events.CHANGE,
                                                           new Action <Bridge.Html5.Event>((e) => {
                var date = e.Date != null ? e.Date.ToIsoString(true) : "";
                WidgetDiv.hide();
                if (thisField.sourceBlock_ != null)
                {
                    // Call any validation function, and allow it to override.
                    date = thisField.callValidator(date);
                }
                thisField.setValue(date);
            }));
        }
Example #3
0
        /// <summary>
        /// Handles an event and dispatches it to the correct listeners. This
        /// function is a proxy for the real listener the user specified.
        /// </summary>
        /// <param name="listener">The listener object.</param>
        /// <param name="opt_evt">Optional event object that gets passed in via the
        /// native event handlers.</param>
        /// <returns>Result of the event handler.</returns>
        private static bool handleBrowserEvent_(Bridge.Html5.EventTarget _this, goog.events.Listener listener, Bridge.Html5.Event opt_evt = null)
        {
            if (listener.removed)
            {
                return(true);
            }

            // Synthesize event propagation if the browser does not support W3C
            // event model.
            if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT)
            {
                var ieEvent = opt_evt ??
                              ((Bridge.Html5.Event)goog.le.getObjectByName("window.event"));
                var evt = new goog.events.BrowserEvent(ieEvent, _this);
                /** @type {boolean} */
                var retval = true;

                if (goog.events.CAPTURE_SIMULATION_MODE ==
                    goog.events.CaptureSimulationMode.ON)
                {
                    // If we have not marked this event yet, we should perform capture
                    // simulation.
                    if (!goog.events.isMarkedIeEvent_(ieEvent))
                    {
                        goog.events.markIeEvent_(ieEvent);

                        var ancestors = new JsArray <Node>();
                        for (var parent = (Node)evt.currentTarget; parent != null;
                             parent = parent.ParentNode)
                        {
                            ancestors.Push(parent);
                        }

                        // Fire capture listeners.
                        var type = listener.type;
                        for (var i = ancestors.Length - 1; !evt.propagationStopped_ && i >= 0;
                             i--)
                        {
                            evt.currentTarget = ancestors[i];
                            var result =
                                goog.events.fireListeners_(ancestors[i], type, true, evt);
                            retval = retval && result != null;
                        }

                        // Fire bubble listeners.
                        //
                        // We can technically rely on IE to perform bubble event
                        // propagation. However, it turns out that IE fires events in
                        // opposite order of attachEvent registration, which broke
                        // some code and tests that rely on the order. (While W3C DOM
                        // Level 2 Events TR leaves the event ordering unspecified,
                        // modern browsers and W3C DOM Level 3 Events Working Draft
                        // actually specify the order as the registration order.)
                        for (var i = 0; !evt.propagationStopped_ && i < ancestors.Length; i++)
                        {
                            evt.currentTarget = ancestors[i];
                            var result =
                                goog.events.fireListeners_(ancestors[i], type, false, evt);
                            retval = retval && result != null;
                        }
                    }
                }
                else
                {
                    retval = goog.events.fireListener(listener, evt);
                }
                return(retval);
            }

            // Otherwise, simply fire the listener.
            return(goog.events.fireListener(
                       listener, new goog.events.BrowserEvent(opt_evt, _this)));
        }
Example #4
0
        /// <summary>
        /// Create a palette under the colour field.
        /// </summary>
        public override void showEditor_(bool opt_quietInput)
        {
            WidgetDiv.show(this, this.sourceBlock_.RTL,
                           new Action(FieldColour.widgetDispose_));
            // Create the palette using Closure.
            var picker = new goog.ui.ColorPicker();

            picker.setSize(this.columns_ ?? FieldColour.COLUMNS);
            picker.setColors(new JsArray <string>(this.colours_ ?? FieldColour.COLOURS));

            // Position the palette to line up with the field.
            // Record windowSize and scrollOffset before adding the palette.
            var windowSize   = goog.dom.getViewportSize();
            var scrollOffset = goog.style.getViewportPageOffset(Document.Instance);
            var xy           = this.getAbsoluteXY_();
            var borderBBox   = this.getScaledBBox_();
            var div          = WidgetDiv.DIV;

            picker.render(div);
            picker.setSelectedColor(this.getValue());
            // Record paletteSize after adding the palette.
            var paletteSize = goog.style.getSize(picker.getElement());

            // Flip the palette vertically if off the bottom.
            if (xy.y + paletteSize.height + borderBBox.height >=
                windowSize.height + scrollOffset.y)
            {
                xy.y -= paletteSize.height - 1;
            }
            else
            {
                xy.y += borderBBox.height - 1;
            }
            if (this.sourceBlock_.RTL)
            {
                xy.x += borderBBox.width;
                xy.x -= paletteSize.width;
                // Don't go offscreen left.
                if (xy.x < scrollOffset.x)
                {
                    xy.x = scrollOffset.x;
                }
            }
            else
            {
                // Don't go offscreen right.
                if (xy.x > windowSize.width + scrollOffset.x - paletteSize.width)
                {
                    xy.x = windowSize.width + scrollOffset.x - paletteSize.width;
                }
            }
            WidgetDiv.position(xy.x, xy.y, windowSize, scrollOffset,
                               this.sourceBlock_.RTL);

            // Configure event handler.
            var thisField = this;

            FieldColour.changeEventKey_ = goog.events.listen(picker,
                                                             goog.ui.ColorPicker.EventType.CHANGE,
                                                             new Action <goog.events.Event>((e) => {
                string colour = ((goog.ui.ColorPicker)e.target).getSelectedColor() ?? "#000000";
                WidgetDiv.hide();
                if (thisField.sourceBlock_ != null)
                {
                    // Call any validation function, and allow it to override.
                    colour = thisField.callValidator(colour);
                }
                if (colour != null)
                {
                    thisField.setValue(colour);
                }
            }));
        }