Пример #1
0
        public List<INCoverNode> ParseXmlDocument(XmlDocument results, Regex partOfPathToKeep)
        {
            foreach (var node in results.SafeSelectNodes("//doc").Where(node => !XmlNodeHelper.GetBoolAttribute("excluded", node)))
            {
                documents[XmlNodeHelper.GetIntAttribute("id", node)] = XmlNodeHelper.GetStringAttribute("url", node);
            }

            return (results.SafeSelectNodes("//seqpnt").Select(node => ParseNode(node, partOfPathToKeep))).ToList();
        }
Пример #2
0
        public List<INCoverNode> ParseXmlDocument( XmlDocument results, Regex partOfPathToKeep)
        {
            foreach (var node in results.SafeSelectNodes("//File"))
            {
                _documents[XmlNodeHelper.GetIntAttribute("uid", node)] = XmlNodeHelper.GetStringAttribute("fullPath", node);
            }

            return (results.SafeSelectNodes("//SequencePoint")
                .Select(node => ParseNode(node, partOfPathToKeep))).ToList();
        }
        public void PrepareElementsOnPage_FromShell_MakesVernacularAndNationalEmpty()
        {
            var contents = @"<div class='bloom-page numberedPage A5Portrait bloom-monolingual'
                            id='f4a22289-1755-4b79-afc1-5d20eaa892fe'>
            <div class='marginBox'>
              <div class='bloom-imageContainer'>
            <img alt='' src='test.png' height='20' width='20'/>
              </div>
              <div class='bloom-translationGroup normal-style'>
            <div style='' class='bloom-editable' contenteditable='true'
            lang='en'>The Mother said, Nurse!
            The Nurse answered.</div>
            <div style='' class='bloom-editable' contenteditable='true'
            lang='tpi'>Mama i tok: Sista.
            Sista i tok: Bai mi stori long yu.</div>
              </div>
            </div></div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            TranslationGroupManager.PrepareElementsInPageOrDocument((XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0], _collectionSettings.Object);

            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div/div[contains(@class, 'bloom-editable') and @contenteditable='true' ]", 5);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='xyz']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='es']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='en' and contains(., 'The Mother')]", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='tpi' and contains(., 'Mama i tok')]", 1);
            AssertThatXmlIn.Dom(dom).HasNoMatchForXpath("//div[@lang='xyz' and contains(., 'The Mother')]");
            AssertThatXmlIn.Dom(dom).HasNoMatchForXpath("//div[@lang='xyz' and contains(., 'Mama i tok')]");
            AssertThatXmlIn.Dom(dom).HasNoMatchForXpath("//div[@lang='fr' and contains(., 'The Mother')]");
            AssertThatXmlIn.Dom(dom).HasNoMatchForXpath("//div[@lang='fr' and contains(., 'Mama i tok')]");
        }
		public void DeleteNodes()
		{
			var dom = new XmlDocument();
			dom.LoadXml(@"<?xml version='1.0' encoding='utf-8'?>
<html>
	<body>
		<div class='A'><textarea>A1</textarea></div>
		<div class='B'><textarea>B</textarea></div>
		<div class='A'><textarea>A2</textarea></div>
	</body>
</html>");

			dom.DeleteNodes("descendant-or-self::*[contains(@class, 'A')]");
			Assert.AreEqual(1, dom.SafeSelectNodes("html/body/div").Count);
			Assert.AreEqual("<textarea>B</textarea>", dom.SafeSelectNodes("html/body/div")[0].InnerXml);
		}
Пример #5
0
        /// <summary>
        /// for testing.... todo: maybe they should test ProcessAndCopyImage() directly, instead
        /// </summary>
        public void ChangePicture(string bookFolderPath, XmlDocument dom, string imageId, PalasoImage imageInfo)
        {
            var matches = dom.SafeSelectNodes("//img[@id='" + imageId + "']");
            XmlElement img = matches[0] as XmlElement;

            var imageFileName = ProcessAndCopyImage(imageInfo, bookFolderPath);
            img.SetAttribute("src", imageFileName);
        }
Пример #6
0
        public IEnumerable<IChangeReport> DescribeInitialContents(FileInRevision fileInRevision, TempFile file)
        {
            var dom = new XmlDocument();
            dom.Load(file.Path);

            foreach (XmlNode e in dom.SafeSelectNodes("notes/annotation"))
            {
                yield return new XmlAdditionChangeReport(fileInRevision, e);
            }
        }
        public void PrepareElementsOnPage_HasLabelElementInsideTranslationGroup_LeavesUntouched()
        {
            var contents = @"<div class='bloom-page bloom-translationGroup'>
                        <label class='bloom-bubble'>something helpful</label>
                    </div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            TranslationGroupManager.PrepareElementsInPageOrDocument((XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0], _collectionSettings.Object);

            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//label[@class='bloom-bubble']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//label[@class='bloom-bubble' and text()='something helpful']", 1);
        }
        public void PrepareElementsOnPage_HasEmptyTranslationGroup_MakesVernacularAndNational()
        {
            var contents = @"<div class='bloom-page bloom-translationGroup'>
                    </div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            TranslationGroupManager.PrepareElementsInPageOrDocument((XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0], _collectionSettings.Object);

            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div/div[contains(@class, 'bloom-editable') and @contenteditable='true' ]", 3);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='xyz']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='es']", 1);
        }
        public void PrepareElementsOnPage_HasTextAreaInsideTranslationGroup_MakesVernacularAndNational()
        {
            var contents = @"<div class='bloom-page bloom-translationGroup'>
                        <textarea lang='en'>This is some English</textarea>
                    </div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            TranslationGroupManager.PrepareElementsInPageOrDocument((XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0], _collectionSettings.Object);

            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea", 4);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='en']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='fr']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='es']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='xyz']", 1);
        }
        public void PrepareElementsOnPage_HasNonEditableDiv_LeavesAlone()
        {
            var contents = @"<div class='bloom-page'>
                        <table class='bloom-translationGroup'> <!-- table is used for vertical alignment of the div on some pages -->
                         <td>
                            <div lang='en'>This is some English</div>
                        </td>
                        </table>
                    </div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            TranslationGroupManager.PrepareElementsInPageOrDocument((XmlElement)dom.SafeSelectNodes("//div[@class='bloom-page']")[0], _collectionSettings.Object);

            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//td/div", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//td/div[@lang='en']", 1);
        }
Пример #11
0
		public static void RemoveStyleSheetIfFound(XmlDocument dom, string cssFilePath)
		{
			foreach (XmlElement linkNode in dom.SafeSelectNodes("/html/head/link"))
			{
				var href = linkNode.GetAttribute("href");
				if (href == null)
				{
					continue;
				}
				//strip it down to just the name+extension, so other forms (e.g., via slightly different urls) will be removed.
				var path = href.ToLower().Replace("file://", "");
				if(Path.GetFileName(path)==Path.GetFileName(cssFilePath.ToLower()))
				{
					linkNode.ParentNode.RemoveChild(linkNode);
				}
			}
		}
Пример #12
0
        public void MergeConflictFiles_AncestorExistsButNoConflicts()
        {
            using (
                GroupOfConflictFiles group = new GroupOfConflictFiles("<notes/>",
                                                                      "<notes><annotation guid='bobGuid'/></notes>",
                                                                      "<notes><annotation guid='sallyGuid'/></notes>")
                )
            {
                MergeOrder order = new MergeOrder( group.BobFile.Path,
                                                  group.AncestorFile.Path, group.SallyFile.Path, new NullMergeSituation());
                new ChorusNotesFileHandler().Do3WayMerge(order);

                XmlDocument doc = new XmlDocument();
                doc.Load(group.BobFile.Path);
                Assert.AreEqual(2, doc.SafeSelectNodes("notes/annotation").Count);

            }
        }
        public void PrepareDataBookTranslationGroups_PlaceholdersCreatedAsNeeded()
        {
            var contents = @"<div class='bloom-page'>
                                <div class='bloom-translationGroup'>
                                        <div class='bloom-editable' data-book='bookTitle' lang='en'>Some English</div>
                                </div>
                        </div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            var languages = new string[] {"en","es","fr"};
            TranslationGroupManager.PrepareDataBookTranslationGroups((XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0], languages);

            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div/div[contains(@class, 'bloom-editable')]", 3);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='es']", 1);
            //should touch the existing one
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='en' and text()='Some English']", 1);
        }
 public void UpdateContentLanguageClasses_ExistingPageWith3rdLangRemoved_RemovesContentLanguageClassButLeavesOtherClasses()
 {
     var contents = @"<div class='bloom-page'>
                 <div class='bloom-translationGroup'>
                     <textarea lang='en'></textarea>
                     <textarea class='bloom-content2' lang='222'></textarea>
                     <textarea  class='foo bloom-content3 bar' lang='333'></textarea>
                     </div>
                 </div>";
     var dom = new XmlDocument();
     dom.LoadXml(contents);
     var pageDiv = (XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0];
     TranslationGroupManager.UpdateContentLanguageClasses(pageDiv, "xyz", _collectionSettings.Object.Language2Iso639Code, _collectionSettings.Object.Language3Iso639Code, "222", null);
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='222' and contains(@class, 'bloom-content2')]", 1);
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='333' and contains(@class, 'bloom-content3')]", 0);
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='333' and contains(@class, 'foo')]", 1);
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='333' and contains(@class, 'bar')]", 1);
 }
Пример #15
0
        /// <summary>
        /// If an element has empty contents, like <textarea></textarea>, browsers will sometimes drop the end tag, so that now, when we read it back into xml,
        /// anything following the <textarea> will be interpreted as part of the <textarea>!  This method makes sure such tags are never totally empty.
        /// </summary>
        /// <param name="dom"></param>
        public static void MakeXmlishTagsSafeForInterpretationAsHtml(XmlDocument dom)
        {
            foreach (XmlElement node in dom.SafeSelectNodes("//textarea"))
            {
                if (!node.HasChildNodes)
                {
                    node.AppendChild(node.OwnerDocument.CreateTextNode(""));
                }
            }
            foreach (XmlElement node in dom.SafeSelectNodes("//div"))
            {
                if (!node.HasChildNodes)
                {
                    node.AppendChild(node.OwnerDocument.CreateTextNode(""));
                }
            }

            foreach (XmlElement node in dom.SafeSelectNodes("//p"))
                //without  this, an empty paragraph suddenly takes over the subsequent elements. Browser sees <p></p> and thinks... let's just make it <p>, shall we? Stupid optional-closing language, html is....
            {
                if (!node.HasChildNodes)
                {
                    node.AppendChild(node.OwnerDocument.CreateTextNode(""));
                }
            }

            foreach (XmlElement node in dom.SafeSelectNodes("//span"))
            {
                if (!node.HasChildNodes)
                {
                    node.AppendChild(node.OwnerDocument.CreateTextNode(""));
                }
            }

            foreach (XmlElement node in dom.SafeSelectNodes("//script"))
            {
                if (string.IsNullOrEmpty(node.InnerText) && node.ChildNodes.Count == 0)
                {
                    node.InnerText = " ";
                }
            }

            foreach (XmlElement node in dom.SafeSelectNodes("//style"))
            {
                if (string.IsNullOrEmpty(node.InnerText) && node.ChildNodes.Count == 0)
                {
                    node.InnerText = " ";
                }
            }
        }
 public void UpdateContentLanguageClasses_NewPage_AddsContentLanguageClasses()
 {
     var contents = @"<div class='bloom-page'>
                 <div class='bloom-translationGroup'>
                     <textarea lang='en'></textarea>
                     <textarea lang='222'></textarea>
                     <textarea lang='333'></textarea>
                     </div>
                 </div>";
     var dom = new XmlDocument();
     dom.LoadXml(contents);
     var pageDiv = (XmlElement)dom.SafeSelectNodes("//div[@class='bloom-page']")[0];
     TranslationGroupManager.UpdateContentLanguageClasses(pageDiv, "xyz", _collectionSettings.Object.Language2Iso639Code, _collectionSettings.Object.Language3Iso639Code, "222", "333");
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='222' and contains(@class, 'bloom-content2')]", 1);
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//textarea[@lang='333' and contains(@class, 'bloom-content3')]", 1);
 }
Пример #17
0
 private string GetMetaValue(XmlDocument Dom, string name, string defaultValue)
 {
     var nameSuggestion = Dom.SafeSelectNodes("//head/meta[@name='" + name + "']");
     if (nameSuggestion.Count > 0)
     {
         return ((XmlElement)nameSuggestion[0]).GetAttribute("content");
     }
     return defaultValue;
 }
Пример #18
0
        public string GetMergedLift()
        {
            //            string path = Path.Combine(System.Environment.GetEnvironmentVariable("temp"),
            //                                    @"chorusMergeResult" + Path.GetFileName(_alphaLiftPath) + ".txt");
            //
            //            File.WriteAllText(path, "ENter GetMergedLift()");

            var ancestorDom = new XmlDocument();
            ancestorDom.LoadXml(_ancestorLift);
            //var comonIdToNodeIndex = new Dictionary<string, XmlNode>(StringComparer.OrdinalIgnoreCase);

            var alphaDom = new XmlDocument();
            alphaDom.LoadXml(_alphaLift);
            var alphaIdToNodeIndex = new Dictionary<string, XmlNode>(StringComparer.OrdinalIgnoreCase);

            var betaDom = new XmlDocument();
            betaDom.LoadXml(_betaLift);
            var betaIdToNodeIndex = new Dictionary<string, XmlNode>(StringComparer.OrdinalIgnoreCase);

            var processedIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

            // The memory stream, rather than a string builder, is needed to avoid utf-16 coming out
            using (var memoryStream = new MemoryStream())
            {
                //foreach (XmlNode commonNode in _ancestorDom.SafeSelectNodes("lift/entry"))
                //	comonIdToNodeIndex[LiftUtils.GetId(commonNode)] = commonNode;
                foreach (XmlNode alphaNode in alphaDom.SafeSelectNodes("lift/entry"))
                    alphaIdToNodeIndex[LiftUtils.GetId(alphaNode)] = alphaNode;
                foreach (XmlNode betaNode in betaDom.SafeSelectNodes("lift/entry"))
                    betaIdToNodeIndex[LiftUtils.GetId(betaNode)] = betaNode;

                var settings = CanonicalXmlSettings.CreateXmlWriterSettings();
                settings.CloseOutput = false;
                using (var writer = XmlWriter.Create(memoryStream, settings))
                {
                    WriteStartOfLiftElement(writer, alphaDom);

                    ProcessHeaderNodeHACK(writer, alphaDom, betaDom);
                    // Process alpha's entries
                    ProcessEntries(writer, EventListener, _mergingStrategy, ancestorDom, processedIds,
                                   alphaDom, "alpha", _alphaLift,
                                   betaIdToNodeIndex, "beta", _betaLift);
                    // Process beta's entries
                    ProcessEntries(writer, EventListener, _mergingStrategy, ancestorDom, processedIds,
                                   betaDom, "beta", _betaLift,
                                   alphaIdToNodeIndex, "alpha", _alphaLift);
                    writer.WriteEndElement();
                    writer.Close();
                }

                // Don't use GetBuffer()!!! it pads the results with nulls:  return Encoding.UTF8.GetString(memoryStream.ToArray());
                // This works but doubles the ram use: return Encoding.UTF8.GetString(memoryStream.ToArray());
                return Encoding.UTF8.GetString(memoryStream.GetBuffer(), 0, (int)memoryStream.Position);
            }
        }
Пример #19
0
 private static void DeletePages(XmlDocument bookDom, Func<XmlElement, bool> pageSelectingPredicate)
 {
     // Seems safest to make a list so we're not modifying the document while iterating through it.
     var pagesToDelete = new List<XmlElement>();
     foreach (XmlElement node in bookDom.SafeSelectNodes("//div[contains(@class, 'bloom-page')]"))
     {
         if (pageSelectingPredicate(node))
         {
             pagesToDelete.Add(node);
         }
     }
     foreach (var node in pagesToDelete)
     {
         // An earlier version of this method just set the visibility of the pages we don't want
         // in this printout to display:none, like this:
         //node.SetAttribute("style", "", "display:none");
         // However, this runs up against a defect in Gecko PDF generation: apparently when
         // all the content after the last page in a paginated document is display:none, Gecko
         // puts in an extra blank page. We suspect something like code that detects that
         // the current page is finished and the document is not finished and starts a new page,
         // which turns out not to be needed. The extra blank page can mess up booklet generation
         // and cause an extra sheet of paper to be used (leaving a wasted four blank pages at
         // the end). See BL-705.
         node.ParentNode.RemoveChild(node);
     }
 }
Пример #20
0
 private static void HideEverythingButFirstPageAndRemoveScripts(XmlDocument bookDom)
 {
     bool onFirst = true;
     foreach (XmlElement node in bookDom.SafeSelectNodes("//div[contains(@class, 'bloom-page')]"))
     {
         if (!onFirst)
         {
             node.SetAttribute("style", "", "display:none");
         }
         onFirst =false;
     }
     //Without casting to array, Mono considers this manipulating the enumerable list
     foreach (var node in bookDom.SafeSelectNodes("//script").Cast<XmlNode>().ToArray())
     {
         //TODO: this removes image scaling, which is ok so long as it's already scaled with width/height attributes
         node.ParentNode.RemoveChild(node);
     }
 }
Пример #21
0
        /// <summary>
        /// Where, for example, somewhere on a page something has data-book='foo' lan='fr',
        /// we set the value of that element to French subvalue of the data item 'foo', if we have one.
        /// </summary>
        private void UpdateDomFromDataSet(DataSet data, string elementName,XmlDocument targetDom)
        {
            try
            {
                string query = String.Format("//{0}[(@data-book or @data-collection or @data-library)]", elementName);
                XmlNodeList nodesOfInterest = targetDom.SafeSelectNodes(query);

                foreach (XmlElement node in nodesOfInterest)
                {
                    string key = node.GetAttribute("data-book").Trim();
                    if (key == String.Empty)
                    {
                        key = node.GetAttribute("data-collection").Trim();
                        if(key==string.Empty)
                        {
                            key = node.GetAttribute("data-library").Trim();
                                //"library" is the old name for what is now "collection"
                        }
                    }

                    if (!String.IsNullOrEmpty(key) && data.TextVariables.ContainsKey(key))
                    {
                        if (node.Name.ToLower() == "img")
                        {
                            string imageName =
                                WebUtility.HtmlDecode(data.TextVariables[key].TextAlternatives.GetFirstAlternative());
                            string oldImageName = WebUtility.HtmlDecode(node.GetAttribute("src"));
                            node.SetAttribute("src", imageName);
                            if (oldImageName != imageName)
                            {
                                Guard.AgainstNull(_updateImgNode, "_updateImgNode");
                                _updateImgNode(node);
                            }
                        }
                        else
                        {
                            string lang = node.GetOptionalStringAttribute("lang", "*");
                            if (lang == "N1" || lang == "N2" || lang == "V")
                                lang = data.WritingSystemAliases[lang];

                            //							//see comment later about the inability to clear a value. TODO: when we re-write Bloom, make sure this is possible
                            //							if(data.TextVariables[key].TextAlternatives.Forms.Length==0)
                            //							{
                            //								//no text forms == desire to remove it. THe multitextbase prohibits empty strings, so this is the best we can do: completly remove the item.
                            //								targetDom.RemoveChild(node);
                            //							}
                            //							else
                            if (!String.IsNullOrEmpty(lang)) //if we don't even have this language specified (e.g. no national language), the  give up
                            {
                                //Ideally, we have this string, in this desired language.
                                string s = data.TextVariables[key].TextAlternatives.GetBestAlternativeString(new []{lang, "*"});

                                //But if not, maybe we should copy one in from another national language
                                if(string.IsNullOrEmpty(s))
                                    s = PossiblyCopyFromAnotherLanguage(node, lang, data, key);

                                //NB: this was the focus of a multi-hour bug search, and it's not clear that I got it right.
                                //The problem is that the title page has N1 and n2 alternatives for title, the cover may not.
                                //the gather page was gathering no values for those alternatives (why not), and so GetBestAlternativeSTring
                                //was giving "", which we then used to remove our nice values.
                                //REVIEW: what affect will this have in other pages, other circumstances. Will it make it impossible to clear a value?
                                //Hoping not, as we are differentiating between "" and just not being in the multitext at all.
                                //don't overwrite a datadiv alternative with empty just becuase this page has no value for it.
                                if (s == "" && !data.TextVariables[key].TextAlternatives.ContainsAlternative(lang))
                                    continue;

                                //hack: until I think of a more elegant way to avoid repeating the language name in N2 when it's the exact same as N1...
                                if (data.WritingSystemAliases.Count != 0 && lang == data.WritingSystemAliases["N2"] &&
                                    s ==
                                    data.TextVariables[key].TextAlternatives.GetBestAlternativeString(new[]
                                                                                                          {
                                                                                                              data.
                                                                                                                  WritingSystemAliases
                                                                                                                  ["N1"]
                                                                                                              , "*"
                                                                                                          }))
                                {
                                    s = ""; //don't show it in N2, since it's the same as N1
                                }
                                node.InnerXml = s;
                                //meaning, we'll take "*" if you have it but not the exact choice. * is used for languageName, at least in dec 2011
                            }
                        }
                    }
                }
            }
            catch (Exception error)
            {
                throw new ApplicationException(
                    "Error in MakeAllFieldsOfElementTypeConsistent(," + elementName + "). RawDom was:\r\n" +
                    targetDom.OuterXml, error);
            }
        }
 public void UpdateContentLanguageClasses_Typical_MetadataPage_TurnsOnCorrectLanguages()
 {
     var contents = @"<div class='bloom-page' >
                 <div class='bloom-translationGroup' data-default-languages='N1,N2'>
                     <div class='bloom-editable' lang='xyz'></div>
                     <div class='bloom-editable' lang='fr'></div>
                     <div class='bloom-editable' lang='es'></div>
                     </div>
                 </div>";
     var dom = new XmlDocument();
     dom.LoadXml(contents);
     var pageDiv = (XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0];
     TranslationGroupManager.UpdateContentLanguageClasses(pageDiv, _collectionSettings.Object, "xyz", "222", "333");
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[contains(@class, 'bloom-visibility-code-on')]", 2);
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr' and contains(@class, 'bloom-visibility-code-on')]", 1);
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='es' and contains(@class, 'bloom-visibility-code-on')]", 1);
 }
        public void UpdateContentLanguageClasses_TranslationGroupHasPlaceHolder_PlaceholderCopiedToNewChildren()
        {
            var contents = @"<div class='bloom-page  bloom-trilingual'>
                                <div class='bloom-translationGroup' data-placeholder='copy me' >
                                </div>
                        </div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            TranslationGroupManager.PrepareElementsInPageOrDocument((XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0], _collectionSettings.Object);

            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div/div[contains(@class, 'bloom-editable') and @contenteditable='true' ]", 3);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='xyz' and @data-placeholder='copy me']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr' and @data-placeholder='copy me']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='es' and @data-placeholder='copy me']", 1);
        }
        public void UpdateContentLanguageClasses_PrototypeElementHasImageContainer_ImageContainerCopiedToNewSibling()
        {
            const string contents = @"<div class='bloom-page'>
                                        <div class='bloom-translationGroup'>
                                            <div class='bloom-editable' lang='123'>
                                                Do not copy me.
                                                <br>Do not copy me.</br>
                                                <p>Do not copy me.</p>
                                                <div class='bloom-imageContainer'>
                                                    <img src='foo.png'></img>
                                                    <div contentEditable='true' class='caption'>Do not copy me</div>
                                                </div>
                                                Do not copy me.
                                                <p>Do not copy me.</p>
                                                <p class='foo bloom-cloneToOtherLanguages bar'>Do copy me.</p>
                                            </div>
                                        </div>
                                    </div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            TranslationGroupManager.PrepareElementsInPageOrDocument((XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0], _collectionSettings.Object);

            //the added french should have all the structure including a copy of the image container div, but none of the text except from the bloom-cloneToOtherLanguages paragraph
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']/div/img[@src='foo.png']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']/div/div[@contentEditable='true']", 1);
            //should clear out the caption text (using a raw contentEditable for the caption just becuase bloom-editables inside of bloom-editables is beyond my ambitions at the moment.
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']/div/div[contains(@class,'caption') and @contentEditable='true' and not(text())]", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']/*[contains(text(),'Do not')]", 0);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']//br", 0);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']//p[not(contains(@class,'bloom-cloneToOtherLanguages'))]", 0); // get rid of all paragraphs, except for...
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']//p[contains(@class,'bloom-cloneToOtherLanguages')]", 1); // the one with "bloom-cloneToOtherLanguages"
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']/*[contains(text(),'Do copy me')]", 1);
        }
        public void UpdateContentLanguageClasses_PrototypeHasUnderlinedText_CopyHasNone()
        {
            var contents = @"<div class='bloom-page numberedPage A5Portrait bloom-monolingual'
                            id='f4a22289-1755-4b79-afc1-5d20eaa892fe'>
                            <div class='marginBox'>
                              <div class='bloom-translationGroup normal-style'>
                                <div style='' class='bloom-editable' contenteditable='true'
                                    lang='en'>The <i>Mother</i> said, <u>Nurse!</u>
                                        The Nurse <b>answered</b>.</div>
                            </div></div></div>";
            var dom = new XmlDocument();
            dom.LoadXml(contents);

            TranslationGroupManager.PrepareElementsInPageOrDocument((XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0], _collectionSettings.Object);

            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='xyz']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='fr']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='es']", 1);
            AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[@lang='en' and contains(., 'The Mother')]", 1);
            AssertThatXmlIn.Dom(dom).HasNoMatchForXpath("//div[@lang='fr']/u");
            AssertThatXmlIn.Dom(dom).HasNoMatchForXpath("//div[@lang='fr']/b");
            AssertThatXmlIn.Dom(dom).HasNoMatchForXpath("//div[@lang='fr']/i");
        }
Пример #26
0
 public static void RemoveAllContentTypesMetas(XmlDocument dom)
 {
     foreach (XmlElement n in dom.SafeSelectNodes("//head/meta[@http-equiv='Content-Type']"))
     {
         n.ParentNode.RemoveChild(n);
     }
 }
 public void UpdateContentLanguageClasses_TrilingualBook_AddsBloomTrilingualClassToTranslationGroup()
 {
     var contents = @"<div class='bloom-page  bloom-bilingual'>
                 <div class='bloom-translationGroup'>
                     <textarea lang='en'></textarea>
                     </div>
                 </div>";
     var dom = new XmlDocument();
     dom.LoadXml(contents);
     var pageDiv = (XmlElement)dom.SafeSelectNodes("//div[contains(@class,'bloom-page')]")[0];
     TranslationGroupManager.UpdateContentLanguageClasses(pageDiv, _collectionSettings.Object, "xyz", "222", "333");
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[contains(@class, 'bloom-bilingual')]", 0);//should remove that one
     AssertThatXmlIn.Dom(dom).HasSpecifiedNumberOfMatchesForXpath("//div[contains(@class, 'bloom-trilingual')]", 1);
 }
Пример #28
0
        /// <summary>
        /// Where, for example, somewhere on a page something has data-book='foo' lang='fr',
        /// we set the value of that element to French subvalue of the data item 'foo', if we have one.
        /// </summary>
        private void UpdateDomFromDataSet(DataSet data, string elementName,XmlDocument targetDom, HashSet<Tuple<string, string>> itemsToDelete)
        {
            try
            {
                var query = String.Format("//{0}[(@data-book or @data-collection or @data-library or @data-book-attributes)]", elementName);
                var nodesOfInterest = targetDom.SafeSelectNodes(query);

                foreach (XmlElement node in nodesOfInterest)
                {
                    var key = node.GetAttribute("data-book").Trim();
                    if (key == string.Empty)
                    {
                        key = node.GetAttribute("data-book-attributes").Trim();
                        if (key != string.Empty)
                        {
                            UpdateAttributes(data, node, key);
                            continue;
                        }
                        key = node.GetAttribute("data-collection").Trim();
                        if (key == string.Empty)
                        {
                            key = node.GetAttribute("data-library").Trim(); //"library" is the old name for what is now "collection"
                        }
                    }

                    if (string.IsNullOrEmpty(key)) continue;

                    if (data.TextVariables.ContainsKey(key))
                    {
                        if (UpdateImageFromDataSet(data, node, key)) continue;

                        var lang = node.GetOptionalStringAttribute("lang", "*");
                        if (lang == "N1" || lang == "N2" || lang == "V")
                            lang = data.WritingSystemAliases[lang];

                        //							//see comment later about the inability to clear a value. TODO: when we re-write Bloom, make sure this is possible
                        //							if(data.TextVariables[key].TextAlternatives.Forms.Length==0)
                        //							{
                        //								//no text forms == desire to remove it. THe multitextbase prohibits empty strings, so this is the best we can do: completly remove the item.
                        //								targetDom.RemoveChild(node);
                        //							}
                        //							else
                        if (!string.IsNullOrEmpty(lang)) //if we don't even have this language specified (e.g. no national language), the  give up
                        {
                            //Ideally, we have this string, in this desired language.
                            var s = data.TextVariables[key].TextAlternatives.GetBestAlternativeString(new[] {lang, "*"});

                            if(KeysOfVariablesThatAreUrlEncoded.Contains(key))
                            {
                                Debug.Assert(!s.Contains("&amp;"),"In memory, all image urls should be encoded such that & is just &.");
                            }
                            //But if not, maybe we should copy one in from another national language
                            if (string.IsNullOrEmpty(s))
                                s = PossiblyCopyFromAnotherLanguage(node, lang, data, key);

                            //NB: this was the focus of a multi-hour bug search, and it's not clear that I got it right.
                            //The problem is that the title page has N1 and n2 alternatives for title, the cover may not.
                            //the gather page was gathering no values for those alternatives (why not), and so GetBestAlternativeSTring
                            //was giving "", which we then used to remove our nice values.
                            //REVIEW: what affect will this have in other pages, other circumstances. Will it make it impossible to clear a value?
                            //Hoping not, as we are differentiating between "" and just not being in the multitext at all.
                            //don't overwrite a datadiv alternative with empty just becuase this page has no value for it.
                            if (s == "" && !data.TextVariables[key].TextAlternatives.ContainsAlternative(lang))
                                continue;

                            //hack: until I think of a more elegant way to avoid repeating the language name in N2 when it's the exact same as N1...
                            if (data.WritingSystemAliases.Count != 0 && lang == data.WritingSystemAliases["N2"] &&
                                s ==
                                data.TextVariables[key].TextAlternatives.GetBestAlternativeString(new[]
                                {
                                    data.
                                        WritingSystemAliases
                                        ["N1"]
                                    , "*"
                                }))
                            {
                                s = ""; //don't show it in N2, since it's the same as N1
                            }
                            SetInnerXmlPreservingLabel(key, node, s);
                        }
                    }
                    else if (!HtmlDom.IsImgOrSomethingWithBackgroundImage(node))
                    {
                        // See whether we need to delete something
                        var lang = node.GetOptionalStringAttribute("lang", "*");
                        if (lang == "N1" || lang == "N2" || lang == "V")
                            lang = data.WritingSystemAliases[lang];
                        if (itemsToDelete.Contains(Tuple.Create(key, lang)))
                        {
                            SetInnerXmlPreservingLabel(key, node, "");// a later process may remove node altogether.
                        }
                    }
                }
            }
            catch (Exception error)
            {
                throw new ApplicationException(
                    "Error in UpdateDomFromDataSet(," + elementName + "). RawDom was:\r\n" +
                    targetDom.OuterXml, error);
            }
        }
 /// <summary>
 /// Add to the dictionary which maps original to Localized strings an entry for any language code that doesn't already
 /// have one. We have localizations for a few major languages that map e.g. de->German/Deutsch/etc, so they are functioning
 /// not just to localize but to expand from a language code to an actual name. For any other languages where we don't
 /// have localization information, we'd like to at least expand the cryptic code into a name. This method does that.
 /// </summary>
 /// <param name="xmlDocument"></param>
 /// <param name="mapOriginalToLocalized"></param>
 internal static void AddLanguagesUsedInPage(XmlDocument xmlDocument, Dictionary<string, string> mapOriginalToLocalized)
 {
     var langs = xmlDocument.SafeSelectNodes("//*[@lang]").Cast<XmlElement>()
         .Select(e => e.Attributes["lang"].Value)
         .Distinct()
         .Where(lang => !mapOriginalToLocalized.ContainsKey(lang))
         .ToList();
     if (langs.Any())
     {
         // We don't have a localization for these languages, but we can at least try to give them a name
         var lookup = new LanguageLookupModel(); // < 1ms
         foreach (var lang in langs) // may include things like empty string, z, *, but this is harmless as they are not language codes.
         {
             string match;
             if (lookup.GetBestLanguageName(lang, out match)) // some better name found
                 mapOriginalToLocalized[lang] = match;
         }
     }
 }
 public void FileAlreadyExists_AddsNewConflicts()
 {
     using (TempFile logFile = TempFile.CreateAndGetPathButDontMakeTheFile())
     {
         using (ChorusNotesMergeEventListener log = new ChorusNotesMergeEventListener(logFile.Path))
         {
             log.ConflictOccurred(new DummyConflict());
             log.ConflictOccurred(new DummyConflict());
         }
         using (ChorusNotesMergeEventListener log2 = new ChorusNotesMergeEventListener(logFile.Path))
         {
             log2.ConflictOccurred(new DummyConflict());
             log2.ConflictOccurred(new DummyConflict());
         }
         XmlDocument doc = new XmlDocument();
         doc.Load(logFile.Path);
         Assert.AreEqual(4, doc.SafeSelectNodes("notes/annotation").Count);
     }
 }