예제 #1
0
        private static void ProcessCss(TemplateControl rootControl, string strRawCss)
        {
            // has this template been processed before?
            string strControlType = rootControl.GetType().FullName;
            bool bIsNewStyleSet = false;
            Dictionary hash_xidsToCssClasses = (Dictionary)_hash_processedCss[strControlType] ?? null;
            if (hash_xidsToCssClasses == null)
            {
                hash_xidsToCssClasses = new Dictionary();
                bIsNewStyleSet = true;
            }

            //////
            // rewrite css rules if this is the first time loading this control.
            if (bIsNewStyleSet)
            {
                string strProcessedCss = strRawCss;

                // rerewrite element id references
                strProcessedCss = strProcessedCss.ReplaceRegex(
                    new RegularExpression(@"#[a-zA-Z]\w*", "g"),
                    delegate(string s)
                    {
                        string sSub = s.Substr(1);

                        // if #this
                        if (sSub == "this")
                        {
                            hash_xidsToCssClasses[sSub] = (string)hash_xidsToCssClasses[sSub] ?? GenerateNewAutoCssClass();
#if DEBUG
                            return "." + (string)hash_xidsToCssClasses[sSub] + "/* " + s + " */";
#else
                            return "." + (string)hash_xidsToCssClasses[sSub];
#endif
                        }

                        // if #someLocalId (element)
                        jQueryObject jqElement = (jQueryObject)rootControl._hash_oNamedChildElements[sSub] ?? null;
                        if (jqElement != null)
                        {
                            hash_xidsToCssClasses[sSub] = (string)hash_xidsToCssClasses[sSub] ?? GenerateNewAutoCssClass();
#if DEBUG
                            return "." + (string)hash_xidsToCssClasses[sSub] + "/* " + s + " */";
#else
                            return "." + (string)hash_xidsToCssClasses[sSub];
#endif
                        }

                        // if #someLocalId (control)
                        TemplateControl oControl = (TemplateControl)rootControl._hash_oNamedChildControls[sSub] ?? null;
                        if (oControl != null)
                        {
                            hash_xidsToCssClasses[sSub] = (string)hash_xidsToCssClasses[sSub] ?? GenerateNewAutoCssClass();
#if DEBUG
                            return "." + (string)hash_xidsToCssClasses[sSub] + "/* " + s + " */";
#else
                            return "." + (string)hash_xidsToCssClasses[sSub];
#endif
                        }

                        // unknown. keep.
                        return s;
                    }
                );

                // rewrite url paths
                bool isIE = jQuery.Browser.MSIE;
                string cssBaseUrl = BaseUrlImages;
                if (cssBaseUrl.Length > 0 || isIE)
                {
                    RegularExpression rxUrl = new RegularExpression(@"url\w*\((.*)\)", "i");
                    Func<string, bool> fnIsAbsolute = delegate(string url)
                    {
                        return url.StartsWith("http://") || url.StartsWith("https://");
                    };
                    string currentProtocolDomain;
                    {
                        Location loc = Window.Location;
                        currentProtocolDomain
                            = loc.Protocol
                            + "//"
                            + loc.HostnameAndPort
                            + "/"
                        ;
                    }
                    strProcessedCss = strProcessedCss.ReplaceRegex(
                        new RegularExpression(@":\w*url\w*\(""?.*""?\)", "ig"),
                        delegate(string s)
                        {
                            string[] matches = rxUrl.Exec(s);
                            Debug.Assert(matches.Length == 2);

                            string url = matches[1];
                            if (fnIsAbsolute(url))
                            {
                                // already absolute. no change needed.
                                return s;
                            }

                            // prepend base url
                            url = CombinePaths(cssBaseUrl, url);

                            if (isIE && !fnIsAbsolute(url))
                            {
                                // rewrite url()'s to be absolute (workaround for IE7/8/9 bug with relative paths in dynamically added css in iframes).
                                url = CombinePaths(currentProtocolDomain, url);
                            }

                            return string.Format(@":url(""{0}"")", url);
                        }
                    );
                }

                _processedCss = _processedCss + " " + strProcessedCss;

                
                // update global style
                jQueryObject jqHead = jQuery.Select("head");
                jQueryObject jqStyle;


                if (jQuery.Browser.MSIE)
                {
                    // if IE, we need to concat all style rules (otherwise hit a max css node limit in ie)

                    // is there an existing global css node?
                    jqStyle = jQuery.Select("#" + CssGlobalNodeId);
                    Number ieVersion = Number.ParseDouble(jQuery.Browser.Version);

                    // setting inner html does not work on IE8. so we do a string concat here instead.
                    if (Number.IsFinite(ieVersion) && ieVersion <= 8)
                    {
                        // remove existing global style node if exists.
                        if (jqStyle.Length != 0)
                        {
                            jqStyle.Remove();
                        }

                        // build new global style node.
                        jqStyle = jQuery.FromHtml(@"<style type=""text/css"">" + _processedCss + @"</style>");
                        jqStyle.Attribute("id", CssGlobalNodeId);
                        jqHead.Append(jqStyle);
                    }
                    else
                    {
                        // create new global style node if missing.
                        if (jqStyle.Length == 0)
                        {
                            jqStyle = jQuery.FromHtml(@"<style type=""text/css""></style>");
                            jqStyle.Attribute("id", CssGlobalNodeId);
                            jqHead.Append(jqStyle);
                        }

                        // modify global style node.
                        jqStyle.Text(_processedCss);
                    }
                }
                else
                {
                    // in non-ie, just append another css node.

                    jqStyle = jQuery.FromHtml(@"<style type=""text/css""></style>");
                    jqStyle.Html(strProcessedCss);
                    jqHead.Append(jqStyle);
                }


                // save rewrite rules
                _hash_processedCss[strControlType] = hash_xidsToCssClasses;
            }

            //////
            // apply classes to named elements
            foreach (DictionaryEntry kvp in hash_xidsToCssClasses)
            {
                string key = kvp.Key;
                if (key == "this")
                {
                    rootControl._jqRootElement.AddClass((string)kvp.Value);
                    continue;
                }

                // is it an element?
                jQueryObject jqElement = (jQueryObject)rootControl._hash_oNamedChildElements[key] ?? null;
                if (jqElement != null)
                {
                    jqElement.AddClass((string)kvp.Value);
                    continue;
                }

                // is it a control?
                TemplateControl oControl = (TemplateControl)rootControl._hash_oNamedChildControls[key] ?? null;
                if (oControl != null)
                {
                    oControl.RootElement.AddClass((string)kvp.Value);
                    continue;
                }

#if DEBUG
                throw new Exception("CSS rule found for no corresponding element/control.");
#endif
            }
        }
예제 #2
0
        /// <summary>
        /// For the given template control, retrieve its html template.
        /// </summary>
        /// <param name="templateControl"></param>
        /// <returns></returns>
        private static string FindTemplate(TemplateControl templateControl)
        {
            string templateTypeName = templateControl.GetType().FullName;
            if (!_hash_templateCache.ContainsKey(templateTypeName))
            {
                string strTemplate = (string)Type.GetField(templateControl, "template");
                if (!string.IsNullOrEmpty(strTemplate))
                {
                    _hash_templateCache[templateTypeName] = strTemplate;
                }
                else
                {
                    // search for a private/obfuscated field
                    foreach (DictionaryEntry kvp in Dictionary.GetDictionary(templateControl))
                    {
                        if (!(kvp.Value is string))
                        {
                            continue;
                        }
                        if (!kvp.Key.StartsWith("$"))
                        {
                            continue;
                        }
                        string strTmp = ((string)kvp.Value).Trim(); // todo: avoid a trim.
                        if (strTmp.StartsWith("<"))
                        {
                            _hash_templateCache[templateTypeName] = kvp.Value;
                        }
                    }
                }
            }

            return (string)(_hash_templateCache[templateTypeName] ?? null);
        }