예제 #1
0
        public override object CreateDomElement(object parentRef, out object domElementWhereToPlaceChildren)
        {
            object outerDiv;
            var    outerDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", parentRef, this, out outerDiv);

            outerDivStyle.width  = "100%";
            outerDivStyle.height = "100%";

            var iFrameStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("iframe", outerDiv, this, out _iFrame);

            iFrameStyle.width  = "100%";
            iFrameStyle.height = "100%";
            iFrameStyle.border = "none";

            var source = this.Source;

            if (source != null && !string.IsNullOrEmpty(source.OriginalString))
            {
                Interop.ExecuteJavaScriptAsync("$0.src = $1", _iFrame, source.OriginalString);
            }
            else if (_htmlString != null)
            {
                Interop.ExecuteJavaScriptAsync("srcDoc.set($0, $1)", _iFrame, _htmlString);
            }
            else
            {
                Interop.ExecuteJavaScriptAsync("$0.src = 'about:blank'", _iFrame);
            }

            domElementWhereToPlaceChildren = _iFrame;
            return(outerDiv);
        }
예제 #2
0
        //private double GetRowActualWidth_CSSVersion(RowDefinition rowDefinition)
        //{
        //    //the row's width is basically the width of the whole grid, right?
        //    if (CSharpXamlForHtml5.Environment.IsRunningInJavaScript)
        //    {
        //        return _innerDiv.offsetWidth;
        //    }
        //    else
        //    {
        //        INTERNAL_SimulatorExecuteJavaScript.ForceExecutionOfAllPendingCode(); // Explanation: we usually optimize performance in the Simulator by postponing the JS code that sets the CSS properties. This reduces the number of interop calls between C# and the browser. However, in the current case here we need to have all the properties already applied in order to be able to calculate the size of the DOM element. Therefore we need to call the "ForceExecution" method.
        //        return (double)INTERNAL_HtmlDomManager.CastToJsValue_SimulatorOnly(INTERNAL_HtmlDomManager.GetDomElementAttribute(_innerDiv, "offsetWidth"));
        //    }
        //}

        private object AddTemporaryDivForRowOrColumnDimensions(int columnIndex, int rowIndex)
        {
            dynamic div1;
            dynamic div1style = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", (object)_innerDiv, this, out div1);

            div1style.width    = "100%";
            div1style.height   = "100%";
            div1style.opacity  = "0";
            div1style.position = "relative";

            bool isMsGrid = Grid_InternalHelpers.isMSGrid();

            if (!isMsGrid)
            {
                div1style.gridColumnStart = (columnIndex + 1).ToString(); //Note: +1 because columns start from 1 instead of 0 in js.
                div1style.gridRowStart    = (rowIndex + 1).ToString();    //Note: +1 because columns start from 1 instead of 0 in js.
            }
            else
            {
                div1style.msGridColumn = (columnIndex + 1).ToString(); //Note: +1 because columns start from 1 instead of 0 in js.
                //div1style.msGridColumnSpan = (columnSpan).ToString(); //Note: +1 because columns start from 1 instead of 0 in js and another + 1 because the gridColumnEnd seems to be the column BEFORE WHITCH the span ends.

                div1style.msGridRow = (rowIndex + 1).ToString(); //Note: +1 because columns start from 1 instead of 0 in js.
            }

            return(div1);
        }
예제 #3
0
        public override object CreateDomElement(object parentRef, out object domElementWhereToPlaceChildren)
        {
            object  outerDiv;
            object  middleDiv;
            object  childrenContainerDiv;
            dynamic outerDivStyle             = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", parentRef, this, out outerDiv);
            dynamic middleDivStyle            = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", outerDiv, this, out middleDiv);
            dynamic childrenContainerDivDtyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", middleDiv, this, out childrenContainerDiv);

            if (TextWrapping == TextWrapping.NoWrap)
            {
                outerDivStyle.whiteSpace = "pre"; //nowrap + preserve whitespaces
            }
            else //so that we are sure that it will behave the same on all browsers
            {
                outerDivStyle.whiteSpace = "pre-wrap";      //wrap and preserve whitespaces
            }
            outerDivStyle.overflow              = "hidden"; //keeps the text from overflowing despite the TextBlock's size limitations.
            outerDivStyle.textAlign             = "left";   // this is the default value.
            middleDivStyle.width                = "inherit";
            middleDivStyle.height               = "inherit";
            childrenContainerDivDtyle.width     = "inherit";
            childrenContainerDivDtyle.height    = "inherit";
            childrenContainerDivDtyle.overflowX = "hidden";
            childrenContainerDivDtyle.overflowY = "hidden";
            domElementWhereToPlaceChildren      = childrenContainerDiv;

            return(outerDiv);
        }
예제 #4
0
        ///// <summary>
        ///// Sets the Source property using the supplied stream.
        ///// </summary>
        ///// <param name="stream">The stream that contains the media to load.</param>
        ///// <param name="mimeType">
        ///// The MIME type of the media resource, expressed as the string form typically
        ///// seen in HTTP headers and requests.
        ///// </param>
        //public void SetSource(IRandomAccessStream stream, string mimeType);

        /// <summary>
        /// Stops and resets media to be played from the beginning.
        /// </summary>
        //public void Stop()
        //{
        //    //todo
        //}


        public override object CreateDomElement(object parentRef, out object domElementWhereToPlaceChildren)
        {
            domElementWhereToPlaceChildren = null;
            object  outerDiv;
            dynamic outerDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", parentRef, this, out outerDiv);

            return(outerDiv);
        }
예제 #5
0
        /// <summary>
        /// Set the DOM element that will host the window. This can be set only to new windows. The MainWindow looks for a DIV that has the ID "cshtml5-root".
        /// </summary>
        /// <param name="rootDomElement">The DOM element that will host the window</param>
        public void AttachToDomElement(object rootDomElement)
        {
            if (this.INTERNAL_OuterDomElement != null ||
                this.INTERNAL_RootDomElement != null)
            {
                throw new InvalidOperationException("The method 'Window.AttachToDomElement' can be called only once.");
            }

            if (rootDomElement == null)
            {
                throw new ArgumentNullException("rootDomElement");
            }

            //Note: The "rootDomElement" will contain one DIV for the root of the window visual tree, and other DIVs to host the popups.
            this.INTERNAL_RootDomElement = rootDomElement;

            // Reset the content of the root DIV:
            Interop.ExecuteJavaScriptAsync(@"$0.innerHTML = ''", rootDomElement);

            // In case of XAML view hosted inside an HTML app, we usually set the "position" of the window root to "relative" rather than "absolute" (via external JavaScript code) in order to display it inside a specific DIV. However, in this case, the layers that contain the Popups are placed under the window DIV instead of over it. To work around this issue, we set the root element display to "grid". See the sample app "IntegratingACshtml5AppInAnSPA".
            if (Grid_InternalHelpers.isCSSGridSupported()) //todo: what about the old browsers where "CSS Grid" is not supported?
            {
                Interop.ExecuteJavaScriptAsync("$0.style.display = 'grid'", rootDomElement);
            }

            // Create the DIV that will correspond to the root of the window visual tree:
            object windowRootDiv;

#if CSHTML5NETSTANDARD
            INTERNAL_HtmlDomStyleReference
#else
            dynamic
#endif
            windowRootDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", rootDomElement, this, out windowRootDiv);

            windowRootDivStyle.position  = "absolute";
            windowRootDivStyle.width     = "100%";
            windowRootDivStyle.height    = "100%";
            windowRootDivStyle.overflowX = "hidden";
            windowRootDivStyle.overflowY = "hidden";

            this.INTERNAL_OuterDomElement = windowRootDiv;
            this.INTERNAL_InnerDomElement = windowRootDiv;

            // Set the window as "loaded":
            this._isLoaded = true;

            // Attach the window content, if any:
            object content = this.Content;
            if (content != null)
            {
                OnContentChanged(null, content);
            }

            // Raise the "Loaded" event:
            this.INTERNAL_RaiseLoadedEvent();
        }
        internal static object CreateDomElement(ToggleButton checkBoxOrRadioButton, string domInputType, object parentRef, out object domElementWhereToPlaceChildren)
        {
            object outerDiv;
            var    outerDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", parentRef, checkBoxOrRadioButton, out outerDiv);

            object divInBetween;
            var    divInBetweenStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", outerDiv, checkBoxOrRadioButton, out divInBetween);

            object innerElement;
            var    innerElementStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("input", divInBetween, checkBoxOrRadioButton, out innerElement);

            INTERNAL_HtmlDomManager.SetDomElementAttribute(innerElement, "type", domInputType, forceSimulatorExecuteImmediately: true);
            //we simulate a Horizontal StackPanel (1/2):
            divInBetweenStyle.position = "relative";
            divInBetweenStyle.display  = "table-cell";
            divInBetweenStyle.height   = "100%";

            checkBoxOrRadioButton.INTERNAL_OptionalSpecifyDomElementConcernedByFocus     = innerElement;
            checkBoxOrRadioButton.INTERNAL_OptionalSpecifyDomElementConcernedByIsEnabled = innerElement;

            object divWhereToPlaceChild;
            var    divWhereToPlaceChildStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", outerDiv, checkBoxOrRadioButton, out divWhereToPlaceChild);

            //we simulate a Horizontal StackPanel (2/2):
            divWhereToPlaceChildStyle.position = "relative";
            divWhereToPlaceChildStyle.display  = "table-cell";
            divWhereToPlaceChildStyle.height   = "100%";


            if (INTERNAL_HtmlDomManager.IsInternetExplorer() && domInputType == "checkbox")
            {
                //Note: we add these event handlers because IE does not fire the change event when clicking to go out of the Indeterminate state.
                INTERNAL_EventsHelper.AttachToDomEvents("click", innerElement, (Action <object>)(e =>
                {
                    IsCheckedValueChanged(checkBoxOrRadioButton);
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("click", divWhereToPlaceChild, (Action <object>)(e =>
                {
                    IsCheckedValueChanged(checkBoxOrRadioButton);
                }));
            }
            else
            {
                SubscribeToBasicEventsForRadioButton(checkBoxOrRadioButton, innerElement, divWhereToPlaceChild);
            }

            domElementWhereToPlaceChildren = divWhereToPlaceChild;
            return(outerDiv);
        }
예제 #7
0
        public override object CreateDomElement(object parentRef, out object domElementWhereToPlaceChildren)
        {
            //------------------
            // It is important to create at least 2 divs so that horizontal and vertical alignments work properly (cf. "ApplyHorizontalAlignment" and "ApplyVerticalAlignment" methods)
            //------------------

            object  div1;
            dynamic div1style = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("canvas", parentRef, this, out div1);

            domElementWhereToPlaceChildren = div1;

            // Use the div2 as the js canvas object
            this._jsCanvas    = div1;
            this._jsContext2d = Interop.ExecuteJavaScriptAsync("$0.getContext('2d')", this._jsCanvas);

            Interop.ExecuteJavaScriptAsync("$0.onselectstart = function() { return false; }", this._jsCanvas);

            return(div1);
        }
예제 #8
0
        //BRIDGETODO
        // Bridge bug : when we use virtual, override & out/base in a function, bridge doesn't compile
        // so delete this class when the bug is resolved
        public object CreateDomElement_WorkaroundBridgeInheritanceBug(object parentRef, out object domElementWhereToPlaceChildren)
        {
            //------------------
            // It is important to create at least 2 divs so that horizontal and vertical alignments work properly (cf. "ApplyHorizontalAlignment" and "ApplyVerticalAlignment" methods)
            //------------------

            object  div1;
            dynamic div1style = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", parentRef, this, out div1);
            object  div2;
            dynamic div2style = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", div1, this, out div2);

            div2style.width  = "100%";
            div2style.height = "100%";
            if (INTERNAL_ForceEnableAllPointerEvents)
            {
                div2style.pointerEvents = "all";
            }
            domElementWhereToPlaceChildren = div2;
            return(div1);
        }
예제 #9
0
        private object AddPasswordInputDomElement(object parentRef, out object domElementWhereToPlaceChildren, bool isTemplated)
        {
            dynamic passwordField;
            var     passwordFieldStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("input", parentRef, this, out passwordField);

            //dynamic passwordField = INTERNAL_HtmlDomManager.CreateDomElementAndAppendIt("input", parentRef, this);

            this.INTERNAL_OptionalSpecifyDomElementConcernedByFocus = passwordField;

            _passwordInputField = passwordField;

            domElementWhereToPlaceChildren = passwordField; // Note: this value is used by the Padding_Changed method to set the padding of the PasswordBox.

            if (isTemplated)                                //When templated, we remove the outlining that apears when the element has the focus:
            {
                //if the child of this.INTERNAL_AdditionalOutsideDivForMargins has the tagname "INPUT", replace it with a div:
                var additionalDivForMargins = this.INTERNAL_AdditionalOutsideDivForMargins;

                dynamic newOuterDomElement = CSHTML5.Interop.ExecuteJavaScript(@"(function() {
    var formerInputElement = $0.firstChild;
    var outerDomElement = formerInputElement;
    if(formerInputElement.tagName == 'INPUT') {
        var replacement = document.createElement('div');
        outerDomElement = replacement;
        // copy the attributes:
        for(var i=0; i<formerInputElement.attributes.length; ++i) {
            var at = formerInputElement.attributes[i];
            if(at.name != 'type' && at.name != 'tabIndex') //removing the type (which is now irrelevant) and the tabIndex (which would add the div to the tabbing sequence)
            {
                replacement.setAttribute(at.name, at.value);
            }
        }
        // move the potential children to the replacement node:
        while(formerInputElement.firstChild)
        {
            replacement.appendChild(formerInputElement.firstChild);
        }
        // replace the element:
        formerInputElement.replaceWith(replacement);
    }
    return outerDomElement;
})()", additionalDivForMargins);

                if (!CSHTML5.Interop.IsRunningInTheSimulator)
                {
                    //Note: we replaced the former <input> with a <div> in the DOM tree because it was created before knowing that there was a Template.
                    //      In the Simulator, there is no need to do anything because INTERNAL_OuterDomElement is only linked to the DOM element through its id (which was copied in the replacement <div>).
                    //      In the browser, INTERNAL_OuterDomElement is the Dom element itself so we need to replace it, so we do it here.
                    INTERNAL_OuterDomElement = newOuterDomElement;
                }

                passwordFieldStyle.border          = "transparent";       // This removes the border. We do not need it since we are templated
                passwordFieldStyle.outline         = "solid transparent"; // Note: this is to avoind having the weird border when it has the focus. I could have used outlineWidth = "0px" but or some reason, this causes the caret to not work when there is no text.
                passwordFieldStyle.backgroundColor = "transparent";
                passwordFieldStyle.fontSize        = "inherit";           // Not inherited by default for "input" DOM elements
            }

            passwordFieldStyle.width  = "100%";
            passwordFieldStyle.height = "100%";

            INTERNAL_HtmlDomManager.SetDomElementAttribute(passwordField, "type", "password", forceSimulatorExecuteImmediately: true);

            //passwordField.type = "password";

            //-----------------------
            // Prepare to raise the "TextChanged" event and to update the value of the "Text" property when the DOM text changes:
            //-----------------------
            //todo: why did we put this here instead of in INTERNAL_AttachToDomEvents?
            if (IsRunningOnInternetExplorer())
            {
                //-----------------------
                // Fix "input" event not working under IE:
                //-----------------------
                this.GotFocus  += InternetExplorer_GotFocus;
                this.LostFocus += InternetExplorer_LostFocus;
                INTERNAL_EventsHelper.AttachToDomEvents("textinput", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("paste", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("cut", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("keyup", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("delete", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("mouseup", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
            }
            else
            {
                //-----------------------
                // Modern browsers
                //-----------------------
                INTERNAL_EventsHelper.AttachToDomEvents("input", passwordField, (Action <object>)(e =>
                {
                    PasswordAreaValueChanged();
                }));
            }

            //textArea.style.resize = "none"; //to avoid letting the posibility to the user to resize the TextBox

            if (isTemplated)
            {
                //the following methods were ignored before because _contentEditableDiv was not defined due to the fact that we waited for the template to be made so we would know where to put it.
                //as a consequence, we call them here:
                OnAfterApplyHorizontalAlignmentAndWidth();
                OnAfterApplyVerticalAlignmentAndWidth();

                //Note about tabbing: In WPF and SL, the elements in the template other than the input field can have focus but the input field will get any keypress not handled by them
                //                    For example, you can set the focus on a button included in the template by clicking on it and pressing space will cause a button press, but any character will be added to the Text of the PasswordBox (but the button retains the focus)
                //                    WPF and SL are different in that in SL, every focusable control in the template can get focus through tabbing while in WPF, the whole control is considered as a single tab stop (tabbing into the PasswordBox will directly put the focus on the input element)
                //                    BUT in SL, the input will be first in tabOrder (unless maybe if tabIndex is specifically set, I didn't try that) so if the template goes <Stackpanel><Button/><ContentPresenter/></StackPanel>, by tabbing it will go ContentPresenter first then the Button (example simplified without the names, and also WPF and SL do not use a ContentPresenter but a ScrollViewer or Decorator in which to put the input area)
                //
                //                    In our case, tabbing will go through the elements accessible through tabbing, without changing the order, and text will only be added when the <input> has focus. On click, the focus will be redirected to the <input>, unless the click was on an element that absorbs pointer events.

                CSHTML5.Interop.ExecuteJavaScript(@"$0.addEventListener('click', $1)", this.INTERNAL_OuterDomElement, (Action <object>)PasswordBox_GotFocus);
            }

            return(passwordField);
        }
예제 #10
0
        public override object CreateDomElement(object parentRef, out object domElementWhereToPlaceChildren)
        {
            //INTERNAL_HtmlDomManager.GetDomElementStyleForModification(div).position = "absolute";
            //div.style.position = "absolute";
            //note: size must be set in the div part only (the rest will follow).

            _renderedOrientation = this.Orientation;

            if (_renderedOrientation == Orientation.Horizontal)
            {
                //------v1------//

                //wrapper for the whole stackpanel:
                //<div>
                //  <table style="height:inherit; border-collapse:collapse">
                //    <tr>
                //          ...
                //    </tr>
                //  </table>
                //</div>

                //var table = INTERNAL_HtmlDomManager.CreateDomElement("table");
                //table.style.height = "inherit";
                //table.style.borderCollapse = "collapse";

                //var tr = INTERNAL_HtmlDomManager.CreateDomElement("tr");
                //tr.style.padding = "0px";

                //INTERNAL_HtmlDomManager.AppendChild(table, tr);
                //INTERNAL_HtmlDomManager.AppendChild(div, table);


                //domElementWhereToPlaceChildren = tr;

                //------v2------//
                //wrapper for the whole StackPanel - v2:
                //  <div style="display:table-row">
                //      <div style="margin-left: 0px; margin-right: auto; height: 100%">
                //          ...
                //      </div>
                //  </div>


                object  outerDiv;
                dynamic outerDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", parentRef, this, out outerDiv);

                if (INTERNAL_HtmlDomManager.IsInternetExplorer() && !INTERNAL_HtmlDomManager.IsEdge())     //When in Internet Explorer, we need to use display:grid instead of table so that VerticalAlignment.Stretch works (cf StratX.Star in the products page) but we definitely do not want this to be used in Edge as it crashes and causes the whole app to restart (cf ShowcaseApp with CSHTML5 from v1.0 beta 13.2 to RC1 included)
                {
                    outerDivStyle.display = !Grid_InternalHelpers.isMSGrid() ? outerDivStyle.display = "grid" : Grid_InternalHelpers.INTERNAL_CSSGRID_MS_PREFIX + "grid";
                }
                else
                {
                    outerDivStyle.display = "table";
                }
                object  innerDiv;
                dynamic innerDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", outerDiv, this, out innerDiv);

                innerDivStyle.marginLeft  = "0px";
                innerDivStyle.marginRight = "auto";
                innerDivStyle.height      = "100%";
                innerDivStyle.display     = "table";

                domElementWhereToPlaceChildren = innerDiv;

                return(outerDiv);
            }
            else
            {
#if !BRIDGE
                return(base.CreateDomElement(parentRef, out domElementWhereToPlaceChildren));
#else
                return(CreateDomElement_WorkaroundBridgeInheritanceBug(parentRef, out domElementWhereToPlaceChildren));
#endif
            }
        }
예제 #11
0
        private object AddPasswordInputDomElement(object parentRef, out object domElementWhereToPlaceChildren, bool isTemplated)
        {
            dynamic passwordField;
            var     passwordFieldStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("input", parentRef, this, out passwordField);

            //dynamic passwordField = INTERNAL_HtmlDomManager.CreateDomElementAndAppendIt("input", parentRef, this);

            _passwordInputField = passwordField;

            domElementWhereToPlaceChildren = passwordField;               // Note: this value is used by the Padding_Changed method to set the padding of the PasswordBox.

            if (isTemplated)                                              //When templated, we remove the outlining that apears when the element has the focus:
            {
                passwordFieldStyle.border          = "transparent";       // This removes the border. We do not need it since we are templated
                passwordFieldStyle.outline         = "solid transparent"; // Note: this is to avoind having the weird border when it has the focus. I could have used outlineWidth = "0px" but or some reason, this causes the caret to not work when there is no text.
                passwordFieldStyle.backgroundColor = "transparent";
                passwordFieldStyle.fontSize        = "inherit";           // Not inherited by default for "input" DOM elements
            }

            passwordFieldStyle.width  = "100%";
            passwordFieldStyle.height = "100%";

            INTERNAL_HtmlDomManager.SetDomElementAttribute(passwordField, "type", "password", forceSimulatorExecuteImmediately: true);
            //passwordField.type = "password";

            //-----------------------
            // Prepare to raise the "TextChanged" event and to update the value of the "Text" property when the DOM text changes:
            //-----------------------
            //todo: why did we put this here instead of in INTERNAL_AttachToDomEvents?
            if (IsRunningOnInternetExplorer())
            {
                //-----------------------
                // Fix "input" event not working under IE:
                //-----------------------
                this.GotFocus  += InternetExplorer_GotFocus;
                this.LostFocus += InternetExplorer_LostFocus;
                INTERNAL_EventsHelper.AttachToDomEvents("textinput", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("paste", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("cut", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("keyup", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("delete", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("mouseup", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
            }
            else
            {
                //-----------------------
                // Modern browsers
                //-----------------------
                INTERNAL_EventsHelper.AttachToDomEvents("input", passwordField, (Action <object>)(e =>
                {
                    PasswordAreaValueChanged();
                }));
            }

            //textArea.style.resize = "none"; //to avoid letting the posibility to the user to resize the TextBox

            if (isTemplated)
            {
                //the following methods were ignored before because _contentEditableDiv was not defined due to the fact that we waited for the template to be made so we would know where to put it.
                //as a consequence, we call them here:
                OnAfterApplyHorizontalAlignmentAndWidth();
                OnAfterApplyVerticalAlignmentAndWidth();

                //register to focusin events on the OuterDomElement so that we can "reroute" the focus on the contentEditable element.
                CSHTML5.Interop.ExecuteJavaScript(@"$0.tabIndex = 32767; $0.addEventListener('focusin', $1)", this.INTERNAL_OuterDomElement, (Action <object>)PasswordBox_GotFocus);
                //Note on the line above: 32767 is the maximum value commonly allowed in browsers (and can be considered the default value)
                if (INTERNAL_HtmlDomManager.IsInternetExplorer())
                {
                    //workaround due to IE setting the focus at the end of the click, (or at least after the focusin event), which cancels the work done during focusin.
                    //if I'm not mistaken, the click event happens even when we click on a child of the element so we're all good. (We had to fix the case where a Button had a TextBox inside of it, which is why I assumed that).
                    CSHTML5.Interop.ExecuteJavaScript(@"$0.addEventListener('click', $1)", this.INTERNAL_OuterDomElement, (Action <object>)PasswordBox_GotFocus);
                }
            }

            return(passwordField);
        }
예제 #12
0
        private static void Source_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control  = (MediaElement)d;
            var newValue = (Uri)e.NewValue;

            // Always check that the control is in the Visual Tree before modifying its HTML representation
            if (INTERNAL_VisualTreeManager.IsElementInVisualTree(control))
            {
                string newUri = newValue.ToString();

                // If the new Source is an empty string, we avoid the error messages:
                if (!string.IsNullOrWhiteSpace(newUri))
                {
                    string tagString = "none";

                    string valueForHtml5SourceProperty = INTERNAL_UriHelper.ConvertToHtml5Path(newValue.ToString(), control);

                    string newExtensionLowercase = GetExtension(newUri).ToLower();

                    if (SupportedVideoTypes.Contains(newExtensionLowercase))
                    {
                        if (control.IsAudioOnly || control._mediaElement == null) //note: I chose to use IsAudioOnly here because using e.oldValue would make it recreate the video tag when it was already a video tag.
                        {
                            tagString           = "video";
                            control.IsAudioOnly = false;
                        }
                    }
                    else if (SupportedAudioTypes.Contains(newExtensionLowercase))
                    {
                        if (!control.IsAudioOnly || control._mediaElement == null) //note: I chose to use IsAudioOnly here because using e.oldValue would make it recreate the audio tag when it was already a audio tag.
                        {
                            tagString           = "audio";
                            control.IsAudioOnly = true;
                        }
                    }
                    else
                    {
                        throw new NotSupportedException("ERROR: The MediaElement control only supports files of the following types: VIDEO: mp4, ogv, webm, 3gp - AUDIO: mp3, ogg - Note: for best browser compatibility, it is recommended to use only MP3 and MP4 files.");
                    }
                    if (tagString != "none") //tagString != "none" means that the new Uri has a different type (audio VS video) than the old one, so we need to (re)create the dom tag.
                    {
                        if (control._mediaElement != null)
                        {
                            INTERNAL_HtmlDomManager.RemoveFromDom(control._mediaElement); //note: there can be only one child element.
                        }
#if OPENSILVER
                        if (!INTERNAL_InteropImplementation.IsRunningInTheSimulator_WorkAround() || tagString == "video")
#else
                        if (CSharpXamlForHtml5.Environment.IsRunningInJavaScript || tagString == "video")
#endif
                        {
                            object element      = null;
                            object outerDiv     = control.INTERNAL_OuterDomElement;
                            var    elementStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle(tagString, outerDiv, control, out element);

                            control._mediaElement_ForAudioOnly_ForSimulatorOnly = null;

                            control._mediaElement = element;

                            if (tagString == "video")
                            {
                                elementStyle.width  = "100%";
                                elementStyle.height = "100%";
                            }

                            control.Refresh(); //we refresh all the values of the element in the visual tree
                        }
                        else //when we are in the simulator, we don't want to use the <audio> tag, we will use a wpf one instead (because awesomium doesn't support .mp3 for example)
                        {
#if !CSHTML5NETSTANDARD
                            if (control._mediaElement_ForAudioOnly_ForSimulatorOnly == null)
                            {
                                control._mediaElement_ForAudioOnly_ForSimulatorOnly = INTERNAL_Simulator.WpfMediaElementFactory.Create((Action)control.SimulatorMediaElement_Loaded, (Action)control.SimulatorMediaElement_MediaEnded);
                            }
                            control._mediaElement_ForAudioOnly_ForSimulatorOnly.Source = new Uri(valueForHtml5SourceProperty);
                            control.Refresh_SimulatorOnly();
#endif
                            return;
                        }
                    }

                    // Update the "src" property of the <video> or <audio> tag
                    INTERNAL_HtmlDomManager.SetDomElementAttribute(control._mediaElement, "src", valueForHtml5SourceProperty, forceSimulatorExecuteImmediately: true);
                }
                else
                {
                    if (control._mediaElement != null)
                    {
                        // Remove previous video/audio if any:
                        INTERNAL_HtmlDomManager.SetDomElementAttribute(control._mediaElement, "src", "", forceSimulatorExecuteImmediately: true);
                    }
                }
            }
        }
예제 #13
0
        private object AddContentEditableDomElement(object parentRef, out object domElementWhereToPlaceChildren)
        {
            bool   isReadOnly = this.Host.IsReadOnly;
            object outerDiv;
            var    outerDivStyle   = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", parentRef, this, out outerDiv);
            string backgroundColor = "transparent"; //value when it is templated

            outerDivStyle.backgroundColor = backgroundColor;
            outerDivStyle.height          = "100%";

            object middleDiv;
            var    middleDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", outerDiv, this, out middleDiv);

            middleDivStyle.width  = "100%";
            middleDivStyle.height = "100%";

            object contentEditableDiv;
            var    contentEditableDivStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", middleDiv, this, out contentEditableDiv);

            _contentEditableDiv = contentEditableDiv;
            Host.UpdateFocusContentEditable(_contentEditableDiv);
            if (INTERNAL_HtmlDomManager.IsInternetExplorer())
            {
                //set the class to remove margins on <p> inside the contentEditableDiv
                OpenSilver.Interop.ExecuteJavaScript(@"$0.classList.add(""ie_set_p_margins_to_zero"")", contentEditableDiv);
            }

            contentEditableDivStyle.width  = "100%";
            contentEditableDivStyle.height = "100%";

            // Apply Host.TextWrapping
            contentEditableDivStyle.whiteSpace = Host.TextWrapping == TextWrapping.NoWrap ? "nowrap" : "pre-wrap";

            // Apply Host.HorizontalScrollBarVisibility
            contentEditableDivStyle.overflowX = ScrollBarVisibilityToHtmlString(Host.HorizontalScrollBarVisibility) ?? "hidden";

            // Apply Host.VerticalScrollBarVisibility
            contentEditableDivStyle.overflowY = ScrollBarVisibilityToHtmlString(Host.VerticalScrollBarVisibility) ?? "hidden";

            contentEditableDivStyle.outline    = "solid transparent"; // Note: this is to avoind having the weird border when it has the focus. I could have used outlineWidth = "0px" but or some reason, this causes the caret to not work when there is no text.
            contentEditableDivStyle.background = "solid transparent";
            contentEditableDivStyle.cursor     = "text";

            // Apply TextAlignment
            UpdateTextAlignment(contentEditableDivStyle, Host.TextAlignment);

            string isContentEditable = (!isReadOnly).ToString().ToLower();

            INTERNAL_HtmlDomManager.SetDomElementAttribute(contentEditableDiv, "contentEditable", isContentEditable);
            this.INTERNAL_OptionalSpecifyDomElementConcernedByFocus = contentEditableDiv;
            this.INTERNAL_OptionalSpecifyDomElementConcernedByMinMaxHeightAndWidth = contentEditableDiv;

            contentEditableDivStyle.minWidth  = "14px";
            contentEditableDivStyle.minHeight = (Math.Floor(this.Host.FontSize * 1.5 * 1000) / 1000).ToInvariantString() + "px"; // Note: We multiply by 1000 and then divide by 1000 so as to only keep 3 decimals at the most. //Note: setting "minHeight" is for FireFox only, because other browsers don't seem to need it. The "1.5" factor is here to ensure that the resulting Height is the same as that of the PasswordBox.

            // Fix for Internet Explorer: when pressing Enter in the ContentEditable div, IE will create a new paragraph, which results in graphical issues to the distance between paragraphs. To fix this issue, we put an empty DIV inside by default. When IE detects that there are DIVs inside, it adds a new DIV instead of creating a new paragraph when the user presses Enter.
            if (INTERNAL_HtmlDomManager.IsInternetExplorer())
            {
                object divToImproveIELineBreaks;
                var    divToImproveIELineBreaksStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("div", contentEditableDiv, this, out divToImproveIELineBreaks);
            }

            domElementWhereToPlaceChildren = contentEditableDiv;

            // Set the mark saying that the pointer events must be "absorbed" by the TextBox:
            INTERNAL_HtmlDomManager.SetDomElementProperty(outerDiv, "data-absorb-events", true);

            //-----------------------
            // Prepare to raise the "TextChanged" event and to update the value of the "Text" property when the DOM text changes:
            //-----------------------
            //todo: why did we put this here instead of in INTERNAL_AttachToDomEvents?
            if (IsRunningOnInternetExplorer())
            {
                //-----------------------
                // Fix "input" event not working under IE:
                //-----------------------
                this.GotFocus  += InternetExplorer_GotFocus;
                this.LostFocus += InternetExplorer_LostFocus;
                INTERNAL_EventsHelper.AttachToDomEvents("textinput", contentEditableDiv, (Action <object>)(e =>
                {
                    InternetExplorer_RaiseTextChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("paste", contentEditableDiv, (Action <object>)(e =>
                {
                    InternetExplorer_RaiseTextChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("cut", contentEditableDiv, (Action <object>)(e =>
                {
                    InternetExplorer_RaiseTextChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("keyup", contentEditableDiv, (Action <object>)(e =>
                {
                    InternetExplorer_RaiseTextChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("delete", contentEditableDiv, (Action <object>)(e =>
                {
                    InternetExplorer_RaiseTextChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("mouseup", contentEditableDiv, (Action <object>)(e =>
                {
                    InternetExplorer_RaiseTextChangedIfNecessary();
                }));
            }
            else
            {
                //-----------------------
                // Modern browsers
                //-----------------------
                INTERNAL_EventsHelper.AttachToDomEvents("input", contentEditableDiv, (Action <object>)(e =>
                {
                    TextAreaValueChanged();
                }));
            }

            //-----------------------
            // Prevent pressing Enter for line break when "AcceptsReturn" is false and prevent pressing any other key than backspace when "MaxLength" is reached:
            // Also prevent the default event when pressing tab and add "\t" when "AcceptsTab" is set to true:
            //-----------------------
            if (IsRunningInJavaScript())
            {
#if OPENSILVER
                throw new InvalidOperationException();
#elif BRIDGE
                //BRIDGETODO : here the code below works weird
                // instance = this
                // makes instance working properly, where it shouldn't
                //Note: I think the reason why instance = this works is because it is set with the correct context of "this",
                //      so instance = this TextBox. If it was inside the function defined as callback of addEventListener,
                //      "this" would be in the context of the event triggered, so it would be the contentEditable div.
                Bridge.Script.Write(@"
var instance = $1;
$0.addEventListener('keydown', function(e) {
    if (e.keyCode == 13 && instance.AcceptsReturn !== true)
    {
        e.preventDefault();
        return false;
    }

    var isAddingTabulation = e.keyCode == 9 && instance.AcceptsTab == true;
    var isRemovingTabulation = isAddingTabulation && e.shiftKey;
    if(isRemovingTabulation)
    {
        isAddingTabulation = false
    }

    if((isAddingTabulation || e.keyCode == 13 || e.keyCode == 32 || e.keyCode > 47) && instance.MaxLength != 0)
    {
        var textLength = instance.GetTextLengthIncludingNewLineCompensation();

        if (e.keyCode == 13)
        {
            textLength += 1; //because adding a new line takes 2 characters instead of 1.
        }
        if(textLength >= instance.MaxLength)
        {
            e.preventDefault();
            return false;
        }
    }

    if(isAddingTabulation)
    {
        //we need to add '\t' where the cursor is, prevent the event (which would change the focus) and dispatch the event for the text changed:
        var sel, range;
        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.rangeCount) {
                range = sel.getRangeAt(0);
                range.deleteContents();
                range.insertNode(document.createTextNode('\t'));
                sel.collapseToEnd();
                range.collapse(false); //for IE
            }
        } else if (document.selection && document.selection.createRange) {
            range = document.selection.createRange();
            range.text = '\t';
            document.selection.collapseToEnd();
        }
        if (window.IS_EDGE)
        {
            sel.removeAllRanges();
            sel.addRange(range);
        }

        instance.TextAreaValueChanged(); //todo: test this.
        e.preventDefault();
            return false;
    }
    if (isRemovingTabulation)
    {
        var sel, range;
        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.rangeCount) {
                range = sel.getRangeAt(0);
                if(range.collapsed)
                {
                    //if the previous character is a '\t', we want to remove it:
                    var rangeStartContainer = range.startContainer;
                    var rangeStartOffset = range.startOffset;

                    //we get the node that contains the text that needs changing and the index of the character to remove:
                    var textNodeToModify = undefined;
                    var indexToRemove = -1;
                    if(rangeStartContainer.nodeType == Node.TEXT_NODE && rangeStartOffset > 0)
                    {
        
                        textNodeToModify = rangeStartContainer;
                        indexToRemove = rangeStartOffset - 1;
                    }
                    else //The potential tab to remove is in the node that is right before the selection(caret) so we look at the last character of the 'previous sibling':
                    {
                        var previousSibling = undefined;

                        // we get the previous node:
                        if(rangeStartContainer.nodeType == Node.TEXT_NODE) //the caret was right before the first element of a textNode. I am not sure if we can arrive here since this case seems to be considered as 'the caret is between the nodes' instead of 'the caret is in the node but before the first character'
                        {
                            previousSibling = rangeStartContainer.previousSibling;
                        }
                        else //the caret is considered between nodes so the range container is the element that contains the text nodes.
                        {
                            if(rangeStartOffset > 0) //otherwise, we are at the first character inside a new div (or p), which means at the start of a new line so nothing to remove.
                            {
                                previousSibling = rangeStartContainer.childNodes[rangeStartOffset -1];
                            }
                        }

                        //We update the node and index to modify:
                        if(previousSibling != undefined && previousSibling.nodeType == Node.TEXT_NODE)
                        {
                            textNodeToModify = previousSibling;
                            indexToRemove = previousSibling.textContent.length - 1;
                        } //else, the previous node was not a text node so there has to be a new line between the caret and the previous text so nothing to remove here.
                    }
        
                    if(textNodeToModify != undefined && indexToRemove != -1)
                    {
                        //range.startContainer.textContent = range.startContainer.textContent.substring(rangeStartOffset)
                        var textContent = textNodeToModify.textContent;
                        if(textContent[indexToRemove] == '\t')
                        {
                            var resultingString = textContent.substring(0, indexToRemove); //note: text.substring(0,-1) returns ""
                            resultingString += textContent.substring(indexToRemove + 1); //note: 'aaa'.substring(25) returns ""
                            textNodeToModify.textContent = resultingString;
                        }
                    }
    
                }
            }
        }
        //todo: else.
        instance.TextAreaValueChanged(); //todo: test this.
        e.preventDefault();
            return false;
    }

}, false);", contentEditableDiv, this);//AcceptsReturn, MaxLength
#endif
            }
#if OPENSILVER
            else
            {
                // ---- SIMULATOR ----
                string uid = ((INTERNAL_HtmlDomElementReference)contentEditableDiv).UniqueIdentifier;

                // Set the "data-accepts-return" property (that we have invented) so that the "KeyDown" and "Paste" JavaScript events can retrieve this value:
                // also set the "data-maxlength" and the "data-isreadonly"
                INTERNAL_HtmlDomManager.ExecuteJavaScript($@"
var element = document.getElementByIdSafe(""{uid}"");
element.setAttribute(""data-acceptsreturn"", ""{this.Host.AcceptsReturn.ToString().ToLower()}"");
element.setAttribute(""data-maxlength"", ""{this.Host.MaxLength}"");
element.setAttribute(""data-isreadonly"",""{isReadOnly.ToString().ToLower()}"");
element.setAttribute(""data-acceptstab"", ""{this.Host.AcceptsTab.ToString().ToLower()}"");");

                // Register the "keydown" javascript event:
                INTERNAL_HtmlDomManager.ExecuteJavaScript($@"
var element_OutsideEventHandler = document.getElementByIdSafe(""{uid}"");
element_OutsideEventHandler.addEventListener('keydown', function(e) {{

    var element_InsideEventHandler = document.getElementByIdSafe(""{uid}""); // For some reason we need to get again the reference to the element.
    var acceptsReturn = element_InsideEventHandler.getAttribute(""data-acceptsreturn"");
    var maxLength = element_InsideEventHandler.getAttribute(""data-maxlength"");
    var acceptsTab = element_InsideEventHandler.getAttribute(""data-acceptstab"");

    if (e.keyCode == 13)
    {{
        if(acceptsReturn != ""true"")
        {{
            e.preventDefault();
            return false;
        }}
    }}

    var isAddingTabulation = e.keyCode == 9 && acceptsTab == ""true"";

    if((isAddingTabulation || e.keyCode == 13 || e.keyCode == 32 || e.keyCode > 47) && maxLength != 0)
    {{
        var text = getTextAreaInnerText(element_InsideEventHandler);
        if (!acceptsReturn) {{
            text = text.replace(""\n"", """").replace(""\r"", """");
        }}

        var correctionDueToNewLines = 0;
        if (e.keyCode == 13)
        {{
            ++correctionDueToNewLines; //because adding a new line takes 2 characters instead of 1.
        }}
        if(text.length + correctionDueToNewLines >= maxLength)
        {{
            if (!window.getSelection().toString()) {{
                e.preventDefault();
                return false;
            }}
        }}
    }}

    if(isAddingTabulation)
    {{
        //we need to add '\t' where the cursor is, prevent the event (which would change the focus) and dispatch the event for the text changed:
        var sel, range;
        if (window.getSelection) {{
            sel = window.getSelection();
            if (sel.rangeCount) {{
                range = sel.getRangeAt(0);
                range.deleteContents();
                range.insertNode(document.createTextNode('\t'));
                sel.collapseToEnd();
                range.collapse(false); //for IE
            }}
        }} else if (document.selection && document.selection.createRange) {{
            range = document.selection.createRange();
            range.text = '\t';
            document.selection.collapseToEnd();
        }}
        if (window.IS_EDGE)
        {{
            sel.removeAllRanges();
            sel.addRange(range);
        }}

        instance.TextAreaValueChanged(); //todo: test this.
        e.preventDefault();
            return false;
    }}
}}, false);");//comma added on purpose because we need to get maxLength somehow (see how we did for acceptsReturn).
            }
#endif

            //-----------------------
            // Enforce only Plain Text + prevent line breaks if "AcceptsReturn" is false. This is required because in a ContentEditable div, the user can paste rich text. Furthermore, on IE, pressing Enter will insert a new paragraph.
            //-----------------------
            if (IsRunningInJavaScript())
            {
#if OPENSILVER
                throw new InvalidOperationException();
#elif BRIDGE
                var acceptsReturn = this.Host.AcceptsReturn;
                //todo: shouldn't we add a check for maxlength in the script below like in the other versions of this addEventListenter (in the simulator version below and in the #if !BRIDGE part above)?
                Bridge.Script.Write(@"
{0}.addEventListener('paste', function(e) {
    var isReadOnly= {1};
    if(!isReadOnly)
    {
        var isSingleLine = ({2} !== true); // This is the current value at the time when the event is raised.
        // Chrome supports setting ContentEditable to PlainText-Only, so we try this first:
        {0}.setAttribute('contenteditable', 'PLAINTEXT-ONLY');
        if ({0}.contentEditable === 'plaintext-only') // If setting the attribute worked, we can read it back (in lowercase)
        {
          // --- CHROME: ---
          // Nothing else to do about rich text conversion to plain text.
          // However we still need to remove line breaks if AcceptsReturn is false:
          if (isSingleLine){
            e.preventDefault();
            var content = (e.originalEvent || e).clipboardData.getData('text/plain');
            content = content.replace(/\n/g, '').replace(/\r/g, '');
            document.execCommand('insertText', false, content);
          }
    }
    else
        {
          {0}.setAttribute('contenteditable', 'true');
          if (e.clipboardData){

            // --- FIREFOX: ---
            e.preventDefault();
            var content = (e.originalEvent || e).clipboardData.getData('text/plain');
            if (isSingleLine){
              content = content.replace(/\n/g, '').replace(/\r/g, '');
            }
            document.execCommand('insertText', false, content);
          }
          else if (window.clipboardData){

            // --- INTERNET EXPLORER: ---
            e.preventDefault();
            var content = window.clipboardData.getData('Text');
            if (window.getSelection)
            {
              var newDiv = document.createElement('div');
              if (isSingleLine){
                content = content.replace(/\n/g, '').replace(/\r/g, '');
              }
              content = content.replace(/\r\n/g, '<br />');
              newDiv.innerHTML = content.replace(/\n/g, '<br />');
              var range = window.getSelection().getRangeAt(0);
              range.deleteContents()
              range.insertNode( newDiv );
              //window.getSelection().getRangeAt(0).insertNode( document.createTextNode(content) );
            }
          }
      }
            }
  
}, false);", contentEditableDiv, isReadOnly, acceptsReturn);
                //BRIDGETODO : check the code up
#endif
            }
#if OPENSILVER
            else
            {
                // ---- SIMULATOR ----
                string uid = ((INTERNAL_HtmlDomElementReference)contentEditableDiv).UniqueIdentifier;

                // The simulator uses Chrome, so we can set "ContentEditable" to plain-text only:
                // We still need to prevent prevent line breaks in the pasted text if "AcceptsReturn" is false:
                INTERNAL_HtmlDomManager.ExecuteJavaScript($@"
var element_OutsideEventHandler = document.getElementByIdSafe(""{uid}"");
element_OutsideEventHandler.addEventListener('paste', function(e) {{
    var element_InsideEventHandler = document.getElementByIdSafe(""{uid}""); // For some reason we need to get again the reference to the element.
    var isReadOnly= element_InsideEventHandler.getAttribute(""data-isreadonly"");
    if(isReadOnly !=""true"")
    {{
        var acceptsReturn = element_InsideEventHandler.getAttribute(""data-acceptsreturn"");
        var maxLength = element_InsideEventHandler.getAttribute(""data-maxlength"");
        element_InsideEventHandler.setAttribute(""contentEditable"", ""PLAINTEXT-ONLY"");
        if (acceptsReturn != ""true""){{
            e.preventDefault();
            var content = (e.originalEvent || e).clipboardData.getData('text/plain');
           if(content !== undefined){{
                content = content.replace(/\n/g, '').replace(/\r/g, '');
            }}
            if(maxLength != 0) {{
                var text = getTextAreaInnerText(element_InsideEventHandler);
                //var text = element_InsideEventHandler.innerText;
                if (!acceptsReturn) {{
                    text = text.replace(""\n"", """").replace(""\r"", """");
                }}

                var correctionDueToNewLines = 0;
                var textBoxTextLength = text.length + correctionDueToNewLines;
                var lengthComparison = maxLength - (content.length + textBoxTextLength);
                if(lengthComparison < 0) {{
                    content = content.substr(0, content.length+lengthComparison);
                }}
            }}
            document.execCommand('insertText', false, content);
        
        }}
    }}
    

}}, false);");
            }
#endif

            return(outerDiv);
        }
예제 #14
0
        private object AddPasswordInputDomElement(object parentRef, out object domElementWhereToPlaceChildren, bool isTemplated)
        {
            object passwordField;
            var    passwordFieldStyle = INTERNAL_HtmlDomManager.CreateDomElementAppendItAndGetStyle("input", parentRef, this, out passwordField);

            this.INTERNAL_OptionalSpecifyDomElementConcernedByFocus = passwordField;

            _passwordInputField = passwordField;

            domElementWhereToPlaceChildren = passwordField;           // Note: this value is used by the Padding_Changed method to set the padding of the PasswordBox.

            passwordFieldStyle.border          = "transparent";       // This removes the border. We do not need it since we are templated
            passwordFieldStyle.outline         = "solid transparent"; // Note: this is to avoind having the weird border when it has the focus. I could have used outlineWidth = "0px" but or some reason, this causes the caret to not work when there is no text.
            passwordFieldStyle.backgroundColor = "transparent";
            passwordFieldStyle.fontSize        = "inherit";           // Not inherited by default for "input" DOM elements

            passwordFieldStyle.width  = "100%";
            passwordFieldStyle.height = "100%";

            INTERNAL_HtmlDomManager.SetDomElementAttribute(passwordField, "type", "password", forceSimulatorExecuteImmediately: true);

            //-----------------------
            // Prepare to raise the "TextChanged" event and to update the value of the "Text" property when the DOM text changes:
            //-----------------------
            //todo: why did we put this here instead of in INTERNAL_AttachToDomEvents?
            if (IsRunningOnInternetExplorer())
            {
                //-----------------------
                // Fix "input" event not working under IE:
                //-----------------------
                this.GotFocus  += InternetExplorer_GotFocus;
                this.LostFocus += InternetExplorer_LostFocus;
                INTERNAL_EventsHelper.AttachToDomEvents("textinput", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("paste", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("cut", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("keyup", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("delete", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
                INTERNAL_EventsHelper.AttachToDomEvents("mouseup", passwordField, (Action <object>)(e =>
                {
                    InternetExplorer_RaisePasswordChangedIfNecessary();
                }));
            }
            else
            {
                //-----------------------
                // Modern browsers
                //-----------------------
                INTERNAL_EventsHelper.AttachToDomEvents("input", passwordField, (Action <object>)(e =>
                {
                    PasswordAreaValueChanged();
                }));
            }

            return(passwordField);
        }