├── Deanimator.safariextension
├── Info.plist
├── Settings.plist
├── deanimator.js
└── global.html
├── LICENSE
└── readme.mdown
/Deanimator.safariextension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Author
6 | Mat Sadler
7 | CFBundleDisplayName
8 | Deanimator
9 | CFBundleIdentifier
10 | com.github.matsadler.deanimator
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleShortVersionString
14 | 0.3.0
15 | CFBundleVersion
16 | 0.3.0
17 | Chrome
18 |
19 | Global Page
20 | global.html
21 |
22 | Content
23 |
24 | Scripts
25 |
26 | Start
27 |
28 | deanimator.js
29 |
30 |
31 |
32 | Description
33 | Stop animated GIFs.
34 | ExtensionInfoDictionaryVersion
35 | 1.0
36 | Permissions
37 |
38 | Website Access
39 |
40 | Include Secure Pages
41 |
42 | Level
43 | All
44 |
45 |
46 | Update Manifest URL
47 | http://matsadler.github.com/deanimator/updates.plist
48 | Website
49 | http://github.com/matsadler/deanimator
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Deanimator.safariextension/Settings.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | DefaultValue
7 |
8 | Key
9 | applyToAll
10 | Title
11 | Apply to all images
12 | Type
13 | CheckBox
14 |
15 |
16 | DefaultValue
17 |
18 | Key
19 | applyToBackgroundImages
20 | Title
21 | Apply to background images
22 | Type
23 | CheckBox
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Deanimator.safariextension/deanimator.js:
--------------------------------------------------------------------------------
1 | var ImagesByURL = {
2 | hash: {},
3 | add: function (url, image) {
4 | var store = (this.hash[url] || (this.hash[url] = []));
5 | if (store.indexOf(image) < 0) {
6 | store.push(image);
7 | }
8 | return image;
9 | },
10 | remove: function (url) {
11 | var value = this.hash[url];
12 | delete this.hash[url];
13 | return value || [];
14 | },
15 | include: function (url) {
16 | return this.hash.hasOwnProperty(url);
17 | }
18 | };
19 |
20 | function deanimate(images) {
21 | [].slice.call(images).forEach(function (image) {
22 | if (!ImagesByURL.include(image.src)) {
23 | safari.self.tab.dispatchMessage("toDataURL", image.src);
24 | }
25 | ImagesByURL.add(image.src, image);
26 | });
27 | }
28 |
29 |
30 | function deanimateBackground(elements) {
31 | [].slice.call(elements).forEach(function (element) {
32 | var style = window.getComputedStyle(element, null),
33 | match = style.backgroundImage.match(/^url\((.*)\)$/),
34 | url = match ? match[1] : null;
35 | if (url) {
36 | if (!ImagesByURL.include(url)) {
37 | safari.self.tab.dispatchMessage("toDataURL", url);
38 | }
39 | ImagesByURL.add(url, element);
40 | }
41 | });
42 | }
43 |
44 | var Responders = {
45 | imageAsDataURL: function (event) {
46 | var message = event.message, images = ImagesByURL.remove(message.url);
47 | images.forEach(function (image) {
48 | if (image.src === message.url) {
49 | image.src = message.dataURL;
50 | }
51 | });
52 | images.forEach(function (image) {
53 | var style = window.getComputedStyle(image, null);
54 | if (style.backgroundImage === "url(" + message.url + ")") {
55 | image.style.backgroundImage = "url(" + message.dataURL + ")";
56 | }
57 | });
58 | },
59 | applyToBackgroundImages: function (event) {
60 | deanimateBackground(document.querySelectorAll("*"));
61 | }
62 | };
63 |
64 | safari.self.addEventListener("message", function (event) {
65 | var responder = Responders[event.name];
66 | if (responder) {
67 | responder(event);
68 | }
69 | });
70 |
71 | window.addEventListener("DOMContentLoaded", function (event) {
72 | deanimate(document.images);
73 | });
74 |
75 | window.addEventListener("load", function (event) {
76 | safari.self.tab.dispatchMessage("applyToBackgroundImages");
77 | });
78 |
79 | window.addEventListener("DOMNodeInserted", function (event) {
80 | if (event.target.tagName === "IMG") {
81 | deanimate([event.target]);
82 | } else if (event.target.getElementsByTagName) {
83 | deanimate(event.target.getElementsByTagName("img"));
84 | }
85 | });
--------------------------------------------------------------------------------
/Deanimator.safariextension/global.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | global
5 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2018 Matthew Sadler.
2 |
3 | Permission is hereby granted, free of charge, to any
4 | person obtaining a copy of this software and associated
5 | documentation files (the "Software"), to deal in the
6 | Software without restriction, including without
7 | limitation the rights to use, copy, modify, merge,
8 | publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software
10 | is furnished to do so, subject to the following
11 | conditions:
12 |
13 | The above copyright notice and this permission notice
14 | shall be included in all copies or substantial portions
15 | of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | DEALINGS IN THE SOFTWARE.
26 |
--------------------------------------------------------------------------------
/readme.mdown:
--------------------------------------------------------------------------------
1 | # Deanimator #
2 |
3 | Safari extension to stop/disable animated GIFs.
4 |
5 | [Download](http://github.com/downloads/matsadler/deanimator/Deanimator-0.3.0.safariextz)
--------------------------------------------------------------------------------