private BlogEditingTemplate ParseBlogPostIntoTemplate(BlogPostRegionLocatorStrategy regionLocator, IProgressHost progress, string postUrl)
        {
            progress.UpdateProgress(Res.Get(StringId.ProgressCreatingEditingTemplate));

            BlogPostRegions regions            = regionLocator.LocateRegionsOnUIThread(progress, postUrl);
            IHTMLElement    primaryTitleRegion = GetPrimaryEditableTitleElement(regions.BodyRegion, regions.Document, regions.TitleRegions);

            // IF
            //   - primaryTitleRegion is not null (title found)
            //   - BodyRegion is null (no post body found)
            //   - AND primaryTitleRegion is a link
            if (primaryTitleRegion != null && regions.BodyRegion == null && primaryTitleRegion.tagName.ToLower() == "a")
            {
                // Title region was detected, but body region was not.
                // It is possible that only titles are shown on the homepage
                // Try requesting the post itself, and loading regions from the post itself

                // HACK Somewhere the 'about:' protocol replaces http/https, replace it again with the correct protocol
                var pathMatch = new Regex("^about:(.*)$").Match((primaryTitleRegion as IHTMLAnchorElement).href);
                Debug.Assert(pathMatch.Success);                                             // Assert that this URL is to the format we expect
                var newPostPath = pathMatch.Groups[1].Value;                                 // Grab the path from the URL
                var homepageUri = new Uri(_blogHomepageUrl);
                var newPostUrl  = $"{homepageUri.Scheme}://{homepageUri.Host}{newPostPath}"; // Recreate the full post URL

                // Set the NextTryPostUrl flag in the region locater
                // This will indicate to the other thread that another page should be parsed
                _nextTryPostUrl = newPostUrl;
                return(null);
            }

            BlogEditingTemplate template = GenerateBlogTemplate((IHTMLDocument3)regions.Document, primaryTitleRegion, regions.TitleRegions, regions.BodyRegion);

            progress.UpdateProgress(100, 100);
            return(template);
        }
        public BlogEditingTemplateDetector(IBlogClientUIContext uiContext, Control parentControl, IBlogSettingsAccessor blogSettings, bool probeForManifest)
            : this(uiContext, parentControl)
        {
            BlogAccount blogAccount     = new BlogAccount(blogSettings.ServiceName, blogSettings.ClientType, blogSettings.PostApiUrl, blogSettings.HostBlogId);
            string      blogTemplateDir = BlogEditingTemplate.GetBlogTemplateDir(blogSettings.Id);

            SetContext(blogAccount, blogSettings.Credentials, blogSettings.HomepageUrl, blogTemplateDir, blogSettings.ManifestDownloadInfo, probeForManifest, blogSettings.ProviderId, blogSettings.OptionOverrides, blogSettings.UserOptionOverrides, blogSettings.HomePageOverrides);
        }
Beispiel #3
0
        private BlogEditingTemplate ParseBlogPostIntoTemplate(BlogPostRegionLocatorStrategy regionLocator, IProgressHost progress)
        {
            progress.UpdateProgress(Res.Get(StringId.ProgressCreatingEditingTemplate));

            BlogPostRegions     regions            = regionLocator.LocateRegionsOnUIThread(progress);
            IHTMLElement        primaryTitleRegion = GetPrimaryEditableTitleElement(regions.BodyRegion, regions.Document, regions.TitleRegions);
            BlogEditingTemplate template           = GenerateBlogTemplate((IHTMLDocument3)regions.Document, primaryTitleRegion, regions.TitleRegions, regions.BodyRegion);

            progress.UpdateProgress(100, 100);
            return(template);
        }
        /// <summary>
        /// Parses a webpage into an editing template using a marshalled callback on the UI context's thread.
        /// </summary>
        /// <param name="uiContext"></param>
        /// <param name="progress"></param>
        /// <returns></returns>
        private string ParseWebpageIntoEditingTemplate_OnUIThread(Control uiContext, BlogPostRegionLocatorStrategy regionLocator, IProgressHost progress, string postUrl)
        {
            BlogEditingTemplate blogEditingTemplate = (BlogEditingTemplate)uiContext.Invoke(
                new TemplateParser(ParseBlogPostIntoTemplate),
                new object[] {
                regionLocator,
                new ProgressTick(progress, 1, 100),
                postUrl
            });

            return(blogEditingTemplate?.Template);
        }
Beispiel #5
0
        private void DetectWeblogSettingsCompleted(object result)
        {
            // no-op if we don't have a blog detected
            if (HostBlogId == String.Empty)
            {
                return;
            }

            // get the editing template directory
            string blogTemplateDir = BlogEditingTemplate.GetBlogTemplateDir(_localBlogId);

            // set context for template detector
            BlogAccount blogAccount = new BlogAccount(ServiceName, ClientType, PostApiUrl, HostBlogId);

            _blogEditingTemplateDetector.SetContext(blogAccount, _credentials, _homepageUrl, blogTemplateDir, _manifestDownloadInfo, false, _providerId, _optionOverrides, null, _homePageOverrides);
        }
        public void LoadHtmlFragment(string title, string postBodyHtml, string baseUrl, BlogEditingTemplate editingTemplate)
        {
            const int SPACE_BETWEEN_TITLE_AND_BODY = 4;
            if (editingTemplate.ContainsTitle)
            {
                // Make sure the title textbox is showing if there is a title.
                textBoxTitle.Visible = true;
                panelSourceEditor.Top = textBoxTitle.Bottom + SPACE_BETWEEN_TITLE_AND_BODY;
                panelSourceEditor.Height = Height - panelSourceEditor.Top;
                textBoxTitle.Text = title;
            }
            else
            {
                // We need to hide the title textbox if there is no title.
                textBoxTitle.Visible = false;
                panelSourceEditor.Top = textBoxTitle.Top;
                panelSourceEditor.Height = Height - panelSourceEditor.Top;
            }

            //make the post body HTML look pretty
            postBodyHtml = ApplyPostBodyFormatting(postBodyHtml);

            sourceControl.LoadHtmlFragment(postBodyHtml);
            sourceControl.Focus();
        }
        private BlogEditingTemplateFiles SafeGetTemplates(IProgressHost progress)
        {
            WriterEditingManifest    editingManifest = null;
            BlogEditingTemplateFiles templateFiles   = new BlogEditingTemplateFiles();

            try
            {
                // if we have a manifest url then try to get our manifest
                if (_manifestDownloadInfo != null)
                {
                    // try to get the editing manifest
                    string manifestUrl = _manifestDownloadInfo.SourceUrl;
                    editingManifest = WriterEditingManifest.FromUrl(
                        new Uri(manifestUrl),
                        _blogClient,
                        _credentials,
                        true);

                    // progress
                    CheckCancelRequested(progress);
                    progress.UpdateProgress(20, 100);
                }

                // if we have no editing manifest then probe (if allowed)
                if ((editingManifest == null) && _probeForManifest)
                {
                    editingManifest = WriterEditingManifest.FromHomepage(
                        new LazyHomepageDownloader(_blogHomepageUrl, new HttpRequestHandler(_blogClient.SendAuthenticatedHttpRequest)),
                        new Uri(_blogHomepageUrl),
                        _blogClient,
                        _credentials);
                }

                // progress
                CheckCancelRequested(progress);
                progress.UpdateProgress(40, 100);

                // if we got one then return templates from it as-appropriate
                if (editingManifest != null)
                {
                    if (editingManifest.WebLayoutUrl != null)
                    {
                        string webLayoutTemplate = DownloadManifestTemplate(new ProgressTick(progress, 10, 100), editingManifest.WebLayoutUrl);
                        if (BlogEditingTemplate.ValidateTemplate(webLayoutTemplate))
                        {
                            // download supporting files
                            string templateFile = DownloadTemplateFiles(webLayoutTemplate, _blogHomepageUrl, new ProgressTick(progress, 20, 100));

                            // return the template
                            templateFiles.FramedTemplate = new BlogEditingTemplateFile(BlogEditingTemplateType.Framed, templateFile);
                        }
                        else
                        {
                            Trace.WriteLine("Invalid webLayoutTemplate specified in manifest");
                        }
                    }

                    if (editingManifest.WebPreviewUrl != null)
                    {
                        string webPreviewTemplate = DownloadManifestTemplate(new ProgressTick(progress, 10, 100), editingManifest.WebPreviewUrl);
                        if (BlogEditingTemplate.ValidateTemplate(webPreviewTemplate))
                        {
                            // download supporting files
                            string templateFile = DownloadTemplateFiles(webPreviewTemplate, _blogHomepageUrl, new ProgressTick(progress, 20, 100));

                            // return the template
                            templateFiles.WebPageTemplate = new BlogEditingTemplateFile(BlogEditingTemplateType.Webpage, templateFile);
                        }
                        else
                        {
                            Trace.WriteLine("Invalid webPreviewTemplate specified in manifest");
                        }
                    }
                }
            }
            catch
            {
            }
            finally
            {
                progress.UpdateProgress(100, 100);
            }

            return(templateFiles);
        }
        public void LoadHtmlFragment(string title, string blogPostBody, string baseUrl, BlogEditingTemplate editingTemplate)
        {
            _spellingManager.ClearIgnoreOnce();
            _templateContainsTitle = editingTemplate.ContainsTitle;

            //if any manually attached behaviors are attached, remove them.
            //Note: this is necessary to prevent errors from occuring when switching between wysiwyg and code view
            //to quickly.
            DetachBehaviors();

            // Deterministically dispose any automatically created behaviors.
            _elementBehaviorManager.DisposeCreatedBehaviors();

            if (TidyWhitespace && Editable)
            {
                blogPostBody = HTMLTrimmer.Trim(blogPostBody, true);
                if (blogPostBody != String.Empty)
                    blogPostBody += CONTENT_BODY_PADDING;
            }

            // SInce this action is reverted in the deattach of the behvaiors, we only do this in edit mode,
            // otherwie there is no deattach to balance it out.  See that AttachBehaviors() doesnt attach in edit mode
            if (Editable)
            {
                //attach the extended entry HTML behavior
                blogPostBody = PostBodyEditingElementBehavior.ApplyExtendedEntryBehavior(blogPostBody);
            }

            //Hack: cache the title and body HTML to avoid returning a bogus value
            //GetEdited[Html|TitleHtml] is called before the document behaviors are attached.
            _lastSetTitle = title;
            _lastSetBodyHtml = blogPostBody;

            preserver.Reset();
            blogPostBody = preserver.ScanAndPreserve(blogPostBody);

            // update html content with standard header and footer
            // Hack: put some padding at the bottom of the div so that the bottom line of text does not get
            // cutoff if it extends below the baseline (p's and g's sometimes cause issues)

            //put an ID'd span around the title so that editing behaviors can be attachd to it.
            //Note: use a span instead of a DIV as since DIVs can't be nested inside inline elements, so if
            //the title text was surrounded by inline tags (like font, or bold, etc) then the DIV would
            //break the rendering of the surrounding inline styles.
            string titleHtml = _strategy.OnTitleInserted(title);

            if (blogPostBody == String.Empty && TidyWhitespace)
                blogPostBody = "<p>&nbsp;</p>";

            blogPostBody = _strategy.OnBodyInserted(blogPostBody);

            string postHtml = editingTemplate.ApplyTemplateToPostHtml(title, titleHtml, blogPostBody);

            //add the base tag for the HTML so relative resource references in the post will be resolved.
            postHtml = postHtml.Replace("</HEAD>", String.Format(CultureInfo.InvariantCulture, "<BASE href=\"{0}\"></HEAD>", baseUrl));

            // save the content to a temp file for loading
            string documentPath = TempFileManager.Instance.CreateTempFile("index.htm");
            using (StreamWriter streamWriter = new StreamWriter(documentPath, false, Encoding.UTF8))
                streamWriter.Write(postHtml);

            // load the document
            base.LoadHtmlFile(documentPath);
        }
        public void SetTheme(string wysiwygHTML, string previewHTML, bool containsTitle)
        {
            if (string.IsNullOrEmpty(wysiwygHTML))
                throw new ArgumentException("wysiwygHTML cannot be a null or empty");

            Debug.Assert(wysiwygHTML.ToLower(CultureInfo.InvariantCulture).Contains("<head"), "wysiwygHTML does not contain head element");
            Debug.Assert(wysiwygHTML.ToLower(CultureInfo.InvariantCulture).Contains("<body"), "wysiwygHTML does not contain body element");

            BeforeSetTheme(ref wysiwygHTML, ref previewHTML, containsTitle);

            //transform the template HTML into the form required by the HTML editor
            string wysiwygTemplateWithBehaviors = CreateTemplateWithBehaviors(wysiwygHTML, _normalHtmlContentEditor.BehaviorManager);
            _editingTemplateWysiwyg = new BlogEditingTemplate(wysiwygTemplateWithBehaviors, containsTitle);

            if (!string.IsNullOrEmpty(previewHTML))
            {
                Debug.Assert(previewHTML.ToLower(CultureInfo.InvariantCulture).Contains("<head"), "previewHTML does not contain head element");
                Debug.Assert(previewHTML.ToLower(CultureInfo.InvariantCulture).Contains("<body"), "previewHTML does not contain body element");
                string previewTemplateWithBehaviors = CreateTemplateWithBehaviors(previewHTML, new NullElementBehaviorManager());
                _editingTemplatePreview = new BlogEditingTemplate(previewTemplateWithBehaviors, containsTitle);
            }

            ReloadEditor();
        }
        private BlogEditingTemplate GetSurroundingContent()
        {
            // surrounding content based on standard header and footer
            if (_editingTemplateWysiwyg == null)
            {
                throw new Exception("SetTheme was not called before the editor was loaded");
            }

            BlogEditingTemplate template = null;

            switch (CurrentEditingMode)
            {
                case EditingMode.Wysiwyg:
                    template = _editingTemplateWysiwyg;
                    break;

                case EditingMode.Preview:
                    template = _editingTemplatePreview;
                    break;

                case EditingMode.Source:
                    template = new BlogEditingTemplate(_editingTemplateWysiwyg.ContainsTitle);
                    break;

                case EditingMode.PlainText:
                    template = EditingTemplatePlain;
                    break;

            }

            if (template != null)
                return template;

            throw new Exception("Cannot find correct template for EditingMode: " + CurrentEditingMode);
        }