-
Notifications
You must be signed in to change notification settings - Fork 815
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10041 from Automattic/try/one-click-site-verify
One-click site verification and search console integration
- Loading branch information
Showing
20 changed files
with
685 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
Popup Monitor | ||
============= | ||
|
||
Popup Monitor is a small utility to facilitate the monitoring of a popup window close action, which is especially useful for temporary popup windows (e.g. an authorization step). | ||
|
||
## Usage | ||
|
||
A Popup Monitor instance offers an `open` function which accepts an identical set of arguments as the standard `window.open` browser offering. When the window is closed, a `close` event is emitted to the instance with the name of the closed window. | ||
|
||
```js | ||
import PopupMonitor 'lib/popup-monitor'; | ||
|
||
const popupMonitor = new PopupMonitor(); | ||
|
||
popupMonitor.open( 'https://wordpress.com/', 'my-popup' ); | ||
|
||
popupMonitor.on( 'close', function( name ) { | ||
if ( 'my-popup' === name ) { | ||
console.log( 'Window closed!' ); | ||
} | ||
} ); | ||
``` | ||
|
||
## Methods | ||
|
||
- `open( url, name, features )`: Proxies an identical call to `window.open` and begins to monitor the window open state. | ||
- `getScreenCenterSpecs( width, height )`: A helper method for generating a feature (specification) string of a specific width and height at the center of the user's screen. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/** @format */ | ||
|
||
/** | ||
* External dependencies | ||
*/ | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import Emitter from 'mixins/emitter'; | ||
|
||
/** | ||
* PopupMonitor component | ||
* | ||
* @public | ||
*/ | ||
function PopupMonitor() { | ||
this.intervals = {}; | ||
this.monitorInterval = null; | ||
this.windowInstance = null; | ||
this.onMessage = messageEvent => { | ||
if ( messageEvent.source === this.windowInstance ) { | ||
this.emit( 'message', messageEvent.data ); | ||
} | ||
}; | ||
} | ||
|
||
Emitter( PopupMonitor.prototype ); | ||
|
||
/** | ||
* Opens a new popup and starts monitoring it for changes. This should only be | ||
* invoked on a user action to avoid the popup being blocked. Returns the | ||
* current instance of PopupMonitor to enable chainability | ||
* | ||
* @param {string} url The URL to be loaded in the newly opened window | ||
* @param {string} name A string name for the new window | ||
* @param {string} specs An optional parameter listing the features of the new window as a string | ||
* @return {PopupMonitor} this instance | ||
* @public | ||
*/ | ||
PopupMonitor.prototype.open = function( url, name, specs ) { | ||
name = name || Date.now(); | ||
|
||
this.windowInstance = window.open( url, name, specs ); | ||
this.startMonitoring( name, this.windowInstance ); | ||
|
||
window.addEventListener( 'message', this.onMessage, false ); | ||
|
||
return this; | ||
}; | ||
|
||
/** | ||
* Returns a popup window specification string fragment containing properties | ||
* to visually center the popup on the user's current screen. | ||
* | ||
* @param {number} width The desired width of the popup | ||
* @param {number} height The desired height of the popup | ||
* @return {string} Popup window specificatino string fragment | ||
* @public | ||
*/ | ||
PopupMonitor.prototype.getScreenCenterSpecs = function( width, height ) { | ||
const screenTop = typeof window.screenTop !== 'undefined' ? window.screenTop : window.screenY, | ||
screenLeft = typeof window.screenLeft !== 'undefined' ? window.screenLeft : window.screenX; | ||
|
||
return [ | ||
'width=' + width, | ||
'height=' + height, | ||
'top=' + ( screenTop + window.innerHeight / 2 - height / 2 ), | ||
'left=' + ( screenLeft + window.innerWidth / 2 - width / 2 ), | ||
].join(); | ||
}; | ||
|
||
/** | ||
* Returns true if the popup with the specified name is closed, or false | ||
* otherwise | ||
* | ||
* @param {string} name The name of the popup window to check | ||
* @return {boolean} result | ||
* @public | ||
*/ | ||
PopupMonitor.prototype.isOpen = function( name ) { | ||
let isClosed = false; | ||
|
||
try { | ||
isClosed = this.intervals[ name ] && this.intervals[ name ].closed; | ||
} catch ( e ) {} | ||
|
||
return ! isClosed; | ||
}; | ||
|
||
/** | ||
* Detects if any popup windows have closed since the last interval run and | ||
* triggers a close event for any closed windows. If no popup windows remain | ||
* open, then the interval is stopped. | ||
*/ | ||
PopupMonitor.prototype.checkStatus = function() { | ||
for ( const name in this.intervals ) { | ||
if ( this.intervals.hasOwnProperty( name ) && ! this.isOpen( name ) ) { | ||
this.emit( 'close', name ); | ||
delete this.intervals[ name ]; | ||
} | ||
} | ||
|
||
if ( 0 === Object.keys( this.intervals ).length ) { | ||
clearInterval( this.monitorInterval ); | ||
delete this.monitorInterval; | ||
window.removeEventListener( 'message', this.onMessage ); | ||
} | ||
}; | ||
|
||
/** | ||
* Starts monitoring a popup window instance for changes on a recurring | ||
* interval. | ||
* | ||
* @param {string} name The name of hte popup window to monitor | ||
* @param {window} windowInstance The popup window instance | ||
*/ | ||
PopupMonitor.prototype.startMonitoring = function( name, windowInstance ) { | ||
if ( ! this.monitorInterval ) { | ||
this.monitorInterval = setInterval( this.checkStatus.bind( this ), 100 ); | ||
} | ||
|
||
this.intervals[ name ] = windowInstance; | ||
}; | ||
|
||
export default PopupMonitor; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
Sharing | ||
========= | ||
|
||
Small utility library for requesting authorization of sharing services. | ||
|
||
## Usage | ||
|
||
```es6 | ||
import requestExternalAccess from 'lib/sharing'; | ||
|
||
requestExternalAccess( service.connect_URL, () => { | ||
// Do something after the authorization window has closed | ||
} ); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import PopupMonitor from 'lib/popup-monitor'; | ||
|
||
const requestExternalAccess = ( url, cb ) => { | ||
const popupMonitor = new PopupMonitor(); | ||
let lastMessage; | ||
|
||
popupMonitor.open( | ||
url, | ||
null, | ||
'toolbar=0,location=0,status=0,menubar=0,' + popupMonitor.getScreenCenterSpecs( 780, 700 ) | ||
); | ||
|
||
popupMonitor.once( 'close', () => { | ||
let keyringId = null; | ||
if ( lastMessage && lastMessage.keyring_id ) { | ||
keyringId = Number( lastMessage.keyring_id ); | ||
} | ||
cb( keyringId ); | ||
} ); | ||
|
||
popupMonitor.on( 'message', message => ( lastMessage = message ) ); | ||
}; | ||
|
||
export default requestExternalAccess; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import * as reducer from './reducer'; | ||
|
||
export default reducer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { combineReducers } from 'redux'; | ||
import get from 'lodash/get'; | ||
import assign from 'lodash/assign'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
JETPACK_SET_INITIAL_STATE, | ||
} from 'state/action-types'; | ||
|
||
export const connectUrls = ( state = {}, action ) => { | ||
switch ( action.type ) { | ||
case JETPACK_SET_INITIAL_STATE: | ||
return assign( {}, action.initialState.externalServicesConnectUrls ); | ||
default: | ||
return state; | ||
} | ||
}; | ||
|
||
export const reducer = combineReducers( { | ||
connectUrls, | ||
} ); | ||
|
||
/** | ||
* Return a connect url for a given service name. | ||
* | ||
* @param {Object} state Global state tree. | ||
* @param {String} serviceName Name of the external service. | ||
* @return {String} Url to connect to the service or null. | ||
*/ | ||
export function getExternalServiceConnectUrl( state, serviceName ) { | ||
return get( state.jetpack.publicize.connectUrls, serviceName, null ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
JETPACK_SITE_VERIFY_GOOGLE_STATUS_FETCH, | ||
JETPACK_SITE_VERIFY_GOOGLE_STATUS_FETCH_FAIL, | ||
JETPACK_SITE_VERIFY_GOOGLE_STATUS_FETCH_SUCCESS, | ||
JETPACK_SITE_VERIFY_GOOGLE_REQUEST, | ||
JETPACK_SITE_VERIFY_GOOGLE_REQUEST_SUCCESS, | ||
JETPACK_SITE_VERIFY_GOOGLE_REQUEST_FAIL, | ||
} from 'state/action-types'; | ||
|
||
import restApi from 'rest-api'; | ||
import { translate as __ } from 'i18n-calypso'; | ||
import { createNotice } from 'components/global-notices/state/notices/actions'; | ||
|
||
export const checkVerifyStatusGoogle = () => { | ||
return ( dispatch ) => { | ||
dispatch( { | ||
type: JETPACK_SITE_VERIFY_GOOGLE_STATUS_FETCH | ||
} ); | ||
return restApi.fetchVerifySiteGoogleStatus().then( data => { | ||
dispatch( { | ||
type: JETPACK_SITE_VERIFY_GOOGLE_STATUS_FETCH_SUCCESS, | ||
verified: data.verified, | ||
token: data.token | ||
} ); | ||
|
||
return data; | ||
} ).catch( error => { | ||
dispatch( { | ||
type: JETPACK_SITE_VERIFY_GOOGLE_STATUS_FETCH_FAIL, | ||
error: error.response, | ||
} ); | ||
|
||
return Promise.reject( error.response ); | ||
} ); | ||
}; | ||
}; | ||
|
||
export const verifySiteGoogle = () => { | ||
return ( dispatch ) => { | ||
dispatch( { | ||
type: JETPACK_SITE_VERIFY_GOOGLE_REQUEST | ||
} ); | ||
return restApi.verifySiteGoogle().then( data => { | ||
dispatch( { | ||
verified: data.verified, | ||
type: JETPACK_SITE_VERIFY_GOOGLE_REQUEST_SUCCESS, | ||
} ); | ||
|
||
if ( data.verified ) { | ||
dispatch( createNotice( 'is-success', __( 'Site is verified' ), { id: 'verify-site-google-verified', duration: 2000 } ) ); | ||
} | ||
|
||
return data; | ||
} ).catch( error => { | ||
dispatch( { | ||
type: JETPACK_SITE_VERIFY_GOOGLE_REQUEST_FAIL, | ||
error: error.response, | ||
} ); | ||
|
||
return Promise.reject( error.response ); | ||
} ); | ||
}; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import * as reducer from './reducer'; | ||
import * as actions from './actions'; | ||
|
||
const all = { ...reducer, ...actions }; | ||
|
||
export default all; |
Oops, something went wrong.