OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file provides common methods that can be shared by other JavaScripts. | 5 // This file provides common methods that can be shared by other JavaScripts. |
6 | 6 |
| 7 goog.provide('__crweb.common'); |
| 8 |
7 /** | 9 /** |
8 * Namespace for this file. It depends on |__gCrWeb| having already been | 10 * Namespace for this file. It depends on |__gCrWeb| having already been |
9 * injected. String 'common' is used in |__gCrWeb['common']| as it needs to be | 11 * injected. String 'common' is used in |__gCrWeb['common']| as it needs to be |
10 * accessed in Objective-C code. | 12 * accessed in Objective-C code. |
11 */ | 13 */ |
12 __gCrWeb['common'] = {}; | 14 __gCrWeb['common'] = {}; |
13 | 15 |
14 /* Beginning of anonymous object. */ | 16 /* Beginning of anonymous object. */ |
15 new function() { | 17 new function() { |
16 // JSON safe object to protect against custom implementation of Object.toJSON | 18 // JSON safe object to protect against custom implementation of Object.toJSON |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 __gCrWeb.common.createAndDispatchHTMLEvent = function( | 571 __gCrWeb.common.createAndDispatchHTMLEvent = function( |
570 element, type, bubbles, cancelable) { | 572 element, type, bubbles, cancelable) { |
571 var changeEvent = element.ownerDocument.createEvent('HTMLEvents'); | 573 var changeEvent = element.ownerDocument.createEvent('HTMLEvents'); |
572 changeEvent.initEvent(type, bubbles, cancelable); | 574 changeEvent.initEvent(type, bubbles, cancelable); |
573 | 575 |
574 // A timer is used to avoid reentering JavaScript evaluation. | 576 // A timer is used to avoid reentering JavaScript evaluation. |
575 window.setTimeout(function() { | 577 window.setTimeout(function() { |
576 element.dispatchEvent(changeEvent); | 578 element.dispatchEvent(changeEvent); |
577 }, 0); | 579 }, 0); |
578 }; | 580 }; |
| 581 |
| 582 /** |
| 583 * Retrieves favicon information. |
| 584 * |
| 585 * @return {Object} Object containing favicon data. |
| 586 */ |
| 587 __gCrWeb.common.getFavicons = function() { |
| 588 var favicons = []; |
| 589 var hasFavicon = false; |
| 590 favicons.toJSON = null; // Never inherit Array.prototype.toJSON. |
| 591 var links = document.getElementsByTagName('link'); |
| 592 var linkCount = links.length; |
| 593 for (var i = 0; i < linkCount; ++i) { |
| 594 if (links[i].rel) { |
| 595 var rel = links[i].rel.toLowerCase(); |
| 596 if (rel == 'shortcut icon' || |
| 597 rel == 'icon' || |
| 598 rel == 'apple-touch-icon' || |
| 599 rel == 'apple-touch-icon-precomposed') { |
| 600 var favicon = { |
| 601 rel: links[i].rel.toLowerCase(), |
| 602 href: links[i].href |
| 603 }; |
| 604 favicons.push(favicon); |
| 605 if (rel == 'icon' || rel == 'shortcut icon') { |
| 606 hasFavicon = true; |
| 607 } |
| 608 } |
| 609 } |
| 610 } |
| 611 if (!hasFavicon) { |
| 612 // If an HTTP(S)? webpage does not reference a "favicon" then search |
| 613 // for a file named "favicon.ico" at the root of the website (legacy). |
| 614 // http://en.wikipedia.org/wiki/Favicon |
| 615 var location = document.location; |
| 616 if (location.protocol == 'http:' || location.protocol == 'https:') { |
| 617 var favicon = { |
| 618 rel: 'icon', |
| 619 href: location.origin + '/favicon.ico' |
| 620 }; |
| 621 favicons.push(favicon); |
| 622 } |
| 623 } |
| 624 return favicons; |
| 625 }; |
| 626 |
| 627 /** |
| 628 * Checks whether an <object> node is plugin content (as <object> can also be |
| 629 * used to embed images). |
| 630 * @param {HTMLElement} node The <object> node to check. |
| 631 * @return {Boolean} Whether the node appears to be a plugin. |
| 632 * @private |
| 633 */ |
| 634 var objectNodeIsPlugin_ = function(node) { |
| 635 return node.hasAttribute('classid') || |
| 636 (node.hasAttribute('type') && node.type.indexOf('image/') != 0); |
| 637 }; |
| 638 |
| 639 /** |
| 640 * Checks whether plugin a node has fallback content. |
| 641 * @param {HTMLElement} node The node to check. |
| 642 * @return {Boolean} Whether the node has fallback. |
| 643 * @private |
| 644 */ |
| 645 var pluginHasFallbackContent_ = function(node) { |
| 646 return node.textContent.trim().length > 0 || |
| 647 node.getElementsByTagName('img').length > 0; |
| 648 }; |
| 649 |
| 650 /** |
| 651 * Returns a list of plugin elements in the document that have no fallback |
| 652 * content. For nested plugins, only the innermost plugin element is returned. |
| 653 * @return {Array} A list of plugin elements. |
| 654 * @private |
| 655 */ |
| 656 var findPluginNodesWithoutFallback_ = function() { |
| 657 var pluginNodes = []; |
| 658 var objects = document.getElementsByTagName('object'); |
| 659 var objectCount = objects.length; |
| 660 for (var i = 0; i < objectCount; i++) { |
| 661 var object = objects[i]; |
| 662 if (objectNodeIsPlugin_(object) && |
| 663 !pluginHasFallbackContent_(object)) { |
| 664 pluginNodes.push(object); |
| 665 } |
| 666 } |
| 667 var applets = document.getElementsByTagName('applet'); |
| 668 var appletsCount = applets.length; |
| 669 for (var i = 0; i < appletsCount; i++) { |
| 670 var applet = applets[i]; |
| 671 if (!pluginHasFallbackContent_(applet)) { |
| 672 pluginNodes.push(applet); |
| 673 } |
| 674 } |
| 675 return pluginNodes; |
| 676 }; |
| 677 |
| 678 /** |
| 679 * Finds and stores any plugins that don't have placeholders. |
| 680 * Returns true if any plugins without placeholders are found. |
| 681 */ |
| 682 __gCrWeb.common.updatePluginPlaceholders = function() { |
| 683 var plugins = findPluginNodesWithoutFallback_(); |
| 684 if (plugins.length > 0) { |
| 685 // Store the list of plugins in a known place for the replacement script |
| 686 // to use, then trigger it. |
| 687 __gCrWeb['placeholderTargetPlugins'] = plugins; |
| 688 return true; |
| 689 } |
| 690 return false; |
| 691 }; |
579 } // End of anonymous object | 692 } // End of anonymous object |
OLD | NEW |