[Pkg-mozext-commits] [colorediffs-extension] 01/02: Imported Upstream version 0.6.2012.01.27.14.07.45
Michael Fladischer
fladi-guest at moszumanska.debian.org
Wed May 14 09:45:57 UTC 2014
This is an automated email from the git hooks/post-receive script.
fladi-guest pushed a commit to branch master
in repository colorediffs-extension.
commit 716c2474f614a9dfcedca799c32afb26babcab20
Author: Michael Fladischer <FladischerMichael at fladi.at>
Date: Mon May 20 21:18:50 2013 +0200
Imported Upstream version 0.6.2012.01.27.14.07.45
---
LICENSE | 470 ++++++++++++++++++
chrome.manifest | 5 +
.../content/colorediffs/bindings/bindings.css | 7 +
.../content/colorediffs/bindings/colorpicker.css | 9 +
.../content/colorediffs/bindings/main-bindings.xbl | 97 ++++
.../content/colorediffs/callbacks.js | 38 ++
.../content/colorediffs/colorediffs.js | 150 ++++++
.../content/colorediffs/contents.rdf | 31 ++
chrome/colorediffs.jar!/content/colorediffs/dom.js | 44 ++
.../content/colorediffs/globals.js | 151 ++++++
.../colorediffs.jar!/content/colorediffs/icon.png | Bin 0 -> 1396 bytes
.../content/colorediffs/ilUtils.js | 28 ++
.../content/colorediffs/main-overlay.xul | 102 ++++
.../content/colorediffs/msgwindowoverlay.xul | 6 +
.../colorediffs/options/context-view-options.xul | 63 +++
.../colorediffs/options/options-pref-callback.js | 32 ++
.../content/colorediffs/options/options-pref.js | 63 +++
.../content/colorediffs/options/options.css | 17 +
.../content/colorediffs/options/options.js | 207 ++++++++
.../content/colorediffs/options/options.xul | 122 +++++
.../options/side-by-side-view-options.xul | 112 +++++
.../colorediffs/options/unified-view-options.xul | 63 +++
.../content/colorediffs/overlay.js | 79 +++
.../content/colorediffs/overlay.xul | 6 +
.../content/colorediffs/parsers/context-parser.js | 160 ++++++
.../content/colorediffs/parsers/main-parser.js | 8 +
.../content/colorediffs/parsers/unified-parser.js | 551 +++++++++++++++++++++
.../colorediffs.jar!/content/colorediffs/prefs.js | 100 ++++
.../content/colorediffs/toolbar.js | 111 +++++
.../colorediffs/transformations/add-title.js | 14 +
.../colorediffs/transformations/calc-chunk-size.js | 19 +
.../transformations/collect-tab-sizes.js | 40 ++
.../colorediffs/transformations/composite-init.js | 134 +++++
.../colorediffs/transformations/composite-run.js | 89 ++++
.../transformations/composite-transformation.js | 15 +
.../transformations/detect-old-new-files.js | 23 +
.../transformations/find-common-name.js | 253 ++++++++++
.../transformations/main-transformation.js | 6 +
.../transformations/make-lines-equal-length.js | 73 +++
.../replace-file-names-transformation.js | 20 +
.../colorediffs/transformations/replace-tabs.js | 23 +
.../transformations/select-old-new-files.js | 27 +
.../transformations/show-line-numbers.js | 87 ++++
.../show-whitespaces-transformation.js | 23 +
.../transformations/truncate-file-names.js | 87 ++++
.../content/colorediffs/views/context-view.js | 243 +++++++++
.../content/colorediffs/views/main-view.js | 3 +
.../content/colorediffs/views/side-by-side-view.js | 335 +++++++++++++
.../content/colorediffs/views/unified-view.js | 219 ++++++++
chrome/colorediffs.jar!/skin/colorediffs.css | 17 +
chrome/colorediffs.jar!/skin/line-numbers.png | Bin 0 -> 342 bytes
chrome/colorediffs.jar!/skin/options.png | Bin 0 -> 325 bytes
chrome/colorediffs.jar!/skin/white-space.png | Bin 0 -> 289 bytes
defaults/preferences/colorediffs.js | 66 +++
install.rdf | 32 ++
55 files changed, 4680 insertions(+)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7714141
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,470 @@
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
diff --git a/chrome.manifest b/chrome.manifest
new file mode 100644
index 0000000..69da7da
--- /dev/null
+++ b/chrome.manifest
@@ -0,0 +1,5 @@
+content colorediffs jar:chrome/colorediffs.jar!/content/colorediffs/
+skin colorediffs classic/1.0 jar:chrome/colorediffs.jar!/skin/
+
+overlay chrome://messenger/content/messenger.xul chrome://colorediffs/content/overlay.xul
+overlay chrome://messenger/content/messageWindow.xul chrome://colorediffs/content/msgwindowoverlay.xul
diff --git a/chrome/colorediffs.jar!/content/colorediffs/bindings/bindings.css b/chrome/colorediffs.jar!/content/colorediffs/bindings/bindings.css
new file mode 100644
index 0000000..f7a97d9
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/bindings/bindings.css
@@ -0,0 +1,7 @@
+viewsmenu {
+ -moz-binding: url('chrome://colorediffs/content/bindings/main-bindings.xbl#views');
+}
+
+colorpicker {
+ -moz-binding: url('chrome://colorediffs/content/bindings/main-bindings.xbl#color-picker');
+}
diff --git a/chrome/colorediffs.jar!/content/colorediffs/bindings/colorpicker.css b/chrome/colorediffs.jar!/content/colorediffs/bindings/colorpicker.css
new file mode 100644
index 0000000..386b760
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/bindings/colorpicker.css
@@ -0,0 +1,9 @@
+.colorpickerspacer {
+ height: 12px;
+ border: 1px inset #CCCCCC;
+}
+
+.colorpickerbutton {
+ min-width: 60px;
+ margin: 1px;
+}
diff --git a/chrome/colorediffs.jar!/content/colorediffs/bindings/main-bindings.xbl b/chrome/colorediffs.jar!/content/colorediffs/bindings/main-bindings.xbl
new file mode 100644
index 0000000..5266687
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/bindings/main-bindings.xbl
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<bindings
+ xmlns="http://www.mozilla.org/xbl"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:xbl="http://www.mozilla.org/xbl">
+ <binding id="views">
+ <content>
+ <xul:menulist xbl:inherits="command,preference">
+ <xul:menupopup>
+ <xul:menuitem label="plain" value="none"/>
+ </xul:menupopup>
+ </xul:menulist>
+ </content>
+ <implementation>
+ <constructor><![CDATA[
+ var menulist = document.getAnonymousNodes(this)[0];
+ var menupopup = menulist.firstChild;
+
+ for(var view in colorediffsGlobal.views) {
+ var item = document.createElement("menuitem");
+ item.setAttribute("label", view);
+ item.setAttribute("value", view);
+ menupopup.appendChild(item);
+ }
+
+ if (menulist.hasAttribute('preference')) {
+ var pref = document.getElementById(menulist.getAttribute('preference'));
+ this.selectedItem = pref.valueFromPreferences;
+ }
+ ]]></constructor>
+ <property name="selectedItem">
+ <getter><![CDATA[
+ return document.getAnonymousNodes(this)[0].selectedItem.value;
+ ]]></getter>
+ <setter><![CDATA[
+ var menulist = document.getAnonymousNodes(this)[0];
+ var items = menulist.firstChild.childNodes;
+ for( var i=0; i < items.length; i++ ) {
+ if ( items[i].getAttribute("value") == val ) {
+ menulist.selectedItem = items[i];
+ break;
+ }
+ }
+ ]]></setter>
+ </property>
+ <property name="value">
+ <getter><![CDATA[
+ return this.selectedItem;
+ ]]></getter>
+ <setter><![CDATA[
+ this.selectedItem = val;
+ ]]></setter>
+ </property>
+ </implementation>
+ </binding>
+
+ <binding id="color-picker">
+ <resources>
+ <stylesheet src="chrome://colorediffs/content/bindings/colorpicker.css"/>
+ </resources>
+ <content>
+ <xul:button class="colorpickerbutton" xbl:inherits="preference">
+ <xul:spacer class="colorpickerspacer" flex="1"/>
+ </xul:button>
+ </content>
+ <implementation>
+ <constructor><![CDATA[
+ ]]></constructor>
+ <property name="color">
+ <getter><![CDATA[
+ return document.getAnonymousNodes(this)[0].firstChild.style.backgroundColor;
+ ]]></getter>
+ <setter><![CDATA[
+ document.getAnonymousNodes(this)[0].firstChild.style.backgroundColor = val;
+ ]]></setter>
+ </property>
+ <property name="value">
+ <getter><![CDATA[
+ return this.color;
+ ]]></getter>
+ </property>
+ </implementation>
+ <handlers>
+ <handler event="click" button="0"><![CDATA[
+ var colorObj = { NoDefault:false, Type:"Page", TextColor:0, PageColor:0, Cancel:false };
+
+ window.openDialog("chrome://editor/content/EdColorPicker.xul", "_blank", "chrome,close,titlebar,modal", "", colorObj);
+
+ if (colorObj.Cancel) {
+ return;
+ }
+
+ this.color = colorObj.BackgroundColor;
+ ]]></handler>
+ </handlers>
+ </binding>
+</bindings>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/callbacks.js b/chrome/colorediffs.jar!/content/colorediffs/callbacks.js
new file mode 100644
index 0000000..dfc164a
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/callbacks.js
@@ -0,0 +1,38 @@
+if (!colorediffsGlobal) {
+ var colorediffsGlobal = {};
+}
+
+colorediffsGlobal.tooltipCallback = function(element) {
+ var me = colorediffsGlobal;
+
+ function getTooltip() {
+ var elem = element;
+
+ while( elem && elem.nodeName.toLowerCase() != "body" && elem.nodeName.toLowerCase() != "browser" && elem.nodeName.toLowerCase() != "html" && (elem.getAttribute('title') == null || elem.getAttribute('title') == "")) {
+ elem = elem.parentNode;
+ }
+ return (elem != null)?elem.getAttribute('title'):null;
+ };
+
+ if ( me.isActive() ) {
+ var title = getTooltip();
+ if (title == "") {
+ title = null;
+ }
+
+ me.$("colorediff-tooltip").value = title;
+ return title != null;
+ } else {
+ return false;
+ }
+
+};
+
+colorediffsGlobal.scrollCallback = function(evt) {
+ var ourclass = evt.target.getAttribute('class');
+ var opositeClass = (ourclass == "left")?"right":"left";
+
+ var otherSide = evt.target.parentNode.parentNode.getElementsByClassName(opositeClass)[0];
+ otherSide.scrollLeft = evt.target.scrollLeft;
+};
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/colorediffs.js b/chrome/colorediffs.jar!/content/colorediffs/colorediffs.js
new file mode 100644
index 0000000..963be22
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/colorediffs.js
@@ -0,0 +1,150 @@
+if (!colorediffsGlobal) {
+ var colorediffsGlobal = {};
+}
+
+colorediffsGlobal.isMessageDiff = function() {
+ var content = this.getMessagePane();
+ if (!content) {
+ return false;
+ }
+
+ var messagePrefix = /^mailbox-message:|^imap-message:|^news-message:/i;
+ if ( ! messagePrefix.test(gMessageDisplay.folderDisplay.selectedMessageUris[0]) ) {
+ return false;
+ }
+
+ var message = content.contentDocument;
+ var body = message.body;
+
+ if ( !body ) {
+ return false;
+ }
+
+ var text = colorediffsGlobal.htmlToPlainText(body.innerHTML);
+
+ for each (var parser in colorediffsGlobal.parsers) {
+ if (parser.couldParse(text)) {
+ return true;
+ }
+ }
+ return false;
+};
+
+colorediffsGlobal.writeDebugFile = function(filename, html, pref) {
+ if (pref.debugDir.has()) {
+ var debugDir = pref.debugDir.get();
+ if ( debugDir != "" ) {
+ var file = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+ file.initWithPath(debugDir);
+ file.append(filename);
+
+ var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
+ .createInstance(Components.interfaces.nsIFileOutputStream);
+
+ foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+ foStream.write(html, html.length);
+ foStream.close();
+ }
+ }
+};
+
+colorediffsGlobal.onLoadMessage = function() {
+ var me = colorediffsGlobal;
+
+ var message = me.getMessagePane().contentDocument;
+ var pref = new colorediffsGlobal.Pref(colorediffsGlobal.getPrefs());
+ me.writeDebugFile("before1.html", message.documentElement.innerHTML, pref);
+
+ if (!me.isMessageDiff()) {
+ me.setActive(false);
+ me.colorediffsToolbar.initToolbar();
+ return;
+ }
+
+ me.setActive(true);
+ me.colorediffsToolbar.initToolbar();
+
+ //don't do anything if user wants plain
+ if (pref.mode.get() == 'none') {
+ return;
+ }
+
+ var body = message.body;
+
+ me.writeDebugFile("before.html", message.documentElement.innerHTML, pref);
+
+ var divs = body.getElementsByTagName("div");
+ if ( !divs ) {
+ return;
+ }
+
+ var reloadPlanned = false;
+
+ var text = me.fold(divs, function(div, text) {
+ switch(div.getAttribute("class")) {
+ case "moz-text-plain":
+ case "moz-text-flowed":
+ return text + colorediffsGlobal.stripHtml(div) + "\n\n\n";
+ case "moz-text-html":
+ //that means we're looking at HTML part of multipart mail
+ //Check if we're after reload
+ if (colorediffsGlobal.restorePreferHtmlTo === undefined) {
+ //Will try to make Thunderird reload it with text part in use.
+ colorediffsGlobal.restorePreferHtmlTo = pref.preferHtml.get();
+ pref.preferHtml.set(true);
+ ReloadMessage();
+ reloadPlanned = true;
+ } else { //ok, reloading was bad idea, but maybe html part is only log and diff is actually in attached file
+ // so let's give it a try
+ return text + colorediffsGlobal.stripHtml(div) + "\n\n\n";
+ }
+ default:
+ return text;
+ }
+ }, "");
+
+ if (reloadPlanned) {
+ return; //got to reload
+ }
+
+ //Should do it here so we can check whether we planned reload or not in the code that actually plan it.
+ if (colorediffsGlobal.restorePreferHtmlTo !== undefined) {
+ pref.preferHtml.set(colorediffsGlobal.restorePreferHtmlTo);
+ delete colorediffsGlobal.restorePreferHtmlTo;
+ }
+
+ //no luck finding a moz styled divs,
+ // let's try just stripping all html out
+ if (text == "") {
+ text = colorediffsGlobal.stripHtml(body);
+ }
+
+ me.writeDebugFile("text.html", text, pref);
+ //Choose parser
+ var il = colorediffsGlobal.parse(text, pref);
+
+ //Apply filters
+ il = colorediffsGlobal.transform(il, pref);
+
+ var dom = new colorediffsGlobal.domHelper(message);
+
+ //Generate view
+ var renderedStyleBody = colorediffsGlobal.render(il, pref, dom);
+
+ var head = message.getElementsByTagName("head")[0];
+ head.appendChild(renderedStyleBody[0]);
+
+ body.innerHTML = "";
+ body.appendChild(renderedStyleBody[1]);
+
+ me.writeDebugFile("after.html", message.documentElement.innerHTML, pref);
+
+
+ //inner functions
+ //Strip <pre wrap=""><br><hr size="4" width="90%"><br> tags from every div
+ function stripThunderbirdGeneratedHtml(html) {
+ return html.replace(/^<pre .*?>(?:<br>(?:<hr .*?>|<fieldset .*?>.*?<\/fieldset>)<br>)?((?:.|\n)*)<\/pre>$/i, "$1");
+ }
+};
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/contents.rdf b/chrome/colorediffs.jar!/content/colorediffs/contents.rdf
new file mode 100644
index 0000000..70b9125
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/contents.rdf
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+
+ <RDF:Seq about="urn:mozilla:package:root">
+ <RDF:li resource="urn:mozilla:package:colorediffs"/>
+ </RDF:Seq>
+
+ <RDF:Description about="urn:mozilla:package:colorediffs"
+ chrome:displayName="Colored Diffs"
+ chrome:name="colorediffs">
+ </RDF:Description>
+
+
+ <!-- overlay information -->
+ <RDF:Seq about="urn:mozilla:overlays">
+ <RDF:li resource="chrome://messenger/content/messenger.xul"/>
+ <RDF:li resource="chrome://messenger/content/messageWindow.xul"/>
+ </RDF:Seq>
+
+
+ <RDF:Seq about="chrome://messenger/content/messenger.xul">
+ <RDF:li>chrome://colorediffs/content/overlay.xul</RDF:li>
+ </RDF:Seq>
+
+ <RDF:Seq about="chrome://messenger/content/messageWindow.xul">
+ <RDF:li>chrome://colorediffs/content/msgwindowoverlay.xul</RDF:li>
+ </RDF:Seq>
+
+</RDF:RDF>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/dom.js b/chrome/colorediffs.jar!/content/colorediffs/dom.js
new file mode 100644
index 0000000..e80e419
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/dom.js
@@ -0,0 +1,44 @@
+colorediffsGlobal.domHelper = function(doc) {
+
+ function addElements(element, start_index, array) {
+ var length = array.length;
+ for(var i = start_index; i < length; ++i) {
+ var arg = array[i];
+ switch(typeof arg) {
+ case "string":
+ element.innerHTML += arg;
+ break;
+ case "object":
+ if (arg instanceof Element) {
+ element.appendChild(arg);
+ } else if (arg instanceof Array) {
+ arguments.callee(element, 0, arg);
+ }
+ break;
+ case "function":
+ var res = arg();
+ if ( res != null ) {
+ element.appendChild(res);
+ }
+ break;
+ }
+ }
+ }
+
+ this.createElement = function(tag, attributes) {
+ var element = doc.createElement(tag);
+ for (var attribute in attributes) {
+ element.setAttribute(attribute, attributes[attribute]);
+ }
+
+ addElements(element, 2, arguments);
+
+ return element;
+ };
+
+ this.createDocumentFragment = function() {
+ var element = doc.createDocumentFragment();
+ addElements(element, 0, arguments);
+ return element;
+ };
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/globals.js b/chrome/colorediffs.jar!/content/colorediffs/globals.js
new file mode 100644
index 0000000..f24693f
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/globals.js
@@ -0,0 +1,151 @@
+if (!colorediffsGlobal) {
+ var colorediffsGlobal = {
+ parsers:{},
+ transformations:{},
+ views:{}
+ };
+}
+
+colorediffsGlobal.$ = function(id) {
+ return document.getElementById(id);
+};
+
+colorediffsGlobal.$R = function(f) {
+ return f();
+};
+
+colorediffsGlobal.getMessagePane = function() {
+ if (!this.gmessagePane) {
+ this.gmessagePane = this.$("messagepane");
+ }
+
+ return this.gmessagePane;
+};
+
+colorediffsGlobal.isActive = function(m) {
+ var node = colorediffsGlobal.$("colorediff-mode");
+ if ( node ) {
+ return node.value;
+ } else {
+ return false;
+ }
+};
+
+colorediffsGlobal.setActive = function(m) {
+ colorediffsGlobal.$("colorediff-mode").value = m;
+};
+
+colorediffsGlobal.pad = function(string, l, s) {
+ if (!s) s = " ";
+
+ if ( string.length < l ) {
+ var padding = new Array(Math.ceil((l - string.length)/s.length) + 1);
+
+ return string.concat(padding.join(s));
+ } else {
+ return string;
+ }
+};
+
+colorediffsGlobal.isUpperCaseLetter = function(c) {
+ return /^[A-Z]$/.test(c);
+};
+
+colorediffsGlobal.getPrefs = function() {
+ return Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+};
+
+colorediffsGlobal.htmlToPlainText = function(html) {
+ var texts = html.split(/(<\/?[^>]+>)/);
+ var text = texts.map(function(string) {
+ if (string.length > 0 && string[0] == '<') {
+ //replace smileys
+ var regExpRes = string.match(/^<img.*?alt\s*=\s*['"](.*)["']/i);
+ if (regExpRes) {
+ return regExpRes[1];
+ } else {
+ return "";
+ }
+ } else {
+ //return string;
+ return string.replace(/&([^;]+);/g, function(str, p1) {
+ switch (p1) {
+ case "nbsp": return " ";
+ case "amp": return "&";
+ case "lt": return "<";
+ case "gt": return ">";
+ case "quot": return '"';
+ }
+ return " ";
+ });
+ }
+ }).join("");
+
+ return text;
+};
+
+colorediffsGlobal.outerHtml = function(dom_node, innerHtml) {
+ var html = "<" + dom_node.tagName;
+ if (dom_node.hasAttributes()) {
+ var attributes = dom_node.attributes;
+ var attributes_length = attributes.length;
+ for (let i = 0; i < attributes_length; i++) {
+ var attribute = attributes[i];
+ html += ' ' + attribute.name + '="' + attribute.value.replace('"', '\\"') + '"';
+ }
+ }
+ html += '>' + innerHtml + '</' + dom_node.tagName + '>';
+ return html;
+};
+
+colorediffsGlobal.stripHtml = function(dom_node) {
+ if (dom_node.nodeName == "#text") {
+ return colorediffsGlobal.escapeHTML(dom_node.textContent);
+ } else if (dom_node.nodeType == 1) {
+ var klass = dom_node.getAttribute("class");
+ var text = colorediffsGlobal.stripHtmlList(dom_node.childNodes);
+ if (klass != null && (klass.indexOf('moz-txt-link') == 0 || klass.indexOf('moz-smiley') == 0)) {
+ text = colorediffsGlobal.outerHtml(dom_node, text);
+ }
+ return text;
+ } else {
+ //it's not a real dom node, comment of something similar.
+ // better to ignore it
+ return "";
+ }
+};
+
+colorediffsGlobal.stripHtmlList = function(dom_node_list) {
+ var text = "";
+ var nodes_length = dom_node_list.length;
+ for (let i = 0; i < nodes_length; i++) {
+ text += colorediffsGlobal.stripHtml(dom_node_list[i]);
+ }
+ return text;
+};
+
+colorediffsGlobal.escapeHTML = function(text) {
+ text = text.replace("&", "&", "g");
+ text = text.replace("<", "<", "g");
+ text = text.replace(">", ">", "g");
+ text = text.replace('"', """, "g");
+ return text;
+};
+
+colorediffsGlobal.unescapeHTML = function(text) {
+ text = text.replace("&", "&", "g");
+ text = text.replace("<", "<", "g");
+ text = text.replace(">", ">", "g");
+ text = text.replace(""", '"', "g");
+ text = text.replace(" ", ' ', "g");
+ return text;
+};
+
+colorediffsGlobal.fold = function(a, fun, o) {
+ var l = a.length;
+ for (var i=0; i < l; ++i) {
+ o = fun(a[i], o);
+ }
+ return o;
+};
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/icon.png b/chrome/colorediffs.jar!/content/colorediffs/icon.png
new file mode 100644
index 0000000..b494d79
Binary files /dev/null and b/chrome/colorediffs.jar!/content/colorediffs/icon.png differ
diff --git a/chrome/colorediffs.jar!/content/colorediffs/ilUtils.js b/chrome/colorediffs.jar!/content/colorediffs/ilUtils.js
new file mode 100644
index 0000000..3de8de5
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/ilUtils.js
@@ -0,0 +1,28 @@
+colorediffsGlobal.ilUtils = {
+ chunksMap: function (file, func) {
+ var result = [];
+ var l = 0;
+ if ( file['new'] && file['new'].chunks ) {
+ l = Math.max(l, file['new'].chunks.length);
+ } else if ( file['old'] && file['old'].chunks ) {
+ l = Math.max(l, file['old'].chunks.length);
+ }
+
+ for (var i = 0; i < l; i++) {
+ var old_chunk = null;
+ if ( file['old'] && file['old'].chunks && file['old'].chunks[i] ) {
+ old_chunk = file['old'].chunks[i];
+ }
+
+ var new_chunk = null;
+ if ( file['new'] && file['new'].chunks && file['new'].chunks[i] ) {
+ new_chunk = file['new'].chunks[i];
+ }
+
+
+ result.push(func(old_chunk, new_chunk));
+ }
+
+ return result;
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/main-overlay.xul b/chrome/colorediffs.jar!/content/colorediffs/main-overlay.xul
new file mode 100644
index 0000000..b1937ae
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/main-overlay.xul
@@ -0,0 +1,102 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://colorediffs/content/bindings/bindings.css" type="text/css"?>
+
+<overlay id="main-colorediffs" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/globals.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/prefs.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/overlay.js"/>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/dom.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/ilUtils.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/callbacks.js"/>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/parsers/unified-parser.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/parsers/context-parser.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/parsers/main-parser.js"/>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/composite-transformation.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/composite-init.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/composite-run.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/add-title.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/strip-html.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/find-common-name.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/detect-old-new-files.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/select-old-new-files.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/truncate-file-names.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/make-lines-equal-length.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/replace-file-names-transformation.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/replace-tabs.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/show-whitespaces-transformation.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/show-line-numbers.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/collect-tab-sizes.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/calc-chunk-size.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/main-transformation.js"/>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/views/side-by-side-view.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/views/unified-view.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/views/context-view.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/views/main-view.js"/>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/colorediffs.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/toolbar.js"/>
+
+ <vbox id="messagepanebox">
+ <toolbar id="colorediffs-toolbar" toolbarname="Colorediffs Toolbar"
+ class="chromeclass-toolbar" customizable="true" insertafter="msgHeaderView" hidden="true">
+ <toolbaritem>
+ <viewsmenu id="colorediffs-view-mode" command="cmd_change_mode"/>
+ </toolbaritem>
+ <toolbarbutton id="colorediffs-show-line-numbers" tooltiptext="Show/hide line numbers"
+ command="cmd_change_line_numbers_mode" checked="false"/>
+ <toolbarbutton id="colorediffs-show-whitespaces" tooltiptext="Show/hide whitespace chars"
+ command="cmd_change_white_spaces_mode" checked="false"/>
+ <toolbaritem>
+ <menulist tooltiptext="Tune what should be shown" id="colorediffs-diff-mode" command="cmd_change_diff_mode">
+ <menupopup>
+ <menuitem label="both" value="both"/>
+ <menuitem label="new" value="new"/>
+ <menuitem label="old" value="old"/>
+ </menupopup>
+ </menulist>
+ </toolbaritem>
+ <toolbarbutton id="colorediffs-options" tooltiptext="Show options dialog"
+ command="cmd_show_options"/>
+ <toolbaritem>
+ <menulist tooltiptext="Tab size" id="colorediffs-tab-size" command="cmd_change_tab_size">
+ <menupopup>
+ <menuitem label="2" value="2"/>
+ <menuitem label="4" value="4"/>
+ <menuitem label="8" value="8"/>
+ </menupopup>
+ </menulist>
+ </toolbaritem>
+ <toolbarbutton id="colorediffs-close-toolbar" tooltiptext="Hide toolbar"
+ command="cmd_change_toolbar"/>
+ </toolbar>
+ </vbox>
+
+ <window id="messengerWindow">
+ <commands>
+ <command id="cmd_change_mode" oncommand="colorediffsGlobal.colorediffsToolbar.selectMode();"/>
+ <command id="cmd_change_white_spaces_mode" oncommand="colorediffsGlobal.colorediffsToolbar.toggleWhiteSpaces();"/>
+ <command id="cmd_change_line_numbers_mode" oncommand="colorediffsGlobal.colorediffsToolbar.toggleLineNumbers();"/>
+ <command id="cmd_show_options" oncommand="colorediffsGlobal.colorediffsToolbar.showOptions();"/>
+ <command id="cmd_change_diff_mode" oncommand="colorediffsGlobal.colorediffsToolbar.selectDiffMode();"/>
+ <command id="cmd_change_tab_size" oncommand="colorediffsGlobal.colorediffsToolbar.selectTabSize();"/>
+ <command id="cmd_change_toolbar" oncommand="colorediffsGlobal.colorediffsToolbar.closeToolbar();"/>
+ </commands>
+
+ <broadcasterset>
+ <broadcaster id="colorediff-mode" value="true"/>
+ </broadcasterset>
+
+ <popupset>
+ <tooltip id="colorediffs-mytooltip-wrapper" orient="vertical" style="background-color: #33DD00;" onpopupshowing="return colorediffsGlobal.tooltipCallback(document.tooltipNode);">
+ <label id="colorediff-tooltip"/>
+ </tooltip>
+ </popupset>
+ </window>
+
+ <browser id="messagepane" tooltip="colorediffs-mytooltip-wrapper"/>
+</overlay>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/msgwindowoverlay.xul b/chrome/colorediffs.jar!/content/colorediffs/msgwindowoverlay.xul
new file mode 100644
index 0000000..354b3f9
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/msgwindowoverlay.xul
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://colorediffs/skin/colorediffs.css" type="text/css"?>
+<?xul-overlay href="chrome://colorediffs/content/main-overlay.xul"?>
+
+<overlay id="msgwindowoverlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+</overlay>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/options/context-view-options.xul b/chrome/colorediffs.jar!/content/colorediffs/options/context-view-options.xul
new file mode 100644
index 0000000..93cb84a
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/options/context-view-options.xul
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://colorediffs/content/bindings.css" type="text/css"?>
+<?xul-overlay href="chrome://colorediffs/content/main-overlay.xul"?>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <deck id="view-properties">
+ <preferences>
+ <preference id="c_title-fg-pref" name="diffColorer.c_title_fg" type="string"/>
+ <preference id="c_title-bg-pref" name="diffColorer.c_title_bg" type="string"/>
+ <preference id="c_deletedLine-fg-pref" name="diffColorer.c_deletedLine_fg" type="string"/>
+ <preference id="c_deletedLine-bg-pref" name="diffColorer.c_deletedLine_bg" type="string"/>
+ <preference id="c_addedLine-fg-pref" name="diffColorer.c_addedLine_fg" type="string"/>
+ <preference id="c_addedLine-bg-pref" name="diffColorer.c_addedLine_bg" type="string"/>
+ <preference id="c_steadyLine-fg-pref" name="diffColorer.c_steadyLine_fg" type="string"/>
+ <preference id="c_steadyLine-bg-pref" name="diffColorer.c_steadyLine_bg" type="string"/>
+ <preference id="c_anchor-fg-pref" name="diffColorer.c_anchor_fg" type="string"/>
+ <preference id="c_anchor-bg-pref" name="diffColorer.c_anchor_bg" type="string"/>
+ <preference id="c_precode-fg-pref" name="diffColorer.c_precode_fg" type="string"/>
+ <preference id="c_precode-bg-pref" name="diffColorer.c_precode_bg" type="string"/>
+ </preferences>
+
+ <grid id="context-view-options" flex="1">
+ <columns>
+ <column/>
+ <column class="pickercolumn"/>
+ <column class="pickercolumn"/>
+ </columns>
+ <rows>
+ <row class="center"><spacer/></row>
+ <row align="center">
+ <label value="Title:"/>
+ <colorpicker id="title_fg" preference="c_title-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="title_bg" preference="c_title-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Deleted Lines:"/>
+ <colorpicker id="deletedLine_fg" preference="c_deletedLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="deletedLine_bg" preference="c_deletedLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Added Lines:"/>
+ <colorpicker id="addedLine_fg" preference="c_addedLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="addedLine_bg" preference="c_addedLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Steady Lines:"/>
+ <colorpicker id="steadyLine_fg" preference="c_steadyLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="steadyLine_bg" preference="c_steadyLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Anchors:"/>
+ <colorpicker id="anchor_fg" preference="c_anchor-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="anchor_bg" preference="c_anchor-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Precode:"/>
+ <colorpicker id="precode_fg" preference="c_precode-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="precode_bg" preference="c_precode-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ </rows>
+ </grid>
+ </deck>
+</overlay>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/options/options-pref-callback.js b/chrome/colorediffs.jar!/content/colorediffs/options/options-pref-callback.js
new file mode 100644
index 0000000..d1fa162
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/options/options-pref-callback.js
@@ -0,0 +1,32 @@
+colorediffsGlobal.OptionsPrefCallbackModel = function(prefModel, callback) {
+ this.getBoolPref = function(prop) {
+ return prefModel.getBoolPref(prop);
+ };
+
+ this.setBoolPref = function(prop, value) {
+ prefModel.setBoolPref(prop, value);
+ callback();
+ };
+
+ this.getIntPref = function(prop) {
+ return prefModel.getIntPref(prop);
+ };
+
+ this.setIntPref = function(prop, value) {
+ prefModel.setIntPref(prop, value);
+ callback();
+ };
+
+ this.getCharPref = function(prop) {
+ return prefModel.getCharPref(prop);
+ };
+
+ this.setCharPref = function(prop, value) {
+ prefModel.setCharPref(prop, value);
+ callback();
+ };
+
+ this.prefHasUserValue = function(prop) {
+ return prefModel.prefHasUserValue(prop);
+ };
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/options/options-pref.js b/chrome/colorediffs.jar!/content/colorediffs/options/options-pref.js
new file mode 100644
index 0000000..491eae0
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/options/options-pref.js
@@ -0,0 +1,63 @@
+if (!colorediffsGlobal) {
+ colorediffsGlobal = {};
+}
+
+colorediffsGlobal.OptionsPrefModel = function(prefModel) {
+ var boolPrefs = {};
+ var charPrefs = {};
+ var intPrefs = {};
+
+ var getPref = function(hash, prop, defFunc) {
+ return (hash[prop] != undefined) ? hash[prop] : defFunc(prop);
+ };
+
+ var setPref = function(hash, prop, value) {
+ hash[prop] = value;
+ };
+
+ var hasPref = function(prop) {
+ return boolPrefs[prop] != undefined || charPrefs[prop] != undefined || intPrefs[prop] != undefined;;
+ };
+
+ this.getBoolPref = function(prop) {
+ return getPref(boolPrefs, prop, prefModel.getBoolPref);
+ };
+
+ this.setBoolPref = function(prop, value) {
+ setPref(boolPrefs, prop, value);
+ };
+
+ this.getIntPref = function(prop) {
+ return getPref(intPrefs, prop, prefModel.getIntPref);
+ };
+
+ this.setIntPref = function(prop, value) {
+ setPref(intPrefs, prop, value);
+ };
+
+ this.getCharPref = function(prop) {
+ return getPref(charPrefs, prop, prefModel.getCharPref);
+ };
+
+ this.setCharPref = function(prop, value) {
+ setPref(charPrefs, prop, value);
+ };
+
+ this.prefHasUserValue = function(prop) {
+ return hasPref(prop) || prefModel.prefHasUserValue(prop);
+ };
+
+ this.saveToModel = function() {
+ for (var b in boolPrefs) {
+ prefModel.setBoolPref(b, boolPrefs[b]);
+ }
+
+ for (var c in charPrefs) {
+ prefModel.setCharPref(c, charPrefs[c]);
+ }
+
+ for (var i in intPrefs) {
+ prefModel.setIntPref(c, intPrefs[i]);
+ }
+ };
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/options/options.css b/chrome/colorediffs.jar!/content/colorediffs/options/options.css
new file mode 100644
index 0000000..4023d68
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/options/options.css
@@ -0,0 +1,17 @@
+#previewbox {
+ background-color:white;
+ border: 1px inset ThreedShadow;
+ padding: 5px;
+ height:8em;
+ width:30em;
+}
+
+.center {
+ text-align:center;
+}
+
+.pickercolumn {
+ width:5em;
+}
+
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/options/options.js b/chrome/colorediffs.jar!/content/colorediffs/options/options.js
new file mode 100644
index 0000000..b601810
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/options/options.js
@@ -0,0 +1,207 @@
+if (!colorediffsGlobal) {
+ var colorediffsGlobal = {}
+}
+
+colorediffsGlobal.initOptions = function() {
+ var me = colorediffsGlobal;
+
+ var globalPrefs = new colorediffsGlobal.Pref(colorediffsGlobal.getPrefs());
+
+ if ( globalPrefs.instantApply.get() ) {
+ //repaint all the instances at every change.
+ var internalPrefs = new colorediffsGlobal.OptionsPrefCallbackModel(
+ colorediffsGlobal.getPrefs(),
+ function() {
+ updatePreview();
+ //repaint actual mail message
+ var observerService =
+ Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService);
+ observerService.notifyObservers(null, "colored-diff-update", null);
+ });
+ } else {
+ //Store changes and commit them only by OK button.
+ //Repaint only preview
+ var cachedPrefs = new colorediffsGlobal.OptionsPrefModel(colorediffsGlobal.getPrefs());
+
+ var internalPrefs = new colorediffsGlobal.OptionsPrefCallbackModel(
+ cachedPrefs,
+ function() {
+ updatePreview();
+ });
+ }
+
+ var prefs = new colorediffsGlobal.Pref(internalPrefs);
+
+ var getNodeGetter = function (name) {
+ return function() {return me.$(name);}
+ }
+
+ var getViewModeNode = getNodeGetter('view_mode');
+ var getViewNode = getNodeGetter('view');
+ var getPreviewNode = getNodeGetter('previewbox');
+
+ var savePrefs = function() {
+ if (cachedPrefs) {
+ cachedPrefs.saveToModel();
+
+ //repaint actual mail message
+ var observerService =
+ Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService);
+ observerService.notifyObservers(null, "colored-diff-update", null);
+ } //else everything is saved and updated already
+ }
+
+ var updatePreview = function() {
+ if (prefs.mode.get() == "none") {
+ var code = "" + <r><![CDATA[
+<pre>
+Log message
+
+File title
+===============================
+--- filename
++++ filename
+@@ -10,4 +10,5 @@
+ line1
+ line2
+ line3
++line4
+ line5
+</pre>
+]]></r>;
+
+
+ var doc = getPreviewNode().contentDocument;
+ var head = doc.getElementsByTagName("head")[0];
+ head.innerHTML = "";
+
+ var body = doc.getElementsByTagName("body")[0];
+ body.innerHTML = code;
+
+ } else {
+ var status = ["S", "S", "S", "A", "S"];
+
+ var il = {
+ log:"Log message",
+ files:[
+ {title: "File title",
+ additional_info:null,
+ 'old': {
+ name: "filename",
+ chunks: [
+ {line:10,
+ code:[
+ " line1",
+ " line2",
+ " line3",
+ null,
+ " line5"],
+ status: status,
+ doesnt_have_new_line:false}]
+ },
+ 'new': {
+ name: "filename",
+ chunks: [
+ {line:10,
+ code:[
+ " line1",
+ " line2",
+ " line3",
+ " line4",
+ " line5"],
+ status: status,
+ doesnt_have_new_line:false}]
+ }}]};
+
+ var doc = getPreviewNode().contentDocument;
+ var dom = new colorediffsGlobal.domHelper(doc);
+
+ //Apply filters
+ var il = colorediffsGlobal.transform(il, prefs);
+
+ //Generate view
+ var renderedStyleBody = colorediffsGlobal.render(il, prefs, dom);
+
+ var head = doc.getElementsByTagName("head")[0];
+ head.innerHTML = "";
+ head.appendChild(renderedStyleBody[0]);
+
+ var body = doc.getElementsByTagName("body")[0];
+ body.innerHTML = "";
+ body.appendChild(renderedStyleBody[1]);
+ }
+ }
+
+ colorediffsGlobal.options = {
+ checkOptions : function() {
+ savePrefs();
+ return true;
+ },
+
+ onChangeMode : function() {
+ var deck = me.$("view-properties");
+
+ if (getViewNode().selectedItem == "none") {
+ deck.selectedIndex = 0;
+ } else {
+ var view = me.views[getViewNode().selectedItem];
+
+ //change options page
+ var children = deck.childNodes;
+ var l = children.length;
+
+ for (var i=1; i <l; i++) {
+ if (children[i].id == view.getPropertyPageId()) {
+ deck.selectedIndex = i;
+ break;
+ }
+ }
+ }
+
+ window.sizeToContent();
+ },
+
+ //new code
+ changePref: function(control) {
+ var pref = document.getElementById(control.getAttribute('preference'));
+
+ if (control.value != undefined) {
+ var value = control.value;
+ } else if (control.checked != undefined) {
+ var value = control.checked;
+ } else if (control.color != undefined) {
+ var value = control.color;
+ } else if (control.selectedItem != undefined) {
+ var value = control.selectedItem;
+ }
+
+ switch (pref.type) {
+ case "bool":
+ internalPrefs.setBoolPref(pref.name, value);
+ break;
+ case "string":
+ internalPrefs.setCharPref(pref.name, value);
+ break;
+ }
+ }
+
+ }
+
+ getPreviewNode().contentWindow.setTimeout(function() {
+ if (getPreviewNode().contentDocument.getElementsByTagName("body")[0].innerHTML == "") {
+ updatePreview();
+ }
+ getPreviewNode().contentWindow.setTimeout(arguments.callee, 1000);
+ }, 1000);
+
+ //init code
+ updatePreview();
+ colorediffsGlobal.options.onChangeMode();
+}
+
+colorediffsGlobal.deleteOptions = function() {
+ colorediffsGlobal.options = null;
+}
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/options/options.xul b/chrome/colorediffs.jar!/content/colorediffs/options/options.xul
new file mode 100644
index 0000000..eb1b9fd
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/options/options.xul
@@ -0,0 +1,122 @@
+<?xml version="1.0"?>
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://colorediffs/content/options/options.css" type="text/css"?>
+<?xml-stylesheet href="chrome://colorediffs/content/bindings/bindings.css" type="text/css"?>
+
+<?xul-overlay href="chrome://colorediffs/content/options/unified-view-options.xul"?>
+<?xul-overlay href="chrome://colorediffs/content/options/context-view-options.xul"?>
+<?xul-overlay href="chrome://colorediffs/content/options/side-by-side-view-options.xul"?>
+
+<prefwindow xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ id="settings"
+ onload="colorediffsGlobal.initOptions();"
+ persist="width height screenX screenY sizemode"
+ ondialogaccept="colorediffsGlobal.options.checkOptions();colorediffsGlobal.deleteOptions();"
+ ondialogcancel="colorediffsGlobal.deleteOptions();"
+ title="Colored Diffs"
+ width = "1000">
+
+ <prefpane id="colorediffsSettingsPane" style = "width:200em">
+ <preferences>
+ <preference id="show-whitespace" name="diffColorer.show-whitespace" type="bool" instantApply="false"/>
+ <preference id="show-line-numbers" name="diffColorer.show-line-numbers" type="bool" instantApply="false"/>
+ <preference id="show-toolbar" name="diffColorer.show-toolbar" type="bool"/>
+ <preference id="view-mode-pref" name="diffColorer.view-mode" type="string"/>
+ </preferences>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/globals.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/prefs.js"/>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/composite-transformation.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/composite-init.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/composite-run.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/find-common-name.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/strip-html.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/detect-old-new-files.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/select-old-new-files.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/truncate-file-names.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/make-lines-equal-length.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/add-title.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/replace-file-names-transformation.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/replace-tabs.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/show-whitespaces-transformation.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/show-line-numbers.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/collect-tab-sizes.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/calc-chunk-size.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/transformations/main-transformation.js"/>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/views/side-by-side-view.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/views/unified-view.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/views/context-view.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/views/main-view.js"/>
+
+ <script type="application/x-javascript" src="chrome://colorediffs/content/options/options-pref.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/options/options-pref-callback.js"/>
+ <script type="application/x-javascript" src="chrome://colorediffs/content/options/options.js"/>
+
+ <commands>
+ <command id="cmd_change_mode" oncommand="colorediffsGlobal.options.changePref(event.explicitOriginalTarget);colorediffsGlobal.options.onChangeMode();"/>
+ <command id="cmd_change_color" oncommand="updatePreview();"/>
+ <command id="cmd_change_pref" oncommand="colorediffsGlobal.options.changePref(event.explicitOriginalTarget);"/>
+ </commands>
+
+ <broadcasterset>
+ <broadcaster id="view_mode" value="unified"/>
+ </broadcasterset>
+
+ <!--this is the nice way to set style to multiple controls-->
+ <!--all the controls should work this way but I don't have time to do this now-->
+ <broadcasterset>
+ <broadcaster id="sbs_steadyLine" style=""/>
+ <broadcaster id="sbs_addedLine" style=""/>
+ </broadcasterset>
+
+ <hbox style = "width:200em">
+ <tabbox>
+ <tabs>
+ <tab label="Views"/>
+ <tab label="General options"/>
+ </tabs>
+ <tabpanels>
+ <tabpanel>
+ <groupbox>
+ <caption>
+ <label value="Choose view:"/>
+ <viewsmenu id="view" command="cmd_change_mode" preference="view-mode-pref"/>
+ </caption>
+ <hbox align="center">
+ <spacer flex="1"/>
+ <deck id="view-properties">
+ <box id="plan-view-options"/>
+ </deck>
+ </hbox>
+ <spacer style="margin-top:10px"/>
+ </groupbox>
+ </tabpanel>
+ <tabpanel>
+ <hbox align="baseline">
+ <vbox>
+ <checkbox id="show-whitespaces" label="Show whitespaces" checked="false" command="cmd_change_pref" preference="show-whitespace"/>
+ <checkbox id="show-line-numbers" label="Show line numbers" checked="false" command="cmd_change_pref" preference="show-line-numbers"/>
+ </vbox>
+ <checkbox id="show-toolbar" label="Show toolbar" checked="false" command="cmd_change_pref" preference="show-toolbar"/>
+ </hbox>
+ </tabpanel>
+ </tabpanels>
+ </tabbox>
+ <spacer/>
+ <vbox style="width:50em">
+ <deck>
+ <box/>
+ <tab/>
+ </deck>
+ <browser
+ onload="colorediffsGlobal.options.onChangeMode();"
+ id="previewbox" flex="1"/>
+ </vbox>
+ </hbox>
+ <spacer flex="1" style="height:5px;"/>
+ </prefpane>
+</prefwindow>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/options/side-by-side-view-options.xul b/chrome/colorediffs.jar!/content/colorediffs/options/side-by-side-view-options.xul
new file mode 100644
index 0000000..cc37200
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/options/side-by-side-view-options.xul
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://colorediffs/content/bindings.css" type="text/css"?>
+<?xul-overlay href="chrome://colorediffs/content/main-overlay.xul"?>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <deck id="view-properties">
+ <preferences>
+ <preference id="sbs_log-fg-pref" name="diffColorer.sbs_log_fg" type="string"/>
+ <preference id="sbs_log-bg-pref" name="diffColorer.sbs_log_bg" type="string"/>
+ <preference id="sbs_precode-fg-pref" name="diffColorer.sbs_precode_fg" type="string"/>
+ <preference id="sbs_precode-bg-pref" name="diffColorer.sbs_precode_bg" type="string"/>
+ <preference id="sbs_left-title-fg-pref" name="diffColorer.sbs_left-title_fg" type="string"/>
+ <preference id="sbs_left-title-bg-pref" name="diffColorer.sbs_left-title_bg" type="string"/>
+ <preference id="sbs_right-title-fg-pref" name="diffColorer.sbs_right-title_fg" type="string"/>
+ <preference id="sbs_right-title-bg-pref" name="diffColorer.sbs_right-title_bg" type="string"/>
+ <preference id="sbs_file-diff-fg-pref" name="diffColorer.sbs_file-diff_fg" type="string"/>
+ <preference id="sbs_file-diff-bg-pref" name="diffColorer.sbs_file-diff_bg" type="string"/>
+ <preference id="sbs_left-fg-pref" name="diffColorer.sbs_left_fg" type="string"/>
+ <preference id="sbs_left-bg-pref" name="diffColorer.sbs_left_bg" type="string"/>
+ <preference id="sbs_right-fg-pref" name="diffColorer.sbs_right_fg" type="string"/>
+ <preference id="sbs_right-bg-pref" name="diffColorer.sbs_right_bg" type="string"/>
+ <preference id="sbs_emptyLine-fg-pref" name="diffColorer.sbs_emptyLine_fg" type="string"/>
+ <preference id="sbs_emptyLine-bg-pref" name="diffColorer.sbs_emptyLine_bg" type="string"/>
+ <preference id="sbs_title-fg-pref" name="diffColorer.sbs_title_fg" type="string"/>
+ <preference id="sbs_title-bg-pref" name="diffColorer.sbs_title_bg" type="string"/>
+ <preference id="sbs_deletedLine-fg-pref" name="diffColorer.sbs_deletedLine_fg" type="string"/>
+ <preference id="sbs_deletedLine-bg-pref" name="diffColorer.sbs_deletedLine_bg" type="string"/>
+ <preference id="sbs_addedLine-fg-pref" name="diffColorer.sbs_addedLine_fg" type="string"/>
+ <preference id="sbs_addedLine-bg-pref" name="diffColorer.sbs_addedLine_bg" type="string"/>
+ <preference id="sbs_steadyLine-fg-pref" name="diffColorer.sbs_steadyLine_fg" type="string"/>
+ <preference id="sbs_steadyLine-bg-pref" name="diffColorer.sbs_steadyLine_bg" type="string"/>
+ <preference id="sbs_anchor-fg-pref" name="diffColorer.sbs_anchor_fg" type="string"/>
+ <preference id="sbs_anchor-bg-pref" name="diffColorer.sbs_anchor_bg" type="string"/>
+ </preferences>
+
+ <grid id="side-by-side-view-options" flex="1">
+ <columns>
+ <column/>
+ <column class="pickercolumn"/>
+ <column class="pickercolumn"/>
+ </columns>
+ <rows>
+ <row class="center"><spacer/></row>
+ <row align="center">
+ <label value="Log:"/>
+ <colorpicker id="sbs_log_fg" preference="sbs_log-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_log_bg" preference="sbs_log-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Whole diff:"/>
+ <colorpicker id="sbs_file-diff_fg" preference="sbs_file-diff-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_file-diff_bg" preference="sbs_file-diff-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Title:"/>
+ <colorpicker id="sbs_title_fg" preference="sbs_title-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_title_bg" preference="sbs_title-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Additional info:"/>
+ <colorpicker id="sbs_precode_fg" preference="sbs_precode-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_precode_bg" preference="sbs_precode-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Left diff header:"/>
+ <colorpicker id="sbs_left-title_fg" preference="sbs_left-title-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_left-title_bg" preference="sbs_left-title-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Right diff header:"/>
+ <colorpicker id="sbs_right-title_fg" preference="sbs_right-title-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_right-title_bg" preference="sbs_right-title-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Anchors:"/>
+ <colorpicker id="sbs_anchor_fg" preference="sbs_anchor-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_anchor_bg" preference="sbs_anchor-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Left diff:"/>
+ <colorpicker id="sbs_left_fg" preference="sbs_left-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_left_bg" preference="sbs_left-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Right diff:"/>
+ <colorpicker id="sbs_right_fg" preference="sbs_right-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_right_bg" preference="sbs_right-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Deleted Lines:"/>
+ <colorpicker id="sbs_deletedLine_fg" preference="sbs_deletedLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_deletedLine_bg" preference="sbs_deletedLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Added Lines:"/>
+ <colorpicker id="sbs_addedLine_fg" preference="sbs_addedLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_addedLine_bg" preference="sbs_addedLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Steady Lines:"/>
+ <colorpicker id="sbs_steadyLine_fg" preference="sbs_steadyLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_steadyLine_bg" preference="sbs_steadyLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Non existing line:"/>
+ <colorpicker id="sbs_emptyLine_fg" preference="sbs_emptyLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="sbs_emptyLine_bg" preference="sbs_emptyLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ </rows>
+ </grid>
+ </deck>
+</overlay>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/options/unified-view-options.xul b/chrome/colorediffs.jar!/content/colorediffs/options/unified-view-options.xul
new file mode 100644
index 0000000..f11a156
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/options/unified-view-options.xul
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://colorediffs/content/bindings.css" type="text/css"?>
+<?xul-overlay href="chrome://colorediffs/content/main-overlay.xul"?>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <deck id="view-properties">
+ <preferences>
+ <preference id="title-fg-pref" name="diffColorer.title_fg" type="string"/>
+ <preference id="title-bg-pref" name="diffColorer.title_bg" type="string"/>
+ <preference id="deletedLine-fg-pref" name="diffColorer.deletedLine_fg" type="string"/>
+ <preference id="deletedLine-bg-pref" name="diffColorer.deletedLine_bg" type="string"/>
+ <preference id="addedLine-fg-pref" name="diffColorer.addedLine_fg" type="string"/>
+ <preference id="addedLine-bg-pref" name="diffColorer.addedLine_bg" type="string"/>
+ <preference id="steadyLine-fg-pref" name="diffColorer.steadyLine_fg" type="string"/>
+ <preference id="steadyLine-bg-pref" name="diffColorer.steadyLine_bg" type="string"/>
+ <preference id="anchor-fg-pref" name="diffColorer.anchor_fg" type="string"/>
+ <preference id="anchor-bg-pref" name="diffColorer.anchor_bg" type="string"/>
+ <preference id="precode-fg-pref" name="diffColorer.precode_fg" type="string"/>
+ <preference id="precode-bg-pref" name="diffColorer.precode_bg" type="string"/>
+ </preferences>
+
+ <grid id="unified-view-options" flex="1">
+ <columns>
+ <column/>
+ <column class="pickercolumn"/>
+ <column class="pickercolumn"/>
+ </columns>
+ <rows>
+ <row class="center"><spacer/></row>
+ <row align="center">
+ <label value="Title:"/>
+ <colorpicker id="title_fg" preference="title-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="title_bg" preference="title-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Deleted Lines:"/>
+ <colorpicker id="deletedLine_fg" preference="deletedLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="deletedLine_bg" preference="deletedLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Added Lines:"/>
+ <colorpicker id="addedLine_fg" preference="addedLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="addedLine_bg" preference="addedLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Steady Lines:"/>
+ <colorpicker id="steadyLine_fg" preference="steadyLine-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="steadyLine_bg" preference="steadyLine-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Anchors:"/>
+ <colorpicker id="anchor_fg" preference="anchor-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="anchor_bg" preference="anchor-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ <row align="center">
+ <label value="Precode:"/>
+ <colorpicker id="precode_fg" preference="precode-fg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ <colorpicker id="precode_bg" preference="precode-bg-pref" command="cmd_change_pref" type="button" flex="1"/>
+ </row>
+ </rows>
+ </grid>
+ </deck>
+</overlay>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/overlay.js b/chrome/colorediffs.jar!/content/colorediffs/overlay.js
new file mode 100644
index 0000000..985c41b
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/overlay.js
@@ -0,0 +1,79 @@
+if (!colorediffsGlobal) {
+ var colorediffsGlobal = {};
+}
+
+//This observer make sure message get redrew if user change layout
+colorediffsGlobal.MailPaneConfigObserver = {
+ observe: function(subject, topic, prefName) {
+ // verify that we're changing the mail pane config pref
+ if (topic == "nsPref:changed") {
+ colorediffsGlobal.load();
+ }
+ }
+};
+
+colorediffsGlobal.load = function() {
+ var me = colorediffsGlobal;
+
+ var gmessagepane = me.getMessagePane();
+ if (gmessagepane) {
+ gmessagepane.addEventListener("load", function() {me.onLoadMessage();}, true);
+ }
+
+ var updateObserver = {
+ observe: function(subject, topic, data) {
+ if(topic=="colored-diff-update" && me.isActive()) {
+ ReloadMessage();
+ }
+ }
+ };
+
+ var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
+ observerService.addObserver(updateObserver, "colored-diff-update", false);
+
+ var unload = function() {
+ var pref = me.getPrefs();
+ pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
+ pref.removeObserver("mail.pane_config.dynamic", me.MailPaneConfigObserver);
+
+ observerService.removeObserver(updateObserver, "colored-diff-update");
+ };
+
+ window.addEventListener("unload", unload, false);
+
+// Components.utils.import("resource://test-framework/main.js");
+// run_tests("{282C3C7A-15A8-4037-A30D-BBEB17FFC76B}", "content/colorediffs/tests", document);
+
+ // var pref = new colorediffsGlobal.Pref(colorediffsGlobal.getPrefs());
+ // if (pref.debugDir.has()) {
+ // //run tests
+
+ // var MY_ID = "{282C3C7A-15A8-4037-A30D-BBEB17FFC76B}";
+ // var em = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);
+ // var file = em.getInstallLocation(MY_ID).getItemFile(MY_ID, "test-framework/main.js");
+ // var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
+ // var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
+ // fstream.init(file, -1, 0, 0);
+ // sstream.init(fstream);
+
+ // var data = "";
+ // var str = sstream.read(4096);
+ // while (str.length > 0) {data += str; str = sstream.read(4096);}
+
+ // sstream.close();
+ // fstream.close();
+
+ // eval(data);
+ // run_tests(MY_ID, "content/colorediffs/tests/", document);
+ // }
+};
+
+colorediffsGlobal.temp = function() {
+ var me = colorediffsGlobal;
+ var pref = me.getPrefs();
+
+ pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
+ pref.addObserver("mail.pane_config.dynamic", me.MailPaneConfigObserver, false);
+
+ window.addEventListener("load", function() {me.load();}, false);
+}();
diff --git a/chrome/colorediffs.jar!/content/colorediffs/overlay.xul b/chrome/colorediffs.jar!/content/colorediffs/overlay.xul
new file mode 100644
index 0000000..c6e3080
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/overlay.xul
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://colorediffs/skin/colorediffs.css" type="text/css"?>
+<?xul-overlay href="chrome://colorediffs/content/main-overlay.xul"?>
+
+<overlay id="colorediffs" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+</overlay>
diff --git a/chrome/colorediffs.jar!/content/colorediffs/parsers/context-parser.js b/chrome/colorediffs.jar!/content/colorediffs/parsers/context-parser.js
new file mode 100644
index 0000000..7242dce
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/parsers/context-parser.js
@@ -0,0 +1,160 @@
+colorediffsGlobal.parsers["context"] = {
+ parse:function(text) {
+ var parseFile = function(title, code) {
+ var parseChunk = function(code) {
+ var chunks = {};
+ chunks['old'] = {};
+ chunks['new'] = {};
+
+ var parts = code.split(/^(?:\*|\-){3}\s+(\d+)\,\d+\s+(?:\*|\-){4}$/m);
+
+ //parts[0] is "\n"
+ // parts[1] is line number of old code
+ // parts[2] is either old code or "\n"
+ // parts[3] is line number of new code
+ // parts[4] is new code
+
+ chunks['new'].line = Number(parts[3]);
+ chunks['old'].line = Number(parts[1]);
+
+ //split code
+ chunks['old'].code = [];
+ chunks['new'].code = [];
+
+ var line_status = [];
+
+ var processSteadyParts = function(oldCodeString, newCodeString) {
+ var i=0, j=0;
+
+ var oldCode = [];
+ var newCode = [];
+
+ var oldLines = oldCodeString.trim("\n").split("\n");
+ var newLines = newCodeString.trim("\n").split("\n");
+
+ var line_status = [];
+
+ while ( i < oldLines.length || j < newLines.length ) {
+ if (/^\-(.*)$/.test(oldLines[i])) {
+ oldCode.push(oldLines[i].substring(2));
+ newCode.push(null);
+ line_status.push("D"); //Deleted
+ i++;
+ } else if (/^\+(.*)$/.test(newLines[j])) {
+ newCode.push(newLines[j].substring(2));
+ oldCode.push(null);
+ line_status.push("A"); //Added
+ j++;
+ } else {
+ if ( /^ (.*)$/.test(oldLines[i] ) ) {
+ oldCode.push(oldLines[i].substring(2));
+ newCode.push(oldLines[i].substring(2));
+ line_status.push("S"); //the Same
+ } else if ( /^ (.*)$/.test(newLines[j] ) ) {
+ newCode.push(newLines[j].substring(2));
+ oldCode.push(newLines[j].substring(2));
+ line_status.push("S"); //the Same
+ }
+ i++; j++;
+ }
+ }
+ return [oldCode, newCode, line_status];
+ }
+
+ //Separate modified parts from non-modified
+ var modifiedPartsOld = parts[2].split(/(\n(?:!.*\n)+)/);
+ var modifiedPartsNew = parts[4].split(/(\n(?:!.*\n)+)/);
+
+ //There are always the same number of modified/non-modified parts in old and new code
+ for (var i = 0; i < modifiedPartsOld.length; i++) {
+ if ( /^!/m.test(modifiedPartsOld[i]) ) {
+ //modified parts
+ chunks['old'].code = chunks['old'].code.concat(modifiedPartsOld[i].trim("\n").replace(/^! /mg, "").split("\n"));
+ chunks['new'].code = chunks['new'].code.concat(modifiedPartsNew[i].trim("\n").replace(/^! /mg, "").split("\n"));
+ var minCodeLength = Math.min(chunks['old'].code.length, chunks['new'].code.length);
+
+ while ( line_status.length < minCodeLength ) {
+ line_status.push("C"); //Changed
+ }
+
+ while ( chunks['old'].code.length < chunks['new'].code.length ) {
+ chunks['old'].code.push(null);
+ line_status.push("A"); //Added
+ }
+ while ( chunks['old'].code.length > chunks['new'].code.length ) {
+ chunks['new'].code.push(null);
+ line_status.push("D"); //Deleted
+ }
+ } else {
+ //steady parts
+ var splittedCode = processSteadyParts(modifiedPartsOld[i], modifiedPartsNew[i]);
+ chunks['old'].code = chunks['old'].code.concat(splittedCode[0]);
+ chunks['new'].code = chunks['new'].code.concat(splittedCode[1]);
+ line_status = line_status.concat(splittedCode[2]);
+ }
+ }
+
+ var oldLines = parts[2].trim("\n").split("\n");
+ var newLines = parts[4].trim("\n").split("\n");
+ var oldLastLine = oldLines[oldLines.length-1];
+ var newLastLine = newLines[newLines.length-1];;
+
+ chunks['old'].doesnt_have_new_line = /^\\ No newline at end of file$/.test(oldLastLine);
+ chunks['new'].doesnt_have_new_line = /^\\ No newline at end of file$/.test(newLastLine);
+
+ chunks['old'].status = chunks['new'].status = line_status;
+
+ return chunks;
+ }
+
+ var res_file = {'old':{}, 'new':{}};
+
+ res_file.title = title;
+
+ var parts = code.split(/^\*{4,}$/m);
+ //parts[0] is some text before code
+
+ //get filename from it
+ var filename = "";
+ var regExpRes = parts[0].match(/---\s+(.*?)(?:\s|\n)+/);
+ if (regExpRes) {
+ res_file['new'].name = res_file['old'].name = regExpRes[1];
+ }
+
+ res_file.additional_file_info = parts[0];
+ res_file['old'].chunks = [];
+ res_file['new'].chunks = [];
+
+ for ( var i = 1; i < parts.length; i++ ) {
+ var chunks = parseChunk(parts[i]);
+
+ res_file['old'].chunks.push(chunks['old']);
+ res_file['new'].chunks.push(chunks['new']);
+ }
+
+ return res_file;
+ }
+
+
+ //main function body
+ var res = {}
+
+ var diffs = text.split(/(?:\n\n((?:.*\n){1,3}[-=]+\n))|(?:\n\n(diff.*)\n)/);
+ //Ok, diffs[0] is log, put it away.
+ //diffs[odd] are titles
+ //diffs[even] are diffs themselves
+ res.log = diffs[0];
+ res.files = [];
+
+ for ( var i = 1; i < diffs.length; i += 3 ) {
+ res.files.push(parseFile(diffs[i]+diffs[i+1], diffs[i+2]));
+ }
+
+ return res;
+ },
+ couldParse: function(text) {
+ var line_tag = /^(?:\*|\-){3}\s+(\d+)\,\d+\s+(?:\*|\-){4}$/m;
+ return line_tag.test(text);
+ }
+};
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/parsers/main-parser.js b/chrome/colorediffs.jar!/content/colorediffs/parsers/main-parser.js
new file mode 100644
index 0000000..65c09c0
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/parsers/main-parser.js
@@ -0,0 +1,8 @@
+colorediffsGlobal.parse = function(code, pref) {
+ for each (var parser in colorediffsGlobal.parsers) {
+ if (parser.couldParse(code)) {
+ return parser.parse(code, pref);
+ }
+ }
+ return null;
+}
diff --git a/chrome/colorediffs.jar!/content/colorediffs/parsers/unified-parser.js b/chrome/colorediffs.jar!/content/colorediffs/parsers/unified-parser.js
new file mode 100644
index 0000000..6257125
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/parsers/unified-parser.js
@@ -0,0 +1,551 @@
+//diff grammar
+// normal_line = \d+\n
+// postfix = normal_line | normal_line postfix
+// new_file = additional_file_info blank_line new_code
+// new_code = normal_line | normal_line new_code
+
+colorediffsGlobal.parsers["unified"] = {
+ parse: function(text, pref) {
+
+ var lines = text.split("\n");
+ var curr_line = 0;
+
+ function _try(f) {
+ var saved_line = curr_line;
+
+ var res = false;
+ try {
+ res = f();
+ } catch (e) {
+ }
+
+ if ( res ) {
+ return true;
+ } else {
+ curr_line = saved_line;
+ return false;
+ }
+ }
+
+ function _should(f) {
+ if (!f) {
+ throw "ASSERT FAILED";
+ }
+ }
+
+ function _try_many() {
+ for (var i = 0; i < arguments.length; i++) {
+ if (_try(arguments[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function _next() {
+ curr_line++;
+ if (curr_line >= lines.length) {
+ throw "EOF";
+ }
+ }
+
+ function _get() {
+ return lines[curr_line];
+ }
+
+ function _accept(r) {
+ var res = r.test(lines[curr_line]);
+ if (res) _next();
+ return res;
+
+ }
+
+ function _test(r) {
+ return r.test(lines[curr_line]);
+ }
+
+ // blank_line = \n
+ function blank_line() {
+ return /^$/;
+ }
+
+ function custom_log_terminator() {
+ return /^# Begin patch$/; //for bazaar merger
+ }
+
+ // diff = log blank_line code postfix
+ function diff() {
+ var result = {postfix:""};
+
+ log_and_code(result);
+ code_and_postfix(result);
+
+ return result;
+ }
+
+ function code_and_postfix(result) {
+ function _(func) { return function() { return func(result); }; };
+
+ try {
+ while(true) {
+ _try(_(code(result)));
+ if (_try(_(postfix))) {
+ break;
+ } else {
+ result.postfix += _get() + "\n";
+ _next();
+ }
+ }
+ } catch (e) {
+ }
+
+ return true;
+ }
+
+ function postfix(result) {
+ var postfix = "";
+ var max_postfix_size = pref.parserMaxPostfixSize.get();
+
+ var i = 0;
+
+ while(_get() || _test(blank_line())) {
+ postfix += _get() + "\n";
+ i++;
+ if ( i > max_postfix_size ) {
+ return false;
+ }
+ try {
+ _next();
+ } catch (e) {
+ break;
+ }
+ }
+
+ result.postfix += postfix;
+ return true;
+ }
+
+ // log = normal_line | normal_line log
+ function log_and_code(result) {
+ var log1 = "";
+ all:
+ do {
+ while(!_test(blank_line()) && !_test(custom_log_terminator())) {
+ log1 += _get() + "\n";
+ try {
+ _next();
+ } catch (e) {
+ break all;
+ }
+ }
+ log1 += _get() + "\n";
+ _next();
+ } while( !_try(function() {return code(result);}) );
+
+ result.log = log1.trim("\n");
+ }
+
+ // code = file blank_line | file blank_line code
+ function code(result) {
+ if ( !result.files ) {
+ result.files = [];
+ }
+
+ try {
+ do {
+ //skip blank lines
+ while( _test(blank_line()) ) { _next(); }
+ } while( _try(function() {return file(result);}) );
+ } catch (e) {
+ }
+
+ return result.files.length != 0;
+ }
+
+ // file = title file_info chunks | file_info chunks | "--- NEW FILE:" \s file_name " ---" new_file
+ function file(result) {
+ var file = {'old':{}, 'new':{}};
+
+ function _(func) { return function() { return func(file, result); } };
+
+ if (_try_many(
+ _(patch_binary_file),
+ _(normal_file),
+ _(cvs_new_file),
+ _(cvs_deleted_file),
+ _(cvs_binary_file),
+ _(svn_binary_file)
+ )) {
+ result.files.push(file);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function normal_file(file) {
+ function _(func) { return function() { return func(file); }; };
+
+ _try(_(title));
+ _try(_(additional_file_info));
+ _should(file_info(file));
+ _should(chunks(file));
+ return true;
+ }
+
+ function cvs_new_file_title() {
+ return _test(/^--- NEW FILE:\s.* ---$/);
+ }
+
+ function cvs_new_file(file, result) {
+ _should(cvs_new_file_title());
+ var name = _get().match(/^--- NEW FILE:\s(.*) ---$/)[1];
+ _next();
+ _should(new_file(file, result, name));
+ return true;
+ }
+
+ function cvs_binary_file_title() {
+ return _test(/^---\s(?:new\s)?BINARY FILE:\s.*\s---$/);
+ }
+
+ function extract_binary_file_name(file, data) {
+ var r = data.match(/\b(\w[ \w-\/\.]+\.[\w]+\w)\b/);
+ if ( r && r[1] ) {
+ file['new'].name = file['old'].name = r[1];
+ } else {
+ file['new'].name = file['old'].name = "";
+ }
+ }
+
+ function cvs_binary_file(file) {
+ _should(cvs_binary_file_title());
+ extract_binary_file_name(file, _get());
+ _next();
+ _should(additional_file_info(file));
+ return true;
+ }
+
+ function patch_binary_file(file) {
+ _should(_test(/^Binary files .* and .* differ$/));
+ var r = _get().match(/^Binary files (.*) and (.*) differ$/);
+ if (r) {
+ file['old'].name = r[1];
+ file['new'].name = r[2];
+ }
+ _next();
+ return true;
+ }
+
+ function cvs_deleted_file_title() {
+ return _test(/^--- .* DELETED ---$/);
+ }
+
+ function cvs_deleted_file(file) {
+ _should(cvs_deleted_file_title());
+ file['old'].name = _get().match(/^--- (.*) DELETED ---$/)[1];
+ _next();
+ return true;
+ }
+
+ function svn_binary_file(file) {
+ _should(title(file));
+ _should(additional_file_info(file));
+
+ extract_file_name_from_raw_data(file, file.title);
+
+ return true;
+ }
+
+ function extract_file_name_from_raw_data(file, data) {
+ var r = data.match(/\b(\w[\w-\/\.]+\.[\w]+\w)\b/);
+ if ( r && r[1] ) {
+ file['new'].name = file['old'].name = r[1];
+ } else {
+ file['new'].name = file['old'].name = "";
+ }
+ }
+
+ // title = normal_line "==========================" | normal_line "---------------------------" | normal_line title
+ function title(file) {
+ var max_title_size = pref.parserMaxTitleSize.get();
+ var min_title_delimiter_chars_count = pref.parserMinTitleDelimiterCharsCount.get();
+ var delimiterRegexp = new RegExp("^[-=]{" + min_title_delimiter_chars_count + ",}$");
+ var title = "";
+ var num = 0;
+ do {
+ title += _get() + "\n";
+ _next();
+ num++;
+
+ if ( num >= max_title_size || _test(blank_line()) ) {
+ return false;
+ }
+ } while (!_test(delimiterRegexp));
+
+ _next();
+ file.title = title.trim("\n");
+ return true;
+ }
+
+ // file_info = additional_file_info old_file_info new_file_info | old_file_info new_file_info
+ function file_info(file) {
+ if (_test(/^---/)) {
+ var oldFileInfo = getFileInfo(_get());
+ _next();
+ var newFileInfo = getFileInfo(_get());
+ _next();
+
+ file['old'].name = oldFileInfo[0];
+ file['old'].version = oldFileInfo[1];
+
+ file['new'].name = newFileInfo[0];
+ file['new'].version = newFileInfo[1];
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // old_file_info = "---" old_file_name "\t" date "\t" version
+ // new_file_info = "+++" new_file_name "\t" date "\t" version
+ // old_file_name = file_name
+ // new_file_name = file_name
+ // file_name = [^\t]+
+ // date = [^\t]+
+ // version = [^\t]+
+ function getFileInfo(s) {
+ var fiReg = /^[+-]{3}\s(.*?)(?:\t(.*))?$/;
+ var r = fiReg.exec(s);
+
+ if (r) {
+ if (/(empty file)/.test(r[1])) { //Filename should match that
+ return ["", r[1] + " " + r[2]];
+ } else {
+ return [r[1], r[2]];
+ }
+ } else {
+ return [s, ""];
+ }
+ }
+
+ // additional_file_info = normal_line | normal_line additional_file_info
+ function additional_file_info(file) {
+ var max_additional_info_size = pref.parserMaxAdditionalInfoSize.get();
+ var additional_file_info = "";
+ var num = 0;
+ while ( !_test(/^---/) && !_test(blank_line())) {
+ if (num >= max_additional_info_size) {
+ return false;
+ }
+
+ additional_file_info += _get() + "\n";
+ _next();
+ num++;
+ }
+
+ file.additional_info = additional_file_info;
+ return true;
+ }
+
+ // chunks = chunk | chunk chunks
+ function chunks(file) {
+ file['old'].chunks = [];
+ file['new'].chunks = [];
+ while( _try(function() {return chunk(file);}) ) {
+ }
+
+ return file['old'].chunks.length == file['new'].chunks.length && file['new'].chunks.length > 0;
+ }
+
+ // chunk = anchor diff_code
+ function chunk(file) {
+ var old_chunk = {code:[]};
+ var new_chunk = {code:[]};
+ anchor(old_chunk, new_chunk);
+ diff_code(old_chunk, new_chunk);
+ file['old'].chunks.push(old_chunk);
+ file['new'].chunks.push(new_chunk);
+ return true;
+ }
+
+ // anchor = @@ \-\d+(,\d+)? \+\d+(,\d+)? @@
+ function anchor(old_chunk, new_chunk) {
+ var regExpRes = _get().match(/^@@\s+\-(\d+)(?:\,\d+)?\s+\+(\d+)(?:\,\d+)?\s+@@/);
+ old_chunk.line = Number(regExpRes[1]);
+ new_chunk.line = Number(regExpRes[2]);
+ if (_test(/@@$/)) {
+ _next();
+ } else {
+ //git adds the first line of code to the anchor line for some reason
+ //TODO: do you think it is better to split the string instead of rewriting it?
+ lines[curr_line] = _get().slice(regExpRes[0].length);
+ }
+ }
+
+ function check_next_paragraph_for_code() {
+ return !_try(function() {
+ return !_try(function() {
+ //skip initial blanks
+ while( _test(blank_line()) ) { _next(); }
+ while(true) {
+ if (_test(/^\-(.*)$/)) {
+ } else if (_test(/^\+(.*)$/)) {
+ } else if (_test(/^\\ No newline at end of file$/)) {
+ } else if (_test(/^ (.*)$/)) {
+ } else if (_test(blank_line())) {
+ return true;
+ } else {
+ return false;
+ }
+ try { _next(); } catch (e) {return true;}
+ }
+ });
+ });
+ }
+
+ // diff_code = diff_code_line | diff_code_line diff_code
+ // diff_code_line = " " .* | "+" .* | "-" .*
+ function diff_code(old_chunk, new_chunk) {
+ function makeEqualLength() {
+ while ( old_chunk.code.length < new_chunk.code.length ) {
+ line_status[old_chunk.code.length] = "A"; //Added
+ old_chunk.code.push(null);
+ }
+ while ( old_chunk.code.length > new_chunk.code.length ) {
+ line_status[new_chunk.code.length] = "D"; //Deleted
+ new_chunk.code.push(null);
+ }
+ }
+
+ var line_status = [];
+ var temp_result = {files: []};
+
+ old_chunk.doesnt_have_new_line = false;
+ new_chunk.doesnt_have_new_line = false;
+
+ var prev_line = null;
+
+ while(true) {
+ if (_test(/^---\s/)) { //might be the beginning of other file
+ //here is the trick. Inside _try_many stores the current_line position and checks a bunch of titles.
+ // If any of the titles match it saves the new position otherwise it restore the old one.
+ // The outer _try checks if the nested one return true which means title was matched and new position is saved
+ // and convert that to false so actually position would be restored.
+ // If however _try_many returns false that means position didn't move and we can return true and save it once again.
+ // So _try returns false means there was a match and true means there wasn't
+ // Position would not be affected anyway.
+ if (!_try(function() {
+ return !_try_many(
+ function() { return file_info({'old':{}, 'new':{}}); },
+ cvs_new_file_title,
+ cvs_deleted_file_title,
+ cvs_binary_file_title
+ );
+ }
+ )) {
+ break;
+ }
+ } else if (_test(/^\-(.*)$/)) {
+ line_status[old_chunk.code.length] = "C"; //Changed
+ old_chunk.code.push(_get().substring(1));
+ } else if (_test(/^\+(.*)$/)) {
+ line_status[new_chunk.code.length] = "C"; //Changed
+ new_chunk.code.push(_get().substring(1));
+ } else if (_test(/^\\ No newline at end of file$/)) {
+ //check what sign previous line has if there was any
+ if ( prev_line != null ) {
+ if (/^\-/.test(prev_line)) {
+ old_chunk.doesnt_have_new_line = true;
+ } else if (/^\+/.test(prev_line)) {
+ new_chunk.doesnt_have_new_line = true;
+ } else if (/^ /.test(prev_line)) {
+ old_chunk.doesnt_have_new_line = true;
+ new_chunk.doesnt_have_new_line = true;
+ }
+ }
+ } else if (_test(/^ (.*)$/)) {
+ makeEqualLength();
+ old_chunk.code.push(_get().substring(1));
+ new_chunk.code.push(_get().substring(1));
+ line_status.push("S"); //the Same
+ } else if (_test(blank_line())) {
+ if (check_next_paragraph_for_code()) {
+ makeEqualLength();
+ old_chunk.code.push("");
+ new_chunk.code.push("");
+ line_status.push("S"); //the Same
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ prev_line = _get();
+ try { _next(); } catch (e) {break;}
+ }
+ makeEqualLength();
+
+ new_chunk.status = old_chunk.status = line_status;
+ }
+
+ function new_file(f, result, name) {
+ var code = [];
+ var status = [];
+ var temp_result = {files: []};
+
+ try {
+ while(true) {
+ while(!_test(/^--- .* ---$/) && !_test(/^Index: /)) {
+ code.push(_get());
+ status.push("A");
+ _next();
+ }
+
+ if (_try(function() { return file(temp_result); })) {
+ break;
+ }
+ }
+ } catch (e) {
+ }
+
+ code.pop();
+ status.pop();
+
+ var new_file = {
+ 'new': {
+ name: name,
+ chunks: [{
+ line:1,
+ code: code,
+ status: status
+ }]
+ },
+ 'old': {}
+ };
+
+ result.files.push(new_file);
+ result.files = result.files.concat(temp_result.files);
+
+ var file_to_copy = result.files[result.files.length - 1];
+ result.files.pop();
+
+ //copy next file to first argument
+ for (var a in file_to_copy) {
+ f[a] = file_to_copy[a];
+ }
+
+ return true;
+
+ }
+
+ return diff();
+
+ },
+ couldParse: function(text) {
+ var line_tag = /^@@\s+\-\d+(?:\,\d+)?\s\+\d+(?:\,\d+)?\s+@@/m;
+ var new_tag = /^--- NEW FILE:\s.* ---$/m;
+ var binary_tag = /^---\s(?:new\s)?BINARY FILE:\s.*\s---$/m;
+ return line_tag.test(text) || new_tag.test(text) || binary_tag.test(text);
+ }
+}
diff --git a/chrome/colorediffs.jar!/content/colorediffs/prefs.js b/chrome/colorediffs.jar!/content/colorediffs/prefs.js
new file mode 100644
index 0000000..0103673
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/prefs.js
@@ -0,0 +1,100 @@
+if (!colorediffsGlobal) {
+ var colorediffsGlobal = {};
+}
+
+colorediffsGlobal.Pref = function (prefModel) {
+ var me = this;
+ var pref = prefModel;
+
+ var createGetSet = function(name, prop_name, getter, setter) {
+ me[name] = {
+ get: function() { return getter(prop_name); },
+ set: function(value) { setter(prop_name, value); },
+ has: function () {return pref.prefHasUserValue(prop_name);}
+ };
+ };
+
+ var createBoolGetSet = function(name, prop_name) {
+ var getBoolPref = function(p) {
+ return pref.getBoolPref(p);
+ };
+
+ var setBoolPref = function(p, v) {
+ return pref.setBoolPref(p, v);
+ };
+
+ createGetSet(name, prop_name, getBoolPref, setBoolPref);
+ };
+
+ var createIntGetSet = function(name, prop_name) {
+ var getIntPref = function(p) {
+ return pref.getIntPref(p);
+ };
+
+ var setIntPref = function(p, v) {
+ return pref.setIntPref(p, v);
+ };
+
+ createGetSet(name, prop_name, getIntPref, setIntPref);
+ };
+
+ var getCharPref = function(p) {
+ return pref.getCharPref(p);
+ };
+
+ var setCharPref = function(p, v) {
+ pref.setCharPref(p, v);
+ };
+
+ var createCharGetSet = function(name, prop_name) {
+ createGetSet(name, prop_name, getCharPref, setCharPref);
+ };
+
+ var getProperty = function(prop, color) {
+ var v = getCharPref(color);
+ if (v) {
+ return prop + ": " + v + ";";
+ } else {
+ return "";
+ }
+ };
+
+ me.getColorProps = function(baseName) {
+ return getProperty("color", baseName + "_fg") + getProperty("background-color", baseName + "_bg");
+ };
+
+ me.getColorBG = function(baseName) {
+ return getCharPref(baseName + "_bg");
+ };
+
+ me.getColorFG = function(baseName) {
+ return getCharPref(baseName + "_fg");
+ };
+
+ me.setColorBG = function(baseName, value) {
+ setCharPref(baseName + "_bg", value);
+ };
+
+ me.setColorFG = function(baseName, value) {
+ setCharPref(baseName + "_fg", value);
+ };
+
+
+ createCharGetSet("mode", "diffColorer.view-mode");
+ createCharGetSet("debugDir", "diffColorer.debug-dir");
+ createBoolGetSet("showWhiteSpace", "diffColorer.show-whitespace");
+ createBoolGetSet("showToolbar", "diffColorer.show-toolbar");
+ createBoolGetSet("instantApply", "browser.preferences.instantApply");
+
+ createIntGetSet("parserMaxTitleSize", "diffColorer.parser.max-title-size");
+ createIntGetSet("parserMinTitleDelimiterCharsCount", "diffColorer.parser.min-title-delimiter-chars-count");
+ createIntGetSet("parserMaxAdditionalInfoSize", "diffColorer.parser.max-additional-info-size");
+ createIntGetSet("parserMaxPostfixSize", "diffColorer.parser.max-postfix-size");
+
+ createCharGetSet("diffMode", "diffColorer.diff-mode");
+ createBoolGetSet("showLineNumbers", "diffColorer.show-line-numbers");
+
+ createBoolGetSet("preferHtml", "mailnews.display.prefer_plaintext");
+
+ createIntGetSet("tabSize", "diffColorer.tab-size");
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/toolbar.js b/chrome/colorediffs.jar!/content/colorediffs/toolbar.js
new file mode 100644
index 0000000..279dfe7
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/toolbar.js
@@ -0,0 +1,111 @@
+if (!colorediffsGlobal) {
+ var colorediffsGlobal = {};
+}
+
+colorediffsGlobal.colorediffsToolbar = new function() {
+ var me = colorediffsGlobal;
+ var pref = new me.Pref(me.getPrefs());
+
+ var getNode = function (name) {
+ return function() {return me.$(name);};
+ };
+
+ var getViewModeNode = getNode('colorediffs-view-mode');
+ var getDiffModeNode = getNode('colorediffs-diff-mode');
+ var getTabSizeNode = getNode('colorediffs-tab-size');
+ var getShowWhiteSpacesNode = getNode('colorediffs-show-whitespaces');
+ var getShowLineNumbersNode = getNode('colorediffs-show-line-numbers');
+ var getToolbarNode = getNode('colorediffs-toolbar');
+
+ var reloadWithScrollPreserved = function() {
+ var mp = me.getMessagePane();
+ var oldScroll = mp.contentWindow.scrollY;
+ mp.addEventListener(
+ "load",
+ function() {
+ mp.contentWindow.scrollTo(0, oldScroll);
+ mp.removeEventListener("load", arguments.callee, true);
+ },
+ true);
+ ReloadMessage();
+ };
+
+ var updatePrefs = function() {
+ pref.showWhiteSpace.set(getShowWhiteSpacesNode().checked);
+ pref.showLineNumbers.set(getShowLineNumbersNode().checked);
+ pref.mode.set(getViewModeNode().selectedItem);
+ pref.diffMode.set(getDiffModeNode().selectedItem.value);
+ pref.tabSize.set(getTabSizeNode().selectedItem.value);
+ pref.showToolbar.set(!getToolbarNode().hidden);
+ };
+
+ this.selectMode = function () {
+ updatePrefs();
+ ReloadMessage();
+ };
+
+ this.toggleWhiteSpaces = function () {
+ getShowWhiteSpacesNode().checked = !getShowWhiteSpacesNode().checked;
+ updatePrefs();
+
+ reloadWithScrollPreserved();
+ };
+
+ this.toggleLineNumbers = function () {
+ getShowLineNumbersNode().checked = !getShowLineNumbersNode().checked;
+ updatePrefs();
+
+ reloadWithScrollPreserved();
+ };
+
+ this.showOptions = function() {
+ var features = "chrome,titlebar,toolbar,centerscreen";
+ window.openDialog("chrome://colorediffs/content/options/options.xul", "Preferences", features);
+ };
+
+ this.selectDiffMode = function() {
+ updatePrefs();
+ reloadWithScrollPreserved();
+ };
+
+ this.selectTabSize = function() {
+ updatePrefs();
+ reloadWithScrollPreserved();
+ };
+
+ this.closeToolbar = function() {
+ getToolbarNode().hidden=true;
+ updatePrefs();
+ };
+
+ function selectComboByValue(menulist, value) {
+ var items = menulist.firstChild.childNodes;
+ for( var i=0; i < items.length; i++ ) {
+ if ( items[i].getAttribute("value") == value ) {
+ menulist.selectedItem = items[i];
+ break;
+ }
+ }
+ }
+
+ this.initToolbar = function () {
+ if (pref.showToolbar.get()) {
+ //check if should be shown
+ if (!me.isActive()) {
+ getToolbarNode().hidden=true;
+ } else {
+ getToolbarNode().hidden=false;
+ getShowWhiteSpacesNode().checked = pref.showWhiteSpace.get();
+
+ //update combobox
+ getViewModeNode().selectedItem = pref.mode.get();
+ getShowLineNumbersNode().checked = pref.showLineNumbers.get();
+
+ selectComboByValue(getDiffModeNode(), pref.diffMode.get());
+ selectComboByValue(getTabSizeNode(), pref.tabSize.get());
+ }
+ } else {
+ getToolbarNode().hidden=true;
+ }
+ };
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/add-title.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/add-title.js
new file mode 100644
index 0000000..24e3e93
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/add-title.js
@@ -0,0 +1,14 @@
+colorediffsGlobal.transformations.composite.members["add-title"] = {
+ init: function(registrator, pref) {
+
+ registrator.addListener("add-title", "file", addTitle, "find-common-name");
+
+ function addTitle(file) {
+ if (!file.title) {
+ file.title = file.common_name;
+ }
+
+ return file;
+ }
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/calc-chunk-size.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/calc-chunk-size.js
new file mode 100644
index 0000000..8dc7afa
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/calc-chunk-size.js
@@ -0,0 +1,19 @@
+colorediffsGlobal.transformations.composite.members["calc-chunk-size"] = {
+ init: function(registrator, pref) {
+
+ registrator.addListener("calc-chunk-size-init-chunk", "chunk", initChunk);
+ registrator.addListener("calc-chunk-size", "line", sumLine, ["calc-chunk-size-init-chunk", "select-old-new-files"]);
+
+ function initChunk(chunk) {
+ chunk.code_size = 0;
+ return chunk;
+ }
+
+ function sumLine(line, i, chunk) {
+ if (line != null) {
+ chunk.code_size++;
+ }
+ return line;
+ }
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/collect-tab-sizes.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/collect-tab-sizes.js
new file mode 100644
index 0000000..4c15607
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/collect-tab-sizes.js
@@ -0,0 +1,40 @@
+colorediffsGlobal.transformations.composite.members["collect-tab-sizes"] = {
+ init: function(registrator, pref) {
+ if (pref.mode.get() == "side-by-side" || pref.tabSize.get() != 8 || pref.showWhiteSpace.get() || pref.showLineNumbers.get()) {
+ registrator.addListener("collect-tab-sizes-init-chunk", "chunk", initChunk);
+ registrator.addListener("collect-tab-sizes", "line", collectTabSizes, "collect-tab-sizes-init-chunk");
+ }
+
+ function initChunk(chunk) {
+ chunk.tab_sizes = new Array(chunk.code.length);
+ return chunk;
+ }
+
+ function collectTabSizes(line, i, chunk) {
+ chunk.tab_sizes[i] = calcTabSizes(line);
+
+ return line;
+ }
+
+ function calcTabSizes(s) {
+ if (s) {
+ var offsetCorrector = 0;
+ var tab_sizes = [];
+ var i = -1;
+ while ((i = s.indexOf("\t", i + 1)) != -1) {
+ var l = pref.tabSize.get() - (i + offsetCorrector) % pref.tabSize.get();
+ tab_sizes.push(l);
+ offsetCorrector += l - 1;
+ }
+
+ if (tab_sizes.length == 0) {
+ return null;
+ } else {
+ return tab_sizes;
+ }
+ } else {
+ return null;
+ }
+ }
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-init.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-init.js
new file mode 100644
index 0000000..8477212
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-init.js
@@ -0,0 +1,134 @@
+colorediffsGlobal.transformations["composite"].methods.initOthers =
+ function (pref) {
+ var callbacks = {};
+ var dependants = {};
+
+ for each (var member in colorediffsGlobal.transformations.composite.members) {
+ member.init({
+ addListener: function(name, type, callback, depends) {
+ var node = {
+ type:type,
+ callback:callback,
+ ancessorCount:0
+ };
+
+ callbacks[name] = node;
+
+ if (depends) {
+ if (depends instanceof Array) {
+ for (var i = 0; i < depends.length; i++) {
+ addDependant(depends[i], node);
+ }
+ } else {
+ addDependant(depends, node);
+ }
+ } else {
+ addDependant("root", node);
+ }
+
+ function addDependant(dependsOn, node) {
+ if (dependants[dependsOn]) {
+ dependants[dependsOn].push(node);
+ } else {
+ dependants[dependsOn] = [node];
+ }
+ }
+ }
+ }, pref);
+ }
+
+
+ var roots = buildDependenciesGraph();
+ dependants = null;
+ callbacks = null;
+
+ var nodes = buildTree(["file", "chunk-pair", "chunk", "line"]);
+ roots = null;
+
+ function buildDependenciesGraph() {
+ callbacks["root"] = {};
+
+ for (var name in dependants) {
+ if (callbacks[name]) {
+ callbacks[name].children = dependants[name];
+ if (name != "root") {
+ dependants[name].forEach(function(node) {
+ node.ancessorCount++;
+ });
+ }
+ } else {//The callback we depends on isn't enabled, should go to the root
+ for (var i = 0; i < dependants[name].length; i++) {
+ var dependant = dependants[name][i];
+ if (dependant.ancessorCount == 0) { // push only if we aren't depends on something enabled
+ dependant.ancessorCount = 1;
+ callbacks["root"].children.push(dependant);
+ }
+ }
+ }
+ }
+
+ return callbacks["root"].children;
+ }
+
+ function buildTree(types) {
+ var nodes = [];
+
+ while(true) {
+ var node = {
+ callbacks:[]
+ };
+
+ var i = 0;
+ while( i < roots.length ) {
+ if ( roots[i].type == types[0] ) {
+ node.callbacks.push(roots[i].callback);
+
+ var iWasReplaced = false;
+ var children = roots[i].children;
+ if (children) {
+ for (var j = 0; j < children.length; j++) {
+ if ( --children[j].ancessorCount == 0 ) {
+ if ( !iWasReplaced ) {
+ roots[i] = children[j];
+ iWasReplaced = true;
+ } else {
+ roots.push(children[j]);
+ }
+ }
+ }
+ }
+ if ( !iWasReplaced ) {
+ roots.splice(i, 1);
+ }
+ } else {
+ i++;
+ }
+ }
+
+ if (types.length > 1) {//recursion stop condition
+ node.next = buildTree(types.slice(1));
+ } else {
+ node.next = null;
+ }
+
+ if (node.callbacks.length == 0 && node.next == null) {//if nothing got changed
+ break;
+ } else {
+ nodes.push(node);
+ }
+
+ if (types.length == 1) { //There are no chance we could find something with our type now
+ break;
+ }
+ }
+
+ if (nodes.length == 0) {
+ return null;
+ } else {
+ return nodes;
+ }
+ }
+
+ return nodes;
+ }
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-run.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-run.js
new file mode 100644
index 0000000..43e00ed
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-run.js
@@ -0,0 +1,89 @@
+colorediffsGlobal.transformations["composite"].methods.proceedIL =
+ function (il, nodes) {
+ il.files.forEach(function(file) {proceedFile(file, nodes);});
+
+ function proceedFile(file, nodes) {
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].callbacks.forEach(
+ function(callback) {
+ callback(file, il);
+ }
+ );
+
+ if (nodes[i].next) {
+ var l = 0;
+
+ if ( file['old'] && file['old'].chunks ) {
+ l = file['old'].chunks.length;
+ } else if ( file['new'] && file['new'].chunks ) {
+ l = file['new'].chunks.length;
+ }
+
+ for (var j = 0; j < l; j++) {
+ var old_chunk = null;
+ var new_chunk = null;
+
+ if ( file['old'] && file['old'].chunks ) {
+ old_chunk = file['old'].chunks[j];
+ }
+
+ if ( file['new'] && file['new'].chunks ) {
+ new_chunk = file['new'].chunks[j];
+ }
+
+ proceedChunkPair(file, old_chunk, new_chunk, nodes[i].next);
+ }
+ }
+ }
+ }
+
+ function proceedChunkPair(file, old_chunk, new_chunk, nodes) {
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].callbacks.forEach(
+ function(callback) {
+ callback(old_chunk, new_chunk, file);
+ }
+ );
+
+ if (nodes[i].next) {
+ if (old_chunk) {
+ proceedChunk(file, old_chunk, nodes[i].next);
+ }
+
+ if (new_chunk) {
+ proceedChunk(file, new_chunk, nodes[i].next);
+ }
+ }
+ }
+ }
+
+ function proceedChunk(file, chunk, nodes) {
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].callbacks.forEach(
+ function(callback) {
+ callback(chunk, file);
+ }
+ );
+
+ if (nodes[i].next) {
+ chunk.code = chunk.code.map(
+ function(line, j) {
+ return proceedLine(file, chunk, line, j, nodes[i].next);
+ }
+ );
+ }
+ }
+ }
+
+ function proceedLine(file, chunk, line, index, nodes) {
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].callbacks.forEach(
+ function(callback) {
+ line = callback(line, index, chunk, file);
+ }
+ );
+ }
+ return line;
+ }
+ }
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-transformation.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-transformation.js
new file mode 100644
index 0000000..0ee1fe9
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/composite-transformation.js
@@ -0,0 +1,15 @@
+colorediffsGlobal.transformations["composite"] = {
+ run: function (il, pref) {
+
+ //add transformations
+ var nodes = colorediffsGlobal.transformations.composite.methods.initOthers(pref);
+
+ //proceed
+ colorediffsGlobal.transformations.composite.methods.proceedIL(il, nodes);
+
+ return il;
+ }
+};
+
+colorediffsGlobal.transformations.composite.members = {};
+colorediffsGlobal.transformations.composite.methods = {};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/detect-old-new-files.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/detect-old-new-files.js
new file mode 100644
index 0000000..a50a418
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/detect-old-new-files.js
@@ -0,0 +1,23 @@
+colorediffsGlobal.transformations.composite.members["detect-old-new-files"] = {
+ init: function(registrator, pref) {
+
+ registrator.addListener("detect-old-new-files", "file", detectOldNewFiles);
+
+ function detectOldNewFiles(file) {
+ if (file['new'] && file['new'].chunks && file['old'] && file['old'].chunks) {
+ deleteSide('new');
+ deleteSide('old');
+ }
+
+ function deleteSide(side_to_delete) {
+ if ( !file[side_to_delete].chunks[0] || file[side_to_delete].chunks[0].line == 0 ) {
+ file[side_to_delete].chunks = null;
+ }
+ }
+
+
+ return file;
+ }
+
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/find-common-name.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/find-common-name.js
new file mode 100644
index 0000000..02fdcc9
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/find-common-name.js
@@ -0,0 +1,253 @@
+colorediffsGlobal.transformations.composite.members["find-common-name"] = {
+ init: function(registrator, pref) {
+
+ registrator.addListener("find-common-name", "file", findCommonName);
+
+ function findCommonName(file, il) {
+ if ( file['new'].name || file['old'].name ) {
+ //get common part of the names
+ var commonPart = returnCommonPart(file['new'].name || "", file['old'].name || "");
+
+ //try all the combinations of it on the log until found something
+ //common_name = found_part
+ file.common_name = checkCombinations(il.log, commonPart) || commonPart;
+
+ file.id = file.common_name;
+ }
+
+ return file;
+ }
+
+ function returnCommonPart(s1, s2) {
+ if (s1 && !s2) {
+ return s1;
+ } else if (s2 && !s1) {
+ return s2;
+ }
+ var d = findDiff(s1, s2);
+ var max = "";
+ for (var o = d; o; o = o.next[0]) {
+ if (o.prev.length == 0 || o.prev.length == 2) {//funny way to find out if this is a common part
+ if (o.text.length > max.length) {
+ max = o.text;
+ }
+ }
+ }
+ return max.trim();
+ }
+
+ function skipNextComponent(s) {
+ var i1 = s.indexOf("/");
+ var i2 = s.indexOf("\\");
+
+ var i = Math.max(i1, i2) + 1;
+
+ if ( i > 0 ) {
+ return s.substring(i);
+ } else {
+ return "";
+ }
+ }
+
+ function checkPathCombinations(log, name) {
+ do {
+ if ( log.indexOf(name) >= 0 ) {
+ return name;
+ }
+
+ name = skipNextComponent(name);
+ } while( name != "" );
+ return null;
+ }
+
+ function chopToLastSpace(s) {
+ if (s.indexOf(" ") == -1) {
+ return "";
+ } else {
+ return s.replace(/ +.*?$/, "");
+ }
+ }
+
+ function checkCombinations(log, name) {
+ do {
+ var tempN = checkPathCombinations(log, name);
+ if ( tempN != null ) {
+ return tempN;
+ }
+
+ name = chopToLastSpace(name);
+ } while( name != "" );
+ return null;
+ }
+
+ function findDiff(a, b) {
+ //replace element in array
+ function replace(arr, el, new_el) {
+ if (el == new_el) return;
+ for (var i=0; arr[i]; i++) {
+ if (arr[i] == el) {
+ arr[i] = new_el;
+ break;
+ }
+ }
+ }
+
+ function zip(arr) {
+ var res = [];
+ var prev = null;
+ for (var i=0; arr[i]; i++) {
+ if (arr[i] != prev) {
+ res.push(arr[i]);
+ }
+ prev = arr[i];
+ }
+ return res;
+ }
+
+ function join(old_o, new_o) {
+ var common = {
+ text: old_o.text,
+ prev: zip(old_o.prev, new_o.prev),
+ next: zip(old_o.next, new_o.next)
+ };
+
+ for (let i = 0; i < common.prev.length; i++) {
+ replace(common.prev[i].next, old_o, common);
+ replace(common.prev[i].next, new_o, common);
+ }
+
+ for (let i = 0; i < common.next.length; i++) {
+ replace(common.prev[i].prev, old_o, common);
+ replace(common.prev[i].prev, new_o, common);
+ }
+ }
+
+ function break_to_tokens(s) {
+ var ts = s.split(/([^A-Za-z0-9])/);
+ var res = {text:"", next:[], prev: []};
+ var next = res;
+ for (var i = 0; typeof(ts[i]) != "undefined"; i++) {
+ var new_o = {text:ts[i], next:[], prev: []};
+ next.next.push(new_o);
+ new_o.prev.push(next);
+ next = new_o;
+ }
+ res.next[0].prev = [];
+ return {first: res.next[0], last: next};
+ }
+
+ //vtokens are used as keys in hash to look for anchors
+ // should also have a link to what tokens it's from
+ // should contain one or more tokens
+// function break_to_vtokens(s) {
+// var res = [];
+// for (var i = 0; s[i]; i++) {
+// res.push(s.substr(i, 3));
+// }
+// return res;
+// }
+ function break_to_vtokens(tokens) {
+ var res = [];
+ for (var o = tokens.first; o; o = o.next[0]) {
+ res.push({anchor:o.text, tokens:[o]});
+ }
+ return res;
+ }
+
+ var hash = {};
+
+ var new_tokens = break_to_tokens(b);
+ var new_vtokens = break_to_vtokens(new_tokens);
+ for (var i = 0; new_vtokens[i]; i++) {
+ var temp = hash[new_vtokens[i].anchor];
+ if (!temp) {
+ //we are interested in new/old tokens only if nc==oc==1
+ hash[new_vtokens[i].anchor] = temp = {nc: 0, oc: 0, new_tokens: new_vtokens[i].tokens, old_tokens:[]};
+ }
+ temp.nc++;
+ }
+
+ var old_tokens = break_to_tokens(a);
+ var old_vtokens = break_to_vtokens(old_tokens);
+ for (i = 0; old_vtokens[i]; i++) {
+ var temp = hash[old_vtokens[i].anchor];
+ if (!temp) {
+ hash[old_vtokens[i].anchor] = temp = {nc: 0, oc: 0, new_tokens: [], old_tokens:[]};
+ }
+ temp.oc++;
+ temp.old_tokens = old_vtokens[i].tokens; //we are interested in new/old tokens only if nc==oc==1
+ }
+
+ var common_first = {text:"", prev:[], next:[old_tokens.first, new_tokens.first]};
+ var common_last = {text:"", next:[], prev:[old_tokens.last, new_tokens.last]};
+ old_tokens.first.prev.push(common_first); new_tokens.first.prev.push(common_first);
+ old_tokens.last.next.push(common_last); new_tokens.last.next.push(common_last);
+ var res = {first:common_first, last:common_last};
+
+ for (el in hash) {
+ var e = hash[el];
+ if (e.nc == 1 && e.oc == 1) {
+ for (i = 0; e.old_tokens[i] && e.new_tokens[i]; i++) {
+ join(e.old_tokens[i], e.new_tokens[i]);
+ }
+ }
+ }
+
+ for (var o = res.first; o; o = o.next[0]) {
+ if (o.next.length == 2) {
+ //we're on common element, see if we can join next one
+ if (o.next[0].text == o.next[1].text) {
+ join(o.next[0], o.next[1]);
+ }
+ }
+ }
+
+ for (o = res.last; o; o = o.prev[0]) {
+ if (o.prev.length == 2) {
+ //we're on common element, see if we can join previous one
+ if (o.prev[0].text == o.prev[1].text) {
+ join(o.prev[0], o.prev[1]);
+ }
+ }
+ }
+
+ //simplify result by joining tokens from the same group (common, old) together
+ for (o = res.first; o;) {
+ //if a <-> b exclusively
+ if (o.next.length == 1 && o.next[0].prev.length == 1) {
+ var onext = o.next[0];
+ //join a and b
+ o.text = o.text + onext.text;
+ o.next = onext.next;
+ for (i = 0; o.next[i]; i++) {
+ replace(o.next[i].prev, onext, o);
+ }
+ } else {
+ o = o.next[0];
+ }
+ }
+
+ //simplify result by joining tokens from the same group (common, new) together
+ for (o = res.first; o;) {
+ //if a <-> b exclusively
+ if (o.next.length == 1 && o.next[0].prev.length == 1) {
+ var onext = o.next[0];
+ //join a and b
+ o.text = o.text + onext.text;
+ o.next = onext.next;
+ for (i = 0; o.next[i]; i++) {
+ replace(o.next[i].prev, onext, o);
+ }
+ } else {
+ o = o.next[o.next.length-1];
+ }
+ }
+
+ return res.first;
+ }
+
+
+ //test
+ //findDiff("This is a diff line", "This is a new line");
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/main-transformation.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/main-transformation.js
new file mode 100644
index 0000000..27b0735
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/main-transformation.js
@@ -0,0 +1,6 @@
+colorediffsGlobal.transform = function(il, pref) {
+ for each (var tr in colorediffsGlobal.transformations) {
+ il = tr.run(il, pref);
+ }
+ return il;
+}
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/make-lines-equal-length.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/make-lines-equal-length.js
new file mode 100644
index 0000000..fd79647
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/make-lines-equal-length.js
@@ -0,0 +1,73 @@
+colorediffsGlobal.transformations.composite.members["make-lines-equal-length"] = {
+ init: function(registrator, pref) {
+ if (pref.mode.get() == "side-by-side") {
+ registrator.addListener("make-lines-equal-length-init-chunk", "chunk", initChunk);
+ registrator.addListener("make-lines-equal-length-calc-pad-length", "line", calcPadLength, ["collect-tab-sizes", "make-lines-equal-length-init-chunk"]);
+ registrator.addListener("make-lines-equal-length-sync-pad-length", "chunk-pair", syncPadLength, "make-lines-equal-length-calc-pad-length");
+ registrator.addListener("make-lines-equal-length", "line", padLines, "make-lines-equal-length-sync-pad-length");
+ registrator.addListener("make-lines-equal-length-close-chunk", "chunk", closeChunk, "make-lines-equal-length");
+ }
+
+ function syncPadLength(old_chunk, new_chunk) {
+ var maxLength = 0;
+
+ if (old_chunk) {
+ maxLength = Math.max(old_chunk.maxLineLength, maxLength);
+ }
+
+ if (new_chunk) {
+ maxLength = Math.max(new_chunk.maxLineLength, maxLength);
+ }
+ if (old_chunk) {
+ old_chunk.maxLineLength = maxLength;
+ }
+
+ if (new_chunk) {
+ new_chunk.maxLineLength = maxLength;
+ }
+ }
+
+ function calcPadLength(line, i, chunk) {
+ chunk.maxLineLength = Math.max(countLength(line, chunk.tab_sizes[i]), chunk.maxLineLength);
+ return line;
+ }
+
+ function initChunk(chunk) {
+ chunk.padding = new Array(chunk.code.length + 1);
+ chunk.maxLineLength = 0;
+ return chunk;
+ }
+
+ function padLines(line, i, chunk) {
+ var lineLength = countLength(line, chunk.tab_sizes[i]);
+
+ var p = colorediffsGlobal.pad("", chunk.maxLineLength - lineLength);
+
+ if (lineLength + p.length == 0) p = " ";
+ chunk.padding[i] = p;
+ return line;
+ }
+
+ function closeChunk(chunk) {
+ chunk.padding[chunk.padding.length - 1] = (colorediffsGlobal.pad("", chunk.maxLineLength)); //used if \No new line at end of file in old and new parts differs
+ delete chunk.maxLineLength;
+ return chunk;
+ }
+
+ function countLength(s, tab_sizes) {
+ if (s) {
+ var l = s.length;
+
+ if (tab_sizes) {
+ for (var i = 0; i < tab_sizes.length; i++) {
+ l += tab_sizes[i] - 1;
+ }
+ }
+
+ return l;
+ } else {
+ return 0;
+ }
+ }
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/replace-file-names-transformation.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/replace-file-names-transformation.js
new file mode 100644
index 0000000..8e27cfa
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/replace-file-names-transformation.js
@@ -0,0 +1,20 @@
+colorediffsGlobal.transformations.composite.members["replace-file-names"] = {
+ init: function(registrator, pref) {
+
+ registrator.addListener("replace-file-names", "file", replaceFilesInLog, "find-common-name");
+
+ function replaceFilesInLog(file, il) {
+ replace(file.common_name, file.id, il);
+
+ return file;
+ }
+
+
+ function replace(name, id, il) {
+ if (name) {
+ il.log = il.log.replace(new RegExp("([\\/\\.a-zA-Z0-9-]*\\b" + name.replace(".", "\\.", "g") + "\\b)"), "<a href='#" + id + "'>$1</a>");
+ }
+ }
+ }
+};
+
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/replace-tabs.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/replace-tabs.js
new file mode 100644
index 0000000..3da095b
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/replace-tabs.js
@@ -0,0 +1,23 @@
+colorediffsGlobal.transformations.composite.members["replace-tabs"] = {
+ init: function(registrator, pref) {
+ if ( (pref.showLineNumbers.get() || pref.tabSize.get() != 8) && !pref.showWhiteSpace.get()) {
+ registrator.addListener("replace-tabs", "line", replaceTabs, ["show-line-numbers", "show-whitespaces", "calc-tab-sizes"]);
+ }
+
+ function replaceTabs(line, index, chunk) {
+ var tab_sizes = chunk.tab_sizes[index];
+ if ( line ) {
+ var i = 0;
+ line = line.replace(
+ "\t",
+ function() {
+ return colorediffsGlobal.pad("", tab_sizes[i++]);
+ },
+ "g"
+ );
+
+ }
+ return line;
+ }
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/select-old-new-files.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/select-old-new-files.js
new file mode 100644
index 0000000..6b88aa9
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/select-old-new-files.js
@@ -0,0 +1,27 @@
+colorediffsGlobal.transformations.composite.members["select-old-new-files"] = {
+ init: function(registrator, pref) {
+
+ function register(func) {
+ registrator.addListener("select-old-new-files", "file", func, "find-common-name");
+ }
+
+
+ switch( pref.diffMode.get() ) {
+ case "new":
+ register(function(file) {return selectSide('old', file);});
+ break;
+ case "old":
+ register(function(file) {return selectSide('new', file);});
+ break;
+ }
+
+ function selectSide(side, file) {
+
+ if (file[side] && file[side].chunks) {
+ file[side].chunks = null;
+ }
+
+ return file;
+ }
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/show-line-numbers.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/show-line-numbers.js
new file mode 100644
index 0000000..da910f1
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/show-line-numbers.js
@@ -0,0 +1,87 @@
+colorediffsGlobal.transformations.composite.members["show-line-numbers"] = {
+ init: function(registrator, pref) {
+ if ( pref.showLineNumbers.get() ) {
+ registrator.addListener("show-line-numbers-calc-max-line-number", "chunk-pair", calcMaxLineNumber, "calc-chunk-size");
+ registrator.addListener("show-line-numbers-calc-init-chunk", "chunk", initChunk, "show-line-numbers-calc-max-line-number");
+ registrator.addListener("show-line-numbers", "line", addLineNumber, ["show-line-numbers-calc-init-chunk"]);
+ registrator.addListener("show-line-numbers-close-chunk", "chunk", closeChunk, "show-line-numbers");
+ }
+
+ function calcMaxLineNumber(old_chunk, new_chunk) {
+ var maxLineNumber = 0;
+
+ if ( old_chunk ) {
+ maxLineNumber = old_chunk.line + old_chunk.code_size - 1;
+ }
+
+ if ( new_chunk ) {
+ maxLineNumber = Math.max(new_chunk.line + new_chunk.code_size - 1, maxLineNumber);
+ }
+
+ var charsLength = countCharsLength(maxLineNumber);
+
+ if ( old_chunk ) {
+ old_chunk.charsLength = charsLength;
+ }
+
+ if ( new_chunk ) {
+ new_chunk.charsLength = charsLength;
+ }
+ }
+
+ function closeChunk(chunk) {
+ delete chunk.charsLength;
+ delete chunk.local_pad;
+ delete chunk.lineNumber;
+ }
+
+ function initChunk(chunk) {
+ if ( countCharsLength(chunk.line) != chunk.charsLength ) {
+ chunk.local_pad = pad;
+ } else {
+ chunk.local_pad = function(n) { return "" + n; };
+ }
+
+ chunk.lineNumber = chunk.line;
+ return chunk;
+ }
+
+ function addLineNumber(line, i, chunk) {
+ if ( line != null ) {
+ line = decorate(chunk.local_pad(chunk.lineNumber, chunk.charsLength)) + line;
+
+ chunk.lineNumber++;
+ } else if (chunk.padding && chunk.padding[i]) {
+ chunk.padding[i] = decoratePadding(colorediffsGlobal.pad("", chunk.charsLength)) + chunk.padding[i];
+ }
+
+ return line;
+ }
+
+ function decorate(s) {
+ return "<span style='border-right:solid 1px;border-left:solid 1px;margin-right:2px;padding-left:1px;padding-right:1px'>" + s + "</span>";
+ }
+
+ function decoratePadding(s) {
+ return "<span style='margin-right:4px;padding-left:1px;padding-right:1px'>" + s + "</span>";
+ }
+
+ //works for numbers > 0 only
+ function countCharsLength(n) {
+ var c = 1;
+ while( (n = Math.floor(n / 10)) > 0 ) { c++; }
+ return c;
+ }
+
+ function pad(n, length) {
+ var s = "" + n;
+ var nLength = countCharsLength(n);
+ while ( nLength < length ) {
+ s = " " + s;
+ nLength++;
+ }
+
+ return s;
+ }
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/show-whitespaces-transformation.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/show-whitespaces-transformation.js
new file mode 100644
index 0000000..9403ef8
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/show-whitespaces-transformation.js
@@ -0,0 +1,23 @@
+colorediffsGlobal.transformations.composite.members["show-whitespaces"] = {
+ init: function(registrator, pref) {
+ if (pref.showWhiteSpace.get()) {
+ registrator.addListener("show-whitespaces", "line", replaceWhitespaces, ["collect-tab-sizes"]);
+ }
+
+ function replaceWhitespaces(line, index, chunk) {
+ var tab_sizes = chunk.tab_sizes[index];
+ if ( line ) {
+ line = line.replace(" ", "·", "g");
+ var i = 0;
+ line = line.replace(
+ "\t",
+ function() {
+ return "»" + colorediffsGlobal.pad("", tab_sizes[i++] - 1);
+ },
+ "g"
+ );
+ }
+ return line;
+ }
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/transformations/truncate-file-names.js b/chrome/colorediffs.jar!/content/colorediffs/transformations/truncate-file-names.js
new file mode 100644
index 0000000..f65f4f8
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/transformations/truncate-file-names.js
@@ -0,0 +1,87 @@
+colorediffsGlobal.transformations.composite.members["truncate-file-names"] = {
+ init: function(registrator, pref) {
+
+ registrator.addListener("truncate-file-names", "file", truncateFileNames, ["find-common-name", "select-old-new-files"]);
+
+ function truncateFileNames(file, il) {
+ if (file.common_name) {
+ file.commonNameTruncated = truncateFileName(file.common_name, 80);
+ }
+
+ if (file['new'] && file['new'].name) {
+ file['new'].name15Truncated = truncateFileName(file['new'].name, 80);
+ if (pref.mode.get() == "unified" && file['old'] && file['old'].name) {
+ file['new'].name7Truncated = truncateFileName(file['new'].name, 30);
+ }
+ }
+
+ if (file['old'] && file['old'].name) {
+ file['old'].name15Truncated = truncateFileName(file['old'].name, 80);
+ if (pref.mode.get() == "unified" && file['new'] && file['new'].name) {
+ file['old'].name7Truncated = truncateFileName(file['old'].name, 30);
+ }
+ }
+
+ return file;
+ }
+
+ function truncateFileName(name, length) {
+ var nameLength = name.length;
+
+ length -= 3;
+
+ if ( nameLength <= length ) {
+ return name;
+ } else {
+ var nextIndex = -1;
+ var lastIndex = nameLength;
+ do {
+ var a = skipLastComponent();
+ var b = skipNextComponent();
+ } while(a || b);
+
+ if ( nextIndex == lastIndex ) {
+ return name;
+ } else {
+ return name.substring(0, nextIndex + 1) + "..." + name.substring(lastIndex);
+ }
+ }
+
+
+ function skipNextComponent() {
+ var i1 = name.indexOf("/", nextIndex + 1);
+ var i2 = name.indexOf("\\", nextIndex + 1);
+
+ var i = Math.max(i1, i2);
+
+ if ( i > 0 && nextIndex <= lastIndex && calcLenght(i, lastIndex) <= length ) {
+ nextIndex = i;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function skipLastComponent() {
+ var i1 = name.lastIndexOf("/", lastIndex - 1);
+ var i2 = name.lastIndexOf("\\", lastIndex - 1);
+
+ var i = Math.max(i1, i2);
+
+ if ( i > 0 && nextIndex <= lastIndex && calcLenght(nextIndex, i) <= length ) {
+ lastIndex = i;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function calcLenght(nextIndex, lastIndex) {
+ return nameLength - lastIndex + nextIndex + 1;
+ }
+
+ return name;
+ }
+
+ }
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/views/context-view.js b/chrome/colorediffs.jar!/content/colorediffs/views/context-view.js
new file mode 100644
index 0000000..b32c3ba
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/views/context-view.js
@@ -0,0 +1,243 @@
+
+colorediffsGlobal.views["context"] = {
+ render: function(il, pref, dom) {
+ var me = colorediffsGlobal;
+
+ return [
+ function() {
+ var colorStyle = function(style, prop) {
+ return "." + style + " {" + pref.getColorProps(prop) + "}\n";
+ }
+
+ var stylecontent = "";
+
+ stylecontent += colorStyle("linetag", "diffColorer.c_anchor");
+ stylecontent += colorStyle("addline", "diffColorer.c_addedLine");
+ stylecontent += colorStyle("delline", "diffColorer.c_deletedLine");
+ stylecontent += colorStyle("steadyline", "diffColorer.c_steadyLine");
+ stylecontent += colorStyle("title", "diffColorer.c_title");
+ stylecontent += colorStyle("precode", "diffColorer.c_precode");
+ //stylecontent += ".addline {color: red;}\n";
+ stylecontent += "pre {font-family:monospace;}\n";
+ stylecontent += ".title, .linetag, .diffs, .addline, .delline, .precode {margin:0;}\n";
+ return dom.createElement("style", null, stylecontent);
+ }(),
+ dom.createDocumentFragment(
+ dom.createElement("pre", {id:'log', 'class':'log', wrap: ""}, il.log),
+ il.files.map(function(file) {
+ return dom.createElement(
+ "div", {'class':'file-diff', title:file.commonNameTruncated, id:file.id, width:"100%"},
+ dom.createElement(
+ "pre", {'class':'title', wrap: ""},
+ file.title + "\n======================================="
+ ),
+ dom.createElement(
+ "pre", {'class':'precode', wrap: ""},
+ file.additional_info
+ ),
+ function () {
+ if (file['old'].chunks || file['new'].chunks) {
+ var old_name;
+ var new_name;
+ var old_version;
+ var new_version;
+
+ if ( file['old'] && file['old'].name ) {
+ old_name = file['old'].name;
+ old_version = (file['old'].version) ? "\t" + file['old'].version : "";
+ } else {
+ old_name = file['new'].name;
+ old_version = "";
+ }
+
+ if ( file['new'] && file['new'].name ) {
+ new_name = file['new'].name;
+ new_version = (file['new'].version) ? "\t" + file['new'].version : "";
+ } else {
+ new_name = file['old'].name;
+ new_version = "";
+ }
+
+
+ return [dom.createElement(
+ "pre", {'class':'delline'},
+ "*** " + old_name + old_version
+ ),
+ dom.createElement(
+ "pre", {'class':'addline'},
+ "--- " + new_name + new_version
+ )];
+ } else {
+ return null;
+ }
+ }(),
+ me.ilUtils.chunksMap(file, function(old_chunk, new_chunk) {
+ if (old_chunk == null) {
+ old_chunk = gen_empty_chunk(new_chunk);
+ }
+
+ if (new_chunk == null) {
+ new_chunk = gen_empty_chunk(old_chunk);
+ }
+
+ var oldCodeDecorated = [];
+ var newCodeDecorated = [];
+
+ var oldCodeDecoratedDelayed = [];
+ var newCodeDecoratedDelayed = [];
+
+ var oldLine = old_chunk.line;
+ var newLine = new_chunk.line;
+
+ var oldCode = old_chunk.code.concat([]); //copy array
+ var newCode = new_chunk.code.concat([]); //copy array
+
+ if (old_chunk.doesnt_have_new_line != new_chunk.doesnt_have_new_line) {
+ oldCode.pop();newCode.pop();
+ }
+
+ oldCode.push("");newCode.push("");
+
+ var onlyNew = true;
+ var onlyOld = true;
+ var l = oldCode.length;
+
+ for (var i=0; i < l; ++i) {
+ if ( oldCode[i] == newCode[i] ) {
+ if (oldCodeDecoratedDelayed.length == 0 && newCodeDecoratedDelayed.length != 0) {
+ newCodeDecorated = newCodeDecorated.concat(newCodeDecoratedDelayed);
+ onlyOld = false;
+ } else if (newCodeDecoratedDelayed.length == 0 && oldCodeDecoratedDelayed.length != 0) {
+ oldCodeDecorated = oldCodeDecorated.concat(oldCodeDecoratedDelayed);
+ onlyNew = false;
+ } else if (newCodeDecoratedDelayed.length != 0 && oldCodeDecoratedDelayed.length != 0) {
+ newCodeDecorated = newCodeDecorated.concat(
+ newCodeDecoratedDelayed.map(
+ function(line) {
+ return line.replace(">+ ", ">! ");
+ }
+ ));
+ oldCodeDecorated = oldCodeDecorated.concat(
+ oldCodeDecoratedDelayed.map(
+ function(line) {
+ return line.replace(">- ", ">! ");
+ }
+ ));
+
+ onlyNew = false;
+ onlyOld = false;
+ }
+
+ newCodeDecoratedDelayed = [];
+ oldCodeDecoratedDelayed = [];
+
+ var line = oldCode[i];
+
+ oldCodeDecorated.push("<div class='steadyline' title='" + file['old'].name15Truncated + ":" + oldLine + "'> " + line +" </div>");
+ newCodeDecorated.push("<div class='steadyline' title='" + file['new'].name15Truncated + ":" + newLine + "'> " + line +" </div>");
+
+ newLine++;
+ oldLine++;
+ } else {
+ if ( newCode[i] != null ) {
+ var line = newCode[i];
+ newCodeDecoratedDelayed.push("<div class='addline' title='" + file['new'].name15Truncated + ":" + newLine + "'>+ " + line +" </div>");
+ newLine++;
+ }
+ if ( oldCode[i] != null ) {
+ var line = oldCode[i];
+ oldCodeDecoratedDelayed.push("<div class='delline' title='" + file['old'].name15Truncated + ":" + oldLine + "'>- " + line +" </div>");
+ oldLine++;
+ }
+ }
+ }
+
+ oldCodeDecorated.pop(); newCodeDecorated.pop();
+
+ if (old_chunk.doesnt_have_new_line) {
+ oldCodeDecorated.push("<div class='steadyline' title='" + file['old'].name15Truncated + "'>\\ No newline at end of file</div>");
+ }
+
+ if (new_chunk.doesnt_have_new_line) {
+ newCodeDecorated.push("<div class='steadyline' title='" + file['new'].name15Truncated + "'>\\ No newline at end of file</div>");
+ }
+
+
+ if ( onlyOld ) {
+ newCodeDecorated = [];
+ }
+
+ if ( onlyNew ) {
+ oldCodeDecorated = [];
+ }
+
+ return [
+ dom.createElement(
+ "pre", {'class':'linetag'},
+ "***************"
+ ),
+ dom.createElement(
+ "pre", {'class':'linetag'},
+ "*** " +
+ old_chunk.line +
+ "," + old_chunk.code_size +
+ " ****"
+ ),
+ function() {
+ if (onlyNew) {
+ return null;
+ } else {
+ return dom.createElement(
+ "pre", {'class':'diffs'},
+ oldCodeDecorated.join("")
+ );
+ }
+ },
+ dom.createElement(
+ "pre", {'class':'linetag'},
+ "--- " +
+ new_chunk.line +
+ "," + new_chunk.code_size +
+ " ----"
+ ),
+ function() {
+ if (onlyOld) {
+ return null;
+ } else {
+ return dom.createElement(
+ "pre", {'class':'diffs'},
+ newCodeDecorated.join("")
+ );
+ }
+ }
+ ];
+ }
+ ),
+ dom.createElement(
+ "pre", {},
+ ""
+ )
+ );
+ }
+ ),
+ dom.createElement(
+ "pre", {wrap: ""},
+ il.postfix || ""
+ )
+ )
+ ];
+
+
+ function gen_empty_chunk(oposite_chunk) {
+ var chunk = {line:0, code:[], code_size:0};
+ for (var i = 0; i < oposite_chunk.code.length; i++ ) {
+ chunk.code.push(null);
+ }
+ return chunk;
+ }
+
+ //Seriously, that bug is annoying.
+ return null;
+ },
+ getPropertyPageId: function() {return "context-view-options";}
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/views/main-view.js b/chrome/colorediffs.jar!/content/colorediffs/views/main-view.js
new file mode 100644
index 0000000..c5cd7b0
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/views/main-view.js
@@ -0,0 +1,3 @@
+colorediffsGlobal.render = function(il, pref, dom) {
+ return colorediffsGlobal.views[pref.mode.get()].render(il, pref, dom);
+}
diff --git a/chrome/colorediffs.jar!/content/colorediffs/views/side-by-side-view.js b/chrome/colorediffs.jar!/content/colorediffs/views/side-by-side-view.js
new file mode 100644
index 0000000..70cdbfc
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/views/side-by-side-view.js
@@ -0,0 +1,335 @@
+
+colorediffsGlobal.views["side-by-side"] = {
+ render: function(il, pref, dom) {
+ var me = colorediffsGlobal;
+
+ function createCodeElement (side, code) {
+ var e = dom.createElement("pre", {'class':side}, code);
+ e.addEventListener("scroll", function(evt) {colorediffsGlobal.scrollCallback(evt);}, false);
+ return e;
+ }
+
+ function pcp(str) {
+ return str.replace(/\$cp{(.*?)}/g, function(str, prop) {
+ return pref.getColorProps(prop.trim());
+ });
+ }
+
+ function createCodeLine(klass, title, code) {
+ var t = (title)?"title='" + title + "'" : "";
+ return "<span class='" + klass + "' " + t + ">" + code + "</span>\n";
+ }
+
+ return [
+ function() {
+ var stylecontent = "";
+ stylecontent += " .log {$cp{diffColorer.sbs_log }; padding: 5px; border: 1px solid black;overflow:auto;}\n";
+ stylecontent += " .file-diff {$cp{diffColorer.sbs_file-diff }; padding: 3px;margin:5px;border: 1px solid black; table-layout: fixed;}\n";
+ stylecontent += " .title {$cp{diffColorer.sbs_title };padding: 5px; margin:0; overflow:auto; border: 1px solid black;}\n";
+ stylecontent += " .pre-code {$cp{diffColorer.sbs_precode }; margin:0;overflow:auto;}\n";
+ stylecontent += " .addline {$cp{diffColorer.sbs_addedLine }; margin-left:5px;margin-right:5px;}\n";
+ stylecontent += " .delline {$cp{diffColorer.sbs_deletedLine}; margin-left:5px;margin-right:5px;}\n";
+ stylecontent += " .steadyline {$cp{diffColorer.sbs_steadyLine }; margin-left:5px;margin-right:5px;}\n";
+ stylecontent += " .linetag {$cp{diffColorer.sbs_anchor }; text-align:center;clear:left;margin:0;}\n";
+ stylecontent += " .left {$cp{diffColorer.sbs_left };margin:0; overflow:auto; border: 1px solid black;padding-top:5px;padding-bottom:5px;}\n";
+ stylecontent += " .right {$cp{diffColorer.sbs_right };margin:0; overflow:auto; border: 1px solid black;padding-top:5px;padding-bottom:5px;}\n";
+ stylecontent += " .left-title {$cp{diffColorer.sbs_left-title };padding: 0; margin:0; overflow:auto; border: 1px solid black;}\n";
+ stylecontent += " .right-title {$cp{diffColorer.sbs_right-title};padding: 0; margin:0; overflow:auto; border: 1px solid black;}\n";
+ stylecontent += " .left .addline {$cp{diffColorer.sbs_emptyLine };color: green;}\n";
+ stylecontent += " .right .delline {$cp{diffColorer.sbs_emptyLine };color: green;}\n";
+
+ return dom.createElement("style", null, pcp(stylecontent));
+ }(),
+ dom.createDocumentFragment(
+ dom.createElement("pre", {id:'log', 'class':'log', wrap: ""}, il.log),
+ il.files.map(function(file) {
+
+ return dom.createElement(
+ "table", {'class':'file-diff', title:file.commonNameTruncated, id:file.id, width:"99%", align:"center"},
+ dom.createElement(
+ "tr", {},
+ dom.createElement(
+ "td", {colspan:2},
+ dom.createElement(
+ "pre", {'class':'title', wrap: ""},
+ file.title
+ )
+ )
+ ),
+ dom.createElement(
+ "tr", {'class':'pre-code'},
+ dom.createElement(
+ "td", {colspan:2},
+ dom.createElement(
+ "pre", {'class':'pre-code', wrap: ""},
+ file.additional_info
+ )
+ )
+ ),
+ function() {
+ if ( file['old'] && file['old'].chunks && file['new'] && file['new'].chunks ) {
+ return side_by_side_file(file);
+ } else if ( file['old'] && file['old'].chunks ) {
+ return standalone_file(file, 'old');
+ } else if ( file['new'] && file['new'].chunks ) {
+ return standalone_file(file, 'new');
+ } else {
+ return null;
+ }
+ } ()
+ );
+ }
+ ),
+ dom.createElement(
+ "pre", {wrap: "", style: "overflow:auto;"},
+ il.postfix || ""
+ )
+ )
+ ];
+
+ function side_by_side_file(file) {
+ var old_version = (file['old'].version) ? "\t" + file['old'].version : "";
+ var new_version = (file['new'].version) ? "\t" + file['new'].version : "";
+
+ var old_title = (file['old'].name + old_version).replace(" ", " ", "g");
+ var new_title = (file['new'].name + new_version).replace(" ", " ", "g");
+
+ return [
+ dom.createElement(
+ "tr", {},
+ dom.createElement(
+ "td", {valign:'top', width:'50%'},
+ dom.createElement(
+ 'pre', {'class':'left-title', wrap: ""},
+ dom.createElement('div', {style: 'padding:5px'}, old_title))
+ ),
+ dom.createElement(
+ "td", {valign:'top', width:'50%'},
+ dom.createElement(
+ 'pre', {'class':'right-title', wrap: ""},
+ dom.createElement('div', {style: 'padding:5px'}, new_title))
+ )
+ ),
+ me.ilUtils.chunksMap(file, function(old_chunk, new_chunk) {
+ var prev_old_class = null;
+ var prev_new_class = null;
+
+
+ function startCodeBlockIfNeeded(old_class, new_class) {
+ if (old_class != prev_old_class) {
+ if (prev_old_class) {
+ oldCodeDecorated += "</div>";
+ }
+ oldCodeDecorated += "<div class='" + old_class + "'>";
+ prev_old_class = old_class;
+ }
+ if (new_class != prev_new_class) {
+ if (prev_new_class) {
+ newCodeDecorated += "</div>";
+ }
+ newCodeDecorated += "<div class='" + new_class + "'>";
+ prev_new_class = new_class;
+ }
+ }
+
+ var oldCodeDecorated = "";
+ var newCodeDecorated = "";
+ var oldLine = old_chunk.line;
+ var newLine = new_chunk.line;
+
+ var oldCode = old_chunk.code;
+ var newCode = new_chunk.code;
+
+ var oldPadding = old_chunk.padding;
+ var newPadding = new_chunk.padding;
+
+ var l = old_chunk.code.length;
+
+ for (var i=0; i < l; ++i) {
+ var oldCodeLine = oldCode[i] + oldPadding[i];
+ var newCodeLine = newCode[i] + newPadding[i];
+
+ switch( old_chunk.status[i] ) {
+ case "A": //Added
+ startCodeBlockIfNeeded('addline', 'addline');
+ oldCodeDecorated += createCodeLine('addline', null, oldPadding[i]);
+ newCodeDecorated += createCodeLine('addline', file['new'].name15Truncated + ":" + newLine, newCodeLine);
+ newLine++;
+ break;
+ case "D": //Deleted
+ startCodeBlockIfNeeded('delline', 'delline');
+ newCodeDecorated += createCodeLine('delline', null, newPadding[i]);
+ oldCodeDecorated += createCodeLine('delline', file['old'].name15Truncated + ":" + oldLine, oldCodeLine);
+ oldLine++;
+ break;
+ case "C": //Changed
+ startCodeBlockIfNeeded('delline', 'addline');
+ oldCodeDecorated += createCodeLine('delline', file['old'].name15Truncated + ":" + oldLine, oldCodeLine);
+ newCodeDecorated += createCodeLine('addline', file['new'].name15Truncated + ":" + newLine, newCodeLine);
+ newLine++;
+ oldLine++;
+ break;
+ case "S": //the Same
+ startCodeBlockIfNeeded('steadyline', 'steadyline');
+ oldCodeDecorated += createCodeLine('steadyline', file['old'].name15Truncated + ":" + oldLine, oldCodeLine);
+ newCodeDecorated += createCodeLine('steadyline', file['new'].name15Truncated + ":" + newLine, newCodeLine);
+ newLine++;
+ oldLine++;
+ break;
+ }
+ }
+
+ if (old_chunk.doesnt_have_new_line && !new_chunk.doesnt_have_new_line) {
+ startCodeBlockIfNeeded('addline', 'addline');
+ newCodeDecorated += createCodeLine('addline', file['new'].name15Truncated + ":" + newLine, newPadding[i]);
+ oldCodeDecorated += createCodeLine('addline', file['old'].name15Truncated, oldPadding[i]);
+ }
+
+ if (!old_chunk.doesnt_have_new_line && new_chunk.doesnt_have_new_line) {
+ startCodeBlockIfNeeded('delline', 'delline');
+ newCodeDecorated += createCodeLine('delline', file['new'].name15Truncated, newPadding[i]);
+ oldCodeDecorated += createCodeLine('delline', file['old'].name15Truncated + ":" + oldLine, oldPadding[i]);
+ }
+
+ oldCodeDecorated += "</div>";
+ newCodeDecorated += "</div>";
+
+ return [
+ dom.createElement(
+ "tr", {'class':'linetag'},
+ dom.createElement("td", {colspan:2},
+ "@@ -" + old_chunk.line +
+ "," + old_chunk.code_size +
+ " +" +new_chunk.line +
+ "," + new_chunk.code_size +
+ " @@")
+ ),
+ dom.createElement(
+ "tr", {'class':'diffs'},
+ dom.createElement(
+ "td", {valign:'top', width:'50%'},
+ createCodeElement('left', oldCodeDecorated)
+ ),
+ dom.createElement(
+ "td", {valign:'top', width:'50%'},
+ createCodeElement('right', newCodeDecorated)
+ )
+ )
+ ];
+ }
+ )
+ ];
+ }
+
+ function standalone_file(file, side) {
+ var version = (file[side].version) ? "\t" + file[side].version : "";
+
+ switch(side) {
+ case "new":
+ var changedClass = "addline";
+ var ignoredTag = "D";
+ var anchorSign = "+";
+ var sideClass = "right";
+ break;
+ case "old":
+ var changedClass = "delline";
+ var ignoredTag = "A";
+ var anchorSign = "-";
+ var sideClass = "left";
+ break;
+ }
+
+ return [
+ dom.createElement(
+ "tr", {},
+ dom.createElement(
+ "td", {valign:'top', colspan:'2'},
+ dom.createElement(
+ 'pre', {'class':sideClass+"-title", wrap: ""},
+ dom.createElement('div', {style: 'padding:5px'}, file[side].name + version)
+ )
+ )
+ ),
+ file[side].chunks.map(function(chunk) {
+ function getDecoratedLine(decoratedClass, code, line) {
+ return createCodeLine(decoratedClass, file[side].name15Truncated + ":" + line, code);
+ }
+
+ var prev_class = null;
+
+ function startCodeBlockIfNeeded(klass) {
+ if (klass != prev_class) {
+ if (prev_class) {
+ codeDecorated += "</div>";
+ }
+ codeDecorated += "<div class='" + klass + "'>";
+ prev_class = klass;
+ }
+ }
+
+ var codeDecorated = "";
+ var line = chunk.line;
+
+ var code = chunk.code;
+ var padding = chunk.padding;
+
+ var l = chunk.code.length;
+
+ for (var i=0; i < l; ++i) {
+ var codeLine = code[i] + padding[i];
+
+ if ( codeLine == "" ) {
+ codeLine = " ";
+ }
+
+ switch( chunk.status[i] ) {
+ case "A": //Added
+ case "D": //Deleted
+ case "C": //Changed
+ startCodeBlockIfNeeded(changedClass);
+ if (ignoredTag != chunk.status[i]) {
+ codeDecorated += getDecoratedLine(changedClass, codeLine, line);
+ line++;
+ }
+ break;
+ case "S": //the Same
+ startCodeBlockIfNeeded('steadyline');
+ codeDecorated += getDecoratedLine('steadyline', codeLine, line);
+ line++;
+ break;
+ }
+
+ }
+
+ if (chunk.doesnt_have_new_line) {
+ startCodeBlockIfNeeded('steadyline');
+ codeDecorated += createCodeLine('steadyline', file.name15Truncated, "\\ No newline at end of file");
+ }
+
+ codeDecorated += "</div>";
+
+ return [
+ dom.createElement(
+ "tr", {'class':'linetag'},
+ dom.createElement("td", {colspan:'2'},
+ "@@ " + anchorSign + chunk.line +
+ "," + chunk.code_size +
+ " @@")
+ ),
+ dom.createElement(
+ "tr", {'class':'diffs'},
+ dom.createElement(
+ "td", {valign:'top', colspan:'2'},
+ dom.createElement("pre", {'class':sideClass}, codeDecorated)
+ )
+ )
+ ];
+ }
+ )
+ ];
+ }
+
+ return null;
+ },
+ getPropertyPageId: function() {return "side-by-side-view-options";}
+};
diff --git a/chrome/colorediffs.jar!/content/colorediffs/views/unified-view.js b/chrome/colorediffs.jar!/content/colorediffs/views/unified-view.js
new file mode 100644
index 0000000..1d5f1cd
--- /dev/null
+++ b/chrome/colorediffs.jar!/content/colorediffs/views/unified-view.js
@@ -0,0 +1,219 @@
+
+colorediffsGlobal.views["unified"] = {
+ render: function(il, pref, dom) {
+ var me = colorediffsGlobal;
+
+ return [
+ function() {
+ var colorStyle = function(style, prop) {
+ return "." + style + " {" + pref.getColorProps(prop) + "}\n";
+ }
+
+ var stylecontent = "";
+
+ stylecontent += colorStyle("linetag", "diffColorer.anchor");
+ stylecontent += colorStyle("addline", "diffColorer.addedLine");
+ stylecontent += colorStyle("delline", "diffColorer.deletedLine");
+ stylecontent += colorStyle("steadyline", "diffColorer.steadyLine");
+ stylecontent += colorStyle("title", "diffColorer.title");
+ stylecontent += colorStyle("precode", "diffColorer.precode");
+ //stylecontent += ".addline {color: red;}\n";
+ stylecontent += "pre {font-family:monospace;}\n";
+ stylecontent += ".title, .linetag, .diffs, .addline, .delline, .precode {margin:0;}\n";
+ return dom.createElement("style", null, stylecontent);
+ }(),
+ dom.createDocumentFragment(
+ dom.createElement("pre", {id:'log', 'class':'log', wrap: ""}, il.log),
+ il.files.map(function(file) {
+ return dom.createElement(
+ "div", {'class':'file-diff', title:file.commonNameTruncated, id:file.id, width:"100%"},
+ dom.createElement(
+ "pre", {'class':'title', wrap: ""},
+ file.title + "\n======================================="
+ ),
+ dom.createElement(
+ "pre", {'class':'precode', wrap: ""},
+ file.additional_info
+ ),
+ function () {
+ if (file['old'].chunks || file['new'].chunks) {
+ var old_name;
+ var new_name;
+ var old_version;
+ var new_version;
+
+ if ( file['old'] && file['old'].name ) {
+ old_name = file['old'].name;
+ old_version = (file['old'].version) ? "\t" + file['old'].version : "";
+ } else {
+ old_name = file['new'].name;
+ old_version = "";
+ }
+
+ if ( file['new'] && file['new'].name ) {
+ new_name = file['new'].name;
+ new_version = (file['new'].version) ? "\t" + file['new'].version : "";
+ } else {
+ new_name = file['old'].name;
+ new_version = "";
+ }
+
+
+ return [dom.createElement(
+ "pre", {'class':'delline'},
+ "--- " + old_name + old_version
+ ),
+ dom.createElement(
+ "pre", {'class':'addline'},
+ "+++ " + new_name + new_version
+ )];
+ } else {
+ return null;
+ }
+ }(),
+ me.ilUtils.chunksMap(file, function(old_chunk, new_chunk) {
+ var only_new = false;
+ var only_old = false;
+
+
+ if (old_chunk == null) {
+ only_new = true;
+ old_chunk = gen_empty_chunk(new_chunk);
+ }
+
+ if (new_chunk == null) {
+ only_old = true;
+ new_chunk = gen_empty_chunk(old_chunk);
+ }
+
+ var codeDecorated = [];
+ var oldCodeDecorated = [];
+ var newCodeDecorated = [];
+
+ var oldLine = old_chunk.line;
+ var newLine = new_chunk.line;
+
+ var oldCode = old_chunk.code; //.concat([]); //do not copy array;
+ var newCode = new_chunk.code; //.concat([]); //do not copy array
+
+ var l = new_chunk.code.length;
+
+ for (var i=0; i < l; ++i) {
+ switch( new_chunk.status[i] ) {
+ case "A": //Added
+ var line = newCode[i];
+
+ newCodeDecorated.push("<div class='addline' title='" + file['new'].name15Truncated + ":" + newLine + "'>+" + line +" </div>");
+ newLine++;
+ break;
+ case "D": //Deleted
+ var line = oldCode[i];
+
+ oldCodeDecorated.push("<div class='delline' title='" + file['old'].name15Truncated + ":" + oldLine + "'>-" + line +" </div>");
+ oldLine++;
+ break;
+ case "C": //Changed
+ newCodeDecorated.push("<div class='addline' title='" + file['new'].name15Truncated + ":" + newLine + "'>+" + newCode[i] +" </div>");
+ oldCodeDecorated.push("<div class='delline' title='" + file['old'].name15Truncated + ":" + oldLine + "'>-" + oldCode[i] +" </div>");
+ newLine++;
+ oldLine++;
+ break;
+ case "S": //the Same
+ if ( !only_new ) {
+ codeDecorated = codeDecorated.concat(oldCodeDecorated);
+ }
+
+ if ( !only_old ) {
+ codeDecorated = codeDecorated.concat(newCodeDecorated);
+ }
+
+ oldCodeDecorated = [];
+ newCodeDecorated = [];
+
+ if ( only_old ) {
+ var line = oldCode[i];
+ var tooltip = file['old'].name15Truncated + ':' + oldLine;
+ } else if (only_new) {
+ var line = newCode[i];
+ var tooltip = file['new'].name15Truncated + ':' + newLine;
+ } else {
+ var line = newCode[i];
+ var tooltip = "old: " + file['old'].name7Truncated + ':' + oldLine + ", " +
+ "new: " + file['new'].name7Truncated + ':' + newLine;
+ }
+
+ codeDecorated.push("<div class='steadyline' title='" + tooltip + "'> " + line +" </div>");
+
+ newLine++;
+ oldLine++;
+ break;
+ }
+ }
+
+ if (old_chunk.doesnt_have_new_line && !new_chunk.doesnt_have_new_line) {
+ oldCodeDecorated.push("<div class='steadyline' title='" + file['old'].name15Truncated + "'>\\ No newline at end of file</div>");
+ }
+
+ if (!old_chunk.doesnt_have_new_line && new_chunk.doesnt_have_new_line) {
+ newCodeDecorated.push("<div class='steadyline' title='" + file['new'].name15Truncated + "'>\\ No newline at end of file</div>");
+ }
+
+ if ( !only_new ) {
+ codeDecorated = codeDecorated.concat(oldCodeDecorated);
+ }
+
+ if ( !only_old ) {
+ codeDecorated = codeDecorated.concat(newCodeDecorated);
+ }
+
+ if (old_chunk.doesnt_have_new_line && new_chunk.doesnt_have_new_line) {
+ codeDecorated.push("<div class='steadyline' title='" + file.commonNameTruncated + "'>\\ No newline at end of file</div>");
+ }
+
+ return [
+ dom.createElement(
+ "pre", {'class':'linetag'},
+ "@@ -" + old_chunk.line +
+ "," + old_chunk.code_size +
+ " +" +new_chunk.line +
+ "," + new_chunk.code_size +
+ " @@"
+ ),
+ dom.createElement(
+ "pre", {'class':'diffs'},
+ codeDecorated.join("")
+ )
+ ];
+ }
+ ),
+ dom.createElement(
+ "pre", {},
+ ""
+ )
+ );
+ }
+ ),
+ dom.createElement(
+ "pre", {wrap: ""},
+ il.postfix || ""
+ )
+ )
+ ];
+
+
+ function gen_empty_chunk(oposite_chunk) {
+ var chunk = {line:0, code:[], code_size:0};
+ for (var i = 0; i < oposite_chunk.code.length; i++ ) {
+ chunk.code.push(null);
+ }
+
+ chunk.status = oposite_chunk.status;
+
+ return chunk;
+ }
+
+ //Seriously, that bug is annoying.
+ return null;
+ },
+ getPropertyPageId: function() {return "unified-view-options";}
+};
diff --git a/chrome/colorediffs.jar!/skin/colorediffs.css b/chrome/colorediffs.jar!/skin/colorediffs.css
new file mode 100644
index 0000000..f233721
--- /dev/null
+++ b/chrome/colorediffs.jar!/skin/colorediffs.css
@@ -0,0 +1,17 @@
+#colorediffs-show-whitespaces {
+ list-style-image: url("chrome://colorediffs/skin/white-space.png");
+}
+
+#colorediffs-options {
+ list-style-image: url("chrome://colorediffs/skin/options.png");
+}
+
+#colorediffs-show-line-numbers {
+ list-style-image: url("chrome://colorediffs/skin/line-numbers.png");
+}
+
+#colorediffs-close-toolbar {
+ /*-moz-image-region: rect(0px, 48px, 16px, 32px);*/
+ height: 24px;
+ list-style-image: url("chrome://global/skin/icons/Close.gif");
+}
\ No newline at end of file
diff --git a/chrome/colorediffs.jar!/skin/line-numbers.png b/chrome/colorediffs.jar!/skin/line-numbers.png
new file mode 100644
index 0000000..7946357
Binary files /dev/null and b/chrome/colorediffs.jar!/skin/line-numbers.png differ
diff --git a/chrome/colorediffs.jar!/skin/options.png b/chrome/colorediffs.jar!/skin/options.png
new file mode 100644
index 0000000..a6d18d8
Binary files /dev/null and b/chrome/colorediffs.jar!/skin/options.png differ
diff --git a/chrome/colorediffs.jar!/skin/white-space.png b/chrome/colorediffs.jar!/skin/white-space.png
new file mode 100644
index 0000000..8b66ca0
Binary files /dev/null and b/chrome/colorediffs.jar!/skin/white-space.png differ
diff --git a/defaults/preferences/colorediffs.js b/defaults/preferences/colorediffs.js
new file mode 100644
index 0000000..79f3a5a
--- /dev/null
+++ b/defaults/preferences/colorediffs.js
@@ -0,0 +1,66 @@
+pref("diffColorer.anchor_fg", "blue");
+pref("diffColorer.anchor_bg", "white");
+pref("diffColorer.steadyLine_fg", "grey");
+pref("diffColorer.steadyLine_bg", "white");
+pref("diffColorer.deletedLine_fg", "red");
+pref("diffColorer.deletedLine_bg", "white");
+pref("diffColorer.addedLine_fg", "green");
+pref("diffColorer.addedLine_bg", "white");
+pref("diffColorer.title_fg", "#840084");
+pref("diffColorer.title_bg", "white");
+pref("diffColorer.precode_fg", "lightgrey");
+pref("diffColorer.precode_bg", "white");
+
+pref("diffColorer.c_anchor_fg", "blue");
+pref("diffColorer.c_anchor_bg", "white");
+pref("diffColorer.c_steadyLine_fg", "grey");
+pref("diffColorer.c_steadyLine_bg", "white");
+pref("diffColorer.c_deletedLine_fg", "red");
+pref("diffColorer.c_deletedLine_bg", "white");
+pref("diffColorer.c_addedLine_fg", "green");
+pref("diffColorer.c_addedLine_bg", "white");
+pref("diffColorer.c_title_fg", "#840084");
+pref("diffColorer.c_title_bg", "white");
+pref("diffColorer.c_precode_fg", "lightgrey");
+pref("diffColorer.c_precode_bg", "white");
+
+pref("diffColorer.sbs_anchor_fg", "blue");
+pref("diffColorer.sbs_anchor_bg", "#DDFF88");
+pref("diffColorer.sbs_steadyLine_fg", "#484848");
+pref("diffColorer.sbs_steadyLine_bg", "#EFEFEF");
+pref("diffColorer.sbs_deletedLine_fg", "#4F0000");
+pref("diffColorer.sbs_deletedLine_bg", "#EFAAAA");
+pref("diffColorer.sbs_addedLine_fg", "#004F00");
+pref("diffColorer.sbs_addedLine_bg", "#AAEFAA");
+pref("diffColorer.sbs_title_fg", "#000025");
+pref("diffColorer.sbs_title_bg", "#9988FF");
+pref("diffColorer.sbs_log_fg", "black");
+pref("diffColorer.sbs_log_bg", "lightgray");
+pref("diffColorer.sbs_file-diff_fg", "white");
+pref("diffColorer.sbs_file-diff_bg", "#DDFF88");
+pref("diffColorer.sbs_precode_fg", "gray");
+pref("diffColorer.sbs_precode_bg", "#DDFF88");
+pref("diffColorer.sbs_left-title_fg", "#4F0000");
+pref("diffColorer.sbs_left-title_bg", "#EFAAAA");
+pref("diffColorer.sbs_right-title_fg", "#004F00");
+pref("diffColorer.sbs_right-title_bg", "#AAEFAA");
+pref("diffColorer.sbs_right_fg", "white");
+pref("diffColorer.sbs_right_bg", "#EFEFEF");
+pref("diffColorer.sbs_left_fg", "white");
+pref("diffColorer.sbs_left_bg", "#EFEFEF");
+pref("diffColorer.sbs_emptyLine_fg", "white");
+pref("diffColorer.sbs_emptyLine_bg", "#997777");
+
+pref("diffColorer.view-mode", "unified");
+pref("diffColorer.debug-mode", false);
+pref("diffColorer.show-whitespace", true);
+pref("diffColorer.show-toolbar", true);
+
+pref("diffColorer.parser.max-title-size", 5);
+pref("diffColorer.parser.min-title-delimiter-chars-count", 15);
+pref("diffColorer.parser.max-additional-info-size", 7);
+pref("diffColorer.parser.max-postfix-size", 15);
+
+pref("diffColorer.diff-mode", "both");
+pref("diffColorer.show-line-numbers", false);
+pref("diffColorer.tab-size", 8);
diff --git a/install.rdf b/install.rdf
new file mode 100644
index 0000000..70ff770
--- /dev/null
+++ b/install.rdf
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
+ xmlns:NC="http://home.netscape.com/NC-rdf#"
+ xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <RDF:Description RDF:about="urn:mozilla:install-manifest"
+ em:id="{282C3C7A-15A8-4037-A30D-BBEB17FFC76B}"
+ em:name="Colored Diffs"
+ em:version="0.6.2012.01.27.14.07.45"
+ em:creator="Vadim Atlygin"
+ em:description="Color diffs sent by SVN/CVS notifications."
+ em:homepageURL="http://code.google.com/p/colorediffs/"
+ em:iconURL="chrome://colorediffs/content/icon.png"
+ em:optionsURL="chrome://colorediffs/content/options/options.xul"
+ >
+ <em:targetApplication>
+ <RDF:Description>
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
+ <em:maxVersion>10.*</em:maxVersion>
+ <em:minVersion>3.0a1pre</em:minVersion>
+
+ </RDF:Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <RDF:Description>
+ <em:id>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</em:id>
+ <em:maxVersion>2.0.*</em:maxVersion>
+ <em:minVersion>2.0a2</em:minVersion>
+
+ </RDF:Description>
+ </em:targetApplication>
+ </RDF:Description>
+</RDF:RDF>
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/colorediffs-extension.git
More information about the Pkg-mozext-commits
mailing list