From 4062030731a3af81bfa0f7c0b373320fcd4b5dd1 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Fri, 10 May 2019 14:03:21 -0700 Subject: [PATCH] Remove goog.userAgent dependency. --- core/bubble.js | 9 +++---- core/comment.js | 5 ++-- core/contextmenu.js | 5 ++-- core/field.js | 3 +-- core/field_angle.js | 10 ++++---- core/field_dropdown.js | 7 +++--- core/field_textinput.js | 12 ++++----- core/flyout_horizontal.js | 1 - core/flyout_vertical.js | 4 +-- core/grid.js | 4 +-- core/inject.js | 3 +-- core/utils.js | 51 +++++++++++++++++++++++++++++++++++---- core/workspace_audio.js | 12 ++++----- 13 files changed, 79 insertions(+), 47 deletions(-) diff --git a/core/bubble.js b/core/bubble.js index 7befb33cc..ef2ff9c71 100644 --- a/core/bubble.js +++ b/core/bubble.js @@ -27,9 +27,10 @@ goog.provide('Blockly.Bubble'); goog.require('Blockly.Touch'); +goog.require('Blockly.utils'); goog.require('Blockly.Workspace'); + goog.require('goog.math.Coordinate'); -goog.require('goog.userAgent'); /** @@ -224,10 +225,8 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) { this.bubbleGroup_ = Blockly.utils.createSvgElement('g', {}, null); var filter = {'filter': 'url(#' + this.workspace_.options.embossFilterId + ')'}; - if (goog.userAgent.getUserAgentString().indexOf('JavaFX') != -1) { - // Multiple reports that JavaFX can't handle filters. UserAgent: - // Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.44 - // (KHTML, like Gecko) JavaFX/8.0 Safari/537.44 + if (Blockly.utils.userAgent.JAVA_FX) { + // Multiple reports that JavaFX can't handle filters. // https://github.com/google/blockly/issues/99 filter = {}; } diff --git a/core/comment.js b/core/comment.js index a1d7fbc02..f269e5ec6 100644 --- a/core/comment.js +++ b/core/comment.js @@ -32,8 +32,6 @@ goog.require('Blockly.Events.Ui'); goog.require('Blockly.Icon'); goog.require('Blockly.utils'); -goog.require('goog.userAgent'); - /** * Class for a comment. @@ -184,7 +182,8 @@ Blockly.Comment.prototype.setVisible = function(visible) { } Blockly.Events.fire( new Blockly.Events.Ui(this.block_, 'commentOpen', !visible, visible)); - if ((!this.block_.isEditable() && !this.textarea_) || goog.userAgent.IE) { + if ((!this.block_.isEditable() && !this.textarea_) || + Blockly.utils.userAgent.IE) { // Steal the code from warnings to make an uneditable text bubble. // MSIE does not support foreignobject; textareas are impossible. // https://docs.microsoft.com/en-us/openspecs/ie_standards/ms-svg/56e6e04c-7c8c-44dd-8100-bd745ee42034 diff --git a/core/contextmenu.js b/core/contextmenu.js index bd8b38f8e..e8e75f18d 100644 --- a/core/contextmenu.js +++ b/core/contextmenu.js @@ -39,7 +39,6 @@ goog.require('goog.events'); goog.require('goog.math.Coordinate'); goog.require('goog.ui.Menu'); goog.require('goog.ui.MenuItem'); -goog.require('goog.userAgent'); /** @@ -280,7 +279,7 @@ Blockly.ContextMenu.blockDuplicateOption = function(block) { */ Blockly.ContextMenu.blockCommentOption = function(block) { var commentOption = { - enabled: !goog.userAgent.IE + enabled: !Blockly.utils.userAgent.IE }; // If there's already a comment, add an option to delete it. if (block.comment) { @@ -388,7 +387,7 @@ Blockly.ContextMenu.workspaceCommentOption = function(ws, e) { var wsCommentOption = { // Foreign objects don't work in IE. Don't let the user create comments // that they won't be able to edit. - enabled: !goog.userAgent.IE + enabled: !Blockly.utils.userAgent.IE }; wsCommentOption.text = Blockly.Msg.ADD_COMMENT; wsCommentOption.callback = function() { diff --git a/core/field.js b/core/field.js index 854bfad85..54d4cf657 100644 --- a/core/field.js +++ b/core/field.js @@ -34,7 +34,6 @@ goog.require('Blockly.utils'); goog.require('goog.math.Size'); goog.require('goog.style'); -goog.require('goog.userAgent'); /** @@ -496,7 +495,7 @@ Blockly.Field.getCachedWidth = function(textElement) { // Attempt to compute fetch the width of the SVG text element. try { - if (goog.userAgent.IE || goog.userAgent.EDGE) { + if (Blockly.utils.userAgent.IE || Blockly.utils.userAgent.EDGE) { width = textElement.getBBox().width; } else { width = textElement.getComputedTextLength(); diff --git a/core/field_angle.js b/core/field_angle.js index edea08ae4..3fb335bd1 100644 --- a/core/field_angle.js +++ b/core/field_angle.js @@ -30,8 +30,6 @@ goog.require('Blockly.DropDownDiv'); goog.require('Blockly.FieldTextInput'); goog.require('Blockly.utils'); -goog.require('goog.userAgent'); - /** * Class for an editable angle field. @@ -163,7 +161,9 @@ Blockly.FieldAngle.prototype.dispose_ = function() { */ Blockly.FieldAngle.prototype.showEditor_ = function() { var noFocus = - goog.userAgent.MOBILE || goog.userAgent.ANDROID || goog.userAgent.IPAD; + Blockly.utils.userAgent.MOBILE || + Blockly.utils.userAgent.ANDROID || + Blockly.utils.userAgent.IPAD; // Mobile browsers have issues with in-line textareas (focus & keyboards). Blockly.FieldAngle.superClass_.showEditor_.call(this, noFocus); @@ -207,10 +207,10 @@ Blockly.FieldAngle.prototype.showEditor_ = function() { }, svg); } - + var border = this.sourceBlock_.getColourBorder(); border = border.colourBorder == null ? border.colourLight : border.colourBorder; - + Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), border); Blockly.DropDownDiv.showPositionedByField(this); // The angle picker is different from other fields in that it updates on diff --git a/core/field_dropdown.js b/core/field_dropdown.js index ac2475f3a..a0c18f3d0 100644 --- a/core/field_dropdown.js +++ b/core/field_dropdown.js @@ -35,7 +35,6 @@ goog.require('Blockly.utils.uiMenu'); goog.require('goog.events'); goog.require('goog.ui.Menu'); goog.require('goog.ui.MenuItem'); -goog.require('goog.userAgent'); /** @@ -97,7 +96,8 @@ Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH = 0.45; /** * Android can't (in 2014) display "▾", so use "▼" instead. */ -Blockly.FieldDropdown.ARROW_CHAR = goog.userAgent.ANDROID ? '\u25BC' : '\u25BE'; +Blockly.FieldDropdown.ARROW_CHAR = + Blockly.utils.userAgent.ANDROID ? '\u25BC' : '\u25BE'; /** * Mouse cursor style when over the hotspot that initiates the editor. @@ -525,7 +525,8 @@ Blockly.FieldDropdown.prototype.renderSelectedText_ = function() { * implementation. */ Blockly.FieldDropdown.prototype.updateWidth = function() { - if (this.imageJson_ && (goog.userAgent.IE || goog.userAgent.EDGE)) { + if (this.imageJson_ && + (Blockly.utils.userAgent.IE || Blockly.utils.userAgent.EDGE)) { // Recalculate the full width. var arrowWidth = Blockly.Field.getCachedWidth(this.arrow_); var width = Number(this.imageJson_.width) + arrowWidth + diff --git a/core/field_textinput.js b/core/field_textinput.js index 997552f1d..251d06898 100644 --- a/core/field_textinput.js +++ b/core/field_textinput.js @@ -32,7 +32,6 @@ goog.require('Blockly.Msg'); goog.require('Blockly.utils'); goog.require('goog.math.Coordinate'); -goog.require('goog.userAgent'); /** @@ -166,8 +165,9 @@ Blockly.FieldTextInput.prototype.setSpellcheck = function(check) { Blockly.FieldTextInput.prototype.showEditor_ = function(opt_quietInput) { this.workspace_ = this.sourceBlock_.workspace; var quietInput = opt_quietInput || false; - if (!quietInput && (goog.userAgent.MOBILE || goog.userAgent.ANDROID || - goog.userAgent.IPAD)) { + if (!quietInput && (Blockly.utils.userAgent.MOBILE || + Blockly.utils.userAgent.ANDROID || + Blockly.utils.userAgent.IPAD)) { this.showPromptEditor_(); } else { this.showInlineEditor_(quietInput); @@ -301,7 +301,7 @@ Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(_e) { this.setValue(text); Blockly.Events.setGroup(false); this.validate_(); - } else if (goog.userAgent.WEBKIT) { + } else if (Blockly.utils.userAgent.WEBKIT) { // Cursor key. Render the source block to show the caret moving. // Chrome only (version 26, OS X). this.sourceBlock_.render(); @@ -348,13 +348,13 @@ Blockly.FieldTextInput.prototype.resizeEditor_ = function() { // Shift by a few pixels to line up exactly. xy.y += 1; - if (goog.userAgent.GECKO && Blockly.WidgetDiv.DIV.style.top) { + if (Blockly.utils.userAgent.GECKO && Blockly.WidgetDiv.DIV.style.top) { // Firefox mis-reports the location of the border by a pixel // once the WidgetDiv is moved into position. xy.x -= 1; xy.y -= 1; } - if (goog.userAgent.WEBKIT) { + if (Blockly.utils.userAgent.WEBKIT) { xy.y -= 3; } div.style.left = xy.x + 'px'; diff --git a/core/flyout_horizontal.js b/core/flyout_horizontal.js index 33f9eaa19..4000aa81d 100644 --- a/core/flyout_horizontal.js +++ b/core/flyout_horizontal.js @@ -33,7 +33,6 @@ goog.require('Blockly.Flyout'); goog.require('Blockly.WorkspaceSvg'); goog.require('goog.math.Rect'); -goog.require('goog.userAgent'); /** diff --git a/core/flyout_vertical.js b/core/flyout_vertical.js index d88c669f4..417a3e4f6 100644 --- a/core/flyout_vertical.js +++ b/core/flyout_vertical.js @@ -30,10 +30,10 @@ goog.require('Blockly.Block'); goog.require('Blockly.Events'); goog.require('Blockly.Flyout'); goog.require('Blockly.FlyoutButton'); +goog.require('Blockly.utils'); goog.require('Blockly.WorkspaceSvg'); goog.require('goog.math.Rect'); -goog.require('goog.userAgent'); /** @@ -337,7 +337,7 @@ Blockly.VerticalFlyout.prototype.getClientRect = function() { // Firefox sometimes reports the wrong value for the client rect. // See https://github.com/google/blockly/issues/1425 and // https://bugzilla.mozilla.org/show_bug.cgi?id=1066435 - if (goog.userAgent.GECKO && + if (Blockly.utils.userAgent.GECKO && this.targetWorkspace_ && this.targetWorkspace_.isMutator) { // The position of the left side of the mutator workspace in pixels // relative to the window origin. diff --git a/core/grid.js b/core/grid.js index ae6a8f9ca..52669ca51 100644 --- a/core/grid.js +++ b/core/grid.js @@ -29,8 +29,6 @@ goog.provide('Blockly.Grid'); goog.require('Blockly.utils'); -goog.require('goog.userAgent'); - /** * Class for a workspace's grid. @@ -187,7 +185,7 @@ Blockly.Grid.prototype.moveTo = function(x, y) { this.gridPattern_.setAttribute('x', x); this.gridPattern_.setAttribute('y', y); - if (goog.userAgent.IE || goog.userAgent.EDGE) { + if (Blockly.utils.userAgent.IE || Blockly.utils.userAgent.EDGE) { // IE/Edge doesn't notice that the x/y offsets have changed. // Force an update. this.update(this.scale_); diff --git a/core/inject.js b/core/inject.js index 57d2a13b4..deeb6c63a 100644 --- a/core/inject.js +++ b/core/inject.js @@ -36,7 +36,6 @@ goog.require('Blockly.WorkspaceSvg'); goog.require('Blockly.WorkspaceDragSurfaceSvg'); goog.require('goog.ui.Component'); -goog.require('goog.userAgent'); /** @@ -434,7 +433,7 @@ Blockly.inject.bindDocumentEvents_ = function() { Blockly.bindEvent_(document, 'touchend', null, Blockly.longStop_); Blockly.bindEvent_(document, 'touchcancel', null, Blockly.longStop_); // Some iPad versions don't fire resize after portrait to landscape change. - if (goog.userAgent.IPAD) { + if (Blockly.utils.userAgent.IPAD) { Blockly.bindEventWithChecks_(window, 'orientationchange', document, function() { // TODO (#397): Fix for multiple Blockly workspaces. diff --git a/core/utils.js b/core/utils.js index 2a30ae6bf..617d5bfdc 100644 --- a/core/utils.js +++ b/core/utils.js @@ -34,7 +34,6 @@ goog.provide('Blockly.utils'); goog.require('goog.dom'); goog.require('goog.math.Coordinate'); -goog.require('goog.userAgent'); /** @@ -46,9 +45,7 @@ goog.require('goog.userAgent'); * @param {string} attributeName Name of attribute to remove. */ Blockly.utils.removeAttribute = function(element, attributeName) { - // goog.userAgent.isVersion is deprecated, but the replacement is - // goog.userAgent.isVersionOrHigher. - if (goog.userAgent.IE && goog.userAgent.isVersion('10.0')) { + if (Blockly.utils.userAgent.IE10) { element.setAttribute(attributeName, null); } else { element.removeAttribute(attributeName); @@ -277,7 +274,7 @@ Blockly.utils.createSvgElement = function(name, attrs, parent) { * @return {boolean} True if right-click. */ Blockly.utils.isRightButton = function(e) { - if (e.ctrlKey && goog.userAgent.MAC) { + if (e.ctrlKey && Blockly.utils.userAgent.MAC) { // Control-clicking on Mac OS X is treated as a right-click. // WebKit on Mac OS X fails to change button to 2 (but Gecko does). return true; @@ -1046,3 +1043,47 @@ Blockly.utils.clampNumber = function(lowerBound, number, upperBound) { } return Math.max(lowerBound, Math.min(number, upperBound)); }; + +Blockly.utils.userAgent = {}; +(function(raw) { + Blockly.utils.userAgent.raw = raw; + var rawUpper = Blockly.utils.userAgent.raw.toUpperCase(); + /** + * Case-insensitive test of whether name is in the useragent string. + * @param {string} name Name to test. + */ + function has(name) { + return rawUpper.indexOf(name.toUpperCase()) != -1; + } + // Browsers. Logic from: + // https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/browser.js + Blockly.utils.userAgent.IE = has('Trident') || has('MSIE'); + Blockly.utils.userAgent.IE10 = has('MSIE 10.0'); // 10.1 does not exist. + Blockly.utils.userAgent.EDGE = has('Edge'); + // Useragent for JavaFX: + // Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.44 + // (KHTML, like Gecko) JavaFX/8.0 Safari/537.44 + Blockly.utils.userAgent.JAVA_FX = has('JavaFX'); + // Engines. Logic from: + // https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/engine.js + Blockly.utils.userAgent.WEBKIT = has('WebKit') && + !Blockly.utils.userAgent.EDGE; + Blockly.utils.userAgent.GECKO = has('Gecko') && + !Blockly.utils.userAgent.IE && !Blockly.utils.userAgent.EDGE; + // Platform. Logic from: + // https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/platform.js + Blockly.utils.userAgent.ANDROID = has('Android'); + Blockly.utils.userAgent.IPAD = has('iPad'); + Blockly.utils.userAgent.IPOD = has('iPod'); + Blockly.utils.userAgent.IPHONE = has('iPhone') && + !Blockly.utils.userAgent.IPAD && !Blockly.utils.userAgent.IPOD; + Blockly.utils.userAgent.MAC = has('Macintosh'); + // Device. Logic from: + // https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/device.js + Blockly.utils.userAgent.TABLET = Blockly.utils.userAgent.IPAD || + (Blockly.utils.userAgent.ANDROID && !has('Mobile')) || has('Silk'); + Blockly.utils.userAgent.MOBILE = !Blockly.utils.userAgent.TABLET && + (Blockly.utils.userAgent.IPOD || Blockly.utils.userAgent.IPHONE || + Blockly.utils.userAgent.ANDROID || has('IEMobile')); +})((this.navigator && this.navigator.userAgent) || ''); + diff --git a/core/workspace_audio.js b/core/workspace_audio.js index 8b7089f91..8d58c4156 100644 --- a/core/workspace_audio.js +++ b/core/workspace_audio.js @@ -27,7 +27,7 @@ goog.provide('Blockly.WorkspaceAudio'); -goog.require('goog.userAgent'); +goog.require('Blockly.utils'); /** @@ -115,7 +115,7 @@ Blockly.WorkspaceAudio.prototype.preload = function() { sound.pause(); // iOS can only process one sound at a time. Trying to load more than one // corrupts the earlier ones. Just load one and leave the others uncached. - if (goog.userAgent.IPAD || goog.userAgent.IPHONE) { + if (Blockly.utils.userAgent.IPAD || Blockly.utils.userAgent.IPHONE) { break; } } @@ -138,11 +138,9 @@ Blockly.WorkspaceAudio.prototype.play = function(name, opt_volume) { } this.lastSound_ = now; var mySound; - var ie9 = goog.userAgent.DOCUMENT_MODE && - goog.userAgent.DOCUMENT_MODE === 9; - if (ie9 || goog.userAgent.IPAD || goog.userAgent.ANDROID) { - // Creating a new audio node causes lag in IE9, Android and iPad. Android - // and IE9 refetch the file from the server, iPad uses a singleton audio + if (Blockly.utils.userAgent.IPAD || Blockly.utils.userAgent.ANDROID) { + // Creating a new audio node causes lag in Android and iPad. Android + // refetches the file from the server, iPad uses a singleton audio // node which must be deleted and recreated for each new audio tag. mySound = sound; } else {