diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/agpl-3.0.txt releases/unplus-2.043/source/agpl-3.0.txt
1,661d0
< GNU AFFERO GENERAL PUBLIC LICENSE
< Version 3, 19 November 2007
<
< Copyright (C) 2007 Free Software Foundation, Inc.
< Everyone is permitted to copy and distribute verbatim copies
< of this license document, but changing it is not allowed.
<
< Preamble
<
< The GNU Affero General Public License is a free, copyleft license for
< software and other kinds of works, specifically designed to ensure
< cooperation with the community in the case of network server software.
<
< The licenses for most software and other practical works are designed
< to take away your freedom to share and change the works. By contrast,
< our General Public Licenses are intended to guarantee your freedom to
< share and change all versions of a program--to make sure it remains free
< software for all its users.
<
< When we speak of free software, we are referring to freedom, not
< price. Our General Public Licenses are designed to make sure that you
< have the freedom to distribute copies of free software (and charge for
< them if you wish), that you receive source code or can get it if you
< want it, that you can change the software or use pieces of it in new
< free programs, and that you know you can do these things.
<
< Developers that use our General Public Licenses protect your rights
< with two steps: (1) assert copyright on the software, and (2) offer
< you this License which gives you legal permission to copy, distribute
< and/or modify the software.
<
< A secondary benefit of defending all users' freedom is that
< improvements made in alternate versions of the program, if they
< receive widespread use, become available for other developers to
< incorporate. Many developers of free software are heartened and
< encouraged by the resulting cooperation. However, in the case of
< software used on network servers, this result may fail to come about.
< The GNU General Public License permits making a modified version and
< letting the public access it on a server without ever releasing its
< source code to the public.
<
< The GNU Affero General Public License is designed specifically to
< ensure that, in such cases, the modified source code becomes available
< to the community. It requires the operator of a network server to
< provide the source code of the modified version running there to the
< users of that server. Therefore, public use of a modified version, on
< a publicly accessible server, gives the public access to the source
< code of the modified version.
<
< An older license, called the Affero General Public License and
< published by Affero, was designed to accomplish similar goals. This is
< a different license, not a version of the Affero GPL, but Affero has
< released a new version of the Affero GPL which permits relicensing under
< this license.
<
< The precise terms and conditions for copying, distribution and
< modification follow.
<
< TERMS AND CONDITIONS
<
< 0. Definitions.
<
< "This License" refers to version 3 of the GNU Affero General Public License.
<
< "Copyright" also means copyright-like laws that apply to other kinds of
< works, such as semiconductor masks.
<
< "The Program" refers to any copyrightable work licensed under this
< License. Each licensee is addressed as "you". "Licensees" and
< "recipients" may be individuals or organizations.
<
< To "modify" a work means to copy from or adapt all or part of the work
< in a fashion requiring copyright permission, other than the making of an
< exact copy. The resulting work is called a "modified version" of the
< earlier work or a work "based on" the earlier work.
<
< A "covered work" means either the unmodified Program or a work based
< on the Program.
<
< To "propagate" a work means to do anything with it that, without
< permission, would make you directly or secondarily liable for
< infringement under applicable copyright law, except executing it on a
< computer or modifying a private copy. Propagation includes copying,
< distribution (with or without modification), making available to the
< public, and in some countries other activities as well.
<
< To "convey" a work means any kind of propagation that enables other
< parties to make or receive copies. Mere interaction with a user through
< a computer network, with no transfer of a copy, is not conveying.
<
< An interactive user interface displays "Appropriate Legal Notices"
< to the extent that it includes a convenient and prominently visible
< feature that (1) displays an appropriate copyright notice, and (2)
< tells the user that there is no warranty for the work (except to the
< extent that warranties are provided), that licensees may convey the
< work under this License, and how to view a copy of this License. If
< the interface presents a list of user commands or options, such as a
< menu, a prominent item in the list meets this criterion.
<
< 1. Source Code.
<
< The "source code" for a work means the preferred form of the work
< for making modifications to it. "Object code" means any non-source
< form of a work.
<
< A "Standard Interface" means an interface that either is an official
< standard defined by a recognized standards body, or, in the case of
< interfaces specified for a particular programming language, one that
< is widely used among developers working in that language.
<
< The "System Libraries" of an executable work include anything, other
< than the work as a whole, that (a) is included in the normal form of
< packaging a Major Component, but which is not part of that Major
< Component, and (b) serves only to enable use of the work with that
< Major Component, or to implement a Standard Interface for which an
< implementation is available to the public in source code form. A
< "Major Component", in this context, means a major essential component
< (kernel, window system, and so on) of the specific operating system
< (if any) on which the executable work runs, or a compiler used to
< produce the work, or an object code interpreter used to run it.
<
< The "Corresponding Source" for a work in object code form means all
< the source code needed to generate, install, and (for an executable
< work) run the object code and to modify the work, including scripts to
< control those activities. However, it does not include the work's
< System Libraries, or general-purpose tools or generally available free
< programs which are used unmodified in performing those activities but
< which are not part of the work. For example, Corresponding Source
< includes interface definition files associated with source files for
< the work, and the source code for shared libraries and dynamically
< linked subprograms that the work is specifically designed to require,
< such as by intimate data communication or control flow between those
< subprograms and other parts of the work.
<
< The Corresponding Source need not include anything that users
< can regenerate automatically from other parts of the Corresponding
< Source.
<
< The Corresponding Source for a work in source code form is that
< same work.
<
< 2. Basic Permissions.
<
< All rights granted under this License are granted for the term of
< copyright on the Program, and are irrevocable provided the stated
< conditions are met. This License explicitly affirms your unlimited
< permission to run the unmodified Program. The output from running a
< covered work is covered by this License only if the output, given its
< content, constitutes a covered work. This License acknowledges your
< rights of fair use or other equivalent, as provided by copyright law.
<
< You may make, run and propagate covered works that you do not
< convey, without conditions so long as your license otherwise remains
< in force. You may convey covered works to others for the sole purpose
< of having them make modifications exclusively for you, or provide you
< with facilities for running those works, provided that you comply with
< the terms of this License in conveying all material for which you do
< not control copyright. Those thus making or running the covered works
< for you must do so exclusively on your behalf, under your direction
< and control, on terms that prohibit them from making any copies of
< your copyrighted material outside their relationship with you.
<
< Conveying under any other circumstances is permitted solely under
< the conditions stated below. Sublicensing is not allowed; section 10
< makes it unnecessary.
<
< 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
<
< No covered work shall be deemed part of an effective technological
< measure under any applicable law fulfilling obligations under article
< 11 of the WIPO copyright treaty adopted on 20 December 1996, or
< similar laws prohibiting or restricting circumvention of such
< measures.
<
< When you convey a covered work, you waive any legal power to forbid
< circumvention of technological measures to the extent such circumvention
< is effected by exercising rights under this License with respect to
< the covered work, and you disclaim any intention to limit operation or
< modification of the work as a means of enforcing, against the work's
< users, your or third parties' legal rights to forbid circumvention of
< technological measures.
<
< 4. Conveying Verbatim Copies.
<
< You may convey verbatim copies of the Program's source code as you
< receive it, in any medium, provided that you conspicuously and
< appropriately publish on each copy an appropriate copyright notice;
< keep intact all notices stating that this License and any
< non-permissive terms added in accord with section 7 apply to the code;
< keep intact all notices of the absence of any warranty; and give all
< recipients a copy of this License along with the Program.
<
< You may charge any price or no price for each copy that you convey,
< and you may offer support or warranty protection for a fee.
<
< 5. Conveying Modified Source Versions.
<
< You may convey a work based on the Program, or the modifications to
< produce it from the Program, in the form of source code under the
< terms of section 4, provided that you also meet all of these conditions:
<
< a) The work must carry prominent notices stating that you modified
< it, and giving a relevant date.
<
< b) The work must carry prominent notices stating that it is
< released under this License and any conditions added under section
< 7. This requirement modifies the requirement in section 4 to
< "keep intact all notices".
<
< c) You must license the entire work, as a whole, under this
< License to anyone who comes into possession of a copy. This
< License will therefore apply, along with any applicable section 7
< additional terms, to the whole of the work, and all its parts,
< regardless of how they are packaged. This License gives no
< permission to license the work in any other way, but it does not
< invalidate such permission if you have separately received it.
<
< d) If the work has interactive user interfaces, each must display
< Appropriate Legal Notices; however, if the Program has interactive
< interfaces that do not display Appropriate Legal Notices, your
< work need not make them do so.
<
< A compilation of a covered work with other separate and independent
< works, which are not by their nature extensions of the covered work,
< and which are not combined with it such as to form a larger program,
< in or on a volume of a storage or distribution medium, is called an
< "aggregate" if the compilation and its resulting copyright are not
< used to limit the access or legal rights of the compilation's users
< beyond what the individual works permit. Inclusion of a covered work
< in an aggregate does not cause this License to apply to the other
< parts of the aggregate.
<
< 6. Conveying Non-Source Forms.
<
< You may convey a covered work in object code form under the terms
< of sections 4 and 5, provided that you also convey the
< machine-readable Corresponding Source under the terms of this License,
< in one of these ways:
<
< a) Convey the object code in, or embodied in, a physical product
< (including a physical distribution medium), accompanied by the
< Corresponding Source fixed on a durable physical medium
< customarily used for software interchange.
<
< b) Convey the object code in, or embodied in, a physical product
< (including a physical distribution medium), accompanied by a
< written offer, valid for at least three years and valid for as
< long as you offer spare parts or customer support for that product
< model, to give anyone who possesses the object code either (1) a
< copy of the Corresponding Source for all the software in the
< product that is covered by this License, on a durable physical
< medium customarily used for software interchange, for a price no
< more than your reasonable cost of physically performing this
< conveying of source, or (2) access to copy the
< Corresponding Source from a network server at no charge.
<
< c) Convey individual copies of the object code with a copy of the
< written offer to provide the Corresponding Source. This
< alternative is allowed only occasionally and noncommercially, and
< only if you received the object code with such an offer, in accord
< with subsection 6b.
<
< d) Convey the object code by offering access from a designated
< place (gratis or for a charge), and offer equivalent access to the
< Corresponding Source in the same way through the same place at no
< further charge. You need not require recipients to copy the
< Corresponding Source along with the object code. If the place to
< copy the object code is a network server, the Corresponding Source
< may be on a different server (operated by you or a third party)
< that supports equivalent copying facilities, provided you maintain
< clear directions next to the object code saying where to find the
< Corresponding Source. Regardless of what server hosts the
< Corresponding Source, you remain obligated to ensure that it is
< available for as long as needed to satisfy these requirements.
<
< e) Convey the object code using peer-to-peer transmission, provided
< you inform other peers where the object code and Corresponding
< Source of the work are being offered to the general public at no
< charge under subsection 6d.
<
< A separable portion of the object code, whose source code is excluded
< from the Corresponding Source as a System Library, need not be
< included in conveying the object code work.
<
< A "User Product" is either (1) a "consumer product", which means any
< tangible personal property which is normally used for personal, family,
< or household purposes, or (2) anything designed or sold for incorporation
< into a dwelling. In determining whether a product is a consumer product,
< doubtful cases shall be resolved in favor of coverage. For a particular
< product received by a particular user, "normally used" refers to a
< typical or common use of that class of product, regardless of the status
< of the particular user or of the way in which the particular user
< actually uses, or expects or is expected to use, the product. A product
< is a consumer product regardless of whether the product has substantial
< commercial, industrial or non-consumer uses, unless such uses represent
< the only significant mode of use of the product.
<
< "Installation Information" for a User Product means any methods,
< procedures, authorization keys, or other information required to install
< and execute modified versions of a covered work in that User Product from
< a modified version of its Corresponding Source. The information must
< suffice to ensure that the continued functioning of the modified object
< code is in no case prevented or interfered with solely because
< modification has been made.
<
< If you convey an object code work under this section in, or with, or
< specifically for use in, a User Product, and the conveying occurs as
< part of a transaction in which the right of possession and use of the
< User Product is transferred to the recipient in perpetuity or for a
< fixed term (regardless of how the transaction is characterized), the
< Corresponding Source conveyed under this section must be accompanied
< by the Installation Information. But this requirement does not apply
< if neither you nor any third party retains the ability to install
< modified object code on the User Product (for example, the work has
< been installed in ROM).
<
< The requirement to provide Installation Information does not include a
< requirement to continue to provide support service, warranty, or updates
< for a work that has been modified or installed by the recipient, or for
< the User Product in which it has been modified or installed. Access to a
< network may be denied when the modification itself materially and
< adversely affects the operation of the network or violates the rules and
< protocols for communication across the network.
<
< Corresponding Source conveyed, and Installation Information provided,
< in accord with this section must be in a format that is publicly
< documented (and with an implementation available to the public in
< source code form), and must require no special password or key for
< unpacking, reading or copying.
<
< 7. Additional Terms.
<
< "Additional permissions" are terms that supplement the terms of this
< License by making exceptions from one or more of its conditions.
< Additional permissions that are applicable to the entire Program shall
< be treated as though they were included in this License, to the extent
< that they are valid under applicable law. If additional permissions
< apply only to part of the Program, that part may be used separately
< under those permissions, but the entire Program remains governed by
< this License without regard to the additional permissions.
<
< When you convey a copy of a covered work, you may at your option
< remove any additional permissions from that copy, or from any part of
< it. (Additional permissions may be written to require their own
< removal in certain cases when you modify the work.) You may place
< additional permissions on material, added by you to a covered work,
< for which you have or can give appropriate copyright permission.
<
< Notwithstanding any other provision of this License, for material you
< add to a covered work, you may (if authorized by the copyright holders of
< that material) supplement the terms of this License with terms:
<
< a) Disclaiming warranty or limiting liability differently from the
< terms of sections 15 and 16 of this License; or
<
< b) Requiring preservation of specified reasonable legal notices or
< author attributions in that material or in the Appropriate Legal
< Notices displayed by works containing it; or
<
< c) Prohibiting misrepresentation of the origin of that material, or
< requiring that modified versions of such material be marked in
< reasonable ways as different from the original version; or
<
< d) Limiting the use for publicity purposes of names of licensors or
< authors of the material; or
<
< e) Declining to grant rights under trademark law for use of some
< trade names, trademarks, or service marks; or
<
< f) Requiring indemnification of licensors and authors of that
< material by anyone who conveys the material (or modified versions of
< it) with contractual assumptions of liability to the recipient, for
< any liability that these contractual assumptions directly impose on
< those licensors and authors.
<
< All other non-permissive additional terms are considered "further
< restrictions" within the meaning of section 10. If the Program as you
< received it, or any part of it, contains a notice stating that it is
< governed by this License along with a term that is a further
< restriction, you may remove that term. If a license document contains
< a further restriction but permits relicensing or conveying under this
< License, you may add to a covered work material governed by the terms
< of that license document, provided that the further restriction does
< not survive such relicensing or conveying.
<
< If you add terms to a covered work in accord with this section, you
< must place, in the relevant source files, a statement of the
< additional terms that apply to those files, or a notice indicating
< where to find the applicable terms.
<
< Additional terms, permissive or non-permissive, may be stated in the
< form of a separately written license, or stated as exceptions;
< the above requirements apply either way.
<
< 8. Termination.
<
< You may not propagate or modify a covered work except as expressly
< provided under this License. Any attempt otherwise to propagate or
< modify it is void, and will automatically terminate your rights under
< this License (including any patent licenses granted under the third
< paragraph of section 11).
<
< However, if you cease all violation of this License, then your
< license from a particular copyright holder is reinstated (a)
< provisionally, unless and until the copyright holder explicitly and
< finally terminates your license, and (b) permanently, if the copyright
< holder fails to notify you of the violation by some reasonable means
< prior to 60 days after the cessation.
<
< Moreover, your license from a particular copyright holder is
< reinstated permanently if the copyright holder notifies you of the
< violation by some reasonable means, this is the first time you have
< received notice of violation of this License (for any work) from that
< copyright holder, and you cure the violation prior to 30 days after
< your receipt of the notice.
<
< Termination of your rights under this section does not terminate the
< licenses of parties who have received copies or rights from you under
< this License. If your rights have been terminated and not permanently
< reinstated, you do not qualify to receive new licenses for the same
< material under section 10.
<
< 9. Acceptance Not Required for Having Copies.
<
< You are not required to accept this License in order to receive or
< run a copy of the Program. Ancillary propagation of a covered work
< occurring solely as a consequence of using peer-to-peer transmission
< to receive a copy likewise does not require acceptance. However,
< nothing other than this License grants you permission to propagate or
< modify any covered work. These actions infringe copyright if you do
< not accept this License. Therefore, by modifying or propagating a
< covered work, you indicate your acceptance of this License to do so.
<
< 10. Automatic Licensing of Downstream Recipients.
<
< Each time you convey a covered work, the recipient automatically
< receives a license from the original licensors, to run, modify and
< propagate that work, subject to this License. You are not responsible
< for enforcing compliance by third parties with this License.
<
< An "entity transaction" is a transaction transferring control of an
< organization, or substantially all assets of one, or subdividing an
< organization, or merging organizations. If propagation of a covered
< work results from an entity transaction, each party to that
< transaction who receives a copy of the work also receives whatever
< licenses to the work the party's predecessor in interest had or could
< give under the previous paragraph, plus a right to possession of the
< Corresponding Source of the work from the predecessor in interest, if
< the predecessor has it or can get it with reasonable efforts.
<
< You may not impose any further restrictions on the exercise of the
< rights granted or affirmed under this License. For example, you may
< not impose a license fee, royalty, or other charge for exercise of
< rights granted under this License, and you may not initiate litigation
< (including a cross-claim or counterclaim in a lawsuit) alleging that
< any patent claim is infringed by making, using, selling, offering for
< sale, or importing the Program or any portion of it.
<
< 11. Patents.
<
< A "contributor" is a copyright holder who authorizes use under this
< License of the Program or a work on which the Program is based. The
< work thus licensed is called the contributor's "contributor version".
<
< A contributor's "essential patent claims" are all patent claims
< owned or controlled by the contributor, whether already acquired or
< hereafter acquired, that would be infringed by some manner, permitted
< by this License, of making, using, or selling its contributor version,
< but do not include claims that would be infringed only as a
< consequence of further modification of the contributor version. For
< purposes of this definition, "control" includes the right to grant
< patent sublicenses in a manner consistent with the requirements of
< this License.
<
< Each contributor grants you a non-exclusive, worldwide, royalty-free
< patent license under the contributor's essential patent claims, to
< make, use, sell, offer for sale, import and otherwise run, modify and
< propagate the contents of its contributor version.
<
< In the following three paragraphs, a "patent license" is any express
< agreement or commitment, however denominated, not to enforce a patent
< (such as an express permission to practice a patent or covenant not to
< sue for patent infringement). To "grant" such a patent license to a
< party means to make such an agreement or commitment not to enforce a
< patent against the party.
<
< If you convey a covered work, knowingly relying on a patent license,
< and the Corresponding Source of the work is not available for anyone
< to copy, free of charge and under the terms of this License, through a
< publicly available network server or other readily accessible means,
< then you must either (1) cause the Corresponding Source to be so
< available, or (2) arrange to deprive yourself of the benefit of the
< patent license for this particular work, or (3) arrange, in a manner
< consistent with the requirements of this License, to extend the patent
< license to downstream recipients. "Knowingly relying" means you have
< actual knowledge that, but for the patent license, your conveying the
< covered work in a country, or your recipient's use of the covered work
< in a country, would infringe one or more identifiable patents in that
< country that you have reason to believe are valid.
<
< If, pursuant to or in connection with a single transaction or
< arrangement, you convey, or propagate by procuring conveyance of, a
< covered work, and grant a patent license to some of the parties
< receiving the covered work authorizing them to use, propagate, modify
< or convey a specific copy of the covered work, then the patent license
< you grant is automatically extended to all recipients of the covered
< work and works based on it.
<
< A patent license is "discriminatory" if it does not include within
< the scope of its coverage, prohibits the exercise of, or is
< conditioned on the non-exercise of one or more of the rights that are
< specifically granted under this License. You may not convey a covered
< work if you are a party to an arrangement with a third party that is
< in the business of distributing software, under which you make payment
< to the third party based on the extent of your activity of conveying
< the work, and under which the third party grants, to any of the
< parties who would receive the covered work from you, a discriminatory
< patent license (a) in connection with copies of the covered work
< conveyed by you (or copies made from those copies), or (b) primarily
< for and in connection with specific products or compilations that
< contain the covered work, unless you entered into that arrangement,
< or that patent license was granted, prior to 28 March 2007.
<
< Nothing in this License shall be construed as excluding or limiting
< any implied license or other defenses to infringement that may
< otherwise be available to you under applicable patent law.
<
< 12. No Surrender of Others' Freedom.
<
< If conditions are imposed on you (whether by court order, agreement or
< otherwise) that contradict the conditions of this License, they do not
< excuse you from the conditions of this License. If you cannot convey a
< covered work so as to satisfy simultaneously your obligations under this
< License and any other pertinent obligations, then as a consequence you may
< not convey it at all. For example, if you agree to terms that obligate you
< to collect a royalty for further conveying from those to whom you convey
< the Program, the only way you could satisfy both those terms and this
< License would be to refrain entirely from conveying the Program.
<
< 13. Remote Network Interaction; Use with the GNU General Public License.
<
< Notwithstanding any other provision of this License, if you modify the
< Program, your modified version must prominently offer all users
< interacting with it remotely through a computer network (if your version
< supports such interaction) an opportunity to receive the Corresponding
< Source of your version by providing access to the Corresponding Source
< from a network server at no charge, through some standard or customary
< means of facilitating copying of software. This Corresponding Source
< shall include the Corresponding Source for any work covered by version 3
< of the GNU General Public License that is incorporated pursuant to the
< following paragraph.
<
< Notwithstanding any other provision of this License, you have
< permission to link or combine any covered work with a work licensed
< under version 3 of the GNU General Public License into a single
< combined work, and to convey the resulting work. The terms of this
< License will continue to apply to the part which is the covered work,
< but the work with which it is combined will remain governed by version
< 3 of the GNU General Public License.
<
< 14. Revised Versions of this License.
<
< The Free Software Foundation may publish revised and/or new versions of
< the GNU Affero General Public License from time to time. Such new versions
< will be similar in spirit to the present version, but may differ in detail to
< address new problems or concerns.
<
< Each version is given a distinguishing version number. If the
< Program specifies that a certain numbered version of the GNU Affero General
< Public License "or any later version" applies to it, you have the
< option of following the terms and conditions either of that numbered
< version or of any later version published by the Free Software
< Foundation. If the Program does not specify a version number of the
< GNU Affero General Public License, you may choose any version ever published
< by the Free Software Foundation.
<
< If the Program specifies that a proxy can decide which future
< versions of the GNU Affero General Public License can be used, that proxy's
< public statement of acceptance of a version permanently authorizes you
< to choose that version for the Program.
<
< Later license versions may give you additional or different
< permissions. However, no additional obligations are imposed on any
< author or copyright holder as a result of your choosing to follow a
< later version.
<
< 15. Disclaimer of Warranty.
<
< THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
< APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
< HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
< OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
< THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
< PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
< IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
< ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
<
< 16. Limitation of Liability.
<
< IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
< WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
< THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
< GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
< USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
< DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
< PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
< EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
< SUCH DAMAGES.
<
< 17. Interpretation of Sections 15 and 16.
<
< If the disclaimer of warranty and limitation of liability provided
< above cannot be given local legal effect according to their terms,
< reviewing courts shall apply local law that most closely approximates
< an absolute waiver of all civil liability in connection with the
< Program, unless a warranty or assumption of liability accompanies a
< copy of the Program in return for a fee.
<
< END OF TERMS AND CONDITIONS
<
< How to Apply These Terms to Your New Programs
<
< If you develop a new program, and you want it to be of the greatest
< possible use to the public, the best way to achieve this is to make it
< free software which everyone can redistribute and change under these terms.
<
< To do so, attach the following notices to the program. It is safest
< to attach them to the start of each source file to most effectively
< state the exclusion of warranty; and each file should have at least
< the "copyright" line and a pointer to where the full notice is found.
<
<
< Copyright (C)
<
< This program is free software: you can redistribute it and/or modify
< it under the terms of the GNU Affero General Public License as published by
< the Free Software Foundation, either version 3 of the License, or
< (at your option) any later version.
<
< This program is distributed in the hope that it will be useful,
< but WITHOUT ANY WARRANTY; without even the implied warranty of
< MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< GNU Affero General Public License for more details.
<
< You should have received a copy of the GNU Affero General Public License
< along with this program. If not, see .
<
< Also add information on how to contact you by electronic and paper mail.
<
< If your software can interact with users remotely through a computer
< network, you should also make sure that it provides a way for users to
< get its source. For example, if your program is a web application, its
< interface could display a "Source" link that leads users to an archive
< of the code. There are many ways you could offer source, and different
< solutions will be better for different programs; see section 13 for the
< specific requirements.
<
< You should also get your employer (if you work as a programmer) or school,
< if any, to sign a "copyright disclaimer" for the program, if necessary.
< For more information on this, and how to apply and follow the GNU AGPL, see
< .
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/common.js releases/unplus-2.043/source/chrome/content/common.js
1,156d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
< /**
< * Common things which need to be loaded everywhere,
< * such as getting settings.
< */
< UnPlug2 = {
< UnPlug2 : function () {
< var prefs_service = Components.classes["@mozilla.org/preferences-service;1"]
< .getService(Components.interfaces.nsIPrefService)
< this._prefs = prefs_service.getBranch("extensions.unplug2.");
< this._root_prefs = prefs_service.getBranch("");
< this._locale = Components.classes["@mozilla.org/intl/stringbundle;1"]
< .getService(Components.interfaces.nsIStringBundleService)
< .createBundle("chrome://unplug/locale/strings.txt");
< this._js_console = Components.classes["@mozilla.org/consoleservice;1"]
< .getService(Components.interfaces.nsIConsoleService);
< this._re_trim = /^\s*(.*?)\s*$/m;
< this._unicodeconvert = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
< .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
< },
<
< /**
< * get_pref
< * return value of an unplug setting (or def if it doesn't exist)
< */
< get_pref : function (name, def) {
< return UnPlug2._get_pref(name, def, UnPlug2._prefs);
< },
<
< /**
< * return value of a pref (or def if it doesn't exist
< */
< get_root_pref : function (name, def) {
< return UnPlug2._get_pref(name, def, UnPlug2._root_prefs);
< },
<
< _get_pref : function (name, def, prefs) {
< switch (prefs.getPrefType(name)) {
< case prefs.PREF_STRING:
< return prefs.getCharPref(name);
< case prefs.PREF_INT:
< return prefs.getIntPref(name);
< case prefs.PREF_BOOL:
< return prefs.getBoolPref(name);
< default:
< return def;
< }
< },
<
< /**
< * set_pref
< * set value of an unplug setting
< */
< set_pref : function (name, value) {
< switch (typeof(value)) {
< case "number":
< this._prefs.setIntPref(name, value);
< break
< case "boolean":
< this._prefs.setBoolPref(name, value);
< break
< case "string":
< this._prefs.setCharPref(name, value);
< break
< default:
< throw "Cannot set pref of type" + typeof(value);
< }
< },
<
< /**
< * return a translated version of the string
< */
< str : function (name) {
< try {
< return this._locale.GetStringFromName(name)
< } catch(e) {
< return "#{" + name + "}";
< }
< },
<
< /**
< * Print to js console log
< */
< log : function (msg) {
< this._js_console.logStringMessage("UnPlug2: " + msg);
< },
<
< /**
< * document.getElelementById for xml files
< */
< get_element : function (node, tagname, idname) {
< var ellist = node.getElementsByTagName(tagname);
< for (var i=0; i < ellist.length; i++) {
< if (ellist[i].getAttribute("id") == idname) {
< return ellist[i]
< }
< }
< return null;
< },
<
< trim : function (x) {
< if (!x)
< return "";
< return UnPlug2._re_trim.exec(x)[1];
< },
<
< decode : function (encoding, s) {
< this._unicodeconvert.charset = encoding
< return this._unicodeconvert.ConvertToUnicode(s);
< },
<
< toString : function () {
< return "";
< },
<
< // these should be updated by hand:
< version : 2.042,
< codename : "newyork",
<
< // the following line is auto-generated by upload.sh:
< revision : 201102282323,
<
< // do one-time setup stuff:
< setup_number : 1,
<
< end_of_object : 1 }
<
< // init
< UnPlug2.UnPlug2();
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/config/config.js releases/unplus-2.043/source/chrome/content/config/config.js
1,191d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
< function do_load() {
< if (window.arguments && window.arguments.length >= 1) {
< if (window.arguments[0] == "setup") {
< setup_unplug();
< }
< }
< set_text();
< set_extern_tools();
< detect_toolbarbutton();
< goto_tab_requested();
< setup_restart_notices();
< }
<
< function set_text() {
< document.getElementById("dmethod-saveas").setAttribute("label", UnPlug2.str("dmethod.saveas"))
< document.getElementById("dmethod-openover").setAttribute("label", UnPlug2.str("dmethod.open-over"))
< }
<
< function set_extern_tools() {
< var names = UnPlug2DownloadMethods.get_extern_tool_names();
< var elem = document.getElementById("extern-tool");
< for (var i = 0; i < names.length; ++i) {
< elem.appendItem(UnPlug2.str("dmethod." + names[i]), names[i]);
< }
< elem.selectedIndex = 0;
< }
<
< function edit_extern_tool() {
< var elem = document.getElementById("extern-tool");
< var name = elem.selectedItem.value;
< window.openDialog("chrome://unplug/content/config/extern.xul", "chrome,modal", "unplug_extern", name);
< }
<
< function browser_window() {
< var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
< .getService(Components.interfaces.nsIWindowMediator);
< var w = wm.getMostRecentWindow("navigator:browser");
< return w;
< }
<
< function detect_toolbarbutton() {
< var w = browser_window()
< if (!w)
< return;
< var tbl = w.document.getElementsByTagName("toolbar");
< var have_btn = false;
< for (var i = 0; i < tbl.length; ++i) {
< if (tbl[i].currentSet.split(",").indexOf("unplug2_toolbarbutton") >= 0) {
< have_btn = true;
< break;
< }
< }
< var checkbox = document.getElementById("add_toolbar_button");
< checkbox.checked = have_btn;
< checkbox.disabled = false;
< }
<
< function toggle_toolbarbutton() {
< var w = browser_window()
< if (!w)
< return;
< var tbl = w.document.getElementsByTagName("toolbar");
< var have_btn = false;
< for (var i = 0; i < tbl.length; ++i) {
< if (tbl[i].currentSet.split(",").indexOf("unplug2_toolbarbutton") >= 0) {
< // remove button
< var updatedset = tbl[i].currentSet.split(",").filter(function (x) {
< return x != "unplug2_toolbarbutton";
< }).join(",");
< tbl[i].setAttribute("currentset", updatedset);
< w.document.persist(tbl[i].getAttribute("id"),"currentset");
< return;
< }
< }
<
< var navtoolbar = w.document.getElementById("nav-bar");
< if (!navtoolbar || navtoolbar.currentSet.indexOf(",") < 0) {
< alert("Cannot add - where's nav-bar?");
< return;
< }
< // add button
< navtoolbar.setAttribute("currentset", navtoolbar.currentSet + ",unplug2_toolbarbutton");
< w.document.persist(navtoolbar.getAttribute("id"),"currentset");
< }
<
< function goto_tab_requested() {
< if (window.arguments && window.arguments.length >= 1)
< goto_tab(window.arguments[0]);
< }
<
< function goto_tab(tabname) {
< var pwin = document.getElementById("cn_unplug2_config");
< var p = null;
< switch (tabname) {
< case "welcome":
< case "setup":
< p = document.getElementById("tababout");
< break;
< case "main":
< p = document.getElementById("tabgeneral");
< break;
< case "downloader":
< p = document.getElementById("tabdownload");
< break;
< }
< pwin.showPane(p);
< }
<
< function setup_restart_notices() {
< var showpopup = (function () {
< var box = document.getElementById("integration_notification");
< var notification = box.getNotificationWithValue("restart-needed");
< if (!notification) {
< var buttons = [{
< accessKey : "R",
< callback : restart_firefox,
< label : "Restart",
< popup : null }];
< box.appendNotification(
< "Restart firefox to apply these changes",
< "restart-needed",
< "chrome://browser/skin/Info.png",
< box.PRIORITY_WARNING_MEDIUM,
< buttons);
< }
< });
< var el = document.getElementsByClassName("needs_restart");
< for (var i = 0; i < el.length; ++i) {
< el[i].addEventListener("command", showpopup, false);
< };
< }
<
< function restart_firefox() {
< // Like chrome://mozapps/content/extensions/extensions.js
< const nsIAppStartup = Components.interfaces.nsIAppStartup;
< Components.classes["@mozilla.org/toolkit/app-startup;1"]
< .getService(nsIAppStartup)
< .quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit);
< }
<
< /*
< * This function is called once, to set up unplug
< */
< function setup_unplug() {
< // check if we've set up everthing we need to (eg: installed toolbar button, etc)
< switch (UnPlug2.get_pref("setup_number", 0)) {
< case 0:
< /* We're adding ourselves to the add-ons bar,
< * so this is less important. We'll skip it by default:
< if (!detect_toolbarbutton())
< toggle_toolbarbutton();
< */
< UnPlug2.set_pref("setup_number", 1);
< break;
< default:
< UnPlug2.log("Unknown setup_number " + UnPlug2.get_pref("setup_number", 0));
< break;
< }
<
< // show setup complete message
< document.getElementById("setup_complete").style.display = "block";
< }
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/config/config.xul releases/unplus-2.043/source/chrome/content/config/config.xul
1,140d0
<
<
<
< %dtdcommon;
<
< %dtdlocal;
< ]>
<
<
<
<
<
<
<
<
<
<
<
<
< &about.description;
<
<
<
< &about.updated;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< &rulesxml.description;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/config/extern.js releases/unplus-2.043/source/chrome/content/config/extern.js
1,111d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
< var get_config_name = (function () {
< return (window.arguments && window.arguments[0]) || "ERROR";
< });
<
< var is_valid_file = (function (fname) {
< try {
< var f = Components.classes["@mozilla.org/file/local;1"]
< .createInstance(Components.interfaces.nsILocalFile);
< f.initWithPath(fname);
< return (f.exists() && f.isExecutable());
< } catch (e) {
< // initWithPath on windows for "/usr/bin/..." raises error
< return false;
< }
< });
<
< var onload = (function () {
< var config_name = get_config_name();
< var config_info = UnPlug2DownloadMethods.getinfo(config_name);
<
< var setup_dialog = (function () {
< document.getElementById("need-to-install").setAttribute("value",
< UnPlug2.str("need_to_install").replace("%s", UnPlug2.str("dmethod." + config_name)));
< document.getElementById("location-of").setAttribute("value",
< UnPlug2.str("location_of").replace("%s", UnPlug2.str("dmethod." + config_name)));
< if (config_info && config_info.weblinks) {
< var linkbox = document.getElementById("link-box");
< for (var i = 0; i < config_info.weblinks.length; ++i) {
< var l = document.createElement("label");
< l.className = "text-link";
< l.setAttribute("href", config_info.weblinks[i].url);
< l.setAttribute("value", config_info.weblinks[i].label);
< linkbox.appendChild(l);
< }
< }
< });
< var search_usual_places = (function () {
< var value = UnPlug2.get_pref("dmethod." + config_name) || "";
< document.getElementById("execfile").value = "";
< if (value && is_valid_file(value)) {
< document.getElementById("execfile").value = value;
< } else {
< if (config_info && config_info.exec_file_list) {
< for (var i = 0; i < config_info.exec_file_list.length; ++i) {
< if (is_valid_file(config_info.exec_file_list[i])) {
< document.getElementById("execfile").value = config_info.exec_file_list[i];
< break;
< }
< }
< }
< }
< document.getElementById("execfile").disabled = false;
< document.getElementById("browsebutton").disabled = false;
< });
< setup_dialog();
< window.setTimeout(search_usual_places, 2);
< });
< window.addEventListener("load", onload, false);
<
< var onaccept = (function () {
< var config_name = get_config_name();
< var elem = document.getElementById("execfile");
< if (!elem.value || is_valid_file(elem.value)) {
< UnPlug2.set_pref("dmethod." + config_name, elem.value);
< } else {
< alert("Not an executable file: " + elem.value);
< elem.focus();
< return false; // inhibit closing of page
< }
< });
<
<
< var dobrowse = (function () {
< var config_name = get_config_name();
< var title = UnPlug2.str("location_of").replace("%s", UnPlug2.str("dmethod." + config_name));
< var filepicker = Components.classes["@mozilla.org/filepicker;1"]
< .createInstance(Components.interfaces.nsIFilePicker);
< filepicker.init(window, title, Components.interfaces.nsIFilePicker.modeOpen);
<
< var ret = filepicker.show()
< if (ret == Components.interfaces.nsIFilePicker.returnOK) {
< document.getElementById("execfile").value = filepicker.file.path;
< }
< });
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/config/extern.xul releases/unplus-2.043/source/chrome/content/config/extern.xul
1,65d0
<
<
<
< %dtdcommon;
<
< %dtdlocal;
< ]>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/display/download.js releases/unplus-2.043/source/chrome/content/display/download.js
1,531d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
< var UnPlug2DownloadMethods = {
< _button_lookup : {},
< _button_names : [],
<
< add_button : (function(name, data) {
< this._button_names.push(name);
< this._button_lookup[name] = data;
< }),
<
< finish : (function () {
< var lookup = this._button_lookup;
<
< // fix for config
< var prefer = UnPlug2.get_pref("downloader");
< switch (prefer) {
< case "saveas" :
< lookup["saveas"].obscurity = -50;
< break;
< case "auto":
< // use add-ons if possible
< lookup["flashgot"].obscurity = -50;
< lookup["dta"].obscurity = -40;
< lookup["saveas"].obscurity = -30;
< break;
< case "openover":
< lookup["open-over"].obscurity = -50;
< break;
< default:
< UnPlug2.log("UnPlug2DownloadMethods preference of " + prefer + " is not supported");
< break;
< }
<
< // sort _button_names
< this._button_names.sort(function (a, b) {
< var aobs = lookup[a].obscurity;
< var bobs = lookup[b].obscurity;
< return aobs - bobs;
< });
< }),
<
< /* button_names:
< * returns the button names, in order of preference (ie, the most obscure last)
< */
< button_names : (function () {
< return this._button_names;
< }),
< get_extern_tool_names : (function () {
< var out = [];
< for (var i = 0; i < this._button_names.length; ++i) {
< var name = this._button_names[i];
< if (this._button_lookup[name].signal_get_argv) {
< out.push(name);
< }
< }
< return out;
< }),
< getinfo : (function (name) {
< return this._button_lookup[name];
< }),
< callback : (function (name, result) {
< var that = this;
< return (function (evt) {
< try {
< that.exec(name, result);
< } catch (e) {
< UnPlug2.log("Error in UnPlug2DownloadMethods for " + name + " " + result.toSource() + " with error " + e.toSource());
< }
< evt.stopPropagation();
< });
< }),
< exec : (function (name, result) {
< var data = this._button_lookup[name];
< if (!data) {
< throw "Unknown button name " + name;
< }
< if (!data.avail(result)) {
< throw "Cannot use DownloadMethod " + name + " with " + result.toSource();
< }
< if (data.signal_get_argv) {
< // check nsiProcess supports runwAsync -- see below
< // this will avoid disapointment of downloading rtmpdump before being
< // told there was no point
< var process = Components.classes["@mozilla.org/process/util;1"]
< .createInstance(Components.interfaces.nsIProcess);
< if (!process.runwAsync) {
< alert("Firefox 4 required");
< throw "nsIProcess.runwAsync is not implemented";
< }
< // work out where rtmpdump lives
< var exec_file = UnPlug2.get_pref("dmethod." + name);
< if (!this._nsifile_if_exec(exec_file)) {
< window.openDialog("chrome://unplug/content/config/extern.xul", "chrome,modal", "unplug_extern", name);
< return; // note: signal to downloader won't get sent
< }
< // open download window and get it to call exec_from_siganl
< UnPlug2ExternDownloader.signal({
< result: result,
< name : name });
< } else if (data.exec_fp) {
< // if a method implements exec_fp, it wishes to use the "normal" file-picker code
< // and we'll pass them the appropriate file object in the arguments
< var file = this._save_as_box(result.details.name, result.details.file_ext);
< if (!file) {
< return;
< }
< data.exec_fp(result, file);
< } else {
< data.exec(result);
< }
< }),
<
< exec_from_signal : (function (signal) {
< /*
< * This code is executed from display/extern/extern.xul
< * and is triggered by sending that window a postMessage.
< *
< * IMPORTANT
< * Currently this shows a save-as dialog, but future versions
< * may start a download without asking. In practice this means
< * data may be saved to an arbitary location on disk, so this
< * should only be called based on a response from priviliged
< * code.
< */
< var data = this._button_lookup[signal.name];
< if (!data) {
< throw "Unknown button name " + signal.name;
< }
< var file = this._save_as_box(signal.result.details.name, signal.result.details.file_ext);
< if (!file) {
< return null;
< }
<
< var exec_file = UnPlug2.get_pref("dmethod." + signal.name);
< exec_file = this._nsifile_if_exec(exec_file);
< if (!exec_file) {
< throw "UnPlug display - this is not an exec_file"
< }
< var argv = data.signal_get_argv(signal.result, file);
< var process = Components.classes["@mozilla.org/process/util;1"]
< .createInstance(Components.interfaces.nsIProcess);
< process.init(exec_file);
< // we use runwAsync and use utf-16 strings, otherwise you get junk for
< // filenames due to the unicode encoding conversions
< if (!process.runwAsync) {
< alert("Firefox 4 required");
< throw "nsIProcess.runwAsync is not implemented";
< }
< process.runwAsync(
< argv,
< argv.length,
< null, // we could use an nsIObserver here, but we'll just poll process.isRunning for now
< false );
< return {
< process : process,
< file : file.file }
< }),
<
< /**
< * Displays save-as box
< * return { file : nsIFile?, fileURL : nsIFileURL? }, or null for cancel.
< */
< _save_as_box : (function (name, ext) {
< // make string, strip whitespace
< name = (name || "no name").replace(RegExp("(^\\s|\\s$)", "g"), "");
< ext = (ext || "").replace(RegExp("(^\\s+|\\s+$)", "g"), "");
<
< // look for .ext in name
< if (!ext) {
< var ext_re = RegExp("\\.(\\w{1,5})$");
< var ext_match = ext_re.exec(name);
< if (ext_match) {
< ext = ext_match[1];
< name = name.replace(ext_re, "");
< } else {
< ext = "flv"; // fallback
< }
< }
<
< // replace bad characters with "_"
< name = name.replace(RegExp("[\\*\\\\/\\?\\<\\>~#\\|`\\$\\&;:%\"'\x00-\x1f]+", "g"), "_");
< ext = ext.replace(RegExp("[^\\w\\s]+", "g"), "_");
<
< var nsIFilePicker = Components.interfaces.nsIFilePicker;
< var filepicker = Components.classes["@mozilla.org/filepicker;1"]
< .createInstance(nsIFilePicker);
< filepicker.init(window, "Save as", nsIFilePicker.modeSave);
<
< // default directory
< var path = UnPlug2.get_pref("savepath");
< if (!path) {
< path = Components.classes["@mozilla.org/download-manager;1"]
< .getService(Components.interfaces.nsIDownloadManager)
< .defaultDownloadsDirectory.path;
< }
< if (path) {
< var f = Components.classes["@mozilla.org/file/local;1"]
< .createInstance(Components.interfaces.nsILocalFile);
< f.initWithPath(path);
< if (f.exists() && f.isDirectory()) {
< filepicker.displayDirectory = f;
< }
< }
<
< // default file name
< filepicker.defaultString = name + "." + ext;
< //filepicker.defaultExtention = ext;
<
< var ret = filepicker.show();
< if (ret != nsIFilePicker.returnOK && ret != nsIFilePicker.returnReplace)
< return null; // cancelled
< UnPlug2.set_pref("savepath", filepicker.file.parent.path);
< return { "file" : filepicker.file, "fileURL" : filepicker.fileURL };
< }),
<
< _nsifile_if_exec : (function (fname) {
< if (!fname) {
< return null;
< }
< var f = Components.classes["@mozilla.org/file/local;1"]
< .createInstance(Components.interfaces.nsILocalFile);
< f.initWithPath(fname);
< return (f.exists() && f.isExecutable()) ? f : null;
< })
< }
<
< var UnPlug2ExternDownloader = {
< window_name : "x-unplug-exten-dld",
< url : "chrome://unplug/content/display/extern/extern.xul",
< get_window : (function () {
< var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
< .getService(Components.interfaces.nsIWindowMediator);
< // var wl = wm.getEnumerator("dialog");
< var wl = wm.getEnumerator(null);
< while (wl.hasMoreElements()) {
< var win = wl.getNext().QueryInterface(Components.interfaces.nsIDOMWindow);
< if (win.location == this.url) {
< return win;
< }
< }
< return null;
< }),
< signal : (function (action) {
< var action = window.JSON.stringify(action);
< var extern_window = this.get_window();
< if (extern_window) {
< extern_window.postMessage(action, "*");
< } else {
< extern_window = window.openDialog(this.url, "", "chrome");
< var onload = (function (action) {
< return (function () {
< this.postMessage(action, "*");
< });
< })(action);
< extern_window.addEventListener("load", onload, false);
< }
< })
< }
<
<
< // ----- download method definitions follow -----
<
< UnPlug2DownloadMethods.add_button("saveas", {
< avail : (function (res) {
< return res.download.url && (
< res.download.url.indexOf("http://") == 0
< || res.download.url.indexOf("https://") == 0
< || res.download.url.indexOf("ftp://") == 0);
< }),
< exec_fp : (function (res, file) {
< var io_service = Components.classes["@mozilla.org/network/io-service;1"]
< .getService(Components.interfaces.nsIIOService)
< var nsiurl = io_service.newURI(res.download.url, null, null);
< var nsireferer = nsiurl;
< try {
< nsireferer = io_service.newURI(res.download.referer, null, null);
< } catch(e) {
< // pass
< }
<
< var persistArgs = {
< source : nsiurl,
< contentType : "application/octet-stream",
< target : file.fileURL,
< postData : null,
< bypassCache : false
< };
<
< // var persist = makeWebBrowserPersist();
< var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
< createInstance(Components.interfaces.nsIWebBrowserPersist);
<
< // Calculate persist flags.
< const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
< persist.persistFlags = (
< nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
< nsIWBP.PERSIST_FLAGS_FROM_CACHE |
< nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION );
<
< // Create download and initiate it (below)
< var tr = Components.classes["@mozilla.org/transfer;1"].createInstance(Components.interfaces.nsITransfer);
<
< tr.init(persistArgs.source, persistArgs.target, "", null, null, null, persist);
<
< persist.progressListener = tr;
< persist.saveURI(persistArgs.source, null, nsireferer, persistArgs.postData, null, persistArgs.target);
< }),
< obscurity : 0,
< css : "saveas",
< group : "main"
< });
<
< UnPlug2DownloadMethods.add_button("dta", {
< avail : (function (res) {
< if (!window.opener.DTA_AddingFunctions && !window.DTA) {
< return false;
< }
< if (!res.download.url) {
< return false;
< }
< if (res.download.url.indexOf("http://") != 0 && res.download.url.indexOf("https://") != 0) {
< return false;
< }
< return true;
< }),
< exec_fp : (function (res, fileobj) {
< var file = fileobj.file;
< if (file.leafName.indexOf("*") >= 0) {
< // we use the renaming mask, which treats *name*, etc as special.
< throw "Filename contains star";
< }
<
< // call String() explicitly as DTA alters string
< link = {
< "url" : res.download.url, // string
< "postData" : null,
< "referrer" : String(res.download.referer || ""), // an object with toURL
< "dirSave" : String(file.parent.path), // an object with addFinalSlash
< "fileName" : String(file.leafName), // string
< "description" : String(file.leafName) } // string
< UnPlug2.log("Hello DTA, I'm sending you: " + link.toSource());
< if (window.DTA) {
< // DTA 2.0
< DTA.sendLinksToManager(window, true, [link]);
< } else {
< // DTA 1.0
< window.opener.DTA_AddingFunctions.sendToDown(true, [link]);
< }
< }),
< obscurity : 25,
< css : "dta",
< group : "main"
< });
<
< UnPlug2DownloadMethods.add_button("flashgot", {
< avail : (function (res) {
< if (! Components.classes["@maone.net/flashgot-service;1"]) {
< // flashgot not installed
< return false;
< }
< // flashgot is installed
< return (res.download.url && (
< res.download.url.indexOf("http://") == 0
< || res.download.url.indexOf("https://") == 0))
< }),
< exec : (function (res) {
< var flashgot_service = Components.classes["@maone.net/flashgot-service;1"]
< .getService(Components.interfaces.nsISupports)
< .wrappedJSObject;
< var name = res.details.name + "." + res.details.file_ext;
< var links=[{
< href: res.download.url,
< description: name,
< fname : name,
< // XXX can we set the save-as thingy?
< noRedir: false }];
< links.referrer = res.download.referer || null;
< links.document = window.document; // origWindow XXX TODO should not be from chrome
< links.browserWindow = flashgot_service.getBrowserWindow(links.document);
< flashgot_service.download(links);
< flashgot_service.DMS[flashgot_service.defaultDM].download(links, flashgot_service.OP_ONE)
< }),
< obscurity : 20,
< css : "flashgot",
< group : "main"
< });
<
< UnPlug2DownloadMethods.add_button("rtmpdump", {
< avail : (function (res) {
< var url = res.download.rtmp || res.download.url;
< return url && (
< url.indexOf("rtmp://") == 0
< || url.indexOf("rtmpe://") == 0);
< }),
< signal_get_argv : (function (res, savefile) {
< var cmds = [
< "--verbose",
< "--rtmp", res.download.rtmp || res.download.url,
< "--pageUrl", res.download.referer,
< "--swfUrl", res.download.swfurl || res.download.referer, // this is invalid, but good enough most of the time.
< "--flv", savefile.file.path ];
< if (res.download.rtmp) {
< if (res.download.playpath) {
< cmds.push("--playpath");
< cmds.push(res.download.playpath);
< }
< if (res.download.app) {
< cmds.push("--app");
< cmds.push(res.download.app);
< }
< }
< return cmds;
< }),
< exec_file_list : [
< "/usr/bin/rtmpdump" ],
< weblinks : [
< { url : "http://rtmpdump.mplayerhq.hu/", label : "rtmpdump.mplayerhq.hu" }],
< obscurity : 50,
< css : "extern rtmpdump",
< group : "special"
< });
<
< UnPlug2DownloadMethods.add_button("open-tab", {
< avail : (function (res) {
< return (res.download.url ? true : false);
< }),
< exec : (function (res) {
< var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
< .getService(Components.interfaces.nsIWindowMediator);
< var gbrowser = wm.getMostRecentWindow("navigator:browser").gBrowser;
< var t = gbrowser.addTab(res.download.url);
< gbrowser.selectedTab = t;
< }),
< obscurity : 100,
< css : "open open-tab",
< group : "open"
< });
<
< UnPlug2DownloadMethods.add_button("open-new", {
< avail : (function (res) {
< return (res.download.url ? true : false);
< }),
< exec : (function (res) {
< window.open(res.download.url);
< }),
< obscurity : 100,
< css : "open open-new",
< group : "open"
< });
<
< UnPlug2DownloadMethods.add_button("open-over", {
< avail : (function (res) {
< return (res.download.url ? true : false);
< }),
< exec : (function (res) {
< UnPlug2SearchPage._win.location = res.download.url;
< }),
< obscurity : 110,
< css : "open open-over",
< group : "open"
< });
<
< UnPlug2DownloadMethods.add_button("copyurl", {
< avail : (function (res) {
< return (res.download.url ? true : false);
< }),
< exec : (function (res) {
< var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
< .getService(Components.interfaces.nsIClipboardHelper);
< clipboard.copyString(res.download.url);
< }),
< obscurity : 200,
< css : "copyurl",
< group : "copy"
< });
<
< UnPlug2DownloadMethods.add_button("vlc", {
< avail : (function (res) {
< var url = res.download.url;
< if (!url) {
< return false;
< }
< var proto = url.substring(0, url.indexOf(":"))
< return (["mms", "http", "https", "rtsp"].indexOf(proto) != -1);
< }),
< signal_get_argv : (function (res, savefile) {
< return [
< "--no-one-instance",
< "-Isignals", // no gui
< res.download.url,
< ":demux=dump",
< ":demuxdump-file=" + savefile.file.path,
< ":sout-all",
< "vlc://quit" ];
< }),
< exec_file_list : [
< "/usr/bin/vlc" ],
< weblinks : [
< { url : "http://videolan.org/vlc", label : "videolan.org" }],
< obscurity : 90,
< css : "extern vlc",
< group : "special"
< });
<
< UnPlug2DownloadMethods.finish();
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/display/extern/extern.js releases/unplus-2.043/source/chrome/content/display/extern/extern.js
1,183d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
< UnPlug2Extern = {
< watching : [],
<
< add_program_box : (function (download_method, filename) {
< var template = document.getElementById("program-template");
< var container = document.getElementById("program-container");
< var dupe = template.cloneNode(true);
< var labels = dupe.getElementsByTagName("label");
< dupe.setAttribute("collapsed", false);
< dupe.getElementsByTagName("description")[0].setAttribute("value", filename);
< labels[0].setAttribute("value", UnPlug2.str("dmethod." + download_method));
< container.appendChild(dupe);
< this.set_program_box_status(dupe, 0, "running");
< return dupe;
< }),
<
< set_program_box_status : (function (doc, file_size, process_status) {
< var labels = doc.getElementsByTagName("label");
< if (file_size < 2.5 * 1024 * 1024) {
< file_size = (file_size / 1024).toFixed(1) + " KiB";
< } else if (file_size < 2.5 * 1024 * 1024 * 1024) {
< file_size = (file_size / (1024 * 1024)).toFixed(1) + " MiB";
< } else {
< file_size = (file_size / (1024 * 1024 * 1024)).toFixed(1) + " GiB";
< }
< labels[1].setAttribute("value", file_size);
< labels[2].setAttribute("value", UnPlug2.str("proc.status." + process_status));
< doc.className = "process process-status-" + process_status;
< }),
<
< receive_signal_callback : (function () {
< var extern = this;
< return (function (event) {
< /*
< * IMPORTANT
< * Anyone can send signals to this window, so it is
< * vitally important to check the message comes from
< * privilidged code (chrome).
< */
< if (event.origin.indexOf("chrome:") != 0) {
< return;
< }
< var msg = window.JSON.parse(event.data);
< var rtn = UnPlug2DownloadMethods.exec_from_signal(msg);
< if (rtn) {
< rtn.node = extern.add_program_box(msg.name, rtn.file.leafName);
< extern.setup_kill_button(rtn);
< extern.watching.push(rtn);
< }
< });
< }),
<
< setup_kill_button : (function (rtn) {
<
< // TODO - we really want a smaller and nicer cancel button
< var that = this;
<
< rtn.node.getElementsByTagName("button")[0].addEventListener("command", (function () {
< // no point in killing if it's already dead
< if (!rtn.process.isRunning) {
< return;
< }
<
< // ask it we want to delete
< // Alt+F4 defaults to POS_1
< var prompt_service = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
< .getService(Components.interfaces.nsIPromptService);
< var checkbox = { "value" : true };
< var button = prompt_service.confirmEx(window, UnPlug2.str("extern.cancel.title"),
< UnPlug2.str("extern.cancel.onefile").replace("%s", rtn.file.leafName),
< prompt_service.BUTTON_POS_0 * prompt_service.BUTTON_TITLE_IS_STRING +
< prompt_service.BUTTON_POS_1 * prompt_service.BUTTON_TITLE_IS_STRING,
< UnPlug2.str("extern.cancel.stop"), UnPlug2.str("extern.cancel.dontstop"), null,
< UnPlug2.str("extern.cancel.deletefile"),
< checkbox);
< if (button === 0) {
< that.do_kill(rtn, checkbox.value);
< }
< }), false);
< }),
<
< do_kill : (function (rtn, rm_file) {
< if (!rtn.process.isRunning) {
< return; // don't delete if it's just finished.
< }
< rtn.was_killed = true;
< rtn.process.kill();
< if (rm_file) {
< try {
< rtn.file.remove(false);
< } catch (e) {} // file does not exist
< }
< }),
<
< remove_kill_button : (function (doc) {
< var n = doc.getElementsByTagName("button")[0];
< n.style.visibility = "hidden"; // don't delete as has race with kill button setup
< }),
<
< poll : (function () {
< var extern = this;
< // TODO this makes this not threadsafe, we may mess up if we
< // call watching.push() from a different thread.
< extern.watching = extern.watching.filter(function (item, idx, arr) {
< var file_size = 0;
< if (item.file.exists()) {
< file_size = item.file.fileSize;
< }
< if (item.process.isRunning) {
< extern.set_program_box_status(item.node, file_size, "running");
< } else {
< if (item.was_killed || item.process.exitValue) {
< extern.set_program_box_status(item.node, file_size, "error");
< } else if (file_size == 0) {
< // EXIT_SUCCESS + no file is error from vlc
< extern.set_program_box_status(item.node, file_size, "error");
< } else {
< extern.set_program_box_status(item.node, file_size, "done");
< }
< // remove from array
< extern.remove_kill_button(item.node);
< return false;
< }
< return true;
< });
< }),
<
< want_close : (function () {
< if (this.watching.length == 0) {
< return true; // no reason not to exit
< }
<
< var prompt_service = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
< .getService(Components.interfaces.nsIPromptService);
< var checkbox = { "value" : true };
< var button = prompt_service.confirmEx(window, UnPlug2.str("extern.cancel.title"),
< UnPlug2.str("extern.cancel.manyfile").replace("%s", this.watching.length),
< prompt_service.BUTTON_POS_0 * prompt_service.BUTTON_TITLE_IS_STRING +
< prompt_service.BUTTON_POS_1 * prompt_service.BUTTON_TITLE_IS_STRING,
< UnPlug2.str("extern.cancel.stop"), UnPlug2.str("extern.cancel.dontstop"), null,
< UnPlug2.str("extern.cancel.deletefile"),
< checkbox);
< if (button === 0) {
< for (var i = 0; i < this.watching.length; ++i) {
< this.do_kill(this.watching[i], checkbox.value);
< }
< return true; // ok to exit
< } else {
< return false; // clicked cancel
< }
< })
< }
<
< window.addEventListener("message", UnPlug2Extern.receive_signal_callback(), false);
< window.setInterval((function () { UnPlug2Extern.poll() }), 3000);
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/display/extern/extern.xul releases/unplus-2.043/source/chrome/content/display/extern/extern.xul
1,71d0
<
<
<
<
< %dtdcommon;
<
< %dtdextern;
< ]>
<
<
<
<
<
<
<
<
<
< &extern.description;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/display/pop/pop.js releases/unplus-2.043/source/chrome/content/display/pop/pop.js
1,405d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
< UnPlug2SearchPage = {
< UnPlug2SearchPage : function (args) {
< // parent window (the one we want to search)
< this._win = args.tgt_window;
<
< // preferered downloaders from config
< switch (UnPlug2.get_pref("downloader")) {
< case "saveas":
< this.preferred_downloaders = ["saveas"];
< break;
< case "openover":
< this.preferred_downloaders = ["openover"];
< break;
< default:
< this.preferred_downloaders = ["dta", "flashgot", "saveas"];
< break;
< }
< // fallbacks (if the default fails)
< this.preferred_downloaders.push("special");
< this.preferred_downloaders.push("saveas");
< // this.preferred_downloaders.push("openover");
< this.preferred_downloaders.push("fallback");
<
< // set this to true to stop everything
< this._stopped = false;
<
< // results array to be populated when a callback occurs
< this.download_to_uid = {}; // { result.download.toSource() : 1 }
< this.results = []; // { 1 : result } ... or rather [ ..., result, ... ]
< this.media_id_lookup = {}; // { "youtube-324121" : [1, ...] }
< this.playlist_id_lookup = {}; // { "youtube-uploader-1213" : [1, ...] }
< },
<
< /**
< * search the parent window for media, returning search result objects
< */
< do_search : function () {
< document.getElementById("dynamic_download").value = UnPlug2.str("search_busy");
< document.getElementById("dynamic_results").value = UnPlug2.str("search_no_results_yet");
<
< try {
< UnPlug2Search._reset(); // this may not be needed because we always start from a fresh window
< UnPlug2Search.search(this._win, this._search_callback)
< } catch (e) {
< UnPlug2.log(e.toSource());
< }
< },
<
< /**
< * Callback for UnPlug2Rules.search
< * Called for each result found. This may be asynchromous (ie, after additional files are downloaded).
< */
< _search_callback : (function (obj) {
< UnPlug2.log("callback: " + obj.toSource());
< switch (obj.type) {
< case "result":
< return UnPlug2SearchPage._search_callback_result(obj);
< case "progress":
< return UnPlug2SearchPage._search_callback_progress(obj);
< default:
< UnPlug2.log("Callback function got a " + result.type + " (not a result)!");
< return;
< }
< }),
<
< _search_callback_progress : (function (info) {
< try {
< var searchbar = document.getElementById("search_progress");
< var status_label = document.getElementById("dynamic_download");
< if (info.finished) {
< searchbar.mode = "determined";
< searchbar.value = "100";
< status_label.value = UnPlug2.str("search_done");
<
< var num_results = UnPlug2SearchPage.results.length;
< document.getElementById("stop_button").disabled = true;
< if (num_results == 0) {
< document.getElementById("dynamic_results").value = UnPlug2.str("search_no_results");
< document.getElementById("dynamic_results").className = "failed";
< } else if (num_results == 1) {
< document.getElementById("dynamic_results").value = UnPlug2.str("search_1_result");
< } else {
< document.getElementById("dynamic_results").value = UnPlug2.str("search_n_results").replace("#", num_results);
< }
< } else {
< if (info.downloads == 1){
< status_label.value.value = UnPlug2.str("search_1_active_download");
< } else {
< // note: info.downloads can be zero if we've downloaded the last page,
< // but there are items which have been marked "defer" scheduled to be run.
< status_label.value.value = UnPlug2.str("search_n_active_downloads").replace("#", info.downloads);
< }
< if (info.percent == 0 || info.percent == 100) {
< searchbar.mode = "undetermined";
< } else {
< searchbar.mode = "determined";
< searchbar.value = info.percent;
< }
< }
< } catch (e) {
< UnPlug2.log(e.toSource());
< var e = document.getElementById("dynamic_results");
< e.value = "Have errors";
< }
< }),
<
< _search_callback_result : (function (result) {
< /*
< * detect if it's an exact duplicate
< * In JavaScript, asking if {"X" : "Y"} == {"X" : "Y"} -> false
< * So convert to source strings and compare to give the correct answer!
< */
< var download_tosource = result.download.toSource();
< var uid = UnPlug2SearchPage.download_to_uid[download_tosource]; // TODO -- also need to check this key is not a "native object" like "length", "toString", etc!
<
< if (uid === undefined) {
< try {
< // we need to add a new object
< var uid = UnPlug2SearchPage.results.length;
< UnPlug2SearchPage.download_to_uid[download_tosource] = uid;
< UnPlug2SearchPage.results[uid] = result;
< result.uid = uid;
<
< var reselem = UnPlug2SearchPage.result_e_create();
< reselem.setAttribute("id", "result_" + uid);
< reselem.setAttribute("tooltiptext", "uid=" + uid + "\n\ndownload=" + result.download.toSource() + "\n\noriginal = " + result.details.toSource());
<
< // sets download callbacks, etc
< UnPlug2SearchPage.result_e_set_download(reselem, result);
<
< // this sets labels, icons, descripions, css, etc
< // but wont ever move the element
< UnPlug2SearchPage.result_e_set_description(reselem, result);
<
< // container for the group, eg the mediaid and/or playlistid
< UnPlug2SearchPage.set_container(uid, reselem, result.details);
<
< } catch(e) {
< UnPlug2.log("ERROR displaying result " + e.toSource());
< }
< } else {
< var reselem = document.getElementById("result_" + uid);
< var old_result = UnPlug2SearchPage.results[uid];
< if (old_result.details.certainty < result.details.certainty) {
< // Update
< UnPlug2SearchPage.results[uid].details = result.details;
<
< // we need to update this.results and the widget displayed on the page with our better data
< reselem.setAttribute("tooltiptext", reselem.getAttribute("tooltiptext") + "\n\nupdated = " + result.details.toSource());
< UnPlug2SearchPage.result_e_set_description(reselem, result);
<
< // it can attach/detach from the parent element as needed
< UnPlug2SearchPage.update_container(uid, reselem, old_result.details, result.description);
< } else {
< reselem.setAttribute("tooltiptext", reselem.getAttribute("tooltiptext") + "\n\nignored = " + result.details.toSource());
< }
< }
< }),
<
< result_e_create : function () {
< var orig = document.getElementById("unplug_result_template");
< var dupe = orig.cloneNode(true);
< dupe.collapsed = false;
< return dupe;
< },
<
< result_e_set_download : function (reselem, result) {
< var popup = reselem.getElementsByTagName("menupopup")[0];
< var button_names = UnPlug2DownloadMethods.button_names();
< var prev_elem_group = null;
< var avail_elements = [];
<
< // we want to replace the old callbacks with new callbacks
< while (popup.firstChild) {
< popup.removeChild(popup.firstChild);
< }
< for (var i = 0; i < button_names.length; ++i) {
< var name = button_names[i];
< var info = UnPlug2DownloadMethods.getinfo(name);
< if (info.avail(result)) {
< if (prev_elem_group != info.group && avail_elements.length != 0) {
< var spacer = document.createElement("menuseparator");
< popup.appendChild(spacer);
< }
< prev_elem_group = info.group;
< avail_elements.push(name);
< var elem = document.createElement("menuitem");
< prev_elem_is_spacer = false;
< elem.setAttribute("accesskey", UnPlug2.str("dmethod." + name + ".a"))
< elem.setAttribute("label", UnPlug2.str("dmethod." + name));
< elem.setAttribute("tooltiptext", UnPlug2.str("dmethod." + name + ".tip"));
< elem.className = "menuitem-iconic " + info.css;
< elem.addEventListener("command", UnPlug2DownloadMethods.callback(name, result), false);
< popup.appendChild(elem);
< }
< }
<
< var copy_button = reselem.getElementsByTagName("toolbarbutton")[0];
< copy_button.setAttribute("label", UnPlug2.str("dmethod.copyurl"));
< copy_button.setAttribute("accesskey", UnPlug2.str("dmethod.copyurl.a"));
< copy_button.setAttribute("tooltiptext", UnPlug2.str("dmethod.copyurl.tip"));
<
< var copy_info = UnPlug2DownloadMethods.getinfo("copyurl");
< if (copy_info && copy_info.avail(result)) {
< copy_button.addEventListener("command", UnPlug2DownloadMethods.callback("copyurl", result), false);
< copy_button.setAttribute("disabled", false);
< } else {
< copy_button.setAttribute("disabled", true);
< }
<
< var main_button = reselem.getElementsByTagName("toolbarbutton")[1];
< if (avail_elements.length == 0) {
< main_button.setAttribute("disabled", true);
< main_button.className = "menuitem-icon unavailable"
< main_button.setAttribute("tooltiptext", UnPlug2.str("dmethod.unavailable.tip"));
< } else {
< var name = avail_elements[0];
< var info = UnPlug2DownloadMethods.getinfo(name);
< main_button.className = "menuitem-iconic " + info.css;
< main_button.addEventListener("command", UnPlug2DownloadMethods.callback(name, result), false);
< main_button.setAttribute("tooltiptext", UnPlug2.str("dmethod." + name + ".tip"));
< }
<
< // setup drag and drop
< if (result.download.url) { // make draggable if simple url only
< var image = reselem.getElementsByTagName("image")[0]; // ur-thumbnail
< reselem.setAttribute("draggable", true);
< reselem.addEventListener("dragstart", (function (url, image) {
< return (function (event) {
< event.dataTransfer.setData('text/uri-list', url);
< event.dataTransfer.setData('text/plain', url);
< event.dataTransfer.effectAllowed = "link";
< event.dataTransfer.setDragImage(image, 25, 25);
< });
< })(result.download.url, image), true);
< }
< },
<
< result_e_set_description : function (reselem, result) {
< // variables for use in the callbaks (closures)
< var uid = result.uid;
< var details = result.details;
< var that = UnPlug2SearchPage;
<
< var name_label = reselem.getElementsByTagName("label")[0];
< name_label.setAttribute("value", details.name);
< var desc_label = reselem.getElementsByTagName("label")[1];
< desc_label.setAttribute("value", details.description);
< var protocol_label = reselem.getElementsByTagName("label")[2];
< protocol_label.setAttribute("value", details.protocol);
< var host_label = reselem.getElementsByTagName("label")[3];
< host_label.setAttribute("value", details.host);
< var thumbnail = reselem.getElementsByTagName("image")[0];
< thumbnail.setAttribute("src", details.thumbnail);
<
< reselem.className = [
< "file-ext-" + (details.file_ext || "unknown"),
< "certainty-" + (details.certainty < 0 ? "low" : "high"),
< "unplug-result" ].join(" ")
< },
<
< set_container : function (uid, reselem, details) {
< if (!details.mediaid) {
< document.getElementById("results").appendChild(reselem);
< return;
< }
<
< var minfo = this.media_id_lookup[details.mediaid];
< // escape used here because could have all sorts of special characters in mediaid
< var eid = "mediaid_" + escape(details.mediaid || "none");
< var container = document.getElementById(eid);
< if (! container) {
< container = document.createElement("vbox");
< container.className = "container";
< container.id = eid;
< document.getElementById("results").appendChild(container);
< }
< if (minfo === undefined) {
< this.media_id_lookup[details.mediaid] = {
< certainty : details.certainty,
< quality : details.quality,
< best : uid };
< reselem.className += " mediaid-best";
< container.appendChild(reselem);
< } else {
< if (minfo.certainty < details.certainty || (minfo.certainty == details.certainty && minfo.quality < details.quality)) {
< var old_best = document.getElementById("result_" + minfo["best"]);
< old_best.className = old_best.className.replace("mediaid-best", "mediaid-collapse");
< // this media info is the main one
< this.media_id_lookup[details.mediaid] = {
< certainty : details.certainty,
< quality : details.quality,
< best : uid };
< reselem.className += " mediaid-best";
< container.insertBefore(reselem, container.firstChild);
< } else {
< reselem.className += " mediaid-collapse";
< container.appendChild(reselem);
< }
< }
< container.appendChild(reselem);
< },
<
< update_container : function (uid, reselem, old_details, new_details) {
< if ((old_details.mediaid || "none") != (new_descripton.mediaid || "none")) {
< // remove from current container
< reselem.parentNode.removeChild(reselem);
< // and add to the new one
< UnPlug2SearchPage.set_container(uid, reselem, new_details);
< }
< },
<
< toString : function () {
< return '';
< },
<
< send_nothing_found_msg : function () {
< if (!confirm(UnPlug2.str("nothing_found_send_data")))
< return;
< try {
< UnPlug2SearchPage.send_nothing_found_msg_noask();
< } catch (e) {
< UnPlug2.log("Error sending nothing found msg " + e.toSource());
< }
< },
<
< send_nothing_found_msg_noask : function () {
< var el = document.getElementById("notfound_button");
< if (!el) {
< UnPlug2.log("No element in xul called notfound");
< return;
< }
< el.disabled = "true";
< el.label = UnPlug2.str("nothing_found_sending");
<
< var dl = new UnPlug2Download(
< null, // ref
< "http://unplug.dbatley.com/popularity_contest/submit.cgi",
< "problem=yes&useragent=" + escape(window.navigator.userAgent) + "&url=" + escape(UnPlug2SearchPage._win.location.href) + "&version=" + UnPlug2.version + "&revision=" + UnPlug2.revision + "&codename=" + UnPlug2.codename,
< null, null, // callbacks
< 10000);
< dl.start()
< },
<
< done_nothing_found_msg : function () {
< var el = document.getElementById("notfound_button");
< el.label = UnPlug2.str("nothing_found_done");
< },
<
< failed_nothing_found_msg : function () {
< var el = document.getElementById("notfound_button");
< el.label = UnPlug2.str("nothing_found_failed");
< el.disabled = "false";
< },
<
< /*
< * Stop downloading/searching pages!
< */
< abort : function () {
< UnPlug2Search._stopped = true;
< UnPlug2Search.abort();
< },
<
< /**
< * When someone clicks the configure button on unplug_result
< */
< configure : function (tabname) {
< window.openDialog("chrome://unplug/content/config/config.xul", "", "", tabname);
< },
<
< endofobject : 1 }
<
< //init
< UnPlug2SearchPage.UnPlug2SearchPage(window.arguments[0])
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/display/pop/pop.xul releases/unplus-2.043/source/chrome/content/display/pop/pop.xul
1,123d0
<
<
<
<
< %dtdcommon;
<
< %dtdlocal;
< ]>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/overlay/all.js releases/unplus-2.043/source/chrome/content/overlay/all.js
1,116d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
<
< /**
< * Things the overlay needs, such as opening the popup window.
< */
< UnPlug2Overlay = {
< UnPlug2Overlay : function () {
< // TODO - don't use a flag, just use:
< // window.removeEventListener("load", Flashblock.onInstall, true);
< this._have_loaded_browser = false;
<
< // popup window (if not closed) from last button click
< this._popup_window_ref = null;
< },
<
< /**
< * Run a search (by opening a popup window and giving it the page to work with)
< */
< run : function () {
< try {
< var data = {
< // window of document to examine
< "tgt_window" : this.get_current_window() }
< try {
< UnPlug2Overlay._popup_win_ref.close();
< } catch(e) {
< // pass
< }
< UnPlug2Overlay._popup_win_ref = window.openDialog("chrome://unplug/content/display/pop/pop.xul", "unplug_window", "chrome,centerscreen", data );
< UnPlug2Overlay._popup_win_ref.focus();
< } catch (e) {
< UnPlug2.log(e.toSource());
< }
< },
<
< /**
< * Function which is called once, when chrome://browser has finished loading.
< * This removes the items from menus which we don't care about.
< */
< browser_loaded : function () {
< var menus = [ "toolsmenu", "contextmenu", "addonsbar" ];
< for (var i = 0 ; i < menus.length; i++) {
< var name = menus[i];
< try {
< if ( ! UnPlug2.get_pref("add_to_" + name, true) ) {
< var el = window.document.getElementById("unplug2_" + name)
< el.collapsed = true;
< }
< } catch(e) {
< UnPlug2.log("Error removing " + name + " because " + e.toSource());
< }
< }
<
< // check if we've set up everthing we need to (eg: installed toolbar button, etc)
< if (UnPlug2.get_pref("setup_number", 0) < UnPlug2.setup_number) {
< window.setTimeout((function () {
< window.openDialog("chrome://unplug/content/config/config.xul", "", "", "setup");
< }), 1000);
< }
< },
<
< /**
< * Function which is called each time a page is loaded
< */
< page_loaded : function () {
< if ( !this._have_loaded_browser ) {
< this.browser_loaded();
< this._have_loaded_browser = true;
< }
< },
<
< /**
< * Returns the window in the curently open tab
< */
< get_current_window : function () {
< var br = getBrowser();
< var br_tab = br.getBrowserAtIndex(br.mTabContainer.selectedIndex);
< return br_tab.contentWindow;
< },
<
< toString : function () {
< return "";
< },
<
< version : 2.0 };
<
< // init
< UnPlug2Overlay.UnPlug2Overlay();
<
< window.addEventListener("load", function () { UnPlug2Overlay.page_loaded(); }, false);
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/overlay/firefox.js releases/unplus-2.043/source/chrome/content/overlay/firefox.js
1,28d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/overlay/firefox.xul releases/unplus-2.043/source/chrome/content/overlay/firefox.xul
1,58d0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/overlay/seamonkey.js releases/unplus-2.043/source/chrome/content/overlay/seamonkey.js
1,28d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/overlay/seamonkey.xul releases/unplus-2.043/source/chrome/content/overlay/seamonkey.xul
1,46d0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/rules.xml releases/unplus-2.043/source/chrome/content/rules.xml
1,1099d0
<
<
<
<
<
< 77.247.178.106
< 247realmedia.com
< addtoany.com
< addthis.com
< adjug.com
< admeld.com
< adreactor.com
< adtechus.com
< adultfriendfinder.com
< adxpansion.com
< api.connect.facebook.com
< alleliteads.com
< contentabc.com
< cpro.baidu.com
< doubleclick.net
< ebay.com
< facebook.com
< fbcdn.net
< googlesyndication.com
< invitemedia.com
< mediagra.com
< mediaplex.com
< mookie1.com
< quantserve.com
< reliablebanners.com
< whaleads.com
< xtendmedia.com
< yieldmanager.com
< youtube.com
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< /video/(\d+)/
<
< url=(.*?)&
<
<
<
<
<
<
<
< id=(\d+)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< iid\s*=\s*(\d+)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< iid\s*:\s*"(\d+)"
< title\s*:\s*"(.*?)"
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< clip_id: '(\d+)',
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< /video/video\-(\d+)\.html
<
<
<
<
<
<
<
<
<
<
<
<
< <div\s+id=["']current\-title["']\s*>([\s\S]*?)</div\s*>
<
< href=["'](http://[^"']+)["']
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< intl\.esperanto\.mtvi\.com
< var uri\s*=\s*"(.*?)"
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< magnatune\.com.*[&\?]playlist_url=([^&]+)
<
<
<
< <location>(.*?)</location>
< <image>(.*?)</image>
< <annotation>(.*?)</annotation>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< addVariable\("content_video",\s*"([^"]+)"\)
< "unit_long(\d+)"
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< (addParam|addVariable)\s*\(\s*["'](image|thumbnail|preview)["']\s*,\s*["'](.*?)["']\s*\)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< so\.addVariable\("file",\s*"(http://[^"]+)"\)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< /playlist/
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/search/rules.js releases/unplus-2.043/source/chrome/content/search/rules.js
1,669d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
<
< UnPlug2Rules = {
< /*
< * Executes an if_* statement.
< * statement_name should not begin with "if_"
< * If there isn't a suitable if_* statement, one will be made by returning the result from appropriate each_* functions
< */
< exec_if : function (statement_name, node, variables, url, text, doc) {
< var rule = UnPlug2Rules.get_rule("if_" + statement_name);
<
< // if no , try and return the first part of the statement.
< if (!rule) {
< // response list is already prefixed variables with ref
< var response_list = UnPlug2Rules.exec_each(statement_name, node, variables, url, text, doc);
< if (response_list.length < 1)
< throw statement_name + " returned empty list"
< return response_list[0];
< }
<
< // exec the
< var response = UnPlug2Rules.exec_statement(rule, node, variables, url, text, doc);
<
< // valid responses: true, false, object_of_new_variables_without_prefixes
< if (response === false) {
< // throw statement_name + " returned false";
< return false;
< }
< if (response === true) {
< return {};
< }
< if (rule.apply_ref) {
< var ref = node.getAttribute("ref");
< return UnPlug2Rules._prefix_variables(ref, response);
< }
< UnPlug2.log("if_" + statement_name + " did not return true or false, it returned " + response.toSource());
< return false;
< },
<
< /*
< * Executes an ifnot_* statement.
< * statement_name should not begin with "ifnot_"
< * An ifnot_* statement is executes.
< * If there's no if_* statement, the if_* (or each_*) statement is executed, and the opposite is returned. If throws an exception, treats this as being true.
< */
< exec_ifnot : function (statement_name, node, variables, url, text, doc) {
< var rule = UnPlug2Rules.get_rule("ifnot_" + statement_name);
< if (rule) {
< return (UnPlug2Rules.exec_statement(rule, node, variables, url, text, doc) !== false);
< }
<
< try {
< return (!UnPlug2Rules.exec_if(statement_name, node, variables, url, text, doc));
< } catch (e) {
< return true;
< }
< },
<
< /*
< * Executes an optional_* statement.
< * statement_name should not begin with "optional_"
< * This is actually just a wrapper for if_* statements.
< */
< exec_optional : function (statement_name, node, variables, url, text, doc) {
< try {
< return UnPlug2Rules.exec_if(statement_name, node, variables, url, text, doc);
< } catch (e) {
< // it's optional, we don't care about failure.
< }
< },
<
< /*
< * Executes an each_* statement.
< * statement_name should not begin with "each_"
< */
< exec_each : function (statement_name, node, variables, url, text, doc) {
< var rule = UnPlug2Rules.get_rule("each_" + statement_name);
< var response_list = UnPlug2Rules.exec_statement(rule, node, variables, url, text, doc);
< var ref = node.getAttribute("ref");
< for (var i=0; i < response_list.length; i++) {
< if (!rule.apply_ref) {
< // without apply_ref set this responds by exporting variables without the prefix!
< // TODO - is this right behaviour?
< // pass -- just leave as is
< } else {
< response_list[i] = UnPlug2Rules._prefix_variables(ref, response_list[i]);
< }
< }
< return response_list;
< },
<
< /*
< * Return an object describing the rule
< */
< get_rule : function (rulename) {
< return UnPlug2Rules[rulename];
< },
<
< /*
< * Private.
< * puts "ref" in front of results
< */
< _prefix_variables : function (ref, response) {
< if (!ref)
< return {};
< var response_with_ref = {};
< for (k in response) {
< response_with_ref[ref + "." + k] = response[k];
< }
< return response_with_ref;
< },
<
< /**
< * Execute a statement.
< *
< * IMPORTANT: You should not normally call this function - instead you should call the exec_if(), exec_optional() or exec_each() functions as appropriate.
< *
< * This will return an object containing new variables which are not prefixed by $ref, or throw on failure.
< * Rule is one of the rules, which you can get with get_rule().
< * node is the dom element of the statement from rules.xml (so we can get attributes)
< * variables is the variables available to this scope
< */
< exec_statement : function (rule, node, variables, url, text, doc) {
< if (!rule)
< throw "Rule " + rule + " is not a rule which has been implemented in " + UnPlug2.version + " " + UnPlug2.revision;
< if (node.hasAttribute("debug")) {
< alert("Rule: " + rule + " Node: " + node + "\nVar: " + variables.toSource() + "\nUrl: " + url + "\nDoc: " + doc + "\n\n" + text);
< }
<
< // use rule.required and rule.optional to make a data object to feed to rule.execute
< var data = {}
< if (rule.required) {
< for (var i=0; i < rule.required.length; i++) {
< var attrname = rule.required[i];
< var value = null;
< if (attrname == "innerHTML") {
< value = UnPlug2.trim(node.textContent);
< } else {
< value = node.getAttribute(attrname);
< }
< if (!value)
< throw "Attribute " + attrname + " required";
< data[attrname] = variables.subst(value);
< }
< }
< if (rule.optional) {
< for (var i=0; i < rule.optional.length; i++) {
< var attrname = rule.optional[i];
< var value = null;
< if (attrname == "innerHTML") {
< value = UnPlug2.trim(node.textContent);
< } else {
< value = node.getAttribute(attrname);
< }
< try {
< data[attrname] = variables.subst(value ? value : "");
< } catch (e) {
< // problems substing variables is fine as it's optional
< // eg - errors substing thumbnail won't take down rule.
< data[attrname] = "";
<
< // although we can force it to be required sometimes, like
< if (rule.enforce && rule.enforce.indexOf(attrname) >= 0) {
< throw "If set, attribute " + attrname + " must be valid.";
< }
< }
< }
< }
< // exec function - may throw, return true or false, or return an object
< return rule.execute(data, url, text, doc);
< },
<
< /**
< * Reurns true if name is not an empty string
< */
< if_isset : {
< order : 0,
< optional : ["name"],
< execute : function (data, url, text, doc) {
< if (data.name)
< return true;
< return false;
< }
< },
<
< /*
< * Returns true if min <= unplug_version < max
< * Also returns true if unplug_version is null.
< */
< if_version : {
< order : 10,
< optional : ["min", "max"],
< execute : function (data, url, text, doc) {
< if (data.min && UnPlug2.version < parseFloat(data.min))
< return false;
< if (data.max && UnPlug2.version >= parseFloat(data.max))
< return false;
< return true;
< }
< },
<
< /*
< * Returns true if min <= unplug_revision < max
< */
< if_revision : {
< // order decides which rule is done first. if_ is done 0..100; download/media/etc 500...600
< order : 10,
< optional : ["min", "max"],
< execute : function (data, url, text, doc) {
< if (UnPlug2.revision == null)
< return true;
< if (data.min && UnPlug2.revision < parseFloat(data.min))
< return false;
< if (data.max && UnPlug2.revision >= parseFloat(data.max))
< return false;
< return true;
< }
< },
<
< /*
< * Returns if config variable "name" is set to "value"
< */
< if_config : {
< order : 10,
< optional : ["name", "value"],
< execute : function (data, url, text, doc) {
< var prefvalue = String(UnPlug2.get_pref(data.name, ""))
< if (prefvalue == data.value)
< return true;
< return false;
< }
< },
<
< /*
< * Private.
< * Takes the response to a RegExp.exec (or String.match) and creates an object containing {"1" : "subexpression 1 result", "2" : ... };
< */
< _re_resp : function (re_resp) {
< if (!re_resp)
< return false; // no matches
< var result = {};
< for (var i=1; i < re_resp.length; i++)
< if (re_resp[i])
< result[i] = re_resp[i];
< return result;
< },
<
< /*
< * Matches a regular expression contained in innerHTML
< */
< if_re : {
< order : 90,
< optional : ["string", "flags", "tagname", "innerHTML", "re"],
< enforce : ["string"],
< apply_ref : true,
< execute : function (data, url, text, doc) {
< if (!data.innerHTML && !data.re) {
< throw "Needs innerHTML or re in if_re";
< }
<
< var re = RegExp(data.re || data.innerHTML, data.flags);
<
< if (data.tagname && !doc)
< UnPlug2.log("No document for if_re with elemname - searching page");
<
< if (data.tagname && doc) {
< for each (elem in doc.getElementsByTagName(data.tagname)) {
< var r = UnPlug2Rules._re_resp(re.exec(elem.textContent));
< if (r) {
< return r;
< }
< }
< return false;
< } else {
< return UnPlug2Rules._re_resp(re.exec(data.string || text))
< }
< }
< },
<
< each_re : {
< order : 90,
< required : ["re"],
< optional : ["string", "flags", "tagname"],
< enforce : ["string"],
< apply_ref : true,
< execute : function (data, url, text, doc) {
< var re = RegExp(data.re, data.flags + "g");
< var response = [];
< var texts = [];
< if (data.tagname && doc) {
< var elemlist = doc.getElementsByTagName(data.tagname);
< for each (elem in elemlist) {
< texts[texts.length] = elem.textContent;
< }
< } else {
< texts = [ data.string || text ];
< }
< for (var i = 0; i < texts.length; i++) {
< var rr;
< var k = 0;
< while (rr = re.exec(texts[i])) {
< response[response.length] = UnPlug2Rules._re_resp(rr);
< if (++k > 100) {
< UnPlug2.log("Baling out of each_re in rules.js because hit limit of " + k + ". Error is with " + data.toSource() + " on text " + texts[i].substring(100))
< break;
< }
< }
< }
< return response;
< }
< },
<
< /*
< * Returns false
< */
< if_false : {
< order : 0,
< apply_ref : false,
< execute : function (data, url, text, doc) {
< return false;
< }
< },
< if_true : {
< order : 0,
< apply_ref : false,
< execute : function (data, url, text, doc) {
< return true;
< }
< },
<
< /*
< * Checks for equality
< */
< if_equal : {
< order : 1,
< required : ["a", "b"],
< apply_ref : false,
< execute : function (data, url, text, doc) {
< return ( data.a == data.b ) ? true : false;
< }
< },
<
< /*
< * Is a switch statement
< */
< if_switch : {
< order : 10,
< required : ["input"],
< optional : ["k1", "v1", "k2", "v2", "k3", "v3", "k4", "v4",
< "k5", "v5", "k6", "v6", "k7", "v7", "k8", "v8", "k9", "v9",
< "k10", "v10", "k11", "v11", "k12", "v12", "k13", "v13", "k14", "v14",
< "k15", "v15", "k16", "v16", "k17", "v17", "k18", "v18", "k19", "v19",
< "k20", "v20"],
< apply_ref : true,
< execute : function (data, url, text, doc) {
< if (!data.input) { return false; }
< switch (data.input) {
< case data.k1: return {1: data.v1};
< case data.k2: return {1: data.v2};
< case data.k3: return {1: data.v3};
< case data.k4: return {1: data.v4};
< case data.k5: return {1: data.v5};
< case data.k6: return {1: data.v6};
< case data.k7: return {1: data.v7};
< case data.k8: return {1: data.v8};
< case data.k9: return {1: data.v9};
< case data.k10: return {1: data.v10};
< case data.k11: return {1: data.v11};
< case data.k12: return {1: data.v12};
< case data.k13: return {1: data.v13};
< case data.k14: return {1: data.v14};
< case data.k15: return {1: data.v15};
< case data.k16: return {1: data.v16};
< case data.k17: return {1: data.v17};
< case data.k18: return {1: data.v18};
< case data.k19: return {1: data.v19};
< case data.k20: return {1: data.v20};
< default: return false;
< }
< }
< },
<
< /*
< * Checks the url.
< */
< if_url : {
< order : 20,
< optional : [
< "inhost", // substring is in host
< "inurl", // substring is in spec
< "inpath", // substring is in path
< "path", // matches start of path
< "port", // matches port exactly
< "host"], // matches end of host in whole words
< apply_ref : true, // populate $ref = url.spec, $ref.host = url.host, etc....
< execute : function (data, url, text, doc) {
< if (data.inhost) {
< if (url.host.indexOf(data.inhost) < 0)
< return false;
< }
< if (data.inurl) {
< if (url.spec.indexOf(data.inurl) < 0)
< return false;
< }
< if (data.inpath) {
< if (url.path.indexOf(data.inpath) < 0)
< return false;
< }
< if (data.port) {
< if (url.port != data.port)
< return false;
< }
< if (data.protocol) {
< if (url.scheme != data.protocol)
< return false;
< }
< if (data.path) {
< if (url.path.indexOf(data.path) != 0)
< return false;
< }
< if (data.host) {
< /*
< * TODO - this isn't implemented properly
< * examle of host
< * eg: foo.com
< * matches foo.com
< * matches www.yay.foo.com
< * doesn't match foo.com.nyud.net
< * doesn't match xyay.com
< * possibly matches yay.com.
< */
< if (url.host.indexOf(data.host) < 0)
< return false;
< }
< var rtn = {
< "url" : url.spec,
< "post" : url.port,
< "path" : url.path,
< "protocol" : url.scheme,
< "host" : url.host }
< return rtn;
< }
< },
<
< /**
< * When docs are not availaible, each_element calls this function
< */
< _get_attrib_from_tagname_string : function (tag, attrib) {
< // attrib="value"
< // attrib='value'
< // var m = RegExp("\\b" + attrib + "=([\"\'])([^\\1]+)", "i").exec(tag); -- TODO why didn;t this work?
< var m = RegExp("\\b" + attrib + "=([\"\'])(.*?)\\1", "i").exec(tag);
< if (m)
< return m[2];
< // attrib=value
< var m = RegExp("\\b" + attrib + "=([^\\s]+)", "i").exec(tag);
< if (m)
< return m[1];
< return null;
< },
<
< /*
< * Iterates over the dom elements in doc which match the specified pattern
< */
< each_element : {
< order : 70,
< optional : [
< "tagname",
< "elemid",
< "require_attrs",
< "attrs",
< "string",
< "slow"],
< apply_ref : true,
< execute : function (data, url, text, doc) {
< var search_with_dom = true;
< if (data.string || !doc)
< search_with_dom = false;
< // TODO - this next line should be configurable for flashblock/no flashblock and for about:config settings too!
< // TODO - and this is only really useful where we can get original source from cache
< if ((data.tagname == "embed" || data.tagname == "object") && false)
< search_with_dom = false;
< if (!search_with_dom) {
< UnPlug2.log("each_element works slowly when not given a document!");
< if (!data.tagname)
< throw "each_element requires a document or a tagname";
< // "slow" tags, like searching all anchors, is skipped because this is likely to be significantly worse performance than using the dom.
< if (data.slow)
< return false;
< var rtn = [];
< var reg = RegExp("<" + data.tagname + "([^>]*)>", "gi");
< while (true) {
< var regresult = reg.exec(data.string || text);
< if (!regresult)
< break;
< var tag = regresult[1];
< var single_rtn = {};
<
< var require_attrs = data.require_attrs.split(",");
< if (require_attrs.indexOf("innerHTML") > -1)
< throw "innerHTML not supported by without a doc.";
< var got_all_req = true;
< for (var i = 0; i < require_attrs.length; i++) {
< var x = UnPlug2Rules._get_attrib_from_tagname_string(tag, require_attrs[i]);
< // x = (x || "").replace(RegExp("^\\s+|\\s+$", "g"), "") // strip whitespace
< if (!x) {
< got_all_req = false;
< break;
< }
< single_rtn[require_attrs[i]] = x;
< }
< if (!got_all_req)
< continue
<
< var attrs = data.attrs.split(",");
< for (var i = 0; i < attrs.length; i++) {
< var x = UnPlug2Rules._get_attrib_from_tagname_string(tag, attrs[i]);
< if (x)
< single_rtn[attrs[i]] = x;
< }
< rtn[rtn.length] = single_rtn;
< }
< return rtn;
< }
< // above this line is the slow regexp version for no document
< // below this line is the fast dom version for those with a document
<
< // apply elemid and tagname
< if (data.elemid) {
< var elem = doc.getElementById(data.elemid);
< if (!elem)
< return false;
< if (data.tagname && data.tagname != elem.tagName)
< throw "Element with id did not match tagname";
< var elem_list = [elem];
< } else if (data.tagname) {
< var elem_list = doc.getElementsByTagName(data.tagname);
< } else {
< throw "each_element has no tagname and no elemid";
< }
<
< // elem_list is populated with a list of possible elements
< var result_list = [];
< for (var i=0; i < elem_list.length; i++) {
< var elem = elem_list[i];
<
< // get the variables that are in response of this one element
< var result = {};
< var got_all_required = true;
< for each (req_attr in data.require_attrs.split(",")) {
< switch (req_attr) {
< case "innerHTML" :
< result.innerHTML = elem.textContent;
< if (!result.innerHTML) {
< got_all_required = false;
< }
< break;
< case "":
< break;
< default:
< var attrvalue = elem.getAttribute(req_attr);
< if (attrvalue)
< result[req_attr] = attrvalue;
< else
< got_all_required = false;
< break;
< }
< }
< if (!got_all_required) {
< continue;
< }
< for each (attr in data.attrs.split(",")) {
< switch (attr) {
< case "innerHTML" :
< result.innerHTML = elem.textContent;
< break;
< case "":
< break;
< default:
< var attrvalue = elem.getAttribute(attr);
< if (attrvalue)
< result[attr] = attrvalue;
< break;
< }
< }
<
< // add this one element's response to the list
< result_list[result_list.length] = result;
< }
<
< return result_list;
< }
< },
<
< _media_ext : [
< "wma", "wmv",
< "mpg", "mpeg", "mp3", "mp2", "mp4",
< "divx", "avi",
< "ogg", "ogv", "flac", "speex",
< "mkv",
< "3gp",
< "flv" ],
<
< if_ext : {
< order : 70,
< required : ["filename"],
< optional : [
< "ext",
< "is_media"],
< apply_ref : true,
< execute : function (data, url, text, doc) {
< var fullname = data.filename.toLowerCase();
<
< // strip gubbinns from end of url
< var lasthash = fullname.lastIndexOf("#");
< if (lasthash > 0)
< fullname = fullname.substring(0, lasthash);
< var lastquestion = fullname.lastIndexOf("?");
< if (lastquestion > 0)
< fullname = fullname.substring(0, lastquestion);
< var lastsemi = fullname.lastIndexOf(";");
< if (lastsemi > 0)
< fullname = fullname.substring(0, lastsemi);
<
< // get ext
< var lastdot = fullname.lastIndexOf(".");
< if (lastdot < 0)
< return false;
<
< var ext = fullname.substring(lastdot+1).toLowerCase();
< if (ext.length < 1 || ext.length > 5)
< return false;
<
< if (data.is_media) {
< if (UnPlug2Rules._media_ext.indexOf(ext) < 0)
< return false;
< }
<
< // return true
< return { ref : ext };
< }
< },
<
< end_of_object : 1 };
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/content/search/search.js releases/unplus-2.043/source/chrome/content/search/search.js
1,1385d0
< /*
< * _ ___
< * /\ / /___ / _ \ /\ /\ _ ___
< * / // // _ \ / // // // // // _ \
< * / // // // / / ___// // // // // /
< * \___//_//_/ /_/ /_/ \___/ \_ /
< * \___/
< *
< * Compunach UnPlug
< * Copyright (C) 2010 David Batley
< *
< * This program is free software: you can redistribute it and/or modify
< * it under the terms of the GNU Affero General Public License as
< * published by the Free Software Foundation, either version 3 of the
< * License, or (at your option) any later version.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU Affero General Public License
< * along with this program. If not, see .
< *
< */
<
< /**
< * A download. Don't forget to make this with "new", ie:
< * var foo = new UnPlug2Download(url, UnPlug2Search._download_callback_ok, UnPlug2Search._download_callback_fail, 5000);
< * This should normally be created by calling a function in UnPlug2Search (so it gets registered in the "busy" list.
< * The download will timeout after timeout miliseconds (so we don't download all of a massive file, if we've got it wrong.
< * Reference is a way of working out what download is what.
< */
< UnPlug2Download = function (reference, url, post_data, callback_ok, callback_fail, timeout) {
< this.url = url;
< this._post_data = post_data;
< this.reference = reference;
< this._extern_callback_ok = callback_ok;
< this._extern_callback_fail = callback_fail;
< this._done = false;
< this._percent = 0;
< this._xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
< .createInstance(Components.interfaces.nsIXMLHttpRequest);
< this._timeout_delay = timeout;
< this.text = null;
< this.xmldoc = null;
< this._started = false;
<
< // this in these callbacks are xhttprequests.
< // which is dumb
< var realthis = this;
< try {
< this._xmlhttp.addEventListener("progress", function (evt) { realthis._internal_callback_progress(evt); }, false);
< } catch (e) {
< // pass -- fails for ff 2.0
< }
< this._xmlhttp.addEventListener("load", function () { realthis._internal_callback_ok(); }, false);
< this._xmlhttp.addEventListener("error", function () { realthis._internal_callback_fail(); }, false);
<
< // abort isn't in 3.0.5
< // this._xmlhttp.addEventListener("abort", this._internal_callback_fail, false);
<
< return this;
< }
< UnPlug2Download.prototype = {
< load_flags : (
< // load from cache (if possible)
< Components.interfaces.nsIRequest.LOAD_FROM_CACHE
< // supress popup warnings, http auth prompts, etc
< | Components.interfaces.nsIRequest.LOAD_BACKGROUND),
< /**
< * Returns true if the download has started
< */
< is_started : function () {
< return this._started || this._done;
< },
<
< /**
< * Starts the download (possibly after a small delay)
< */
< start : function (delay) {
< if (this._started) {
< return;
< }
< this._started = true;
< if (delay) {
< window.setTimeout((function (that) {
< return (function () {
< that._do_start();
< })
< })(this), delay);
< } else {
< this._do_start();
< }
< },
< _do_start : function () {
< if (this._done) {
< return; // this is set on cancel.
< }
< var realthis = this;
< this._timeout = window.setTimeout((function () { realthis._timeout_callback(); }), this._timeout_delay);
<
< if (this._post_data) {
< this._xmlhttp.open('POST', this.url, true);
< this._xmlhttp.channel.loadFlags |= this.load_flags;
< this._xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
< this._xmlhttp.send(this._post_data);
< } else {
< this._xmlhttp.open('GET', this.url, true);
< this._xmlhttp.channel.loadFlags |= this.load_flags;
< this._xmlhttp.send(null);
< }
< },
<
< /**
< * Returns true if the download has completed (or failed)
< */
< is_complete : function () {
< return this._done;
< },
<
< /**
< * Return the percetage of the file which has been downloaded.
< */
< percent_complete : function () {
< if (this._done)
< return 100;
< return this._percent;
< },
<
< /**
< * Aboarts the download, if possible
< */
< cancel : function () {
< try {
< this._xmlhttp.abort();
< } catch (e) {
< UnPlug2.log("Cancel download error " + e.toSource());
< }
< if (!this._done) {
< this._internal_callback_fail();
< }
< },
<
< _internal_callback_ok : function () {
< if (this._done) {
< UnPlug2.log("Duplicate callback: ok " + this)
< return
< }
< this.clear_timeout()
< this._done = true;
< this.text = this._xmlhttp.responseText;
< this.xmldoc = this._xmlhttp.responseXML;
< this._extern_callback_ok(this);
< },
<
< _internal_callback_fail : function () {
< if (this._done) {
< UnPlug2.log("Duplicate callback: fail " + this)
< return
< }
< this.clear_timeout()
< this._done = true;
< this._extern_callback_fail(this);
< },
<
< _internal_callback_progress : function (evt) {
< if (evt.lengthComputable) {
< p = 100 * evt.loaded / evt.total;
< if (p >= 0 && p <= 100)
< this._percent = p;
< }
< },
<
< _timeout_callback : function () {
< UnPlug2.log("Timeout " + String(this));
< this._timeout = null;
< this.cancel();
< },
<
< clear_timeout : function () {
< if (this._timeout) {
< window.clearTimeout(this._timeout);
< this._timeout = null;
< }
< },
<
< toString : function () {
< return "";
< },
<
< version: 2.0 }
<
<
<
< /**
< * An object to keep track of variable scopes
< * init with a parent UnPlug2Variables object (or null), and an object containing variable names to update
< * don't forget to use "new" - new UnPlug2Variables(pnt, {foo : "bar"})
< */
< function UnPlug2Variables(p, updates) {
< this._parent = p;
< this._vars = updates;
< }
< UnPlug2Variables.prototype = {
< /**
< * Get a variable
< */
< get : function (name) {
< var value = this._vars[name];
< if (typeof(value) != "undefined")
< return value;
< if (this._parent)
< return this._parent.get(name);
< return undefined;
< },
<
< /**
< * Set a variable
< */
< set : function (name, value) {
< this._vars[name] = value;
< },
<
< /**
< * Set varaibles from an objecy
< */
< update : function (updates) {
< for (k in updates)
< this._vars[k] = updates[k];
< },
<
< toString : function () {
< return "var(" + this._vars.toSource() + "+" + String(this._parent) + ")";
< },
<
< /**
< * Return traceback as a string
< */
< trace : function () {
< return "";
< },
<
< /**
< * Returns an array of .traceback strings.
< */
< traceback : function (partial_list) {
< if (!partial_list)
< partial_list = Array("");
< if (this._parent)
< this._parent.traceback(partial_list);
< if (this._vars[".trace"])
< partial_list[partial_list.length] = this._vars[".trace"];
< return partial_list;
< },
<
< /**
< * return "text" with the variables substituted into the ${...} placeholders.
< * throws if invalid variable or other errors
< */
< subst : function (text) {
< var variables = this;
< if (!text)
< return "";
< return text.replace(
< /\$\{([^\}]+)\}/g,
< function (wholematch, varfullname, offset, origstring) {
< // ${func3:func2:func1:varname}
< var parts = varfullname.split(":");
< parts.reverse() // reverse so we can .pop() in _subst_apply_functions()
< return variables._subst_apply_functions(parts);
< });
< },
<
< subst_optional : function (text) {
< try {
< return this.subst(text);
< } catch (e) {
< return "";
< }
< },
<
< // parts here is in REVERSE ORDER
< _subst_apply_functions : function (parts) {
< // is last element, so get variable name
< if (parts.length == 1) {
< var value = this.get(parts[0]);
< if (!value)
< throw "Variable is undefined: " + parts[0] + " at " + this.trace() + " in " + this;
< return value;
< }
<
< // is not last element so first part is a function:
< var funcname = parts.pop()
< switch (funcname) {
< /**
< * Decodes url %nn escape codes in variable
< */
< case "urldecode":
< // we could use decodeURI here, but that fails to
< // unescape all the characters we want (colon, slash, ...)
< // but we still want to interpret as unicode
< var v = this._subst_apply_functions(parts)
< return UnPlug2.decode("UTF-8", unescape(v)).replace("+", " ", "g");
< case "urldecode_unicode":
< var encoding = parts.pop();
< var v = this._subst_apply_functions(parts)
< return UnPlug2.decode(encoding, unescape(v)).replace("+", " ", "g");
< /**
< * Encodes url %nn escape codes in variable
< */
< case "urlencode":
< return escape(this._subst_apply_functions(parts));
< /**
< * Regular expression escape
< */
< case "reescape":
< var specials = RegExp("[\\" + ("\\.*+{}()[]$^-".split("").join("\\")) + "]", "g");
< var x = this._subst_apply_functions(parts).replace(specials, (function (substr) {
< return "\\" + substr;
< }));
< return x
< /**
< * decode html entities TODO
< */
< case "htmldecode":
< return this._subst_apply_functions(parts).replace(
< /&(.*?);/g,
< function (str, m, offset, s) {
< switch (m) {
< case "amp": return "&";
< case "quot": return "\"";
< }
< if (m[0] == "#")
< return String.fromCharCode(m.substr(1));
< throw "Unknown htmldecode: entity " + m;
< });
< /**
< * Decodes \xNN javascript escape sequences
< */
< case "jsdecode":
< return this._subst_apply_functions(parts).replace(
< /\\(b|f|n|r|t|v|\'|\"|\\|\/|[0-7]{3}|x[0-9a-fA-F]{2}|u[0-9a-fA-f]{4})/g, function (wholematch, esc, offset, origstring) {
< switch (esc.charAt(0)) {
< case "b" : return "\b";
< case "f" : return "\f";
< case "n" : return "\n";
< case "r" : return "\r";
< case "t" : return "\t";
< case "v" : return "\v";
< case "\'" : return "\'";
< case "\"" : return "\"";
< case "/" : return "/";
< case "x": return String.fromCharCode(parseInt(esc.substring(1), 16));
< case "u": return String.fromCharCode(parseInt(esc.substring(1), 16));
< case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": return String.fromCharCode(parseInt(esc, 8));
< }
< throw "Unknown escape in jsdecode " + esc;
< });
< /**
< * ${randomfloat}
< */
< case "randomfloat":
< if (parts.length != 0)
< throw "Cannot parse ${randomfloat}";
< return Math.random();
< /**
< * ${randomint:numchars}
< */
< case "randomint":
< if (parts.length != 1)
< throw "Cannot parse ${randomint:...}";
< var r = "";
< for (var i = 0; i < parseInt(parts[0]); ++i) {
< r += "0123456789"[Math.floor(Math.random() * 10)];
< }
< return r
< /**
< * ${optional:varname}
< */
< case "optional":
< try {
< return this._subst_apply_functions(parts);
< } catch (e) {
< return "";
< }
< /**
< * ${required:varname}
< */
< case "required":
< var r = this._subst_apply_functions(parts);
< if (r) {
< return r;
< } else {
< throw "Variable gave empty string: " + parts.toSource()
< }
< /**
< * ${either:var1:var2:....}
< */
< case "either":
< while (parts.length > 0) {
< var p = parts.pop()
< var z = "";
< try {
< z = this._subst_apply_functions([p]);
< } catch (e) {
< continue;
< }
< if (z) {
< return z;
< }
< }
< return "";
< /**
< * ${translate:name_in_locale_file}
< */
< case "translate":
< if (parts.length != 1)
< throw "Invalid length for ${translate:...}";
< return UnPlug2.str(parts[0]);
< /*
< * ${substring:start:variablename}
< * ${substring:start:end:variablename}
< * can be -ve numbers (like python)
< */
< case "substring":
< var n1 = Number(parts.pop())
< var n2 = Number(parts[parts.length-1]);
< if (parts[parts.length-1] == "end") {
< n2 = null;
< parts.pop();
< } else if (isNaN(n2)) {
< // ${substring:start:var}
< n2 = null;
< } else {
< // ${substring:start:end:var}
< parts.pop() // pop n2
< }
< var fullstring = String(this._subst_apply_functions(parts));
< if (n1 < 0) {
< n1 += fullstring.length;
< }
< if (!n2) {
< n2 = fullstring.length;
< } else if (n2 < 0) {
< n2 += fullstring.length;
< }
< return fullstring.substring(n1, n2);
< case "reversed":
< var value = this._subst_apply_functions(parts);
< return value.split("").reverse().join("")
< /**
< * ${padprefix:pad_char:boundary_size:variable}
< * Pads variabe with pad_char until length divisible by boundary_size.
< */
< case "padprefix":
< var prefixvalue = parts.pop()
< var prefixboundary = Number(parts.pop())
< var value = this._subst_apply_functions(parts);
< if (prefixvalue.length != 1)
< throw "char must be length 1 in ${padprefix}";
< if (!prefixboundary)
< throw "Invalid boundary size in ${padprefix}";
< while (value.length % prefixboundary)
< value = prefixvalue + value;
< return value;
< /**
< * ${padprefix:pad_char:size:variable}
< * Adds pad_char to the left of variable until it is at least size long
< */
< case "leftpad":
< var prefixvalue = parts.pop()
< var len = Number(parts.pop())
< var value = this._subst_apply_functions(parts);
< if (prefixvalue.length != 1)
< throw "char must be length 1 in ${padleft}";
< if (!len)
< throw "Invalid size in ${padleft}";
< while (value.length < len)
< value = prefixvalue + value;
< return value;
< /**
< * ${hextostr:varname}
< */
< case "hextostr":
< var hex = this._subst_apply_functions(parts);
< if (hex.length % 2) {
< hex = "0" + hex;
< }
< var twohexes = Array();
< for (var i = 0; i < hex.length; i+= 2) {
< twohexes[twohexes.length] = hex.substring(i, i+2);
< }
< return twohexes.map(function (x) { return String.fromCharCode(Number("0x" + x)); }).join("");
< /**
< * ${qparam:paramname:urlvarname}
< */
< case "qparam":
< var qname = parts.pop();
< var urlstring = this._subst_apply_functions(parts);
< urlstring = urlstring.substring(urlstring.indexOf("?")+1);
< urlstring = "&" + urlstring + "&";
< var r = RegExp("&" + qname + "=([^&]+)");
< var m = r.exec(urlstring);
< if (!m) {
< throw "qparam:" + qname + " is not in " + urlstring;
< }
< return unescape(m[1]);
< /**
< * ${megavideo:un:key1:key2}
< */
< case "megavideo":
< if (parts.length != 3) {
< throw "wrong number of args for magavideo";
< }
< var un = this._subst_apply_functions([parts[2]]);
< var key1 = this._subst_apply_functions([parts[1]]);
< var key2 = this._subst_apply_functions([parts[0]]);
< return this.megavideo_hash(un, key1, key2);
< /**
< * ${youku:....}
< */
< case "youku":
< if (parts.length != 6) {
< throw "wrong number of args for youku";
< }
< var mediatype = parts[5];
< var key1 = this._subst_apply_functions([parts[4]]);
< var key2 = this._subst_apply_functions([parts[3]]);
< var seed = this._subst_apply_functions([parts[2]]);
< var streamid = this._subst_apply_functions([parts[1]]);
< var pieceid = this._subst_apply_functions([parts[0]]);
< return this.youku_url(mediatype, key1, key2, seed, streamid, pieceid);
< default:
< throw "Undefined function for variables: " + funcname;
< }
< },
<
< megavideo_hash : (function (un, key1, key2) {
< var hex2bin = {
< "0" : "0000", "1" : "0001", "2" : "0010", "3" : "0011",
< "4" : "0100", "5" : "0101", "6" : "0110", "7" : "0111",
< "8" : "1000", "9" : "1001", "a" : "1010", "b" : "1011",
< "c" : "1100", "d" : "1101", "e" : "1110", "f" : "1111" };
< var bin2hex = {
< "0000" : "0", "0001" : "1", "0010" : "2", "0011" : "3",
< "0100" : "4", "0101" : "5", "0110" : "6", "0111" : "7",
< "1000" : "8", "1001" : "9", "1010" : "a", "1011" : "b",
< "1100" : "c", "1101" : "d", "1110" : "e", "1111" : "f" };
<
< var donkey = Array();
< key1 = parseInt(key1);
< key2 = parseInt(key2);
< for (var i = 0; i < 384; ++i) {
< key1 = ((key1 * 11) + 77213) % 81371
< key2 = ((key2 * 17) + 92717) % 192811
< donkey[i] = (key1 + key2) % 128
< }
<
< var bin = Array();
< for (var i = 0; i < un.length; ++i) {
< bin.push(hex2bin[un[i]]);
< }
< bin = bin.join("").split("")
<
< if (bin.length != 128) {
< throw "bin is the wrong length";
< }
<
< for (var i = 256; i >= 0; --i) {
< var j = donkey[i];
< var k = i % 128;
< var tmp = bin[k];
< bin[k] = bin[j];
< bin[j] = tmp;
< }
<
< for (var i = 0; i < 128; ++i) {
< if (donkey[i + 256] & 0x01) {
< if (bin[i] == "0") {
< bin[i] = "1";
< } else if (bin[i] == "1") {
< bin[i] = "0";
< } else {
< throw "unexpected value";
< }
< }
< }
<
< var result = Array();
< bin = bin.join("");
< for (var i = 0; i < bin.length; i += 4) {
< result.push(bin2hex[bin.substring(i, i+4)]);
< }
<
< return result.join("");
< }),
<
< youku_url : (function (mediatype, key1, key2, randomseed, streamid, piece_num) {
< var r = (function () { return "0123456789"[Math.floor(Math.random() * 10)] });
< var hex = "0123456789ABCDEF"
<
< piece_num = hex[Math.floor(piece_num / 16)] + hex[piece_num % 16];
<
< // get the codebook like in cg_hun()
< var codebook = ""
< var t = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890"
< randomseed = parseInt(randomseed)
< while (t.length > 0) {
< randomseed = ((randomseed * 211) + 30031) % 65536;
< var idx = Math.floor(randomseed * t.length / 65536);
< var c = t.charAt(idx);
< if (!c) { throw "Youku: infinite loop of doom at " + idx.toSource() + " of " + t.toSource() + " => " + c.toSource() ; }
< codebook += c;
< t = t.replace(c, "");
< }
<
< // decode the uuid like in cg_fun()
< var fileid = "";
< var fileid_stars = streamid.split("*");
< fileid_stars.pop();
< for (var i = 0; i < fileid_stars.length; ++i) {
< fileid += codebook[parseInt(fileid_stars[i])];
< }
<
< // make the url
< var url = [];
< url.push("http://f.youku.com/player/getFlvPath/sid/");
< url.push(Math.floor((new Date()).getTime()))
< for (var i = 0; i < 8; ++i) {
< url.push(r());
< }
< url.push("_");
< url.push(piece_num);
< url.push("/st/");
< url.push(mediatype);
< url.push("/fileid/");
< url.push(fileid.substring(0, 8));
< url.push(piece_num);
< url.push(fileid.substring(10, fileid.length));
< url.push("?K=");
< url.push(key2);
< url.push((parseInt(key1, 16) ^ 0xa55aa5a5).toString(16).toLowerCase()); // xor
< url.push("&myp=0&ts=" + r() + r() + r());
< return url.join("");
< }),
<
< endofobject : 1 }
<
< UnPlug2Search = {
< UnPlug2Search : function () {
< this._reset();
<
< this.blank_variables = new UnPlug2Variables(null, {
< '.version' : UnPlug2.version,
< '.revision' : UnPlug2.revision,
< '$' : '$' })
<
< this._io_service = Components.classes["@mozilla.org/network/io-service;1"]
< .getService(Components.interfaces.nsIIOService)
< },
<
< /**
< * Default timeout to downloads, in ms.
< */
< default_timeout : 30000,
<
< /**
< * Ask for a file to be downloaded
< * url must be an nsIURI object
< */
< _queue_download : function (url, post_data, rules_to_apply, variables, timeout) {
< if (UnPlug2Search._stopped)
< return
<
< var dl_id = UnPlug2Search._downloads.length;
< if (dl_id > 100) {
< UnPlug2.log("Not queuing download: too many downloads " + url);
< return
< }
<
< // set priority from download-priority hook
< priority = 50;
< for each (node in UnPlug2Search.get_hooks("download-priority")) {
< for each (child in node.getElementsByTagName("priority")) {
< if (url.host.indexOf(child.textContent) < 0) {
< continue;
< }
< switch (child.getAttribute("level")) {
< case "very-high": priority -= 20; break;
< case "high": priority -= 10; break;
< case "normal": break;
< case "low": priority += 10; break;
< case "very-low": priority += 20; break;
< case "never":
< UnPlug2.log("Not downloading " + url.spec + " because forbidden in download-priority hook");
< return;
< default:
< UnPlug2.log("Invalid priority for download-priority hook " + child.getAttribute("level"));
< break;
< }
< }
< }
<
< UnPlug2Search._downloads[dl_id] = {
< rules_to_apply: rules_to_apply,
< variables : variables,
< download: null,
< nsiuri: url,
< priority : priority };
< // start download after setting everything else up
< try {
< UnPlug2Search._downloads[dl_id].download = new UnPlug2Download(
< dl_id,
< url.spec,
< post_data,
< UnPlug2Search._download_callback_ok,
< UnPlug2Search._download_callback_fail,
< timeout);
< UnPlug2.log("Download queued " + UnPlug2Search._downloads[dl_id].download + " priority " + UnPlug2Search._downloads[dl_id].priority);
< } catch (e) {
< UnPlug2.log("Download failed to be queued for " + UnPlug2Search._downloads[dl_id].download + " because " + e.toSource());
< // .download not assigned
< UnPlug2Search._downloads[dl_id].download = null;
< }
< UnPlug2Search._do_download_poll = true;
< },
<
< poll : function () {
< var statusinfo = UnPlug2Search.statusinfo();
< UnPlug2Search.callback(statusinfo);
<
< // noting to do, so lets stop
< if (statusinfo.finished) {
< UnPlug2.log("Finished search");
< UnPlug2Search._stopped = true;
< }
<
< if (UnPlug2Search._stopped) {
< // a message with type=progress finished=true will have
< // been sent, so we can stop the poller.
< UnPlug2.log("Stopping: search finished.");
< window.clearInterval(UnPlug2Search._poll_timer);
< UnPlug2Search._poll_timer = null;
< return;
< }
<
< if (UnPlug2Search._do_download_poll) {
< UnPlug2Search._do_download_poll = false;
< UnPlug2Search._download_poll();
< }
< },
<
< /**
< * Should be called regularly to start queued downloads
< */
< _download_poll : function () {
< var concurrent_downloads = 5; // XXX CONFIGURABLE
< for (var i = 0; i < UnPlug2Search._downloads.length; i++) {
< if (UnPlug2Search._downloads[i]
< && UnPlug2Search._downloads[i].download
< && UnPlug2Search._downloads[i].download.is_started() == true
< && UnPlug2Search._downloads[i].download.is_complete() == false) {
< --concurrent_downloads;
< }
< }
< if (concurrent_downloads <= 0) {
< return;
< }
< var startable_downloads = [];
< for (var i = 0; i < UnPlug2Search._downloads.length; i++) {
< if (UnPlug2Search._downloads[i]
< && UnPlug2Search._downloads[i].download
< && UnPlug2Search._downloads[i].download.is_started() == false) {
< startable_downloads[startable_downloads.length] = i;
< }
< }
< startable_downloads.sort(function (a, b) {
< return UnPlug2Search._downloads[a].priority - UnPlug2Search._downloads[b].priority;
< });
< for (var i = 0; i < startable_downloads.length && i < concurrent_downloads; ++i) {
< var dl_id = startable_downloads[i];
< try {
< // use a small (100ms) delay here so we don't block main thread for a long time
< UnPlug2Search._downloads[dl_id].download.start(100);
< UnPlug2.log("Starting download id = " + dl_id);
< } catch (e) {
< UnPlug2.log("Starting Download failed for " + dl_id + " / " + UnPlug2Search._downloads[dl_id].download + " because " + e.toSource());
< UnPlug2Search._downloads[dl_id].download = null;
< }
< }
< },
<
< _download_callback_ok : function (dl) {
< UnPlug2.log("Downloaded " + dl);
< var dlinfo = UnPlug2Search._downloads[dl.reference];
< var dlxml = dl.xmldoc;
< if (dlxml && dlxml.getElementsByTagName("parsererror").length > 0) {
< UnPlug2.log("Document has poorly-formatted xml (consider regexp on whole text). Url=" + dl.url)
< dlxml = null;
< }
< UnPlug2Search._apply_rules_to_document(dlinfo.nsiuri, dl.text, dlxml, dlinfo.rules_to_apply, dlinfo.variables);
< UnPlug2Search._downloads[dl.reference].download = null;
< UnPlug2Search._do_download_poll = true;
< },
<
< _download_callback_fail : function (dl) {
< // it really can't find UnPlug2 object in all cases!
< try {
< UnPlug2.log("Failed download " + dl);
< } catch(e) {
< // can't do alert() here either .. sheesh!
< }
< UnPlug2Search._downloads[dl.reference].download = null;
< UnPlug2Search._do_download_poll = true;
< },
<
< /**
< * Cancels all downloads
< */
< cancel_downloads : function () {
< for (var i = 0; i < UnPlug2Search._downloads.length; i++) {
< var d = UnPlug2Search._downloads[i];
< if (d && d.download) {
< d.download.cancel()
< }
< }
< },
<
< /**
< * Stop downloading and stop search process
< */
< abort : function () {
< UnPlug2Search._stopped = true;
< UnPlug2Search.cancel_downloads();
< },
<
< /**
< * Get a "hooks" item from rules.xml for adjusting eg download priority
< * Returns an array
< */
< get_hooks : function (hookname) {
< if (UnPlug2Search._hooks === undefined) {
< UnPlug2Search._hooks = {};
< var hooknodes = UnPlug2Search.get_rules_xml().getElementsByTagName("hook");
< for (var i = 0; i < hooknodes.length; ++i) {
< var hooknode = hooknodes[i];
< var hookname = hooknode.getAttribute("for");
< if (UnPlug2Search._hooks[hookname] === undefined) {
< UnPlug2Search._hooks[hookname] = [];
< }
< UnPlug2Search._hooks[hookname].push(hooknode);
< }
< }
< return UnPlug2Search._hooks[hookname] || [];
< },
<
< /**
< * Load the xml document containing the rules
< * Returns the element of the document (which contains a number of elements as children)
< */
< get_rules_xml : function () {
< if (!UnPlug2Search._search_xml) {
< var req = new XMLHttpRequest();
< var filename = "chrome://unplug/content/rules.xml";
<
< // this response is synchronous (not async) because it's a local file.
< // sync by use of false in 3rd arg
< req.open('GET', filename, false);
< req.send(null);
< if (req.status != 0) {
< UnPlug2.log("Cannot open " + filename);
< throw "Cannot open " + filename;
< }
< var xmldoc = req.responseXML;
< var unplugnode = null;
< for each (node in xmldoc.childNodes) {
< if (node.tagName && node.tagName.toLowerCase() == "unplug") {
< unplugnode = node;
< break;
< }
< }
< if (!unplugnode) {
< UnPlug2.log("Invalid root node for document " + xmldoc);
< throw "Cannot load xml rules - no root node";
< }
< UnPlug2Search._search_xml = unplugnode;
< }
< return UnPlug2Search._search_xml;
< },
<
< /**
< * Find media in window "win", and call function "callback" for eac result found.
< * Callback may be called both immediately, and after additional files are downloaded.
< */
< search : function (win, callback) {
< if (!this.statusinfo().finished) {
< throw "Already in search";
< }
<
< // start search poller
< this._reset();
< this.callback = callback;
< // don't let UnPlug2Search.poll suggest we've finished before we really start
< // (ie: fix race condition). This gets decremented later.
< UnPlug2Search._defered_rules_count += 1;
< if (!UnPlug2Search._poll_timer) {
< UnPlug2Search._poll_timer = window.setInterval(UnPlug2Search.poll, 100);
< }
<
< this._apply_rules_to_window(
< win,
< this.get_rules_xml(),
< this.blank_variables);
<
< UnPlug2Search._defered_rules_count -= 1; // see above
<
< if (UnPlug2.get_pref("popularity_contest")) {
< var dl = new UnPlug2Download(
< null, // ref
< "http://unplug.dbatley.com/popularity_contest/submit.cgi",
< "useragent=" + escape(window.navigator.userAgent) + "&url=" + escape(win.location.href) + "&version=" + UnPlug2.version + "&revision=" + UnPlug2.revision + "&codename=" + UnPlug2.codename,
< null, null, // callbacks
< 10000);
< dl.start()
< }
< },
<
< /**
< * apply rules in a -type element to a window.
< */
< _apply_rules_to_window : function (win, rules_xml, variables) {
< var serializer = new XMLSerializer();
< var xml_text = serializer.serializeToString(win.document);
< //var xml_text = win.document.body.innerHTML;
<
< var url = this._io_service.newURI(String(win.location), null, null);
< UnPlug2Search._apply_rules_to_document(
< url, // url (a nsiURI)
< xml_text, // we need to serialize the document into text
< win.document, // the xml of the document
< rules_xml, // a to apply
< variables); // for ${...} substitution in the rules.
<
< // also search in frames
< for (var i = 0; i < win.frames.length; i++) {
< UnPlug2Search._apply_rules_to_window(win.frames[i], rules_xml, variables);
< }
< },
<
< /**
< * The protocols it's fine to download with a
< */
< _downloadable_protocols : [
< "http", "https", "ftp", "gopher",
< ],
<
< /**
< * apply rules in a -type element to a document and url.
< * To apply the rules, we need the url of the document, the document in text and in xml (or null).
< * We also need the rules we'll be applying, and the variables for the variable substitutions - ${...} - in those rules.
< * The url is a nsIURI
< */
< _apply_rules_to_document : function (url, text, doc, rules_xml, variables) {
< if (UnPlug2Search._stopped)
< return;
<
< if (["http", "https"].indexOf(url.scheme) < 0) {
< UnPlug2.log("Invalid url for search " + url.spec);
< return;
< }
<
< // add special variables
< variables = new UnPlug2Variables(variables, {
< ".url" : url.spec,
< ".url.protocol" : url.protocol,
< ".has_doc" : doc ? true : false,
< ".trace" : rules_xml.getAttribute("id") || "" })
<
< // the if_* statements add variables, which are available to deeper levels in rules.xml
< var updated_variables = new UnPlug2Variables(variables, {})
<
< /*
< * evaluate all the if_* statements, updating the variables in updated_variables if needed
< */
< var node;
< for each (node in rules_xml.childNodes) {
< var nodetagname = node.tagName ? node.tagName.toLowerCase() : "";
< var funcname = null;
< var optional = null;
< var exectype = null;
< if (nodetagname.substring(0, 3) == "if_") {
< funcname = nodetagname.substring(3);
< exectype = "if";
< optional = false;
< } else if (nodetagname.substring(0, 6) == "ifnot_") {
< funcname = nodetagname.substring(6);
< exectype = "ifnot";
< optional = false;
< } else if (nodetagname.substring(0, 9) == "optional_") {
< funcname = nodetagname.substring(9);
< exectype = "optional";
< optional = true;
< } else {
< continue;
< }
<
< // exec UnPlug2Rules.if_*(...);
< // which returns either false or an object with additional variables
< // note: variables are passed to this function for use with eg
< // but variables object should not be edited directly.
< var result = false;
< try {
< result = UnPlug2Rules["exec_" + exectype](funcname, node, variables, url, text, doc);
< } catch (e) {
< UnPlug2.log("Error in " + nodetagname + " because " + e.toSource() + " " + variables.trace());
< }
<
< if (result) {
< // add to updated variables
< updated_variables.update(result);
< } else {
< // fail one if_* condition means the whole is failed
< if (!optional)
< return; // failed
< }
< }
<
< /*
< * evaluate all each_* statements
< */
< var node;
< for each (node in rules_xml.childNodes) {
< var nodetagname = node.tagName ? node.tagName.toLowerCase() : "";
< if (nodetagname.substring(0, 5) == "each_") {
< // exec UnPlug2Rules.each_*(...);
< // which returns either false or an array of objects which contain updated variables
< // example:
< //
< // on
< // foo bar
< // returns [{ id: "hello" }, { id: "bar", lang: "en" }]]
< var result_list = false;
< try {
< result_list = UnPlug2Rules.exec_each(nodetagname.substring(5), node, updated_variables, url, text, doc);
< } catch (e) {
< UnPlug2.log("Error in " + nodetagname + " because " + e.toSource() + " " + variables.trace());
< }
< if (result_list) {
< for (var j = 0; j < result_list.length; j++) {
< var result = result_list[j];
< var new_variables = new UnPlug2Variables(updated_variables, result)
< UnPlug2Search._apply_rules_to_document(
< url,
< text,
< doc,
< node, // this is the node
< new_variables) // updated_variables + variables from each_* tag
< }
< }
< }
< }
<
<
< /*
< * apply all the and nodes, etc.
< */
< var node;
< for each (node in rules_xml.childNodes) {
< if (!node.tagName) {
< continue;
< }
< var nodetagname = node.tagName.toLowerCase();
< if (nodetagname.substring(0, 3) != "if_" && nodetagname.substring(0, 6) != "ifnot_" && nodetagname.substring(0, 9) != "optional_" && nodetagname.substring(0, 5) != "each_") {
< try {
< switch (nodetagname.toLowerCase()) {
< case "rule":
< case "then":
< case "ruleset":
< var referenced_node = node;
< if (node.hasAttribute("goto")) {
< // getElementById is broken on firefox! gah!
< if (node.getAttribute("goto") === "*") {
< referenced_node = UnPlug2Search.get_rules_xml()
< } else {
< referenced_node = UnPlug2.get_element(UnPlug2Search.get_rules_xml(), "rule", node.getAttribute("goto"));
< }
< if (!referenced_node)
< throw "Cannot find node to goto " + node.getAttribute("goto");
< }
< if (node.hasAttribute("defer")) {
< /*
< the code below does a good job of keeping the arguments the same
< ie: referenced_node does not change to the last one in the file inside the timeout
< but it is a rather insane
< */
< UnPlug2Search._defered_rules_count += 1;
< window.setTimeout((function (args) {
< return (function () {
< UnPlug2Search._defered_rules_count -= 1;
< UnPlug2Search._apply_rules_to_document.apply(UnPlug2Search, args);
< })
< })([
< url,
< text,
< doc,
< referenced_node,
< updated_variables ])
< , 500)
< } else {
< UnPlug2Search._apply_rules_to_document(
< url,
< text,
< doc,
< referenced_node,
< updated_variables);
< }
< break;
< case "hook":
< // do nothing
< break
< case "download":
< case "playlist": // synonym, eg for .3mu/.asx files which we can parse
< var relative_url = updated_variables.subst(node.getAttribute("url"));
< if (!relative_url)
< throw "download has no url";
< var abs_url = this._io_service.newURI(relative_url, null, url);
< if (UnPlug2Search._downloadable_protocols.indexOf(abs_url.scheme) < 0) {
< throw "Cannot download " + abs_url.spec + " because bad protocol";
< }
< var post = "";
< if (node.hasAttribute("post")) {
< post = updated_variables.subst_optional(node.getAttribute("post"))
< if (!post) {
< throw "Post data failed";
< }
< }
< UnPlug2Search._queue_download(
< abs_url,
< post,
< node,
< updated_variables,
< UnPlug2Search.default_timeout)
< break;
< case "media":
< /*
< TODO -- new things to implement!
<
< */
<
< // get url
< var relative_url = updated_variables.subst(node.getAttribute("url"));
< if (!relative_url)
< throw "Media invalid as empty url";
< var abs_url = this._io_service.newURI(relative_url, null, url);
<
< // get download method
< var download_method = { "url" : abs_url.spec }
< if (node.hasAttribute("post")) {
< download_method = {
< "http_post" : [
< abs_url.spec,
< updated_variables.subst(node.getAttribute("post"))
< ]
< };
< }
< if (node.hasAttribute("referer")) {
< download_method.referer = updated_variables.subst_optional(node.getAttribute("referer"));
< }
< download_method.referer = download_method.referer || String(UnPlug2SearchPage._win.location);
<
< switch (node.getAttribute("method")) {
< case "rtmp":
< download_method.rtmp = download_method.url;
< delete download_method["url"];
< var attrs = ["app", "playpath", "swfurl"];
< for (var aidx = 0; aidx < attrs.length; ++aidx) {
< if (node.hasAttribute(attrs[aidx])) {
< download_method[attrs[aidx]] = updated_variables.subst_optional(node.getAttribute(attrs[aidx]));
< }
< }
< break;
< default:
< // pass
< break;
< }
<
< // make response
< var result = UnPlug2Search._make_response_object_result(
< abs_url,
< download_method,
< updated_variables,
< node,
< updated_variables.trace());
<
< // callback
< UnPlug2Search.callback(result);
< break;
< default:
< throw "Not implemented";
< }
< } catch(e) {
< UnPlug2.log("Failed to action " + nodetagname + " because " + e.toSource() + " " + variables.trace());
< }
< }
< }
< },
<
< /**
< * Return an unplug result object, for passing to the callback
< * The format is JSON-compatible
< * (no no native objects, etc)
< *
< * Download method must be a JSON object (it's sent to the callback function). It must have a type of "result".
< * It's used by download components (eg "copy url", "save with firefox", "save with dta", etc) to decide how and if they work. Examples below:
< * { "link" : url }
< * for basic urls
< * { "link" : url, "referer" : referer }.
< * urls with referer. The referer attribute will be ignored by components which don't support it.
< * { "http_post" : [ url, post_data ] }
< * http post request
< *
< * Download can be used to track duplicate results
< */
< _make_response_object_result : function (nsiuri, download_method, variables, node, trace) {
< var levels = { "very-low" : -20, "low" : -10, "mid" : 0, "high" : +10, "very-high" : +20 };
< var guesses = UnPlug2Search.guess_from_uri(nsiuri);
< var default_quality = 0;
< var default_certainty = +10; // high!
<
< var title = variables.subst_optional(node.getAttribute("title"));
< var file_ext = variables.subst_optional(node.getAttribute("type"));
< var description = variables.subst_optional(node.getAttribute("description"));
< var thumbnailurl = variables.subst_optional(node.getAttribute("thumbnail"));
< var certainty = levels[variables.subst_optional(node.getAttribute("certainty"))];
< var quality = levels[variables.subst_optional(node.getAttribute("quality"))];
<
< var result_object = {
< "type" : "result",
< "details" : {
< "name" : title || guesses.base_name,
< "mediaid" : variables.subst_optional(node.getAttribute("mediaid")) || null,
< "playlistid" : variables.subst_optional(node.getAttribute("playlistid")) || null,
< "certainty" : certainty === undefined ? default_certainty : certainty,
< "quality" : quality === undefined ? default_quality : quality,
<
< // IMPORTANT this is used for advice only (not used for downloading) !!
< "protocol" : nsiuri.scheme,
< "host" : guesses.host,
<
< // more details we may know
< "swf" : ((file_ext || guesses.file_ext) == "swf"), // TODO roll this into file_ext?
< "file_ext" : file_ext || guesses.file_ext || "flv",
< "description" : description || null,
< "thumbnail" : thumbnailurl || null,
< "trace" : trace },
< "download" : download_method };
<
< return result_object;
< },
<
< /**
< * Gets a filename from the url
< */
< guess_from_uri : function (uri) {
< /* nsIRUI have scheme, host, port, and path (note: can be "")
< * nsIURL also have a fileName (made of fileBaseName and fileExtension) which can be "" if uri ends in "/". In this case we want to look at the directory which won't have #ref or ?query or ;param.
< */
< var data = {
< host : "",
< file_ext : "",
< base_name : "" };
<
< // the host SHOULD be available in the nsIURI,
< // but this raises an exception for unusual protocols!
< // there's no guarentee that "host" is meaningful, eg: data links
< try {
< data.host = uri.hostPort;
< } catch(e) {
< // pass
< }
<
< if (uri instanceof Components.interfaces.nsIURL) {
< // these are in nsIURL but not in nsIURI
< // easy! but these can be empty strings
< data.file_ext = uri.fileExtension;
< data.base_name = uri.fileBaseName;
< }
< if (!data.file_ext || !data.base_name) {
< var u = uri.spec;
< // trim endings, like #foo ;foo ?foo
< u = RegExp("^([^\\?;#]*)([\\?;#]|$)").exec(uri.spec)[1];
< // take the last meaningful segment after the final slash
< var r = RegExp("(^|/)([^/]+)/*$").exec(u);
< if (r) {
< u = r[2];
< r = RegExp("^(.*)\\.([a-zA-Z0-9]{1,5})$").exec(u);
< if (r) {
< data.base_name = r[1];
< data.file_ext = r[2];
< } else {
< data.base_name = u;
< }
< }
< }
< return data;
< },
<
< /**
< * Call when it's all over
< */
< _reset : function () {
< // "this" is a lie!!
< UnPlug2Search.callback = function ( res ) { UnPlug2.log("Cannot use callback for result " + res.toSource()); };
< UnPlug2Search._downloads = [];
< UnPlug2Search._do_download_poll = false;
< UnPlug2Search._defered_rules_count = 0;
< },
<
< /**
< * Returns information about the current status
< * The object returned should be JSONable and have a type of "progress"
< */
< statusinfo : function () {
< // count remaining objects / data
< var attempted_downloads = 0;
< var active_downloads = 0;
< var completed_pct = 0;
< for (var i = 0; i < UnPlug2Search._downloads.length; i++) {
< var di = UnPlug2Search._downloads[i];
< if (di) {
< ++attempted_downloads;
< if (di.download) {
< completed_pct += di.download.percent_complete();
< if (di.download.is_complete() == false) {
< ++active_downloads;
< }
< } else {
< // we cleared the download because it was done
< completed_pct += 100;
< }
< }
< }
< var finished_ok = (active_downloads == 0 && UnPlug2Search._defered_rules_count == 0) ? true : false;
< var info = {
< type : "progress",
< downloads : active_downloads,
< finished : (finished_ok || UnPlug2Search._stopped) ? true : false,
< percent : completed_pct / (attempted_downloads || 1)
< };
< return info;
< },
<
< toString : function () {
< return '';
< },
<
< version : 2.0 }
<
< // init
< UnPlug2Search.UnPlug2Search()
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/de-DE/common.dtd releases/unplus-2.043/source/chrome/locale/de-DE/common.dtd
1,35d0
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/de-DE/config.dtd releases/unplus-2.043/source/chrome/locale/de-DE/config.dtd
1,83d0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/de-DE/extern.dtd releases/unplus-2.043/source/chrome/locale/de-DE/extern.dtd
1,30d0
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/de-DE/overlay.dtd releases/unplus-2.043/source/chrome/locale/de-DE/overlay.dtd
1,12d0
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/de-DE/searchpage.dtd releases/unplus-2.043/source/chrome/locale/de-DE/searchpage.dtd
1,38d0
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/de-DE/strings.txt releases/unplus-2.043/source/chrome/locale/de-DE/strings.txt
1,74d0
< extensions.{unplug@compunach}.description=Download embedded media
<
< # Confirmation after clicking on "Nothing found" button
< nothing_found_send_data=Möchten Sie den Entwicklern von UnPlug Informationen über diese Webseite zukommen lassen?
<
< # Short status strings during/after clicking "Nothing found" button
< nothing_found_sending=Sended...
< nothing_found_done=Danke!
< nothing_found_failed=Fehlgeschlagen
<
< # for below the search box
< search_done=Fertig
< search_busy=Arbeitet
< search_1_active_download=1 aktiver Download
< search_n_active_downloads=# aktive Downloads
< search_no_results_yet=Keine Ergebnisse bis jetzt
< search_1_result=1 Ergebnis
< search_n_results=# Ergebnisse
< search_no_results=keine Ergebnisse
< cannot_download_this_kind=Kann diese Datei nicht herunterladen Typ
<
< # for rules.xml
< high_quality=Hohe Qualität
< low_quality= Niedrige Qualität
< mid_quality=Normale Qualität
< hd_quality=HD Qualität
< embedplayer=Eingebettetes Odjekt (vielleicht ein MediaPlayer und kein Video)
<
< # download methods
< dmethod.open-tab=In neuem Tab Öffnen
< dmethod.open-tab.a=T
< dmethod.open-tab.tip=
< dmethod.open-new=In neuem Fenster Öffnen
< dmethod.open-new.a=F
< dmethod.open-new.tip=
< dmethod.open-over=Im aktuellen Fenster Öffnen
< dmethod.open-over.a=a
< dmethod.open-over.tip=
< dmethod.saveas=Speichern als
< dmethod.saveas.a=S
< dmethod.saveas.tip=Benutze den Download Manager von Firefox.
< dmethod.dta=DownThemAll
< dmethod.dta.a=A
< dmethod.dta.tip=Download mit dem DownThemAll Addon.
< dmethod.flashgot=FlashGot
< dmethod.flashgot.a=G
< dmethod.flashgot.tip=Download mit dem FlashGot Addon.
< dmethod.copyurl=Kopiere Link
< dmethod.copyurl.a=K
< dmethod.copyurl.tip=
< dmethod.rtmpdump=Rtmpdump
< dmethod.rtmpdump.a=R
< dmethod.rtmpdump.tip=Verwenden Sie ein Software-Tool zum Download dieser Datei.
< dmethod.vlc=VLC
< dmethod.vlc.a=V
< dmethod.vlc.tip=Verwenden Sie ein Software-Tool zum Download dieser Datei.
<
< dmethod.unavailable.tip=Kein Downloader
<
< proc.status.error=Fehler
< proc.status.running=Läufen
< proc.status.done=Fertig
<
< # external download methods
< need_to_install=You need to install %s to download this file
< location_of=Location of %s
<
< extern.cancel.title=UnPlug: Cancel download
< extern.cancel.onefile=Would you like to cancel the download of %s?
< extern.cancel.manyfile=Would you like to cancel %s active downloads?
< extern.cancel.stop=Stoppen
< extern.cancel.dontstop=Nicht stoppen
< extern.cancel.deletefile=Delete partially downloaded file
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/en-US/common.dtd releases/unplus-2.043/source/chrome/locale/en-US/common.dtd
1,35d0
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/en-US/config.dtd releases/unplus-2.043/source/chrome/locale/en-US/config.dtd
1,83d0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/en-US/extern.dtd releases/unplus-2.043/source/chrome/locale/en-US/extern.dtd
1,30d0
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/en-US/overlay.dtd releases/unplus-2.043/source/chrome/locale/en-US/overlay.dtd
1,12d0
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/en-US/searchpage.dtd releases/unplus-2.043/source/chrome/locale/en-US/searchpage.dtd
1,38d0
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/en-US/strings.txt releases/unplus-2.043/source/chrome/locale/en-US/strings.txt
1,75d0
< extensions.{unplug@compunach}.description=Download embedded media
<
< # Confirmation after clicking on "Nothing found" button
< nothing_found_send_data=Would you like to send information about this webpage to the developers of UnPlug?
<
< # Short status strings during/after clicking "Nothing found" button
< nothing_found_sending=Sending...
< nothing_found_done=Thanks!
< nothing_found_failed=Failed
<
< # for below the search box
< search_done=Finished
< search_busy=Busy
< search_1_active_download=Searching 1 page
< search_n_active_downloads=Searching # pages
< search_no_results_yet=No results yet
< search_1_result=1 result
< search_n_results=# results
< search_no_results=No results
< cannot_download_this_kind=Cannot download this kind of file
<
<
< # for rules.xml
< high_quality=High quality
< low_quality=Low quality
< mid_quality=Normal quality
< hd_quality=High definition
< embedplayer=Embedded object (may be media player, not video)
<
< # download methods
< dmethod.open-tab=Open in a new tab
< dmethod.open-tab.a=t
< dmethod.open-tab.tip=Open in a new tab.
< dmethod.open-new=Open in a new window
< dmethod.open-new.a=n
< dmethod.open-new.tip=Open in a new window.
< dmethod.open-over=Open over the current window
< dmethod.open-over.a=v
< dmethod.open-over.tip=Equivalent to clicking a link to the media on the page.
< dmethod.saveas=Save as
< dmethod.saveas.a=S
< dmethod.saveas.tip=Use Firefox's default download manager.
< dmethod.dta=DownThemAll
< dmethod.dta.a=A
< dmethod.dta.tip=Download with the DownThemAll extension.
< dmethod.flashgot=FlashGot
< dmethod.flashgot.a=F
< dmethod.flashgot.tip=Download with the FlashGot extension.
< dmethod.copyurl=Copy link
< dmethod.copyurl.a=y
< dmethod.copyurl.tip=Copy media location to the clipboard.
< dmethod.rtmpdump=Rtmpdump
< dmethod.rtmpdump.a=R
< dmethod.rtmpdump.tip=Get or run rtmpdump.
< dmethod.vlc=VLC
< dmethod.vlc.a=V
< dmethod.vlc.tip=Download with VLC media player
<
< dmethod.unavailable.tip=Cannot download this file.
<
< proc.status.error=Error
< proc.status.running=Running
< proc.status.done=Done
<
< # external download methods
< need_to_install=You need to install %s to download this file
< location_of=Location of %s
<
< extern.cancel.title=UnPlug: Cancel download
< extern.cancel.onefile=Would you like to cancel the download of %s?
< extern.cancel.manyfile=Would you like to cancel %s active downloads?
< extern.cancel.stop=Stop
< extern.cancel.dontstop=Don't stop
< extern.cancel.deletefile=Delete partially downloaded file
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/fr-FR/common.dtd releases/unplus-2.043/source/chrome/locale/fr-FR/common.dtd
1,35d0
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/fr-FR/config.dtd releases/unplus-2.043/source/chrome/locale/fr-FR/config.dtd
1,83d0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/fr-FR/extern.dtd releases/unplus-2.043/source/chrome/locale/fr-FR/extern.dtd
1,30d0
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/fr-FR/overlay.dtd releases/unplus-2.043/source/chrome/locale/fr-FR/overlay.dtd
1,12d0
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/fr-FR/searchpage.dtd releases/unplus-2.043/source/chrome/locale/fr-FR/searchpage.dtd
1,38d0
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/fr-FR/strings.txt releases/unplus-2.043/source/chrome/locale/fr-FR/strings.txt
1,75d0
< extensions.{unplug@compunach}.description=Télécharger le média intégré
<
< # Confirmation after clicking on "Nothing found" button
< nothing_found_send_data=Voulez-vous envoyer des informations sur cette page web aux développeurs d'UnPlug ?
<
< # Short status strings during/after clicking "Nothing found" button
< nothing_found_sending=Envoi...
< nothing_found_done=Merci !
< nothing_found_failed=Échec
<
< # for below the search box
< search_done=Terminé
< search_busy=Occupé
< search_1_active_download=Recherche 1 page
< search_n_active_downloads=Recherche # pages
< search_no_results_yet=Pas encore de résultat
< search_1_result=1 résultat
< search_n_results=# résultats
< search_no_results=Aucun résultat
< cannot_download_this_kind=Impossible de télécharger ce type de fichier
<
<
< # for rules.xml
< high_quality=Haute qualité
< low_quality=Basse qualité
< mid_quality=Qualité normale
< hd_quality=Haute définition
< embedplayer=Objet intégré (pas une vidéo, possiblement un lecteur)
<
< # download methods
< dmethod.open-tab=Ouvrir dans un nouvel onglet
< dmethod.open-tab.a=o
< dmethod.open-tab.tip=Ouvrir dans un nouvel onglet.
< dmethod.open-new=Ouvrir dans une nouvelle fenêtre
< dmethod.open-new.a=f
< dmethod.open-new.tip=Ouvrir dans une nouvelle fenêtre.
< dmethod.open-over=Ouvrir dans la fenêtre courante
< dmethod.open-over.a=c
< dmethod.open-over.tip=Équivaut à cliquer sur un lien vers le média dans la page.
< dmethod.saveas=Enregistrer sous
< dmethod.saveas.a=s
< dmethod.saveas.tip=Utiliser le gestionnaire de téléchargement par défaut de Firefox.
< dmethod.dta=DownThemAll
< dmethod.dta.a=D
< dmethod.dta.tip=Télécharger avec l'extension DownThemAll.
< dmethod.flashgot=FlashGot
< dmethod.flashgot.a=F
< dmethod.flashgot.tip=Télécharger avec l'extension FlashGot.
< dmethod.copyurl=Copier le lien
< dmethod.copyurl.a=l
< dmethod.copyurl.tip=Copier l'emplacement du média dans le presse-papiers.
< dmethod.rtmpdump=Rtmpdump
< dmethod.rtmpdump.a=R
< dmethod.rtmpdump.tip=Obtenir ou exécuter rtmpdump.
< dmethod.vlc=VLC
< dmethod.vlc.a=V
< dmethod.vlc.tip=Obtenir ou exécuter VLC
<
< dmethod.unavailable.tip=Impossible de télécharger le fichier.
<
< proc.status.error=Erreur
< proc.status.running=En cours
< proc.status.done=Terminé
<
< # external download methods
< need_to_install=Vous devez installer %s pour télécharger le fichier.
< location_of=Emplacement de %s
<
< extern.cancel.title=UnPlug : arrêt du téléchargement
< extern.cancel.onefile=Voulez-vous interrompre le téléchargement de %s ?
< extern.cancel.manyfile=Voulez-vous interrompre %s tééchargements en cours ?
< extern.cancel.stop=Arrêter
< extern.cancel.dontstop=Ne pas arrêter
< extern.cancel.deletefile=Supprimer le fichier partiellement téléchargé
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/hu-HU/common.dtd releases/unplus-2.043/source/chrome/locale/hu-HU/common.dtd
1,35d0
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/hu-HU/config.dtd releases/unplus-2.043/source/chrome/locale/hu-HU/config.dtd
1,83d0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/hu-HU/extern.dtd releases/unplus-2.043/source/chrome/locale/hu-HU/extern.dtd
1,30d0
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/hu-HU/overlay.dtd releases/unplus-2.043/source/chrome/locale/hu-HU/overlay.dtd
1,12d0
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/hu-HU/searchpage.dtd releases/unplus-2.043/source/chrome/locale/hu-HU/searchpage.dtd
1,39d0
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/hu-HU/strings.txt releases/unplus-2.043/source/chrome/locale/hu-HU/strings.txt
1,74d0
< extensions.{unplug@compunach}.description=Beágyazott média letöltés
<
< # Confirmation after clicking on "Nothing found" button
< nothing_found_send_data=Akarsz információt küldeni az Unplug fejlesztőinek erről a weboldalról?
<
< # Short status strings during/after clicking "Nothing found" button
< nothing_found_sending=Küldés...
< nothing_found_done=Köszönet!
< nothing_found_failed=Hiba
<
< # for below the search box
< search_done=Kész
< search_busy=Dolgozik
< search_1_active_download=1 oldal keresés
< search_n_active_downloads=# oldal keresés
< search_no_results_yet=Nincs találat
< search_1_result=1 találat
< search_n_results=# találat
< search_no_results=Nincs találat
< cannot_download_this_kind=Nem lehet letölteni ezt a típusú fájlt
<
<
< # for rules.xml
< high_quality=Magas minőség
< low_quality=Alacsony minőség
< mid_quality=Normál minőség
< hd_quality=Nagy felbontás
< embedplayer=Beágyazott objektum (valószínűleg médialejátszó, nem video)
<
< # download methods
< dmethod.open-tab=Megnyitás új fülön
< dmethod.open-tab.a=f
< dmethod.open-tab.tip=Megnyitás új fülön.
< dmethod.open-new=Megnyitás új ablakban
< dmethod.open-new.a=a
< dmethod.open-new.tip=Megnyitás új ablakban.
< dmethod.open-over=Megnyitás a jelenlegi ablakban
< dmethod.open-over.a=j
< dmethod.open-over.tip=Egyenértékű a weboldalon lévő média linkjére kattintással.
< dmethod.saveas=Mentés másként
< dmethod.saveas.a=M
< dmethod.saveas.tip=A Firefox alapértelmezett letöltéskezelőjének használata.
< dmethod.dta=DownThemAll
< dmethod.dta.a=A
< dmethod.dta.tip=Letöltés a DownThemAll kiegészítővel.
< dmethod.flashgot=FlashGot
< dmethod.flashgot.a=F
< dmethod.flashgot.tip=Letöltés a FlashGot kiegészítővel.
< dmethod.copyurl=Link másolása
< dmethod.copyurl.a=L
< dmethod.copyurl.tip=Média címének másolása a vágólapra.
< dmethod.rtmpdump=Rtmpdump
< dmethod.rtmpdump.a=R
< dmethod.rtmpdump.tip=Eszköz (rtmpdump) beszerzése vagy futtatása.
< dmethod.vlc=VLC
< dmethod.vlc.a=V
< dmethod.vlc.tip=Eszköz (vlc) beszerzése vagy futtatása.
< dmethod.unavailable.tip=Nem lehet letölteni ezt a fájlt.
<
< proc.status.error=Error
< proc.status.running=Running
< proc.status.done=Done
<
< # external download methods
< need_to_install=You need to install %s to download this file
< location_of=Location of %s
<
< extern.cancel.title=UnPlug: Cancel download
< extern.cancel.onefile=Would you like to cancel the download of %s?
< extern.cancel.manyfile=Would you like to cancel %s active downloads?
< extern.cancel.stop=Leállítás
< extern.cancel.dontstop=Don't stop
< extern.cancel.deletefile=Delete partially downloaded file
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/pl-PL/common.dtd releases/unplus-2.043/source/chrome/locale/pl-PL/common.dtd
1,35d0
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/pl-PL/config.dtd releases/unplus-2.043/source/chrome/locale/pl-PL/config.dtd
1,83d0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/pl-PL/extern.dtd releases/unplus-2.043/source/chrome/locale/pl-PL/extern.dtd
1,30d0
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/pl-PL/overlay.dtd releases/unplus-2.043/source/chrome/locale/pl-PL/overlay.dtd
1,12d0
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/pl-PL/searchpage.dtd releases/unplus-2.043/source/chrome/locale/pl-PL/searchpage.dtd
1,39d0
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/pl-PL/strings.txt releases/unplus-2.043/source/chrome/locale/pl-PL/strings.txt
1,73d0
< extensions.{unplug@compunach}.description=Download embedded media
<
< # Confirmation after clicking on "Nothing found" button
< nothing_found_send_data=Czy chcesz wysłać informacje o tej stronie do deweloperów UnPlug?
<
< # Short status strings during/after clicking "Nothing found" button
< nothing_found_sending=Wysyłanie...
< nothing_found_done=Dzięki !
< nothing_found_failed=Błąd
<
< # for below the search box
< search_done=Zakończono
< search_busy=Busy
< search_1_active_download=1 aktywne pobieranie
< search_n_active_downloads=# aktywne pobierania
< search_no_results_yet=Jeszcze brak wyników
< search_1_result=1 wynik
< search_n_results=# wyników
< search_no_results=Brak wyników
< cannot_download_this_kind=Cannot download this kind of file
<
< # for rules.xml
< high_quality=Wysoka jakość
< low_quality=Niska jakość
< mid_quality=Normalna jakość
< hd_quality=High definition
< embedplayer=Osadzony objekt (prawdopodobnie odtwarzacz, nie wideo)
<
< # download methods
< dmethod.open-tab=Otwórz w nowej karcie
< dmethod.open-tab.a=k
< dmethod.open-tab.tip=
< dmethod.open-new=Otwórz w nowym oknie
< dmethod.open-new.a=n
< dmethod.open-new.tip=
< dmethod.open-over=Otwórz w tym oknie
< dmethod.open-over.a=o
< dmethod.open-over.tip=
< dmethod.saveas=Zapisz jako
< dmethod.saveas.a=Z
< dmethod.saveas.tip=Użyj wbudowanego menedżera pobrań Firefoxa.
< dmethod.dta=DownThemAll
< dmethod.dta.a=A
< dmethod.dta.tip=Pobierz rozszerzeniem DownThemAll.
< dmethod.flashgot=FlashGot
< dmethod.flashgot.a=F
< dmethod.flashgot.tip=Pobierz rozszerzeniem FlashGot.
< dmethod.copyurl=Kopiuj link
< dmethod.copyurl.a=K
< dmethod.copyurl.tip=
< dmethod.rtmpdump=Rtmpdump
< dmethod.rtmpdump.a=R
< dmethod.rtmpdump.tip=
< dmethod.vlc=VLC
< dmethod.vlc.a=V
< dmethod.vlc.tip=
<
< dmethod.unavailable.tip=No downloader
<
< proc.status.error=Error
< proc.status.running=Running
< proc.status.done=Done
<
< # external download methods
< need_to_install=You need to install %s to download this file
< location_of=Location of %s
<
< extern.cancel.title=UnPlug: Cancel download
< extern.cancel.onefile=Would you like to cancel the download of %s?
< extern.cancel.manyfile=Would you like to cancel %s active downloads?
< extern.cancel.stop=Stop
< extern.cancel.dontstop=Don't stop
< extern.cancel.deletefile=Delete partially downloaded file
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/sv-SE/common.dtd releases/unplus-2.043/source/chrome/locale/sv-SE/common.dtd
1,35d0
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/sv-SE/config.dtd releases/unplus-2.043/source/chrome/locale/sv-SE/config.dtd
1,83d0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/sv-SE/extern.dtd releases/unplus-2.043/source/chrome/locale/sv-SE/extern.dtd
1,30d0
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/sv-SE/overlay.dtd releases/unplus-2.043/source/chrome/locale/sv-SE/overlay.dtd
1,12d0
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/sv-SE/searchpage.dtd releases/unplus-2.043/source/chrome/locale/sv-SE/searchpage.dtd
1,38d0
<
<
<
<
<
<
<
<
<
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/locale/sv-SE/strings.txt releases/unplus-2.043/source/chrome/locale/sv-SE/strings.txt
1,75d0
< extensions.{unplug@compunach}.description=Ladda ner inbäddade mediefiler
<
< # Confirmation after clicking on "Nothing found" button
< nothing_found_send_data=Vill du skicka information om den här webbsidan till utvecklarna av UnPlug?
<
< # Short status strings during/after clicking "Nothing found" button
< nothing_found_sending=Skickar...
< nothing_found_done=Tusen tack!
< nothing_found_failed=Misslyckades
<
< # for below the search box
< search_done=Sökning slutförd
< search_busy=Upptagen
< search_1_active_download=Söker på 1 sida
< search_n_active_downloads=Söker på # sidor
< search_no_results_yet=Inga resultat ännu
< search_1_result=1 resultat
< search_n_results=# resultat
< search_no_results=Inga resultat
< cannot_download_this_kind=Kan inte ladda ner den här typen av fil
<
<
< # for rules.xml
< high_quality=Hög kvalitet
< low_quality=Låg kvalitet
< mid_quality=Normal kvalitet
< hd_quality=Hög upplösning
< embedplayer=Inbäddat objekt (kan vara mediespelare, inte video)
<
< # download methods
< dmethod.open-tab=Öppna i en ny flik
< dmethod.open-tab.a=f
< dmethod.open-tab.tip=Öppna i en ny flik.
< dmethod.open-new=Öppna i ett nytt fönster
< dmethod.open-new.a=n
< dmethod.open-new.tip=Öppna i ett nytt fönster.
< dmethod.open-over=Öppna över det aktuella fönstret
< dmethod.open-over.a=v
< dmethod.open-over.tip=Motsvarar att klicka på en länk till mediefilerna på sidan.
< dmethod.saveas=Spara som...
< dmethod.saveas.a=S
< dmethod.saveas.tip=Använd Firefox standardnerladdningshanterare (Filhämtaren).
< dmethod.dta=DownThemAll
< dmethod.dta.a=A
< dmethod.dta.tip=Ladda ner med tillägget DownThemAll.
< dmethod.flashgot=FlashGot
< dmethod.flashgot.a=F
< dmethod.flashgot.tip=Ladda ner med tillägget FlashGot.
< dmethod.copyurl=Kopiera länk
< dmethod.copyurl.a=p
< dmethod.copyurl.tip=Kopiera mediefilens adress till Urklipp.
< dmethod.rtmpdump=RTMPDump
< dmethod.rtmpdump.a=R
< dmethod.rtmpdump.tip=Hämta eller kör RTMPDump.
< dmethod.vlc=VLC
< dmethod.vlc.a=V
< dmethod.vlc.tip=Hämta eller kör VLC
<
< dmethod.unavailable.tip=Kan inte ladda ner den här filen.
<
< proc.status.error=Fel
< proc.status.running=Körs...
< proc.status.done=Slutförd
<
< # external download methods
< need_to_install=Du måste installera %s för att ladda ner den här filen
< location_of=Sökväg till %s
<
< extern.cancel.title=UnPlug: Cancel download
< extern.cancel.onefile=Would you like to cancel the download of %s?
< extern.cancel.manyfile=Would you like to cancel %s active downloads?
< extern.cancel.stop=Stopp
< extern.cancel.dontstop=Don't stop
< extern.cancel.deletefile=Delete partially downloaded file
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/skin/extern.css releases/unplus-2.043/source/chrome/skin/extern.css
1,37d0
<
< .process .filename {
< overflow: hidden;
< }
<
< .process .status {
< font-weight: bold;
< }
<
< .process-status-done .status {
< color: #00cc00;
< }
<
< .process-status-error .status {
< color: #cc0000;
< }
<
< .process-status-running .status {
< color: #000000;
< }
<
< button.stop {
< /* list-style-image: url("chrome://unplug/skin/tango-16/process-stop.png"); */
< }
<
< label.method {
< display: none;
< }
<
< label.size {
< width: 8em;
< }
<
< label.status {
< width: 8em;
< }
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/skin/overlay.css releases/unplus-2.043/source/chrome/skin/overlay.css
1,14d0
< toolbarbutton#unplug2_toolbarbutton {
< list-style-image : url(chrome://unplug/skin/unplug-24.png);
< }
<
< toolbar[iconsize="small"] toolbarbutton#unplug2_toolbarbutton {
< list-style-image : url(chrome://unplug/skin/unplug-16.png);
< }
<
< menuitem#unplug2_toolsmenu ,
< menuitem#unplug2_contextmenu,
< toolbarbutton#unplug2_taskbutton {
< list-style-image : url(chrome://unplug/skin/unplug-16.png);
< }
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome/skin/searchpage.css releases/unplus-2.043/source/chrome/skin/searchpage.css
1,118d0
< .unplug-result {
< }
<
< .unplug-result image.ur-thumbnail {
< width: 4.8em;
< height: 2.8em;
< border: 1px black solid;
< margin: 0.2em;
< background: #000000;
< }
<
< .unplug-result label.ur-name {
< font-weight: bold;
< }
<
< .unplug-result label.ur-protocol,
< .unplug-result label.ur-host {
< font-size: smaller;
< color: #008000;
< }
<
< .unplug-result label.ur-protocol {
< }
<
< .unplug-result label.ur-description {
< }
<
< .unplug-result.file-ext-swf,
< .unplug-result.certainty-low {
< opacity: 0.5;
< }
<
< .unplug-result .menuitem-iconic.config {
< list-style-image: url("chrome://unplug/skin/tango-16/preferences-system.png");
< }
<
< .unplug-result .menuitem-iconic.saveas {
< list-style-image: url("chrome://unplug/skin/tango-16/document-save-as.png");
< }
<
< .unplug-result .menuitem-iconic.dta {
< list-style-image: url("chrome://dta/skin/common/dta.png");
< }
<
< .unplug-result .menuitem-iconic.flashgot {
< list-style-image: url("chrome://flashgot/skin/fg1.png");
< }
<
< .unplug-result .menuitem-iconic.unavailable {
< list-style-image: url("chrome://unplug/skin/tango-16/dialog-error.png");
< }
<
< .unplug-result .menuitem-iconic.extern {
< list-style-image: url("chrome://unplug/skin/tango-16/applications-system.png");
< }
<
< .unplug-result .menuitem-iconic.copyurl {
< list-style-image: url("chrome://unplug/skin/tango-16/edit-copy.png");
< }
<
< .unplug-result .menuitem-iconic.open-tab {
< list-style-image: url("chrome://unplug/skin/tango-16/tab-new.png");
< }
<
< .unplug-result .menuitem-iconic.open-new {
< list-style-image: url("chrome://unplug/skin/tango-16/window-new.png");
< }
<
< .unplug-result .menuitem-iconic.open-over {
< list-style-image: url("chrome://unplug/skin/tango-16/window.png");
< }
<
< .unplug-result toolbarbutton > toolbarbutton > label {
< /* this aligns the label on the drop-down buttons correctly (ie: not just on the top) */
< max-height : 1em;
< }
<
< #dynamic_results.failed {
< color: #cc0000;
< font-weight: bold;
< }
<
< #stop_button {
< list-style-image: url("chrome://unplug/skin/tango-16/process-stop.png");
< }
<
< #stop_button[disabled] {
< /* greyscale; brightness + 100% */
< list-style-image: url("chrome://unplug/skin/tango-16/process-stop-disabled.png");
< }
<
< vbox.container {
< border: 1px black solid;
< margin: 0;
< padding: 0;
< }
<
< vbox.container#mediaid_none {
< /* TODO - not used */
< }
<
< .unplug-result.mediaid-best {
< }
< .unplug-result.mediaid-collapse {
< }
<
< .unplug-result.mediaid-collapse label.ur-name {
< opacity: 0.8;
< display: none;
< }
< .unplug-result.mediaid-collapse image.ur-thumbnail {
< visibility: hidden;
< }
< .unplug-result.mediaid-collapse label.ur-protocol,
< .unplug-result.mediaid-collapse label.ur-host {
< /* display: none; */
< }
<
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/applications-system.png and releases/unplus-2.043/source/chrome/skin/tango-16/applications-system.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/dialog-error.png and releases/unplus-2.043/source/chrome/skin/tango-16/dialog-error.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/document-save-as.png and releases/unplus-2.043/source/chrome/skin/tango-16/document-save-as.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/edit-copy.png and releases/unplus-2.043/source/chrome/skin/tango-16/edit-copy.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/preferences-system.png and releases/unplus-2.043/source/chrome/skin/tango-16/preferences-system.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/process-stop-disabled.png and releases/unplus-2.043/source/chrome/skin/tango-16/process-stop-disabled.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/process-stop.png and releases/unplus-2.043/source/chrome/skin/tango-16/process-stop.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/tab-new.png and releases/unplus-2.043/source/chrome/skin/tango-16/tab-new.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/window-new.png and releases/unplus-2.043/source/chrome/skin/tango-16/window-new.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-16/window.png and releases/unplus-2.043/source/chrome/skin/tango-16/window.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-32/dialog-information.png and releases/unplus-2.043/source/chrome/skin/tango-32/dialog-information.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-32/document-save-as.png and releases/unplus-2.043/source/chrome/skin/tango-32/document-save-as.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-32/mail-attachment.png and releases/unplus-2.043/source/chrome/skin/tango-32/mail-attachment.png differ
Binary files releases/unplug-2.042/source/chrome/skin/tango-32/system-search.png and releases/unplus-2.043/source/chrome/skin/tango-32/system-search.png differ
Binary files releases/unplug-2.042/source/chrome/skin/unplug-16.png and releases/unplus-2.043/source/chrome/skin/unplug-16.png differ
Binary files releases/unplug-2.042/source/chrome/skin/unplug-24.png and releases/unplus-2.043/source/chrome/skin/unplug-24.png differ
Binary files releases/unplug-2.042/source/chrome/skin/unplug-32.png and releases/unplus-2.043/source/chrome/skin/unplug-32.png differ
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/chrome.manifest releases/unplus-2.043/source/chrome.manifest
1,22d0
< content unplug chrome/content/
<
< # Firefox
< overlay chrome://browser/content/browser.xul chrome://unplug/content/overlay/firefox.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
< # SeaMonkey
< overlay chrome://navigator/content/navigator.xul chrome://unplug/content/overlay/seamonkey.xul application={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}
<
<
< skin unplug default chrome/skin/
<
< #testing
< #locale unplug en-US chrome/locale/pl-PL/
<
< locale unplug en-US chrome/locale/en-US/
< locale unplug de-DE chrome/locale/de-DE/
< locale unplug pl-PL chrome/locale/pl-PL/
< locale unplug hu-HU chrome/locale/hu-HU/
< locale unplug fr-FR chrome/locale/fr-FR/
< locale unplug sv-SE chrome/locale/sv-SE/
<
<
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/defaults/preferences/unplug2.js releases/unplus-2.043/source/defaults/preferences/unplug2.js
1,8d0
< pref("extensions.unplug2.setup_number", 0);
< pref("extensions.unplug2.add_to_contextmenu", true);
< pref("extensions.unplug2.add_to_toolsmenu", true);
< pref("extensions.unplug2.add_to_addonsbar", true);
< pref("extensions.unplug2.downloader", "auto");
< pref("extensions.unplug2.popularity_contest", false);
< pref("extensions.unplug2.show_all", false);
<
diff --new-file --recursive --suppress-common-lines --exclude changes.txt --exclude diff.txt releases/unplug-2.042/source/install.rdf releases/unplus-2.043/source/install.rdf
1,39d0
<
<
<
< Ushi (de-DE)
< DenB (fr-FR)
< Juhász Zsolt (hu-HU)
< Konradmb (pl-PL)
< Mikael Hiort af Ornäs (sv-SE)
<
<
<
< {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
< 3.0
< 4.0.*
<
<
<
<
<
< {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}
< 2.0
< 2.1b1
<
<
<
<
Binary files releases/unplug-2.042/unplug.xpi and releases/unplus-2.043/unplug.xpi differ