From: Argiris K. <be...@us...> - 2005-11-11 06:17:58
|
Update of /cvsroot/magicajax/magicajax/Core/UI In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6302/Core/UI Added Files: AjaxControl.cs AjaxPage.cs AjaxUserControl.cs RenderedByScriptControl.cs Log Message: Put source files to module 'magicajax' divided in directories Core, Examples, and CustomControls. --- NEW FILE: AjaxUserControl.cs --- #region LGPL License /* MagicAjax Library Copyright (C) 2005 MagicAjax Project Team This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #endregion using System; using System.Web; namespace MagicAjax.UI { /// <summary> /// Includes the CallBack event, Context, Request and Response, for convenience. /// </summary> /// <remarks> /// You can implement the ICallBackEventHandler on your usercontrol to handle the /// CallBack event, and use the HttpContext.Current, CallBackHelper.Request and /// CallBackHelper.Response properties. /// /// You cannot use the Context, Request and Response of the System.Web.UI.UserControl /// because, during a CallBack, the Context of the page is invalid. If you don't want /// to replace the UserControl.Request and UserControl.Response from your code for /// CallBackHelper.Request and CallBackHelper.Response, and your usercontrol is inherited /// from System.Web.UI.UserControl, you can use AjaxUserControl for convenience. /// </remarks> public class AjaxUserControl : System.Web.UI.UserControl, ICallBackEventHandler { /// <summary> /// Raised by MagicAjaxModule when a CallBack occurs /// </summary> public event EventHandler CallBack; /// <summary> /// The base UserControl Request property doesn't work during a CallBack. Use this instead. /// </summary> public new HttpRequest Request { get { return Context.Request; } } /// <summary> /// The base UserControl Response property doesn't work during a CallBack. Use this instead. /// </summary> public new HttpResponse Response { get { return Context.Response; } } /// <summary> /// Raises the CallBack event. /// </summary> /// <remarks> /// Called by MagicAjaxModule. /// </remarks> public void RaiseCallBackEvent() { OnCallBack (EventArgs.Empty); } protected override HttpContext Context { get { return HttpContext.Current; } } protected virtual void OnCallBack(EventArgs e) { if (CallBack != null) CallBack(this, e); } } } --- NEW FILE: AjaxPage.cs --- #region LGPL License /* MagicAjax Library Copyright (C) 2005 MagicAjax Project Team This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #endregion using System; using System.Web; namespace MagicAjax.UI { /// <summary> /// Includes the CallBack event, Context, Request and Response, for convenience. /// </summary> /// <remarks> /// Inhering from AjaxPage is not required to apply AJAX on your pages. You can /// implement the ICallBackEventHandler on your page to handle the CallBack event, and /// use the HttpContext.Current, CallBackHelper.Request and CallBackHelper.Response /// properties. /// /// You cannot use the Context, Request and Response of the System.Web.UI.Page /// because, during a CallBack, the Context of the page is invalid. If you don't want /// to replace the Page.Request and Page.Response from your code for /// CallBackHelper.Request and CallBackHelper.Response, and your page is inherited /// from System.Web.UI.Page, you can use AjaxPage for convenience. /// </remarks> public class AjaxPage : System.Web.UI.Page, ICallBackEventHandler { /// <summary> /// Raised by MagicAjaxModule when a CallBack occurs /// </summary> public event EventHandler CallBack; /// <summary> /// The base Page Request property doesn't work during a CallBack. Use this instead. /// </summary> public new HttpRequest Request { get { return Context.Request; } } /// <summary> /// The base Page Response property doesn't work during a CallBack. Use this instead. /// </summary> public new HttpResponse Response { get { return Context.Response; } } /// <summary> /// Raises the CallBack event. /// </summary> /// <remarks> /// Called by MagicAjaxModule. /// </remarks> public void RaiseCallBackEvent() { OnCallBack (EventArgs.Empty); } protected override HttpContext Context { get { return HttpContext.Current; } } protected virtual void OnCallBack(EventArgs e) { if (CallBack != null) CallBack(this, e); } } } --- NEW FILE: AjaxControl.cs --- #region LGPL License /* MagicAjax Library Copyright (C) 2005 MagicAjax Project Team This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #endregion using System; using System.Web.UI; using System.Web.UI.WebControls; using System.ComponentModel; namespace MagicAjax.UI { /// <summary> /// The base control for controls to get notified for callback events from the client. /// </summary> public class AjaxControl : System.Web.UI.WebControls.WebControl, ICallBackEventHandler { /// <summary> /// Raised by the MagicAjaxModule. /// </summary> public event EventHandler CallBack; /// <summary> /// Implements the ICallBackEventHandler interface. It is called by the MagicAjaxModule. /// </summary> public void RaiseCallBackEvent() { OnCallBack(EventArgs.Empty); } public bool IsPageNoStoreMode { get { return (MagicAjaxModule.Instance.Configuration.PageStore.Mode == Configuration.PageStoreMode.NoStore); } } public AjaxControl() { } public AjaxControl(HtmlTextWriterTag tag) : base(tag) { } protected override void OnPreRender(EventArgs e) { // Register 'CallBackObject.js' script MagicAjaxModule.Instance.EnableAjaxOnPage(this.Page); base.OnPreRender (e); } protected virtual void OnCallBack(EventArgs e) { if (CallBack != null) CallBack(this, e); } } } --- NEW FILE: RenderedByScriptControl.cs --- #region LGPL License /* MagicAjax Library Copyright (C) 2005 MagicAjax Project Team This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #endregion using System; using System.Web.UI; using System.Web.UI.WebControls; using System.ComponentModel; namespace MagicAjax.UI { #region Public Class RenderStartEventArgs /// <summary> /// It contains the HtmlTextWriter writer event argument to be used during a /// RenderStart event. /// </summary> public class RenderStartEventArgs : EventArgs { private bool abortRendering = false; private HtmlTextWriter writer; public bool AbortRendering { get { return abortRendering; } set { abortRendering = value; } } public HtmlTextWriter Writer { get { return writer; } } public RenderStartEventArgs(HtmlTextWriter writer) { this.writer = writer; } } #endregion /// <summary> /// The event handler for a RenderStart event. /// </summary> public delegate void RenderStartEventHandler(object sender, RenderStartEventArgs e); /// <summary> /// This control manages its appearance on the page using javascript that sends /// to the client during a CallBack. /// </summary> /// <remarks> /// It provides the basic functionality for controls like AjaxPanel. It manages /// its tag attributes using javascript. /// </remarks> public abstract class RenderedByScriptControl : AjaxControl, IPreWriteScriptEventHandler, IScriptWriter { protected abstract void RenderByScript(); private bool _isRenderedOnPage = false; private bool _monitorVisibilityState = true; private string _currentTagHtml = null; private bool _isHtmlRendered = false; public event RenderStartEventHandler RenderStart; public event EventHandler RenderEnd; public event EventHandler PreWriteScript; public override bool Visible { get { return base.Visible; } set { if ( CallBackHelper.IsCallBack && IsRenderedOnPage && MonitorVisibilityState && value != base.Visible ) CallBackHelper.WriteSetVisibilityOfElementScript (ClientID, value); base.Visible = value; } } /// <summary> /// Determines whether the RenderedByScriptControl control has been rendered /// on the page, either by normal rendering or by script. /// </summary> /// <remarks> /// IsRenderedOnPage is set to true during a normal rendering or a rendering /// by script. It is set to false at WriteScript method when the Visible property /// is false. /// </remarks> [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsRenderedOnPage { get { return _isRenderedOnPage; } } /// <summary> /// Gets or sets whether every time "Visible" property is changed /// CallBackHelper.WriteSetVisibilityOfElementScript method should be called. /// Default is true. /// </summary> /// <remarks> /// If this property is true, every time you change the "Visible" property during a /// CallBack, the display attribute of the style of the control on the page will /// be set to "" or "none" by calling the CallBackHelper.WriteSetVisibilityOfElementScript /// method. /// </remarks> [Bindable(false), Category("Behavior"), DefaultValue(true)] public bool MonitorVisibilityState { get { return _monitorVisibilityState; } set { _monitorVisibilityState = value; } } /// <summary> /// Returns the tag name of the control. /// </summary> /// <returns></returns> public string GetTagName() { return TagKey.ToString(); } public RenderedByScriptControl() { this.ID = ""; } public RenderedByScriptControl(HtmlTextWriterTag tag) : base(tag) { this.ID = ""; } /// <summary> /// It defines whether the RenderedByScriptControl was already rendered during /// a normal rendering. /// </summary> /// <remarks> /// The RenderedByScriptControl can be normally rendered by the Render method /// even during a CallBack (i.e when all the controls of an AjaxPanel is new /// and the AjaxPanel renders all of them in a single html rendering). /// In this case it's not necessary to send any javascript to the client. /// </remarks> protected bool IsHtmlRendered { get { return _isHtmlRendered; } } protected override void OnCallBack(EventArgs e) { _isHtmlRendered = false; base.OnCallBack(e); } protected override void OnPreRender(EventArgs e) { if ( ! IsChildOfRenderedByScriptControl(this) ) { // Firefox, when performing a refresh, loads the page but keeps any INPUT // field values. Thus, the html of a RenderedByScriptControl is restored // as if the page was loaded because of the browser's "Back Button". // To resolve this, the name of the storing fields is different for // each page request. string hiddenStore = this.ClientID + "$RBS_Store" + DateTime.Now.Ticks; Page.RegisterHiddenField(hiddenStore, null); Page.RegisterArrayDeclaration("RBS_Controls", String.Format("document.all[\"{0}$RBS_Holder\"]", this.ClientID)); Page.RegisterArrayDeclaration("RBS_Controls_Store", String.Format("document.all[\"{0}\"]", hiddenStore)); } base.OnPreRender (e); } protected bool IsChildOfRenderedByScriptControl(Control control) { if (control.Parent == null || control.Parent == control.Page) return false; else if (control.Parent is RenderedByScriptControl) return true; else return IsChildOfRenderedByScriptControl(control.Parent); } /// <summary> /// Normal rendering. /// </summary> /// <remarks> /// It raises the RenderStart and RenderEnd events. If the rendering is not /// aborted during the RenderStart event, it renders the control and sets /// the _isHtmlRendered variable to true. /// </remarks> /// <param name="writer"></param> protected override void Render(HtmlTextWriter writer) { if ( IsPageNoStoreMode ) _isRenderedOnPage = true; RenderStartEventArgs eventArgs = new RenderStartEventArgs(writer); OnRenderStart(eventArgs); if (!eventArgs.AbortRendering) { // Put the html of this control inside a SPAN tag so that it can // be saved and restored when the page is loaded from the Browser's cache, // i.e. when the back button is pressed. writer.Write("<span id='{0}$RBS_Holder'>", this.ClientID); base.Render (writer); writer.Write("</span>"); _isHtmlRendered = true; _isRenderedOnPage = true; } OnRenderEnd(EventArgs.Empty); } /// <summary> /// It stores the tag html for later checking. /// </summary> /// <param name="writer"></param> public override void RenderBeginTag(HtmlTextWriter writer) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); HtmlTextWriter strwriter = new HtmlTextWriter(new System.IO.StringWriter(sb)); base.RenderBeginTag (strwriter); _currentTagHtml = sb.ToString(); base.RenderBeginTag (writer); } /// <summary> /// Called by MagicAjaxModule /// </summary> public virtual void RaisePreWriteScriptEvent() { OnPreWriteScript (EventArgs.Empty); } /// <summary> /// If the tag html of the control is changed, send the attributes using javascript. /// </summary> /// <returns>True if rendering by script was needed, False if it was not</returns> public virtual void WriteScript() { if ( ! this.Visible ) { _isRenderedOnPage = false; return; } // If there was a normal rendering, javascript is not needed if (IsHtmlRendered) return; if ( ! IsRenderedOnPage ) { Control con = FindNextVisibleSibling(); CallBackHelper.WriteAddElementScript (Parent.ClientID, this.GetTagName(), this.ClientID, "", (con == null) ? null : con.ClientID); } System.Text.StringBuilder sb = new System.Text.StringBuilder(); HtmlTextWriter strwriter = new HtmlTextWriter(new System.IO.StringWriter(sb)); // Take care of the tag of the control base.RenderBeginTag (strwriter); string html = sb.ToString(); sb.Length = 0; if(_currentTagHtml != html) { CallBackHelper.WriteSetAttributesOfControl (ClientID, FormatAttributes(html)); _currentTagHtml = html; } this.RenderByScript(); _isRenderedOnPage = true; } protected virtual void OnRenderStart(RenderStartEventArgs eventArgs) { if (RenderStart != null) RenderStart(this, eventArgs); } protected virtual void OnRenderEnd(EventArgs e) { if (RenderEnd != null) RenderEnd(this, e); } protected virtual void OnPreWriteScript(EventArgs e) { if (PreWriteScript != null) PreWriteScript(this, e); } /// <summary> /// Finds the next visible control of the control collection of this /// control's parent that has its ID attribute set. /// </summary> /// <returns></returns> private Control FindNextVisibleSibling() { for (int i=Parent.Controls.IndexOf(this) + 1; i < Parent.Controls.Count; i++) { Control con = Parent.Controls[i]; if (con.Visible && con.ID != null) return con; } return null; } /// <summary> /// It finds the attributes from the html of the control's tag, and formats them /// so that they are send by CallBackHelper.WriteSetAttributesOfControl method. /// </summary> /// <param name="html">The html tag of the control</param> /// <returns></returns> private string FormatAttributes(string html) { System.Text.StringBuilder sb = new System.Text.StringBuilder(html); System.Text.StringBuilder attribs = new System.Text.StringBuilder(); int mode = 0; for (int i=0; i < sb.Length; i++) { char ch = sb[i]; if (ch == '>') break; switch (mode) { case 0: if (ch == ' ') mode++; break; case 1: switch (ch) { case '\"': mode++; break; case ' ': attribs.Append ('|'); break; default: attribs.Append (ch); break; } break; case 2: if (ch == '\"') mode--; else attribs.Append (ch); break; } } return attribs.ToString(); } } } |