Пример #1
0
        /// <summary>
        /// Add elements to the set of matched elements.
        /// </summary>
        ///
        /// <param name="elements">
        /// The elements to add.
        /// </param>
        ///
        /// <returns>
        /// A new CQ object.
        /// </returns>
        ///
        /// <url>
        /// http://api.jquery.com/add/
        /// </url>

        public CQ Add(IEnumerable <IDomObject> elements)
        {
            CQ res = NewInstance(this);

            res.AddSelection(elements);
            return(res);
        }
Пример #2
0
        private CQ FindImpl(Selector selector)
        {
            CQ csq = New();

            csq.AddSelection(selector.Select(Document, this));
            csq.Selector = selector;
            return(csq);
        }
Пример #3
0
        private CQ FindImpl(Selector selector)
        {
            CQ  csq       = NewCqInDomain();
            var selection = selector.ToContextSelector().Select(Document, this);

            csq.AddSelection(selection);
            csq.Selector = selector;
            return(csq);
        }
Пример #4
0
        /// <summary>
        /// Selects then zero-based nth cells  (th and td) from all rows in any matched tables. This will
        /// most likely no do what you expect if the table has colspan cells.
        /// </summary>
        ///
        /// <param name="column">
        /// The zero-based index of the column to target.
        /// </param>
        ///
        /// <returns>
        /// A new CQ object containing all the th and td cells in the specified column.
        /// </returns>

        public CQ GetTableColumn(int column)
        {
            CQ result = New();

            foreach (var el in FilterElements(this, "table"))
            {
                result.AddSelection(el.Cq().Find(String.Format("tr>th:eq({0}), tr>td:eq({0})", column)));
            }
            return(result);
        }
Пример #5
0
 /// <summary>
 /// Create a new CQ object from a single element. Unlike the constructor method <see cref="CsQuery.CQ"/>
 /// this new objet is not bound to any context from the element.
 /// </summary>
 ///
 /// <param name="element">
 /// The element to wrap
 /// </param>
 ///
 /// <returns>
 /// A new CQ object
 /// </returns>
 
 public static CQ Create(IDomObject element)
 {
     CQ csq = new CQ();
     if (element is IDomDocument) {
         csq.Document = (IDomDocument)element;
         csq.AddSelection(csq.Document.ChildNodes);
     } else {
         csq.CreateNewFragment(Objects.Enumerate(element));
     }
     return csq;
 }
Пример #6
0
        /// <summary>
        /// Given a table header or cell, returns all members of the column in the table. This will most
        /// likely not work as you would expect if there are colspan cells.
        /// </summary>
        ///
        /// <returns>
        /// A new CQ object containing all the th and td cells in the specified column.
        /// </returns>

        public CQ GetTableColumn()
        {
            var els    = this.Filter("th,td");
            CQ  result = New();

            foreach (var el in els)
            {
                var elCq     = el.Cq();
                int colIndex = elCq.Index();
                result.AddSelection(elCq.Closest("table").GetTableColumn(colIndex));
            }
            return(result);
        }
Пример #7
0
        /// <summary>
        /// Create a new CQ object from a single element. Unlike the constructor method <see cref="CsQuery.CQ"/>
        /// this new objet is not bound to any context from the element.
        /// </summary>
        ///
        /// <param name="element">
        /// The element to wrap
        /// </param>
        ///
        /// <returns>
        /// A new CQ object
        /// </returns>

        public static CQ Create(IDomObject element)
        {
            CQ csq = new CQ();

            if (element is IDomDocument)
            {
                csq.Document = (IDomDocument)element;
                csq.AddSelection(csq.Document.ChildNodes);
            }
            else
            {
                csq.CreateNewFragment(Objects.Enumerate(element));
            }
            return(csq);
        }
Пример #8
0
        /// <summary>
        /// Get the first ancestor element of any element in the seleciton set that is also one of the
        /// elements in the sequence passed by parameter, beginning at the current element and
        /// progressing up through the DOM tree.
        /// </summary>
        ///
        /// <param name="elements">
        /// The elements to target.
        /// </param>
        ///
        /// <returns>
        /// A new CQ object.
        /// </returns>
        ///
        /// <url>
        /// http://api.jquery.com/closest/#closest1
        /// </url>

        public CQ Closest(IEnumerable <IDomObject> elements)
        {
            // Use a hashset to operate faster - since we already have one for the selection set anyway

            HashSet <IDomObject> elementSet = new HashSet <IDomObject>(elements);

            CQ csq = NewCqInDomain();

            foreach (var el in SelectionSet)
            {
                var search = el;
                while (search != null)
                {
                    if (elementSet.Contains(search))
                    {
                        csq.AddSelection(search);
                        search = null;
                        continue;
                    }
                    search = search.ParentNode;
                }
            }
            return(csq);
        }
Пример #9
0
        /// <summary>
        /// Configures a new instance for a sequence of elements and an existing context.
        /// </summary>
        ///
        /// <param name="elements">
        /// A sequence of elements.
        /// </param>
        /// <param name="context">
        /// The context.
        /// </param>

        private void ConfigureNewInstance(CQ dom,IEnumerable<IDomObject> elements, CQ context)
        {
            dom.CsQueryParent = context;
            dom.AddSelection(elements);
        }
Пример #10
0
        /// <summary>
        /// Insert every element in the selection at or after the index of each target (adding offset to
        /// the index). If there is more than one target, the a clone is made of the selection for the
        /// 2nd and later targets.
        /// </summary>
        ///
        /// <exception cref="InvalidOperationException">
        /// Thrown if attempting to add elements to a disconnected (parentless) sequence
        /// </exception>
        ///
        /// <param name="target">
        /// The target element
        /// </param>
        /// <param name="offset">
        /// The offset from the target at which to begin inserting
        /// </param>
        /// <param name="insertedElements">
        /// [out] The inserted elements.
        /// </param>
        ///
        /// <returns>
        /// The current CQ object
        /// </returns>

        protected CQ InsertAtOffset(IEnumerable<IDomObject> target, int offset, out CQ insertedElements)
        {
            CQ cq = target as CQ;
            SelectionSet<IDomObject> sel = null;

            if (cq!=null) {
                sel = cq.SelectionSet;
            }

            bool isTargetCsQuery = cq != null;
            
            bool isFirst = true;

            // Copy the target list: it could change otherwise
            List<IDomObject> targets = new List<IDomObject>(target);
            insertedElements = new CQ();
            bool isEmptyTarget = sel.Count == 0;

            // bind the source to the target's document if it was itself a CsQuery object, and update its selection set to reflect the 
            // current document.

            if (isTargetCsQuery)
            {
                Document = cq.Document;
            }

            if (isTargetCsQuery && isEmptyTarget)
            {
                // If appending items to an empty selection, just add them to the selection set
                sel.AddRange(SelectionSet);
                insertedElements.AddSelection(SelectionSet);

                // selection set will be messed up if document was changed; rebuild it
                SelectionSet.Clear();
                SelectionSet.AddRange(insertedElements);
            }
            else
            {
                foreach (var el in targets)
                {
                    if (el.IsDisconnected)
                    {
                        // Disconnected items are added to the selection set (if that's the target)
                        if (!isTargetCsQuery)
                        {
                            throw new InvalidOperationException("You can't add elements to a disconnected element list, it must be in a selection set");
                        }
                        int index = sel.IndexOf(el);

                        sel.OutputOrder = SelectionSetOrder.OrderAdded;
        
                        foreach (var item in SelectionSet)
                        {
                            sel.Insert(index + offset, item);
                        }
                        insertedElements.AddSelection(SelectionSet);

                        // selection set will be messed up if document was changed; rebuild it
                        SelectionSet.Clear();
                        SelectionSet.AddRange(insertedElements);
                    }
                    else
                    {
                        if (isFirst)
                        {
                            insertedElements.AddSelection(SelectionSet);
                            InsertAtOffset(el, offset);
                            isFirst = false;
                            // selection set will be messed up if document was changed; rebuild it
                            SelectionSet.Clear();
                            SelectionSet.AddRange(insertedElements);
                        }
                        else
                        {
                            var clone = Clone();
                            clone.InsertAtOffset(el, offset);
                            insertedElements.AddSelection(clone);
                        }
                    }
                }
            }



            return this;
        }
Пример #11
0
        /// <summary>
        /// Insert every element in the selection at or after the index of each target (adding offset to
        /// the index). If there is more than one target, the a clone is made of the selection for the
        /// 2nd and later targets.
        /// </summary>
        ///
        /// <exception cref="InvalidOperationException">
        /// Thrown if attempting to add elements to a disconnected (parentless) sequence
        /// </exception>
        ///
        /// <param name="target">
        /// The target element
        /// </param>
        /// <param name="offset">
        /// The offset from the target at which to begin inserting
        /// </param>
        /// <param name="insertedElements">
        /// [out] The inserted elements.
        /// </param>
        ///
        /// <returns>
        /// The current CQ object
        /// </returns>

        protected CQ InsertAtOffset(IEnumerable <IDomObject> target, int offset, out CQ insertedElements)
        {
            CQ cq = target as CQ;
            SelectionSet <IDomObject> targetSelectionSet = null;

            if (cq != null)
            {
                targetSelectionSet = cq.SelectionSet;
            }

            bool isTargetCsQuery = cq != null;

            bool isFirst = true;

            // Copy the target list: it could change otherwise
            List <IDomObject> targets = new List <IDomObject>(target);

            insertedElements = NewInstance();
            bool isEmptyTarget = targetSelectionSet.Count == 0;

            // bind the source to the target's document if it was itself a CsQuery object, and update its selection set to reflect the
            // current document.

            if (isTargetCsQuery)
            {
                Document = cq.Document;
            }

            if (isTargetCsQuery && isEmptyTarget)
            {
                // If appending items to an empty selection, just add them to the selection set
                targetSelectionSet.AddRange(SelectionSet);
                insertedElements.AddSelection(SelectionSet);

                // selection set will be messed up if document was changed; rebuild it
                //SelectionSet.Clear();
                //SelectionSet.AddRange(insertedElements);
            }
            else
            {
                foreach (var el in targets)
                {
                    if (el.IsDisconnected)
                    {
                        // Disconnected items are added to the selection set (if that's the target)
                        if (!isTargetCsQuery)
                        {
                            throw new InvalidOperationException("You can't add elements to a disconnected element list, it must be in a selection set");
                        }
                        int index = targetSelectionSet.IndexOf(el);

                        targetSelectionSet.OutputOrder = SelectionSetOrder.OrderAdded;

                        foreach (var item in SelectionSet)
                        {
                            targetSelectionSet.Insert(index + offset, item);
                        }
                        insertedElements.AddSelection(SelectionSet);

                        // selection set will be messed up if document was changed; rebuild it
                        //SelectionSet.Clear();
                        //SelectionSet.AddRange(insertedElements);
                    }
                    else
                    {
                        if (isFirst)
                        {
                            insertedElements.AddSelection(SelectionSet);
                            InsertAtOffset(el, offset);
                            isFirst = false;
                            // selection set will be messed up if document was changed; rebuild it
                            //SelectionSet.Clear();
                            //SelectionSet.AddRange(insertedElements);
                        }
                        else
                        {
                            var clone = Clone();
                            clone.InsertAtOffset(el, offset);
                            insertedElements.AddSelection(clone);
                        }
                    }
                }
            }



            return(this);
        }
Пример #12
0
        /// <summary>
        /// Insert every element in the selection at or after the index of each target (adding offset to
        /// the index). If there is more than one target, the a clone is made of the selection for the
        /// 2nd and later targets.
        /// </summary>
        ///
        /// <remarks>
        /// This is a helper for Before and After. There is special handling when the target is not part
        /// of a DOM. Instead of altering the DOM, this method will alter the selection set, and return a
        /// CQ object that contains the new sequence. Normally, it would return the same CQ object (but
        /// alter the DOM).
        /// </remarks>
        ///
        /// <param name="target">
        /// The target element.
        /// </param>
        /// <param name="offset">
        /// The offset from the target at which to begin inserting.
        /// </param>
        /// <param name="insertedElements">
        /// [out] The inserted elements.
        /// </param>
        ///
        /// <returns>
        /// The current CQ object.
        /// </returns>

        protected CQ InsertAtOffset(CQ target, int offset, out CQ insertedElements)
        {
            // Copy the target list: it could change otherwise
            List <IDomObject> targets = new List <IDomObject>(target);
            bool isTargetDisconnected = (target.CsQueryParent != null && target.Document != target.CsQueryParent.Document) ||
                                        targets.Any(item => item.ParentNode == null);

            bool isFirst = true;


            insertedElements = NewCqUnbound();


            // bind the source to the target's document if it was itself a CsQuery object, and update its selection set to reflect the
            // current document.

            Document = target.Document;

            if (isTargetDisconnected)
            {
                // When the target is disconnected, just append elements to the selection set, not to the DOM

                CQ result = NewCqInDomain();
                result.CsQueryParent = this.CsQueryParent;

                if (offset == 0)
                {
                    result.AddSelection(Selection);
                }
                result.AddSelection(target);

                if (offset == 1)
                {
                    result.AddSelection(Selection);
                }

                result.SelectionSet.OutputOrder = SelectionSetOrder.OrderAdded;
                insertedElements.AddSelection(Selection);
                return(result);
            }
            else
            {
                foreach (var el in targets)
                {
                    bool isElDisconnected = el.ParentNode == null;

                    if (isFirst)
                    {
                        insertedElements.AddSelection(SelectionSet);
                        InsertAtOffset(el, offset);
                        isFirst = false;
                    }
                    else
                    {
                        var clone = this.Clone();
                        clone.InsertAtOffset(el, offset);
                        insertedElements.AddSelection(clone);
                    }
                }
            }
            return(target);
        }
Пример #13
0
        /// <summary>
        /// Insert every element in the selection at or after the index of each target (adding offset to
        /// the index). If there is more than one target, the a clone is made of the selection for the
        /// 2nd and later targets.
        /// </summary>
        ///
        /// <remarks>
        /// This is a helper for Before and After. There is special handling when the target is not part
        /// of a DOM. Instead of altering the DOM, this method will alter the selection set, and return a
        /// CQ object that contains the new sequence. Normally, it would return the same CQ object (but
        /// alter the DOM).
        /// </remarks>
        ///
        /// <param name="target">
        /// The target element.
        /// </param>
        /// <param name="offset">
        /// The offset from the target at which to begin inserting.
        /// </param>
        /// <param name="insertedElements">
        /// [out] The inserted elements.
        /// </param>
        ///
        /// <returns>
        /// The current CQ object.
        /// </returns>

        protected CQ InsertAtOffset(CQ target, int offset, out CQ insertedElements)
        {
            
            // Copy the target list: it could change otherwise
            List<IDomObject> targets = new List<IDomObject>(target);
            bool isTargetDisconnected = (target.CsQueryParent != null && target.Document != target.CsQueryParent.Document) ||
                targets.Any(item => item.ParentNode == null);

            bool isFirst = true;

            
            insertedElements = NewCqUnbound();
            

            // bind the source to the target's document if it was itself a CsQuery object, and update its selection set to reflect the 
            // current document.

            Document = target.Document;

            if (isTargetDisconnected)
            {
                // When the target is disconnected, just append elements to the selection set, not to the DOM
                    
                CQ result = NewCqInDomain();
                result.CsQueryParent = this.CsQueryParent;

                if (offset == 0)
                {
                    result.AddSelection(Selection);
                }
                result.AddSelection(target);

                if (offset == 1)
                {
                    result.AddSelection(Selection);
                }

                result.SelectionSet.OutputOrder = SelectionSetOrder.OrderAdded;
                insertedElements.AddSelection(Selection);
                return result;
            }
            else
            {

                foreach (var el in targets)
                {
                    bool isElDisconnected = el.ParentNode == null;
                    
                    if (isFirst)
                    {
                        insertedElements.AddSelection(SelectionSet);
                        InsertAtOffset(el, offset);
                        isFirst = false;
                    }
                    else
                    {
                        var clone = this.Clone();
                        clone.InsertAtOffset(el, offset);
                        insertedElements.AddSelection(clone);
                    }
                    
                }
            }
            return target;
        }
Пример #14
0
        /// <summary>
        /// Add elements to the set of matched elements.
        /// </summary>
        ///
        /// <param name="elements">
        /// The elements to add.
        /// </param>
        ///
        /// <returns>
        /// A new CQ object.
        /// </returns>
        ///
        /// <url>
        /// http://api.jquery.com/add/
        /// </url>

        public CQ Add(IEnumerable<IDomObject> elements)
        {
            CQ res = new CQ(this);
            res.AddSelection(elements);
            return res;
        }
Пример #15
0
        /// <summary>
        /// Configures a new instance for a sequence of elements and an existing context.
        /// </summary>
        ///
        /// <param name="elements">
        /// A sequence of elements.
        /// </param>
        /// <param name="context">
        /// The context.
        /// </param>

        private void ConfigureNewInstance(CQ dom, IEnumerable <IDomObject> elements, CQ context)
        {
            dom.CsQueryParent = context;
            dom.AddSelection(elements);
        }