private List<IPage> UpdateItems(IEnumerable<IPage> pages)
{
RemoveThumbnailListeners();
var result = new List<IPage>();
var firstRealPage = pages.FirstOrDefault(p => p.Book != null);
if (firstRealPage == null)
{
_browser.Navigate(@"about:blank", false); // no pages, we just want a blank screen, if anything.
return result;
}
var frame = BloomFileLocator.GetBrowserFile("bookEdit", "pageThumbnailList", "pageThumbnailList.html");
var backColor = ColorToHtmlCode(BackColor);
var htmlText = RobustFile.ReadAllText(frame, Encoding.UTF8).Replace("DarkGray", backColor);
_usingTwoColumns = RoomForTwoColumns;
if (!RoomForTwoColumns)
htmlText = htmlText.Replace("columns: 4", "columns: 2").Replace("<div class=\"gridItem placeholder\" id=\"placeholder\"></div>", "");
var dom = new HtmlDom(XmlHtmlConverter.GetXmlDomFromHtml(htmlText));
dom = firstRealPage.Book.GetHtmlDomReadyToAddPages(dom);
var pageDoc = dom.RawDom;
// BL-987: Add styles to optimize performance on Linux
if (SIL.PlatformUtilities.Platform.IsLinux)
{
var style = pageDoc.CreateElement("style");
style.InnerXml = "img { image-rendering: optimizeSpeed; image-rendering: -moz-crisp-edges; image-rendering: crisp-edges; }";
pageDoc.GetElementsByTagName("head")[0].AppendChild(style);
}
var body = pageDoc.GetElementsByTagName("body")[0];
var gridlyParent = body.SelectSingleNode("//*[@id='pageGrid']");
int pageNumber = 0;
_pageMap.Clear();
foreach (var page in pages)
{
var pageElement = page.GetDivNodeForThisPage();
if (pageElement == null)
continue; // or crash? How can this happen?
result.Add(page);
var pageElementForThumbnail = pageDoc.ImportNode(pageElement, true) as XmlElement;
// BL-1112: Reduce size of images in page thumbnails.
// We are setting the src to empty so that we can use JavaScript to request the thumbnails
// in a controlled manner that should reduce the likelihood of not receiving the image quickly
// enough and displaying the alt text rather than the image.
DelayAllImageNodes(pageElementForThumbnail);
var cellDiv = pageDoc.CreateElement("div");
cellDiv.SetAttribute("class", ClassForGridItem);
var gridId = GridId(page);
cellDiv.SetAttribute("id", gridId);
_pageMap.Add(gridId, page);
gridlyParent.AppendChild(cellDiv);
//we wrap our incredible-shrinking page in a plain 'ol div so that we
//have something to give a border to when this page is selected
var pageContainer = pageDoc.CreateElement("div");
pageContainer.SetAttribute("class", PageContainerClass);
pageContainer.AppendChild(pageElementForThumbnail);
/* And here it gets fragile (for not).
The nature of how we're doing the thumbnails (relying on scaling) seems to mess up
the browser's normal ability to assign a width to the parent div. So our parent
here, .pageContainer, doesn't grow with the size of its child. Sigh. So for the
moment, we assign appropriate sizes, by hand. We rely on c# code to add these
classes, since we can't write a rule in css3 that peeks into a child attribute.
*/
var pageClasses = pageElementForThumbnail.GetStringAttribute("class").Split(new[] {' '});
var cssClass = pageClasses.FirstOrDefault(c => c.ToLowerInvariant().EndsWith("portrait") || c.ToLower().EndsWith("landscape"));
if (!string.IsNullOrEmpty(cssClass))
pageContainer.SetAttribute("class", "pageContainer " + cssClass);
cellDiv.AppendChild(pageContainer);
var captionDiv = pageDoc.CreateElement("div");
captionDiv.SetAttribute("class", "thumbnailCaption");
cellDiv.AppendChild(captionDiv);
string captionI18nId;
var captionOrPageNumber = page.GetCaptionOrPageNumber(ref pageNumber, out captionI18nId);
if (!string.IsNullOrEmpty(captionOrPageNumber))
captionDiv.InnerText = I18NHandler.GetTranslationDefaultMayNotBeEnglish(captionI18nId, captionOrPageNumber);
}
// set interval based on physical RAM
var intervalAttrib = pageDoc.CreateAttribute("data-thumbnail-interval");
intervalAttrib.Value = _thumbnailInterval;
body.Attributes.Append(intervalAttrib);
_browser.WebBrowser.DocumentCompleted += WebBrowser_DocumentCompleted;
_verticalScrollDistance = _browser.VerticalScrollDistance;
_baseForRelativePaths = dom.BaseForRelativePaths;
_browser.Navigate(dom);
return result;
}